通用系统互连子系统¶
简介¶
此框架旨在提供一个标准的内核接口来控制 SoC 上互连的设置。这些设置可以是多个互连设备或功能块之间的吞吐量、延迟和优先级。可以动态控制它以节省功耗或提供最大性能。
互连总线是具有可配置参数的硬件,可以根据从各种驱动程序收到的请求在数据路径上设置这些参数。互连总线的示例是芯片组中各个组件或功能块之间的互连。SoC 上可能存在多个互连,它们可以是多层的。
下面是真实世界 SoC 互连总线拓扑的简化图。
+----------------+ +----------------+
| HW Accelerator |--->| M NoC |<---------------+
+----------------+ +----------------+ |
| | +------------+
+-----+ +-------------+ V +------+ | |
| DDR | | +--------+ | PCIe | | |
+-----+ | | Slaves | +------+ | |
^ ^ | +--------+ | | C NoC |
| | V V | |
+------------------+ +------------------------+ | | +-----+
| |-->| |-->| |-->| CPU |
| |-->| |<--| | +-----+
| Mem NoC | | S NoC | +------------+
| |<--| |---------+ |
| |<--| |<------+ | | +--------+
+------------------+ +------------------------+ | | +-->| Slaves |
^ ^ ^ ^ ^ | | +--------+
| | | | | | V
+------+ | +-----+ +-----+ +---------+ +----------------+ +--------+
| CPUs | | | GPU | | DSP | | Masters |-->| P NoC |-->| Slaves |
+------+ | +-----+ +-----+ +---------+ +----------------+ +--------+
|
+-------+
| Modem |
+-------+
术语¶
互连提供程序是互连硬件的软件定义。上图中互连提供程序为 M NoC、S NoC、C NoC、P NoC 和 Mem NoC。
互连节点是互连硬件端口的软件定义。每个互连提供程序由多个互连节点组成,这些节点连接到其他 SoC 组件,包括其他互连提供程序。图中 CPU 连接到内存的点称为互连节点,属于 Mem NoC 互连提供程序。
互连端点是路径的第一个或最后一个元素。每个端点都是一个节点,但并非每个节点都是一个端点。
互连路径是两个端点之间的所有内容,包括为从源节点到达目标节点而必须遍历的所有节点。它可能包括跨多个互连提供程序的多个主从对。
互连消费者是利用提供程序公开的数据路径的实体。消费者向提供程序发送请求,要求各种吞吐量、延迟和优先级。通常,消费者是设备驱动程序,它们根据自身需要发送请求。消费者的一个示例是支持各种格式和图像大小的视频解码器。
互连提供程序¶
互连提供程序是实现初始化和配置互连总线硬件的方法的实体。互连提供程序驱动程序应向互连提供程序核心注册。
-
struct icc_node_data¶
icc 节点数据
定义:
struct icc_node_data {
struct icc_node *node;
u32 tag;
};
成员
节点
icc 节点
标签
标签
-
struct icc_onecell_data¶
单单元互连提供程序的驱动程序数据
定义:
struct icc_onecell_data {
unsigned int num_nodes;
struct icc_node *nodes[] ;
};
成员
num_nodes
此设备中的节点数
节点
指向此设备中节点的指针数组
-
struct icc_provider¶
可能提供多个互连控制的互连提供程序(控制器)实体
定义:
struct icc_provider {
struct list_head provider_list;
struct list_head nodes;
int (*set)(struct icc_node *src, struct icc_node *dst);
int (*aggregate)(struct icc_node *node, u32 tag, u32 avg_bw, u32 peak_bw, u32 *agg_avg, u32 *agg_peak);
void (*pre_aggregate)(struct icc_node *node);
int (*get_bw)(struct icc_node *node, u32 *avg, u32 *peak);
struct icc_node* (*xlate)(const struct of_phandle_args *spec, void *data);
struct icc_node_data* (*xlate_extended)(const struct of_phandle_args *spec, void *data);
struct device *dev;
int users;
bool inter_set;
void *data;
};
成员
provider_list
已注册互连提供程序的列表
节点
互连提供程序节点的内部列表
set
指向设备特定设置操作函数的指针
aggregate
指向设备特定聚合操作函数的指针
pre_aggregate
指向在聚合开始之前调用的设备特定函数的指针(可选)
get_bw
指向设备特定函数以获取当前带宽的指针
xlate
用于从 phandle 参数映射节点的提供程序特定回调
xlate_extended
用于从 phandle 参数映射节点数据的供应商特定回调
dev
此互连提供程序所属的设备
用户
活动用户数
inter_set
是否使用 set 配置提供程序间的配对
数据
指向私有数据的指针
-
struct icc_node¶
互连拓扑的一部分的实体
定义:
struct icc_node {
int id;
const char *name;
struct icc_node **links;
size_t num_links;
struct icc_provider *provider;
struct list_head node_list;
struct list_head search_list;
struct icc_node *reverse;
u8 is_traversed:1;
struct hlist_head req_list;
u32 avg_bw;
u32 peak_bw;
u32 init_avg;
u32 init_peak;
void *data;
};
成员
id
平台特定的节点 id
name
在 debugfs 中使用的节点名称
链接
指向在遍历时可以接下来前往的位置的目标列表
num_links
与其他互连节点的链接数
提供程序
指向此节点的互连提供程序
node_list
父提供程序的“节点”列表中的列表项
search_list
在遍历节点图时使用的列表
反向
遍历节点图时指向上一个节点的指针
is_traversed
在遍历节点图时使用的标志
req_list
与此节点关联的 QoS 约束请求的列表
avg_bw
来自所有消费者的平均带宽请求的聚合值
peak_bw
来自所有消费者的峰值带宽请求的聚合值
init_avg
在初始化期间从硬件读取的平均带宽值
init_peak
在初始化期间从硬件读取的峰值带宽值
数据
指向私有数据的指针
互连消费者¶
互连消费者是使用互连 API 获取端点之间的路径并设置这些互连路径的带宽/延迟/QoS 要求的客户端。这些接口目前没有文档记录。
互连 debugfs 接口¶
与几个其他子系统一样,互连将创建一些文件以用于调试和自省。debugfs 中的文件不被视为 ABI,因此应用程序软件不应依赖于内核版本之间格式细节的更改。
/sys/kernel/debug/interconnect/interconnect_summary
:
显示系统中所有互连节点及其聚合带宽请求。在每个节点下缩进显示来自每个设备的带宽请求。
/sys/kernel/debug/interconnect/interconnect_graph
:
以 graphviz dot 格式显示互连图。它显示系统中所有互连节点和链接,并将来自同一提供程序的节点分组为子图。该格式是人类可读的,也可以通过点管道生成许多图形格式的图表
$ cat /sys/kernel/debug/interconnect/interconnect_graph | \
dot -Tsvg > interconnect_graph.svg
test-client
目录提供了向任何任意路径发出 BW 请求的接口。请注意,出于安全原因,此功能默认情况下禁用,没有 Kconfig 来启用它。启用它需要修改 #define INTERCONNECT_ALLOW_WRITE_DEBUGFS
的代码。用法示例
cd /sys/kernel/debug/interconnect/test-client/
# Configure node endpoints for the path from CPU to DDR on
# qcom/sm8550.
echo chm_apps > src_node
echo ebi > dst_node
# Get path between src_node and dst_node. This is only
# necessary after updating the node endpoints.
echo 1 > get
# Set desired BW to 1GBps avg and 2GBps peak.
echo 1000000 > avg_bw
echo 2000000 > peak_bw
# Vote for avg_bw and peak_bw on the latest path from "get".
# Voting for multiple paths is possible by repeating this
# process for different nodes endpoints.
echo 1 > commit