From 2e4e504830ac7f9435bf28c86be169354729f3de Mon Sep 17 00:00:00 2001 From: jsg Date: Thu, 24 Aug 2023 06:27:21 +0000 Subject: [PATCH] drm/amd/display: Implement workaround for writing to OTG_PIXEL_RATE_DIV register From Saaem Rizvi 4bdfe20d85b32274234bbcd705d5547fd70a4ea1 in linux-6.1.y/6.1.47 74fa4c81aadf418341f0d073c864ea7dca730a2e in mainline linux --- .../pci/drm/amd/display/dc/dcn20/dcn20_dccg.h | 3 ++- .../pci/drm/amd/display/dc/dcn32/dcn32_dccg.c | 22 +++++++++++++++++++ .../pci/drm/amd/display/dc/dcn32/dcn32_dccg.h | 3 ++- .../drm/amd/display/dc/dcn32/dcn32_hwseq.c | 2 +- .../drm/amd/display/dc/dcn32/dcn32_resource.h | 3 ++- 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/sys/dev/pci/drm/amd/display/dc/dcn20/dcn20_dccg.h b/sys/dev/pci/drm/amd/display/dc/dcn20/dcn20_dccg.h index 915a20461c7..893c0809cd4 100644 --- a/sys/dev/pci/drm/amd/display/dc/dcn20/dcn20_dccg.h +++ b/sys/dev/pci/drm/amd/display/dc/dcn20/dcn20_dccg.h @@ -230,7 +230,8 @@ type DTBCLK_P2_SRC_SEL;\ type DTBCLK_P2_EN;\ type DTBCLK_P3_SRC_SEL;\ - type DTBCLK_P3_EN; + type DTBCLK_P3_EN;\ + type DENTIST_DISPCLK_CHG_DONE; struct dccg_shift { DCCG_REG_FIELD_LIST(uint8_t) diff --git a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_dccg.c b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_dccg.c index 3fb4bcc3435..ffbb739d85b 100644 --- a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_dccg.c +++ b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_dccg.c @@ -42,6 +42,20 @@ #define DC_LOGGER \ dccg->ctx->logger +/* This function is a workaround for writing to OTG_PIXEL_RATE_DIV + * without the probability of causing a DIG FIFO error. + */ +static void dccg32_wait_for_dentist_change_done( + struct dccg *dccg) +{ + struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + + uint32_t dentist_dispclk_value = REG_READ(DENTIST_DISPCLK_CNTL); + + REG_WRITE(DENTIST_DISPCLK_CNTL, dentist_dispclk_value); + REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 2000); +} + static void dccg32_get_pixel_rate_div( struct dccg *dccg, uint32_t otg_inst, @@ -110,21 +124,29 @@ static void dccg32_set_pixel_rate_div( REG_UPDATE_2(OTG_PIXEL_RATE_DIV, OTG0_PIXEL_RATE_DIVK1, k1, OTG0_PIXEL_RATE_DIVK2, k2); + + dccg32_wait_for_dentist_change_done(dccg); break; case 1: REG_UPDATE_2(OTG_PIXEL_RATE_DIV, OTG1_PIXEL_RATE_DIVK1, k1, OTG1_PIXEL_RATE_DIVK2, k2); + + dccg32_wait_for_dentist_change_done(dccg); break; case 2: REG_UPDATE_2(OTG_PIXEL_RATE_DIV, OTG2_PIXEL_RATE_DIVK1, k1, OTG2_PIXEL_RATE_DIVK2, k2); + + dccg32_wait_for_dentist_change_done(dccg); break; case 3: REG_UPDATE_2(OTG_PIXEL_RATE_DIV, OTG3_PIXEL_RATE_DIVK1, k1, OTG3_PIXEL_RATE_DIVK2, k2); + + dccg32_wait_for_dentist_change_done(dccg); break; default: BREAK_TO_DEBUGGER(); diff --git a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_dccg.h b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_dccg.h index 1c46fad0977..fc3c9c650d4 100644 --- a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_dccg.h +++ b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_dccg.h @@ -147,7 +147,8 @@ DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P3_SRC_SEL, mask_sh),\ DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P3_EN, mask_sh),\ DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO_SEL, mask_sh),\ - DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL, mask_sh) + DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL, mask_sh),\ + DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh) struct dccg *dccg32_create( diff --git a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_hwseq.c index 601b65483ef..fa075789c9e 100644 --- a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_hwseq.c +++ b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_hwseq.c @@ -1177,7 +1177,7 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign *k2_div = PIXEL_RATE_DIV_BY_2; else *k2_div = PIXEL_RATE_DIV_BY_4; - } else if (dc_is_dp_signal(stream->signal)) { + } else if (dc_is_dp_signal(stream->signal) || dc_is_virtual_signal(stream->signal)) { if (two_pix_per_container) { *k1_div = PIXEL_RATE_DIV_BY_1; *k2_div = PIXEL_RATE_DIV_BY_2; diff --git a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.h b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.h index 026cf13d203..03cdfb55778 100644 --- a/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.h +++ b/sys/dev/pci/drm/amd/display/dc/dcn32/dcn32_resource.h @@ -1272,7 +1272,8 @@ unsigned int dcn32_calc_num_avail_chans_for_mall(struct dc *dc, int num_chans); DCCG_SRII(PHASE, DTBCLK_DTO, 0), DCCG_SRII(PHASE, DTBCLK_DTO, 1), \ DCCG_SRII(PHASE, DTBCLK_DTO, 2), DCCG_SRII(PHASE, DTBCLK_DTO, 3), \ SR(DCCG_AUDIO_DTBCLK_DTO_MODULO), SR(DCCG_AUDIO_DTBCLK_DTO_PHASE), \ - SR(OTG_PIXEL_RATE_DIV), SR(DTBCLK_P_CNTL), SR(DCCG_AUDIO_DTO_SOURCE) \ + SR(OTG_PIXEL_RATE_DIV), SR(DTBCLK_P_CNTL), \ + SR(DCCG_AUDIO_DTO_SOURCE), SR(DENTIST_DISPCLK_CNTL) \ ) /* VMID */ -- 2.20.1