Commit 7f4a7253 authored by Eric Bernstein's avatar Eric Bernstein Committed by Alex Deucher

drm/amd/display: update mpc add/remove functions

Signed-off-by: default avatarEric Bernstein <eric.bernstein@amd.com>
Reviewed-by: default avatarDmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Acked-by: default avatarHarry Wentland <Harry.Wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 98b49c2f
...@@ -881,7 +881,8 @@ static void dcn10_init_hw(struct dc *dc) ...@@ -881,7 +881,8 @@ static void dcn10_init_hw(struct dc *dc)
xfm->funcs->transform_reset(xfm); xfm->funcs->transform_reset(xfm);
dc->res_pool->mpc->funcs->remove( dc->res_pool->mpc->funcs->remove(
dc->res_pool->mpc, dc->res_pool->opps[i], i); dc->res_pool->mpc, &(dc->res_pool->opps[i]->mpc_tree),
dc->res_pool->opps[i]->inst, i);
/* Blank controller using driver code instead of /* Blank controller using driver code instead of
* command table. * command table.
...@@ -1079,7 +1080,8 @@ static void plane_atomic_disconnect(struct dc *dc, ...@@ -1079,7 +1080,8 @@ static void plane_atomic_disconnect(struct dc *dc,
if (dc->debug.sanity_checks) if (dc->debug.sanity_checks)
verify_allow_pstate_change_high(dc->hwseq); verify_allow_pstate_change_high(dc->hwseq);
mpc->funcs->remove(mpc, dc->res_pool->opps[opp_id], fe_idx); mpc->funcs->remove(mpc, &(dc->res_pool->opps[opp_id]->mpc_tree),
dc->res_pool->opps[opp_id]->inst, fe_idx);
} }
/* disable HW used by plane. /* disable HW used by plane.
...@@ -2299,8 +2301,9 @@ static void update_dchubp_dpp( ...@@ -2299,8 +2301,9 @@ static void update_dchubp_dpp(
plane_state->format, plane_state->format,
EXPANSION_MODE_ZERO); EXPANSION_MODE_ZERO);
mpcc_cfg.mi = mi; mpcc_cfg.dpp_id = mi->inst;
mpcc_cfg.opp = pipe_ctx->stream_res.opp; mpcc_cfg.opp_id = pipe_ctx->stream_res.opp->inst;
mpcc_cfg.tree_cfg = &(pipe_ctx->stream_res.opp->mpc_tree);
for (top_pipe = pipe_ctx->top_pipe; top_pipe; top_pipe = top_pipe->top_pipe) for (top_pipe = pipe_ctx->top_pipe; top_pipe; top_pipe = top_pipe->top_pipe)
mpcc_cfg.z_index++; mpcc_cfg.z_index++;
if (dc->debug.surface_visual_confirm) if (dc->debug.surface_visual_confirm)
...@@ -2317,7 +2320,8 @@ static void update_dchubp_dpp( ...@@ -2317,7 +2320,8 @@ static void update_dchubp_dpp(
mpcc_cfg.pre_multiplied_alpha = is_rgb_cspace( mpcc_cfg.pre_multiplied_alpha = is_rgb_cspace(
pipe_ctx->stream->output_color_space) pipe_ctx->stream->output_color_space)
&& per_pixel_alpha; && per_pixel_alpha;
dc->res_pool->mpc->funcs->add(dc->res_pool->mpc, &mpcc_cfg); mi->mpcc_id = dc->res_pool->mpc->funcs->add(dc->res_pool->mpc, &mpcc_cfg);
mi->opp_id = mpcc_cfg.opp_id;
pipe_ctx->plane_res.scl_data.lb_params.alpha_en = per_pixel_alpha; pipe_ctx->plane_res.scl_data.lb_params.alpha_en = per_pixel_alpha;
pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP; pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP;
...@@ -2528,7 +2532,8 @@ static void dcn10_apply_ctx_for_surface( ...@@ -2528,7 +2532,8 @@ static void dcn10_apply_ctx_for_surface(
/* reset mpc */ /* reset mpc */
dc->res_pool->mpc->funcs->remove( dc->res_pool->mpc->funcs->remove(
dc->res_pool->mpc, dc->res_pool->mpc,
old_pipe_ctx->stream_res.opp, &(old_pipe_ctx->stream_res.opp->mpc_tree),
old_pipe_ctx->stream_res.opp->inst,
old_pipe_ctx->pipe_idx); old_pipe_ctx->pipe_idx);
old_pipe_ctx->stream_res.opp->mpcc_disconnect_pending[old_pipe_ctx->plane_res.mi->mpcc_id] = true; old_pipe_ctx->stream_res.opp->mpcc_disconnect_pending[old_pipe_ctx->plane_res.mi->mpcc_id] = true;
......
...@@ -118,17 +118,19 @@ static void mpc10_assert_mpcc_idle_before_connect(struct dcn10_mpc *mpc10, int i ...@@ -118,17 +118,19 @@ static void mpc10_assert_mpcc_idle_before_connect(struct dcn10_mpc *mpc10, int i
static void mpc10_mpcc_remove( static void mpc10_mpcc_remove(
struct mpc *mpc, struct mpc *mpc,
struct output_pixel_processor *opp, struct mpc_tree_cfg *tree_cfg,
int opp_id,
int dpp_id) int dpp_id)
{ {
struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
int mpcc_id, z_idx; int mpcc_id, z_idx;
for (z_idx = 0; z_idx < opp->mpc_tree.num_pipes; z_idx++) /* find z_idx for the dpp to be removed */
if (opp->mpc_tree.dpp[z_idx] == dpp_id) for (z_idx = 0; z_idx < tree_cfg->num_pipes; z_idx++)
if (tree_cfg->dpp[z_idx] == dpp_id)
break; break;
if (z_idx == opp->mpc_tree.num_pipes) { if (z_idx == tree_cfg->num_pipes) {
/* In case of resume from S3/S4, remove mpcc from bios left over */ /* In case of resume from S3/S4, remove mpcc from bios left over */
REG_SET(MPCC_OPP_ID[dpp_id], 0, REG_SET(MPCC_OPP_ID[dpp_id], 0,
MPCC_OPP_ID, 0xf); MPCC_OPP_ID, 0xf);
...@@ -139,7 +141,7 @@ static void mpc10_mpcc_remove( ...@@ -139,7 +141,7 @@ static void mpc10_mpcc_remove(
return; return;
} }
mpcc_id = opp->mpc_tree.mpcc[z_idx]; mpcc_id = tree_cfg->mpcc[z_idx];
REG_SET(MPCC_OPP_ID[mpcc_id], 0, REG_SET(MPCC_OPP_ID[mpcc_id], 0,
MPCC_OPP_ID, 0xf); MPCC_OPP_ID, 0xf);
...@@ -149,82 +151,101 @@ static void mpc10_mpcc_remove( ...@@ -149,82 +151,101 @@ static void mpc10_mpcc_remove(
MPCC_BOT_SEL, 0xf); MPCC_BOT_SEL, 0xf);
if (z_idx > 0) { if (z_idx > 0) {
int top_mpcc_id = opp->mpc_tree.mpcc[z_idx - 1]; int top_mpcc_id = tree_cfg->mpcc[z_idx - 1];
if (z_idx + 1 < opp->mpc_tree.num_pipes) if (z_idx + 1 < tree_cfg->num_pipes)
/* mpcc to be removed is in the middle of the tree */
REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0, REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0,
MPCC_BOT_SEL, opp->mpc_tree.mpcc[z_idx + 1]); MPCC_BOT_SEL, tree_cfg->mpcc[z_idx + 1]);
else { else {
/* mpcc to be removed is at the bottom of the tree */
REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0, REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0,
MPCC_BOT_SEL, 0xf); MPCC_BOT_SEL, 0xf);
REG_UPDATE(MPCC_CONTROL[top_mpcc_id], REG_UPDATE(MPCC_CONTROL[top_mpcc_id],
MPCC_MODE, MODE_TOP_ONLY); MPCC_MODE, MODE_TOP_ONLY);
} }
} else if (opp->mpc_tree.num_pipes > 1) } else if (tree_cfg->num_pipes > 1)
REG_SET(MUX[opp->inst], 0, /* mpcc to be removed is at the top of the tree */
MPC_OUT_MUX, opp->mpc_tree.mpcc[z_idx + 1]); REG_SET(MUX[opp_id], 0,
MPC_OUT_MUX, tree_cfg->mpcc[z_idx + 1]);
else else
REG_SET(MUX[opp->inst], 0, MPC_OUT_MUX, 0xf); /* mpcc to be removed is the only one in the tree */
REG_SET(MUX[opp_id], 0, MPC_OUT_MUX, 0xf);
/* mark this mpcc as not in use */
mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id); mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id);
opp->mpc_tree.num_pipes--; tree_cfg->num_pipes--;
for (; z_idx < opp->mpc_tree.num_pipes; z_idx++) { for (; z_idx < tree_cfg->num_pipes; z_idx++) {
opp->mpc_tree.dpp[z_idx] = opp->mpc_tree.dpp[z_idx + 1]; tree_cfg->dpp[z_idx] = tree_cfg->dpp[z_idx + 1];
opp->mpc_tree.mpcc[z_idx] = opp->mpc_tree.mpcc[z_idx + 1]; tree_cfg->mpcc[z_idx] = tree_cfg->mpcc[z_idx + 1];
} }
opp->mpc_tree.dpp[opp->mpc_tree.num_pipes] = 0xdeadbeef; tree_cfg->dpp[tree_cfg->num_pipes] = 0xdeadbeef;
opp->mpc_tree.mpcc[opp->mpc_tree.num_pipes] = 0xdeadbeef; tree_cfg->mpcc[tree_cfg->num_pipes] = 0xdeadbeef;
} }
static void mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg) static void mpc10_add_to_tree_cfg(
struct mpc *mpc,
struct mpcc_cfg *cfg,
int mpcc_id)
{ {
struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
int mpcc_mode = MODE_TOP_ONLY;
int position = cfg->z_index;
struct mpc_tree_cfg *tree_cfg = cfg->tree_cfg;
int alpha_blnd_mode = cfg->per_pixel_alpha ? int alpha_blnd_mode = cfg->per_pixel_alpha ?
BLND_PP_ALPHA : BLND_GLOBAL_ALPHA; BLND_PP_ALPHA : BLND_GLOBAL_ALPHA;
int mpcc_mode = MODE_TOP_ONLY; int z_idx;
int mpcc_id, z_idx;
ASSERT(cfg->z_index < mpc10->num_mpcc); REG_SET(MPCC_OPP_ID[mpcc_id], 0,
MPCC_OPP_ID, cfg->opp_id);
for (z_idx = 0; z_idx < cfg->opp->mpc_tree.num_pipes; z_idx++) REG_SET(MPCC_TOP_SEL[mpcc_id], 0,
if (cfg->opp->mpc_tree.dpp[z_idx] == cfg->mi->inst) MPCC_TOP_SEL, cfg->dpp_id);
break;
if (z_idx == cfg->opp->mpc_tree.num_pipes) {
ASSERT(cfg->z_index <= cfg->opp->mpc_tree.num_pipes);
mpcc_id = mpc10_get_idle_mpcc_id(mpc10);
/*todo: remove hack*/
mpcc_id = cfg->mi->inst;
ASSERT(!(mpc10->mpcc_in_use_mask & 1 << mpcc_id));
if (mpc->ctx->dc->debug.sanity_checks) if (position == 0) {
mpc10_assert_mpcc_idle_before_connect(mpc10, mpcc_id); /* idle dpp/mpcc is added to the top layer of tree */
} else {
ASSERT(cfg->z_index < cfg->opp->mpc_tree.num_pipes);
mpcc_id = cfg->opp->mpc_tree.mpcc[z_idx];
mpc10_mpcc_remove(mpc, cfg->opp, cfg->mi->inst);
}
REG_SET(MPCC_OPP_ID[mpcc_id], 0, if (tree_cfg->num_pipes > 0) {
MPCC_OPP_ID, cfg->opp->inst); /* get instance of previous top mpcc */
int prev_top_mpcc_id = tree_cfg->mpcc[0];
REG_SET(MPCC_TOP_SEL[mpcc_id], 0, REG_SET(MPCC_BOT_SEL[mpcc_id], 0,
MPCC_TOP_SEL, cfg->mi->inst); MPCC_BOT_SEL, prev_top_mpcc_id);
mpcc_mode = MODE_BLEND;
}
/* opp will get new output. from new added mpcc */
REG_SET(MUX[cfg->opp_id], 0, MPC_OUT_MUX, mpcc_id);
} else if (position == tree_cfg->num_pipes) {
/* idle dpp/mpcc is added to the bottom layer of tree */
if (cfg->z_index > 0) { /* get instance of previous bottom mpcc, set to middle layer */
int top_mpcc_id = cfg->opp->mpc_tree.mpcc[cfg->z_index - 1]; int prev_bot_mpcc_id = tree_cfg->mpcc[tree_cfg->num_pipes - 1];
REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0, REG_SET(MPCC_BOT_SEL[prev_bot_mpcc_id], 0,
MPCC_BOT_SEL, mpcc_id); MPCC_BOT_SEL, mpcc_id);
REG_UPDATE(MPCC_CONTROL[top_mpcc_id], REG_UPDATE(MPCC_CONTROL[prev_bot_mpcc_id],
MPCC_MODE, MODE_BLEND); MPCC_MODE, MODE_BLEND);
} else
REG_SET(MUX[cfg->opp->inst], 0, MPC_OUT_MUX, mpcc_id);
if (cfg->z_index < cfg->opp->mpc_tree.num_pipes) { /* mpcc_id become new bottom mpcc*/
int bot_mpcc_id = cfg->opp->mpc_tree.mpcc[cfg->z_index]; REG_SET(MPCC_BOT_SEL[mpcc_id], 0,
MPCC_BOT_SEL, 0xf);
} else {
/* idle dpp/mpcc is added to middle of tree */
int above_mpcc_id = tree_cfg->mpcc[position - 1];
int below_mpcc_id = tree_cfg->mpcc[position];
/* mpcc above new mpcc_id has new bottom mux*/
REG_SET(MPCC_BOT_SEL[above_mpcc_id], 0,
MPCC_BOT_SEL, mpcc_id);
REG_UPDATE(MPCC_CONTROL[above_mpcc_id],
MPCC_MODE, MODE_BLEND);
/* mpcc_id bottom mux is from below mpcc*/
REG_SET(MPCC_BOT_SEL[mpcc_id], 0, REG_SET(MPCC_BOT_SEL[mpcc_id], 0,
MPCC_BOT_SEL, bot_mpcc_id); MPCC_BOT_SEL, below_mpcc_id);
mpcc_mode = MODE_BLEND; mpcc_mode = MODE_BLEND;
} }
...@@ -234,18 +255,50 @@ static void mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg) ...@@ -234,18 +255,50 @@ static void mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg)
MPCC_ALPHA_MULTIPLIED_MODE, cfg->pre_multiplied_alpha, MPCC_ALPHA_MULTIPLIED_MODE, cfg->pre_multiplied_alpha,
MPCC_BLND_ACTIVE_OVERLAP_ONLY, false); MPCC_BLND_ACTIVE_OVERLAP_ONLY, false);
/* update mpc_tree_cfg with new mpcc */
for (z_idx = tree_cfg->num_pipes; z_idx > position; z_idx--) {
tree_cfg->dpp[z_idx] = tree_cfg->dpp[z_idx - 1];
tree_cfg->mpcc[z_idx] = tree_cfg->mpcc[z_idx - 1];
}
tree_cfg->dpp[position] = cfg->dpp_id;
tree_cfg->mpcc[position] = mpcc_id;
tree_cfg->num_pipes++;
}
static int mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg)
{
struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
int mpcc_id, z_idx;
ASSERT(cfg->z_index < mpc10->num_mpcc);
/* check in dpp already exists in mpc tree */
for (z_idx = 0; z_idx < cfg->tree_cfg->num_pipes; z_idx++)
if (cfg->tree_cfg->dpp[z_idx] == cfg->dpp_id)
break;
if (z_idx == cfg->tree_cfg->num_pipes) {
ASSERT(cfg->z_index <= cfg->tree_cfg->num_pipes);
mpcc_id = mpc10_get_idle_mpcc_id(mpc10);
ASSERT(!(mpc10->mpcc_in_use_mask & 1 << mpcc_id));
if (mpc->ctx->dc->debug.sanity_checks)
mpc10_assert_mpcc_idle_before_connect(mpc10, mpcc_id);
} else {
ASSERT(cfg->z_index < cfg->tree_cfg->num_pipes);
mpcc_id = cfg->tree_cfg->mpcc[z_idx];
mpc10_mpcc_remove(mpc, cfg->tree_cfg, cfg->opp_id, cfg->dpp_id);
}
/* add dpp/mpcc pair to mpc_tree_cfg and update mpcc registers */
mpc10_add_to_tree_cfg(mpc, cfg, mpcc_id);
/* set background color */
mpc10_set_bg_color(mpc10, &cfg->black_color, mpcc_id); mpc10_set_bg_color(mpc10, &cfg->black_color, mpcc_id);
/* mark this mpcc as in use */
mpc10->mpcc_in_use_mask |= 1 << mpcc_id; mpc10->mpcc_in_use_mask |= 1 << mpcc_id;
for (z_idx = cfg->opp->mpc_tree.num_pipes; z_idx > cfg->z_index; z_idx--) {
cfg->opp->mpc_tree.dpp[z_idx] = cfg->opp->mpc_tree.dpp[z_idx - 1]; return mpcc_id;
cfg->opp->mpc_tree.mpcc[z_idx] = cfg->opp->mpc_tree.mpcc[z_idx - 1];
}
cfg->opp->mpc_tree.dpp[cfg->z_index] = cfg->mi->inst;
cfg->opp->mpc_tree.mpcc[cfg->z_index] = mpcc_id;
cfg->opp->mpc_tree.num_pipes++;
cfg->mi->opp_id = cfg->opp->inst;
cfg->mi->mpcc_id = mpcc_id;
} }
const struct mpc_funcs dcn10_mpc_funcs = { const struct mpc_funcs dcn10_mpc_funcs = {
......
...@@ -29,8 +29,9 @@ ...@@ -29,8 +29,9 @@
#include "opp.h" #include "opp.h"
struct mpcc_cfg { struct mpcc_cfg {
struct mem_input *mi; int dpp_id;
struct output_pixel_processor *opp; int opp_id;
struct mpc_tree_cfg *tree_cfg;
unsigned int z_index; unsigned int z_index;
struct tg_color black_color; struct tg_color black_color;
...@@ -44,9 +45,10 @@ struct mpc { ...@@ -44,9 +45,10 @@ struct mpc {
}; };
struct mpc_funcs { struct mpc_funcs {
void (*add)(struct mpc *mpc, struct mpcc_cfg *cfg); int (*add)(struct mpc *mpc, struct mpcc_cfg *cfg);
void (*remove)(struct mpc *mpc, void (*remove)(struct mpc *mpc,
struct output_pixel_processor *opp, struct mpc_tree_cfg *tree_cfg,
int opp_id,
int mpcc_inst); int mpcc_inst);
void (*wait_for_idle)(struct mpc *mpc, int id); void (*wait_for_idle)(struct mpc *mpc, int id);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment