diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2016-09-26 12:30:48 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-10-21 12:23:50 -0400 |
commit | d138dd3c0c70979215f3184cf36f95875e37932e (patch) | |
tree | 61bd350525aca0355886f3fb51304271e442d3eb | |
parent | 6e0c7c3358d4e8e9917a97348e6f77da88226cbe (diff) |
drm: Add support for optional per-plane rotation property
Not all planes on the system may support the same rotations/reflections,
so make it possible to create a separate property for each plane.
This way userspace gets told exactly which rotations/reflections are
possible for each plane.
v2: Add drm_plane_create_rotation_property() helper
v3: Drop the BIT(), __builtin_ffs(x) - 1,
Moar WARNs for bad parameters
Deal with superfluous code shuffling
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> (v1)
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1474907460-10717-4-git-send-email-ville.syrjala@linux.intel.com
-rw-r--r-- | drivers/gpu/drm/drm_atomic.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_blend.c | 35 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 6 | ||||
-rw-r--r-- | include/drm/drm_blend.h | 3 | ||||
-rw-r--r-- | include/drm/drm_plane.h | 2 |
5 files changed, 49 insertions, 3 deletions
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 13ce95ee458e..f81706387889 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c | |||
@@ -705,7 +705,8 @@ int drm_atomic_plane_set_property(struct drm_plane *plane, | |||
705 | state->src_w = val; | 705 | state->src_w = val; |
706 | } else if (property == config->prop_src_h) { | 706 | } else if (property == config->prop_src_h) { |
707 | state->src_h = val; | 707 | state->src_h = val; |
708 | } else if (property == config->rotation_property) { | 708 | } else if (property == config->rotation_property || |
709 | property == plane->rotation_property) { | ||
709 | if (!is_power_of_2(val & DRM_ROTATE_MASK)) | 710 | if (!is_power_of_2(val & DRM_ROTATE_MASK)) |
710 | return -EINVAL; | 711 | return -EINVAL; |
711 | state->rotation = val; | 712 | state->rotation = val; |
@@ -765,7 +766,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane, | |||
765 | *val = state->src_w; | 766 | *val = state->src_w; |
766 | } else if (property == config->prop_src_h) { | 767 | } else if (property == config->prop_src_h) { |
767 | *val = state->src_h; | 768 | *val = state->src_h; |
768 | } else if (property == config->rotation_property) { | 769 | } else if (property == config->rotation_property || |
770 | property == plane->rotation_property) { | ||
769 | *val = state->rotation; | 771 | *val = state->rotation; |
770 | } else if (property == plane->zpos_property) { | 772 | } else if (property == plane->zpos_property) { |
771 | *val = state->zpos; | 773 | *val = state->zpos; |
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c index 85172a977bf3..e52aece30900 100644 --- a/drivers/gpu/drm/drm_blend.c +++ b/drivers/gpu/drm/drm_blend.c | |||
@@ -162,6 +162,41 @@ struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, | |||
162 | } | 162 | } |
163 | EXPORT_SYMBOL(drm_mode_create_rotation_property); | 163 | EXPORT_SYMBOL(drm_mode_create_rotation_property); |
164 | 164 | ||
165 | int drm_plane_create_rotation_property(struct drm_plane *plane, | ||
166 | unsigned int rotation, | ||
167 | unsigned int supported_rotations) | ||
168 | { | ||
169 | static const struct drm_prop_enum_list props[] = { | ||
170 | { __builtin_ffs(DRM_ROTATE_0) - 1, "rotate-0" }, | ||
171 | { __builtin_ffs(DRM_ROTATE_90) - 1, "rotate-90" }, | ||
172 | { __builtin_ffs(DRM_ROTATE_180) - 1, "rotate-180" }, | ||
173 | { __builtin_ffs(DRM_ROTATE_270) - 1, "rotate-270" }, | ||
174 | { __builtin_ffs(DRM_REFLECT_X) - 1, "reflect-x" }, | ||
175 | { __builtin_ffs(DRM_REFLECT_Y) - 1, "reflect-y" }, | ||
176 | }; | ||
177 | struct drm_property *prop; | ||
178 | |||
179 | WARN_ON((supported_rotations & DRM_ROTATE_MASK) == 0); | ||
180 | WARN_ON(!is_power_of_2(rotation & DRM_ROTATE_MASK)); | ||
181 | WARN_ON(rotation & ~supported_rotations); | ||
182 | |||
183 | prop = drm_property_create_bitmask(plane->dev, 0, "rotation", | ||
184 | props, ARRAY_SIZE(props), | ||
185 | supported_rotations); | ||
186 | if (!prop) | ||
187 | return -ENOMEM; | ||
188 | |||
189 | drm_object_attach_property(&plane->base, prop, rotation); | ||
190 | |||
191 | if (plane->state) | ||
192 | plane->state->rotation = rotation; | ||
193 | |||
194 | plane->rotation_property = prop; | ||
195 | |||
196 | return 0; | ||
197 | } | ||
198 | EXPORT_SYMBOL(drm_plane_create_rotation_property); | ||
199 | |||
165 | /** | 200 | /** |
166 | * drm_rotation_simplify() - Try to simplify the rotation | 201 | * drm_rotation_simplify() - Try to simplify the rotation |
167 | * @rotation: Rotation to be simplified | 202 | * @rotation: Rotation to be simplified |
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 8fffac8c5c75..e0d428f9d1cb 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -392,7 +392,11 @@ static int restore_fbdev_mode(struct drm_fb_helper *fb_helper) | |||
392 | if (plane->type != DRM_PLANE_TYPE_PRIMARY) | 392 | if (plane->type != DRM_PLANE_TYPE_PRIMARY) |
393 | drm_plane_force_disable(plane); | 393 | drm_plane_force_disable(plane); |
394 | 394 | ||
395 | if (dev->mode_config.rotation_property) { | 395 | if (plane->rotation_property) { |
396 | drm_mode_plane_set_obj_prop(plane, | ||
397 | plane->rotation_property, | ||
398 | DRM_ROTATE_0); | ||
399 | } else if (dev->mode_config.rotation_property) { | ||
396 | drm_mode_plane_set_obj_prop(plane, | 400 | drm_mode_plane_set_obj_prop(plane, |
397 | dev->mode_config.rotation_property, | 401 | dev->mode_config.rotation_property, |
398 | DRM_ROTATE_0); | 402 | DRM_ROTATE_0); |
diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h index bb493410396c..fd351924e1c5 100644 --- a/include/drm/drm_blend.h +++ b/include/drm/drm_blend.h | |||
@@ -54,6 +54,9 @@ static inline bool drm_rotation_90_or_270(unsigned int rotation) | |||
54 | 54 | ||
55 | struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, | 55 | struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, |
56 | unsigned int supported_rotations); | 56 | unsigned int supported_rotations); |
57 | int drm_plane_create_rotation_property(struct drm_plane *plane, | ||
58 | unsigned int rotation, | ||
59 | unsigned int supported_rotations); | ||
57 | unsigned int drm_rotation_simplify(unsigned int rotation, | 60 | unsigned int drm_rotation_simplify(unsigned int rotation, |
58 | unsigned int supported_rotations); | 61 | unsigned int supported_rotations); |
59 | 62 | ||
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 02353904cdba..98b39d66eb32 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h | |||
@@ -385,6 +385,7 @@ enum drm_plane_type { | |||
385 | * @type: type of plane (overlay, primary, cursor) | 385 | * @type: type of plane (overlay, primary, cursor) |
386 | * @state: current atomic state for this plane | 386 | * @state: current atomic state for this plane |
387 | * @zpos_property: zpos property for this plane | 387 | * @zpos_property: zpos property for this plane |
388 | * @rotation_property: rotation property for this plane | ||
388 | * @helper_private: mid-layer private data | 389 | * @helper_private: mid-layer private data |
389 | */ | 390 | */ |
390 | struct drm_plane { | 391 | struct drm_plane { |
@@ -431,6 +432,7 @@ struct drm_plane { | |||
431 | struct drm_plane_state *state; | 432 | struct drm_plane_state *state; |
432 | 433 | ||
433 | struct drm_property *zpos_property; | 434 | struct drm_property *zpos_property; |
435 | struct drm_property *rotation_property; | ||
434 | }; | 436 | }; |
435 | 437 | ||
436 | #define obj_to_plane(x) container_of(x, struct drm_plane, base) | 438 | #define obj_to_plane(x) container_of(x, struct drm_plane, base) |