@@ -162,6 +162,7 @@ struct hdmi_data_info {
162162 unsigned int enc_out_encoding ;
163163 unsigned int pix_repet_factor ;
164164 struct hdmi_vmode video_mode ;
165+ bool update ;
165166};
166167
167168struct dw_hdmi_i2c {
@@ -2152,6 +2153,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
21522153{
21532154 int ret ;
21542155 void * data = hdmi -> plat_data -> phy_data ;
2156+ bool need_delay = false;
21552157
21562158 hdmi_disable_overflow_interrupts (hdmi );
21572159
@@ -2234,6 +2236,8 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
22342236 if (ret )
22352237 return ret ;
22362238 hdmi -> phy .enabled = true;
2239+ } else {
2240+ need_delay = true;
22372241 }
22382242 /* HDMI Initialization Step B.3 */
22392243 dw_hdmi_enable_video_path (hdmi );
@@ -2266,6 +2270,9 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
22662270 if (hdmi -> cable_plugin && hdmi -> sink_is_hdmi )
22672271 hdmi_enable_overflow_interrupts (hdmi );
22682272
2273+ /* XXX: Add delay to make csc work before unmute video. */
2274+ if (need_delay )
2275+ msleep (50 );
22692276 return 0 ;
22702277}
22712278
@@ -2519,13 +2526,12 @@ static void dw_hdmi_connector_destroy(struct drm_connector *connector)
25192526}
25202527
25212528static void
2522- dw_hdmi_connector_atomic_flush (struct drm_connector * connector ,
2529+ dw_hdmi_connector_atomic_begin (struct drm_connector * connector ,
25232530 struct drm_connector_state * conn_state )
25242531{
25252532 struct dw_hdmi * hdmi = container_of (connector , struct dw_hdmi ,
2526- connector );
2533+ connector );
25272534 void * data = hdmi -> plat_data -> phy_data ;
2528- struct drm_display_mode * mode = NULL ;
25292535 unsigned int enc_in_bus_format ;
25302536 unsigned int enc_out_bus_format ;
25312537 unsigned int enc_in_encoding ;
@@ -2534,21 +2540,8 @@ dw_hdmi_connector_atomic_flush(struct drm_connector *connector,
25342540 if (!hdmi -> hpd_state || !conn_state -> crtc )
25352541 return ;
25362542
2537- DRM_DEBUG ("%s\n" , __func__ );
2538-
2539- /*
2540- * If HDMI is enabled in uboot, it's need to record
2541- * drm_display_mode and set phy status to enabled.
2542- */
2543- if (!hdmi -> hdmi_data .video_mode .mpixelclock ) {
2544- mode = & conn_state -> crtc -> mode ;
2545- memcpy (& hdmi -> previous_mode , mode , sizeof (hdmi -> previous_mode ));
2546- hdmi -> hdmi_data .video_mode .mpixelclock = mode -> clock ;
2547- hdmi -> hdmi_data .video_mode .previous_pixelclock = mode -> clock ;
2548- hdmi -> hdmi_data .video_mode .previous_tmdsclock = mode -> clock ;
2549- hdmi -> phy .enabled = true;
2543+ if (!hdmi -> hdmi_data .video_mode .mpixelclock )
25502544 return ;
2551- }
25522545
25532546 if (hdmi -> plat_data -> get_enc_in_encoding )
25542547 enc_in_encoding = hdmi -> plat_data -> get_enc_in_encoding (data );
@@ -2572,10 +2565,51 @@ dw_hdmi_connector_atomic_flush(struct drm_connector *connector,
25722565 if (enc_in_encoding != hdmi -> hdmi_data .enc_in_encoding ||
25732566 enc_out_encoding != hdmi -> hdmi_data .enc_out_encoding ||
25742567 enc_in_bus_format != hdmi -> hdmi_data .enc_in_bus_format ||
2575- enc_out_bus_format != hdmi -> hdmi_data .enc_out_bus_format )
2568+ enc_out_bus_format != hdmi -> hdmi_data .enc_out_bus_format ) {
2569+ hdmi -> hdmi_data .update = true;
2570+ hdmi_writeb (hdmi , HDMI_FC_GCP_SET_AVMUTE , HDMI_FC_GCP );
2571+ /* XXX: Add delay to make av mute work on sink*/
2572+ msleep (50 );
2573+ } else {
2574+ hdmi -> hdmi_data .update = false;
2575+ }
2576+ }
2577+
2578+ static void
2579+ dw_hdmi_connector_atomic_flush (struct drm_connector * connector ,
2580+ struct drm_connector_state * conn_state )
2581+ {
2582+ struct dw_hdmi * hdmi = container_of (connector , struct dw_hdmi ,
2583+ connector );
2584+ struct drm_display_mode * mode = NULL ;
2585+
2586+ if (!hdmi -> hpd_state || !conn_state -> crtc )
2587+ return ;
2588+
2589+ DRM_DEBUG ("%s\n" , __func__ );
2590+
2591+ /*
2592+ * If HDMI is enabled in uboot, it's need to record
2593+ * drm_display_mode and set phy status to enabled.
2594+ */
2595+ if (!hdmi -> hdmi_data .video_mode .mpixelclock ) {
2596+ mode = & conn_state -> crtc -> mode ;
2597+ memcpy (& hdmi -> previous_mode , mode , sizeof (hdmi -> previous_mode ));
2598+ hdmi -> hdmi_data .video_mode .mpixelclock = mode -> clock ;
2599+ hdmi -> hdmi_data .video_mode .previous_pixelclock = mode -> clock ;
2600+ hdmi -> hdmi_data .video_mode .previous_tmdsclock = mode -> clock ;
2601+ hdmi -> phy .enabled = true;
2602+ return ;
2603+ }
2604+
2605+ if (hdmi -> hdmi_data .update ) {
25762606 dw_hdmi_setup (hdmi , & hdmi -> previous_mode );
2577- else if (connector -> state -> hdr_metadata_changed && hdmi -> sink_is_hdmi )
2607+ hdmi_writeb (hdmi , HDMI_FC_GCP_CLEAR_AVMUTE , HDMI_FC_GCP );
2608+ hdmi -> hdmi_data .update = false;
2609+ } else if (connector -> state -> hdr_metadata_changed &&
2610+ hdmi -> sink_is_hdmi ) {
25782611 hdmi_config_hdr_infoframe (hdmi );
2612+ }
25792613}
25802614
25812615static int
@@ -2668,6 +2702,7 @@ static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs =
26682702 .get_modes = dw_hdmi_connector_get_modes ,
26692703 .mode_valid = dw_hdmi_connector_mode_valid ,
26702704 .best_encoder = dw_hdmi_connector_best_encoder ,
2705+ .atomic_begin = dw_hdmi_connector_atomic_begin ,
26712706 .atomic_flush = dw_hdmi_connector_atomic_flush ,
26722707};
26732708
0 commit comments