Customize PCIe (per-controller status / lanes / speed)
Overview
PCIe on Tegra264 (Thor, pcie@C0..C5) and Tegra234 (Orin,
pcie@C0..C10) is split across multiple controllers that share the
UPHY lane pool with USB3 / MGBE / UFS. Each controller's runtime
behavior is determined by two surfaces, both required:
| Surface | Target | Authoritative for |
|---|---|---|
ODMDATA pcie@N_status=β¦ (+ pcie@N_max-link-speed, pcie@N_pcie-mode, pcie@N_clk-scheme, pcie-cN-endpoint-enable) |
/pcie/pcie@N in BPMP DTB |
UPHY lane power, refclk gating, controller-side power rails |
Kernel-DT overlay on &pcieN |
/bus@0/pcie@<addr> in kernel DTB |
Kernel probe, lane width, link speed, RC/EP mode |
Skipping the kernel overlay on a disable lets the kernel probe a powered-down PHY (link timeouts in dmesg). Skipping the ODMDATA token on a disable leaves BPMP holding the PHY hot.
Agentic, not table-driven β no controller table, no
questions.json. Every controller, lane width, schematic-routed
receptacle, and authoritative DT node address is discovered at runtime
from the docs + DTB + carrier pinmap.
The output is a kernel-DT overlay commit only. Per-controller
fragment@N blocks are appended to the composite custom overlay
.dts per
../../references/bsp-customization-kernel-dtb.md
and committed to the bsp_sources/ hardware repo.
/jetson-build-source compiles the composite to .dtbo and owns its
Makefile + flash-conf registration.
This skill MUST NOT edit ODMDATA="...". All ODMDATA tokens
(pcie@N_status=β¦, pcie@N_max-link-speed, pcie@N_pcie-mode,
pcie@N_clk-scheme, pcie-cN-endpoint-enable, plus the
uphyX-config-N surface tokens and UPHY_CONFIG="" clear) are
emitted by /jetson-customize-uphy in a single atomic commit on the
carrier flash-conf fork. The allocation table this skill consumes
from the UPHY sidecar already tells the operator which controllers
are okay / disabled / per-lane sized; this skill only translates
that table into kernel-DT overlay fragments and verifies that the
overlay agrees with the ODMDATA already committed by customize-uphy
(consistency check in Step 8 β disagreement is reported, not silently
fixed).
When to invoke
- The user says "configure PCIe", "enable PCIe controller", "set PCIe
num-lanes", "change PCIe link speed", or asks to flip a
pcie@N_statustoken. - A specific PCIe slot or M.2 receptacle doesn't enumerate after flash, OR the link trains at the wrong width / speed.
jetson-customize-uphyran and re-allocated lanes across PCIe controllers (e.g. switched fromuphy0-config-7touphy0-config-6enabling PCIe C3); the per-controller side now needs to be brought up.jetson-customize-mgbereports the QSFP path is wired but the kernel doesn't probe its PCIe-side companion (rare; XFI configurations).
Prerequisites:
- Active profile with
reference_devkit:+custom_carrier:blocks. <source.root_path>/Linux_for_Tegra/.gitexists (/jetson-init-source).- /jetson-derive-carrier has run β carrier flash-conf fork is in the overlay tracker.
- /jetson-customize-uphy has run β its JSON sidecar at
<workspace>/target-platform/<profile-stem>.jetson-customize-uphy.jsondrives the per-controllerenabledecision. - Source-of-truth docs registered or supplied at prompt: Adaptation Guide, Module Design Guide, SoC TRM.
- When
custom_carrier:is present, bothdocuments.custom_carrier_schematicANDdocuments.custom_carrier_pinmux_xlsare REQUIRED. Refuse the run if either is missing β routing on a custom carrier cannot be guessed. Reference-devkit-only profiles skip this check. dtcon PATH.
Procedure (summary)
Full step-by-step walkthrough lives in
references/procedure.md. High-level flow:
- Resolve active target + open source-of-truth documents (incl.
<carrier-pinmap>,<ref-dtb>,<uphy-state>). Refuse if<uphy-state>is missing. - Diff PCIe topology β devkit vs custom carrier β by decompiling
<ref-dtb>and grepping the schematic forPEX<N>_*net labels. AskUserQuestion(multiSelect) β which controllers to customize.- Per-controller verification: pinmap + schematic +
pin_verifier.pyforPE<N>_CLKREQ_L,PE<N>_RST_L, optionalPE<N>_WAKE_L. - Auto-derive per-controller plan (
enablefrom<uphy-state>,lanes/speedfrom Adaptation Guide,modehard-pinned to"rc") β mandatory confirm-or-customize gate. - Append per-controller
fragment@Nblocks (marker/* custom-bsp: pcie:pcie@<addr> */) to the composite custom overlay.dtsinbsp_sources/. Pre-flightdtc+fdtoverlay. Commit via the workflow's preview gate. Do not editODMDATAβ /jetson-customize-uphy already emittedpcie@N_status=β¦,pcie@N_max-link-speed,pcie@N_pcie-mode,pcie@N_clk-scheme, andpcie-cN-endpoint-enablein its single atomic ODMDATA commit. This skill only translates the per-controller plan into kernel-DT overlay fragments. - (Step folded into Step 6 β overlay-only emission.)
- Cross-check ODMDATA vs overlay consistency. On a contradictory
row, stop and ask the user how to recover the two commits.
Never run
git reset --hardautonomously. - Write run-state JSON sidecar at
<workspace>/target-platform/<profile-stem>.jetson-customize-pcie.json- summary, then drive the downstream next-step chain via sequential
AskUserQuestionprompts perreferences/procedure.mdStep 9. Never substitute a printed "Next step: β¦" line for the prompts.
- summary, then drive the downstream next-step chain via sequential
Limitations
- Mode hard-pinned to RC. Endpoint mode is only emitted when the
operator passes
mode_override="ep"in Step 5c. enableis derived, not asked. UPHY-allocated controllers are mandatorilyokay; non-allocated are mandatorilydisabled.- No upstream BSP edits. Output lands in
Linux_for_Tegra/+bsp_sources/only. - Pre-flight overlay merge is a sanity check, not the production build. /jetson-build-source is authoritative.
- Flash-conf overlay registration is out of scope. Owned by /jetson-build-source Step 5.0a.
Troubleshooting
<uphy-state>missing β run /jetson-customize-uphy first.- Slot doesn't enumerate after flash β check
dmesg | grep pcie; re-verify ODMDATApcie@<N>_status=okayand the overlay fragment agree (Step 8 table inreferences/procedure.md). - Link trains at wrong width β confirm UPHY config in
<uphy-state>allocates the expected lane count; the kernel fragment'snum-lanesmust match. compatiblemismatch β fix the composite root, not the fragment. UEFI plugin-manager silently skips on mismatch.- Contradictory ODMDATA-vs-overlay row β ask the user; do not
auto-
git reset --hard. See gotchas. - Common pitfalls β see
references/gotchas.md(RC pinning, node- address sourcing, stock-disabled controllers, intra-file handoff withjetson-customize-uphy).
References
references/procedure.mdβ full nine- step procedure (topology diff, plan derivation, overlay append, ODMDATA cross-check, sidecar).references/gotchas.mdβ failure modes- invariants (RC pinning, address sourcing, BPMP handoff).
../../scripts/pin_verifier.pyβ shared HSIO pin verifier (Step 4).../../references/platform_template.yamlβdocuments:block consumed by Step 1.../../context/bsp-customization-workflow.mdβ overlay edit protocol + commit message preview gate.../../references/bsp-customization-kernel-dtb.mdβ composite overlay filename / skeleton / append protocol.../jetson-customize-uphy/SKILL.mdβ sibling skill that owns UPHY lane allocation; its sidecar drives the per-controllerenabledecision.../jetson-customize-pinmux/SKILL.mdβ sibling skill invoked by Step 4 (with operator confirmation) to fix HSIO pin SFIO mismatches.../jetson-customize-mgbe/SKILL.mdβ sibling for MGBE controllers; shares the two-surface (ODMDATA- overlay) pattern.
../jetson-derive-carrier/SKILL.mdβ must run first; produces the carrier flash-conf fork edited in Step 6.../jetson-init-source/SKILL.mdβ produces the overlay tracker + bsp_sources repo this skill commits into.