Skip to content

soc: apple: aop: T8132 (M4 MacBook Air) AOP and microphones - #434

Closed
erikwb wants to merge 5 commits into
aurora-silicon:integration/aurorafrom
erikwb:j713/aop-audio
Closed

erikwb wants to merge 5 commits into
aurora-silicon:integration/aurorafrom
erikwb:j713/aop-audio

Conversation

@erikwb

@erikwb erikwb commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

This brings up the AOP on the J713 (MacBook Air 13" M4, T8132), the aurora way, as on the J616s (#406). The firmware runs the audio, and this PR enables its first service: the internal microphones (3 channels, 48 kHz, through aop_audio). The jack (#437) and the speakers (#439) follow on the same AOP.

Updated after review: the bootloader now hands the AOP over as on T6040. There is no ADT reader, DAPF writer or raw iommu_map in the kernel any more, and the driver change is down to a match entry using the T6040 configuration. Companion PRs:

What the bootloader does for T8132

The T8132 AOP takes the T6040 boot arguments (EC0p 0x100_0000_0000, nCal 0, alig 64, AOPt 0). iBoot leaves the boot-argument table at its defaults in the AOP SRAM and the AOP halted, and the ADT gives __ETEXT the DART address 0x100_0000_0000. What differs from T6040 is what iBoot leaves behind, and m1n1 now handles it when /chosen requests the AOP's handoff and the AOP CPU is halted:

  1. The AOP DART's DAPF is empty. Without it, the firmware's first MMIO access (PMGR at 0x388284038) is rejected and RTKit endpoint discovery times out. m1n1 programs the 16 slices from the ADT, reads them back, and restores all of them on a mismatch.
  2. The firmware reaches the DAPF windows through its DART at their physical addresses. m1n1 reserves the 15 merged windows with identity iommu-addresses, so the IOMMU core maps them as direct regions.
  3. iBoot moves __OS_LOG at every boot (0x10004600000, 0x1000624c000, 0x1000528c000, …). m1n1 reserves it, and __ETEXT, through the same dt_reserve_asc_segments() path as T6040.

All 17 regions land in the AOP's memory-region. On any failure, m1n1 disables the AOP.

What I ruled out on the way

  • Static __OS_LOG reservation: wrong on the next boot.
  • Translated MMIO without the DAPF fails with fill region, and bypass without the DAPF fails with BPF reject.
  • Bypass with the DAPF fails with BPF reject on host DRAM: the DAPF also filters DRAM in bypass, and all 16 slices are in use.
  • What works: a translated domain, the DAPF windows identity-mapped, and the DAPF programmed. That's what the handoff now provides.

Notes for review

  • The ADMAC channel map is the T6041 one (ADT iop-audio-controller: speaker base-ns 0/1, jack 4/5, mics on LEAP).
  • No speaker or amp nodes are added here. Nothing in this PR can drive the speakers.
  • The J713 DT already lists /arm-io/aop in /chosen/linux-enablement-mac,dapf-handoff. With an older m1n1 the AOP gets no memory-region, and the driver refuses to start it ("No firmware memory-region from the bootloader").

Testing

J713, 8-core GPU, integration/aurora 420a1c8 + this series (+ #437, #439, #429, #432 and the #389 hash). Boot chain: m1n1 cda8314d + aaf9fe96 + the handoff, U-Boot 6c1d2d14 + the import.

dapf: Programmed 16 T8132 DAPF slices for /arm-io/dart-aop
FDT: /soc/aop@390600000: 15 AOP DAPF windows reserved
FDT: /soc/aop@390600000: AOP handed off with its DAPF and firmware segments
OF: reserved mem: 0x0000010000ab0000..0x0000010000ac7fff (96 KiB) nomap non-reusable asc-firmware@10000ab0000
apple_aop 390c00000.aop: RTKit: Initializing (protocol version 12)
  • The microphones, headphone jack and speakers all work.
  • No DART faults or warnings.
  • Display, GPU, Wi-Fi and Bluetooth are unaffected.

Checks:

  • checkpatch --strict is clean on all five commits.
  • dt_binding_check passes for apple,t6041-aop.yaml and apple,t6041-aop-audio.yaml.
  • dtbs_check on t8132-j713.dtb reports nothing for the AOP or the ADMACs. Its one message is the existing /chosen handoff string list.

Not tested: unbind/rebind and system sleep. J713 suspend is still refused.

@erikwb

erikwb commented Oct 24, 2026

Copy link
Copy Markdown
Contributor Author

Force-pushed one fix: the AOP audio binding required at least the three speaker-side DMA names, so the mics-only J713 node failed dtbs_check. dma-names now allows the microphones alone, the microphones with the jack, and the two speaker layouts. dt_binding_check and dtbs_check (J713, J616s) are now clean for the AOP. The code is unchanged.

@RyanTheTide RyanTheTide left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked the T8132 configuration against T6040, the ADT bounds, DAPF programming and readback, firmware-region admission and probe failure paths.

This needs the loader handoff used for the T6040 work. DAPF setup and the moving __OS_LOG reservation belong in m1n1, with reserved mappings described to the IOMMU core. Adding another ADT reader and raw iommu_map calls in the AOP consumer goes against that ownership model.

There is also an error-path problem. Probe programs the DAPF before check_fw_regions and map_adt_firmware. A later admission or allocation failure leaves those writes applied. The readback-mismatch rollback does not cover those exits. map_identity also leaves earlier successful mappings in the DMA domain when a later window fails, without a teardown owner.

The combined tree passed the apple-dcp host tests, 63/63, and the Asahi KUnit tests, 86/86. Universal WERROR builds are still running. I have no J713 runtime result of my own. This is not merge-ready until the loader and mapping ownership are resolved.

@RyanTheTide

Copy link
Copy Markdown
Contributor

Confirmed the DMA-name layouts in 8209c2d440af. The targeted AOP/audio bindings and J713/J616s DTB checks pass here. The remaining changes requested in my review concern the loader handoff and ownership of DAPF writes and IOMMU mappings across probe failures.

@RyanTheTide

Copy link
Copy Markdown
Contributor

Final software gates now pass on the combined tree containing these heads and the proposed common config correction in #438. Both defconfig plus asahi.config and the Fedora-base recipe build Image, modules and DTBs with WERROR enabled. The Fedora recipe also covers KUNIT=m. Every requested asahi.config setting survives resolution. Asahi KUnit passes 86/86 and apple-dcp host tests pass 63/63. The targeted J713/J616s binding and DTB checks have no diagnostics.

The build and binding gates pass. The loader handoff and mapping-ownership changes requested in the review remain unresolved, so this is still not merge-ready.

@RyanTheTide

Copy link
Copy Markdown
Contributor

Final qualification for 8209c2d440af7664cfcb9eb8a2b22acd62110cbd. The combined test source is 031f7dec92a1bef6b72509b08c5c597f50474adb, tree 36854d3a72e4efdf2c352166498ab436adaf3c48.

Both defconfig plus asahi.config and the Fedora-base shipping recipe pass the full Image/modules/DTB build with WERROR enabled. Every requested fragment value survives olddefconfig. Asahi KUnit passes 86/86, apple-dcp host tests pass 63/63, and targeted J713/J616s binding/DTB checks have no diagnostics. Strict source-style checks pass; commit sign-offs are checked separately. The attribution audit found no new material Gravity implementation blocks. Existing GPL-2.0-only Cody Ho and Niklas Sheth credit is preserved.

The DMA-name binding point is resolved. The DAPF/firmware handoff and error-path ownership of DAPF writes and raw IOMMU mappings remain unresolved. The handoff belongs in the loader. Not merge-ready for those code holds and the #438 dependency. No J713 runtime result is claimed.

The T8132 (M4) AOP runs the same firmware transport as the T6041 one, and
its bootloader hands it over the same way. It also programs the AOP DART's
address filter (DAPF) and reserves the filter's windows, which the firmware
reaches through its DART at their physical addresses. The windows come in
memory-region with the firmware segments, up to 16 of them.

Signed-off-by: Erik Bourget <erik@ebourget.net>
The T8132 AOP audio service is the T6041 one: the same LPAI microphone
flow, and the same ADMAC channel map for the speakers and the jack. Allow
"apple,t8132-aop-audio" in front of the T6041 compatible.

A machine brought up in steps lists only the streams it has so far, so
allow the microphones alone, and the microphones with the jack, besides
the speaker layouts.

Signed-off-by: Erik Bourget <erik@ebourget.net>
The T8132 (M4) AOP takes the T6040 boot arguments (EC0p 0x100_0000_0000,
nCal 0, alig 64, AOPt 0): iBoot leaves the boot-argument table at its
defaults in the AOP SRAM and the AOP halted, and the ADT gives __ETEXT the
DART address 0x100_0000_0000. The bootloader programs the AOP DART's DAPF
and reserves the firmware segments and the DAPF windows, so the T6040
configuration applies unchanged.

Tested on J713 (MacBook Air 13" M4) with m1n1 handing the AOP over (its
memory-region holds __ETEXT, __OS_LOG and the 15 DAPF windows): the AOP
starts, and the microphones capture (3 channels, 48 kHz) through
aop_audio.

Signed-off-by: Erik Bourget <erik@ebourget.net>
Describe the T8132 AOP with its mailbox and DART, and the audio fabric's
two ADMACs (admac-leap-ns on DART stream 10, admac-base-ns on stream 8),
all disabled. Addresses and interrupts are the ADT's; the ADMAC channel
map is the T6041 one: the microphones on LEAP channel 1.

Signed-off-by: Erik Bourget <erik@ebourget.net>
Enable the AOP, its DART and mailbox, and the ADMACs on the MacBook Air
13" M4, with the AOP audio service for the three microphones.

/chosen already asks for the AOP's handoff: m1n1 programs the AOP DART's
DAPF and adds the firmware segments and the DAPF windows to the AOP's
memory-region, or disables the AOP.

Signed-off-by: Erik Bourget <erik@ebourget.net>
@erikwb

erikwb commented Oct 25, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review. Reworked the way you described: the bootloader now owns the handoff, as on T6040.

Tested on the J713 with the whole chain: 16 slices programmed, 17 regions mapped, and the mics, jack and speakers work. The control DTB appended to stage 2 needs the AOP node for m1n1 to act; where that DTB is generated is Eryk's call (noted in m1n1#47).

@RyanTheTide

RyanTheTide commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

The current head removes the kernel ADT reader, DAPF writer and raw IOMMU mapping path, so the original kernel-side ownership findings are addressed. T8132 now takes the existing T6040 AOP configuration. The contributor reports the complete loader handoff, seventeen regions and working microphones, jack and speakers on J713.

The stacked kernel at 5b6f5515e2f8 passed both full universal and Fedora-base WERROR builds (Image, modules and DTBs); both preserve all 131 common-config settings. ARM64 16 KiB KUnit passed 275/275. DCP host tests passed 63/63, and the PMGR and radio SID checks passed. The M4 host suite has the same five failing groups as the pinned base (18/23 on each); the AFKv2 HPD harness also fails on both. These are recorded failures, not a full host-suite pass. All six T8132 DTBs were checked: 13 schema diagnostics against 11 on the base, with exactly two new DCP dma-noncoherent binding errors from #429. The seven targeted binding checks passed. These software gates do not replace the required shared-code boots.

This still waits on m1n1 #47's window-union fix and gate rerun. U-Boot #13 is required for per-kernel DTBs; the bundled-tree path already has the control-tree reservations. Package the enabled J713 AOP control DTB with that loader, then merge this before #437 and #450. The combined audio train also needs the shared AOP/audio regression boot. The old changes-requested text concerns the removed implementation, not a request to restore it.

@RyanTheTide

RyanTheTide commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

The revised kernel path uses loader-owned mappings, which resolves the earlier raw DAPF/IOMMU ownership concern. The remaining software hold is in the required m1n1#47 companion at 8d749003fdf1.

A synthetic counterexample for dapf_t8132_windows() uses inclusive spans [0x10000, 0x13fff], [0x20000, 0x23fff] and [0x12000, 0x20fff]. Growing the previous aligned window leaves the next output window overlapping it, because the scan does not revisit the grown window. The existing public test passes, the added coalescing counterexample fails, and decrementing pos before continuing makes both pass. That loader correction needs review before qualifying the handoff chain; this is a helper-contract failure, not a claim of a measured kernel failure.

On integration/aurora at 421e314 with shared #438 and #456, DCP is PASS (63/63). KUnit has 905 passes and 1 policy skips. Universal WERROR is PASS; Fedora-base WERROR is PASS. Targeted DT validation passes.

Needs fix, m1n1#47 must recheck a grown window before its successor. The operator reports #456 passed all 63 host groups with stock make 3.81 and GNU Make; this worker did not rerun native macOS on the assembled base. Hardware still needed: After loader fix, J713 AOP startup/failure/rebind; Neo and M1 Pro/M2 regression.

@erikwb

erikwb commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

The m1n1#47 window-union fix has landed. It is in 1b9b611ba3ef, which is now the head of m1n1#47, not 8d749003fdf1. When a slice grows the window before its insertion point, coalescing now continues from that grown window. Your counterexample ([0x10000,0x13fff], [0x20000,0x23fff], [0x12000,0x20fff] → [0x10000,0x24000)) and the earlier ordering are both regression tests in test_j713_aop_dapf.py, and both fail on the old code. Details are in https://github.com/aurora-silicon/m1n1/pull/47#issuecomment-6405105749.

@erikwb

erikwb commented Nov 1, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #819 (the T8132 AOP: binding and match entry) and #820 (the J713 audio on it), both on integration/aurora. The loader-owned handoff from your review is unchanged. #819 gives the m1n1#47 and u-boot#13 status and the AOP start-failure/rebind result you asked for.

@erikwb erikwb closed this Nov 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants