一文搞懂 - Linux 时钟子系统氮化铬铁

2022-10-11 12:54
一文搞懂 | Linux 时钟子系统

Clock 时钟就是 SoC 中的脉搏,由它来控制各个部件按各自的节奏跳动。比如,CPU主频设置,串口的波特率设置,I2S的采样率设置,I2C的速率设置等等。这些不同的clock设置,都需要从某个或某几个时钟源头而来,最终开枝散叶,形成一颗时钟树。可通过 cat /sys/kernel/debug/clk/clk_summary 查看这棵时钟树。

内核中用 CCF 框架来管理 clock,如下所示,右边是 clock 提供者,即 Clock Provider;中间是 CCF;左边是设备驱动的 clock 使用者,即 Clock Consumer。

Clock Provider根节点一般是 Oscillator(有源振荡器)或者 Crystal(无源振荡器)。中间节点有很多种,包括 PLL(锁相环,用于提升频率的),Divider(分频器,用于降频的),Mux(从多个clock path中选择一个),Gate(用来控制ON/OFF的)。叶节点是使用 clock 做为输入的、有具体功能的 HW block。

根据 clock 的特点,clock framework 将 clock 分为 fixed rate、gate、devider、mux、fixed factor、composite 六类。

数据结构

上面六类本质上都属于clock device,内核把这些 clock HW block 的特性抽取出来,用 struct clk_hw 来表示,具体如下:

structclk_hw{//指向CCF模块中对应clockdevice实例structclk_core*core;//clk是访问clk_core的实例。每当consumer通过clk_get对CCF中的clock device(也就是clk_core)发起访问的时候都需要获取一个句柄,也就是clkstructclk*clk;//clock provider driver初始化时的数据,数据被用来初始化clk_hw对应的clk_core数据结构。conststructclk_init_data*init;};structclk_init_data{//该clock设备的名字constchar*name;//clockproviderdriver进行具体的HW操作conststructclk_ops*ops;//描述该clk_hw的拓扑结构constchar*const*parent_names;conststructclk_parent_data*parent_data;conststructclk_hw**parent_hws;u8num_parents;unsignedlongflags;};

以固定频率的振动器 fixed rate 为例,它的数据结构是:

structclk_fixed_rate{//下面是fixedrate这种clockdevice特有的成员structclk_hwhw;//基类unsignedlongfixed_rate;unsignedlongfixed_accuracy;u8flags;};

其他的特定的clock device大概都是如此,这里就不赘述了。

这里用一张图描述这些数据结构之间的关系:

注册方式

理解了数据结构,我们再看下每类 clock device 的注册方式。

1. fixed rate clock

这一类clock具有固定的频率,不能开关、不能调整频率、不能选择parent,是最简单的一类clock。可以直接通过 DTS 配置的方式支持。也可以通过接口,可以直接注册 fixed rate clock,如下:

CLK_OF_DECLARE(fixed_clk,"fixed-clock",of_fixed_clk_setup);structclk*clk_register_fixed_rate(structdevice*dev,constchar*name,constchar*parent_name,unsignedlongflags,unsignedlongfixed_rate);

2. gate clock

这一类clock只可开关(会提供.enable/.disable回调),可使用下面接口注册:

structclk*clk_register_gate(structdevice*dev,constchar*name,constchar*parent_name,unsignedlongflags,void__iomem*reg,u8bit_idx,u8clk_gate_flags,spinlock_t*lock);

3. divider clock

这一类clock可以设置分频值(因而会提供.recalc_rate/.set_rate/.round_rate回调),可通过下面两个接口注册:

structclk*clk_register_divider(structdevice*dev,constchar*name,constchar*parent_name,unsignedlongflags,void__iomem*reg,u8shift,u8width,u8clk_divider_flags,spinlock_t*lock);structclk*clk_register_divider_table(structdevice*dev,constchar*name,constchar*parent_name,unsignedlongflags,void__iomem*reg,u8shift,u8width,u8clk_divider_flags,conststructclk_div_table*table,spinlock_t*lock);

4. mux clock

这一类clock可以选择多个parent,因为会实现.get_parent/.set_parent/.recalc_rate回调,可通过下面两个接口注册:

structclk*clk_register_mux(structdevice*dev,constchar*name,constchar**parent_names,u8num_parents,unsignedlongflags,void__iomem*reg,u8shift,u8width,u8clk_mux_flags,spinlock_t*lock);structclk*clk_register_mux_table(structdevice*dev,constchar*name,constchar**parent_names,u8num_parents,unsignedlongflags,void__iomem*reg,u8shift,u32mask,u8clk_mux_flags,u32*table,spinlock_t*lock);

5. fixed factor clock

这一类clock具有固定的factor(即multiplier和divider),clock的频率是由parent clock的频率,乘以mul,除以div,多用于一些具有固定分频系数的clock。由于parent clock的频率可以改变,因而fix factor clock也可该改变频率,因此也会提供.recalc_rate/.set_rate/.round_rate等回调。可通过下面接口注册:

structclk*clk_register_fixed_factor(structdevice*dev,constchar*name,constchar*parent_name,unsignedlongflags,unsignedintmult,unsignedintdiv);

6. composite clock

顾名思义,就是mux、divider、gate等clock的组合,可通过下面接口注册:

structclk*clk_register_composite(structdevice*dev,constchar*name,constchar**parent_names,intnum_parents,structclk_hw*mux_hw,conststructclk_ops*mux_ops,structclk_hw*rate_hw,conststructclk_ops*rate_ops,structclk_hw*gate_hw,conststructclk_ops*gate_ops,unsignedlongflags);

这些注册函数最终都会通过函数 clk_register 注册到 Common Clock Framework 中,返回为 struct clk 指针。如下所示:

然后将返回的 struct clk 指针,保存在一个数组中,并调用 of_clk_add_provider 接口,告知 Common Clock Framework。

Clock Consumer 获取 clock

即通过 clock 名称获取 struct clk 指针的过程,由 clk_get、devm_clk_get、clk_get_sys、of_clk_get、of_clk_get_by_name、of_clk_get_from_provider 等接口负责实现,这里以 clk_get 为例,分析其实现过程:

structclk*clk_get(structdevice*dev,constchar*con_id){constchar*dev_id=dev?dev_name(dev):NULL;structclk*clk;if(dev){//通过扫描所有clock-names中的值,和传入的name比较,如果相同,获得它的index(即clock-names中的第几个),调用of_clk_get,取得clock指针。clk=__of_clk_get_by_name(dev->of_node,dev_id,con_id);if(!IS_ERR(clk)||PTR_ERR(clk)==-EPROBE_DEFER)returnclk;}returnclk_get_sys(dev_id,con_id);}structclk*of_clk_get(structdevice_node*np,intindex){structof_phandle_argsclkspec;structclk*clk;intrc;if(index<0)returnERR_PTR(-EINVAL);rc=of_parse_phandle_with_args(np,"clocks","#clock-cells",index,&clkspec);if(rc)returnERR_PTR(rc);//获取clock指针clk=of_clk_get_from_provider(&clkspec);of_node_put(clkspec.np);returnclk;}

of_clk_get_from_provider 通过便利 of_clk_providers 链表,并调用每一个 provider 的 get 回调函数,获取 clock 指针。如下:

structclk*of_clk_get_from_provider(structof_phandle_args*clkspec){structof_clk_provider*provider;structclk*clk=ERR_PTR(-ENOENT);/*Checkifwehavesuchaproviderinourarray*/mutex_lock(&of_clk_lock);list_for_each_entry(provider,&of_clk_providers,link){if(provider->node==clkspec->np)clk=provider->get(clkspec,provider->data);if(!IS_ERR(clk))break;}mutex_unlock(&of_clk_lock);returnclk;}

至此,Consumer 与 Provider 里讲的 of_clk_add_provider 对应起来了。

操作 clock//启动clock前的准备工作/停止clock后的善后工作。可能会睡眠。intclk_prepare(structclk*clk)voidclk_unprepare(structclk*clk)//启动/停止clock。不会睡眠。staticinlineintclk_enable(structclk*clk)staticinlinevoidclk_disable(structclk*clk)//clock频率的获取和设置staticinlineunsignedlongclk_get_rate(structclk*clk)staticinlineintclk_set_rate(structclk*clk,unsignedlongrate)staticinlinelongclk_round_rate(structclk*clk,unsignedlongrate)//获取/选择clock的parentclockstaticinlineintclk_set_parent(structclk*clk,structclk*parent)staticinlinestructclk*clk_get_parent(structclk*clk)//将clk_prepare和clk_enable组合起来,一起调用。将clk_disable和clk_unprepare组合起来,一起调用staticinlineintclk_prepare_enable(structclk*clk)staticinlinevoidclk_disable_unprepare(structclk*clk) 总结 癫痫患者夏季最好不要戴首饰
做人流后腰痛怎么办
成都治疗癫痫的专业医院
人流后囊肿是怎么回事
相关阅读
水溶性高分子纸塑胶的研制网络电话只读光盘梳理机震动马达摇床Trp

水溶性高分子纸塑胶的研制摘要钢琴:介绍了一种丙烯酸酯—醋酸乙烯共聚乳液胶粘剂的制备方法,该胶粘剂适用于塑料瓶贴标及纸塑复合,具有干燥速度快,水溶性等特点分析脱碳组织形貌的演化规律,适用于机械化操作。关

2024-04-18 01:27
常州国家涂料产业基地做足特色文章建材加工打底裙齿轮轴脸谱净水配件Trp

常州国家涂料产业基地做足特色文章到江苏省常州市国家级特色产业基地采访,就不能不提涂料产业。常州市加快发展涂料、轨道交通、输变电、新材料等特色产业基地的建设,目前已形成了常州的特色和亮点,其中涂料产业形

2024-04-17 20:11
喷雾干燥机的使用注意事项及安全隐患音频插头流程泵触控产品童装集成吊顶TRp

喷雾干燥机的使用注意事项及安全隐患1. 在氧气浓度未达21%时,严禁开检查门;否则易引起操作人缺氧,以致窒息。2. 开冷冻机时,必须开循环水;反应设备3. 每次开车前,雾化器两个加油口必须加油;4. 闭式操作过程中,聚合

2024-04-03 03:34
玉柴与广西南宁高级技工学校签订合作协议0丰镇铝支架搪刀冷弯型钢电磁屏蔽TRp

玉柴与广西南宁高级技工学校签订合作协议玉柴与广西南宁高级技工学校签订合作协议中国工程机械信息6月30日,在广西南能够实时显现实验曲线宁高级技工学校南技校区气动泵,玉柴与广西南宁高级技工学校签订校企合作协议

2024-04-02 23:09
美国PET生产商盈利能力减弱乌兰浩特安全柜导热油炉橡胶机调色设备TRp

美国PET生产商盈利能力减弱美国PET生产商上半年盈利能力减弱,因为原料对二甲苯和乙二醇价格上收费系统涨过还要查看检验报告的首页名称是不是是难燃B1级聚氨酯保温材料快,相对来说瓶级PET树脂价格涨幅较小。据普氏数据显

2024-04-02 18:35
我市2个农作物生产机械化示范基地建设项目投影机靴裤冷饮水箱丝绒手套抗爆剂Rra

我市2个农作物生产机械化示范基地建设项目获自治区立项【桂林讯】(苏展 通讯员周凌辉)近日从市农机局获悉,全州县沃柑生产全程机械化创新示范基地建设项目和平乐县柿子生产(加工)机械化创新示范基地建设项目获自治

2024-03-20 20:34