From 229652c6ab0f690e308dece7176de52809ef11a8 Mon Sep 17 00:00:00 2001 From: Ryan Murray Date: Wed, 28 Oct 2026 14:52:45 +1100 Subject: [PATCH 1/3] drm/asahi: m3: drop the unused T8122 HwDataA switch t8122_hwdata.rs described the +0x418c block as written "unless asahi.t8122_hwdata_418c=0" and carried a parser and on/off values for that parameter. No module parameter was ever registered and nothing calls the parser, so the switch exists only on paper, and Aurora selects behaviour from the chip and firmware identity, not from command line switches. Remove the parameter values, parse(), enabled() and their test, and say that the identity selects the block as it selects the rest of HwDataA. The words, the offset, write() and its tests are unchanged, so the host tests still check the data Satya Benson recorded. Assisted-by: LLM Signed-off-by: Ryan Murray Co-Authored-By: Claude Opus 5.5 --- drivers/gpu/drm/asahi/m3/t8122_hwdata.rs | 37 ++---------------------- 1 file changed, 3 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/asahi/m3/t8122_hwdata.rs b/drivers/gpu/drm/asahi/m3/t8122_hwdata.rs index a86ec5e646037..841063767da9c 100644 --- a/drivers/gpu/drm/asahi/m3/t8122_hwdata.rs +++ b/drivers/gpu/drm/asahi/m3/t8122_hwdata.rs @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-2.0-only OR MIT //! The 20-word block at HwDataA +0x418c..+0x41db that the runtime backend writes on a T8122 -//! with the G15 14.8.3 firmware, unless `asahi.t8122_hwdata_418c=0`. Plain data only, so that -//! the host tests run it (tools/asahi). +//! with the G15 14.8.3 firmware. The chip and firmware identity select it, as they select the +//! rest of HwDataA; there is no switch to leave it out. Plain data only, so that the host tests +//! run it (tools/asahi). //! //! The words are not in the device tree, and what they mean is not known. They have been //! tested on 10-core and 8-core J613s only; J615 on this firmware is untested. @@ -31,28 +32,8 @@ pub(crate) const WORDS: [u32; 20] = [ /// Size of the block in bytes. pub(crate) const SIZE: usize = WORDS.len() * 4; -/// `asahi.t8122_hwdata_418c` values: 0 leaves the range as the builder made it (zero), 1 writes -/// the block. The default is 1. -pub(crate) const OFF: u64 = 0; -pub(crate) const ON: u64 = 1; -pub(crate) const DEFAULT: u64 = ON; - const _: () = assert!(SIZE == 0x50 && OFFSET % 4 == 0); -/// Parse `asahi.t8122_hwdata_418c`: `0` or `1`. Anything else is refused. -pub(crate) fn parse(text: &str) -> Option { - match text.trim() { - "0" => Some(OFF), - "1" => Some(ON), - _ => None, - } -} - -/// Whether a parameter value asks for the block. -pub(crate) fn enabled(value: u64) -> bool { - value == ON -} - /// Write the block into `hwdata_a`, the bytes of HwDataA. Nothing outside /// `OFFSET..OFFSET + SIZE` changes. Err, with nothing written, when `hwdata_a` is too short. pub(crate) fn write(hwdata_a: &mut [u8]) -> Result<(), ()> { @@ -112,16 +93,4 @@ mod tests { let mut exact = vec![0u8; OFFSET + SIZE]; assert_eq!(write(&mut exact), Ok(())); } - - #[test] - fn the_parameter_accepts_0_and_1_only_and_defaults_to_1() { - assert_eq!(parse("0"), Some(OFF)); - assert_eq!(parse("1"), Some(ON)); - assert_eq!(parse(" 1\n"), Some(ON)); - for text in ["", "2", "-1", "+1", "0x1", "on", "yes", "01"] { - assert_eq!(parse(text), None, "{text:?}"); - } - assert!(enabled(DEFAULT)); - assert!(!enabled(OFF)); - } } From f5a04f7e0304ef25e87ba2d3101fe04173a4c551 Mon Sep 17 00:00:00 2001 From: Ryan Murray Date: Wed, 28 Oct 2026 14:39:32 +1100 Subject: [PATCH 2/3] soc: apple: rename the T6030 display gate to the Apple display gate The gate already serves T6030, T6031 and T8122 through struct gate_soc, so it is no longer a T6030 driver. Rename the file to display-gate.c, the object to apple-display-gate and the option to APPLE_DISPLAY_GATE, so the other SoCs' internal display handoffs can join it instead of growing a driver each. No functional change: the gate, its SoC table, its command line options and its KUnit test are unchanged. The driver was written by Chris Kearney; this only moves it. Assisted-by: LLM Signed-off-by: Ryan Murray Co-Authored-By: Claude Opus 5.5 --- drivers/pmdomain/apple/Kconfig | 2 +- drivers/soc/apple/Kconfig | 8 ++++---- drivers/soc/apple/Makefile | 10 +++++----- .../{t6030-display-gate-test.c => display-gate-test.c} | 2 +- .../soc/apple/{t6030-display-gate.c => display-gate.c} | 6 +++--- tools/asahi/t6030-pmp-supplier-tests.py | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) rename drivers/soc/apple/{t6030-display-gate-test.c => display-gate-test.c} (99%) rename drivers/soc/apple/{t6030-display-gate.c => display-gate.c} (99%) diff --git a/drivers/pmdomain/apple/Kconfig b/drivers/pmdomain/apple/Kconfig index 5f0a9d95c196c..e25dd30281fc4 100644 --- a/drivers/pmdomain/apple/Kconfig +++ b/drivers/pmdomain/apple/Kconfig @@ -39,7 +39,7 @@ config APPLE_PMP_REPORT On T8122 (M3), T6031 (M3 Max), and opted-in T6030 (M3 Pro) Macs whose boot loader hands the - internal display over (see APPLE_T6030_DISPLAY_GATE), iBoot leaves + internal display over (see APPLE_DISPLAY_GATE), iBoot leaves the PMP halted, and this driver starts it when the display driver first asks for it. Once its nodes are enabled the PMP may run until the next reboot. That holds when the start then fails, too (the PMP diff --git a/drivers/soc/apple/Kconfig b/drivers/soc/apple/Kconfig index cbd8a0f0d430a..c06d4b38e9238 100644 --- a/drivers/soc/apple/Kconfig +++ b/drivers/soc/apple/Kconfig @@ -229,8 +229,8 @@ config APPLE_CLPC Say 'y' or 'm' here if you have an Apple SoC with a PMC. -config APPLE_T6030_DISPLAY_GATE - bool "Apple T6030 internal display enable gate" +config APPLE_DISPLAY_GATE + bool "Apple internal display enable gate" depends on ARCH_APPLE && OF_DYNAMIC && OF_OVERLAY default ARCH_APPLE help @@ -278,7 +278,7 @@ config APPLE_T6041_DISPLAY_GATE config APPLE_T6030_GPU_PMP_LINK bool - depends on APPLE_T6030_DISPLAY_GATE + depends on APPLE_DISPLAY_GATE default n help Link an opted-in T6030 GPU to the PMP admitted by the display gate. @@ -287,7 +287,7 @@ config APPLE_T6030_GPU_PMP_LINK config APPLE_DISPLAY_GATE_KUNIT_TEST bool "KUnit tests for the Apple display gate" if !KUNIT_ALL_TESTS - depends on KUNIT=y && APPLE_T6030_DISPLAY_GATE + depends on KUNIT=y && APPLE_DISPLAY_GATE default KUNIT_ALL_TESTS help Runs the display gate on test device trees with the T6030, T6031 diff --git a/drivers/soc/apple/Makefile b/drivers/soc/apple/Makefile index 65d7c9d27c9c3..52c36dfc066f1 100644 --- a/drivers/soc/apple/Makefile +++ b/drivers/soc/apple/Makefile @@ -17,11 +17,11 @@ apple-rtkit-helper-y = rtkit-helper.o obj-$(CONFIG_APPLE_SART) += apple-sart.o apple-sart-y = sart.o -obj-$(CONFIG_APPLE_T6030_DISPLAY_GATE) += apple-t6030-display.o -apple-t6030-display-y := t6030-display-gate.o t6030-pmp.dtbo.o t6030-j516s-pmp.dtbo.o -apple-t6030-display-$(CONFIG_APPLE_DISPLAY_GATE_KUNIT_TEST) += t6031-gate-test.dtbo.o \ - t6030-gate-test.dtbo.o \ - t8122-gate-test.dtbo.o +obj-$(CONFIG_APPLE_DISPLAY_GATE) += apple-display-gate.o +apple-display-gate-y := display-gate.o t6030-pmp.dtbo.o t6030-j516s-pmp.dtbo.o +apple-display-gate-$(CONFIG_APPLE_DISPLAY_GATE_KUNIT_TEST) += t6031-gate-test.dtbo.o \ + t6030-gate-test.dtbo.o \ + t8122-gate-test.dtbo.o # The gate adds the interrupt parent from the base tree at boot. DTC_FLAGS_t6030-pmp := -Wno-interrupts_property DTC_FLAGS_t6030-j516s-pmp := -Wno-interrupts_property diff --git a/drivers/soc/apple/t6030-display-gate-test.c b/drivers/soc/apple/display-gate-test.c similarity index 99% rename from drivers/soc/apple/t6030-display-gate-test.c rename to drivers/soc/apple/display-gate-test.c index a970405c6205e..73b36e5a722b6 100644 --- a/drivers/soc/apple/t6030-display-gate-test.c +++ b/drivers/soc/apple/display-gate-test.c @@ -13,7 +13,7 @@ * - T8122 (t8122-gate-test.dtso): on by default, with the full handoff, * and nothing changed when a check of the handoff or of the reused PMP * topology fails. - * Included at the end of t6030-display-gate.c. + * Included at the end of display-gate.c. * * The test trees are applied once and stay: the gate gives some properties * names it does not allocate, which the tree must never free. Each case diff --git a/drivers/soc/apple/t6030-display-gate.c b/drivers/soc/apple/display-gate.c similarity index 99% rename from drivers/soc/apple/t6030-display-gate.c rename to drivers/soc/apple/display-gate.c index 2f73104b05c8c..443a821a7e3aa 100644 --- a/drivers/soc/apple/t6030-display-gate.c +++ b/drivers/soc/apple/display-gate.c @@ -1972,7 +1972,7 @@ static void __init gate_run(void) } /* Runs before of_platform_default_populate_init() at arch_initcall_sync. */ -static int __init apple_t6030_display_gate(void) +static int __init apple_display_gate(void) { int i; @@ -1995,8 +1995,8 @@ static int __init apple_t6030_display_gate(void) gate_run(); return 0; } -arch_initcall(apple_t6030_display_gate); +arch_initcall(apple_display_gate); #if IS_ENABLED(CONFIG_APPLE_DISPLAY_GATE_KUNIT_TEST) -#include "t6030-display-gate-test.c" +#include "display-gate-test.c" #endif diff --git a/tools/asahi/t6030-pmp-supplier-tests.py b/tools/asahi/t6030-pmp-supplier-tests.py index 3379b2911f480..d323dffbef728 100755 --- a/tools/asahi/t6030-pmp-supplier-tests.py +++ b/tools/asahi/t6030-pmp-supplier-tests.py @@ -21,7 +21,7 @@ import sys ROOT = Path(__file__).resolve().parents[2] -GATE = "drivers/soc/apple/t6030-display-gate.c" +GATE = "drivers/soc/apple/display-gate.c" REPORT = "drivers/pmdomain/apple/pmp-report.c" EXPORT = "drivers/soc/apple/pmp-export.c" @@ -84,7 +84,7 @@ def main(): kconfig = (ROOT / "drivers/soc/apple/Kconfig").read_text() section = kconfig.split("config APPLE_T6030_GPU_PMP_LINK\n", 1)[1].split("\nconfig ", 1)[0] assert '\n\tbool\n' in "\n" + section and "\n\tdefault n\n" in section - assert "depends on APPLE_T6030_DISPLAY_GATE" in section + assert "depends on APPLE_DISPLAY_GATE" in section parts = [function(gate, "static struct device_node *__init gate_find_one("), function(gate, "static int __init gate_gpu_pmp_link("), function(report, "static struct device_node *apple_pmp_report_t6030_entry("), From 136ac6d9937f171b205b1678a800e6c9cdb7a337 Mon Sep 17 00:00:00 2001 From: Ryan Murray Date: Wed, 28 Oct 2026 14:53:39 +1100 Subject: [PATCH 3/3] soc: apple: display gate: take over the T6041 handoff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The J616s internal display and external display chain had their own gate, t6041-display-gate.c, beside the display gate that already serves T6030, T6031 and T8122. Both do the same job: enable the display nodes the device tree keeps disabled, before devices are created, once the boot loader's handoff checks out. Make T6041 an entry in the display gate's SoC table, matched on the apple,t6040 SoC compatible instead of the J616s board. Its handoff has a sequence of its own (the DCP is adopted running and the PMP is the device tree's own), so struct gate_soc gains a run hook, and the T6041 checks use the gate's existing helpers (gate_marked(), gate_disabled(), gate_target()) instead of copies. Appending a display DART to the display subsystem's iommus is now one helper, gate_iommus_append(), shared by the T6030 external processors and the J616s external chain; it is not __init, as the external chain is powered up from a work item. The checks, the order of the enabled nodes, the staged external power-up and the messages (with their apple-t6041-display: prefix) are as before. APPLE_T6041_DISPLAY_GATE is gone; APPLE_DISPLAY_GATE covers it and was already on wherever the T6041 gate was. The T6041 gate was written by Ryan Murray, its external display power-up by František Balázsy. Assisted-by: LLM Signed-off-by: Ryan Murray Co-Authored-By: Claude Opus 5.5 --- .../dts/apple/t6040-j616s-extdisp-hdmi.dtsi | 2 +- .../dts/apple/t6040-j616s-extdisp-usbc.dtsi | 2 +- .../boot/dts/apple/t6040-j616s-extdisp.dtsi | 2 +- arch/arm64/boot/dts/apple/t6040-j616s.dts | 2 +- drivers/soc/apple/Kconfig | 27 +- drivers/soc/apple/Makefile | 2 - drivers/soc/apple/display-gate.c | 663 +++++++++++++++++- drivers/soc/apple/t6041-display-gate.c | 655 ----------------- 8 files changed, 660 insertions(+), 695 deletions(-) delete mode 100644 drivers/soc/apple/t6041-display-gate.c diff --git a/arch/arm64/boot/dts/apple/t6040-j616s-extdisp-hdmi.dtsi b/arch/arm64/boot/dts/apple/t6040-j616s-extdisp-hdmi.dtsi index b414a0bddee7d..f471f9332e939 100644 --- a/arch/arm64/boot/dts/apple/t6040-j616s-extdisp-hdmi.dtsi +++ b/arch/arm64/boot/dts/apple/t6040-j616s-extdisp-hdmi.dtsi @@ -4,7 +4,7 @@ * -> atcphy3 -> DP-to-HDMI converter) with every node left DISABLED. The * nodes must not be enabled at boot in the device tree: powering the DISPEXT * chain without the PMP acknowledgement hangs the machine before root. The - * enable gate (drivers/soc/apple/t6041-display-gate.c) switches them on in + * enable gate (drivers/soc/apple/display-gate.c) switches them on in * order once the PMP is bound. * * dispext0's DART is not in the display node's iommus: the gate appends it diff --git a/arch/arm64/boot/dts/apple/t6040-j616s-extdisp-usbc.dtsi b/arch/arm64/boot/dts/apple/t6040-j616s-extdisp-usbc.dtsi index 3d375fd93a98e..6fbf8d6a27f89 100644 --- a/arch/arm64/boot/dts/apple/t6040-j616s-extdisp-usbc.dtsi +++ b/arch/arm64/boot/dts/apple/t6040-j616s-extdisp-usbc.dtsi @@ -2,7 +2,7 @@ /* * USB-C DisplayPort: dcpext1 over any of the three Type-C ports. As for * HDMI, the DISPEXT1 chain and dcpext1 stay DISABLED in the DTB and are - * enabled by the enable gate (drivers/soc/apple/t6041-display-gate.c). The + * enabled by the enable gate (drivers/soc/apple/display-gate.c). The * routes go through the display fabric (typec-routes, end of this file): * tipd's mode switch reaches dcpext1, which claims the port. Boot-time * changes: mode-switch on atcphy0..2 (the PHY registers a Type-C mode diff --git a/arch/arm64/boot/dts/apple/t6040-j616s-extdisp.dtsi b/arch/arm64/boot/dts/apple/t6040-j616s-extdisp.dtsi index b6486f293da9d..ef7f9afb47028 100644 --- a/arch/arm64/boot/dts/apple/t6040-j616s-extdisp.dtsi +++ b/arch/arm64/boot/dts/apple/t6040-j616s-extdisp.dtsi @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ OR MIT /* * External display resources of the J616s. Everything here is disabled in - * the device tree: the enable gate (drivers/soc/apple/t6041-display-gate.c) + * the device tree: the enable gate (drivers/soc/apple/display-gate.c) * switches the chain on once the boot loader has provided the firmware * memory of the external display processors, so without that the booted * hardware state is the same as without this file. diff --git a/arch/arm64/boot/dts/apple/t6040-j616s.dts b/arch/arm64/boot/dts/apple/t6040-j616s.dts index 3995f5d4db16a..6c28c95f8155d 100644 --- a/arch/arm64/boot/dts/apple/t6040-j616s.dts +++ b/arch/arm64/boot/dts/apple/t6040-j616s.dts @@ -4368,7 +4368,7 @@ #include "t6040-j616s-usb3.dtsi" -/* External display chain, all disabled: the gate in drivers/soc/apple/t6041-display-gate.c enables it. */ +/* External display chain, all disabled: the gate in drivers/soc/apple/display-gate.c enables it. */ #include "t6040-j616s-extdisp.dtsi" #include "t6040-j616s-extdisp-mem-loader.dtsi" #include "t6040-j616s-extdisp-hdmi.dtsi" diff --git a/drivers/soc/apple/Kconfig b/drivers/soc/apple/Kconfig index c06d4b38e9238..4da82f85b2465 100644 --- a/drivers/soc/apple/Kconfig +++ b/drivers/soc/apple/Kconfig @@ -257,24 +257,15 @@ config APPLE_DISPLAY_GATE apple_t6031_display.enable=1 on the kernel command line, and only with the PMP values the boot loader passes. - Say 'y' if you want the native display on M3 Pro MacBook Pros. - -config APPLE_T6041_DISPLAY_GATE - bool "Apple T6041 internal display enable gate" - depends on ARCH_APPLE && OF_DYNAMIC - default ARCH_APPLE - help - The J616s (M4 Pro) device tree keeps the internal display nodes - disabled, so the display stays on the boot framebuffer until the - boot loader has handed the running display coprocessor over. This - option enables those nodes before devices are created, only when - the boot loader has published a complete T6041 handoff for the - 26.6.2 display firmware. It also powers up the J616s external - display chain (HDMI, Type-C DisplayPort) once the boot loader has - given the external display processors their firmware memory. - Without these, or with nomodeset, it does nothing. - - Say 'y' if you want the native display on M4 Pro MacBook Pros. + On T6041 (M4 Pro) device trees it enables the internal display nodes + only when the boot loader has handed the running display coprocessor + over (apple,t6041-handoff, 26.6.2 display firmware), and powers up + the J616s external display chain (HDMI, Type-C DisplayPort) once the + boot loader has given the external display processors their + firmware memory. Without these, or with nomodeset, it does nothing. + + Say 'y' if you want the native display on M3 Pro, M3 Max, M3 and + M4 Pro Macs. config APPLE_T6030_GPU_PMP_LINK bool diff --git a/drivers/soc/apple/Makefile b/drivers/soc/apple/Makefile index 52c36dfc066f1..56d7c1e7b8abf 100644 --- a/drivers/soc/apple/Makefile +++ b/drivers/soc/apple/Makefile @@ -32,8 +32,6 @@ DTC_FLAGS_t6030-gate-test := -Wno-interrupts_property -Wno-chosen_node_is_root \ -Wno-avoid_unnecessary_addr_size DTC_FLAGS_t8122-gate-test := -Wno-interrupts_property -Wno-chosen_node_is_root -obj-$(CONFIG_APPLE_T6041_DISPLAY_GATE) += t6041-display-gate.o - obj-$(CONFIG_APPLE_TUNABLE) += apple-tunable.o apple-tunable-y = tunable.o diff --git a/drivers/soc/apple/display-gate.c b/drivers/soc/apple/display-gate.c index 443a821a7e3aa..b178583d09901 100644 --- a/drivers/soc/apple/display-gate.c +++ b/drivers/soc/apple/display-gate.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only OR MIT /* - * Apple T6030 internal display enable gate, and its T8122 counterpart + * Apple internal display enable gate (T6030, T6031, T8122 and T6041) * * The T6030 device tree describes the internal display (the DCP, its * mailbox, the two display DARTs and the display subsystem) with every node @@ -62,10 +62,24 @@ * DISP_SYS), and its PMP power states are in another PMGR block. On every * T6031 boot the gate also logs what the boot loader handed over, so that * a boot without the option already records what the next one needs. + * + * On T6041 (the display coprocessor of the M4 Pro, apple,t6040) m1n1 hands + * over the DCP that iBoot leaves running. It marks the DCP, the display + * subsystem and the DCP's piodma child with apple,t6041-handoff and names + * the display firmware in apple,firmware-compat. There is no PMP to add or + * complete: the device tree describes it and its own driver starts it. The + * gate checks the handoff and the running DCP, enables the internal display + * nodes, and powers up the external display chain in stages once the PMP is + * bound (see gate_t6041_run()). This part was a driver of its own, + * t6041-display-gate.c, by Ryan Murray and František Balázsy. */ #define pr_fmt(fmt) fmt +#include +#include +#include +#include #include #include #include @@ -73,12 +87,16 @@ #include #include #include +#include +#include #include #include #include #include #include +#include #include +#include #include