drm/ssd130x: stale pixels when the GPU renders into the framebuffer
Fabio Piparo <[email protected]>
| Newsgroups | org.freedesktop.lists.dri-devel |
|---|---|
| Message-ID | <CAB3Lz5ZuAJcgKpx0L-O3a-1psk+vwBMeH_Eux+OAgaYcyfFm6A@mail.gmail.com> |
The symptom =========== I am working with a Raspberry Pi 5 driving a 128x32 SSD1306 over I2C through ssd130x, brought up with dtoverlay=ssd1306, and a GLES client rendering into it. The GPU renders straight into the panel's framebuffer. The panel shows a blocky pattern that is affected by CPU load. The kernel is 6.18.39. A capture: https://files.fabiopiparo.com/ssd130-line-glitch.webp This is a simple trail traveling left to right, and the busier the Pi is, the shorter the trail (link above). On an idle machine the leftovers build up into a blocky fog. That was the clue that pointed me at the CPU cache, since the lifetime of the artifact tracks memory pressure. The trace ========= I made a test program that flips between two alternating solid frames while i2c_write payloads are traced. 15 of the 31 flushes carry bytes from both frames in one payload, mixed at 64 byte granularity. What appears to happen ====================== My reading: the driver's XRGB conversion reads the framebuffer through a cached mapping while the GPU writes the same memory directly, so what reaches the panel is whatever lines the CPU still holds. The 64 byte granularity and the load dependence both fit that, and write-combining the mapping makes it stop. What stops it ============= Setting shmem->map_wc in a .gem_create_object hook makes all the traced payloads come out as expected. Whether the exporter is the right place for this, I do not know. I am happy to test anything on this hardware and report back. Disclosure ========== The panel, the symptom and the i2c trace come from my own hardware. The analysis above and the change came out of a long debugging session with an AI assistant.