PCIe总线-RK3588 PCIe RC初始化流程分析(十二)

1.简介

RK3588 PCIe RC的初始化涉及PCIe设备枚举、中断(INTx、MSI、MSI-X)配置、BAR配置、ATU配置、链路训练等,下面一一介绍。

2.初始化

当RC的模式为RK_PCIE_EP_TYPE时,平台驱动调用rk_add_pcie_port函数初始化RC,流程如下图所示,具体的工作有:

  1. 设置Host初始化回调函数结构体rk_pcie_host_ops,该结构体的实现和SoC硬件相关。
  2. 分配pci_host_bridge数据结构,并解析设备树中的"bus-range""ranges""dma-ranges"属性,后面详细分析该函数。
  3. 初始化中断
    1. 设置MSI/MSI-X中断控制器的irq_chip,该结构体用来响应、屏蔽、解除屏蔽、设置MSI/MSI-X中断功能。
    2. 创建MSI/MSI-X中断的第一级irq_domain,对应的irq_domain_opsdw_pcie_msi_domain_ops
    3. 创建MSI/MSI-X中断的第二级irq_domain,对应的msi_domain_infodw_pcie_msi_domain_info,第一级和第二级的irq_domain级联。
    4. 映射MSI Data的地址。
  4. 设置Root Bus配置空间访问方法为dw_pcie_ops,其他Bus的配置空间访问方法为dw_child_pcie_ops
  5. 初始化RC Port相关的配置和建立link。
    1. 初始化RC Port相关的配置。
      1. 设置速度、lanes数量、lanes的编号、link width,使能fast link。
      2. 关闭和屏蔽MSI中断。
      3. 设置RC Inbound BAR为64位P-MEM。
      4. 设置INTx中断为INTA#。
      5. 设置Primary、Secondary、Subordinate总线编号分别为0、1、0xFF。
      6. 使能IO、MEM、Bus Master、SERR。
      7. 配置OUT Bound MEM类型的ATU。主要设置Region的方向和编号、CPU低32位地址、CPU高32位地址、Region的大小、PCIe低32位地址、PCIe高32位地址、匹配的Function Number和TLP类型,最后使能Region。
      8. 配置OUT Bound IO类型的ATU。配置内容和步骤8一样。
      9. 设置RC Port的类型为PCI_CLASS_BRIDGE_PCI。
      10. 关闭RC Inbound的BAR0和BAR1。
    2. 建立link。
      1. 拉低PERST#,复位总线上的所有设备。
      2. 先关闭LTSSM,清除link状态,使能client reset or link down中断,最后使能LTSSM。
      3. 延时,CEM要求PERST#的时间至少为100ms+100us,这里延时200ms。
      4. 拉高PERST#,释放复位。
      5. 等待PCIe链路硬件link训练完成,建立link。
  6. 枚举PCIe总线,后面详细分析该函数。

RC初始化流程

如下图所示,pci_host_bridge数据结构的分配和桥地址资源的解析在devm_pci_alloc_host_bridge函数中,具体的工作有:

  1. 首先分配pci_host_bridge数据结构。
  2. 设置中断相关的回调函数,pci_common_swizzle用于处理PCI设备INTx#中断引脚路由的函数,将PCI设备中断引脚INTx#通过旋转的方式接到PCI Host主桥上。of_irq_parse_and_map_pci用于将INTx#中断号映射为Linux软件中断号。
  3. 请求资源。
    1. 从设备树中解析"bus-range"属性,即总线编号资源,同时转总线编号范围换成resource,最后添加到pci_host_bridge结构体中的windows链表中。
    2. 从设备树中解析"range"属性,即Outbound地址资源(CPU地址、PCI地址、MEM和IO地址类型),同时将地址资源换成resource,最后添加到pci_host_bridge结构体中的windows链表中。
    3. 从设备树中解析"dma-ranges"属性,即Inbound地址资源(CPU地址、PCI地址、MEM地址类型),同时将地址资源换成resource,最后添加到pci_host_bridge结构体中的windows链表中。

分配host_bridge

桥地址资源使用下面的回调函数解析。

[drivers/of/address.c]
static struct of_bus of_busses[] = {
#ifdef CONFIG_PCI
	/* PCI */
	{
		.name = "pci",
		.addresses = "assigned-addresses",
		.match = of_bus_pci_match,
		.count_cells = of_bus_pci_count_cells,
		.map = of_bus_pci_map,
		.translate = of_bus_pci_translate,
		.has_flags = true,
		.get_flags = of_bus_pci_get_flags,
	},
	......
};

static unsigned int of_bus_pci_get_flags(const __be32 *addr)
{
	unsigned int flags = 0;
	u32 w = be32_to_cpup(addr);

	if (!IS_ENABLED(CONFIG_PCI))
		return 0;

	switch((w >> 24) & 0x03) {
	case 0x01:
		flags |= IORESOURCE_IO;  // IO
		break;
	case 0x02: /* 32 bits */
	case 0x03: /* 64 bits */
		flags |= IORESOURCE_MEM; // MEM
		break;
	}
	if (w & 0x40000000)
		flags |= IORESOURCE_PREFETCH; // P-MEM
	return flags;
}

3.ATU

RC初始化的时候,会调用dw_pcie_prog_outbound_atu函数配置Outbound ATU region。每个ATU region有7组寄存器,分别是1个VIEWPORT寄存器、3组CTRL寄存器、1组BASE寄存器、1组TARGET寄存器、1组LIMIT寄存器。

3.1.VIEWPORT寄存器

ATU region的7组寄存器地址相同,设置某个region,由IATU_VIEWPORT_OFF寄存器设置。如下图所示,REGION_INDEX设置region的编号,REGION_DIR设置region的方向。

VIEWPORT

3.2.CTRL寄存器

下图是画出了两组CTRL寄存器,第三组用于配置Virtual Function,这里不介绍。第一组CTRL寄存器,用于配置Outbound/Inbound的传输的类型、TC、ATTR、Function编号等。第二组CTRL寄存器用于配置Outbound/Inbound的MSG_CODE、BAR编号、使能Region等。

CTRL寄存器

3.3.BASE寄存器

如下图所示,BASE寄存器共有2两个,一个配置Outbound/Inbound的低32的BASE地址,另一个配置Outbound/Inbound的高32的BASE地址。LWR_BASE_HW为硬件设置,表示该region地址的最小范围(4kB、8kB、16kB、32kB、64kB,默认为64kB),Outbound方向时LWR_BASE_RW表示存储器域基地址,Inbound方向时LWR_BASE_RW表示PCIe域基地址,UPPER_BASE_RW表示对应基地址的高32位。

BASE寄存器

3.4.TARGET寄存器

如下图所示,TARGET寄存器共有2两个,一个配置Outbound/Inbound的低32的TARGET地址,另一个配置Outbound/Inbound的高32的TARGET地址。LWR_TARGET_HW为硬件设置,表示该region地址的最小范围(4kB、8kB、16kB、32kB、64kB,默认为64kB),Outbound方向时LWR_TARGET_HW表示PCIe域基地址,Inbound方向时LWR_TARGET_HW表示存储器域基地址,UPPER_TARGET_RW表示对应基地址的高32位。

TARGET寄存器

3.5.LIMIT寄存器

如下图所示,LIMIT寄存器用于配置region的大小。

LIMIT寄存器

参考资料

  1. PCIEXPRESS体系结构导读
  2. PCI Express technology 3.0
  3. PCI Express® Base Specification Revision 5.0 Version 1.0
  4. Rockchip RK3588 TRM
  5. Linux kernel 5.10
  • 10
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值