K1 平台 AMD 显卡适配指南
本文档为在 K1 平台 上适配 AMD 显卡的开发者提供参考。 以 Radeon HD7350 为例,介绍适配过程中对 Linux 内核的主要修改,并解释原因。本指南也适用于同代及其他 AMD GPU 的适配。
背景介绍
Linux 内核中的独立显卡驱动依托于 DRM(Direct Rendering Manager)子系统。 DRM 是一个用于管理 GPU(图形处理单元)资源的内核模块,提供统一的接口,以支持不同厂商的显卡。 它的整体结构可分为以下几个层次:
-
用户空间接口 通过
ioctl
等接口与 用户空间的图形库(如 Mesa、X.Org、Wayland)进行交互,应用程序 可通过这些库访问 GPU。 交互流程:应用 → 图形库 → DRMioctl
→ DRM 驱动 → GPU -
DRM 核心层(DRM Core) 提供统一的框架和通用功能,包括显卡设备初始化、资源分配、内存管理、任务调度与同步、以及用户空间和内核空间的通信接口。
-
GEM(Graphics Execution Manager)
- 提供图形内存对象的管理
- 支持显存的高效分配与共享
- 允许用户空间应用创建和管理图形缓冲区,实现高效渲染
-
TTM(Translation Table Maps)
- 负责显存与系统内存的映射和管理,可作为 GEM 的后端
- 提供在内存压力下的资源调度与分配策略
-
调度与同步(Command Scheduling)
- 管理 GPU 多任务的调度
- 使用 Fence 等机制协调内核与用户空间操作的顺序, 避免资源冲突
-
内存管理(VRAM Management)
- 负责显存分配、映射与回收
- 支持 零拷贝(Zero-Copy) 技术,减少内核与用户空间之间的数据传输开销
-
-
硬件特定驱动模块(Driver Modules)
- 负责不同厂商和型号的 GPU 的硬件控制
- 典型驱动:
nouveau
(NVIDIA 开源驱动)、amdgpu
和radeon
(AMD驱动)
radeon 驱动结构框图:
配置与修改
在将 AMD 显卡适配至 K1 平台时,需要对 显卡驱动、设备树 (Device Tree)、地址映射、缓存策略、DMA 位宽以及中断管理 等进行修改与调整。 对于 RISC-V 架构平台,这些调整应在充分理解 内存管理机制 和 PCIe 地址空间映射 的前提下进行。
本参考文档将从以下几个方面展开:
- 设备树解析与地址映射
- 添加 write-combining 支持
- 缓存属性与访问权限的调整
- DMA 地址宽度适配
- MSI 中断支持限制
- Linux 内核显卡驱动配置。
设备树与地址映射
设备树解析:
- 在设备树中,
ranges
属性定义了子设备地址空间与父设备地址空间的映射关系。 - 在 PCIe 主控节点中,
ranges
通常包含四个部分:<地址属性, PCIe地址, CPU地址, 地址长度>
示例修改如下:
diff --git a/arch/riscv/boot/dts/spacemit/k1-x.dtsi b/arch/riscv/boot/dts/spacemit/k1-x.dtsi
index 7ea166ca6fb0..fd978a379c37 100644
--- a/arch/riscv/boot/dts/spacemit/k1-x.dtsi
+++ b/arch/riscv/boot/dts/spacemit/k1-x.dtsi
@@ -2198,7 +2198,8 @@ pcie2_rc: pcie@ca800000 {
#address-cells = <3>;
#size-cells = <2>;
ranges = <0x01000000 0x0 0xb7002000 0 0xb7002000 0x0 0x100000>,
- <0x02000000 0x0 0xa0000000 0 0xa0000000 0x0 0x17000000>;
+ <0x42000000 0x0 0xa0000000 0 0xa0000000 0x0 0x10000000>,
+ <0x02000000 0x0 0xb0000000 0 0xb0000000 0x0 0x7000000>;
interconnects = <&dram_range2>;
interconnect-names = "dma-mem";
-
改动前:
- 源地址
0xa0000000
→ 目标地址0xa0000000
- 大小
0x17000000
(368 MB),属性为 MEM
- 源地址
-
改动后:
- 第一段:源地址
0xa0000000
→ 目标地址0xa0000000
,大小0x10000000
(256 MB),属性为 MEM + 预取 - 第二段:源地址
0xb0000000
→ 目标 地址0xb0000000
,大小0x7000000
(112 MB),属性为 MEM
- 第一段:源地址
此调整将较大显存区间分段,其中一部分设置为预取,提高访问性能。
提示
- K1 平台上 pcie2 可用地址空间总计 384MB,包括配置空间和 BAR 空间。
- 修改设备树时,应参考现有 GPU 的 BAR 地址范围,并适当划分映射区域。
添加 wc(write-combining) 支持
diff --git a/arch/riscv/include/asm/pci.h b/arch/riscv/include/asm/pci.h
index cc2a184cfc2e..9f6f59aff214 100644
--- a/arch/riscv/include/asm/pci.h
+++ b/arch/riscv/include/asm/pci.h
@@ -27,6 +27,10 @@ static inline int pcibus_to_node(struct pci_bus *bus)
#endif
#endif /* defined(CONFIG_PCI) && defined(CONFIG_NUMA) */
+#if defined(CONFIG_SOC_SPACEMIT_K1X)
+#define arch_can_pci_mmap_wc() 1
+#endif
+
/* Generic PCI */
#include <asm-generic/pci.h>
- 在 K1 平台 PCI 地址映射中启用 write-combining (WC)。
- WC 模式生效需要资源具备 IORESOURCE_PREFETCH 标志。
- 结合设备树修改,可在 PCI 资源映射到用户空间时启用 WC,从而提升显存访问效率。