Repository navigation
pmdomain: apple: pmc: enable the M4 external display boost, for 4K at 120 Hz - #1006
Merged
RyanTheTide merged 3 commits intoNov 6, 2026
Merged
Conversation
On T8132 a display pipe votes for memory bandwidth and for a faster display clock through two PMC interfaces: bandwidth request (BWR) and boost. Each interface has an enable word with one bit per agent, and the PMC ignores the votes of a pipe whose bits are clear. macOS sets a pipe's two bits when the pipe's SYS power state powers on, and clears them before it powers off. Describe such a pair of bits as an interface-* child node of the PMC, provided as a power domain whose parent is the power state the enables need. The bits are set after the parent powers on and cleared before it powers off. Only the T8132 PMC has these words, so other PMCs may not have interface nodes. Signed-off-by: Erik Bourget <erik@ebourget.net>
… domains The T8132 PMC ignores an external display pipe's bandwidth and boost votes until the pipe's bits are set in the BWR and boost interface enable words. With them clear, the pipe's display clock stays at its lowest state, and a 4K mode at 120 Hz shows only the first lines of each frame. macOS sets the bits when the pipe's SYS power state powers on, and clears them before it powers off. Add the offsets of the two enable words in the "rails" region to the per-SoC layout: 0x2020 and 0x2028 on T8132, and 0 elsewhere, where an interface node is rejected. Provide each interface-* child node as a power domain that joins its parent domain like the cluster domains do. Power on sets the pipe's boost bit and then its BWR bit, and power off clears them, each with a read-modify-write under the PMC lock that is read back. If the BWR word does not take the change, the boost bit gets back the value it had before, and the call fails with -EIO. A bit claimed by two domains is rejected. The domain is IRQ safe: the PMGR power states that depend on it are, and genpd refuses an IRQ-safe subdomain under a parent that is not. The callbacks only take the PMC's raw spinlock and access MMIO. Like a voter domain, an interface domain starts from the hardware state: it is on if both of its bits are already set. With only one bit set it starts off and that bit is left alone until the domain powers on, which sets the other one; a failed power on keeps it as well. So the driver never drops a vote the boot loader left before the pipe powers off. When the PMC goes away, the domains' bits get back their values at probe, as the rail enables do. System sleep needs nothing extra: genpd powers the domain off and on with the domains that depend on it, and the words, like the rail enables, are not saved and restored. Show both words in the debugfs status, and add KUnit cases for setting and clearing a pipe's bits next to the internal display's boost bit, for a BWR word that does not take the change, for the boot states, and for the domain linked between IRQ-safe SYS and FE power states the way the PMGR driver links them, powered through a device on FE. Signed-off-by: Erik Bourget <erik@ebourget.net>
The PMC ignores the bandwidth and boost votes of an external display pipe until the pipe's BWR and boost interface enables are set, so the pipe's display clock stays at its lowest state and a 4K mode at 120 Hz shows only the first lines of each frame. Describe the enables of dispext0 (BWR bit 3, boost bit 1) and dispext1 (BWR bit 4, boost bit 2) under the PMC, each with the pipe's SYS power state as its parent. On the J713, where the PMC is enabled, make each pipe's FE power state depend on them as well as on SYS. genpd then powers on SYS, the enables and FE in that order, and powers them off in reverse, so the enables are only set while SYS is on. The other T8132 boards keep the PMC disabled, so the dependency lives in the J713 DT and not in t8132-pmgr.dtsi, where it would hold their FE power states back for good. The legacy-loader adapter copies the t8132-memory.dtsi nodes, phandles included, into a loader tree that lacks them. The interface nodes' parents do not resolve there, and the loader's PMGR states do not use the nodes, so drop them from the adapter's data. Signed-off-by: Erik Bourget <erik@ebourget.net>
This was referenced Nov 6, 2026
Contributor
|
Merge train (MTR, 06/11): merging. An independent adversarial review found it strictly T8132-gated: interface nodes need 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.
On the M4 (T8132) the PMC ignores an external display pipe's bandwidth-request (BWR) and boost votes until the pipe's bits are set in two interface enable words. With them clear, the pipe's display clock stays at its lowest performance state. Everything up to about 772 Mpixel/s works, but a 3840x2160 120 Hz mode (1188 MHz) shows only the first lines of each frame and the rest stays dark. macOS sets the bits when the pipe's SYS power state powers on and clears them before it powers off. This PR does the same, through genpd.
interface-*child node of the PMC, provided as a power domain, withpower-domains(the power state the enables need),apple,bwr-bitandapple,boost-bit. Only the T8132 PMC may have them.t8132-memory.dtsi, each with its pipe's SYS power state as parent.Together with the drm/apple realtime bandwidth and DSC PR (#1007), this makes 3840x2160 at 120 Hz work on an external monitor through a Thunderbolt dock.
Not done here: macOS also sets a third enable (DVMR) and tells the PMP the pipe's power state. Neither was needed for the result above.
Testing:
KUnit (
apple-pmcsuite, arm64): 13/13, including bit setting and clearing next to the internal display's boost bit, a word that doesn't take the change, the boot states, and the domain linked between IRQ-safe SYS and FE power states, powered through a device on FE.make dt_binding_check(apple,pmc.yaml) anddtbs_checkfor every T8132 board: no new messages.scripts/checkpatch.pl --strict: clean on all three commits.J713 with a CalDigit TS5 dock and two 3840x2160 monitors, with the drm/apple PR (drm/apple: 4K at 120 Hz on the M4 MacBook Air external displays #1007):
This was developed and tested by Claude (Anthropic), working with me on the J713.