drm/amd/display: disable DPP RCG before DPP CLK enable

[ Upstream commit 1bcd679209 ]

[why]
DPP CLK enable needs to disable DPPCLK RCG first.
The DPPCLK_en in dccg should always be enabled when the corresponding
pipe is enabled.

Reviewed-by: Hansen Dsouza <hansen.dsouza@amd.com>
Signed-off-by: Charlene Liu <Charlene.Liu@amd.com>
Signed-off-by: Ray Wu <ray.wu@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Stable-dep-of: cfa0904a35 ("drm/amd/display: Prevent Gating DTBCLK before It Is Properly Latched")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Charlene Liu
2025-11-25 09:51:29 -05:00
committed by Greg Kroah-Hartman
parent 467904aabb
commit b1515304a5
2 changed files with 38 additions and 21 deletions

View File

@@ -391,6 +391,7 @@ static void dccg35_set_dppclk_rcg(struct dccg *dccg,
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp && enable) if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp && enable)
return; return;
@@ -411,6 +412,8 @@ static void dccg35_set_dppclk_rcg(struct dccg *dccg,
BREAK_TO_DEBUGGER(); BREAK_TO_DEBUGGER();
break; break;
} }
//DC_LOG_DEBUG("%s: inst(%d) DPPCLK rcg_disable: %d\n", __func__, inst, enable ? 0 : 1);
} }
static void dccg35_set_dpstreamclk_rcg( static void dccg35_set_dpstreamclk_rcg(
@@ -1112,30 +1115,24 @@ static void dcn35_set_dppclk_enable(struct dccg *dccg,
{ {
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
switch (dpp_inst) { switch (dpp_inst) {
case 0: case 0:
REG_UPDATE(DPPCLK_CTRL, DPPCLK0_EN, enable); REG_UPDATE(DPPCLK_CTRL, DPPCLK0_EN, enable);
if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)
REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK0_ROOT_GATE_DISABLE, enable);
break; break;
case 1: case 1:
REG_UPDATE(DPPCLK_CTRL, DPPCLK1_EN, enable); REG_UPDATE(DPPCLK_CTRL, DPPCLK1_EN, enable);
if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)
REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK1_ROOT_GATE_DISABLE, enable);
break; break;
case 2: case 2:
REG_UPDATE(DPPCLK_CTRL, DPPCLK2_EN, enable); REG_UPDATE(DPPCLK_CTRL, DPPCLK2_EN, enable);
if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)
REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK2_ROOT_GATE_DISABLE, enable);
break; break;
case 3: case 3:
REG_UPDATE(DPPCLK_CTRL, DPPCLK3_EN, enable); REG_UPDATE(DPPCLK_CTRL, DPPCLK3_EN, enable);
if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)
REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK3_ROOT_GATE_DISABLE, enable);
break; break;
default: default:
break; break;
} }
//DC_LOG_DEBUG("%s: dpp_inst(%d) DPPCLK_EN = %d\n", __func__, dpp_inst, enable);
} }
@@ -1163,14 +1160,18 @@ static void dccg35_update_dpp_dto(struct dccg *dccg, int dpp_inst,
ASSERT(false); ASSERT(false);
phase = 0xff; phase = 0xff;
} }
dccg35_set_dppclk_rcg(dccg, dpp_inst, false);
REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0, REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
DPPCLK0_DTO_PHASE, phase, DPPCLK0_DTO_PHASE, phase,
DPPCLK0_DTO_MODULO, modulo); DPPCLK0_DTO_MODULO, modulo);
dcn35_set_dppclk_enable(dccg, dpp_inst, true); dcn35_set_dppclk_enable(dccg, dpp_inst, true);
} else } else {
dcn35_set_dppclk_enable(dccg, dpp_inst, false); dcn35_set_dppclk_enable(dccg, dpp_inst, false);
/*we have this in hwss: disable_plane*/
//dccg35_set_dppclk_rcg(dccg, dpp_inst, true);
}
dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk; dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk;
} }
@@ -1182,6 +1183,7 @@ static void dccg35_set_dppclk_root_clock_gating(struct dccg *dccg,
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp) if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)
return; return;
switch (dpp_inst) { switch (dpp_inst) {
case 0: case 0:
REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK0_ROOT_GATE_DISABLE, enable); REG_UPDATE(DCCG_GATE_DISABLE_CNTL6, DPPCLK0_ROOT_GATE_DISABLE, enable);
@@ -1198,6 +1200,8 @@ static void dccg35_set_dppclk_root_clock_gating(struct dccg *dccg,
default: default:
break; break;
} }
//DC_LOG_DEBUG("%s: dpp_inst(%d) rcg: %d\n", __func__, dpp_inst, enable);
} }
static void dccg35_get_pixel_rate_div( static void dccg35_get_pixel_rate_div(
@@ -1521,28 +1525,30 @@ static void dccg35_set_physymclk_root_clock_gating(
switch (phy_inst) { switch (phy_inst) {
case 0: case 0:
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
PHYASYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); PHYASYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
break; break;
case 1: case 1:
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
PHYBSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); PHYBSYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
break; break;
case 2: case 2:
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
PHYCSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); PHYCSYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
break; break;
case 3: case 3:
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
PHYDSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); PHYDSYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
break; break;
case 4: case 4:
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
PHYESYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0); PHYESYMCLK_ROOT_GATE_DISABLE, enable ? 0 : 1);
break; break;
default: default:
BREAK_TO_DEBUGGER(); BREAK_TO_DEBUGGER();
return; return;
} }
//DC_LOG_DEBUG("%s: dpp_inst(%d) PHYESYMCLK_ROOT_GATE_DISABLE:\n", __func__, phy_inst, enable ? 0 : 1);
} }
static void dccg35_set_physymclk( static void dccg35_set_physymclk(
@@ -1643,6 +1649,8 @@ static void dccg35_dpp_root_clock_control(
return; return;
if (clock_on) { if (clock_on) {
dccg35_set_dppclk_rcg(dccg, dpp_inst, false);
/* turn off the DTO and leave phase/modulo at max */ /* turn off the DTO and leave phase/modulo at max */
dcn35_set_dppclk_enable(dccg, dpp_inst, 1); dcn35_set_dppclk_enable(dccg, dpp_inst, 1);
REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0, REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
@@ -1654,6 +1662,8 @@ static void dccg35_dpp_root_clock_control(
REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0, REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
DPPCLK0_DTO_PHASE, 0, DPPCLK0_DTO_PHASE, 0,
DPPCLK0_DTO_MODULO, 1); DPPCLK0_DTO_MODULO, 1);
/*we have this in hwss: disable_plane*/
//dccg35_set_dppclk_rcg(dccg, dpp_inst, true);
} }
dccg->dpp_clock_gated[dpp_inst] = !clock_on; dccg->dpp_clock_gated[dpp_inst] = !clock_on;

View File

@@ -241,11 +241,6 @@ void dcn35_init_hw(struct dc *dc)
dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub, dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
!dc->res_pool->hubbub->ctx->dc->debug.disable_stutter); !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
} }
if (res_pool->dccg->funcs->dccg_root_gate_disable_control) {
for (i = 0; i < res_pool->pipe_count; i++)
res_pool->dccg->funcs->dccg_root_gate_disable_control(res_pool->dccg, i, 0);
}
for (i = 0; i < res_pool->audio_count; i++) { for (i = 0; i < res_pool->audio_count; i++) {
struct audio *audio = res_pool->audios[i]; struct audio *audio = res_pool->audios[i];
@@ -885,12 +880,18 @@ void dcn35_init_pipes(struct dc *dc, struct dc_state *context)
void dcn35_enable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx, void dcn35_enable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx,
struct dc_state *context) struct dc_state *context)
{ {
struct dpp *dpp = pipe_ctx->plane_res.dpp;
struct dccg *dccg = dc->res_pool->dccg;
/* enable DCFCLK current DCHUB */ /* enable DCFCLK current DCHUB */
pipe_ctx->plane_res.hubp->funcs->hubp_clk_cntl(pipe_ctx->plane_res.hubp, true); pipe_ctx->plane_res.hubp->funcs->hubp_clk_cntl(pipe_ctx->plane_res.hubp, true);
/* initialize HUBP on power up */ /* initialize HUBP on power up */
pipe_ctx->plane_res.hubp->funcs->hubp_init(pipe_ctx->plane_res.hubp); pipe_ctx->plane_res.hubp->funcs->hubp_init(pipe_ctx->plane_res.hubp);
/*make sure DPPCLK is on*/
dccg->funcs->dccg_root_gate_disable_control(dccg, dpp->inst, true);
dpp->funcs->dpp_dppclk_control(dpp, false, true);
/* make sure OPP_PIPE_CLOCK_EN = 1 */ /* make sure OPP_PIPE_CLOCK_EN = 1 */
pipe_ctx->stream_res.opp->funcs->opp_pipe_clock_control( pipe_ctx->stream_res.opp->funcs->opp_pipe_clock_control(
pipe_ctx->stream_res.opp, pipe_ctx->stream_res.opp,
@@ -907,6 +908,7 @@ void dcn35_enable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx,
// Program system aperture settings // Program system aperture settings
pipe_ctx->plane_res.hubp->funcs->hubp_set_vm_system_aperture_settings(pipe_ctx->plane_res.hubp, &apt); pipe_ctx->plane_res.hubp->funcs->hubp_set_vm_system_aperture_settings(pipe_ctx->plane_res.hubp, &apt);
} }
//DC_LOG_DEBUG("%s: dpp_inst(%d) =\n", __func__, dpp->inst);
if (!pipe_ctx->top_pipe if (!pipe_ctx->top_pipe
&& pipe_ctx->plane_state && pipe_ctx->plane_state
@@ -922,6 +924,8 @@ void dcn35_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
{ {
struct hubp *hubp = pipe_ctx->plane_res.hubp; struct hubp *hubp = pipe_ctx->plane_res.hubp;
struct dpp *dpp = pipe_ctx->plane_res.dpp; struct dpp *dpp = pipe_ctx->plane_res.dpp;
struct dccg *dccg = dc->res_pool->dccg;
dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe_ctx); dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe_ctx);
@@ -939,7 +943,8 @@ void dcn35_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
hubp->funcs->hubp_clk_cntl(hubp, false); hubp->funcs->hubp_clk_cntl(hubp, false);
dpp->funcs->dpp_dppclk_control(dpp, false, false); dpp->funcs->dpp_dppclk_control(dpp, false, false);
/*to do, need to support both case*/ dccg->funcs->dccg_root_gate_disable_control(dccg, dpp->inst, false);
hubp->power_gated = true; hubp->power_gated = true;
hubp->funcs->hubp_reset(hubp); hubp->funcs->hubp_reset(hubp);
@@ -951,6 +956,8 @@ void dcn35_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
pipe_ctx->top_pipe = NULL; pipe_ctx->top_pipe = NULL;
pipe_ctx->bottom_pipe = NULL; pipe_ctx->bottom_pipe = NULL;
pipe_ctx->plane_state = NULL; pipe_ctx->plane_state = NULL;
//DC_LOG_DEBUG("%s: dpp_inst(%d)=\n", __func__, dpp->inst);
} }
void dcn35_disable_plane(struct dc *dc, struct dc_state *state, struct pipe_ctx *pipe_ctx) void dcn35_disable_plane(struct dc *dc, struct dc_state *state, struct pipe_ctx *pipe_ctx)