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 e1da48b05d0094a103f6dfbefe7bf736a26fcfd4..961d8936150ab75fea169f6c701b094645233c93 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 8364c9f9231a403d6b2443ed03c9a8b49fda57bf..9b026600b90e8bb548ddd59e4045e4fc07a74ea7 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 a85dc3be786f7846bb6b1b1a8ac0f90300bb7337..c7765e6f09e6dab7afad9fba34e7e02c40228dfb 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 c74f6a3313a27c470feebe92ca294afe875c1f27..a748e6ab9c82892e2b65414fb3946094e32e93bd 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 65c628078ca2ab2547d3aeaeb8198ad69537c449..ec88ee424a7f4de1631b4f24a6d5b096c930aeba 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 edbdb8c88d5c8527d7a2e207cc18a68df714f4a4..e2740482e1cfbe8d06a6dadfacff9b56fe01382c 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 12b282ed7067b48a0cc2fb32cc39a71acab8364e..be0ac613675a2add73e1f783b17c606b0c5af671 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 46b804ed05fba10399e13eb0eca85a4d92b0cd71..c2900c79a2d35781de19f1d4cbce6fa14a332be9 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 8b5bd73b8094a0c37337431b6dcfd513813916bf..edd37898d5500003b8925dba4877ac1b3950bf4d 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 faf37febc6fb86b77395edfcd637ad3f8aa51b12..5661d7a80d543ed78250a1eee709bef4de7c1d18 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 28ceceaf9e3169ab49d8e1536affdca1660def8b..d8b81ad69e35aee2f01248e81e2ce79a796f9b24 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 681bb92c60690d965cc65c1a2d1858867b992e3b..44e405e9bc971544f3aa0b9f460cb3ed9e65e818 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 59fc1c114fbe292b9b88fa3c6af4484dbe43cba9..623cde76debfbafe219c8558143a1065c14391e3 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 2a530a4a39f7f5061e333235ac88e896afe5e405..b610beb075d545fb48bb60d366a96735103dd9c7 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,