diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1297-drm-amd-display-dcn-add-check-surface-in_use.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/1297-drm-amd-display-dcn-add-check-surface-in_use.patch | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1297-drm-amd-display-dcn-add-check-surface-in_use.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1297-drm-amd-display-dcn-add-check-surface-in_use.patch new file mode 100644 index 00000000..9dca3e0b --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1297-drm-amd-display-dcn-add-check-surface-in_use.patch @@ -0,0 +1,240 @@ +From 30811246cbd6287b00b9f8b018b9c809b35471f8 Mon Sep 17 00:00:00 2001 +From: Charlene Liu <charlene.liu@amd.com> +Date: Mon, 4 Feb 2019 14:36:13 -0500 +Subject: [PATCH 1297/2940] drm/amd/display: dcn add check surface in_use + +Driver need to poll the SURFACE_INUSE register to determine when to +start the new task and write data to the checked surface. + +Implement the wait functions, and add the necessary hubbub registers. + +Signed-off-by: Charlene Liu <charlene.liu@amd.com> +Reviewed-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> +Acked-by: Leo Li <sunpeng.li@amd.com> +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 3 ++ + .../drm/amd/display/dc/dcn10/dcn10_hubbub.c | 46 +++++++++++++++++++ + .../drm/amd/display/dc/dcn10/dcn10_hubbub.h | 25 ++++++++-- + .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 22 ++++++++- + .../gpu/drm/amd/display/dc/inc/hw/dchubbub.h | 3 ++ + .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 2 + + 6 files changed, 97 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index 0099e625ac88..73660bf903ae 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -1723,6 +1723,9 @@ static void commit_planes_for_stream(struct dc *dc, + + if (!pipe_ctx->plane_state) + continue; ++ /*make sure hw finished surface update*/ ++ if (dc->hwss.wait_surface_safe_to_update) ++ dc->hwss.wait_surface_safe_to_update(dc, pipe_ctx); + + /* Full fe update*/ + if (update_type == UPDATE_TYPE_FAST) +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c +index e161ad836812..9c6217b99692 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c +@@ -642,6 +642,50 @@ void hubbub1_soft_reset(struct hubbub *hubbub, bool reset) + DCHUBBUB_GLOBAL_SOFT_RESET, reset_en); + } + ++static bool hubbub1_is_surf_still_in_update(struct hubbub *hubbub, uint32_t hbup_inst) ++{ ++ struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); ++ uint32_t still_used_by_dcn = 0; ++ ++ switch (hbup_inst) { ++ case 0: ++ REG_GET(SURFACE_CHECK0_ADDRESS_MSB, ++ CHECKER0_SURFACE_INUSE, ++ &still_used_by_dcn); ++ break; ++ case 1: ++ REG_GET(SURFACE_CHECK1_ADDRESS_MSB, ++ CHECKER1_SURFACE_INUSE, ++ &still_used_by_dcn); ++ break; ++ case 2: ++ REG_GET(SURFACE_CHECK2_ADDRESS_MSB, ++ CHECKER2_SURFACE_INUSE, ++ &still_used_by_dcn); ++ break; ++ case 3: ++ REG_GET(SURFACE_CHECK3_ADDRESS_MSB, ++ CHECKER3_SURFACE_INUSE, ++ &still_used_by_dcn); ++ break; ++ default: ++ break; ++ } ++ return (still_used_by_dcn == 1); ++} ++ ++void hubbub1_wait_for_safe_surf_update(struct hubbub *hubbub, uint32_t hbup_inst) ++{ ++ uint32_t still_used_by_dcn = 0, count = 0; ++ ++ do { ++ still_used_by_dcn = hubbub1_is_surf_still_in_update(hubbub, hbup_inst); ++ udelay(1); ++ count++; ++ } while (still_used_by_dcn == 1 && count < 100); ++ ASSERT(count < 100); ++} ++ + static bool hubbub1_dcc_support_swizzle( + enum swizzle_mode_values swizzle, + unsigned int bytes_per_element, +@@ -860,12 +904,14 @@ static bool hubbub1_get_dcc_compression_cap(struct hubbub *hubbub, + return true; + } + ++ + static const struct hubbub_funcs hubbub1_funcs = { + .update_dchub = hubbub1_update_dchub, + .dcc_support_swizzle = hubbub1_dcc_support_swizzle, + .dcc_support_pixel_format = hubbub1_dcc_support_pixel_format, + .get_dcc_compression_cap = hubbub1_get_dcc_compression_cap, + .wm_read_state = hubbub1_wm_read_state, ++ .wait_for_surf_safe_update = hubbub1_wait_for_safe_surf_update, + }; + + void hubbub1_construct(struct hubbub *hubbub, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h +index 9cd4a5194154..f352e7ab0da6 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h +@@ -52,7 +52,11 @@ + SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \ + SR(DCHUBBUB_TEST_DEBUG_INDEX), \ + SR(DCHUBBUB_TEST_DEBUG_DATA),\ +- SR(DCHUBBUB_SOFT_RESET) ++ SR(DCHUBBUB_SOFT_RESET),\ ++ SR(SURFACE_CHECK0_ADDRESS_MSB),\ ++ SR(SURFACE_CHECK1_ADDRESS_MSB),\ ++ SR(SURFACE_CHECK2_ADDRESS_MSB),\ ++ SR(SURFACE_CHECK3_ADDRESS_MSB) + + #define HUBBUB_SR_WATERMARK_REG_LIST()\ + SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A),\ +@@ -116,6 +120,10 @@ struct dcn_hubbub_registers { + uint32_t DCN_VM_AGP_BOT; + uint32_t DCN_VM_AGP_TOP; + uint32_t DCN_VM_AGP_BASE; ++ uint32_t SURFACE_CHECK0_ADDRESS_MSB; ++ uint32_t SURFACE_CHECK1_ADDRESS_MSB; ++ uint32_t SURFACE_CHECK2_ADDRESS_MSB; ++ uint32_t SURFACE_CHECK3_ADDRESS_MSB; + }; + + /* set field name */ +@@ -133,7 +141,11 @@ struct dcn_hubbub_registers { + HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, mask_sh), \ + HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, mask_sh), \ + HUBBUB_SF(DCHUBBUB_ARB_SAT_LEVEL, DCHUBBUB_ARB_SAT_LEVEL, mask_sh), \ +- HUBBUB_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, mask_sh) ++ HUBBUB_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, mask_sh),\ ++ HUBBUB_SF(SURFACE_CHECK0_ADDRESS_MSB, CHECKER0_SURFACE_INUSE, mask_sh),\ ++ HUBBUB_SF(SURFACE_CHECK1_ADDRESS_MSB, CHECKER1_SURFACE_INUSE, mask_sh),\ ++ HUBBUB_SF(SURFACE_CHECK2_ADDRESS_MSB, CHECKER2_SURFACE_INUSE, mask_sh),\ ++ HUBBUB_SF(SURFACE_CHECK3_ADDRESS_MSB, CHECKER3_SURFACE_INUSE, mask_sh) + + #define HUBBUB_MASK_SH_LIST_DCN10(mask_sh)\ + HUBBUB_MASK_SH_LIST_DCN(mask_sh), \ +@@ -167,7 +179,12 @@ struct dcn_hubbub_registers { + type FB_OFFSET;\ + type AGP_BOT;\ + type AGP_TOP;\ +- type AGP_BASE ++ type AGP_BASE;\ ++ type CHECKER0_SURFACE_INUSE;\ ++ type CHECKER1_SURFACE_INUSE;\ ++ type CHECKER2_SURFACE_INUSE;\ ++ type CHECKER3_SURFACE_INUSE ++ + + + struct dcn_hubbub_shift { +@@ -215,6 +232,8 @@ void hubbub1_wm_read_state(struct hubbub *hubbub, + struct dcn_hubbub_wm *wm); + + void hubbub1_soft_reset(struct hubbub *hubbub, bool reset); ++ ++void hubbub1_wait_for_safe_surf_update(struct hubbub *hubbub, uint32_t hbup_inst); + void hubbub1_construct(struct hubbub *hubbub, + struct dc_context *ctx, + const struct dcn_hubbub_registers *hubbub_regs, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +index 2a3bd75344fd..1131b0775534 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +@@ -88,6 +88,24 @@ static void log_mpc_crc(struct dc *dc, + REG_READ(DPP_TOP0_DPP_CRC_VAL_B_A), REG_READ(DPP_TOP0_DPP_CRC_VAL_R_G)); + } + ++void dcn10_wait_for_surface_safe_to_use(struct dc *dc, ++ struct pipe_ctx *pipe_ctx) ++{ ++ struct hubbub *hubbub = dc->res_pool->hubbub; ++ ++ if (!pipe_ctx->plane_state) ++ return; ++ if (!pipe_ctx->stream) ++ return; ++ ++ if (!pipe_ctx->plane_state->visible) ++ return; ++ if (hubbub->funcs->wait_for_surf_safe_update) { ++ hubbub->funcs->wait_for_surf_safe_update(dc->res_pool->hubbub, ++ pipe_ctx->plane_res.hubp->inst); ++ } ++} ++ + void dcn10_log_hubbub_state(struct dc *dc, struct dc_log_buffer_ctx *log_ctx) + { + struct dc_context *dc_ctx = dc->ctx; +@@ -2945,7 +2963,9 @@ static const struct hw_sequencer_funcs dcn10_funcs = { + .disable_stream_gating = NULL, + .enable_stream_gating = NULL, + .setup_periodic_interrupt = dcn10_setup_periodic_interrupt, +- .setup_vupdate_interrupt = dcn10_setup_vupdate_interrupt ++ .setup_vupdate_interrupt = dcn10_setup_vupdate_interrupt, ++ .wait_surface_safe_to_update = dcn10_wait_for_surface_safe_to_use, ++ + }; + + +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h +index 9d2d8e51306c..ac97d18d5568 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h +@@ -73,6 +73,9 @@ struct hubbub_funcs { + + void (*wm_read_state)(struct hubbub *hubbub, + struct dcn_hubbub_wm *wm); ++ ++ void (*wait_for_surf_safe_update)(struct hubbub *hubbub, ++ uint32_t hbup_inst); + }; + + struct hubbub { +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +index 7676f25216b1..0ede4b604b77 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +@@ -232,6 +232,8 @@ struct hw_sequencer_funcs { + void (*setup_periodic_interrupt)(struct pipe_ctx *pipe_ctx, enum vline_select vline); + void (*setup_vupdate_interrupt)(struct pipe_ctx *pipe_ctx); + ++ void (*wait_surface_safe_to_update)(struct dc *dc, ++ struct pipe_ctx *pipe_ctx); + }; + + void color_space_to_black_color( +-- +2.17.1 + |