RK3588 DesignWare PCIe 控制器详细分析

RK3588 DesignWare PCIe 控制器详细分析

1. 软件分层

RK3588 PCIe RC 的主路径为:

1
2
3
4
pcie-dw-rockchip.c             Rockchip glue
-> pcie-designware.c DWC DBI/iATU/链路公共操作
-> pcie-designware-host.c Host Bridge、MSI、CFG访问
-> drivers/pci/probe.c PCI Core 枚举和资源

controller/pcie-rockchip-host.c对应较早 Rockchip 自有 PCIe IP。RK3588 DTS compatible 为"rockchip,rk3588-pcie", "snps,dw-pcie",匹配pcie-dw-rockchip.c,不能按文件名相似就选旧驱动。

2. 平台匹配

rk_pcie_of_match位于pcie-dw-rockchip.c:918,RK3588 项在 936 行。平台驱动通过module_platform_driver()注册,probe 为rk_pcie_probe()(1880 行)。

本厂商树支持CONFIG_PCIE_RK_THREADED_INIT:打开后 probe 可用kthread_run()执行rk_pcie_really_probe()。这会改变启动日志时序,依赖 PCIe 设备很早出现的驱动需注意异步初始化影响。

3. Probe 主链

1
2
3
4
5
6
7
8
9
10
11
rk_pcie_probe()
-> [线程或直接] rk_pcie_really_probe()
-> 匹配 SoC data
-> rk_pcie_resource_get()
-> rk_pcie_hardware_io_config()
-> rk_pcie_host_config()
-> dw_pcie_host_init()
-> 分配/配置 pci_host_bridge
-> MSI/INTx 与 RC setup
-> start_link
-> pci_host_probe()

本树关键位置:

  • rk_pcie_resource_get():646 行;
  • rk_pcie_hardware_io_config():1476 行;
  • rk_pcie_host_config():1601 行;
  • rk_pcie_really_probe():1728 行;
  • dw_pcie_host_init()pcie-designware-host.c:385

4. 平台资源

Rockchip glue 负责通用 PCI Core 不理解的资源:

  • DBI/APB 等寄存器窗口;
  • clocks 与 resets;
  • regulators;
  • PHY 与 lane mode;
  • PERST#、WAKE#等 GPIO;
  • GRF/系统寄存器;
  • legacy/sys IRQ;
  • 可选 DMA test 和平台扩展。

错误路径必须逆序撤销。PHY 未退出或时钟提前关闭时,不应继续读 DBI/APB。

5. 硬件初始化与链路

rk_pcie_hardware_io_config()完成平台上电、时钟、reset、PHY 和 GPIO 时序;rk_pcie_establish_link()位于 353 行,并作为dw_pcie_ops.start_link使用。

典型链路流程:

1
2
3
4
5
6
7
保持 Endpoint PERST#
-> 打开电源/refclk/PHY
-> 配置 RC mode、lane、速率
-> 释放控制器 reset
-> 释放 PERST#
-> 使能 LTSSM
-> 等待 Data Link Layer Link Active

PERST#释放到配置访问必须满足设备时序。某些 NVMe/Wi-Fi 上电慢,简单增加扫描重试只能掩盖电源或时序问题。

rk_pcie_link_up()位于 246 行,用平台状态判断 Link。Link Up 只是物理/数据链路条件,不保证配置 iATU、BAR window 或 MSI 正确。

6. DWC Host 公共层

dw_pcie_host_init()负责:

  1. 从 DT/平台资源建立 Host Bridge windows;
  2. 建立pci_ops
  3. 初始化 MSI domain(若使用 DWC MSI);
  4. dw_pcie_setup_rc()配置 Root Complex;
  5. 启动链路;
  6. 调用pci_host_probe()

dw_pcie_setup_rc()位于pcie-designware-host.c:694。跨平台公共代码不应直接加入 RK3588 regulator/GPIO 逻辑,这些应留在 Rockchip ops。

7. 配置空间访问

  • Root Port 自身配置通常通过 DBI;
  • 直连下游 BDF 使用 CFG0;
  • 桥后 BDF 使用 CFG1;
  • DWC 临时或固定配置 outbound iATU,再发起 CPU MMIO 读写;
  • 无 Completion/Unsupported Request 最终表现为 PCI BIOS 错误码或全 1。

若 Bus 0 Root Port 可见而 Bus 1 Device 0 不可见,应同时检查 Link 和 CFG0 ATU,而非search.c

8. 地址窗口

DT ranges定义 CPU→PCI I/O/MEM 窗口,DWC outbound iATU真正执行转换。BAR 分配必须落在窗口内。Inbound 方向还可能涉及控制器自身 DMA/EP 模式,不能把 RC outbound 和 EP BAR inbound 混为一谈。

9. 中断

  • Legacy INTx:DTS interrupt-map描述 INTA~INTD,Rockchip 建立 domain 并由系统 IRQ 分发;
  • MSI/MSI-X:由 DWC MSI controller 或外部 parent domain接收;
  • rk_pcie_sys_irq_handler()位于 837 行,处理平台系统事件,不等同于所有 Endpoint MSI handler。

10. 电源管理

rockchip_dw_pcie_pm_ops位于 2263 行。Suspend/resume 必须协调:

  1. 停止下游设备和 DMA;
  2. 保存 PCI 配置;
  3. 停止链路、PHY、clock/power;
  4. resume 时恢复平台硬件与 RC;
  5. 重新建立 Link;
  6. 恢复 PCI 配置和功能驱动。

本树 resume 路径会再次调用硬件配置、Host 配置或链路建立函数,排障时应区分首次 probe 与 resume 日志。

11. RK3588 控制器实例

SoC DTS定义:

  • PCIe 3.0 x4:pcie3x4
  • PCIe 3.0 x2:pcie3x2
  • PCIe 2.0 x1:pcie2x1l0/l1/l2

具体板级 DTS 通常只 enable 实际布线的节点,并补 regulator、reset GPIO、pinctrl、PHY。SoC 有节点不表示板上端口已启用。

12. Bring-up 分层检查

1
2
3
4
5
6
7
电源/时钟/复位/PHY
-> LTSSM 与 Link Up
-> Root Port DBI
-> CFG0 读取 Endpoint VID
-> BAR 与 MEM iATU
-> MSI/INTx
-> 设备驱动 DMA

每层成功后再查下一层。这样可避免把“PHY 未锁定”误判为 PCI Core 枚举 bug,或把“MSI domain 错误”误判为 NVMe 队列逻辑问题。

文章互动

阅读 --

留言

0 条留言

正在加载留言…