aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/gpu/kms-properties.csv1
-rw-r--r--drivers/gpu/drm/Makefile2
-rw-r--r--drivers/gpu/drm/drm_atomic.c4
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c7
-rw-r--r--drivers/gpu/drm/drm_blend.c238
-rw-r--r--drivers/gpu/drm/drm_crtc_internal.h4
-rw-r--r--include/drm/drm_crtc.h20
7 files changed, 275 insertions, 1 deletions
diff --git a/Documentation/gpu/kms-properties.csv b/Documentation/gpu/kms-properties.csv
index b6fcaf639c04..4c5ce3edcfd9 100644
--- a/Documentation/gpu/kms-properties.csv
+++ b/Documentation/gpu/kms-properties.csv
@@ -17,6 +17,7 @@ DRM,Generic,“rotation”,BITMASK,"{ 0, ""rotate-0"" }, { 1, ""rotate-90"" }, {
17,,“CRTC_H”,RANGE,"Min=0, Max=UINT_MAX",Plane,Scanout CRTC (destination) height (atomic) 17,,“CRTC_H”,RANGE,"Min=0, Max=UINT_MAX",Plane,Scanout CRTC (destination) height (atomic)
18,,“FB_ID”,OBJECT,DRM_MODE_OBJECT_FB,Plane,Scanout framebuffer (atomic) 18,,“FB_ID”,OBJECT,DRM_MODE_OBJECT_FB,Plane,Scanout framebuffer (atomic)
19,,“CRTC_ID”,OBJECT,DRM_MODE_OBJECT_CRTC,Plane,CRTC that plane is attached to (atomic) 19,,“CRTC_ID”,OBJECT,DRM_MODE_OBJECT_CRTC,Plane,CRTC that plane is attached to (atomic)
20,,“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"
20,DVI-I,“subconnector”,ENUM,"{ “Unknown”, “DVI-D”, “DVI-A” }",Connector,TBD 21,DVI-I,“subconnector”,ENUM,"{ “Unknown”, “DVI-D”, “DVI-A” }",Connector,TBD
21,,“select subconnector”,ENUM,"{ “Automatic”, “DVI-D”, “DVI-A” }",Connector,TBD 22,,“select subconnector”,ENUM,"{ “Automatic”, “DVI-D”, “DVI-A” }",Connector,TBD
22,TV,“subconnector”,ENUM,"{ ""Unknown"", ""Composite"", ""SVIDEO"", ""Component"", ""SCART"" }",Connector,TBD 23,TV,“subconnector”,ENUM,"{ ""Unknown"", ""Composite"", ""SVIDEO"", ""Component"", ""SCART"" }",Connector,TBD
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index e3dba6f44a79..0238bf8bc8c3 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -24,7 +24,7 @@ drm-$(CONFIG_AGP) += drm_agpsupport.o
24drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \ 24drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
25 drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \ 25 drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
26 drm_kms_helper_common.o drm_dp_dual_mode_helper.o \ 26 drm_kms_helper_common.o drm_dp_dual_mode_helper.o \
27 drm_simple_kms_helper.o 27 drm_simple_kms_helper.o drm_blend.o
28 28
29drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o 29drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
30drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o 30drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 8d2f111fa113..fa3930757972 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -711,6 +711,8 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
711 state->src_h = val; 711 state->src_h = val;
712 } else if (property == config->rotation_property) { 712 } else if (property == config->rotation_property) {
713 state->rotation = val; 713 state->rotation = val;
714 } else if (property == plane->zpos_property) {
715 state->zpos = val;
714 } else if (plane->funcs->atomic_set_property) { 716 } else if (plane->funcs->atomic_set_property) {
715 return plane->funcs->atomic_set_property(plane, state, 717 return plane->funcs->atomic_set_property(plane, state,
716 property, val); 718 property, val);
@@ -767,6 +769,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
767 *val = state->src_h; 769 *val = state->src_h;
768 } else if (property == config->rotation_property) { 770 } else if (property == config->rotation_property) {
769 *val = state->rotation; 771 *val = state->rotation;
772 } else if (property == plane->zpos_property) {
773 *val = state->zpos;
770 } else if (plane->funcs->atomic_get_property) { 774 } else if (plane->funcs->atomic_get_property) {
771 return plane->funcs->atomic_get_property(plane, state, property, val); 775 return plane->funcs->atomic_get_property(plane, state, property, val);
772 } else { 776 } else {
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index de7fddce3cef..20be86d89a20 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -32,6 +32,8 @@
32#include <drm/drm_atomic_helper.h> 32#include <drm/drm_atomic_helper.h>
33#include <linux/fence.h> 33#include <linux/fence.h>
34 34
35#include "drm_crtc_internal.h"
36
35/** 37/**
36 * DOC: overview 38 * DOC: overview
37 * 39 *
@@ -592,6 +594,10 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
592 struct drm_plane_state *plane_state; 594 struct drm_plane_state *plane_state;
593 int i, ret = 0; 595 int i, ret = 0;
594 596
597 ret = drm_atomic_helper_normalize_zpos(dev, state);
598 if (ret)
599 return ret;
600
595 for_each_plane_in_state(state, plane, plane_state, i) { 601 for_each_plane_in_state(state, plane, plane_state, i) {
596 const struct drm_plane_helper_funcs *funcs; 602 const struct drm_plane_helper_funcs *funcs;
597 603
@@ -2955,6 +2961,7 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
2955 state->planes_changed = false; 2961 state->planes_changed = false;
2956 state->connectors_changed = false; 2962 state->connectors_changed = false;
2957 state->color_mgmt_changed = false; 2963 state->color_mgmt_changed = false;
2964 state->zpos_changed = false;
2958 state->event = NULL; 2965 state->event = NULL;
2959} 2966}
2960EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state); 2967EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
new file mode 100644
index 000000000000..f3c0942bd756
--- /dev/null
+++ b/drivers/gpu/drm/drm_blend.c
@@ -0,0 +1,238 @@
1/*
2 * Copyright (C) 2016 Samsung Electronics Co.Ltd
3 * Authors:
4 * Marek Szyprowski <m.szyprowski@samsung.com>
5 *
6 * DRM core plane blending related functions
7 *
8 * Permission to use, copy, modify, distribute, and sell this software and its
9 * documentation for any purpose is hereby granted without fee, provided that
10 * the above copyright notice appear in all copies and that both that copyright
11 * notice and this permission notice appear in supporting documentation, and
12 * that the name of the copyright holders not be used in advertising or
13 * publicity pertaining to distribution of the software without specific,
14 * written prior permission. The copyright holders make no representations
15 * about the suitability of this software for any purpose. It is provided "as
16 * is" without express or implied warranty.
17 *
18 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
20 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
21 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
23 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24 * OF THIS SOFTWARE.
25 */
26#include <drm/drmP.h>
27#include <drm/drm_atomic.h>
28#include <drm/drm_crtc.h>
29#include <linux/export.h>
30#include <linux/slab.h>
31#include <linux/sort.h>
32
33#include "drm_internal.h"
34
35/**
36 * drm_plane_create_zpos_property - create mutable zpos property
37 * @plane: drm plane
38 * @zpos: initial value of zpos property
39 * @min: minimal possible value of zpos property
40 * @max: maximal possible value of zpos property
41 *
42 * This function initializes generic mutable zpos property and enables support
43 * for it in drm core. Drivers can then attach this property to planes to enable
44 * support for configurable planes arrangement during blending operation.
45 * Once mutable zpos property has been enabled, the DRM core will automatically
46 * calculate drm_plane_state->normalized_zpos values. Usually min should be set
47 * to 0 and max to maximal number of planes for given crtc - 1.
48 *
49 * If zpos of some planes cannot be changed (like fixed background or
50 * cursor/topmost planes), driver should adjust min/max values and assign those
51 * planes immutable zpos property with lower or higher values (for more
52 * information, see drm_mode_create_zpos_immutable_property() function). In such
53 * case driver should also assign proper initial zpos values for all planes in
54 * its plane_reset() callback, so the planes will be always sorted properly.
55 *
56 * Returns:
57 * Zero on success, negative errno on failure.
58 */
59int drm_plane_create_zpos_property(struct drm_plane *plane,
60 unsigned int zpos,
61 unsigned int min, unsigned int max)
62{
63 struct drm_property *prop;
64
65 prop = drm_property_create_range(plane->dev, 0, "zpos", min, max);
66 if (!prop)
67 return -ENOMEM;
68
69 drm_object_attach_property(&plane->base, prop, zpos);
70
71 plane->zpos_property = prop;
72
73 if (plane->state) {
74 plane->state->zpos = zpos;
75 plane->state->normalized_zpos = zpos;
76 }
77
78 return 0;
79}
80EXPORT_SYMBOL(drm_plane_create_zpos_property);
81
82/**
83 * drm_plane_create_zpos_immutable_property - create immuttable zpos property
84 * @plane: drm plane
85 * @zpos: value of zpos property
86 *
87 * This function initializes generic immutable zpos property and enables
88 * support for it in drm core. Using this property driver lets userspace
89 * to get the arrangement of the planes for blending operation and notifies
90 * it that the hardware (or driver) doesn't support changing of the planes'
91 * order.
92 *
93 * Returns:
94 * Zero on success, negative errno on failure.
95 */
96int drm_plane_create_zpos_immutable_property(struct drm_plane *plane,
97 unsigned int zpos)
98{
99 struct drm_property *prop;
100
101 prop = drm_property_create_range(plane->dev, DRM_MODE_PROP_IMMUTABLE,
102 "zpos", zpos, zpos);
103 if (!prop)
104 return -ENOMEM;
105
106 drm_object_attach_property(&plane->base, prop, zpos);
107
108 plane->zpos_property = prop;
109
110 if (plane->state) {
111 plane->state->zpos = zpos;
112 plane->state->normalized_zpos = zpos;
113 }
114
115 return 0;
116}
117EXPORT_SYMBOL(drm_plane_create_zpos_immutable_property);
118
119static int drm_atomic_state_zpos_cmp(const void *a, const void *b)
120{
121 const struct drm_plane_state *sa = *(struct drm_plane_state **)a;
122 const struct drm_plane_state *sb = *(struct drm_plane_state **)b;
123
124 if (sa->zpos != sb->zpos)
125 return sa->zpos - sb->zpos;
126 else
127 return sa->plane->base.id - sb->plane->base.id;
128}
129
130/**
131 * drm_atomic_helper_crtc_normalize_zpos - calculate normalized zpos values
132 * @crtc: crtc with planes, which have to be considered for normalization
133 * @crtc_state: new atomic state to apply
134 *
135 * This function checks new states of all planes assigned to given crtc and
136 * calculates normalized zpos value for them. Planes are compared first by their
137 * zpos values, then by plane id (if zpos equals). Plane with lowest zpos value
138 * is at the bottom. The plane_state->normalized_zpos is then filled with unique
139 * values from 0 to number of active planes in crtc minus one.
140 *
141 * RETURNS
142 * Zero for success or -errno
143 */
144static int drm_atomic_helper_crtc_normalize_zpos(struct drm_crtc *crtc,
145 struct drm_crtc_state *crtc_state)
146{
147 struct drm_atomic_state *state = crtc_state->state;
148 struct drm_device *dev = crtc->dev;
149 int total_planes = dev->mode_config.num_total_plane;
150 struct drm_plane_state **states;
151 struct drm_plane *plane;
152 int i, n = 0;
153 int ret = 0;
154
155 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] calculating normalized zpos values\n",
156 crtc->base.id, crtc->name);
157
158 states = kmalloc_array(total_planes, sizeof(*states), GFP_TEMPORARY);
159 if (!states)
160 return -ENOMEM;
161
162 /*
163 * Normalization process might create new states for planes which
164 * normalized_zpos has to be recalculated.
165 */
166 drm_for_each_plane_mask(plane, dev, crtc_state->plane_mask) {
167 struct drm_plane_state *plane_state =
168 drm_atomic_get_plane_state(state, plane);
169 if (IS_ERR(plane_state)) {
170 ret = PTR_ERR(plane_state);
171 goto done;
172 }
173 states[n++] = plane_state;
174 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] processing zpos value %d\n",
175 plane->base.id, plane->name,
176 plane_state->zpos);
177 }
178
179 sort(states, n, sizeof(*states), drm_atomic_state_zpos_cmp, NULL);
180
181 for (i = 0; i < n; i++) {
182 plane = states[i]->plane;
183
184 states[i]->normalized_zpos = i;
185 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] normalized zpos value %d\n",
186 plane->base.id, plane->name, i);
187 }
188 crtc_state->zpos_changed = true;
189
190done:
191 kfree(states);
192 return ret;
193}
194
195/**
196 * drm_atomic_helper_normalize_zpos - calculate normalized zpos values for all
197 * crtcs
198 * @dev: DRM device
199 * @state: atomic state of DRM device
200 *
201 * This function calculates normalized zpos value for all modified planes in
202 * the provided atomic state of DRM device. For more information, see
203 * drm_atomic_helper_crtc_normalize_zpos() function.
204 *
205 * RETURNS
206 * Zero for success or -errno
207 */
208int drm_atomic_helper_normalize_zpos(struct drm_device *dev,
209 struct drm_atomic_state *state)
210{
211 struct drm_crtc *crtc;
212 struct drm_crtc_state *crtc_state;
213 struct drm_plane *plane;
214 struct drm_plane_state *plane_state;
215 int i, ret = 0;
216
217 for_each_plane_in_state(state, plane, plane_state, i) {
218 crtc = plane_state->crtc;
219 if (!crtc)
220 continue;
221 if (plane->state->zpos != plane_state->zpos) {
222 crtc_state =
223 drm_atomic_get_existing_crtc_state(state, crtc);
224 crtc_state->zpos_changed = true;
225 }
226 }
227
228 for_each_crtc_in_state(state, crtc, crtc_state, i) {
229 if (crtc_state->plane_mask != crtc->state->plane_mask ||
230 crtc_state->zpos_changed) {
231 ret = drm_atomic_helper_crtc_normalize_zpos(crtc,
232 crtc_state);
233 if (ret)
234 return ret;
235 }
236 }
237 return 0;
238}
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index 47a500b90fd7..0c34e6d906d1 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -128,3 +128,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
128 128
129int drm_modeset_register_all(struct drm_device *dev); 129int drm_modeset_register_all(struct drm_device *dev);
130void drm_modeset_unregister_all(struct drm_device *dev); 130void drm_modeset_unregister_all(struct drm_device *dev);
131
132/* drm_blend.c */
133int drm_atomic_helper_normalize_zpos(struct drm_device *dev,
134 struct drm_atomic_state *state);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 3edeaf88ebc0..44e070800b6d 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -308,6 +308,7 @@ struct drm_plane_helper_funcs;
308 * @mode_changed: crtc_state->mode or crtc_state->enable has been changed 308 * @mode_changed: crtc_state->mode or crtc_state->enable has been changed
309 * @active_changed: crtc_state->active has been toggled. 309 * @active_changed: crtc_state->active has been toggled.
310 * @connectors_changed: connectors to this crtc have been updated 310 * @connectors_changed: connectors to this crtc have been updated
311 * @zpos_changed: zpos values of planes on this crtc have been updated
311 * @color_mgmt_changed: color management properties have changed (degamma or 312 * @color_mgmt_changed: color management properties have changed (degamma or
312 * gamma LUT or CSC matrix) 313 * gamma LUT or CSC matrix)
313 * @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes 314 * @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes
@@ -344,6 +345,7 @@ struct drm_crtc_state {
344 bool mode_changed : 1; 345 bool mode_changed : 1;
345 bool active_changed : 1; 346 bool active_changed : 1;
346 bool connectors_changed : 1; 347 bool connectors_changed : 1;
348 bool zpos_changed : 1;
347 bool color_mgmt_changed : 1; 349 bool color_mgmt_changed : 1;
348 350
349 /* attached planes bitmask: 351 /* attached planes bitmask:
@@ -1409,6 +1411,9 @@ struct drm_connector {
1409 * @src_w: width of visible portion of plane (in 16.16) 1411 * @src_w: width of visible portion of plane (in 16.16)
1410 * @src_h: height of visible portion of plane (in 16.16) 1412 * @src_h: height of visible portion of plane (in 16.16)
1411 * @rotation: rotation of the plane 1413 * @rotation: rotation of the plane
1414 * @zpos: priority of the given plane on crtc (optional)
1415 * @normalized_zpos: normalized value of zpos: unique, range from 0 to N-1
1416 * where N is the number of active planes for given crtc
1412 * @state: backpointer to global drm_atomic_state 1417 * @state: backpointer to global drm_atomic_state
1413 */ 1418 */
1414struct drm_plane_state { 1419struct drm_plane_state {
@@ -1429,6 +1434,10 @@ struct drm_plane_state {
1429 /* Plane rotation */ 1434 /* Plane rotation */
1430 unsigned int rotation; 1435 unsigned int rotation;
1431 1436
1437 /* Plane zpos */
1438 unsigned int zpos;
1439 unsigned int normalized_zpos;
1440
1432 struct drm_atomic_state *state; 1441 struct drm_atomic_state *state;
1433}; 1442};
1434 1443
@@ -1688,6 +1697,7 @@ enum drm_plane_type {
1688 * @properties: property tracking for this plane 1697 * @properties: property tracking for this plane
1689 * @type: type of plane (overlay, primary, cursor) 1698 * @type: type of plane (overlay, primary, cursor)
1690 * @state: current atomic state for this plane 1699 * @state: current atomic state for this plane
1700 * @zpos_property: zpos property for this plane
1691 * @helper_private: mid-layer private data 1701 * @helper_private: mid-layer private data
1692 */ 1702 */
1693struct drm_plane { 1703struct drm_plane {
@@ -1732,6 +1742,8 @@ struct drm_plane {
1732 const struct drm_plane_helper_funcs *helper_private; 1742 const struct drm_plane_helper_funcs *helper_private;
1733 1743
1734 struct drm_plane_state *state; 1744 struct drm_plane_state *state;
1745
1746 struct drm_property *zpos_property;
1735}; 1747};
1736 1748
1737/** 1749/**
@@ -2958,6 +2970,14 @@ extern void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
2958 uint degamma_lut_size, 2970 uint degamma_lut_size,
2959 bool has_ctm, 2971 bool has_ctm,
2960 uint gamma_lut_size); 2972 uint gamma_lut_size);
2973
2974int drm_plane_create_zpos_property(struct drm_plane *plane,
2975 unsigned int zpos,
2976 unsigned int min, unsigned int max);
2977
2978int drm_plane_create_zpos_immutable_property(struct drm_plane *plane,
2979 unsigned int zpos);
2980
2961/* Helpers */ 2981/* Helpers */
2962struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, 2982struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
2963 uint32_t id, uint32_t type); 2983 uint32_t id, uint32_t type);