mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
drm/modes: parse_cmdline: Add support for specifying panel_orientation (v2)
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
This commit is contained in:
parent
7b1cce760a
commit
4e7a4a6fbd
@ -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.
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
@ -1591,6 +1591,33 @@ static int drm_mode_parse_cmdline_int(const char *delim, unsigned int *int_ret)
|
||||
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_options(const char *str,
|
||||
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;
|
||||
}
|
||||
@ -1715,6 +1745,8 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
|
||||
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;
|
||||
|
@ -64,3 +64,4 @@ cmdline_test(drm_cmdline_test_bpp_extra_and_option)
|
||||
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)
|
||||
|
@ -1092,6 +1092,28 @@ static int drm_cmdline_test_freestanding_force_e_and_options(void *ignored)
|
||||
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)
|
||||
|
@ -1069,6 +1069,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.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user