Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/tegra: Do not implement runtime PM

The Tegra DRM driver heavily relies on the implementations for runtime
suspend/resume to be called at specific times. Unfortunately, there are
some cases where that doesn't work. One example is if the user disables
runtime PM for a given subdevice. Another example is that the PM core
acquires a reference to runtime PM during system sleep, effectively
preventing devices from going into low power modes. This is intentional
to avoid nasty race conditions, but it also causes system sleep to not
function properly on all Tegra systems.

Fix this by not implementing runtime PM at all. Instead, a minimal,
reference-counted suspend/resume infrastructure is added to the host1x
bus. This has the benefit that it can be used regardless of the system
power state (or any transitions we might be in), or whether or not the
user allows runtime PM.

Atomic modesetting guarantees that these functions will end up being
called at the right point in time, so the pitfalls for the more generic
runtime PM do not apply here.

Signed-off-by: Thierry Reding <treding@nvidia.com>

+543 -333
+84 -57
drivers/gpu/drm/tegra/dc.c
··· 1727 1727 { 1728 1728 struct tegra_dc *dc = to_tegra_dc(crtc); 1729 1729 u32 value; 1730 + int err; 1730 1731 1731 1732 if (!tegra_dc_idle(dc)) { 1732 1733 tegra_dc_stop(dc); ··· 1774 1773 1775 1774 spin_unlock_irq(&crtc->dev->event_lock); 1776 1775 1777 - pm_runtime_put_sync(dc->dev); 1776 + err = host1x_client_suspend(&dc->client); 1777 + if (err < 0) 1778 + dev_err(dc->dev, "failed to suspend: %d\n", err); 1778 1779 } 1779 1780 1780 1781 static void tegra_crtc_atomic_enable(struct drm_crtc *crtc, ··· 1786 1783 struct tegra_dc_state *state = to_dc_state(crtc->state); 1787 1784 struct tegra_dc *dc = to_tegra_dc(crtc); 1788 1785 u32 value; 1786 + int err; 1789 1787 1790 - pm_runtime_get_sync(dc->dev); 1788 + err = host1x_client_resume(&dc->client); 1789 + if (err < 0) { 1790 + dev_err(dc->dev, "failed to resume: %d\n", err); 1791 + return; 1792 + } 1791 1793 1792 1794 /* initialize display controller */ 1793 1795 if (dc->syncpt) { ··· 2020 2012 if (!tegra_dc_has_window_groups(dc)) 2021 2013 return 0; 2022 2014 2015 + /* 2016 + * Set the display hub as the host1x client parent for the display 2017 + * controller. This is needed for the runtime reference counting that 2018 + * ensures the display hub is always powered when any of the display 2019 + * controllers are. 2020 + */ 2021 + if (dc->soc->has_nvdisplay) 2022 + client->parent = &tegra->hub->client; 2023 + 2023 2024 dc->syncpt = host1x_syncpt_request(client, flags); 2024 2025 if (!dc->syncpt) 2025 2026 dev_warn(dc->dev, "failed to allocate syncpoint\n"); ··· 2138 2121 return 0; 2139 2122 } 2140 2123 2124 + static int tegra_dc_runtime_suspend(struct host1x_client *client) 2125 + { 2126 + struct tegra_dc *dc = host1x_client_to_dc(client); 2127 + struct device *dev = client->dev; 2128 + int err; 2129 + 2130 + err = reset_control_assert(dc->rst); 2131 + if (err < 0) { 2132 + dev_err(dev, "failed to assert reset: %d\n", err); 2133 + return err; 2134 + } 2135 + 2136 + if (dc->soc->has_powergate) 2137 + tegra_powergate_power_off(dc->powergate); 2138 + 2139 + clk_disable_unprepare(dc->clk); 2140 + pm_runtime_put_sync(dev); 2141 + 2142 + return 0; 2143 + } 2144 + 2145 + static int tegra_dc_runtime_resume(struct host1x_client *client) 2146 + { 2147 + struct tegra_dc *dc = host1x_client_to_dc(client); 2148 + struct device *dev = client->dev; 2149 + int err; 2150 + 2151 + err = pm_runtime_get_sync(dev); 2152 + if (err < 0) { 2153 + dev_err(dev, "failed to get runtime PM: %d\n", err); 2154 + return err; 2155 + } 2156 + 2157 + if (dc->soc->has_powergate) { 2158 + err = tegra_powergate_sequence_power_up(dc->powergate, dc->clk, 2159 + dc->rst); 2160 + if (err < 0) { 2161 + dev_err(dev, "failed to power partition: %d\n", err); 2162 + goto put_rpm; 2163 + } 2164 + } else { 2165 + err = clk_prepare_enable(dc->clk); 2166 + if (err < 0) { 2167 + dev_err(dev, "failed to enable clock: %d\n", err); 2168 + goto put_rpm; 2169 + } 2170 + 2171 + err = reset_control_deassert(dc->rst); 2172 + if (err < 0) { 2173 + dev_err(dev, "failed to deassert reset: %d\n", err); 2174 + goto disable_clk; 2175 + } 2176 + } 2177 + 2178 + return 0; 2179 + 2180 + disable_clk: 2181 + clk_disable_unprepare(dc->clk); 2182 + put_rpm: 2183 + pm_runtime_put_sync(dev); 2184 + return err; 2185 + } 2186 + 2141 2187 static const struct host1x_client_ops dc_client_ops = { 2142 2188 .init = tegra_dc_init, 2143 2189 .exit = tegra_dc_exit, 2190 + .suspend = tegra_dc_runtime_suspend, 2191 + .resume = tegra_dc_runtime_resume, 2144 2192 }; 2145 2193 2146 2194 static const struct tegra_dc_soc_info tegra20_dc_soc_info = { ··· 2617 2535 return 0; 2618 2536 } 2619 2537 2620 - #ifdef CONFIG_PM 2621 - static int tegra_dc_suspend(struct device *dev) 2622 - { 2623 - struct tegra_dc *dc = dev_get_drvdata(dev); 2624 - int err; 2625 - 2626 - err = reset_control_assert(dc->rst); 2627 - if (err < 0) { 2628 - dev_err(dev, "failed to assert reset: %d\n", err); 2629 - return err; 2630 - } 2631 - 2632 - if (dc->soc->has_powergate) 2633 - tegra_powergate_power_off(dc->powergate); 2634 - 2635 - clk_disable_unprepare(dc->clk); 2636 - 2637 - return 0; 2638 - } 2639 - 2640 - static int tegra_dc_resume(struct device *dev) 2641 - { 2642 - struct tegra_dc *dc = dev_get_drvdata(dev); 2643 - int err; 2644 - 2645 - if (dc->soc->has_powergate) { 2646 - err = tegra_powergate_sequence_power_up(dc->powergate, dc->clk, 2647 - dc->rst); 2648 - if (err < 0) { 2649 - dev_err(dev, "failed to power partition: %d\n", err); 2650 - return err; 2651 - } 2652 - } else { 2653 - err = clk_prepare_enable(dc->clk); 2654 - if (err < 0) { 2655 - dev_err(dev, "failed to enable clock: %d\n", err); 2656 - return err; 2657 - } 2658 - 2659 - err = reset_control_deassert(dc->rst); 2660 - if (err < 0) { 2661 - dev_err(dev, "failed to deassert reset: %d\n", err); 2662 - return err; 2663 - } 2664 - } 2665 - 2666 - return 0; 2667 - } 2668 - #endif 2669 - 2670 - static const struct dev_pm_ops tegra_dc_pm_ops = { 2671 - SET_RUNTIME_PM_OPS(tegra_dc_suspend, tegra_dc_resume, NULL) 2672 - }; 2673 - 2674 2538 struct platform_driver tegra_dc_driver = { 2675 2539 .driver = { 2676 2540 .name = "tegra-dc", 2677 2541 .of_match_table = tegra_dc_of_match, 2678 - .pm = &tegra_dc_pm_ops, 2679 2542 }, 2680 2543 .probe = tegra_dc_probe, 2681 2544 .remove = tegra_dc_remove,
+1 -1
drivers/gpu/drm/tegra/dpaux.c
··· 588 588 /* make sure pads are powered down when not in use */ 589 589 tegra_dpaux_pad_power_down(dpaux); 590 590 591 - pm_runtime_put(&pdev->dev); 591 + pm_runtime_put_sync(&pdev->dev); 592 592 pm_runtime_disable(&pdev->dev); 593 593 594 594 drm_dp_aux_unregister(&dpaux->aux);
+2
drivers/gpu/drm/tegra/drm.h
··· 144 144 void tegra_output_exit(struct tegra_output *output); 145 145 void tegra_output_find_possible_crtcs(struct tegra_output *output, 146 146 struct drm_device *drm); 147 + int tegra_output_suspend(struct tegra_output *output); 148 + int tegra_output_resume(struct tegra_output *output); 147 149 148 150 int tegra_output_connector_get_modes(struct drm_connector *connector); 149 151 enum drm_connector_status
+97 -78
drivers/gpu/drm/tegra/dsi.c
··· 840 840 dev_err(dsi->dev, "failed to disable MIPI calibration: %d\n", 841 841 err); 842 842 843 - pm_runtime_put(dsi->dev); 843 + err = host1x_client_suspend(&dsi->client); 844 + if (err < 0) 845 + dev_err(dsi->dev, "failed to suspend: %d\n", err); 844 846 } 845 847 846 848 static void tegra_dsi_encoder_disable(struct drm_encoder *encoder) ··· 884 882 tegra_dsi_unprepare(dsi); 885 883 } 886 884 887 - static void tegra_dsi_prepare(struct tegra_dsi *dsi) 885 + static int tegra_dsi_prepare(struct tegra_dsi *dsi) 888 886 { 889 887 int err; 890 888 891 - pm_runtime_get_sync(dsi->dev); 889 + err = host1x_client_resume(&dsi->client); 890 + if (err < 0) { 891 + dev_err(dsi->dev, "failed to resume: %d\n", err); 892 + return err; 893 + } 892 894 893 895 err = tegra_mipi_enable(dsi->mipi); 894 896 if (err < 0) ··· 905 899 906 900 if (dsi->slave) 907 901 tegra_dsi_prepare(dsi->slave); 902 + 903 + return 0; 908 904 } 909 905 910 906 static void tegra_dsi_encoder_enable(struct drm_encoder *encoder) ··· 917 909 struct tegra_dsi *dsi = to_dsi(output); 918 910 struct tegra_dsi_state *state; 919 911 u32 value; 912 + int err; 920 913 921 - tegra_dsi_prepare(dsi); 914 + err = tegra_dsi_prepare(dsi); 915 + if (err < 0) { 916 + dev_err(dsi->dev, "failed to prepare: %d\n", err); 917 + return; 918 + } 922 919 923 920 state = tegra_dsi_get_state(dsi); 924 921 ··· 1088 1075 return 0; 1089 1076 } 1090 1077 1078 + static int tegra_dsi_runtime_suspend(struct host1x_client *client) 1079 + { 1080 + struct tegra_dsi *dsi = host1x_client_to_dsi(client); 1081 + struct device *dev = client->dev; 1082 + int err; 1083 + 1084 + if (dsi->rst) { 1085 + err = reset_control_assert(dsi->rst); 1086 + if (err < 0) { 1087 + dev_err(dev, "failed to assert reset: %d\n", err); 1088 + return err; 1089 + } 1090 + } 1091 + 1092 + usleep_range(1000, 2000); 1093 + 1094 + clk_disable_unprepare(dsi->clk_lp); 1095 + clk_disable_unprepare(dsi->clk); 1096 + 1097 + regulator_disable(dsi->vdd); 1098 + pm_runtime_put_sync(dev); 1099 + 1100 + return 0; 1101 + } 1102 + 1103 + static int tegra_dsi_runtime_resume(struct host1x_client *client) 1104 + { 1105 + struct tegra_dsi *dsi = host1x_client_to_dsi(client); 1106 + struct device *dev = client->dev; 1107 + int err; 1108 + 1109 + err = pm_runtime_get_sync(dev); 1110 + if (err < 0) { 1111 + dev_err(dev, "failed to get runtime PM: %d\n", err); 1112 + return err; 1113 + } 1114 + 1115 + err = regulator_enable(dsi->vdd); 1116 + if (err < 0) { 1117 + dev_err(dev, "failed to enable VDD supply: %d\n", err); 1118 + goto put_rpm; 1119 + } 1120 + 1121 + err = clk_prepare_enable(dsi->clk); 1122 + if (err < 0) { 1123 + dev_err(dev, "cannot enable DSI clock: %d\n", err); 1124 + goto disable_vdd; 1125 + } 1126 + 1127 + err = clk_prepare_enable(dsi->clk_lp); 1128 + if (err < 0) { 1129 + dev_err(dev, "cannot enable low-power clock: %d\n", err); 1130 + goto disable_clk; 1131 + } 1132 + 1133 + usleep_range(1000, 2000); 1134 + 1135 + if (dsi->rst) { 1136 + err = reset_control_deassert(dsi->rst); 1137 + if (err < 0) { 1138 + dev_err(dev, "cannot assert reset: %d\n", err); 1139 + goto disable_clk_lp; 1140 + } 1141 + } 1142 + 1143 + return 0; 1144 + 1145 + disable_clk_lp: 1146 + clk_disable_unprepare(dsi->clk_lp); 1147 + disable_clk: 1148 + clk_disable_unprepare(dsi->clk); 1149 + disable_vdd: 1150 + regulator_disable(dsi->vdd); 1151 + put_rpm: 1152 + pm_runtime_put_sync(dev); 1153 + return err; 1154 + } 1155 + 1091 1156 static const struct host1x_client_ops dsi_client_ops = { 1092 1157 .init = tegra_dsi_init, 1093 1158 .exit = tegra_dsi_exit, 1159 + .suspend = tegra_dsi_runtime_suspend, 1160 + .resume = tegra_dsi_runtime_resume, 1094 1161 }; 1095 1162 1096 1163 static int tegra_dsi_setup_clocks(struct tegra_dsi *dsi) ··· 1689 1596 return 0; 1690 1597 } 1691 1598 1692 - #ifdef CONFIG_PM 1693 - static int tegra_dsi_suspend(struct device *dev) 1694 - { 1695 - struct tegra_dsi *dsi = dev_get_drvdata(dev); 1696 - int err; 1697 - 1698 - if (dsi->rst) { 1699 - err = reset_control_assert(dsi->rst); 1700 - if (err < 0) { 1701 - dev_err(dev, "failed to assert reset: %d\n", err); 1702 - return err; 1703 - } 1704 - } 1705 - 1706 - usleep_range(1000, 2000); 1707 - 1708 - clk_disable_unprepare(dsi->clk_lp); 1709 - clk_disable_unprepare(dsi->clk); 1710 - 1711 - regulator_disable(dsi->vdd); 1712 - 1713 - return 0; 1714 - } 1715 - 1716 - static int tegra_dsi_resume(struct device *dev) 1717 - { 1718 - struct tegra_dsi *dsi = dev_get_drvdata(dev); 1719 - int err; 1720 - 1721 - err = regulator_enable(dsi->vdd); 1722 - if (err < 0) { 1723 - dev_err(dsi->dev, "failed to enable VDD supply: %d\n", err); 1724 - return err; 1725 - } 1726 - 1727 - err = clk_prepare_enable(dsi->clk); 1728 - if (err < 0) { 1729 - dev_err(dev, "cannot enable DSI clock: %d\n", err); 1730 - goto disable_vdd; 1731 - } 1732 - 1733 - err = clk_prepare_enable(dsi->clk_lp); 1734 - if (err < 0) { 1735 - dev_err(dev, "cannot enable low-power clock: %d\n", err); 1736 - goto disable_clk; 1737 - } 1738 - 1739 - usleep_range(1000, 2000); 1740 - 1741 - if (dsi->rst) { 1742 - err = reset_control_deassert(dsi->rst); 1743 - if (err < 0) { 1744 - dev_err(dev, "cannot assert reset: %d\n", err); 1745 - goto disable_clk_lp; 1746 - } 1747 - } 1748 - 1749 - return 0; 1750 - 1751 - disable_clk_lp: 1752 - clk_disable_unprepare(dsi->clk_lp); 1753 - disable_clk: 1754 - clk_disable_unprepare(dsi->clk); 1755 - disable_vdd: 1756 - regulator_disable(dsi->vdd); 1757 - return err; 1758 - } 1759 - #endif 1760 - 1761 - static const struct dev_pm_ops tegra_dsi_pm_ops = { 1762 - SET_RUNTIME_PM_OPS(tegra_dsi_suspend, tegra_dsi_resume, NULL) 1763 - }; 1764 - 1765 1599 static const struct of_device_id tegra_dsi_of_match[] = { 1766 1600 { .compatible = "nvidia,tegra210-dsi", }, 1767 1601 { .compatible = "nvidia,tegra132-dsi", }, ··· 1702 1682 .driver = { 1703 1683 .name = "tegra-dsi", 1704 1684 .of_match_table = tegra_dsi_of_match, 1705 - .pm = &tegra_dsi_pm_ops, 1706 1685 }, 1707 1686 .probe = tegra_dsi_probe, 1708 1687 .remove = tegra_dsi_remove,
+66 -50
drivers/gpu/drm/tegra/hdmi.c
··· 1146 1146 struct tegra_dc *dc = to_tegra_dc(encoder->crtc); 1147 1147 struct tegra_hdmi *hdmi = to_hdmi(output); 1148 1148 u32 value; 1149 + int err; 1149 1150 1150 1151 /* 1151 1152 * The following accesses registers of the display controller, so make ··· 1172 1171 tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_INT_ENABLE); 1173 1172 tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_INT_MASK); 1174 1173 1175 - pm_runtime_put(hdmi->dev); 1174 + err = host1x_client_suspend(&hdmi->client); 1175 + if (err < 0) 1176 + dev_err(hdmi->dev, "failed to suspend: %d\n", err); 1176 1177 } 1177 1178 1178 1179 static void tegra_hdmi_encoder_enable(struct drm_encoder *encoder) ··· 1189 1186 u32 value; 1190 1187 int err; 1191 1188 1192 - pm_runtime_get_sync(hdmi->dev); 1189 + err = host1x_client_resume(&hdmi->client); 1190 + if (err < 0) { 1191 + dev_err(hdmi->dev, "failed to resume: %d\n", err); 1192 + return; 1193 + } 1193 1194 1194 1195 /* 1195 1196 * Enable and unmask the HDA codec SCRATCH0 register interrupt. This ··· 1496 1489 return 0; 1497 1490 } 1498 1491 1492 + static int tegra_hdmi_runtime_suspend(struct host1x_client *client) 1493 + { 1494 + struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client); 1495 + struct device *dev = client->dev; 1496 + int err; 1497 + 1498 + err = reset_control_assert(hdmi->rst); 1499 + if (err < 0) { 1500 + dev_err(dev, "failed to assert reset: %d\n", err); 1501 + return err; 1502 + } 1503 + 1504 + usleep_range(1000, 2000); 1505 + 1506 + clk_disable_unprepare(hdmi->clk); 1507 + pm_runtime_put_sync(dev); 1508 + 1509 + return 0; 1510 + } 1511 + 1512 + static int tegra_hdmi_runtime_resume(struct host1x_client *client) 1513 + { 1514 + struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client); 1515 + struct device *dev = client->dev; 1516 + int err; 1517 + 1518 + err = pm_runtime_get_sync(dev); 1519 + if (err < 0) { 1520 + dev_err(dev, "failed to get runtime PM: %d\n", err); 1521 + return err; 1522 + } 1523 + 1524 + err = clk_prepare_enable(hdmi->clk); 1525 + if (err < 0) { 1526 + dev_err(dev, "failed to enable clock: %d\n", err); 1527 + goto put_rpm; 1528 + } 1529 + 1530 + usleep_range(1000, 2000); 1531 + 1532 + err = reset_control_deassert(hdmi->rst); 1533 + if (err < 0) { 1534 + dev_err(dev, "failed to deassert reset: %d\n", err); 1535 + goto disable_clk; 1536 + } 1537 + 1538 + return 0; 1539 + 1540 + disable_clk: 1541 + clk_disable_unprepare(hdmi->clk); 1542 + put_rpm: 1543 + pm_runtime_put_sync(dev); 1544 + return err; 1545 + } 1546 + 1499 1547 static const struct host1x_client_ops hdmi_client_ops = { 1500 1548 .init = tegra_hdmi_init, 1501 1549 .exit = tegra_hdmi_exit, 1550 + .suspend = tegra_hdmi_runtime_suspend, 1551 + .resume = tegra_hdmi_runtime_resume, 1502 1552 }; 1503 1553 1504 1554 static const struct tegra_hdmi_config tegra20_hdmi_config = { ··· 1763 1699 return 0; 1764 1700 } 1765 1701 1766 - #ifdef CONFIG_PM 1767 - static int tegra_hdmi_suspend(struct device *dev) 1768 - { 1769 - struct tegra_hdmi *hdmi = dev_get_drvdata(dev); 1770 - int err; 1771 - 1772 - err = reset_control_assert(hdmi->rst); 1773 - if (err < 0) { 1774 - dev_err(dev, "failed to assert reset: %d\n", err); 1775 - return err; 1776 - } 1777 - 1778 - usleep_range(1000, 2000); 1779 - 1780 - clk_disable_unprepare(hdmi->clk); 1781 - 1782 - return 0; 1783 - } 1784 - 1785 - static int tegra_hdmi_resume(struct device *dev) 1786 - { 1787 - struct tegra_hdmi *hdmi = dev_get_drvdata(dev); 1788 - int err; 1789 - 1790 - err = clk_prepare_enable(hdmi->clk); 1791 - if (err < 0) { 1792 - dev_err(dev, "failed to enable clock: %d\n", err); 1793 - return err; 1794 - } 1795 - 1796 - usleep_range(1000, 2000); 1797 - 1798 - err = reset_control_deassert(hdmi->rst); 1799 - if (err < 0) { 1800 - dev_err(dev, "failed to deassert reset: %d\n", err); 1801 - clk_disable_unprepare(hdmi->clk); 1802 - return err; 1803 - } 1804 - 1805 - return 0; 1806 - } 1807 - #endif 1808 - 1809 - static const struct dev_pm_ops tegra_hdmi_pm_ops = { 1810 - SET_RUNTIME_PM_OPS(tegra_hdmi_suspend, tegra_hdmi_resume, NULL) 1811 - }; 1812 - 1813 1702 struct platform_driver tegra_hdmi_driver = { 1814 1703 .driver = { 1815 1704 .name = "tegra-hdmi", 1816 1705 .of_match_table = tegra_hdmi_of_match, 1817 - .pm = &tegra_hdmi_pm_ops, 1818 1706 }, 1819 1707 .probe = tegra_hdmi_probe, 1820 1708 .remove = tegra_hdmi_remove,
+118 -80
drivers/gpu/drm/tegra/hub.c
··· 95 95 96 96 static int tegra_windowgroup_enable(struct tegra_windowgroup *wgrp) 97 97 { 98 + int err = 0; 99 + 98 100 mutex_lock(&wgrp->lock); 99 101 100 102 if (wgrp->usecount == 0) { 101 - pm_runtime_get_sync(wgrp->parent); 103 + err = host1x_client_resume(wgrp->parent); 104 + if (err < 0) { 105 + dev_err(wgrp->parent->dev, "failed to resume: %d\n", err); 106 + goto unlock; 107 + } 108 + 102 109 reset_control_deassert(wgrp->rst); 103 110 } 104 111 105 112 wgrp->usecount++; 106 - mutex_unlock(&wgrp->lock); 107 113 108 - return 0; 114 + unlock: 115 + mutex_unlock(&wgrp->lock); 116 + return err; 109 117 } 110 118 111 119 static void tegra_windowgroup_disable(struct tegra_windowgroup *wgrp) ··· 129 121 wgrp->index); 130 122 } 131 123 132 - pm_runtime_put(wgrp->parent); 124 + host1x_client_suspend(wgrp->parent); 133 125 } 134 126 135 127 wgrp->usecount--; ··· 387 379 struct tegra_plane *p = to_tegra_plane(plane); 388 380 struct tegra_dc *dc; 389 381 u32 value; 382 + int err; 390 383 391 384 /* rien ne va plus */ 392 385 if (!old_state || !old_state->crtc) 393 386 return; 394 387 395 388 dc = to_tegra_dc(old_state->crtc); 389 + 390 + err = host1x_client_resume(&dc->client); 391 + if (err < 0) { 392 + dev_err(dc->dev, "failed to resume: %d\n", err); 393 + return; 394 + } 396 395 397 396 /* 398 397 * XXX Legacy helpers seem to sometimes call ->atomic_disable() even ··· 409 394 if (WARN_ON(p->dc == NULL)) 410 395 p->dc = dc; 411 396 412 - pm_runtime_get_sync(dc->dev); 413 - 414 397 value = tegra_plane_readl(p, DC_WIN_WIN_OPTIONS); 415 398 value &= ~WIN_ENABLE; 416 399 tegra_plane_writel(p, value, DC_WIN_WIN_OPTIONS); 417 400 418 401 tegra_dc_remove_shared_plane(dc, p); 419 402 420 - pm_runtime_put(dc->dev); 403 + host1x_client_suspend(&dc->client); 421 404 } 422 405 423 406 static void tegra_shared_plane_atomic_update(struct drm_plane *plane, ··· 428 415 struct tegra_plane *p = to_tegra_plane(plane); 429 416 dma_addr_t base; 430 417 u32 value; 418 + int err; 431 419 432 420 /* rien ne va plus */ 433 421 if (!plane->state->crtc || !plane->state->fb) ··· 439 425 return; 440 426 } 441 427 442 - pm_runtime_get_sync(dc->dev); 428 + err = host1x_client_resume(&dc->client); 429 + if (err < 0) { 430 + dev_err(dc->dev, "failed to resume: %d\n", err); 431 + return; 432 + } 443 433 444 434 tegra_dc_assign_shared_plane(dc, p); 445 435 ··· 533 515 value &= ~CONTROL_CSC_ENABLE; 534 516 tegra_plane_writel(p, value, DC_WIN_WINDOW_SET_CONTROL); 535 517 536 - pm_runtime_put(dc->dev); 518 + host1x_client_suspend(&dc->client); 537 519 } 538 520 539 521 static const struct drm_plane_helper_funcs tegra_shared_plane_helper_funcs = { ··· 569 551 plane->base.index = index; 570 552 571 553 plane->wgrp = &hub->wgrps[wgrp]; 572 - plane->wgrp->parent = dc->dev; 554 + plane->wgrp->parent = &dc->client; 573 555 574 556 p = &plane->base.base; 575 557 ··· 674 656 static void tegra_display_hub_update(struct tegra_dc *dc) 675 657 { 676 658 u32 value; 659 + int err; 677 660 678 - pm_runtime_get_sync(dc->dev); 661 + err = host1x_client_resume(&dc->client); 662 + if (err < 0) { 663 + dev_err(dc->dev, "failed to resume: %d\n", err); 664 + return; 665 + } 679 666 680 667 value = tegra_dc_readl(dc, DC_CMD_IHUB_COMMON_MISC_CTL); 681 668 value &= ~LATENCY_EVENT; ··· 695 672 tegra_dc_writel(dc, COMMON_ACTREQ, DC_CMD_STATE_CONTROL); 696 673 tegra_dc_readl(dc, DC_CMD_STATE_CONTROL); 697 674 698 - pm_runtime_put(dc->dev); 675 + host1x_client_suspend(&dc->client); 699 676 } 700 677 701 678 void tegra_display_hub_atomic_commit(struct drm_device *drm, ··· 755 732 return 0; 756 733 } 757 734 735 + static int tegra_display_hub_runtime_suspend(struct host1x_client *client) 736 + { 737 + struct tegra_display_hub *hub = to_tegra_display_hub(client); 738 + struct device *dev = client->dev; 739 + unsigned int i = hub->num_heads; 740 + int err; 741 + 742 + err = reset_control_assert(hub->rst); 743 + if (err < 0) 744 + return err; 745 + 746 + while (i--) 747 + clk_disable_unprepare(hub->clk_heads[i]); 748 + 749 + clk_disable_unprepare(hub->clk_hub); 750 + clk_disable_unprepare(hub->clk_dsc); 751 + clk_disable_unprepare(hub->clk_disp); 752 + 753 + pm_runtime_put_sync(dev); 754 + 755 + return 0; 756 + } 757 + 758 + static int tegra_display_hub_runtime_resume(struct host1x_client *client) 759 + { 760 + struct tegra_display_hub *hub = to_tegra_display_hub(client); 761 + struct device *dev = client->dev; 762 + unsigned int i; 763 + int err; 764 + 765 + err = pm_runtime_get_sync(dev); 766 + if (err < 0) { 767 + dev_err(dev, "failed to get runtime PM: %d\n", err); 768 + return err; 769 + } 770 + 771 + err = clk_prepare_enable(hub->clk_disp); 772 + if (err < 0) 773 + goto put_rpm; 774 + 775 + err = clk_prepare_enable(hub->clk_dsc); 776 + if (err < 0) 777 + goto disable_disp; 778 + 779 + err = clk_prepare_enable(hub->clk_hub); 780 + if (err < 0) 781 + goto disable_dsc; 782 + 783 + for (i = 0; i < hub->num_heads; i++) { 784 + err = clk_prepare_enable(hub->clk_heads[i]); 785 + if (err < 0) 786 + goto disable_heads; 787 + } 788 + 789 + err = reset_control_deassert(hub->rst); 790 + if (err < 0) 791 + goto disable_heads; 792 + 793 + return 0; 794 + 795 + disable_heads: 796 + while (i--) 797 + clk_disable_unprepare(hub->clk_heads[i]); 798 + 799 + clk_disable_unprepare(hub->clk_hub); 800 + disable_dsc: 801 + clk_disable_unprepare(hub->clk_dsc); 802 + disable_disp: 803 + clk_disable_unprepare(hub->clk_disp); 804 + put_rpm: 805 + pm_runtime_put_sync(dev); 806 + return err; 807 + } 808 + 758 809 static const struct host1x_client_ops tegra_display_hub_ops = { 759 810 .init = tegra_display_hub_init, 760 811 .exit = tegra_display_hub_exit, 812 + .suspend = tegra_display_hub_runtime_suspend, 813 + .resume = tegra_display_hub_runtime_resume, 761 814 }; 762 815 763 816 static int tegra_display_hub_probe(struct platform_device *pdev) ··· 950 851 static int tegra_display_hub_remove(struct platform_device *pdev) 951 852 { 952 853 struct tegra_display_hub *hub = platform_get_drvdata(pdev); 854 + unsigned int i; 953 855 int err; 954 856 955 857 err = host1x_client_unregister(&hub->client); ··· 959 859 err); 960 860 } 961 861 862 + for (i = 0; i < hub->soc->num_wgrps; i++) { 863 + struct tegra_windowgroup *wgrp = &hub->wgrps[i]; 864 + 865 + mutex_destroy(&wgrp->lock); 866 + } 867 + 962 868 pm_runtime_disable(&pdev->dev); 963 869 964 870 return err; 965 871 } 966 - 967 - static int __maybe_unused tegra_display_hub_suspend(struct device *dev) 968 - { 969 - struct tegra_display_hub *hub = dev_get_drvdata(dev); 970 - unsigned int i = hub->num_heads; 971 - int err; 972 - 973 - err = reset_control_assert(hub->rst); 974 - if (err < 0) 975 - return err; 976 - 977 - while (i--) 978 - clk_disable_unprepare(hub->clk_heads[i]); 979 - 980 - clk_disable_unprepare(hub->clk_hub); 981 - clk_disable_unprepare(hub->clk_dsc); 982 - clk_disable_unprepare(hub->clk_disp); 983 - 984 - return 0; 985 - } 986 - 987 - static int __maybe_unused tegra_display_hub_resume(struct device *dev) 988 - { 989 - struct tegra_display_hub *hub = dev_get_drvdata(dev); 990 - unsigned int i; 991 - int err; 992 - 993 - err = clk_prepare_enable(hub->clk_disp); 994 - if (err < 0) 995 - return err; 996 - 997 - err = clk_prepare_enable(hub->clk_dsc); 998 - if (err < 0) 999 - goto disable_disp; 1000 - 1001 - err = clk_prepare_enable(hub->clk_hub); 1002 - if (err < 0) 1003 - goto disable_dsc; 1004 - 1005 - for (i = 0; i < hub->num_heads; i++) { 1006 - err = clk_prepare_enable(hub->clk_heads[i]); 1007 - if (err < 0) 1008 - goto disable_heads; 1009 - } 1010 - 1011 - err = reset_control_deassert(hub->rst); 1012 - if (err < 0) 1013 - goto disable_heads; 1014 - 1015 - return 0; 1016 - 1017 - disable_heads: 1018 - while (i--) 1019 - clk_disable_unprepare(hub->clk_heads[i]); 1020 - 1021 - clk_disable_unprepare(hub->clk_hub); 1022 - disable_dsc: 1023 - clk_disable_unprepare(hub->clk_dsc); 1024 - disable_disp: 1025 - clk_disable_unprepare(hub->clk_disp); 1026 - return err; 1027 - } 1028 - 1029 - static const struct dev_pm_ops tegra_display_hub_pm_ops = { 1030 - SET_RUNTIME_PM_OPS(tegra_display_hub_suspend, 1031 - tegra_display_hub_resume, NULL) 1032 - }; 1033 872 1034 873 static const struct tegra_display_hub_soc tegra186_display_hub = { 1035 874 .num_wgrps = 6, ··· 997 958 .driver = { 998 959 .name = "tegra-display-hub", 999 960 .of_match_table = tegra_display_hub_of_match, 1000 - .pm = &tegra_display_hub_pm_ops, 1001 961 }, 1002 962 .probe = tegra_display_hub_probe, 1003 963 .remove = tegra_display_hub_remove,
+1 -1
drivers/gpu/drm/tegra/hub.h
··· 17 17 struct mutex lock; 18 18 19 19 unsigned int index; 20 - struct device *parent; 20 + struct host1x_client *parent; 21 21 struct reset_control *rst; 22 22 }; 23 23
+88 -66
drivers/gpu/drm/tegra/sor.c
··· 2255 2255 if (err < 0) 2256 2256 dev_err(sor->dev, "failed to power off I/O pad: %d\n", err); 2257 2257 2258 - pm_runtime_put(sor->dev); 2258 + host1x_client_suspend(&sor->client); 2259 2259 } 2260 2260 2261 2261 static void tegra_sor_hdmi_enable(struct drm_encoder *encoder) ··· 2276 2276 mode = &encoder->crtc->state->adjusted_mode; 2277 2277 pclk = mode->clock * 1000; 2278 2278 2279 - pm_runtime_get_sync(sor->dev); 2279 + err = host1x_client_resume(&sor->client); 2280 + if (err < 0) { 2281 + dev_err(sor->dev, "failed to resume: %d\n", err); 2282 + return; 2283 + } 2280 2284 2281 2285 /* switch to safe parent clock */ 2282 2286 err = tegra_sor_set_parent_clock(sor, sor->clk_safe); ··· 2726 2722 if (output->panel) 2727 2723 drm_panel_unprepare(output->panel); 2728 2724 2729 - pm_runtime_put(sor->dev); 2725 + host1x_client_suspend(&sor->client); 2730 2726 } 2731 2727 2732 2728 static void tegra_sor_dp_enable(struct drm_encoder *encoder) ··· 2746 2742 mode = &encoder->crtc->state->adjusted_mode; 2747 2743 info = &output->connector.display_info; 2748 2744 2749 - pm_runtime_get_sync(sor->dev); 2745 + err = host1x_client_resume(&sor->client); 2746 + if (err < 0) { 2747 + dev_err(sor->dev, "failed to resume: %d\n", err); 2748 + return; 2749 + } 2750 2750 2751 2751 /* switch to safe parent clock */ 2752 2752 err = tegra_sor_set_parent_clock(sor, sor->clk_safe); ··· 3197 3189 return 0; 3198 3190 } 3199 3191 3192 + static int tegra_sor_runtime_suspend(struct host1x_client *client) 3193 + { 3194 + struct tegra_sor *sor = host1x_client_to_sor(client); 3195 + struct device *dev = client->dev; 3196 + int err; 3197 + 3198 + if (sor->rst) { 3199 + err = reset_control_assert(sor->rst); 3200 + if (err < 0) { 3201 + dev_err(dev, "failed to assert reset: %d\n", err); 3202 + return err; 3203 + } 3204 + 3205 + reset_control_release(sor->rst); 3206 + } 3207 + 3208 + usleep_range(1000, 2000); 3209 + 3210 + clk_disable_unprepare(sor->clk); 3211 + pm_runtime_put_sync(dev); 3212 + 3213 + return 0; 3214 + } 3215 + 3216 + static int tegra_sor_runtime_resume(struct host1x_client *client) 3217 + { 3218 + struct tegra_sor *sor = host1x_client_to_sor(client); 3219 + struct device *dev = client->dev; 3220 + int err; 3221 + 3222 + err = pm_runtime_get_sync(dev); 3223 + if (err < 0) { 3224 + dev_err(dev, "failed to get runtime PM: %d\n", err); 3225 + return err; 3226 + } 3227 + 3228 + err = clk_prepare_enable(sor->clk); 3229 + if (err < 0) { 3230 + dev_err(dev, "failed to enable clock: %d\n", err); 3231 + goto put_rpm; 3232 + } 3233 + 3234 + usleep_range(1000, 2000); 3235 + 3236 + if (sor->rst) { 3237 + err = reset_control_acquire(sor->rst); 3238 + if (err < 0) { 3239 + dev_err(dev, "failed to acquire reset: %d\n", err); 3240 + goto disable_clk; 3241 + } 3242 + 3243 + err = reset_control_deassert(sor->rst); 3244 + if (err < 0) { 3245 + dev_err(dev, "failed to deassert reset: %d\n", err); 3246 + goto release_reset; 3247 + } 3248 + } 3249 + 3250 + return 0; 3251 + 3252 + release_reset: 3253 + reset_control_release(sor->rst); 3254 + disable_clk: 3255 + clk_disable_unprepare(sor->clk); 3256 + put_rpm: 3257 + pm_runtime_put_sync(dev); 3258 + return err; 3259 + } 3260 + 3200 3261 static const struct host1x_client_ops sor_client_ops = { 3201 3262 .init = tegra_sor_init, 3202 3263 .exit = tegra_sor_exit, 3264 + .suspend = tegra_sor_runtime_suspend, 3265 + .resume = tegra_sor_runtime_resume, 3203 3266 }; 3204 3267 3205 3268 static const u8 tegra124_sor_xbar_cfg[5] = { ··· 3921 3842 if (!sor->clk_pad) { 3922 3843 char *name; 3923 3844 3924 - err = pm_runtime_get_sync(&pdev->dev); 3845 + err = host1x_client_resume(&sor->client); 3925 3846 if (err < 0) { 3926 - dev_err(&pdev->dev, "failed to get runtime PM: %d\n", 3927 - err); 3847 + dev_err(sor->dev, "failed to resume: %d\n", err); 3928 3848 goto remove; 3929 3849 } 3930 3850 ··· 3934 3856 } 3935 3857 3936 3858 sor->clk_pad = tegra_clk_sor_pad_register(sor, name); 3937 - pm_runtime_put(&pdev->dev); 3859 + host1x_client_suspend(&sor->client); 3938 3860 } 3939 3861 3940 3862 if (IS_ERR(sor->clk_pad)) { ··· 3990 3912 return 0; 3991 3913 } 3992 3914 3993 - static int tegra_sor_runtime_suspend(struct device *dev) 3994 - { 3995 - struct tegra_sor *sor = dev_get_drvdata(dev); 3996 - int err; 3997 - 3998 - if (sor->rst) { 3999 - err = reset_control_assert(sor->rst); 4000 - if (err < 0) { 4001 - dev_err(dev, "failed to assert reset: %d\n", err); 4002 - return err; 4003 - } 4004 - 4005 - reset_control_release(sor->rst); 4006 - } 4007 - 4008 - usleep_range(1000, 2000); 4009 - 4010 - clk_disable_unprepare(sor->clk); 4011 - 4012 - return 0; 4013 - } 4014 - 4015 - static int tegra_sor_runtime_resume(struct device *dev) 4016 - { 4017 - struct tegra_sor *sor = dev_get_drvdata(dev); 4018 - int err; 4019 - 4020 - err = clk_prepare_enable(sor->clk); 4021 - if (err < 0) { 4022 - dev_err(dev, "failed to enable clock: %d\n", err); 4023 - return err; 4024 - } 4025 - 4026 - usleep_range(1000, 2000); 4027 - 4028 - if (sor->rst) { 4029 - err = reset_control_acquire(sor->rst); 4030 - if (err < 0) { 4031 - dev_err(dev, "failed to acquire reset: %d\n", err); 4032 - clk_disable_unprepare(sor->clk); 4033 - return err; 4034 - } 4035 - 4036 - err = reset_control_deassert(sor->rst); 4037 - if (err < 0) { 4038 - dev_err(dev, "failed to deassert reset: %d\n", err); 4039 - reset_control_release(sor->rst); 4040 - clk_disable_unprepare(sor->clk); 4041 - return err; 4042 - } 4043 - } 4044 - 4045 - return 0; 4046 - } 4047 - 4048 3915 static int tegra_sor_suspend(struct device *dev) 4049 3916 { 4050 3917 struct tegra_sor *sor = dev_get_drvdata(dev); ··· 3997 3974 3998 3975 if (sor->hdmi_supply) { 3999 3976 err = regulator_disable(sor->hdmi_supply); 4000 - if (err < 0) 3977 + if (err < 0) { 4001 3978 return err; 3979 + } 4002 3980 } 4003 3981 4004 3982 return 0; ··· 4020 3996 } 4021 3997 4022 3998 static const struct dev_pm_ops tegra_sor_pm_ops = { 4023 - SET_RUNTIME_PM_OPS(tegra_sor_runtime_suspend, tegra_sor_runtime_resume, 4024 - NULL) 4025 3999 SET_SYSTEM_SLEEP_PM_OPS(tegra_sor_suspend, tegra_sor_resume) 4026 4000 }; 4027 4001
+75
drivers/gpu/host1x/bus.c
··· 710 710 struct host1x *host1x; 711 711 int err; 712 712 713 + INIT_LIST_HEAD(&client->list); 714 + mutex_init(&client->lock); 715 + client->usecount = 0; 716 + 713 717 mutex_lock(&devices_lock); 714 718 715 719 list_for_each_entry(host1x, &devices, list) { ··· 772 768 return 0; 773 769 } 774 770 EXPORT_SYMBOL(host1x_client_unregister); 771 + 772 + int host1x_client_suspend(struct host1x_client *client) 773 + { 774 + int err = 0; 775 + 776 + mutex_lock(&client->lock); 777 + 778 + if (client->usecount == 1) { 779 + if (client->ops && client->ops->suspend) { 780 + err = client->ops->suspend(client); 781 + if (err < 0) 782 + goto unlock; 783 + } 784 + } 785 + 786 + client->usecount--; 787 + dev_dbg(client->dev, "use count: %u\n", client->usecount); 788 + 789 + if (client->parent) { 790 + err = host1x_client_suspend(client->parent); 791 + if (err < 0) 792 + goto resume; 793 + } 794 + 795 + goto unlock; 796 + 797 + resume: 798 + if (client->usecount == 0) 799 + if (client->ops && client->ops->resume) 800 + client->ops->resume(client); 801 + 802 + client->usecount++; 803 + unlock: 804 + mutex_unlock(&client->lock); 805 + return err; 806 + } 807 + EXPORT_SYMBOL(host1x_client_suspend); 808 + 809 + int host1x_client_resume(struct host1x_client *client) 810 + { 811 + int err = 0; 812 + 813 + mutex_lock(&client->lock); 814 + 815 + if (client->parent) { 816 + err = host1x_client_resume(client->parent); 817 + if (err < 0) 818 + goto unlock; 819 + } 820 + 821 + if (client->usecount == 0) { 822 + if (client->ops && client->ops->resume) { 823 + err = client->ops->resume(client); 824 + if (err < 0) 825 + goto suspend; 826 + } 827 + } 828 + 829 + client->usecount++; 830 + dev_dbg(client->dev, "use count: %u\n", client->usecount); 831 + 832 + goto unlock; 833 + 834 + suspend: 835 + if (client->parent) 836 + host1x_client_suspend(client->parent); 837 + unlock: 838 + mutex_unlock(&client->lock); 839 + return err; 840 + } 841 + EXPORT_SYMBOL(host1x_client_resume);
+11
include/linux/host1x.h
··· 24 24 * struct host1x_client_ops - host1x client operations 25 25 * @init: host1x client initialization code 26 26 * @exit: host1x client tear down code 27 + * @suspend: host1x client suspend code 28 + * @resume: host1x client resume code 27 29 */ 28 30 struct host1x_client_ops { 29 31 int (*init)(struct host1x_client *client); 30 32 int (*exit)(struct host1x_client *client); 33 + int (*suspend)(struct host1x_client *client); 34 + int (*resume)(struct host1x_client *client); 31 35 }; 32 36 33 37 /** ··· 59 55 60 56 struct host1x_syncpt **syncpts; 61 57 unsigned int num_syncpts; 58 + 59 + struct host1x_client *parent; 60 + unsigned int usecount; 61 + struct mutex lock; 62 62 }; 63 63 64 64 /* ··· 329 321 330 322 int host1x_client_register(struct host1x_client *client); 331 323 int host1x_client_unregister(struct host1x_client *client); 324 + 325 + int host1x_client_suspend(struct host1x_client *client); 326 + int host1x_client_resume(struct host1x_client *client); 332 327 333 328 struct tegra_mipi_device; 334 329