summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHersen Wu <hersenxs.wu@amd.com>2017-01-06 16:23:18 -0500
committerAlex Deucher <alexander.deucher@amd.com>2017-09-26 17:09:13 -0400
commit4b5e7d620901778b24a2980bbc9941eff9b47f77 (patch)
tree3c74bf153f9cef478702cbede856eb6f8788e00e
parentb06b7680e341151c8c60b07ddc6f5e63e7392c17 (diff)
downloadlinux-stable-4b5e7d620901778b24a2980bbc9941eff9b47f77.tar.gz
linux-stable-4b5e7d620901778b24a2980bbc9941eff9b47f77.tar.bz2
linux-stable-4b5e7d620901778b24a2980bbc9941eff9b47f77.zip
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>
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c20
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c12
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c28
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c39
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h3
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 d5cffa51ca96..9f462a299ff3 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 7c27a820e5be..965e47a5acfa 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 e70704d1ba87..f4b8576a0546 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 39906502ad5c..dcb49fe452c5 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 3bf3179e07c5..682a3de7ba48 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 6ac609f6f89f..baa9445833fb 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 895c446cebf9..562c8978fe9c 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__ */