diff options
author | Thierry Reding <treding@nvidia.com> | 2015-08-07 03:29:54 -0400 |
---|---|---|
committer | Thierry Reding <treding@nvidia.com> | 2016-07-04 05:37:00 -0400 |
commit | ef8187d752650fe79239c5de9efc906cb7f6b30d (patch) | |
tree | 7f704924cb03f038f04462000dad4bc41afe4366 /drivers/gpu/drm/tegra/dsi.c | |
parent | 33a8eb8d40ee7fc07f23a407607bdbaa46893b2d (diff) |
drm/tegra: dsi: Implement runtime PM
Use runtime PM to clock-(un)gate, (de)assert reset and control power to
the DSI controller. This ties in nicely with atomic DPMS in that a
runtime PM reference is taken before a pipe is enabled and dropped after
it has been shut down.
Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/gpu/drm/tegra/dsi.c')
-rw-r--r-- | drivers/gpu/drm/tegra/dsi.c | 235 |
1 files changed, 132 insertions, 103 deletions
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index d1239ebc190f..7e75215a9de4 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/of.h> | 13 | #include <linux/of.h> |
14 | #include <linux/of_platform.h> | 14 | #include <linux/of_platform.h> |
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | #include <linux/pm_runtime.h> | ||
16 | #include <linux/reset.h> | 17 | #include <linux/reset.h> |
17 | 18 | ||
18 | #include <linux/regulator/consumer.h> | 19 | #include <linux/regulator/consumer.h> |
@@ -677,6 +678,45 @@ static void tegra_dsi_ganged_disable(struct tegra_dsi *dsi) | |||
677 | tegra_dsi_writel(dsi, 0, DSI_GANGED_MODE_CONTROL); | 678 | tegra_dsi_writel(dsi, 0, DSI_GANGED_MODE_CONTROL); |
678 | } | 679 | } |
679 | 680 | ||
681 | static int tegra_dsi_pad_enable(struct tegra_dsi *dsi) | ||
682 | { | ||
683 | u32 value; | ||
684 | |||
685 | value = DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0); | ||
686 | tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_0); | ||
687 | |||
688 | return 0; | ||
689 | } | ||
690 | |||
691 | static int tegra_dsi_pad_calibrate(struct tegra_dsi *dsi) | ||
692 | { | ||
693 | u32 value; | ||
694 | |||
695 | /* | ||
696 | * XXX Is this still needed? The module reset is deasserted right | ||
697 | * before this function is called. | ||
698 | */ | ||
699 | tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_0); | ||
700 | tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_1); | ||
701 | tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_2); | ||
702 | tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_3); | ||
703 | tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_4); | ||
704 | |||
705 | /* start calibration */ | ||
706 | tegra_dsi_pad_enable(dsi); | ||
707 | |||
708 | value = DSI_PAD_SLEW_UP(0x7) | DSI_PAD_SLEW_DN(0x7) | | ||
709 | DSI_PAD_LP_UP(0x1) | DSI_PAD_LP_DN(0x1) | | ||
710 | DSI_PAD_OUT_CLK(0x0); | ||
711 | tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_2); | ||
712 | |||
713 | value = DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) | | ||
714 | DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3); | ||
715 | tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_3); | ||
716 | |||
717 | return tegra_mipi_calibrate(dsi->mipi); | ||
718 | } | ||
719 | |||
680 | static void tegra_dsi_set_timeout(struct tegra_dsi *dsi, unsigned long bclk, | 720 | static void tegra_dsi_set_timeout(struct tegra_dsi *dsi, unsigned long bclk, |
681 | unsigned int vrefresh) | 721 | unsigned int vrefresh) |
682 | { | 722 | { |
@@ -837,7 +877,7 @@ static void tegra_dsi_encoder_disable(struct drm_encoder *encoder) | |||
837 | 877 | ||
838 | tegra_dsi_disable(dsi); | 878 | tegra_dsi_disable(dsi); |
839 | 879 | ||
840 | return; | 880 | pm_runtime_put(dsi->dev); |
841 | } | 881 | } |
842 | 882 | ||
843 | static void tegra_dsi_encoder_enable(struct drm_encoder *encoder) | 883 | static void tegra_dsi_encoder_enable(struct drm_encoder *encoder) |
@@ -848,6 +888,13 @@ static void tegra_dsi_encoder_enable(struct drm_encoder *encoder) | |||
848 | struct tegra_dsi *dsi = to_dsi(output); | 888 | struct tegra_dsi *dsi = to_dsi(output); |
849 | struct tegra_dsi_state *state; | 889 | struct tegra_dsi_state *state; |
850 | u32 value; | 890 | u32 value; |
891 | int err; | ||
892 | |||
893 | pm_runtime_get_sync(dsi->dev); | ||
894 | |||
895 | err = tegra_dsi_pad_calibrate(dsi); | ||
896 | if (err < 0) | ||
897 | dev_err(dsi->dev, "MIPI calibration failed: %d\n", err); | ||
851 | 898 | ||
852 | state = tegra_dsi_get_state(dsi); | 899 | state = tegra_dsi_get_state(dsi); |
853 | 900 | ||
@@ -876,8 +923,6 @@ static void tegra_dsi_encoder_enable(struct drm_encoder *encoder) | |||
876 | 923 | ||
877 | if (output->panel) | 924 | if (output->panel) |
878 | drm_panel_enable(output->panel); | 925 | drm_panel_enable(output->panel); |
879 | |||
880 | return; | ||
881 | } | 926 | } |
882 | 927 | ||
883 | static int | 928 | static int |
@@ -967,55 +1012,12 @@ static const struct drm_encoder_helper_funcs tegra_dsi_encoder_helper_funcs = { | |||
967 | .atomic_check = tegra_dsi_encoder_atomic_check, | 1012 | .atomic_check = tegra_dsi_encoder_atomic_check, |
968 | }; | 1013 | }; |
969 | 1014 | ||
970 | static int tegra_dsi_pad_enable(struct tegra_dsi *dsi) | ||
971 | { | ||
972 | u32 value; | ||
973 | |||
974 | value = DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0); | ||
975 | tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_0); | ||
976 | |||
977 | return 0; | ||
978 | } | ||
979 | |||
980 | static int tegra_dsi_pad_calibrate(struct tegra_dsi *dsi) | ||
981 | { | ||
982 | u32 value; | ||
983 | |||
984 | tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_0); | ||
985 | tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_1); | ||
986 | tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_2); | ||
987 | tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_3); | ||
988 | tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_4); | ||
989 | |||
990 | /* start calibration */ | ||
991 | tegra_dsi_pad_enable(dsi); | ||
992 | |||
993 | value = DSI_PAD_SLEW_UP(0x7) | DSI_PAD_SLEW_DN(0x7) | | ||
994 | DSI_PAD_LP_UP(0x1) | DSI_PAD_LP_DN(0x1) | | ||
995 | DSI_PAD_OUT_CLK(0x0); | ||
996 | tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_2); | ||
997 | |||
998 | value = DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) | | ||
999 | DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3); | ||
1000 | tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_3); | ||
1001 | |||
1002 | return tegra_mipi_calibrate(dsi->mipi); | ||
1003 | } | ||
1004 | |||
1005 | static int tegra_dsi_init(struct host1x_client *client) | 1015 | static int tegra_dsi_init(struct host1x_client *client) |
1006 | { | 1016 | { |
1007 | struct drm_device *drm = dev_get_drvdata(client->parent); | 1017 | struct drm_device *drm = dev_get_drvdata(client->parent); |
1008 | struct tegra_dsi *dsi = host1x_client_to_dsi(client); | 1018 | struct tegra_dsi *dsi = host1x_client_to_dsi(client); |
1009 | int err; | 1019 | int err; |
1010 | 1020 | ||
1011 | reset_control_deassert(dsi->rst); | ||
1012 | |||
1013 | err = tegra_dsi_pad_calibrate(dsi); | ||
1014 | if (err < 0) { | ||
1015 | dev_err(dsi->dev, "MIPI calibration failed: %d\n", err); | ||
1016 | goto reset; | ||
1017 | } | ||
1018 | |||
1019 | /* Gangsters must not register their own outputs. */ | 1021 | /* Gangsters must not register their own outputs. */ |
1020 | if (!dsi->master) { | 1022 | if (!dsi->master) { |
1021 | dsi->output.dev = client->dev; | 1023 | dsi->output.dev = client->dev; |
@@ -1038,12 +1040,9 @@ static int tegra_dsi_init(struct host1x_client *client) | |||
1038 | drm_connector_register(&dsi->output.connector); | 1040 | drm_connector_register(&dsi->output.connector); |
1039 | 1041 | ||
1040 | err = tegra_output_init(drm, &dsi->output); | 1042 | err = tegra_output_init(drm, &dsi->output); |
1041 | if (err < 0) { | 1043 | if (err < 0) |
1042 | dev_err(client->dev, | 1044 | dev_err(dsi->dev, "failed to initialize output: %d\n", |
1043 | "failed to initialize output: %d\n", | ||
1044 | err); | 1045 | err); |
1045 | goto reset; | ||
1046 | } | ||
1047 | 1046 | ||
1048 | dsi->output.encoder.possible_crtcs = 0x3; | 1047 | dsi->output.encoder.possible_crtcs = 0x3; |
1049 | } | 1048 | } |
@@ -1055,10 +1054,6 @@ static int tegra_dsi_init(struct host1x_client *client) | |||
1055 | } | 1054 | } |
1056 | 1055 | ||
1057 | return 0; | 1056 | return 0; |
1058 | |||
1059 | reset: | ||
1060 | reset_control_assert(dsi->rst); | ||
1061 | return err; | ||
1062 | } | 1057 | } |
1063 | 1058 | ||
1064 | static int tegra_dsi_exit(struct host1x_client *client) | 1059 | static int tegra_dsi_exit(struct host1x_client *client) |
@@ -1070,7 +1065,7 @@ static int tegra_dsi_exit(struct host1x_client *client) | |||
1070 | if (IS_ENABLED(CONFIG_DEBUG_FS)) | 1065 | if (IS_ENABLED(CONFIG_DEBUG_FS)) |
1071 | tegra_dsi_debugfs_exit(dsi); | 1066 | tegra_dsi_debugfs_exit(dsi); |
1072 | 1067 | ||
1073 | reset_control_assert(dsi->rst); | 1068 | regulator_disable(dsi->vdd); |
1074 | 1069 | ||
1075 | return 0; | 1070 | return 0; |
1076 | } | 1071 | } |
@@ -1501,67 +1496,41 @@ static int tegra_dsi_probe(struct platform_device *pdev) | |||
1501 | dsi->clk = devm_clk_get(&pdev->dev, NULL); | 1496 | dsi->clk = devm_clk_get(&pdev->dev, NULL); |
1502 | if (IS_ERR(dsi->clk)) { | 1497 | if (IS_ERR(dsi->clk)) { |
1503 | dev_err(&pdev->dev, "cannot get DSI clock\n"); | 1498 | dev_err(&pdev->dev, "cannot get DSI clock\n"); |
1504 | err = PTR_ERR(dsi->clk); | 1499 | return PTR_ERR(dsi->clk); |
1505 | goto reset; | ||
1506 | } | ||
1507 | |||
1508 | err = clk_prepare_enable(dsi->clk); | ||
1509 | if (err < 0) { | ||
1510 | dev_err(&pdev->dev, "cannot enable DSI clock\n"); | ||
1511 | goto reset; | ||
1512 | } | 1500 | } |
1513 | 1501 | ||
1514 | dsi->clk_lp = devm_clk_get(&pdev->dev, "lp"); | 1502 | dsi->clk_lp = devm_clk_get(&pdev->dev, "lp"); |
1515 | if (IS_ERR(dsi->clk_lp)) { | 1503 | if (IS_ERR(dsi->clk_lp)) { |
1516 | dev_err(&pdev->dev, "cannot get low-power clock\n"); | 1504 | dev_err(&pdev->dev, "cannot get low-power clock\n"); |
1517 | err = PTR_ERR(dsi->clk_lp); | 1505 | return PTR_ERR(dsi->clk_lp); |
1518 | goto disable_clk; | ||
1519 | } | ||
1520 | |||
1521 | err = clk_prepare_enable(dsi->clk_lp); | ||
1522 | if (err < 0) { | ||
1523 | dev_err(&pdev->dev, "cannot enable low-power clock\n"); | ||
1524 | goto disable_clk; | ||
1525 | } | 1506 | } |
1526 | 1507 | ||
1527 | dsi->clk_parent = devm_clk_get(&pdev->dev, "parent"); | 1508 | dsi->clk_parent = devm_clk_get(&pdev->dev, "parent"); |
1528 | if (IS_ERR(dsi->clk_parent)) { | 1509 | if (IS_ERR(dsi->clk_parent)) { |
1529 | dev_err(&pdev->dev, "cannot get parent clock\n"); | 1510 | dev_err(&pdev->dev, "cannot get parent clock\n"); |
1530 | err = PTR_ERR(dsi->clk_parent); | 1511 | return PTR_ERR(dsi->clk_parent); |
1531 | goto disable_clk_lp; | ||
1532 | } | 1512 | } |
1533 | 1513 | ||
1534 | dsi->vdd = devm_regulator_get(&pdev->dev, "avdd-dsi-csi"); | 1514 | dsi->vdd = devm_regulator_get(&pdev->dev, "avdd-dsi-csi"); |
1535 | if (IS_ERR(dsi->vdd)) { | 1515 | if (IS_ERR(dsi->vdd)) { |
1536 | dev_err(&pdev->dev, "cannot get VDD supply\n"); | 1516 | dev_err(&pdev->dev, "cannot get VDD supply\n"); |
1537 | err = PTR_ERR(dsi->vdd); | 1517 | return PTR_ERR(dsi->vdd); |
1538 | goto disable_clk_lp; | ||
1539 | } | ||
1540 | |||
1541 | err = regulator_enable(dsi->vdd); | ||
1542 | if (err < 0) { | ||
1543 | dev_err(&pdev->dev, "cannot enable VDD supply\n"); | ||
1544 | goto disable_clk_lp; | ||
1545 | } | 1518 | } |
1546 | 1519 | ||
1547 | err = tegra_dsi_setup_clocks(dsi); | 1520 | err = tegra_dsi_setup_clocks(dsi); |
1548 | if (err < 0) { | 1521 | if (err < 0) { |
1549 | dev_err(&pdev->dev, "cannot setup clocks\n"); | 1522 | dev_err(&pdev->dev, "cannot setup clocks\n"); |
1550 | goto disable_vdd; | 1523 | return err; |
1551 | } | 1524 | } |
1552 | 1525 | ||
1553 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1526 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1554 | dsi->regs = devm_ioremap_resource(&pdev->dev, regs); | 1527 | dsi->regs = devm_ioremap_resource(&pdev->dev, regs); |
1555 | if (IS_ERR(dsi->regs)) { | 1528 | if (IS_ERR(dsi->regs)) |
1556 | err = PTR_ERR(dsi->regs); | 1529 | return PTR_ERR(dsi->regs); |
1557 | goto disable_vdd; | ||
1558 | } | ||
1559 | 1530 | ||
1560 | dsi->mipi = tegra_mipi_request(&pdev->dev); | 1531 | dsi->mipi = tegra_mipi_request(&pdev->dev); |
1561 | if (IS_ERR(dsi->mipi)) { | 1532 | if (IS_ERR(dsi->mipi)) |
1562 | err = PTR_ERR(dsi->mipi); | 1533 | return PTR_ERR(dsi->mipi); |
1563 | goto disable_vdd; | ||
1564 | } | ||
1565 | 1534 | ||
1566 | dsi->host.ops = &tegra_dsi_host_ops; | 1535 | dsi->host.ops = &tegra_dsi_host_ops; |
1567 | dsi->host.dev = &pdev->dev; | 1536 | dsi->host.dev = &pdev->dev; |
@@ -1572,6 +1541,9 @@ static int tegra_dsi_probe(struct platform_device *pdev) | |||
1572 | goto mipi_free; | 1541 | goto mipi_free; |
1573 | } | 1542 | } |
1574 | 1543 | ||
1544 | platform_set_drvdata(pdev, dsi); | ||
1545 | pm_runtime_enable(&pdev->dev); | ||
1546 | |||
1575 | INIT_LIST_HEAD(&dsi->client.list); | 1547 | INIT_LIST_HEAD(&dsi->client.list); |
1576 | dsi->client.ops = &dsi_client_ops; | 1548 | dsi->client.ops = &dsi_client_ops; |
1577 | dsi->client.dev = &pdev->dev; | 1549 | dsi->client.dev = &pdev->dev; |
@@ -1583,22 +1555,12 @@ static int tegra_dsi_probe(struct platform_device *pdev) | |||
1583 | goto unregister; | 1555 | goto unregister; |
1584 | } | 1556 | } |
1585 | 1557 | ||
1586 | platform_set_drvdata(pdev, dsi); | ||
1587 | |||
1588 | return 0; | 1558 | return 0; |
1589 | 1559 | ||
1590 | unregister: | 1560 | unregister: |
1591 | mipi_dsi_host_unregister(&dsi->host); | 1561 | mipi_dsi_host_unregister(&dsi->host); |
1592 | mipi_free: | 1562 | mipi_free: |
1593 | tegra_mipi_free(dsi->mipi); | 1563 | tegra_mipi_free(dsi->mipi); |
1594 | disable_vdd: | ||
1595 | regulator_disable(dsi->vdd); | ||
1596 | disable_clk_lp: | ||
1597 | clk_disable_unprepare(dsi->clk_lp); | ||
1598 | disable_clk: | ||
1599 | clk_disable_unprepare(dsi->clk); | ||
1600 | reset: | ||
1601 | reset_control_assert(dsi->rst); | ||
1602 | return err; | 1564 | return err; |
1603 | } | 1565 | } |
1604 | 1566 | ||
@@ -1607,6 +1569,8 @@ static int tegra_dsi_remove(struct platform_device *pdev) | |||
1607 | struct tegra_dsi *dsi = platform_get_drvdata(pdev); | 1569 | struct tegra_dsi *dsi = platform_get_drvdata(pdev); |
1608 | int err; | 1570 | int err; |
1609 | 1571 | ||
1572 | pm_runtime_disable(&pdev->dev); | ||
1573 | |||
1610 | err = host1x_client_unregister(&dsi->client); | 1574 | err = host1x_client_unregister(&dsi->client); |
1611 | if (err < 0) { | 1575 | if (err < 0) { |
1612 | dev_err(&pdev->dev, "failed to unregister host1x client: %d\n", | 1576 | dev_err(&pdev->dev, "failed to unregister host1x client: %d\n", |
@@ -1619,14 +1583,78 @@ static int tegra_dsi_remove(struct platform_device *pdev) | |||
1619 | mipi_dsi_host_unregister(&dsi->host); | 1583 | mipi_dsi_host_unregister(&dsi->host); |
1620 | tegra_mipi_free(dsi->mipi); | 1584 | tegra_mipi_free(dsi->mipi); |
1621 | 1585 | ||
1622 | regulator_disable(dsi->vdd); | 1586 | return 0; |
1587 | } | ||
1588 | |||
1589 | #ifdef CONFIG_PM | ||
1590 | static int tegra_dsi_suspend(struct device *dev) | ||
1591 | { | ||
1592 | struct tegra_dsi *dsi = dev_get_drvdata(dev); | ||
1593 | int err; | ||
1594 | |||
1595 | err = reset_control_assert(dsi->rst); | ||
1596 | if (err < 0) { | ||
1597 | dev_err(dev, "failed to assert reset: %d\n", err); | ||
1598 | return err; | ||
1599 | } | ||
1600 | |||
1601 | usleep_range(1000, 2000); | ||
1602 | |||
1623 | clk_disable_unprepare(dsi->clk_lp); | 1603 | clk_disable_unprepare(dsi->clk_lp); |
1624 | clk_disable_unprepare(dsi->clk); | 1604 | clk_disable_unprepare(dsi->clk); |
1625 | reset_control_assert(dsi->rst); | 1605 | |
1606 | regulator_disable(dsi->vdd); | ||
1626 | 1607 | ||
1627 | return 0; | 1608 | return 0; |
1628 | } | 1609 | } |
1629 | 1610 | ||
1611 | static int tegra_dsi_resume(struct device *dev) | ||
1612 | { | ||
1613 | struct tegra_dsi *dsi = dev_get_drvdata(dev); | ||
1614 | int err; | ||
1615 | |||
1616 | err = regulator_enable(dsi->vdd); | ||
1617 | if (err < 0) { | ||
1618 | dev_err(dsi->dev, "failed to enable VDD supply: %d\n", err); | ||
1619 | return err; | ||
1620 | } | ||
1621 | |||
1622 | err = clk_prepare_enable(dsi->clk); | ||
1623 | if (err < 0) { | ||
1624 | dev_err(dev, "cannot enable DSI clock: %d\n", err); | ||
1625 | goto disable_vdd; | ||
1626 | } | ||
1627 | |||
1628 | err = clk_prepare_enable(dsi->clk_lp); | ||
1629 | if (err < 0) { | ||
1630 | dev_err(dev, "cannot enable low-power clock: %d\n", err); | ||
1631 | goto disable_clk; | ||
1632 | } | ||
1633 | |||
1634 | usleep_range(1000, 2000); | ||
1635 | |||
1636 | err = reset_control_deassert(dsi->rst); | ||
1637 | if (err < 0) { | ||
1638 | dev_err(dev, "cannot assert reset: %d\n", err); | ||
1639 | goto disable_clk_lp; | ||
1640 | } | ||
1641 | |||
1642 | return 0; | ||
1643 | |||
1644 | disable_clk_lp: | ||
1645 | clk_disable_unprepare(dsi->clk_lp); | ||
1646 | disable_clk: | ||
1647 | clk_disable_unprepare(dsi->clk); | ||
1648 | disable_vdd: | ||
1649 | regulator_disable(dsi->vdd); | ||
1650 | return err; | ||
1651 | } | ||
1652 | #endif | ||
1653 | |||
1654 | static const struct dev_pm_ops tegra_dsi_pm_ops = { | ||
1655 | SET_RUNTIME_PM_OPS(tegra_dsi_suspend, tegra_dsi_resume, NULL) | ||
1656 | }; | ||
1657 | |||
1630 | static const struct of_device_id tegra_dsi_of_match[] = { | 1658 | static const struct of_device_id tegra_dsi_of_match[] = { |
1631 | { .compatible = "nvidia,tegra210-dsi", }, | 1659 | { .compatible = "nvidia,tegra210-dsi", }, |
1632 | { .compatible = "nvidia,tegra132-dsi", }, | 1660 | { .compatible = "nvidia,tegra132-dsi", }, |
@@ -1640,6 +1668,7 @@ struct platform_driver tegra_dsi_driver = { | |||
1640 | .driver = { | 1668 | .driver = { |
1641 | .name = "tegra-dsi", | 1669 | .name = "tegra-dsi", |
1642 | .of_match_table = tegra_dsi_of_match, | 1670 | .of_match_table = tegra_dsi_of_match, |
1671 | .pm = &tegra_dsi_pm_ops, | ||
1643 | }, | 1672 | }, |
1644 | .probe = tegra_dsi_probe, | 1673 | .probe = tegra_dsi_probe, |
1645 | .remove = tegra_dsi_remove, | 1674 | .remove = tegra_dsi_remove, |