RK3588 kernel-6.1 — Rockchip pcie-rockchip* RC/EP 与 rockchip-pcie-dma 分析
1. 文档范围与源码路径
| 文件 | 路径 |
|---|---|
| 公共层 | drivers/pci/controller/pcie-rockchip.c |
| Root Complex(主机) | drivers/pci/controller/pcie-rockchip-host.c |
| Endpoint(端点) | drivers/pci/controller/pcie-rockchip-ep.c |
| PCIe UDMA / 用户态接口 | drivers/pci/controller/rockchip-pcie-dma.c |
| DMA 结构与 probe 声明 | drivers/pci/controller/rockchip-pcie-dma.h |
寄存器与 struct rockchip_pcie |
drivers/pci/controller/pcie-rockchip.h |
| 用户态 ioctl | include/uapi/linux/rk-pcie-dma.h |
说明:本组驱动源于 RK3399 时代 AXI PCIe Host 实现。RK3588 单板量产 RC 模式更常见绑定 drivers/pci/controller/dwc/pcie-dw-rockchip.c(DesignWare);本文所述 rockchip,rk3399-pcie / rockchip,rk3399-pcie-ep 与 DWC 树并存于源码树,实际启用与否以 defconfig 与 DTS compatible 为准。
2. 总体架构:四文件分工
1 | pcie-rockchip.c # DT 解析、时钟/复位/PHY、端口初始化(RC 或 EP 模式寄存器) |
3. pcie-rockchip.c — RC/EP 共用层
3.1 rockchip_pcie_parse_dt()
- RC:
platform_get_resource_byname(..., "axi-base")→devm_pci_remap_cfg_resource→rockchip->reg_base(下游配置 ECAM 等)。 - EP:
"mem-base"→rockchip->mem_res(供pci_epc分配 BAR 窗口的物理内存描述)。 - 共用:
apb-base、按 lane 的pcie-phy-n(或 deprecatedpcie-phy)、core/mgmt/mgmt-sticky/pipe/pm/pclk/aclkreset、多路时钟、num-lanes、max-link-speed。 - RC 专有:可选
epGPIO(GPIOD_OUT_LOW)。
3.2 rockchip_pcie_init_port()
关键寄存器 PCIE_CLIENT_CONFIG(定义见 pcie-rockchip.h):
| 组合 | 含义 |
|---|---|
PCIE_CLIENT_CONF_ENABLE | PCIE_CLIENT_MODE_RC |
Root Complex:开启访问类型配置、LINK_TRAIN 等与 RC 流程配套 |
PCIE_CLIENT_CONF_DISABLE | PCIE_CLIENT_MODE_EP |
Endpoint:先保持 EP 所需禁用项 |
序列:断言各级 reset → PHY init → core reset → 选 Gen1/Gen2 → 写 PCIE_CLIENT_CONFIG → PHY power_on → 等待 PLL lock → 按 TRM 顺序 deassert mgmt_sticky/core/mgmt/pipe。
4. RC 模式:pcie-rockchip-host.c
4.1 绑定与 PCI 核心对接
rockchip->is_rc = true,compatible:rockchip,rk3399-pcie。devm_pci_alloc_host_bridge+pci_host_probe(bridge)完成枚举。
4.2 配置空间访问
- RC 自身 Type0:
apb_base + PCIE_RC_CONFIG_NORMAL_BASE + offset(rockchip_pcie_rd/wr_own_conf)。 - 下游设备:
reg_base + PCIE_ECAM_OFFSET(bus, devfn, where),访问前rockchip_pcie_cfg_configuration_accesses()选择AXI_WRAPPER_TYPE0_CFG/TYPE1_CFG。 rockchip_pcie_valid_device():根桥下只允许PCI_SLOT(devfn)==0,限制直连端口扫描宽度。
4.3 ATU 与 DMA workaround
rockchip_pcie_cfg_atu():编程 outbound MEM/IO、message region;若dma_trx_enabled为真,对 OB region 1 额外rockchip_pcie_prog_ob_atu(..., mem_reserve_start, 0)(注释 Workaround for PCIe DMA transfer)。dma_trx_enabled == 1时rockchip_pcie_wait_l2()直接返回 0(不强制进 L2,注释 Don’t enter L2 when no ep connected)。
4.4 内置 UDMA(RK3399 风格 APB 寄存器)
rk_pcie_config_dma_rk3399():在dma_table->descs填入 local/bus 地址 64 位、buf_size、bit24 等(与rockchip-pcie-dma.c生成的表一致)。rk_pcie_start_dma_rk3399():写PCIE_APB_CORE_UDMA_BASE + 0x14*chn + {0x04,0x08,0x00}(描述符 PA 低/高、启动控制BIT(0)|(dir<<1))。- 中断:
PCIE_CLIENT_INT_UDMA→rockchip_pcie_handle_dma_interrupt()清除PCIE_UDMA_INT_REG,更新dma_trx_obj。 probe:dma_trx_enabled != 0时rk_pcie_dma_obj_probe(dev),并赋值start_dma_func/config_dma_func。
4.5 dma_trx_enabled 注意点
- DTS 中可出现
rockchip,dma_trx_enabled(例如rk3399pro-evb-v14-linux.dts)。 - 当前仓库
rockchip_pcie_parse_host_dt()未见对该属性的of_property_read_*,dma_trx_enabled默认为 0;若需启用 DMA,须确认 厂商补丁是否在别处赋值,否则会跳过rk_pcie_dma_obj_probe。
5. EP 模式:pcie-rockchip-ep.c
5.1 绑定与框架
rockchip->is_rc = false,compatible:rockchip,rk3399-pcie-ep。devm_pci_epc_create(dev, &rockchip_pcie_epc_ops),对上pci_epf驱动。
5.2 pci_epc_ops 要点
| 回调 | 作用 |
|---|---|
write_header |
Vendor/Device/Class/Subsystem/IRQ pin 等到 PCIE_EP_PF_CONFIG 区域 |
set_bar / clear_bar |
BAR aperture/type + ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_*(inbound:PCI→AXI) |
map_addr / unmap_addr |
Outbound ATU:EP 访问 pci_addr 映射到本地 cpu_addr |
set_msi / get_msi |
编程片上 MSI capability 寄存器 |
raise_irq |
LEGACY:INTx pulse;MSI:配 OB ATU 后 writew 至 irq_cpu_addr |
start |
PCIE_CORE_PHY_FUNC_CFG 按已注册的 **pci_epf function_no` 使能 |
5.3 内存与链路
pci_epc_multi_mem_init:默认mem-base上每SZ_1M一块窗口。irq_cpu_addr:从pci_epc_mem_alloc_addr分配 MSI 触发窗口。- 链路: probe 末尾
PCIE_CLIENT_LINK_TRAIN_ENABLE,最后再PCIE_CLIENT_CONF_ENABLE。 - MSI-X:通过改写 capability next pointer 把 MSI-X 条目移出链表,避免 RC 分配不可用向量。
5.4 与本目录 DMA 文件的关系
- **
pcie-rockchip-ep.c不调用rk_pcie_dma_obj_probe。 - 需要 片上 PCIe DMA + misc/ioctl 的 EP 场景,在同内核树中常体现在
dwc/pcie-dw-ep-rockchip.c(DesignWare)。
6. rockchip-pcie-dma.c — UDMA 与用户态协议
6.1 依赖配置
CONFIG_ROCKCHIP_PCIE_DMA_OBJ=y时rk_pcie_dma_obj_probe/remove为真实实现;否则rockchip-pcie-dma.h内联为空操作。
6.2 硬件抽象
struct dma_trx_obj:本地一致性缓冲区dma_alloc_coherent、远端 PCI 地址remote_mem_start(可由region_base共享内存握手)、多张dma_table、workqueue、hrtimerrk_pcie_scan_timer(默认约 100µs 周期扫描 magic)。- RC 判定:
obj->busno == 0→is_rc(obj)。
6.3 缓冲区协议(注释摘要)
- 每方向约 8MB 分区:wr buf / rd buf 各 1MB 槽 × 多槽,头部 magic
0x12345678、local idx、payload size;ack 使用0xdeadbeef/0xcafebabe。 rk_pcie_prepare_dma()按PCIE_DMA_DATA_SND/RCV_ACK/FREE_ACK/READ_REMOTE填dma_table,调用obj->config_dma_func(由 host 设为rk_pcie_config_dma_rk3399或 DWC 变体),并入队dma_trx_work→start_dma_func。
6.4 用户态接口
miscdevice:open初始化dma_free、bitmap;mmapremap_pfn_range(local_mem_start)。ioctl(见rk-pcie-dma.h):PCIE_DMA_START、GET_LOCAL_READ_BUFFER_INDEX、FREE_LOCAL_READ_BUFFER_INDEX、SYNC_*、WAIT_TRANSFER_COMPLETE、SET_LOOP_COUNT、READ_FROM_REMOTE等。- 缓存一致性:发送路径
dma_sync_single_for_device,接收dma_sync_single_for_cpu。
7. 与 DesignWare(RK3588 常用)对照
| 项目 | 本文 AXI 四文件 | DWC:pcie-dw-rockchip.c / pcie-dw-ep-rockchip.c |
|---|---|---|
Host compatible |
rockchip,rk3399-pcie |
rockchip,rk3568-pcie / rk3588-pcie 等 |
| EP | pcie-rockchip-ep.c |
pcie-dw-ep-rockchip.c |
| DMA 寄存器 | APB PCIE_APB_CORE_UDMA_* |
DWC CDM / doorbell / context(rockchip_pcie_start_dma_dwc) |
dma_trx_obj |
host:rk_pcie_start_dma_rk3399 |
DWC:rockchip_pcie_init_dma_trx |
移植或调试时请以 实际编译进内核的驱动 + DTS 为准。
8. 相关文档
| 文档 | 内容 |
|---|---|
| rk3588-kernel-6.1-驱动DMA编程与PCIe设备DMA传输分析.md | 通用 PCI 设备 DMA 编程 |
| rk3588-kernel-6.1-pci总线架构分析.md | drivers/pci 与 RK Host |
9. 修订记录
| 日期 | 说明 |
|---|---|
| 2026-05-08 | 初版:pcie-rockchip* RC/EP、rockchip-pcie-dma、与 DWC 对照、dma_trx_enabled 说明 |
正在加载留言…