Jetson Thor Bring-up:如何正确使用 Pinmux,以及它和 MB1/MB2/UEFI/Kernel 的

---

在 Jetson AGX Thor / T5000 定制载板 bring-up 时,pinmux 是一个很容易被低估的问题。

很多时候我们看到 DTS 里有这样的配置:

can0_din_pab1 {
    nvidia,pins = "can0_din_pab1";
    nvidia,function = "can0_din";
    nvidia,pull = <TEGRA_PIN_PULL_NONE>;
    nvidia,tristate = <TEGRA_PIN_ENABLE>;
    nvidia,enable-input = <TEGRA_PIN_ENABLE>;
    nvidia,drv-type = <TEGRA_PIN_DEFAULT_DRIVE_1X>;
    nvidia,e-lpbk = <TEGRA_PIN_DISABLE>;
};

刚开始很容易把它理解成:

function = can0_din
所以这个 pin 就是 CAN RX 了

但这个理解是不完整的。

Jetson Thor 的 pinmux 不只是“选择功能”,它实际在配置 SoC PAD 的早期电气状态

这个 pin 接到哪个内部外设?
这个 pin 是否允许 SoC 输出?
输入 buffer 是否打开?
内部上下拉怎么配置?
输出驱动能力是多少?
上电早期是否安全?

也就是说,pinmux 是 bring-up 的第一层,它解决的是:

Kernel 起来之前,这个 pin 应该是什么状态?

而 kernel 解决的是:

系统运行之后,这个外设是否真正工作?

这篇文章就围绕这个核心问题展开:Jetson Thor pinmux 到底配置了什么?它和 MB1、MB2、UEFI、kernel DTS 是什么关系?


1. 先看整体启动流程

Jetson Thor 的启动流程可以简化成下面这样:

Power On / POR
     │
     ▼
BootROM
     │
     ▼
MB1
     │
     ├── 应用早期 BCT 配置
     ├── 应用 pinmux / gpio / padvoltage
     │
     ▼
MB2
     │
     ├── 继续初始化平台资源
     │
     ▼
UEFI
     │
     ├── 加载启动配置
     ├── 加载 kernel / dtb / initrd
     │
     ▼
Linux Kernel
     │
     ├── 解析 kernel DTB
     ├── probe 外设 driver
     ├── 配置 regulator / GPIO / PHY / interrupt / pinctrl
     │
     ▼
User Space

用 Mermaid 表示更直观:

flowchart TD
    A[Power On / POR] --> B[BootROM]
    B --> C[MB1]
    C --> C1[Apply BCT]
    C --> C2[Apply pinmux.dtsi / gpio.dtsi / padvoltage.dtsi]
    C --> D[MB2]
    D --> E[UEFI]
    E --> F[Load Kernel + DTB + Initrd]
    F --> G[Linux Kernel]
    G --> H[Driver Probe]
    H --> I[Runtime GPIO / PHY / Regulator / Display / USB]
    I --> J[User Space]

关键点是:

pinmux 主要在 MB1/bootloader 早期阶段生效;
kernel 后面可以重新配置部分 pin,但不会自动覆盖所有 pin。

所以不能简单认为:

kernel 起来后都会重新配置,pinmux 随便配也没事

这个理解是错误的。


2. Thor Pinmux Template 生成了什么?

Thor 使用的是:

Jetson Thor Series Modules Pinmux Template

这是一个 .xlsm 表格。根据定制载板原理图修改后,点击:

Generate DT File

通常会生成:

pinmux.dtsi
gpio.dtsi
padvoltage.dtsi

三个文件的职责可以这样理解:

文件作用主要生效阶段
pinmux.dtsi配置 function、pull、tristate、input、drive 等 PAD 属性MB1 / bootloader
gpio.dtsi配置 GPIO 初始方向、初始电平等MB1 / bootloader
padvoltage.dtsi配置 I/O 电压域MB1 / bootloader

也就是说,这些文件不是普通 kernel driver 的配置文件,而是 平台早期初始化文件

典型集成路径类似:

Thor Pinmux XLSM
      │
      ├── Generate DT File
      │
      ▼
pinmux.dtsi
gpio.dtsi
padvoltage.dtsi
      │
      ▼
复制到 Linux_for_Tegra/bootloader/
      │
      ▼
flash / 生成镜像
      │
      ▼
MB1/bootloader 早期应用

流程图如下:

flowchart LR
    A[Thor Pinmux XLSM] --> B[Generate DT File]
    B --> C[pinmux.dtsi]
    B --> D[gpio.dtsi]
    B --> E[padvoltage.dtsi]
    C --> F[bootloader directory]
    D --> F
    E --> F
    F --> G[Flash Image]
    G --> H[MB1 Apply Early Pad Config]

3. Pinmux 和 Kernel DTS 不是一回事

这是 bring-up 中最关键的分界。

Pinmux 管什么?

Pinmux 管的是 PAD 级别:

nvidia,function
nvidia,pull
nvidia,tristate
nvidia,enable-input
nvidia,drv-type
nvidia,e-lpbk

也就是:

这个 pin 在电气层面怎么工作

Kernel DTS 管什么?

Kernel DTS 管的是设备和驱动:

controller 是否 enable
clock/reset/interrupt 是否正确
regulator 是否正确
GPIO consumer 是否正确
PHY/lane/role-switch 是否正确
display DCB 是否正确
driver 是否能 probe

也就是:

这个外设在 Linux 运行后怎么工作

两者关系如下:

硬件原理图
   │
   ├── Pinmux XLSM
   │       └── 生成 pinmux/gpio/padvoltage
   │       └── 作用于 MB1/bootloader
   │
   └── Kernel DTS
           └── 打开外设 controller
           └── 配置 GPIO / regulator / PHY / interrupt
           └── 作用于 Linux driver probe

可以总结成一句话:

Pinmux 决定 pin 早期是否安全、是否接到正确功能;
Kernel DTS 决定外设运行时是否真正可用。

4. 用 CAN0_DIN 举例:Pinmux 到底配置了什么?

假设硬件连接是:

CAN Transceiver RXD  --->  SoC CAN0_DIN
CAN Transceiver TXD  <---  SoC CAN0_DOUT

电路方向是:

CAN0_DIN  = SoC 输入,接收 transceiver 的 RXD
CAN0_DOUT = SoC 输出,驱动 transceiver 的 TXD

4.1 错误配置

如果生成出来是:

can0_din_pab1 {
    nvidia,pins = "can0_din_pab1";
    nvidia,function = "rsvd1";
    nvidia,pull = <TEGRA_PIN_PULL_NONE>;
    nvidia,tristate = <TEGRA_PIN_DISABLE>;
    nvidia,enable-input = <TEGRA_PIN_ENABLE>;
};

这里有两个问题。

第一个问题:

nvidia,function = "rsvd1";

rsvd1 是 reserved function,表示没有选择 CAN0_DIN 这个有效外设功能。

所以逻辑上变成:

外部 CAN RXD 进到 pin
        │
        X
        │
没有送到 CAN0_DIN 控制器输入

第二个问题:

nvidia,tristate = <TEGRA_PIN_DISABLE>;

这不是关闭 pin,而是关闭高阻,允许输出驱动。
对于 CAN RX 输入脚来说,这个方向不合理。

4.2 正确配置

CAN RX 应该类似这样:

can0_din_pab1 {
    nvidia,pins = "can0_din_pab1";
    nvidia,function = "can0_din";
    nvidia,pull = <TEGRA_PIN_PULL_NONE>;
    nvidia,tristate = <TEGRA_PIN_ENABLE>;
    nvidia,enable-input = <TEGRA_PIN_ENABLE>;
    nvidia,drv-type = <TEGRA_PIN_DEFAULT_DRIVE_1X>;
    nvidia,e-lpbk = <TEGRA_PIN_DISABLE>;
};

逐项解释:

参数含义
function = "can0_din"这个 pin 接到 CAN0 RX
pull = PULL_NONE不使用内部上下拉,由外部 transceiver 驱动
tristate = ENABLE输出高阻,SoC 不主动驱动这个 pin
enable-input = ENABLE输入 buffer 打开,SoC 可以读取 RX 信号
drv-type = 1X默认驱动能力;对输入脚影响不大
e-lpbk = DISABLE不开 loopback

这里最关键的是三句:

nvidia,function = "can0_din";
nvidia,tristate = <TEGRA_PIN_ENABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>;

可以理解成:

接到 CAN RX
不输出
只读取

5. tristate 最容易理解反

tristateENABLE/DISABLE 不是在说 pin 是否启用,而是在说 是否启用三态高阻

tristate = ENABLE

nvidia,tristate = <TEGRA_PIN_ENABLE>;

意思是:

启用高阻
输出驱动断开
SoC 不主动拉高,也不主动拉低

等效电路:

SoC output driver  X  PIN

适合:

输入脚
unused pin
外部已有驱动源的信号

tristate = DISABLE

nvidia,tristate = <TEGRA_PIN_DISABLE>;

意思是:

关闭高阻
输出驱动打开
SoC 可以主动输出 0 或 1

适合:

输出脚
enable 脚
reset 脚
TX 信号

表格记忆:

配置实际含义典型用途
tristate = ENABLE高阻,不输出RX、输入、unused
tristate = DISABLE可以输出TX、EN、RST

6. Kernel 侧还要怎么配 CAN?

Pinmux 配对了,只表示:

物理 pin 已经接到 CAN 控制器

但 CAN 控制器能不能工作,还要看 kernel DTS 和 driver。

Kernel 侧通常还要确认:

CAN controller 节点是否 enabled
时钟是否正确
reset 是否正确
interrupt 是否正确
transceiver standby/enable GPIO 是否正确
CAN bitrate 是否配置

示意 DTS:

/* 注意:节点名以实际 BSP 为准,这里只是表达关系 */
&mttcan0 {
    status = "okay";

    /*
     * 如果板上 CAN transceiver 有 standby / enable / reset GPIO,
     * 需要在对应 transceiver 节点或驱动属性中描述。
     */
};

如果 CAN transceiver 还有 STB/EN 控制脚,pinmux 也要配置它们的早期状态。例如:

CAN_STB:
  方向:Output
  初始状态:Drive 1 或 Drive 0,取决于 transceiver datasheet
  kernel:后续由 GPIO driver 控制

CAN_EN:
  方向:Output
  初始状态:Drive 1 或 Drive 0,取决于硬件设计
  kernel:后续由 GPIO/regulator/transceiver driver 控制

所以 CAN bring-up 的完整链路是:

flowchart TD
    A[原理图确认 CAN RX/TX/STB/EN] --> B[Pinmux 配 CAN0_DIN/CAN0_DOUT]
    B --> C[MB1 早期应用 pinmux]
    C --> D[Kernel DTS enable mttcan0]
    D --> E[Kernel driver probe]
    E --> F[ip link set can0 up type can bitrate xxx]
    F --> G[candump / cansend 验证]

7. rsvd0/rsvd1/rsvd2/rsvd3 是什么?

在 pinmux 中常看到:

nvidia,function = "rsvd0";

或者:

nvidia,function = "rsvd1";

RSVDReserved,表示保留功能。

它不是:

delete 这个 pin
pin 完全消失
pin 完全断电

更准确地说:

这个 PAD 的 mux 没有选择一个明确的外设功能

比如:

没有选 CAN
没有选 UART
没有选 SPI
没有选 I2C
没有选 PWM

但是 pin 的电气状态仍然存在:

pull 仍然可能生效
tristate 仍然可能生效
enable-input 仍然可能生效
GPIO controller 仍然可能管理它

所以 rsvdX 不能简单理解成“安全”或“低功耗”。真正是否安全,还要看:

tristate 是否高阻
input buffer 是否关闭
pull 是否合理
外部是否有上拉/下拉
是否连接到其他芯片输出
是否涉及 boot strap / reset / recovery

对于 unused pin,比较合理的方向是:

/* 示例,具体 pull 要看硬件 */
unused_xxx {
    nvidia,function = "rsvd0";
    nvidia,tristate = <TEGRA_PIN_ENABLE>;
    nvidia,enable-input = <TEGRA_PIN_DISABLE>;
    nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
};

但如果这个 pin 实际要做 CAN/UART/I2C/SPI,就不能保持 rsvdX


8. USB:为什么不是只改 pinmux?

USB 要分成两层:

高速信号
sideband 控制信号

8.1 高速信号

例如:

USB2 D+
USB2 D-
USB3 TX/RX

这些主要由:

xUSB controller
USB PHY
UPHY lane
kernel USB driver

管理,不是普通 GPIO pinmux 直接拉高拉低。

8.2 Sideband 信号

例如:

VBUS_EN
VBUS_DET
USB_ID
OC
Type-C CC controller interrupt

这些就和 pinmux/GPIO/kernel DTS 强相关。

完整链路:

USB connector
   │
   ├── USB2/USB3 高速线
   │       └── xUSB/PHY/lane/kernel driver
   │
   └── VBUS_EN / VBUS_DET / ID / OC
           └── pinmux + GPIO + regulator + role-switch

示意 DTS:

/* 示例,节点名以实际 BSP 为准 */
usb_vbus_reg: regulator-usb-vbus {
    compatible = "regulator-fixed";
    regulator-name = "usb-vbus";
    gpio = <&gpio XXX GPIO_ACTIVE_HIGH>;
    enable-active-high;
};

&usb_controller_xxx {
    status = "okay";
    vbus-supply = <&usb_vbus_reg>;
    usb-role-switch;
};

Pinmux 负责让 VBUS_EN 这个 GPIO 在早期不乱输出;kernel 负责把它作为 regulator 或 GPIO consumer 使用。

USB bring-up 的判断逻辑:

flowchart TD
    A[USB 不工作] --> B{高速枚举失败还是 VBUS/role 问题?}
    B -->|无 VBUS| C[查 VBUS_EN pinmux + regulator DTS]
    B -->|role 不对| D[查 VBUS_DET / ID / Type-C controller]
    B -->|信号异常| E[查 PHY / UPHY / lane / controller]
    C --> F[示波器量 VBUS]
    D --> G[dmesg 看 role-switch/typec]
    E --> H[查 kernel xUSB/PHY log]

9. DP/HDMI:为什么还要 DCB?

DP/HDMI 更容易混淆,因为它不只是 pinmux。

对于 DP/HDMI,有三层配置:

1. Pinmux
2. Kernel display dtsi
3. DCB

9.1 Pinmux 负责什么?

DP:

HPD 配成对应 DP/HPD 功能
DPAUX 配成 DP_AUX_CHx

HDMI:

HPD 通常作为 GPIO/input
DDC/I2C 配成 I2C
CEC 视需求配置

9.2 Kernel display dtsi 负责什么?

Kernel display dtsi 负责把当前平台显示控制相关配置纳入 kernel DT。

9.3 DCB 负责什么?

DCB 可以理解成显示拓扑表,告诉显示驱动:

这个接口是 DP 还是 HDMI?
使用哪个 connector?
使用哪个 DPAUX/DDC 通信通道?
HDMI capable 是 0 还是 1?

其中 CCB 是 DCB 里的通信通道配置,和 DPAUX/DDC 对应。

DP 的逻辑图:

DP Connector
   │
   ├── Main Lanes
   │       └── Display Controller / PHY
   │
   ├── HPD
   │       └── Pinmux 配成 DP HPD/SFIO
   │
   └── AUX
           └── Pinmux 配成 DP_AUX_CHx
                   │
                   ▼
                 DCB
                   ├── Type = DP
                   ├── HDMI capable = 0
                   ├── CCB = 对应 DPAUXx
                   └── Connector = 对应 connector index

HDMI 的逻辑图:

HDMI Connector
   │
   ├── TMDS
   │       └── Display Controller / PHY
   │
   ├── HPD
   │       └── GPIO/Input/Interrupt
   │
   └── DDC/I2C
           └── I2C/DDC 通道
                   │
                   ▼
                 DCB
                   ├── Type = TMDS
                   ├── HDMI capable = 1
                   ├── CCB = 对应 DDC/I2C
                   └── Connector = 对应 HDMI connector index

所以 DP/HDMI bring-up 不能只看 pinmux:

pinmux 对了,但 DCB 错了:
  driver 可能去错误的 AUX/DDC 通道读 EDID

DCB 对了,但 pinmux 错了:
  AUX/DDC/HPD 信号可能根本不通

kernel display dtsi 没 include:
  display driver 可能拿不到平台显示拓扑

完整流程:

flowchart TD
    A[原理图确认 DP/HDMI connector] --> B[确认 HPD / AUX / DDC 接到哪里]
    B --> C[Pinmux 配 HPD / AUX / DDC]
    C --> D[Kernel DT include display dtsi]
    D --> E[DCB 配 Type / CCB / Connector / HDMI capable]
    E --> F[Kernel display driver probe]
    F --> G[HPD / EDID / AUX-DDC 验证]

10. Pinmux 和 Kernel 的冲突场景

最麻烦的问题通常不是“没配置”,而是 bootloader 和 kernel 配置不一致

场景 1:Bootloader 配成 CAN,Kernel 又当 GPIO

MB1 pinmux:
  function = can0_din

Kernel:
  把同一个 pin 当 GPIO 使用

结果:

早期像 CAN
kernel probe 后变 GPIO
CAN 后面不工作

场景 2:Bootloader 早期输出高,Kernel 后面才改输入

MB1:
  Drive 1

Kernel:
  input

结果:

kernel 启动前这段时间,外部芯片已经被错误拉高

这对 reset、enable、power switch 很危险。

场景 3:Pinmux 是 rsvd,Kernel enable 了外设

pinmux:
  function = rsvd1

kernel:
  mttcan0 status = "okay"

结果:

CAN controller 启动了
但物理 pin 没接到 CAN 功能
外设仍然不工作

11. 实际 bring-up 检查表

11.1 先从原理图开始

不要先看 DTS,先看原理图。

整理一张表:

SoM PinNet Name外部连接方向早期默认态Kernel 是否控制
CAN0_DINCAN_RXDCAN transceiver RXDInputZmttcan
CAN0_DOUTCAN_TXDCAN transceiver TXDOutput按设计mttcan
CAN_STBCAN_STBtransceiver standbyOutputDrive 1/0GPIO
USB_VBUS_ENUSB_PWR_ENpower switch ENOutputDrive 0/Zregulator
HDMI_HPDHDMI_HPDHDMI connectorInputZ/PUGPIO IRQ
DP_AUXDP_AUX_CHxDP connectorBidirectional按 DPdisplay driver

11.2 再检查 Pinmux XLSM

重点看:

Customer Usage
Pin Direction
Required Initial State
Pull
3.3V tolerance
Open-drain
I/O block voltage

11.3 再检查生成的 pinmux.dtsi

例如检查 CAN RX:

grep -n "can0_din" -n pinmux.dtsi

期望看到类似:

nvidia,function = "can0_din";
nvidia,tristate = <TEGRA_PIN_ENABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>;

检查是否还有错误的 reserved:

grep -n "rsvd" pinmux.dtsi

看到 rsvd0/rsvd1 不一定就是错,但要确认这些 pin 是否真的是 unused/GPIO,而不是外设 pin。

11.4 最后检查 kernel DTS

例如:

grep -R "mttcan" kernel-dts/
grep -R "vbus" kernel-dts/
grep -R "dcb" kernel-dts/
grep -R "dpaux" kernel-dts/

目标是确认:

外设 controller enabled
相关 GPIO 被 driver 使用
display DCB include 正确
USB regulator/role-switch 正确
DP/HDMI CCB/connector 对应硬件

12. 最终总结

Jetson Thor bring-up 中,pinmux 和 kernel 的关系可以总结为:

Pinmux:
  解决早期 PAD 状态问题
  作用在 MB1/bootloader 阶段
  重点是 function、pull、tristate、input、drive、pad voltage

Kernel DTS:
  解决运行时外设描述问题
  作用在 Linux driver probe 阶段
  重点是 controller、GPIO、regulator、PHY、interrupt、DCB

Driver:
  解决外设实际运行问题
  作用在系统运行阶段
  负责 probe、初始化、suspend/resume、runtime 控制

最重要的一句话:

Pinmux 配错,kernel 可能根本救不了;
Kernel 配错,pinmux 再正确,外设也不会真正工作。

所以 Thor bring-up 的正确顺序应该是:

原理图确认
   ↓
Pinmux XLSM 配早期状态
   ↓
Generate DT File
   ↓
集成到 bootloader
   ↓
Kernel DTS 配外设运行时资源
   ↓
Flash
   ↓
上板验证 pin 电平 + driver probe + 接口功能

这才是比较稳妥的 Jetson Thor pinmux bring-up 方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值