aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tegra/dsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/tegra/dsi.c')
-rw-r--r--drivers/gpu/drm/tegra/dsi.c248
1 files changed, 141 insertions, 107 deletions
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index d1239ebc190f..3d228ad90e0f 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
681static 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
691static 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
680static void tegra_dsi_set_timeout(struct tegra_dsi *dsi, unsigned long bclk, 720static void tegra_dsi_set_timeout(struct tegra_dsi *dsi, unsigned long bclk,
681 unsigned int vrefresh) 721 unsigned int vrefresh)
682{ 722{
@@ -794,7 +834,6 @@ tegra_dsi_connector_mode_valid(struct drm_connector *connector,
794static const struct drm_connector_helper_funcs tegra_dsi_connector_helper_funcs = { 834static const struct drm_connector_helper_funcs tegra_dsi_connector_helper_funcs = {
795 .get_modes = tegra_output_connector_get_modes, 835 .get_modes = tegra_output_connector_get_modes,
796 .mode_valid = tegra_dsi_connector_mode_valid, 836 .mode_valid = tegra_dsi_connector_mode_valid,
797 .best_encoder = tegra_output_connector_best_encoder,
798}; 837};
799 838
800static const struct drm_encoder_funcs tegra_dsi_encoder_funcs = { 839static const struct drm_encoder_funcs tegra_dsi_encoder_funcs = {
@@ -837,7 +876,7 @@ static void tegra_dsi_encoder_disable(struct drm_encoder *encoder)
837 876
838 tegra_dsi_disable(dsi); 877 tegra_dsi_disable(dsi);
839 878
840 return; 879 pm_runtime_put(dsi->dev);
841} 880}
842 881
843static void tegra_dsi_encoder_enable(struct drm_encoder *encoder) 882static void tegra_dsi_encoder_enable(struct drm_encoder *encoder)
@@ -848,6 +887,13 @@ static void tegra_dsi_encoder_enable(struct drm_encoder *encoder)
848 struct tegra_dsi *dsi = to_dsi(output); 887 struct tegra_dsi *dsi = to_dsi(output);
849 struct tegra_dsi_state *state; 888 struct tegra_dsi_state *state;
850 u32 value; 889 u32 value;
890 int err;
891
892 pm_runtime_get_sync(dsi->dev);
893
894 err = tegra_dsi_pad_calibrate(dsi);
895 if (err < 0)
896 dev_err(dsi->dev, "MIPI calibration failed: %d\n", err);
851 897
852 state = tegra_dsi_get_state(dsi); 898 state = tegra_dsi_get_state(dsi);
853 899
@@ -876,8 +922,6 @@ static void tegra_dsi_encoder_enable(struct drm_encoder *encoder)
876 922
877 if (output->panel) 923 if (output->panel)
878 drm_panel_enable(output->panel); 924 drm_panel_enable(output->panel);
879
880 return;
881} 925}
882 926
883static int 927static int
@@ -967,55 +1011,12 @@ static const struct drm_encoder_helper_funcs tegra_dsi_encoder_helper_funcs = {
967 .atomic_check = tegra_dsi_encoder_atomic_check, 1011 .atomic_check = tegra_dsi_encoder_atomic_check,
968}; 1012};
969 1013
970static 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
980static 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
1005static int tegra_dsi_init(struct host1x_client *client) 1014static int tegra_dsi_init(struct host1x_client *client)
1006{ 1015{
1007 struct drm_device *drm = dev_get_drvdata(client->parent); 1016 struct drm_device *drm = dev_get_drvdata(client->parent);
1008 struct tegra_dsi *dsi = host1x_client_to_dsi(client); 1017 struct tegra_dsi *dsi = host1x_client_to_dsi(client);
1009 int err; 1018 int err;
1010 1019
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. */ 1020 /* Gangsters must not register their own outputs. */
1020 if (!dsi->master) { 1021 if (!dsi->master) {
1021 dsi->output.dev = client->dev; 1022 dsi->output.dev = client->dev;
@@ -1038,12 +1039,9 @@ static int tegra_dsi_init(struct host1x_client *client)
1038 drm_connector_register(&dsi->output.connector); 1039 drm_connector_register(&dsi->output.connector);
1039 1040
1040 err = tegra_output_init(drm, &dsi->output); 1041 err = tegra_output_init(drm, &dsi->output);
1041 if (err < 0) { 1042 if (err < 0)
1042 dev_err(client->dev, 1043 dev_err(dsi->dev, "failed to initialize output: %d\n",
1043 "failed to initialize output: %d\n",
1044 err); 1044 err);
1045 goto reset;
1046 }
1047 1045
1048 dsi->output.encoder.possible_crtcs = 0x3; 1046 dsi->output.encoder.possible_crtcs = 0x3;
1049 } 1047 }
@@ -1055,10 +1053,6 @@ static int tegra_dsi_init(struct host1x_client *client)
1055 } 1053 }
1056 1054
1057 return 0; 1055 return 0;
1058
1059reset:
1060 reset_control_assert(dsi->rst);
1061 return err;
1062} 1056}
1063 1057
1064static int tegra_dsi_exit(struct host1x_client *client) 1058static int tegra_dsi_exit(struct host1x_client *client)
@@ -1070,7 +1064,7 @@ static int tegra_dsi_exit(struct host1x_client *client)
1070 if (IS_ENABLED(CONFIG_DEBUG_FS)) 1064 if (IS_ENABLED(CONFIG_DEBUG_FS))
1071 tegra_dsi_debugfs_exit(dsi); 1065 tegra_dsi_debugfs_exit(dsi);
1072 1066
1073 reset_control_assert(dsi->rst); 1067 regulator_disable(dsi->vdd);
1074 1068
1075 return 0; 1069 return 0;
1076} 1070}
@@ -1494,74 +1488,50 @@ static int tegra_dsi_probe(struct platform_device *pdev)
1494 dsi->format = MIPI_DSI_FMT_RGB888; 1488 dsi->format = MIPI_DSI_FMT_RGB888;
1495 dsi->lanes = 4; 1489 dsi->lanes = 4;
1496 1490
1497 dsi->rst = devm_reset_control_get(&pdev->dev, "dsi"); 1491 if (!pdev->dev.pm_domain) {
1498 if (IS_ERR(dsi->rst)) 1492 dsi->rst = devm_reset_control_get(&pdev->dev, "dsi");
1499 return PTR_ERR(dsi->rst); 1493 if (IS_ERR(dsi->rst))
1494 return PTR_ERR(dsi->rst);
1495 }
1500 1496
1501 dsi->clk = devm_clk_get(&pdev->dev, NULL); 1497 dsi->clk = devm_clk_get(&pdev->dev, NULL);
1502 if (IS_ERR(dsi->clk)) { 1498 if (IS_ERR(dsi->clk)) {
1503 dev_err(&pdev->dev, "cannot get DSI clock\n"); 1499 dev_err(&pdev->dev, "cannot get DSI clock\n");
1504 err = PTR_ERR(dsi->clk); 1500 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 } 1501 }
1513 1502
1514 dsi->clk_lp = devm_clk_get(&pdev->dev, "lp"); 1503 dsi->clk_lp = devm_clk_get(&pdev->dev, "lp");
1515 if (IS_ERR(dsi->clk_lp)) { 1504 if (IS_ERR(dsi->clk_lp)) {
1516 dev_err(&pdev->dev, "cannot get low-power clock\n"); 1505 dev_err(&pdev->dev, "cannot get low-power clock\n");
1517 err = PTR_ERR(dsi->clk_lp); 1506 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 } 1507 }
1526 1508
1527 dsi->clk_parent = devm_clk_get(&pdev->dev, "parent"); 1509 dsi->clk_parent = devm_clk_get(&pdev->dev, "parent");
1528 if (IS_ERR(dsi->clk_parent)) { 1510 if (IS_ERR(dsi->clk_parent)) {
1529 dev_err(&pdev->dev, "cannot get parent clock\n"); 1511 dev_err(&pdev->dev, "cannot get parent clock\n");
1530 err = PTR_ERR(dsi->clk_parent); 1512 return PTR_ERR(dsi->clk_parent);
1531 goto disable_clk_lp;
1532 } 1513 }
1533 1514
1534 dsi->vdd = devm_regulator_get(&pdev->dev, "avdd-dsi-csi"); 1515 dsi->vdd = devm_regulator_get(&pdev->dev, "avdd-dsi-csi");
1535 if (IS_ERR(dsi->vdd)) { 1516 if (IS_ERR(dsi->vdd)) {
1536 dev_err(&pdev->dev, "cannot get VDD supply\n"); 1517 dev_err(&pdev->dev, "cannot get VDD supply\n");
1537 err = PTR_ERR(dsi->vdd); 1518 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 } 1519 }
1546 1520
1547 err = tegra_dsi_setup_clocks(dsi); 1521 err = tegra_dsi_setup_clocks(dsi);
1548 if (err < 0) { 1522 if (err < 0) {
1549 dev_err(&pdev->dev, "cannot setup clocks\n"); 1523 dev_err(&pdev->dev, "cannot setup clocks\n");
1550 goto disable_vdd; 1524 return err;
1551 } 1525 }
1552 1526
1553 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1527 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1554 dsi->regs = devm_ioremap_resource(&pdev->dev, regs); 1528 dsi->regs = devm_ioremap_resource(&pdev->dev, regs);
1555 if (IS_ERR(dsi->regs)) { 1529 if (IS_ERR(dsi->regs))
1556 err = PTR_ERR(dsi->regs); 1530 return PTR_ERR(dsi->regs);
1557 goto disable_vdd;
1558 }
1559 1531
1560 dsi->mipi = tegra_mipi_request(&pdev->dev); 1532 dsi->mipi = tegra_mipi_request(&pdev->dev);
1561 if (IS_ERR(dsi->mipi)) { 1533 if (IS_ERR(dsi->mipi))
1562 err = PTR_ERR(dsi->mipi); 1534 return PTR_ERR(dsi->mipi);
1563 goto disable_vdd;
1564 }
1565 1535
1566 dsi->host.ops = &tegra_dsi_host_ops; 1536 dsi->host.ops = &tegra_dsi_host_ops;
1567 dsi->host.dev = &pdev->dev; 1537 dsi->host.dev = &pdev->dev;
@@ -1572,6 +1542,9 @@ static int tegra_dsi_probe(struct platform_device *pdev)
1572 goto mipi_free; 1542 goto mipi_free;
1573 } 1543 }
1574 1544
1545 platform_set_drvdata(pdev, dsi);
1546 pm_runtime_enable(&pdev->dev);
1547
1575 INIT_LIST_HEAD(&dsi->client.list); 1548 INIT_LIST_HEAD(&dsi->client.list);
1576 dsi->client.ops = &dsi_client_ops; 1549 dsi->client.ops = &dsi_client_ops;
1577 dsi->client.dev = &pdev->dev; 1550 dsi->client.dev = &pdev->dev;
@@ -1583,22 +1556,12 @@ static int tegra_dsi_probe(struct platform_device *pdev)
1583 goto unregister; 1556 goto unregister;
1584 } 1557 }
1585 1558
1586 platform_set_drvdata(pdev, dsi);
1587
1588 return 0; 1559 return 0;
1589 1560
1590unregister: 1561unregister:
1591 mipi_dsi_host_unregister(&dsi->host); 1562 mipi_dsi_host_unregister(&dsi->host);
1592mipi_free: 1563mipi_free:
1593 tegra_mipi_free(dsi->mipi); 1564 tegra_mipi_free(dsi->mipi);
1594disable_vdd:
1595 regulator_disable(dsi->vdd);
1596disable_clk_lp:
1597 clk_disable_unprepare(dsi->clk_lp);
1598disable_clk:
1599 clk_disable_unprepare(dsi->clk);
1600reset:
1601 reset_control_assert(dsi->rst);
1602 return err; 1565 return err;
1603} 1566}
1604 1567
@@ -1607,6 +1570,8 @@ static int tegra_dsi_remove(struct platform_device *pdev)
1607 struct tegra_dsi *dsi = platform_get_drvdata(pdev); 1570 struct tegra_dsi *dsi = platform_get_drvdata(pdev);
1608 int err; 1571 int err;
1609 1572
1573 pm_runtime_disable(&pdev->dev);
1574
1610 err = host1x_client_unregister(&dsi->client); 1575 err = host1x_client_unregister(&dsi->client);
1611 if (err < 0) { 1576 if (err < 0) {
1612 dev_err(&pdev->dev, "failed to unregister host1x client: %d\n", 1577 dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
@@ -1619,14 +1584,82 @@ static int tegra_dsi_remove(struct platform_device *pdev)
1619 mipi_dsi_host_unregister(&dsi->host); 1584 mipi_dsi_host_unregister(&dsi->host);
1620 tegra_mipi_free(dsi->mipi); 1585 tegra_mipi_free(dsi->mipi);
1621 1586
1622 regulator_disable(dsi->vdd); 1587 return 0;
1588}
1589
1590#ifdef CONFIG_PM
1591static int tegra_dsi_suspend(struct device *dev)
1592{
1593 struct tegra_dsi *dsi = dev_get_drvdata(dev);
1594 int err;
1595
1596 if (dsi->rst) {
1597 err = reset_control_assert(dsi->rst);
1598 if (err < 0) {
1599 dev_err(dev, "failed to assert reset: %d\n", err);
1600 return err;
1601 }
1602 }
1603
1604 usleep_range(1000, 2000);
1605
1623 clk_disable_unprepare(dsi->clk_lp); 1606 clk_disable_unprepare(dsi->clk_lp);
1624 clk_disable_unprepare(dsi->clk); 1607 clk_disable_unprepare(dsi->clk);
1625 reset_control_assert(dsi->rst); 1608
1609 regulator_disable(dsi->vdd);
1626 1610
1627 return 0; 1611 return 0;
1628} 1612}
1629 1613
1614static int tegra_dsi_resume(struct device *dev)
1615{
1616 struct tegra_dsi *dsi = dev_get_drvdata(dev);
1617 int err;
1618
1619 err = regulator_enable(dsi->vdd);
1620 if (err < 0) {
1621 dev_err(dsi->dev, "failed to enable VDD supply: %d\n", err);
1622 return err;
1623 }
1624
1625 err = clk_prepare_enable(dsi->clk);
1626 if (err < 0) {
1627 dev_err(dev, "cannot enable DSI clock: %d\n", err);
1628 goto disable_vdd;
1629 }
1630
1631 err = clk_prepare_enable(dsi->clk_lp);
1632 if (err < 0) {
1633 dev_err(dev, "cannot enable low-power clock: %d\n", err);
1634 goto disable_clk;
1635 }
1636
1637 usleep_range(1000, 2000);
1638
1639 if (dsi->rst) {
1640 err = reset_control_deassert(dsi->rst);
1641 if (err < 0) {
1642 dev_err(dev, "cannot assert reset: %d\n", err);
1643 goto disable_clk_lp;
1644 }
1645 }
1646
1647 return 0;
1648
1649disable_clk_lp:
1650 clk_disable_unprepare(dsi->clk_lp);
1651disable_clk:
1652 clk_disable_unprepare(dsi->clk);
1653disable_vdd:
1654 regulator_disable(dsi->vdd);
1655 return err;
1656}
1657#endif
1658
1659static const struct dev_pm_ops tegra_dsi_pm_ops = {
1660 SET_RUNTIME_PM_OPS(tegra_dsi_suspend, tegra_dsi_resume, NULL)
1661};
1662
1630static const struct of_device_id tegra_dsi_of_match[] = { 1663static const struct of_device_id tegra_dsi_of_match[] = {
1631 { .compatible = "nvidia,tegra210-dsi", }, 1664 { .compatible = "nvidia,tegra210-dsi", },
1632 { .compatible = "nvidia,tegra132-dsi", }, 1665 { .compatible = "nvidia,tegra132-dsi", },
@@ -1640,6 +1673,7 @@ struct platform_driver tegra_dsi_driver = {
1640 .driver = { 1673 .driver = {
1641 .name = "tegra-dsi", 1674 .name = "tegra-dsi",
1642 .of_match_table = tegra_dsi_of_match, 1675 .of_match_table = tegra_dsi_of_match,
1676 .pm = &tegra_dsi_pm_ops,
1643 }, 1677 },
1644 .probe = tegra_dsi_probe, 1678 .probe = tegra_dsi_probe,
1645 .remove = tegra_dsi_remove, 1679 .remove = tegra_dsi_remove,