Linux下的clk学习
先看某主板的时钟dts描述,如
1.1固定时钟 fixed-clock
ext_26m: ext-26m {compatible = "fixed-clock";#clock-cells = <0>;clock-frequency = <26000000>;clock-output-names = "ext_26m";};ext_6m5: ext-6m5 {compatible = "fixed-clock";#clock-cells = <0>;clock-frequency = <6500000>;clock-output-names = "ext_6m5";};
该主板有一个外接的26M晶振,ext_26m即外部的26M晶振,有一个固定的ext_6m5时钟,应该是从ext_26m分频而来。
1.2固定因子时钟 fixed-factor-clock
ext_26m: ext-26m {compatible = "fixed-clock";#clock-cells = <0>;clock-frequency = <26000000>;clock-output-names = "ext_26m";
};clk_twpll: clk@40353004 {compatible = "sprd,sc9863a-adjustable-pll-clock";#clock-cells = <0>;reg = <0x0 0x40353004 0x0 0x4>,<0x0 0x40353008 0x0 0x4>,<0x0 0x4035300c 0x0 0x4>;clocks = <&ext_26m>;clock-output-names = "clk_twpll";
};clk_twpll_12m: clk-twpll-12m {compatible = "fixed-factor-clock";#clock-cells = <0>;clock-mult = <1>;clock-div = <128>;clocks = <&clk_twpll>;clock-output-names = "clk_twpll_12m";
};clk_twpll_768m: clk-twpll-768m {compatible = "fixed-factor-clock";#clock-cells = <0>;clock-mult = <1>;clock-div = <2>;clocks = <&clk_twpll>;clock-output-names = "clk_twpll_768m";
};
由某个时钟固定分频而来,
clock-div = <128>;父时钟分频128而来
clocks = <&clk_twpll>,clk_twpll_12m来源于clk_twpll,而clk_twpll来源ext_26m
1.3muxed-clock混合时钟(可从多个时钟中选一个父时钟)
如clk_pwm0其可选的父时钟是ext_32k,clk_rpll_26m,&ext_26m,clk_twpll_48m
clk_pwm0: clk@402d023c {compatible = "sprd,muxed-clock";#clock-cells = <0>;reg = <0x0 0x402d023c 0x0 0x4>;sprd,mux-msk = <0x3>;clocks = <&ext_32k>, <&clk_rpll_26m>, <&ext_26m>,<&clk_twpll_48m>;clock-output-names = "clk_pwm0";};
1.4composite-clock适配时钟(可从多个时钟中选一个父时钟,并对其进行分频)
如clk_aux0其时钟来源可选(clk_set_parent)
clocks = <&ext_32k>, <&clk_rpll_26m>, <&ext_26m>;
sprd,div-msk = <0xf00>;代表其可以进行1到16的分频
clk_aux0: clk@402d022c {compatible = "sprd,composite-clock";#clock-cells = <0>;reg = <0x0 0x402d022c 0x0 0x4>;sprd,mux-msk = <0x3>;sprd,div-msk = <0xf00>;clocks = <&ext_32k>, <&clk_rpll_26m>, <&ext_26m>;clock-output-names = "clk_aux0";
};
1.5gates-clock门时钟(对时钟进行开关,如aux0_clk的开关时钟就是<&clk_aon_apb_gates1 2)
clk_aon_apb_gates1: clk@402e0004 {compatible = "sprd,sc1000-gates-clock";#clock-cells = <1>;reg = <0x0 0x402e0004 0x0 0x3000>;sprd,gates-msk = <0xfa7e7fbf>;clocks = <&clk_aon_apb>;clock-output-names = "pmu_eb", "thm_eb", "aux0_eb","aux1_eb", "aux2_eb", "probe_eb","clk_emc_ref_eb", "ca53_wdg_eb","ap_tmr1_eb", "ap_tmr2_eb", "disp_emc_eb","zip_emc_eb", "gsp_emc_eb", "mm_vsp_eb","mdar_eb", "rtc4m0_cal_eb","rtc4m1_cal_eb", "djtag_eb", "mbox_eb","aon_dma_eb", "aon_apb_def_eb", "orp_jtag_eb","dbg_eb", "dbg_emc_eb", "cross_trig_eb","serdes_dphy_eb";
};
1.6使用例子
sec-nfc@27 {compatible = "sec-nfc";clock-names = "clk_aux0","source","enable";clocks = <&clk_aux0>,<&ext_26m>,<&clk_aon_apb_gates1 2>;};struct clk clk_aux0,clk_parent,clk_enable;clk_aux0 = devm_clk_get(dev, "clk_aux0");if (IS_ERR(clk_aux0)){pr_err("can't get nfc clock dts config: clk_aux0\n");return -1;}clk_parent = devm_clk_get(dev, "source");if (IS_ERR(clk_parent)) {pr_err("can't get nfc clock dts config: source\n");return -1;}clk_set_parent(clk_26m, clk_parent);ret=clk_set_rate(clk_26m,2600000);clk_enable = devm_clk_get(dev, "enable");if (IS_ERR(clk_enable)) {pr_err("can't get nfc clock dts config: enable\n");return -1;}clk_prepare_enable(clk_aux0);clk_prepare_enable(clk_enable)
1.7调试指南
进入时钟目录,如clk_aux0
/sys/kernel/debug/clk/clk_aux0或/d/clk/clk_aux0/
cat clk_rate可以看设置的频率
cat clk_enable_count看开关状态
如果不正常,继续检索log找原因
比如设置的时钟速率为2M,但实际上设置的速率3M,这是因为源时钟48M,可16分频,能得到的最小时钟为3M,驱动会找一个最进行的时钟频率进行配置。
1.8关键函数解析
clk_set_parent从所有父时钟中选一个(根据名字),计算第几个,然后写相应的寄存器,来选择父时钟, 同时也设置了速率就是父时钟的速率。
clk_set_parent
clk_core_set_parent
__clk_recalc_rates
clk_recalc
clk_divider_ops.recalc_rate
clk_divider_recalc_rate
divider_recalc_rate
DIV_ROUND_UP_ULL
clk_set_rate设置速率代码逻辑如下
clk_set_rate
clk_core_set_rate_nolock
clk_calc_new_rates
clk_calc_subtree
clk_recalc
clk_divider_ops.recalc_rate
clk_divider_recalc_rate
divider_recalc_rate
DIV_ROUND_UP_ULL
#define DIV_ROUND_UP_ULL(ll,d) \({ unsigned long long _tmp = (ll)+(d)-1; do_div(_tmp, d); _tmp; })
Linux下的clk学习相关推荐
- linux按进程分配物理内存,linux下内存管理学习心得(一)
最近在学习内存管理的时候,发现对linux下的所谓内存如何管理如何分配都不熟悉,通过最近的查阅资料可总结如下,如有不妥之处欢迎大家批评与指正. 总的的来说linux的内存管理其实主要难理解的是以下几个 ...
- linux下C++编程学习
前言(废话,可略过):之前一直在windows下做C++编程,后来换后台工作接触到linux下C++开发.期间磨磨唧唧浪费了很多时间.记录下历程,给后来的小伙伴提个醒,免得浪费宝贵时间. 一.关于换系 ...
- LINUX下的makefile学习(此文是我学习过程遇到问题时找到的所有回答,感谢其它大佬的回答,各个文章我都标明了原文链接)
看视频学习截图: 针对上面情况就使用makefile工程管理 内容一行写不完,加上'\' : CC=gcc2 CFLAGS=-Wall -std=gnu993 #CFLAGS=-Wall -std=g ...
- linux下c的学习
1.c语言相较于其他语言的优点: (1)良好的移植性 (2)运行效率高 (3)生成目标代码质量高,程序执行效率高 2.静态库与动态库的定义与区别 (1)库(Library)说白了就是一段编译好的二进制 ...
- Linux下sysstat工具学习
Linux下,我们多用ssh链接服务器远程操控.对于系统的监控必不可少,sysstat很不错的监控工具包. sysstat官网:http://sebastien.godard.pagesperso-o ...
- Linux下的C学习笔记
1.linux系统提供的环境 http://blog.csdn.net/feixiaoxing/article/details/7194756 编译:gcc.as.ld 调试:gdb 自动编译:mak ...
- Linux下的Samba学习(二)------用实验快速学习Samba服务器设置
前言:在windows和linux的混合网络中,samba还是有很大用处的,本文用实验的方法快速学习Samba. [实验项目] ①在linux上建立Samba服务器,用类似FTP的客户端smbclie ...
- Unix和Linux下C语言学习指南
引言 尽管 C 语言问世已近 30 年,但它的魅力仍未减退.C 语言继续吸引着众多的开发者,他们为了编写.移植或维护应用程序而必须学习新技能. 本文是为了满足对C语言初学者或想提高自身C语言修为的开发 ...
- bash linux .ee,Linux下Bash shell学习笔记.md
### 1.shell下没有变量类型和定义的概念. >1. 变量直接使用不用定义 >2. 所有值都视为字符串. >3. 在对变量取值都需要加$ >4. 行注释为 # + ### ...
最新文章
- The Hadoop Distributed Filesystem
- 未能在全局命名空间中找到类型或命名空间名称“Wuqi”
- CentOS设置服务开机启动的方法
- Linux调试——gdb调试器的简单使用调试coredump文件
- 报名 | TensorFlow China Roadshow 正式开启
- Python之数据拆分——groupby()方法
- 【Liunx】Linux 系统目录结构
- Mybatis存储过程调用
- Using Delegates with Data Readers to Control DAL Responsibility[转]
- 51单片机8位流水灯左移实现(比较简短)
- 各国货币代码表(Currency Code)
- 单声道数字功放芯片-NTP8835
- 电子通讯录(数据库版存储)
- Python语言程序设计课程论文
- SpringCloud-狂神(1. 概述)学习笔记
- 算法-经典趣题-青蛙过河
- Android 音频可视化
- Dubbo源码分析-Spring与Dubbo整合原理与源码分析(二)
- VOT 2015 Benchmark 使用教程
- Houdini制作全流程你知道多少,快来看看