rk3588 pcie驱动分析之二 (pcie设备树节点分析)

本文主要以rk3588 pcie3.0 x4节点为例,说明pcie设备树配置内容的含义

1、rk3588 pcie设备树配置

bash 复制代码
arch/arm64/boot/dts/rockchip/rk3588.dtsi
pcie3x4: pcie@fe150000/*APB 控制寄存器基地址*/ {
	compatible = "rockchip,rk3588-pcie", "snps,dw-pcie"/*Synopsys DesignWare PCIe IP 核心*/;
	#address-cells = <3>;
	#size-cells = <2>;
	bus-range = <0x00 0x0f>;
	clocks = <&cru ACLK_PCIE_4L_MSTR>, <&cru ACLK_PCIE_4L_SLV>,
		 <&cru ACLK_PCIE_4L_DBI>, <&cru PCLK_PCIE_4L>,
		 <&cru CLK_PCIE_AUX0>, <&cru CLK_PCIE4L_PIPE>;
	clock-names = "aclk_mst", "aclk_slv",
		      "aclk_dbi", "pclk",
		      "aux", "pipe";
	device_type = "pci";  /*设备节点的类型,这里为pci*/
	interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>,
		     <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>,
		     <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
		     <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
		     <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>;
	interrupt-names = "sys", "pmc", "msg", "legacy", "err";
	#interrupt-cells = <1>;
	interrupt-map-mask = <0 0 0 7>;
	interrupt-map = <0 0 0 1 &pcie3x4_intc 0>,
			<0 0 0 2 &pcie3x4_intc 1>,
			<0 0 0 3 &pcie3x4_intc 2>,
			<0 0 0 4 &pcie3x4_intc 3>;
	linux,pci-domain = <0>;
	num-ib-windows = <16>;
	num-ob-windows = <16>;
	num-viewport = <8>;
	max-link-speed = <3>;
	msi-map = <0x0000 &its1 0x0000 0x1000>;
	num-lanes = <4>;
	phys = <&pcie30phy>;
	phy-names = "pcie-phy";
	power-domains = <&power RK3588_PD_PCIE>;
	ranges = <0x00000800 0x0 0xf0000000 0x0 0xf0000000 0x0 0x100000  /*配置空间*/
		  0x81000000 0x0 0xf0100000 0x0 0xf0100000 0x0 0x100000       /*I/O空间*/
		  0x82000000 0x0 0xf0200000 0x0 0xf0200000 0x0 0xe00000      /*32bit非预取内存空间*/
		  0xc3000000 0x9 0x00000000 0x9 0x00000000 0x0 0x40000000>; /*64bit预取内存空间*/
	reg = <0x0 0xfe150000 0x0 0x10000>, /*APB*/
	      <0xa 0x40000000 0x0 0x400000>; /*DBI*/
	reg-names = "pcie-apb", "pcie-dbi";
	resets = <&cru SRST_PCIE0_POWER_UP>, <&cru SRST_P_PCIE0>;
	reset-names = "pcie", "periph";
	rockchip,pipe-grf = <&php_grf>;
	status = "disabled";

	pcie3x4_intc: legacy-interrupt-controller {
		interrupt-controller;
		#address-cells = <0>;
		#interrupt-cells = <1>;
		interrupt-parent = <&gic>;
		interrupts = <GIC_SPI 260 IRQ_TYPE_EDGE_RISING>;
	};
};


&pcie3x4 {
	reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
	vpcie3v3-supply = <&vcc3v3_pcie30>;
	pinctrl-names = "default";  /*管脚复用配置*/
	pinctrl-0 = <&pcie30x4_clkreqn_m1>;
	status = "okay";
};

2、芯片支持分配的BAR空间地址域

低端BAR地址范围是给32bit地址空间使用,高端BAR地址范围是给64bit地址空间使用。

3、PCI地址转换

PCI地址空间和CPU地址空间完全独立,所以地址转换是将PCI地址转换为CPU地址,在设备树中需要使用range,#address-cells和#size-cells属性来完成。

PCI设备配置空间中BAR空间配置的是PCIE域地址空间范围,而设备树中ranges中配置的是cpu域地址范围。

PCI地址使用3个cells,cpu地址使用2个cells,空间大小使用2个cells,cells的大小为4字节。

为什么PCI地址需要使用3个cells?这三个cells分别是标识phys.hi, phys.mid and phys.low

  • phys.hi cell: npt000ss bbbbbbbb dddddfff rrrrrrrr
  • phys.mid cell: hhhhhhhh hhhhhhhh hhhhhhhh hhhhhhhh
  • phys.low cell: llllllll llllllll llllllll llllllll

如果PCI地址为64位,就使用phys.mid and phys.low构成64位地址

phys.high的成员含义如下:

n(bit 31): relocatable region flag (在此不起作用)

p(bit 30): prefetchable (cacheable) region flag,1:预取,0:非预取

t(bit 29): aliased address flag (在此不起作用)

ss(bit 25 24): space code,空间类型编码

  • 00: configuration space,配置空间
  • 01: I/O space,I/O空间
  • 10: 32 bit memory space,32bit 存储空间
  • 11: 64 bit memory space,64bit 存储空间

bbbbbbbb: The PCI bus number. 总线号(8bit)

ddddd: The device number. 设备号(5bit)

fff: The function number. Used for multifunction PCI devices.功能号(3bit)

rrrrrrrr: Register number; used for configuration cycles. 寄存器号(8bit)

就PCI地址转换而言,关键字段是p​和ss。phys.hi中的p​和ss​值决定了当前访问的是哪一类PCI地址空间。

所以range中配置信息分析如下:

0x00000800 0x0 0xf0000000 0x0 0xf0000000 0x0 0x100000,配置空间,起始于PCI地址0xf0000000,大小为1MB,将被映射到主机CPU的0xf0000000地址上。

0x81000000 0x0 0xf0100000 0x0 0xf0100000 0x0 0x1000000,I/0空间,起始于PCI地址0xf0100000,大小为1MB,将被映射到主机CPU的0xf0100000地址上。

0x82000000 0x0 0xf0200000 0x0 0xf0200000 0x0 0xe00000,32位不可预取内存区域,起始于PCI地址0xf0200000,大小为14MB,将被映射到主机CPU的0xf0200000地址上。

0xc3000000 0x9 0x00000000 0x9 0x00000000 0x0 0x40000000>;,64位可预取内存区域,起始于PCI地址0x900000000,大小为1GB,将被映射到主机CPU的0x900000000地址上。

设备树中其他成员的含义在后续驱动详述中会描述其功能以及作用。

相关推荐
霖霖7141 小时前
【ESP32笔记】LED操作和呼吸灯实现
笔记·单片机·嵌入式硬件
zjxtxdy1 小时前
STM32hal库开发-GPIO
stm32·单片机·嵌入式硬件
zbyyd1 小时前
Linux字符设备驱动:LED驱动实战开发
linux·单片机·arm·驱动
曦夜日长1 小时前
Git系统篇,Git远程仓库(三):本地仓库与远程仓库的交互
linux·服务器·网络·git·交互
学linux的QQ蛋2 小时前
sys文件系统与misc文件系统学习小总结
linux·学习·驱动
碧海银沙音频科技研究院5 小时前
炬芯ATS3089X手表的HFP通话不自动路由到设备BT的问题解决
网络·人工智能·嵌入式硬件·算法
曦夜日长10 小时前
Git系统篇,Git本地使用(一):从“究极进化版“到三个区域的底层原理
大数据·linux·git·elasticsearch
youcans_10 小时前
【STM32C5教程】(3)GPIO 按键输入实验
stm32·单片机·嵌入式硬件
shimly12345611 小时前
给断网无 sudo ubuntu22.04 机器安装 nodejs
linux