diff options
author | Lowry Li (Arm Technology China) <Lowry.Li@arm.com> | 2019-05-20 06:33:19 +0300 |
---|---|---|
committer | Liviu Dudau <Liviu.Dudau@arm.com> | 2019-06-19 13:42:17 +0300 |
commit | 109bd7d5f4c2db66541272e5a41aeabd6cfeef95 (patch) | |
tree | 172ac92b83c79be133915461c1b9e9ed6be87929 /drivers/gpu/drm/arm | |
parent | 04e84545b9805f6a141fce0b1f05fb74551094fc (diff) | |
download | linux-109bd7d5f4c2db66541272e5a41aeabd6cfeef95.tar.xz |
drm/komeda: Adds zorder support
- Creates the zpos property.
- Implement komeda_crtc_normalize_zpos to replace
drm_atomic_normalize_zpos, reasons as the following:
1. The drm_atomic_normalize_zpos allows to configure same zpos for
different planes, but komeda doesn't support such configuration.
2. For further slave pipline case, Komeda need to calculate the
max_slave_zorder, we will merge such calculation into
komed_crtc_normalize_zpos to save a separated plane_state loop.
3. For feature none-scaling layer_split, which a plane_state will be
assigned to two individual layers(left/right), which requires two
normalize_zpos for this plane, plane_st->normalize_zpos will be used
by left layer, normalize_zpos + 1 for right_layer.
This patch series depends on:
- https://patchwork.freedesktop.org/series/58710/
- https://patchwork.freedesktop.org/series/59000/
- https://patchwork.freedesktop.org/series/59002/
- https://patchwork.freedesktop.org/series/59747/
- https://patchwork.freedesktop.org/series/59915/
- https://patchwork.freedesktop.org/series/60083/
- https://patchwork.freedesktop.org/series/60698/
Signed-off-by: Lowry Li (Arm Technology China) <lowry.li@arm.com>
Reviewed-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
Diffstat (limited to 'drivers/gpu/drm/arm')
-rw-r--r-- | drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 90 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/display/komeda/komeda_kms.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/display/komeda/komeda_plane.c | 6 |
3 files changed, 97 insertions, 2 deletions
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c index 306ea069a1b4..0ec76656cd1f 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c @@ -100,6 +100,90 @@ static const struct drm_mode_config_helper_funcs komeda_mode_config_helpers = { .atomic_commit_tail = komeda_kms_commit_tail, }; +static int komeda_plane_state_list_add(struct drm_plane_state *plane_st, + struct list_head *zorder_list) +{ + struct komeda_plane_state *new = to_kplane_st(plane_st); + struct komeda_plane_state *node, *last; + + last = list_empty(zorder_list) ? + NULL : list_last_entry(zorder_list, typeof(*last), zlist_node); + + /* Considering the list sequence is zpos increasing, so if list is empty + * or the zpos of new node bigger than the last node in list, no need + * loop and just insert the new one to the tail of the list. + */ + if (!last || (new->base.zpos > last->base.zpos)) { + list_add_tail(&new->zlist_node, zorder_list); + return 0; + } + + /* Build the list by zpos increasing */ + list_for_each_entry(node, zorder_list, zlist_node) { + if (new->base.zpos < node->base.zpos) { + list_add_tail(&new->zlist_node, &node->zlist_node); + break; + } else if (node->base.zpos == new->base.zpos) { + struct drm_plane *a = node->base.plane; + struct drm_plane *b = new->base.plane; + + /* Komeda doesn't support setting a same zpos for + * different planes. + */ + DRM_DEBUG_ATOMIC("PLANE: %s and PLANE: %s are configured same zpos: %d.\n", + a->name, b->name, node->base.zpos); + return -EINVAL; + } + } + + return 0; +} + +static int komeda_crtc_normalize_zpos(struct drm_crtc *crtc, + struct drm_crtc_state *crtc_st) +{ + struct drm_atomic_state *state = crtc_st->state; + struct komeda_plane_state *kplane_st; + struct drm_plane_state *plane_st; + struct drm_framebuffer *fb; + struct drm_plane *plane; + struct list_head zorder_list; + int order = 0, err; + + DRM_DEBUG_ATOMIC("[CRTC:%d:%s] calculating normalized zpos values\n", + crtc->base.id, crtc->name); + + INIT_LIST_HEAD(&zorder_list); + + /* This loop also added all effected planes into the new state */ + drm_for_each_plane_mask(plane, crtc->dev, crtc_st->plane_mask) { + plane_st = drm_atomic_get_plane_state(state, plane); + if (IS_ERR(plane_st)) + return PTR_ERR(plane_st); + + /* Build a list by zpos increasing */ + err = komeda_plane_state_list_add(plane_st, &zorder_list); + if (err) + return err; + } + + list_for_each_entry(kplane_st, &zorder_list, zlist_node) { + plane_st = &kplane_st->base; + fb = plane_st->fb; + plane = plane_st->plane; + + plane_st->normalized_zpos = order++; + + DRM_DEBUG_ATOMIC("[PLANE:%d:%s] zpos:%d, normalized zpos: %d\n", + plane->base.id, plane->name, + plane_st->zpos, plane_st->normalized_zpos); + } + + crtc_st->zpos_changed = true; + + return 0; +} + static int komeda_kms_check(struct drm_device *dev, struct drm_atomic_state *state) { @@ -111,7 +195,7 @@ static int komeda_kms_check(struct drm_device *dev, if (err) return err; - /* komeda need to re-calculate resource assumption in every commit + /* Komeda need to re-calculate resource assumption in every commit * so need to add all affected_planes (even unchanged) to * drm_atomic_state. */ @@ -119,6 +203,10 @@ static int komeda_kms_check(struct drm_device *dev, err = drm_atomic_add_affected_planes(state, crtc); if (err) return err; + + err = komeda_crtc_normalize_zpos(crtc, new_crtc_st); + if (err) + return err; } err = drm_atomic_helper_check_planes(dev, state); diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h index e6e059f2af52..c07b4ab1b1d2 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h @@ -7,6 +7,7 @@ #ifndef _KOMEDA_KMS_H_ #define _KOMEDA_KMS_H_ +#include <linux/list.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc_helper.h> @@ -46,6 +47,8 @@ struct komeda_plane { struct komeda_plane_state { /** @base: &drm_plane_state */ struct drm_plane_state base; + /** @zlist_node: zorder list node */ + struct list_head zlist_node; /* @img_enhancement: on/off image enhancement */ u8 img_enhancement : 1; diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c index 9e049ee9014a..c0e381cee524 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c @@ -22,7 +22,7 @@ komeda_plane_init_data_flow(struct drm_plane_state *st, memset(dflow, 0, sizeof(*dflow)); - dflow->blending_zorder = st->zpos; + dflow->blending_zorder = st->normalized_zpos; /* if format doesn't have alpha, fix blend mode to PIXEL_NONE */ dflow->pixel_blend_mode = fb->format->has_alpha ? @@ -345,6 +345,10 @@ static int komeda_plane_add(struct komeda_kms_dev *kms, if (err) goto cleanup; + err = drm_plane_create_zpos_property(plane, layer->base.id, 0, 8); + if (err) + goto cleanup; + return 0; cleanup: komeda_plane_destroy(plane); |