106
106
#define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 */
107
107
#define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 */
108
108
#define HHI_HDMI_PHY_CNTL1 0x3a4 /* 0xe9 */
109
+ #define PHY_CNTL1_INIT 0x03900000
110
+ #define PHY_INVERT BIT(17)
109
111
#define HHI_HDMI_PHY_CNTL2 0x3a8 /* 0xea */
110
112
#define HHI_HDMI_PHY_CNTL3 0x3ac /* 0xeb */
111
113
#define HHI_HDMI_PHY_CNTL4 0x3b0 /* 0xec */
@@ -130,6 +132,8 @@ struct meson_dw_hdmi_data {
130
132
unsigned int addr );
131
133
void (* dwc_write )(struct meson_dw_hdmi * dw_hdmi ,
132
134
unsigned int addr , unsigned int data );
135
+ u32 cntl0_init ;
136
+ u32 cntl1_init ;
133
137
};
134
138
135
139
struct meson_dw_hdmi {
@@ -384,26 +388,6 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
384
388
dw_hdmi_bus_fmt_is_420 (hdmi ))
385
389
mode_is_420 = true;
386
390
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
-
407
391
/* TMDS pattern setup */
408
392
if (mode -> clock > 340000 && !mode_is_420 ) {
409
393
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,
425
409
/* Setup PHY parameters */
426
410
meson_hdmi_phy_setup_mode (dw_hdmi , mode , mode_is_420 );
427
411
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
-
442
412
/* Disable clock, fifo, fifo_wr */
443
413
regmap_update_bits (priv -> hhi , HHI_HDMI_PHY_CNTL1 , 0xf , 0 );
444
414
@@ -492,7 +462,9 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi,
492
462
493
463
DRM_DEBUG_DRIVER ("\n" );
494
464
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 );
496
468
}
497
469
498
470
static 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 = {
610
582
.fast_io = true,
611
583
};
612
584
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 = {
614
586
.top_read = dw_hdmi_top_read ,
615
587
.top_write = dw_hdmi_top_write ,
616
588
.dwc_read = dw_hdmi_dwc_read ,
617
589
.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 ,
618
601
};
619
602
620
603
static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = {
621
604
.top_read = dw_hdmi_g12a_top_read ,
622
605
.top_write = dw_hdmi_g12a_top_write ,
623
606
.dwc_read = dw_hdmi_g12a_dwc_read ,
624
607
.dwc_write = dw_hdmi_g12a_dwc_write ,
608
+ .cntl0_init = 0x000b4242 , /* Bandgap */
609
+ .cntl1_init = PHY_CNTL1_INIT ,
625
610
};
626
611
627
612
static 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)
656
641
meson_dw_hdmi -> data -> top_write (meson_dw_hdmi ,
657
642
HDMITX_TOP_CLK_CNTL , 0xff );
658
643
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
+
659
651
/* Enable HDMI-TX Interrupt */
660
652
meson_dw_hdmi -> data -> top_write (meson_dw_hdmi , HDMITX_TOP_INTR_STAT_CLR ,
661
653
HDMITX_TOP_INTR_CORE );
@@ -865,11 +857,11 @@ static const struct dev_pm_ops meson_dw_hdmi_pm_ops = {
865
857
866
858
static const struct of_device_id meson_dw_hdmi_of_table [] = {
867
859
{ .compatible = "amlogic,meson-gxbb-dw-hdmi" ,
868
- .data = & meson_dw_hdmi_gx_data },
860
+ .data = & meson_dw_hdmi_gxbb_data },
869
861
{ .compatible = "amlogic,meson-gxl-dw-hdmi" ,
870
- .data = & meson_dw_hdmi_gx_data },
862
+ .data = & meson_dw_hdmi_gxl_data },
871
863
{ .compatible = "amlogic,meson-gxm-dw-hdmi" ,
872
- .data = & meson_dw_hdmi_gx_data },
864
+ .data = & meson_dw_hdmi_gxl_data },
873
865
{ .compatible = "amlogic,meson-g12a-dw-hdmi" ,
874
866
.data = & meson_dw_hdmi_g12a_data },
875
867
{ }
0 commit comments