Display engine: the DRC never receives the backend's pixels #22
Labels
No labels
blocked-physical
cleanup
hardware
infra
kernel
P1-critical
P2-high
P3-normal
P4-later
reliability
security
upstream
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
tiagoagueda/a80#22
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Half resolved 2026-08-28 — see 44-hdmi.md. Retitled, because the original
framing was wrong in both directions.
The encoder works, and needed no new driver
The A80's HDMI is a Synopsys DesignWare HDMI TX v1.32a with an Allwinner vendor PHY — the
same arrangement as the A83T, not the Allwinner-native controller the A10/A31 use. Read off the
block itself:
So mainline's existing
allwinner,sun8i-a83t-dw-hdmiandallwinner,sun8i-a83t-hdmi-phycompatibles drive it unmodified. This was DT only.
Verified with a TV attached: connector reports
connected, 256 bytes of EDID read back overDDC,
1920x1080@60set with TMDS and the TCON1 pixel clock both at 148.5 MHz, and disablingthe CRTC makes the TV report "no signal".
What is actually missing: the display engine
The old text called the pipeline complete because every node binds. They do — but nothing had
ever consumed their output, because this SoC has never had an encoder. The path has never
scanned out, and it does not work.
With
modetestholding a mode, everything except one block is correct:sun6i_drc.cis 124 lines that deassert a reset and enable two clocks and write no registersat all, assuming the block powers up passing data through. On the A80 it does not. From the
vendor BSP (
lowlevel_sun9iw1/iep_drc_ebios.{c,h}):gnectl0x00enbit 0,modbits 8-9drcsize0x04(h-1) << 16 | (w-1)0xc0-0xecdrc_csc_tab[0..11]Stepping it up on the live pipeline:
+ drcsize + gnectl.en, mode 2+ identity CSC+ BT.601 YUV→RGB CSCThe red was explained: the CSC held
0x04a7…, the BT.601 YUV→RGB matrix left by the vendorbootloader, and we were feeding it RGB.
Where it is stuck
That A/B is the useful measurement. The DRC's output is a constant derived from the CSC offset
terms — identity has zero offsets and gives noise, YUV601 has non-zero offsets and gives flat
green. It does not depend on the framebuffer at all.
So the DRC runs but never receives the backend's pixels. The BE→DRC interconnect is the open
question, and it is the one thing between here and a picture.
Already ruled out:
DE_BE_Output_Select()writes bits 20-22 of the backendMODE_CTL(0x800),and the vendor calls it as
DE_BE_Output_Select(screen_id, screen_id)with 1 and 2 mapping to 0— so those bits should be zero, and ours are.
Worth looking at next:
DE_SYSat0x03000000andDISP_SYSat0x03010000. Mainline mapsonly
0x30bytes of the first, purely as a clock controller (de_clocks), and never touches thesecond at all.
Tools for this are in
probe/:deprobe.kodumps BE1/DRC1/TCON1 live,drcfix.koprograms theDRC with selectable mode and CSC.
⚠️ Nothing has been submitted upstream. See 42-upstreaming.md.
HDMI / display output: pipeline exists in mainline, encoder does notto Display engine: the DRC never receives the backend's pixelsResolved 2026-08-28. There is a picture.
The framebuffer console appears on the TV at boot and
modetestputs a SMPTE pattern onscreen at 1920x1080@60 with no probe modules loaded.
Four independent faults, each of which alone gives a screen full of noise while every
register reads back as correctly configured hardware:
sun6i_drc.cwrites no registers at all. The A80's DRC needs its size, an identityCSC over the BT.709 matrix it holds at reset, and a double-buffer latch - without
which the registers read back perfectly and do nothing. Measured through the DRC's own
write-back: programmed gives 57376/65536 non-zero and 8 distinct values (the bars),
stock mainline gives 0.
physical
0xfc900000; the hardware was told0xdc900000. Both give the same low wordonce shifted, differing only in the four high bits.
alpha and the A80 reads those padding bits as zero.
mechanism (
needs_de_be_mux) but sets it only for the A31.Kernel commits on
draco-aw80:15592f068,3a822cea9,133105f40.The original framing of this issue - "the DRC never receives the backend's pixels" - was
wrong, and wrong because of a probe that read the layer address register as a byte address
when it is a bit address. Written up in
46-hdmi-picture.md.
Follow-ups opened separately for the two things this leaves behind.