Commit feb4a3cd authored by Eric Bernstein's avatar Eric Bernstein Committed by Alex Deucher

drm/amd/display: Integrating MPC pseudocode

Integrating MPC pseudocode to support new blending cases
with secondary MPCC list.
This includes a design change to MPC data structures and
interfaces.
Signed-off-by: default avatarEric Bernstein <eric.bernstein@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarHarry Wentland <harry.wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 4b87d3a8
...@@ -579,8 +579,6 @@ enum dc_timing_standard { ...@@ -579,8 +579,6 @@ enum dc_timing_standard {
TIMING_STANDARD_MAX TIMING_STANDARD_MAX
}; };
enum dc_color_depth { enum dc_color_depth {
COLOR_DEPTH_UNDEFINED, COLOR_DEPTH_UNDEFINED,
COLOR_DEPTH_666, COLOR_DEPTH_666,
......
...@@ -573,28 +573,25 @@ static void plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx) ...@@ -573,28 +573,25 @@ static void plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
int fe_idx = pipe_ctx->pipe_idx; int fe_idx = pipe_ctx->pipe_idx;
struct hubp *hubp = dc->res_pool->hubps[fe_idx]; struct hubp *hubp = dc->res_pool->hubps[fe_idx];
struct mpc *mpc = dc->res_pool->mpc; struct mpc *mpc = dc->res_pool->mpc;
int opp_id, z_idx; int opp_id;
int mpcc_id = -1; struct mpc_tree *mpc_tree_params;
struct mpcc *mpcc_to_remove = NULL;
/* look at tree rather than mi here to know if we already reset */ /* look at tree rather than mi here to know if we already reset */
for (opp_id = 0; opp_id < dc->res_pool->pipe_count; opp_id++) { for (opp_id = 0; opp_id < dc->res_pool->pipe_count; opp_id++) {
struct output_pixel_processor *opp = dc->res_pool->opps[opp_id]; struct output_pixel_processor *opp = dc->res_pool->opps[opp_id];
for (z_idx = 0; z_idx < opp->mpc_tree.num_pipes; z_idx++) { mpc_tree_params = &(opp->mpc_tree_params);
if (opp->mpc_tree.dpp[z_idx] == fe_idx) { mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, fe_idx);
mpcc_id = opp->mpc_tree.mpcc[z_idx]; if (mpcc_to_remove != NULL)
break;
}
}
if (mpcc_id != -1)
break; break;
} }
/*Already reset*/ /*Already reset*/
if (opp_id == dc->res_pool->pipe_count) if (opp_id == dc->res_pool->pipe_count)
return; return;
mpc->funcs->remove(mpc, &(dc->res_pool->opps[opp_id]->mpc_tree), mpc->funcs->remove_mpcc(mpc, mpc_tree_params, mpcc_to_remove);
dc->res_pool->opps[opp_id]->inst, fe_idx);
if (hubp->funcs->hubp_disconnect) if (hubp->funcs->hubp_disconnect)
hubp->funcs->hubp_disconnect(hubp); hubp->funcs->hubp_disconnect(hubp);
...@@ -652,7 +649,7 @@ static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx) ...@@ -652,7 +649,7 @@ static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
REG_UPDATE(DPP_CONTROL[fe_idx], REG_UPDATE(DPP_CONTROL[fe_idx],
DPP_CLOCK_ENABLE, 0); DPP_CLOCK_ENABLE, 0);
if (opp_id != 0xf && dc->res_pool->opps[opp_id]->mpc_tree.num_pipes == 0) if (opp_id != 0xf && dc->res_pool->opps[opp_id]->mpc_tree_params.opp_list == NULL)
REG_UPDATE(OPP_PIPE_CONTROL[opp_id], REG_UPDATE(OPP_PIPE_CONTROL[opp_id],
OPP_PIPE_CLOCK_EN, 0); OPP_PIPE_CLOCK_EN, 0);
...@@ -677,7 +674,7 @@ static void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx) ...@@ -677,7 +674,7 @@ static void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
static void dcn10_init_hw(struct dc *dc) static void dcn10_init_hw(struct dc *dc)
{ {
int i; int i, opp_id;
struct abm *abm = dc->res_pool->abm; struct abm *abm = dc->res_pool->abm;
struct dmcu *dmcu = dc->res_pool->dmcu; struct dmcu *dmcu = dc->res_pool->dmcu;
struct dce_hwseq *hws = dc->hwseq; struct dce_hwseq *hws = dc->hwseq;
...@@ -740,17 +737,19 @@ static void dcn10_init_hw(struct dc *dc) ...@@ -740,17 +737,19 @@ static void dcn10_init_hw(struct dc *dc)
} }
} }
/* Initialize MPC tree based on HW values */
for (opp_id = 0; opp_id < dc->res_pool->pipe_count; opp_id++) {
struct output_pixel_processor *opp = dc->res_pool->opps[opp_id];
struct mpc_tree *mpc_tree_params = &(opp->mpc_tree_params);
dc->res_pool->mpc->funcs->init_mpcc_list_from_hw(dc->res_pool->mpc, mpc_tree_params);
}
for (i = 0; i < dc->res_pool->pipe_count; i++) { for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct timing_generator *tg = dc->res_pool->timing_generators[i]; struct timing_generator *tg = dc->res_pool->timing_generators[i];
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
struct output_pixel_processor *opp = dc->res_pool->opps[i];
struct mpc_tree_cfg *mpc_tree = &opp->mpc_tree;
struct hubp *hubp = dc->res_pool->hubps[i]; struct hubp *hubp = dc->res_pool->hubps[i];
mpc_tree->dpp[0] = i;
mpc_tree->mpcc[0] = i;
mpc_tree->num_pipes = 1;
pipe_ctx->stream_res.tg = tg; pipe_ctx->stream_res.tg = tg;
pipe_ctx->pipe_idx = i; pipe_ctx->pipe_idx = i;
...@@ -1694,38 +1693,6 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx, ...@@ -1694,38 +1693,6 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
} }
} }
static void set_mpc_output_csc(struct dc *dc,
struct pipe_ctx *pipe_ctx,
enum dc_color_space colorspace,
uint16_t *matrix,
int opp_id)
{
struct mpc *mpc = dc->res_pool->mpc;
int i;
struct out_csc_color_matrix tbl_entry;
enum mpc_output_csc_mode ocsc_mode = MPC_OUTPUT_CSC_COEF_A;
if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
//uint16_t matrix[12];
for (i = 0; i < 12; i++)
tbl_entry.regval[i] = matrix[i];
tbl_entry.color_space = colorspace;
if (mpc->funcs->set_output_csc != NULL)
mpc->funcs->set_output_csc(mpc,
opp_id,
&tbl_entry,
ocsc_mode);
} else {
if (mpc->funcs->set_ocsc_default != NULL)
mpc->funcs->set_ocsc_default(mpc,
opp_id,
colorspace,
ocsc_mode);
}
}
static void program_output_csc(struct dc *dc, static void program_output_csc(struct dc *dc,
struct pipe_ctx *pipe_ctx, struct pipe_ctx *pipe_ctx,
enum dc_color_space colorspace, enum dc_color_space colorspace,
...@@ -1736,13 +1703,6 @@ static void program_output_csc(struct dc *dc, ...@@ -1736,13 +1703,6 @@ static void program_output_csc(struct dc *dc,
program_csc_matrix(pipe_ctx, program_csc_matrix(pipe_ctx,
colorspace, colorspace,
matrix); matrix);
else
set_mpc_output_csc(dc,
pipe_ctx,
colorspace,
matrix,
opp_id);
} }
static bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx) static bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx)
...@@ -1914,35 +1874,73 @@ static void update_dpp(struct dpp *dpp, struct dc_plane_state *plane_state) ...@@ -1914,35 +1874,73 @@ static void update_dpp(struct dpp *dpp, struct dc_plane_state *plane_state)
static void update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx) static void update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
{ {
struct mpcc_cfg mpcc_cfg = {0};
struct hubp *hubp = pipe_ctx->plane_res.hubp; struct hubp *hubp = pipe_ctx->plane_res.hubp;
struct pipe_ctx *top_pipe; struct mpcc_blnd_cfg blnd_cfg;
bool per_pixel_alpha = bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe; int mpcc_id;
struct mpcc *new_mpcc;
struct mpc *mpc = dc->res_pool->mpc;
struct mpc_tree *mpc_tree_params = &(pipe_ctx->stream_res.opp->mpc_tree_params);
/* TODO: proper fix once fpga works */ /* TODO: proper fix once fpga works */
mpcc_cfg.dpp_id = hubp->inst;
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)
mpcc_cfg.z_index++;
if (dc->debug.surface_visual_confirm) if (dc->debug.surface_visual_confirm)
dcn10_get_surface_visual_confirm_color( dcn10_get_surface_visual_confirm_color(
pipe_ctx, &mpcc_cfg.black_color); pipe_ctx, &blnd_cfg.black_color);
else else
color_space_to_black_color( color_space_to_black_color(
dc, pipe_ctx->stream->output_color_space, dc, pipe_ctx->stream->output_color_space,
&mpcc_cfg.black_color); &blnd_cfg.black_color);
mpcc_cfg.per_pixel_alpha = per_pixel_alpha;
if (per_pixel_alpha)
blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA;
else
blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA;
blnd_cfg.overlap_only = false;
blnd_cfg.global_alpha = 0xff;
blnd_cfg.global_gain = 0xff;
/* DCN1.0 has output CM before MPC which seems to screw with /* DCN1.0 has output CM before MPC which seems to screw with
* pre-multiplied alpha. * pre-multiplied alpha.
*/ */
mpcc_cfg.pre_multiplied_alpha = is_rgb_cspace( blnd_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;
hubp->mpcc_id = dc->res_pool->mpc->funcs->add(dc->res_pool->mpc, &mpcc_cfg);
hubp->opp_id = mpcc_cfg.opp_id; /*
* TODO: remove hack
* Note: currently there is a bug in init_hw such that
* on resume from hibernate, BIOS sets up MPCC0, and
* we do mpcc_remove but the mpcc cannot go to idle
* after remove. This cause us to pick mpcc1 here,
* which causes a pstate hang for yet unknown reason.
*/
mpcc_id = hubp->inst;
/* check if this MPCC is already being used */
new_mpcc = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, mpcc_id);
/* remove MPCC if being used */
if (new_mpcc != NULL)
mpc->funcs->remove_mpcc(mpc, mpc_tree_params, new_mpcc);
if (dc->debug.sanity_checks)
mpc->funcs->assert_mpcc_idle_before_connect(
dc->res_pool->mpc, mpcc_id);
/* Call MPC to insert new plane */
new_mpcc = mpc->funcs->insert_plane(dc->res_pool->mpc,
mpc_tree_params,
&blnd_cfg,
NULL,
NULL,
hubp->inst,
mpcc_id);
ASSERT(new_mpcc != NULL);
hubp->opp_id = pipe_ctx->stream_res.opp->inst;
hubp->mpcc_id = mpcc_id;
} }
static void update_scaler(struct pipe_ctx *pipe_ctx) static void update_scaler(struct pipe_ctx *pipe_ctx)
......
...@@ -30,9 +30,6 @@ ...@@ -30,9 +30,6 @@
#define TO_DCN10_MPC(mpc_base) \ #define TO_DCN10_MPC(mpc_base) \
container_of(mpc_base, struct dcn10_mpc, base) container_of(mpc_base, struct dcn10_mpc, base)
#define MAX_MPCC 6
#define MAX_OPP 6
#define MPC_COMMON_REG_LIST_DCN1_0(inst) \ #define MPC_COMMON_REG_LIST_DCN1_0(inst) \
SRII(MPCC_TOP_SEL, MPCC, inst),\ SRII(MPCC_TOP_SEL, MPCC, inst),\
SRII(MPCC_BOT_SEL, MPCC, inst),\ SRII(MPCC_BOT_SEL, MPCC, inst),\
...@@ -42,7 +39,8 @@ ...@@ -42,7 +39,8 @@
SRII(MPCC_BG_G_Y, MPCC, inst),\ SRII(MPCC_BG_G_Y, MPCC, inst),\
SRII(MPCC_BG_R_CR, MPCC, inst),\ SRII(MPCC_BG_R_CR, MPCC, inst),\
SRII(MPCC_BG_B_CB, MPCC, inst),\ SRII(MPCC_BG_B_CB, MPCC, inst),\
SRII(MPCC_BG_B_CB, MPCC, inst) SRII(MPCC_BG_B_CB, MPCC, inst),\
SRII(MPCC_SM_CONTROL, MPCC, inst)
#define MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(inst) \ #define MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(inst) \
SRII(MUX, MPC_OUT, inst) SRII(MUX, MPC_OUT, inst)
...@@ -56,6 +54,7 @@ ...@@ -56,6 +54,7 @@
uint32_t MPCC_BG_G_Y[MAX_MPCC]; \ uint32_t MPCC_BG_G_Y[MAX_MPCC]; \
uint32_t MPCC_BG_R_CR[MAX_MPCC]; \ uint32_t MPCC_BG_R_CR[MAX_MPCC]; \
uint32_t MPCC_BG_B_CB[MAX_MPCC]; \ uint32_t MPCC_BG_B_CB[MAX_MPCC]; \
uint32_t MPCC_SM_CONTROL[MAX_MPCC]; \
uint32_t MUX[MAX_OPP]; uint32_t MUX[MAX_OPP];
#define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\ #define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\
...@@ -65,12 +64,20 @@ ...@@ -65,12 +64,20 @@
SF(MPCC0_MPCC_CONTROL, MPCC_ALPHA_BLND_MODE, mask_sh),\ SF(MPCC0_MPCC_CONTROL, MPCC_ALPHA_BLND_MODE, mask_sh),\
SF(MPCC0_MPCC_CONTROL, MPCC_ALPHA_MULTIPLIED_MODE, mask_sh),\ SF(MPCC0_MPCC_CONTROL, MPCC_ALPHA_MULTIPLIED_MODE, mask_sh),\
SF(MPCC0_MPCC_CONTROL, MPCC_BLND_ACTIVE_OVERLAP_ONLY, mask_sh),\ SF(MPCC0_MPCC_CONTROL, MPCC_BLND_ACTIVE_OVERLAP_ONLY, mask_sh),\
SF(MPCC0_MPCC_CONTROL, MPCC_GLOBAL_ALPHA, mask_sh),\
SF(MPCC0_MPCC_CONTROL, MPCC_GLOBAL_GAIN, mask_sh),\
SF(MPCC0_MPCC_STATUS, MPCC_IDLE, mask_sh),\ SF(MPCC0_MPCC_STATUS, MPCC_IDLE, mask_sh),\
SF(MPCC0_MPCC_STATUS, MPCC_BUSY, mask_sh),\ SF(MPCC0_MPCC_STATUS, MPCC_BUSY, mask_sh),\
SF(MPCC0_MPCC_OPP_ID, MPCC_OPP_ID, 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_G_Y, MPCC_BG_G_Y, mask_sh),\
SF(MPCC0_MPCC_BG_R_CR, MPCC_BG_R_CR, mask_sh),\ SF(MPCC0_MPCC_BG_R_CR, MPCC_BG_R_CR, mask_sh),\
SF(MPCC0_MPCC_BG_B_CB, MPCC_BG_B_CB, mask_sh),\ SF(MPCC0_MPCC_BG_B_CB, MPCC_BG_B_CB, mask_sh),\
SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_EN, mask_sh),\
SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_MODE, mask_sh),\
SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FRAME_ALT, mask_sh),\
SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FIELD_ALT, mask_sh),\
SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_FRAME_POL, mask_sh),\
SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_TOP_POL, mask_sh),\
SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh) SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh)
#define MPC_REG_FIELD_LIST(type) \ #define MPC_REG_FIELD_LIST(type) \
...@@ -80,12 +87,20 @@ ...@@ -80,12 +87,20 @@
type MPCC_ALPHA_BLND_MODE;\ type MPCC_ALPHA_BLND_MODE;\
type MPCC_ALPHA_MULTIPLIED_MODE;\ type MPCC_ALPHA_MULTIPLIED_MODE;\
type MPCC_BLND_ACTIVE_OVERLAP_ONLY;\ type MPCC_BLND_ACTIVE_OVERLAP_ONLY;\
type MPCC_GLOBAL_ALPHA;\
type MPCC_GLOBAL_GAIN;\
type MPCC_IDLE;\ type MPCC_IDLE;\
type MPCC_BUSY;\ type MPCC_BUSY;\
type MPCC_OPP_ID;\ type MPCC_OPP_ID;\
type MPCC_BG_G_Y;\ type MPCC_BG_G_Y;\
type MPCC_BG_R_CR;\ type MPCC_BG_R_CR;\
type MPCC_BG_B_CB;\ type MPCC_BG_B_CB;\
type MPCC_SM_EN;\
type MPCC_SM_MODE;\
type MPCC_SM_FRAME_ALT;\
type MPCC_SM_FIELD_ALT;\
type MPCC_SM_FORCE_NEXT_FRAME_POL;\
type MPCC_SM_FORCE_NEXT_TOP_POL;\
type MPC_OUT_MUX; type MPC_OUT_MUX;
struct dcn_mpc_registers { struct dcn_mpc_registers {
...@@ -117,23 +132,57 @@ void dcn10_mpc_construct(struct dcn10_mpc *mpcc10, ...@@ -117,23 +132,57 @@ void dcn10_mpc_construct(struct dcn10_mpc *mpcc10,
const struct dcn_mpc_mask *mpc_mask, const struct dcn_mpc_mask *mpc_mask,
int num_mpcc); int num_mpcc);
int mpc10_mpcc_add( struct mpcc *mpc1_insert_plane(
struct mpc *mpc, struct mpc *mpc,
struct mpcc_cfg *cfg); struct mpc_tree *tree,
struct mpcc_blnd_cfg *blnd_cfg,
void mpc10_mpcc_remove( struct mpcc_sm_cfg *sm_cfg,
struct mpc *mpc, struct mpcc *insert_above_mpcc,
struct mpc_tree_cfg *tree_cfg, int dpp_id,
int opp_id, int mpcc_id);
int dpp_id);
void mpc1_remove_mpcc(
void mpc10_assert_idle_mpcc( struct mpc *mpc,
struct mpc *mpc, struct mpc_tree *tree,
int id); struct mpcc *mpcc);
void mpc10_update_blend_mode( void mpc1_reset_mpcc(
struct mpc *mpc, struct mpc *mpc,
struct mpcc_cfg *cfg); int mpcc_id);
int mpc10_get_opp_id(struct mpc *mpc, int mpcc_id);
void mpc1_assert_idle_mpcc(
struct mpc *mpc,
int id);
void mpc1_set_bg_color(
struct mpc *mpc,
struct tg_color *bg_color,
int id);
void mpc1_update_stereo_mix(
struct mpc *mpc,
struct mpcc_sm_cfg *sm_cfg,
int mpcc_id);
bool mpc1_is_mpcc_idle(
struct mpc *mpc,
int mpcc_id);
void mpc1_assert_mpcc_idle_before_connect(
struct mpc *mpc,
int mpcc_id);
void mpc1_init_mpcc_list_from_hw(
struct mpc *mpc,
struct mpc_tree *tree);
struct mpcc *mpc1_get_mpcc(
struct mpc *mpc,
int mpcc_id);
struct mpcc *mpc1_get_mpcc_for_dpp(
struct mpc_tree *tree,
int dpp_id);
#endif #endif
...@@ -330,12 +330,19 @@ void dcn10_opp_construct(struct dcn10_opp *oppn10, ...@@ -330,12 +330,19 @@ void dcn10_opp_construct(struct dcn10_opp *oppn10,
const struct dcn10_opp_shift *opp_shift, const struct dcn10_opp_shift *opp_shift,
const struct dcn10_opp_mask *opp_mask) const struct dcn10_opp_mask *opp_mask)
{ {
int i;
oppn10->base.ctx = ctx; oppn10->base.ctx = ctx;
oppn10->base.inst = inst; oppn10->base.inst = inst;
oppn10->base.funcs = &dcn10_opp_funcs; oppn10->base.funcs = &dcn10_opp_funcs;
oppn10->base.mpc_tree_params.opp_id = inst;
oppn10->base.mpc_tree_params.opp_list = NULL;
for (i = 0; i < MAX_PIPES; i++)
oppn10->base.mpcc_disconnect_pending[i] = false;
oppn10->regs = regs; oppn10->regs = regs;
oppn10->opp_shift = opp_shift; oppn10->opp_shift = opp_shift;
oppn10->opp_mask = opp_mask; oppn10->opp_mask = opp_mask;
} }
...@@ -26,7 +26,10 @@ ...@@ -26,7 +26,10 @@
#define __DC_MPCC_H__ #define __DC_MPCC_H__
#include "dc_hw_types.h" #include "dc_hw_types.h"
#include "opp.h" #include "hw_shared.h"
#define MAX_MPCC 6
#define MAX_OPP 6
enum mpc_output_csc_mode { enum mpc_output_csc_mode {
MPC_OUTPUT_CSC_DISABLE = 0, MPC_OUTPUT_CSC_DISABLE = 0,
...@@ -34,45 +37,156 @@ enum mpc_output_csc_mode { ...@@ -34,45 +37,156 @@ enum mpc_output_csc_mode {
MPC_OUTPUT_CSC_COEF_B MPC_OUTPUT_CSC_COEF_B
}; };
struct mpcc_cfg {
int dpp_id;
int opp_id;
struct mpc_tree_cfg *tree_cfg;
unsigned int z_index;
struct tg_color black_color; enum mpcc_blend_mode {
bool per_pixel_alpha; MPCC_BLEND_MODE_BYPASS,
bool pre_multiplied_alpha; MPCC_BLEND_MODE_TOP_LAYER_PASSTHROUGH,
MPCC_BLEND_MODE_TOP_LAYER_ONLY,
MPCC_BLEND_MODE_TOP_BOT_BLENDING
};
enum mpcc_alpha_blend_mode {
MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA,
MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN,
MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA
};
/*
* MPCC blending configuration
*/
struct mpcc_blnd_cfg {
struct tg_color black_color; /* background color */
enum mpcc_alpha_blend_mode alpha_mode; /* alpha blend mode */
bool pre_multiplied_alpha; /* alpha pre-multiplied mode flag */
int global_gain;
int global_alpha;
bool overlap_only;
};
struct mpcc_sm_cfg {
bool enable;
/* 0-single plane,2-row subsampling,4-column subsampling,6-checkboard subsampling */
int sm_mode;
/* 0- disable frame alternate, 1- enable frame alternate */
bool frame_alt;
/* 0- disable field alternate, 1- enable field alternate */
bool field_alt;
/* 0-no force,2-force frame polarity from top,3-force frame polarity from bottom */
int force_next_frame_porlarity;
/* 0-no force,2-force field polarity from top,3-force field polarity from bottom */
int force_next_field_polarity;
};
/*
* MPCC connection and blending configuration for a single MPCC instance.
* This struct is used as a node in an MPC tree.
*/
struct mpcc {
int mpcc_id; /* MPCC physical instance */
int dpp_id; /* DPP input to this MPCC */
struct mpcc *mpcc_bot; /* pointer to bottom layer MPCC. NULL when not connected */
struct mpcc_blnd_cfg blnd_cfg; /* The blending configuration for this MPCC */
struct mpcc_sm_cfg sm_cfg; /* stereo mix setting for this MPCC */
};
/*
* MPC tree represents all MPCC connections for a pipe.
*/
struct mpc_tree {
int opp_id; /* The OPP instance that owns this MPC tree */
struct mpcc *opp_list; /* The top MPCC layer of the MPC tree that outputs to OPP endpoint */
}; };
struct mpc { struct mpc {
const struct mpc_funcs *funcs; const struct mpc_funcs *funcs;
struct dc_context *ctx; struct dc_context *ctx;
struct mpcc mpcc_array[MAX_MPCC];
}; };
struct mpc_funcs { struct mpc_funcs {
int (*add)(struct mpc *mpc, struct mpcc_cfg *cfg); /*
* Insert DPP into MPC tree based on specified blending position.
* Only used for planes that are part of blending chain for OPP output
*
* Parameters:
* [in/out] mpc - MPC context.
* [in/out] tree - MPC tree structure that plane will be added to.
* [in] blnd_cfg - MPCC blending configuration for the new blending layer.
* [in] sm_cfg - MPCC stereo mix configuration for the new blending layer.
* stereo mix must disable for the very bottom layer of the tree config.
* [in] insert_above_mpcc - Insert new plane above this MPCC. If NULL, insert as bottom plane.
* [in] dpp_id - DPP instance for the plane to be added.
* [in] mpcc_id - The MPCC physical instance to use for blending.
*
* Return: struct mpcc* - MPCC that was added.
*/
struct mpcc* (*insert_plane)(
struct mpc *mpc,
struct mpc_tree *tree,
struct mpcc_blnd_cfg *blnd_cfg,
struct mpcc_sm_cfg *sm_cfg,
struct mpcc *insert_above_mpcc,
int dpp_id,
int mpcc_id);
void (*remove)(struct mpc *mpc, /*
struct mpc_tree_cfg *tree_cfg, * Remove a specified MPCC from the MPC tree.
int opp_id, *
int mpcc_inst); * Parameters:
* [in/out] mpc - MPC context.
* [in/out] tree - MPC tree structure that plane will be removed from.
* [in/out] mpcc - MPCC to be removed from tree.
*
* Return: void
*/
void (*remove_mpcc)(
struct mpc *mpc,
struct mpc_tree *tree,
struct mpcc *mpcc);
void (*wait_for_idle)(struct mpc *mpc, int id); /*
* Reset the MPCC HW status by disconnecting all muxes.
*
* Parameters:
* [in/out] mpc - MPC context.
* [in] mpcc_id - The MPCC physical instance to reset.
*
* Return: void
*/
void (*reset_mpcc)(
struct mpc *mpc,
int mpcc_id);
void (*update_blend_mode)(struct mpc *mpc, struct mpcc_cfg *cfg); /*
* Update the blending configuration for a specified MPCC.
*
* Parameters:
* [in/out] mpc - MPC context.
* [in] blnd_cfg - MPCC blending configuration.
* [in] mpcc_id - The MPCC physical instance.
*
* Return: void
*/
void (*update_blending)(
struct mpc *mpc,
struct mpcc_blnd_cfg *blnd_cfg,
int mpcc_id);
int (*get_opp_id)(struct mpc *mpc, int mpcc_id); struct mpcc* (*get_mpcc_for_dpp)(
struct mpc_tree *tree,
int dpp_id);
void (*wait_for_idle)(struct mpc *mpc, int id);
void (*set_output_csc)(struct mpc *mpc, void (*assert_mpcc_idle_before_connect)(struct mpc *mpc, int mpcc_id);
int opp_id,
const struct out_csc_color_matrix *tbl_entry,
enum mpc_output_csc_mode ocsc_mode);
void (*set_ocsc_default)(struct mpc *mpc, void (*init_mpcc_list_from_hw)(
int opp_id, struct mpc *mpc,
enum dc_color_space color_space, struct mpc_tree *tree);
enum mpc_output_csc_mode ocsc_mode);
int (*get_opp_id)(struct mpc *mpc, int mpcc_id);
}; };
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "hw_shared.h" #include "hw_shared.h"
#include "dc_hw_types.h" #include "dc_hw_types.h"
#include "transform.h" #include "transform.h"
#include "mpc.h"
struct fixed31_32; struct fixed31_32;
...@@ -204,7 +205,7 @@ struct output_pixel_processor { ...@@ -204,7 +205,7 @@ struct output_pixel_processor {
struct dc_context *ctx; struct dc_context *ctx;
uint32_t inst; uint32_t inst;
struct pwl_params regamma_params; struct pwl_params regamma_params;
struct mpc_tree_cfg mpc_tree; struct mpc_tree mpc_tree_params;
bool mpcc_disconnect_pending[MAX_PIPES]; bool mpcc_disconnect_pending[MAX_PIPES];
const struct opp_funcs *funcs; const struct opp_funcs *funcs;
}; };
......
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