Repository navigation
drm/apple: 4K at 120 Hz on the M4 MacBook Air external displays - #1007
Merged
RyanTheTide merged 5 commits intoNov 6, 2026
Merged
Conversation
An external sink can list timings, such as 3840x2160 at 120 Hz, whose 8-bpc RGB SDR colour elements the timing marks as needing DSC (DSCRequiredColorElementIDs). The TimingElements walk treated those like the unsafe ones (UnsafeColorElementIDs), so such a timing was never offered. Tell the two lists apart in the parser, and offer a timing whose only 8-bpc RGB SDR colour element needs DSC. An element that needs DSC is considered only at 8 bpc, and the lowest depth still comes first, then an element that needs no DSC over one that does. The choice is unchanged for every timing whose lowest uncompressed depth is 8 bpc or less. A DSC mode is checked against the link at 8 bpp, the lowest DSC target; the firmware picks the compressed rate itself. A DSC mode is never marked preferred and never taken as the fallback: it is used only when userspace picks it. Signed-off-by: Erik Bourget <erik@ebourget.net>
…ailbox The external DCP firmware asks for a realtime bandwidth mailbox at pipe start (D003, rt_bandwidth_setup_ap) and writes its bandwidth requests there every frame. The M4 backend declined the service, so the pipe never requested the bandwidth it needs at high pixel rates such as 3840x2160 at 120 Hz. macOS answers D003 for a T8132 external pipe with the pipe's 8-byte bandwidth request slot in the PMC as the mailbox. The mailbox length (8) selects the scratch-only protocol, with no doorbell, which the firmware reaches through its display register window 4. Take the slot from the DT, through apple,bw-scratch as on the other DCPs: the provider's reg range, the firmware display register index (which must be 4) and an offset. The slot must lie inside the DCP's disp-4 window. Answer D003 with it, and decline as before without one, as on the internal panel, whose node has none. The firmware then maps its register windows with D411 (mapDeviceMemoryWithIndex). Answer it for every disp-N window the DT describes, with the physical address as the DVA, as the desktop 26.x backends do: the firmware reaches those windows on its DART-bypass stream. An index the DT does not describe is refused. Signed-off-by: Erik Bourget <erik@ebourget.net>
The T8132 external DCPs take apple,bw-scratch for their 8-byte realtime bandwidth request slot in the PMC. Unlike the other DCPs, where the scratch register becomes an extra display register window, the slot lies inside the window the display index names (disp-4). Say so in the property's description. Signed-off-by: Erik Bourget <erik@ebourget.net>
… slots Describe the external pipes' realtime bandwidth request slots in the PMC, 0x2c000 (dcpext0) and 0x30000 (dcpext1) into the window both DCPs have as disp-4, and point each dcpext at its slot with apple,bw-scratch (display register index 4), so that the driver can hand the slot to the firmware as its bandwidth mailbox. Signed-off-by: Erik Bourget <erik@ebourget.net>
The J713 external DCP completes a direct swap (D590) several milliseconds after its A407 reply, up to about 10 ms whatever the refresh rate. With one swap in flight and the flip event sent at D590, a frame takes that time plus the compositor's own, which holds a 120 Hz mode to about 60 frames a second. Let up to two direct swaps be outstanding, set by the module parameter t8132_ext_swap_depth (2 by default, 1 to send every flip at its D590 as before): - A replied direct swap moves from the session's swap state to an ordered queue (oldest first) with its window, link generation and 5 s deadline, so that the next A406/A407 can go out. A third frame while two are in flight gets -EBUSY; the copy path stays refused while any direct swap is in flight. - Flip events: a frame submitted with nothing older in flight gets its flip event at once (iomfb_m4_ext_present_direct() returns 1); one submitted behind another gets it when the older swap completes or is given up. At depth 2 a flip event can therefore come before the firmware confirms that the frame replaced the previous one, so a compositor may draw into a buffer that is still on screen. - Completions: a D590 completes the swap it names, with its displayed flag, and the earlier swaps in its head-of-line list, which macOS completes as displayed. A swap it does not name stays in flight until its own D590 or its give-up. The firmware completes swaps in order; a newer swap completing first is warned about. A swap completed through a later swap's D590 is remembered, so that its own late D590 is dropped, and A406 handing out such an ID again orphans the start, as for given-up swaps. - Screen state follows the D590s in arrival order, a D590 that comes before its swap's A407 reply included. With displayed = 1 the swap's window is the one on screen; with displayed = 0 nothing on screen is retired, on the direct, given-up, copy and blank paths alike. Windows of both swaps in flight, and of every given-up swap that may still show them, stay mapped. Every direct completion, and every give-up, leaves the copy surfaces stale. - The give-up work expires queued swaps one by one at their own deadline, or at once when the link goes; settle, sleep, suspend and hotplug wait for or drop the whole queue. - D581 (swap_complete_head_of_line) is logged and left to the D590 or the give-up. With the PMC's display bandwidth agents enabled (a separate change), a 3840x2160 120 Hz DSC mode runs at 120 frames a second at depth 2. Signed-off-by: Erik Bourget <erik@ebourget.net>
This was referenced Nov 6, 2026
Contributor
|
Merge train (MTR, 06/11): merging, with notes. Review: all of it runs only under Notes for follow-up:
Gates: test merge 2d3579ef = integration/aurora 11eccbe + #1005 #994 #930 #658 #992 #1006 #1007 #1008 #531 (#992 has since landed on its own); base 11eccbe.
Hardware (7.3.0-aurora-mtr1106a, one-shot boots, fleet recipe):
|
This was referenced Nov 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follows #957. It makes high-refresh modes usable on the M4 MacBook Air's external DCPs:
DSCRequiredColorElementIDs) was dropped along with the unsafe ones; the parser now tells the two lists apart. For a typical 4K monitor that means 3840x2160 at 120 Hz and 2560x1440 at 240 Hz.apple,bw-scratch, and must lie inside the DCP'sdisp-4window.disp-Nwindow the DT describes is answered with its physical address, as on the desktop 26.x backends; any other index is refused.t8132_ext_swap_depth, default 2; 1 restores flip-at-D590). D590's displayed flag and its head-of-line completions decide what is on screen, and every buffer that is on screen or in flight stays mapped.DT: a binding note for the T8132 dcpext bandwidth slot, and the J713's two slots plus
apple,bw-scratchon dcpext0 and dcpext1.Full-rate 4K120 also needs the PMC interface enables (#1006, pmdomain). Without them the pipe's display clock isn't boosted, and only the first lines of each frame show. With DSC, 4K120 fits an HBR2 x4 link, so it also runs next to a second 4K60 monitor on one dock.
Testing:
KUnit (drm/apple suites): 384 tests, 382 passed, 2 skipped.
make dt_binding_check(apple,dcp.yaml) anddtbs_check(t8132-j713): no new messages.scripts/checkpatch.pl --strict: clean on all five commits; each commit builds on its own.J713 with a CalDigit TS5 dock and two MSI MPG 322U X24 monitors, with the PMC PR (pmdomain: apple: pmc: enable the M4 external display boost, for 4K at 120 Hz #1006):
This was developed and tested by Claude (Anthropic), working with me on the J713.