Skip to content

Commit

Permalink
drm/komeda: Add layer split support
Browse files Browse the repository at this point in the history
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: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
  • Loading branch information
james qian wang (Arm Technology China) authored and Liviu Dudau committed Jun 19, 2019
1 parent b35d092 commit a407a65
Show file tree
Hide file tree
Showing 6 changed files with 378 additions and 11 deletions.
8 changes: 8 additions & 0 deletions drivers/gpu/drm/arm/display/komeda/komeda_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
22 changes: 20 additions & 2 deletions drivers/gpu/drm/arm/display/komeda/komeda_kms.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

/**
Expand All @@ -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;
};

/**
Expand Down Expand Up @@ -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);
Expand Down
23 changes: 21 additions & 2 deletions drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
12 changes: 12 additions & 0 deletions drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 */
};

Expand Down Expand Up @@ -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);

Expand Down
Loading

0 comments on commit a407a65

Please sign in to comment.