Chapter 84: QSPI LCD¶
What: displays driven over quad-SPI (4 data lanes instead of 1) for ~4× the bandwidth of plain SPI. Common on round smartwatch-style LCDs: GC9D01 (round 160×160), ST77916 (round 360×360), SH8601 (AMOLED). We cover why QSPI matters for displays, the quad-mode MIPI-DBI command framing, the i.MX6ULL QSPI controller’s display-mode constraints, and how the mainline
mipi-dbihelper handles quad transfers.Why: a plain-SPI 360×360 16-bit display needs 259 KB per frame, at 40 MHz SPI that’s 52 ms = ~19 fps full-refresh, too slow for smooth animation. Quad-SPI quadruples the data rate to about 13 ms per frame, or 75 fps. That is the difference between smooth animation and a slideshow. QSPI is newer and less common. Fewer mainline drivers exist, so you are more likely to write your own.
Focus: QSPI display = MIPI-DBI commands sent over 4 data lanes. The command model is identical to Ch 83 (CASET/RASET/RAMWR), but each byte’s 8 bits are spread across 4 IO lines (2 bits per line per clock), so pixels stream 4× faster. The challenge is that the i.MX6ULL QSPI controller is designed for flash, not displays, using it for a display means working within its command-LUT model.
84.1 Why QSPI for displays¶
Bandwidth math for a full-frame refresh at 16-bit color:
Display |
Pixels |
Bytes/frame |
@40 MHz SPI (1-bit) |
@40 MHz QSPI (4-bit) |
|---|---|---|---|---|
240×240 |
57600 |
115 KB |
23 ms (43 fps) |
6 ms (170 fps) |
360×360 |
129600 |
259 KB |
52 ms (19 fps) |
13 ms (77 fps) |
454×454 |
206116 |
412 KB |
82 ms (12 fps) |
21 ms (48 fps) |
For small displays plain SPI is fine. For 360×360+ round AMOLEDs (smartwatch class), QSPI is needed for smooth animation. Partial updates (Ch 83) help, but full-frame animation (a sweeping watch hand redrawing the whole face) needs the bandwidth.
84.2 Quad-SPI signaling¶
Plain SPI: 1 data line (MOSI), 1 bit per clock. Quad-SPI: 4 data lines (IO0–IO3), 4 bits per clock, 4× the throughput at the same clock rate.
Plain SPI: MOSI ─ b7 b6 b5 b4 b3 b2 b1 b0 (8 clocks per byte)
Quad SPI: IO3 ─ b7 b3 (2 clocks per byte)
IO2 ─ b6 b2
IO1 ─ b5 b1
IO0 ─ b4 b0
For displays, a common framing (the “QSPI display” convention used by these controllers):
Command phase: single-lane (IO0 only), with a leading “command marker” byte.
Address phase: single-lane or quad.
Data phase: quad-lane (pixels stream 4× fast).
The exact framing is controller-specific. A typical ST77916 write:
/CS↓
single-lane: 0x02 (write marker) + 0x00 + cmd + 0x00
quad-lane: pixel data ...
/CS↑
84.3 The i.MX6ULL QSPI-for-display problem¶
The i.MX6ULL QSPI controller (fsl-quadspi) was designed for NOR flash (Ch 64), not displays. It works through a LUT (look-up table) of pre-programmed command sequences, you fill LUT entries describing “command + address + dummy + data” phases, then trigger them.
For a display, this is awkward:
The flash-oriented driver assumes memory-mapped reads (XIP). Displays are write-only streams.
The LUT model doesn’t naturally fit “send command on 1 lane, then stream N KB of pixels on 4 lanes.”
Mainline
fsl-quadspi.c(the MTD driver) doesn’t expose a display path.
MTD: Memory Technology Device, Linux’s raw flash subsystem for eraseblock-based storage.
Two practical approaches on i.MX6ULL:
Use the QSPI in
spi-memmode. Recent kernels expose the QSPI controller via thespi_memAPI, whichmipi_dbican drive for quad transfers. The mainlinespi-nxp-fspi.c(for i.MX8) supports this. The olderfsl-quadspi.c(i.MX6) has limited support. Check your kernel.Bit-bang or use a different SoC. If the QSPI controller can’t do display-style transfers, you’re stuck with plain SPI on i.MX6ULL. QSPI displays are more at home on i.MX8M / RP2040 / ESP32-S3 which have flexible QSPI/PIO peripherals.
Honest assessment: the i.MX6ULL is not a great host for QSPI displays. Its QSPI is flash-centric. For a product needing a QSPI AMOLED, an i.MX8M Mini (with FlexSPI) or a dedicated display co-processor is a better fit. We still cover the topic. The displays are increasingly common, and you will likely meet them on a more capable SoC.
84.4 How mipi_dbi handles quad mode¶
Some SPI controllers expose spi_mem with quad support. On those SoCs, the mipi_dbi helper can issue quad transfers. The newer DRM tiny drivers (e.g., for the ST77903, SH8601 AMOLEDs) use spi_mem_op structures:
/* Conceptual — quad pixel write via spi_mem */
struct spi_mem_op op = SPI_MEM_OP(
SPI_MEM_OP_CMD(0x32, 1), /* command on 1 lane */
SPI_MEM_OP_ADDR(3, (0x002C00), 1), /* RAMWR address, 1 lane */
SPI_MEM_OP_NO_DUMMY,
SPI_MEM_OP_DATA_OUT(len, pixels, 4)); /* pixels on 4 lanes! */
spi_mem_exec_op(spimem, &op);
The SPI_MEM_OP_DATA_OUT(len, buf, 4), the trailing 4 says “4-lane (quad) data phase.” The controller spreads the bytes across IO0–IO3. This is the same spi_mem_op abstraction we saw in the QSPI flash chapter (Ch 64.6), repurposed for display data.
A from-scratch QSPI display driver on a supporting SoC would:
Acquire the
spi_memdevice.Send the init sequence via single-lane
spi_mem_ops.Implement the
mipi_dbifb_dirtycallback to send CASET/RASET (single-lane) then RAMWR pixels (quad-lane) viaspi_mem_exec_op.
The structure mirrors Ch 83’s myst7789.c, but the pixel-write path uses a quad spi_mem_op instead of a plain spi_sync. We do not reproduce the full driver. It is the Ch 83 driver with the data phase changed to quad. It only works on an SoC whose controller supports quad spi_mem writes, stock i.MX6ULL does not.
84.5 When QSPI display makes sense¶
Scenario |
Bus choice |
|---|---|
240×240 static UI, occasional updates |
plain SPI (Ch 83) |
360×360 round watch face, full-screen animation |
QSPI (on a capable SoC) |
Large UI, video |
parallel RGB (Ch 82) or MIPI-DSI (not on i.MX6ULL) |
i.MX6ULL specifically |
plain SPI or parallel RGB, QSPI display support is weak |
For the i.MX6ULL reader: prefer parallel RGB (Ch 82) for big/fast displays, plain SPI (Ch 83) for small ones. QSPI displays are a “know it exists, use on a better SoC” topic.
84.6 Key Notes¶
Quad data lanes can reduce pixel-transfer time, but command phases, overhead and refresh synchronization still affect usable frame rate.
The i.MX6ULL QSPI controller is flash-oriented. A display design needs demonstrated compatibility between its transaction model, Linux support and the panel protocol.
Command lane width and data lane width are separate fields of a transaction. Lane order, chip select and initialization must match the module.
Transport speed does not remove tearing or power constraints. A plain SPI or parallel RGB design may be more appropriate when support for quad display transfers is uncertain.
84.7 Pitfalls¶
Assuming i.MX6ULL QSPI does displays well. It doesn’t, it’s flash-centric. Verify
spi_memquad-out support before committing to a QSPI display on this SoC.Quad-mode lane order. The bit-to-lane mapping (which bits go on IO0 vs IO3) varies. A wrong mapping gives scrambled pixels. Match the controller’s convention.
Command vs data lane count. Commands usually go on 1 lane, pixels on 4. Sending the command on 4 lanes confuses the controller. The
spi_mem_opcmd/data buswidth fields must be set per phase.Pull-ups on IO2/IO3. In single-lane mode, IO2/IO3 may double as /WP and /HOLD. For display use they’re data. Ensure no conflicting pulls.
Frame tearing at high fps. Without vsync/TE-pin synchronization, fast full-frame updates tear. Many QSPI AMOLEDs have a TE (tearing-effect) output. Wire it to a GPIO IRQ and sync updates.
MCU bridge: Think of an IRQ like an EXTI/NVIC interrupt path, except Linux splits the hard interrupt from deferred work and must share lines across drivers. MCU bridge: Think of Linux GPIO like the same pin set/reset block you used on STM32, but accessed through a kernel subsystem that owns numbering, direction, interrupts, and user-space exposure. IRQ: interrupt request, the signal path that tells the CPU or interrupt controller that hardware needs service. GPIO: General-Purpose Input/Output, a pin controlled as a digital input, output, or interrupt source.
Power: AMOLED inrush. QSPI AMOLEDs can draw significant current when displaying bright white. Budget the rail accordingly.
Init sequence length. AMOLED init sequences are long (50–100 commands) with vendor-specific gamma/voltage. Get the exact sequence from the module vendor.
84.8 Going deeper¶
drivers/gpu/drm/tiny/: newer entries (st7571, sh8601-style) show quad approaches on capable SoCs.drivers/spi/spi-mem.c: thespi_mem_opabstraction shared between flash and these displays.drivers/spi/spi-nxp-fspi.c: i.MX8 FlexSPI driver with quad support (contrast with i.MX6’sfsl-quadspi.c).Documentation/spi/spi-summary.rst: SPI/QSPI overview.ST77916 / SH8601 datasheets: QSPI display command framing.
i.MX6ULL Reference Manual, QuadSPI chapter: the LUT model and its constraints.
Note on Group H so far: parallel RGB (Ch 82) for big/fast on i.MX6ULL, plain SPI (Ch 83) for small/cheap, QSPI (Ch 84) for high-bandwidth-on-capable-SoCs. The next two chapters cover the non-raster display technologies: OLED character/graphic displays + e-paper (Ch 85), and the touch input that turns a display into an interface (Ch 86).
Next chapter: Chapter 85: OLED & e-paper (SSD1306 / SH1106 / SSD1680). Tiny monochrome OLEDs and the radically different e-paper refresh model.