bcm27xx: update patches from RPi foundation
[openwrt/staging/luka.git] / target / linux / bcm27xx / patches-5.4 / 950-0484-drm-modes-parse_cmdline-Add-support-for-specifying-p.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0484-drm-modes-parse_cmdline-Add-support-for-specifying-p.patch b/target/linux/bcm27xx/patches-5.4/950-0484-drm-modes-parse_cmdline-Add-support-for-specifying-p.patch
new file mode 100644 (file)
index 0000000..cbda9ec
--- /dev/null
@@ -0,0 +1,157 @@
+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;