drm/komeda: Add component komeda_merger
Introduce a new component komeda_merger, because D71 HW supports to split a whole image to two half parts and does the scaling independently. Merger merges two separate results to one, and output it to compositor or wb_layer For this patch: - Add the definition of komeda_merger/merger_state - Report and initialize komeda_merger according to the D71 HW. v2: Rebase Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com> Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
This commit is contained in:
parent
619053220a
commit
9a28105f5a
|
@ -767,6 +767,77 @@ static int d71_downscaling_clk_check(struct komeda_pipeline *pipe,
|
|||
0 : -EINVAL;
|
||||
}
|
||||
|
||||
static void d71_merger_update(struct komeda_component *c,
|
||||
struct komeda_component_state *state)
|
||||
{
|
||||
struct komeda_merger_state *st = to_merger_st(state);
|
||||
u32 __iomem *reg = c->reg;
|
||||
u32 index;
|
||||
|
||||
for_each_changed_input(state, index)
|
||||
malidp_write32(reg, MG_INPUT_ID0 + index * 4,
|
||||
to_d71_input_id(&state->inputs[index]));
|
||||
|
||||
malidp_write32(reg, MG_SIZE, HV_SIZE(st->hsize_merged,
|
||||
st->vsize_merged));
|
||||
malidp_write32(reg, BLK_CONTROL, BLK_CTRL_EN);
|
||||
}
|
||||
|
||||
static void d71_merger_dump(struct komeda_component *c, struct seq_file *sf)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
dump_block_header(sf, c->reg);
|
||||
|
||||
get_values_from_reg(c->reg, MG_INPUT_ID0, 1, &v);
|
||||
seq_printf(sf, "MG_INPUT_ID0:\t\t0x%X\n", v);
|
||||
|
||||
get_values_from_reg(c->reg, MG_INPUT_ID1, 1, &v);
|
||||
seq_printf(sf, "MG_INPUT_ID1:\t\t0x%X\n", v);
|
||||
|
||||
get_values_from_reg(c->reg, BLK_CONTROL, 1, &v);
|
||||
seq_printf(sf, "MG_CONTROL:\t\t0x%X\n", v);
|
||||
|
||||
get_values_from_reg(c->reg, MG_SIZE, 1, &v);
|
||||
seq_printf(sf, "MG_SIZE:\t\t0x%X\n", v);
|
||||
}
|
||||
|
||||
static const struct komeda_component_funcs d71_merger_funcs = {
|
||||
.update = d71_merger_update,
|
||||
.disable = d71_component_disable,
|
||||
.dump_register = d71_merger_dump,
|
||||
};
|
||||
|
||||
static int d71_merger_init(struct d71_dev *d71,
|
||||
struct block_header *blk, u32 __iomem *reg)
|
||||
{
|
||||
struct komeda_component *c;
|
||||
struct komeda_merger *merger;
|
||||
u32 pipe_id, comp_id;
|
||||
|
||||
get_resources_id(blk->block_info, &pipe_id, &comp_id);
|
||||
|
||||
c = komeda_component_add(&d71->pipes[pipe_id]->base, sizeof(*merger),
|
||||
comp_id,
|
||||
BLOCK_INFO_INPUT_ID(blk->block_info),
|
||||
&d71_merger_funcs,
|
||||
MG_NUM_INPUTS_IDS, get_valid_inputs(blk),
|
||||
MG_NUM_OUTPUTS_IDS, reg,
|
||||
"CU%d_MERGER", pipe_id);
|
||||
|
||||
if (IS_ERR(c)) {
|
||||
DRM_ERROR("Failed to initialize merger.\n");
|
||||
return PTR_ERR(c);
|
||||
}
|
||||
|
||||
merger = to_merger(c);
|
||||
|
||||
set_range(&merger->hsize_merged, 4, 4032);
|
||||
set_range(&merger->vsize_merged, 4, 4096);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void d71_improc_update(struct komeda_component *c,
|
||||
struct komeda_component_state *state)
|
||||
{
|
||||
|
@ -992,7 +1063,10 @@ int d71_probe_block(struct d71_dev *d71,
|
|||
break;
|
||||
|
||||
case D71_BLK_TYPE_CU_SPLITTER:
|
||||
break;
|
||||
|
||||
case D71_BLK_TYPE_CU_MERGER:
|
||||
err = d71_merger_init(d71, blk, reg);
|
||||
break;
|
||||
|
||||
case D71_BLK_TYPE_DOU:
|
||||
|
|
|
@ -91,6 +91,9 @@ komeda_pipeline_get_component_pos(struct komeda_pipeline *pipe, int id)
|
|||
case KOMEDA_COMPONENT_SCALER1:
|
||||
pos = to_cpos(pipe->scalers[id - KOMEDA_COMPONENT_SCALER0]);
|
||||
break;
|
||||
case KOMEDA_COMPONENT_MERGER:
|
||||
pos = to_cpos(pipe->merger);
|
||||
break;
|
||||
case KOMEDA_COMPONENT_IPS0:
|
||||
case KOMEDA_COMPONENT_IPS1:
|
||||
temp = mdev->pipelines[id - KOMEDA_COMPONENT_IPS0];
|
||||
|
|
|
@ -276,6 +276,18 @@ struct komeda_compiz_state {
|
|||
struct komeda_compiz_input_cfg cins[KOMEDA_COMPONENT_N_INPUTS];
|
||||
};
|
||||
|
||||
struct komeda_merger {
|
||||
struct komeda_component base;
|
||||
struct malidp_range hsize_merged;
|
||||
struct malidp_range vsize_merged;
|
||||
};
|
||||
|
||||
struct komeda_merger_state {
|
||||
struct komeda_component_state base;
|
||||
u16 hsize_merged;
|
||||
u16 vsize_merged;
|
||||
};
|
||||
|
||||
struct komeda_improc {
|
||||
struct komeda_component base;
|
||||
u32 supported_color_formats; /* DRM_RGB/YUV444/YUV420*/
|
||||
|
@ -357,6 +369,8 @@ struct komeda_pipeline {
|
|||
struct komeda_scaler *scalers[KOMEDA_PIPELINE_MAX_SCALERS];
|
||||
/** @compiz: compositor */
|
||||
struct komeda_compiz *compiz;
|
||||
/** @merger: merger */
|
||||
struct komeda_merger *merger;
|
||||
/** @wb_layer: writeback layer */
|
||||
struct komeda_layer *wb_layer;
|
||||
/** @improc: post image processor */
|
||||
|
@ -399,17 +413,19 @@ struct komeda_pipeline_state {
|
|||
#define to_layer(c) container_of(c, struct komeda_layer, base)
|
||||
#define to_compiz(c) container_of(c, struct komeda_compiz, base)
|
||||
#define to_scaler(c) container_of(c, struct komeda_scaler, base)
|
||||
#define to_merger(c) container_of(c, struct komeda_merger, base)
|
||||
#define to_improc(c) container_of(c, struct komeda_improc, base)
|
||||
#define to_ctrlr(c) container_of(c, struct komeda_timing_ctrlr, base)
|
||||
|
||||
#define to_layer_st(c) container_of(c, struct komeda_layer_state, base)
|
||||
#define to_compiz_st(c) container_of(c, struct komeda_compiz_state, base)
|
||||
#define to_scaler_st(c) container_of(c, struct komeda_scaler_state, base)
|
||||
#define to_merger_st(c) container_of(c, struct komeda_merger_state, base)
|
||||
#define to_improc_st(c) container_of(c, struct komeda_improc_state, base)
|
||||
#define to_ctrlr_st(c) container_of(c, struct komeda_timing_ctrlr_state, base)
|
||||
|
||||
#define priv_to_comp_st(o) container_of(o, struct komeda_component_state, obj)
|
||||
#define priv_to_pipe_st(o) container_of(o, struct komeda_pipeline_state, obj)
|
||||
#define priv_to_pipe_st(o) container_of(o, struct komeda_pipeline_state, obj)
|
||||
|
||||
/* pipeline APIs */
|
||||
struct komeda_pipeline *
|
||||
|
|
|
@ -146,6 +146,49 @@ static int komeda_compiz_obj_add(struct komeda_kms_dev *kms,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct drm_private_state *
|
||||
komeda_merger_atomic_duplicate_state(struct drm_private_obj *obj)
|
||||
{
|
||||
struct komeda_merger_state *st;
|
||||
|
||||
st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL);
|
||||
if (!st)
|
||||
return NULL;
|
||||
|
||||
komeda_component_state_reset(&st->base);
|
||||
__drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj);
|
||||
|
||||
return &st->base.obj;
|
||||
}
|
||||
|
||||
static void komeda_merger_atomic_destroy_state(struct drm_private_obj *obj,
|
||||
struct drm_private_state *state)
|
||||
{
|
||||
kfree(to_merger_st(priv_to_comp_st(state)));
|
||||
}
|
||||
|
||||
static const struct drm_private_state_funcs komeda_merger_obj_funcs = {
|
||||
.atomic_duplicate_state = komeda_merger_atomic_duplicate_state,
|
||||
.atomic_destroy_state = komeda_merger_atomic_destroy_state,
|
||||
};
|
||||
|
||||
static int komeda_merger_obj_add(struct komeda_kms_dev *kms,
|
||||
struct komeda_merger *merger)
|
||||
{
|
||||
struct komeda_merger_state *st;
|
||||
|
||||
st = kzalloc(sizeof(*st), GFP_KERNEL);
|
||||
if (!st)
|
||||
return -ENOMEM;
|
||||
|
||||
st->base.component = &merger->base;
|
||||
drm_atomic_private_obj_init(&kms->base,
|
||||
&merger->base.obj, &st->base.obj,
|
||||
&komeda_merger_obj_funcs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct drm_private_state *
|
||||
komeda_improc_atomic_duplicate_state(struct drm_private_obj *obj)
|
||||
{
|
||||
|
@ -311,6 +354,12 @@ int komeda_kms_add_private_objs(struct komeda_kms_dev *kms,
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
if (pipe->merger) {
|
||||
err = komeda_merger_obj_add(kms, pipe->merger);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = komeda_improc_obj_add(kms, pipe->improc);
|
||||
if (err)
|
||||
return err;
|
||||
|
|
Loading…
Reference in New Issue