From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> 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@xxxxxxxxx> Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> --- 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 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel