Customize UPHY lane allocation
Purpose
Select a UPHY lane allocation on a Jetson custom carrier and edit the
carrier flash-conf fork's ODMDATA="..." to apply the chosen
uphyX-config-N token(s) (plus the UPHY_CONFIG="" clear required for
uphy0-config-6). Kernel-DT alignment per controller is not done
here — after the ODMDATA commit lands, this skill dispatches to the
per-controller skills (/jetson-customize-pcie,
/jetson-customize-mgbe, /jetson-customize-usb), each of which must
compare the chosen allocation against the reference kernel DTB
node-by-node and emit an overlay fragment only when the K-stock value
disagrees with the chosen allocation. Discovery is agentic: options,
lanes, and controllers come from the Adaptation Guide, carrier
schematic, and Module / SoC TRM at run time — never hard-coded. Every
user-visible step renders its data as a markdown table, and the final
summary includes a changes-summary table.
Prerequisites
- Active target-platform profile with
reference_devkit: and
custom_carrier:.
<source.root_path>/Linux_for_Tegra/.git initialized
(/jetson-init-source).
- Forked carrier conf present (
/jetson-derive-carrier).
- Reachable Adaptation Guide via
documents.adaptation_guide ->
documents.bsp_developer_guide -> web fetch -> Step-1 prompt
fallback.
- When
custom_carrier: is present, both
documents.custom_carrier_schematic AND
documents.custom_carrier_pinmux_xls are REQUIRED. The skill
refuses to run if either is missing — routing decisions for the
custom carrier cannot be guessed. Reference-devkit-only profiles
(no custom_carrier: block) do not require these.
Overview
UPHY (unified PHY) is the shared high-speed PHY pool on Tegra264 (Thor)
and Tegra234 (Orin). Lane allocation is selected by ODMDATA tokens
(uphy0-config-N, Thor also uphy1-config-N) parsed at flash time by
tegraflash_impl_t264.py::tegraflash_update_bpmp_dtb() and written
into /uphy/uphy{0,1}-config of the BPMP DTB.
Output is a single atomic ODMDATA commit in
<source.root_path>/Linux_for_Tegra/ carrying the chosen
uphyX-config-N token(s), the UPHY_CONFIG="" clear (for
uphy0-config-6), AND every per-controller ODMDATA token derived
from the chosen allocation (pcie@N_status=*, mgbeN-speed-*, USB SS
per-port tokens). Sub-skills (/jetson-customize-pcie,
/jetson-customize-mgbe, /jetson-customize-usb) own only the
kernel-DT overlay fragments — they MUST NOT touch ODMDATA. All
commits follow the batched pristine + customization pattern in
../../context/bsp-customization-workflow.md. Upstream BSP at
<bsp_image.root_path>/ is never edited.
When to invoke
- User says "configure UPHY", "uphy lane allocation",
"set uphy0-config-N", "change MGBE speed", or asks to remap
PCIe / MGBE / USB3 / UFS on a custom carrier.
- A UPHY-fed controller doesn't enumerate after flash, OR cold boot
dies in BL31 SError /
BPMP firmware is not ready.
- A downstream skill reports FMON fault or BPMP-DTB lane mismatch.
Procedure (summary)
Eight steps; full detail in references/procedure.md.
Resolve target + docs. Refuse without active profile, custom
carrier, source-tree git, or forked carrier conf. Resolve Adaptation
Guide / schematic / Module Design Guide / SoC TRM.
Locate "Configure the UPHY Lane" in the Adaptation Guide (PDF /
HTML mirror / WebFetch). Cross-check Module Design Guide + SoC TRM.
Cross-reference the carrier schematic. Cite UPHY net names
(MGBE2_TX_P/N, PEX5_LN0+-, etc.). Zero matching nets = unrouted.
Enumerate matching UPHY options. Surface every documented
uphy0-config-N (and Thor uphy1-config-N) index.
Ask the user which config (HARD GATE). Print tables first, then
AskUserQuestion — one per UPHY surface, plus carrier-routing
confirmation if any allocated lane is unrouted. Persist answers to
the JSON sidecar (references/run-state-sidecar.md).
Edit carrier flash-conf fork (atomic ODMDATA commit). This skill
owns every ODMDATA token for the run. One ODMDATA="..." line, one
commit, all tokens. Sub-skills MUST NOT touch ODMDATA.
Decompile the BPMP DTB at
<bsp_image.root_path>/Linux_for_Tegra/bootloader/generic/<BPFDTB_FILE>
(BPFDTB_FILE from the carrier conf) to snapshot stock state, then
emit tokens in this order:
a. UPHY surface tokens — every chosen uphyX-config-N (Thor:
both surfaces, even if one equals the guide default). Order
uphy0 then uphy1; separator ,.
b. Per-controller tokens — one per row whose plan-state differs
from BPMP-stock. Match-rows get no token (redundant tokens can
drop the whole line).
- PCIe:
pcie@N_status=okay|disabled.
- MGBE:
mgbeN-speed-<rate> on allocate, mgbeN-speed-del
on disable. FMON arms on the controller's own clocks
regardless of UPHY allocation — missing del ⇒ BL31 SError
reboot loop. Single most common post-flash failure on Thor.
- USB SS: per-port tokens when the SoC grammar exposes them.
c.
UPHY_CONFIG="" clear when uphy0-config-6 is selected
(BCT pinmux clear per Adaptation Guide).
Build the per-controller allocation table and dispatch. Derive
one row per UPHY-fed controller (PCIe / MGBE / USB SS / UFS) with
{class, instance, allocated?, BPMP-stock, K-stock, routed?, Desired K state}. This table drives both (a) Step 6's ODMDATA
tokens and (b) the sub-skills' overlay fragments — build it
before Step 6 commits.
Then invoke /jetson-customize-pcie, /jetson-customize-mgbe, and
/jetson-customize-usb for kernel-DT overlay fragments only
(no ODMDATA edits — Step 6 owns the line). Each sub-skill re-reads
K-stock from
<bsp_image.root_path>/Linux_for_Tegra/kernel/dtb/tegra<soc>-*-nv.dtb
and skips emission when K-stock matches Desired K state. UFS
handling stays inline here (no UFS sub-skill).
Invoke all three whenever their controller class is present on
this SoC (e.g. skip MGBE on Orin). Ask the operator first; on
yes, run the sub-skill inline.
Summary + next-step chain. Headline, breakdown, choices table
(UPHY surface | chosen config | lane summary | UPHY_CONFIG-clear),
changes-summary table (file | repo | commit SHA | one-line
summary covering this skill's commit + every dispatched sub-skill's
commit), then drive the downstream chain (more I/O? build & promote?
flash? validate?) via sequential AskUserQuestion prompts per
references/procedure.md Step 8. Never substitute a printed
"Next step: …" line for the prompts.
Limitations
- Only supports Tegra234 (Orin) and Tegra264 (Thor) UPHY surfaces.
- Does not edit pinmux, PCIe-only DT properties absent from BPMP DTB
(
num-lanes, pcie-mode), or upstream BSP files.
- Does not flash, build, or promote — chain into
/jetson-build-source
and downstream skills.
- Hard-coded option tables are forbidden; if no Adaptation Guide
source resolves the skill refuses rather than guessing.
- Not table-driven across releases: every run re-reads the Guide for
the active BSP version.
Troubleshooting
- Cold boot reboot loop / BL31
plat_setup.c:726 / BPMP firmware is not ready after uphy0-config-6: a later
^UPHY_CONFIG= line in the carrier conf re-overrode the clear.
Comment it (see references/procedure.md Step 6).
wait-for-device failed at flash, BPMP DTB unchanged: an
ODMDATA token had wrong shape (e.g. mgbe0-speed-0). One bad token
drops the whole ODMDATA="..." line. Inspect grammar in
references/procedure.md.
- BL31 SError reboot loop after disabling an MGBE: missing
mgbeN-speed-del. FMON arms on the controller's own clocks
regardless of UPHY allocation.
- Newly-routed controller doesn't enumerate: stock kernel DTB had
status="disabled". Overlay must emit status="okay" (matrix
row 4 in references/procedure.md).
- Pinmap delta=0 but board still misbehaves: UPHY differential
pairs are absent from pinmux
.xlsm. Drive decisions off schematic
net names, not the pinmap.
- Duplicate
pcie@<addr> fragments: another skill
(jetson-customize-pcie) already owns that node. Scope this skill
to MGBE / UFS / USB3 SS / PCIe-status-only and cite the other
overlay.
References
references/procedure.md — full eight-step procedure.
references/gotchas.md — cross-cutting gotchas.
references/run-state-sidecar.md — JSON sidecar schema + idempotency.
../../references/platform_template.yaml — documents: schema.
../../context/bsp-customization-workflow.md — overlay edit protocol.
../../references/bsp-customization-kernel-dtb.md — composite-overlay
filename / append protocol.
../jetson-derive-carrier/SKILL.md — produces the conf this skill
edits.
../jetson-init-source/SKILL.md — produces the two git repos this
skill commits into.
../jetson-generate-kb/SKILL.md — KB consulted for chip family +
file locations.
1---2name: jetson-customize-uphy3description: Configure Jetson UPHY lane allocation (uphy0/uphy1-config) on Orin/Thor custom carriers. Do NOT use for pinmux or PCIe-only edits.4license: Apache-2.05---67# Customize UPHY lane allocation89## Purpose1011Select a UPHY lane allocation on a Jetson custom carrier and edit the12carrier flash-conf fork's `ODMDATA="..."` to apply the chosen13`uphyX-config-N` token(s) (plus the `UPHY_CONFIG=""` clear required for14`uphy0-config-6`). Kernel-DT alignment per controller is **not** done15here — after the ODMDATA commit lands, this skill dispatches to the16per-controller skills (`/jetson-customize-pcie`,17`/jetson-customize-mgbe`, `/jetson-customize-usb`), each of which must18compare the chosen allocation against the **reference kernel DTB**19node-by-node and emit an overlay fragment only when the K-stock value20disagrees with the chosen allocation. Discovery is agentic: options,21lanes, and controllers come from the Adaptation Guide, carrier22schematic, and Module / SoC TRM at run time — never hard-coded. Every23user-visible step renders its data as a markdown table, and the final24summary includes a changes-summary table.2526## Prerequisites2728- Active target-platform profile with `reference_devkit:` and29 `custom_carrier:`.30- `<source.root_path>/Linux_for_Tegra/.git` initialized31 (`/jetson-init-source`).32- Forked carrier conf present (`/jetson-derive-carrier`).33- Reachable Adaptation Guide via `documents.adaptation_guide` ->34 `documents.bsp_developer_guide` -> web fetch -> Step-1 prompt35 fallback.36- **When `custom_carrier:` is present, both37 `documents.custom_carrier_schematic` AND38 `documents.custom_carrier_pinmux_xls` are REQUIRED.** The skill39 refuses to run if either is missing — routing decisions for the40 custom carrier cannot be guessed. Reference-devkit-only profiles41 (no `custom_carrier:` block) do not require these.4243## Overview4445UPHY (unified PHY) is the shared high-speed PHY pool on Tegra264 (Thor)46and Tegra234 (Orin). Lane allocation is selected by `ODMDATA` tokens47(`uphy0-config-N`, Thor also `uphy1-config-N`) parsed at flash time by48`tegraflash_impl_t264.py::tegraflash_update_bpmp_dtb()` and written49into `/uphy/uphy{0,1}-config` of the BPMP DTB.5051Output is a **single atomic ODMDATA commit** in52`<source.root_path>/Linux_for_Tegra/` carrying the chosen53`uphyX-config-N` token(s), the `UPHY_CONFIG=""` clear (for54`uphy0-config-6`), AND every per-controller ODMDATA token derived55from the chosen allocation (`pcie@N_status=*`, `mgbeN-speed-*`, USB SS56per-port tokens). Sub-skills (`/jetson-customize-pcie`,57`/jetson-customize-mgbe`, `/jetson-customize-usb`) own only the58kernel-DT overlay fragments — they MUST NOT touch ODMDATA. All59commits follow the batched pristine + customization pattern in60`../../context/bsp-customization-workflow.md`. Upstream BSP at61`<bsp_image.root_path>/` is never edited.6263## When to invoke6465- User says "configure UPHY", "uphy lane allocation",66 "set uphy0-config-N", "change MGBE speed", or asks to remap67 PCIe / MGBE / USB3 / UFS on a custom carrier.68- A UPHY-fed controller doesn't enumerate after flash, OR cold boot69 dies in BL31 SError / `BPMP firmware is not ready`.70- A downstream skill reports FMON fault or BPMP-DTB lane mismatch.7172## Procedure (summary)7374Eight steps; full detail in `references/procedure.md`.75761. **Resolve target + docs.** Refuse without active profile, custom77 carrier, source-tree git, or forked carrier conf. Resolve Adaptation78 Guide / schematic / Module Design Guide / SoC TRM.792. **Locate "Configure the UPHY Lane"** in the Adaptation Guide (PDF /80 HTML mirror / `WebFetch`). Cross-check Module Design Guide + SoC TRM.813. **Cross-reference the carrier schematic.** Cite UPHY net names82 (`MGBE2_TX_P/N`, `PEX5_LN0+-`, etc.). Zero matching nets = unrouted.834. **Enumerate matching UPHY options.** Surface every documented84 `uphy0-config-N` (and Thor `uphy1-config-N`) index.855. **Ask the user which config (HARD GATE).** Print tables first, then86 `AskUserQuestion` — one per UPHY surface, plus carrier-routing87 confirmation if any allocated lane is unrouted. Persist answers to88 the JSON sidecar (`references/run-state-sidecar.md`).896. **Edit carrier flash-conf fork (atomic ODMDATA commit).** This skill90 owns every ODMDATA token for the run. One `ODMDATA="..."` line, one91 commit, all tokens. Sub-skills MUST NOT touch ODMDATA.9293 Decompile the BPMP DTB at94 `<bsp_image.root_path>/Linux_for_Tegra/bootloader/generic/<BPFDTB_FILE>`95 (`BPFDTB_FILE` from the carrier conf) to snapshot stock state, then96 emit tokens in this order:9798 a. **UPHY surface tokens** — every chosen `uphyX-config-N` (Thor:99 both surfaces, even if one equals the guide default). Order100 `uphy0` then `uphy1`; separator `,`.101 b. **Per-controller tokens** — one per row whose plan-state differs102 from BPMP-stock. Match-rows get no token (redundant tokens can103 drop the whole line).104 - PCIe: `pcie@N_status=okay|disabled`.105 - MGBE: `mgbeN-speed-<rate>` on allocate, **`mgbeN-speed-del`**106 on disable. FMON arms on the controller's own clocks107 regardless of UPHY allocation — missing `del` ⇒ BL31 SError108 reboot loop. Single most common post-flash failure on Thor.109 - USB SS: per-port tokens when the SoC grammar exposes them.110 c. **`UPHY_CONFIG=""` clear** when `uphy0-config-6` is selected111 (BCT pinmux clear per Adaptation Guide).1127. **Build the per-controller allocation table and dispatch.** Derive113 one row per UPHY-fed controller (PCIe / MGBE / USB SS / UFS) with114 `{class, instance, allocated?, BPMP-stock, K-stock, routed?,115 Desired K state}`. This table drives both (a) Step 6's ODMDATA116 tokens and (b) the sub-skills' overlay fragments — build it117 before Step 6 commits.118119 Then invoke `/jetson-customize-pcie`, `/jetson-customize-mgbe`, and120 `/jetson-customize-usb` for **kernel-DT overlay fragments only**121 (no ODMDATA edits — Step 6 owns the line). Each sub-skill re-reads122 K-stock from123 `<bsp_image.root_path>/Linux_for_Tegra/kernel/dtb/tegra<soc>-*-nv.dtb`124 and skips emission when K-stock matches Desired K state. UFS125 handling stays inline here (no UFS sub-skill).126127 Invoke all three whenever their controller class is present on128 this SoC (e.g. skip MGBE on Orin). Ask the operator first; on129 `yes`, run the sub-skill inline.1308. **Summary + next-step chain.** Headline, breakdown, **choices table**131 (UPHY surface | chosen config | lane summary | UPHY_CONFIG-clear),132 **changes-summary table** (file | repo | commit SHA | one-line133 summary covering this skill's commit + every dispatched sub-skill's134 commit), then drive the downstream chain (more I/O? build & promote?135 flash? validate?) via sequential `AskUserQuestion` prompts per136 `references/procedure.md` Step 8. Never substitute a printed137 "Next step: …" line for the prompts.138139## Limitations140141- Only supports Tegra234 (Orin) and Tegra264 (Thor) UPHY surfaces.142- Does not edit pinmux, PCIe-only DT properties absent from BPMP DTB143 (`num-lanes`, `pcie-mode`), or upstream BSP files.144- Does not flash, build, or promote — chain into `/jetson-build-source`145 and downstream skills.146- Hard-coded option tables are forbidden; if no Adaptation Guide147 source resolves the skill refuses rather than guessing.148- Not table-driven across releases: every run re-reads the Guide for149 the active BSP version.150151## Troubleshooting152153- **Cold boot reboot loop / BL31 `plat_setup.c:726` / `BPMP firmware154 is not ready`** after `uphy0-config-6`: a later155 `^UPHY_CONFIG=` line in the carrier conf re-overrode the clear.156 Comment it (see `references/procedure.md` Step 6).157- **`wait-for-device failed` at flash, BPMP DTB unchanged**: an158 ODMDATA token had wrong shape (e.g. `mgbe0-speed-0`). One bad token159 drops the whole `ODMDATA="..."` line. Inspect grammar in160 `references/procedure.md`.161- **BL31 SError reboot loop after disabling an MGBE**: missing162 `mgbeN-speed-del`. FMON arms on the controller's own clocks163 regardless of UPHY allocation.164- **Newly-routed controller doesn't enumerate**: stock kernel DTB had165 `status="disabled"`. Overlay must emit `status="okay"` (matrix166 row 4 in `references/procedure.md`).167- **Pinmap delta=0 but board still misbehaves**: UPHY differential168 pairs are absent from pinmux `.xlsm`. Drive decisions off schematic169 net names, not the pinmap.170- **Duplicate `pcie@<addr>` fragments**: another skill171 (`jetson-customize-pcie`) already owns that node. Scope this skill172 to MGBE / UFS / USB3 SS / PCIe-status-only and cite the other173 overlay.174175## References176177- `references/procedure.md` — full eight-step procedure.178- `references/gotchas.md` — cross-cutting gotchas.179- `references/run-state-sidecar.md` — JSON sidecar schema + idempotency.180- `../../references/platform_template.yaml` — `documents:` schema.181- `../../context/bsp-customization-workflow.md` — overlay edit protocol.182- `../../references/bsp-customization-kernel-dtb.md` — composite-overlay183 filename / append protocol.184- `../jetson-derive-carrier/SKILL.md` — produces the conf this skill185 edits.186- `../jetson-init-source/SKILL.md` — produces the two git repos this187 skill commits into.188- `../jetson-generate-kb/SKILL.md` — KB consulted for chip family +189 file locations.