diff options
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-.patch | 356 |
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 + |