diff options
author | Qingqing Zhuo <qingqing.zhuo@amd.com> | 2021-08-25 19:29:28 +0300 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2021-09-23 22:17:30 +0300 |
commit | 1bd3bc745e7f02f471fbf6e3f5f2ac5d788c9f39 (patch) | |
tree | 88325c2dddf290fd58778be4f78647f20918d36f /drivers/gpu/drm/amd/display/dc/irq | |
parent | a62427ef9b55d4b5aec2b08dc9b2d9719572bf57 (diff) | |
download | linux-1bd3bc745e7f02f471fbf6e3f5f2ac5d788c9f39.tar.xz |
drm/amd/display: Extend w/a for hard hang on HPD to dcn20
[Why]
HPD disable and enable sequences are not mutually exclusive on Linux.
For HPDs that spans under 1s (i.e. HPD low = 1s), part of the disable
sequence (specifically, a request to SMU to lower refclk) could come
right before the call to PHY enablement, causing DMUB to access an
irresponsive PHY and thus a hard hang on the system.
[How]
Disable 48mhz refclk off when there is any HPD status in connected state
for dcn20.
Reviewed-by: Hersen Wu <hersenxs.wu@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/irq')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c | 25 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.h | 2 |
2 files changed, 27 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c b/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c index c4b067d01895..49d87fe5c167 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c @@ -132,6 +132,31 @@ enum dc_irq_source to_dal_irq_source_dcn20( } } +uint32_t dal_get_hpd_state_dcn20(struct irq_service *irq_service, enum dc_irq_source source) +{ + const struct irq_source_info *info; + uint32_t addr; + uint32_t value; + uint32_t current_status; + + info = find_irq_source_info(irq_service, source); + if (!info) + return 0; + + addr = info->status_reg; + if (!addr) + return 0; + + value = dm_read_reg(irq_service->ctx, addr); + current_status = + get_reg_field_value( + value, + HPD0_DC_HPD_INT_STATUS, + DC_HPD_SENSE); + + return current_status; +} + static bool hpd_ack( struct irq_service *irq_service, const struct irq_source_info *info) diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.h b/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.h index aee4b37999f1..f60a203e7188 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.h +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.h @@ -31,4 +31,6 @@ struct irq_service *dal_irq_service_dcn20_create( struct irq_service_init_data *init_data); +uint32_t dal_get_hpd_state_dcn20(struct irq_service *irq_service, enum dc_irq_source source); + #endif |