From 67f216975687ac7ab0569e1f4f07d5625be7b856 Mon Sep 17 00:00:00 2001 From: Jos Dehaes Date: Tue, 10 Nov 2026 15:14:23 +0100 Subject: [PATCH 1/7] arm64: dts: apple: t6041-j616c: give the external DCPs a text region The loader fills the M4 Max's external DCP firmware memory only from the three-region layout the M4 Pro uses: a text, a data and a heap placeholder (t6040-j616s-extdisp-mem-loader.dtsi). It points the text region at the internal DCP's TEXT, which the processors share, and fills the other two from the ADT. The J616c's HDMI and USB-C dcpext nodes describe only data and heap, so on a J614c the loader refuses both processors and the display gate keeps the external displays off: DCP: T6041: dcpext0 firmware memory refused; placeholder remains disabled DCP: T6041: dcpext1 firmware memory refused; placeholder remains disabled apple-t6041-display: /dcp@3a2e00000: no firmware memory, nothing enabled Add the text placeholder to both, as on the M4 Pro. The display gate only needs every region to be available asc-mem. Signed-off-by: Jos Dehaes Co-Authored-By: Claude Opus 5.5 --- arch/arm64/boot/dts/apple/t6041-j616c-hdmi.dtsi | 17 ++++++++++++++--- arch/arm64/boot/dts/apple/t6041-j616c-usbc.dtsi | 15 +++++++++++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/arch/arm64/boot/dts/apple/t6041-j616c-hdmi.dtsi b/arch/arm64/boot/dts/apple/t6041-j616c-hdmi.dtsi index 7bf6baf4a2f11..b5770a86c9fed 100644 --- a/arch/arm64/boot/dts/apple/t6041-j616c-hdmi.dtsi +++ b/arch/arm64/boot/dts/apple/t6041-j616c-hdmi.dtsi @@ -5,7 +5,7 @@ * * Every node is disabled. No DISPEXT0 power domain is described: the chain * runs as iBoot leaves it powered. The boot loader fills dcpext0's firmware - * memory (the data and heap regions below; the text region is the internal + * memory (the regions below; it points the text region at the internal * DCP's), and the display gate (drivers/soc/apple/display-gate.c) then * enables the chain and adds dispext0's DART to the display subsystem's * iommus. @@ -17,6 +17,17 @@ }; reserved-memory { + /* + * The loader replaces this placeholder with the internal DCP's + * TEXT, which the external processors share, as on the M4 Pro. + */ + dcpext0_text: dcpext0-text { + compatible = "apple,asc-mem"; + reg = <0x0 0x0 0x0 0x4000>; + no-map; + status = "disabled"; + }; + dcpext0_data: dcpext0-data { compatible = "apple,asc-mem"; reg = <0x0 0x0 0x0 0x4000>; @@ -46,8 +57,8 @@ mux-control-names = "dp-xbar"; mux-index = <0>; apple,dptx-phy = <3>; - memory-region = <&dcpext0_data>, <&dcpext0_heap>; - memory-region-names = "data", "heap"; + memory-region = <&dcpext0_text>, <&dcpext0_data>, <&dcpext0_heap>; + memory-region-names = "text", "data", "heap"; }; &atcphy3 { diff --git a/arch/arm64/boot/dts/apple/t6041-j616c-usbc.dtsi b/arch/arm64/boot/dts/apple/t6041-j616c-usbc.dtsi index 35f6bfc990e8d..28acf941dc0db 100644 --- a/arch/arm64/boot/dts/apple/t6041-j616c-usbc.dtsi +++ b/arch/arm64/boot/dts/apple/t6041-j616c-usbc.dtsi @@ -15,6 +15,17 @@ }; reserved-memory { + /* + * The loader replaces this placeholder with the internal DCP's + * TEXT, which the external processors share, as on the M4 Pro. + */ + dcpext1_text: dcpext1-text { + compatible = "apple,asc-mem"; + reg = <0x0 0x0 0x0 0x4000>; + no-map; + status = "disabled"; + }; + dcpext1_data: dcpext1-data { compatible = "apple,asc-mem"; reg = <0x0 0x0 0x0 0x4000>; @@ -41,8 +52,8 @@ /* indexed by route */ apple,typec-dptx-phys = <0 1 2>; apple,typec-mux-indices = <2 2 2>; - memory-region = <&dcpext1_data>, <&dcpext1_heap>; - memory-region-names = "data", "heap"; + memory-region = <&dcpext1_text>, <&dcpext1_data>, <&dcpext1_heap>; + memory-region-names = "text", "data", "heap"; typec-routes { #address-cells = <1>; From 87449597e669b79c1797a973520cc540a9bdf710 Mon Sep 17 00:00:00 2001 From: Jos Dehaes Date: Tue, 10 Nov 2026 15:28:56 +0100 Subject: [PATCH 2/7] arm64: dts: apple: t6041-j614c-j616c: add DisplayPort and HDMI audio The M4 Max laptops have external displays but no audio for them: no SIO alias, no dpaudio controllers, and no DPA power domains, which only t6040-pmgr.dtsi describes. Their ADT has the M4 Pro's audio path (J614c read from the running machine): dcpext0's audio is dp-audio1 on SIO DMA channel 0x66 and dcpext1's is dp-audio2 on 0x68, and the PMGR has UART_P (0x1a0) and DPA_P (0x1a8) under SIO and DPA1 (0x238) and DPA2 (0x240) under DPA_P. Describe them as t6040-j616s-dpaudio.dtsi does: the four domains, the SIO alias the loader uses to reserve the SIO firmware and enable the SIO, the two dpaudio controllers and their links to dcpext0 and dcpext1, the SIO CPU domain's parents, and the SIO DART and mailbox. Signed-off-by: Jos Dehaes Co-Authored-By: Claude Opus 5.5 --- .../boot/dts/apple/t6041-j614c-j616c.dtsi | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t6041-j614c-j616c.dtsi b/arch/arm64/boot/dts/apple/t6041-j614c-j616c.dtsi index fec641445c5d5..442fcbe3ddf3f 100644 --- a/arch/arm64/boot/dts/apple/t6041-j614c-j616c.dtsi +++ b/arch/arm64/boot/dts/apple/t6041-j614c-j616c.dtsi @@ -2543,3 +2543,136 @@ &ps_qspi { status = "okay"; }; + +/* + * DisplayPort/HDMI audio, as on the M4 Pro boards (t6040-j616s-dpaudio.dtsi). + * The J614c's ADT has the J616s's: dcpext0's audio is dp-audio1 (SIO DMA + * channel 0x66) and dcpext1's is dp-audio2 (0x68), and the PMGR has UART_P + * (0x1a0) and DPA_P (0x1a8) under SIO, and DPA1 (0x238) and DPA2 (0x240) + * under DPA_P. The SIO stays disabled here: the loader enables it once it has + * reserved the firmware iBoot loaded (it finds it by the alias). + */ +&pmgr { + ps_uart_p: power-controller@1a0 { + compatible = "apple,t6041-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x1a0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "uart_p"; + power-domains = <&ps_sio>; + }; + + ps_dpa_p: power-controller@1a8 { + compatible = "apple,t6041-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x1a8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "dpa_p"; + power-domains = <&ps_sio>; + apple,always-on; + }; + + ps_dpa1: power-controller@238 { + compatible = "apple,t6041-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x238 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "dpa1"; + power-domains = <&ps_dpa_p>; + }; + + ps_dpa2: power-controller@240 { + compatible = "apple,t6041-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x240 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "dpa2"; + power-domains = <&ps_dpa_p>; + }; +}; + +/ { + aliases { + sio = &sio; + }; + + dpaudio1: audio-controller-1 { + compatible = "apple,t6041-dpaudio", "apple,dpaudio"; + dmas = <&sio 0x66>; + dma-names = "tx"; + power-domains = <&ps_dpa1>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dpaudio1_dcpext: endpoint { + remote-endpoint = <&dcpext0_audio>; + }; + }; + }; + }; + + dpaudio2: audio-controller-2 { + compatible = "apple,t6041-dpaudio", "apple,dpaudio"; + dmas = <&sio 0x68>; + dma-names = "tx"; + power-domains = <&ps_dpa2>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dpaudio2_dcpext: endpoint { + remote-endpoint = <&dcpext1_audio>; + }; + }; + }; + }; +}; + +&dcpext0 { + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dcpext0_audio: endpoint { + remote-endpoint = <&dpaudio1_dcpext>; + }; + }; + }; +}; + +&dcpext1 { + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dcpext1_audio: endpoint { + remote-endpoint = <&dpaudio2_dcpext>; + }; + }; + }; +}; + +/* The SIO firmware drives the SPI, UART and DP audio shims: keep their parents on. */ +&ps_sio_cpu { + power-domains = <&ps_sio>, <&ps_spi_p>, <&ps_uart_p>, <&ps_dpa_p>; + status = "okay"; +}; + +&sio_dart { + status = "okay"; +}; + +&sio_mbox { + status = "okay"; +}; From 19af11724bf97036a90cd20ee7aa265b68a60ba7 Mon Sep 17 00:00:00 2001 From: Jos Dehaes Date: Tue, 10 Nov 2026 15:48:48 +0100 Subject: [PATCH 3/7] arm64: dts: apple: t6041-j614c-j616c: enable USB 3 on the USB-C ports The M4 Max laptops run their three USB-C ports at USB 2 only: the PHYs carry a hardcoded USB 2 tunable, the controllers are limited to high speed with only their USB 2 PHY, and nothing connects the connectors' SuperSpeed lanes. The left-front port's DisplayPort description adds a hardcoded set of ATC tunables for atcphy1. Their ADT has the M4 Pro's per-port ATC and controller tunables (atc-phy0..2, usb-drd0..2, J614c read from the running machine), which the loader copies into the PHY and controller nodes, as it does on the J614s. Describe the ports as the M4 Pro does: the controllers use both PHYs, the PHYs link to the connectors' SuperSpeed lanes and to the controllers, and the PHY mailboxes are on. Drop the hardcoded tunables, which the loader would otherwise duplicate. The HDMI PHY keeps its own. Signed-off-by: Jos Dehaes Co-Authored-By: Claude Opus 5.5 --- .../boot/dts/apple/t6041-j614c-j616c.dtsi | 146 +++++++++++--- .../boot/dts/apple/t6041-j616c-usbc.dtsi | 189 +----------------- 2 files changed, 116 insertions(+), 219 deletions(-) diff --git a/arch/arm64/boot/dts/apple/t6041-j614c-j616c.dtsi b/arch/arm64/boot/dts/apple/t6041-j614c-j616c.dtsi index ff5f0340e267a..3c7123151e129 100644 --- a/arch/arm64/boot/dts/apple/t6041-j614c-j616c.dtsi +++ b/arch/arm64/boot/dts/apple/t6041-j614c-j616c.dtsi @@ -1763,6 +1763,13 @@ remote-endpoint = <&dwc3_0_hs>; }; }; + + port@1 { + reg = <1>; + typec0_connector_ss: endpoint { + remote-endpoint = <&atcphy0_ss>; + }; + }; }; }; }; @@ -1803,6 +1810,13 @@ remote-endpoint = <&dwc3_1_hs>; }; }; + + port@1 { + reg = <1>; + typec1_connector_ss: endpoint { + remote-endpoint = <&atcphy1_ss>; + }; + }; }; }; }; @@ -1836,14 +1850,46 @@ remote-endpoint = <&dwc3_2_hs>; }; }; + + port@1 { + reg = <1>; + typec2_connector_ss: endpoint { + remote-endpoint = <&atcphy2_ss>; + }; + }; }; }; }; }; -/* The left-back port, USB 2 as the other two. */ +/* + * USB 3 on the three USB-C ports. The loader appends the PHY and controller + * tunables from the ADT, as on the M4 Pro, and disables a port it can't tune. + */ &atcphy0 { - apple,tunable-usb2-host = <0x8 0x7003 0x3>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + atcphy0_ss: endpoint { + remote-endpoint = <&typec0_connector_ss>; + }; + }; + + port@1 { + reg = <1>; + atcphy0_usb3: endpoint { + remote-endpoint = <&dwc3_0_ss>; + }; + }; + }; +}; + +&atcphy0_mbox { status = "okay"; }; @@ -1856,15 +1902,6 @@ }; &dwc3_0 { - maximum-speed = "high-speed"; - phys = <&atcphy0 PHY_TYPE_USB2>; - phy-names = "usb2-phy"; - apple,tunable-gbl-host = <0x4 0x0001ef00 0x00002f00>, <0x1c 0x00000100 0x0>, - <0x2c 0x000a07ff 0x000800c8>, <0x100 0x02000100 0x02000100>, - <0x504 0x00001000 0x0>, <0x528 0xff0000ff 0x06000006>, - <0x52c 0xff0000ff 0x08000008>, <0x538 0x00000800 0x00000800>, - <0x580 0xffffffff 0x6f000006>; - apple,tunable-cfg-host = <0x20 0xff 0x1b>; status = "okay"; ports { @@ -1877,11 +1914,40 @@ remote-endpoint = <&typec0_connector_hs>; }; }; + + port@1 { + reg = <1>; + dwc3_0_ss: endpoint { + remote-endpoint = <&atcphy0_usb3>; + }; + }; }; }; &atcphy1 { - apple,tunable-usb2-host = <0x8 0x7003 0x3>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + atcphy1_ss: endpoint { + remote-endpoint = <&typec1_connector_ss>; + }; + }; + + port@1 { + reg = <1>; + atcphy1_usb3: endpoint { + remote-endpoint = <&dwc3_1_ss>; + }; + }; + }; +}; + +&atcphy1_mbox { status = "okay"; }; @@ -1894,15 +1960,6 @@ }; &dwc3_1 { - maximum-speed = "high-speed"; - phys = <&atcphy1 PHY_TYPE_USB2>; - phy-names = "usb2-phy"; - apple,tunable-gbl-host = <0x4 0x0001ef00 0x00002f00>, <0x1c 0x00000100 0x0>, - <0x2c 0x000a07ff 0x000800c8>, <0x100 0x02000100 0x02000100>, - <0x504 0x00001000 0x0>, <0x528 0xff0000ff 0x06000006>, - <0x52c 0xff0000ff 0x08000008>, <0x538 0x00000800 0x00000800>, - <0x580 0xffffffff 0x6f000006>; - apple,tunable-cfg-host = <0x20 0xff 0x1b>; status = "okay"; ports { @@ -1915,11 +1972,40 @@ remote-endpoint = <&typec1_connector_hs>; }; }; + + port@1 { + reg = <1>; + dwc3_1_ss: endpoint { + remote-endpoint = <&atcphy1_usb3>; + }; + }; }; }; &atcphy2 { - apple,tunable-usb2-host = <0x8 0x7003 0x3>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + atcphy2_ss: endpoint { + remote-endpoint = <&typec2_connector_ss>; + }; + }; + + port@1 { + reg = <1>; + atcphy2_usb3: endpoint { + remote-endpoint = <&dwc3_2_ss>; + }; + }; + }; +}; + +&atcphy2_mbox { status = "okay"; }; @@ -1932,15 +2018,6 @@ }; &dwc3_2 { - maximum-speed = "high-speed"; - phys = <&atcphy2 PHY_TYPE_USB2>; - phy-names = "usb2-phy"; - apple,tunable-gbl-host = <0x4 0x0001ef00 0x00002f00>, <0x1c 0x00000100 0x0>, - <0x2c 0x000a07ff 0x000800c8>, <0x100 0x02000100 0x02000100>, - <0x504 0x00001000 0x0>, <0x528 0xff0000ff 0x06000006>, - <0x52c 0xff0000ff 0x08000008>, <0x538 0x00000800 0x00000800>, - <0x580 0xffffffff 0x6f000006>; - apple,tunable-cfg-host = <0x20 0xff 0x1b>; status = "okay"; ports { @@ -1953,6 +2030,13 @@ remote-endpoint = <&typec2_connector_hs>; }; }; + + port@1 { + reg = <1>; + dwc3_2_ss: endpoint { + remote-endpoint = <&atcphy2_usb3>; + }; + }; }; }; diff --git a/arch/arm64/boot/dts/apple/t6041-j616c-usbc.dtsi b/arch/arm64/boot/dts/apple/t6041-j616c-usbc.dtsi index 35f6bfc990e8d..7ba659dc5d6a5 100644 --- a/arch/arm64/boot/dts/apple/t6041-j616c-usbc.dtsi +++ b/arch/arm64/boot/dts/apple/t6041-j616c-usbc.dtsi @@ -6,7 +6,7 @@ * dcpext1, its DARTs, mailbox, crossbar and Type-C route are disabled, as * for HDMI: the display gate enables them once the boot loader has filled * dcpext1's firmware memory. A disabled route is no mode switch, so typec1 - * then keeps USB2 and PD as before. + * then keeps USB and PD as before. */ / { @@ -64,13 +64,6 @@ &typec1 { ports { - port@1 { - reg = <1>; - typec1_connector_ss: endpoint { - remote-endpoint = <&atcphy1_ss>; - }; - }; - port@3 { reg = <3>; typec1_dcpext1: endpoint { @@ -83,184 +76,4 @@ &atcphy1 { mode-switch; orientation-switch; - - apple,tunable-axi2af = - <0x0 0x800000ff 0x8000001c>, - <0x4 0x80ff00ff 0x801b0003>, - <0x8 0x80ff00ff 0x801b0003>, - <0xc 0x80ff00ff 0x801b0005>, - <0x10 0x80ff00ff 0x801b0003>, - <0x14 0x80ff00ff 0x801b0003>, - <0x18 0x80ff00ff 0x801b0003>, - <0x1c 0x80ff00ff 0x801b0003>, - <0x20 0x800000ff 0x80000015>, - <0x24 0x800000ff 0x80000038>, - <0x28 0x80ff00ff 0x80380006>, - <0x2c 0x80ff00ff 0x80380006>, - <0x30 0x80ff00ff 0x80380006>, - <0x34 0x80ff00ff 0x80380006>, - <0x38 0x80ff00ff 0x80380006>, - <0x3c 0x80ff00ff 0x80380006>, - <0x40 0x800000ff 0x80000015>, - <0x44 0x800000ff 0x80000015>, - <0x48 0x800000ff 0x80000015>, - <0x100 0x000000ff 0x000000ff>, - <0x108 0xffff0006 0x00100000>, - <0x304 0x3f3f0000 0x04040000>, - <0x308 0x000fffff 0x00001681>, - <0x30c 0x000fffff 0x00001680>, - <0x310 0x70000fff 0x000001e0>, - <0x314 0xf0000fff 0x800001e0>, - <0x318 0x70000fff 0x000001e0>, - <0x31c 0xf0000fff 0x800001e0>, - <0x320 0x70000fff 0x000005a0>, - <0x324 0xf0000fff 0x800005a0>, - <0x328 0x70000fff 0x000005a0>, - <0x32c 0xf0000fff 0x800005a0>, - <0x330 0x70000fff 0x000005a0>, - <0x334 0xf0000fff 0x800005a0>, - <0x338 0x70000fff 0x000005a0>, - <0x33c 0x70000fff 0x000005a0>, - <0x340 0x70000fff 0x000005a0>, - <0x344 0x70000fff 0x000005a0>, - <0x348 0x70000fff 0x000005a0>, - <0x34c 0x70000fff 0x000005a0>, - <0x350 0x70000fff 0x000005a0>, - <0x358 0xffffffff 0x0000ffff>, - <0x35c 0xffffffff 0x0000ffff>, - <0x408 0xffff0020 0x00180020>, - <0x40c 0x000fffff 0x00001681>, - <0x410 0x000fffff 0x00001680>, - <0x414 0x70000fff 0x000001e0>, - <0x418 0x70000fff 0x000001e0>, - <0x41c 0x70000fff 0x000001e0>, - <0x420 0x70000fff 0x000001e0>, - <0x424 0x70000fff 0x000005a0>, - <0x428 0x70000fff 0x000005a0>, - <0x42c 0x70000fff 0x000005a0>, - <0x430 0x70000fff 0x000005a0>, - <0x434 0x70000fff 0x000005a0>, - <0x438 0x70000fff 0x000005a0>, - <0x43c 0x70000fff 0x000005a0>, - <0x440 0x70000fff 0x000005a0>, - <0x444 0x70000fff 0x000005a0>, - <0x448 0x70000fff 0x000005a0>, - <0x44c 0x70000fff 0x000005a0>, - <0x450 0x70000fff 0x000005a0>, - <0x454 0x70000fff 0x000005a0>, - <0x948 0x07ff07ff 0x00280000>, - <0xa48 0x07ff07ff 0x00400040>, - <0xb48 0x07ff07ff 0x00b8010e>, - <0xc48 0x07ff07ff 0x00400020>, - <0xd48 0x07ff07ff 0x008a008a>, - <0x1000 0xffffffff 0x7fffffff>, - <0x4008 0x00000001 0x00000001>, - <0x400c 0x00000001 0x00000001>, - <0x4014 0x00000001 0x00000001>, - <0x4018 0x00000001 0x00000000>, - <0x401c 0x00000001 0x00000001>; - apple,tunable-fabric = - <0x4 0x003f003f 0x00200020>, - <0xc 0x000000f1 0x000000a1>, - <0x10 0x0000801f 0x00000004>, - <0x18 0x003f003f 0x00200020>, - <0x20 0x000000f1 0x000000a1>, - <0x24 0x0000801f 0x00000004>, - <0x2c 0x00ff00ff 0x00960096>, - <0x34 0x000000f1 0x00000071>, - <0x38 0x0000801f 0x00000004>, - <0x40 0x0000003f 0x00000020>, - <0x48 0x0000801f 0x00000004>, - <0x50 0x007f007f 0x00450045>, - <0x58 0x0000801f 0x00000004>, - <0x60 0x0000003f 0x00000020>, - <0x68 0x0000801f 0x00000004>, - <0x70 0x00000001 0x00000001>, - <0x74 0x0000801f 0x00000004>, - <0x7c 0x007f007f 0x00400040>, - <0x80 0x000000f1 0x00000011>, - <0x84 0x00000001 0x00000001>, - <0x88 0x00000001 0x00000001>, - <0x8c 0x0000801f 0x00000004>, - <0x94 0x001f001f 0x00100010>, - <0x98 0x000000f1 0x00000011>, - <0x9c 0x0000801f 0x00000004>, - <0xa4 0x000000ff 0x000000e0>, - <0xa8 0x0000801f 0x00000004>, - <0xb0 0x0000003f 0x00000020>, - <0xb8 0x0000801f 0x00000004>, - <0xc0 0x0000003f 0x00000020>, - <0xc8 0x0000801f 0x00000004>, - <0xd0 0x001f001f 0x00100010>, - <0xd8 0x00000001 0x00000001>, - <0xdc 0x00000001 0x00000001>, - <0xe0 0x0000801f 0x00000004>, - <0xe8 0x0000000f 0x00000008>, - <0xec 0x0000801f 0x00000004>, - <0xf4 0xffffffff 0x01010101>, - <0xf8 0x0000801f 0x00000004>, - <0x100 0x00000001 0x00000001>, - <0x104 0x00000001 0x00000001>, - <0x108 0x0000801f 0x00000004>, - <0x110 0x0000801f 0x00000004>, - <0x118 0x0000801f 0x00000004>, - <0x120 0x00000001 0x00000001>, - <0x124 0x00000001 0x00000001>, - <0x128 0x0000801f 0x00000004>, - <0x130 0xffffffff 0x01010101>, - <0x134 0x0000801f 0x00000004>, - <0x13c 0x00000001 0x00000001>, - <0x140 0x00000001 0x00000001>, - <0x144 0x0000801f 0x00000004>, - <0x14c 0x00000001 0x00000001>, - <0x150 0x00000001 0x00000001>, - <0x154 0x0000801f 0x00000004>, - <0x15c 0x0000801f 0x00000004>, - <0x164 0xffffffff 0x01010101>, - <0x168 0x0000ffff 0x00000101>, - <0x16c 0x0000801f 0x00000004>, - <0x174 0x00000001 0x00000001>, - <0x178 0x00000001 0x00000001>, - <0x17c 0x0000801f 0x00000004>, - <0x184 0x00000001 0x00000001>, - <0x188 0x00000001 0x00000001>, - <0x18c 0x0000801f 0x00000004>; - apple,tunable-common-cfg = - <0x8 0x00000001 0x00000001>; - apple,tunable-axi2af-lioa = - <0x28 0x0000fe2f 0x00000000>, - <0x2c 0x00000007 0x00000000>, - <0x30 0x0000007f 0x00000000>, - <0x34 0x000000ff 0x00000000>, - <0x58 0x0000010b 0x00000000>; - apple,tunable-lane0 = - <0xd094 0x00080000 0x00080000>, - <0xd098 0x00080000 0x00080000>, - <0xd0a4 0x00800000 0x00800000>, - <0xd0a8 0x00200000 0x00200000>; - apple,tunable-lane1 = - <0x1d094 0x00080000 0x00080000>, - <0x1d098 0x00080000 0x00080000>, - <0x1d0a4 0x00800000 0x00800000>, - <0x1d0a8 0x00200000 0x00200000>; - apple,tunable-aus40cmn-shm = - <0xa04 0x0000007c 0x0000004c>; - apple,tunable-auspll = - <0x3224 0x00000c00 0x00000800>, - <0x3230 0x0000001f 0x0000000f>, - <0x3240 0x07d8007f 0x04000039>, - <0x32b0 0x0b800000 0x01800000>, - <0x32e8 0x00060001 0x00040001>, - <0x3338 0x0f800000 0x07800000>; - apple,tunable-cio4pll = - <0x3a30 0x0000001f 0x0000000f>, - <0x3a4c 0x0000fe7f 0x00004e1d>, - <0x3ab0 0x00700000 0x00300000>, - <0x3ae8 0x00060000 0x00020000>; - - port { - atcphy1_ss: endpoint { - remote-endpoint = <&typec1_connector_ss>; - }; - }; }; From 96958485f1e452233c5a5b31f17dbe318e32d529 Mon Sep 17 00:00:00 2001 From: Jos Dehaes Date: Tue, 10 Nov 2026 16:10:22 +0100 Subject: [PATCH 4/7] soc: apple: display-gate: leave the M4 Max ATC1 mailbox to the PHY The M4 Max USB-C display chain lists atcphy1's mailbox among the nodes it enables, and gives up on dcpext1 when any of them is already on. The mailbox is the PHY coprocessor's, which USB3 needs whatever the display does, so a device tree that runs the port at USB3 enables it and the gate then leaves the USB-C display off: apple-t6041-display: /mailbox@38b148000: already enabled, nothing changed Drop it from the chain, as the M4 Pro's leaves its ATC mailboxes out, and mark it enabled in the test fixture as the device tree does. Signed-off-by: Jos Dehaes Co-Authored-By: Claude Opus 5.5 --- drivers/soc/apple/display-gate.c | 6 ++++-- drivers/soc/apple/t6041-gate-test.dtso | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/soc/apple/display-gate.c b/drivers/soc/apple/display-gate.c index 73c56cc29ca21..430695747ea94 100644 --- a/drivers/soc/apple/display-gate.c +++ b/drivers/soc/apple/display-gate.c @@ -2993,8 +2993,10 @@ static const char *const t6041_max_hdmi_nodes[] = { }; static const char *const t6041_max_usbc_nodes[] = { - /* ATC1 mailbox and crossbar, DARTs, mailbox, route, dcpext1 */ - "/mailbox@38b148000", + /* + * ATC1 crossbar, DARTs, mailbox, route, dcpext1. The ATC1 mailbox is + * the PHY's, on for USB3 whatever the display does, as on the M4 Pro. + */ "/mux@38b24c000", "/iommu@602340000", "/iommu@602300000", diff --git a/drivers/soc/apple/t6041-gate-test.dtso b/drivers/soc/apple/t6041-gate-test.dtso index d12929a73c0c9..4b1ecc41439a5 100644 --- a/drivers/soc/apple/t6041-gate-test.dtso +++ b/drivers/soc/apple/t6041-gate-test.dtso @@ -116,7 +116,7 @@ }; mailbox@38b148000 { - status = "disabled"; + status = "okay"; }; mux@38b24c000 { From 48bf7a41d484887cc58dbcfa4eedcf641596d4f7 Mon Sep 17 00:00:00 2001 From: Dj <43033058+DjDeveloperr@users.noreply.github.com> Date: Wed, 11 Nov 2026 11:08:44 -0500 Subject: [PATCH 5/7] test: recognize deferred SEP policy-window unlock Backport the test-only correction from aurora-silicon/linux#1564. The cached ref-key unlock closure is dispatched through the real-root policy window after its definition. Validate that complete dispatch and reject unwrapped or extra invocation; retain call-site inventory and initrd rules. No production SEP, keybag or guard-policy changes. Assisted-by: LLM --- tools/aurora-sep/tests/test_policy_window.py | 53 ++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/tools/aurora-sep/tests/test_policy_window.py b/tools/aurora-sep/tests/test_policy_window.py index fda87d68a3f0c..d226e1d0f23da 100644 --- a/tools/aurora-sep/tests/test_policy_window.py +++ b/tools/aurora-sep/tests/test_policy_window.py @@ -73,6 +73,35 @@ def setUp(self): self.sbio = (APPLE / "sbio.rs").read_text() self.activate = function(self.sbio, "activate_touchid") + def assert_cached_refkey_window(self, body, at): + # A deferred closure's wrapper comes after its definition. Match its + # complete dispatch rather than accepting any later window in the fn. + # Preserve offsets while ignoring words in comments. + clean = re.sub(r"//[^\n]*|/\*.*?\*/", lambda m: " " * len(m[0]), + body, flags=re.S) + closure = re.search(r"\blet\s+(?Punlock)\s*=\s*\|\|\s*\{", clean) + self.assertIsNotNone(closure) + opening = closure.end() - 1 + depth, end = 1, opening + 1 + while depth and end < len(clean): + depth += (clean[end] == "{") - (clean[end] == "}") + end += 1 + self.assertEqual(depth, 0) + self.assertTrue(opening < at < end) + self.assertEqual(clean.count(PREPARE), 1) + # The initrd deliberately leaves the real root's window unused; its + # guarded store is read-only. Only that branch may call unlock directly. + dispatch = re.search( + r"\blet\s+unlocked\s*=\s*if\s+self\.keystore_only\.load\(Relaxed\)\s*" + r"\{\s*(?Punlock)\(\)\s*\}\s*else\s*" + r"\{\s*crate::xart_guard::policy_window\((?Punlock)\)\s*\};", + clean) + self.assertIsNotNone(dispatch) + self.assertGreater(dispatch.start(), end) + self.assertEqual( + [m.start() for m in re.finditer(r"\bunlock\b", clean)], + [closure.start("binding"), dispatch.start("initrd"), dispatch.start("root")]) + def test_touchid_designates_inside_the_window(self): at = self.activate.index(DESIGNATE) self.assertIn("crate::xart_guard::policy_window(", statement(self.activate, at)) @@ -87,6 +116,26 @@ def test_touchid_designates_a_keybag_that_already_existed(self): self.assertLess(recovered, self.activate.index(DESIGNATE)) self.assertNotIn("sks_provision_identity_keybag(", self.activate) + def test_cached_refkey_window_wraps_deferred_unlock(self): + body = function((APPLE / "refkey.rs").read_text(), "refkey_unseal_cached") + self.assert_cached_refkey_window(body, body.index(PREPARE)) + + def test_cached_refkey_rejects_unguarded_real_root_unlock(self): + body = function((APPLE / "refkey.rs").read_text(), "refkey_unseal_cached") + wrapped = "crate::xart_guard::policy_window(unlock)" + self.assertEqual(body.count(wrapped), 1) + body = body.replace(wrapped, "unlock()") + with self.assertRaises(AssertionError): + self.assert_cached_refkey_window(body, body.index(PREPARE)) + + def test_cached_refkey_rejects_extra_unguarded_unlock(self): + body = function((APPLE / "refkey.rs").read_text(), "refkey_unseal_cached") + dispatch = "let unlocked = if self.keystore_only.load(Relaxed)" + self.assertEqual(body.count(dispatch), 1) + body = body.replace(dispatch, "unlock();\n " + dispatch) + with self.assertRaises(AssertionError): + self.assert_cached_refkey_window(body, body.index(PREPARE)) + def test_no_other_path_designates_outside_a_window(self): # A new designate of an existing keybag needs the window too; add it # here once it runs in one. @@ -99,6 +148,9 @@ def test_no_other_path_designates_outside_a_window(self): self.assertTrue(callers) for f, outer, body, at in callers: with self.subTest(caller=outer): + if (f, outer) == ("refkey.rs", "refkey_unseal_cached"): + self.assert_cached_refkey_window(body, at) + continue before = body[:at] self.assertTrue("crate::xart_guard::policy_window(" in before or "crate::xart_guard::close_policy_window(" in before, @@ -107,3 +159,4 @@ def test_no_other_path_designates_outside_a_window(self): if __name__ == "__main__": unittest.main() + From 1e704a12a6164d0ea8d61ffd6b6ba290fb40cb12 Mon Sep 17 00:00:00 2001 From: Dj <43033058+DjDeveloperr@users.noreply.github.com> Date: Wed, 11 Nov 2026 11:54:57 -0500 Subject: [PATCH 6/7] test: remove the extra policy-window fixture EOF blank Whitespace only; preserve every assertion and negative control. Assisted-by: LLM --- tools/aurora-sep/tests/test_policy_window.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/aurora-sep/tests/test_policy_window.py b/tools/aurora-sep/tests/test_policy_window.py index d226e1d0f23da..8ae2a619e44ad 100644 --- a/tools/aurora-sep/tests/test_policy_window.py +++ b/tools/aurora-sep/tests/test_policy_window.py @@ -159,4 +159,3 @@ def test_no_other_path_designates_outside_a_window(self): if __name__ == "__main__": unittest.main() - From 6ca6a22729fa2528f17f0473d07d79f16471f195 Mon Sep 17 00:00:00 2001 From: Dj <43033058+DjDeveloperr@users.noreply.github.com> Date: Wed, 11 Nov 2026 12:33:38 -0500 Subject: [PATCH 7/7] test: align policy-window check with merged PR #1561 Use the exact upstream test from ea10c4dba3be; supersede the duplicate local repair. Production source is unchanged. Signed-off-by: Diljit Singh --- tools/aurora-sep/tests/test_policy_window.py | 83 +++++++------------- 1 file changed, 28 insertions(+), 55 deletions(-) diff --git a/tools/aurora-sep/tests/test_policy_window.py b/tools/aurora-sep/tests/test_policy_window.py index 8ae2a619e44ad..d233b8c6ebd7a 100644 --- a/tools/aurora-sep/tests/test_policy_window.py +++ b/tools/aurora-sep/tests/test_policy_window.py @@ -73,35 +73,6 @@ def setUp(self): self.sbio = (APPLE / "sbio.rs").read_text() self.activate = function(self.sbio, "activate_touchid") - def assert_cached_refkey_window(self, body, at): - # A deferred closure's wrapper comes after its definition. Match its - # complete dispatch rather than accepting any later window in the fn. - # Preserve offsets while ignoring words in comments. - clean = re.sub(r"//[^\n]*|/\*.*?\*/", lambda m: " " * len(m[0]), - body, flags=re.S) - closure = re.search(r"\blet\s+(?Punlock)\s*=\s*\|\|\s*\{", clean) - self.assertIsNotNone(closure) - opening = closure.end() - 1 - depth, end = 1, opening + 1 - while depth and end < len(clean): - depth += (clean[end] == "{") - (clean[end] == "}") - end += 1 - self.assertEqual(depth, 0) - self.assertTrue(opening < at < end) - self.assertEqual(clean.count(PREPARE), 1) - # The initrd deliberately leaves the real root's window unused; its - # guarded store is read-only. Only that branch may call unlock directly. - dispatch = re.search( - r"\blet\s+unlocked\s*=\s*if\s+self\.keystore_only\.load\(Relaxed\)\s*" - r"\{\s*(?Punlock)\(\)\s*\}\s*else\s*" - r"\{\s*crate::xart_guard::policy_window\((?Punlock)\)\s*\};", - clean) - self.assertIsNotNone(dispatch) - self.assertGreater(dispatch.start(), end) - self.assertEqual( - [m.start() for m in re.finditer(r"\bunlock\b", clean)], - [closure.start("binding"), dispatch.start("initrd"), dispatch.start("root")]) - def test_touchid_designates_inside_the_window(self): at = self.activate.index(DESIGNATE) self.assertIn("crate::xart_guard::policy_window(", statement(self.activate, at)) @@ -116,26 +87,6 @@ def test_touchid_designates_a_keybag_that_already_existed(self): self.assertLess(recovered, self.activate.index(DESIGNATE)) self.assertNotIn("sks_provision_identity_keybag(", self.activate) - def test_cached_refkey_window_wraps_deferred_unlock(self): - body = function((APPLE / "refkey.rs").read_text(), "refkey_unseal_cached") - self.assert_cached_refkey_window(body, body.index(PREPARE)) - - def test_cached_refkey_rejects_unguarded_real_root_unlock(self): - body = function((APPLE / "refkey.rs").read_text(), "refkey_unseal_cached") - wrapped = "crate::xart_guard::policy_window(unlock)" - self.assertEqual(body.count(wrapped), 1) - body = body.replace(wrapped, "unlock()") - with self.assertRaises(AssertionError): - self.assert_cached_refkey_window(body, body.index(PREPARE)) - - def test_cached_refkey_rejects_extra_unguarded_unlock(self): - body = function((APPLE / "refkey.rs").read_text(), "refkey_unseal_cached") - dispatch = "let unlocked = if self.keystore_only.load(Relaxed)" - self.assertEqual(body.count(dispatch), 1) - body = body.replace(dispatch, "unlock();\n " + dispatch) - with self.assertRaises(AssertionError): - self.assert_cached_refkey_window(body, body.index(PREPARE)) - def test_no_other_path_designates_outside_a_window(self): # A new designate of an existing keybag needs the window too; add it # here once it runs in one. @@ -146,15 +97,37 @@ def test_no_other_path_designates_outside_a_window(self): # after a ref-key create has closed the window for the boot. callers = calls(PREPARE) self.assertTrue(callers) + deferred = 0 for f, outer, body, at in callers: with self.subTest(caller=outer): - if (f, outer) == ("refkey.rs", "refkey_unseal_cached"): - self.assert_cached_refkey_window(body, at) - continue before = body[:at] - self.assertTrue("crate::xart_guard::policy_window(" in before - or "crate::xart_guard::close_policy_window(" in before, - f"{f}: {outer}") + if ("crate::xart_guard::policy_window(" in before + or "crate::xart_guard::close_policy_window(" in before): + continue + # The call sits in a closure that is run later. + self.assertEqual((f, outer), ("refkey.rs", "refkey_unseal_cached")) + self.assertIn("let unlock = || {", before) + deferred += 1 + self.assert_unlock_runs_in_the_window_or_the_initrd(body[at:]) + self.assertEqual(deferred, 1) + + def assert_unlock_runs_in_the_window_or_the_initrd(self, after): + """`unlock` is run twice: in the window, or bare in the initrd. + + The trusted-key-only initrd attach (keystore_only) leaves the boot's + one window to the real root: "Do not consume the real root's one + policy window in the initrd". Its designate runs with the window + shut, where the guard lets no existing session record be rewritten. + """ + uses = re.findall(r"\bunlock\b(?!\s*=)", after) + self.assertEqual(len(uses), 2) + self.assertRegex( + after, + r"if self\.keystore_only\.load\(Relaxed\) \{\s*" + r"unlock\(\)\s*" + r"\} else \{\s*" + r"crate::xart_guard::policy_window\(unlock\)\s*" + r"\}") if __name__ == "__main__":