Hi all!
This is my first attempt to get TILER working on newer kernels (tested with letux-5.6.y and letux-5.7) following on from our discussions on the forum.
As I don't have access to a Pyra prototype or LCD, I've tested this by rotating the HDMI output with the command-line rotate parameter (although, in fact, hopefully this patch fixes the rotated HDMI output on the Pyra).
I've also attempted to test it by pretending a Pyra LCD is attached by using omap5-uevm+pyra4+boe.dtb, TILER seems to be being set up and the framebuffer rotated but for some reason I can't get X to start this way - this doesn't seem to be related to the patch though.
Instead of the old parameter that rotated all framebuffers, this patch goes a slightly different way by adding a drm.force_hw_rotation parameter to enable 90/270 degree hardware rotation, then the usual rotation infrastructure can be used.
It would be great to get some feedback on the code as I don't have much experience with the kernel code style. Some help testing this on Pyra hardware would also be appreciated, ideally if someone is able to apply this to the correct tree and test.
Best
David Shah
Remove the command-line rotation override, and add a new command-line parameter drm.force_hw_rotation that forces use of hardware rotation even for 90/270 degrees.
Once this new parameter is set, the generic rotation/panel orientation APIs can be used with TILER.
Signed-off-by: David Shah dave@ds0.me --- drivers/gpu/drm/drm_client_modeset.c | 8 ++++++- drivers/gpu/drm/drm_fb_helper.c | 21 +++++++++---------- .../drm/omapdrm/displays/panel-boe-w677l.c | 1 + 3 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c index 3035584f6dc7..a96c73fa0c99 100644 --- a/drivers/gpu/drm/drm_client_modeset.c +++ b/drivers/gpu/drm/drm_client_modeset.c @@ -25,6 +25,11 @@
#define DRM_CLIENT_MAX_CLONED_CONNECTORS 8
+static bool force_hw_rotation = false; +module_param_named(force_hw_rotation, force_hw_rotation, bool, 0644); +MODULE_PARM_DESC(force_hw_rotation, + "Force hardware rotation even for 90/270 degrees [default=false]"); + struct drm_client_offset { int x, y; }; @@ -951,7 +956,8 @@ bool drm_client_rotation(struct drm_mode_set *modeset, unsigned int *rotation) * depending on the hardware this may require the framebuffer * to be in a specific tiling format. */ - if (((*rotation & DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_0 && + if ((!force_hw_rotation && + (*rotation & DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_0 && (*rotation & DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_180) || !plane->rotation_property) return false; diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index f5ce655c27ca..469f1503281b 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -79,9 +79,6 @@ MODULE_PARM_DESC(drm_leak_fbdev_smem, "Allow unsafe leaking fbdev physical smem address [default=false]"); #endif
-static uint drm_fbdev_rotation = 0; -module_param_named(fbdev_rotation, drm_fbdev_rotation, uint, 0644); - static LIST_HEAD(kernel_fb_helper_list); static DEFINE_MUTEX(kernel_fb_helper_lock);
@@ -1448,6 +1445,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, struct drm_connector *connector; struct drm_mode_set *mode_set; int best_depth = 0; + int rotation = 0;
memset(&sizes, 0, sizeof(struct drm_fb_helper_surface_size)); sizes.surface_depth = 24; @@ -1558,7 +1556,10 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, if (!desired_mode) continue;
- if (drm_rotation_90_or_270(drm_fbdev_rotation)) { + rotation = 0; + + if (drm_client_rotation(mode_set, &rotation) && + drm_rotation_90_or_270(rotation)) { height = desired_mode->hdisplay; width = desired_mode->vdisplay; } else { @@ -1571,8 +1572,8 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, x = mode_set->x; y = mode_set->y;
- sizes.surface_width = max_t(u32, desired_mode->hdisplay + x, sizes.surface_width); - sizes.surface_height = max_t(u32, desired_mode->vdisplay + y, sizes.surface_height); + sizes.surface_width = max_t(u32, width + x, sizes.surface_width); + sizes.surface_height = max_t(u32, height + y, sizes.surface_height);
for (j = 0; j < mode_set->num_connectors; j++) { struct drm_connector *connector = mode_set->connectors[j]; @@ -1709,10 +1710,6 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
modeset->fb = fb_helper->fb;
- if (drm_fbdev_rotation) - /* Override orientation declared by panel XXX FIXME */ - sw_rotations |= DRM_MODE_ROTATE_0; - else if (drm_client_rotation(modeset, &rotation)) /* Rotating in hardware, fbcon should not rotate */ sw_rotations |= DRM_MODE_ROTATE_0; @@ -1899,6 +1896,7 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) { int err = 0; unsigned width, height; + int rotation = 0;
if (!drm_fbdev_emulation || !fb_helper) return 0; @@ -1921,7 +1919,8 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) drm_dbg_kms(fb_helper->dev, "\n");
/* XXX FIXME */ - if (drm_rotation_90_or_270(drm_fbdev_rotation)) { + if (drm_client_rotation(fb_helper->client.modesets, &rotation) && + drm_rotation_90_or_270(rotation)) { width = fb_helper->fb->height; height = fb_helper->fb->width; } else { diff --git a/drivers/gpu/drm/omapdrm/displays/panel-boe-w677l.c b/drivers/gpu/drm/omapdrm/displays/panel-boe-w677l.c index d95a23e15feb..0029796c7f4a 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-boe-w677l.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-boe-w677l.c @@ -800,6 +800,7 @@ static int w677l__panel_get_modes(struct omap_dss_device *dssdev,
connector->display_info.width_mm = 63; connector->display_info.height_mm = 112; + connector->display_info.panel_orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP;
return omapdss_display_get_modes(connector, &ddata->vm); }
Hi David,
Am 02.06.2020 um 18:16 schrieb David Shah dave@ds0.me:
Hi all!
This is my first attempt to get TILER working on newer kernels (tested with letux-5.6.y and letux-5.7) following on from our discussions on the forum.
As I don't have access to a Pyra prototype or LCD, I've tested this by rotating the HDMI output with the command-line rotate parameter (although, in fact, hopefully this patch fixes the rotated HDMI output on the Pyra).
I've also attempted to test it by pretending a Pyra LCD is attached by using omap5-uevm+pyra4+boe.dtb, TILER seems to be being set up and the framebuffer rotated but for some reason I can't get X to start this way - this doesn't seem to be related to the patch though.
Instead of the old parameter that rotated all framebuffers, this patch goes a slightly different way by adding a drm.force_hw_rotation parameter to enable 90/270 degree hardware rotation, then the usual rotation infrastructure can be used.
It would be great to get some feedback on the code as I don't have much experience with the kernel code style. Some help testing this on Pyra hardware would also be appreciated, ideally if someone is able to apply this to the correct tree and test.
I quickly applied to letux-5.7 and could start. But the LCD remains black and there is no backlight. And there is no /dev/fb0 (haven't checked dmesg yet). So this seems to be a different problem.
But here are the good news: placed on top of letux-5.6.y makes the console framebuffer be rotated properly! tiler-ctl has no function any more of course.
So I'll add it to the next letux-5.4.y and letux-5.6.y builds. What I have changed is to set the new parameter to true by default. And try to find out why 5.7 is broken (again).
So this is a good workaround. A better solution would be to somehow read the panel orientation from device tree and not define it in the panel driver. And to get rid of the force_hw_rotation module parameter. But that all can be polished later.
BR and thanks for your good guess what has to be done, Nikolaus