OSDN Git Service

drm/amd/display: Fix DMUB outbox trace in S4 (#4465)
authorHung, Cruise <Cruise.Hung@amd.com>
Fri, 13 May 2022 01:16:42 +0000 (09:16 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 1 Jun 2022 19:56:48 +0000 (15:56 -0400)
[Why]
DMUB Outbox0 read/write pointer not sync after resumed from S4.
And that caused old traces were sent to outbox.

[How]
Disable DMUB Outbox0 interrupt
and clear DMUB Outbox0 read/write pointer when resumes from S4.
And then enable Outbox0 interrupt before starts DMCUB.

Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: Jasdeep Dhillon <jdhillon@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Cruise Hung <Cruise.Hung@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c

index 616013c..0eb89e1 100644 (file)
@@ -513,12 +513,10 @@ void dccg31_set_physymclk(
 /* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */
 static void dccg31_set_dtbclk_dto(
                struct dccg *dccg,
-               int dtbclk_inst,
-               int req_dtbclk_khz,
-               int num_odm_segments,
-               const struct dc_crtc_timing *timing)
+               struct dtbclk_dto_params *params)
 {
        struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+       int req_dtbclk_khz = params->pixclk_khz;
        uint32_t dtbdto_div;
 
        /* Mode                 DTBDTO Rate       DTBCLK_DTO<x>_DIV Register
@@ -529,57 +527,56 @@ static void dccg31_set_dtbclk_dto(
         * DSC native 4:2:2     pixel rate/2      4
         * Other modes          pixel rate        8
         */
-       if (num_odm_segments == 4) {
+       if (params->num_odm_segments == 4) {
                dtbdto_div = 2;
-               req_dtbclk_khz = req_dtbclk_khz / 4;
-       } else if ((num_odm_segments == 2) ||
-                       (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) ||
-                       (timing->flags.DSC && timing->pixel_encoding == PIXEL_ENCODING_YCBCR422
-                                       && !timing->dsc_cfg.ycbcr422_simple)) {
+               req_dtbclk_khz = params->pixclk_khz / 4;
+       } else if ((params->num_odm_segments == 2) ||
+                       (params->timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) ||
+                       (params->timing->flags.DSC && params->timing->pixel_encoding == PIXEL_ENCODING_YCBCR422
+                                       && !params->timing->dsc_cfg.ycbcr422_simple)) {
                dtbdto_div = 4;
-               req_dtbclk_khz = req_dtbclk_khz / 2;
+               req_dtbclk_khz = params->pixclk_khz / 2;
        } else
                dtbdto_div = 8;
 
-       if (dccg->ref_dtbclk_khz && req_dtbclk_khz) {
+       if (params->ref_dtbclk_khz && req_dtbclk_khz) {
                uint32_t modulo, phase;
 
                // phase / modulo = dtbclk / dtbclk ref
-               modulo = dccg->ref_dtbclk_khz * 1000;
-               phase = div_u64((((unsigned long long)modulo * req_dtbclk_khz) + dccg->ref_dtbclk_khz - 1),
-                       dccg->ref_dtbclk_khz);
+               modulo = params->ref_dtbclk_khz * 1000;
+               phase = div_u64((((unsigned long long)modulo * req_dtbclk_khz) + params->ref_dtbclk_khz - 1),
+                               params->ref_dtbclk_khz);
 
-               REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
-                               DTBCLK_DTO_DIV[dtbclk_inst], dtbdto_div);
+               REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+                               DTBCLK_DTO_DIV[params->otg_inst], dtbdto_div);
 
-               REG_WRITE(DTBCLK_DTO_MODULO[dtbclk_inst], modulo);
-               REG_WRITE(DTBCLK_DTO_PHASE[dtbclk_inst], phase);
+               REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo);
+               REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase);
 
-               REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
-                               DTBCLK_DTO_ENABLE[dtbclk_inst], 1);
+               REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+                               DTBCLK_DTO_ENABLE[params->otg_inst], 1);
 
-               REG_WAIT(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
-                               DTBCLKDTO_ENABLE_STATUS[dtbclk_inst], 1,
+               REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+                               DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1,
                                1, 100);
 
                /* The recommended programming sequence to enable DTBCLK DTO to generate
                 * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should
                 * be set only after DTO is enabled
                 */
-               REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
-                               PIPE_DTO_SRC_SEL[dtbclk_inst], 1);
-
-               dccg->dtbclk_khz[dtbclk_inst] = req_dtbclk_khz;
+               REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+                               PIPE_DTO_SRC_SEL[params->otg_inst], 1);
        } else {
-               REG_UPDATE_3(OTG_PIXEL_RATE_CNTL[dtbclk_inst],
-                               DTBCLK_DTO_ENABLE[dtbclk_inst], 0,
-                               PIPE_DTO_SRC_SEL[dtbclk_inst], 0,
-                               DTBCLK_DTO_DIV[dtbclk_inst], dtbdto_div);
+               REG_UPDATE_3(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+                               DTBCLK_DTO_ENABLE[params->otg_inst], 0,
+                               PIPE_DTO_SRC_SEL[params->otg_inst], 0,
+                               DTBCLK_DTO_DIV[params->otg_inst], dtbdto_div);
 
                REG_WRITE(DTBCLK_DTO_MODULO[dtbclk_inst], 0);
                REG_WRITE(DTBCLK_DTO_PHASE[dtbclk_inst], 0);
 
-               dccg->dtbclk_khz[dtbclk_inst] = 0;
+               REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
+               REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
        }
 }
 
index 8d45748..c7bd7e2 100644 (file)
@@ -132,6 +132,8 @@ void dmub_dcn31_reset(struct dmub_srv *dmub)
        REG_WRITE(DMCUB_INBOX1_WPTR, 0);
        REG_WRITE(DMCUB_OUTBOX1_RPTR, 0);
        REG_WRITE(DMCUB_OUTBOX1_WPTR, 0);
+       REG_WRITE(DMCUB_OUTBOX0_RPTR, 0);
+       REG_WRITE(DMCUB_OUTBOX0_WPTR, 0);
        REG_WRITE(DMCUB_SCRATCH0, 0);
 
        /* Clear the GPINT command manually so we don't send anything during boot. */