Clock
芯片名称 | 内核版本 |
---|---|
RK303X | LINUX4.4 & 4.19 & 5.10 |
RK312X | LINUX4.4 & 4.19 & 5.10 |
RK322X | LINUX4.4 & 4.19 & 5.10 |
RK3288X | LINUX4.4 & 4.19 & 5.10 |
RK3328 | LINUX4.4 & 4.19 & 5.10 |
RK3368 | LINUX4.4 & 4.19 & 5.10 |
RK3399 | LINUX4.4 & 4.19 & 5.10 |
RV1108 | LINUX4.4 & 4.19 & 5.10 |
PX30 | LINUX4.4 & 4.19 & 5.10 |
RV1126 | LINUX4.19 & 5.10 |
RK356X | LINUX4.19 & 5.10 |
RK3588 | LINUX5.10 |
RK3576 | LINUX6.1 |
RV1103B | LINUX5.10 |
RK3506 | LINUX6.1 |
前言
本文档主要介绍 RK 平台时钟子系统框架介绍以及配置。
读者对象
本文档(本指南)主要适用于以下工程师:
- 技术支持工程师
- 软件开发工程师
1. 方案概述
1.1 概述
本章主要描 述时钟子系统相关的重要概念、时钟方案、总体流程、代码结构。
1.2 重要概念
时钟子系统
这里讲的时钟是给 SOC 各组件提供时钟的树状框架,并不是内核使用的时间,和其他模块一样,CLOCK 也有框架,用于适配不同的平台。适配层之上是客户代码和接口,也就是各模块(如需要时钟信号的外设,USB 等)的驱动。适配层之下是具体的 SOC 级的时钟操作细节。
时钟树结构
可运行 LINUX 的主流处理器平台,都有非常复杂的 CLOCK TREE,我们随便拿一个处理器的 SPEC,查看 CLOCK 相关的章节,一定会有非常庞大和复杂的树状图,这个图由 CLOCK 相关的器件,以及这些器件输出的 CLOCK 组成。
相关器件
CLOCK 相关的器件包括:用于产生 CLOCK 的 Oscillator(有源振荡器,也称作谐振荡器)或者 Crystal(无源振荡器,也称晶振);用于倍频的 PLL(锁相环,Phase Locked Loop);用于分频的 Divider;用于多路选择的 MUX;用于 CLOCK ENABLE 控制的与门;使用 CLOCK 的硬件模块(可称作 CONSUMER);等等。
1.3 时钟方案
每一个 SOC 都有自己的时钟分配方案,主要是包括 PLL 的设置,各个 CLOCK 的父属性、DIV、MUX 等。芯片不同,时钟方案是有差异的。
图表 1‑1 时钟树的示例图
项目 | 功能 | 路径 |
---|---|---|
clk | rk3xxx.c 中主要是 CLOCK 的寄存器描述、CLOCK 之间的树状关系描述等 | drivers/clk/rockchip/clk-rk3xxx.c |
rk3xxx.c | .h 中是 CLOCK 的 ID 定义,通过 ID 匹配 CLOCK Name | include/dt-bindings/clock/rk3xxx-cru.h |
RK 特别的处理 | 处理 RK 的 PLL 时钟,处理 RK 的一些特殊时钟如 LCDC、I2S 等 | drivers/clk/rockchip/clk-xxx.c |
CLK API | 提供 Linux 环境下供 Driver 调用的接口 | drivers/clk/clk-xxx.x |
1.4 总体流程
图表 1‑2 时钟配置流程图
主要内容包括(不需要所有 CLOCK 都支持):
- Enable/Disable CLOCK。
- 设置 CLOCK 的频率。
- 选择 CLOCK 的 Parent。
1.5 代码结构
图表 1‑3 CLOCK代码构成
项目 | 功能 | 路径 |
---|---|---|
clk-rk3xxx.c | .c中主要是CLOCK的寄存器描述、CLOCK之间的树状关系描述等 | drivers/clk/rockchip/clk-rk3xxx.c |
rk3xxx-cru.h | .h中是CLOCK的ID定义,通过ID匹配CLOCK Name | include/dt-bindings/clock/rk3xxx-cru.h include/dt-bindings/clock/rockchip,rk3xxx-cru.h |
RK 特别的处理 | 处理RK的PLL时钟,处理RK的一些特殊时钟如LCDC、I2S等 | drivers/clk/rockchip/clk-xxx.c |
CLK API | 提供Linux环境下供Driver调用的接口 | drivers/clk/clk-xxx.x |
CLOCK 的软件框架由 CLOCK 的 Device Tree(CLOCK 的寄存器描述、CLOCK 之间的树状关系等)、Device driver 的 CLOCK 配置和 CLOCK API 三部分构成。这三部分的功能、CLOCK 代码路径如表 1-1 所示。
2. CLOCK 开发指南
2.1 概述
本章描述如何修改时钟配置、使用 API 接口及调试 CLOCK 程序。
2.2 时钟的相关概念
2.2.1 PLL
锁相环,是由 24M 的晶振输入,然后内部锁相环锁出相应的频率。这是 SOC 所有 CLOCK 的时钟的源。SOC 的所有总线及设备的时钟都是从 PLL 分频下来的。RK 平台主要 PLL 有:
图表 2‑1 PLL描述
PLL | 子设备 | 用途 | 备注 |
---|---|---|---|
APLL | CLOCK_CORE | CPU 的时钟 | 一般只给 CPU 使用,因为 CPU 会变频,APLL 会根据 CPU 要求的频率变化 |
DPLL | CLOCK_DDR | DDR 的时钟 | 一般只给 DDR 使用,因为 DDR 会变频,DPLL 会根据 DDR 要求变化 |
GPLL | 提供总线、外设时钟做备份 | 一般设置在 594M 或者 1200M,保证基本的 100、200、300、400M 的时钟都有输出 | |
CPLL | GMAC 或者其他设备做备份 | 一般可能是 400、500、800、1000M。或者是给 Lcdc 独占使用 | |
NPLL | 给其他设备做备份 | 一般可能是 1188M,或者给 Lcdc 独占使用 |
2.2.2 总线
我们 SOC 的总线有 ACLK_PERI、HCLK_PERI、PCLK_PERI、ACLK_BUS、HCLK_BUS、PCLK_BUS.(ACLK 用于数据传输,PCLK 跟 HCLK 一般是用于寄存器读写)
而区分 BUS 跟 PERI 主要是为了做高速和低速总线的区分,ACLK 范围 100-300M,PCLK 范围 50M150M,HCLK 范围 37M150M。BUS 下面主要是一些低速的设备,如 I2C、I2S、SPI 等,PERI 下面一般是 EMMC、GMAC、USB 等。不同的芯片在设计时会有一些差异。例如:对于某些对总线速度要求较高时,可能单独给此设备设计一个独立的 ACLK(如 ACLK_EMMC 或者 ACLK_USB 等)。
各个设备的总线时钟会挂在上面这些时钟下面,如下图结构:
图表 2‑2 总线时钟结构
备注:
RK3399上设计将高速和低速总线彻底分开,分成高速:ACLK_PERIHP、HCLK_PERIHP、PCLK_PERIHP;低速:ACLK_PERILP0、HCLK_PERILP0、PCLK_PERILP0、HCLK_PERILP1、PCLK_PERILP1。这样做是为了功耗最优,根据不同的需求可以设置不同的总线频率。(具体每个设备在哪条总线下详细见时钟图)
可以参考(EMMC、GMAC、USB等有自己的ACLK)。
2.2.3 GATING
CLOCK 的框架中有很多的 GATING,主要是为了降低功耗使用,在一些设备关闭,CLOCK 不需要维持的时候,可以关闭 GATING,节省功耗。
RK CLOCK 的框架的 GATING 是按照树的结构,有父子属性。GATING 的开关有一个引用计数机制,使用这个计数来实现 CLOCK 打开时,会遍历打开其父 CLOCK。在子 CLOCK 关闭时,父 CLOCK 会遍历所有的子 CLOCK,在所有的子都关闭的时候才会关闭父 CLOCK。
(如:I2S2 在使用的时候,必须要打开图中三个 GATING(如图 2-2),但是软件上只需要开最后一级的 GATING,时钟结构会自动的打开其 parent 的 GATING)
图表 2‑3 GATING示例图