diff options
Diffstat (limited to 'drivers/gpu/drm/drm_client_modeset.c')
-rw-r--r-- | drivers/gpu/drm/drm_client_modeset.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c index 33d4988f22ae..e95fceac8f8b 100644 --- a/drivers/gpu/drm/drm_client_modeset.c +++ b/drivers/gpu/drm/drm_client_modeset.c @@ -824,6 +824,7 @@ bool drm_client_rotation(struct drm_mode_set *modeset, unsigned int *rotation) { struct drm_connector *connector = modeset->connectors[0]; struct drm_plane *plane = modeset->crtc->primary; + struct drm_cmdline_mode *cmdline; u64 valid_mask = 0; unsigned int i; @@ -844,6 +845,35 @@ bool drm_client_rotation(struct drm_mode_set *modeset, unsigned int *rotation) *rotation = DRM_MODE_ROTATE_0; } + /** + * The panel already defined the default rotation + * through its orientation. Whatever has been provided + * on the command line needs to be added to that. + * + * Unfortunately, the rotations are at different bit + * indices, so the math to add them up are not as + * trivial as they could. + * + * Reflections on the other hand are pretty trivial to deal with, a + * simple XOR between the two handle the addition nicely. + */ + cmdline = &connector->cmdline_mode; + if (cmdline->specified) { + unsigned int cmdline_rest, panel_rest; + unsigned int cmdline_rot, panel_rot; + unsigned int sum_rot, sum_rest; + + panel_rot = ilog2(*rotation & DRM_MODE_ROTATE_MASK); + cmdline_rot = ilog2(cmdline->rotation_reflection & DRM_MODE_ROTATE_MASK); + sum_rot = (panel_rot + cmdline_rot) % 4; + + panel_rest = *rotation & ~DRM_MODE_ROTATE_MASK; + cmdline_rest = cmdline->rotation_reflection & ~DRM_MODE_ROTATE_MASK; + sum_rest = panel_rest ^ cmdline_rest; + + *rotation = (1 << sum_rot) | sum_rest; + } + /* * TODO: support 90 / 270 degree hardware rotation, * depending on the hardware this may require the framebuffer |