aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3112-drm-amd-display-Use-real-BE-and-FE-index-to-program-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3112-drm-amd-display-Use-real-BE-and-FE-index-to-program-.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3112-drm-amd-display-Use-real-BE-and-FE-index-to-program-.patch356
1 files changed, 356 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3112-drm-amd-display-Use-real-BE-and-FE-index-to-program-.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3112-drm-amd-display-Use-real-BE-and-FE-index-to-program-.patch
new file mode 100644
index 00000000..edd8411f
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3112-drm-amd-display-Use-real-BE-and-FE-index-to-program-.patch
@@ -0,0 +1,356 @@
+From bbdcc329b8aca375c265e504d55d6c538e9692c1 Mon Sep 17 00:00:00 2001
+From: Yongqiang Sun <yongqiang.sun@amd.com>
+Date: Tue, 19 Dec 2017 16:47:02 -0500
+Subject: [PATCH 3112/4131] drm/amd/display: Use real BE and FE index to
+ program regs.
+
+In case of some pipes are fused, pipe_idx should not
+be used to program pipe regs. Instead of that, BE and FE
+inst number should be used for reg index.
+
+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>
+---
+ drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 1 +
+ drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 2 +
+ .../amd/display/dc/dce110/dce110_hw_sequencer.c | 14 ++---
+ .../drm/amd/display/dc/dce110/dce110_resource.c | 4 +-
+ .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 63 ++++++++++++++--------
+ .../gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 3 +-
+ drivers/gpu/drm/amd/display/dc/inc/core_types.h | 1 +
+ 7 files changed, 55 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
+index 331891c..c6a7507 100644
+--- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
++++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
+@@ -486,6 +486,7 @@ static void split_stream_across_pipes(
+ secondary_pipe->plane_res.ipp = pool->ipps[secondary_pipe->pipe_idx];
+ secondary_pipe->plane_res.xfm = pool->transforms[secondary_pipe->pipe_idx];
+ secondary_pipe->plane_res.dpp = pool->dpps[secondary_pipe->pipe_idx];
++ secondary_pipe->plane_res.mpcc_inst = pool->dpps[secondary_pipe->pipe_idx]->inst;
+ if (primary_pipe->bottom_pipe) {
+ ASSERT(primary_pipe->bottom_pipe != secondary_pipe);
+ secondary_pipe->bottom_pipe = primary_pipe->bottom_pipe;
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+index cacda2e..211210c 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+@@ -1054,6 +1054,7 @@ static int acquire_first_split_pipe(
+ pipe_ctx->plane_res.ipp = pool->ipps[i];
+ pipe_ctx->plane_res.dpp = pool->dpps[i];
+ pipe_ctx->stream_res.opp = pool->opps[i];
++ pipe_ctx->plane_res.mpcc_inst = pool->dpps[i]->inst;
+ pipe_ctx->pipe_idx = i;
+
+ pipe_ctx->stream = stream;
+@@ -1406,6 +1407,7 @@ static int acquire_first_free_pipe(
+ pipe_ctx->plane_res.xfm = pool->transforms[i];
+ pipe_ctx->plane_res.dpp = pool->dpps[i];
+ pipe_ctx->stream_res.opp = pool->opps[i];
++ pipe_ctx->plane_res.mpcc_inst = pool->dpps[i]->inst;
+ pipe_ctx->pipe_idx = i;
+
+
+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 57bc994..f415f38 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
+@@ -625,7 +625,7 @@ static enum dc_status bios_parser_crtc_source_select(
+ const struct dc_sink *sink = pipe_ctx->stream->sink;
+
+ crtc_source_select.engine_id = pipe_ctx->stream_res.stream_enc->id;
+- crtc_source_select.controller_id = pipe_ctx->pipe_idx + 1;
++ crtc_source_select.controller_id = pipe_ctx->stream_res.tg->inst + 1;
+ /*TODO: Need to un-hardcode color depth, dp_audio and account for
+ * the case where signal and sink signal is different (translator
+ * encoder)*/
+@@ -1091,7 +1091,7 @@ static void build_audio_output(
+
+ audio_output->pll_info.dto_source =
+ translate_to_dto_source(
+- pipe_ctx->pipe_idx + 1);
++ pipe_ctx->stream_res.tg->inst + 1);
+
+ /* TODO hard code to enable for now. Need get from stream */
+ audio_output->pll_info.ss_enabled = true;
+@@ -2147,7 +2147,7 @@ static void program_surface_visibility(const struct dc *dc,
+ } else if (!pipe_ctx->plane_state->visible)
+ blank_target = true;
+
+- dce_set_blender_mode(dc->hwseq, pipe_ctx->pipe_idx, blender_mode);
++ dce_set_blender_mode(dc->hwseq, pipe_ctx->stream_res.tg->inst, blender_mode);
+ pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target);
+
+ }
+@@ -2189,7 +2189,7 @@ static void set_plane_config(
+ memset(&tbl_entry, 0, sizeof(tbl_entry));
+ adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
+
+- dce_enable_fe_clock(dc->hwseq, pipe_ctx->pipe_idx, true);
++ dce_enable_fe_clock(dc->hwseq, mi->inst, true);
+
+ set_default_colors(pipe_ctx);
+ if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
+@@ -2495,7 +2495,7 @@ void dce110_fill_display_configs(
+
+ num_cfgs++;
+ cfg->signal = pipe_ctx->stream->signal;
+- cfg->pipe_idx = pipe_ctx->pipe_idx;
++ cfg->pipe_idx = pipe_ctx->stream_res.tg->inst;
+ cfg->src_height = stream->src.height;
+ cfg->src_width = stream->src.width;
+ cfg->ddi_channel_mapping =
+@@ -2659,7 +2659,7 @@ static void dce110_program_front_end_for_pipe(
+ memset(&adjust, 0, sizeof(adjust));
+ adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
+
+- dce_enable_fe_clock(dc->hwseq, pipe_ctx->pipe_idx, true);
++ dce_enable_fe_clock(dc->hwseq, mi->inst, true);
+
+ set_default_colors(pipe_ctx);
+ if (pipe_ctx->stream->csc_color_matrix.enable_adjustment
+@@ -2817,7 +2817,7 @@ static void dce110_apply_ctx_for_surface(
+
+ static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx)
+ {
+- int fe_idx = pipe_ctx->pipe_idx;
++ int fe_idx = pipe_ctx->plane_res.mi->inst;
+
+ /* Do not power down fe when stream is active on dce*/
+ if (dc->current_state->res_ctx.pipe_ctx[fe_idx].stream)
+diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
+index 5228ee7..9adb5e9 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
+@@ -700,7 +700,7 @@ static void get_pixel_clock_parameters(
+ pixel_clk_params->requested_pix_clk = stream->timing.pix_clk_khz;
+ pixel_clk_params->encoder_object_id = stream->sink->link->link_enc->id;
+ pixel_clk_params->signal_type = pipe_ctx->stream->signal;
+- pixel_clk_params->controller_id = pipe_ctx->pipe_idx + 1;
++ pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1;
+ /* TODO: un-hardcode*/
+ pixel_clk_params->requested_sym_clk = LINK_RATE_LOW *
+ LINK_RATE_REF_FREQ_IN_KHZ;
+@@ -973,7 +973,7 @@ static struct pipe_ctx *dce110_acquire_underlay(
+
+ dc->hwss.enable_display_power_gating(
+ dc,
+- pipe_ctx->pipe_idx,
++ pipe_ctx->stream_res.tg->inst,
+ dcb, PIPE_GATING_CONTROL_DISABLE);
+
+ /*
+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 0e58185..ad77223 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
+@@ -597,8 +597,8 @@ static void dcn10_verify_allow_pstate_change_high(struct dc *dc)
+ /* trigger HW to start disconnect plane from stream on the next vsync */
+ static void plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
+ {
+- int fe_idx = pipe_ctx->pipe_idx;
+- struct hubp *hubp = dc->res_pool->hubps[fe_idx];
++ struct hubp *hubp = pipe_ctx->plane_res.hubp;
++ int dpp_id = pipe_ctx->plane_res.dpp->inst;
+ struct mpc *mpc = dc->res_pool->mpc;
+ int opp_id;
+ struct mpc_tree *mpc_tree_params;
+@@ -609,7 +609,7 @@ static void plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
+ struct output_pixel_processor *opp = dc->res_pool->opps[opp_id];
+
+ mpc_tree_params = &(opp->mpc_tree_params);
+- mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, fe_idx);
++ mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id);
+ if (mpcc_to_remove != NULL)
+ break;
+ }
+@@ -619,7 +619,7 @@ static void plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
+ return;
+
+ mpc->funcs->remove_mpcc(mpc, mpc_tree_params, mpcc_to_remove);
+- dc->res_pool->opps[opp_id]->mpcc_disconnect_pending[fe_idx] = true;
++ dc->res_pool->opps[opp_id]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
+
+ dc->optimized_required = true;
+
+@@ -630,21 +630,21 @@ static void plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
+ dcn10_verify_allow_pstate_change_high(dc);
+ }
+
+-static void plane_atomic_power_down(struct dc *dc, int fe_idx)
++static void plane_atomic_power_down(struct dc *dc, struct pipe_ctx *pipe_ctx)
+ {
+ struct dce_hwseq *hws = dc->hwseq;
+- struct dpp *dpp = dc->res_pool->dpps[fe_idx];
++ struct dpp *dpp = pipe_ctx->plane_res.dpp;
+
+ if (REG(DC_IP_REQUEST_CNTL)) {
+ REG_SET(DC_IP_REQUEST_CNTL, 0,
+ IP_REQUEST_EN, 1);
+- dpp_pg_control(hws, fe_idx, false);
+- hubp_pg_control(hws, fe_idx, false);
++ dpp_pg_control(hws, dpp->inst, false);
++ hubp_pg_control(hws, pipe_ctx->plane_res.hubp->inst, false);
+ dpp->funcs->dpp_reset(dpp);
+ REG_SET(DC_IP_REQUEST_CNTL, 0,
+ IP_REQUEST_EN, 0);
+ dm_logger_write(dc->ctx->logger, LOG_DEBUG,
+- "Power gated front end %d\n", fe_idx);
++ "Power gated front end %d\n", pipe_ctx->pipe_idx);
+ }
+ }
+
+@@ -653,16 +653,16 @@ static void plane_atomic_power_down(struct dc *dc, int fe_idx)
+ */
+ static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
+ {
+- int fe_idx = pipe_ctx->pipe_idx;
+ struct dce_hwseq *hws = dc->hwseq;
+- struct hubp *hubp = dc->res_pool->hubps[fe_idx];
++ struct hubp *hubp = pipe_ctx->plane_res.hubp;
+ int opp_id = hubp->opp_id;
++ int dpp_id = pipe_ctx->plane_res.dpp->inst;
+
+ dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe_ctx);
+
+ hubp->funcs->hubp_clk_cntl(hubp, false);
+
+- REG_UPDATE(DPP_CONTROL[fe_idx],
++ REG_UPDATE(DPP_CONTROL[dpp_id],
+ DPP_CLOCK_ENABLE, 0);
+
+ if (opp_id != 0xf && dc->res_pool->opps[opp_id]->mpc_tree_params.opp_list == NULL)
+@@ -672,7 +672,7 @@ static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
+ hubp->power_gated = true;
+ dc->optimized_required = false; /* We're powering off, no need to optimize */
+
+- plane_atomic_power_down(dc, fe_idx);
++ plane_atomic_power_down(dc, pipe_ctx);
+
+ pipe_ctx->stream = NULL;
+ memset(&pipe_ctx->stream_res, 0, sizeof(pipe_ctx->stream_res));
+@@ -768,18 +768,21 @@ static void dcn10_init_hw(struct dc *dc)
+ struct timing_generator *tg = dc->res_pool->timing_generators[i];
+ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+ struct hubp *hubp = dc->res_pool->hubps[i];
++ struct dpp *dpp = dc->res_pool->dpps[i];
+
+ pipe_ctx->stream_res.tg = tg;
+ pipe_ctx->pipe_idx = i;
+
+ pipe_ctx->plane_res.hubp = hubp;
+- hubp->mpcc_id = i;
++ pipe_ctx->plane_res.dpp = dpp;
++ pipe_ctx->plane_res.mpcc_inst = dpp->inst;
++ hubp->mpcc_id = dpp->inst;
+ hubp->opp_id = 0xf;
+ hubp->power_gated = false;
+
+ dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
+ dc->res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
+- dc->res_pool->opps[i]->mpcc_disconnect_pending[i] = true;
++ dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
+ pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
+
+ plane_atomic_disconnect(dc, pipe_ctx);
+@@ -1323,7 +1326,7 @@ static void dcn10_enable_plane(
+ undo_DEGVIDCN10_253_wa(dc);
+
+ power_on_plane(dc->hwseq,
+- pipe_ctx->pipe_idx);
++ pipe_ctx->plane_res.hubp->inst);
+
+ /* enable DCFCLK current DCHUB */
+ pipe_ctx->plane_res.hubp->funcs->hubp_clk_cntl(pipe_ctx->plane_res.hubp, true);
+@@ -1687,7 +1690,7 @@ static void update_dchubp_dpp(
+ if (plane_state->update_flags.bits.full_update) {
+ enable_dppclk(
+ dc->hwseq,
+- pipe_ctx->pipe_idx,
++ pipe_ctx->plane_res.dpp->inst,
+ pipe_ctx->stream_res.pix_clk_params.requested_pix_clk,
+ context->bw.dcn.calc_clk.dppclk_div);
+ dc->current_state->bw.dcn.cur_clk.dppclk_div =
+@@ -2231,12 +2234,24 @@ static void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx, struct dc *dc)
+ return;
+ }
+
++static struct hubp *get_hubp_by_inst(struct resource_pool *res_pool, int mpcc_inst)
++{
++ int i;
++
++ for (i = 0; i < res_pool->pipe_count; i++) {
++ if (res_pool->hubps[i]->inst == mpcc_inst)
++ return res_pool->hubps[i];
++ }
++ ASSERT(false);
++ return NULL;
++}
++
+ static void dcn10_wait_for_mpcc_disconnect(
+ struct dc *dc,
+ struct resource_pool *res_pool,
+ struct pipe_ctx *pipe_ctx)
+ {
+- int i;
++ int mpcc_inst;
+
+ if (dc->debug.sanity_checks) {
+ dcn10_verify_allow_pstate_change_high(dc);
+@@ -2245,11 +2260,13 @@ static void dcn10_wait_for_mpcc_disconnect(
+ if (!pipe_ctx->stream_res.opp)
+ return;
+
+- for (i = 0; i < MAX_PIPES; i++) {
+- if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[i]) {
+- res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, i);
+- pipe_ctx->stream_res.opp->mpcc_disconnect_pending[i] = false;
+- res_pool->hubps[i]->funcs->set_blank(res_pool->hubps[i], true);
++ for (mpcc_inst = 0; mpcc_inst < MAX_PIPES; mpcc_inst++) {
++ if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst]) {
++ struct hubp *hubp = get_hubp_by_inst(res_pool, mpcc_inst);
++
++ res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, mpcc_inst);
++ pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst] = false;
++ hubp->funcs->set_blank(hubp, true);
+ /*dm_logger_write(dc->ctx->logger, LOG_ERROR,
+ "[debug_mpo: wait_for_mpcc finished waiting on mpcc %d]\n",
+ i);*/
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+index 494f35f..4610d9c 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+@@ -818,7 +818,7 @@ static void get_pixel_clock_parameters(
+ pixel_clk_params->requested_pix_clk = stream->timing.pix_clk_khz;
+ pixel_clk_params->encoder_object_id = stream->sink->link->link_enc->id;
+ pixel_clk_params->signal_type = pipe_ctx->stream->signal;
+- pixel_clk_params->controller_id = pipe_ctx->pipe_idx + 1;
++ pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1;
+ /* TODO: un-hardcode*/
+ pixel_clk_params->requested_sym_clk = LINK_RATE_LOW *
+ LINK_RATE_REF_FREQ_IN_KHZ;
+@@ -965,6 +965,7 @@ static struct pipe_ctx *dcn10_acquire_idle_pipe_for_layer(
+ idle_pipe->plane_res.hubp = pool->hubps[idle_pipe->pipe_idx];
+ idle_pipe->plane_res.ipp = pool->ipps[idle_pipe->pipe_idx];
+ idle_pipe->plane_res.dpp = pool->dpps[idle_pipe->pipe_idx];
++ idle_pipe->plane_res.mpcc_inst = pool->dpps[idle_pipe->pipe_idx]->inst;
+
+ return idle_pipe;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+index d697105..8dcaf91 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+@@ -188,6 +188,7 @@ struct plane_resource {
+ struct input_pixel_processor *ipp;
+ struct transform *xfm;
+ struct dpp *dpp;
++ uint8_t mpcc_inst;
+ };
+
+ struct pipe_ctx {
+--
+2.7.4
+