- 时钟系统结构
rockchip的时钟系统代码位于drivers/clk/rockchip,目录整体结构如下:
从上面的文件结构中我们可以看到,rockchip的时钟系统基本包含了CCF框架提到的时钟使能、复用、分频、倍频等功能。RK3399的时钟系统主体是clk-rk3399.c这个文件。
- 初始化方式
kernel中的时钟初始化代码位于驱动初始化这个层面,相较于CPU初始化而言,它是比较靠后的。在此之前,CPU及基本外设的工作时钟,由bootrom或者U-Boot及其他bootloader配置,有的CPU在时钟系统完全工作之前是工作于低频模式,而有的CPU则上电解复位之后便工作于高频模式,不可一概而论。
说到kernel中的时钟系统初始化,就不得不提CLK_OF_DECLARE这个宏定义,在时钟驱动中通过它来声明初始化函数,其实现原理如下图所示:
- RK3399时钟系统实现
rockchip为全系列芯片提供了统一的时钟初始化API,这一点非常值得我们借鉴同时也是很好的一种代码架构模式。RK3399的时钟初始化涉及两部分内容,分别是cru和pmu,二者原理相通,本文以cru初始化为例。具体包括:
上图中涉及到的CCF文件在前文已经描述过。
3.1 核心初始化
RK3399基于数据结构rockchip_clk_provider描述整体的时钟结构,以此代表clock provider。
在设备树rk3399.dtsi文件中以grf: syscon@ff770000和pmugrf: syscon@ff320000定义了grf和pmugrf,包含了时钟控制相关的寄存器。
通过rockchip_clk_init()例化数据结构struct rockchip_clk_provider:
3.2 PLL初始化
RK3399芯片内部包含了8个PLL,分别是LPLL, BPLL, CPLL, GPLL, NPLL, VPLL, VPLL, PPLL,如下图所示:
在代码中使用数据结构struct rockchip_pll_clock描述RK3399的PLL:
PLL的配置在程序中进行固化,如下:
通过rockchip_clk_register_pll()函数初始化PLL,主要是例化数据结构struct rockchip_clk_pll并完成时钟的注册,重点包含如下几个方面:
上面的rockchip_rk3399_pll_clk_ops数据结构包含了PLL一系列的控制函数,如:
3.2 复用/分频/GATE
这部分的初始化内容不限于标题所述,只是这3部分内容更为重要而已。
在代码中通过数据结构rockchip_clk_branch描述RK3399时钟系统的控制功能,如下:
其相关配置在程序中固化,基本涵盖了cru时钟单元的所有输出时钟控制信息。
通过函数rockchip_clk_register_branches()完成进行各功能的例化并完成时钟注册。
3.3 其他时钟控制项
- Tips 1
以上所有的时钟完成注册后,会将时钟信息更新进RK3399的时钟信息表,如下:
- Tips 2
若希望上电之后某些时钟常开,可以配置数据结构rk3399_cru_critical_clocks,例如:
Tips 3
打印RK3399的时钟树(信息很多),可以查看当前环境下所有的时钟信息,例如:
原作者:linux与soc
|