* [PATCH v2 0/3] drm/exynos: introduce generic zpos property
@ 2016-01-11 11:03 Marek Szyprowski
2016-01-11 11:03 ` [PATCH v2 1/3] drm: add " Marek Szyprowski
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Marek Szyprowski @ 2016-01-11 11:03 UTC (permalink / raw)
To: dri-devel, linux-samsung-soc
Cc: Marek Szyprowski, Inki Dae, Daniel Vetter,
Ville Syrjälä, Joonyoung Shim, Seung-Woo Kim,
Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
Tobias Jakobi, Gustavo Padovan, Benjamin Gaignard, vincent.abriou,
fabien.dessenne
Hello all,
This patch series is a continuation of rework of blending support in
Exynos DRM driver. Some background can be found here:
http://www.spinics.net/lists/dri-devel/msg96969.html
Daniel Vetter suggested that zpos property should be made generic, with
well-defined semantics. This patchset is my proposal for such generic
zpos property:
- added zpos properties to drm core and plane state structures,
- added helpers for normalizing zpos properties of given set of planes,
- well defined semantics: planes are sorted by zpos values and then plane
id value if zpos equals.
Patches are based on top of latest exynos-drm-next branch.
Best regards
Marek Szyprowski
Samsung R&D Institute Poland
Changelog:
v2:
- dropped 2 fixes for Exynos DRM, which got merged in meantime
- added more comments and kernel docs for core functions as suggested
by Daniel Vetter
- reworked initialization of zpos properties (moved assiging property
class to common code), now the code in the driver is even simpler
- while reworking of intialization of zpos property code, did the same
change to generic rotation property
v1: http://www.spinics.net/lists/dri-devel/msg97709.html
- initial version
Patch summary:
Marek Szyprowski (3):
drm: add generic zpos property
drm/exynos: use generic code for managing zpos plane property
drm: simplify initialization of rotation property
Documentation/DocBook/gpu.tmpl | 14 ++++-
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 10 ++--
drivers/gpu/drm/drm_atomic.c | 4 ++
drivers/gpu/drm/drm_atomic_helper.c | 45 +++++++++++++++
drivers/gpu/drm/drm_crtc.c | 73 +++++++++++++++++++++++--
drivers/gpu/drm/exynos/exynos_drm_drv.h | 1 -
drivers/gpu/drm/exynos/exynos_drm_plane.c | 66 +++++-----------------
drivers/gpu/drm/exynos/exynos_mixer.c | 19 ++++++-
drivers/gpu/drm/i915/intel_display.c | 6 +-
drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 3 +-
drivers/gpu/drm/omapdrm/omap_drv.c | 3 +-
include/drm/drm_atomic_helper.h | 2 +
include/drm/drm_crtc.h | 16 +++++-
13 files changed, 182 insertions(+), 80 deletions(-)
--
1.9.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 1/3] drm: add generic zpos property
2016-01-11 11:03 [PATCH v2 0/3] drm/exynos: introduce generic zpos property Marek Szyprowski
@ 2016-01-11 11:03 ` Marek Szyprowski
2016-01-11 15:14 ` Daniel Vetter
2016-01-11 11:03 ` [PATCH v2 2/3] drm/exynos: use generic code for managing zpos plane property Marek Szyprowski
2016-01-11 11:03 ` [PATCH v2 3/3] drm: simplify initialization of rotation property Marek Szyprowski
2 siblings, 1 reply; 8+ messages in thread
From: Marek Szyprowski @ 2016-01-11 11:03 UTC (permalink / raw)
To: dri-devel, linux-samsung-soc
Cc: Marek Szyprowski, Inki Dae, Daniel Vetter,
Ville Syrjälä, Joonyoung Shim, Seung-Woo Kim,
Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
Tobias Jakobi, Gustavo Padovan, Benjamin Gaignard, vincent.abriou,
fabien.dessenne
This patch adds support for generic plane's zpos property property with
well-defined semantics:
- added zpos properties to drm core and plane state structures
- added helpers for normalizing zpos properties of given set of planes
- well defined semantics: planes are sorted by zpos values and then plane
id value if zpos equals
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
Documentation/DocBook/gpu.tmpl | 14 +++++++++--
drivers/gpu/drm/drm_atomic.c | 4 ++++
drivers/gpu/drm/drm_atomic_helper.c | 45 +++++++++++++++++++++++++++++++++++
drivers/gpu/drm/drm_crtc.c | 47 +++++++++++++++++++++++++++++++++++++
include/drm/drm_atomic_helper.h | 2 ++
include/drm/drm_crtc.h | 12 ++++++++++
6 files changed, 122 insertions(+), 2 deletions(-)
diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl
index 6c6e81a9eaf4..e81acd999891 100644
--- a/Documentation/DocBook/gpu.tmpl
+++ b/Documentation/DocBook/gpu.tmpl
@@ -2004,7 +2004,7 @@ void intel_crt_init(struct drm_device *dev)
<td valign="top" >Description/Restrictions</td>
</tr>
<tr>
- <td rowspan="37" valign="top" >DRM</td>
+ <td rowspan="38" valign="top" >DRM</td>
<td valign="top" >Generic</td>
<td valign="top" >“rotation”</td>
<td valign="top" >BITMASK</td>
@@ -2256,7 +2256,7 @@ void intel_crt_init(struct drm_device *dev)
<td valign="top" >property to suggest an Y offset for a connector</td>
</tr>
<tr>
- <td rowspan="3" valign="top" >Optional</td>
+ <td rowspan="4" valign="top" >Optional</td>
<td valign="top" >“scaling mode”</td>
<td valign="top" >ENUM</td>
<td valign="top" >{ "None", "Full", "Center", "Full aspect" }</td>
@@ -2280,6 +2280,16 @@ void intel_crt_init(struct drm_device *dev)
<td valign="top" >TBD</td>
</tr>
<tr>
+ <td valign="top" > "zpos" </td>
+ <td valign="top" >RANGE</td>
+ <td valign="top" >Min=0, Max=255</td>
+ <td valign="top" >Plane</td>
+ <td valign="top" >Plane's 'z' position during blending (0 for background, 255 for frontmost).
+ If two planes assigned to same CRTC have equal zpos values, the plane with higher plane
+ id is treated as closer to front. Can be IMMUTABLE if driver doesn't support changing
+ planes' order.</td>
+ </tr>
+ <tr>
<td rowspan="20" valign="top" >i915</td>
<td rowspan="2" valign="top" >Generic</td>
<td valign="top" >"Broadcast RGB"</td>
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 6a21e5c378c1..97bb069cb6a3 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -614,6 +614,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 == config->zpos_property) {
+ state->zpos = val;
} else if (plane->funcs->atomic_set_property) {
return plane->funcs->atomic_set_property(plane, state,
property, val);
@@ -670,6 +672,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 == config->zpos_property) {
+ *val = state->zpos;
} else if (plane->funcs->atomic_get_property) {
return plane->funcs->atomic_get_property(plane, state, property, val);
} else {
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 268d37f26960..167d32346e2f 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -31,6 +31,7 @@
#include <drm/drm_crtc_helper.h>
#include <drm/drm_atomic_helper.h>
#include <linux/fence.h>
+#include <linux/sort.h>
/**
* DOC: overview
@@ -2781,3 +2782,47 @@ void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
kfree(state);
}
EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
+
+static int __drm_atomic_helper_plane_zpos_cmp(const void *a, const void *b)
+{
+ const struct drm_plane *pa = *(struct drm_plane **)a;
+ const struct drm_plane *pb = *(struct drm_plane **)b;
+ int zpos_a = 0, zpos_b = 0;
+
+ if (pa->state)
+ zpos_a = pa->state->zpos << 16;
+ if (pb->state)
+ zpos_b = pb->state->zpos << 16;
+
+ zpos_a += pa->base.id;
+ zpos_b += pb->base.id;
+
+ return zpos_a - zpos_b;
+}
+
+/**
+ * drm_atomic_helper_normalize_zpos - calculate normalized zpos values
+ * @planes: arrays of pointer to planes to consider for normalization
+ * @count: number of planes in the above array
+ *
+ * This function takes arrays of pointers to planes and calculates normalized
+ * zpos value for them taking into account each planes[i]->state->zpos value
+ * and plane's id. Planes are compared first by their zpos values, then in case
+ * they equal, by plane id. Plane with lowest zpos value is at the bottom.
+ * The plane[i]->state->normalized_zpos is then filled with uniqe values from 0
+ * to count-1.
+ * Note: a side effect of this function is the fact that the planes array will
+ * be modified (sorted). It is up to the caller to construct planes array with
+ * all planes that have been assigned to given crtc.
+ */
+void drm_atomic_helper_normalize_zpos(struct drm_plane *planes[], int count)
+{
+ int i;
+
+ sort(planes, count, sizeof(struct drm_plane *),
+ __drm_atomic_helper_plane_zpos_cmp, NULL);
+ for (i = 0; i < count; i++)
+ if (planes[i]->state)
+ planes[i]->state->normalized_zpos = i;
+}
+EXPORT_SYMBOL(drm_atomic_helper_normalize_zpos);
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 62fa95fa5471..e33866084b70 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -5880,6 +5880,53 @@ struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
EXPORT_SYMBOL(drm_mode_create_rotation_property);
/**
+ * drm_mode_create_zpos_property - create muttable zpos property
+ * @dev: DRM device
+ *
+ * This function initializes generic muttable 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.
+ * Drivers can also use drm_atomic_helper_normalize_zpos() function to calculate
+ * drm_plane_state->normalized_zpos values.
+ */
+int drm_mode_create_zpos_property(struct drm_device *dev)
+{
+ struct drm_property *prop;
+
+ prop = drm_property_create_range(dev, 0, "zpos", 0, 255);
+ if (!prop)
+ return -ENOMEM;
+
+ dev->mode_config.zpos_property = prop;
+ return 0;
+}
+EXPORT_SYMBOL(drm_mode_create_zpos_property);
+
+/**
+ * drm_plane_create_zpos_property - create immuttable zpos property
+ * @dev: DRM device
+ *
+ * This function initializes generic immuttable 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.
+ */
+int drm_mode_create_zpos_immutable_property(struct drm_device *dev)
+{
+ struct drm_property *prop;
+
+ prop = drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "zpos",
+ 0, 255);
+ if (!prop)
+ return -ENOMEM;
+
+ dev->mode_config.zpos_immutable_property = prop;
+ return 0;
+}
+EXPORT_SYMBOL(drm_mode_create_zpos_immutable_property);
+
+/**
* DOC: Tile group
*
* Tile groups are used to represent tiled monitors with a unique
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index a286cce98720..2a7ade5ad8bd 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -141,6 +141,8 @@ __drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
struct drm_connector_state *state);
+void drm_atomic_helper_normalize_zpos(struct drm_plane *planes[], int count);
+
/**
* drm_atomic_crtc_for_each_plane - iterate over planes currently attached to CRTC
* @plane: the loop cursor
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 3b040b355472..13035e2c5e51 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1243,6 +1243,9 @@ struct drm_connector {
* plane (in 16.16)
* @src_w: width of visible portion of plane (in 16.16)
* @src_h: height of visible portion of plane (in 16.16)
+ * @zpos: priority of the given plane on crtc (optional)
+ * @normalized_zpos: normalized value of zpos: uniqe, range from 0 to
+ * (number of planes - 1) for given crtc
* @state: backpointer to global drm_atomic_state
*/
struct drm_plane_state {
@@ -1263,6 +1266,10 @@ struct drm_plane_state {
/* Plane rotation */
unsigned int rotation;
+ /* Plane zpos */
+ unsigned int zpos;
+ unsigned int normalized_zpos;
+
struct drm_atomic_state *state;
};
@@ -2083,6 +2090,8 @@ struct drm_mode_config {
struct drm_property *tile_property;
struct drm_property *plane_type_property;
struct drm_property *rotation_property;
+ struct drm_property *zpos_property;
+ struct drm_property *zpos_immutable_property;
struct drm_property *prop_src_x;
struct drm_property *prop_src_y;
struct drm_property *prop_src_w;
@@ -2484,6 +2493,9 @@ extern struct drm_property *drm_mode_create_rotation_property(struct drm_device
extern unsigned int drm_rotation_simplify(unsigned int rotation,
unsigned int supported_rotations);
+extern int drm_mode_create_zpos_property(struct drm_device *dev);
+extern int drm_mode_create_zpos_immutable_property(struct drm_device *dev);
+
/* Helpers */
static inline struct drm_plane *drm_plane_find(struct drm_device *dev,
--
1.9.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 2/3] drm/exynos: use generic code for managing zpos plane property
2016-01-11 11:03 [PATCH v2 0/3] drm/exynos: introduce generic zpos property Marek Szyprowski
2016-01-11 11:03 ` [PATCH v2 1/3] drm: add " Marek Szyprowski
@ 2016-01-11 11:03 ` Marek Szyprowski
2016-01-11 15:13 ` Daniel Vetter
2016-01-11 11:03 ` [PATCH v2 3/3] drm: simplify initialization of rotation property Marek Szyprowski
2 siblings, 1 reply; 8+ messages in thread
From: Marek Szyprowski @ 2016-01-11 11:03 UTC (permalink / raw)
To: dri-devel, linux-samsung-soc
Cc: Marek Szyprowski, Inki Dae, Daniel Vetter,
Ville Syrjälä, Joonyoung Shim, Seung-Woo Kim,
Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
Tobias Jakobi, Gustavo Padovan, Benjamin Gaignard, vincent.abriou,
fabien.dessenne
This patch replaces zpos property handling custom code in Exynos DRM
driver with calls to generic DRM code.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/gpu/drm/exynos/exynos_drm_drv.h | 1 -
drivers/gpu/drm/exynos/exynos_drm_plane.c | 66 +++++++------------------------
drivers/gpu/drm/exynos/exynos_mixer.c | 19 +++++++--
3 files changed, 30 insertions(+), 56 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 17b5ded72ff1..244ae6c4482c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -217,7 +217,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;
unsigned long da_start;
unsigned long da_space_size;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index d86227236f55..ba46bc3de796 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -137,9 +137,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;
}
}
@@ -155,7 +155,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;
}
@@ -168,43 +167,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,
@@ -213,8 +175,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
@@ -302,20 +262,21 @@ static const struct drm_plane_helper_funcs plane_helper_funcs = {
};
static void exynos_plane_attach_zpos_property(struct drm_plane *plane,
- unsigned int zpos)
+ 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;
+ if (immutable) {
+ if (!dev->mode_config.zpos_immutable_property)
+ if (!drm_mode_create_zpos_immutable_property(dev))
+ return;
+ prop = dev->mode_config.zpos_immutable_property;
+ } else {
+ if (!dev->mode_config.zpos_property)
+ if (!drm_mode_create_zpos_property(dev))
+ return;
+ prop = dev->mode_config.zpos_property;
}
drm_object_attach_property(&plane->base, prop, zpos);
@@ -344,7 +305,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->zpos,
+ !(config->capabilities & EXYNOS_DRM_PLANE_CAP_ZPOS));
return 0;
}
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index b5fbc1cbf024..6ab68eca0004 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -34,6 +34,7 @@
#include <linux/component.h>
#include <drm/exynos_drm.h>
+#include <drm/drm_atomic_helper.h>
#include "exynos_drm_drv.h"
#include "exynos_drm_crtc.h"
@@ -95,6 +96,8 @@ struct mixer_context {
struct drm_device *drm_dev;
struct exynos_drm_crtc *crtc;
struct exynos_drm_plane planes[MIXER_WIN_NR];
+ struct drm_plane *zpos_planes[MIXER_WIN_NR];
+ int num_planes;
int pipe;
unsigned long flags;
bool interlace;
@@ -478,6 +481,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;
@@ -562,7 +566,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);
@@ -587,6 +591,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;
@@ -678,7 +683,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 */
@@ -981,6 +986,12 @@ static void mixer_atomic_begin(struct exynos_drm_crtc *crtc)
if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
return;
+ /*
+ * Normalizing up to 3 planes is cheap, no need for checking
+ * if zpos has been really changed.
+ */
+ drm_atomic_helper_normalize_zpos(mixer_ctx->zpos_planes,
+ mixer_ctx->num_planes);
mixer_vsync_set_update(mixer_ctx, false);
}
@@ -1203,13 +1214,15 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data)
for (i = 0; i < MIXER_WIN_NR; i++) {
if (i == VP_DEFAULT_WIN && !ctx->vp_enabled)
- continue;
+ break;
ret = exynos_plane_init(drm_dev, &ctx->planes[i], i,
1 << ctx->pipe, &plane_configs[i]);
if (ret)
return ret;
+ ctx->zpos_planes[i] = &ctx->planes[i].base;
}
+ ctx->num_planes = i;
exynos_plane = &ctx->planes[DEFAULT_WIN];
ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
--
1.9.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 3/3] drm: simplify initialization of rotation property
2016-01-11 11:03 [PATCH v2 0/3] drm/exynos: introduce generic zpos property Marek Szyprowski
2016-01-11 11:03 ` [PATCH v2 1/3] drm: add " Marek Szyprowski
2016-01-11 11:03 ` [PATCH v2 2/3] drm/exynos: use generic code for managing zpos plane property Marek Szyprowski
@ 2016-01-11 11:03 ` Marek Szyprowski
2 siblings, 0 replies; 8+ messages in thread
From: Marek Szyprowski @ 2016-01-11 11:03 UTC (permalink / raw)
To: dri-devel, linux-samsung-soc
Cc: Marek Szyprowski, Inki Dae, Daniel Vetter,
Ville Syrjälä, Joonyoung Shim, Seung-Woo Kim,
Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
Tobias Jakobi, Gustavo Padovan, Benjamin Gaignard, vincent.abriou,
fabien.dessenne
This patch simplifies initialization of generic rotation property and
aligns the code to match recently introduced function for intializing
generic zpos property. It also adds missing documentation.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 10 ++++------
drivers/gpu/drm/drm_crtc.c | 26 +++++++++++++++++++------
drivers/gpu/drm/i915/intel_display.c | 6 ++----
drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 3 +--
drivers/gpu/drm/omapdrm/omap_drv.c | 3 +--
include/drm/drm_crtc.h | 4 ++--
6 files changed, 30 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index 1ffe9c329c46..4f9606cdf0f2 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -967,12 +967,10 @@ atmel_hlcdc_plane_create_properties(struct drm_device *dev)
if (!props->alpha)
return ERR_PTR(-ENOMEM);
- dev->mode_config.rotation_property =
- drm_mode_create_rotation_property(dev,
- BIT(DRM_ROTATE_0) |
- BIT(DRM_ROTATE_90) |
- BIT(DRM_ROTATE_180) |
- BIT(DRM_ROTATE_270));
+ drm_mode_create_rotation_property(dev, BIT(DRM_ROTATE_0) |
+ BIT(DRM_ROTATE_90) |
+ BIT(DRM_ROTATE_180) |
+ BIT(DRM_ROTATE_270));
if (!dev->mode_config.rotation_property)
return ERR_PTR(-ENOMEM);
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index e33866084b70..890c5925e6db 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -5861,10 +5861,20 @@ void drm_mode_config_cleanup(struct drm_device *dev)
}
EXPORT_SYMBOL(drm_mode_config_cleanup);
-struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
- unsigned int supported_rotations)
+/**
+ * drm_mode_create_rotation_property - create generic rotation property
+ * @dev: DRM device
+ * @supported_rotations: bitmask of supported rotation modes
+ *
+ * This function initializes generic rotation property and enables support
+ * for it in drm core. Drivers can then attach this property to planes to enable
+ * support for different rotation modes.
+ */
+int drm_mode_create_rotation_property(struct drm_device *dev,
+ unsigned int supported_rotations)
{
- static const struct drm_prop_enum_list props[] = {
+ struct drm_property *prop;
+ static const struct drm_prop_enum_list values[] = {
{ DRM_ROTATE_0, "rotate-0" },
{ DRM_ROTATE_90, "rotate-90" },
{ DRM_ROTATE_180, "rotate-180" },
@@ -5873,9 +5883,13 @@ struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
{ DRM_REFLECT_Y, "reflect-y" },
};
- return drm_property_create_bitmask(dev, 0, "rotation",
- props, ARRAY_SIZE(props),
- supported_rotations);
+ prop = drm_property_create_bitmask(dev, 0, "rotation", values,
+ ARRAY_SIZE(values), supported_rotations);
+ if (!prop)
+ return -ENOMEM;
+
+ dev->mode_config.rotation_property = prop;
+ return 0;
}
EXPORT_SYMBOL(drm_mode_create_rotation_property);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 02f6ccb848a9..5b7ba46491a0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14042,8 +14042,7 @@ void intel_create_rotation_property(struct drm_device *dev, struct intel_plane *
if (INTEL_INFO(dev)->gen >= 9)
flags |= BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_270);
- dev->mode_config.rotation_property =
- drm_mode_create_rotation_property(dev, flags);
+ drm_mode_create_rotation_property(dev, flags);
}
if (dev->mode_config.rotation_property)
drm_object_attach_property(&plane->base.base,
@@ -14179,8 +14178,7 @@ static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
if (INTEL_INFO(dev)->gen >= 4) {
if (!dev->mode_config.rotation_property)
- dev->mode_config.rotation_property =
- drm_mode_create_rotation_property(dev,
+ drm_mode_create_rotation_property(dev,
BIT(DRM_ROTATE_0) |
BIT(DRM_ROTATE_180));
if (dev->mode_config.rotation_property)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
index 432c09836b0e..8defeec0d453 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
@@ -76,8 +76,7 @@ static void mdp5_plane_install_rotation_property(struct drm_device *dev,
return;
if (!dev->mode_config.rotation_property)
- dev->mode_config.rotation_property =
- drm_mode_create_rotation_property(dev,
+ drm_mode_create_rotation_property(dev,
BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y));
if (dev->mode_config.rotation_property)
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index dfafdb602ad2..c6ce2b31f1c5 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -304,8 +304,7 @@ static int omap_modeset_init_properties(struct drm_device *dev)
struct omap_drm_private *priv = dev->dev_private;
if (priv->has_dmm) {
- dev->mode_config.rotation_property =
- drm_mode_create_rotation_property(dev,
+ drm_mode_create_rotation_property(dev,
BIT(DRM_ROTATE_0) | BIT(DRM_ROTATE_90) |
BIT(DRM_ROTATE_180) | BIT(DRM_ROTATE_270) |
BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y));
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 13035e2c5e51..7fe38dc8244a 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -2488,8 +2488,8 @@ extern int drm_format_plane_cpp(uint32_t format, int plane);
extern int drm_format_horz_chroma_subsampling(uint32_t format);
extern int drm_format_vert_chroma_subsampling(uint32_t format);
extern const char *drm_get_format_name(uint32_t format);
-extern struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
- unsigned int supported_rotations);
+extern int drm_mode_create_rotation_property(struct drm_device *dev,
+ unsigned int supported_rotations);
extern unsigned int drm_rotation_simplify(unsigned int rotation,
unsigned int supported_rotations);
--
1.9.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/3] drm/exynos: use generic code for managing zpos plane property
2016-01-11 11:03 ` [PATCH v2 2/3] drm/exynos: use generic code for managing zpos plane property Marek Szyprowski
@ 2016-01-11 15:13 ` Daniel Vetter
2016-01-12 9:34 ` Marek Szyprowski
0 siblings, 1 reply; 8+ messages in thread
From: Daniel Vetter @ 2016-01-11 15:13 UTC (permalink / raw)
To: Marek Szyprowski
Cc: dri-devel, linux-samsung-soc, Inki Dae, Daniel Vetter,
Ville Syrjälä, Joonyoung Shim, Seung-Woo Kim,
Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
Tobias Jakobi, Gustavo Padovan, Benjamin Gaignard, vincent.abriou,
fabien.dessenne
On Mon, Jan 11, 2016 at 12:03:04PM +0100, Marek Szyprowski wrote:
> This patch replaces zpos property handling custom code in Exynos DRM
> driver with calls to generic DRM code.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
> drivers/gpu/drm/exynos/exynos_drm_drv.h | 1 -
> drivers/gpu/drm/exynos/exynos_drm_plane.c | 66 +++++++------------------------
> drivers/gpu/drm/exynos/exynos_mixer.c | 19 +++++++--
> 3 files changed, 30 insertions(+), 56 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
> index 17b5ded72ff1..244ae6c4482c 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
> @@ -217,7 +217,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;
>
> unsigned long da_start;
> unsigned long da_space_size;
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
> index d86227236f55..ba46bc3de796 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
> @@ -137,9 +137,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;
> }
> }
>
> @@ -155,7 +155,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;
> }
>
> @@ -168,43 +167,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,
> @@ -213,8 +175,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
> @@ -302,20 +262,21 @@ static const struct drm_plane_helper_funcs plane_helper_funcs = {
> };
>
> static void exynos_plane_attach_zpos_property(struct drm_plane *plane,
> - unsigned int zpos)
> + 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;
> + if (immutable) {
> + if (!dev->mode_config.zpos_immutable_property)
> + if (!drm_mode_create_zpos_immutable_property(dev))
> + return;
> + prop = dev->mode_config.zpos_immutable_property;
> + } else {
> + if (!dev->mode_config.zpos_property)
> + if (!drm_mode_create_zpos_property(dev))
> + return;
> + prop = dev->mode_config.zpos_property;
> }
>
> drm_object_attach_property(&plane->base, prop, zpos);
> @@ -344,7 +305,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->zpos,
> + !(config->capabilities & EXYNOS_DRM_PLANE_CAP_ZPOS));
>
> return 0;
> }
> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
> index b5fbc1cbf024..6ab68eca0004 100644
> --- a/drivers/gpu/drm/exynos/exynos_mixer.c
> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
> @@ -34,6 +34,7 @@
> #include <linux/component.h>
>
> #include <drm/exynos_drm.h>
> +#include <drm/drm_atomic_helper.h>
>
> #include "exynos_drm_drv.h"
> #include "exynos_drm_crtc.h"
> @@ -95,6 +96,8 @@ struct mixer_context {
> struct drm_device *drm_dev;
> struct exynos_drm_crtc *crtc;
> struct exynos_drm_plane planes[MIXER_WIN_NR];
> + struct drm_plane *zpos_planes[MIXER_WIN_NR];
> + int num_planes;
> int pipe;
> unsigned long flags;
> bool interlace;
> @@ -478,6 +481,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;
> @@ -562,7 +566,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);
>
> @@ -587,6 +591,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;
> @@ -678,7 +683,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 */
> @@ -981,6 +986,12 @@ static void mixer_atomic_begin(struct exynos_drm_crtc *crtc)
> if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
> return;
>
> + /*
> + * Normalizing up to 3 planes is cheap, no need for checking
> + * if zpos has been really changed.
> + */
> + drm_atomic_helper_normalize_zpos(mixer_ctx->zpos_planes,
> + mixer_ctx->num_planes);
Hm, this is a bit a cumbersome interface for drivers and will make
converting over to the normalized zpos more work. Can't we handle this in
the atomic helpers directly? I'm thinking of the following flow:
- if new_plane_state->zpos != old_plane_state->zpos then set new_crtc_state->zpos_changed
- if new_crtc_state->plane_mask != old_crtc_state->plane_mask ||
new_crtc_state->zpos_changed then recompute normilized zpos.
Imo that would fit well in drm_atomic_helper_check_planes().
With that bit of additional logic drivers can just use normlized_zpos and
don't need to care about anything really.
Thoughts?
-Daniel
> mixer_vsync_set_update(mixer_ctx, false);
> }
>
> @@ -1203,13 +1214,15 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data)
>
> for (i = 0; i < MIXER_WIN_NR; i++) {
> if (i == VP_DEFAULT_WIN && !ctx->vp_enabled)
> - continue;
> + break;
>
> ret = exynos_plane_init(drm_dev, &ctx->planes[i], i,
> 1 << ctx->pipe, &plane_configs[i]);
> if (ret)
> return ret;
> + ctx->zpos_planes[i] = &ctx->planes[i].base;
> }
> + ctx->num_planes = i;
>
> exynos_plane = &ctx->planes[DEFAULT_WIN];
> ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
> --
> 1.9.2
>
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/3] drm: add generic zpos property
2016-01-11 11:03 ` [PATCH v2 1/3] drm: add " Marek Szyprowski
@ 2016-01-11 15:14 ` Daniel Vetter
0 siblings, 0 replies; 8+ messages in thread
From: Daniel Vetter @ 2016-01-11 15:14 UTC (permalink / raw)
To: Marek Szyprowski
Cc: dri-devel, linux-samsung-soc, Inki Dae, Daniel Vetter,
Ville Syrjälä, Joonyoung Shim, Seung-Woo Kim,
Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
Tobias Jakobi, Gustavo Padovan, Benjamin Gaignard, vincent.abriou,
fabien.dessenne
On Mon, Jan 11, 2016 at 12:03:03PM +0100, Marek Szyprowski wrote:
> This patch adds support for generic plane's zpos property property with
> well-defined semantics:
> - added zpos properties to drm core and plane state structures
> - added helpers for normalizing zpos properties of given set of planes
> - well defined semantics: planes are sorted by zpos values and then plane
> id value if zpos equals
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
> Documentation/DocBook/gpu.tmpl | 14 +++++++++--
> drivers/gpu/drm/drm_atomic.c | 4 ++++
> drivers/gpu/drm/drm_atomic_helper.c | 45 +++++++++++++++++++++++++++++++++++
> drivers/gpu/drm/drm_crtc.c | 47 +++++++++++++++++++++++++++++++++++++
> include/drm/drm_atomic_helper.h | 2 ++
> include/drm/drm_crtc.h | 12 ++++++++++
> 6 files changed, 122 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl
> index 6c6e81a9eaf4..e81acd999891 100644
> --- a/Documentation/DocBook/gpu.tmpl
> +++ b/Documentation/DocBook/gpu.tmpl
> @@ -2004,7 +2004,7 @@ void intel_crt_init(struct drm_device *dev)
> <td valign="top" >Description/Restrictions</td>
> </tr>
> <tr>
> - <td rowspan="37" valign="top" >DRM</td>
> + <td rowspan="38" valign="top" >DRM</td>
> <td valign="top" >Generic</td>
> <td valign="top" >“rotation”</td>
> <td valign="top" >BITMASK</td>
> @@ -2256,7 +2256,7 @@ void intel_crt_init(struct drm_device *dev)
> <td valign="top" >property to suggest an Y offset for a connector</td>
> </tr>
> <tr>
> - <td rowspan="3" valign="top" >Optional</td>
> + <td rowspan="4" valign="top" >Optional</td>
> <td valign="top" >“scaling mode”</td>
> <td valign="top" >ENUM</td>
> <td valign="top" >{ "None", "Full", "Center", "Full aspect" }</td>
> @@ -2280,6 +2280,16 @@ void intel_crt_init(struct drm_device *dev)
> <td valign="top" >TBD</td>
> </tr>
> <tr>
> + <td valign="top" > "zpos" </td>
> + <td valign="top" >RANGE</td>
> + <td valign="top" >Min=0, Max=255</td>
> + <td valign="top" >Plane</td>
> + <td valign="top" >Plane's 'z' position during blending (0 for background, 255 for frontmost).
> + If two planes assigned to same CRTC have equal zpos values, the plane with higher plane
> + id is treated as closer to front. Can be IMMUTABLE if driver doesn't support changing
> + planes' order.</td>
> + </tr>
> + <tr>
> <td rowspan="20" valign="top" >i915</td>
> <td rowspan="2" valign="top" >Generic</td>
> <td valign="top" >"Broadcast RGB"</td>
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 6a21e5c378c1..97bb069cb6a3 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -614,6 +614,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 == config->zpos_property) {
> + state->zpos = val;
> } else if (plane->funcs->atomic_set_property) {
> return plane->funcs->atomic_set_property(plane, state,
> property, val);
> @@ -670,6 +672,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 == config->zpos_property) {
> + *val = state->zpos;
> } else if (plane->funcs->atomic_get_property) {
> return plane->funcs->atomic_get_property(plane, state, property, val);
> } else {
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 268d37f26960..167d32346e2f 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -31,6 +31,7 @@
> #include <drm/drm_crtc_helper.h>
> #include <drm/drm_atomic_helper.h>
> #include <linux/fence.h>
> +#include <linux/sort.h>
>
> /**
> * DOC: overview
> @@ -2781,3 +2782,47 @@ void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
> kfree(state);
> }
> EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
> +
> +static int __drm_atomic_helper_plane_zpos_cmp(const void *a, const void *b)
> +{
> + const struct drm_plane *pa = *(struct drm_plane **)a;
> + const struct drm_plane *pb = *(struct drm_plane **)b;
> + int zpos_a = 0, zpos_b = 0;
> +
> + if (pa->state)
> + zpos_a = pa->state->zpos << 16;
> + if (pb->state)
> + zpos_b = pb->state->zpos << 16;
> +
> + zpos_a += pa->base.id;
> + zpos_b += pb->base.id;
> +
> + return zpos_a - zpos_b;
> +}
> +
> +/**
> + * drm_atomic_helper_normalize_zpos - calculate normalized zpos values
> + * @planes: arrays of pointer to planes to consider for normalization
> + * @count: number of planes in the above array
> + *
> + * This function takes arrays of pointers to planes and calculates normalized
> + * zpos value for them taking into account each planes[i]->state->zpos value
> + * and plane's id. Planes are compared first by their zpos values, then in case
> + * they equal, by plane id. Plane with lowest zpos value is at the bottom.
> + * The plane[i]->state->normalized_zpos is then filled with uniqe values from 0
> + * to count-1.
> + * Note: a side effect of this function is the fact that the planes array will
> + * be modified (sorted). It is up to the caller to construct planes array with
> + * all planes that have been assigned to given crtc.
> + */
> +void drm_atomic_helper_normalize_zpos(struct drm_plane *planes[], int count)
> +{
> + int i;
> +
> + sort(planes, count, sizeof(struct drm_plane *),
> + __drm_atomic_helper_plane_zpos_cmp, NULL);
> + for (i = 0; i < count; i++)
> + if (planes[i]->state)
> + planes[i]->state->normalized_zpos = i;
> +}
> +EXPORT_SYMBOL(drm_atomic_helper_normalize_zpos);
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 62fa95fa5471..e33866084b70 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -5880,6 +5880,53 @@ struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
> EXPORT_SYMBOL(drm_mode_create_rotation_property);
>
> /**
> + * drm_mode_create_zpos_property - create muttable zpos property
> + * @dev: DRM device
> + *
> + * This function initializes generic muttable 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.
> + * Drivers can also use drm_atomic_helper_normalize_zpos() function to calculate
> + * drm_plane_state->normalized_zpos values.
Should also document return value semantics. Same for all the others with
non-void return value. But I have some more thoughts about the helper
interface itself (in reply to patch 2) so maybe that should wait a bit
until that's settled.
-Daniel
> + */
> +int drm_mode_create_zpos_property(struct drm_device *dev)
> +{
> + struct drm_property *prop;
> +
> + prop = drm_property_create_range(dev, 0, "zpos", 0, 255);
> + if (!prop)
> + return -ENOMEM;
> +
> + dev->mode_config.zpos_property = prop;
> + return 0;
> +}
> +EXPORT_SYMBOL(drm_mode_create_zpos_property);
> +
> +/**
> + * drm_plane_create_zpos_property - create immuttable zpos property
> + * @dev: DRM device
> + *
> + * This function initializes generic immuttable 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.
> + */
> +int drm_mode_create_zpos_immutable_property(struct drm_device *dev)
> +{
> + struct drm_property *prop;
> +
> + prop = drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "zpos",
> + 0, 255);
> + if (!prop)
> + return -ENOMEM;
> +
> + dev->mode_config.zpos_immutable_property = prop;
> + return 0;
> +}
> +EXPORT_SYMBOL(drm_mode_create_zpos_immutable_property);
> +
> +/**
> * DOC: Tile group
> *
> * Tile groups are used to represent tiled monitors with a unique
> diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
> index a286cce98720..2a7ade5ad8bd 100644
> --- a/include/drm/drm_atomic_helper.h
> +++ b/include/drm/drm_atomic_helper.h
> @@ -141,6 +141,8 @@ __drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
> void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
> struct drm_connector_state *state);
>
> +void drm_atomic_helper_normalize_zpos(struct drm_plane *planes[], int count);
> +
> /**
> * drm_atomic_crtc_for_each_plane - iterate over planes currently attached to CRTC
> * @plane: the loop cursor
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 3b040b355472..13035e2c5e51 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -1243,6 +1243,9 @@ struct drm_connector {
> * plane (in 16.16)
> * @src_w: width of visible portion of plane (in 16.16)
> * @src_h: height of visible portion of plane (in 16.16)
> + * @zpos: priority of the given plane on crtc (optional)
> + * @normalized_zpos: normalized value of zpos: uniqe, range from 0 to
> + * (number of planes - 1) for given crtc
> * @state: backpointer to global drm_atomic_state
> */
> struct drm_plane_state {
> @@ -1263,6 +1266,10 @@ struct drm_plane_state {
> /* Plane rotation */
> unsigned int rotation;
>
> + /* Plane zpos */
> + unsigned int zpos;
> + unsigned int normalized_zpos;
> +
> struct drm_atomic_state *state;
> };
>
> @@ -2083,6 +2090,8 @@ struct drm_mode_config {
> struct drm_property *tile_property;
> struct drm_property *plane_type_property;
> struct drm_property *rotation_property;
> + struct drm_property *zpos_property;
> + struct drm_property *zpos_immutable_property;
> struct drm_property *prop_src_x;
> struct drm_property *prop_src_y;
> struct drm_property *prop_src_w;
> @@ -2484,6 +2493,9 @@ extern struct drm_property *drm_mode_create_rotation_property(struct drm_device
> extern unsigned int drm_rotation_simplify(unsigned int rotation,
> unsigned int supported_rotations);
>
> +extern int drm_mode_create_zpos_property(struct drm_device *dev);
> +extern int drm_mode_create_zpos_immutable_property(struct drm_device *dev);
> +
> /* Helpers */
>
> static inline struct drm_plane *drm_plane_find(struct drm_device *dev,
> --
> 1.9.2
>
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/3] drm/exynos: use generic code for managing zpos plane property
2016-01-11 15:13 ` Daniel Vetter
@ 2016-01-12 9:34 ` Marek Szyprowski
2016-01-12 10:39 ` Daniel Vetter
0 siblings, 1 reply; 8+ messages in thread
From: Marek Szyprowski @ 2016-01-12 9:34 UTC (permalink / raw)
To: Daniel Vetter
Cc: dri-devel, linux-samsung-soc, Inki Dae, Ville Syrjälä,
Joonyoung Shim, Seung-Woo Kim, Andrzej Hajda, Krzysztof Kozlowski,
Bartlomiej Zolnierkiewicz, Tobias Jakobi, Gustavo Padovan,
Benjamin Gaignard, vincent.abriou, fabien.dessenne
Hello,
On 2016-01-11 16:13, Daniel Vetter wrote:
> On Mon, Jan 11, 2016 at 12:03:04PM +0100, Marek Szyprowski wrote:
>> This patch replaces zpos property handling custom code in Exynos DRM
>> driver with calls to generic DRM code.
>>
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> ---
>> drivers/gpu/drm/exynos/exynos_drm_drv.h | 1 -
>> drivers/gpu/drm/exynos/exynos_drm_plane.c | 66 +++++++------------------------
>> drivers/gpu/drm/exynos/exynos_mixer.c | 19 +++++++--
>> 3 files changed, 30 insertions(+), 56 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
>> index 17b5ded72ff1..244ae6c4482c 100644
>> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
>> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
>> @@ -217,7 +217,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;
>>
>> unsigned long da_start;
>> unsigned long da_space_size;
>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
>> index d86227236f55..ba46bc3de796 100644
>> --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
>> +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
>> @@ -137,9 +137,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;
>> }
>> }
>>
>> @@ -155,7 +155,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;
>> }
>>
>> @@ -168,43 +167,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,
>> @@ -213,8 +175,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
>> @@ -302,20 +262,21 @@ static const struct drm_plane_helper_funcs plane_helper_funcs = {
>> };
>>
>> static void exynos_plane_attach_zpos_property(struct drm_plane *plane,
>> - unsigned int zpos)
>> + 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;
>> + if (immutable) {
>> + if (!dev->mode_config.zpos_immutable_property)
>> + if (!drm_mode_create_zpos_immutable_property(dev))
>> + return;
>> + prop = dev->mode_config.zpos_immutable_property;
>> + } else {
>> + if (!dev->mode_config.zpos_property)
>> + if (!drm_mode_create_zpos_property(dev))
>> + return;
>> + prop = dev->mode_config.zpos_property;
>> }
>>
>> drm_object_attach_property(&plane->base, prop, zpos);
>> @@ -344,7 +305,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->zpos,
>> + !(config->capabilities & EXYNOS_DRM_PLANE_CAP_ZPOS));
>>
>> return 0;
>> }
>> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
>> index b5fbc1cbf024..6ab68eca0004 100644
>> --- a/drivers/gpu/drm/exynos/exynos_mixer.c
>> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
>> @@ -34,6 +34,7 @@
>> #include <linux/component.h>
>>
>> #include <drm/exynos_drm.h>
>> +#include <drm/drm_atomic_helper.h>
>>
>> #include "exynos_drm_drv.h"
>> #include "exynos_drm_crtc.h"
>> @@ -95,6 +96,8 @@ struct mixer_context {
>> struct drm_device *drm_dev;
>> struct exynos_drm_crtc *crtc;
>> struct exynos_drm_plane planes[MIXER_WIN_NR];
>> + struct drm_plane *zpos_planes[MIXER_WIN_NR];
>> + int num_planes;
>> int pipe;
>> unsigned long flags;
>> bool interlace;
>> @@ -478,6 +481,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;
>> @@ -562,7 +566,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);
>>
>> @@ -587,6 +591,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;
>> @@ -678,7 +683,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 */
>> @@ -981,6 +986,12 @@ static void mixer_atomic_begin(struct exynos_drm_crtc *crtc)
>> if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
>> return;
>>
>> + /*
>> + * Normalizing up to 3 planes is cheap, no need for checking
>> + * if zpos has been really changed.
>> + */
>> + drm_atomic_helper_normalize_zpos(mixer_ctx->zpos_planes,
>> + mixer_ctx->num_planes);
> Hm, this is a bit a cumbersome interface for drivers and will make
> converting over to the normalized zpos more work. Can't we handle this in
> the atomic helpers directly? I'm thinking of the following flow:
>
> - if new_plane_state->zpos != old_plane_state->zpos then set new_crtc_state->zpos_changed
> - if new_crtc_state->plane_mask != old_crtc_state->plane_mask ||
> new_crtc_state->zpos_changed then recompute normilized zpos.
>
> Imo that would fit well in drm_atomic_helper_check_planes().
>
> With that bit of additional logic drivers can just use normlized_zpos and
> don't need to care about anything really.
Okay, I will try to implement this logic.
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/3] drm/exynos: use generic code for managing zpos plane property
2016-01-12 9:34 ` Marek Szyprowski
@ 2016-01-12 10:39 ` Daniel Vetter
0 siblings, 0 replies; 8+ messages in thread
From: Daniel Vetter @ 2016-01-12 10:39 UTC (permalink / raw)
To: Marek Szyprowski
Cc: Daniel Vetter, dri-devel, linux-samsung-soc, Inki Dae,
Ville Syrjälä, Joonyoung Shim, Seung-Woo Kim,
Andrzej Hajda, Krzysztof Kozlowski, Bartlomiej Zolnierkiewicz,
Tobias Jakobi, Gustavo Padovan, Benjamin Gaignard, vincent.abriou,
fabien.dessenne
On Tue, Jan 12, 2016 at 10:34:27AM +0100, Marek Szyprowski wrote:
> Hello,
>
> On 2016-01-11 16:13, Daniel Vetter wrote:
> >On Mon, Jan 11, 2016 at 12:03:04PM +0100, Marek Szyprowski wrote:
> >>This patch replaces zpos property handling custom code in Exynos DRM
> >>driver with calls to generic DRM code.
> >>
> >>Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> >>---
> >> drivers/gpu/drm/exynos/exynos_drm_drv.h | 1 -
> >> drivers/gpu/drm/exynos/exynos_drm_plane.c | 66 +++++++------------------------
> >> drivers/gpu/drm/exynos/exynos_mixer.c | 19 +++++++--
> >> 3 files changed, 30 insertions(+), 56 deletions(-)
> >>
> >>diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
> >>index 17b5ded72ff1..244ae6c4482c 100644
> >>--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
> >>+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
> >>@@ -217,7 +217,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;
> >> unsigned long da_start;
> >> unsigned long da_space_size;
> >>diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
> >>index d86227236f55..ba46bc3de796 100644
> >>--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
> >>+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
> >>@@ -137,9 +137,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;
> >> }
> >> }
> >>@@ -155,7 +155,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;
> >> }
> >>@@ -168,43 +167,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,
> >>@@ -213,8 +175,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
> >>@@ -302,20 +262,21 @@ static const struct drm_plane_helper_funcs plane_helper_funcs = {
> >> };
> >> static void exynos_plane_attach_zpos_property(struct drm_plane *plane,
> >>- unsigned int zpos)
> >>+ 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;
> >>+ if (immutable) {
> >>+ if (!dev->mode_config.zpos_immutable_property)
> >>+ if (!drm_mode_create_zpos_immutable_property(dev))
> >>+ return;
> >>+ prop = dev->mode_config.zpos_immutable_property;
> >>+ } else {
> >>+ if (!dev->mode_config.zpos_property)
> >>+ if (!drm_mode_create_zpos_property(dev))
> >>+ return;
> >>+ prop = dev->mode_config.zpos_property;
> >> }
> >> drm_object_attach_property(&plane->base, prop, zpos);
> >>@@ -344,7 +305,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->zpos,
> >>+ !(config->capabilities & EXYNOS_DRM_PLANE_CAP_ZPOS));
> >> return 0;
> >> }
> >>diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
> >>index b5fbc1cbf024..6ab68eca0004 100644
> >>--- a/drivers/gpu/drm/exynos/exynos_mixer.c
> >>+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
> >>@@ -34,6 +34,7 @@
> >> #include <linux/component.h>
> >> #include <drm/exynos_drm.h>
> >>+#include <drm/drm_atomic_helper.h>
> >> #include "exynos_drm_drv.h"
> >> #include "exynos_drm_crtc.h"
> >>@@ -95,6 +96,8 @@ struct mixer_context {
> >> struct drm_device *drm_dev;
> >> struct exynos_drm_crtc *crtc;
> >> struct exynos_drm_plane planes[MIXER_WIN_NR];
> >>+ struct drm_plane *zpos_planes[MIXER_WIN_NR];
> >>+ int num_planes;
> >> int pipe;
> >> unsigned long flags;
> >> bool interlace;
> >>@@ -478,6 +481,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;
> >>@@ -562,7 +566,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);
> >>@@ -587,6 +591,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;
> >>@@ -678,7 +683,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 */
> >>@@ -981,6 +986,12 @@ static void mixer_atomic_begin(struct exynos_drm_crtc *crtc)
> >> if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
> >> return;
> >>+ /*
> >>+ * Normalizing up to 3 planes is cheap, no need for checking
> >>+ * if zpos has been really changed.
> >>+ */
> >>+ drm_atomic_helper_normalize_zpos(mixer_ctx->zpos_planes,
> >>+ mixer_ctx->num_planes);
> >Hm, this is a bit a cumbersome interface for drivers and will make
> >converting over to the normalized zpos more work. Can't we handle this in
> >the atomic helpers directly? I'm thinking of the following flow:
> >
> >- if new_plane_state->zpos != old_plane_state->zpos then set new_crtc_state->zpos_changed
> >- if new_crtc_state->plane_mask != old_crtc_state->plane_mask ||
> > new_crtc_state->zpos_changed then recompute normilized zpos.
> >
> >Imo that would fit well in drm_atomic_helper_check_planes().
> >
> >With that bit of additional logic drivers can just use normlized_zpos and
> >don't need to care about anything really.
>
> Okay, I will try to implement this logic.
Just to avoid another respin: If you do so I think it still makes sense to
export the current set of functions, for drivers which don't use helpers
or need to figure out the normalized zpos earlier or whatever.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2016-01-12 10:39 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-01-11 11:03 [PATCH v2 0/3] drm/exynos: introduce generic zpos property Marek Szyprowski
2016-01-11 11:03 ` [PATCH v2 1/3] drm: add " Marek Szyprowski
2016-01-11 15:14 ` Daniel Vetter
2016-01-11 11:03 ` [PATCH v2 2/3] drm/exynos: use generic code for managing zpos plane property Marek Szyprowski
2016-01-11 15:13 ` Daniel Vetter
2016-01-12 9:34 ` Marek Szyprowski
2016-01-12 10:39 ` Daniel Vetter
2016-01-11 11:03 ` [PATCH v2 3/3] drm: simplify initialization of rotation property Marek Szyprowski
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.