9797#include <drm/drm_audio_component.h>
9898#include <drm/drm_gem_atomic_helper.h>
9999
100+ #include <media/cec-notifier.h>
100101#include <acpi/video.h>
101102
102103#include "ivsrcid/dcn/irqsrcs_dcn_1_0.h"
@@ -2751,6 +2752,48 @@ static void resume_mst_branch_status(struct drm_dp_mst_topology_mgr *mgr)
27512752 mutex_unlock (& mgr -> lock );
27522753}
27532754
2755+ void hdmi_cec_unset_edid (struct amdgpu_dm_connector * aconnector )
2756+ {
2757+ struct cec_notifier * n = aconnector -> notifier ;
2758+
2759+ if (!n )
2760+ return ;
2761+
2762+ cec_notifier_phys_addr_invalidate (n );
2763+ }
2764+
2765+ void hdmi_cec_set_edid (struct amdgpu_dm_connector * aconnector )
2766+ {
2767+ struct drm_connector * connector = & aconnector -> base ;
2768+ struct cec_notifier * n = aconnector -> notifier ;
2769+
2770+ if (!n )
2771+ return ;
2772+
2773+ cec_notifier_set_phys_addr (n ,
2774+ connector -> display_info .source_physical_address );
2775+ }
2776+
2777+ static void s3_handle_hdmi_cec (struct drm_device * ddev , bool suspend )
2778+ {
2779+ struct amdgpu_dm_connector * aconnector ;
2780+ struct drm_connector * connector ;
2781+ struct drm_connector_list_iter conn_iter ;
2782+
2783+ drm_connector_list_iter_begin (ddev , & conn_iter );
2784+ drm_for_each_connector_iter (connector , & conn_iter ) {
2785+ if (connector -> connector_type == DRM_MODE_CONNECTOR_WRITEBACK )
2786+ continue ;
2787+
2788+ aconnector = to_amdgpu_dm_connector (connector );
2789+ if (suspend )
2790+ hdmi_cec_unset_edid (aconnector );
2791+ else
2792+ hdmi_cec_set_edid (aconnector );
2793+ }
2794+ drm_connector_list_iter_end (& conn_iter );
2795+ }
2796+
27542797static void s3_handle_mst (struct drm_device * dev , bool suspend )
27552798{
27562799 struct amdgpu_dm_connector * aconnector ;
@@ -3022,6 +3065,8 @@ static int dm_suspend(struct amdgpu_ip_block *ip_block)
30223065 if (IS_ERR (adev -> dm .cached_state ))
30233066 return PTR_ERR (adev -> dm .cached_state );
30243067
3068+ s3_handle_hdmi_cec (adev_to_drm (adev ), true);
3069+
30253070 s3_handle_mst (adev_to_drm (adev ), true);
30263071
30273072 amdgpu_dm_irq_suspend (adev );
@@ -3294,6 +3339,8 @@ static int dm_resume(struct amdgpu_ip_block *ip_block)
32943339 */
32953340 amdgpu_dm_irq_resume_early (adev );
32963341
3342+ s3_handle_hdmi_cec (ddev , false);
3343+
32973344 /* On resume we need to rewrite the MSTM control bits to enable MST*/
32983345 s3_handle_mst (ddev , false);
32993346
@@ -3603,6 +3650,7 @@ void amdgpu_dm_update_connector_after_detect(
36033650 dc_sink_retain (aconnector -> dc_sink );
36043651 if (sink -> dc_edid .length == 0 ) {
36053652 aconnector -> drm_edid = NULL ;
3653+ hdmi_cec_unset_edid (aconnector );
36063654 if (aconnector -> dc_link -> aux_mode ) {
36073655 drm_dp_cec_unset_edid (& aconnector -> dm_dp_aux .aux );
36083656 }
@@ -3612,6 +3660,7 @@ void amdgpu_dm_update_connector_after_detect(
36123660 aconnector -> drm_edid = drm_edid_alloc (edid , sink -> dc_edid .length );
36133661 drm_edid_connector_update (connector , aconnector -> drm_edid );
36143662
3663+ hdmi_cec_set_edid (aconnector );
36153664 if (aconnector -> dc_link -> aux_mode )
36163665 drm_dp_cec_attach (& aconnector -> dm_dp_aux .aux ,
36173666 connector -> display_info .source_physical_address );
@@ -3628,6 +3677,7 @@ void amdgpu_dm_update_connector_after_detect(
36283677 amdgpu_dm_update_freesync_caps (connector , aconnector -> drm_edid );
36293678 update_connector_ext_caps (aconnector );
36303679 } else {
3680+ hdmi_cec_unset_edid (aconnector );
36313681 drm_dp_cec_unset_edid (& aconnector -> dm_dp_aux .aux );
36323682 amdgpu_dm_update_freesync_caps (connector , NULL );
36333683 aconnector -> num_modes = 0 ;
@@ -7044,6 +7094,7 @@ static void amdgpu_dm_connector_unregister(struct drm_connector *connector)
70447094 if (amdgpu_dm_should_create_sysfs (amdgpu_dm_connector ))
70457095 sysfs_remove_group (& connector -> kdev -> kobj , & amdgpu_group );
70467096
7097+ cec_notifier_conn_unregister (amdgpu_dm_connector -> notifier );
70477098 drm_dp_aux_unregister (& amdgpu_dm_connector -> dm_dp_aux .aux );
70487099}
70497100
@@ -8280,6 +8331,27 @@ create_i2c(struct ddc_service *ddc_service,
82808331 return i2c ;
82818332}
82828333
8334+ int amdgpu_dm_initialize_hdmi_connector (struct amdgpu_dm_connector * aconnector )
8335+ {
8336+ struct cec_connector_info conn_info ;
8337+ struct drm_device * ddev = aconnector -> base .dev ;
8338+ struct device * hdmi_dev = ddev -> dev ;
8339+
8340+ if (amdgpu_dc_debug_mask & DC_DISABLE_HDMI_CEC ) {
8341+ drm_info (ddev , "HDMI-CEC feature masked\n" );
8342+ return - EINVAL ;
8343+ }
8344+
8345+ cec_fill_conn_info_from_drm (& conn_info , & aconnector -> base );
8346+ aconnector -> notifier =
8347+ cec_notifier_conn_register (hdmi_dev , NULL , & conn_info );
8348+ if (!aconnector -> notifier ) {
8349+ drm_err (ddev , "Failed to create cec notifier\n" );
8350+ return - ENOMEM ;
8351+ }
8352+
8353+ return 0 ;
8354+ }
82838355
82848356/*
82858357 * Note: this function assumes that dc_link_detect() was called for the
@@ -8343,6 +8415,10 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
83438415 drm_connector_attach_encoder (
83448416 & aconnector -> base , & aencoder -> base );
83458417
8418+ if (connector_type == DRM_MODE_CONNECTOR_HDMIA ||
8419+ connector_type == DRM_MODE_CONNECTOR_HDMIB )
8420+ amdgpu_dm_initialize_hdmi_connector (aconnector );
8421+
83468422 if (connector_type == DRM_MODE_CONNECTOR_DisplayPort
83478423 || connector_type == DRM_MODE_CONNECTOR_eDP )
83488424 amdgpu_dm_initialize_dp_connector (dm , aconnector , link -> link_index );
0 commit comments