Portrait Display Rotation Issues: Why It's Broken (Kernel + Plymouth)

Dear Volumionauts,

I’ve completed extensive research into portrait display rotation problems many Volumio users experience, particularly during boot and with Plymouth splash screens. This isn’t a Volumio bug - it’s a fundamental Linux kernel limitation.

The Core Problem

Linux DRM (Direct Rendering Manager) assumes all displays are landscape-oriented by default. When you have a portrait-native panel (like many touch displays with 320x1480, 720x1280, or 1080x1920 resolution), the kernel’s rotation logic breaks down.

Evidence across multiple hardware platforms

This issue affects:

  • Waveshare portrait displays (all models)
  • Raspberry Pi official 7" Display 2 (720x1280)
  • Freescale i.MX6 ARM systems with portrait panels
  • Generic embedded portrait LCDs

Multiple developer communities (Raspberry Pi Forums, NXP Community, Linux kernel developers) have documented identical behavior: rotation parameters produce unexpected or wrong orientations on portrait-native panels.

Why rotation values don’t work

When you set video=HDMI-A-1:rotate=90, the kernel calculates rotation FROM a landscape baseline. But portrait panels already start rotated. The math fails:

  • rotate=0 may show 90 CCW
  • rotate=90 may show 90 CCW
  • rotate=180 may show 90 CW
  • rotate=270 may show 90 CCW

This inconsistency occurs because fbcon rotation values and video rotation values use different coordinate systems, and both assume landscape orientation.

Plymouth splash screen impact

Plymouth inherits the framebuffer state from the kernel. When the kernel provides a broken rotation state, Plymouth displays incorrectly. Additionally:

  • Plymouth’s Image.Text.Rotate() function exists and works for images
  • BUT: Rotated text suffers severe clipping on portrait displays
  • Dynamic text (service messages) becomes unreadable when rotated 90/270 degrees
  • This is documented in Plymouth’s portrait mode implementations

The device rotation workaround problem

Many users try device-level rotation (kernel parameters). This works for landscape displays but fails for portrait-native panels because the firmware and kernel disagree about the panel’s base orientation. The only “solution” some users find is disabling KMS acceleration entirely - which cripples graphics performance.

Behavior varies by Raspberry Pi model

Multiple users report:

  • Rotation works on Pi 3 and Pi 4
  • Same configuration fails on Pi 5
  • This indicates firmware regression, not configuration error

Bottom line

If you have a portrait-native display and experience rotation issues during boot or with Plymouth:

  1. This is a known Linux kernel DRM architectural limitation
  2. It affects all portrait-native panels, not specific brands
  3. Plymouth cannot fix what the kernel provides incorrectly
  4. The issue exists across multiple embedded Linux platforms

This is not something Volumio can fix at the application level. The problem exists in the kernel’s fundamental assumptions about display orientation. Perhaps something will change in future, but today - “it is what it is”.

Kind Regards,


Research sources: Linux kernel DRM source code, Raspberry Pi developer forums, NXP embedded community, Plymouth freedesktop documentation, multiple cross-platform embedded Linux discussions

2 Likes

Dear Volumionauts,

Portrait display rotation: A working solution

Following up on my previous post about portrait display rotation issues - I’ve built a solution that works around the kernel limitations.

The solution: volumio-plymouth-adaptive

Repository:

Instead of fighting the broken kernel rotation, this approach uses two strategies:

1. Pre-Rotated Image Assets (volumio-adaptive theme)

  • Creates image sequences rotated at 0, 90, 180, 270 degrees ahead of time
  • Selects the correct sequence at boot based on plymouth= kernel parameter
  • No initramfs rebuild needed - just edit cmdline.txt and reboot
  • Preserves all volumio-player theme features

2. Framebuffer Rotation for Text (volumio-text theme)

  • Uses system-level video=...,rotate= or fbcon=rotate: parameters
  • Lets the framebuffer handle text rotation instead of Plymouth
  • Lightweight fallback for minimal installations

Why this works

The kernel’s DRM rotation is fundamentally broken for portrait-native panels because it assumes landscape baseline. By pre-rotating assets and using framebuffer rotation for text, we bypass the problem entirely.

Key features

  • Runtime rotation detection (no initramfs rebuild for display changes)
  • Works with Volumio OTA updates
  • Tested on Raspberry Pi 5 with Waveshare 11.9" LCD (320x1480)
  • Proper parameter separation (plymouth= for images, video=/fbcon= for text)
  • Complete documentation and installation guides

Current status

Both themes are complete (v1.0) and tested. The repository includes:

  • Full installation instructions
  • Configuration examples
  • Documentation on Volumio’s config file hierarchy
  • Integration notes for volumio-os

Testing welcome

If you have portrait displays and have struggled with rotation issues, I’d appreciate testing and feedback. The repository includes everything needed for installation and configuration.

The bottom line: Portrait display rotation CAN work reliably - you just need to work around the kernel’s assumptions rather than depend on them.

Kind Regards,

3 Likes

Dear Volumoinauts,

Update: Plymouth rotation prototype successfully tested

Following my earlier post about portrait display rotation limitations, I’m pleased to report I’ve developed a working prototype solution for Plymouth boot splash screens.

The prototype solution

Rather than fighting kernel DRM rotation limitations, I’ve implemented a theme-based approach:

  1. Pre-rotated image sequences

    • Plymouth theme includes 4 complete image sets (sequence0, sequence90, sequence180, sequence270)
    • Each sequence contains pre-rotated PNG assets
    • No runtime image transformation needed
  2. Dynamic sequence selection

    • New plymouth= boot parameter selects correct sequence
    • Boot with plymouth=90, plymouth=180, or plymouth=270
    • Theme script patched at boot time to load appropriate sequence
    • Works in read-only initramfs via bind-mount technique
  3. Consolidated implementation

    • Single Plymouth init script handles both theme rotation and SPI screen support
    • Maintains existing framebuffer rotation for SPI displays
    • Clean integration with Volumio build system

Technical details

The implementation uses a copy-patch-bindmount approach:

  • Plymouth rotation script reads plymouth= parameter from /proc/cmdline
  • Copies theme script to writable /tmp
  • Patches rotation variable (plymouth_rotation = 90)
  • Bind mounts patched version over original
  • Plymouth reads patched script and loads correct image sequence

This works because we’re not asking the kernel to rotate - I’re simply selecting pre-rotated assets.

Current status - Prototype Phase

  • Core implementation complete and tested
  • Rotation works correctly during boot
  • No performance impact observed
  • Compatible with both console and future X server modes

Remaining work

  • Plymouth exits slightly early (2-5s gap before console/UI appears)
  • Investigating systemd service handoff timing
  • Testing on additional hardware configurations
  • Integration into official Volumio OS builds pending

This is a remarkable milestone - I’ve proven the concept works. The original research about kernel limitations remains valid - we simply found a way to work around it specifically for Plymouth. Sometimes the best solution is to avoid the problem entirely.

More updates as testing continues.

Kind Regards,

4 Likes

Hey @nerd

This is realy exciting news. Great addition. Locking forward to see it “live” !

Best Regards / C

Dear Volumionauts,

Major update: Plymouth rotation solution - release 1.02

Following my previous posts about the prototype solution, I’m excited to share a significant milestone in the Plymouth rotation implementation.

What’s new in release 1.02 - message overlay system

After extensive development work (many days and nights of effort), the final technical challenge has been solved: displaying boot messages at all rotation angles.

The solution - pre-rendered message overlays:

  • 104 transparent PNG overlay images

    • 13 critical Volumio boot messages
    • 4 rotation angles (0, 90, 180, 270 degrees)
    • 2 adaptive sizes (breakpoint at 400px smallest dimension)
  • Layered rendering approach

    • Logo renders below (Z-index 1)
    • Transparent message overlay renders above (Z-index 2)
    • Logo shows through transparency, text visible below logo
    • Universal positioning - works at all rotations
  • Smart message matching

    • Pattern-based text detection
    • Handles variable content (version numbers)
    • Compatible with OEM builds

Why pre-rendered images? - Plymouth’s fundamental limitations

This is NOT a Volumio limitation. This is a fundamental gap in Plymouth’s mainstream support:

Early development attempts using Plymouth’s native dynamic text rendering with rotation transformation consistently failed across ALL platforms:

  • Complex coordinate mapping differs for each rotation angle

    • Plymouth provides no unified coordinate transformation API
    • Each rotation (90, 180, 270) requires completely different positioning math
    • Mainstream Plymouth documentation offers no solution for this
  • Text positioning off-screen at 90/270 degrees on narrow displays

    • Plymouth’s coordinate system assumes landscape orientation
    • Portrait-native panels break these assumptions
    • This affects ALL Linux distributions, not just Volumio
  • Severe text clipping in Plymouth’s Image.Text.Rotate() function

    • Plymouth’s rotation API exists but produces unreadable results
    • Rotated text suffers severe clipping artifacts
    • This is documented in upstream Plymouth’s portrait mode implementations
    • The function works for simple images but fails for rendered text

Critical point: These are limitations in Plymouth itself and mainstream Linux graphics stack - not Volumio-specific issues. Any Linux distribution attempting rotated text during boot faces identical problems. The Plymouth project provides no working solution for dynamic text rendering on rotated displays.

Final solution uses static pre-rendered overlays because Plymouth’s mainstream support for dynamic rotated text rendering is insufficient:

  • No runtime coordinate transformation needed
  • Simple sprite centering works universally
  • Perfect text quality at all angles
  • Logo visibility maintained through transparency

This approach works around Plymouth’s limitations rather than depending on incomplete mainstream features.

Testing results

Extensively tested on Waveshare 11.9" LCD (1480x320 resolution - the most challenging constraint due to narrow dimension):

  • Rotation 0°: Text below logo, full size ✓
  • Rotation 90°: Text below logo, compact size (320px constraint) ✓
  • Rotation 180°: Text below logo, full size ✓
  • Rotation 270°: Text below logo, compact size ✓

All 13 Volumio boot messages display correctly:

  • Firmware update notifications (critical for OTA)
  • Factory reset warnings
  • Storage expansion progress
  • USB device status
  • System startup completion

Current status - release 1.02

This release includes:

  • Complete Plymouth theme script with universal rotation support
  • 104 transparent overlay images for boot messages
  • Message pattern matching system with OEM compatibility
  • Adaptive sizing based on display dimensions
  • Runtime rotation detection (no initramfs rebuild for display changes)
  • Full documentation and integration guides
    Next steps - path to production

Before this solution can be integrated into official Volumio OS builds, it must undergo rigorous testing:

  • Raspberry Pi platforms: Pi 3, Pi 4, Pi 5 (ARM architecture)
  • x86-64/amd64 platforms: Generic PCs, embedded x86 systems
  • Various portrait display hardware configurations
  • OEM build compatibility verification
  • Integration testing with Volumio build system
  • Community feedback and real-world usage validation

This represents nights and days of concentrated effort to work around limitations in mainstream Plymouth support that have frustrated users across ALL Linux distributions with portrait displays. The technical foundation is solid, but thorough cross-platform validation is essential before production deployment.

If you have portrait displays (ARM or x86-64) and want to help test this solution, the Volumio OS repository contains complete installation instructions. Your feedback will be invaluable for the final production release.

Portrait displays CAN work reliably on Linux - you just need to work around Plymouth’s mainstream limitations rather than depend on incomplete features.

Kind Regards,

3 Likes

Amazing @nerd :wink:

Dear Volumionauts,

Following up on my v1.02 release post - repository documentation is now complete and verified.

Status: Ready for V4 beta builds

All documentation has been reviewed and corrected. The repository now contains accurate installation procedures, technical specifications, and troubleshooting guides for the transparent message overlay system.

Repository

Changes since last update:

  • Complete documentation suite verified
  • All file structures and references corrected
  • Installation and troubleshooting guides expanded
  • Technical architecture fully documented
  • Ready for integration into Volumio OS build system

Testing welcome on ARM (Pi 3/4/5) and x86-64 platforms with portrait displays.

Kind Regards,

Dear Volumionauts,

Setup Guide: Portrait Display Rotation with Plymouth

Quick Configuration

Edit /boot/cmdline.txt (single line, space-separated parameters):

For portrait display rotated 270° (cable at bottom):
video=HDMI-A-1:320x1480M@60,rotate=90 plymouth=90

For portrait display rotated 90° (cable at top):
video=HDMI-A-1:800x480M@60,rotate=270 plymouth=270

For landscape upside-down:
video=HDMI-A-1:1920x1080M@60,rotate=180 plymouth=180

For landscape normal:
plymouth=0
(or omit plymouth= parameter)

The Formula:
plymouth_value = (360 - rotate_value) % 360

What Each Parameter Does

video=HDMI-A-1:WIDTHxHEIGHTM@60,rotate=XXX

  • Rotates console text and framebuffer
  • Use your display’s native resolution
  • Interface: HDMI-A-1, DSI-1, etc.

plymouth=XXX

  • Selects pre-rotated Plymouth image sequence
  • Values: 0, 90, 180, 270
  • Required for volumio-adaptive theme

What to Expect

Boot sequence with both parameters:

  1. Plymouth splash appears correctly rotated
  2. Volumio logo animation plays at correct orientation
  3. Boot messages display as transparent overlays
  4. Console text appears correctly rotated
  5. Smooth transition to UI

With runtime detection installed:

  • Change rotation by editing cmdline.txt only
  • Reboot - no initramfs rebuild needed
  • Theme automatically adapts to new rotation

Troubleshooting

Console correct but Plymouth wrong?

  • Check plymouth= parameter exists in cmdline.txt
  • Verify formula: plymouth = (360 - rotate) % 360

Plymouth correct but console wrong?

  • Check video=…,rotate= parameter
  • Verify display interface (HDMI-A-1, DSI-1, etc.)

Nothing displays?

  • Verify cmdline.txt is single line
  • Check quiet splash parameters present
  • Confirm theme installed: sudo plymouth-set-default-theme

See repository RASPBERRY_PI_SETUP.md for detailed procedures.

Tested Hardware

Working configurations:

  • Waveshare 11.9" LCD (320x1480)
  • Raspberry Pi Display 2 (720x1280)
  • Generic portrait panels
  • FHD/QHD landscape displays
  • Raspberry Pi 3, 4, 5

Installation

Full installation guide in repository INSTALLATION.md
Runtime detection recommended for easy rotation changes

Kind Regards,

1 Like

Hey @nerd

Maybe a dumb question (again) but will Plymouth Adaptive theme work with Touch Display plugin? What about Virtual keyboard?
I’m on Volumio 4.062 running on a Rpi5 (latest firmware eeprom update ) and using a 7" Rpi Touch Display 2. As for now it works. It would be good to know before I proceed with an installation.

Best Regards / C

Hey @ClaesM,

Not at all. This work fixes init level rotation coordinator. Touch Display plugin is in loaded system, xorg user space. However - if plugin breaks for some reason - please post your findings in the relevant thread.

Kind Regards,

1 Like

Hey @nerd
I have some problems when install Plymouth adaptive

Best Regards / C

Hey @ClaesM,

It is shipped in Beta 4.064 already.

Kind Regards,

1 Like

Hey @nerd

So I just need to do some changes in /boot/userconfig.txt and /boot/cmdline.txt ?

Best Regards / C

Hey @ClaesM,

You will find complete usage examples in one of the very well known problematic displays.

Kind Regards,

Hey @nerd

I’m using RPI 5 with RPI Touch Display 2 Latest Volumio 4.066. Display connected to DSI=2, not HDMI so I’m a bit concerned abot how to make it work but I guess it would be something like this at the end of cmdline.txt ?

video=DSI-2:720x1280@60,rotate=270 plymouth=270

Best Regards / C

Hey @ClaesM,

Which physical port are you using? The one closer to the USB-C port port, you will need only:
/boot/userconfig.txt

[all]
dtoverlay=vc4-kms-dsi-ili9881-7inch,rotation=270

This was fixed in kernel’s repo a while back. More information here.

Kind Regards,

Thank @nerd

Yes, I’m using the port closer to USB-C port. This is what I have in my userconfig.txt right now. Is this ok?

# Add your custom config.txt options to this file, which will be preserved during updates
[all]
display_auto_detect=1
dtoverlay=vc4-kms-dsi-ili9881-7inch,rotation=270
dtparam=rtc_bbat_vchg=3000000
gpu_mem=128
#### Touch Display rotation setting below: do not alter ####
display_lcd_rotate=3
display_hdmi_rotate=3

Best Regards / C