106106#define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 */
107107#define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 */
108108#define HHI_HDMI_PHY_CNTL1 0x3a4 /* 0xe9 */
109+ #define PHY_CNTL1_INIT 0x03900000
110+ #define PHY_INVERT BIT(17)
109111#define HHI_HDMI_PHY_CNTL2 0x3a8 /* 0xea */
110112#define HHI_HDMI_PHY_CNTL3 0x3ac /* 0xeb */
111113#define HHI_HDMI_PHY_CNTL4 0x3b0 /* 0xec */
@@ -130,6 +132,8 @@ struct meson_dw_hdmi_data {
130132 unsigned int addr );
131133 void (* dwc_write )(struct meson_dw_hdmi * dw_hdmi ,
132134 unsigned int addr , unsigned int data );
135+ u32 cntl0_init ;
136+ u32 cntl1_init ;
133137};
134138
135139struct meson_dw_hdmi {
@@ -384,26 +388,6 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
384388 dw_hdmi_bus_fmt_is_420 (hdmi ))
385389 mode_is_420 = true;
386390
387- /* Enable clocks */
388- regmap_update_bits (priv -> hhi , HHI_HDMI_CLK_CNTL , 0xffff , 0x100 );
389-
390- /* Bring HDMITX MEM output of power down */
391- regmap_update_bits (priv -> hhi , HHI_MEM_PD_REG0 , 0xff << 8 , 0 );
392-
393- /* Bring out of reset */
394- dw_hdmi -> data -> top_write (dw_hdmi , HDMITX_TOP_SW_RESET , 0 );
395-
396- /* Enable internal pixclk, tmds_clk, spdif_clk, i2s_clk, cecclk */
397- dw_hdmi_top_write_bits (dw_hdmi , HDMITX_TOP_CLK_CNTL ,
398- 0x3 , 0x3 );
399-
400- /* Enable cec_clk and hdcp22_tmdsclk_en */
401- dw_hdmi_top_write_bits (dw_hdmi , HDMITX_TOP_CLK_CNTL ,
402- 0x3 << 4 , 0x3 << 4 );
403-
404- /* Enable normal output to PHY */
405- dw_hdmi -> data -> top_write (dw_hdmi , HDMITX_TOP_BIST_CNTL , BIT (12 ));
406-
407391 /* TMDS pattern setup */
408392 if (mode -> clock > 340000 && !mode_is_420 ) {
409393 dw_hdmi -> data -> top_write (dw_hdmi , HDMITX_TOP_TMDS_CLK_PTTN_01 ,
@@ -425,20 +409,6 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
425409 /* Setup PHY parameters */
426410 meson_hdmi_phy_setup_mode (dw_hdmi , mode , mode_is_420 );
427411
428- /* Setup PHY */
429- regmap_update_bits (priv -> hhi , HHI_HDMI_PHY_CNTL1 ,
430- 0xffff << 16 , 0x0390 << 16 );
431-
432- /* BIT_INVERT */
433- if (dw_hdmi_is_compatible (dw_hdmi , "amlogic,meson-gxl-dw-hdmi" ) ||
434- dw_hdmi_is_compatible (dw_hdmi , "amlogic,meson-gxm-dw-hdmi" ) ||
435- dw_hdmi_is_compatible (dw_hdmi , "amlogic,meson-g12a-dw-hdmi" ))
436- regmap_update_bits (priv -> hhi , HHI_HDMI_PHY_CNTL1 ,
437- BIT (17 ), 0 );
438- else
439- regmap_update_bits (priv -> hhi , HHI_HDMI_PHY_CNTL1 ,
440- BIT (17 ), BIT (17 ));
441-
442412 /* Disable clock, fifo, fifo_wr */
443413 regmap_update_bits (priv -> hhi , HHI_HDMI_PHY_CNTL1 , 0xf , 0 );
444414
@@ -492,7 +462,9 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi,
492462
493463 DRM_DEBUG_DRIVER ("\n" );
494464
495- regmap_write (priv -> hhi , HHI_HDMI_PHY_CNTL0 , 0 );
465+ /* Fallback to init mode */
466+ regmap_write (priv -> hhi , HHI_HDMI_PHY_CNTL1 , dw_hdmi -> data -> cntl1_init );
467+ regmap_write (priv -> hhi , HHI_HDMI_PHY_CNTL0 , dw_hdmi -> data -> cntl0_init );
496468}
497469
498470static enum drm_connector_status dw_hdmi_read_hpd (struct dw_hdmi * hdmi ,
@@ -610,18 +582,31 @@ static const struct regmap_config meson_dw_hdmi_regmap_config = {
610582 .fast_io = true,
611583};
612584
613- static const struct meson_dw_hdmi_data meson_dw_hdmi_gx_data = {
585+ static const struct meson_dw_hdmi_data meson_dw_hdmi_gxbb_data = {
614586 .top_read = dw_hdmi_top_read ,
615587 .top_write = dw_hdmi_top_write ,
616588 .dwc_read = dw_hdmi_dwc_read ,
617589 .dwc_write = dw_hdmi_dwc_write ,
590+ .cntl0_init = 0x0 ,
591+ .cntl1_init = PHY_CNTL1_INIT | PHY_INVERT ,
592+ };
593+
594+ static const struct meson_dw_hdmi_data meson_dw_hdmi_gxl_data = {
595+ .top_read = dw_hdmi_top_read ,
596+ .top_write = dw_hdmi_top_write ,
597+ .dwc_read = dw_hdmi_dwc_read ,
598+ .dwc_write = dw_hdmi_dwc_write ,
599+ .cntl0_init = 0x0 ,
600+ .cntl1_init = PHY_CNTL1_INIT ,
618601};
619602
620603static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = {
621604 .top_read = dw_hdmi_g12a_top_read ,
622605 .top_write = dw_hdmi_g12a_top_write ,
623606 .dwc_read = dw_hdmi_g12a_dwc_read ,
624607 .dwc_write = dw_hdmi_g12a_dwc_write ,
608+ .cntl0_init = 0x000b4242 , /* Bandgap */
609+ .cntl1_init = PHY_CNTL1_INIT ,
625610};
626611
627612static void meson_dw_hdmi_init (struct meson_dw_hdmi * meson_dw_hdmi )
@@ -656,6 +641,13 @@ static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi)
656641 meson_dw_hdmi -> data -> top_write (meson_dw_hdmi ,
657642 HDMITX_TOP_CLK_CNTL , 0xff );
658643
644+ /* Enable normal output to PHY */
645+ meson_dw_hdmi -> data -> top_write (meson_dw_hdmi , HDMITX_TOP_BIST_CNTL , BIT (12 ));
646+
647+ /* Setup PHY */
648+ regmap_write (priv -> hhi , HHI_HDMI_PHY_CNTL1 , meson_dw_hdmi -> data -> cntl1_init );
649+ regmap_write (priv -> hhi , HHI_HDMI_PHY_CNTL0 , meson_dw_hdmi -> data -> cntl0_init );
650+
659651 /* Enable HDMI-TX Interrupt */
660652 meson_dw_hdmi -> data -> top_write (meson_dw_hdmi , HDMITX_TOP_INTR_STAT_CLR ,
661653 HDMITX_TOP_INTR_CORE );
@@ -865,11 +857,11 @@ static const struct dev_pm_ops meson_dw_hdmi_pm_ops = {
865857
866858static const struct of_device_id meson_dw_hdmi_of_table [] = {
867859 { .compatible = "amlogic,meson-gxbb-dw-hdmi" ,
868- .data = & meson_dw_hdmi_gx_data },
860+ .data = & meson_dw_hdmi_gxbb_data },
869861 { .compatible = "amlogic,meson-gxl-dw-hdmi" ,
870- .data = & meson_dw_hdmi_gx_data },
862+ .data = & meson_dw_hdmi_gxl_data },
871863 { .compatible = "amlogic,meson-gxm-dw-hdmi" ,
872- .data = & meson_dw_hdmi_gx_data },
864+ .data = & meson_dw_hdmi_gxl_data },
873865 { .compatible = "amlogic,meson-g12a-dw-hdmi" ,
874866 .data = & meson_dw_hdmi_g12a_data },
875867 { }
0 commit comments