diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0132-drm-amd-display-set-blank-functionality.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0132-drm-amd-display-set-blank-functionality.patch | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0132-drm-amd-display-set-blank-functionality.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0132-drm-amd-display-set-blank-functionality.patch new file mode 100644 index 00000000..5170e61c --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0132-drm-amd-display-set-blank-functionality.patch @@ -0,0 +1,287 @@ +From a28efa8938defc8973807cb77f4556755495629b Mon Sep 17 00:00:00 2001 +From: Hersen Wu <hersenxs.wu@amd.com> +Date: Fri, 6 Jan 2017 16:23:18 -0500 +Subject: [PATCH 0132/4131] drm/amd/display: set blank functionality + +1. remove the sleep mechanism while set_blank true from +the timing generator. +Since Hw sequencer is the one that manages the flow +he will be responsible for wait for blanck in a critical places. + +Signed-off-by: Leon Elazar <leon.elazar@amd.com> +Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> +Acked-by: Harry Wentland <Harry.Wentland@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + .../gpu/drm/amd/display/dc/core/dc_hw_sequencer.c | 20 +++++++++++ + .../amd/display/dc/dce110/dce110_hw_sequencer.c | 12 +++---- + .../display/dc/dce110/dce110_timing_generator.c | 28 +--------------- + .../display/dc/dce110/dce110_timing_generator.h | 2 +- + .../display/dc/dce110/dce110_timing_generator_v.c | 39 +++------------------- + .../drm/amd/display/dc/inc/hw/timing_generator.h | 2 +- + drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h | 3 ++ + 7 files changed, 37 insertions(+), 69 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c +index d5cffa5..9f462a2 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c +@@ -91,3 +91,23 @@ void color_space_to_black_color( + break; + } + } ++ ++bool hwss_wait_for_blank_complete( ++ struct timing_generator *tg) ++{ ++ int counter; ++ ++ for (counter = 0; counter < 100; counter++) { ++ if (tg->funcs->is_blanked(tg)) ++ break; ++ ++ msleep(1); ++ } ++ ++ if (counter == 100) { ++ dm_error("DC: failed to blank crtc!\n"); ++ return false; ++ } ++ ++ return true; ++} +diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +index 7c27a82..965e47a 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +@@ -623,7 +623,7 @@ static void program_scaler(const struct core_dc *dc, + &pipe_ctx->scl_data); + } + +-static enum dc_status prog_pixclk_crtc_otg( ++static enum dc_status dce110_prog_pixclk_crtc_otg( + struct pipe_ctx *pipe_ctx, + struct validate_context *context, + struct core_dc *dc) +@@ -641,6 +641,7 @@ static enum dc_status prog_pixclk_crtc_otg( + pipe_ctx->tg->funcs->set_blank_color( + pipe_ctx->tg, + &black_color); ++ + /* + * Must blank CRTC after disabling power gating and before any + * programming, otherwise CRTC will be hung in bad state +@@ -1047,7 +1048,8 @@ static void reset_single_pipe_hw_ctx( + struct validate_context *context) + { + core_link_disable_stream(pipe_ctx); +- if (!pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, true)) { ++ pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, true); ++ if (!hwss_wait_for_blank_complete(pipe_ctx->tg)) { + dm_error("DC: failed to blank crtc!\n"); + BREAK_TO_DEBUGGER(); + } +@@ -1560,9 +1562,6 @@ static void update_plane_addr(const struct core_dc *dc, + surface->public.flip_immediate); + + surface->status.requested_address = surface->public.address; +- +- if (surface->public.visible) +- pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, false); + } + + void dce110_update_pending_status(struct pipe_ctx *pipe_ctx) +@@ -1718,6 +1717,7 @@ static void init_hw(struct core_dc *dc) + /* Blank controller using driver code instead of + * command table. */ + tg->funcs->set_blank(tg, true); ++ hwss_wait_for_blank_complete(tg); + } + + for (i = 0; i < dc->res_pool->audio_count; i++) { +@@ -2002,7 +2002,7 @@ static const struct hw_sequencer_funcs dce110_funcs = { + .set_drr = set_drr, + .set_static_screen_control = set_static_screen_control, + .reset_hw_ctx_wrap = reset_hw_ctx_wrap, +- .prog_pixclk_crtc_otg = prog_pixclk_crtc_otg, ++ .prog_pixclk_crtc_otg = dce110_prog_pixclk_crtc_otg, + }; + + bool dce110_hw_sequencer_construct(struct core_dc *dc) +diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c +index e70704d..f4b8576 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c ++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c +@@ -1808,7 +1808,7 @@ bool dce110_tg_is_blanked(struct timing_generator *tg) + return false; + } + +-bool dce110_tg_set_blank(struct timing_generator *tg, ++void dce110_tg_set_blank(struct timing_generator *tg, + bool enable_blanking) + { + struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); +@@ -1824,8 +1824,6 @@ bool dce110_tg_set_blank(struct timing_generator *tg, + value = 0; + + if (enable_blanking) { +- int counter; +- + set_reg_field_value( + value, + 1, +@@ -1834,32 +1832,8 @@ bool dce110_tg_set_blank(struct timing_generator *tg, + + dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL), value); + +- for (counter = 0; counter < 100; counter++) { +- value = dm_read_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL)); +- +- if (get_reg_field_value( +- value, +- CRTC_BLANK_CONTROL, +- CRTC_BLANK_DATA_EN) == 1 && +- get_reg_field_value( +- value, +- CRTC_BLANK_CONTROL, +- CRTC_CURRENT_BLANK_STATE) == 1) +- break; +- +- msleep(1); +- } +- +- if (counter == 100) { +- dm_logger_write(tg->ctx->logger, LOG_ERROR, +- "timing generator %d blank timing out.\n", +- tg110->controller_id); +- return false; +- } + } else + dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_BLANK_CONTROL), 0); +- +- return true; + } + + bool dce110_tg_validate_timing(struct timing_generator *tg, +diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h +index 3990650..dcb49fe 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h ++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h +@@ -257,7 +257,7 @@ void dce110_tg_program_timing(struct timing_generator *tg, + + bool dce110_tg_is_blanked(struct timing_generator *tg); + +-bool dce110_tg_set_blank(struct timing_generator *tg, ++void dce110_tg_set_blank(struct timing_generator *tg, + bool enable_blanking); + + bool dce110_tg_validate_timing(struct timing_generator *tg, +diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c +index 3bf3179..682a3de 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c ++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c +@@ -72,12 +72,11 @@ static bool dce110_timing_generator_v_disable_crtc(struct timing_generator *tg) + return true; + } + +-static bool dce110_timing_generator_v_blank_crtc(struct timing_generator *tg) ++static void dce110_timing_generator_v_blank_crtc(struct timing_generator *tg) + { + struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); + uint32_t addr = mmCRTCV_BLANK_CONTROL; + uint32_t value = dm_read_reg(tg->ctx, addr); +- uint8_t counter = 100; + + set_reg_field_value( + value, +@@ -92,35 +91,9 @@ static bool dce110_timing_generator_v_blank_crtc(struct timing_generator *tg) + CRTC_BLANK_DE_MODE); + + dm_write_reg(tg->ctx, addr, value); +- +- while (counter > 0) { +- value = dm_read_reg(tg->ctx, addr); +- +- if (get_reg_field_value( +- value, +- CRTCV_BLANK_CONTROL, +- CRTC_BLANK_DATA_EN) == 1 && +- get_reg_field_value( +- value, +- CRTCV_BLANK_CONTROL, +- CRTC_CURRENT_BLANK_STATE) == 1) +- break; +- +- msleep(1); +- counter--; +- } +- +- if (!counter) { +- dm_logger_write(tg->ctx->logger, LOG_ERROR, +- "timing generator %d blank timing out.\n", +- tg110->controller_id); +- return false; +- } +- +- return true; + } + +-static bool dce110_timing_generator_v_unblank_crtc(struct timing_generator *tg) ++static void dce110_timing_generator_v_unblank_crtc(struct timing_generator *tg) + { + uint32_t addr = mmCRTCV_BLANK_CONTROL; + uint32_t value = dm_read_reg(tg->ctx, addr); +@@ -138,8 +111,6 @@ static bool dce110_timing_generator_v_unblank_crtc(struct timing_generator *tg) + CRTC_BLANK_DE_MODE); + + dm_write_reg(tg->ctx, addr, value); +- +- return true; + } + + static bool dce110_timing_generator_v_is_in_vertical_blank( +@@ -429,13 +400,13 @@ static void dce110_timing_generator_v_enable_advanced_request( + dm_write_reg(tg->ctx, addr, value); + } + +-static bool dce110_timing_generator_v_set_blank(struct timing_generator *tg, ++static void dce110_timing_generator_v_set_blank(struct timing_generator *tg, + bool enable_blanking) + { + if (enable_blanking) +- return dce110_timing_generator_v_blank_crtc(tg); ++ dce110_timing_generator_v_blank_crtc(tg); + else +- return dce110_timing_generator_v_unblank_crtc(tg); ++ dce110_timing_generator_v_unblank_crtc(tg); + } + + static void dce110_timing_generator_v_program_timing(struct timing_generator *tg, +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h +index 6ac609f..baa9445 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h +@@ -129,7 +129,7 @@ struct timing_generator_funcs { + uint32_t early_cntl); + void (*wait_for_state)(struct timing_generator *tg, + enum crtc_state state); +- bool (*set_blank)(struct timing_generator *tg, ++ void (*set_blank)(struct timing_generator *tg, + bool enable_blanking); + bool (*is_blanked)(struct timing_generator *tg); + void (*set_overscan_blank_color) (struct timing_generator *tg, const struct tg_color *color); +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 895c446..562c897 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +@@ -151,4 +151,7 @@ void color_space_to_black_color( + enum dc_color_space colorspace, + struct tg_color *black_color); + ++bool hwss_wait_for_blank_complete( ++ struct timing_generator *tg); ++ + #endif /* __DC_HW_SEQUENCER_H__ */ +-- +2.7.4 + |