summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_client_modeset.c
diff options
context:
space:
mode:
authorMaxime Ripard <maxime.ripard@bootlin.com>2019-06-19 12:17:51 +0200
committerMaxime Ripard <maxime.ripard@bootlin.com>2019-06-19 12:17:51 +0200
commit1bf4e09227c345e246062285eba4b8fe660e512e (patch)
tree45396ee8fa752b77e08db4c2ae3be1f1c21dab2b /drivers/gpu/drm/drm_client_modeset.c
parent3aeeb13d899627fe2b86bdbdcd0927cf7192234f (diff)
drm/modes: Allow to specify rotation and reflection on the commandline
Rotations and reflections setup are needed in some scenarios to initialise properly the initial framebuffer. Some drivers already had a bunch of quirks to deal with this, such as either a private kernel command line parameter (omapdss) or on the device tree (various panels). In order to accomodate this, let's create a video mode parameter to deal with the rotation and reflexion. Reviewed-by: Noralf Trønnes <noralf@tronnes.org> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com> Link: https://patchwork.freedesktop.org/patch/msgid/777da16e42db757c1f5b414b5ca34507097fed5c.1560783090.git-series.maxime.ripard@bootlin.com
Diffstat (limited to 'drivers/gpu/drm/drm_client_modeset.c')
-rw-r--r--drivers/gpu/drm/drm_client_modeset.c30
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