@@ -1727,6 +1727,7 @@ static void tegra_crtc_atomic_disable(struct drm_crtc *crtc,
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 );
@@ -1773,7 +1774,9 @@ static void tegra_crtc_atomic_disable(struct drm_crtc *crtc,
1773
1774
1774
1775
spin_unlock_irq (& crtc -> dev -> event_lock );
1775
1776
1776
- pm_runtime_put_sync (dc -> dev );
1777
+ err = host1x_client_suspend (& dc -> client );
1778
+ if (err < 0 )
1779
+ dev_err (dc -> dev , "failed to suspend: %d\n" , err );
1777
1780
}
1778
1781
1779
1782
static void tegra_crtc_atomic_enable (struct drm_crtc * crtc ,
@@ -1783,8 +1786,13 @@ static void tegra_crtc_atomic_enable(struct drm_crtc *crtc,
1783
1786
struct tegra_dc_state * state = to_dc_state (crtc -> state );
1784
1787
struct tegra_dc * dc = to_tegra_dc (crtc );
1785
1788
u32 value ;
1789
+ int err ;
1786
1790
1787
- pm_runtime_get_sync (dc -> dev );
1791
+ err = host1x_client_resume (& dc -> client );
1792
+ if (err < 0 ) {
1793
+ dev_err (dc -> dev , "failed to resume: %d\n" , err );
1794
+ return ;
1795
+ }
1788
1796
1789
1797
/* initialize display controller */
1790
1798
if (dc -> syncpt ) {
@@ -1996,7 +2004,7 @@ static bool tegra_dc_has_window_groups(struct tegra_dc *dc)
1996
2004
1997
2005
static int tegra_dc_init (struct host1x_client * client )
1998
2006
{
1999
- struct drm_device * drm = dev_get_drvdata (client -> parent );
2007
+ struct drm_device * drm = dev_get_drvdata (client -> host );
2000
2008
unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED ;
2001
2009
struct tegra_dc * dc = host1x_client_to_dc (client );
2002
2010
struct tegra_drm * tegra = drm -> dev_private ;
@@ -2012,6 +2020,15 @@ static int tegra_dc_init(struct host1x_client *client)
2012
2020
if (!tegra_dc_has_window_groups (dc ))
2013
2021
return 0 ;
2014
2022
2023
+ /*
2024
+ * Set the display hub as the host1x client parent for the display
2025
+ * controller. This is needed for the runtime reference counting that
2026
+ * ensures the display hub is always powered when any of the display
2027
+ * controllers are.
2028
+ */
2029
+ if (dc -> soc -> has_nvdisplay )
2030
+ client -> parent = & tegra -> hub -> client ;
2031
+
2015
2032
dc -> syncpt = host1x_syncpt_request (client , flags );
2016
2033
if (!dc -> syncpt )
2017
2034
dev_warn (dc -> dev , "failed to allocate syncpoint\n" );
@@ -2077,9 +2094,9 @@ static int tegra_dc_init(struct host1x_client *client)
2077
2094
2078
2095
/*
2079
2096
* Inherit the DMA parameters (such as maximum segment size) from the
2080
- * parent device.
2097
+ * parent host1x device.
2081
2098
*/
2082
- client -> dev -> dma_parms = client -> parent -> dma_parms ;
2099
+ client -> dev -> dma_parms = client -> host -> dma_parms ;
2083
2100
2084
2101
return 0 ;
2085
2102
@@ -2121,9 +2138,74 @@ static int tegra_dc_exit(struct host1x_client *client)
2121
2138
return 0 ;
2122
2139
}
2123
2140
2141
+ static int tegra_dc_runtime_suspend (struct host1x_client * client )
2142
+ {
2143
+ struct tegra_dc * dc = host1x_client_to_dc (client );
2144
+ struct device * dev = client -> dev ;
2145
+ int err ;
2146
+
2147
+ err = reset_control_assert (dc -> rst );
2148
+ if (err < 0 ) {
2149
+ dev_err (dev , "failed to assert reset: %d\n" , err );
2150
+ return err ;
2151
+ }
2152
+
2153
+ if (dc -> soc -> has_powergate )
2154
+ tegra_powergate_power_off (dc -> powergate );
2155
+
2156
+ clk_disable_unprepare (dc -> clk );
2157
+ pm_runtime_put_sync (dev );
2158
+
2159
+ return 0 ;
2160
+ }
2161
+
2162
+ static int tegra_dc_runtime_resume (struct host1x_client * client )
2163
+ {
2164
+ struct tegra_dc * dc = host1x_client_to_dc (client );
2165
+ struct device * dev = client -> dev ;
2166
+ int err ;
2167
+
2168
+ err = pm_runtime_get_sync (dev );
2169
+ if (err < 0 ) {
2170
+ dev_err (dev , "failed to get runtime PM: %d\n" , err );
2171
+ return err ;
2172
+ }
2173
+
2174
+ if (dc -> soc -> has_powergate ) {
2175
+ err = tegra_powergate_sequence_power_up (dc -> powergate , dc -> clk ,
2176
+ dc -> rst );
2177
+ if (err < 0 ) {
2178
+ dev_err (dev , "failed to power partition: %d\n" , err );
2179
+ goto put_rpm ;
2180
+ }
2181
+ } else {
2182
+ err = clk_prepare_enable (dc -> clk );
2183
+ if (err < 0 ) {
2184
+ dev_err (dev , "failed to enable clock: %d\n" , err );
2185
+ goto put_rpm ;
2186
+ }
2187
+
2188
+ err = reset_control_deassert (dc -> rst );
2189
+ if (err < 0 ) {
2190
+ dev_err (dev , "failed to deassert reset: %d\n" , err );
2191
+ goto disable_clk ;
2192
+ }
2193
+ }
2194
+
2195
+ return 0 ;
2196
+
2197
+ disable_clk :
2198
+ clk_disable_unprepare (dc -> clk );
2199
+ put_rpm :
2200
+ pm_runtime_put_sync (dev );
2201
+ return err ;
2202
+ }
2203
+
2124
2204
static const struct host1x_client_ops dc_client_ops = {
2125
2205
.init = tegra_dc_init ,
2126
2206
.exit = tegra_dc_exit ,
2207
+ .suspend = tegra_dc_runtime_suspend ,
2208
+ .resume = tegra_dc_runtime_resume ,
2127
2209
};
2128
2210
2129
2211
static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
@@ -2535,65 +2617,10 @@ static int tegra_dc_remove(struct platform_device *pdev)
2535
2617
return 0 ;
2536
2618
}
2537
2619
2538
- #ifdef CONFIG_PM
2539
- static int tegra_dc_suspend (struct device * dev )
2540
- {
2541
- struct tegra_dc * dc = dev_get_drvdata (dev );
2542
- int err ;
2543
-
2544
- err = reset_control_assert (dc -> rst );
2545
- if (err < 0 ) {
2546
- dev_err (dev , "failed to assert reset: %d\n" , err );
2547
- return err ;
2548
- }
2549
-
2550
- if (dc -> soc -> has_powergate )
2551
- tegra_powergate_power_off (dc -> powergate );
2552
-
2553
- clk_disable_unprepare (dc -> clk );
2554
-
2555
- return 0 ;
2556
- }
2557
-
2558
- static int tegra_dc_resume (struct device * dev )
2559
- {
2560
- struct tegra_dc * dc = dev_get_drvdata (dev );
2561
- int err ;
2562
-
2563
- if (dc -> soc -> has_powergate ) {
2564
- err = tegra_powergate_sequence_power_up (dc -> powergate , dc -> clk ,
2565
- dc -> rst );
2566
- if (err < 0 ) {
2567
- dev_err (dev , "failed to power partition: %d\n" , err );
2568
- return err ;
2569
- }
2570
- } else {
2571
- err = clk_prepare_enable (dc -> clk );
2572
- if (err < 0 ) {
2573
- dev_err (dev , "failed to enable clock: %d\n" , err );
2574
- return err ;
2575
- }
2576
-
2577
- err = reset_control_deassert (dc -> rst );
2578
- if (err < 0 ) {
2579
- dev_err (dev , "failed to deassert reset: %d\n" , err );
2580
- return err ;
2581
- }
2582
- }
2583
-
2584
- return 0 ;
2585
- }
2586
- #endif
2587
-
2588
- static const struct dev_pm_ops tegra_dc_pm_ops = {
2589
- SET_RUNTIME_PM_OPS (tegra_dc_suspend , tegra_dc_resume , NULL )
2590
- };
2591
-
2592
2620
struct platform_driver tegra_dc_driver = {
2593
2621
.driver = {
2594
2622
.name = "tegra-dc" ,
2595
2623
.of_match_table = tegra_dc_of_match ,
2596
- .pm = & tegra_dc_pm_ops ,
2597
2624
},
2598
2625
.probe = tegra_dc_probe ,
2599
2626
.remove = tegra_dc_remove ,
0 commit comments