Skip to content

arm64: dts: apple: t8122: SPI2 and SPI4 run from the 24 MHz reference, not 200 MHz - #1598

Open
satchlj wants to merge 4 commits into
aurora-silicon:integration/aurorafrom
satchlj:fix/t8122-spi-clock-20261111
Open

satchlj wants to merge 4 commits into
aurora-silicon:integration/aurorafrom
satchlj:fix/t8122-spi-clock-20261111

Conversation

@satchlj

@satchlj satchlj commented Nov 11, 2026

Copy link
Copy Markdown
Member

Claude Fable 5.2 on @satchlj's behalf

Fixes Touch ID matching on J613 (M3 MacBook Air, T8122), which failed with SPI receive timeouts while reading fingerprint frames. This is the remaining failure reported on #1491 (0 matches in 6 attempts); #1491 fixed the transmit-only case and did not touch this path.

Cause. The T8122 device tree gives SPI2 (the fingerprint sensor's bus, spi@2a1108000) and SPI4 (spi@2a1110000) a 200 MHz input clock. Their real input is the 24 MHz reference. For an 8 MHz device the driver therefore programmed divider 25 and the bus ran at 0.96 MHz. A 29,184-byte frame took 243.2 ms against a 229 ms timeout.

Evidence for 24 MHz

  • Hardware timing: six frames of 29,184 bytes each took 243.2 ms with divider 25, which is 29184 × 8 / 0.96 MHz; that divider only yields 0.96 MHz from a 24 MHz input.
  • The J613 Apple device tree describes both controllers' clocks as 24 MHz. QSPI is 200 MHz there and is left unchanged.
  • A diagnostic kernel that only widened the timeout matched 3 of 3, confirming the timeout was the failure. An earlier candidate (reordering the FIFO threshold acknowledgement) matched 0 of 4 and is not part of this PR.

Commits

  1. arm64: dts: apple: t8122: Fix the fingerprint SPI input clock: SPI2 references the 24 MHz clock.
  2. spi: apple: Account for the programmed clock in receive timeouts: the timeout and the polling decision use the rate actually achieved after divider rounding, not the requested rate, so a rounded divider cannot reproduce this failure. Adds a host test (tools/spi/apple-spi-clock-test.py) that rejects the original driver.
  3. arm64: dts: apple: t8122: Correct the SPI4 reference clock: same correction for SPI4.

Tested on hardware (J613, exact head f1c9d85)
Kernel 7.3.0-aurora73-exact-1111-spi-D-ARCH, which is integration plus the then-open J613 PR heads plus these three commits and one transfer-metadata debug line, booted with a one-shot Stage 2 carrying the corrected device tree (the running device tree on this machine comes from the boot loader, so the dts change only takes effect through a rebuilt Stage 2).

  • Live device tree: both controllers reference /clock-ref, 24 MHz.
  • Driver: clk=24000000 div=3 on every transfer.
  • Nine full 29,184-byte frames: 29,202 to 29,252 µs each (expected wire time 29,184 µs; before the fix 243,199 µs or more). No SPI timeout and no failed transfer in the whole boot.
  • Touch ID: 5 matches in 5 verifications that received a touch (fprintd-verify, @satchlj's enrolled finger). Seven earlier verification windows expired with no finger on the sensor and attempted no frame transfer.

Offline

  • The repo's DT check on all 137 Apple boards: no new warnings; the only DTB differences are the two clock references.
  • Host clock/timeout test, arm64 build of the driver, checkpatch.

Not tested

  • SPI4 transfer timing on hardware (only its device-tree reference and divider were observed), enrollment, and lock-screen unlock on this kernel.
  • Other SoCs: T8132's SPI2 is already correct. T8122 SPI1 and the T6030/T6031 controllers were not changed because we have no clock evidence for them; they may deserve the same check by someone with that hardware.
  • That boot used a trial Stage 2 on which the display handoff was refused and the boot framebuffer was kept; unrelated to SPI, but it means this was not a full-health boot.

🤖 Generated with Claude Code

The J613 ADT gives SPI2 clock ID 0x198 a 24 MHz boot frequency.
On hardware, divider 25 produces 0.96 MHz: six 29184-byte frames take
243.2 ms and overrun the 229 ms receive deadline.

Use the existing 24 MHz reference clock so an 8 MHz request selects
divider 3. Leave SPI1 unchanged pending evidence for that controller.

Signed-off-by: Satya Benson <satya@benson.earth>
The divider rounds up, so a requested transfer rate can exceed the
achieved rate even when the input clock is described correctly. Record
the effective speed after clamping the divider and use it for the IRQ
transfer deadline and the polling decision.

Add a host test extracting the production preparation function and timeout
expression. Cover exact and rounded divisors, the divider limit and the
polling threshold with address and undefined-behavior sanitizers.

Signed-off-by: Satya Benson <satya@benson.earth>
The J613 boot clock table also describes SPI4 clock ID 0x19a as 24 MHz.
Use clkref for this unclaimed controller; the QSPI clock ID 0x188 is
200 MHz and remains unchanged.

Signed-off-by: Satya Benson <satya@benson.earth>
@satchlj

satchlj commented Nov 12, 2026

Copy link
Copy Markdown
Member Author

Claude Fable 5.2 on @satchlj's behalf

Hardware confirmation of the device-tree part, with an unpatched driver (2026-11-11, J613 M3 MacBook Air).

  • Kernel: the default package kernel 7.3.0-aurora73-ppt-2-ARCH (30.12), which does not carry this PR's driver-side changes.
  • Device tree: from the installed boot loader, Stage 2 458a7bb1cc11fd43dad41fc4e6ef6b66b8c42e8324f424ac589aa5d4347f6788, whose device trees are built from integration 4f141fc8 + thunderbolt: apple: enable the J613 USB4 host-to-host path #1490 + drm/apple: support J613 native26 external displays #973 + this PR at f1c9d85f. Live tree: spi@2a1108000 (fingerprint sensor) and spi@2a1110000 reference clock-ref, 24 MHz; the sensor binds at 8000000 Hz.
  • Result: fprintd-verify, five attempts by the owner, five verify-match (the first after one verify-retry-scan). One lock-screen unlock with the finger also passed. No spi_master … transfer timed out and no -110 in the kernel log for the whole boot.
  • For comparison, this morning on the same kernel with the previous device tree (SPI on the 200 MHz clock) every attempt ended in an SPI receive timeout and there were no matches.

Not observed: frame duration and the programmed clock divider. This kernel logs neither, so the expected ~29 ms frames and divider 3 are not confirmed by these records. The driver part of this PR was not run here.

@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.

The effective-rate accounting is right, and the J613 frame timing confirms the 24 MHz input. One small hardening: if clk_get_rate() ever returns 0, cr is 0 and the new effective_speed_hz line divides by zero; clamping cr to at least 1 would avoid that. We will run it on our SPI keyboard and Touch ID machines before merging.

@RyanTheTide

Copy link
Copy Markdown
Contributor

Interim results. Kernel: integration e661192 plus this PR and the others in this round, one-shot.

  • M1 Pro: the SPI keyboard and trackpad bind with no SPI errors and still work after 3 s2idle cycles.
  • M4 Pro (J616s): the MTP keyboard and trackpad are unchanged, with no SPI errors.

The M2 (SPI keyboard) run is still queued. The clk_get_rate() = 0 clamp from the review is still open. It's a small change, and we'd like it in before merging.

If clk_get_rate() returns zero, the calculated divider is zero and
computing effective_speed_hz divides by zero. Clamp the divider to at
least one before programming it and calculating the effective speed,
as suggested by RyanTheTide in review. Non-zero clock rates retain
their existing behavior.

Signed-off-by: Satya Benson <satya@benson.earth>
@satchlj

satchlj commented Nov 13, 2026

Copy link
Copy Markdown
Member Author

GPT-6.1 Sol on @satchlj's behalf

Pushed b876103 as one signed-off, fast-forward commit, addressing RyanTheTide's review. In drivers/spi/spi-apple.c:328-332, the existing upper bound is followed by cr = max(cr, 1U); (line 330), before programming the divider and dividing by it for effective_speed_hz. A zero clock therefore gives divider 1 and effective rate 0; the receive timeout already clamps its rate denominator to at least 1.

Checks:

  • Commit checkpatch: 0 errors, 0 warnings; git diff --check passed.
  • Compiled drivers/spi/spi-apple.o for arm64 with LLVM=1 in alba's neo-build VM (ELF aarch64), including CONFIG_SPI_APPLE_KUNIT_TEST=y.
  • Ran the driver's spi-apple-irq KUnit suite under arm64 QEMU in neo-build: all 7 tests passed.
  • Existing tools/spi/apple-spi-clock-test.py passed with address/undefined-behavior sanitizers. A supplemental, uncommitted zero-clock case also passed, checking divider 1, effective rate 0, polling choice and timeout arithmetic alongside the existing cases.

This commit has NOT been booted on hardware. The J613 is away until Friday 2026-11-13 afternoon US Eastern. The change does not alter behaviour for a non-zero clock rate.

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