]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 8 Feb 2025 09:02:26 +0000 (10:02 +0100)
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 <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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
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 22ac2b7e49aeae66e6ce182f77be943df14151f4..da963f73829f6c388a5b465e2a327cf91f974c27 100644 (file)
@@ -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,
index 69119b2fdce23b878f9148e62cfa37a7820ac30f..193e48b440ef1850f346a6e70a816fc4637db17d 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 0637e4c552d8a29cda4bb087b391b2d6d7305805..b405fa22f87a9e4f8b24db3f91713699dda0d5ea 100644 (file)
@@ -1660,6 +1660,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 cd2bfcc51276503db21c0b7e5d8567c53b16a2ae..6efcb10abf3deed953a175673d34c09855b795f3 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 e13d69a22c1c7fc91fe69696408a46951deb1ceb..4e2d9d381db3936ab46526c73279af2616416509 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 60a64d290352743f2d6ad1148be45d275df89bd0..c55b1b8be8ffd6cb70b8ef13b4bca2017fcf7f74 100644 (file)
@@ -483,6 +483,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 = {
@@ -497,6 +499,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 8394e8c069199fd7d63367a0aeaca723899bf99d..a65a0ddee64672bca7ae4bfcef9ffe97ec6ca460 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 ca5b4b28a66441bca370578d11d4e05097db9d4c..45023fa9b708dcf0620bc85161999518f0eda4c7 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 d1f05b82b3dd5cb37db23abf994d2e2c6421bc07..e7625290c0e467ffb6a9398c0861ce1a886faef6 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 b1ebf5053b4fc3286b0d03a1d8f506caa690d195..2d52100510f05f596a7eec2805a30524c3e7cc9a 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,
@@ -974,6 +974,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 e599cdc465bfd2a1936f447696482930d6296846..463f7abe35a7dd2f7d5fff6e7393538ef4efb83a 100644 (file)
@@ -788,6 +788,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;
@@ -944,6 +945,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 16580d62427891fe91001f0e0da8ea301db6b216..eec16b0a199dd4983660b9fb60a9629b28172ff1 100644 (file)
@@ -152,6 +152,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,