Commit c40a09e5 authored by Nicholas Kazlauskas's avatar Nicholas Kazlauskas Committed by Alex Deucher

drm/amd/display: Add callbacks for DMUB HPD IRQ notifications

[Why]
We need HPD IRQ notifications (RX, short pulse) to properly handle
DP MST for DPIA connections.

[How]
A null pointer exception currently occurs when these are received
so add a check to validate that we have a handler installed for
the notification.

Extend the HPD handler to also handle HPD IRQ (RX) since the logic is
the same.

Fixes: e27c41d5 ("drm/amd/display: Support for DMUB HPD interrupt handling")
Reviewed-by: default avatarWayne Lin <Wayne.Lin@amd.com>
Reviewed-by: default avatarJude Shih <shenshih@amd.com>
Acked-by: default avatarAnson Jacob <Anson.Jacob@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent d82b3266
...@@ -217,6 +217,7 @@ static const struct drm_format_info * ...@@ -217,6 +217,7 @@ static const struct drm_format_info *
amd_get_format_info(const struct drm_mode_fb_cmd2 *cmd); amd_get_format_info(const struct drm_mode_fb_cmd2 *cmd);
static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector); static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector);
static void handle_hpd_rx_irq(void *param);
static bool static bool
is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state, is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state,
...@@ -683,8 +684,12 @@ void dmub_hpd_callback(struct amdgpu_device *adev, struct dmub_notification *not ...@@ -683,8 +684,12 @@ void dmub_hpd_callback(struct amdgpu_device *adev, struct dmub_notification *not
} }
drm_connector_list_iter_end(&iter); drm_connector_list_iter_end(&iter);
if (hpd_aconnector) if (hpd_aconnector) {
handle_hpd_irq_helper(hpd_aconnector); if (notify->type == DMUB_NOTIFICATION_HPD)
handle_hpd_irq_helper(hpd_aconnector);
else if (notify->type == DMUB_NOTIFICATION_HPD_IRQ)
handle_hpd_rx_irq(hpd_aconnector);
}
} }
/** /**
...@@ -760,6 +765,10 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params) ...@@ -760,6 +765,10 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params)
DRM_ERROR("DM: notify type %d invalid!", notify.type); DRM_ERROR("DM: notify type %d invalid!", notify.type);
continue; continue;
} }
if (!dm->dmub_callback[notify.type]) {
DRM_DEBUG_DRIVER("DMUB notification skipped, no handler: type=%d\n", notify.type);
continue;
}
if (dm->dmub_thread_offload[notify.type] == true) { if (dm->dmub_thread_offload[notify.type] == true) {
dmub_hpd_wrk = kzalloc(sizeof(*dmub_hpd_wrk), GFP_ATOMIC); dmub_hpd_wrk = kzalloc(sizeof(*dmub_hpd_wrk), GFP_ATOMIC);
if (!dmub_hpd_wrk) { if (!dmub_hpd_wrk) {
...@@ -1560,6 +1569,10 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) ...@@ -1560,6 +1569,10 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
DRM_ERROR("amdgpu: fail to register dmub hpd callback"); DRM_ERROR("amdgpu: fail to register dmub hpd callback");
goto error; goto error;
} }
if (!register_dmub_notify_callback(adev, DMUB_NOTIFICATION_HPD_IRQ, dmub_hpd_callback, true)) {
DRM_ERROR("amdgpu: fail to register dmub hpd callback");
goto error;
}
#endif /* CONFIG_DRM_AMD_DC_DCN */ #endif /* CONFIG_DRM_AMD_DC_DCN */
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment