aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/0132-drm-amd-display-set-blank-functionality.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/0132-drm-amd-display-set-blank-functionality.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/0132-drm-amd-display-set-blank-functionality.patch287
1 files changed, 287 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/0132-drm-amd-display-set-blank-functionality.patch b/common/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/common/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
+