完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
绝大多数的电子器件都是由时钟驱动其工作的。而SoC芯片或电路板中的时钟以树状结构呈现,按时钟域进行划分,按照不同的时钟需求进行管理。
出于功耗和数据传输时序控制等目的,在内核代码中对时钟进行统一注册、统一管理。kernel代码中很早就出现了时钟管理机制,甚至早于git版本管控之前。 1. 时钟定义 ARM处理器平台中基于dts描述时钟树,包括时钟结构、时钟属性等信息。由时钟框架驱动和设备驱动解析dts中时钟树信息,完成时钟系统的初始化、管理、使用。在设备树中定义了时钟的providers和consumers。前者代表时钟提供者,通常是一个固定的PLL,后者代表时钟使用者,例如处理器核心以及各种外部设备等。 1.1 Clock providers 1. #clock-cells 时钟提供者输出的时钟路数,当#clock-cells为0时,代表仅输出1路时钟,若大于等于1,则代表输出多路时钟,Clock consumers通过编号索引使用。 下面的时钟结点clock-cells为0,代表仅能够输出1路时钟,这里面只提供了一路24MHz的固定时钟。 xin24m: xin24m { compatible = "fixed-clock"; clock-frequency = <24000000>; clock-output-names = "xin24m"; #clock-cells = <0>; }; 下面的时钟结点中clock-cells为1,代表能够输出多路时钟,这里面我们可以看出它提供了两路时钟分别是PLL_PPLL和FCLK_CM0S_SRC_PMU,时钟频率分别是67.6MHz和97MHz。 pmucru: pmu-clock-controller@ff750000 { ... #clock-cells = <1>; #reset-cells = <1>; assigned-clocks = <&pmucru PLL_PPLL>, <&pmucru FCLK_CM0S_SRC_PMU>; assigned-clock-rates = <676000000>, <97000000>; }; 2. clock-output-names 顾名思义,它定义了输出时钟的名字。当clock consumers使用这路时钟的时候,我们可以见名知意。从下面的clock-output-names可以清楚的直到,这是外部晶振提供的24MHz时钟。 xin24m: xin24m { compatible = "fixed-clock"; clock-frequency = <24000000>; clock-output-names = "xin24m"; #clock-cells = <0>; }; 3. clock-indices 这并不是一个必选项,当然也不常见。当存在多路输出时钟时,clock consumer以index引用对应的时钟,默认不指定clock-indices且没有使用assigned-clocks时,index索引是线性增长的,像下面这样,ckil的index是0,而ckih的index就是1。 oscillator { #clock-cells = <1>; clock-output-names = "ckil", "ckih"; }; 当定义了clock-indices之后,index的值由clock-indices决定,像下面这样: oscillator { #clock-cells = <1>; clock-output-names = "ckil", "ckih"; }; 4. assigned-clocks 当输出多路时钟时,为没路输出时钟进行编号,以phandle+specifier组合进行管理,像下面这样: pmucru: pmu-clock-controller@ff750000 { ... assigned-clocks = <&pmucru PLL_PPLL>, <&pmucru FCLK_CM0S_SRC_PMU>; assigned-clock-rates = <676000000>, <97000000>; }; PLL_PPLL代表了specifier,其定义位于头文件include/dt-bindings/clock/rk3399-cru.h中。需要说明的是,这个头文件很重要,所有的specifier都可以在这里找到对应的宏。 5. assigned-clock-rates 这个定义是和assigned-clocks成对使用的。它代表了assigned-clocks所对应的时钟频率,例如PLL_PPLL所对应的时钟频率是67.6MHz。 pmucru: pmu-clock-controller@ff750000 { ... assigned-clocks = <&pmucru PLL_PPLL>, <&pmucru FCLK_CM0S_SRC_PMU>; assigned-clock-rates = <676000000>, <97000000>; }; 6. clock-frequency 当不使用assigned-clock-rates为输出时钟指定大小时,可以利用clock-frequency进行指定。像下面这样,指定了osc的时钟频率为32.678Khz。 osc: oscillator { compatible = "fixed-clock"; #clock-cells = <1>; clock-frequency = <32678>; clock-output-names = "osc"; }; 1.2 Clock consumers Clock consumers意为时钟使用者,通常是CPU核心部件或者其他外设。 我们以dsi为例说明Clock consumers设备树的组成。 vopb: vop@ff900000 { compatible = "rockchip,rk3399-vop-big"; reg = <0x0 0xff900000 0x0 0x600>, <0x0 0xff901c00 0x0 0x200>, <0x0 0xff902000 0x0 0x1000>; reg-names = "regs", "cabc_lut", "gamma_lut"; interrupts = clocks = <&cru ACLK_VOP0>, <&cru DCLK_VOP0>, <&cru HCLK_VOP0>, <&cru DCLK_VOP0_DIV>; clock-names = "aclk_vop", "dclk_vop", "hclk_vop", "dclk_source"; ... }; 1. clocks 它代表了设备的时钟源,通常以phandle+specifier组合进行引用。例如本例中,aclk_vop时钟使用的是cru模块提供的ACLK_VOP0,它的时钟频率在cru结点中定义,大小是400000000。 2. clock-names 这代表了Clock consumers中使用的时钟名字,方便设备驱动代码进行相应的时钟解析,例如: static int vop_bind(struct device *dev, struct device *master, void *data) { ... vop->aclk = devm_clk_get(vop->dev, "aclk_vop"); if (IS_ERR(vop->aclk)) { dev_err(vop->dev, "failed to get aclk sourcen"); return PTR_ERR(vop->aclk); } ... } 以上是ARM平台RK3399的软件时钟树定义方式,具体可查看rk3399.dtsi文件。除此之外,可参考如下内核文档做相关了解。
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
1924 浏览 1 评论
synopsys 的design ware:DW_fpv_div,浮点数除法器,默认32位下,想提升覆盖率(TMAX),如果用功能case去提升覆盖率呢?
2406 浏览 1 评论
RK3588 GStreamer调试四路鱼眼摄像头四宫格显示报错
5193 浏览 1 评论
【飞凌嵌入式OK3576-C开发板体验】RKNN神经网络-YOLO图像识别
254 浏览 0 评论
【飞凌嵌入式OK3576-C开发板体验】SSH远程登录网络配置及CAN通讯
1336 浏览 0 评论
浏览过的版块 |
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 18:38 , Processed in 0.519326 second(s), Total 71, Slave 54 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号