Linux clk 模型

Linux CLK驱动笔记 clk_register首先初始化clk_ops,clk_core_populate_parent_map初这个函数主要是根据parent_num申请了clk_parent_map,则将parent_names[i]字符串赋值给了clk_parent_map的name。clk的parent是在__clk_init_parent的时候被填充的,没有全部填充,先执行get_parent获取index,然后执行clk_core_fill_parent_index填充当前的parent。 阅读详情

Linux clk 模型

 

Linux clk模型采用面向对象的思想来设计实现的。

在porting层创建一个一个的clk节点对象,然后将所有的clk节点对象连成一个list。

当驱动层需要设置时钟的时候,通过porting层与驱动层直接的api函数进行操作。首先通过clk_get函数,根据clk节点的名字,获取clk节点。然后,使用clk_set_rate()函数设置clk节点的时钟。clk_set_rate() 函数最终将会调用clk节点对象的成员函数 clk->set_rate() 设置时钟。

层次关系如下图所示:


1. 驱动层与porting层之间的api

驱动层与porting层之间的api,定义在include/linux/clk.h文件中

       

        // clk的结构体,空的,

// 正真的实现在arch\arm\plat-vc088x\include\plat\clock.h

struct clk;

       

        // 根据name获得注册过的clk

struct clk *clk_get(struct device *dev, constchar *id);   

 

// 释放clk

void clk_put(struct clk *clk);

 

//打开和关闭clk

int clk_enable(struct clk *clk);

void clk_disable(struct clk *clk);

 

// 设置clk的频率,获得clk的频率

int clk_set_rate(struct clk *clk, unsignedlong rate);

long clk_round_rate(struct clk *clk, unsignedlong rate); //无法设置精确clk

unsigned long clk_get_rate(struct clk*clk);

 

// 设置clk的parent,获取clk的parent

int clk_set_parent(struct clk *clk, structclk *parent);

struct clk *clk_get_parent(struct clk*clk);

 

 

clk结构体,在arch\arm\plat-vc088x\include\plat\clock.h实现。

 

其它函数,在arch\arm\plat-vc088x\ clock.c 中实现,供驱动层模块调用。

 

2. clk porting层

2.1 clk porting 层包含3个文件

clk porting 层主要包括3个文件:

arch\arm\plat-vc088x\include\plat\clock.h  // clk结构体的实现

arch\arm\plat-vc088x\clock.c   // 驱动层与porting层之间的api的实现

arch\arm\mach-vc0882\clock-vortex.c // 建立clk 节点链表

 

2.2 clk的描述

在arch\arm\mach-vc0882\clock-vortex.c文件中定义了下面这个数组:

      static struct clk* sys_clks[];

 

这个数组使用struct clk结构体描述了所有的时钟节点。

                    

                     clk节点的数据结构,采用面向对象的思想。

 

                     下面以snr为例,介绍如何描述clk节点的。

static struct clk snr_clk = {

       .name  = "snr_clk", // 驱动层通过clk_get函数获取clk使用

       .flags = CLK_FLAG_DIV |CLK_FLAG_GATE | RECALC_ON_ENABLE,

       .parent = &XCLK,

       .max_dividor = 64,

       .private_data =&snr_clkdata,

       .enable = v8clk_clear_gatebit, // clk_enable 最终的实现代码 

       .disable = v8clk_set_gatebit, // clk_ disable 最终的实现代码

       .recalc =vc88x_clk_recalc,

       .set_rate = v8clk_setrate,// clk_ set_rate 最终的实现代码

       .init = vc88x_clk_init,

};

static struct clk_data snr_clkdata = {

       .clk_cfg_reg =V8REG_CLKRST_CIF_MCLK_CFG,

       .cfg_data =&snr_clkcfg,

       .cfg_mask = 0x3F00,

       .pfnCfg =div_calculator,

       .pfnRate = div_parser,

 

       .clk_ctrl_reg =V8REG_CLKRST_CIF_MCLK_CTRL,

       .gate_bit =(1<<1),

};

 

struct clk_data 这个结构体,用来保存clk节点的寄存器以及相关的bit信息的。这些成员变量在clk_set_rate、clk_enable、clk_ disable等api中被使用的。比较重要的,有如下成员变量:

clk_ctrl_reg

gate_bit

bypass_bit

clk_status_reg

clk_sw_rst_reg

clk_cfg_reg

div_max

div_min

div_shift

                       

2.3 clk的注册以及初始化过程

              1.建立clk 节点list

              2.初始化所有clk

 

在时钟初始化的过程中,通过clk_register函数,将sys_clks数组中所有的时钟节点,都注册到一个list中。函数调用过程如下:

->init_machine()(vortex_init ())

                  -> vc088x_register_baseclocks ()

                     -> clk_register ()

                                   ->list_add () // 建立clk 节点list

->clk->init(clk); // 这个时候会初始化clk

       -> clk->set_rate()

 

3. 驱动程序如何使用clk模型的api

根据clk节点的name,通过clk_get 获取时钟节点。

 

clk1 = clk_get(&dev, " snr_clk");

clk2 = clk_get(&dev, " dpi_pixel_clk ");

clk3 = clk_get(&dev, " cvbs_pixel_clk ");

clk4= clk_get(&dev, " vdac_pixel_clk ");

……

 

然后,就可以通过驱动层与porting层之间的api来设置各个时钟节点。

 

clk_disable(clk1);

 

clk_set_rate(clk2, 24*1000000);

 

clk_enable(clk3);

 

4. cpu切频如何使用clk模型的api

       cpu切频驱动程序包括以下几个文件:

drivers\cpufreq\

cpufreq.c 

cpufreq_conservative.c     // 按次序切频

cpufreq_ondemand.c        // 按命令切频

cpufreq_performance.c     // 最高频率

cpufreq_powersave.c        // 最低频率

cpufreq_stats.c

cpufreq_userspace.c

freq_table.c

 

       cpu切频 porting 层包括以下几个文件:

arch\arm\plat-vc088x\cpu.c      // structcpufreq_driver 结构体

       

其中,cpufreq_driver 结构体的成员函数,基于linux clk 模型的驱动层和porting层的api来实现的。

static struct cpufreq_driver v8_driver = {

       .flags             = CPUFREQ_STICKY,

       .verify            = v8_verify_speed,

       .target            = v8_target,    // 切频最终调用的函数

       .get         = v8_getspeed,

       .init        = v8_cpu_init,

       .exit        = v8_cpu_exit,

       .name             = "v8cpu",

       .attr        = v8_cpufreq_attr,

};

 

 

v8_driver .target->

       v8_target()

clk_set_rate(cpu_clk, freqs.new * 1000);

 

v8_driver .get->

       v8_getspeed()

rate = clk_get_rate(cpu_clk) / 1000;


S3C6410 clk_get_rate获取系统时钟 通过clk_get_rate(), 和 clk_get ();函数获取系统的时钟频率 先看一下函数的定义 struct clk *clk_get(struct device *dev, const char *id); struct clk { struct list_head list; struct module *owner; struct clk 阅读详情

相关推荐

深入解析Linux时钟管理:从devm_clk_get到clk_prepare_enable的实战指南

本文深入解析Linux内核时钟管理框架,详细介绍了从使用devm_clk_get获取时钟资源,到通过clk_prepare_enable进行安全使能的完整流程。文章结合实战案例,阐述了时钟API的设计哲学、引用计数机制、常见调试技巧及错误处理方法,旨在帮助驱动开发者编写稳定高效的Linux设备驱动。

weixin_29227585的博客 77

Exynos4412的Linux5.4.174时钟驱动开发(四)——clk API的调用方法

基于CCF,时钟使用者(clock consumer)对应于clk API;时钟生产者(clock provider)对应于底层时钟硬件驱动。介绍了clock provider如何构建clk_hw结构体,clock consumer如何构建clk结构体。分析了clk API是如何与底层时钟硬件驱动对应一致的。最后,举例说明了clk API的调用方法。

weixin_42408707的博客 1339

Linux时钟子系统:CCF框架与驱动开发实践

时钟管理是嵌入式系统开发的核心基础技术之一,它通过精确的时序控制确保硬件协同工作。Linux内核采用CCF(Common Clock Framework)框架统一管理时钟资源,该框架采用Provider-CCF-Consumer三层架构设计,实现了硬件无关的时钟操作接口。在驱动开发中,开发者通过clk_set_rate等标准API即可完成时钟配置,无需关心底层硬件差异。时钟子系统广泛应用于CPU主频调节、外设工作时钟控制等场景,其稳定性和性能直接影响系统整体表现。通过分析clk_core等关键数据结构和cl

weixin_28729843的博客 342

linux下基于vc088x开发板分析CLK模型(时钟管理)

Linux clk 模型 &nbsp; Linux clk模型采用面向对象的思想来设计实现的。 在porting层创建一个一个的clk节点对象,然后将所有的clk节点对象连成一个list。 当驱动层需要设置时钟的时候,通过porting层与驱动层直接的api函数进行操作。首先通过clk_get函数,根据clk节点的名字,获取clk节点。然...

qq_40788950的博客 741

【linux kernel】一文总结linux的clk框架

本文浅析linux的clk框架

iriczhao的博客 2136

linux时钟子系统3-各种时钟函数的分析

前言 在前一篇的刚开始引用了一个经典的clk设定的例子,然后大篇幅的详细的讲解了 clk_register的过程,接下来我们将继续讲解这个经典例子中所引用的各个函数,我们在贴一下。 static int sunxi_spi_clk_init(struct sunxi_spi *sspi, u32 mod_clk) { int ret = 0; long rate = 0; //获取设备树中,对应时钟部分的第1项: clk_pll_periph0 (作为父时钟) sspi->pclk = of_

human!的专栏 281

linux clk模型

本模块是对平台(CPU 内部集成)的所有时钟源进行建模,提供对时钟源(clk)的操作接口。 Clocking rate (Crystal/DPLL/ARM core): 26.0/332/500 MHz  clk,clocksource, 锁相环(phase lock loops: pll.),多个时钟源,晶振,脉冲频率,时钟频率,晶振漂移, clk表示CPU内部的一个频率(

nancygreen的专栏 988

LatentSync:开源数字人唇形同步技术的实战部署与优化指南

本文详细介绍了开源数字人唇形同步工具LatentSync的实战部署与优化全流程。从核心原理(潜在扩散模型与TREPA技术)解析,到手把手完成环境搭建、模型获取及首次推理。文章深入探讨了自定义素材处理、关键参数调优(如guidance_scale),并提供了显存不足、人脸检测失败等常见问题的解决方案与性能优化技巧,旨在帮助用户高效部署并提升生成效果。

9o8p7i6u5y的博客 1007

转载:Linux clk驱动框架

转载 linux clk驱动框架 &lt;div class="article-info-box"&gt; &lt;div class="article-bar-top d-flex"&gt; ...

qq_21547927的博客 764

西安电子科技大学841学长经验分享(总成绩第三名)

西安电子科技大学841学长经验分享(总成绩第三名)

qq_30953547的博客 1082

STM32F103C8T6键盘DIY全攻略:从电路设计到固件烧录(附避坑指南)

本文详细介绍了基于STM32F103C8T6微控制器的DIY键盘制作全流程,涵盖硬件电路设计、按键矩阵实现、USB HID通信及固件烧录等关键步骤。特别针对常见问题提供避坑指南,帮助开发者高效完成从电路设计到功能实现的完整过程,打造个性化瀚文键盘。

soda5的博客 770

[Linux]学习笔记系列 -- [drivers][clk]clk

Linux内核中的drivers/clk目录实现了通用时钟框架(CCF),用于统一管理SoC的时钟资源。该框架通过提供者/消费者模型,将设备驱动与具体时钟硬件解耦,解决了早期各厂商时钟管理方案碎片化的问题。CCF结合设备树描述时钟拓扑,自动处理时钟依赖关系,提供标准API如clk_prepare_enable和clk_set_rate。其优势包括代码可移植性、数据驱动配置和集中电源管理,已成为现代SoC平台的必备组件,广泛应用于CPU、外设和多媒体等驱动的时钟管理。

wdfk-prog.space 851

微信聊天记录解密,必须是root的手机

手机上安装x-plore软件,将/data/data目录的相关EnMicroMsg.db auth_info_key_prefs.xml拷贝到/storge/emulated/0目录后才可以拷贝到电脑。路径:/data/data/com.tencent.mm/shared_prefs/auth_info_key_prefs.xml。但是是加密过的 需要解密 解密密码生成规则是手机IMEI+微信UIN md5(32位小写)后的前7位。安卓手机要root测试版本微信要7或者8版本都可以。选择message表。

venus60的专栏 1006

RK3399教程:linux clk使用

linux clk使用 在linux的clk的设备模型中,clk分为生产者和消费者,生产者是soc的厂商编写的clk驱动,注册到clk管理框架中。消费者就是具体的设备驱动,设备驱动根据标准的函数获取到clk的句柄,然后设置和配置产生clk。为何这么设计?其实也很简单,芯片产商最清楚clk的锁相环怎么设置,所以这部分驱动由芯片产商去编写,我们设备驱动只要使用标准的api就可以使用时钟了,所以这个框架将很底层的芯片clk的管理抽象出来做了一套通用的架构,好处就是将耦合性降到最低比如芯片厂商有MTK,ROCKCH

qq_27809619的博客 1690

第1期技术: DQN算法原理及实现过程

利用神经网络近似值函数的方法表示为: V^(s,w)≈Vπ(s)q^(s,a,w)≈qπ(s,a) \hat{V}(s, w) \approx V_{\pi}(s) \\ \hat{q}(s, a, w) \approx q_{\pi}(s, a) V^(s,w)≈Vπ​(s)q^​(s,a,w)≈qπ​(s,a) 那么具体的工作过程是怎样实现的? 以及如何从端到端的过程,本文将讲解Deep Q Network(DQN, 而这正是由DeepMind于2013年和2015年分别提出的两篇论文《Playi

深度强化学习实验室:一个“开源开放、共享共进”的强化学习学术组织。 4953

激光雷达的64线,32线,16线,你弄懂了吗?

激光雷达的 64 线、32 线、16 线是指激光雷达系统中能够同时发射和接收激光脉冲的激光线的数量5。

谢谢大家的关注和点赞!这里只有纯纯的知识干货,没有一句废话。希望能实实在在帮到大家~要是觉得有用,别忘了给我点支持哟,你 2637

Linux 时钟子系统详解

在现代SoC中,时钟系统是所有硬件模块能正常工作的基础CPU、总线、外设控制器、存储接口等模块,本质上都是同步数字电路,其时序行为完全依赖于时钟信号‍​​是Linux内核中用于统一管理系统clock资源的子系统,为各模块提供时钟信号,主要解决以下问题如何统一描述复杂的时钟硬件结构如何让不同设备安全地共享同一时钟资源如何在不暴露硬件细节的前提下操作时钟(实现clock控制的通用逻辑)如何将时钟管理与设备树、功耗管理结合‍。

weixin_51107304的博客 951

从零实现深度学习框架【实现自己的PyTorch(已完结)】

本着“凡我不能创造的,我就不能理解”的思想,此系列文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导。

日积月累,天道酬勤 6862

Linux 内核时钟子系统剖析:从硬件抽象到设备驱动

本文深入剖析了Linux内核时钟子系统(CCF)的工作原理,从硬件抽象到设备驱动实现。文章详细解释了时钟树的管理、六类标准时钟设备(如门控、分频器)的抽象,并通过实例演示了如何编写时钟提供者(Provider)驱动和消费者(Consumer)驱动,帮助开发者掌握这一核心子系统的设计与应用。

weixin_29196315的博客 535

大模型实战—通义千问大模型微调

这个参数仅针对 llama 类型的模型结构,默认勾选的是 q_proj 和 v_proj,具体的名词不容易理解,我就不多说了,可以简单的认为是对模型的理解能力进行优化,一般这两个就够了。当这个值较高时,适应新任务的能力会增强,但是对基础模型的影响会比较大,有过拟合的风险,尤其是在数据量有限的情况下。为了方便测试,我在云环境也创建了一个镜像,相关的环境都配置好了,可以直接使用几个国内开源的大语言模型,比如清华智谱的ChatGLM3-6B、零一万物的Yi-34B,还有最近阿里云开源的Qwen1.5-32B。

7万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

近400位内核专家相聚华科,第19届CLK大会圆满落幕,硬核回放已上线

2024 年 10 月 26 日,第 19届中国 Linux 内核开发者大会(以下简称 CLK 大会)于湖北武汉成功举办,线上观看人次超8万。来自全国各地的近 400 名内核开发者相约华中科技大学,聆听讲座,共商 Linux 内核未来之发展,共享内核技术之盛宴。现在就让我们一起来回顾一下本次大会的精彩内容吧。(图/大会现场)CLK 大会举办至今已是第 19 届,由清华大学、Intel、华为、...

内核工匠 3092

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

linux之clk模块

clk_register :此函数核心作用是生成并初始化clk,顺便加入到全局链表。但是此链表主要是管理所有注册的clk,为clk相关操作提供支持。这里需要说明的一点是:如果是通过此方式注册的clk,在没有其它注册函数支持下,可以通过__clk_lookup函数来获取clk,不过一般不使用此方式。__clk_of_table这个数组一般由CLK_OF_DECLARE申明。这个函数只能获取使用register_clkdev系列注册函数注册的clk。源码路径:kernel/driver/clk/ck.c。

bruk_spp的博客 839

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

上一篇: request_mem_region,ioremap 和phys_to_virt()
下一篇: gpio_request的使用
Jason-25
博客等级 码龄17年 10粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值