From 78707581e9bf5210c2718d3fa8ef8e5067d3d487 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Thu, 9 Jan 2025 15:03:48 -0500 Subject: [PATCH] drm/amd/display: Add hubp cache reset when powergating BugLink: https://bugs.launchpad.net/bugs/2111953 commit 01130f5260e5868fb6b15ab8c00dbc894139f48e upstream. [Why] When HUBP is power gated, the SW state can get out of sync with the hardware state causing cursor to not be programmed correctly. [How] Similar to DPP, add a HUBP reset function which is called wherever HUBP is initialized or powergated. This function will clear the cursor position and attribute cache allowing for proper programming when the HUBP is brought back up. Cc: Mario Limonciello Cc: Alex Deucher Cc: stable@vger.kernel.org Reviewed-by: Sung Lee Signed-off-by: Aric Cyr Signed-off-by: Wayne Lin Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman Signed-off-by: Manuel Diewald Signed-off-by: Mehmet Basaran --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c | 3 +++ drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c | 10 +++++++++- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h | 2 ++ drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c | 1 + drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hubp.c | 1 + drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c | 3 +++ drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c | 3 +++ drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c | 1 + drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c | 1 + drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubp.c | 1 + .../gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 2 ++ .../gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 2 ++ drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h | 2 ++ 13 files changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c index ef52e6b6eccf..5a5bfadd9210 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c @@ -194,6 +194,9 @@ void dpp_reset(struct dpp *dpp_base) dpp->filter_h = NULL; dpp->filter_v = NULL; + memset(&dpp_base->pos, 0, sizeof(dpp_base->pos)); + memset(&dpp_base->att, 0, sizeof(dpp_base->att)); + memset(&dpp->scl_data, 0, sizeof(dpp->scl_data)); memset(&dpp->pwl_data, 0, sizeof(dpp->pwl_data)); } diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c index 22ac2b7e49ae..da963f73829f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c @@ -532,6 +532,12 @@ void hubp1_dcc_control(struct hubp *hubp, bool enable, SECONDARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk); } +void hubp_reset(struct hubp *hubp) +{ + memset(&hubp->pos, 0, sizeof(hubp->pos)); + memset(&hubp->att, 0, sizeof(hubp->att)); +} + void hubp1_program_surface_config( struct hubp *hubp, enum surface_pixel_format format, @@ -1337,8 +1343,9 @@ static void hubp1_wait_pipe_read_start(struct hubp *hubp) void hubp1_init(struct hubp *hubp) { - //do nothing + hubp_reset(hubp); } + static const struct hubp_funcs dcn10_hubp_funcs = { .hubp_program_surface_flip_and_addr = hubp1_program_surface_flip_and_addr, @@ -1351,6 +1358,7 @@ static const struct hubp_funcs dcn10_hubp_funcs = { .hubp_set_vm_context0_settings = hubp1_set_vm_context0_settings, .set_blank = hubp1_set_blank, .dcc_control = hubp1_dcc_control, + .hubp_reset = hubp_reset, .mem_program_viewport = min_set_viewport, .set_hubp_blank_en = hubp1_set_hubp_blank_en, .set_cursor_attributes = hubp1_cursor_set_attributes, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h index 09784222cc03..766a6a2d72e3 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h @@ -745,6 +745,8 @@ void hubp1_dcc_control(struct hubp *hubp, bool enable, enum hubp_ind_block_size independent_64b_blks); +void hubp_reset(struct hubp *hubp); + bool hubp1_program_surface_flip_and_addr( struct hubp *hubp, const struct dc_plane_address *address, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c index 0c999314e01d..f277a12f19b8 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c @@ -1654,6 +1654,7 @@ static struct hubp_funcs dcn20_hubp_funcs = { .set_blank = hubp2_set_blank, .set_blank_regs = hubp2_set_blank_regs, .dcc_control = hubp2_dcc_control, + .hubp_reset = hubp_reset, .mem_program_viewport = min_set_viewport, .set_cursor_attributes = hubp2_cursor_set_attributes, .set_cursor_position = hubp2_cursor_set_position, diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hubp.c index 35dd4bac242a..a95c5a44e685 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hubp.c @@ -116,6 +116,7 @@ static struct hubp_funcs dcn201_hubp_funcs = { .set_cursor_position = hubp1_cursor_set_position, .set_blank = hubp1_set_blank, .dcc_control = hubp1_dcc_control, + .hubp_reset = hubp_reset, .mem_program_viewport = min_set_viewport, .hubp_clk_cntl = hubp1_clk_cntl, .hubp_vtg_sel = hubp1_vtg_sel, diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c index e13d69a22c1c..4e2d9d381db3 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c @@ -811,6 +811,8 @@ static void hubp21_init(struct hubp *hubp) struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp); //hubp[i].HUBPREQ_DEBUG.HUBPREQ_DEBUG[26] = 1; REG_WRITE(HUBPREQ_DEBUG, 1 << 26); + + hubp_reset(hubp); } static struct hubp_funcs dcn21_hubp_funcs = { .hubp_enable_tripleBuffer = hubp2_enable_triplebuffer, @@ -823,6 +825,7 @@ static struct hubp_funcs dcn21_hubp_funcs = { .hubp_set_vm_system_aperture_settings = hubp21_set_vm_system_aperture_settings, .set_blank = hubp1_set_blank, .dcc_control = hubp1_dcc_control, + .hubp_reset = hubp_reset, .mem_program_viewport = hubp21_set_viewport, .set_cursor_attributes = hubp2_cursor_set_attributes, .set_cursor_position = hubp1_cursor_set_position, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c index 75547ce86c09..610a13bb7525 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c @@ -480,6 +480,8 @@ void hubp3_init(struct hubp *hubp) struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); //hubp[i].HUBPREQ_DEBUG.HUBPREQ_DEBUG[26] = 1; REG_WRITE(HUBPREQ_DEBUG, 1 << 26); + + hubp_reset(hubp); } static struct hubp_funcs dcn30_hubp_funcs = { @@ -494,6 +496,7 @@ static struct hubp_funcs dcn30_hubp_funcs = { .set_blank = hubp2_set_blank, .set_blank_regs = hubp2_set_blank_regs, .dcc_control = hubp3_dcc_control, + .hubp_reset = hubp_reset, .mem_program_viewport = min_set_viewport, .set_cursor_attributes = hubp2_cursor_set_attributes, .set_cursor_position = hubp2_cursor_set_position, diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c index 8394e8c06919..a65a0ddee646 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c @@ -79,6 +79,7 @@ static struct hubp_funcs dcn31_hubp_funcs = { .hubp_set_vm_system_aperture_settings = hubp3_set_vm_system_aperture_settings, .set_blank = hubp2_set_blank, .dcc_control = hubp3_dcc_control, + .hubp_reset = hubp_reset, .mem_program_viewport = min_set_viewport, .set_cursor_attributes = hubp2_cursor_set_attributes, .set_cursor_position = hubp2_cursor_set_position, diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c index ca5b4b28a664..45023fa9b708 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c @@ -181,6 +181,7 @@ static struct hubp_funcs dcn32_hubp_funcs = { .set_blank = hubp2_set_blank, .set_blank_regs = hubp2_set_blank_regs, .dcc_control = hubp3_dcc_control, + .hubp_reset = hubp_reset, .mem_program_viewport = min_set_viewport, .set_cursor_attributes = hubp32_cursor_set_attributes, .set_cursor_position = hubp2_cursor_set_position, diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubp.c index 771fcd0d3b99..d2ba3451ec58 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubp.c @@ -199,6 +199,7 @@ struct hubp_funcs dcn35_hubp_funcs = { .hubp_set_vm_system_aperture_settings = hubp3_set_vm_system_aperture_settings, .set_blank = hubp2_set_blank, .dcc_control = hubp3_dcc_control, + .hubp_reset = hubp_reset, .mem_program_viewport = min_set_viewport, .set_cursor_attributes = hubp2_cursor_set_attributes, .set_cursor_position = hubp2_cursor_set_position, diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c index dc4c495cbe3f..0c737ce9336a 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c @@ -1246,6 +1246,7 @@ void dcn10_plane_atomic_power_down(struct dc *dc, if (hws->funcs.hubp_pg_control) hws->funcs.hubp_pg_control(hws, hubp->inst, false); + hubp->funcs->hubp_reset(hubp); dpp->funcs->dpp_reset(dpp); REG_SET(DC_IP_REQUEST_CNTL, 0, @@ -1403,6 +1404,7 @@ void dcn10_init_pipes(struct dc *dc, struct dc_state *context) /* Disable on the current state so the new one isn't cleared. */ pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; + hubp->funcs->hubp_reset(hubp); dpp->funcs->dpp_reset(dpp); pipe_ctx->stream_res.tg = tg; diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c index 7bcabacda00f..9bc5ca1ed10e 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c @@ -800,6 +800,7 @@ void dcn35_init_pipes(struct dc *dc, struct dc_state *context) /* Disable on the current state so the new one isn't cleared. */ pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; + hubp->funcs->hubp_reset(hubp); dpp->funcs->dpp_reset(dpp); pipe_ctx->stream_res.tg = tg; @@ -939,6 +940,7 @@ void dcn35_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx) /*to do, need to support both case*/ hubp->power_gated = true; + hubp->funcs->hubp_reset(hubp); dpp->funcs->dpp_reset(dpp); pipe_ctx->stream = NULL; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h index 7f3f9b69e903..6dd8ad8dd882 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h @@ -108,6 +108,8 @@ struct hubp_funcs { void (*dcc_control)(struct hubp *hubp, bool enable, enum hubp_ind_block_size blk_size); + void (*hubp_reset)(struct hubp *hubp); + void (*mem_program_viewport)( struct hubp *hubp, const struct rect *viewport,