Commit 635a4ba1 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'drm-for-v4.8-zpos' of git://people.freedesktop.org/~airlied/linux

Pull drm zpos property support from Dave Airlie:
 "This tree was waiting on some media stuff I hadn't had time to get a
  stable branchpoint off, so I just waited until it was all in your tree
  first.

  It's been around a bit on the list and shouldn't affect anything
  outside adding the generic API and moving some ARM drivers to using
  it"

* tag 'drm-for-v4.8-zpos' of git://people.freedesktop.org/~airlied/linux:
  drm: rcar: use generic code for managing zpos plane property
  drm/exynos: use generic code for managing zpos plane property
  drm: sti: use generic zpos for plane
  drm: add generic zpos property
parents 52ddb7e9 586efded
......@@ -17,6 +17,7 @@ DRM,Generic,“rotation”,BITMASK,"{ 0, ""rotate-0"" }, { 1, ""rotate-90"" }, {
,,“CRTC_H”,RANGE,"Min=0, Max=UINT_MAX",Plane,Scanout CRTC (destination) height (atomic)
,,“FB_ID”,OBJECT,DRM_MODE_OBJECT_FB,Plane,Scanout framebuffer (atomic)
,,“CRTC_ID”,OBJECT,DRM_MODE_OBJECT_CRTC,Plane,CRTC that plane is attached to (atomic)
,,“zpos”,RANGE,"Min=0, Max=UINT_MAX","Plane,Z-order of the plane.Planes with higher Z-order values are displayed on top, planes with identical Z-order values are display in an undefined order"
,DVI-I,“subconnector”,ENUM,"{ “Unknown”, “DVI-D”, “DVI-A” }",Connector,TBD
,,“select subconnector”,ENUM,"{ “Automatic”, “DVI-D”, “DVI-A” }",Connector,TBD
,TV,“subconnector”,ENUM,"{ ""Unknown"", ""Composite"", ""SVIDEO"", ""Component"", ""SCART"" }",Connector,TBD
......
......@@ -24,7 +24,7 @@ drm-$(CONFIG_AGP) += drm_agpsupport.o
drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
drm_kms_helper_common.o drm_dp_dual_mode_helper.o \
drm_simple_kms_helper.o
drm_simple_kms_helper.o drm_blend.o
drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
......
......@@ -711,6 +711,8 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
state->src_h = val;
} else if (property == config->rotation_property) {
state->rotation = val;
} else if (property == plane->zpos_property) {
state->zpos = val;
} else if (plane->funcs->atomic_set_property) {
return plane->funcs->atomic_set_property(plane, state,
property, val);
......@@ -767,6 +769,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
*val = state->src_h;
} else if (property == config->rotation_property) {
*val = state->rotation;
} else if (property == plane->zpos_property) {
*val = state->zpos;
} else if (plane->funcs->atomic_get_property) {
return plane->funcs->atomic_get_property(plane, state, property, val);
} else {
......
......@@ -32,6 +32,8 @@
#include <drm/drm_atomic_helper.h>
#include <linux/fence.h>
#include "drm_crtc_internal.h"
/**
* DOC: overview
*
......@@ -592,6 +594,10 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
struct drm_plane_state *plane_state;
int i, ret = 0;
ret = drm_atomic_helper_normalize_zpos(dev, state);
if (ret)
return ret;
for_each_plane_in_state(state, plane, plane_state, i) {
const struct drm_plane_helper_funcs *funcs;
......@@ -2955,6 +2961,7 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
state->planes_changed = false;
state->connectors_changed = false;
state->color_mgmt_changed = false;
state->zpos_changed = false;
state->event = NULL;
}
EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
......
/*
* Copyright (C) 2016 Samsung Electronics Co.Ltd
* Authors:
* Marek Szyprowski <m.szyprowski@samsung.com>
*
* DRM core plane blending related functions
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include <drm/drmP.h>
#include <drm/drm_atomic.h>
#include <drm/drm_crtc.h>
#include <linux/export.h>
#include <linux/slab.h>
#include <linux/sort.h>
#include "drm_internal.h"
/**
* drm_plane_create_zpos_property - create mutable zpos property
* @plane: drm plane
* @zpos: initial value of zpos property
* @min: minimal possible value of zpos property
* @max: maximal possible value of zpos property
*
* This function initializes generic mutable zpos property and enables support
* for it in drm core. Drivers can then attach this property to planes to enable
* support for configurable planes arrangement during blending operation.
* Once mutable zpos property has been enabled, the DRM core will automatically
* calculate drm_plane_state->normalized_zpos values. Usually min should be set
* to 0 and max to maximal number of planes for given crtc - 1.
*
* If zpos of some planes cannot be changed (like fixed background or
* cursor/topmost planes), driver should adjust min/max values and assign those
* planes immutable zpos property with lower or higher values (for more
* information, see drm_mode_create_zpos_immutable_property() function). In such
* case driver should also assign proper initial zpos values for all planes in
* its plane_reset() callback, so the planes will be always sorted properly.
*
* Returns:
* Zero on success, negative errno on failure.
*/
int drm_plane_create_zpos_property(struct drm_plane *plane,
unsigned int zpos,
unsigned int min, unsigned int max)
{
struct drm_property *prop;
prop = drm_property_create_range(plane->dev, 0, "zpos", min, max);
if (!prop)
return -ENOMEM;
drm_object_attach_property(&plane->base, prop, zpos);
plane->zpos_property = prop;
if (plane->state) {
plane->state->zpos = zpos;
plane->state->normalized_zpos = zpos;
}
return 0;
}
EXPORT_SYMBOL(drm_plane_create_zpos_property);
/**
* drm_plane_create_zpos_immutable_property - create immuttable zpos property
* @plane: drm plane
* @zpos: value of zpos property
*
* This function initializes generic immutable zpos property and enables
* support for it in drm core. Using this property driver lets userspace
* to get the arrangement of the planes for blending operation and notifies
* it that the hardware (or driver) doesn't support changing of the planes'
* order.
*
* Returns:
* Zero on success, negative errno on failure.
*/
int drm_plane_create_zpos_immutable_property(struct drm_plane *plane,
unsigned int zpos)
{
struct drm_property *prop;
prop = drm_property_create_range(plane->dev, DRM_MODE_PROP_IMMUTABLE,
"zpos", zpos, zpos);
if (!prop)
return -ENOMEM;
drm_object_attach_property(&plane->base, prop, zpos);
plane->zpos_property = prop;
if (plane->state) {
plane->state->zpos = zpos;
plane->state->normalized_zpos = zpos;
}
return 0;
}
EXPORT_SYMBOL(drm_plane_create_zpos_immutable_property);
static int drm_atomic_state_zpos_cmp(const void *a, const void *b)
{
const struct drm_plane_state *sa = *(struct drm_plane_state **)a;
const struct drm_plane_state *sb = *(struct drm_plane_state **)b;
if (sa->zpos != sb->zpos)
return sa->zpos - sb->zpos;
else
return sa->plane->base.id - sb->plane->base.id;
}
/**
* drm_atomic_helper_crtc_normalize_zpos - calculate normalized zpos values
* @crtc: crtc with planes, which have to be considered for normalization
* @crtc_state: new atomic state to apply
*
* This function checks new states of all planes assigned to given crtc and
* calculates normalized zpos value for them. Planes are compared first by their
* zpos values, then by plane id (if zpos equals). Plane with lowest zpos value
* is at the bottom. The plane_state->normalized_zpos is then filled with unique
* values from 0 to number of active planes in crtc minus one.
*
* RETURNS
* Zero for success or -errno
*/
static int drm_atomic_helper_crtc_normalize_zpos(struct drm_crtc *crtc,
struct drm_crtc_state *crtc_state)
{
struct drm_atomic_state *state = crtc_state->state;
struct drm_device *dev = crtc->dev;
int total_planes = dev->mode_config.num_total_plane;
struct drm_plane_state **states;
struct drm_plane *plane;
int i, n = 0;
int ret = 0;
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] calculating normalized zpos values\n",
crtc->base.id, crtc->name);
states = kmalloc_array(total_planes, sizeof(*states), GFP_TEMPORARY);
if (!states)
return -ENOMEM;
/*
* Normalization process might create new states for planes which
* normalized_zpos has to be recalculated.
*/
drm_for_each_plane_mask(plane, dev, crtc_state->plane_mask) {
struct drm_plane_state *plane_state =
drm_atomic_get_plane_state(state, plane);
if (IS_ERR(plane_state)) {
ret = PTR_ERR(plane_state);
goto done;
}
states[n++] = plane_state;
DRM_DEBUG_ATOMIC("[PLANE:%d:%s] processing zpos value %d\n",
plane->base.id, plane->name,
plane_state->zpos);
}
sort(states, n, sizeof(*states), drm_atomic_state_zpos_cmp, NULL);
for (i = 0; i < n; i++) {
plane = states[i]->plane;
states[i]->normalized_zpos = i;
DRM_DEBUG_ATOMIC("[PLANE:%d:%s] normalized zpos value %d\n",
plane->base.id, plane->name, i);
}
crtc_state->zpos_changed = true;
done:
kfree(states);
return ret;
}
/**
* drm_atomic_helper_normalize_zpos - calculate normalized zpos values for all
* crtcs
* @dev: DRM device
* @state: atomic state of DRM device
*
* This function calculates normalized zpos value for all modified planes in
* the provided atomic state of DRM device. For more information, see
* drm_atomic_helper_crtc_normalize_zpos() function.
*
* RETURNS
* Zero for success or -errno
*/
int drm_atomic_helper_normalize_zpos(struct drm_device *dev,
struct drm_atomic_state *state)
{
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
struct drm_plane *plane;
struct drm_plane_state *plane_state;
int i, ret = 0;
for_each_plane_in_state(state, plane, plane_state, i) {
crtc = plane_state->crtc;
if (!crtc)
continue;
if (plane->state->zpos != plane_state->zpos) {
crtc_state =
drm_atomic_get_existing_crtc_state(state, crtc);
crtc_state->zpos_changed = true;
}
}
for_each_crtc_in_state(state, crtc, crtc_state, i) {
if (crtc_state->plane_mask != crtc->state->plane_mask ||
crtc_state->zpos_changed) {
ret = drm_atomic_helper_crtc_normalize_zpos(crtc,
crtc_state);
if (ret)
return ret;
}
}
return 0;
}
......@@ -128,3 +128,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
int drm_modeset_register_all(struct drm_device *dev);
void drm_modeset_unregister_all(struct drm_device *dev);
/* drm_blend.c */
int drm_atomic_helper_normalize_zpos(struct drm_device *dev,
struct drm_atomic_state *state);
......@@ -64,7 +64,6 @@ struct exynos_drm_plane_state {
struct exynos_drm_rect src;
unsigned int h_ratio;
unsigned int v_ratio;
unsigned int zpos;
};
static inline struct exynos_drm_plane_state *
......@@ -221,7 +220,6 @@ struct exynos_drm_private {
* this array is used to be aware of which crtc did it request vblank.
*/
struct drm_crtc *crtc[MAX_CRTC];
struct drm_property *plane_zpos_property;
struct device *dma_dev;
void *mapping;
......
......@@ -139,9 +139,9 @@ static void exynos_drm_plane_reset(struct drm_plane *plane)
exynos_state = kzalloc(sizeof(*exynos_state), GFP_KERNEL);
if (exynos_state) {
exynos_state->zpos = exynos_plane->config->zpos;
plane->state = &exynos_state->base;
plane->state->plane = plane;
plane->state->zpos = exynos_plane->config->zpos;
}
}
......@@ -157,7 +157,6 @@ exynos_drm_plane_duplicate_state(struct drm_plane *plane)
return NULL;
__drm_atomic_helper_plane_duplicate_state(plane, &copy->base);
copy->zpos = exynos_state->zpos;
return &copy->base;
}
......@@ -170,43 +169,6 @@ static void exynos_drm_plane_destroy_state(struct drm_plane *plane,
kfree(old_exynos_state);
}
static int exynos_drm_plane_atomic_set_property(struct drm_plane *plane,
struct drm_plane_state *state,
struct drm_property *property,
uint64_t val)
{
struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
struct exynos_drm_plane_state *exynos_state =
to_exynos_plane_state(state);
struct exynos_drm_private *dev_priv = plane->dev->dev_private;
const struct exynos_drm_plane_config *config = exynos_plane->config;
if (property == dev_priv->plane_zpos_property &&
(config->capabilities & EXYNOS_DRM_PLANE_CAP_ZPOS))
exynos_state->zpos = val;
else
return -EINVAL;
return 0;
}
static int exynos_drm_plane_atomic_get_property(struct drm_plane *plane,
const struct drm_plane_state *state,
struct drm_property *property,
uint64_t *val)
{
const struct exynos_drm_plane_state *exynos_state =
container_of(state, const struct exynos_drm_plane_state, base);
struct exynos_drm_private *dev_priv = plane->dev->dev_private;
if (property == dev_priv->plane_zpos_property)
*val = exynos_state->zpos;
else
return -EINVAL;
return 0;
}
static struct drm_plane_funcs exynos_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
......@@ -215,8 +177,6 @@ static struct drm_plane_funcs exynos_plane_funcs = {
.reset = exynos_drm_plane_reset,
.atomic_duplicate_state = exynos_drm_plane_duplicate_state,
.atomic_destroy_state = exynos_drm_plane_destroy_state,
.atomic_set_property = exynos_drm_plane_atomic_set_property,
.atomic_get_property = exynos_drm_plane_atomic_get_property,
};
static int
......@@ -304,23 +264,13 @@ static const struct drm_plane_helper_funcs plane_helper_funcs = {
};
static void exynos_plane_attach_zpos_property(struct drm_plane *plane,
unsigned int zpos)
bool immutable)
{
struct drm_device *dev = plane->dev;
struct exynos_drm_private *dev_priv = dev->dev_private;
struct drm_property *prop;
prop = dev_priv->plane_zpos_property;
if (!prop) {
prop = drm_property_create_range(dev, 0, "zpos",
0, MAX_PLANE - 1);
if (!prop)
return;
dev_priv->plane_zpos_property = prop;
}
drm_object_attach_property(&plane->base, prop, zpos);
/* FIXME */
if (immutable)
drm_plane_create_zpos_immutable_property(plane, 0);
else
drm_plane_create_zpos_property(plane, 0, 0, MAX_PLANE - 1);
}
int exynos_plane_init(struct drm_device *dev,
......@@ -346,7 +296,8 @@ int exynos_plane_init(struct drm_device *dev,
exynos_plane->index = index;
exynos_plane->config = config;
exynos_plane_attach_zpos_property(&exynos_plane->base, config->zpos);
exynos_plane_attach_zpos_property(&exynos_plane->base,
!(config->capabilities & EXYNOS_DRM_PLANE_CAP_ZPOS));
return 0;
}
......@@ -477,6 +477,7 @@ static void vp_video_buffer(struct mixer_context *ctx,
struct drm_display_mode *mode = &state->base.crtc->state->adjusted_mode;
struct mixer_resources *res = &ctx->mixer_res;
struct drm_framebuffer *fb = state->base.fb;
unsigned int priority = state->base.normalized_zpos + 1;
unsigned long flags;
dma_addr_t luma_addr[2], chroma_addr[2];
bool tiled_mode = false;
......@@ -561,7 +562,7 @@ static void vp_video_buffer(struct mixer_context *ctx,
mixer_cfg_scan(ctx, mode->vdisplay);
mixer_cfg_rgb_fmt(ctx, mode->vdisplay);
mixer_cfg_layer(ctx, plane->index, state->zpos + 1, true);
mixer_cfg_layer(ctx, plane->index, priority, true);
mixer_cfg_vp_blend(ctx);
mixer_run(ctx);
......@@ -586,6 +587,7 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
struct drm_display_mode *mode = &state->base.crtc->state->adjusted_mode;
struct mixer_resources *res = &ctx->mixer_res;
struct drm_framebuffer *fb = state->base.fb;
unsigned int priority = state->base.normalized_zpos + 1;
unsigned long flags;
unsigned int win = plane->index;
unsigned int x_ratio = 0, y_ratio = 0;
......@@ -677,7 +679,7 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
mixer_cfg_scan(ctx, mode->vdisplay);
mixer_cfg_rgb_fmt(ctx, mode->vdisplay);
mixer_cfg_layer(ctx, win, state->zpos + 1, true);
mixer_cfg_layer(ctx, win, priority, true);
mixer_cfg_gfx_blend(ctx, win, is_alpha_format(fb->pixel_format));
/* layer update mandatory for mixer 16.0.33.0 */
......
......@@ -196,7 +196,7 @@ void rcar_du_crtc_route_output(struct drm_crtc *crtc,
static unsigned int plane_zpos(struct rcar_du_plane *plane)
{
return to_rcar_plane_state(plane->plane.state)->zpos;
return plane->plane.state->normalized_zpos;
}
static const struct rcar_du_format_info *
......
......@@ -92,7 +92,6 @@ struct rcar_du_device {
struct {
struct drm_property *alpha;
struct drm_property *colorkey;
struct drm_property *zpos;
} props;
unsigned int dpad0_source;
......
......@@ -527,11 +527,6 @@ static int rcar_du_properties_init(struct rcar_du_device *rcdu)
if (rcdu->props.colorkey == NULL)
return -ENOMEM;
rcdu->props.zpos =
drm_property_create_range(rcdu->ddev, 0, "zpos", 1, 7);
if (rcdu->props.zpos == NULL)
return -ENOMEM;
return 0;
}
......
......@@ -652,7 +652,7 @@ static void rcar_du_plane_reset(struct drm_plane *plane)
state->source = RCAR_DU_PLANE_MEMORY;
state->alpha = 255;
state->colorkey = RCAR_DU_COLORKEY_NONE;
state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
plane->state = &state->state;
plane->state->plane = plane;
......@@ -670,8 +670,6 @@ static int rcar_du_plane_atomic_set_property(struct drm_plane *plane,
rstate->alpha = val;
else if (property == rcdu->props.colorkey)
rstate->colorkey = val;
else if (property == rcdu->props.zpos)
rstate->zpos = val;
else
return -EINVAL;
......@@ -690,8 +688,6 @@ static int rcar_du_plane_atomic_get_property(struct drm_plane *plane,
*val = rstate->alpha;
else if (property == rcdu->props.colorkey)
*val = rstate->colorkey;
else if (property == rcdu->props.zpos)
*val = rstate->zpos;
else
return -EINVAL;
......@@ -763,8 +759,7 @@ int rcar_du_planes_init(struct rcar_du_group *rgrp)
drm_object_attach_property(&plane->plane.base,
rcdu->props.colorkey,
RCAR_DU_COLORKEY_NONE);
drm_object_attach_property(&plane->plane.base,
rcdu->props.zpos, 1);
drm_plane_create_zpos_property(&plane->plane, 1, 1, 7);
}
return 0;
......
......@@ -51,7 +51,6 @@ static inline struct rcar_du_plane *to_rcar_plane(struct drm_plane *plane)
* @hwindex: 0-based hardware plane index, -1 means unused
* @alpha: value of the plane alpha property
* @colorkey: value of the plane colorkey property
* @zpos: value of the plane zpos property
*/
struct rcar_du_plane_state {
struct drm_plane_state state;
......@@ -62,7 +61,6 @@ struct rcar_du_plane_state {
unsigned int alpha;
unsigned int colorkey;
unsigned int zpos;
};
static inline struct rcar_du_plane_state *
......
......@@ -43,12 +43,12 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
.src_y = 0,
.src_w = mode->hdisplay << 16,
.src_h = mode->vdisplay << 16,
.zpos = 0,
},
.format = rcar_du_format_info(DRM_FORMAT_ARGB8888),
.source = RCAR_DU_PLANE_VSPD1,
.alpha = 255,
.colorkey = 0,
.zpos = 0,
};
if (rcdu->info->gen >= 3)
......@@ -152,7 +152,7 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
.pixelformat = 0,
.pitch = fb->pitches[0],
.alpha = state->alpha,
.zpos = state->zpos,
.zpos = state->state.zpos,
};
unsigned int i;
......@@ -267,7 +267,7 @@ static void rcar_du_vsp_plane_reset(struct drm_plane *plane)
return;
state->alpha = 255;
state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
plane->state = &state->state;
plane->state->plane = plane;
......@@ -282,8 +282,6 @@ static int rcar_du_vsp_plane_atomic_set_property(struct drm_plane *plane,
if (property == rcdu->props.alpha)
rstate->alpha = val;
else if (property == rcdu->props.zpos)
rstate->zpos = val;
else
return -EINVAL;
......@@ -300,8 +298,6 @@ static int rcar_du_vsp_plane_atomic_get_property(struct drm_plane *plane,
if (property == rcdu->props.alpha)
*val = rstate->alpha;
else if (property == rcdu->props.zpos)
*val = rstate->zpos;
else
return -EINVAL;
......@@ -381,8 +377,8 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp)
drm_object_attach_property(&plane->plane.base,
rcdu->props.alpha, 255);
drm_object_attach_property(&plane->plane.base,
rcdu->props.zpos, 1);
drm_plane_create_zpos_property(&plane->plane, 1, 1,
vsp->num_planes - 1);
}
return 0;
......
......@@ -349,8 +349,8 @@ struct drm_plane_funcs sti_cursor_plane_helpers_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = sti_cursor_destroy,
.set_property = sti_plane_set_property,
.reset = drm_atomic_helper_plane_reset,
.set_property = drm_atomic_helper_plane_set_property,
.reset = sti_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
.late_register = sti_cursor_late_register,
......
......@@ -886,8 +886,8 @@ struct drm_plane_funcs sti_gdp_plane_helpers_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = sti_gdp_destroy,
.set_property = sti_plane_set_property,
.reset = drm_atomic_helper_plane_reset,
.set_property = drm_atomic_helper_plane_set_property,
.reset = sti_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
.late_register = sti_gdp_late_register,
......
......@@ -1254,8 +1254,8 @@ struct drm_plane_funcs sti_hqvdp_plane_helpers_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = sti_hqvdp_destroy,
.set_property = sti_plane_set_property,
.reset = drm_atomic_helper_plane_reset,
.set_property = drm_atomic_helper_plane_set_property,
.reset = sti_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
.late_register = sti_hqvdp_late_register,
......
......@@ -239,13 +239,10 @@ static void sti_mixer_set_background_area(struct sti_mixer *mixer,
int sti_mixer_set_plane_depth(struct sti_mixer *mixer, struct sti_plane *plane)
{
int plane_id, depth = plane->zorder;
int plane_id, depth = plane->drm_plane.state->normalized_zpos;
unsigned int i;
u32 mask, val;
if ((depth < 1) || (depth > GAM_MIXER_NB_DEPTH_LEVEL))
return 1;
switch (plane->desc) {
case STI_GDP_0:
plane_id = GAM_DEPTH_GDP0_ID;
......@@ -278,8 +275,8 @@ int sti_mixer_set_plane_depth(struct sti_mixer *mixer, struct sti_plane *plane)
break;
}
mask |= GAM_DEPTH_MASK_ID << (3 * (depth - 1));
plane_id = plane_id << (3 * (depth - 1));
mask |= GAM_DEPTH_MASK_ID << (3 * depth);
plane_id = plane_id << (3 * depth);
DRM_DEBUG_DRIVER("%s %s depth=%d\n", sti_mixer_to_str(mixer),
sti_plane_to_str(plane), depth);
......
......@@ -14,15 +14,6 @@
#include "sti_drv.h"
#include "sti_plane.h"
/* (Background) < GDP0 < GDP1 < HQVDP0 < GDP2 < GDP3 < (ForeGround) */
enum sti_plane_desc sti_plane_default_zorder[] = {
STI_GDP_0,
STI_GDP_1,
STI_HQVDP_0,
STI_GDP_2,
STI_GDP_3,
};
const char *sti_plane_to_str(struct sti_plane *plane)
{
switch (plane->desc) {
......@@ -96,59 +87,46 @@ void sti_plane_update_fps(struct sti_plane *plane,
plane->fps_info.fips_str);
}
int sti_plane_set_property(struct drm_plane *drm_plane,
struct drm_property *property,
uint64_t val)
static int sti_plane_get_default_zpos(enum drm_plane_type type)
{
struct drm_device *dev = drm_plane->dev;
struct sti_private *private = dev->dev_private;
struct sti_plane *plane = to_sti_plane(drm_plane);
DRM_DEBUG_DRIVER("\n");
if (property == private->plane_zorder_property) {
plane->zorder = val;
switch (type) {
case DRM_PLANE_TYPE_PRIMARY:
return 0;
case DRM_PLANE_TYPE_OVERLAY:
return 1;
case DRM_PLANE_TYPE_CURSOR:
return 7;
}
return 0;
}
return -EINVAL;
void sti_plane_reset(struct drm_plane *plane)
{
drm_atomic_helper_plane_reset(plane);
plane->state->zpos = sti_plane_get_default_zpos(plane->type);
}
static void sti_plane_attach_zorder_property(struct drm_plane *drm_plane)
static void sti_plane_attach_zorder_property(struct drm_plane *drm_plane,
enum drm_plane_type type)
{
struct drm_device *dev = drm_plane->dev;
struct sti_private *private = dev->dev_private;
struct sti_plane *plane = to_sti_plane(drm_plane);
struct drm_property *prop;
prop = private->plane_zorder_property;
if (!prop) {
prop = drm_property_create_range(dev, 0, "zpos", 1,
GAM_MIXER_NB_DEPTH_LEVEL);
if (!prop)
return;
int zpos = sti_plane_get_default_zpos(type);
private->plane_zorder_property = prop;
switch (type) {
case DRM_PLANE_TYPE_PRIMARY:
case DRM_PLANE_TYPE_OVERLAY:
drm_plane_create_zpos_property(drm_plane, zpos, 0, 6);
break;
case DRM_PLANE_TYPE_CURSOR:
drm_plane_create_zpos_immutable_property(drm_plane, zpos);
break;
}
drm_object_attach_property(&drm_plane->base, prop, plane->zorder);
}
void sti_plane_init_property(struct sti_plane *plane,
enum drm_plane_type type)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(sti_plane_default_zorder); i++)
if (sti_plane_default_zorder[i] == plane->desc)
break;
plane->zorder = i + 1;
if (type == DRM_PLANE_TYPE_OVERLAY)
sti_plane_attach_zorder_property(&plane->drm_plane);
sti_plane_attach_zorder_property(&plane->drm_plane, type);
DRM_DEBUG_DRIVER("drm plane:%d mapped to %s with zorder:%d\n",
plane->drm_plane.base.id,
sti_plane_to_str(plane), plane->zorder);
DRM_DEBUG_DRIVER("drm plane:%d mapped to %s\n",
plane->drm_plane.base.id, sti_plane_to_str(plane));
}
......@@ -66,14 +66,12 @@ struct sti_fps_info {
* @plane: drm plane it is bound to (if any)
* @desc: plane type & id
* @status: to know the status of the plane
* @zorder: plane z-order
* @fps_info: frame per second info
*/
struct sti_plane {
struct drm_plane drm_plane;
enum sti_plane_desc desc;
enum sti_plane_status status;
int zorder;
struct sti_fps_info fps_info;
};
......@@ -82,10 +80,7 @@ void sti_plane_update_fps(struct sti_plane *plane,
bool new_frame,
bool new_field);
int sti_plane_set_property(struct drm_plane *drm_plane,
struct drm_property *property,
uint64_t val);
void sti_plane_init_property(struct sti_plane *plane,
enum drm_plane_type type);
void sti_plane_reset(struct drm_plane *plane);
#endif
......@@ -308,6 +308,7 @@ struct drm_plane_helper_funcs;
* @mode_changed: crtc_state->mode or crtc_state->enable has been changed
* @active_changed: crtc_state->active has been toggled.
* @connectors_changed: connectors to this crtc have been updated
* @zpos_changed: zpos values of planes on this crtc have been updated
* @color_mgmt_changed: color management properties have changed (degamma or
* gamma LUT or CSC matrix)
* @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes
......@@ -344,6 +345,7 @@ struct drm_crtc_state {
bool mode_changed : 1;
bool active_changed : 1;
bool connectors_changed : 1;
bool zpos_changed : 1;
bool color_mgmt_changed : 1;
/* attached planes bitmask:
......@@ -1409,6 +1411,9 @@ struct drm_connector {
* @src_w: width of visible portion of plane (in 16.16)
* @src_h: height of visible portion of plane (in 16.16)
* @rotation: rotation of the plane
* @zpos: priority of the given plane on crtc (optional)
* @normalized_zpos: normalized value of zpos: unique, range from 0 to N-1
* where N is the number of active planes for given crtc
* @state: backpointer to global drm_atomic_state
*/
struct drm_plane_state {
......@@ -1429,6 +1434,10 @@ struct drm_plane_state {
/* Plane rotation */
unsigned int rotation;
/* Plane zpos */
unsigned int zpos;
unsigned int normalized_zpos;
struct drm_atomic_state *state;
};
......@@ -1688,6 +1697,7 @@ enum drm_plane_type {
* @properties: property tracking for this plane
* @type: type of plane (overlay, primary, cursor)
* @state: current atomic state for this plane
* @zpos_property: zpos property for this plane
* @helper_private: mid-layer private data
*/
struct drm_plane {
......@@ -1732,6 +1742,8 @@ struct drm_plane {
const struct drm_plane_helper_funcs *helper_private;
struct drm_plane_state *state;
struct drm_property *zpos_property;
};
/**
......@@ -2958,6 +2970,14 @@ extern void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
uint degamma_lut_size,
bool has_ctm,
uint gamma_lut_size);
int drm_plane_create_zpos_property(struct drm_plane *plane,
unsigned int zpos,
unsigned int min, unsigned int max);
int drm_plane_create_zpos_immutable_property(struct drm_plane *plane,
unsigned int zpos);
/* Helpers */
struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
uint32_t id, uint32_t type);
......
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