drm/komeda: Add new component komeda_splitter

Similar to Layer Split, but Splitter is used for writeback, which splits
the compiz result to two half parts and then feed them to two scalers.

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:
james qian wang (Arm Technology China) 2019-06-12 11:20:12 +01:00 committed by Liviu Dudau
parent f461d6591f
commit 4b9baf74ef
4 changed files with 133 additions and 2 deletions

View File

@ -808,6 +808,68 @@ static int d71_downscaling_clk_check(struct komeda_pipeline *pipe,
0 : -EINVAL;
}
static void d71_splitter_update(struct komeda_component *c,
struct komeda_component_state *state)
{
struct komeda_splitter_state *st = to_splitter_st(state);
u32 __iomem *reg = c->reg;
malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(state, 0));
malidp_write32(reg, BLK_SIZE, HV_SIZE(st->hsize, st->vsize));
malidp_write32(reg, SP_OVERLAP_SIZE, st->overlap & 0x1FFF);
malidp_write32(reg, BLK_CONTROL, BLK_CTRL_EN);
}
static void d71_splitter_dump(struct komeda_component *c, struct seq_file *sf)
{
u32 v[3];
dump_block_header(sf, c->reg);
get_values_from_reg(c->reg, BLK_INPUT_ID0, 1, v);
seq_printf(sf, "SP_INPUT_ID0:\t\t0x%X\n", v[0]);
get_values_from_reg(c->reg, BLK_CONTROL, 3, v);
seq_printf(sf, "SP_CONTROL:\t\t0x%X\n", v[0]);
seq_printf(sf, "SP_SIZE:\t\t0x%X\n", v[1]);
seq_printf(sf, "SP_OVERLAP_SIZE:\t0x%X\n", v[2]);
}
static const struct komeda_component_funcs d71_splitter_funcs = {
.update = d71_splitter_update,
.disable = d71_component_disable,
.dump_register = d71_splitter_dump,
};
static int d71_splitter_init(struct d71_dev *d71,
struct block_header *blk, u32 __iomem *reg)
{
struct komeda_component *c;
struct komeda_splitter *splitter;
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(*splitter),
comp_id,
BLOCK_INFO_INPUT_ID(blk->block_info),
&d71_splitter_funcs,
1, get_valid_inputs(blk), 2, reg,
"CU%d_SPLITTER", pipe_id);
if (IS_ERR(c)) {
DRM_ERROR("Failed to initialize splitter");
return -1;
}
splitter = to_splitter(c);
set_range(&splitter->hsize, 4, d71->max_line_size);
set_range(&splitter->vsize, 4, d71->max_vsize);
return 0;
}
static void d71_merger_update(struct komeda_component *c,
struct komeda_component_state *state)
{
@ -1102,6 +1164,7 @@ int d71_probe_block(struct d71_dev *d71,
break;
case D71_BLK_TYPE_CU_SPLITTER:
err = d71_splitter_init(d71, blk, reg);
break;
case D71_BLK_TYPE_CU_MERGER:

View File

@ -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_SPLITTER:
pos = to_cpos(pipe->splitter);
break;
case KOMEDA_COMPONENT_MERGER:
pos = to_cpos(pipe->merger);
break;

View File

@ -301,6 +301,17 @@ struct komeda_merger_state {
u16 vsize_merged;
};
struct komeda_splitter {
struct komeda_component base;
struct malidp_range hsize, vsize;
};
struct komeda_splitter_state {
struct komeda_component_state base;
u16 hsize, vsize;
u16 overlap;
};
struct komeda_improc {
struct komeda_component base;
u32 supported_color_formats; /* DRM_RGB/YUV444/YUV420*/
@ -388,6 +399,8 @@ struct komeda_pipeline {
struct komeda_scaler *scalers[KOMEDA_PIPELINE_MAX_SCALERS];
/** @compiz: compositor */
struct komeda_compiz *compiz;
/** @splitter: for split the compiz output to two half data flows */
struct komeda_splitter *splitter;
/** @merger: merger */
struct komeda_merger *merger;
/** @wb_layer: writeback layer */
@ -432,14 +445,16 @@ 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_splitter(c) container_of(c, struct komeda_splitter, 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_scaler_st(c) container_of(c, struct komeda_scaler_state, base)
#define to_splitter_st(c) container_of(c, struct komeda_splitter_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)

View File

@ -146,6 +146,50 @@ static int komeda_compiz_obj_add(struct komeda_kms_dev *kms,
return 0;
}
static struct drm_private_state *
komeda_splitter_atomic_duplicate_state(struct drm_private_obj *obj)
{
struct komeda_splitter_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_splitter_atomic_destroy_state(struct drm_private_obj *obj,
struct drm_private_state *state)
{
kfree(to_splitter_st(priv_to_comp_st(state)));
}
static const struct drm_private_state_funcs komeda_splitter_obj_funcs = {
.atomic_duplicate_state = komeda_splitter_atomic_duplicate_state,
.atomic_destroy_state = komeda_splitter_atomic_destroy_state,
};
static int komeda_splitter_obj_add(struct komeda_kms_dev *kms,
struct komeda_splitter *splitter)
{
struct komeda_splitter_state *st;
st = kzalloc(sizeof(*st), GFP_KERNEL);
if (!st)
return -ENOMEM;
st->base.component = &splitter->base;
drm_atomic_private_obj_init(&kms->base,
&splitter->base.obj, &st->base.obj,
&komeda_splitter_obj_funcs);
return 0;
}
static struct drm_private_state *
komeda_merger_atomic_duplicate_state(struct drm_private_obj *obj)
{
@ -354,6 +398,12 @@ int komeda_kms_add_private_objs(struct komeda_kms_dev *kms,
if (err)
return err;
if (pipe->splitter) {
err = komeda_splitter_obj_add(kms, pipe->splitter);
if (err)
return err;
}
if (pipe->merger) {
err = komeda_merger_obj_add(kms, pipe->merger);
if (err)