PCIe 驱动
1. 概述
1.1 功能简介
PCIe(Peripheral Component Interconnect Express)是高速串行计算机扩展总线标准。RK3576 内置 PCIe 控制器,支持 PCIe 2.1 标准,可用于连接 NVMe SSD、WiFi/蓝牙模块、以太网控制器等高速外设,适用于存储扩展和高速外设接入场景。M4-R2 底板具体的 PCIe 接口(M.2 插槽)以实际物料为准(待板上验证)。
1.2 应用场景
- NVMe SSD:连接 NVMe 固态硬盘,实现高速存储
- WiFi 模块:连接 PCIe 接口的 WiFi 模块(如 AP6xxx 系列)
- 以太网:连接 PCIe 千兆/2.5G 以太网控制器
- 4G/5G 模块:连接 PCIe 接口的蜂窝通信模块
- AI 加速卡:连接 PCIe 接口的 NPU/VPU 加速模块
1.3 工作原理
RK3576 的 PCIe 控制器支持以下特性:
| 特性 | 说明 |
|---|---|
| PCIe 版本 | PCIe 2.1 |
| 速率 | 最高 5GT/s(x1/x2 lanes) |
| 通道数 | 最多 2 lanes |
| 模式 | RC(Root Complex)模式 |
| EP 模式 | 支持 Endpoint 模式(部分控制器) |
| L1 子状态 | 支持低功耗状态 |
具体 PCIe 通道数与版本以实际发布的 RK3576 规格书与 SDK 配置为准(待板上验证)。
2. 硬件准备
2.1 硬件清单
| 组件 | 型号/规格 | 数量 | 备注 |
|---|---|---|---|
| 主控板 | C-3576BQ 核心板 + M4-R2 底板 | 1 | |
| 调试串口线 | USB 转 TTL(3.3V) | 1 | 波特率 1500000 |
| NVMe SSD(可选) | M.2 NVMe | 1 | 用于 PCIe 存储测试 |
| PCIe WiFi 模块(可选) | AP6xxx 系列 | 1 | M.2 E-Key |
2.2 引脚连接
M4-R2 底板具体的 PCIe 接口位置(M.2 插槽)以实际原理图与物料为准(待板上验证),插入对应设备即可。
PCIe 接口在底板原理图中有标注,包含 TX/RX 差分对和参考时钟。
2.3 硬件确认
# 查看 PCIe 设备
lspci
# 输出示例:
# 00:00.0 PCI bridge: Rockchip Electronics Co., Ltd. Device 3576
# 01:00.0 Non-Volatile memory controller: ...
# 查看 PCIe 设备详情
lspci -v
# 查看 PCIe 链路速度
lspci -s 01:00.0 -vv | grep LnkSta
# 输出示例: LnkSta: Speed 5GT/s, Width x13. 软件准备
3.1 内核配置
确认以下内核配置已启用:
CONFIG_PCI=y
CONFIG_PCI_ROCKCHIP_HOST=y
CONFIG_PCIE_DW_ROCKCHIP_HOST=y
CONFIG_NVME_CORE=y
CONFIG_BLK_DEV_NVME=y
CONFIG_OF=y
CONFIG_OF_PCI=y
CONFIG_PCIE_DW_ROCKCHIP_HOST是 Rockchip PCIe 控制器 Host 驱动。NVMe 需要CONFIG_BLK_DEV_NVME。
3.2 设备树
RK3576 的 PCIe 控制器在设备树中定义(以下为 RK 平台通用结构示例):
pcie2x1l0: pcie@fe170000 {
compatible = "rockchip,rk3576-pcie", "rockchip,rk3568-pcie";
reg = <0x0 0xfe170000 0x0 0x4000>;
interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "msi";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 7>;
interrupt-map = <0 0 0 1 &gic GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru ACLK_PCIE_ROOT>, <&cru PCLK_PCIE_ROOT>,
<&cru CLK_PCIE_PIPE_PHY>;
clock-names = "aclk_mst", "aclk_slv", "clk_pciephy_ref1";
resets = <&cru SRST_PCIE3_DATA>;
reset-names = "pcie";
phys = <&pcie2_phy PHY_TYPE_PCIE2>;
phy-names = "pciephy";
max-link-speed = <2>;
lanes = <1>;
status = "disabled";
};以上寄存器基地址、中断号与时钟标识为 RK 平台通用结构示例,具体数值以实际发布的 RK3576 SDK 设备树为准(待板上确认)。
4. 操作步骤
4.1 查看 PCIe 设备
# 查看所有 PCIe 设备
lspci
# 查看 PCIe 设备详情
lspci -v
# 查看 PCIe 链路信息
lspci -s 01:00.0 -vv | grep -E "LnkCap|LnkSta"
# 查看 PCIe 控制器信息
lspci -vv | grep -A 5 "PCI bridge"4.2 NVMe SSD 操作
# 查看 NVMe 设备
lsblk | grep nvme
# 输出示例:nvme0n1
# 查看 NVMe 设备信息
nvme id-ctrl /dev/nvme0
# 查看 NVMe SMART 信息
nvme smart-log /dev/nvme0
# 测试 NVMe 读写速度
dd if=/dev/zero of=/dev/nvme0n1 bs=1M count=100 oflag=direct
dd if=/dev/nvme0n1 of=/dev/null bs=1M count=100 iflag=direct4.3 PCIe WiFi 模块操作
# 查看 WiFi 设备(PCIe 接口)
lspci | grep -i network
# 查看 WiFi 驱动
lspci -s 01:00.0 -k | grep "Kernel driver"4.4 设备树中配置 PCIe
&pcie2x1l0 {
status = "okay";
reset-gpios = <&gpio1 RK_PB0 GPIO_ACTIVE_HIGH>;
vpcie3v3-supply = <&vcc3v3_pcie>;
max-link-speed = <2>;
lanes = <1>;
};5. 代码详解
5.1 内核中 PCIe 驱动的注册
// RK3576 PCIe 控制器驱动(简化)
// drivers/pci/controller/pcie-dw-rockchip.c
static struct platform_driver rockchip_pcie_driver = {
.probe = rockchip_pcie_probe,
.remove = rockchip_pcie_remove,
.driver = {
.name = "rockchip-pcie",
.of_match_table = rockchip_pcie_match,
},
};
static const struct of_device_id rockchip_pcie_match[] = {
{ .compatible = "rockchip,rk3576-pcie" },
{ /* sentinel */ }
};5.2 用户空间 PCIe 操作的内核调用链
用户空间 lspci
→ pci_bus_read_config()
→ rockchip_pcie_rd_conf()
→ 通过 PCIe 配置空间读取设备信息
→ 返回 Vendor ID、Device ID 等6. 常见问题
6.1 PCIe 设备无法识别
现象: lspci 无设备输出
解决方案:
# 检查 PCIe 控制器时钟
cat /sys/kernel/debug/clk/clk_pcie_pipe_phy/clk_rate
# 检查设备树中 PCIe 节点状态
# 具体节点路径以实际 DTB 反编译结果为准
dtc -I dtb -O dts /sys/firmware/fdt | grep -A3 "pcie@"
# 检查 PCIe PHY 状态
cat /sys/kernel/debug/clk/clk_pciephy_ref1/clk_rate确认设备树中 PCIe 节点 status = "okay",检查设备供电和连接。
6.2 PCIe 链路速度不达标
现象: PCIe 设备只有低速运行
解决方案:
# 查看链路速度
lspci -vv | grep LnkSta
# 检查 PCIe PHY 时钟
cat /sys/kernel/debug/clk/clk_pcie_pipe_phy/clk_rate检查 PCIe PHY 配置,确认信号完整性。
6.3 NVMe SSD 读写速度慢
现象: NVMe SSD 速度远低于标称值
解决方案:
# 测试顺序读写
dd if=/dev/zero of=/dev/nvme0n1 bs=1M count=1000 oflag=direct
dd if=/dev/nvme0n1 of=/dev/null bs=1M count=1000 iflag=direct
# 使用 fio 深度测试
fio --name=test --filename=/dev/nvme0n1 --rw=read --bs=1M --size=1G --numjobs=4 --runtime=30检查 PCIe 链路速度和宽度,确认 DMA 配置正确。
相关文档
- GPIO驱动与控制 — GPIO 控制
- SDMMC-eMMC驱动 — 存储驱动对比
- 设备树详解与实践 — 设备树配置
- 核心板参数 — 硬件事实基线
