@@ -159,6 +159,8 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
159159 struct vc4_hdmi * vc4_hdmi = connector_to_vc4_hdmi (connector );
160160 bool connected = false;
161161
162+ WARN_ON (pm_runtime_resume_and_get (& vc4_hdmi -> pdev -> dev ));
163+
162164 if (vc4_hdmi -> hpd_gpio ) {
163165 if (gpio_get_value_cansleep (vc4_hdmi -> hpd_gpio ) ^
164166 vc4_hdmi -> hpd_active_low )
@@ -180,10 +182,12 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
180182 }
181183 }
182184
185+ pm_runtime_put (& vc4_hdmi -> pdev -> dev );
183186 return connector_status_connected ;
184187 }
185188
186189 cec_phys_addr_invalidate (vc4_hdmi -> cec_adap );
190+ pm_runtime_put (& vc4_hdmi -> pdev -> dev );
187191 return connector_status_disconnected ;
188192}
189193
@@ -473,7 +477,6 @@ static void vc4_hdmi_encoder_post_crtc_powerdown(struct drm_encoder *encoder,
473477 HDMI_READ (HDMI_VID_CTL ) & ~VC4_HD_VID_CTL_ENABLE );
474478
475479 clk_disable_unprepare (vc4_hdmi -> pixel_bvb_clock );
476- clk_disable_unprepare (vc4_hdmi -> hsm_clock );
477480 clk_disable_unprepare (vc4_hdmi -> pixel_clock );
478481
479482 ret = pm_runtime_put (& vc4_hdmi -> pdev -> dev );
@@ -784,13 +787,6 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder,
784787 return ;
785788 }
786789
787- ret = clk_prepare_enable (vc4_hdmi -> hsm_clock );
788- if (ret ) {
789- DRM_ERROR ("Failed to turn on HSM clock: %d\n" , ret );
790- clk_disable_unprepare (vc4_hdmi -> pixel_clock );
791- return ;
792- }
793-
794790 vc4_hdmi_cec_update_clk_div (vc4_hdmi );
795791
796792 /*
@@ -801,15 +797,13 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder,
801797 (hsm_rate > VC4_HSM_MID_CLOCK ? 150000000 : 75000000 ));
802798 if (ret ) {
803799 DRM_ERROR ("Failed to set pixel bvb clock rate: %d\n" , ret );
804- clk_disable_unprepare (vc4_hdmi -> hsm_clock );
805800 clk_disable_unprepare (vc4_hdmi -> pixel_clock );
806801 return ;
807802 }
808803
809804 ret = clk_prepare_enable (vc4_hdmi -> pixel_bvb_clock );
810805 if (ret ) {
811806 DRM_ERROR ("Failed to turn on pixel bvb clock: %d\n" , ret );
812- clk_disable_unprepare (vc4_hdmi -> hsm_clock );
813807 clk_disable_unprepare (vc4_hdmi -> pixel_clock );
814808 return ;
815809 }
@@ -1929,6 +1923,29 @@ static int vc5_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
19291923 return 0 ;
19301924}
19311925
1926+ #ifdef CONFIG_PM
1927+ static int vc4_hdmi_runtime_suspend (struct device * dev )
1928+ {
1929+ struct vc4_hdmi * vc4_hdmi = dev_get_drvdata (dev );
1930+
1931+ clk_disable_unprepare (vc4_hdmi -> hsm_clock );
1932+
1933+ return 0 ;
1934+ }
1935+
1936+ static int vc4_hdmi_runtime_resume (struct device * dev )
1937+ {
1938+ struct vc4_hdmi * vc4_hdmi = dev_get_drvdata (dev );
1939+ int ret ;
1940+
1941+ ret = clk_prepare_enable (vc4_hdmi -> hsm_clock );
1942+ if (ret )
1943+ return ret ;
1944+
1945+ return 0 ;
1946+ }
1947+ #endif
1948+
19321949static int vc4_hdmi_bind (struct device * dev , struct device * master , void * data )
19331950{
19341951 const struct vc4_hdmi_variant * variant = of_device_get_match_data (dev );
@@ -2165,11 +2182,18 @@ static const struct of_device_id vc4_hdmi_dt_match[] = {
21652182 {}
21662183};
21672184
2185+ static const struct dev_pm_ops vc4_hdmi_pm_ops = {
2186+ SET_RUNTIME_PM_OPS (vc4_hdmi_runtime_suspend ,
2187+ vc4_hdmi_runtime_resume ,
2188+ NULL )
2189+ };
2190+
21682191struct platform_driver vc4_hdmi_driver = {
21692192 .probe = vc4_hdmi_dev_probe ,
21702193 .remove = vc4_hdmi_dev_remove ,
21712194 .driver = {
21722195 .name = "vc4_hdmi" ,
21732196 .of_match_table = vc4_hdmi_dt_match ,
2197+ .pm = & vc4_hdmi_pm_ops ,
21742198 },
21752199};
0 commit comments