Skip to content

PCI: apple: train a T6050 root port the boot loader left down (J716s N1) - #1182

Merged
RyanTheTide merged 12 commits into
aurora-silicon:integration/aurorafrom
rolotrealanis98:n1-kernel-train
Nov 10, 2026
Merged

RyanTheTide merged 12 commits into
aurora-silicon:integration/aurorafrom
rolotrealanis98:n1-kernel-train

Conversation

@rolotrealanis98

Copy link
Copy Markdown
Contributor

On the M5 Pro/Max laptops iBoot leaves apcie0 port 0, the N1 Wi-Fi/Bluetooth, untrained: the N1 is held off (SMC GPIO gP13 low, PERST# low), the shared PCIe PHY is in reset with its clocks off, and the port's power states are gated. #937 adopts a port only if the boot loader trained it, so until now Wi-Fi needed a loader that trains the port (on the J716s our m1n1 does, with ANS started for its storage checks and an SMC reset pulse). edimoldovan's J714c tree lets the kernel train the port itself when the adoption checks find the link down and the port names its endpoint's power line; the adoption checks then run unchanged. This brings that work here, with what the J716s (MacBook Pro 16-inch, M5 Pro) needs on top.

Commits:

  1. PCI: apple: T6050 adopted ports: no ASPM, and a shutdown that holds the port (ed). ASPM stripped from adopted root ports, and a shutdown that parks each adopted port as the boot stage leaves it. Without it the J716s freezes about 30 s after the N1 firmware starts unless pcie_aspm=off is set, and a restart with the link alive does not come back. This supersedes the ASPM-only change I had held for PCI: apple: adopt the T6050 root ports the boot loader trained #937.
  2. dt-bindings: pci: apple,pcie: Let the OS train a T6050 root port. pwren-gpios on a T6050 root port, the new reg-names and the six host tunable lists.
  3. PCI: apple: T6050 adopt: train a port the boot loader left down (ed). The shared PHY is brought up (clocked and out of reset), then the RC run bit, PERST# held, the endpoint powered, then PCI: apple: adopt the T6050 root ports the boot loader trained #937's port enable, configure and train sequences, then the bus numbers. Root-port configure now reaches the root port through ECAM, because there is no pci_dev before enumeration.
  4. PCI: apple: T6050 cold train: apply the host tunables (ed). apple,tunable-{axi2af,cio3pllcore,pcieclkgen,phy,phy-ip-pll,phy-ip-auspma} in m1n1's order. The phy list is what clears lane bit 28, which the adoption checks require.
  5. dt-bindings: iommu: apple,dart: add apple,manual-availability (ed).
  6. iommu: apple-dart: probe a manual-availability DART after its client (ed). Merged next to the J713 display-DART checks in apple_dart_probe().
  7. PCI: apple: make an adopted port's DART available (ed). The DART of a port that is not up takes an SError when probed. With this it can be enabled in the DT and still probe only after the host has the port up.
  8. PCI: apple: T6050 cold train: reset a warm N1, power it off at shutdown. A restart resets the SoC but not the N1, which keeps running its firmware. The train now holds the power line low for 250 ms (the 50 ms of commit 3 does not reset a warm N1; m1n1 measured 250 ms on the J716s). It takes PERST# and the power line before its first register write, so that a probe deferred for the late SMC GPIO bank leaves the hardware untouched. The link-up wait is 1 s, as m1n1 allows. Shutdown drops the power line after the park when Linux trained the port.
  9. gpio: macsmc: drive the J716s N1 power line with its ADT template. The J716s ADT gives the N1's power line as pKW4("gP13", 0x00800000), the same descriptor as J713's radio. It is written as 0x00800000 | level, the write m1n1 uses on this machine, instead of the generic CMD_OUTPUT (which the J714c uses).

The J716s DT change goes on top of #1167, because the J716s DT is not in this tree: branch n1-kernel-train-dt = #1167 + commit 5 + arm64: dts: apple: t6050-j716s: let the kernel train the N1's port. That commit adds the shared PHY, PHY common block and the four tunable windows to pcie0, pwren-gpios = <&smc_gpio 0x13> on port00, the SMC's first GPIO bank (gP keys), apple,manual-availability on dart_apcie0, and the port's power chain in pmgr1. iBoot leaves APCIE_SYS_GP, APCIE_PHY_SW and APHY_GP_AUS5 in auto-PM with the block gated, the same on the J714c. In that commit they are always on with auto-PM off, rather than genpd-managed as in the J714c tree: the adopted link is kept up through suspend-to-idle, and genpd would power a consumer's domain off in system sleep. I can add it to #1167 instead if you prefer.

Loader contract. port00 and dart_apcie0 stay disabled in the DT. The loader enables them when the port is up, or when the port is down but names pwren-gpios and its DART has apple,manual-availability. The loader copies the six host lists from the ADT (apcie-<name>-tunables, cio3pllcore moved into the pcieclkgen window at +0x2200 as in the J714c tree) next to the port lists it already copies. These values differ between the J716s and the J714c (the PHY PLL fields), so they cannot be static. That is the m1n1 side (follow-up to aurora-silicon/m1n1#65): with it, the m1n1 N1 training (ANS start, SMC pulse, warm-entry handling) is no longer needed.

Tested on: J716s, kernel 7.3.0-g50d99dcea7b4 = our J716s series (#937, #938, #1167 and the T6050 PRs) + these commits. The patches here are the same, rebased, with two cosmetic changes: kzalloc_obj() in the DART change and a shorter field comment. Boots self-testing from the primary slot, battery on, no pcie_aspm=off:

  • Port left down by the loader (m1n1 fills the DT only, no training): m1n1 n1: port 0: rc ctl 0x0 stat 0x1, port status 0x6 linksts 0xc300220c ltssm 0x0, n1: port 0 not up: root port and DART okay. Kernel:
    [    1.004191] pcie-apple 1cb0000000.pcie: port 0: trained by Linux, the boot loader left it down
    [    1.005704] pcie-apple 1cb0000000.pcie: port 0: RID 0100 -> SID 1, slot 1
    [    1.006961] pcie-apple 1cb0000000.pcie: adopted port 0, endpoint 01:00
    [    1.360162] pcie-apple 1cb0000000.pcie: port 0: link retrained after a root-port reset
    [    1.387031] pcie-apple 1cb0000000.pcie: port 0: RID 0101 -> SID 2, slot 2
    [    1.389455] pcie-apple 1cb0000000.pcie: port 0: RID 0102 -> SID 3, slot 3
    [    4.320192] apple_centauri 0000:01:00.0: Wi-Fi firmware channel list: 709 bytes, capabilities: 570 bytes
    
    106b:1900, 1902 and 1903 enumerate; wlan0 associates; hci0 up; uptime 77 s at the first SSH login.
  • Warm restart (systemctl reboot with wlan0 in use): the next boot trains the port again (same lines, 1.036 s), Wi-Fi and Bluetooth back.
  • Port trained by the loader (the previous path): adopted as before, with the DART probed after the host; Wi-Fi and Bluetooth up.
  • Suspend-to-idle with the N1 adopted (our s2idle patch for adopted links, not part of this PR) passed twice on the loader-trained path. The kernel-trained port goes through the same adoption.

Checks (omacom's tools/aurora-ci, run locally against this base):

  • check-commits: pass (every commit signed off; checkpatch notes only the missing author sign-off on edimoldovan's six commits).
  • compile-check, per commit (defconfig + asahi.config, PCIE_APPLE, APPLE_DART, GPIO_MACSMC, MFD_MACSMC on; clang 21.1.8, W=1): pass. The base and each of the 9 commits compile with 0 errors and 0 new W=1 warnings, including the three users of include/linux/soc/apple/dart.h.
  • dt-check (dtschema 2026.9): PASS. No new problems. The two changed bindings pass dt_binding_check; 118 DTBs build at base and head.
  • checkpatch --strict: 0 warnings. The only errors are NO_AUTHOR_SIGN_OFF on edimoldovan's commits (see Authorship).
  • DT half (n1-kernel-train-dt on arm64: dts: apple: add the J716s (MacBook Pro 16-inch, M5 Pro) #1167): t6050-j716s.dtb builds and its dtbs_check has no new warnings. dt-check reports no new blocking problems, but its dt-validate step fails at base and head alike (KeyError 'uint8-array', from conflicting apple,tunable types in three bindings). Advisory only: gpio@67500000 has a unit name without reg (the same pattern as the existing gp bank at gpio@67700000).

Dependencies: #937: branch n1-kernel-train is stacked on its head a873be0 (j716c/t6050-pcie), so this PR targets j716c/t6050-pcie and can be retargeted to integration/aurora once #937 lands. Nothing in integration/aurora adopts a T6050 link without it. The DT half depends on #1167 and on commit 2 here.

Authorship: commits 1, 3-7 are edimoldovan's (from t6050-j714c on his fork, where the cold train has run on the J714c). They carry his authorship but no Signed-off-by of his own, only mine. @edimoldovan, could you add your Signed-off-by, or say if you would rather send them yourself?

Open questions:

  • gP13: the template write on the J716s and CMD_OUTPUT on the J714c. Is the template right for both machines? Then the J714c could take the same path.
  • cio3pllcore at pcieclkgen + 0x2200 is the J714c tree's placement. The m1n1 training this replaces never applied cio3pllcore, pcieclkgen or the PHY-IP lists, and trained the J716s anyway.
  • Always-on GP domains (J716s DT) versus genpd consumers (J714c tree). The second needs the host to stay out of genpd's system-sleep power-off for a link kept through s2idle.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 7, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-07T22:50:44.342116Z a0e28f1 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a0e28f1c1a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +2280 to +2282
bus = pcie->cfg->busr.start + 1 + port->idx;
if (bus > pcie->cfg->busr.end)
return -EINVAL;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Match cold-trained bus numbers to the admitted port order

When earlier root ports are disabled or rejected, this gives a higher-numbered cold port the wrong secondary bus: port 1 alone gets bus 2. In the normal non-PCI_PROBE_ONLY path, pci_host_common_init() enables PCI_REASSIGN_ALL_BUS, and pci_scan_bridge_extend() assigns the first surviving bridge bus 1 unless it has fixed EA bus numbers. Adoption has already recorded bus 2 in adopted_bus and installed its RID route, so apple_pcie_map_bus() rejects endpoint accesses on the newly assigned bus 1; alternatively, adoption fails earlier if iommu-map already describes bus 1. Choose numbers consistent with the actually admitted ports, or prevent the PCI core from renumbering them.

Useful? React with 👍 / 👎.

Comment on lines +2663 to +2665
ret = apple_pcie_t6050_cold_train(port);
if (!ret)
ret = apple_pcie_adopt_link(port);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Park cold-trained ports on subsequent setup failures

If cold training succeeds but the second adoption check or subsequent IRQ setup fails, err_teardown calls apple_pcie_port_teardown(), which removes IRQ/RID state but does not assert PERST#, stop the port clocks, or lower the newly acquired pwren. The failed port is then absent from pcie->ports, or the host probe fails altogether, so apple_pcie_shutdown() cannot park that live link either. This can leave precisely the link-alive state that the new shutdown hook is intended to eliminate on restart. Track cold-training ownership and unwind the powered/trained hardware before discarding a failed port.

Useful? React with 👍 / 👎.

Comment on lines +4076 to +4077
if (!apple_dart_is_available(dev->of_node))
return dev_err_probe(dev, -EPROBE_DEFER, "waiting for its client\n");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Exempt late DART providers from fw_devlink probe ordering

With fw_devlink=on fw_devlink.strict=1, a manual-availability DART referenced by the host's iommu-map creates a probe deadlock. Strict mode treats inferred dependencies as “mandatory dependencies” (Documentation/admin-guide/kernel-parameters.txt:1831-1833), and drivers/of/property.c parses iommu-map into a host-to-DART supplier link. Consequently, device_links_check_suppliers() prevents apple_pcie_probe() from running until the DART binds, while this new check defers the DART until that same host probe calls apple_pcie_dart_available(). Make the late-provider relationship visible to fw_devlink, for example through a documented post-init-providers requirement, so both devices do not remain deferred indefinitely.

Useful? React with 👍 / 👎.

@rolotrealanis98

Copy link
Copy Markdown
Contributor Author

The base branch j716c/t6050-pcie was force-pushed (a873be0 to 911da8c), so the head conflicted with it in apple,pcie.yaml, pcie-apple.c and gpio-macsmc.c; rebased onto 911da8c with the conflicts resolved and edimoldovan's commits unchanged in content. The binding also needed the six new reg-names in the second t6050 block that the new base added (maxItems 14 to 20); the nine commits compile clean at W=1 per commit.

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

Needed before this can go in:

  1. Signed-off-by from the author. These six commits are authored by ed <edimoldovan@gmail.com> and carry only Rolando Trevino's Signed-off-by: 1fe4cb3, a053aaf, ef54401, 3cd54a5, 9e8ec7e, 5d83e63. Each needs the author's own Signed-off-by: Eduard Moldovan <edimoldovan@gmail.com> (added by him, e.g. git rebase -x 'git commit --amend --no-edit -s' on his side), with Rolando's kept after it as the person passing them on.

  2. Base. j716c/t6050-pcie (911da8c) is already contained in integration/aurora, so this can be retargeted to integration/aurora with the same nine commits. After retargeting it conflicts with integration/aurora in Documentation/devicetree/bindings/iommu/apple,dart.yaml and drivers/iommu/apple-dart.c (both sides add next to the same hunks); please rebase onto integration/aurora and resolve those.

  3. Named fields for the new register writes in pcie-apple.c:

    • apple_pcie_t6050_cold_train(): writel(0x140, pcie->base + CORE_RC_T6050_PRE_RUN) needs the value built from named, commented fields.
    • apple_pcie_t6050_shared_phy_on(): T6050_PHY_CFG BIT(0) and BIT(4) and T6050_PHY_STAT BIT(0) need names.
    • apple_pcie_shutdown() copies the PME_Turn_Off/L2 part of apple_pcie_t6050_reset_root_port() (| 0x100 on PORT_APPCLK, writel(0x11, 0x88), the poll of 0x88 bit 0, PORT_LINKSTS BIT(6), port->phy BIT(31)). Please move that sequence into one helper used by both, with names for those values (0x100 is PORT_APPCLK_CGDIS).

Lab-board scope checked: the PCIe changes run only with t6050_hw.adopt_link, the DART deferral only with apple,manual-availability, and the SMC GPIO change only on apple,j716s.

@edimoldovan

Copy link
Copy Markdown
Contributor

Signed-off-by: Eduard Moldovan edimoldovan@gmail.com
If this is enough, go for it @rolotrealanis98

edimoldovan and others added 10 commits November 10, 2026 05:50
…he port

On the J714c the one-boot kernel (aurora's adopt path, the N1 in its ROM
personality without firmware) froze 20-40 s after boot: user space first,
then the whole SoC; a boot with pcie_aspm=off ran clean, a boot with the
PCIe node disabled ran clean. The bus notifier that strips ASPM L1 from
tunneled root ports now serves adopt_link hosts too and strips L0s and L1
from the adopted root ports, so the link stays in L0.

A restart with the adopted link alive never came back to m1n1 (hard reset
needed), while the same restart with the PCIe node disabled did. The
platform driver gets a shutdown that puts each adopted port back into the
boot stage's cold state: bridge decoding off, PME_Turn_Off and L2, PERST#
asserted, the port and its lane clocks stopped (the first half of
apple_pcie_t6050_reset_root_port, without the restart).

Link: edimoldovan/linux-aurora@ab24d156868e
Signed-off-by: Eduard Moldovan <edimoldovan@gmail.com>
Signed-off-by: Rolando Trevino <rolotrealanis@gmail.com>
A T6050 root port that names its endpoint's power line can be left
untrained by the boot loader: the OS powers the endpoint and trains the
link itself, then adopts it like a port the boot loader trained.

Allow pwren-gpios on such a port, the windows the train uses in
reg-names (phy-shared, phy-common, axi2af, pcieclkgen, phy-window,
phy-ip) and the six host tunable lists the boot loader copies from the
Apple device tree, as (offset, width, mask, value) groups.

Signed-off-by: Rolando Trevino <rolotrealanis@gmail.com>
Assisted-by: LLM Claude
The adopt path takes a T6050 port only if the boot loader trained its link.
iBoot does not on the J714c: its N1 is held off (SMC GPIO gP13 low, PERST#
low), the shared PCIe PHY is in reset with its clocks off, and Wi-Fi works
only when the port is trained over the m1n1 proxy before the kernel starts.

When the adopt checks find the link down and the port names pwren-gpios,
train it: the shared PHY clocked and out of reset (phy-shared, phy-common),
the RC running, PERST# held and the endpoint powered, then the port enable,
configure and train sequences the root-port reset already uses, and the
bus numbers a boot loader leaves. The adopt checks then run unchanged. The
adopt gate accepts pwren-gpios on such a port.

The root-port configure step now reaches the root port through the ECAM
window: before enumeration there is no pci_dev. The root-port reset uses
the same code.

Link: edimoldovan/linux-aurora@0f96cc6c00e1
Signed-off-by: Eduard Moldovan <edimoldovan@gmail.com>
Signed-off-by: Rolando Trevino <rolotrealanis@gmail.com>
A port trained without the boot loader's tunables comes up, but the PHY
tunables are what clear lane bit 28 (and the shared PHY's bit 26); the
adopt checks expect that state, and every proxy-trained boot has had it.
Apply the host lists the DT carries (apple,tunable-axi2af, -cio3pllcore,
-pcieclkgen, -phy, then -phy-ip-pll and -phy-ip-auspma after the PHY
clocks), in m1n1's order. The windows may contain windows mapped elsewhere,
so they are mapped without claiming them.

Link: edimoldovan/linux-aurora@17ada56a25c9
Signed-off-by: Eduard Moldovan <edimoldovan@gmail.com>
Signed-off-by: Rolando Trevino <rolotrealanis@gmail.com>
A DART behind a PCIe root complex answers only once the root complex is
up. Mark such a DART so it probes only after its client says so.

Link: edimoldovan/linux-aurora@8805d2777c8b
Signed-off-by: Eduard Moldovan <edimoldovan@gmail.com>
Signed-off-by: Rolando Trevino <rolotrealanis@gmail.com>
A DART marked apple,manual-availability defers its probe until its
client calls apple_dart_make_available() for its node.

[Rolando: kzalloc_obj(), which this tree prefers]

Link: edimoldovan/linux-aurora@dbd43f4ff3da
Signed-off-by: Eduard Moldovan <edimoldovan@gmail.com>
Signed-off-by: Rolando Trevino <rolotrealanis@gmail.com>
Once a port is adopted, trained by the bootloader or by Linux, the root
complex is up: make the port's DART available.

Link: edimoldovan/linux-aurora@3291060c462a
Signed-off-by: Eduard Moldovan <edimoldovan@gmail.com>
Signed-off-by: Rolando Trevino <rolotrealanis@gmail.com>
A restart resets the SoC but not the J716s N1: it keeps running its
firmware with its power line (SMC gP13) released. m1n1 found that a
50 ms power cycle does not bring such an N1 back in its ROM
personality, and holds the line low for 250 ms when it reads released
(the J716s warm-restart runs, three of three). The cold train cannot
read the line back, so it always holds it low for 250 ms; a cold boot
pays 200 ms.

The train takes PERST# and the power line before its first register
write: the SMC's GPIO bank probes late, and a probe deferred for it
must not leave the shared PHY and the root complex half set up.

The J716s N1 got up to 1 s for link up in m1n1 after its power-up;
the train now allows the same instead of 500 ms. The root-port reset
shares the wait, where only a failure takes longer.

A port Linux trained keeps the endpoint's power line, and shutdown
drops it after parking the port, so the boot after a restart finds the
N1 cold whether its loader trains the port or the kernel does.

Signed-off-by: Rolando Trevino <rolotrealanis@gmail.com>
Assisted-by: LLM Claude
The J716s N1's power line is /arm-io/apcie0/pci-bridge0 function-reset,
pKW4("gP13", 0x00800000): the descriptor J713's /amfm/function-reg_on
uses. m1n1 trains the N1's port on the J716s by writing that template
with the level in its low bits (0x00800000, then 0x00800001); the
generic CMD_OUTPUT write was never tried on this machine.

Drive gP13 on the J716s as on J713, so the kernel's own train of the
port powers the N1 with the same SMC writes.

Signed-off-by: Rolando Trevino <rolotrealanis@gmail.com>
Assisted-by: LLM Claude
Name the bits the T6050 shared PHY bring-up and the RC run write use,
after what a trace of macOS bringing the port up and down shows them
doing: PORT_APPCLK_CGDIS (the clock gate disable the driver already
defines) for the 0x100 written before PME_Turn_Off, PORT_PME_TURN_OFF
for the 0x88 register macOS writes 0x11 to, PORT_LINKSTS_L2 for the link
status bit macOS reads as "reached L2", and PHY_LANE_CFG_REFCLKCGEN_B31
for the lane bit it clears after asserting PERST#. The PHY_CFG bits 0
and 4, PHY_STAT bit 0, the PME_Turn_Off bit 4 and the two bits of the
0x140 written to the RC before it runs have no documented meaning, so
they get neutral names and a comment with what the traces show.

The PME_Turn_Off and L2 wait was written out twice, in the root-port
reset and in the shutdown. Move it into apple_pcie_t6050_port_l2(). The
register writes, values, order and timeouts are unchanged. Both polls
now always run, so a failed first poll in the root-port reset no longer
skips the second one (a read-only poll, up to 500 ms on that error
path); the shutdown already ran both.

Signed-off-by: Rolando Trevino <rolotrealanis@gmail.com>
Assisted-by: LLM Claude
@rolotrealanis98
rolotrealanis98 changed the base branch from j716c/t6050-pcie to integration/aurora November 10, 2026 11:43
@rolotrealanis98

Copy link
Copy Markdown
Contributor Author

Updated (head 5282665), retargeted to integration/aurora and rebased onto 0227cec.

  1. Sign-off. Eduard's six commits now carry Signed-off-by: Eduard Moldovan <edimoldovan@gmail.com> before mine, taken from his comment above. Authorship is unchanged, so checkpatch still notes that the author name is "ed". If the trailer has to come from a push of his, tell me and I will ask him.
  2. Base. The conflicts in apple,dart.yaml and apple-dart.c keep both sides.
  3. Names, in one new commit on top (5282665) so Eduard's commits stay as he wrote them:
    • 0x140 at CORE_RC_T6050_PRE_RUN is built from two named bits, and T6050_PHY_CFG bits 0 and 4 and T6050_PHY_STAT bit 0 have names. A trace of macOS shows these being written and polled but not what they mean, so the names are neutral and the comments say what the trace shows.
    • The PME_Turn_Off/L2 sequence is apple_pcie_t6050_port_l2(), used by the root-port reset and by shutdown, with PORT_APPCLK_CGDIS, PORT_PME_TURN_OFF and PORT_LINKSTS_L2.
    • One difference on an error path: the root-port reset used to skip the L2 poll when the PME_Turn_Off poll failed; the helper runs both, as shutdown already did.

All ten commits compile with W=1 and no warnings. Not boot-tested since the rebase.

Two of the Codex findings are real and not fixed here, since I cannot test either on the hardware yet: a cold-trained port is not parked if a later setup step fails, and a apple,manual-availability DART deadlocks with the host under fw_devlink.strict=1. The bus-number finding is not a bug: adoption reads the bus number back from config space.

When the driver cold-trains a T6050 port it raises the endpoint's power
(pwren), releases PERST# and trains the link. If the second adoption
check, the IRQ setup or a later step then fails, err_teardown only
releases the IRQ and RID state and drops the port from pcie->ports. The
shutdown hook walks that list, so it never parks the port: the link
stays up and the endpoint powered across a restart, the state the hook
exists to prevent. A failure inside the cold train after the pwren write
leaves the same.

Remember that the cold train raised pwren (port->powered, set just
before the write) and, from err_teardown, put the port back the way the
shutdown hook does. The park sequence is now one function,
apple_pcie_t6050_port_park(), used by the shutdown hook and by the
failure path: PME_Turn_Off to L2, PERST# asserted, the lane clock
request off, the port disabled and its clocks stopped, the endpoint's
power off. The unwind runs after apple_pcie_port_teardown(), which
still writes the port's registers and so needs the port clocked.

What runs depends on how far the cold train got:
- Failure before the pwren write: nothing. pwren was requested low and
  no port register was written, so there is nothing to undo.
- Link not up (the enable, configure or train step failed): no
  PME_Turn_Off, which has no one to answer and would only wait out two
  500 ms timeouts; then the rest of the sequence. The disable is best
  effort on a port that was never fully enabled: its first wait may
  time out, in which case the endpoint is still powered off.
- Link up (the second adoption check, IRQ setup or a later step
  failed): the full sequence as at shutdown, after clearing the bus
  numbers the cold train wrote, as the hook does.

The shutdown hook runs the same steps in the same order as before. The
disable no longer takes a pci_dev: it read the root port's LTSSM state
through config space, which does not exist during probe, and now reads
the same register through the ECAM window as the rest of the cold
train does.

The success path and the adopt-only (loader-trained) path are not
changed. Compile-tested only.

Signed-off-by: Rolando Trevino <rolotrealanis@gmail.com>
Assisted-by: LLM Claude
…availability DART

A DART marked apple,manual-availability defers its probe until the PCIe
host calls apple_dart_make_available() from its own probe. The host's
iommu-map makes fw_devlink create a host to DART supplier link;
iommu-map is an optional supplier, enforced only under
fw_devlink.strict=1, where the host then waits for the DART while the
DART waits for the host and neither probes.

post-init-providers is the property for this: fw_devlink ignores the
link to a supplier listed in it (the flag is merged onto the link that
iommu-map created). Allow it on the host node and say in the
apple,manual-availability description that the host must list the DART
there. No driver change is needed.

Compile-tested only.

Signed-off-by: Rolando Trevino <rolotrealanis@gmail.com>
Assisted-by: LLM Claude
@rolotrealanis98

Copy link
Copy Markdown
Contributor Author

Two more commits on top (head 22dcb0f) for the two Codex findings I had left open. Both are compile-tested only; the J716s is busy, and I will boot them and report here.

  • de988b6 "T6050 cold train: park the port when its setup fails". The driver records that the cold train raised pwren, and err_teardown then parks the port: PME_Turn_Off to L2 only if the link is up, PERST# asserted, the lane clock request off, the port disabled, the endpoint's power off. The sequence is one function, apple_pcie_t6050_port_park(), which the shutdown hook now calls too, with the same steps in the same order as before.

    One change reaches paths that have run on hardware: apple_pcie_t6050_port_disable() no longer takes a pci_dev. It read the root port's LTSSM state through config space, which does not exist yet during probe, and now reads the same register through the ECAM window. The shutdown hook and the root-port reset use that function, so they need a new boot test as well.

  • 22dcb0f "allow post-init-providers for a manual-availability DART". Under fw_devlink.strict=1 the host waited for the DART that iommu-map names while that DART waited for the host. The host node now lists the DART in post-init-providers, which makes fw_devlink skip that link (as t8103-j313.dts does for its framebuffer). This commit allows the property in the apple,pcie binding and says so in the apple,manual-availability description; the J716s DT gets the property in arm64: dts: apple: t6050-j716s: let the kernel train the N1 root port (on #1167) #1183.

All twelve commits compile with W=1 and no warnings; dtbs_check of t6050-j716s passes on the #1183 branch.

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.

3 participants