@@ -370,7 +370,7 @@ int dcp_get_connector_type(struct platform_device *pdev)
370370}
371371EXPORT_SYMBOL_GPL (dcp_get_connector_type );
372372
373- #define DPTX_CONNECT_TIMEOUT msecs_to_jiffies(1000 )
373+ #define DPTX_CONNECT_TIMEOUT msecs_to_jiffies(2000 )
374374
375375static int dcp_dptx_connect (struct apple_dcp * dcp , u32 port )
376376{
@@ -410,24 +410,16 @@ static int dcp_dptx_connect(struct apple_dcp *dcp, u32 port)
410410
411411 usleep_range (5 , 10 );
412412
413+ if (dcp -> connector_type == DRM_MODE_CONNECTOR_DisplayPort )
414+ dptxport_set_hpd (dcp -> dptxport [port ].service , true);
415+
413416 return 0 ;
414417
415418out_unlock :
416419 mutex_unlock (& dcp -> hpd_mutex );
417420 return ret ;
418421}
419422
420- int dcp_dptx_connect_oob (struct platform_device * pdev , u32 port )
421- {
422- struct apple_dcp * dcp = platform_get_drvdata (pdev );
423- int err = dcp_dptx_connect (dcp , port );
424- if (err < 0 )
425- return err ;
426- dptxport_set_hpd (dcp -> dptxport [port ].service , true);
427- return 0 ;
428- }
429- EXPORT_SYMBOL_GPL (dcp_dptx_connect_oob );
430-
431423static int dcp_dptx_disconnect (struct apple_dcp * dcp , u32 port )
432424{
433425 dev_info (dcp -> dev , "%s(port=%d)\n" , __func__ , port );
@@ -442,11 +434,69 @@ static int dcp_dptx_disconnect(struct apple_dcp *dcp, u32 port)
442434 return 0 ;
443435}
444436
437+ static void dcp_deferred_hpd_work (struct work_struct * work )
438+ {
439+ struct apple_dcp * dcp = container_of (to_delayed_work (work ), struct apple_dcp , hpd_wq );
440+ int err ;
441+
442+ guard (mutex )(& dcp -> hpd_deferred_mutex );
443+ dev_info (dcp -> dev , "%s\n" , __func__ );
444+
445+ switch (dcp -> hpd .state ) {
446+ case DCP_HPD_OOB_CONNECTED :
447+ err = dcp_dptx_connect (dcp , dcp -> hpd .port );
448+ if (err < 0 )
449+ dev_warn (dcp -> dev , "OOB HPD connect failed:%d\n" , err );
450+ break ;
451+ case DCP_HPD_OOB_DISCONNECTED :
452+ dptxport_set_hpd (dcp -> dptxport [dcp -> hpd .port ].service , false);
453+ err = dcp_dptx_disconnect (dcp , dcp -> hpd .port );
454+ if (err < 0 )
455+ dev_warn (dcp -> dev , "OOB HPD disconnect failed:%d\n" , err );
456+ break ;
457+ default :
458+ return ;
459+ }
460+ }
461+
462+ static int dcp_dptx_schedule_hdp_work (struct apple_dcp * dcp ,
463+ enum dcp_hdp_state state , u32 port )
464+ {
465+ guard (mutex )(& dcp -> hpd_deferred_mutex );
466+ dcp -> hpd .port = port ;
467+ dcp -> hpd .state = state ;
468+
469+ if (state == DCP_HPD_OOB_CONNECTED )
470+ {
471+ guard (mutex )(& dcp -> hpd_mutex );
472+ if (dcp -> dptxport [port ].connected )
473+ return 0 ;
474+
475+ if (delayed_work_pending (& dcp -> hpd_wq ))
476+ timer_reduce (& dcp -> hpd_wq .timer , msecs_to_jiffies (100 ));
477+ else
478+ schedule_delayed_work (& dcp -> hpd_wq , msecs_to_jiffies (2000 ));
479+ } else {
480+ if (!delayed_work_pending (& dcp -> hpd_wq ))
481+ schedule_delayed_work (& dcp -> hpd_wq , msecs_to_jiffies (25 ));
482+ }
483+
484+ return 0 ;
485+ }
486+
487+ int dcp_dptx_connect_oob (struct platform_device * pdev , u32 port )
488+ {
489+ struct apple_dcp * dcp = platform_get_drvdata (pdev );
490+
491+ return dcp_dptx_schedule_hdp_work (dcp , DCP_HPD_OOB_CONNECTED , port );
492+ }
493+ EXPORT_SYMBOL_GPL (dcp_dptx_connect_oob );
494+
445495int dcp_dptx_disconnect_oob (struct platform_device * pdev , u32 port )
446496{
447497 struct apple_dcp * dcp = platform_get_drvdata (pdev );
448- dptxport_set_hpd ( dcp -> dptxport [ port ]. service , false);
449- return dcp_dptx_disconnect (dcp , port );
498+
499+ return dcp_dptx_schedule_hdp_work (dcp , DCP_HPD_OOB_DISCONNECTED , port );
450500}
451501EXPORT_SYMBOL_GPL (dcp_dptx_disconnect_oob );
452502
@@ -971,6 +1021,8 @@ static int dcp_comp_bind(struct device *dev, struct device *main, void *data)
9711021 dev_info (dev , "DCP index:%u dptx target phy: %u dptx die: %u\n" ,
9721022 dcp -> index , dcp -> dptx_phy , dcp -> dptx_die );
9731023 mutex_init (& dcp -> hpd_mutex );
1024+ mutex_init (& dcp -> hpd_deferred_mutex );
1025+ INIT_DELAYED_WORK (& dcp -> hpd_wq , dcp_deferred_hpd_work );
9741026
9751027 if (!show_notch )
9761028 ret = of_property_read_u32 (dev -> of_node , "apple,notch-height" ,
@@ -1114,6 +1166,7 @@ static void dcp_comp_unbind(struct device *dev, struct device *main, void *data)
11141166 cancel_work_sync (& dcp -> bl_update_wq );
11151167 }
11161168 cancel_work_sync (& dcp -> vblank_wq );
1169+ cancel_delayed_work_sync (& dcp -> hpd_wq );
11171170
11181171 devm_clk_put (dev , dcp -> clk );
11191172 dcp -> clk = NULL ;
0 commit comments