raspberrypi / linux

Kernel source tree for Raspberry Pi-provided kernel builds. Issues unrelated to the linux kernel should be posted on the community forum at https://forums.raspberrypi.com/
Other
11.03k stars 4.95k forks source link

fbtft broken on kernels newer than 5.0 #3263

Closed satmandu closed 4 years ago

satmandu commented 4 years ago

I am loading the waveshare35a.dts overlay in config.txt thus to get a lcd screen connected:

[all]
device_tree_address=0x03000000
enable_uart=1
dtparam=spi=on
dtoverlay=pi3-disable-bt
dtoverlay=waveshare35a:rotate=270,speed=21000000,debug=1
dtoverlay=vc4-kms-v3d
dtparam=i2c_arm=on
initramfs initrd.img followkernel

cmdline.txt:

net.ifnames=0 dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait fsck.mode=force fsck.repair=yes fbcon=map:10 fbcon=font:ProFont6x11 logo.nologo nosplash cma=128M@256M

This works with the testing kernel8.img kernel at https://github.com/Hexxeh/rpi-firmware/tree/master This also works with the ubuntu 19.10 5.0.0-1017-raspi2 arm64 kernel. This does not work with a rpi-5.3.y kernel from today. (Kernel is modified with BCM2708_VCMEM so that I get vcdbg messages.)

Working ubuntu 5.0.0-1017-raspi2 kernel: 5.0.0-1017-raspi2 dmesg: https://paste.ubuntu.com/p/GKPnqw86MC/ 5.0.0-1017-raspi2 config: https://paste.ubuntu.com/p/mT7RDnYQS3/ Broken: 5.3.0-v8-gb03118b64 dmesg: https://paste.ubuntu.com/p/f8tjHTPk2Z/ 5.3.0-v8-gb03118b64 kernel config: https://paste.ubuntu.com/p/gyYyRM8jJH/

sudo vcgencmd version 
Sep  3 2019 23:52:29 
Copyright (c) 2012 Broadcom
version 6dc34ddf57a9cb5e234d00a4490d0b6a31688526 (clean) (release) (start)

sudo vcdbg log msg
Failed to allocate -1716518942 bytes for message buffer

sudo dtoverlay -d /boot/firmware/overlays -l
No overlays loaded

uname -a
Linux bridge 5.0.0-1017-raspi2 #17-Ubuntu SMP Thu Sep 12 14:25:40 UTC 2019 aarch64 aarch64 aarch64 GNU/Linux

Am I doing something wrong?

pelwell commented 4 years ago

What evidence do you have that the overlay hasn't been applied? dtoverlay -l will only show overlays applied at runtime with the dtoverlay command.

You can dtc -I fs /proc/device-tree to dump the loaded DT in textual form. Try running that with and without the overlay in config.txt, then compare the two.

satmandu commented 4 years ago

Mea culpa for not understanding.

It looks like the dtoverlays are being applied correctly in both.

(had to compile dtc 1.5.1 to get proper output)

device tree dmesg Functionality notes
5.0.21-v8-g0222b82b2 5.0 +
5.0.21-v8-g0222b82b2 5.0 +
5.3 5.3 -
5.3.7-v8-gaa4c02b03 5.3.7-v8-gaa4c02b03 - w/ 5.4rc4 fbtft
5.4-rc2 5.4-rc2 -
5.4-rc4 5.4-rc4 -

I guess I'll ask upstream to see if fbtft is having issues in 5.3.

satmandu commented 4 years ago

This is resolved with dts modifications since as per discussion with Phil Reid "Prior to the switch to gpiod polarity definitions in the dts file where not being honoured."

The switch in the staging fbtft driver happens in Linux Kernel 5.1, and is finally fixed for Kernel 5.4. (confirmed in a rpi 5.3 kernel compiled with the fbtft modules from kernel 5.4)

FYI one also appears to have to boot with CONFIG_SPI_BCM2835AUX=m set in the kernel build config.

satmandu commented 2 weeks ago

Necroposting here as an update.

The Wavshare 3.5a display is working fine on a Raspberry Pi 3B+ using the 64-bit 6.6.47 kernel from https://github.com/raspberrypi/rpi-firmware with the Debian/12 Bookworm version of Raspberry Pi OS (64-bit).

I am using these changes from defaults in /boot/firmware/config.txt:

# dtparam=i2c_arm=on # (I don't need this on since I'm not using the touchscreen.)
dtparam=spi=on
dtoverlay=waveshare35a:rotate=270,speed=21000000,debug=1

Additionally I have this added to my /boot/firmware/cmdline.txt:

fbcon=map:10 fbcon=font:ProFont6x11

I did have to download the wavshare35a.dtbo:

cd /boot/firmware/overlays
sudo curl -OLf https://github.com/swkim01/waveshare-dtoverlays/raw/master/waveshare35a.dtbo

After making those changes and rebooting, the display is working. I have not tried to get the touchscreen working as per https://github.com/swkim01/waveshare-dtoverlays/issues/29 .

pelwell commented 2 weeks ago

Do you really need the spi dtparam? The overlay should enable SPI for itself, so it's a bit poor if you do.

6by9 commented 2 weeks ago

If memory serves correctly, the Waveshare 3.5a display is identical from the software side to the Ozzmaker PiScreen, and works perfectly with the standard dtoverlay=piscreen. (I have one on my desk in the office and write the relevant dtoverlay on the back of it, so can confirm on Monday).

Use dtoverlay=piscreen,drmand it should use the tinydrm drivers instead of fbtft, and therefore be available as a normal display under Wayfire and labwc.

satmandu commented 2 weeks ago

If memory serves correctly, the Waveshare 3.5a display is identical from the software side to the Ozzmaker PiScreen, and works perfectly with the standard dtoverlay=piscreen. (I have one on my desk in the office and write the relevant dtoverlay on the back of it, so can confirm on Monday).

Use dtoverlay=piscreen,drmand it should use the tinydrm drivers instead of fbtft, and therefore be available as a normal display under Wayfire and labwc.

Using dtoverlay=piscreen,drm definitely works to get the console up on the screen, but I only get a black screen when I try to enable a gui login using raspi-config. (I'm selecting wayfire.) (Thanks for helping me make this setup simpler!)

(This is entirely acceptable to me, as this older device is becoming a standalone call screening device with call attendant for my parents, and they won't really use the screen.)

6by9 commented 2 weeks ago

Using dtoverlay=piscreen,drm definitely works to get the console up on the screen, but I only get a black screen when I try to enable a gui login using raspi-config. (I'm selecting wayfire.) (Thanks for helping me make this setup simpler!)

Have you got an HDMI display connected at the same time? Run the "Screen Configuration" app, enable SPI-1 as a display, and place it where you want it in the extended desktop. Mainline Mesa and Raspberry Pi OS have the relevant patches to Mesa to support these SPI screens (https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26129), but it may not be in Debian's packages.

satmandu commented 2 weeks ago

No external HDMI display is connected. Maybe once the mesa updates land in a release that Debian has I'll take a look again, but the goal for this device is to sit silently and mostly ignored, so I may not get there at all.

6by9 commented 2 weeks ago

I'm suggesting you connect an HDMI monitor to check what the state of play is.

You can also do the same over SSH using WAYLAND_DISPLAY=wayland-0 wlr-randr to list the current displays, and I'd expect WAYLAND_DISPLAY=wayland-0 wlr-randr --output SPI-1 --on --pos 0,0 to set it as the monitor at 0 offset in the desktop.

satmandu commented 2 weeks ago

Without attaching an HDMI monitor, it does appear that lightdm appears to start but fail to find any X displays.

from /var/log/Xorg.0.log:

[    54.373] (==) Using config directory: "/etc/X11/xorg.conf.d"
[    54.373] (==) Using system config directory "/usr/share/X11/xorg.conf.d"
[    54.377] (==) ServerLayout "ServerLayout0"
[    54.377] (==) No screen section available. Using defaults.
[    54.377] (**) |-->Screen "Default Screen Section" (0)
[    54.377] (**) |   |-->Monitor "<default monitor>"
[    54.378] (==) No device specified for screen "Default Screen Section".
        Using the first device section listed.
[    54.378] (**) |   |-->Device "kms"
[    54.378] (==) No monitor specified for screen "Default Screen Section".
        Using a default monitor configuration.
[    54.378] (**) Option "BlankTime" "0"
[    54.378] (**) Option "StandbyTime" "0"
[    54.378] (**) Option "SuspendTime" "0"
[    54.378] (**) Option "OffTime" "0"
[    54.378] (**) Option "Debug" "dmabuf_capable"

Meanwhile /var/log/lightdm/lightdm.log says...

[+0.08s] DEBUG: User /org/freedesktop/Accounts/User1000 added
[+1.36s] DEBUG: Seat seat0: Creating display server of type x
[+3.66s] DEBUG: Seat seat0: Plymouth is running on VT 1, but this is less than the configured minimum of 7 so not replacing it
[+3.66s] DEBUG: Quitting Plymouth
[+4.17s] DEBUG: Using VT 7
[+4.17s] DEBUG: Seat seat0: Starting local X display on VT 7
[+4.17s] DEBUG: XServer 0: Logging to /var/log/lightdm/x-0.log
[+4.17s] DEBUG: XServer 0: Writing X server authority to /var/run/lightdm/root/:0
[+4.17s] DEBUG: XServer 0: Launching X Server
[+4.18s] DEBUG: Launching process 904: /usr/bin/X :0 -seat seat0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch
[+4.18s] DEBUG: XServer 0: Waiting for ready signal from X server :0
[+4.18s] DEBUG: Acquired bus name org.freedesktop.DisplayManager
[+4.18s] DEBUG: Registering seat with bus path /org/freedesktop/DisplayManager/Seat0
[+10.83s] DEBUG: Got signal 10 from process 904
[+10.83s] DEBUG: XServer 0: Got signal from X server :0

Do I need to do some xorg config magic to get that to work? I assume that the lightdm greeter won't pass along the display from plymouth directly to wayfire so it can try to ?

Also, I did manage to get plymouth to work.

I had to carry out the following steps, modifying the instructions from https://github.com/notro/fbtft/wiki/Bootsplash#setup-initramfs :

echo 'export FRAMEBUFFER=/dev/fb1' | sudo tee /etc/initramfs-tools/conf.d/fb1
cat << MODULES_EOF  | sudo tee -a /etc/initramfs-tools/modules
spi_bcm2835
ili9486
drm_kms_helper
drm_dma_helper
vc4
drm_mipi_dbi
drm_display_helper
MODULES_EOF

cat << SPI_EOF  | sudo tee /etc/initramfs-tools/scripts/init-top/spi
#!/bin/sh

modprobe spi_bcm2835
SPI_EOF
sudo chmod +x /etc/initramfs-tools/scripts/init-top/spi

sudo update-initramfs -u -k `uname -r`
sudo cp /boot/initrd.img-`uname -r` /boot/firmware/initramfs8

Since wayfire never starts up, WAYLAND_DISPLAY=wayland-0 wlr-randr doesn't actually give any output, and pgrep wayfire is empty...

6by9 commented 2 weeks ago

You'd said

Using dtoverlay=piscreen,drm definitely works to get the console up on the screen, but I only get a black screen when I try to enable a gui login using raspi-config. (I'm selecting wayfire.) (Thanks for helping me make this setup simpler!)

Based on those logs, you're not running Wayfire and are still in X11. It is possible to get X to work these SPI displays, but is a real pain with xrandr --setprovideroutputsource type commands.

If you wish to pursue this, I'd suggest you install labwc via sudo apt install labwc, and then select that via raspi-config. Wayfire is VERY heavy on GPU 3D usage, and Pi0-3 can't quite keep up. labwc uses alternate renderers which are lighter weight.

satmandu commented 2 weeks ago

Ah there we go.

WAYLAND_DISPLAY=wayland-0 wlr-randr
SPI-1 "(null) (null) (SPI-1)"
  Physical size: 73x49 mm
  Enabled: yes
  Modes:
    480x320 px, 0.007000 Hz (preferred, current)
  Position: 0,0
  Transform: normal
  Scale: 1.000000

Once I get back I'll see if there is actually a display showing!

satmandu commented 2 weeks ago

The display is working with wayland! Does the piscreen need any special configuration to get the touchscreen working with wayland?

6by9 commented 2 weeks ago

The display is working with wayland! Does the piscreen need any special configuration to get the touchscreen working with wayland?

First check that your touchscreen is listed via libinput list-devices.

It's generally worth assigning the touch input to a specific screen, otherwise touch events are stretched over the entire desktop. The easiest way in Raspberry Pi OS is to use the "Screen Configuration" app as it will create the relevant json entries in the required file for labwc. Right click on SPI-1's representation and it should have a "Touschscreen" submenu.

satmandu commented 1 week ago

Looks like we have the proper input device:

libinput list-devices
Device:           ADS7846 Touchscreen
Kernel:           /dev/input/event2
Group:            1
Seat:             seat0, default
Capabilities:     touch 
Tap-to-click:     n/a
Tap-and-drag:     n/a
Tap drag lock:    n/a
Left-handed:      n/a
Nat.scrolling:    n/a
Middle emulation: n/a
Calibration:      identity matrix
Scroll methods:   none
Click methods:    none
Disable-w-typing: n/a
Disable-w-trackpointing: n/a
Accel profiles:   n/a
Rotation:         n/a

Device:           vc4-hdmi
Kernel:           /dev/input/event0
Group:            2
Seat:             seat0, default
Capabilities:     keyboard pointer 
Tap-to-click:     n/a
Tap-and-drag:     n/a
Tap drag lock:    n/a
Left-handed:      disabled
Nat.scrolling:    disabled
Middle emulation: n/a
Calibration:      n/a
Scroll methods:   *button
Click methods:    none
Disable-w-typing: n/a
Disable-w-trackpointing: n/a
Accel profiles:   flat *adaptive
Rotation:         n/a

Unfortunately setting up the LIBINPUT_CALIBRATION_MATRIX with udev doing something like ATTRS{name}=="ADS7846 Touchscreen", ENV{LIBINPUT_CALIBRATION_MATRIX}="0.000000 1.000000 0.000000 -1.000000 0.000000 1.000000" doesn't appear to flip the xy axes appropriately for touchscreen input when I'm in labwc.

Is there any chance of using the swapxy override from https://github.com/raspberrypi/linux/blob/rpi-6.6.y/arch/arm/boot/dts/overlays/ads7846-overlay.dts? I don't see that option in https://github.com/raspberrypi/linux/blob/rpi-6.6.y/arch/arm/boot/dts/overlays/piscreen-overlay.dts but I do see that option in the wavshare overlay: https://github.com/swkim01/waveshare-dtoverlays/blob/master/waveshare35a.dts

6by9 commented 1 week ago

I have no issues with all the overrides being copied over, as long as the default behaviour remains the same. The README will need to be updated too.

I'm not treating it as a priority, but you're welcome to submit a PR with the change.

satmandu commented 1 week ago

Putting together a PR... quick question:

Does ti,swap-xy; in the piscreen.dts imply that swap-xy is already a default?

            piscreen_ts: piscreen-ts@1 {
                compatible = "ti,ads7846";
                reg = <1>;

                spi-max-frequency = <2000000>;
                interrupts = <17 2>; /* high-to-low edge triggered */
                interrupt-parent = <&gpio>;
                pendown-gpio = <&gpio 17 GPIO_ACTIVE_LOW>;
                ti,swap-xy;
                ti,x-plate-ohms = /bits/ 16 <100>;
                ti,pressure-max = /bits/ 16 <255>;
            };
        };

Otherwise my PR consists entirely of this:

diff --git a/arch/arm/boot/dts/overlays/piscreen-overlay.dts b/arch/arm/boot/dts/overlays/piscreen-overlay.dts
index 29bcd41f3..9807a747f 100644
--- a/arch/arm/boot/dts/overlays/piscreen-overlay.dts
+++ b/arch/arm/boot/dts/overlays/piscreen-overlay.dts
@@ -103,5 +103,8 @@ __overrides__ {
                xohms =         <&piscreen_ts>,"ti,x-plate-ohms;0";
                drm =           <&piscreen>,"compatible=waveshare,rpi-lcd-35",
                                <&piscreen>,"reset-gpios:8=",<GPIO_ACTIVE_HIGH>;
+               invertx =       <&piscreen_ts>,"touchscreen-inverted-x?";
+               inverty =       <&piscreen_ts>,"touchscreen-inverted-y?";
+               swapxy =        <&piscreen_ts>,"touchscreen-swapped-x-y?";
        };
 };
6by9 commented 1 week ago

Putting together a PR... quick question:

Does ti,swap-xy; in the piscreen.dts imply that swap-xy is already a default?

Yes.

Based on https://www.raspberrypi.com/documentation/computers/configuration.html#part2.2.3 I believe you'll want

               swapxy =        <&piscreen_ts>,"touchscreen-swapped-x-y!";
satmandu commented 1 week ago

Thanks all. I added a PR. Should I wait for a workflow to build the dtbo? I assume I need to do a full kernel build for that?

pelwell commented 1 week ago

You can extract a built dtbo from the artifacts of the first kernel build to complete: https://github.com/raspberrypi/linux/actions/runs/10702910993/artifacts/1891382366

pelwell commented 1 week ago

But in general, you should only need to do the make ... *_defconfig and make ... dtbs steps, both of which are quick.