图:PCIe 设备连接链路
设备之间的路径称为链路(Link)。它由一个或多个发送和接收对组成。链路中的一对称为通道(Lane)。Qualcomm Linux 设备中的 PCIe 设备连接支持 16 个通道。通道数或链路宽度为 x16。 下表列出了设备的 PCIe 连接类型。表:PCIe 连接
| PCIe 类型 | 说明 |
|---|---|
| 根复合体(RC) | 将 CPU 连接到 PCIe 拓扑 |
| 交换机 | 连接 2 个以上的端口并充当数据包路由器 |
| 桥 | 连接不同的总线:例如,PCIe 到 PCIe,或 PCIe 到外设组件互连(PCI) |
| 端点(EP) | 位于 PCIe 拓扑树结构的底部,只有一个上游端口 |
| 传统端点 | 使用较旧的 PCI 总线操作以支持向后兼容 |
PCIe 主机模式枚举功能
系统首次上电时,在系统主机处理器上运行的配置软件只知道 Bus 0 的存在(如果支持 PCIe)。软件不了解总线拓扑或连接到总线的任何设备。枚举过程会发现系统中存在的各种总线、设备和功能。 枚举完成后,系统中的每条总线编号如下:- 主总线号表示直接连接到桥的主接口(朝向根复合体)的总线。
- 次总线号表示直接连接到桥的次接口(远离根复合体)的总线。
- 从属总线号表示存在于桥下游侧的编号最高的总线。
- 链路训练
- 扫描总线上的设备
- 注册
PCIe 分层架构
下图展示了 PCIe 软件架构。
图:PCIe 软件架构
下图展示了 PCIe 的分层架构模型。图:PCIe 分层架构
交换的传输单元如下。- 物理层实体之间的有序集(Ordered set)。
- 数据链路层实体之间的数据链路层数据包(DLLP)。
- 事务层实体之间的事务层数据包(TLP)。
表:PCIe 架构中的层
| 层 | 特性 |
|---|---|
| 物理层 | 逻辑子块:链路训练、初始化和维护。 |
| 物理子块:8b/10b 编码和解码,以及并串和串并转换。 | |
| 数据链路层 | DLLP 数据包的组装和拆卸。 |
| 链路层 CRC(LCRC)的生成和验证。 | |
| 确认和否定确认协议(重传出错的 TLP)。 | |
| 事务层 | TLP 数据包的组装和拆卸。 |
| 端到端 CRC(ECRC)的生成和验证。 | |
| 流量控制:接收实体使用 DLLP 通告可用接收缓冲区大小信息。 | |
| 服务质量(QoS):流量类别(TC)到虚拟通道(VC)的映射。 | |
| 事务排序:在 VC 内实现事务排序规则。 |
图:PCIe 配置地址空间
PCIe 软件驱动程序配置
PCIe 控制器驱动程序初始化 PCIe 资源并执行链路训练。训练成功后,控制器驱动程序调用 PCIe 框架进行链路枚举,例如端点发现、识别客户端驱动程序并探测这些驱动程序。有关 PCIe 框架和客户端驱动程序 PCIe 注册的更多信息,请参阅 https://www.kernel.org/doc/html/latest/PCI/index.html。链路训练
链路训练包括以下操作:- 位于 https://github.com/torvalds/linux/blob/master/drivers/pci/controller/dwc/pcie-qcom.c 的 PCIe 驱动程序
pcie-qcom.c文件从设备树获取所需资源,例如稳压器、时钟。 - PCIe 驱动程序调用位于 https://github.com/torvalds/linux/blob/master/drivers/pci/controller/dwc/pcie-designware-host.c 的 Synopsys DesignWare® Core 主机驱动程序 pcie-designware-host.c 文件来初始化根复合体。
- Synopsys DesignWare Core 驱动程序执行所有必要的初始化。
- Synopsys DesignWare Core 驱动程序调用函数指针以执行主机初始化。
- Qualcomm PCIe 驱动程序执行 PHY 上电,启用所有稳压器、时钟。
- Synopsys DesignWare Core 驱动程序通过调用启动链路的函数指针来开始链路训练。
硬件初始化
驱动程序初始化并配置 PCIe 硬件模块并执行链路训练。初始化在调用platform _probe() 驱动函数之后进行。
注意:PCIE_0 根复合体实例默认启用,用于 WLAN EP 连接。
为 Dragonwing IQ-9075(Lemans)启用 PCIe 端点(EP)模式
Dragonwing IQ-9075(Lemans)上的每个 PCIe 控制器实例都可以运行在根复合体(RC)或端点(EP)模式,但不能同时运行两种模式。设备树在同一基地址处为每种模式定义了单独的节点,并且每个 PCIe 实例每次只能启用其中一个。注意:Monaco 也支持 PCIe EP 模式,但该支持尚未包含在当前内核代码树中,计划在后续版本中提供。
表:Lemans PCIe EP 节点
| EP 节点 | RC 节点(互斥) | Compatible | num-lanes | linux,pci-domain |
|---|---|---|---|---|
| pcie0_ep | pcie0 | qcom,sa8775p-pcie-ep | 2 | 0 |
| pcie1_ep | pcie1 | qcom,sa8775p-pcie-ep | 4 | 1 |
pcie0_ep 和 pcie1_ep 均在 arch/arm64/boot/dts/qcom/lemans.dtsi 中定义,且默认 status = "disabled",因为对应的 RC 节点(pcie0、pcie1)已启用。绑定到这些节点的 Qualcomm PCIe EP 控制器驱动程序为 drivers/pci/controller/dwc/pcie-qcom-ep.c(驱动名称 qcom-pcie-ep)。
PCIe EP 模式内核配置
CONFIG_PCI_ENDPOINT 和 CONFIG_PCI_ENDPOINT_CONFIGFS 已在 Lemans defconfig 中启用。用于构建 Qualcomm EP 控制器驱动程序的 CONFIG_PCIE_QCOM_EP 默认未启用,必须开启才能启用 EP 模式。CONFIG_PCI_EPF_MHI 及其依赖项 CONFIG_MHI_BUS_EP 也默认未启用,必须开启才能使用 MHI 端点功能。
要启用这些配置,请将以下补丁应用到 arch/arm64/configs/defconfig 文件。
注意:
CONFIG_PCIE_QCOM_EP 依赖 CONFIG_PCI_ENDPOINT,并选择 drivers/pci/controller/dwc/Kconfig 中定义的 CONFIG_PCIE_DW_EP 和 CONFIG_PCIE_QCOM_COMMON。CONFIG_PCI_EPF_MHI 定义于 drivers/pci/endpoint/functions/Kconfig,依赖 CONFIG_MHI_BUS_EP——即 drivers/bus/mhi/ep/Kconfig 中的 MHI 端点总线实现。在设备树中启用 EP 节点
pcie1(RC)和 pcie1_ep(EP)都在 lemans.dtsi 中通过标签定义,且 pcie1 在其中默认 status = "disabled"。然而,lemans-evk.dts 又通过板载 M.2 E-key 连接器将 pcie1 重新启用为 RC 模式(&pcie1 { ... status = "okay"; };)。由于每个 PCIe 实例在同一时间只能处于 RC 或 EP 中的一种模式,因此在 Lemans EVK 上将 PCIE_1 切换为 EP 模式意味着禁用该 RC 覆盖,并改为启用 pcie1_ep。将以下更改应用到 arch/arm64/boot/dts/qcom/lemans-evk.dts:
pcie1_default_state(在 lemans-evk.dts 靠后位置的 &tlmm 节点中定义)为 GPIO 4 (PERST#) 和 GPIO 5 (WAKE#) 设置了引脚功能、驱动强度和偏置,但没有固定它们的方向,因此 EP 节点可以复用与 RC 模式相同的 pinctrl 组和物理 GPIO。但是,每个 GPIO 上的信号方向会在两种模式之间反转:
- 在 RC 模式下,
pcie-qcom.c将 PERST# GPIO 请求为GPIOD_OUT_HIGH——根复合体驱动 PERST# 以复位下行设备。RC 模式不驱动 WAKE# GPIO。 - 在 EP 模式下,
pcie-qcom-ep.c将reset-gpios请求为GPIOD_IN——端点将 PERST# 作为输入读取,由连接的根复合体驱动;并将wake-gpios请求为GPIOD_OUT_LOW——端点将 WAKE# 作为输出驱动到主机。
注意:上游
qcom,pcie-ep.yaml 绑定要求提供 reset-gpios,即连接到由所连接根复合体驱动的 PERST# 输入的 GPIO。lemans.dtsi 中的 pcie1_ep 节点没有定义该属性,因为它是板卡相关的。PCIE_0:禁用 pcie0 RC 覆盖,改为启用 pcie0_ep,复用 pcie0_default_state pinctrl 组及其 PERST#/WAKE# GPIO。
注意:禁用
pcie0 也会同时禁用 M.2 E-key 连接器的 PCIe 链路(pcieport0),因为该连接器在 RC 模式下接线到 PCIE_0。仅当你不需要将 M.2 连接器用于 PCIe 卡时,才将 PCIE_0 切换到 EP 模式。phys、iommus、interconnects、power-domains、clocks 和 resets 已在两个 EP 节点中填充完毕,标准 bring-up 时无需修改。
PCIe EP 驱动初始化
pcie-qcom-ep.c 中的 qcom_pcie_ep_probe() 会获取 parf、dbi、mmio 和 dma 寄存器区域、全部五个实例时钟、core 复位、reset(PERST#)和可选的 wake(WAKE#) GPIO,以及可选的 pciephy PHY,然后调用公共的 DesignWare dw_pcie_ep_init() 来初始化端点核心。Lemans 匹配 qcom,sa8775p-pcie-ep compatible 字符串,该字符串选择 cfg_1_34_0 配置(启用 HDMA 支持、NO_SNOOP 覆盖,并禁用 MHI RAM 奇偶校验)。
一个全局 IRQ 线程(qcom_pcie_ep_global_irq_thread())用于处理由连接的根复合体触发的链路建立/断开事件、总线主控使能(BME),以及 PM turn-off/D 状态通知。
使用 configfs 绑定 MHI 端点功能
pci-epf-mhi.c 驱动在 pci_epf_mhi_ids[] 中为每个 SoC 注册一个设备 ID,每个都有各自的 header(vendor/device ID)和 MHI 通道配置。Lemans 匹配 pci_epf_mhi_sa8775p 条目,该条目设置设备 ID 0x0116,使用 BAR_0、32 个 MSI 向量、MRU 为 0x8000,并启用 DMA 辅助传输(MHI_EPF_USE_DMA)。该条目还选择标准的 mhi_v1_channels 表(LOOPBACK、SAHARA、DIAG、SSR、QDSS、EFS、MBIM、QMI、IP-CTRL-1、IPCR、DUN、IP_SW0)。header 和通道配置由此条目固定,因此无需通过 configfs 写入 vendorid/deviceid。
内核在启用 pcie1_ep 的情况下启动后,使用 PCI 端点 configfs 接口将 MHI 端点功能绑定到 qcom-pcie-ep 控制器。functions 目录名称必须与 pci_epf_mhi_sa8775p 条目匹配,以便探测到正确的设备 ID 和通道表。
start 写入 1 会声明端点已就绪,允许链路与连接的根复合体进行训练。pci_epf_mhi_bind() 会从父 qcom-pcie-ep 平台设备中查找 mmio 寄存器区域和 doorbell 中断,而 pci_epf_mhi_link_up() 会在链路建立后注册 MHI 端点控制器。
注意:如果
mhi_bus_ep 和 pci_epf_mhi 构建为独立模块,请先加载 mhi_bus_ep,因为 CONFIG_PCI_EPF_MHI 依赖 CONFIG_MHI_BUS_EP。验证 MHI EP 模式枚举
在连接到 Lemans EP 端口的主机上,确认设备已作为具有该 MHI 设备 ID 的 PCI 端点被枚举。启用 QPS615 PCIe 交换机
本节介绍如何在 Qualcomm Linux 硬件 SoC 中启用 QPS615 PCIe 交换机。QPS615 交换机端点在PCIe1 实例上受支持。下图展示了 QPS615 端点和连接。
图:QPS615 PCIe 交换机连接图
可从以下位置访问 Qualcomm PCIe 驱动程序文档:- https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/pci/qcom%2Cpcie-sc8280xp.yaml
- https://elixir.bootlin.com/linux/v6.6.48/source/Documentation/devicetree/bindings/pci/qcom,pcie.yaml
- https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/phy/qcom%2Csc8280xp-qmp-pcie-phy.yaml
PCIe 相关配置
以下配置默认启用,以支持 QPS615 交换机。若要将其用于其他 PCIe 端点,请通过还原代码更改来禁用 QPS615 交换机的默认支持。 要启用 PCIe 相关的configs,请将以下补丁应用到 /arch/arm64/configs/qcom_addons.config 文件。
消息信号中断(MSI)
当前的 MSI 映射并不包含所有向量。Qualcomm Linux 硬件 SoC 支持八个向量。每个向量又支持 32 个 MSI。因此,支持的 MSI 总数为 256。 有关为此 PCIe 实例添加所有受支持的 MSI 组的信息,请参阅 https://lore.kernel.org/linux-arm-msm/f1168212-bc6e-4570-869c-2870d6f248ad@linaro.org/T/。PCIe 内核驱动程序日志示例
以下是来自 QPS615 设备枚举的 PCIe 内核驱动程序日志示例。通过 QPS615 PCIe 交换机支持的以太网接口
QPS615 PCIe 交换机为设备启用以太网连接。当设备加载 QPS615 驱动程序并建立 PCIe 链路时,默认情况下会在设备启动期间自动激活受支持的以太网接口。 要自定义默认配置或启用 Qualcomm 硬件设置之外的额外 MAC/PHY 组件,请参阅 Qualcomm Linux Ethernet guide 中的 Bring up Ethernet 部分。表:支持的以太网接口
| 接口类型 | 速度 | 连接器类型 | 说明 |
|---|---|---|---|
| QEP PHY (SGMII) | 2.5 GbE | IX/RJ45 连接器(QEP8121) |
|
| AQR PHY (USXGMII) | 10 GbE | IX/RJ45 连接器(AQR113C) |
|
启用替代硬件组件
您可以连接 Qualcomm 提供的硬件配置之外的 MAC/PHY 组件并将其启用。 要将 QPS615 替换为其他基于 PCIe 的 MAC/PHY,请参阅启用 QPS615 PCIe 交换机。注意:您必须从相应的供应商处获取 MAC/PHY 驱动程序和固件。Qualcomm 对这些配置更改不承担责任。
通过 PCIe 交换机启用 USB 接口
本节介绍如何在 Qualcomm Linux 硬件 SoC 中通过 PCIe 交换机激活 USB 接口。PCIE1 实例连接到 QPS615 交换机的端点,QPS615 的下游端口连接到 PCIe 转 USB 端点。有关使用 QPS615 的 PCIe 转 USB 端点连接,请参阅位于 https://docs.qualcomm.com/bundle/publicresource/topics/80-80021-251/rb3_hardware_overview.html 的主板和转接板框图。注意:Dragonwing IQ-9075 PCIe 软件不支持 USB。
下载 PCIe 转 USB 控制器固件
要从 https://www.renesas.com/us/en/products/interface/usb-switches-hubs/upd720201-usb-30-host-controller#design_development 下载固件,请注册并登录 https://www.renesas.com/。将下载的固件文件重命名为 renesas_usb_fw.mem。注意:为防止命令失败,请在更新 Renesas 固件之前,按照 Set up the device 部分中的说明更新软件。
- 通过 USB 线缆将设备连接到主机 PC 以使用 adb。
- 将固件推送到设备。
- 要激活固件,请执行以下任一选项。
- 选项 A:重启目标设备以启用 USB Type-A 端口。
- 选项 B:手动绑定 Renesas xHCI 驱动程序。
- 验证固件枚举。
用于 PCIe 转 USB 设备枚举参考的 PCIe 内核驱动程序日志
您可以运行以下命令来查看设备信息:- 要显示 USB 中的设备信息,请运行以下命令。
将显示以下消息。
- 要显示 PCIe 中的设备信息,请运行以下命令。
将显示以下消息。
级联连接 QPS615 交换机
以级联方式连接 QPS615 交换机,以启用额外的以太网、PCIe 和 USB 端口。注意:此功能仅在 QCS6490 中受支持。
图:QPS615 交换机级联连接
- 要重置 QPS615 交换机,请切换 QPS615 #1 和 QPS615 #2 的 RESX GPIO。
- 要控制端点重置,请触发 PERST。两个交换机共享 PERST。
- 连接到交换机的设备:
- QPS615 PCIe 树节点层次结构是静态固定的。
- 用于交换 USP 和 DSP 端口的所有节点都在 PCIe 初始化期间创建。
- 其中一个交换机 DSP 端口代表 WLAN。
- 如果禁用 WLAN 节点,将禁用 WLAN 设备,但 PCIe 下游端口仍保持启用状态,并返回默认的最大链路宽度。
- 直接连接的 WLAN 设备:
- 仅禁用单个节点。
- 当 WLAN 被禁用时,返回 Invalid argument。
通过 PCIe 接口启用 NVMe
本节介绍如何使用 PCIe 启用 NVMe 以进行存储扩展。要验证 NVMe 是否通过 PCIe 接口连接,请执行以下操作:- 要显示 PCIe 设备信息,请运行以下命令。
输出:
- 找到 PCIe 日志。
输出:
- 要找到 NVMe 目录,请运行以下命令。
输出:
为 SMMUv2 目标更新 iommu-map 属性
对使用 SMMUv2 IOMMU 处理 PCIe 的目标(例如 Dragonwing IQ-9075 (Lemans)、Monaco 和 Kodiak)而言,每个 PCIe Requester ID (RID) 都会通过 PCIe host bridge 节点中的iommu-map 属性转换为一个 Stream ID (SID)。在给 PCIe 根复合体下游添加设备、交换机或端点时,此属性配置错误是导致出现 no iommu-map translation for id 失败的常见原因。
iommu-map 的工作原理
每个iommu-map 条目具有以下形式:
drivers/of/base.c: of_map_id())按以下规则处理:
count = 1 时,映射简化为 RID == rid_base -> SID = sid_base。每个条目使用 count = 1(稀疏点映射)可将一个 RID 精确固定到一个 SID,无论 RID 值有多大,并可避免耗尽 SMMU 实现的 SID 范围。
注意:简单的单一 range 条目,例如
iommu-map = <0x0 &pcie_smmu 0x0000 0x500>;,会将 count 个连续的 RID 映射到 count 个连续的 SID,因此 SID 偏移会随 RID 值成比例增长。一旦来自下游交换机或额外端点的 RID 超出 SMMU 可用的 SID 范围,这种映射就会失败。PCIe RID 与 SID 基础
PCIe RID 是一个 16 位值,编码了总线、设备和功能:表:常见 RID 值
| Bus | Dev | Fn | RID (hex) | 说明 |
|---|---|---|---|---|
| 0 | 0 | 0 | 0x0000 | 根复合体,始终存在 |
| 1 | 0 | 0 | 0x0100 | RC 下行的第一个设备(端点或交换机上行) |
| 2 | 1 | 0 | 0x0208 | 交换机下行端口,设备 1 |
| 2 | 16 | 1 | 0x0281 | lspci 地址 02:10.1 |
lemans.dtsi 参考示例
Lemans 定义了两个 PCIe 控制器,每个都映射到共享pcie_smmu(qcom,sa8775p-smmu-500,一个 SMMUv2 系列 IOMMU)中各自的 SID 子范围。pcie0 使用 SID 基址 0x0000,pcie1 使用 SID 基址 0x0080,因此它们的 SID 空间不会重叠。
0x0000(bus 0, dev 0, fn 0)在 pcie0 上映射到 SID 0x0000,在 pcie1 上映射到 SID 0x0080。RID 0x0100(bus 1, dev 0, fn 0)在 pcie0 上映射到 SID 0x0001,在 pcie1 上映射到 SID 0x0081。Monaco 使用其自身的 pcie_smmu 实例遵循相同模式;Kodiak 也遵循相同模式,只是使用 apps_smmu(qcom,sc7280-smmu-500)而不是专用的 pcie_smmu。
注意:
lemans-ride-common.dtsi 在 pcieport0(bus 1, dev 0, fn 0 — RID 0x0100)上挂载了一个 WiFi 芯片,并从 lemans.dtsi 继承 iommu-map 而未覆盖,因为基础文件已经涵盖了该 RID。为交换机拓扑扩展 iommu-map
如果在控制器下游安装了 PCIe 交换机(例如,通过两个交换机端口在 bus 4 上添加 NVMe SSD),请在条目列表中为每个 RID 增加一行,并对每一项保持count = 1:
0x0000 到 0x0004),全部位于 pcie0 的子范围之内;而不是使用一个 count = 0x500 的单一 range 条目,后者可能超出 SMMU 实现的 SID 范围。
注意:分配给每个 RID 的 SID 值不必是连续的,也不必按 RID 顺序排列。它们只需在该控制器的
iommu-map 内唯一,并且位于 SMMU 实现的 SID 范围内。诊断缺失的 iommu-map 条目
当设备的 RID 没有匹配的iommu-map 条目时,内核日志会记录类似如下的错误:
- 从日志中读取 RID。在此示例中,RID 为
0x0281。 - 将 RID 解码为总线、设备和功能。
与同一日志行中的
lspci地址交叉核对(0001:02:10.1→ bus 2, device 0x10, function 1)。字段一致,确认 RID 解码正确。 - 为该设备选择一个空闲 SID。查看现有的
iommu-map条目,选一个尚未被此控制器映射中其他条目使用、并且在 SMMU 实现的 SID 范围内的 SID。 - 使用
count = 1添加条目。如果 fn0 和 fn1 连续且都还没有 SID,可以用一个count = 2的条目同时覆盖两者:<0x0280 &apps_smmu 0x1403 0x2>会将 RID0x0280映射到 SID0x1403,将 RID0x0281映射到 SID0x1404。 - 重新构建 DTB、刷写并重启,然后确认修复效果。
错误行必须不再出现。
注意:无论是否存在
iommu-map 条目,lspci 都会显示设备,因为 lspci 直接读取 PCI 配置空间,不受 IOMMU 映射影响。请使用 dmesg,而不是 lspci,来确认缺失的条目已被修复。drivers/of/base.c: of_map_id()。
PCIe 客户端驱动程序示例
客户端驱动程序定义device-id 表和 pci_driver 结构,并向 PCIe 框架注册。以下是一些 PCIe 客户端驱动程序示例,供参考。
- 用于保存客户端特定私有数据的数据结构示例。
- 驱动程序示例:您可以根据驱动程序特定的数据结构提供数据。
- 带有驱动程序特定数据的设备 ID 表示例。客户端驱动程序使用
0x306设备 ID 进行注册。
注意:
MODULE_DEVICE_TABLE(pci, sample_pci_id_table); 是强制性的。- 带有客户端驱动程序名称、
pci-id表和回调的pci_driver数据结构示例。在向 PCI 框架注册时会传递指向此结构的指针。 - 要向 PCI 固件注册,请从
module_init()中调用pci_register_driver(&sample_pci_driver)。
PCIe 启用(bringup)
有关 PCIe 启用的信息,请参阅 PCIe-related configurations 和 QPS615 switch support。PCIe 功耗优化
PCIe 定义了两种类型的电源管理方法。- 电源管理软件,用于确定每个设备的电源管理能力并单独管理每个设备
- 无需软件干预的系统,例如活动状态电源管理(ASPM)
PCIe L0 链路状态
PCIe 电源管理定义了以下 L0 链路状态:- L0:活动状态,所有 PCIe 事务和其他操作均已启用
- L0s:具有低恢复延迟的 ASPM 状态(节能待机状态)
PCIe 设备状态
PCIe 电源管理定义了以下设备状态:- D0(强制):设备处于完全开启状态,其中有两个子状态
- D0uninitialized:设备复位后,功能处于 D0uninitialized 状态,等待被枚举和配置。
- D0active
- 枚举和配置过程完成后,功能处于 D0active 状态。
- 当系统软件启用一个或多个(任意组合)功能参数(例如内存空间使能、I/O 空间使能或 BME 位)时,功能进入 D0active 状态。
- D1(可选):浅睡眠状态
- 除 PME 消息外,功能不能发起 TLP
- 除配置事务外,功能不能作为事务的目标。
- 功能通过对 PM 控制和状态寄存器进行编程来发出进入 D1 状态的软件命令。
- D2(可选):深睡眠状态
- 除 PME 消息外,功能不能发起 TLP
- 除配置事务外,功能不能作为事务的目标。
- 功能通过对 PM 控制和状态寄存器进行编程来发出进入 D2 状态的软件命令。
- D3(强制):设备处于最低功耗状态,功能必须支持两种 D3 状态
- D3hot
- 除 PME 消息外,功能不能发起 TLP。
- 除配置事务外,功能不能作为事务的目标。
- 功能通过对电源状态字段进行编程来发出进入 D3hot 状态的软件命令。
- D3cold:设备进入 D3cold 状态并断电;电源恢复后,设备进入 D0uninitialized 状态。
PCIe 验证
有关 PCIe 验证的信息,请参阅 PCIe-related configurations 和 QPS615 switch support。调试 PCIe 问题
lspci 和 setpci 命令是 Linux 发行版的原生命令。这些命令具有不同级别的输出。这些命令还可以提供对 PCI 总线上训练的不同组件的能力和状态的有用的即时快照。这些能力大多是 PCIe 基础规范所要求的配置空间寄存器的反映。有关更多详细信息,请参阅 https://pcisig.com/specifications。要查看使用说明,请运行以下命令。
- 显示设备信息
将显示以下消息。
- 显示设备控制寄存器中的 PCIe 设备和供应商 ID。
将显示以下消息。
PCIe 示例
有关上游设备树参考的信息,请参阅以下文件。- QCS6490 和 QCS5430:https://elixir.bootlin.com/linux/v7.0-rc7/source/arch/arm64/boot/dts/qcom/kodiak.dtsi
- Dragonwing IQ-9075:https://elixir.bootlin.com/linux/v7.0-rc7/source/arch/arm64/boot/dts/qcom/lemans.dtsi
- Dragonwing IQ-8275:https://elixir.bootlin.com/linux/v7.0-rc7/source/arch/arm64/boot/dts/qcom/monaco.dtsi
- Dragonwing IQ-615:https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git/tree/arch/arm64/boot/dts/qcom/qcs615.dtsi?h=arm64-for-6.16
- https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/pci/controller/dwc/pcie-qcom.c?h=v6.8-rc6#n1634
- QCS6490 和 QCS5430:https://elixir.bootlin.com/linux/v7.0-rc7/source/arch/arm64/boot/dts/qcom/kodiak.dtsi
- Dragonwing IQ-9075:https://elixir.bootlin.com/linux/v7.0-rc7/source/arch/arm64/boot/dts/qcom/lemans.dtsi
- Dragonwing IQ-615:https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git/tree/arch/arm64/boot/dts/qcom/qcs615.dtsi?h=arm64-for-6.16
客户端与 PCI 驱动程序操作流程示例
下图展示了 PCIe 客户端驱动程序为客户端配置 PCIe 驱动程序所遵循的顺序。
客户端与 PCI 驱动程序高层调用流程示例
下图展示了 PCIe 客户端驱动程序与 PCIe 驱动程序之间的高层调用流程和调用详细信息。

