linux clk驱动框架

转载 2017年11月14日 23:12:56

clk common framework(ccf)子系统,用来完成对clock的统一管理.
如今,可运行Linux的主流处理器平台,都有非常复杂的clock tree,我们随便拿一个处理器的spec,查看clock相关的章节,一定会有一个非常庞大和复杂的树状图,这个图由clock相关的器件,以及这些器件输出的clock组成。下图是一个示例:
这里写图片描述
clock相关的器件包括:用于产生clock的Oscillator(有源振荡器,也称作谐振荡器)或者Crystal(无源振荡器,也称晶振);用于倍频的PLL(锁相环,Phase Locked Loop);用于分频的divider;用于多路选择的Mux;用于clock enable控制的与门;使用clock的硬件模块(可称作consumer);等等.common clock framework的管理对象,就是上图蓝色字体描述的clock(在软件中用struct clk抽象,以后就简称clk),主要内容包括(不需要所有clk都支持):
1)enable/disable clk。
2)设置clk的频率。
3)选择clk的parent,例如hw3_clk可以选择osc_clk、pll2_clk或者pll3_clk作为输入源.

clk framework是内核中用来统一管理clock的子系统。代码存在于kernel/driver/clk目录中。 要使用clkframework来实现厂商自己平台上的clock驱动,首先需要在defconfig中使能如下的几个CONFIG来配置内核。
CONFIG_CLKDEV_LOOKUP=y
CONFIG_HAVE_CLK_PREPARE=y
CONFIG_COMMON_CLK=y
CONFIG_COMMON_CLK_DEBUG=y
如果配置了debug ,内核将生成相应的debugfs,在启动后将会挂载于/sys/kernel/debug目录下。
内核中clk framework 主要提供的功能有:

1. 向上提供给其他driver调用的接口API
2.  向下提供给clock driver注册的接口API
3.  debugfs创建
4.  若干个基于dts配置的通用clock模型(通过调用注册接口API)

这里写图片描述
上图中的黄色区域都是clk core所实现的功能,灰色区域是clock驱动开发需要做的事情,而绿色区域是其他device driver需要使用clock时要调用到的clk功能。

为其他设备驱动提供的接口(API)
struct clk *clk_get(struct device *dev, const char *id);
struct clk *devm_clk_get(struct device *dev, const char *id);
int clk_enable(struct clk *clk);
void clk_disable(struct clk *clk);
unsigned long clk_get_rate(struct clk *clk);
void clk_put(struct clk *clk);
long clk_round_rate(struct clk *clk, unsigned long rate);
int clk_set_rate(struct clk *clk, unsigned long rate);
int clk_set_parent(struct clk *clk, struct clk *parent);
struct clk *clk_get_parent(struct clk *clk);
int clk_prepare(struct clk *clk);
void clk_unprepare(struct clk *clk);
这些都是比较重要的api接口,主要是在device driver中调用来设置device的clk的。这部分的实现最终会调用到clk_ops中的回调函数来设置硬件并且会更新core中的clk链表.作为一个clk设备,它有可能会改变rate,那么作为device driver的一方需要获取到这个改变,并作出相应的响应,那么就可以通过通知功能的接口来实现,我们可以在感兴趣的clk上注册notifier_block,然后当该clk的rate发生了改变的时候会通过__clk_notify,通知到相应的回调函数,来做相应的处理。
int clk_notifier_register(struct clk *clk, struct notifier_block *nb);
int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb);

clk 设备驱动
1.几个重要的结构体,具体的结构可以参看内核源码。
clk_hw,clk_init_data ,clk_ops
clk
clk_hw结构体可以看到其中封装了一个clk_ops结构体,它是一个clk驱动需要实现的关键结构,厂商需要实现此结构体,并把它注册到clk framework。clk_hw是联系clk_ops和struct clk的纽带。它一般会被封装到一个厂商自己定义的更大的结构体中,主要是用来建立与struct clk的联系。
clk主要是用来抽象clk硬件的差异,并完成一些通用操作的封装。其中的hw成员变量是与之关联的clk_hw结构。

相关文章推荐

linux CLK时钟驱动

前述:本篇linux时钟驱动以UART6串口为例。 一、时钟设备寄存器配置 1. UART6有两种时钟源选择APLL\UPLL(可通过技术手册查看),如图 clk[uart6_aplldiv...

android2.3.4----5.ov9650驱动分析--附clk设置

一. V4L2的模块的初始化过程 module_init(videodev_init) –> videodev_init 在drivers/media/video/v4l2-dev.c中...

MC9S12XS128硬件底层驱动_set_bus_clk.c(总线时钟设置实现)

MC9S12XS128,设置总线时钟频率实现部分。
  • lxiongh
  • lxiongh
  • 2011年04月26日 19:49
  • 1710

Linux时钟管理clk

硬件资源越来越庞大和复杂,内核的另一个挑战就是要便捷的管理这些资源。同时,面对如此之多的平台不同的CPU,管理机制需要统一适用,这就需要对资源的管理抽象到更加通用的层次。CPU中各个模块都需要时钟驱动...

Linux clk 模型

Linux clk 模型   Linux clk模型采用面向对象的思想来设计实现的。 在porting层创建一个一个的clk节点对象,然后将所有的clk节点对象连成一个list。 当驱动层需要...

linux-2.2.12内核之clk_get()函数浅析

clk_get(NULL,"adc")可以获得adc时钟,每一个外设都有自己的工作频率, PRSCVL是A/D转换器时钟的预分频功能时A/D时钟的计算公式 A/D时钟  = PCLK / (PRS...

HDMI 接口在 Linux驱动框架解析

  • 2015年07月13日 18:26
  • 874KB
  • 下载

linux驱动 SPI源码框架分析

  • 2016年03月09日 16:29
  • 209KB
  • 下载

Linux内核usb驱动框架——U盘挂载

这个十一,除了写说明书和整理代码等常规任务外,唯一有点意思的就是写个usb驱动了。 根据师兄的建议,下载了2.6.32的内核源码,在/usr/src/linux-2.6.32.27/drivers/...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux clk驱动框架
举报原因:
原因补充:

(最多只允许输入30个字)