Skip to content

j613 (MacBook Air M3): external DisplayPort over USB-C on both ports (dcpext), with patches #103

Open

Description

@GehrmannSolutions

External DisplayPort over USB-C works on the M3 MacBook Air on both USB-C ports, together with the M3 GPU. It runs the second display pipe (dcpext) with the 14.7 firmware iBoot loads. One root cause is a T8122 PMP bug that is not specific to external displays; it is filed separately as #102. The rest is J613 device tree, a Linux-started 14.7 dcpext path, and a few protocol fixes. The series is 12 patches on integration/aurora; it applies cleanly to today's 67d8e916.

Machine and build

  • MacBook Air 13" M3, apple,j613 / apple,t8122, 10-core GPU
  • asahi,os-fw-version: 14.7, asahi,system-fw-version: 27.0
  • Kernel: integration/aurora 80ee1e97, release recipe config, plus the series below. GPU: current14 with asahi.t8122_dpe_leak=1 (see M3 Air: qualify each shipped J613/J615 firmware profile separately #26). m1n1: stage 1 v1.6.1; the m1n1 in boot.bin is Aurora's d05ba17d plus two small changes (below); boot.bin carries the J613 DTB built from this series' DTS.
  • Hyprland 0.56.2, mesa-m3 26.1.4 (GPU rendering)
  • Monitors: Lenovo T34w-30 (USB-C with hub, 3440x1440@60), Lenovo M14 (USB-C, 1920x1080@60); with our development series also an LG 34" ultrawide (3440x1440@100)
  • Ports: left-back (ATC0, next to MagSafe) and left-front (ATC1)

What was missing or wrong

  1. No dcpext on T8122. The DT has no dcpext, DARTs, mailbox, or ATC display crossbars. m1n1 does not reserve the dcpext firmware on t8122: dt_set_display() returns from the t8122 branch before dt_reserve_dcpext_firmware().
  2. 14.7 only for handed-over processors. Aurora drives 14.7 firmware through its DCPLink session, for processors the boot loader hands over (internal panels, T6030 dcpext). The J613 dcpext is started by Linux and speaks the classic IOMFB protocol with 14.7 firmware, as in asahi-wip-7.2 + Enable t8122 external display support AsahiLinux/linux#607. Aurora had dropped the 14.7 template layouts.
  3. Link flaps every ~4 s. On T8122, the DPAV "open" call (group 4, cmd 6) before the first EDID read is never answered. The firmware drops the display about 50 ms later, retrains, and reports it again. Enable t8122 external display support AsahiLinux/linux#607 never sends that call; it reads the EDID with group 1, cmd 7 directly.
  4. First modeset hangs forever. The PMP request bits are record indices on T8122 (T8122 PMP: request bits are soc-device record indices, so the DISP/ANS requests (bits 7/17) reach PACC0/SCODEC #102). DISPEXT is never active, so the dcpext waits forever for its DISP_EXT DVFS vote.
  5. Switching ports could leave the new display dark. When a display is unplugged while one on the other port waits for the single dcpext pipeline, the fabric hands the pipeline over at once. The desktop's later power-off of the old display's CRTC then dropped the HPD of the new connection. Whether it worked depended on who was faster.

The series (12 patches)

Device tree:

  • t8122: dcpext, its DARTs and mailbox, and the ATC display crossbars (all disabled)
  • t8122-j613: dcpext wired to both USB-C ports (typec-routes route@0 left-back, route@1 left-front, connector port@3, crossbar state 2 = dispext1,0 on either ATC, DPTX target = ATC index as on M1/M2). Routes and node stay disabled in the DTB.

PMP:

Display gate:

  • Enable the T8122 dcpext after the panel handoff, only if m1n1 marked its firmware as reserved: node, its routes, <&dispext0_dart 0> appended to the display subsystem's iommus, active floor on dispext_cpu (as T6030), and the PMP DISPEXT request. apple_t8122_display.dcpext=0 keeps it off.

appledrm:

  • 14.7 IOMFB template layouts back, and a RAM page for bw-scratch in Dashboard mode (bw-scratch without bw-doorbell; the firmware's only write through the pmgr dashboard mapping is a 64-bit zero on power-off, which the DART rejects and which crashes the DCP).
  • New variant DCP_FIRMWARE_V_14_7_TEMPLATE for apple,t8122-dcpext only, driven through the classic IOMFB template (tables from asahi-wip-7.2), with AFK start polling (from Enable t8122 external display support AsahiLinux/linux#607). Every path that tests DCP_FIRMWARE_V_14_7 (DCPLink, T6030, the internal panel) is unchanged.
  • A failed dcpext never holds up the panel: probe/bind failures turn it into an unusable pipe, and its routes are disabled.
  • What the T8122 dcpext firmware needs: wait for the PMP DISPEXT ack before running its CPU (as T6030's dcpext_check_power()), no DPAV "open" call, and the Enable t8122 external display support AsahiLinux/linux#607 DPTX connect model (no validate, connect without supports-HPD, GET_SUPPORTS_HPD 0, HPD after the 2 s link-config wait, tiled hints acked with 0).
  • Type-C fabric (generic, small): a CRTC power-off after its display was unplugged leaves the next display's connection alone (problem 5); a display that has to wait for a pipeline is logged once with its port, e.g. display on USB-C Left-front waits for an external display pipeline: ….

RTKit:

m1n1 (two small changes, described here for Aurora's m1n1):

  • on t8122, call dt_reserve_dcpext_firmware() after the display handoff;
  • on t8122, leave dcpext disabled and set apple,t8122-dcpext-firmware-ready = <1> once its firmware is reserved. Enabling it in m1n1, as on t8112, breaks the panel for any kernel that cannot drive a T8122 dcpext. The kernel gate enables it instead.

With the new boot.bin and a stock kernel nothing changes: the dcpext stays disabled. With the new kernel and an old boot.bin (no marker), the gate leaves it disabled.

Results

Same machine, PMP running, GPU on, this series as the daily kernel since 2026-10-13.

Action Result
Rear port alone (T34w-30 3440x1440@60; earlier LG 3440x1440@100) pass
Front port alone (Lenovo M14 1920x1080@60) pass
GPU at the same time (GL/Vulkan desktop) pass
Internal panel pass
Second display on the other port waits (one dcpext pipe), log line names the port; that port's xhci comes back up cleanly (USB devices behind it not checked)
Unplug the active display → the waiting one takes over, rear → front and front → rear pass, 2 rounds each, picture after ~2.5 s, no replug
Unplug/replug pass
DPMS off/on pass with earlier builds of this series and the development series; not repeated with this exact build
Lid closed with one external display (desktop moves, no suspend) pass
Logs over these tests no RemotePort timeouts, link faults or xhci errors

The EDID is read (the desktop shows the monitor's name).

What is not tested

In progress: two external displays with the lid closed, the second one on the internal pipe (as macOS does it). A feasibility build shows both pictures; a clean version will be a separate report.

Parts of the series are ports from AsahiLinux#607 (by a-ramses), AsahiLinux#608 (by sofus13) and asahi-wip-7.2: the dcpext DT nodes, the 14.7 template tables, AFK polling and sync-syslog-ack. The commits say so. The series is available as a branch (GehrmannSolutions/linux-aurora, tars/aurora-j613-dp-v2), or as patches or a PR, whichever is easier to review.

Disclosure: the analysis, the patches and this text were made together with Claude Code (Anthropic). The tests were run on real hardware (the MacBook Air above), and the results were checked there.

Activity

  1. chriskearney commented on Oct 13, 2026

    @chriskearney

    Thank you, this is excellent work, and the PMP record finding in #102 is a real fix. I've reviewed the series and carried it, with fixes, as draft #114 (branch review/j613-external-dp on integration/aurora). Your authorship and sign-offs are kept, and each commit has a line saying what changed.

    Changes from review:

    • Shared code is gated to the T8122 dcpext.
      • The bandwidth-scratch RAM page is now built only into the 14.7 template. The 13.5 path of the M2 and M1/M2 Pro/Max Macs had compiled it in.
      • The CRTC power-off change after an unplug now runs only for the T8122 dcpext (ext_failsafe). As posted, it also changed M1/M2 and M3 Pro Type-C handling.
    • The device tree no longer turns anything on without the boot loader's marker.
      • On J613, the two dcpext DARTs, the mailbox and the ATC display crossbars stay disabled, and the ATC common power states are no longer always-on in the DTB.
      • The display gate enables all of them in its one changeset, and only when apple,t8122-dcpext-firmware-ready is present.
      • If the boot loader already enabled any of them, the gate leaves the dcpext off.
    • Credit and wording: the Enable t8122 external display support AsahiLinux/linux#607 ports carry Co-developed-by:/Signed-off-by: for its author, the comments and messages are reworded to our house style, and the session trailers are dropped.

    Local results:

    • the build is clean, with no new warnings in touched files;
    • only the T8122 DTBs change, and only by disabled or inert nodes;
    • the display KUnit suite matches the base, and the new pmp_records_t8122 passes.

    Before merging, could you boot this exact branch on your J613?

    1. With your boot.bin, the one with the marker: external display on each port, unplug and replug, the takeover between ports, the internal panel and the GPU. The enabling now happens in the kernel gate, so this is the new path. Does your m1n1 change leave the DARTs, mailbox and crossbars disabled, as the gate now expects?
    2. With a boot.bin without the marker (Aurora's current one): internal panel, GPU, and one suspend/resume. This checks the PMP request change (commit 1) on its own, since it applies to every J613 on the 14.x path.

    Your m1n1 changes go to our m1n1 fork as a separate PR; the kernel side stays off until that lands.

  2. GehrmannSolutions commented on Oct 14, 2026

    @GehrmannSolutions
    Author

    Thanks a lot for carrying the series! We'll do both test boots on the J613 and report back here.

    One question before I open the m1n1 PR: omacom/m1n1 has the AGENTS.md inherited from Asahi, which says the maintainers forbid any use of AI/LLM tools. Our m1n1 change (two small commits in kboot.c: reserve the dcpext ASC firmware on t8122 after the display handoff, then leave the node disabled and set apple,t8122-dcpext-firmware-ready) was written with Claude Code, like the rest of this series. Does that rule apply to your fork? If not, I'll open the PR with the same AI disclosure as here. If it does, I can describe the exact behaviour instead, so one of you can write it.

    (Written with Claude Code, reviewed by me.)

  3. GehrmannSolutions commented on Oct 14, 2026

    @GehrmannSolutions
    Author

    Both test boots of #114 are done on the J613 (M3 Air 13", macOS 14.7 firmware). Kernel: review/j613-external-dp at a372a728e exactly (tree cc8a906d), built with our usual config. Both boot.bins carry the DTBs built from that branch and the same chosen.asahi,t8122-* options. All checks passed.

    1. With our boot.bin (m1n1 sets the marker)

    • Gate: enabled /soc/dcp@31ac00000 with its Type-C routes, DARTs, mailbox, 2 display crossbar(s) with ATC common power kept on, display DART /soc/iommu@319304000 in the display subsystem, CPU power floor and PMP DISPEXT request. PMP request 0x21800 (records 0x1800), acknowledged.
    • Your question: yes, our m1n1 leaves them all disabled. I compared /sys/firmware/fdt with the branch's t8122-j613.dtb. m1n1 changes the status of the GPU, its mailbox, the uat-* reserved memory, the framebuffer and one NVRAM partition, and adds the marker to the dcpext node. The dcpext node, both dcpext DARTs (319304000, 31930c000), the mailbox (31ac08000) and both crossbars (70304c000, b0304c000) are still disabled in the handed-over FDT. atc0_common/atc1_common have no apple,always-on in the DTB or after m1n1, and have it at runtime, from the gate's changeset.
    • External displays: a 3440x1440 monitor on the left-back port and a 1080p portable on the left-front port.
      • Each port alone: picture, also after unplug and replug, several times. ✅
      • Second display while the first one runs: it stays dark, the kernel logs display on USB-C Left-front waits for an external display pipeline … (and Left-back the other way round). ✅
      • Takeover: unplugging the active display gives the waiting one a picture on its own, in both directions. ✅
    • Internal panel: fine throughout. ✅
    • GPU: Hyprland renders through zink on Honeykrisp (Apple M3 (G15G C0)), firmware running, jobs complete, no faults. ✅
    • Also one s2idle suspend/resume with the lid open and the external display connected: both pictures back after about 5 s. ✅

    2. With Aurora's boot.bin (packaged m1n1-aurora 1.6.1.aurora17-5, no marker)

    • Gate: /soc/dcp@31ac00000 left disabled: the boot loader did not reserve its firmware. The external display stays dark, as expected. ✅
    • PMP (commit 1): request bits 0x800 are soc-device records, request 0x20800, PMP ready: PTD status 0x1 request 0x20800 ack 0x208f0, then PMP running with the display request acknowledged for the panel DCP and PMP GPU device 5 power acknowledged. ✅
    • Internal panel ✅, GPU (first compute and render jobs complete) ✅, one s2idle suspend/resume, panel back at once ✅.

    Only side note: every lid-open s2idle logs a few Bluetooth: hci0: command 0x0c01 tx timeout at suspend entry. That happens with our older kernel too, so it is not from this branch.

    (Tests run by TARS, my Claude Code agent, with me plugging the displays; written with Claude Code, reviewed by me.)

  4. GehrmannSolutions commented on Oct 14, 2026

    @GehrmannSolutions
    Author

    Two small things while #114 is still a draft:

    1. The wait message in the last commit is wrong about replugging. It says:

    display on USB-C Left-front waits for an external display pipeline: it drives another display; to switch, unplug that one, then plug this one in again
    

    No replug is needed. In test 1 the waiting display came up by itself both times the active one was unplugged, in both directions (front → rear and rear → front), a few seconds after the unplug. That matches the code: the fabric hands the pipeline to the waiting port when the other display goes. A wording that fits:

    display on USB-C Left-front waits for an external display pipeline: it drives another display; unplug that one and this one takes over
    

    2. Heads-up on a follow-up: lid closed with two external displays. We have a working set for that (one display on dcpext, the second on the internal pipe while the lid is closed, as macOS does). It is experimental and runs on this J613 every day now. It would touch #114's ground in two places:

    • Device tree: a (disabled) Type-C route from the internal DCP to the left-front port, so that port's connector gets a second endpoint.
    • Gate: turning that route on in the same changeset as dcpext.

    We'll rebuild the set on top of #114 in its style (described but disabled in the DT, turned on only by the gate, behind the marker) and offer it only once #114 has landed. Nothing in #114 needs to change for it. Mentioning it now in case it matters for how you settle the gate.

    (Written with Claude Code, reviewed by me.)

  5. chriskearney commented on Oct 15, 2026

    @chriskearney

    Thanks for both test boots, @GehrmannSolutions. #114 is merged into integration/aurora as aca27422, with your exact tested commits and four review fixes on top:

    • Display gate: no dcpext without a display driver (nomodeset or not built), so USB on both ports can't hang waiting for a mode switch. It also refuses without a usable PMP DISPEXT request, as T6030 does.
    • Probe: waits until every route's PHY and crossbar is there, so a late second route can't disable the dcpext for the boot. A crash report from a dcpext that was given up no longer hits an uninitialised completion.
    • rtkit: the kdebug buffer is capped at 4 MiB, and the polled waits take a completion that arrives at the deadline.
    • Wait message: now uses your wording. The display lights up on its own when another one is unplugged, and the line is logged only with the display's HPD up.

    The boot loader half isn't merged yet, so this issue stays open. Your lid-closed dual-display set can go on top of this as a new PR whenever it's ready.

  6. GehrmannSolutions commented on Oct 15, 2026

    @GehrmannSolutions
    Author

    The lid-closed dual-display set is up as #127, on top of the merged #114 (integration/aurora 54f78d6). It needs the same boot-loader marker as #114, so it depends on the m1n1 half here too.

    (Written with TARS, my Claude Code agent.)

  7. tonibergholm commented on Oct 19, 2026

    @tonibergholm

    AI-assisted native report (Codex); visual checks and Touch ID unlock were confirmed by the machine owner.

    Additional J613/T8122, OS firmware 14.7 / system firmware 27.0 result with an ARZOPA Z1FC, direct USB-C cable. Running 7.1.12-2-20261017.20-sep-ARCH, source c46d7dcdb8712ea9aeb0ce47b439ffae76371e55; installed kernel package remains .19 because this is an isolated .20 test boot/module tree. The machine also retains local brightness/camera modules and DT CPU thermal controls; GPU uses the existing legacy Mesa profile. m1n1 package is 1.6.1.aurora17-5, source d05ba17d.

    The packaged bootloader correctly left dcpext disabled (the boot loader did not reserve its firmware). For a one-boot local trial, I rebuilt that m1n1 source with the reservation/disabled-node-marker approach described here, additionally restricted to J613/T8122, OS 14.7 and an existing internal handoff marker. The exact DTB/U-Boot/config payload tail was preserved. No stage1, firmware/calibration contents, kernel sleep guard or GPU clock limit was changed. Reference/candidate builds and seven actual-helper/libfdt controls passed; those controls mock firmware outcomes and do not qualify boot by themselves. Local compiler was GCC 16.1.1.

    Native results:

    Check Result
    Cold-plug boot on rear port (nearest MagSafe) Both internal panel and Z1FC correct; external 1920×1080/60 Hz
    PMP/DCPEXT admission Firmware-ready marker=1; kernel enables dcpext/routes; request 0x21800, ack 0x218f0
    1080p144 runtime mode 20-second test, compositor reported 144 Hz, owner confirmed clear/stable picture; automatically restored 60 Hz
    Rear-port unplug/replug Picture recovered correctly
    Move to front/trackpad-side port Picture correct at 1080p60; sysfs port2, DRM DP-2 on this machine
    DPMS off/on Both reported off, then on; both pictures recovered correctly
    GPU checks OpenGL red/blue and Vulkan compute passed with both displays, after hotplug/front-port move/DPMS, and after suspend
    Normal s2idle with front-port display attached Success counter 0→1, fail=0; both pictures returned and Touch ID unlocked

    The suspend was short: journal entry-to-exit wall time 14.591379 s, monotonic delta 4.551598 s, hence approximately 10.039781 s clock-suspended. This is not longer-sleep acceptance or a residency/energy measurement.

    I initially predicted refusal after reading the T6030 guard, then corrected that interpretation against the native result and probe assignment: .20 sets external only for apple,t6030-dcpext; J613 uses apple,t8122-dcpext / ext_failsafe, so that guard does not apply. No guard was removed or bypassed for the test.

    The existing internal-DCP copy_edid failed: -ENODEV warning repeated during display transitions; no external-DCP timeout/fault was captured in the selected hotplug/mode windows. This is not a completely clean-journal claim.

    All six CPU zones retained both-cluster cooling bindings and 58/95/110°C trips. The original thermal-enabled stage2 was hash-verified and restored on disk automatically 90 seconds after boot, without changing the running trial. Root and ESP backups remain; no persistent candidate or new display config was retained on disk.

    Still unqualified: repeated boots, longer/repeated external-display sleep, sustained 144 Hz, clamshell/two-display use, DP audio, docks/HDMI/MST and power draw. This report is only this J613/14.7 + named monitor.

    Selected native evidence and local build scope. The local reservation candidate derives from the approach reported by GehrmannSolutions in this issue; this does not claim a new general display implementation or upstream bootloader merge.

    20 October: unplugged boot, longer-mode limits and corrected thermal tail

    Same J613 / OS 14.7 / system 27.0 / Aurora .20 scope. A refreshed stage2 uses the same gated local m1n1 prefix with the corrected package-managed thermal DTB tail. This fixes a local overlay-extraction sensor-order bug, not a change to the upstream DT proposal. Exact candidate SHA256 ff1cc419f93244f27612a20b33b5fde22fbc1850771f487f8898279b60d24c53.

    • Boot with ARZOPA disconnected, then rear-port hotplug: both pictures correct at 1080p60; OpenGL/Vulkan readbacks pass. Firmware-ready marker=1, DCPEXT okay, six exact thermal sensor indices/trips/bindings retained. The 90-second rollback restored verified package baseline 2f4037b0...; Omarchy update verification passed.
    • Three-second DPMS off/on: both outputs off in all twelve samples, then both pictures correct; GPU checks pass.
    • One normal rear-port attached-display s2idle cycle, lid open: success 0→1, fail=0, 20.656675 seconds clock-suspended by BOOTTIME-minus-MONOTONIC delta. Both pictures correct and Touch ID unlocked; GPU readbacks, brightness 265/77 and all six thermal zones/cooling bindings recovered. No guard bypass.

    144 Hz remains unqualified beyond short intervals. An earlier 20 October trial unexpectedly lost the external display after 25.35 seconds at 144 Hz with the cable untouched (sampled temperature peak 61.265 C; no temperature-guard stop). Replug left DRM connected but Hyprland disabled; explicit disabled=false at 60 Hz restored the picture. This explains the recovery step, not the original dropout. A later visual run stayed clear for 200.77 seconds until the unchanged temperature guard restored 60 Hz. On the corrected-tail candidate, one 10-second 144 Hz interval and return to 60 Hz succeeded; the guard cancelled the remaining planned mode cycles at 14.995 seconds, during the 60 Hz dwell (aggregate 77.015 C). No guard was relaxed to finish a test.

    Type-C sysfs port numbering changed across boots. The earlier port2/front-port correspondence is specific to that boot, not a persistent physical mapping; there is no established power-loss diagnosis for the dropout.

    Corrected boot/hotplug/mode evidence, DPMS, attached sleep. The original dropout, repeated/long sleep, sustained 144 Hz, display audio/HDR and power draw remain unresolved/unqualified. AI-assisted tests/report with Codex; Toni confirmed pictures and Touch ID.

  8. GehrmannSolutions commented on Nov 2, 2026

    @GehrmannSolutions
    Author

    DP/HDMI audio on the J613, for the "still unqualified" list: no sound so far.

    Setup: J613 (OS firmware 14.7), our daily kernel (Aurora release 20 + #127, #135, #146 and the J613 brightness patch), a TV behind a USB-C DisplayPort-to-HDMI adapter (ITE "DP2HDMI") on the dcpext port.

    • Picture: works.
    • Sound: there is no output to pick. ALSA lists only the internal card (AppleJ613), and PipeWire offers only the speakers and headphones.

    Why, as far as I can see:

    Going by the T6030 layout, I'd expect the T8122 SIO at 0x2a1c00000 and its mailbox at 0x2a1c08000 (IRQs 798-801). On both SoCs, admac sits 0x21fc000 after sio_dart, and its IRQ is 13 below the DART's. That is an inference, not checked against the ADT. If anyone has the J613 ADT values for /arm-io/sio and the dp-audio channels, that would settle it. We'd like to try it once we're on the 7.2 base.

    (Written with TARS, my Claude Code agent; tested by me on the machine.)

  9. ericjuta commented on Nov 4, 2026

    @ericjuta

    J615 (MacBook Air 15" M3): external DisplayPort over USB-C works, with two changes

    The J613 series from #103/#114 also drives an external display on the J615 (apple,j615 / apple,t8122, OS firmware 14.7), but only with two extra changes. Without them, enabling dcpext reproduces the internal-panel crash from omacom/m1n1#14 on this board.

    Machine

    • MacBook Air 15" M3 (J615), asahi,os-fw-version 14.7, FileVault-style LUKS root
    • Kernel: integration/aurora b798f2b0 + the commits below (7.2.11). m1n1-aurora 1.6.1.aurora22 with chosen.asahi,t8122-dcpext=1
    • Hyprland, Samsung C49G95T (Odyssey G9 / CRG9 class, 5120x1440), direct USB-C to DP cable, left-back port

    What I found

    1. The m1n1 reservation alone is harmless. With the reservation and marker published but apple_t8122_display.dcpext=0, the internal panel works, with no DART faults. (This is the boot m1n1#14 asked for.)
    2. The crash comes from adding dispext0_dart to the display subsystem's iommus. With the gate's full changeset, the internal DCP's DART faults about 2 s into boot (120× apple-dart 28d304000.iommu: translation fault … NO PMD/PTE FOR IOVA at 0x1000a000000..0x1000ad2a300), then RTKit: co-processor has crashed and the panel goes dark. Skipping only that step (new switch apple_t8122_display.dcpext_disp_dart=0) keeps the panel up with dcpext, routes, DARTs, mailbox, crossbars and the PMP DISPEXT request enabled.
    3. Without that DART in the shared domain, the dcpext can't read framebuffers. The modeset completes (5120x1440@120), then 319304000.iommu faults at the framebuffer DVAs (0x10fea000000…) and the dcpext crashes. Fixed by an fbdma child of the dcpext (dispext0_dart stream 0, with the display subsystem's DVA window). appledrm mirrors each swapped framebuffer into its domain, read-only, at the same DVA. GPU-imported buffers must use obj->sgt: drm_gem_dma_get_sg_table() gives bogus pages for them and the map trips io-pgtable-dart.c:241.

    Commits (branch j615/external-dp)

    • soc: apple: t8122 display gate: dcpext_disp_dart switch
    • drm: apple: dcp: mirror framebuffers into the T8122 dcpext fbdma domain
    • arm64: dts: apple: t8122-j615: external display over USB-C (dcpext): the J613 routes block, same Type-C wiring (usb-pd@c Left-back/ATC0, usb-pd@a Left-front/ATC1), plus fbdma
    • PR drm/apple: enable J615 panel brightness control #354 (J615 brightness), carried so the panel keeps its backlight

    Results

    Check Result
    Internal panel, GPU desktop pass
    Left-back, C49G95T at 5120x1440@120 (also 2560x1440@60 during takeover) pass, EDID name shown, stable picture
    Translation faults or DCP crashes during the session 0
    Pipeline takeover: a hub on left-front held the pipe at boot; unplugging it handed the pipe to left-back pass, no replug
    Left-front with the monitor (one early attempt) HPD timeouts (group 8 cmd 8 … -110), link faults 22/24; not retried
    Backlight (apple-panel-bl) with #354 pass

    Not tested yet

    Suspend/resume with the display attached, repeated unplug/replug, left-front port, other monitors, MST/docks/HDMI adapters, DP audio.

    Open question

    Why does the shared display-subsystem domain fault the internal DART on J615, when it works on J613? My guess is that the window intersection with dispext0_dart (apple,dma-range 0..0xfffff0000) changes the internal domain's aperture or level count. I haven't checked that.

    Branch: https://github.com/ericjuta/linux-aurora/tree/j615/external-dp (on b798f2b0)

    Disclosure: the analysis, the patches and this text were made with an AI coding agent (Claude). The tests ran on real hardware (the J615 above), and I checked the picture.

  10. ericjuta commented on Nov 4, 2026

    @ericjuta

    Follow-up from the same J615 boot (j615/external-dp, C49G95T on left-back, 5120x1440@120):

    Check Result
    Unplug/replug, twice pass, picture back each time (link, EDID, modeset)
    s2idle suspend/resume with the display attached, lid open pass, 14 s asleep, display back about 5 s after resume
    Lid closed with the external display (desktop moves, no suspend) pass
    DART translation faults / DCP crashes over all of this 0

    Not covered: the left-front port with the monitor (every link this boot used DPTX PHY 0), longer sleeps, docks/HDMI/MST, DP audio.

    (AI-assisted, checked by me on the machine.)

  11. ericjuta commented on Nov 4, 2026

    @ericjuta

    Left-front port, same boot: pass. C49G95T on DP-2 at 5120x1440@120, framebuffers mirrored, 0 faults, internal panel up beside it. Both USB-C ports drive the external display on the J615 (one at a time).

    (AI-assisted, checked by me.)

  12. ericjuta commented on Nov 4, 2026

    @ericjuta

    Added drm: apple: dcp-fabric: give an idle port's pipeline to a waiting display to j615/external-dp.

    A USB-C hub with a DP output (Genesys 05e3:0610/0626) enters DP alt mode with nothing plugged into it and takes the only external pipeline. A monitor on the other port then waits until the hub is unplugged. With this commit, a port whose display has HPD up takes the pipeline from a port whose sink never asserted HPD and has no display connected:

    allocated Type-C DPTX PHY 0                       # hub, left-back
    external display pipeline moves from USB-C Left-back (no display) to the display on USB-C Left-front
    allocated Type-C DPTX PHY 1
    dcp_hotplug() connected:1 … nr_modes:32           # C49G95T, 5120x1440@120
    

    The hub keeps USB working on its port, with 0 faults. Nothing changes when the pipeline holder has a display, for tunnels, or for ports in SAFE.

    (AI-assisted, tested by me on the J615.)

  13. ericjuta commented on Nov 4, 2026

    @ericjuta

    The J615 work is now up as two PRs on integration/aurora: #356 (J615 dcpext: gate switch, fbdma mirror, DTS) and #357 (idle-port pipeline handover, independent, also relevant to J613). J615 brightness stays in #354.

  14. GehrmannSolutions commented on Nov 12, 2026

    @GehrmannSolutions
    Author

    J613 on linux-aurora 7.2.11.aurora16-1 + m1n1-aurora 1.6.1.aurora23-2 (edge): external DisplayPort over USB-C works out of the box.

    For the qualification of omacom/omarchy-pkgs#2424 / #2425: the pin notes say the exact aurora16 tree was not lab-booted, so here is a real J613 boot. It's a MacBook Air 13" M3 on official Omarchy packages (migrated via omarchy-mac#690), switched with omarchy channel set edge, with no local patches and no boot args added.

    One unrelated line from the USB-C PD side while swapping: sn201202x 1-0a: cable revalidation failed after 3 attempts. I saw no effect from it.

    Disclosure: the analysis and this text were made with an AI coding agent (Claude Code). The tests ran on the real J613 and were checked by me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions