Commit a407a650 authored by james qian wang (Arm Technology China)'s avatar james qian wang (Arm Technology China) Committed by Liviu Dudau

drm/komeda: Add layer split support

Komeda supports two types of layer split:
- none-scaling split
- scaling split
Since D71 merger only support scaler as input, so for none-scaling split,
the two layer dflow will be output to compiz directly. for scaling_split,
the data flow will be merged by merger firstly, then output the merged
data flow to compiz.

Komeda handles the split in kernel completely to hide the detailed and
complicated split calcualtion to user mode, for user only need to set the
layer_split property to enable/disable it.

v2: Rebase
Signed-off-by: default avatarJames Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
Signed-off-by: default avatarLiviu Dudau <liviu.dudau@arm.com>
parent b35d0927
......@@ -173,6 +173,14 @@ static int komeda_crtc_normalize_zpos(struct drm_crtc *crtc,
plane = plane_st->plane;
plane_st->normalized_zpos = order++;
/* When layer_split has been enabled, one plane will be handled
* by two separated komeda layers (left/right), which may needs
* two zorders.
* - zorder: for left_layer for left display part.
* - zorder + 1: will be reserved for right layer.
*/
if (to_kplane_st(plane_st)->layer_split)
order++;
DRM_DEBUG_ATOMIC("[PLANE:%d:%s] zpos:%d, normalized zpos: %d\n",
plane->base.id, plane->name,
......
......@@ -36,6 +36,8 @@ struct komeda_plane {
/** @prop_img_enhancement: for on/off image enhancement */
struct drm_property *prop_img_enhancement;
/** @prop_layer_split: for on/off layer_split */
struct drm_property *prop_layer_split;
};
/**
......@@ -50,8 +52,11 @@ struct komeda_plane_state {
/** @zlist_node: zorder list node */
struct list_head zlist_node;
/* @img_enhancement: on/off image enhancement */
u8 img_enhancement : 1;
/* @img_enhancement: on/off image enhancement
* @layer_split: on/off layer_split
*/
u8 img_enhancement : 1,
layer_split : 1;
};
/**
......@@ -155,6 +160,19 @@ is_only_changed_connector(struct drm_crtc_state *st, struct drm_connector *conn)
return BIT(drm_connector_index(conn)) == changed_connectors;
}
static inline bool has_flip_h(u32 rot)
{
u32 rotation = drm_rotation_simplify(rot,
DRM_MODE_ROTATE_0 |
DRM_MODE_ROTATE_90 |
DRM_MODE_REFLECT_MASK);
if (rotation & DRM_MODE_ROTATE_90)
return !!(rotation & DRM_MODE_REFLECT_Y);
else
return !!(rotation & DRM_MODE_REFLECT_X);
}
unsigned long komeda_calc_aclk(struct komeda_crtc_state *kcrtc_st);
int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms, struct komeda_dev *mdev);
......
......@@ -265,16 +265,35 @@ static void komeda_component_verify_inputs(struct komeda_component *c)
}
}
static struct komeda_layer *
komeda_get_layer_split_right_layer(struct komeda_pipeline *pipe,
struct komeda_layer *left)
{
int index = left->base.id - KOMEDA_COMPONENT_LAYER0;
int i;
for (i = index + 1; i < pipe->n_layers; i++)
if (left->layer_type == pipe->layers[i]->layer_type)
return pipe->layers[i];
return NULL;
}
static void komeda_pipeline_assemble(struct komeda_pipeline *pipe)
{
struct komeda_component *c;
int id;
struct komeda_layer *layer;
int i, id;
dp_for_each_set_bit(id, pipe->avail_comps) {
c = komeda_pipeline_get_component(pipe, id);
komeda_component_verify_inputs(c);
}
/* calculate right layer for the layer split */
for (i = 0; i < pipe->n_layers; i++) {
layer = pipe->layers[i];
layer->right = komeda_get_layer_split_right_layer(pipe, layer);
}
}
int komeda_assemble_pipelines(struct komeda_dev *mdev)
......
......@@ -228,6 +228,12 @@ struct komeda_layer {
struct malidp_range hsize_in, vsize_in;
u32 layer_type; /* RICH, SIMPLE or WB */
u32 supported_rots;
/* komeda supports layer split which splits a whole image to two parts
* left and right and handle them by two individual layer processors
* Note: left/right are always according to the final display rect,
* not the source buffer.
*/
struct komeda_layer *right;
};
struct komeda_layer_state {
......@@ -339,6 +345,7 @@ struct komeda_data_flow_cfg {
u8 en_scaling : 1,
en_img_enhancement : 1,
en_split : 1,
is_yuv : 1,
right_part : 1; /* right part of display image if split enabled */
};
......@@ -493,6 +500,11 @@ int komeda_build_wb_data_flow(struct komeda_layer *wb_layer,
int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
struct komeda_crtc_state *kcrtc_st);
int komeda_build_layer_split_data_flow(struct komeda_layer *left,
struct komeda_plane_state *kplane_st,
struct komeda_crtc_state *kcrtc_st,
struct komeda_data_flow_cfg *dflow);
int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe,
struct komeda_crtc_state *kcrtc_st);
......
......@@ -45,7 +45,8 @@ komeda_plane_init_data_flow(struct drm_plane_state *st,
return -EINVAL;
}
dflow->en_img_enhancement = kplane_st->img_enhancement;
dflow->en_img_enhancement = !!kplane_st->img_enhancement;
dflow->en_split = !!kplane_st->layer_split;
komeda_complete_data_flow_cfg(dflow, fb);
......@@ -91,7 +92,12 @@ komeda_plane_atomic_check(struct drm_plane *plane,
if (err)
return err;
err = komeda_build_layer_data_flow(layer, kplane_st, kcrtc_st, &dflow);
if (dflow.en_split)
err = komeda_build_layer_split_data_flow(layer,
kplane_st, kcrtc_st, &dflow);
else
err = komeda_build_layer_data_flow(layer,
kplane_st, kcrtc_st, &dflow);
return err;
}
......@@ -181,6 +187,8 @@ komeda_plane_atomic_get_property(struct drm_plane *plane,
if (property == kplane->prop_img_enhancement)
*val = st->img_enhancement;
else if (property == kplane->prop_layer_split)
*val = st->layer_split;
else
return -EINVAL;
......@@ -198,6 +206,8 @@ komeda_plane_atomic_set_property(struct drm_plane *plane,
if (property == kplane->prop_img_enhancement)
st->img_enhancement = !!val;
else if (property == kplane->prop_layer_split)
st->layer_split = !!val;
else
return -EINVAL;
......@@ -247,6 +257,16 @@ komeda_plane_create_layer_properties(struct komeda_plane *kplane,
kplane->prop_img_enhancement = prop;
}
/* property: layer split */
if (layer->right) {
prop = drm_property_create_bool(drm, DRM_MODE_PROP_ATOMIC,
"layer_split");
if (!prop)
return -ENOMEM;
kplane->prop_layer_split = prop;
drm_object_attach_property(&plane->base, prop, 0);
}
return 0;
}
......
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