@@ -102,6 +102,8 @@ struct dp_display_private {
102102 struct dp_display_mode dp_mode ;
103103 struct msm_dp dp_display ;
104104
105+ bool encoder_mode_set ;
106+
105107 /* wait for audio signaling */
106108 struct completion audio_comp ;
107109
@@ -279,13 +281,24 @@ static void dp_display_send_hpd_event(struct msm_dp *dp_display)
279281 drm_helper_hpd_irq_event (connector -> dev );
280282}
281283
282- static int dp_display_send_hpd_notification ( struct dp_display_private * dp ,
283- bool hpd )
284+
285+ static void dp_display_set_encoder_mode ( struct dp_display_private * dp )
284286{
285- static bool encoder_mode_set ;
286287 struct msm_drm_private * priv = dp -> dp_display .drm_dev -> dev_private ;
287288 struct msm_kms * kms = priv -> kms ;
288289
290+ if (!dp -> encoder_mode_set && dp -> dp_display .encoder &&
291+ kms -> funcs -> set_encoder_mode ) {
292+ kms -> funcs -> set_encoder_mode (kms ,
293+ dp -> dp_display .encoder , false);
294+
295+ dp -> encoder_mode_set = true;
296+ }
297+ }
298+
299+ static int dp_display_send_hpd_notification (struct dp_display_private * dp ,
300+ bool hpd )
301+ {
289302 if ((hpd && dp -> dp_display .is_connected ) ||
290303 (!hpd && !dp -> dp_display .is_connected )) {
291304 DRM_DEBUG_DP ("HPD already %s\n" , (hpd ? "on" : "off" ));
@@ -298,15 +311,6 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp,
298311
299312 dp -> dp_display .is_connected = hpd ;
300313
301- if (dp -> dp_display .is_connected && dp -> dp_display .encoder
302- && !encoder_mode_set
303- && kms -> funcs -> set_encoder_mode ) {
304- kms -> funcs -> set_encoder_mode (kms ,
305- dp -> dp_display .encoder , false);
306- DRM_DEBUG_DP ("set_encoder_mode() Completed\n" );
307- encoder_mode_set = true;
308- }
309-
310314 dp_display_send_hpd_event (& dp -> dp_display );
311315
312316 return 0 ;
@@ -342,7 +346,6 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
342346
343347 dp_add_event (dp , EV_USER_NOTIFICATION , true, 0 );
344348
345-
346349end :
347350 return rc ;
348351}
@@ -359,6 +362,8 @@ static void dp_display_host_init(struct dp_display_private *dp)
359362 if (dp -> usbpd -> orientation == ORIENTATION_CC2 )
360363 flip = true;
361364
365+ dp_display_set_encoder_mode (dp );
366+
362367 dp_power_init (dp -> power , flip );
363368 dp_ctrl_host_init (dp -> ctrl , flip );
364369 dp_aux_init (dp -> aux );
@@ -442,24 +447,42 @@ static void dp_display_handle_video_request(struct dp_display_private *dp)
442447 }
443448}
444449
445- static int dp_display_handle_irq_hpd (struct dp_display_private * dp )
450+ static int dp_display_handle_port_ststus_changed (struct dp_display_private * dp )
446451{
447- u32 sink_request ;
448-
449- sink_request = dp -> link -> sink_request ;
452+ int rc = 0 ;
450453
451- if (sink_request & DS_PORT_STATUS_CHANGED ) {
452- if (dp_display_is_sink_count_zero (dp )) {
453- DRM_DEBUG_DP ("sink count is zero, nothing to do\n" );
454- return - ENOTCONN ;
454+ if (dp_display_is_sink_count_zero (dp )) {
455+ DRM_DEBUG_DP ("sink count is zero, nothing to do\n" );
456+ if (dp -> hpd_state != ST_DISCONNECTED ) {
457+ dp -> hpd_state = ST_DISCONNECT_PENDING ;
458+ dp_add_event (dp , EV_USER_NOTIFICATION , false, 0 );
459+ }
460+ } else {
461+ if (dp -> hpd_state == ST_DISCONNECTED ) {
462+ dp -> hpd_state = ST_CONNECT_PENDING ;
463+ rc = dp_display_process_hpd_high (dp );
464+ if (rc )
465+ dp -> hpd_state = ST_DISCONNECTED ;
455466 }
467+ }
468+
469+ return rc ;
470+ }
471+
472+ static int dp_display_handle_irq_hpd (struct dp_display_private * dp )
473+ {
474+ u32 sink_request = dp -> link -> sink_request ;
456475
457- return dp_display_process_hpd_high (dp );
476+ if (dp -> hpd_state == ST_DISCONNECTED ) {
477+ if (sink_request & DP_LINK_STATUS_UPDATED ) {
478+ DRM_ERROR ("Disconnected, no DP_LINK_STATUS_UPDATED\n" );
479+ return - EINVAL ;
480+ }
458481 }
459482
460483 dp_ctrl_handle_sink_request (dp -> ctrl );
461484
462- if (dp -> link -> sink_request & DP_TEST_LINK_VIDEO_PATTERN )
485+ if (sink_request & DP_TEST_LINK_VIDEO_PATTERN )
463486 dp_display_handle_video_request (dp );
464487
465488 return 0 ;
@@ -490,19 +513,10 @@ static int dp_display_usbpd_attention_cb(struct device *dev)
490513 rc = dp_link_process_request (dp -> link );
491514 if (!rc ) {
492515 sink_request = dp -> link -> sink_request ;
493- if (sink_request & DS_PORT_STATUS_CHANGED ) {
494- /* same as unplugged */
495- hpd -> hpd_high = 0 ;
496- dp -> hpd_state = ST_DISCONNECT_PENDING ;
497- dp_add_event (dp , EV_USER_NOTIFICATION , false, 0 );
498- }
499-
500- rc = dp_display_handle_irq_hpd (dp );
501-
502- if (!rc && (sink_request & DS_PORT_STATUS_CHANGED )) {
503- hpd -> hpd_high = 1 ;
504- dp -> hpd_state = ST_CONNECT_PENDING ;
505- }
516+ if (sink_request & DS_PORT_STATUS_CHANGED )
517+ rc = dp_display_handle_port_ststus_changed (dp );
518+ else
519+ rc = dp_display_handle_irq_hpd (dp );
506520 }
507521
508522 return rc ;
@@ -668,6 +682,7 @@ static int dp_disconnect_pending_timeout(struct dp_display_private *dp, u32 data
668682static int dp_irq_hpd_handle (struct dp_display_private * dp , u32 data )
669683{
670684 u32 state ;
685+ int ret ;
671686
672687 mutex_lock (& dp -> event_mutex );
673688
@@ -678,7 +693,10 @@ static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data)
678693 return 0 ;
679694 }
680695
681- dp_display_usbpd_attention_cb (& dp -> pdev -> dev );
696+ ret = dp_display_usbpd_attention_cb (& dp -> pdev -> dev );
697+ if (ret == - ECONNRESET ) { /* cable unplugged */
698+ dp -> core_initialized = false;
699+ }
682700
683701 mutex_unlock (& dp -> event_mutex );
684702
0 commit comments