Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d138dd3c authored by Ville Syrjälä's avatar Ville Syrjälä Committed by Daniel Vetter
Browse files

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: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> (v1)
Reviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1474907460-10717-4-git-send-email-ville.syrjala@linux.intel.com
parent 6e0c7c33
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -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;
+35 −0
Original line number Diff line number Diff line
@@ -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
+5 −1
Original line number Diff line number Diff line
@@ -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);
+3 −0
Original line number Diff line number Diff line
@@ -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);

+2 −0
Original line number Diff line number Diff line
@@ -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)