@@ -99,6 +99,7 @@ struct hdmi_vmode {
99
99
unsigned int mpixelclock ;
100
100
unsigned int mpixelrepetitioninput ;
101
101
unsigned int mpixelrepetitionoutput ;
102
+ unsigned int mtmdsclock ;
102
103
};
103
104
104
105
struct hdmi_data_info {
@@ -543,7 +544,7 @@ static void hdmi_init_clk_regenerator(struct dw_hdmi *hdmi)
543
544
static void hdmi_clk_regenerator_update_pixel_clock (struct dw_hdmi * hdmi )
544
545
{
545
546
mutex_lock (& hdmi -> audio_mutex );
546
- hdmi_set_clk_regenerator (hdmi , hdmi -> hdmi_data .video_mode .mpixelclock ,
547
+ hdmi_set_clk_regenerator (hdmi , hdmi -> hdmi_data .video_mode .mtmdsclock ,
547
548
hdmi -> sample_rate );
548
549
mutex_unlock (& hdmi -> audio_mutex );
549
550
}
@@ -552,7 +553,7 @@ void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate)
552
553
{
553
554
mutex_lock (& hdmi -> audio_mutex );
554
555
hdmi -> sample_rate = rate ;
555
- hdmi_set_clk_regenerator (hdmi , hdmi -> hdmi_data .video_mode .mpixelclock ,
556
+ hdmi_set_clk_regenerator (hdmi , hdmi -> hdmi_data .video_mode .mtmdsclock ,
556
557
hdmi -> sample_rate );
557
558
mutex_unlock (& hdmi -> audio_mutex );
558
559
}
@@ -653,6 +654,20 @@ static bool hdmi_bus_fmt_is_yuv422(unsigned int bus_format)
653
654
}
654
655
}
655
656
657
+ static bool hdmi_bus_fmt_is_yuv420 (unsigned int bus_format )
658
+ {
659
+ switch (bus_format ) {
660
+ case MEDIA_BUS_FMT_UYYVYY8_0_5X24 :
661
+ case MEDIA_BUS_FMT_UYYVYY10_0_5X30 :
662
+ case MEDIA_BUS_FMT_UYYVYY12_0_5X36 :
663
+ case MEDIA_BUS_FMT_UYYVYY16_0_5X48 :
664
+ return true;
665
+
666
+ default :
667
+ return false;
668
+ }
669
+ }
670
+
656
671
static int hdmi_bus_fmt_color_depth (unsigned int bus_format )
657
672
{
658
673
switch (bus_format ) {
@@ -882,7 +897,8 @@ static void hdmi_video_packetize(struct dw_hdmi *hdmi)
882
897
u8 val , vp_conf ;
883
898
884
899
if (hdmi_bus_fmt_is_rgb (hdmi -> hdmi_data .enc_out_bus_format ) ||
885
- hdmi_bus_fmt_is_yuv444 (hdmi -> hdmi_data .enc_out_bus_format )) {
900
+ hdmi_bus_fmt_is_yuv444 (hdmi -> hdmi_data .enc_out_bus_format ) ||
901
+ hdmi_bus_fmt_is_yuv420 (hdmi -> hdmi_data .enc_out_bus_format )) {
886
902
switch (hdmi_bus_fmt_color_depth (
887
903
hdmi -> hdmi_data .enc_out_bus_format )) {
888
904
case 8 :
@@ -1036,7 +1052,7 @@ EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_write);
1036
1052
*/
1037
1053
void dw_hdmi_set_high_tmds_clock_ratio (struct dw_hdmi * hdmi )
1038
1054
{
1039
- unsigned long mtmdsclock = hdmi -> hdmi_data .video_mode .mpixelclock ;
1055
+ unsigned long mtmdsclock = hdmi -> hdmi_data .video_mode .mtmdsclock ;
1040
1056
1041
1057
/* Control for TMDS Bit Period/TMDS Clock-Period Ratio */
1042
1058
if (hdmi -> connector .display_info .hdmi .scdc .supported ) {
@@ -1198,6 +1214,8 @@ static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi,
1198
1214
const struct dw_hdmi_curr_ctrl * curr_ctrl = pdata -> cur_ctr ;
1199
1215
const struct dw_hdmi_phy_config * phy_config = pdata -> phy_config ;
1200
1216
1217
+ /* TOFIX Will need 420 specific PHY configuration tables */
1218
+
1201
1219
/* PLL/MPLL Cfg - always match on final entry */
1202
1220
for (; mpll_config -> mpixelclock != ~0UL ; mpll_config ++ )
1203
1221
if (mpixelclock <= mpll_config -> mpixelclock )
@@ -1245,6 +1263,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
1245
1263
const struct dw_hdmi_phy_data * phy = hdmi -> phy .data ;
1246
1264
const struct dw_hdmi_plat_data * pdata = hdmi -> plat_data ;
1247
1265
unsigned long mpixelclock = hdmi -> hdmi_data .video_mode .mpixelclock ;
1266
+ unsigned long mtmdsclock = hdmi -> hdmi_data .video_mode .mtmdsclock ;
1248
1267
int ret ;
1249
1268
1250
1269
dw_hdmi_phy_power_off (hdmi );
@@ -1273,7 +1292,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
1273
1292
}
1274
1293
1275
1294
/* Wait for resuming transmission of TMDS clock and data */
1276
- if (mpixelclock > HDMI14_MAX_TMDSCLK )
1295
+ if (mtmdsclock > HDMI14_MAX_TMDSCLK )
1277
1296
msleep (100 );
1278
1297
1279
1298
return dw_hdmi_phy_power_on (hdmi );
@@ -1390,6 +1409,8 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
1390
1409
frame .colorspace = HDMI_COLORSPACE_YUV444 ;
1391
1410
else if (hdmi_bus_fmt_is_yuv422 (hdmi -> hdmi_data .enc_out_bus_format ))
1392
1411
frame .colorspace = HDMI_COLORSPACE_YUV422 ;
1412
+ else if (hdmi_bus_fmt_is_yuv420 (hdmi -> hdmi_data .enc_out_bus_format ))
1413
+ frame .colorspace = HDMI_COLORSPACE_YUV420 ;
1393
1414
else
1394
1415
frame .colorspace = HDMI_COLORSPACE_RGB ;
1395
1416
@@ -1547,15 +1568,18 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
1547
1568
struct drm_hdmi_info * hdmi_info = & hdmi -> connector .display_info .hdmi ;
1548
1569
struct hdmi_vmode * vmode = & hdmi -> hdmi_data .video_mode ;
1549
1570
int hblank , vblank , h_de_hs , v_de_vs , hsync_len , vsync_len ;
1550
- unsigned int vdisplay ;
1571
+ unsigned int vdisplay , hdisplay ;
1551
1572
1552
- vmode -> mpixelclock = mode -> clock * 1000 ;
1573
+ vmode -> mtmdsclock = vmode -> mpixelclock = mode -> clock * 1000 ;
1553
1574
1554
1575
dev_dbg (hdmi -> dev , "final pixclk = %d\n" , vmode -> mpixelclock );
1555
1576
1577
+ if (hdmi_bus_fmt_is_yuv420 (hdmi -> hdmi_data .enc_out_bus_format ))
1578
+ vmode -> mtmdsclock /= 2 ;
1579
+
1556
1580
/* Set up HDMI_FC_INVIDCONF */
1557
1581
inv_val = (hdmi -> hdmi_data .hdcp_enable ||
1558
- vmode -> mpixelclock > HDMI14_MAX_TMDSCLK ||
1582
+ vmode -> mtmdsclock > HDMI14_MAX_TMDSCLK ||
1559
1583
hdmi_info -> scdc .scrambling .low_rates ?
1560
1584
HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
1561
1585
HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE );
@@ -1589,6 +1613,22 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
1589
1613
1590
1614
hdmi_writeb (hdmi , inv_val , HDMI_FC_INVIDCONF );
1591
1615
1616
+ hdisplay = mode -> hdisplay ;
1617
+ hblank = mode -> htotal - mode -> hdisplay ;
1618
+ h_de_hs = mode -> hsync_start - mode -> hdisplay ;
1619
+ hsync_len = mode -> hsync_end - mode -> hsync_start ;
1620
+
1621
+ /*
1622
+ * When we're setting a YCbCr420 mode, we need
1623
+ * to adjust the horizontal timing to suit.
1624
+ */
1625
+ if (hdmi_bus_fmt_is_yuv420 (hdmi -> hdmi_data .enc_out_bus_format )) {
1626
+ hdisplay /= 2 ;
1627
+ hblank /= 2 ;
1628
+ h_de_hs /= 2 ;
1629
+ hsync_len /= 2 ;
1630
+ }
1631
+
1592
1632
vdisplay = mode -> vdisplay ;
1593
1633
vblank = mode -> vtotal - mode -> vdisplay ;
1594
1634
v_de_vs = mode -> vsync_start - mode -> vdisplay ;
@@ -1607,7 +1647,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
1607
1647
1608
1648
/* Scrambling Control */
1609
1649
if (hdmi_info -> scdc .supported ) {
1610
- if (vmode -> mpixelclock > HDMI14_MAX_TMDSCLK ||
1650
+ if (vmode -> mtmdsclock > HDMI14_MAX_TMDSCLK ||
1611
1651
hdmi_info -> scdc .scrambling .low_rates ) {
1612
1652
/*
1613
1653
* HDMI2.0 Specifies the following procedure:
@@ -1645,31 +1685,28 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
1645
1685
}
1646
1686
1647
1687
/* Set up horizontal active pixel width */
1648
- hdmi_writeb (hdmi , mode -> hdisplay >> 8 , HDMI_FC_INHACTV1 );
1649
- hdmi_writeb (hdmi , mode -> hdisplay , HDMI_FC_INHACTV0 );
1688
+ hdmi_writeb (hdmi , hdisplay >> 8 , HDMI_FC_INHACTV1 );
1689
+ hdmi_writeb (hdmi , hdisplay , HDMI_FC_INHACTV0 );
1650
1690
1651
1691
/* Set up vertical active lines */
1652
1692
hdmi_writeb (hdmi , vdisplay >> 8 , HDMI_FC_INVACTV1 );
1653
1693
hdmi_writeb (hdmi , vdisplay , HDMI_FC_INVACTV0 );
1654
1694
1655
1695
/* Set up horizontal blanking pixel region width */
1656
- hblank = mode -> htotal - mode -> hdisplay ;
1657
1696
hdmi_writeb (hdmi , hblank >> 8 , HDMI_FC_INHBLANK1 );
1658
1697
hdmi_writeb (hdmi , hblank , HDMI_FC_INHBLANK0 );
1659
1698
1660
1699
/* Set up vertical blanking pixel region width */
1661
1700
hdmi_writeb (hdmi , vblank , HDMI_FC_INVBLANK );
1662
1701
1663
1702
/* Set up HSYNC active edge delay width (in pixel clks) */
1664
- h_de_hs = mode -> hsync_start - mode -> hdisplay ;
1665
1703
hdmi_writeb (hdmi , h_de_hs >> 8 , HDMI_FC_HSYNCINDELAY1 );
1666
1704
hdmi_writeb (hdmi , h_de_hs , HDMI_FC_HSYNCINDELAY0 );
1667
1705
1668
1706
/* Set up VSYNC active edge delay (in lines) */
1669
1707
hdmi_writeb (hdmi , v_de_vs , HDMI_FC_VSYNCINDELAY );
1670
1708
1671
1709
/* Set up HSYNC active pulse width (in pixel clks) */
1672
- hsync_len = mode -> hsync_end - mode -> hsync_start ;
1673
1710
hdmi_writeb (hdmi , hsync_len >> 8 , HDMI_FC_HSYNCINWIDTH1 );
1674
1711
hdmi_writeb (hdmi , hsync_len , HDMI_FC_HSYNCINWIDTH0 );
1675
1712
0 commit comments