drm/amd/display: Add hubp cache reset when powergating
authorAric Cyr <Aric.Cyr@amd.com>
Thu, 9 Jan 2025 20:03:48 +0000 (15:03 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 24 Jan 2025 14:56:22 +0000 (09:56 -0500)
[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 <mario.limonciello@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
Reviewed-by: Sung Lee <sung.lee@amd.com>
Signed-off-by: Aric Cyr <Aric.Cyr@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
14 files changed:
drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp.c
drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c
drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.h
drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c
drivers/gpu/drm/amd/display/dc/hubp/dcn201/dcn201_hubp.c
drivers/gpu/drm/amd/display/dc/hubp/dcn21/dcn21_hubp.c
drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c
drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.c
drivers/gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c
drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c
drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h

index e1da48b..961d893 100644 (file)
@@ -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));
 }
index 8364c9f..9b02660 100644 (file)
@@ -546,6 +546,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,
@@ -1351,8 +1357,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,
@@ -1365,6 +1372,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,
index a85dc3b..c7765e6 100644 (file)
@@ -746,6 +746,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,
index c74f6a3..a748e6a 100644 (file)
@@ -1674,6 +1674,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,
index 65c6280..ec88ee4 100644 (file)
@@ -121,6 +121,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,
index edbdb8c..e274048 100644 (file)
@@ -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,
index 12b282e..be0ac61 100644 (file)
@@ -499,6 +499,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 = {
@@ -513,6 +515,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,
index 46b804e..c2900c7 100644 (file)
@@ -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,
index 8b5bd73..edd3789 100644 (file)
@@ -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,
index faf37fe..5661d7a 100644 (file)
@@ -199,6 +199,7 @@ static 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,
index 28cecea..d8b81ad 100644 (file)
@@ -141,7 +141,7 @@ void hubp401_update_mall_sel(struct hubp *hubp, uint32_t mall_sel, bool c_cursor
 
 void hubp401_init(struct hubp *hubp)
 {
-       //For now nothing to do, HUBPREQ_DEBUG_DB register is removed on DCN4x.
+       hubp_reset(hubp);
 }
 
 void hubp401_vready_at_or_After_vsync(struct hubp *hubp,
@@ -998,6 +998,7 @@ static struct hubp_funcs dcn401_hubp_funcs = {
        .hubp_set_vm_system_aperture_settings = hubp3_set_vm_system_aperture_settings,
        .set_blank = hubp2_set_blank,
        .set_blank_regs = hubp2_set_blank_regs,
+       .hubp_reset = hubp_reset,
        .mem_program_viewport = hubp401_set_viewport,
        .set_cursor_attributes  = hubp32_cursor_set_attributes,
        .set_cursor_position    = hubp401_cursor_set_position,
index 681bb92..44e405e 100644 (file)
@@ -1286,6 +1286,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,
@@ -1447,6 +1448,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;
index 59fc1c1..623cde7 100644 (file)
@@ -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;
@@ -956,6 +957,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;
index 2a530a4..b610beb 100644 (file)
@@ -163,6 +163,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,