@@ -648,6 +648,14 @@ static struct clk_bulk_data hdmitx_clks[] = {
648648 xlnx_hdmi_writel(hdmi, HDMI_TX_PIO_OUT_CLR,\
649649 HDMI_TX_PIO_OUT_BRIDGE_PIXEL)
650650
651+ #define xlnx_pioout_bridge_pixel_set (hdmi ) \
652+ xlnx_hdmi_writel(hdmi, HDMI_TX_PIO_OUT_SET,\
653+ HDMI_TX_PIO_OUT_BRIDGE_PIXEL)
654+
655+ #define xlnx_pioout_bridge_yuv_set (hdmi ) \
656+ xlnx_hdmi_writel(hdmi, HDMI_TX_PIO_OUT_SET,\
657+ HDMI_TX_PIO_OUT_BRIDGE_YUV420)
658+
651659#define xlnx_hdmi_auxintr_enable (hdmi ) \
652660 xlnx_hdmi_writel(hdmi, HDMI_TX_AUX_CTRL_SET,\
653661 HDMI_TX_AUD_CTRL_IE)
@@ -948,6 +956,16 @@ static void xlnx_hdmi_vtc_set_timing(struct xlnx_hdmi *hdmi,
948956 hdmi -> config .htiming_div_fact ;
949957 hsync_len = (mode -> hsync_end - mode -> hsync_start ) /
950958 hdmi -> config .htiming_div_fact ;
959+ if (hdmi -> xvidc_colorfmt == HDMI_TX_CSF_YCRCB_420 ) {
960+ if (hactive & 0x1 || hfront_porch & 0x1 ||
961+ hback_porch & 0x1 || hsync_len & 0x1 )
962+ dev_dbg (hdmi -> dev , "VTC does not support this timing\n" );
963+
964+ hactive = hactive / 2 ;
965+ hfront_porch = hfront_porch / 2 ;
966+ hback_porch = hback_porch / 2 ;
967+ hsync_len = hsync_len / 2 ;
968+ }
951969 htotal = hactive + hfront_porch + hsync_len + hback_porch ;
952970 hsync_start = hactive + hfront_porch ;
953971 hbackporch_start = hsync_start + hsync_len ;
@@ -2335,7 +2353,7 @@ static void xlnx_hdmi_piointr_handler(struct xlnx_hdmi *hdmi)
23352353 phy_cfg .hdmi .tx_params = 1 ;
23362354 phy_cfg .hdmi .ppc = hdmi -> config .ppc ;
23372355 phy_cfg .hdmi .bpc = hdmi -> config .bpc ;
2338- phy_cfg .hdmi .fmt = HDMI_TX_CSF_RGB ;
2356+ phy_cfg .hdmi .fmt = hdmi -> xvidc_colorfmt ;
23392357 phy_cfg .hdmi .tx_tmdsclk = hdmi -> tmds_clk ;
23402358 for (i = 0 ; i < HDMI_MAX_LANES ; i ++ ) {
23412359 ret = phy_configure (hdmi -> phy [i ], & phy_cfg );
@@ -2474,8 +2492,18 @@ static void xlnx_hdmi_piointr_handler(struct xlnx_hdmi *hdmi)
24742492
24752493 hdmi -> hdmi_stream_up = 1 ;
24762494
2477- xlnx_pioout_bridge_yuv_clr (hdmi );
2478- xlnx_pioout_bridge_pixel_clr (hdmi );
2495+ if (hdmi -> xvidc_colorfmt == HDMI_TX_CSF_YCRCB_420 ) {
2496+ xlnx_pioout_bridge_yuv_set (hdmi );
2497+ xlnx_pioout_bridge_pixel_clr (hdmi );
2498+ } else {
2499+ if (hdmi -> iframe .pixel_repeat ) {
2500+ xlnx_pioout_bridge_yuv_clr (hdmi );
2501+ xlnx_pioout_bridge_pixel_set (hdmi );
2502+ } else {
2503+ xlnx_pioout_bridge_yuv_clr (hdmi );
2504+ xlnx_pioout_bridge_pixel_clr (hdmi );
2505+ }
2506+ }
24792507 xlnx_hdmi_stream_start (hdmi );
24802508 xlnx_hdmi_clkratio (hdmi );
24812509 }
@@ -2937,6 +2965,17 @@ color_formats xlnx_hdmi_find_media_bus(struct xlnx_hdmi *hdmi,
29372965 }
29382966}
29392967
2968+ static u64 xlnx_hdmi_get_tmdsclk (struct xlnx_hdmi * hdmi , struct drm_display_mode * adjusted_mode )
2969+ {
2970+ u32 tmdsclk ;
2971+
2972+ tmdsclk = adjusted_mode -> clock * 1000 ;
2973+ if (hdmi -> xvidc_colorfmt == HDMI_TX_CSF_YCRCB_420 )
2974+ tmdsclk = tmdsclk >> 1 ;
2975+
2976+ return tmdsclk ;
2977+ }
2978+
29402979/**
29412980 * xlnx_hdmi_encoder_atomic_mode_set - drive the HDMI timing parameters
29422981 *
@@ -3025,7 +3064,7 @@ xlnx_hdmi_encoder_atomic_mode_set(struct drm_encoder *encoder,
30253064 dev_dbg (hdmi -> dev , "xvidc_colorfmt = %d\n" , hdmi -> xvidc_colorfmt );
30263065 dev_dbg (hdmi -> dev , "xvidc_colordepth = %d\n" , hdmi -> xvidc_colordepth );
30273066
3028- hdmi -> tmds_clk = adjusted_mode -> clock * 1000 ;
3067+ hdmi -> tmds_clk = xlnx_hdmi_get_tmdsclk ( hdmi , adjusted_mode ) ;
30293068 dev_dbg (hdmi -> dev , "tmds_clk = %u\n" , hdmi -> tmds_clk );
30303069
30313070 if (connector -> display_info .is_hdmi )
@@ -3090,7 +3129,7 @@ xlnx_hdmi_encoder_atomic_mode_set(struct drm_encoder *encoder,
30903129 xlnx_pioout_bridge_pixel_clr (hdmi );
30913130 }
30923131
3093- dev_dbg (hdmi -> dev , "mode->clock = %u Hz\n" , adjusted_mode -> clock );
3132+ dev_dbg (hdmi -> dev , "tmds_clk = %u Hz\n" , hdmi -> tmds_clk );
30943133
30953134 hdmi -> wait_for_streamup = 0 ;
30963135 wait_event_timeout (hdmi -> wait_event , hdmi -> wait_for_streamup ,
0 commit comments