drm: Add support for optional per-plane rotation property
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Mon, 26 Sep 2016 16:30:48 +0000 (19:30 +0300)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 21 Oct 2016 16:23:50 +0000 (18:23 +0200)
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
drivers/gpu/drm/drm_atomic.c
drivers/gpu/drm/drm_blend.c
drivers/gpu/drm/drm_fb_helper.c
include/drm/drm_blend.h
include/drm/drm_plane.h

index 13ce95ee458e2dc0b6dd819b9dc6f7540891ac95..f817063878899eabd6cfcbd6c942dabdf8e79e2b 100644 (file)
@@ -705,7 +705,8 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
                state->src_w = val;
        } else if (property == config->prop_src_h) {
                state->src_h = val;
-       } else if (property == config->rotation_property) {
+       } else if (property == config->rotation_property ||
+                  property == plane->rotation_property) {
                if (!is_power_of_2(val & DRM_ROTATE_MASK))
                        return -EINVAL;
                state->rotation = val;
@@ -765,7 +766,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
                *val = state->src_w;
        } else if (property == config->prop_src_h) {
                *val = state->src_h;
-       } else if (property == config->rotation_property) {
+       } else if (property == config->rotation_property ||
+                  property == plane->rotation_property) {
                *val = state->rotation;
        } else if (property == plane->zpos_property) {
                *val = state->zpos;
index 85172a977bf3eccf5ec3ea3b1a83797364a396e4..e52aece309009be8f354a4b2368ba2d9804daf2b 100644 (file)
@@ -162,6 +162,41 @@ struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_mode_create_rotation_property);
 
+int drm_plane_create_rotation_property(struct drm_plane *plane,
+                                      unsigned int rotation,
+                                      unsigned int supported_rotations)
+{
+       static const struct drm_prop_enum_list props[] = {
+               { __builtin_ffs(DRM_ROTATE_0) - 1,   "rotate-0" },
+               { __builtin_ffs(DRM_ROTATE_90) - 1,  "rotate-90" },
+               { __builtin_ffs(DRM_ROTATE_180) - 1, "rotate-180" },
+               { __builtin_ffs(DRM_ROTATE_270) - 1, "rotate-270" },
+               { __builtin_ffs(DRM_REFLECT_X) - 1,  "reflect-x" },
+               { __builtin_ffs(DRM_REFLECT_Y) - 1,  "reflect-y" },
+       };
+       struct drm_property *prop;
+
+       WARN_ON((supported_rotations & DRM_ROTATE_MASK) == 0);
+       WARN_ON(!is_power_of_2(rotation & DRM_ROTATE_MASK));
+       WARN_ON(rotation & ~supported_rotations);
+
+       prop = drm_property_create_bitmask(plane->dev, 0, "rotation",
+                                          props, ARRAY_SIZE(props),
+                                          supported_rotations);
+       if (!prop)
+               return -ENOMEM;
+
+       drm_object_attach_property(&plane->base, prop, rotation);
+
+       if (plane->state)
+               plane->state->rotation = rotation;
+
+       plane->rotation_property = prop;
+
+       return 0;
+}
+EXPORT_SYMBOL(drm_plane_create_rotation_property);
+
 /**
  * drm_rotation_simplify() - Try to simplify the rotation
  * @rotation: Rotation to be simplified
index 8fffac8c5c7500a3375ada984761a6f459cd2a8a..e0d428f9d1cb3f65273918b3b2c346c128a15b50 100644 (file)
@@ -392,7 +392,11 @@ static int restore_fbdev_mode(struct drm_fb_helper *fb_helper)
                if (plane->type != DRM_PLANE_TYPE_PRIMARY)
                        drm_plane_force_disable(plane);
 
-               if (dev->mode_config.rotation_property) {
+               if (plane->rotation_property) {
+                       drm_mode_plane_set_obj_prop(plane,
+                                                   plane->rotation_property,
+                                                   DRM_ROTATE_0);
+               } else if (dev->mode_config.rotation_property) {
                        drm_mode_plane_set_obj_prop(plane,
                                                    dev->mode_config.rotation_property,
                                                    DRM_ROTATE_0);
index bb493410396cd77883227a58ddc70da21e3e4a4e..fd351924e1c5b573710819edf84b29cb21009171 100644 (file)
@@ -54,6 +54,9 @@ static inline bool drm_rotation_90_or_270(unsigned int rotation)
 
 struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
                                                       unsigned int supported_rotations);
+int drm_plane_create_rotation_property(struct drm_plane *plane,
+                                      unsigned int rotation,
+                                      unsigned int supported_rotations);
 unsigned int drm_rotation_simplify(unsigned int rotation,
                                   unsigned int supported_rotations);
 
index 02353904cdba7523183fd57ae9623b53283a3294..98b39d66eb32b1610ac38e0a447d2320f4c0e711 100644 (file)
@@ -385,6 +385,7 @@ enum drm_plane_type {
  * @type: type of plane (overlay, primary, cursor)
  * @state: current atomic state for this plane
  * @zpos_property: zpos property for this plane
+ * @rotation_property: rotation property for this plane
  * @helper_private: mid-layer private data
  */
 struct drm_plane {
@@ -431,6 +432,7 @@ struct drm_plane {
        struct drm_plane_state *state;
 
        struct drm_property *zpos_property;
+       struct drm_property *rotation_property;
 };
 
 #define obj_to_plane(x) container_of(x, struct drm_plane, base)