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,
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)
static void power_on_plane(
struct dc_context *ctx,
- uint8_t plane_id,
- uint8_t inst)
+ int plane_id)
{
uint32_t inst_offset = 0;
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
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
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];
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 &&
}
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;
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);
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
*/
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(
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,
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 */
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.
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(
/* 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;
{
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);
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(
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)
{