From 9b4cf0e9aff84039c9ba2cd83c909c4151d89db1 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 21:06:54 +0100 Subject: [PATCH 01/31] dt-bindings: iommu: apple,sart: Add T8152 compatible The T8152 (M6) SART (ADT sart-version 4) keeps the per-entry configuration, address and size registers in three separate arrays, so it is not compatible with the earlier SARTs. Add apple,t8152-sart. Signed-off-by: Thomas Glanzmann Signed-off-by: Acelogic --- Documentation/devicetree/bindings/iommu/apple,sart.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/iommu/apple,sart.yaml b/Documentation/devicetree/bindings/iommu/apple,sart.yaml index e6482453d6dac..021fb3eb5b8f5 100644 --- a/Documentation/devicetree/bindings/iommu/apple,sart.yaml +++ b/Documentation/devicetree/bindings/iommu/apple,sart.yaml @@ -26,6 +26,9 @@ description: SART3, first seen in M1 Pro/Max, extends both the address space and filter entry size to 42 bit. + SART4, found in T8152 (M6), moves the configuration, address and size + registers into separate arrays. + properties: compatible: oneOf: @@ -45,6 +48,7 @@ properties: - apple,t6000-sart - apple,t8015-sart - apple,t8103-sart + - apple,t8152-sart reg: maxItems: 1 From b16eae52b77a9fdc9d32b0a62597fe2c73e184b1 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 21:06:54 +0100 Subject: [PATCH 02/31] dt-bindings: nvme: apple,nvme-ans: Add T8152 compatible T8152 (M6) uses the secure ANS2 register layout and is not compatible with the earlier controllers. There is no T8152 PMGR provider yet; the loader leaves ANS powered and the driver treats the reset as optional, so do not require resets and power domains for apple,t8152-nvme-ans2. Signed-off-by: Thomas Glanzmann Signed-off-by: Acelogic --- .../devicetree/bindings/nvme/apple,nvme-ans.yaml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml b/Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml index a6dafcf594289..b0f21ee126b01 100644 --- a/Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml +++ b/Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml @@ -22,6 +22,7 @@ properties: - apple,t8122-nvme-ans2 - const: apple,t8103-nvme-ans2 - const: apple,t8132-nvme-ans2 + - const: apple,t8152-nvme-ans2 - items: - const: apple,t8132-nvme-ans2 - const: apple,t8103-nvme-ans2 @@ -110,6 +111,18 @@ properties: buffers must remain reserved and protected by the SART. allOf: + - if: + properties: + compatible: + not: + contains: + const: apple,t8152-nvme-ans2 + then: + required: + - resets + - power-domains + - power-domain-names + - if: properties: compatible: @@ -170,9 +183,6 @@ required: - compatible - reg - reg-names - - resets - - power-domains - - power-domain-names - mboxes - interrupts - apple,sart From 359d13aada8142ec35896d9030aa50ba99ddbb32 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 21:06:54 +0100 Subject: [PATCH 03/31] dt-bindings: mailbox: apple,mailbox: Add T8152 ANS mailbox The T8152 (M6) ANS co-processor is reached through a 0x80 window in the post-office mailbox bank. No interrupts are described for it and the host polls it. Add apple,t8152-ans-mailbox and only require interrupts for the other mailboxes. Signed-off-by: Thomas Glanzmann Signed-off-by: Acelogic --- .../bindings/mailbox/apple,mailbox.yaml | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml b/Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml index cd19124e724c3..1a40e2e38786b 100644 --- a/Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml +++ b/Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml @@ -75,6 +75,11 @@ properties: AOP setup-port mailbox with a separate register layout. const: apple,t8140-aop-setup-mailbox + - description: + T8152 ANS post-office mailbox, a 0x80 window in the post-office + bank. No interrupts are described for it; the host polls it. + const: apple,t8152-ans-mailbox + - description: An older ASC mailbox interface found on T2 and A11 that is also used for the NVMe coprocessor and the system management @@ -148,6 +153,20 @@ allOf: - const: send-empty - const: recv-not-empty + - if: + properties: + compatible: + contains: + const: apple,t8152-ans-mailbox + then: + properties: + interrupts: false + interrupt-names: false + else: + required: + - interrupts + - interrupt-names + - if: properties: compatible: @@ -211,8 +230,6 @@ allOf: required: - compatible - reg - - interrupts - - interrupt-names - "#mbox-cells" additionalProperties: false From 2c87179a0c0888cb5d9d4b80c2df50754662d93f Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sat, 24 Oct 2026 13:30:24 +0200 Subject: [PATCH 04/31] soc: apple: sart: add the T8152 coastguard SART (sart-version 4) Config, paddr and size registers at 0x00, 0x60 and 0xc0 per entry, in 4 KiB units, as m1n1 src/sart.c. Needed by ANS2 on the M6 Mac mini. Signed-off-by: Thomas Glanzmann [Acelogic: Exercised on the ported code by a read-only probe on the M6; write testing was done on Thomas Glanzmann's original J873 series.] Signed-off-by: Acelogic --- drivers/soc/apple/sart.c | 41 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/soc/apple/sart.c b/drivers/soc/apple/sart.c index 6cedcb867c61b..c44b14c655be8 100644 --- a/drivers/soc/apple/sart.c +++ b/drivers/soc/apple/sart.c @@ -195,6 +195,43 @@ static void sart3_set_entry(struct apple_sart *sart, int index, u8 flags, writel(flags, sart->regs + APPLE_SART3_CONFIG(index)); } +#define APPLE_SART4_CONFIG(idx) (0x00 + 4 * (idx)) +#define APPLE_SART4_PADDR(idx) (0x60 + 4 * (idx)) +#define APPLE_SART4_PADDR_SHIFT 12 +#define APPLE_SART4_SIZE(idx) (0xc0 + 4 * (idx)) +#define APPLE_SART4_SIZE_SHIFT 12 +#define APPLE_SART4_SIZE_MAX GENMASK(29, 0) +#define APPLE_SART4_FLAGS_ALLOW 0xff + +/* T8152 "coastguard" SART (ADT sart-version 4), layout as m1n1 src/sart.c. */ +static void sart4_get_entry(struct apple_sart *sart, int index, u8 *flags, + phys_addr_t *paddr, size_t *size) +{ + phys_addr_t paddr_ = readl(sart->regs + APPLE_SART4_PADDR(index)); + size_t size_ = readl(sart->regs + APPLE_SART4_SIZE(index)); + + *flags = readl(sart->regs + APPLE_SART4_CONFIG(index)); + *size = size_ << APPLE_SART4_SIZE_SHIFT; + *paddr = paddr_ << APPLE_SART4_PADDR_SHIFT; +} + +static void sart4_set_entry(struct apple_sart *sart, int index, u8 flags, + phys_addr_t paddr_shifted, size_t size_shifted) +{ + writel(paddr_shifted, sart->regs + APPLE_SART4_PADDR(index)); + writel(size_shifted, sart->regs + APPLE_SART4_SIZE(index)); + writel(flags, sart->regs + APPLE_SART4_CONFIG(index)); +} + +static struct apple_sart_ops sart_ops_v4 = { + .get_entry = sart4_get_entry, + .set_entry = sart4_set_entry, + .flags_allow = APPLE_SART4_FLAGS_ALLOW, + .size_shift = APPLE_SART4_SIZE_SHIFT, + .paddr_shift = APPLE_SART4_PADDR_SHIFT, + .size_max = APPLE_SART4_SIZE_MAX, +}; + static struct apple_sart_ops sart_ops_v3 = { .get_entry = sart3_get_entry, .set_entry = sart3_set_entry, @@ -409,6 +446,10 @@ static void apple_sart_shutdown(struct platform_device *pdev) } static const struct of_device_id apple_sart_of_match[] = { + { + .compatible = "apple,t8152-sart", + .data = &sart_ops_v4, + }, { .compatible = "apple,t6000-sart", .data = &sart_ops_v3, From 83e97d02765cd2e67204615e97a732c3a681fec5 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sat, 24 Oct 2026 13:30:24 +0200 Subject: [PATCH 05/31] soc: apple: mailbox: add the J873 ANS post-office mailbox Add a polled, interrupt-free provider for the ANS post-office window. ANS uses mailbox 3 of the non-alias post-office bank (0x316010300), a 0x80-byte window with the same counted-FIFO layout as the T8152 SMC mailbox. No interrupt is described for it, so the provider claims none: receive runs on the receive poller of the GFX ASCWrap v8 provider, send polls the FIFO status, and the receive hold/release hooks do nothing for it. It binds only on the J873, at exactly that window. Signed-off-by: Thomas Glanzmann [Acelogic: adapted for aurora-wip, which has no PMP post-office provider: the original made the PMP provider's J873 window check per hardware entry and added ANS next to PMP; here the polled mode is added for the ANS entry alone. Exercised on the ported code by a read-only probe on the M6; write testing was done on Thomas Glanzmann's original J873 series.] Co-developed-by: Acelogic Signed-off-by: Acelogic --- drivers/soc/apple/mailbox.c | 63 +++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/drivers/soc/apple/mailbox.c b/drivers/soc/apple/mailbox.c index c13c03f9d92ab..8e864229d5efe 100644 --- a/drivers/soc/apple/mailbox.c +++ b/drivers/soc/apple/mailbox.c @@ -220,6 +220,10 @@ struct apple_mbox_hw { unsigned int num_ascwrap_v6_roles; /* T8152 GPU ASCWrap v8: wrapper + iop-vbar + post-office window + PSD. */ bool is_ascwrap_v8; + /* No interrupts are described; receive and send are polled. */ + bool rx_poll_required; + /* J873 post-office window a polled provider must sit at. */ + u64 j873_window; /* Status word counts RX occupancy and free TX slots; paired transfers. */ bool counted_fifo; bool ap_initializes_mailboxes; @@ -251,7 +255,7 @@ struct apple_mbox_priv { struct apple_mbox mbox; /* ASCWrap v8 only: the provider's PMGR2 PSD service block (read-only). */ void __iomem *psd_regs; - /* ASCWrap v8 only: receive by polling; fixed at probe. */ + /* ASCWrap v8 and polled providers: receive by polling; fixed at probe. */ bool rx_poll_only; /* rx_lock: recv interrupt enabled and not yet disabled again. */ bool rx_irq_live; @@ -270,7 +274,7 @@ static struct apple_mbox_priv *apple_mbox_to_priv(struct apple_mbox *mbox) /* Only providers allocated by apple_mbox_probe() have a receive poller. */ static bool apple_mbox_has_rx_poller(const struct apple_mbox *mbox) { - return mbox->hw->is_ascwrap_v8; + return mbox->hw->is_ascwrap_v8 || mbox->hw->rx_poll_required; } /* Both ASCWrap generations share the consumer lifecycle API below. */ @@ -1038,12 +1042,17 @@ EXPORT_SYMBOL(apple_mbox_stop); void apple_mbox_hold_rx(struct apple_mbox *mbox) { + /* A polled provider claims no receive interrupt. */ + if (mbox->hw->rx_poll_required) + return; disable_irq(mbox->irq_recv_not_empty); } EXPORT_SYMBOL(apple_mbox_hold_rx); void apple_mbox_release_rx(struct apple_mbox *mbox) { + if (mbox->hw->rx_poll_required) + return; enable_irq(mbox->irq_recv_not_empty); } EXPORT_SYMBOL(apple_mbox_release_rx); @@ -1105,7 +1114,8 @@ static void apple_mbox_quiesce(void *data) if (mbox->irq_send_empty >= 0) synchronize_irq(mbox->irq_send_empty); complete_all(&mbox->tx_empty); - synchronize_irq(mbox->irq_recv_not_empty); + if (mbox->irq_recv_not_empty >= 0) + synchronize_irq(mbox->irq_recv_not_empty); spin_lock_irqsave(&mbox->rx_lock, flags); had_rx = mbox->rx; @@ -1369,6 +1379,16 @@ static int apple_mbox_probe(struct platform_device *pdev) return ret; } else { res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + /* + * A polled provider must be exactly its own 0x80-byte window of + * the J873 post-office bank; the rest belongs to other roles. + */ + if (mbox->hw->rx_poll_required && + (!of_machine_is_compatible("apple,j873g") || !res || + res->start != mbox->hw->j873_window || + resource_size(res) != APPLE_ASCWRAP_V8_MBOX_SIZE)) + return dev_err_probe(dev, -EINVAL, + "post-office window does not match the J873 profile\n"); if (!res || resource_size(res) < mbox->hw->reg_offset + mbox->hw->i2a_recv1 + sizeof(u64)) return dev_err_probe(dev, -EINVAL, @@ -1380,6 +1400,21 @@ static int apple_mbox_probe(struct platform_device *pdev) mbox->regs = (u8 __iomem *)mbox->regs + mbox->hw->reg_offset; } + if (mbox->hw->rx_poll_required) { + mbox->rx_util_min = -1; + mbox->rx_util_min_applied = -1; + spin_lock_init(&mbox->rx_lock); + spin_lock_init(&mbox->tx_lock); + mutex_init(&mbox->lifecycle_lock); + init_completion(&mbox->tx_empty); + priv->rx_poll_only = true; + INIT_DELAYED_WORK(&priv->rx_poll_work, apple_mbox_v8_rx_poll_work); + mbox->irq_recv_not_empty = -ENXIO; + mbox->irq_send_empty = -ENXIO; + dev_info(dev, "J873 post-office: paired transfers, bounded polling, no IRQ claim\n"); + goto setup_pm; + } + mbox->irq_recv_not_empty = platform_get_irq_byname(pdev, "recv-not-empty"); if (mbox->irq_recv_not_empty < 0) @@ -1431,6 +1466,7 @@ static int apple_mbox_probe(struct platform_device *pdev) return ret; } +setup_pm: ret = devm_pm_runtime_enable(dev); if (ret) return ret; @@ -1706,8 +1742,29 @@ static const struct apple_mbox_hw apple_mbox_t8152_smc_hw = { .has_irq_controls = false, }; +/* + * T8152 ANS: msgbox-mailbox-num 3 in the non-alias post-office bank, the + * same counted FIFO as the SMC mailbox. Its interrupt ordering is not known, + * so no interrupt is described and both directions are polled. + */ +static const struct apple_mbox_hw apple_mbox_t8152_ans_hw = { + .rx_poll_required = true, + .j873_window = 0x316010300ULL, + .counted_fifo = true, + .control_full = GENMASK(11, 8), /* free TX slots */ + .control_empty = GENMASK(3, 0), /* RX occupancy */ + .a2i_control = 0x20, + .a2i_send0 = 0x10, + .a2i_send1 = 0x18, + .i2a_control = 0x20, + .i2a_recv0 = 0x00, + .i2a_recv1 = 0x08, + .has_irq_controls = false, +}; + static const struct of_device_id apple_mbox_of_match[] = { { .compatible = "apple,t8152-smc-mailbox", .data = &apple_mbox_t8152_smc_hw }, + { .compatible = "apple,t8152-ans-mailbox", .data = &apple_mbox_t8152_ans_hw }, { .compatible = "apple,t6031-agx-asc-mailbox", .data = &apple_mbox_asc_hw }, { .compatible = "apple,t8122-agx-asc-mailbox", .data = &apple_mbox_asc_hw }, { .compatible = "apple,t8152-gfx-ascwrap-v8", .data = &apple_mbox_t8152_gfx_ascwrap_v8_hw }, From 81bc2a911813a8367a10fde004b7eb2bce28625c Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sat, 24 Oct 2026 13:30:25 +0200 Subject: [PATCH 06/31] nvme: apple: add T8152 (M6) with the secure register layout The M6 ADT marks ANS2 with nvme-secure-reg-layout: as in macOS AppleANS2NVMeController with its 0x92a flag, AQA/ASQ/ACQ and the I/O queue registers move up by 0x4000 and LINEAR_SQ_CTRL moves to 0x2813c; CC/CSTS, doorbells and NVMMU stay. NVMe and NVMMU share one window, and there is no reset provider yet. Reads and writes verified on J873. Signed-off-by: Thomas Glanzmann [Acelogic: adapted for aurora-wip: the T8152 entry joins the T8142 and T6040 ones and sets NVME_QUIRK_BROKEN_FUA like the T8132, T8140 and T8142 entries, and the moved LINEAR_SQ_CTRL is used inside the existing lsq_in_nvmmu check. The read and write verification above was on Thomas Glanzmann's original J873 series; the ported code is exercised by a read-only probe on the M6.] Signed-off-by: Acelogic --- drivers/nvme/host/apple.c | 68 ++++++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 12 deletions(-) diff --git a/drivers/nvme/host/apple.c b/drivers/nvme/host/apple.c index e4c9a1ccd38a0..08ec93ad92780 100644 --- a/drivers/nvme/host/apple.c +++ b/drivers/nvme/host/apple.c @@ -65,6 +65,15 @@ #define APPLE_ANS_LINEAR_ASQ_DB 0x2490c #define APPLE_ANS_LINEAR_IOSQ_DB 0x24910 +/* + * ADT nvme-secure-reg-layout (T8152, macOS AppleANS2NVMeController with its + * 0x92a flag set): AQA/ASQ/ACQ and the I/O queue registers move up by + * 0x4000 and LINEAR_SQ_CTRL moves into the NVMMU block. CC/CSTS, the + * doorbells and the NVMMU TCB registers stay where they are. + */ +#define APPLE_ANS_SECURE_QREG_SHIFT 0x4000 +#define APPLE_ANS_SECURE_LINEAR_SQ_CTRL 0x2813c + #define APPLE_NVMMU_NUM_TCBS 0x28100 #define APPLE_NVMMU_ASQ_TCB_BASE 0x28108 #define APPLE_NVMMU_IOSQ_TCB_BASE 0x28110 @@ -208,6 +217,9 @@ struct apple_nvme_hw { bool needs_ioq_registers; /* T8132 needs a PMGR reset when starting a stopped coprocessor. */ bool cold_reset; + /* No reset provider yet; only an adopted live session can come up. */ + bool optional_reset; + bool secure_reg_layout; u32 max_queue_depth; unsigned long quirks; }; @@ -377,6 +389,17 @@ static int apple_nvme_read_handoff(struct apple_nvme *anv) return apple_nvme_can_adopt_rtkit(anv) ? 0 : -EIO; } +static u32 apple_nvme_qreg(const struct apple_nvme *anv, u32 reg) +{ + return anv->hw->secure_reg_layout ? reg + APPLE_ANS_SECURE_QREG_SHIFT : reg; +} + +static u32 apple_nvme_lsq_ctrl(const struct apple_nvme *anv) +{ + return anv->hw->secure_reg_layout ? APPLE_ANS_SECURE_LINEAR_SQ_CTRL : + APPLE_ANS_LINEAR_SQ_CTRL; +} + static inline struct apple_nvme *queue_to_apple_nvme(struct apple_nvme_queue *q) { if (q->is_adminq) @@ -1786,10 +1809,10 @@ static void apple_nvme_reset_work(struct work_struct *work) */ if (!anv->hw->lsq_in_nvmmu) { writel(APPLE_ANS_LINEAR_SQ_EN, - anv->mmio_nvme + APPLE_ANS_LINEAR_SQ_CTRL); + anv->mmio_nvme + apple_nvme_lsq_ctrl(anv)); if (anv->hw->needs_ioq_registers) { u32 lsq_ctrl = readl(anv->mmio_nvme + - APPLE_ANS_LINEAR_SQ_CTRL); + apple_nvme_lsq_ctrl(anv)); if (!(lsq_ctrl & APPLE_ANS_LINEAR_SQ_EN)) { dev_err(anv->dev, @@ -1812,9 +1835,11 @@ static void apple_nvme_reset_work(struct work_struct *work) if (anv->hw->needs_ioq_registers) ioqa_depth--; ioqa = ioqa_depth | (ioqa_depth << 16); - writel(ioqa, anv->mmio_nvme + APPLE_ANS_MAX_PEND_CMDS_CTRL); + writel(ioqa, anv->mmio_nvme + + apple_nvme_qreg(anv, APPLE_ANS_MAX_PEND_CMDS_CTRL)); if (anv->hw->needs_ioq_registers && - readl(anv->mmio_nvme + APPLE_ANS_MAX_PEND_CMDS_CTRL) != ioqa) { + readl(anv->mmio_nvme + + apple_nvme_qreg(anv, APPLE_ANS_MAX_PEND_CMDS_CTRL)) != ioqa) { dev_err(anv->dev, "failed to program I/O queue aperture\n"); ret = -EIO; goto out; @@ -1828,11 +1853,11 @@ static void apple_nvme_reset_work(struct work_struct *work) /* Setup the admin queue */ aqa = APPLE_NVME_AQ_DEPTH - 1; aqa |= aqa << 16; - writel(aqa, anv->mmio_nvme + NVME_REG_AQA); + writel(aqa, anv->mmio_nvme + apple_nvme_qreg(anv, NVME_REG_AQA)); apple_nvme_writeq(anv, anv->adminq.sq_dma_addr, - anv->mmio_nvme + NVME_REG_ASQ); + anv->mmio_nvme + apple_nvme_qreg(anv, NVME_REG_ASQ)); apple_nvme_writeq(anv, anv->adminq.cq_dma_addr, - anv->mmio_nvme + NVME_REG_ACQ); + anv->mmio_nvme + apple_nvme_qreg(anv, NVME_REG_ACQ)); if (anv->hw->has_lsq_nvmmu) { /* Setup NVMMU for both queues */ @@ -1899,10 +1924,10 @@ static void apple_nvme_reset_work(struct work_struct *work) * dedicated registers. Without them it crashes and its crash log * reports null I/O SQ and CQ addresses. */ - apple_nvme_writeq(anv, anv->ioq.cq_dma_addr, - anv->mmio_nvme + APPLE_ANS_IOCQ_REGISTER); - apple_nvme_writeq(anv, anv->ioq.sq_dma_addr, - anv->mmio_nvme + APPLE_ANS_IOSQ_REGISTER); + apple_nvme_writeq(anv, anv->ioq.cq_dma_addr, anv->mmio_nvme + + apple_nvme_qreg(anv, APPLE_ANS_IOCQ_REGISTER)); + apple_nvme_writeq(anv, anv->ioq.sq_dma_addr, anv->mmio_nvme + + apple_nvme_qreg(anv, APPLE_ANS_IOSQ_REGISTER)); } nr_io_queues = 1; if (anv->hw->has_queue_count) { @@ -2393,7 +2418,10 @@ static struct apple_nvme *apple_nvme_alloc(struct platform_device *pdev) goto out_detach_genpd; } - anv->reset = devm_reset_control_array_get_exclusive(anv->dev); + if (anv->hw->optional_reset) + anv->reset = devm_reset_control_array_get_optional_exclusive(anv->dev); + else + anv->reset = devm_reset_control_array_get_exclusive(anv->dev); if (IS_ERR(anv->reset)) { ret = dev_err_probe(dev, PTR_ERR(anv->reset), "Failed to get reset control"); @@ -2754,6 +2782,21 @@ static const struct apple_nvme_hw apple_nvme_t6040_hw = { .quirks = NVME_QUIRK_NO_APST, }; +/* + * T8152 uses the post-M4 queue setup, but its NVMe registers and NVMMU share + * one window (0x325cc0000 on J873) like T8103, with the secure register + * layout. There is no T8152 PMGR driver yet, so the controller has no reset + * line in the DT. + */ +static const struct apple_nvme_hw apple_nvme_t8152_hw = { + .has_lsq_nvmmu = true, + .needs_ioq_registers = true, + .optional_reset = true, + .secure_reg_layout = true, + .max_queue_depth = 64, + .quirks = NVME_QUIRK_BROKEN_FUA, +}; + static const struct of_device_id apple_nvme_of_match[] = { { .compatible = "apple,t6041-nvme-ans2", .data = &apple_nvme_t6040_hw }, { .compatible = "apple,t8015-nvme-ans2", .data = &apple_nvme_t8015_hw }, @@ -2761,6 +2804,7 @@ static const struct of_device_id apple_nvme_of_match[] = { { .compatible = "apple,t8132-nvme-ans2", .data = &apple_nvme_t8132_hw }, { .compatible = "apple,t8140-nvme-ans2", .data = &apple_nvme_t8140_hw }, { .compatible = "apple,t8142-nvme-ans2", .data = &apple_nvme_t8142_hw }, + { .compatible = "apple,t8152-nvme-ans2", .data = &apple_nvme_t8152_hw }, { .compatible = "apple,nvme-ans2", .data = &apple_nvme_t8103_hw }, {}, }; From a400e257002e585430953a2a24082acd1c716f7f Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 15:11:45 +0100 Subject: [PATCH 07/31] nvme: apple: send the shutdown notification on T8152 The post-M4 disable path only clears CC.EN, so the ANS firmware treats every system shutdown as unclean: on the next boot it logs "uncleanReboot yes" and abandons its open bands (host SLC, parity, CLOG). On T8152, send the NVMe shutdown notification (CC.SHN normal, wait for CSTS.SHST complete) before the CC.EN clear on system shutdown. The RTKit co-processor is still left running, as before. Tested on a J873 (Mac mini M6): after a reboot the firmware no longer reports an unclean reboot (0 instead of 4 "uncleanReboot yes" messages). Signed-off-by: Thomas Glanzmann [Acelogic: adapted for aurora-wip, which already sends the notification at the final system shutdown of every post-M4 controller: T8152 also sends it when the driver is removed, as the original did, but not for system sleep. The test above was on Thomas Glanzmann's original J873 series; the ported code is exercised by a read-only probe on the M6.] Signed-off-by: Acelogic --- drivers/nvme/host/apple.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/nvme/host/apple.c b/drivers/nvme/host/apple.c index 08ec93ad92780..5d59726edeb13 100644 --- a/drivers/nvme/host/apple.c +++ b/drivers/nvme/host/apple.c @@ -220,6 +220,8 @@ struct apple_nvme_hw { /* No reset provider yet; only an adopted live session can come up. */ bool optional_reset; bool secure_reg_layout; + /* Also send the NVMe shutdown notification (CC.SHN) on removal. */ + bool shutdown_notify; u32 max_queue_depth; unsigned long quirks; }; @@ -1376,10 +1378,13 @@ static int apple_nvme_disable_locked(struct apple_nvme *anv, bool shutdown) * The final system shutdown is the exception for SHN: without it the * controller counts every Linux shutdown as unsafe (SMART * unsafe_shutdowns) and recovers on the next start, which slows the - * loader and the first seconds of I/O. A failed SHN changes nothing: - * the CC.EN clear below still runs. + * loader and the first seconds of I/O. Where the firmware handles it, + * removal sends it too. A failed SHN changes nothing: the CC.EN clear + * below still runs. */ - if (READ_ONCE(anv->final_shutdown) && !apple_rtkit_is_crashed(anv->rtk)) { + if ((READ_ONCE(anv->final_shutdown) || + (shutdown && anv->hw->shutdown_notify && READ_ONCE(anv->removing))) && + !apple_rtkit_is_crashed(anv->rtk)) { ret = nvme_disable_ctrl(&anv->ctrl, true); if (ret) dev_warn(anv->dev, "shutdown notification failed: %d\n", ret); @@ -2793,6 +2798,7 @@ static const struct apple_nvme_hw apple_nvme_t8152_hw = { .needs_ioq_registers = true, .optional_reset = true, .secure_reg_layout = true, + .shutdown_notify = true, .max_queue_depth = 64, .quirks = NVME_QUIRK_BROKEN_FUA, }; From 8eb5187fd12c0b3798aa3a5ca1c9381c662484f1 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sat, 24 Oct 2026 13:30:25 +0200 Subject: [PATCH 08/31] arm64: dts: apple: j873: ANS2 NVMe Mailbox, SART and NVMe nodes for the internal SSD. The driver wakes iBoot's running ANS firmware with a fresh RTKit handshake. Signed-off-by: Thomas Glanzmann [Acelogic: adapted for aurora-wip: the nodes go into t8152-j873-nvme.dtsi, which t8152-j873g.dts includes, instead of a separate t8152-j873-nvme.dtb layered on the USB tree. Exercised on the ported code by a read-only probe on the M6; write testing was done on Thomas Glanzmann's original J873 series.] Signed-off-by: Acelogic --- .../arm64/boot/dts/apple/t8152-j873-nvme.dtsi | 35 +++++++++++++++++++ arch/arm64/boot/dts/apple/t8152-j873g.dts | 1 + 2 files changed, 36 insertions(+) create mode 100644 arch/arm64/boot/dts/apple/t8152-j873-nvme.dtsi diff --git a/arch/arm64/boot/dts/apple/t8152-j873-nvme.dtsi b/arch/arm64/boot/dts/apple/t8152-j873-nvme.dtsi new file mode 100644 index 0000000000000..c53059ab55d34 --- /dev/null +++ b/arch/arm64/boot/dts/apple/t8152-j873-nvme.dtsi @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * J873g ANS2 NVMe. + * iBoot leaves the ANS firmware running with the NVMe controller disabled; + * the driver wakes it with a fresh RTKit handshake (as m1n1 does). NVMe + * registers and NVMMU share the 0x325cc0000 window. The mailbox is the ANS + * post-office window (msgbox-mailbox-num 3, no alias: 0x316000000 + + * 0x10300). No PMGR power or reset yet. + * Resources are from the 26A434 ADT: ans, sart-ans. + */ + +/ { + soc { + ans_mbox: mailbox@316010300 { + compatible = "apple,t8152-ans-mailbox"; + reg = <0x3 0x16010300 0x0 0x80>; + #mbox-cells = <0>; + }; + + sart: iommu@325c50000 { + compatible = "apple,t8152-sart"; + reg = <0x3 0x25c50000 0x0 0xc000>; + }; + + nvme: nvme@325cc0000 { + compatible = "apple,t8152-nvme-ans2"; + reg = <0x3 0x25cc0000 0x0 0x60000>, + <0x3 0x21600000 0x0 0x4000>; + reg-names = "nvme", "ans"; + interrupts = ; + mboxes = <&ans_mbox>; + apple,sart = <&sart>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apple/t8152-j873g.dts b/arch/arm64/boot/dts/apple/t8152-j873g.dts index 1513a2abbc83f..77e5e1abdf18a 100644 --- a/arch/arm64/boot/dts/apple/t8152-j873g.dts +++ b/arch/arm64/boot/dts/apple/t8152-j873g.dts @@ -286,3 +286,4 @@ #include "t8152-j873-pmc.dtsi" #include "t8152-j873-qspi.dtsi" +#include "t8152-j873-nvme.dtsi" From 9c56293bc07aab63f5b09dd1502bf5e35f0c0425 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sat, 24 Oct 2026 12:35:44 +0200 Subject: [PATCH 09/31] arm64: dts: apple: j873: USB1 (back-left) USB2 host bring-up Describe usb-drd1 as a plain DWC3 host behind its two T8110-style DARTs. The loader powers the controller, wakes the port's HPM (SSPS 0) and initialises the eUSB2 PHY in host mode before Linux starts. Resources are from the 26A434 ADT. A USB keyboard enumerates. Signed-off-by: Thomas Glanzmann [Acelogic: adapted for aurora-wip: the nodes go into t8152-j873-usb.dtsi, which t8152-j873g.dts includes, instead of a separate t8152-j873-usb.dtb. dtbs_check warns that the snps,dwc3 binding allows one iommus entry; the controller sits behind two DARTs, as described here.] Signed-off-by: Acelogic --- arch/arm64/boot/dts/apple/t8152-j873-usb.dtsi | 37 +++++++++++++++++++ arch/arm64/boot/dts/apple/t8152-j873g.dts | 1 + 2 files changed, 38 insertions(+) create mode 100644 arch/arm64/boot/dts/apple/t8152-j873-usb.dtsi diff --git a/arch/arm64/boot/dts/apple/t8152-j873-usb.dtsi b/arch/arm64/boot/dts/apple/t8152-j873-usb.dtsi new file mode 100644 index 0000000000000..59f0dcf394617 --- /dev/null +++ b/arch/arm64/boot/dts/apple/t8152-j873-usb.dtsi @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * J873g USB1 (usb-drd1, back-left port) USB2 host bring-up. + * The loader powers the controller and initialises the eUSB2 PHY in host + * mode before Linux starts (no PMGR, PHY or Type-C driver yet), so the + * controller is described as a plain DWC3 host behind its two DARTs. + * Resources are from the 26A434 ADT: dart-usb1, usb-drd1. + */ + +/ { + soc { + usb1_dart0: iommu@40b020000 { + compatible = "apple,t8152-dart", "apple,t8110-dart"; + reg = <0x4 0x0b020000 0x0 0xc000>; + interrupts = ; + #iommu-cells = <1>; + }; + + usb1_dart1: iommu@40b040000 { + compatible = "apple,t8152-dart", "apple,t8110-dart"; + reg = <0x4 0x0b040000 0x0 0xc000>; + interrupts = ; + #iommu-cells = <1>; + }; + + usb1: usb@40a430000 { + compatible = "snps,dwc3"; + reg = <0x4 0x0a430000 0x0 0xcd00>; + interrupts = ; + dr_mode = "host"; + maximum-speed = "high-speed"; + iommus = <&usb1_dart0 0>, <&usb1_dart1 1>; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apple/t8152-j873g.dts b/arch/arm64/boot/dts/apple/t8152-j873g.dts index 77e5e1abdf18a..ac38151e0acb0 100644 --- a/arch/arm64/boot/dts/apple/t8152-j873g.dts +++ b/arch/arm64/boot/dts/apple/t8152-j873g.dts @@ -287,3 +287,4 @@ #include "t8152-j873-pmc.dtsi" #include "t8152-j873-qspi.dtsi" #include "t8152-j873-nvme.dtsi" +#include "t8152-j873-usb.dtsi" From 7c13f45712128843ebce56d9238330339162c627 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sat, 24 Oct 2026 12:42:59 +0200 Subject: [PATCH 10/31] arm64: dts: apple: j873: USB2 host for the front ports (usb-drd2) usb-drd2 feeds the on-board VL822 hub (05ac:800f) behind the two front USB-C ports. Describe it like usb-drd1: plain DWC3 host behind its two DARTs (0x383020000/0x383040000, IRQ 1750), controller IRQ 1763. The loader also releases the hub from reset (nub-gpio 39). Signed-off-by: Thomas Glanzmann [Acelogic: the nodes go into t8152-j873-usb.dtsi; dtbs_check gives the same snps,dwc3 iommus warning as for usb-drd1.] Signed-off-by: Acelogic --- arch/arm64/boot/dts/apple/t8152-j873-usb.dtsi | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/apple/t8152-j873-usb.dtsi b/arch/arm64/boot/dts/apple/t8152-j873-usb.dtsi index 59f0dcf394617..e5cd25e427fe4 100644 --- a/arch/arm64/boot/dts/apple/t8152-j873-usb.dtsi +++ b/arch/arm64/boot/dts/apple/t8152-j873-usb.dtsi @@ -1,10 +1,11 @@ // SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * J873g USB1 (usb-drd1, back-left port) USB2 host bring-up. - * The loader powers the controller and initialises the eUSB2 PHY in host + * J873g USB2 host bring-up: usb-drd1 (back-left port) and usb-drd2 + * (front ports via the on-board hub). + * The loader powers the controllers and initialises the eUSB2 PHYs in host * mode before Linux starts (no PMGR, PHY or Type-C driver yet), so the - * controller is described as a plain DWC3 host behind its two DARTs. - * Resources are from the 26A434 ADT: dart-usb1, usb-drd1. + * controllers are described as plain DWC3 hosts behind their two DARTs. + * Resources are from the 26A434 ADT: dart-usb1/2, usb-drd1/2. */ / { @@ -33,5 +34,31 @@ snps,dis_u2_susphy_quirk; snps,dis_u3_susphy_quirk; }; + + usb2_dart0: iommu@383020000 { + compatible = "apple,t8152-dart", "apple,t8110-dart"; + reg = <0x3 0x83020000 0x0 0xc000>; + interrupts = ; + #iommu-cells = <1>; + }; + + usb2_dart1: iommu@383040000 { + compatible = "apple,t8152-dart", "apple,t8110-dart"; + reg = <0x3 0x83040000 0x0 0xc000>; + interrupts = ; + #iommu-cells = <1>; + }; + + /* usb-drd2: on-board VL822 hub behind the two front USB-C ports. */ + usb2: usb@382430000 { + compatible = "snps,dwc3"; + reg = <0x3 0x82430000 0x0 0xcd00>; + interrupts = ; + dr_mode = "host"; + maximum-speed = "high-speed"; + iommus = <&usb2_dart0 0>, <&usb2_dart1 1>; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + }; }; }; From 199c58c9e45672d45f34bbfe12d4b4f737fa3e59 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 09:45:57 +0100 Subject: [PATCH 11/31] PCI: apple: keep T8152 endpoints at the reset Max_Read_Request_Size On T8152 (J873) the on-board RTL8127A transmits much slower with large read requests: r8169 sets MRRS to 4096, which limits 9000-byte frames to 7.0 Gbit/s (UDP, iperf3 to an ixgbe peer). At 2048 it reaches 7.9, at 1024, 512 or 256 the full 9.93 Gbit/s; at MTU 1500 TCP Tx goes from 9.1 to 9.4 Gbit/s and UDP Tx from 7.9 to 9.5. Set no_inc_mrrs on the T8152 host bridge so devices keep the 512-byte reset value and drivers cannot raise it. Signed-off-by: Thomas Glanzmann Signed-off-by: Acelogic --- drivers/pci/controller/pcie-apple.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c index 3173186c85209..a378955bb922c 100644 --- a/drivers/pci/controller/pcie-apple.c +++ b/drivers/pci/controller/pcie-apple.c @@ -224,6 +224,12 @@ struct hw_info { * lane PIPE reset status, then release PORT_T8152_PIPE_RST. */ bool pipe_rst; + /* + * Keep endpoints at their reset Max_Read_Request_Size (512 bytes). + * On T8152 an RTL8127 at MRRS 4096 (what r8169 asks for) transmits + * 9000-byte frames at 7.0 Gbit/s; at 512 it reaches 9.93. + */ + bool no_inc_mrrs; }; static const struct hw_info t8103_hw = { @@ -279,6 +285,7 @@ static const struct hw_info t8152_hw = { .max_rid2sid = 512, .refbuf_off = true, .pipe_rst = true, + .no_inc_mrrs = true, }; static const struct hw_info t8103_pciec_hw = { @@ -3116,6 +3123,7 @@ static int apple_pcie_probe(struct platform_device *pdev) pcie = pci_host_bridge_priv(bridge); pcie->dev = dev; pcie->hw = hw; + bridge->no_inc_mrrs = hw->no_inc_mrrs; if (of_property_present(dev->of_node, "apple,managed-sids")) { u32 ids[15]; int count = of_property_count_u32_elems(dev->of_node, "apple,managed-sids"); From 1ef5ecd7bc670f4a678d4698e36ae8a017da7552 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sat, 24 Oct 2026 14:58:10 +0200 Subject: [PATCH 12/31] arm64: dts: apple: j873: apcie port 2 with the on-board 10GbE NIC Describe apcie port 2 next to port 0 (N1): its DART (dart-apcie2), the port with PERST# on AP GPIO 5 and its INTx controller and bus range like the other Apple root ports, and the NIC (MAC address filled in by the loader). The ADT names an aqc107 there; the device has PCI ID 10ec:8127 and is driven by r8169. pcie-apple brings the port up with the T602x port layout plus two steps from macOS: clear PHY_LANE_CFG bit 4 in the refclk handshake (AppleT8152PCIePort::_initializeRefclkBuffer), and after PERST# wait for the lane PIPE reset status (port 0xa8) and clear port 0x82c bit 16 (APCIECoreRCGen5Port::enablePortHardware). The loader must first ungate the AUS5 PHY and write lane-cfg to RC reg 4. Link: Gen3 x1, 10Gbps. Signed-off-by: Thomas Glanzmann [Acelogic: adapted for aurora-wip, where the T8152 hw entry, both macOS steps, the AP GPIO controller and port 0 (N1) already exist: only the device tree part remains, in t8152-j873-ethernet.dtsi, squashed with the original follow-up that describes the port per the binding, and the subject changed to match. Port 2 is bus 2 (RID 0x200 to dart-apcie2 stream 1), and the per-port interrupts are listed up to port 2. A port 2 setup failure (lanes stuck in PIPE reset, for example) fails the whole host, port 0 included, so the aura loader's j873_pcie_prep() (PHY tunables, AUS5 ungate, lane-cfg, dart-apcie0/2 tunables) must run before Linux starts. At runtime the NIC identifies as RTL8125CP (XID 0x708).] Signed-off-by: Acelogic --- .../boot/dts/apple/t8152-j873-ethernet.dtsi | 67 +++++++++++++++++++ arch/arm64/boot/dts/apple/t8152-j873g.dts | 1 + 2 files changed, 68 insertions(+) create mode 100644 arch/arm64/boot/dts/apple/t8152-j873-ethernet.dtsi diff --git a/arch/arm64/boot/dts/apple/t8152-j873-ethernet.dtsi b/arch/arm64/boot/dts/apple/t8152-j873-ethernet.dtsi new file mode 100644 index 0000000000000..a2350ed7bee4e --- /dev/null +++ b/arch/arm64/boot/dts/apple/t8152-j873-ethernet.dtsi @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * J873g internal PCIe (apcie) port 2: the on-board 10GbE NIC (ADT + * /arm-io/apcie/pci-bridge2/lan0; the ADT names an aqc107, the device has + * PCI ID 10ec:8127 and identifies as a Realtek RTL8125CP, XID 0x708). + * iBoot leaves the APCIE power domains on and + * the root complex enabled, but the AUS5 PHY gated and the lanes assigned + * to port 0; the loader ungates the PHY, writes the ADT lane-cfg and applies + * the dart-apcie2 tunables first. Port setup follows the T602x/T8122 + * register layout. Port 0 (N1) is bus 1, port 2 is bus 2. + * Resources are from the 26A434 ADT: apcie, dart-apcie2, gpio0. + */ +#include + +/ { + soc { + pcie2_dart: iommu@38a000000 { + compatible = "apple,t8152-dart", "apple,t8110-dart"; + reg = <0x3 0x8a000000 0x0 0xc000>; + #iommu-cells = <1>; + interrupts = ; + }; + }; +}; + +&pcie { + reg = <0x1c 0xb0000000 0x0 0x1000000>, /* config */ + <0x3 0x8c000000 0x0 0x4000>, /* rc */ + <0x3 0x88028000 0x0 0x4000>, /* port0 */ + <0x3 0x8f010000 0x0 0x4000>, /* phy0 */ + <0x3 0x8a028000 0x0 0x4000>, /* port2 */ + <0x3 0x8f018000 0x0 0x4000>; /* phy2 */ + reg-names = "config", "rc", "port0", "phy0", "port2", "phy2"; + /* One per root port, indexed by the port number. */ + interrupts = , + , + ; + iommu-map = <0x100 &pcie0_dart 1 1>, + <0x101 &pcie0_dart 2 1>, + <0x102 &pcie0_dart 3 1>, + <0x200 &pcie2_dart 1 1>; + bus-range = <0 7>; + + port02: pci@2,0 { + device_type = "pci"; + reg = <0x1000 0x0 0x0 0x0 0x0>; + reset-gpios = <&pinctrl_ap 5 GPIO_ACTIVE_LOW>; + bus-range = <2 2>; + #address-cells = <3>; + #size-cells = <2>; + ranges; + + interrupt-controller; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &port02 0 0 0 0>, + <0 0 0 2 &port02 0 0 0 1>, + <0 0 0 3 &port02 0 0 0 2>, + <0 0 0 4 &port02 0 0 0 3>; + + ethernet0: ethernet@0,0 { + reg = <0x20000 0x0 0x0 0x0 0x0>; + /* Filled in by the loader from the ADT. */ + local-mac-address = [00 00 00 00 00 00]; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apple/t8152-j873g.dts b/arch/arm64/boot/dts/apple/t8152-j873g.dts index ac38151e0acb0..67c7c9c0d4f44 100644 --- a/arch/arm64/boot/dts/apple/t8152-j873g.dts +++ b/arch/arm64/boot/dts/apple/t8152-j873g.dts @@ -288,3 +288,4 @@ #include "t8152-j873-qspi.dtsi" #include "t8152-j873-nvme.dtsi" #include "t8152-j873-usb.dtsi" +#include "t8152-j873-ethernet.dtsi" From cef0a05d16eccf6b7f4394d66f4666953eb7b6e8 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 22:53:27 +0100 Subject: [PATCH 13/31] arm64: dts: apple: j873: ethernet0 alias Boot loaders (m1n1, aura) fill in the on-board NIC's MAC address through the ethernet0 alias, as on the other Apple machines. Signed-off-by: Thomas Glanzmann [Acelogic: adapted for aurora-wip: the alias goes into t8152-j873-ethernet.dtsi.] Signed-off-by: Acelogic --- arch/arm64/boot/dts/apple/t8152-j873-ethernet.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t8152-j873-ethernet.dtsi b/arch/arm64/boot/dts/apple/t8152-j873-ethernet.dtsi index a2350ed7bee4e..66965f04af13d 100644 --- a/arch/arm64/boot/dts/apple/t8152-j873-ethernet.dtsi +++ b/arch/arm64/boot/dts/apple/t8152-j873-ethernet.dtsi @@ -13,6 +13,10 @@ #include / { + aliases { + ethernet0 = ðernet0; + }; + soc { pcie2_dart: iommu@38a000000 { compatible = "apple,t8152-dart", "apple,t8110-dart"; From 4d0152993810f42ce8b172ec5484ce2397ce4d15 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 21:19:57 +0100 Subject: [PATCH 14/31] dt-bindings: watchdog: apple,wdt: Add T8152 compatible The T8152 (M6) watchdog is compatible with the T8103 one. Signed-off-by: Thomas Glanzmann Signed-off-by: Acelogic --- Documentation/devicetree/bindings/watchdog/apple,wdt.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/watchdog/apple,wdt.yaml b/Documentation/devicetree/bindings/watchdog/apple,wdt.yaml index 00b0f2ec2bdb4..0a21eb27ad083 100644 --- a/Documentation/devicetree/bindings/watchdog/apple,wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/apple,wdt.yaml @@ -24,6 +24,7 @@ properties: - apple,t8122-wdt - apple,t8132-wdt - apple,t8140-wdt + - apple,t8152-wdt - const: apple,t8103-wdt - items: - enum: From c9eeda6528376098cc38f3c5ad4cb3ee41c7a0a1 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 21:19:57 +0100 Subject: [PATCH 15/31] dt-bindings: spmi: apple,spmi: Add T8152 compatible The T8152 (M6) SPMI controller is a fourth generation with its FIFO registers moved to 0x200, so it is not compatible with the T8103 one. Signed-off-by: Thomas Glanzmann [Acelogic: adapted for aurora-wip, which already describes the gen-4 T8142 controller and drives its layout: T8152 takes an apple,t8142-spmi fallback instead of a driver match of its own.] Signed-off-by: Acelogic --- Documentation/devicetree/bindings/spmi/apple,spmi.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/spmi/apple,spmi.yaml b/Documentation/devicetree/bindings/spmi/apple,spmi.yaml index ac2e7407ef780..e504ed9a8871a 100644 --- a/Documentation/devicetree/bindings/spmi/apple,spmi.yaml +++ b/Documentation/devicetree/bindings/spmi/apple,spmi.yaml @@ -38,6 +38,11 @@ properties: - apple,t8132-spmi - apple,t8140-spmi - const: apple,t8103-spmi + - description: + The gen-4 controller of T8152, with its FIFO registers at 0x200. + items: + - const: apple,t8152-spmi + - const: apple,t8142-spmi reg: minItems: 1 From 8c011c1b0d126d784645a3a7f737e614b43df44c Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 21:19:57 +0100 Subject: [PATCH 16/31] dt-bindings: nvmem: apple,spmi-nvmem: Add woodcote PMIC The primary PMU of T8152 (M6) machines is "woodcote" (ADT pmu-main), with the boot flags in the same scratchpad layout as the other Apple PMICs. Signed-off-by: Thomas Glanzmann Signed-off-by: Acelogic --- Documentation/devicetree/bindings/nvmem/apple,spmi-nvmem.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/nvmem/apple,spmi-nvmem.yaml b/Documentation/devicetree/bindings/nvmem/apple,spmi-nvmem.yaml index fe8b2001f4fa5..4a2ba5158b0f6 100644 --- a/Documentation/devicetree/bindings/nvmem/apple,spmi-nvmem.yaml +++ b/Documentation/devicetree/bindings/nvmem/apple,spmi-nvmem.yaml @@ -28,6 +28,7 @@ properties: - apple,simetra-pmic - apple,stowe-pmic - apple,vale-pmic + - apple,woodcote-pmic - const: apple,spmi-nvmem reg: From 5ba4dea4e64d6eeed57f7409999f37a87e10e976 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 14:56:45 +0100 Subject: [PATCH 17/31] mfd: macsmc: register macsmc-reboot on T8152 T8152 registers only macsmc-hwmon. The reboot function only writes the MBSE key, and key writes already work on this SMC. Register macsmc-reboot as well; notifications, GPIO and the power supply stay unregistered. On a J873 (Mac mini M6), reboot then sends MBSE = rest, then phra, and the machine restarts with the boot chime; poweroff sends offw, then off1, and it switches off. Signed-off-by: Thomas Glanzmann [Acelogic: adapted for aurora-wip, whose T8152 hwmon leaves fan control to the firmware: its fan keys are read-only unless the unsafe fan_control parameter is set (in the original, macsmc-hwmon drove the fan through F0md/F0Tg), and the comment says so. The reboot and power off test above was on Thomas Glanzmann's original J873 series.] Signed-off-by: Acelogic --- drivers/mfd/macsmc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/macsmc.c b/drivers/mfd/macsmc.c index 546e5cdbb72ad..2050127a98c57 100644 --- a/drivers/mfd/macsmc.c +++ b/drivers/mfd/macsmc.c @@ -63,9 +63,15 @@ static const struct mfd_cell apple_smc_devs[] = { static const struct mfd_cell apple_smc_low_gpio_dev = MFD_CELL_OF("macsmc-low-gpio", NULL, NULL, 0, 0, "apple,smc-low-gpio"); -/* T8152 currently exposes read-only telemetry; firmware owns fan control. */ +/* + * T8152: temperatures and fans (hwmon; the fan keys are read-only unless the + * unsafe fan_control parameter is set) and power off/restart (reboot, which + * only writes the MBSE key). Notifications, GPIO and the power supply are not + * qualified there yet. + */ static const struct mfd_cell apple_smc_telemetry_devs[] = { MFD_CELL_OF("macsmc-hwmon", NULL, NULL, 0, 0, "apple,smc-hwmon"), + MFD_CELL_OF("macsmc-reboot", NULL, NULL, 0, 0, "apple,smc-reboot"), }; static void apple_smc_read_sram(struct apple_smc *smc, void *buf, size_t size) @@ -546,7 +552,7 @@ static int apple_smc_probe(struct platform_device *pdev) return dev_err_probe(smc->dev, ret, "Failed to get key count"); smc->key_count = be32_to_cpu(count); - /* Notifications, GPIO and power management are not qualified on T8152. */ + /* T8152: key reads and writes are qualified; notifications and GPIO are not. */ if (of_device_is_compatible(dev->of_node, "apple,t8152-smc")) return devm_mfd_add_devices(smc->dev, PLATFORM_DEVID_NONE, apple_smc_telemetry_devs, From 0c2a84ea8f8df23b8318f8b491ac94c0407a482e Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 14:56:45 +0100 Subject: [PATCH 18/31] arm64: dts: apple: j873: SMC power off/restart and the watchdog Describe the SMC reboot function (apple,smc-reboot) and the watchdog (ADT /arm-io/wdt, wdt,t8152, IRQ 447), with a 24 MHz clkref (the ADT timebase-frequency) as on T8103. The PMU NVMEM boot flags are not described yet; macsmc-reboot treats them as optional. The watchdog registers at 24 MHz and provides /dev/watchdog and a restart fallback. Signed-off-by: Thomas Glanzmann [Acelogic: the nodes use the labels of t8152-j873g.dts.] Signed-off-by: Acelogic --- arch/arm64/boot/dts/apple/t8152-j873g.dts | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t8152-j873g.dts b/arch/arm64/boot/dts/apple/t8152-j873g.dts index 67c7c9c0d4f44..36c14293fb6db 100644 --- a/arch/arm64/boot/dts/apple/t8152-j873g.dts +++ b/arch/arm64/boot/dts/apple/t8152-j873g.dts @@ -205,6 +205,15 @@ opp-level = <3>; }; }; + + /* The 24 MHz timebase (ADT timebase-frequency), as on T8103. */ + clkref: clock-ref { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "clkref"; + }; + timer { compatible = "arm,armv8-timer"; interrupts = , @@ -241,6 +250,14 @@ #performance-domain-cells = <0>; }; + /* ADT /arm-io/wdt (wdt,t8152): restart fallback and /dev/watchdog. */ + wdt: watchdog@3082b0000 { + compatible = "apple,t8152-wdt", "apple,t8103-wdt"; + reg = <3 0x082b0000 0 0x4000>; + clocks = <&clkref>; + interrupts = ; + }; + smc_mbox: mailbox@30c710080 { compatible = "apple,t8152-smc-mailbox"; reg = <3 0x0c710080 0 0x80>; @@ -257,6 +274,15 @@ reg-names = "smc", "sram"; mboxes = <&smc_mbox>; + /* + * Power off (MBSE = off1) and restart (MBSE = phra). The + * PMU NVMEM boot flags are not described yet; the driver + * treats them as optional. + */ + smc_reboot: reboot { + compatible = "apple,smc-reboot"; + }; + hwmon { compatible = "apple,smc-hwmon"; apple,discover-temperatures; From 6061934c7964cea3f15b6c06498e511d847abfa3 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 15:11:45 +0100 Subject: [PATCH 19/31] arm64: dts: apple: j873: PMU boot flags on SPMI for power off 'off1' only keeps the machine off when the PMU shutdown flag is set; without it the J873 powered back on into m1n1 at once. Describe nub-spmi0 (gen 4, 0x308714000, 16 KiB) and its primary PMU (pmu-main, "woodcote", slave 0xe) as an apple,spmi-nvmem with the boot flags in its legacy scratchpad (ADT info-leg_scrpad = 0xf800, laid out as on T8103 and T8140): boot_stage 0xf801 (read 0x30, kernel started), boot_error_count and panic_count 0xf802, shutdown_flag 0xf80f bit 3. Hand them to macsmc-reboot. Tested: poweroff now leaves the Mac mini off; reboot still restarts. Signed-off-by: Thomas Glanzmann [Acelogic: the controller takes the apple,t8142-spmi fallback of the aurora-wip binding.] Signed-off-by: Acelogic --- arch/arm64/boot/dts/apple/t8152-j873g.dts | 59 +++++++++++++++++++++-- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/arch/arm64/boot/dts/apple/t8152-j873g.dts b/arch/arm64/boot/dts/apple/t8152-j873g.dts index 36c14293fb6db..180b435f1d969 100644 --- a/arch/arm64/boot/dts/apple/t8152-j873g.dts +++ b/arch/arm64/boot/dts/apple/t8152-j873g.dts @@ -10,6 +10,7 @@ #include #include +#include / { compatible = "apple,j873g", "apple,t8152", "apple,arm-platform"; @@ -250,6 +251,54 @@ #performance-domain-cells = <0>; }; + /* + * ADT /arm-io/nub-spmi0 (gen 4) and its primary PMU, pmu-main + * ("woodcote", slave 0xe). The boot flags live in the legacy + * scratchpad (info-leg_scrpad = 0xf800), laid out as on T8103 + * and T8140; boot_stage read 0x30 (kernel started) here. + */ + nub_spmi0: spmi@308714000 { + /* + * Gen 4: FIFO registers at 0x200 (the block is 0x4000 + * long); polled, so no interrupts are described yet. + */ + compatible = "apple,t8152-spmi", "apple,t8142-spmi"; + reg = <0x3 0x08714000 0x0 0x4000>; + #address-cells = <2>; + #size-cells = <0>; + + pmic@e { + compatible = "apple,woodcote-pmic", "apple,spmi-nvmem"; + reg = <0xe SPMI_USID>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + boot_stage: boot-stage@f801 { + reg = <0xf801 0x1>; + }; + + boot_error_count: boot-error-count@f802,0 { + reg = <0xf802 0x1>; + bits = <0 4>; + }; + + panic_count: panic-count@f802,4 { + reg = <0xf802 0x1>; + bits = <4 4>; + }; + + /* Set before off1, or the machine powers back on. */ + shutdown_flag: shutdown-flag@f80f,3 { + reg = <0xf80f 0x1>; + bits = <3 1>; + }; + }; + }; + }; + /* ADT /arm-io/wdt (wdt,t8152): restart fallback and /dev/watchdog. */ wdt: watchdog@3082b0000 { compatible = "apple,t8152-wdt", "apple,t8103-wdt"; @@ -274,13 +323,13 @@ reg-names = "smc", "sram"; mboxes = <&smc_mbox>; - /* - * Power off (MBSE = off1) and restart (MBSE = phra). The - * PMU NVMEM boot flags are not described yet; the driver - * treats them as optional. - */ + /* Power off (MBSE = off1) and restart (MBSE = phra). */ smc_reboot: reboot { compatible = "apple,smc-reboot"; + nvmem-cells = <&shutdown_flag>, <&boot_stage>, + <&boot_error_count>, <&panic_count>; + nvmem-cell-names = "shutdown_flag", "boot_stage", + "boot_error_count", "panic_count"; }; hwmon { From edd345ad332ce915af32cbb99ae537c50e635fbf Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 21:44:53 +0100 Subject: [PATCH 20/31] dt-bindings: arm: apple: apple,pmgr: Add T8152 compatible The T8152 (M6) PMGR blocks are compatible with the T8103 ones. Signed-off-by: Thomas Glanzmann Signed-off-by: Acelogic --- Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml b/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml index 5d9f55c3e5899..b059430cee63d 100644 --- a/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml +++ b/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml @@ -45,6 +45,7 @@ properties: - apple,t8132-pmgr - apple,t8140-pmgr - apple,t8142-pmgr + - apple,t8152-pmgr - const: apple,t8103-pmgr - const: syscon - const: simple-mfd From 2c943f48e8d467f0f8119f61fcdddae8c2270fb0 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 21:44:53 +0100 Subject: [PATCH 21/31] dt-bindings: power: apple,pmgr-pwrstate: Add T8152 compatible The T8152 (M6) PMGR power state registers are compatible with the T8103 ones. Signed-off-by: Thomas Glanzmann Signed-off-by: Acelogic --- Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml b/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml index 1c3bd5a5b5d2c..eeaf5f20827f9 100644 --- a/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml +++ b/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml @@ -69,6 +69,7 @@ properties: - apple,t8132-pmgr-pwrstate - apple,t8140-pmgr-pwrstate - apple,t8142-pmgr-pwrstate + - apple,t8152-pmgr-pwrstate - const: apple,t8103-pmgr-pwrstate reg: From 5e49fec7858a20e35fcf5c9c335c265aecec3513 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 21:44:54 +0100 Subject: [PATCH 22/31] dt-bindings: i2c: apple,i2c: Add T8152 compatible The T8152 (M6) I2C controllers are compatible with the T8103 ones. Signed-off-by: Thomas Glanzmann Signed-off-by: Acelogic --- Documentation/devicetree/bindings/i2c/apple,i2c.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/i2c/apple,i2c.yaml b/Documentation/devicetree/bindings/i2c/apple,i2c.yaml index 5c827af153cb5..f117341886ca5 100644 --- a/Documentation/devicetree/bindings/i2c/apple,i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/apple,i2c.yaml @@ -30,6 +30,7 @@ properties: - apple,t8122-i2c - apple,t8132-i2c - apple,t8140-i2c + - apple,t8152-i2c - const: apple,t8103-i2c - items: - enum: From 523a1caa53ea200de6bdd23aebf912d8149f26af Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 21:44:53 +0100 Subject: [PATCH 23/31] dt-bindings: mailbox: apple,mailbox: Add T8152 ASC wrapper mailbox The T8152 (M6) SMC and AOP mailboxes are ASC wrapper v8 instances, described with two interrupts (send-empty, recv-not-empty) like the T8140 AOP setup port, but without an IOMMU or DMA window. Add apple,t8152-ascwrap-v8-mailbox and split the conditions into interrupt layout and setup-port resources. Signed-off-by: Thomas Glanzmann [Acelogic: adapted for aurora-wip, where the SMC mailbox already has its own apple,t8152-smc-mailbox compatible with this interrupt layout: the new compatible is described for the AOP mailbox and joins that interrupt condition. The T8140 setup-port conditions are unchanged.] Signed-off-by: Acelogic --- .../devicetree/bindings/mailbox/apple,mailbox.yaml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml b/Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml index 1a40e2e38786b..5c112f77a53a2 100644 --- a/Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml +++ b/Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml @@ -27,6 +27,12 @@ properties: masking provided by the interrupt controller. const: apple,t8152-smc-mailbox + - description: + T8152 ASC wrapper (v8) mailbox of the AOP, with the counted + FIFOs of the SMC mailbox, described with its send-empty and + recv-not-empty interrupts. + const: apple,t8152-ascwrap-v8-mailbox + - description: ASC mailboxes are the most common variant found on the M1 used for example for the display controller, the system management @@ -142,7 +148,9 @@ allOf: properties: compatible: contains: - const: apple,t8152-smc-mailbox + enum: + - apple,t8152-ascwrap-v8-mailbox + - apple,t8152-smc-mailbox then: properties: interrupts: @@ -215,6 +223,8 @@ allOf: - apple,t6021-ane-mailbox - apple,t8112-ane-mailbox - apple,t8140-aop-setup-mailbox + - apple,t8152-ans-mailbox + - apple,t8152-ascwrap-v8-mailbox - apple,t8152-smc-mailbox then: properties: From d237a9aa748912da5ce1d383decb585bf2639026 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 21:44:53 +0100 Subject: [PATCH 24/31] dt-bindings: dma: apple,admac: Add T8152 compatible The T8152 (M6) ADMAC (ADT admac-evolution,t8152) has its own register layout, so it is not compatible with the earlier ones. Signed-off-by: Thomas Glanzmann Signed-off-by: Acelogic --- Documentation/devicetree/bindings/dma/apple,admac.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/dma/apple,admac.yaml b/Documentation/devicetree/bindings/dma/apple,admac.yaml index 64d80cd5f4bcd..17e3f37e673c5 100644 --- a/Documentation/devicetree/bindings/dma/apple,admac.yaml +++ b/Documentation/devicetree/bindings/dma/apple,admac.yaml @@ -44,6 +44,7 @@ properties: - items: - const: apple,t6041-admac - const: apple,t8132-admac + - const: apple,t8152-admac reg: maxItems: 1 From f1ce875e034a3449bf08a60b2e29729f6826c738 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 21:16:37 +0100 Subject: [PATCH 25/31] dt-bindings: iommu: apple,dart: add apple,retain-translation On T8152 iBoot hands dart-sbr over translating for the AOP and the audio ADMAC without setting the lock bit, and the AOP firmware keeps using the inherited mappings. Describe the property that tells the OS to inherit such a DART instead of resetting it, and who owns which root entries. Signed-off-by: Thomas Glanzmann Signed-off-by: Acelogic --- .../devicetree/bindings/iommu/apple,dart.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Documentation/devicetree/bindings/iommu/apple,dart.yaml b/Documentation/devicetree/bindings/iommu/apple,dart.yaml index 514b17641bf5b..9968b519a6db7 100644 --- a/Documentation/devicetree/bindings/iommu/apple,dart.yaml +++ b/Documentation/devicetree/bindings/iommu/apple,dart.yaml @@ -169,6 +169,17 @@ properties: and filtering state without a separate page-table root. Source and destination must differ, and both must exist on the controller. + apple,retain-translation: + type: boolean + description: > + The bootloader hands this DART over translating, with stream page + tables that a co-processor's firmware keeps using, but without setting + the hardware lock. The operating system then treats the DART as locked: + it does not reset it or replace the inherited stream roots, adds its + own mappings only in root entries that are empty at handoff, and on + detach clears only the entries it added. The entries present at handoff + stay owned by the firmware, which may keep using them at any time. + required: - compatible - reg From 76188ec353b94e2274566d0f736954897d8c54a9 Mon Sep 17 00:00:00 2001 From: Acelogic Date: Sat, 7 Nov 2026 21:53:37 -0500 Subject: [PATCH 26/31] soc: apple: mailbox: match the T8152 AOP ASC wrapper mailbox The T8152 AOP mailbox (ADT aop, iop,ascwrap-v8, mailbox 0 of the bank at 0x310740000) is the same counted FIFO as the SMC mailbox, with the same send-empty and recv-not-empty interrupts. Match apple,t8152-ascwrap-v8-mailbox, the compatible of the J873 AOP mailbox node, to the SMC mailbox layout. Signed-off-by: Acelogic --- drivers/soc/apple/mailbox.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/soc/apple/mailbox.c b/drivers/soc/apple/mailbox.c index 8e864229d5efe..4f39be303968a 100644 --- a/drivers/soc/apple/mailbox.c +++ b/drivers/soc/apple/mailbox.c @@ -1764,6 +1764,8 @@ static const struct apple_mbox_hw apple_mbox_t8152_ans_hw = { static const struct of_device_id apple_mbox_of_match[] = { { .compatible = "apple,t8152-smc-mailbox", .data = &apple_mbox_t8152_smc_hw }, + /* The AOP's ASC wrapper mailbox has the SMC mailbox's counted FIFOs. */ + { .compatible = "apple,t8152-ascwrap-v8-mailbox", .data = &apple_mbox_t8152_smc_hw }, { .compatible = "apple,t8152-ans-mailbox", .data = &apple_mbox_t8152_ans_hw }, { .compatible = "apple,t6031-agx-asc-mailbox", .data = &apple_mbox_asc_hw }, { .compatible = "apple,t8122-agx-asc-mailbox", .data = &apple_mbox_asc_hw }, From 613be379ab9198402eecc007409a65e6c29fad81 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 20:17:31 +0100 Subject: [PATCH 27/31] iommu: apple-dart: inherit an unlocked bootloader translation on request On T8152 iBoot leaves dart-sbr translating for the AOP and the audio ADMAC: streams 0, 1 and 42 have live page tables, and the firmware's own mappings sit in root slot 16 of each. Unlike the DARTs SPTM locks, the lock bit is not set, so the driver would reset the DART and pull the tables out from under the AOP firmware. With apple,retain-translation the DART is treated as locked: the inherited roots are kept and Linux publishes its mappings into vacant root slots. Signed-off-by: Thomas Glanzmann Signed-off-by: Acelogic --- drivers/iommu/apple-dart.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c index d39ee78d9d73c..94c79671db6fd 100644 --- a/drivers/iommu/apple-dart.c +++ b/drivers/iommu/apple-dart.c @@ -3976,6 +3976,14 @@ static irqreturn_t apple_dart_irq(int irq, void *dev) static bool apple_dart_is_locked(struct apple_dart *dart) { + /* + * apple,retain-translation: the bootloader left live stream tables + * that a co-processor's firmware depends on, but did not set the lock + * bit (T8152 dart-sbr: AOP and audio ADMAC streams). Treat it as + * locked so the tables are inherited rather than reset. + */ + if (of_property_read_bool(dart->dev->of_node, "apple,retain-translation")) + return true; return !!(apple_dart_readl(dart, dart->hw->lock) & dart->hw->lock_bit); } From 5bef582af4beafab3bd4c02e85ec133253f0111c Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 20:17:31 +0100 Subject: [PATCH 28/31] dmaengine: apple-admac: support the T8152 layout The T8152 ADMAC (ADT admac-evolution,t8152; worked out from the macOS AudioDMAController-T8152 driver and on hardware) keeps the per-channel register block and the global start/stop/interrupt registers, but: - the channel blocks are 0x4000 apart, TX n at 0x40000 + 0x4000 n and RX n at 0x80000 + 0x4000 n; - a channel is put in state 2 (+0x30 bits 3:0) and +0x4 is written 0x029b0000 before it is started, as macOS does; - the last descriptor word carries a descriptor id 1..255 in its low byte, which macOS never leaves at 0; - the SRAM size registers carry the channel count in bits 31:24, and the AP's carveouts start above the firmware's (base 0x1000, 1 KiB blocks); - only the word size is set in the bus width register. The descriptor and report FIFO ports are the legacy ones: the RX descriptor port answers at 0x14000 + 4n, not at the 0x10040 + 4n the ADT lists. Signed-off-by: Thomas Glanzmann [Acelogic: adapted for aurora-wip: the descriptor id is set in admac_write_hw_desc(), which writes every descriptor there, the SRAM carveout bounds combine with the T8132 split-channel handling, and the state register is the +0x30 one that aurora-wip programs as REG_CHAN_BURST on T8132.] Signed-off-by: Acelogic --- drivers/dma/apple-admac.c | 80 +++++++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 8 deletions(-) diff --git a/drivers/dma/apple-admac.c b/drivers/dma/apple-admac.c index 60b8c04530634..bdafb0ff4aecb 100644 --- a/drivers/dma/apple-admac.c +++ b/drivers/dma/apple-admac.c @@ -70,13 +70,29 @@ */ #define REG_CHAN_BASE_LEGACY(ch) (0x8000 + (ch) * 0x200) #define REG_CHAN_BASE_EVOLVED(ch) (((ch) & 1 ? 0xc000 : 0x8000) + ((ch) / 2) * 0x200) -#define REG_CHAN_BASE(ad, ch) ((ad)->evolved_layout ? \ +/* + * T8152 (ADT admac-evolution,t8152; the macOS AudioDMAController-T8152 + * driver): the same per-channel block, 0x4000 apart, TX at 0x40000 and RX + * at 0x80000, and a channel has to be put in state 2 (+0x30 bits 3:0) + * before it is started. The descriptor and report FIFO ports are the legacy + * ones (the RX descriptor port answers at 0x14000 + 4n, not at the ADT's + * 0x10040 + 4n). + */ +#define REG_CHAN_BASE_T8152(ch) (((ch) & 1 ? 0x80000 : 0x40000) + ((ch) / 2) * 0x4000) +#define REG_CHAN_BASE(ad, ch) ((ad)->t8152_layout ? REG_CHAN_BASE_T8152(ch) : \ + (ad)->evolved_layout ? \ REG_CHAN_BASE_EVOLVED(ch) : REG_CHAN_BASE_LEGACY(ch)) #define REG_CHAN_CTL(ad, ch) (REG_CHAN_BASE(ad, ch) + 0x00) #define REG_CHAN_CTL_RST_RINGS BIT(0) #define REG_CHAN_CONFIG(ad, ch) (REG_CHAN_BASE(ad, ch) + 0x04) +/* macOS writes this for the T8152 base-ns channels before every start */ +#define CHAN_CONFIG_T8152 0x029b0000 #define REG_CHAN_BURST(ad, ch) (REG_CHAN_BASE(ad, ch) + 0x30) +/* T8152: the low nibble of the same register is the channel state */ +#define REG_CHAN_STATE(ad, ch) REG_CHAN_BURST(ad, ch) +#define CHAN_STATE_MASK GENMASK(3, 0) +#define CHAN_STATE_READY 2 #define REG_DESC_RING(ad, ch) (REG_CHAN_BASE(ad, ch) + 0x70) #define REG_REPORT_RING(ad, ch) (REG_CHAN_BASE(ad, ch) + 0x74) @@ -104,6 +120,11 @@ #define REG_DESC_WRITE(ch) (0x10000 + ((ch) / 2) * 0x4 + ((ch) & 1) * 0x4000) #define REG_REPORT_READ(ch) (0x10100 + ((ch) / 2) * 0x4 + ((ch) & 1) * 0x4000) +/* T8152: the AP's share of each SRAM pool starts above the firmware's. */ +#define T8152_SRAM_BASE 0x1000 +#define T8152_SRAM_BLOCK 1024 +#define SRAM_SIZE_MASK GENMASK(15, 0) + #define REG_TX_INTSTATE(idx) (0x0030 + (idx) * 4) #define REG_RX_INTSTATE(idx) (0x0040 + (idx) * 4) #define REG_GLOBAL_INTSTATE(idx) (0x0050 + (idx) * 4) @@ -124,6 +145,8 @@ struct admac_chan { struct tasklet_struct tasklet; u32 carveout; + /* T8152: transfer descriptor id, 1..255 */ + u8 desc_id; spinlock_t lock; struct admac_tx *current_tx; @@ -164,6 +187,7 @@ struct admac_data { bool set_unk28; bool evolved_layout; bool split_channels; + bool t8152_layout; bool ctl_programmed; int irq; int irq_index; @@ -193,6 +217,7 @@ struct admac_hw { bool set_unk28; bool evolved_layout; bool split_channels; + bool t8152_layout; }; static int admac_alloc_sram_carveout(struct admac_data *ad, @@ -201,6 +226,8 @@ static int admac_alloc_sram_carveout(struct admac_data *ad, { struct admac_sram *sram; int i, ret = 0, nblocks; + u32 first = 0, block = SRAM_BLOCK; + ad->txcache.size = readl_relaxed(ad->base + REG_TX_SRAM_SIZE); ad->rxcache.size = readl_relaxed(ad->base + REG_RX_SRAM_SIZE); /* T8132 reports channel metadata in the upper half of these words. */ @@ -208,6 +235,13 @@ static int admac_alloc_sram_carveout(struct admac_data *ad, ad->txcache.size &= GENMASK(15, 0); ad->rxcache.size &= GENMASK(15, 0); } + if (ad->t8152_layout) { + /* bits 31:24 are the channel count */ + ad->txcache.size &= SRAM_SIZE_MASK; + ad->rxcache.size &= SRAM_SIZE_MASK; + first = T8152_SRAM_BASE; + block = T8152_SRAM_BLOCK; + } if (dir == DMA_MEM_TO_DEV) sram = &ad->txcache; @@ -216,14 +250,14 @@ static int admac_alloc_sram_carveout(struct admac_data *ad, mutex_lock(&ad->cache_alloc_lock); - nblocks = sram->size / SRAM_BLOCK; + nblocks = sram->size > first ? (sram->size - first) / block : 0; for (i = ad->split_channels ? 1 : 0; i < nblocks; i++) if (!(sram->allocated & BIT(i))) break; if (i < nblocks) { - *out = FIELD_PREP(CHAN_SRAM_CARVEOUT_BASE, i * SRAM_BLOCK) | - FIELD_PREP(CHAN_SRAM_CARVEOUT_SIZE, SRAM_BLOCK); + *out = FIELD_PREP(CHAN_SRAM_CARVEOUT_BASE, first + i * block) | + FIELD_PREP(CHAN_SRAM_CARVEOUT_SIZE, block); sram->allocated |= BIT(i); } else { ret = -EBUSY; @@ -240,18 +274,24 @@ static void admac_free_sram_carveout(struct admac_data *ad, { struct admac_sram *sram; u32 base = FIELD_GET(CHAN_SRAM_CARVEOUT_BASE, carveout); + u32 first = 0, block = SRAM_BLOCK; int i; + if (ad->t8152_layout) { + first = T8152_SRAM_BASE; + block = T8152_SRAM_BLOCK; + } + if (dir == DMA_MEM_TO_DEV) sram = &ad->txcache; else sram = &ad->rxcache; - if (WARN_ON(base >= sram->size)) + if (WARN_ON(base < first || base >= sram->size)) return; mutex_lock(&ad->cache_alloc_lock); - i = base / SRAM_BLOCK; + i = (base - first) / block; sram->allocated &= ~BIT(i); mutex_unlock(&ad->cache_alloc_lock); } @@ -354,7 +394,19 @@ static void admac_write_hw_desc(struct admac_data *ad, int channo, writel_relaxed(lower_32_bits(addr), ad->base + REG_DESC_WRITE(channo)); writel_relaxed(upper_32_bits(addr), ad->base + REG_DESC_WRITE(channo)); writel_relaxed(len, ad->base + REG_DESC_WRITE(channo)); - writel_relaxed(FLAG_DESC_NOTIFY, ad->base + REG_DESC_WRITE(channo)); + if (ad->t8152_layout) { + /* + * T8152: the low byte of the last word is a descriptor id, + * which macOS counts 1..255 and never leaves at 0. + */ + struct admac_chan *adchan = &ad->channels[channo]; + + adchan->desc_id = adchan->desc_id == 255 ? 1 : adchan->desc_id + 1; + writel_relaxed(FLAG_DESC_NOTIFY | adchan->desc_id, + ad->base + REG_DESC_WRITE(channo)); + } else { + writel_relaxed(FLAG_DESC_NOTIFY, ad->base + REG_DESC_WRITE(channo)); + } } /* @@ -570,6 +622,11 @@ static void admac_start_chan(struct admac_chan *adchan) ad->base + REG_CHAN_INTSTATUS(ad, adchan->no, ad->irq_index)); writel_relaxed(STATUS_DESC_DONE | STATUS_ERR, ad->base + REG_CHAN_INTMASK(ad, adchan->no, ad->irq_index)); + if (ad->t8152_layout) { + writel_relaxed(CHAN_CONFIG_T8152, ad->base + REG_CHAN_CONFIG(ad, adchan->no)); + admac_modify(ad, REG_CHAN_STATE(ad, adchan->no), CHAN_STATE_MASK, + CHAN_STATE_READY); + } switch (admac_chan_direction(adchan->no)) { case DMA_MEM_TO_DEV: @@ -1091,7 +1148,8 @@ static int admac_device_config(struct dma_chan *chan, * of words position in a frame. That's where the importance of this control * comes from. */ - switch (is_tx ? config->dst_port_window_size : config->src_port_window_size) { + switch (ad->t8152_layout ? 0 : + is_tx ? config->dst_port_window_size : config->src_port_window_size) { case 0 ... 1: break; case 2: @@ -1202,6 +1260,7 @@ static int admac_probe(struct platform_device *pdev) ad->set_unk28 = hw->set_unk28; ad->evolved_layout = hw->evolved_layout; ad->split_channels = hw->split_channels; + ad->t8152_layout = hw->t8152_layout; mutex_init(&ad->cache_alloc_lock); /* @@ -1353,7 +1412,12 @@ static const struct admac_hw admac_t8140_hw = { .evolved_layout = true, }; +static const struct admac_hw admac_t8152_hw = { + .t8152_layout = true, +}; + static const struct of_device_id admac_of_match[] = { + { .compatible = "apple,t8152-admac", .data = &admac_t8152_hw }, { .compatible = "apple,t8140-admac", .data = &admac_t8140_hw }, { .compatible = "apple,t8132-admac", .data = &admac_t8132_hw }, { .compatible = "apple,t8122-admac", .data = &admac_t8122_hw }, From dd923f2443834d36260286aeb9c27355db9aae05 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 20:17:32 +0100 Subject: [PATCH 29/31] arm64: dts: apple: j873: audio Describe the J873 (Mac mini M6) audio: the AOP (mailbox 0x310740080, firmware started by Linux), dart-sbr (shared with the PMP; apple,retain-translation for the firmware's tables), the base-ns ADMAC, the AOP audio node with its DMA channels and MCA power leaves, the I2C1/I2C3 power states and buses with the CS42L84 jack codec and the SN012776 speaker amp (ti,bclk-ratio = <250>), and the macaudio card. Signed-off-by: Thomas Glanzmann [Acelogic: adapted for aurora-wip: the nodes go into t8152-j873-audio.dtsi, which t8152-j873g.dts includes. There is no PMP device tree here, so dart-sbr is described directly (as an apple,t8152-dart with apple,t8110-dart fallback, like the other J873 DARTs), and the I2C power states join the PMGR node that t8152-j873-qspi.dtsi already describes. The speaker stays off by default: the J873 macaudio configuration does not admit it.] Signed-off-by: Acelogic --- .../boot/dts/apple/t8152-j873-audio.dtsi | 261 ++++++++++++++++++ arch/arm64/boot/dts/apple/t8152-j873g.dts | 1 + 2 files changed, 262 insertions(+) create mode 100644 arch/arm64/boot/dts/apple/t8152-j873-audio.dtsi diff --git a/arch/arm64/boot/dts/apple/t8152-j873-audio.dtsi b/arch/arm64/boot/dts/apple/t8152-j873-audio.dtsi new file mode 100644 index 0000000000000..0ecfd9746beb9 --- /dev/null +++ b/arch/arm64/boot/dts/apple/t8152-j873-audio.dtsi @@ -0,0 +1,261 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * J873g audio: the AOP (always-on processor) owns the audio fabric, as + * on T8140. iBoot loads the AOP firmware (j873gaop) and leaves the CPU + * stopped; Linux starts it. The jack codec (CS42L84) and the speaker amp + * (SN012776) are on AP I2C buses; their data goes through AOP services on + * the base-ns ADMAC. Resources are from the 26A434 ADT: aop, dart-sbr, + * admac-base-ns, iop-audio-controller, i2c1, i2c3, pmgr. + */ +#include + +/ { + soc { + /* + * ADT aop: iop,ascwrap-v8, msgbox-mailbox-num 0, using-alias, + * not post-office: mailbox 0, aperture 1 of the bank at reg[2] + * (0x310740000) = 0x310740080. ADT interrupts [627, 626, 628]; + * the first two in the SMC order (send-empty, recv-not-empty). + */ + aop_mbox: mailbox@310740080 { + compatible = "apple,t8152-ascwrap-v8-mailbox"; + reg = <0x3 0x10740080 0x0 0x80>; + interrupts = , + ; + interrupt-names = "send-empty", "recv-not-empty"; + #mbox-cells = <0>; + }; + + /* + * ADT dart-sbr, shared with the PMP: mapper-aop 0, + * mapper-admac-base-ns 42. iBoot leaves streams 0, 1 and 42 + * translating (root slot 16 owned by the firmware) without + * setting the lock bit. + */ + sbr_dart: iommu@318100000 { + compatible = "apple,t8152-dart", "apple,t8110-dart"; + reg = <0x3 0x18100000 0x0 0xc000>; + #iommu-cells = <1>; + interrupts = ; + apple,retain-translation; + }; + + /* + * ADT admac-base-ns (admac-evolution,t8152): 13 TX and 13 RX + * channels, interrupt destination 0, dart-sbr stream 42. + */ + admac_base_ns: dma-controller@313900000 { + compatible = "apple,t8152-admac"; + reg = <0x3 0x13900000 0x0 0xb4000>; + dma-channels = <26>; + interrupts-extended = <&aic AIC_IRQ 640 IRQ_TYPE_LEVEL_HIGH>, + <0>, <0>, <0>; + #dma-cells = <1>; + iommus = <&sbr_dart 42>; + /* slot 17: slot 16 of stream 42 belongs to the firmware */ + apple,dma-range = <0x110 0x0 0x0 0x10000000>; + }; + + /* + * The AOP's PMGR (ADT pmgr devices AUDIO_MCA0_M..AUDIO_MCA5_M at + * 0x308284400 + 0x20 * N). Their parent audio_p is the + * firmware's: it is up while a service is in pw0 or pwrd. + */ + pmgr_aop: power-management@308284000 { + compatible = "apple,t8152-pmgr", "apple,t8103-pmgr", + "syscon", "simple-mfd"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x3 0x08284000 0x0 0x1000>; + + ps_audio_mca0_m: power-controller@400 { + compatible = "apple,t8152-pmgr-pwrstate", + "apple,t8103-pmgr-pwrstate"; + reg = <0x400 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "audio_mca0_m"; + }; + + ps_audio_mca1_m: power-controller@420 { + compatible = "apple,t8152-pmgr-pwrstate", + "apple,t8103-pmgr-pwrstate"; + reg = <0x420 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "audio_mca1_m"; + }; + + ps_audio_mca2_m: power-controller@440 { + compatible = "apple,t8152-pmgr-pwrstate", + "apple,t8103-pmgr-pwrstate"; + reg = <0x440 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "audio_mca2_m"; + }; + + ps_audio_mca3_m: power-controller@460 { + compatible = "apple,t8152-pmgr-pwrstate", + "apple,t8103-pmgr-pwrstate"; + reg = <0x460 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "audio_mca3_m"; + }; + + ps_audio_mca4_m: power-controller@480 { + compatible = "apple,t8152-pmgr-pwrstate", + "apple,t8103-pmgr-pwrstate"; + reg = <0x480 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "audio_mca4_m"; + }; + + ps_audio_mca5_m: power-controller@4a0 { + compatible = "apple,t8152-pmgr-pwrstate", + "apple,t8103-pmgr-pwrstate"; + reg = <0x4a0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "audio_mca5_m"; + }; + }; + + /* ADT i2c1: the CS42L84 jack codec (and the aqc NIC's EEPROM). */ + i2c1: i2c@331014000 { + compatible = "apple,t8152-i2c", "apple,t8103-i2c"; + reg = <0x3 0x31014000 0x0 0x4000>; + clocks = <&clkref>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + power-domains = <&ps_i2c1>; + + /* + * ADT audio-codec-output: function-reset GPIO 0xcc, + * interrupt on gpio0 pin 203. + */ + jack_codec: codec@4b { + compatible = "cirrus,cs42l84"; + reg = <0x4b>; + reset-gpios = <&pinctrl_ap 204 GPIO_ACTIVE_HIGH>; + interrupts-extended = <&pinctrl_ap 203 IRQ_TYPE_LEVEL_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "Jack"; + }; + }; + + /* ADT i2c3: the SN012776 speaker amplifier. */ + i2c3: i2c@33101c000 { + compatible = "apple,t8152-i2c", "apple,t8103-i2c"; + reg = <0x3 0x3101c000 0x0 0x4000>; + clocks = <&clkref>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + power-domains = <&ps_i2c3>; + + /* + * ADT audio-speaker: function-reset GPIO 0xca, interrupt + * on gpio0 pin 193, speaker-config rx_slot 0, + * vsense_slot 0, isense_slot 2. + */ + speaker_amp: codec@38 { + compatible = "ti,sn012776", "ti,tas2764"; + reg = <0x38>; + shutdown-gpios = <&pinctrl_ap 202 GPIO_ACTIVE_HIGH>; + interrupts-extended = <&pinctrl_ap 193 IRQ_TYPE_LEVEL_LOW>; + #sound-dai-cells = <0>; + ti,imon-slot-no = <2>; + ti,vmon-slot-no = <0>; + /* the AOP's speaker frame: 250 BCLKs at 12 MHz */ + ti,bclk-ratio = <250>; + }; + }; + + aop: aop@310c00000 { + compatible = "apple,t8152-aop"; + reg = <0x3 0x10c00000 0x0 0x1e0000>, + <0x3 0x10600000 0x0 0x4000>; + reg-names = "mmio", "asc"; + mboxes = <&aop_mbox>; + mbox-names = "mbox"; + iommus = <&sbr_dart 0>; + /* slot 17: slot 16 belongs to the firmware */ + apple,dma-range = <0x110 0x0 0x10 0x0>; + + /* + * Bound by name to the firmware's "audio" EPIC service. + * ADT iop-audio-controller: cout/cin on base-ns TX5/RX5, + * spkr on TX1 with its sense data on RX1; Linux ADMAC + * channel = 2 * N for TX N, 2 * N + 1 for RX N. + */ + aop_audio: audio { + compatible = "apple,t8152-aop-audio"; + dmas = <&admac_base_ns 10>, <&admac_base_ns 11>, + <&admac_base_ns 2>, <&admac_base_ns 3>; + dma-names = "cout", "cin", "spkr", "sense"; + power-domains = <&ps_audio_mca0_m>, <&ps_audio_mca1_m>, + <&ps_audio_mca2_m>, <&ps_audio_mca3_m>, + <&ps_audio_mca4_m>, <&ps_audio_mca5_m>; + power-domain-names = "mca0", "mca1", "mca2", + "mca3", "mca4", "mca5"; + #sound-dai-cells = <1>; + }; + }; + }; + + sound { + compatible = "apple,j873-macaudio", "apple,macaudio"; + model = "Mac mini J873"; + #address-cells = <1>; + #size-cells = <0>; + + dai-link@0 { + reg = <0>; + link-name = "Headphone Jack"; + + cpu { + sound-dai = <&aop_audio 0>; + }; + codec { + sound-dai = <&jack_codec>; + }; + }; + + dai-link@1 { + reg = <1>; + link-name = "Speaker"; + + cpu { + sound-dai = <&aop_audio 3>; + }; + codec { + sound-dai = <&speaker_amp>; + }; + }; + }; +}; + +/* The I2C power states (PMGR, parent SIO_CPU is always on). */ +&pmgr { + ps_i2c1: power-controller@cc0 { + compatible = "apple,t8152-pmgr-pwrstate", + "apple,t8103-pmgr-pwrstate"; + reg = <0xcc0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "i2c1"; + }; + + ps_i2c3: power-controller@d00 { + compatible = "apple,t8152-pmgr-pwrstate", + "apple,t8103-pmgr-pwrstate"; + reg = <0xd00 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "i2c3"; + }; +}; diff --git a/arch/arm64/boot/dts/apple/t8152-j873g.dts b/arch/arm64/boot/dts/apple/t8152-j873g.dts index 180b435f1d969..2da1a88dc8cf1 100644 --- a/arch/arm64/boot/dts/apple/t8152-j873g.dts +++ b/arch/arm64/boot/dts/apple/t8152-j873g.dts @@ -364,3 +364,4 @@ #include "t8152-j873-nvme.dtsi" #include "t8152-j873-usb.dtsi" #include "t8152-j873-ethernet.dtsi" +#include "t8152-j873-audio.dtsi" From bc141c0a6c9bf48786169920cd2f6ddb74e647e5 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 25 Oct 2026 10:31:26 +0100 Subject: [PATCH 30/31] arm64: dts: apple: j873: describe the fan target and mode keys The J873 SMC has F0Tg (target, flt) and F0md (mode, ui8; lowercase, unlike the F0Md of other machines). With them macsmc_hwmon exposes fan1_target; with fan_control=1 the fan follows it (2500 -> 2499 RPM within 3 s). In automatic mode the SMC keeps the fan at its 1000 RPM minimum even at 93 C under full load, so the OS has to drive it. Signed-off-by: Thomas Glanzmann [Acelogic: adapted for aurora-wip, whose T8152 hwmon leaves fan control to the firmware: the fan node has no apple,fan-manual-control, so the keys only add a read-only fan1_target. The target becomes writable only with the fan_control module parameter (unsafe, off by default); nothing in the kernel writes F0md or F0Tg by itself.] Signed-off-by: Acelogic --- arch/arm64/boot/dts/apple/t8152-j873g.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t8152-j873g.dts b/arch/arm64/boot/dts/apple/t8152-j873g.dts index 2da1a88dc8cf1..db37673de92bb 100644 --- a/arch/arm64/boot/dts/apple/t8152-j873g.dts +++ b/arch/arm64/boot/dts/apple/t8152-j873g.dts @@ -340,6 +340,8 @@ apple,key-id = "F0Ac"; apple,fan-minimum = "F0Mn"; apple,fan-maximum = "F0Mx"; + apple,fan-target = "F0Tg"; + apple,fan-mode = "F0md"; label = "Fan"; }; }; From 6962da594d81907a7a1445db331fa95c322ec5ef Mon Sep 17 00:00:00 2001 From: Acelogic Date: Sun, 8 Nov 2026 02:04:43 -0500 Subject: [PATCH 31/31] arm64: dts: apple: j873: leave the USB 2 hosts to a follow-up The J873g USB 2 host nodes describe the back-left (usb-drd1) and front (usb-drd2) controllers as plain "snps,dwc3" with both DART instances in iommus. The generic dwc3 binding allows a single iommu, so these nodes add two dtbs_check warnings. The Apple dwc3 binding, which does allow two DARTs, needs resets, a USB role switch and PHY descriptions that the J873g does not have yet. Return the J873g USB description to the shared, disabled state that aurora-wip has, until the M6 USB controllers can be described properly: - drop t8152-j873-usb.dtsi and its include; - restore aurora-wip's dwc3_1_dart and dwc3_2_dart overrides. The USB 2 hosts worked on the M6 with the earlier description (both xHCI hosts and the front-port hub enumerated), and they will come back in a follow-up together with the binding work. Signed-off-by: Acelogic --- arch/arm64/boot/dts/apple/t8152-j873-usb.dtsi | 67 ------------------- arch/arm64/boot/dts/apple/t8152-j873g.dts | 17 ++++- 2 files changed, 15 insertions(+), 69 deletions(-) delete mode 100644 arch/arm64/boot/dts/apple/t8152-j873-usb.dtsi diff --git a/arch/arm64/boot/dts/apple/t8152-j873-usb.dtsi b/arch/arm64/boot/dts/apple/t8152-j873-usb.dtsi deleted file mode 100644 index 5ecd42f9e7135..0000000000000 --- a/arch/arm64/boot/dts/apple/t8152-j873-usb.dtsi +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ OR MIT -/* - * J873g USB2 host bring-up: usb-drd1 (back-left port) and usb-drd2 - * (front ports via the on-board hub). - * The loader powers the controllers and initialises the eUSB2 PHYs in host - * mode before Linux starts (no PMGR, PHY or Type-C driver yet), so the - * controllers are described as plain DWC3 hosts behind their two DARTs. - * Resources are from the 26A434 ADT: dart-usb1/2, usb-drd1/2. - * - * dart-usb1 and dart-usb2 each have two DART instances (ADT reg[0] and - * reg[1], 0xc000 each, sharing one interrupt). t8152-peripherals.dtsi lists - * both windows on one node (dwc3_1_dart, dwc3_2_dart), but the DART driver - * drives one instance per node and the binding reads a second reg entry as - * DAPF or auxiliary registers. Keep instance 0 on the shared node, with its - * own window only, and describe instance 1 as a node of its own. - */ - -&dwc3_1_dart { - reg = <0x4 0x0b020000 0x0 0xc000>; - status = "okay"; -}; - -&dwc3_2_dart { - reg = <0x3 0x83020000 0x0 0xc000>; - status = "okay"; -}; - -/ { - soc { - dwc3_1_dart_1: iommu@40b040000 { - compatible = "apple,t8152-dart", "apple,t8110-dart"; - reg = <0x4 0x0b040000 0x0 0xc000>; - interrupts = ; - #iommu-cells = <1>; - }; - - usb1: usb@40a430000 { - compatible = "snps,dwc3"; - reg = <0x4 0x0a430000 0x0 0xcd00>; - interrupts = ; - dr_mode = "host"; - maximum-speed = "high-speed"; - iommus = <&dwc3_1_dart 0>, <&dwc3_1_dart_1 1>; - snps,dis_u2_susphy_quirk; - snps,dis_u3_susphy_quirk; - }; - - dwc3_2_dart_1: iommu@383040000 { - compatible = "apple,t8152-dart", "apple,t8110-dart"; - reg = <0x3 0x83040000 0x0 0xc000>; - interrupts = ; - #iommu-cells = <1>; - }; - - /* usb-drd2: on-board VL822 hub behind the two front USB-C ports. */ - usb2: usb@382430000 { - compatible = "snps,dwc3"; - reg = <0x3 0x82430000 0x0 0xcd00>; - interrupts = ; - dr_mode = "host"; - maximum-speed = "high-speed"; - iommus = <&dwc3_2_dart 0>, <&dwc3_2_dart_1 1>; - snps,dis_u2_susphy_quirk; - snps,dis_u3_susphy_quirk; - }; - }; -}; diff --git a/arch/arm64/boot/dts/apple/t8152-j873g.dts b/arch/arm64/boot/dts/apple/t8152-j873g.dts index 0f98b07748b01..d4900374f1470 100644 --- a/arch/arm64/boot/dts/apple/t8152-j873g.dts +++ b/arch/arm64/boot/dts/apple/t8152-j873g.dts @@ -372,6 +372,12 @@ <0x4 0x3040000 0x0 0xc000>; }; +/* Retain the register view published by this board's live hardware capture. */ +&dwc3_1_dart { + reg = <0x4 0xb020000 0x0 0xc000>, + <0x4 0xb040000 0x0 0xc000>; +}; + /* Retain the register view published by this board's live hardware capture. */ &dwc3_3_dart { reg = <0x4 0x13020000 0x0 0xc000>, @@ -494,11 +500,18 @@ <0x3 0xa0000000 0x0 0x8000>; }; +/* Unexposed chassis port instances remain described and disabled. */ + +/* Retain the register view published by this board's live hardware capture. */ +&dwc3_2_dart { + reg = <0x3 0x83020000 0x0 0xc000>, + <0x3 0x83040000 0x0 0xc000>; +}; + /* * The J873g fragments enable and refine nodes of t8152-peripherals.dtsi - * (the USB, apcie port 2 and dart-sbr DARTs), so they come after it. + * (the apcie port 2 and dart-sbr DARTs), so they come after it. */ #include "t8152-j873-nvme.dtsi" -#include "t8152-j873-usb.dtsi" #include "t8152-j873-ethernet.dtsi" #include "t8152-j873-audio.dtsi"