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
This commit is contained in:
commit
635a4ba111
|
@ -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
|
||||
|
|
Can't render this file because it has a wrong number of fields in line 20.
|
|
@ -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);
|
||||
|
|
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
* 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, ©->base);
|
||||
copy->zpos = exynos_state->zpos;
|
||||
return ©->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 -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sti_plane_attach_zorder_property(struct drm_plane *drm_plane)
|
||||
void sti_plane_reset(struct drm_plane *plane)
|
||||
{
|
||||
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;
|
||||
drm_atomic_helper_plane_reset(plane);
|
||||
plane->state->zpos = sti_plane_get_default_zpos(plane->type);
|
||||
}
|
||||
|
||||
prop = private->plane_zorder_property;
|
||||
if (!prop) {
|
||||
prop = drm_property_create_range(dev, 0, "zpos", 1,
|
||||
GAM_MIXER_NB_DEPTH_LEVEL);
|
||||
if (!prop)
|
||||
return;
|
||||
static void sti_plane_attach_zorder_property(struct drm_plane *drm_plane,
|
||||
enum drm_plane_type type)
|
||||
{
|
||||
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;
|
||||
sti_plane_attach_zorder_property(&plane->drm_plane, type);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue