drm/amd/display: Fix 4to1 MPC black screen with DPP RCO
authorjsg <jsg@openbsd.org>
Tue, 13 Jun 2023 03:04:00 +0000 (03:04 +0000)
committerjsg <jsg@openbsd.org>
Tue, 13 Jun 2023 03:04:00 +0000 (03:04 +0000)
From Nicholas Kazlauskas
c2b2641ecb9aed1613976a2abf56292e206e3694 in linux-6.1.y/6.1.29
bf224e00a9f54e2bf14b4d720a09c3d2f4aa4aa8 in mainline linux

sys/dev/pci/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
sys/dev/pci/drm/amd/display/dc/dcn20/dcn20_hwseq.c
sys/dev/pci/drm/amd/display/dc/dcn31/dcn31_dccg.c
sys/dev/pci/drm/amd/display/dc/dcn314/dcn314_dccg.c
sys/dev/pci/drm/amd/display/dc/dcn314/dcn314_hwseq.c
sys/dev/pci/drm/amd/display/dc/dcn314/dcn314_hwseq.h
sys/dev/pci/drm/amd/display/dc/dcn314/dcn314_init.c
sys/dev/pci/drm/amd/display/dc/inc/hw/dccg.h
sys/dev/pci/drm/amd/display/dc/inc/hw_sequencer_private.h

index 8e46f70..0dcd9fe 100644 (file)
@@ -726,11 +726,15 @@ void dcn10_hubp_pg_control(
        }
 }
 
-static void power_on_plane(
+static void power_on_plane_resources(
        struct dce_hwseq *hws,
        int plane_id)
 {
        DC_LOGGER_INIT(hws->ctx->logger);
+
+       if (hws->funcs.dpp_root_clock_control)
+               hws->funcs.dpp_root_clock_control(hws, plane_id, true);
+
        if (REG(DC_IP_REQUEST_CNTL)) {
                REG_SET(DC_IP_REQUEST_CNTL, 0,
                                IP_REQUEST_EN, 1);
@@ -1237,11 +1241,15 @@ void dcn10_plane_atomic_power_down(struct dc *dc,
                        hws->funcs.hubp_pg_control(hws, hubp->inst, false);
 
                dpp->funcs->dpp_reset(dpp);
+
                REG_SET(DC_IP_REQUEST_CNTL, 0,
                                IP_REQUEST_EN, 0);
                DC_LOG_DEBUG(
                                "Power gated front end %d\n", hubp->inst);
        }
+
+       if (hws->funcs.dpp_root_clock_control)
+               hws->funcs.dpp_root_clock_control(hws, dpp->inst, false);
 }
 
 /* disable HW used by plane.
@@ -2450,7 +2458,7 @@ static void dcn10_enable_plane(
 
        undo_DEGVIDCN10_253_wa(dc);
 
-       power_on_plane(dc->hwseq,
+       power_on_plane_resources(dc->hwseq,
                pipe_ctx->plane_res.hubp->inst);
 
        /* enable DCFCLK current DCHUB */
index f348bc1..2d49e99 100644 (file)
@@ -1087,11 +1087,15 @@ void dcn20_blank_pixel_data(
 }
 
 
-static void dcn20_power_on_plane(
+static void dcn20_power_on_plane_resources(
        struct dce_hwseq *hws,
        struct pipe_ctx *pipe_ctx)
 {
        DC_LOGGER_INIT(hws->ctx->logger);
+
+       if (hws->funcs.dpp_root_clock_control)
+               hws->funcs.dpp_root_clock_control(hws, pipe_ctx->plane_res.dpp->inst, true);
+
        if (REG(DC_IP_REQUEST_CNTL)) {
                REG_SET(DC_IP_REQUEST_CNTL, 0,
                                IP_REQUEST_EN, 1);
@@ -1115,7 +1119,7 @@ static void dcn20_enable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx,
        //if (dc->debug.sanity_checks) {
        //      dcn10_verify_allow_pstate_change_high(dc);
        //}
-       dcn20_power_on_plane(dc->hwseq, pipe_ctx);
+       dcn20_power_on_plane_resources(dc->hwseq, pipe_ctx);
 
        /* enable DCFCLK current DCHUB */
        pipe_ctx->plane_res.hubp->funcs->hubp_clk_cntl(pipe_ctx->plane_res.hubp, true);
index 7f34418..7d2b982 100644 (file)
@@ -66,17 +66,8 @@ void dccg31_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk)
                REG_UPDATE(DPPCLK_DTO_CTRL,
                                DPPCLK_DTO_ENABLE[dpp_inst], 1);
        } else {
-               //DTO must be enabled to generate a 0Hz clock output
-               if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp) {
-                       REG_UPDATE(DPPCLK_DTO_CTRL,
-                                       DPPCLK_DTO_ENABLE[dpp_inst], 1);
-                       REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
-                                       DPPCLK0_DTO_PHASE, 0,
-                                       DPPCLK0_DTO_MODULO, 1);
-               } else {
-                       REG_UPDATE(DPPCLK_DTO_CTRL,
-                                       DPPCLK_DTO_ENABLE[dpp_inst], 0);
-               }
+               REG_UPDATE(DPPCLK_DTO_CTRL,
+                               DPPCLK_DTO_ENABLE[dpp_inst], 0);
        }
        dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk;
 }
index 389a893..85ea333 100644 (file)
@@ -289,8 +289,31 @@ static void dccg314_set_valid_pixel_rate(
        dccg314_set_dtbclk_dto(dccg, &dto_params);
 }
 
+static void dccg314_dpp_root_clock_control(
+               struct dccg *dccg,
+               unsigned int dpp_inst,
+               bool clock_on)
+{
+       struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+       if (clock_on) {
+               /* turn off the DTO and leave phase/modulo at max */
+               REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_ENABLE[dpp_inst], 0);
+               REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
+                         DPPCLK0_DTO_PHASE, 0xFF,
+                         DPPCLK0_DTO_MODULO, 0xFF);
+       } else {
+               /* turn on the DTO to generate a 0hz clock */
+               REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_ENABLE[dpp_inst], 1);
+               REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
+                         DPPCLK0_DTO_PHASE, 0,
+                         DPPCLK0_DTO_MODULO, 1);
+       }
+}
+
 static const struct dccg_funcs dccg314_funcs = {
        .update_dpp_dto = dccg31_update_dpp_dto,
+       .dpp_root_clock_control = dccg314_dpp_root_clock_control,
        .get_dccg_ref_freq = dccg31_get_dccg_ref_freq,
        .dccg_init = dccg31_init,
        .set_dpstreamclk = dccg314_set_dpstreamclk,
index 8e824dc..414d735 100644 (file)
@@ -392,6 +392,16 @@ void dcn314_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx)
                                pix_per_cycle);
 }
 
+void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on)
+{
+       if (!hws->ctx->dc->debug.root_clock_optimization.bits.dpp)
+               return;
+
+       if (hws->ctx->dc->res_pool->dccg->funcs->dpp_root_clock_control)
+               hws->ctx->dc->res_pool->dccg->funcs->dpp_root_clock_control(
+                       hws->ctx->dc->res_pool->dccg, dpp_inst, clock_on);
+}
+
 void dcn314_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on)
 {
        struct dc_context *ctx = hws->ctx;
index c419d3d..c786d5e 100644 (file)
@@ -43,4 +43,6 @@ void dcn314_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx);
 
 void dcn314_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on);
 
+void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on);
+
 #endif /* __DC_HWSS_DCN314_H__ */
index 343f4d9..5267e90 100644 (file)
@@ -137,6 +137,7 @@ static const struct hwseq_private_funcs dcn314_private_funcs = {
        .plane_atomic_disable = dcn20_plane_atomic_disable,
        .plane_atomic_power_down = dcn10_plane_atomic_power_down,
        .enable_power_gating_plane = dcn314_enable_power_gating_plane,
+       .dpp_root_clock_control = dcn314_dpp_root_clock_control,
        .hubp_pg_control = dcn314_hubp_pg_control,
        .program_all_writeback_pipes_in_tree = dcn30_program_all_writeback_pipes_in_tree,
        .update_odm = dcn314_update_odm,
index ce00676..ad6acd1 100644 (file)
@@ -148,18 +148,21 @@ struct dccg_funcs {
                struct dccg *dccg,
                int inst);
 
-void (*set_pixel_rate_div)(
-        struct dccg *dccg,
-        uint32_t otg_inst,
-        enum pixel_rate_div k1,
-        enum pixel_rate_div k2);
-
-void (*set_valid_pixel_rate)(
-        struct dccg *dccg,
-       int ref_dtbclk_khz,
-        int otg_inst,
-        int pixclk_khz);
+       void (*set_pixel_rate_div)(struct dccg *dccg,
+                       uint32_t otg_inst,
+                       enum pixel_rate_div k1,
+                       enum pixel_rate_div k2);
 
+       void (*set_valid_pixel_rate)(
+                       struct dccg *dccg,
+                       int ref_dtbclk_khz,
+                       int otg_inst,
+                       int pixclk_khz);
+
+       void (*dpp_root_clock_control)(
+                       struct dccg *dccg,
+                       unsigned int dpp_inst,
+                       bool clock_on);
 };
 
 #endif //__DAL_DCCG_H__
index a4d61bb..39bd53b 100644 (file)
@@ -115,6 +115,10 @@ struct hwseq_private_funcs {
        void (*plane_atomic_disable)(struct dc *dc, struct pipe_ctx *pipe_ctx);
        void (*enable_power_gating_plane)(struct dce_hwseq *hws,
                bool enable);
+       void (*dpp_root_clock_control)(
+                       struct dce_hwseq *hws,
+                       unsigned int dpp_inst,
+                       bool clock_on);
        void (*dpp_pg_control)(struct dce_hwseq *hws,
                        unsigned int dpp_inst,
                        bool power_on);