[PATCH 3/5] drm: Add drm_rotation_chain()
ville.syrjala at linux.intel.com
ville.syrjala at linux.intel.com
Wed Feb 12 13:15:02 PST 2014
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
drm_rotation_chain() can be used to combine the plane and crtc rotations
to calculate the total rotation for a specific plane.
Cc: Sagar Kamble <sagar.a.kamble at intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
drivers/gpu/drm/drm_crtc.c | 42 ++++++++++++++++++++++++++++++++++++++++++
include/drm/drm_crtc.h | 2 ++
2 files changed, 44 insertions(+)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 7077676..71d366f 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -4065,6 +4065,48 @@ unsigned int drm_rotation_simplify(unsigned int rotation,
EXPORT_SYMBOL(drm_rotation_simplify);
/**
+ * drm_rotation_chain() - Chain plane and crtc rotations together
+ * @crtc_rotation: rotation for the entire crtc
+ * @plane_rotation: rotation for the plane in relation to the crtc
+ *
+ * Given @crtc_rotation and @plane_rotation, this function will
+ * comptute the total rotation for the plane in relation to 0
+ * degree rotated crtc. This can be used eg. to implement full crtc
+ * rotation using just plane rotation in hardware. Obviously that
+ * requires that all planes must support rotation since the crtc
+ * itself won't rotate the composed scene.
+ */
+unsigned int drm_rotation_chain(unsigned int crtc_rotation,
+ unsigned int plane_rotation)
+{
+ unsigned int rotation;
+
+ /* add up the rotation angles */
+ rotation = 1 << ((ffs(plane_rotation & 0xf) + ffs(crtc_rotation & 0xf) - 2) % 4);
+
+ /* plane reflection before plane rotation */
+ rotation |= plane_rotation & (BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y));
+
+ /* crtc reflection after plane rotation and before crtc rotation */
+ switch (plane_rotation & 0xf) {
+ case BIT(DRM_ROTATE_0):
+ case BIT(DRM_ROTATE_180):
+ rotation ^= crtc_rotation & (BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y));
+ break;
+ case BIT(DRM_ROTATE_90):
+ case BIT(DRM_ROTATE_270):
+ if (crtc_rotation & BIT(DRM_REFLECT_X))
+ rotation ^= BIT(DRM_REFLECT_Y);
+ if (crtc_rotation & BIT(DRM_REFLECT_Y))
+ rotation ^= BIT(DRM_REFLECT_X);
+ break;
+ }
+
+ return rotation;
+}
+EXPORT_SYMBOL(drm_rotation_chain);
+
+/**
* drm_mode_config_init - initialize DRM mode_configuration structure
* @dev: DRM device
*
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index ee84a4a..ebb9bf4 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1189,6 +1189,8 @@ extern struct drm_property *drm_mode_create_rotation_property(struct drm_device
unsigned int supported_rotations);
extern unsigned int drm_rotation_simplify(unsigned int rotation,
unsigned int supported_rotations);
+extern unsigned int drm_rotation_chain(unsigned int crtc_rotation,
+ unsigned int plane_rotation);
/* Helpers */
static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev,
--
1.8.3.2
More information about the dri-devel
mailing list