@@ -641,6 +641,87 @@ amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state,
641
641
return NULL ;
642
642
}
643
643
644
+ static void emulated_link_detect (struct dc_link * link )
645
+ {
646
+ struct dc_sink_init_data sink_init_data = { 0 };
647
+ struct display_sink_capability sink_caps = { 0 };
648
+ enum dc_edid_status edid_status ;
649
+ struct dc_context * dc_ctx = link -> ctx ;
650
+ struct dc_sink * sink = NULL ;
651
+ struct dc_sink * prev_sink = NULL ;
652
+
653
+ link -> type = dc_connection_none ;
654
+ prev_sink = link -> local_sink ;
655
+
656
+ if (prev_sink != NULL )
657
+ dc_sink_retain (prev_sink );
658
+
659
+ switch (link -> connector_signal ) {
660
+ case SIGNAL_TYPE_HDMI_TYPE_A : {
661
+ sink_caps .transaction_type = DDC_TRANSACTION_TYPE_I2C ;
662
+ sink_caps .signal = SIGNAL_TYPE_HDMI_TYPE_A ;
663
+ break ;
664
+ }
665
+
666
+ case SIGNAL_TYPE_DVI_SINGLE_LINK : {
667
+ sink_caps .transaction_type = DDC_TRANSACTION_TYPE_I2C ;
668
+ sink_caps .signal = SIGNAL_TYPE_DVI_SINGLE_LINK ;
669
+ break ;
670
+ }
671
+
672
+ case SIGNAL_TYPE_DVI_DUAL_LINK : {
673
+ sink_caps .transaction_type = DDC_TRANSACTION_TYPE_I2C ;
674
+ sink_caps .signal = SIGNAL_TYPE_DVI_DUAL_LINK ;
675
+ break ;
676
+ }
677
+
678
+ case SIGNAL_TYPE_LVDS : {
679
+ sink_caps .transaction_type = DDC_TRANSACTION_TYPE_I2C ;
680
+ sink_caps .signal = SIGNAL_TYPE_LVDS ;
681
+ break ;
682
+ }
683
+
684
+ case SIGNAL_TYPE_EDP : {
685
+ sink_caps .transaction_type =
686
+ DDC_TRANSACTION_TYPE_I2C_OVER_AUX ;
687
+ sink_caps .signal = SIGNAL_TYPE_EDP ;
688
+ break ;
689
+ }
690
+
691
+ case SIGNAL_TYPE_DISPLAY_PORT : {
692
+ sink_caps .transaction_type =
693
+ DDC_TRANSACTION_TYPE_I2C_OVER_AUX ;
694
+ sink_caps .signal = SIGNAL_TYPE_VIRTUAL ;
695
+ break ;
696
+ }
697
+
698
+ default :
699
+ DC_ERROR ("Invalid connector type! signal:%d\n" ,
700
+ link -> connector_signal );
701
+ return ;
702
+ }
703
+
704
+ sink_init_data .link = link ;
705
+ sink_init_data .sink_signal = sink_caps .signal ;
706
+
707
+ sink = dc_sink_create (& sink_init_data );
708
+ if (!sink ) {
709
+ DC_ERROR ("Failed to create sink!\n" );
710
+ return ;
711
+ }
712
+
713
+ link -> local_sink = sink ;
714
+
715
+ edid_status = dm_helpers_read_local_edid (
716
+ link -> ctx ,
717
+ link ,
718
+ sink );
719
+
720
+ if (edid_status != EDID_OK )
721
+ DC_ERROR ("Failed to read EDID" );
722
+
723
+ }
724
+
644
725
static int dm_resume (void * handle )
645
726
{
646
727
struct amdgpu_device * adev = handle ;
@@ -654,6 +735,7 @@ static int dm_resume(void *handle)
654
735
struct drm_plane * plane ;
655
736
struct drm_plane_state * new_plane_state ;
656
737
struct dm_plane_state * dm_new_plane_state ;
738
+ enum dc_connection_type new_connection_type = dc_connection_none ;
657
739
int ret ;
658
740
int i ;
659
741
@@ -684,7 +766,13 @@ static int dm_resume(void *handle)
684
766
continue ;
685
767
686
768
mutex_lock (& aconnector -> hpd_lock );
687
- dc_link_detect (aconnector -> dc_link , DETECT_REASON_HPD );
769
+ if (!dc_link_detect_sink (aconnector -> dc_link , & new_connection_type ))
770
+ DRM_ERROR ("KMS: Failed to detect connector\n" );
771
+
772
+ if (aconnector -> base .force && new_connection_type == dc_connection_none )
773
+ emulated_link_detect (aconnector -> dc_link );
774
+ else
775
+ dc_link_detect (aconnector -> dc_link , DETECT_REASON_HPD );
688
776
689
777
if (aconnector -> fake_enable && aconnector -> dc_link -> local_sink )
690
778
aconnector -> fake_enable = false;
@@ -922,6 +1010,7 @@ static void handle_hpd_irq(void *param)
922
1010
struct amdgpu_dm_connector * aconnector = (struct amdgpu_dm_connector * )param ;
923
1011
struct drm_connector * connector = & aconnector -> base ;
924
1012
struct drm_device * dev = connector -> dev ;
1013
+ enum dc_connection_type new_connection_type = dc_connection_none ;
925
1014
926
1015
/* In case of failure or MST no need to update connector status or notify the OS
927
1016
* since (for MST case) MST does this in it's own context.
@@ -931,7 +1020,21 @@ static void handle_hpd_irq(void *param)
931
1020
if (aconnector -> fake_enable )
932
1021
aconnector -> fake_enable = false;
933
1022
934
- if (dc_link_detect (aconnector -> dc_link , DETECT_REASON_HPD )) {
1023
+ if (!dc_link_detect_sink (aconnector -> dc_link , & new_connection_type ))
1024
+ DRM_ERROR ("KMS: Failed to detect connector\n" );
1025
+
1026
+ if (aconnector -> base .force && new_connection_type == dc_connection_none ) {
1027
+ emulated_link_detect (aconnector -> dc_link );
1028
+
1029
+
1030
+ drm_modeset_lock_all (dev );
1031
+ dm_restore_drm_connector_state (dev , connector );
1032
+ drm_modeset_unlock_all (dev );
1033
+
1034
+ if (aconnector -> base .force == DRM_FORCE_UNSPECIFIED )
1035
+ drm_kms_helper_hotplug_event (dev );
1036
+
1037
+ } else if (dc_link_detect (aconnector -> dc_link , DETECT_REASON_HPD )) {
935
1038
amdgpu_dm_update_connector_after_detect (aconnector );
936
1039
937
1040
@@ -1031,6 +1134,7 @@ static void handle_hpd_rx_irq(void *param)
1031
1134
struct drm_device * dev = connector -> dev ;
1032
1135
struct dc_link * dc_link = aconnector -> dc_link ;
1033
1136
bool is_mst_root_connector = aconnector -> mst_mgr .mst_state ;
1137
+ enum dc_connection_type new_connection_type = dc_connection_none ;
1034
1138
1035
1139
/* TODO:Temporary add mutex to protect hpd interrupt not have a gpio
1036
1140
* conflict, after implement i2c helper, this mutex should be
@@ -1042,7 +1146,24 @@ static void handle_hpd_rx_irq(void *param)
1042
1146
if (dc_link_handle_hpd_rx_irq (dc_link , NULL , NULL ) &&
1043
1147
!is_mst_root_connector ) {
1044
1148
/* Downstream Port status changed. */
1045
- if (dc_link_detect (dc_link , DETECT_REASON_HPDRX )) {
1149
+ if (!dc_link_detect_sink (dc_link , & new_connection_type ))
1150
+ DRM_ERROR ("KMS: Failed to detect connector\n" );
1151
+
1152
+ if (aconnector -> base .force && new_connection_type == dc_connection_none ) {
1153
+ emulated_link_detect (dc_link );
1154
+
1155
+ if (aconnector -> fake_enable )
1156
+ aconnector -> fake_enable = false;
1157
+
1158
+ amdgpu_dm_update_connector_after_detect (aconnector );
1159
+
1160
+
1161
+ drm_modeset_lock_all (dev );
1162
+ dm_restore_drm_connector_state (dev , connector );
1163
+ drm_modeset_unlock_all (dev );
1164
+
1165
+ drm_kms_helper_hotplug_event (dev );
1166
+ } else if (dc_link_detect (dc_link , DETECT_REASON_HPDRX )) {
1046
1167
1047
1168
if (aconnector -> fake_enable )
1048
1169
aconnector -> fake_enable = false;
@@ -1433,6 +1554,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
1433
1554
struct amdgpu_mode_info * mode_info = & adev -> mode_info ;
1434
1555
uint32_t link_cnt ;
1435
1556
int32_t total_overlay_planes , total_primary_planes ;
1557
+ enum dc_connection_type new_connection_type = dc_connection_none ;
1436
1558
1437
1559
link_cnt = dm -> dc -> caps .max_links ;
1438
1560
if (amdgpu_dm_mode_config_init (dm -> adev )) {
@@ -1499,7 +1621,14 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
1499
1621
1500
1622
link = dc_get_link_at_index (dm -> dc , i );
1501
1623
1502
- if (dc_link_detect (link , DETECT_REASON_BOOT )) {
1624
+ if (!dc_link_detect_sink (link , & new_connection_type ))
1625
+ DRM_ERROR ("KMS: Failed to detect connector\n" );
1626
+
1627
+ if (aconnector -> base .force && new_connection_type == dc_connection_none ) {
1628
+ emulated_link_detect (link );
1629
+ amdgpu_dm_update_connector_after_detect (aconnector );
1630
+
1631
+ } else if (dc_link_detect (link , DETECT_REASON_BOOT )) {
1503
1632
amdgpu_dm_update_connector_after_detect (aconnector );
1504
1633
register_backlight_device (dm , link );
1505
1634
}
@@ -2494,7 +2623,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
2494
2623
if (dm_state && dm_state -> freesync_capable )
2495
2624
stream -> ignore_msa_timing_param = true;
2496
2625
finish :
2497
- if (sink && sink -> sink_signal == SIGNAL_TYPE_VIRTUAL )
2626
+ if (sink && sink -> sink_signal == SIGNAL_TYPE_VIRTUAL && aconnector -> base . force != DRM_FORCE_ON )
2498
2627
dc_sink_release (sink );
2499
2628
2500
2629
return stream ;
0 commit comments