PCIE设备树解析

下面是一段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
  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值