目录
1. 时钟系统说明
时钟就是SoC中的脉搏,由它来控制各个部件按各自的节奏跳动。比如CPU主频设置,串口的波特率设置,I2S的采样率设置,I2C的速率设置等等。这些不同的clock 设置,都需要从某个或某几个时钟源头而来,最终开枝散叶,形成一棵时钟树。
Linux的时钟子系统由CCF(common clock framework) 框架管理,CCF向上给其他使用时钟的 IP 提供了通用的时钟接口,向下给驱动开发者提供硬件操作的接口。
这个也是一个consumer、framework、provider的模式。
Provider是时钟的模块的具体实现者,系统开机时,需要通过驱动的时钟框架向系统注册不同的时钟,其他需要时钟的模块通过通用接口获取,使能,设置时钟。
Framework 是内核提供的一套通用时钟实现框架,包含了注册和使用的通用接口。
Consumer 是时钟模块的使用者,比如上面提到的 I2C 模块,Uart 模块的等等。
2. 时钟树
在SoC上的模块很多,为了适应不同模块的时钟要求,会形成一颗时钟树,如下所示:
(1)根节点一般是 Oscillator(有源振荡器)或者Crystal(无源振荡器),表示从芯片外部输入的基准时钟。
(2)包括PLL(锁相环,用于提升频率的)
(3)Divider(分频器,用于降频的)
(4)Mux(从多个clock path中选择一个)
(5)Gate(只能被控制ON/OFF的)。
时钟管理的目标,是支持针对特定时钟实现以下功能:
(1) enable/disable clock。
(2) 设置clock的频率。
(3) 选择clock的parent,例如hw3_clk可以选择osc_clk、pll2_clk或者pll3_clk作为输入源。
3. ccf
ccf(common clock framework)是uboot/kernel提供的系统clock管理框架,它将时钟的使用抽象为3个对象:
- provider - 提供时钟的模块
- consumer - 使用时钟的模块
- ccf - 管理时钟的框架
ccf实现以下功能:
(1) 向consumer提供操作clocks的通用API;
(2) 实现clock控制的通用逻辑(硬件无关);
(3) 向provider提供注册时钟的API,将特定的provider纳入ccf框架管理。
consumer和provider,都只跟ccf交互,互相看不到对方,唯一的交集是Device Tree的配置,consumer需要在dts中指定其依赖的具体时钟,而时钟ID由provider提供。
驱动要做的事情,是将特定Soc的硬件时钟树,转换成provider驱动,即实现硬件相关的时钟操作接口,将时钟树上的各个时钟注册到ccf,以方便consumer驱动使用。
根据不同时钟的特点,clock framework 将 clock 分为 Fixed rate、gate、Divider、Mux、Fixed factor、composite六类,这六类的含义如下:
Fixed Rate clock:
固定频率时钟,提供恒定的时钟信号,适用于需要固定频率的硬件,如PWM(脉宽调制)或定时器。
Gated clock:
门控时钟,只可以被开启或关闭,适用于可以被动态开启或者关闭的硬件,以节约电源
Divider clock:
分频时钟,可以将输入的时钟信号分频,产生一个较低频率的时钟信号,适用于需要降低时钟频率适应设备需要的设备
Muxed clock:
复用时钟,时钟信号可以选择不同的时钟源
Fixed factor clock:
固定系数时钟,可以将输入时钟信号乘以一个固定的系数,产生一个更高或者更低的时钟信号
Composite clock:
组合时钟,可以由多个时钟实体组成,每个时钟实体都有特定的功能,适用于复杂时钟控制策略的硬件,比如复杂时钟路径和时钟管理
Linux 下 cat /sys/kernel/debug/clk/clk_summary 可以查看当前 Soc 的时钟树。