f07e572f64
bcm2708: boot tested on RPi B+ v1.2 bcm2709: boot tested on RPi 3B v1.2 and RPi 4B v1.1 4G bcm2710: boot tested on RPi 3B v1.2 bcm2711: boot tested on RPi 4B v1.1 4G Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
158 lines
5.5 KiB
Diff
158 lines
5.5 KiB
Diff
From 7d395633947fa6595a117f40e0f27ba87be77d6c Mon Sep 17 00:00:00 2001
|
|
From: Hans de Goede <hdegoede@redhat.com>
|
|
Date: Mon, 18 Nov 2019 16:51:30 +0100
|
|
Subject: [PATCH] drm/modes: parse_cmdline: Add support for specifying
|
|
panel_orientation (v2)
|
|
|
|
Commit 4e7a4a6fbdc669c44e6079f9d5eb25673749455f upstream.
|
|
|
|
Sometimes we want to override a connector's panel_orientation from the
|
|
kernel commandline. Either for testing and for special cases, e.g. a kiosk
|
|
like setup which uses a TV mounted in portrait mode.
|
|
|
|
Users can already specify a "rotate" option through a video= kernel cmdline
|
|
option. But that only supports 0/180 degrees (see drm_client_modeset TODO)
|
|
and only works for in kernel modeset clients, not for userspace kms users.
|
|
|
|
The "panel-orientation" connector property OTOH does support 90/270 degrees
|
|
as it leaves dealing with the rotation up to userspace and this does work
|
|
for userspace kms clients (at least those which support this property).
|
|
|
|
Changes in v2:
|
|
-Add missing ':' after @panel_orientation (reported by kbuild test robot)
|
|
|
|
BugLink: https://gitlab.freedesktop.org/plymouth/plymouth/merge_requests/83
|
|
Acked-by: Maxime Ripard <mripard@kernel.org>
|
|
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
|
Link: https://patchwork.freedesktop.org/patch/msgid/20191118155134.30468-9-hdegoede@redhat.com
|
|
---
|
|
Documentation/fb/modedb.rst | 3 ++
|
|
drivers/gpu/drm/drm_modes.c | 32 +++++++++++++++++++
|
|
.../gpu/drm/selftests/drm_cmdline_selftests.h | 1 +
|
|
.../drm/selftests/test-drm_cmdline_parser.c | 22 +++++++++++++
|
|
include/drm/drm_connector.h | 8 +++++
|
|
5 files changed, 66 insertions(+)
|
|
|
|
--- a/Documentation/fb/modedb.rst
|
|
+++ b/Documentation/fb/modedb.rst
|
|
@@ -65,6 +65,9 @@ Valid options are::
|
|
- reflect_y (boolean): Perform an axial symmetry on the Y axis
|
|
- rotate (integer): Rotate the initial framebuffer by x
|
|
degrees. Valid values are 0, 90, 180 and 270.
|
|
+ - panel_orientation, one of "normal", "upside_down", "left_side_up", or
|
|
+ "right_side_up". For KMS drivers only, this sets the "panel orientation"
|
|
+ property on the kms connector as hint for kms users.
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
--- a/drivers/gpu/drm/drm_modes.c
|
|
+++ b/drivers/gpu/drm/drm_modes.c
|
|
@@ -1591,6 +1591,33 @@ static int drm_mode_parse_cmdline_int(co
|
|
return 0;
|
|
}
|
|
|
|
+static int drm_mode_parse_panel_orientation(const char *delim,
|
|
+ struct drm_cmdline_mode *mode)
|
|
+{
|
|
+ const char *value;
|
|
+
|
|
+ if (*delim != '=')
|
|
+ return -EINVAL;
|
|
+
|
|
+ value = delim + 1;
|
|
+ delim = strchr(value, ',');
|
|
+ if (!delim)
|
|
+ delim = value + strlen(value);
|
|
+
|
|
+ if (!strncmp(value, "normal", delim - value))
|
|
+ mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
|
|
+ else if (!strncmp(value, "upside_down", delim - value))
|
|
+ mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
|
|
+ else if (!strncmp(value, "left_side_up", delim - value))
|
|
+ mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP;
|
|
+ else if (!strncmp(value, "right_side_up", delim - value))
|
|
+ mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP;
|
|
+ else
|
|
+ return -EINVAL;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int drm_mode_parse_cmdline_options(const char *str,
|
|
bool freestanding,
|
|
const struct drm_connector *connector,
|
|
@@ -1657,6 +1684,9 @@ static int drm_mode_parse_cmdline_option
|
|
return -EINVAL;
|
|
|
|
mode->tv_margins.bottom = margin;
|
|
+ } else if (!strncmp(option, "panel_orientation", delim - option)) {
|
|
+ if (drm_mode_parse_panel_orientation(delim, mode))
|
|
+ return -EINVAL;
|
|
} else {
|
|
return -EINVAL;
|
|
}
|
|
@@ -1722,6 +1752,8 @@ bool drm_mode_parse_command_line_for_con
|
|
char *bpp_end_ptr = NULL, *refresh_end_ptr = NULL;
|
|
int i, len, ret;
|
|
|
|
+ mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
|
|
+
|
|
#ifdef CONFIG_FB
|
|
if (!mode_option)
|
|
mode_option = fb_mode_option;
|
|
--- a/drivers/gpu/drm/selftests/drm_cmdline_selftests.h
|
|
+++ b/drivers/gpu/drm/selftests/drm_cmdline_selftests.h
|
|
@@ -65,3 +65,4 @@ cmdline_test(drm_cmdline_test_bpp_extra_
|
|
cmdline_test(drm_cmdline_test_extra_and_option)
|
|
cmdline_test(drm_cmdline_test_freestanding_options)
|
|
cmdline_test(drm_cmdline_test_freestanding_force_e_and_options)
|
|
+cmdline_test(drm_cmdline_test_panel_orientation)
|
|
--- a/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c
|
|
+++ b/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c
|
|
@@ -1103,6 +1103,28 @@ static int drm_cmdline_test_freestanding
|
|
return 0;
|
|
}
|
|
|
|
+static int drm_cmdline_test_panel_orientation(void *ignored)
|
|
+{
|
|
+ struct drm_cmdline_mode mode = { };
|
|
+
|
|
+ FAIL_ON(!drm_mode_parse_command_line_for_connector("panel_orientation=upside_down",
|
|
+ &no_connector,
|
|
+ &mode));
|
|
+ FAIL_ON(mode.specified);
|
|
+ FAIL_ON(mode.refresh_specified);
|
|
+ FAIL_ON(mode.bpp_specified);
|
|
+
|
|
+ FAIL_ON(mode.panel_orientation != DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP);
|
|
+
|
|
+ FAIL_ON(mode.rb);
|
|
+ FAIL_ON(mode.cvt);
|
|
+ FAIL_ON(mode.interlace);
|
|
+ FAIL_ON(mode.margins);
|
|
+ FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
#include "drm_selftest.c"
|
|
|
|
static int __init test_drm_cmdline_init(void)
|
|
--- a/include/drm/drm_connector.h
|
|
+++ b/include/drm/drm_connector.h
|
|
@@ -1066,6 +1066,14 @@ struct drm_cmdline_mode {
|
|
unsigned int rotation_reflection;
|
|
|
|
/**
|
|
+ * @panel_orientation:
|
|
+ *
|
|
+ * drm-connector "panel orientation" property override value,
|
|
+ * DRM_MODE_PANEL_ORIENTATION_UNKNOWN if not set.
|
|
+ */
|
|
+ enum drm_panel_orientation panel_orientation;
|
|
+
|
|
+ /**
|
|
* @tv_margins: TV margins to apply to the mode.
|
|
*/
|
|
struct drm_connector_tv_margins tv_margins;
|