diff options
Diffstat (limited to 'meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0556-drm-amd-display-fix-dcn-pipe-reset-sequence.patch')
-rw-r--r-- | meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0556-drm-amd-display-fix-dcn-pipe-reset-sequence.patch | 819 |
1 files changed, 0 insertions, 819 deletions
diff --git a/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0556-drm-amd-display-fix-dcn-pipe-reset-sequence.patch b/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0556-drm-amd-display-fix-dcn-pipe-reset-sequence.patch deleted file mode 100644 index 3ead018a..00000000 --- a/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0556-drm-amd-display-fix-dcn-pipe-reset-sequence.patch +++ /dev/null @@ -1,819 +0,0 @@ -From 14d47cae2bff887e9999c4e1824abe8692f2065b Mon Sep 17 00:00:00 2001 -From: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> -Date: Wed, 14 Jun 2017 18:58:04 -0400 -Subject: [PATCH 0556/4131] drm/amd/display: fix dcn pipe reset sequence - -This change fixes dcn10 front end reset sequence. Previously we -would reset front end during flip which led to issues -in certain MPO and 4k/5k scenarios. We would also never properly -power gate our front end. - -Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> -Reviewed-by: Charlene Liu <Charlene.Liu@amd.com> -Acked-by: Harry Wentland <Harry.Wentland@amd.com> -Signed-off-by: Alex Deucher <alexander.deucher@amd.com> ---- - .../drm/amd/display/amdgpu_dm/amdgpu_dm_types.c | 2 +- - drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 19 +- - drivers/gpu/drm/amd/display/dc/core/dc.c | 22 +- - drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 7 + - drivers/gpu/drm/amd/display/dc/dc.h | 3 - - .../amd/display/dc/dce110/dce110_hw_sequencer.c | 17 +- - .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 226 ++++++++++----------- - drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c | 17 +- - drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h | 4 +- - .../amd/display/dc/dcn10/dcn10_timing_generator.c | 6 +- - .../amd/display/dc/dcn10/dcn10_timing_generator.h | 4 + - drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h | 1 + - drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h | 2 +- - 13 files changed, 155 insertions(+), 175 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c -index abbf575..6054c2f 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c -@@ -2525,7 +2525,7 @@ static void amdgpu_dm_do_flip( - surface_updates->flip_addr = &addr; - - -- dc_update_surfaces_for_stream(adev->dm.dc, surface_updates, 1, acrtc->stream); -+ dc_update_surfaces_and_stream(adev->dm.dc, surface_updates, 1, acrtc->stream, NULL); - - DRM_DEBUG_DRIVER("%s Flipping to hi: 0x%x, low: 0x%x \n", - __func__, -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 3ec702f..00961bc 100644 ---- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c -+++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c -@@ -511,12 +511,14 @@ static void split_stream_across_pipes( - struct pipe_ctx *primary_pipe, - struct pipe_ctx *secondary_pipe) - { -+ int pipe_idx = secondary_pipe->pipe_idx; -+ - if (!primary_pipe->surface) - return; - -- secondary_pipe->stream = primary_pipe->stream; -- secondary_pipe->tg = primary_pipe->tg; -+ *secondary_pipe = *primary_pipe; - -+ secondary_pipe->pipe_idx = pipe_idx; - secondary_pipe->mpcc = pool->mpcc[secondary_pipe->pipe_idx]; - secondary_pipe->mi = pool->mis[secondary_pipe->pipe_idx]; - secondary_pipe->ipp = pool->ipps[secondary_pipe->pipe_idx]; -@@ -528,8 +530,6 @@ static void split_stream_across_pipes( - } - primary_pipe->bottom_pipe = secondary_pipe; - secondary_pipe->top_pipe = primary_pipe; -- secondary_pipe->surface = primary_pipe->surface; -- secondary_pipe->pipe_dlg_param = primary_pipe->pipe_dlg_param; - - resource_build_scaling_params(primary_pipe); - resource_build_scaling_params(secondary_pipe); -@@ -1011,10 +1011,13 @@ bool dcn_validate_bandwidth( - dcn_bw_calc_rq_dlg_ttu(dc, v, hsplit_pipe); - } else if (hsplit_pipe && hsplit_pipe->surface == pipe->surface) { - /* merge previously split pipe */ -- if (pipe->bottom_pipe->bottom_pipe) -- pipe->bottom_pipe->bottom_pipe->top_pipe = pipe; -- memset(pipe->bottom_pipe, 0, sizeof(*pipe->bottom_pipe)); -- pipe->bottom_pipe = pipe->bottom_pipe->bottom_pipe; -+ pipe->bottom_pipe = hsplit_pipe->bottom_pipe; -+ if (hsplit_pipe->bottom_pipe) -+ hsplit_pipe->bottom_pipe->top_pipe = pipe; -+ hsplit_pipe->surface = NULL; -+ hsplit_pipe->stream = NULL; -+ hsplit_pipe->top_pipe = NULL; -+ hsplit_pipe->bottom_pipe = NULL; - resource_build_scaling_params(pipe); - } - /* for now important to do this after pipe split for building e2e params */ -diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c -index 18fde50..2f481ef 100644 ---- a/drivers/gpu/drm/amd/display/dc/core/dc.c -+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c -@@ -963,11 +963,8 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc) - - for (i = 0; i < core_dc->res_pool->pipe_count; i++) - if (context->res_ctx.pipe_ctx[i].stream == NULL -- || context->res_ctx.pipe_ctx[i].surface == NULL) { -- context->res_ctx.pipe_ctx[i].pipe_idx = i; -- core_dc->hwss.power_down_front_end( -- core_dc, &context->res_ctx.pipe_ctx[i]); -- } -+ || context->res_ctx.pipe_ctx[i].surface == NULL) -+ core_dc->hwss.power_down_front_end(core_dc, i); - - /* 3rd param should be true, temp w/a for RV*/ - #if defined(CONFIG_DRM_AMD_DC_DCN1_0) -@@ -989,7 +986,6 @@ bool dc_commit_surfaces_to_stream( - struct dc_plane_info plane_info[MAX_SURFACES]; - struct dc_scaling_info scaling_info[MAX_SURFACES]; - int i; -- bool ret; - struct dc_stream_update *stream_update = - dm_alloc(sizeof(struct dc_stream_update)); - -@@ -1038,10 +1034,10 @@ bool dc_commit_surfaces_to_stream( - new_surface_count, - dc_stream, stream_update); - -- ret = dc_post_update_surfaces_to_stream(dc); -+ dc_post_update_surfaces_to_stream(dc); - - dm_free(stream_update); -- return ret; -+ return true; - } - - static bool is_surface_in_context( -@@ -1217,14 +1213,6 @@ enum surface_update_type dc_check_update_surfaces_for_stream( - return overall_type; - } - --void dc_update_surfaces_for_stream(struct dc *dc, -- struct dc_surface_update *surface_updates, int surface_count, -- const struct dc_stream *dc_stream) --{ -- dc_update_surfaces_and_stream(dc, surface_updates, surface_count, -- dc_stream, NULL); --} -- - enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL; - - void dc_update_surfaces_and_stream(struct dc *dc, -@@ -1401,7 +1389,7 @@ void dc_update_surfaces_and_stream(struct dc *dc, - } - } - -- if (!surface_count) /* reset */ -+ if (surface_count == 0) - core_dc->hwss.apply_ctx_for_surface(core_dc, NULL, context); - - /* Lock pipes for provided surfaces, or all active if full update*/ -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 9aff47e..04579d0 100644 ---- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c -@@ -1096,6 +1096,10 @@ bool resource_attach_surfaces_to_context( - free_pipe->surface = surface; - - if (tail_pipe) { -+ free_pipe->tg = tail_pipe->tg; -+ free_pipe->stream_enc = tail_pipe->stream_enc; -+ free_pipe->audio = tail_pipe->audio; -+ free_pipe->clock_source = tail_pipe->clock_source; - free_pipe->top_pipe = tail_pipe; - tail_pipe->bottom_pipe = free_pipe; - } -@@ -2300,6 +2304,9 @@ bool pipe_need_reprogram( - struct pipe_ctx *pipe_ctx_old, - struct pipe_ctx *pipe_ctx) - { -+ if (!pipe_ctx_old->stream) -+ return false; -+ - if (pipe_ctx_old->stream->sink != pipe_ctx->stream->sink) - return true; - -diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h -index cb70b6d..18f6858 100644 ---- a/drivers/gpu/drm/amd/display/dc/dc.h -+++ b/drivers/gpu/drm/amd/display/dc/dc.h -@@ -415,9 +415,6 @@ bool dc_commit_surfaces_to_stream( - bool dc_post_update_surfaces_to_stream( - struct dc *dc); - --void dc_update_surfaces_for_stream(struct dc *dc, struct dc_surface_update *updates, -- int surface_count, const struct dc_stream *stream); -- - /* Surface update type is used by dc_update_surfaces_and_stream - * The update type is determined at the very beginning of the function based - * on parameters passed in and decides how much programming (or updating) is -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 0bab85b..fd1cb7f 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 -@@ -1185,8 +1185,7 @@ static void disable_vga_and_power_gate_all_controllers( - enable_display_pipe_clock_gating(ctx, - true); - -- dc->hwss.power_down_front_end( -- dc, &dc->current_context->res_ctx.pipe_ctx[i]); -+ dc->hwss.power_down_front_end(dc, i); - } - } - -@@ -1340,7 +1339,7 @@ static void reset_single_pipe_hw_ctx( - resource_unreference_clock_source(&context->res_ctx, dc->res_pool, - &pipe_ctx->clock_source); - -- dc->hwss.power_down_front_end((struct core_dc *)dc, pipe_ctx); -+ dc->hwss.power_down_front_end((struct core_dc *)dc, pipe_ctx->pipe_idx); - - pipe_ctx->stream = NULL; - } -@@ -2538,17 +2537,17 @@ static void dce110_apply_ctx_for_surface( - } - } - --static void dce110_power_down_fe(struct core_dc *dc, struct pipe_ctx *pipe) -+static void dce110_power_down_fe(struct core_dc *dc, int fe_idx) - { - /* Do not power down fe when stream is active on dce*/ -- if (pipe->stream) -+ if (dc->current_context->res_ctx.pipe_ctx[fe_idx].stream) - return; - - dc->hwss.enable_display_power_gating( -- dc, pipe->pipe_idx, dc->ctx->dc_bios, PIPE_GATING_CONTROL_ENABLE); -- if (pipe->xfm) -- pipe->xfm->funcs->transform_reset(pipe->xfm); -- memset(&pipe->scl_data, 0, sizeof(struct scaler_data)); -+ dc, fe_idx, dc->ctx->dc_bios, PIPE_GATING_CONTROL_ENABLE); -+ -+ dc->res_pool->transforms[fe_idx]->funcs->transform_reset( -+ dc->res_pool->transforms[fe_idx]); - } - - static const struct hw_sequencer_funcs dce110_funcs = { -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 edcd736..d0bddfd 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 -@@ -116,18 +116,6 @@ static const struct dcn10_hwseq_reg_offsets reg_offsets[] = { - HWSEQ_REG_SET_N(reg, 1, FD(reg##__##field), val) - - /* TODO should be moved to OTG */ --static void lock_otg_master_update( -- struct dc_context *ctx, -- uint8_t inst) --{ -- uint32_t inst_offset = reg_offsets[inst].otg; -- -- HWSEQ_REG_UPDATE(OTG0_OTG_GLOBAL_CONTROL0, -- OTG_MASTER_UPDATE_LOCK_SEL, inst); -- -- HWSEQ_REG_UPDATE(OTG0_OTG_MASTER_UPDATE_LOCK, -- OTG_MASTER_UPDATE_LOCK, 1); --} - - static bool unlock_master_tg_and_wait( - struct dc_context *ctx, -@@ -148,19 +136,6 @@ static bool unlock_master_tg_and_wait( - return true; - } - --/* TODO: should be moved to OTG ? */ --static void unlock_otg_master( -- struct dc_context *ctx, -- uint8_t inst) --{ -- uint32_t inst_offset = reg_offsets[inst].otg; -- -- /* unlock master locker */ -- HWSEQ_REG_UPDATE(OTG0_OTG_MASTER_UPDATE_LOCK, -- OTG_MASTER_UPDATE_LOCK, 0); --} -- -- - static void wait_no_outstanding_request( - struct dc_context *ctx, - uint8_t plane_id) -@@ -489,8 +464,7 @@ static void hubp_pg_control( - - static void power_on_plane( - struct dc_context *ctx, -- uint8_t plane_id, -- uint8_t inst) -+ int plane_id) - { - uint32_t inst_offset = 0; - -@@ -500,6 +474,8 @@ static void power_on_plane( - hubp_pg_control(ctx, plane_id, true); - HWSEQ_REG_SET(DC_IP_REQUEST_CNTL, - IP_REQUEST_EN, 0); -+ dm_logger_write(ctx->logger, LOG_DC, -+ "Un-gated front end for pipe %d\n", plane_id); - } - - /* fully check bios enabledisplaypowergating table. dal only need dce init -@@ -596,13 +572,13 @@ static void init_hw(struct core_dc *dc) - dc->res_pool->mpcc[i]; - struct mpcc_cfg mpcc_cfg; - -- lock_otg_master_update(dc->ctx, tg->inst); -+ tg->funcs->lock(tg); - mpcc_cfg.opp_id = 0xf; - mpcc_cfg.top_dpp_id = 0xf; - mpcc_cfg.bot_mpcc_id = 0xf; - mpcc_cfg.top_of_tree = true; - mpcc->funcs->set(mpcc, &mpcc_cfg); -- unlock_otg_master(dc->ctx, tg->inst); -+ tg->funcs->unlock(tg); - - tg->funcs->disable_vga(tg); - /* Blank controller using driver code instead of -@@ -822,56 +798,85 @@ static void reset_back_end_for_pipe( - return; - - pipe_ctx->stream = NULL; -+ dm_logger_write(dc->ctx->logger, LOG_DC, -+ "Reset back end for pipe %d, tg:%d\n", -+ pipe_ctx->pipe_idx, pipe_ctx->tg->inst); - } - --static void reset_front_end_for_pipe( -+static void reset_front_end( - struct core_dc *dc, -- struct pipe_ctx *pipe_ctx, -- struct validate_context *context) -+ int fe_idx) - { - struct mpcc_cfg mpcc_cfg; -+ struct mem_input *mi = dc->res_pool->mis[fe_idx]; -+ struct transform *xfm = dc->res_pool->transforms[fe_idx]; -+ struct mpcc *mpcc = dc->res_pool->mpcc[fe_idx]; -+ struct timing_generator *tg = dc->res_pool->timing_generators[mpcc->opp_id]; - -- if (!pipe_ctx->surface) -+ /*Already reset*/ -+ if (mpcc->opp_id == 0xf) - return; - -- pipe_ctx->mi->funcs->dcc_control(pipe_ctx->mi, false, false); -- -- lock_otg_master_update(dc->ctx, pipe_ctx->tg->inst); -+ mi->funcs->dcc_control(mi, false, false); -+ tg->funcs->lock(tg); - - mpcc_cfg.opp_id = 0xf; - mpcc_cfg.top_dpp_id = 0xf; - mpcc_cfg.bot_mpcc_id = 0xf; -- mpcc_cfg.top_of_tree = !pipe_ctx->top_pipe; -- pipe_ctx->mpcc->funcs->set(pipe_ctx->mpcc, &mpcc_cfg); -- -- pipe_ctx->top_pipe = NULL; -- pipe_ctx->bottom_pipe = NULL; -+ mpcc_cfg.top_of_tree = tg->inst == mpcc->inst; -+ mpcc->funcs->set(mpcc, &mpcc_cfg); - -- unlock_master_tg_and_wait(dc->ctx, pipe_ctx->tg->inst); -+ unlock_master_tg_and_wait(dc->ctx, tg->inst); -+ mpcc->funcs->wait_for_idle(mpcc); -+ mi->funcs->set_blank(mi, true); -+ wait_no_outstanding_request(dc->ctx, fe_idx); -+ disable_clocks(dc->ctx, fe_idx); - -- pipe_ctx->mi->funcs->set_blank(pipe_ctx->mi, true); -+ xfm->funcs->transform_reset(xfm); - -- wait_no_outstanding_request(dc->ctx, pipe_ctx->pipe_idx); -+ dm_logger_write(dc->ctx->logger, LOG_DC, -+ "Reset front end %d\n", -+ fe_idx); -+} - -- disable_clocks(dc->ctx, pipe_ctx->pipe_idx); -+static void dcn10_power_down_fe(struct core_dc *dc, int fe_idx) -+{ -+ struct dc_context *ctx = dc->ctx; -+ uint32_t inst_offset = 0; - -- pipe_ctx->xfm->funcs->transform_reset(pipe_ctx->xfm); -+ reset_front_end(dc, fe_idx); - -+ HWSEQ_REG_SET(DC_IP_REQUEST_CNTL, -+ IP_REQUEST_EN, 1); -+ dpp_pg_control(ctx, fe_idx, false); -+ hubp_pg_control(ctx, fe_idx, false); -+ HWSEQ_REG_SET(DC_IP_REQUEST_CNTL, -+ IP_REQUEST_EN, 0); - dm_logger_write(dc->ctx->logger, LOG_DC, -- "Reset front end for pipe %d\n", -- pipe_ctx->pipe_idx); -- -- pipe_ctx->surface = NULL; -+ "Power gated front end %d\n", fe_idx); - } - --static void reset_hw_ctx(struct core_dc *dc, -- struct validate_context *context, -- void (*reset)(struct core_dc *dc, -- struct pipe_ctx *pipe_ctx, -- struct validate_context *context)) -+static void reset_hw_ctx_wrap( -+ struct core_dc *dc, -+ struct validate_context *context) - { - int i; - -+ /* Reset Front End*/ -+ for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) { -+ struct pipe_ctx *pipe_ctx_old = -+ &dc->current_context->res_ctx.pipe_ctx[i]; -+ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; -+ -+ /*if (!pipe_ctx_old->stream) -+ continue;*/ -+ -+ if (!pipe_ctx->stream || !pipe_ctx->surface) -+ dcn10_power_down_fe(dc, i); -+ else if (pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) -+ reset_front_end(dc, i); -+ } -+ /* Reset Back End*/ - for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) { - struct pipe_ctx *pipe_ctx_old = - &dc->current_context->res_ctx.pipe_ctx[i]; -@@ -882,23 +887,13 @@ static void reset_hw_ctx(struct core_dc *dc, - - if (!pipe_ctx->stream || - pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) -- reset(dc, pipe_ctx_old, dc->current_context); -+ reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_context); - } - } - --static void reset_hw_ctx_wrap( -- struct core_dc *dc, -- struct validate_context *context) --{ -- /* Reset Front End*/ -- reset_hw_ctx(dc, context, reset_front_end_for_pipe); -- /* Reset Back End*/ -- reset_hw_ctx(dc, context, reset_back_end_for_pipe); --} -- - --static bool patch_address_for_sbs_tb_stereo(struct pipe_ctx *pipe_ctx, -- PHYSICAL_ADDRESS_LOC *addr) -+static bool patch_address_for_sbs_tb_stereo( -+ struct pipe_ctx *pipe_ctx, PHYSICAL_ADDRESS_LOC *addr) - { - struct core_surface *surface = pipe_ctx->surface; - bool sec_split = pipe_ctx->top_pipe && -@@ -936,8 +931,7 @@ static void update_plane_addr(const struct core_dc *dc, struct pipe_ctx *pipe_ct - } - - static bool dcn10_set_input_transfer_func( -- struct pipe_ctx *pipe_ctx, -- const struct core_surface *surface) -+ struct pipe_ctx *pipe_ctx, const struct core_surface *surface) - { - struct input_pixel_processor *ipp = pipe_ctx->ipp; - const struct core_transfer_func *tf = NULL; -@@ -950,8 +944,8 @@ static bool dcn10_set_input_transfer_func( - tf = DC_TRANSFER_FUNC_TO_CORE(surface->public.in_transfer_func); - - if (surface->public.gamma_correction && dce_use_lut(surface)) -- ipp->funcs->ipp_program_input_lut(ipp, -- surface->public.gamma_correction); -+ ipp->funcs->ipp_program_input_lut(ipp, -+ surface->public.gamma_correction); - - if (tf == NULL) - ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS); -@@ -1333,8 +1327,6 @@ static void dcn10_pipe_control_lock( - struct pipe_ctx *pipe, - bool lock) - { -- struct dce_hwseq *hws = hws = dc->hwseq; -- - /* use TG master update lock to lock everything on the TG - * therefore only top pipe need to lock - */ -@@ -1342,9 +1334,9 @@ static void dcn10_pipe_control_lock( - return; - - if (lock) -- dcn10_lock(pipe->tg); -+ pipe->tg->funcs->lock(pipe->tg); - else -- dcn10_unlock(pipe->tg); -+ pipe->tg->funcs->unlock(pipe->tg); - } - - static bool wait_for_reset_trigger_to_occur( -@@ -1543,7 +1535,7 @@ static void dcn10_power_on_fe( - struct dc_surface *dc_surface = &pipe_ctx->surface->public; - - power_on_plane(dc->ctx, -- pipe_ctx->pipe_idx, pipe_ctx->tg->inst); -+ pipe_ctx->pipe_idx); - - /* enable DCFCLK current DCHUB */ - enable_dcfclk(dc->ctx, -@@ -1694,7 +1686,6 @@ static void update_dchubp_dpp( - struct default_adjustment ocsc = {0}; - struct tg_color black_color = {0}; - struct mpcc_cfg mpcc_cfg; -- struct pipe_ctx *top_pipe; - bool per_pixel_alpha = surface->public.per_pixel_alpha && pipe_ctx->bottom_pipe; - - /* TODO: proper fix once fpga works */ -@@ -1734,14 +1725,13 @@ static void update_dchubp_dpp( - IPP_OUTPUT_FORMAT_12_BIT_FIX); - - pipe_ctx->scl_data.lb_params.alpha_en = per_pixel_alpha; -- for (top_pipe = pipe_ctx; top_pipe != NULL; top_pipe = top_pipe->top_pipe) -- mpcc_cfg.opp_id = top_pipe->opp->inst; - mpcc_cfg.top_dpp_id = pipe_ctx->pipe_idx; - if (pipe_ctx->bottom_pipe) - mpcc_cfg.bot_mpcc_id = pipe_ctx->bottom_pipe->mpcc->inst; - else - mpcc_cfg.bot_mpcc_id = 0xf; -- mpcc_cfg.top_of_tree = !pipe_ctx->top_pipe; -+ mpcc_cfg.opp_id = pipe_ctx->tg->inst; -+ mpcc_cfg.top_of_tree = pipe_ctx->pipe_idx == pipe_ctx->tg->inst; - mpcc_cfg.per_pixel_alpha = per_pixel_alpha; - /* DCN1.0 has output CM before MPC which seems to screw with - * pre-multiplied alpha. -@@ -1749,8 +1739,6 @@ static void update_dchubp_dpp( - mpcc_cfg.pre_multiplied_alpha = is_rgb_cspace( - pipe_ctx->stream->public.output_color_space) - && per_pixel_alpha; -- if (!dc->current_context->res_ctx.pipe_ctx[pipe_ctx->pipe_idx].surface) -- pipe_ctx->mpcc->funcs->wait_for_idle(pipe_ctx->mpcc); - pipe_ctx->mpcc->funcs->set(pipe_ctx->mpcc, &mpcc_cfg); - - color_space_to_black_color( -@@ -1796,7 +1784,7 @@ static void program_all_pipe_in_tree( - /* watermark is for all pipes */ - pipe_ctx->mi->funcs->program_watermarks( - pipe_ctx->mi, &context->bw.dcn.watermarks, ref_clk_mhz); -- lock_otg_master_update(dc->ctx, pipe_ctx->tg->inst); -+ pipe_ctx->tg->funcs->lock(pipe_ctx->tg); - - pipe_ctx->tg->dlg_otg_param.vready_offset = pipe_ctx->pipe_dlg_param.vready_offset; - pipe_ctx->tg->dlg_otg_param.vstartup_start = pipe_ctx->pipe_dlg_param.vstartup_start; -@@ -1852,13 +1840,41 @@ static void dcn10_apply_ctx_for_surface( - { - int i; - -+ /* reset unused mpcc */ -+ /*for (i = 0; i < dc->res_pool->pipe_count; i++) { -+ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; -+ struct pipe_ctx *old_pipe_ctx = -+ &dc->current_context->res_ctx.pipe_ctx[i]; -+ -+ if ((!pipe_ctx->surface && old_pipe_ctx->surface) -+ || (!pipe_ctx->stream && old_pipe_ctx->stream)) { -+ struct mpcc_cfg mpcc_cfg; -+ -+ mpcc_cfg.opp_id = 0xf; -+ mpcc_cfg.top_dpp_id = 0xf; -+ mpcc_cfg.bot_mpcc_id = 0xf; -+ mpcc_cfg.top_of_tree = !old_pipe_ctx->top_pipe; -+ old_pipe_ctx->mpcc->funcs->set(old_pipe_ctx->mpcc, &mpcc_cfg); -+ -+ old_pipe_ctx->top_pipe = NULL; -+ old_pipe_ctx->bottom_pipe = NULL; -+ old_pipe_ctx->surface = NULL; -+ -+ dm_logger_write(dc->ctx->logger, LOG_DC, -+ "Reset mpcc for pipe %d\n", -+ old_pipe_ctx->pipe_idx); -+ } -+ }*/ -+ -+ if (!surface) -+ return; -+ - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; - -- if (!pipe_ctx->surface || pipe_ctx->surface != surface) -+ if (pipe_ctx->surface != surface) - continue; - -- - /* looking for top pipe to program */ - if (!pipe_ctx->top_pipe) - program_all_pipe_in_tree(dc, pipe_ctx, context); -@@ -1910,27 +1926,6 @@ static void dcn10_apply_ctx_for_surface( - context->bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns, - context->bw.dcn.watermarks.d.pte_meta_urgent_ns - ); -- -- for (i = 0; i < dc->res_pool->pipe_count; i++) { -- struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; -- -- if (!pipe_ctx->surface || pipe_ctx->top_pipe) -- continue; -- -- /* unlock master update lock */ -- unlock_otg_master(dc->ctx, pipe_ctx->tg->inst); -- } -- -- /* reset unused pipe */ -- for (i = 0; i < dc->res_pool->pipe_count; i++) { -- struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; -- struct pipe_ctx *old_pipe_ctx = -- &dc->current_context->res_ctx.pipe_ctx[i]; -- -- if ((!pipe_ctx->surface && old_pipe_ctx->surface) -- || (!pipe_ctx->stream && old_pipe_ctx->stream)) -- reset_front_end_for_pipe(dc, old_pipe_ctx, dc->current_context); -- } - } - - static void dcn10_set_bandwidth( -@@ -1992,23 +1987,6 @@ static void dcn10_set_bandwidth( - dcn10_pplib_apply_display_requirements(dc, context); - } - --static void dcn10_power_down_fe(struct core_dc *dc, struct pipe_ctx *pipe) --{ -- struct dc_context *ctx = dc->ctx; -- uint32_t inst_offset = 0; -- -- HWSEQ_REG_SET(DC_IP_REQUEST_CNTL, -- IP_REQUEST_EN, 1); -- dpp_pg_control(ctx, pipe->pipe_idx, false); -- hubp_pg_control(ctx, pipe->pipe_idx, false); -- HWSEQ_REG_SET(DC_IP_REQUEST_CNTL, -- IP_REQUEST_EN, 0); -- -- if (pipe->xfm) -- pipe->xfm->funcs->transform_reset(pipe->xfm); -- memset(&pipe->scl_data, 0, sizeof(pipe->scl_data)); --} -- - static void set_drr(struct pipe_ctx **pipe_ctx, - int num_pipes, int vmin, int vmax) - { -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 b1c590d..7af04bc 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c -@@ -65,17 +65,17 @@ void dcn10_mpcc_set_bg_color( - - static void set_output_mux(struct dcn10_mpcc *mpcc10, int opp_id, int mpcc_id) - { -- ASSERT(mpcc10->opp_id == 0xf || opp_id == mpcc10->opp_id); -- mpcc10->opp_id = opp_id; -+ ASSERT(mpcc10->base.opp_id == 0xf || opp_id == mpcc10->base.opp_id); -+ mpcc10->base.opp_id = opp_id; - REG_UPDATE(OPP_PIPE_CONTROL[opp_id], OPP_PIPE_CLOCK_EN, 1); - REG_SET(MUX[opp_id], 0, MPC_OUT_MUX, mpcc_id); - } - - static void reset_output_mux(struct dcn10_mpcc *mpcc10) - { -- REG_SET(MUX[mpcc10->opp_id], 0, MPC_OUT_MUX, 0xf); -- REG_UPDATE(OPP_PIPE_CONTROL[mpcc10->opp_id], OPP_PIPE_CLOCK_EN, 0); -- mpcc10->opp_id = 0xf; -+ REG_SET(MUX[mpcc10->base.opp_id], 0, MPC_OUT_MUX, 0xf); -+ REG_UPDATE(OPP_PIPE_CONTROL[mpcc10->base.opp_id], OPP_PIPE_CLOCK_EN, 0); -+ mpcc10->base.opp_id = 0xf; - } - - static void dcn10_mpcc_set(struct mpcc *mpcc, struct mpcc_cfg *cfg) -@@ -104,16 +104,17 @@ static void dcn10_mpcc_set(struct mpcc *mpcc, struct mpcc_cfg *cfg) - if (cfg->top_of_tree) { - if (cfg->opp_id != 0xf) - set_output_mux(mpcc10, cfg->opp_id, mpcc->inst); -- else -+ else if (mpcc->opp_id != 0xf) - reset_output_mux(mpcc10); - } -+ mpcc10->base.opp_id = cfg->opp_id; - } - - static void dcn10_mpcc_wait_idle(struct mpcc *mpcc) - { - struct dcn10_mpcc *mpcc10 = TO_DCN10_MPCC(mpcc); - -- REG_WAIT(MPCC_STATUS, MPCC_IDLE, 1, 1000, 1000); -+ REG_WAIT(MPCC_STATUS, MPCC_BUSY, 0, 1000, 1000); - } - - -@@ -139,5 +140,5 @@ void dcn10_mpcc_construct(struct dcn10_mpcc *mpcc10, - mpcc10->mpcc_shift = mpcc_shift; - mpcc10->mpcc_mask = mpcc_mask; - -- mpcc10->opp_id = inst; -+ mpcc10->base.opp_id = inst; - } -diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h -index 0f9f1b9..fff2674 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h -+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h -@@ -68,6 +68,7 @@ struct dcn_mpcc_registers { - SF(MPCC0_MPCC_CONTROL, MPCC_ALPHA_MULTIPLIED_MODE, mask_sh),\ - SF(MPCC0_MPCC_CONTROL, MPCC_BLND_ACTIVE_OVERLAP_ONLY, mask_sh),\ - SF(MPCC0_MPCC_STATUS, MPCC_IDLE, mask_sh),\ -+ SF(MPCC0_MPCC_STATUS, MPCC_BUSY, mask_sh),\ - SF(MPCC0_MPCC_OPP_ID, MPCC_OPP_ID, mask_sh),\ - SF(MPCC0_MPCC_BG_G_Y, MPCC_BG_G_Y, mask_sh),\ - SF(MPCC0_MPCC_BG_R_CR, MPCC_BG_R_CR, mask_sh),\ -@@ -83,6 +84,7 @@ struct dcn_mpcc_registers { - type MPCC_ALPHA_MULTIPLIED_MODE;\ - type MPCC_BLND_ACTIVE_OVERLAP_ONLY;\ - type MPCC_IDLE;\ -+ type MPCC_BUSY;\ - type MPCC_OPP_ID;\ - type MPCC_BG_G_Y;\ - type MPCC_BG_R_CR;\ -@@ -103,8 +105,6 @@ struct dcn10_mpcc { - const struct dcn_mpcc_registers *mpcc_regs; - const struct dcn_mpcc_shift *mpcc_shift; - const struct dcn_mpcc_mask *mpcc_mask; -- -- int opp_id; - }; - - void dcn10_mpcc_construct(struct dcn10_mpcc *mpcc10, -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 58fb29f..802ace2 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 -@@ -575,6 +575,8 @@ void dcn10_lock(struct timing_generator *tg) - { - struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); - -+ REG_SET(OTG_GLOBAL_CONTROL0, 0, -+ OTG_MASTER_UPDATE_LOCK_SEL, tg->inst); - REG_SET(OTG_MASTER_UPDATE_LOCK, 0, - OTG_MASTER_UPDATE_LOCK, 1); - } -@@ -587,9 +589,9 @@ void dcn10_unlock(struct timing_generator *tg) - OTG_MASTER_UPDATE_LOCK, 0); - - /* why are we waiting here? */ -- REG_WAIT(OTG_DOUBLE_BUFFER_CONTROL, -+ /*REG_WAIT(OTG_DOUBLE_BUFFER_CONTROL, - OTG_UPDATE_PENDING, 0, -- 20000, 200000); -+ 20000, 200000);*/ - } - - static void dcn10_get_position(struct timing_generator *tg, -diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h -index c880fa5..3b2a20a 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h -+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h -@@ -37,6 +37,7 @@ - SRI(OTG_VREADY_PARAM, OTG, inst),\ - SRI(OTG_BLANK_CONTROL, OTG, inst),\ - SRI(OTG_MASTER_UPDATE_LOCK, OTG, inst),\ -+ SRI(OTG_GLOBAL_CONTROL0, OTG, inst),\ - SRI(OTG_DOUBLE_BUFFER_CONTROL, OTG, inst),\ - SRI(OTG_H_TOTAL, OTG, inst),\ - SRI(OTG_H_BLANK_START_END, OTG, inst),\ -@@ -83,6 +84,7 @@ struct dcn_tg_registers { - uint32_t OTG_VREADY_PARAM; - uint32_t OTG_BLANK_CONTROL; - uint32_t OTG_MASTER_UPDATE_LOCK; -+ uint32_t OTG_GLOBAL_CONTROL0; - uint32_t OTG_DOUBLE_BUFFER_CONTROL; - uint32_t OTG_H_TOTAL; - uint32_t OTG_H_BLANK_START_END; -@@ -134,6 +136,7 @@ struct dcn_tg_registers { - SF(OTG0_OTG_BLANK_CONTROL, OTG_BLANK_DE_MODE, mask_sh),\ - SF(OTG0_OTG_BLANK_CONTROL, OTG_CURRENT_BLANK_STATE, mask_sh),\ - SF(OTG0_OTG_MASTER_UPDATE_LOCK, OTG_MASTER_UPDATE_LOCK, mask_sh),\ -+ SF(OTG0_OTG_GLOBAL_CONTROL0, OTG_MASTER_UPDATE_LOCK_SEL, mask_sh),\ - SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_UPDATE_PENDING, mask_sh),\ - SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_BLANK_DATA_DOUBLE_BUFFER_EN, mask_sh),\ - SF(OTG0_OTG_H_TOTAL, OTG_H_TOTAL, mask_sh),\ -@@ -224,6 +227,7 @@ struct dcn_tg_registers { - type OTG_CURRENT_BLANK_STATE;\ - type OTG_MASTER_UPDATE_LOCK;\ - type OTG_UPDATE_PENDING;\ -+ type OTG_MASTER_UPDATE_LOCK_SEL;\ - type OTG_BLANK_DATA_DOUBLE_BUFFER_EN;\ - type OTG_H_TOTAL;\ - type OTG_H_BLANK_START;\ -diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h -index 51bc8ef..55c9c30 100644 ---- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h -+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h -@@ -40,6 +40,7 @@ struct mpcc { - const struct mpcc_funcs *funcs; - struct dc_context *ctx; - int inst; -+ int opp_id; - }; - - struct mpcc_funcs { -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 5288481..642ae5e 100644 ---- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h -+++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h -@@ -105,7 +105,7 @@ struct hw_sequencer_funcs { - struct dc_bios *dcb, - enum pipe_gating_control power_gating); - -- void (*power_down_front_end)(struct core_dc *dc, struct pipe_ctx *pipe); -+ void (*power_down_front_end)(struct core_dc *dc, int fe_idx); - - void (*power_on_front_end)(struct core_dc *dc, - struct pipe_ctx *pipe, --- -2.7.4 - |