下面是一段RK3588的PCIE2.0 的RC控制器的DTS配置,我们针对每个配置进行简要说明
pcie2x1l1: pcie@fe180000 {
compatible = "rockchip,rk3588-pcie", "snps,dw-pcie";
#address-cells = <3>;
#size-cells = <2>;
bus-range = <0x30 0x3f>;
clocks = <&cru ACLK_PCIE_1L1_MSTR>, <&cru ACLK_PCIE_1L1_SLV>,
<&cru ACLK_PCIE_1L1_DBI>, <&cru PCLK_PCIE_1L1>,
<&cru CLK_PCIE_AUX3>, <&cru CLK_PCIE1L1_PIPE>;
clock-names = "aclk_mst", "aclk_slv",
"aclk_dbi", "pclk",
"aux", "pipe";
device_type = "pci";
interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 244 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 &pcie2x1l1_intc 0>,
<0 0 0 2 &pcie2x1l1_intc 1>,
<0 0 0 3 &pcie2x1l1_intc 2>,
<0 0 0 4 &pcie2x1l1_intc 3>;
linux,pci-domain = <3>;
num-ib-windows = <8>;
num-ob-windows = <8>;
num-viewport = <4>;
max-link-speed = <2>;
msi-map = <0x3000 &its0 0x3000 0x1000>;
num-lanes = <1>;
phys = <&combphy2_psu PHY_TYPE_PCIE>;
phy-names = "pcie-phy";
ranges = <0x00000800 0x0 0xf3000000 0x0 0xf3000000 0x0 0x100000
0x81000000 0x0 0xf3100000 0x0 0xf3100000 0x0 0x100000
0x82000000 0x0 0xf3200000 0x0 0xf3200000 0x0 0xe00000
0xc3000000 0x9 0xc0000000 0x9 0xc0000000 0x0 0x40000000>;
reg = <0x0 0xfe180000 0x0 0x10000>,
<0xa 0x40c00000 0x0 0x400000>;
reg-names = "pcie-apb", "pcie-dbi";
resets = <&cru SRST_PCIE3_POWER_UP>, <&cru SRST_P_PCIE3>;
reset-names = "pcie", "periph";
rockchip,pipe-grf = <&php_grf>;
status = "disabled";
pcie2x1l1_intc: legacy-interrupt-controller {
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <1>;
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 245 IRQ_TYPE_EDGE_RISING>;
};
};
1、bus-range字段
bus-range = <0x0 0xf>;
该RC下的PCIE总线号的范围为0x0-0xf.
2、ranges 字段
ranges = <0x00000800 0x0 0xf3000000 0x0 0xf3000000 0x0 0x100000
0x81000000 0x0 0xf3100000 0x0 0xf3100000 0x0 0x100000
0x82000000 0x0 0xf3200000 0x0 0xf3200000 0x0 0xe00000
0xc3000000 0x9 0xc0000000 0x9 0xc0000000 0x0 0x40000000>;
ranges表示这个RC下的PCIE总线域的资源配置范围。7个元素为一组,第一个元素表示属性,第二个和第三个为pci域地址,第四个和第五个为CPU域地址空间,第六个和第七个为size。这部分的解析代码在内核的devm_of_pci_get_host_bridge_resources函数中。
我们详细看下第一个元素是如何解析的:
第一个元素表示资源的属性,解析函数如下:
static unsigned int of_bus_pci_get_flags(const __be32 *addr)
{
unsigned int flags = 0;
u32 w = be32_to_cpup(addr); // 是一个用于将32位大端字节序(big-endian)数据转换为主机字节序的宏定义。它用于处理在不同字节序之间进行数据转换的情况。
if (!IS_ENABLED(CONFIG_PCI))
return 0;
switch((w >> 24) & 0x03) {
case 0x01:
flags |= IORESOURCE_IO;
break;
case 0x02: /* 32 bits */
case 0x03: /* 64 bits */
flags |= IORESOURCE_MEM;
break;
}
if (w & 0x40000000)
flags |= IORESOURCE_PREFETCH;
return flags;
}
range字段各元素的含义已在下面进行注释:
ranges = <0x00000800 0x0 0xf3000000 0x0 0xf3000000 0x0 0x100000 // 第一组,属性值是0x00000800,代表err空间。pci域起始是0xf3000000,CPU域起始地址是0xf3000000,范围是0x100000
0x81000000 0x0 0xf3100000 0x0 0xf3100000 0x0 0x100000 // 第二组,属性值是0x81000000,代表IO空间。pci域起始是0xf3100000,CPU域起始地址是0xf3100000,范围是0x100000
0x82000000 0x0 0xf3200000 0x0 0xf3200000 0x0 0xe00000 // 第三组,属性值是0x82000000 ,代表MEM空间。pci域起始是0xf3200000,CPU域起始地址是0xf3200000,范围是0xe00000
0xc3000000 0x9 0xc0000000 0x9 0xc0000000 0x0 0x40000000>; // 第四组,属性值是0xc3000000,代表MEM空间。pci域起始是0x9c0000000 ,CPU域起始地址是0x9c0000000 ,范围是0x40000000