5151#include "linux/of_address.h"
5252#include "linux/of_gpio.h"
5353#include "linux/of_platform.h"
54+ #include "linux/pm_runtime.h"
5455#include "linux/rational.h"
5556#include "sound/dmaengine_pcm.h"
5657#include "sound/pcm_drm_eld.h"
@@ -449,13 +450,38 @@ static void vc4_hdmi_set_infoframes(struct drm_encoder *encoder)
449450 vc4_hdmi_set_spd_infoframe (encoder );
450451}
451452
452- static void vc4_hdmi_encoder_mode_set (struct drm_encoder * encoder ,
453- struct drm_display_mode * unadjusted_mode ,
454- struct drm_display_mode * mode )
453+ static void vc4_hdmi_encoder_disable (struct drm_encoder * encoder )
454+ {
455+ struct drm_device * dev = encoder -> dev ;
456+ struct vc4_dev * vc4 = to_vc4_dev (dev );
457+ struct vc4_hdmi * hdmi = vc4 -> hdmi ;
458+ int ret ;
459+
460+ HDMI_WRITE (VC4_HDMI_RAM_PACKET_CONFIG , 0 );
461+
462+ HDMI_WRITE (VC4_HDMI_TX_PHY_RESET_CTL , 0xf << 16 );
463+ HD_WRITE (VC4_HD_VID_CTL ,
464+ HD_READ (VC4_HD_VID_CTL ) & ~VC4_HD_VID_CTL_ENABLE );
465+
466+ HD_WRITE (VC4_HD_M_CTL , VC4_HD_M_SW_RST );
467+ udelay (1 );
468+ HD_WRITE (VC4_HD_M_CTL , 0 );
469+
470+ clk_disable_unprepare (hdmi -> hsm_clock );
471+ clk_disable_unprepare (hdmi -> pixel_clock );
472+
473+ ret = pm_runtime_put (& hdmi -> pdev -> dev );
474+ if (ret < 0 )
475+ DRM_ERROR ("Failed to release power domain: %d\n" , ret );
476+ }
477+
478+ static void vc4_hdmi_encoder_enable (struct drm_encoder * encoder )
455479{
480+ struct drm_display_mode * mode = & encoder -> crtc -> state -> adjusted_mode ;
456481 struct vc4_hdmi_encoder * vc4_encoder = to_vc4_hdmi_encoder (encoder );
457482 struct drm_device * dev = encoder -> dev ;
458483 struct vc4_dev * vc4 = to_vc4_dev (dev );
484+ struct vc4_hdmi * hdmi = vc4 -> hdmi ;
459485 bool debug_dump_regs = false;
460486 bool hsync_pos = mode -> flags & DRM_MODE_FLAG_PHSYNC ;
461487 bool vsync_pos = mode -> flags & DRM_MODE_FLAG_PVSYNC ;
@@ -475,6 +501,64 @@ static void vc4_hdmi_encoder_mode_set(struct drm_encoder *encoder,
475501 interlaced ,
476502 VC4_HDMI_VERTB_VBP ));
477503 u32 csc_ctl ;
504+ int ret ;
505+
506+ ret = pm_runtime_get_sync (& hdmi -> pdev -> dev );
507+ if (ret < 0 ) {
508+ DRM_ERROR ("Failed to retain power domain: %d\n" , ret );
509+ return ;
510+ }
511+
512+ /* This is the rate that is set by the firmware. The number
513+ * needs to be a bit higher than the pixel clock rate
514+ * (generally 148.5Mhz).
515+ */
516+ ret = clk_set_rate (hdmi -> hsm_clock , 163682864 );
517+ if (ret ) {
518+ DRM_ERROR ("Failed to set HSM clock rate: %d\n" , ret );
519+ return ;
520+ }
521+
522+ ret = clk_set_rate (hdmi -> pixel_clock ,
523+ mode -> clock * 1000 *
524+ ((mode -> flags & DRM_MODE_FLAG_DBLCLK ) ? 2 : 1 ));
525+ if (ret ) {
526+ DRM_ERROR ("Failed to set pixel clock rate: %d\n" , ret );
527+ return ;
528+ }
529+
530+ ret = clk_prepare_enable (hdmi -> pixel_clock );
531+ if (ret ) {
532+ DRM_ERROR ("Failed to turn on pixel clock: %d\n" , ret );
533+ return ;
534+ }
535+
536+ ret = clk_prepare_enable (hdmi -> hsm_clock );
537+ if (ret ) {
538+ DRM_ERROR ("Failed to turn on HDMI state machine clock: %d\n" ,
539+ ret );
540+ clk_disable_unprepare (hdmi -> pixel_clock );
541+ return ;
542+ }
543+
544+ HD_WRITE (VC4_HD_M_CTL , VC4_HD_M_SW_RST );
545+ udelay (1 );
546+ HD_WRITE (VC4_HD_M_CTL , 0 );
547+
548+ HD_WRITE (VC4_HD_M_CTL , VC4_HD_M_ENABLE );
549+
550+ HDMI_WRITE (VC4_HDMI_SW_RESET_CONTROL ,
551+ VC4_HDMI_SW_RESET_HDMI |
552+ VC4_HDMI_SW_RESET_FORMAT_DETECT );
553+
554+ HDMI_WRITE (VC4_HDMI_SW_RESET_CONTROL , 0 );
555+
556+ /* PHY should be in reset, like
557+ * vc4_hdmi_encoder_disable() does.
558+ */
559+ HDMI_WRITE (VC4_HDMI_TX_PHY_RESET_CTL , 0xf << 16 );
560+
561+ HDMI_WRITE (VC4_HDMI_TX_PHY_RESET_CTL , 0 );
478562
479563 if (debug_dump_regs ) {
480564 DRM_INFO ("HDMI regs before:\n" );
@@ -483,9 +567,6 @@ static void vc4_hdmi_encoder_mode_set(struct drm_encoder *encoder,
483567
484568 HD_WRITE (VC4_HD_VID_CTL , 0 );
485569
486- clk_set_rate (vc4 -> hdmi -> pixel_clock , mode -> clock * 1000 *
487- ((mode -> flags & DRM_MODE_FLAG_DBLCLK ) ? 2 : 1 ));
488-
489570 HDMI_WRITE (VC4_HDMI_SCHEDULER_CONTROL ,
490571 HDMI_READ (VC4_HDMI_SCHEDULER_CONTROL ) |
491572 VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT |
@@ -559,28 +640,6 @@ static void vc4_hdmi_encoder_mode_set(struct drm_encoder *encoder,
559640 DRM_INFO ("HDMI regs after:\n" );
560641 vc4_hdmi_dump_regs (dev );
561642 }
562- }
563-
564- static void vc4_hdmi_encoder_disable (struct drm_encoder * encoder )
565- {
566- struct drm_device * dev = encoder -> dev ;
567- struct vc4_dev * vc4 = to_vc4_dev (dev );
568-
569- HDMI_WRITE (VC4_HDMI_RAM_PACKET_CONFIG , 0 );
570-
571- HDMI_WRITE (VC4_HDMI_TX_PHY_RESET_CTL , 0xf << 16 );
572- HD_WRITE (VC4_HD_VID_CTL ,
573- HD_READ (VC4_HD_VID_CTL ) & ~VC4_HD_VID_CTL_ENABLE );
574- }
575-
576- static void vc4_hdmi_encoder_enable (struct drm_encoder * encoder )
577- {
578- struct vc4_hdmi_encoder * vc4_encoder = to_vc4_hdmi_encoder (encoder );
579- struct drm_device * dev = encoder -> dev ;
580- struct vc4_dev * vc4 = to_vc4_dev (dev );
581- int ret ;
582-
583- HDMI_WRITE (VC4_HDMI_TX_PHY_RESET_CTL , 0 );
584643
585644 HD_WRITE (VC4_HD_VID_CTL ,
586645 HD_READ (VC4_HD_VID_CTL ) |
@@ -646,7 +705,6 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
646705}
647706
648707static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
649- .mode_set = vc4_hdmi_encoder_mode_set ,
650708 .disable = vc4_hdmi_encoder_disable ,
651709 .enable = vc4_hdmi_encoder_enable ,
652710};
@@ -1147,33 +1205,6 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
11471205 return - EPROBE_DEFER ;
11481206 }
11491207
1150- /* Enable the clocks at startup. We can't quite recover from
1151- * turning off the pixel clock during disable/enables yet, so
1152- * it's always running.
1153- */
1154- ret = clk_prepare_enable (hdmi -> pixel_clock );
1155- if (ret ) {
1156- DRM_ERROR ("Failed to turn on pixel clock: %d\n" , ret );
1157- goto err_put_i2c ;
1158- }
1159-
1160- /* This is the rate that is set by the firmware. The number
1161- * needs to be a bit higher than the pixel clock rate
1162- * (generally 148.5Mhz).
1163- */
1164- ret = clk_set_rate (hdmi -> hsm_clock , 163682864 );
1165- if (ret ) {
1166- DRM_ERROR ("Failed to set HSM clock rate: %d\n" , ret );
1167- goto err_unprepare_pix ;
1168- }
1169-
1170- ret = clk_prepare_enable (hdmi -> hsm_clock );
1171- if (ret ) {
1172- DRM_ERROR ("Failed to turn on HDMI state machine clock: %d\n" ,
1173- ret );
1174- goto err_unprepare_pix ;
1175- }
1176-
11771208 /* Only use the GPIO HPD pin if present in the DT, otherwise
11781209 * we'll use the HDMI core's register.
11791210 */
@@ -1185,33 +1216,15 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
11851216 & hpd_gpio_flags );
11861217 if (hdmi -> hpd_gpio < 0 ) {
11871218 ret = hdmi -> hpd_gpio ;
1188- goto err_unprepare_hsm ;
1219+ goto err_put_i2c ;
11891220 }
11901221
11911222 hdmi -> hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW ;
11921223 }
11931224
11941225 vc4 -> hdmi = hdmi ;
11951226
1196- /* HDMI core must be enabled. */
1197- if (!(HD_READ (VC4_HD_M_CTL ) & VC4_HD_M_ENABLE )) {
1198- HD_WRITE (VC4_HD_M_CTL , VC4_HD_M_SW_RST );
1199- udelay (1 );
1200- HD_WRITE (VC4_HD_M_CTL , 0 );
1201-
1202- HD_WRITE (VC4_HD_M_CTL , VC4_HD_M_ENABLE );
1203-
1204- HDMI_WRITE (VC4_HDMI_SW_RESET_CONTROL ,
1205- VC4_HDMI_SW_RESET_HDMI |
1206- VC4_HDMI_SW_RESET_FORMAT_DETECT );
1207-
1208- HDMI_WRITE (VC4_HDMI_SW_RESET_CONTROL , 0 );
1209-
1210- /* PHY should be in reset, like
1211- * vc4_hdmi_encoder_disable() does.
1212- */
1213- HDMI_WRITE (VC4_HDMI_TX_PHY_RESET_CTL , 0xf << 16 );
1214- }
1227+ pm_runtime_enable (dev );
12151228
12161229 drm_encoder_init (drm , hdmi -> encoder , & vc4_hdmi_encoder_funcs ,
12171230 DRM_MODE_ENCODER_TMDS , NULL );
@@ -1231,10 +1244,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
12311244
12321245err_destroy_encoder :
12331246 vc4_hdmi_encoder_destroy (hdmi -> encoder );
1234- err_unprepare_hsm :
1235- clk_disable_unprepare (hdmi -> hsm_clock );
1236- err_unprepare_pix :
1237- clk_disable_unprepare (hdmi -> pixel_clock );
1247+ pm_runtime_disable (dev );
12381248err_put_i2c :
12391249 put_device (& hdmi -> ddc -> dev );
12401250
@@ -1253,8 +1263,8 @@ static void vc4_hdmi_unbind(struct device *dev, struct device *master,
12531263 vc4_hdmi_connector_destroy (hdmi -> connector );
12541264 vc4_hdmi_encoder_destroy (hdmi -> encoder );
12551265
1256- clk_disable_unprepare ( hdmi -> pixel_clock );
1257- clk_disable_unprepare ( hdmi -> hsm_clock );
1266+ pm_runtime_disable ( dev );
1267+
12581268 put_device (& hdmi -> ddc -> dev );
12591269
12601270 vc4 -> hdmi = NULL ;
0 commit comments