summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/dc/dcn10
diff options
context:
space:
mode:
authorYongqiang Sun2017-11-02 18:24:20 +0100
committerAlex Deucher2017-12-06 18:47:33 +0100
commit0af4096db9ec6a7b12475bf8d21ee5464722c7a2 (patch)
tree50f4ae97b83fb7c13255a0a86546d3bad141fe2b /drivers/gpu/drm/amd/display/dc/dcn10
parentdrm/amd/display: add warning on long reg_wait (diff)
downloadkernel-qcow2-linux-0af4096db9ec6a7b12475bf8d21ee5464722c7a2.tar.gz
kernel-qcow2-linux-0af4096db9ec6a7b12475bf8d21ee5464722c7a2.tar.xz
kernel-qcow2-linux-0af4096db9ec6a7b12475bf8d21ee5464722c7a2.zip
drm/amd/display: Modified front end initiail in init_hw
Optimized front end initial sequence, reset MPC module properly. Signed-off-by: Yongqiang Sun <yongqiang.sun@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>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn10')
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c66
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c11
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c11
3 files changed, 71 insertions, 17 deletions
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 bd30d49e574a..5d1fb1c297a3 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
@@ -616,10 +616,6 @@ static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
struct hubp *hubp = dc->res_pool->hubps[fe_idx];
struct mpc *mpc = dc->res_pool->mpc;
int opp_id = hubp->opp_id;
- struct timing_generator *tg = pipe_ctx->stream_res.tg;
-
- if (tg == NULL)
- return;
if (opp_id == 0xf)
return;
@@ -700,6 +696,8 @@ static void dcn10_init_hw(struct dc *dc)
struct abm *abm = dc->res_pool->abm;
struct dmcu *dmcu = dc->res_pool->dmcu;
struct dce_hwseq *hws = dc->hwseq;
+ struct dc_bios *dcb = dc->ctx->dc_bios;
+ struct dc_state *context = dc->current_state;
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
REG_WRITE(REFCLK_CNTL, 0);
@@ -720,9 +718,10 @@ static void dcn10_init_hw(struct dc *dc)
}
/* end of FPGA. Below if real ASIC */
- bios_golden_init(dc);
-
- disable_vga(dc->hwseq);
+ if (!dcb->funcs->is_accelerated_mode(dcb)) {
+ bios_golden_init(dc);
+ disable_vga(dc->hwseq);
+ }
for (i = 0; i < dc->link_count; i++) {
/* Power up AND update implementation according to the
@@ -738,22 +737,55 @@ static void dcn10_init_hw(struct dc *dc)
}
for (i = 0; i < dc->res_pool->pipe_count; i++) {
- struct dpp *dpp = dc->res_pool->dpps[i];
struct timing_generator *tg = dc->res_pool->timing_generators[i];
- dpp->funcs->dpp_reset(dpp);
- dc->res_pool->mpc->funcs->remove(
- dc->res_pool->mpc, &(dc->res_pool->opps[i]->mpc_tree),
- dc->res_pool->opps[i]->inst, i);
+ if (tg->funcs->is_tg_enabled(tg))
+ tg->funcs->lock(tg);
+ }
- /* Blank controller using driver code instead of
- * command table.
- */
- tg->funcs->set_blank(tg, true);
- hwss_wait_for_blank_complete(tg);
+ /* Blank controller using driver code instead of
+ * command table.
+ */
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ struct timing_generator *tg = dc->res_pool->timing_generators[i];
+
+ if (tg->funcs->is_tg_enabled(tg)) {
+ tg->funcs->set_blank(tg, true);
+ hwss_wait_for_blank_complete(tg);
+ }
+ }
+
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ struct timing_generator *tg = dc->res_pool->timing_generators[i];
+ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+ pipe_ctx->stream_res.tg = tg;
+ pipe_ctx->pipe_idx = i;
+ pipe_ctx->plane_res.hubp = dc->res_pool->hubps[i];
+ pipe_ctx->plane_res.hubp->mpcc_id = i;
+ pipe_ctx->plane_res.hubp->opp_id =
+ dc->res_pool->mpc->funcs->get_opp_id(dc->res_pool->mpc, i);
+
+ plane_atomic_disconnect(dc, pipe_ctx);
+ }
+
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ struct timing_generator *tg = dc->res_pool->timing_generators[i];
+ if (tg->funcs->is_tg_enabled(tg))
+ tg->funcs->unlock(tg);
+ }
+
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ struct timing_generator *tg = dc->res_pool->timing_generators[i];
+ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+ plane_atomic_disable(dc, pipe_ctx);
plane_atomic_power_down(dc, i);
+ pipe_ctx->stream_res.tg = NULL;
+ pipe_ctx->plane_res.hubp = NULL;
+
tg->funcs->tg_init(tg);
}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
index 76573e1f5b01..5028619d4fb4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
@@ -335,11 +335,22 @@ void mpc10_update_blend_mode(
MPCC_ALPHA_MULTIPLIED_MODE, cfg->pre_multiplied_alpha);
}
+static int mpc10_get_opp_id(struct mpc *mpc, int mpcc_id)
+{
+ struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
+ int opp_id = 0xF;
+
+ REG_GET(MPCC_OPP_ID[mpcc_id], MPCC_OPP_ID, &opp_id);
+
+ return opp_id;
+}
+
const struct mpc_funcs dcn10_mpc_funcs = {
.add = mpc10_mpcc_add,
.remove = mpc10_mpcc_remove,
.wait_for_idle = mpc10_assert_idle_mpcc,
.update_blend_mode = mpc10_update_blend_mode,
+ .get_opp_id = mpc10_get_opp_id,
};
void dcn10_mpc_construct(struct dcn10_mpc *mpc10,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c
index 90e94a3c11a6..d248067810c8 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c
@@ -1212,6 +1212,16 @@ static void tgn10_tg_init(struct timing_generator *tg)
REG_UPDATE(OPTC_INPUT_GLOBAL_CONTROL, OPTC_UNDERFLOW_CLEAR, 1);
}
+static bool tgn10_is_tg_enabled(struct timing_generator *tg)
+{
+ struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ uint32_t otg_enabled = 0;
+
+ REG_GET(OTG_CONTROL, OTG_MASTER_EN, &otg_enabled);
+
+ return (otg_enabled != 0);
+
+}
static const struct timing_generator_funcs dcn10_tg_funcs = {
.validate_timing = tgn10_validate_timing,
.program_timing = tgn10_program_timing,
@@ -1243,6 +1253,7 @@ static const struct timing_generator_funcs dcn10_tg_funcs = {
.is_stereo_left_eye = tgn10_is_stereo_left_eye,
.set_blank_data_double_buffer = tgn10_set_blank_data_double_buffer,
.tg_init = tgn10_tg_init,
+ .is_tg_enabled = tgn10_is_tg_enabled,
};
void dcn10_timing_generator_init(struct dcn10_timing_generator *tgn10)