clk学习

目录

[一,clk-fixed and clk-pll](#一,clk-fixed and clk-pll)

1,clk-fixed

2,clk-pll

[二,clk时钟数 divider/factor/gate/mux/ratio/link介绍](#二,clk时钟数 divider/factor/gate/mux/ratio/link介绍)

1,clk-divider分频器

2,clk-gate开关控制

3,clk-mux多路选择器

[4,clk-ratio 分频比](#4,clk-ratio 分频比)

5,clk-link仅仅做父子绑定,通路使用

6,divider和ratio的区别

7,clk-factor

[三,clk配置,包含配置parent rate和使能](#三,clk配置,包含配置parent rate和使能)


一,clk-fixed and clk-pll

1,clk-fixed

fixed:{ "name": "xtal", "rate": 24000000 }

没啥内容,就是套在时钟树里面,作为后续的parent,实现get_rate可以作为后续clk节点的计算参考。

2,clk-pll

{"parent":"xtal","name":"apll","channel":0},

{"parent":"xtal","name":"dpll","channel":1},

{"parent":"xtal","name":"cpll","channel":2},

{"parent":"xtal","name":"gpll","channel":3},

{"parent":"xtal","name":"npll","channel":4},

val = (read32(CRU_MODE_CON) >> ((pdat->channel == 4) ? 14 : pdat->channel * 4)) & 0x3;

npll的bit位特殊,所以4单独处理,

if(val == 0x1)

{

val = read32(pdat->channel * 0x10);

no = ((val >> 0) & 0x0f) + 1;

nr = ((val >> 8) & 0x3f) + 1;

val = read32((pdat->channel * 0x10 + 0x4));

nf = ((val >> 0) & 0x1fff) + 1;

rate = (24 * nf / (nr * no)) * 1000000;

}

else if(val == 0x2)

{

rate = 32768;

}

else

{

rate = 24000000;

}

以npll为例,con0和con1存放这锁相环nr no nf值,当cru_mode_con寄存器npll值为0x01时

rate = (24 * nf / (nr * no)) * 1000000;

二,clk时钟数 divider/factor/gate/mux/ratio/link介绍

1,clk-divider分频器

执行分频功能的‌硬件电路‌

在Linux内核的通用时钟框架(CCF)中,CLK_DIVIDER_ONE_BASED 是一个用于时钟分频器(clk divider)的标志位,它定义了分频寄存器值与实际分频系数之间的映射关系。

当一个分频器时钟被设置为 CLK_DIVIDER_ONE_BASED 模式时,‌分频寄存器中的值直接等于实际的分频系数‌。例如,如果寄存器中存储的值是 5,那么输出时钟频率就是父时钟频率除以 5。

这与另一种常见的模式(非 ONE_BASED)形成对比:在非 ONE_BASED 模式下,寄存器值为 0 通常表示分频系数为 1(即不分频),寄存器值为 1 表示分频系数为 2,以此类推。而在 ONE_BASED 模式下,寄存器值 0 会被视为无效或特殊状态(通常避免使用),而 1 就代表分频系数为 1

clk_divider_set_rate

{

div = prate / rate;获取分频系数

if(pdat->onebased)

div--;

if(div > mask)

div = mask;

val = read32(pdat->virt);

val &= ~(mask << pdat->shift);

val |= div << pdat->shift;

val |= mask << (pdat->shift + 16);

write32(pdat->virt, val);

}

2,clk-gate开关控制

clk_gate_set_enable

{

val = read32(pdat->virt);

val &= ~(0x1 << pdat->shift);

if(enable)

val |= (pdat->invert ? 0x0 : 0x1) << pdat->shift;

else

val |= (pdat->invert ? 0x1 : 0x0) << pdat->shift;

val |= 0x1 << (pdat->shift + 16);

write32(pdat->virt, val);

}

3,clk-mux多路选择器

clk_mux_set_parent

{

for(i = 0; i < pdat->nparent; i++)

{

if(strcmp(pdat->parenti.name, pname) == 0)

{

val = read32(pdat->virt);

val &= ~(((1 << pdat->width) - 1) << pdat->shift);

val |= pdat->parenti.value << pdat->shift;

val |= ((1 << pdat->width) - 1) << (pdat->shift + 16);

write32(pdat->virt, val);

break;

}

}

}

4,clk-ratio 分频比

Clk Ratio(时钟分频比)‌:这是一个‌数值参数或配置项‌,用于‌定义分频器的行为‌。它指明了输出时钟频率与输入时钟频率之间的比例关系。通常用一个整数 N 表示,表示输出频率是输入频率的 1/N。例如,当 clk_ratio 设置为10时,意味着分频器需要将输入时钟频率降低为原来的十分之一,此时分频器的分频系数 N 就是10。‌‌

peri_hclk_div_con

Control the divider ratio between aclk_periph

and hclk_periph

2'b00: aclk_periph:hclk_periph = 1:1

2'b01: aclk_periph:hclk_periph = 2:1

2'b10: aclk_periph:hclk_periph = 4:1

clk_ratio_set_rate

{

div = prate / rate;

if(div > mask)

div = mask;

val = read32(pdat->virt);

val &= ~(mask << pdat->shift);

/* fls - find last (most-significant) bit set,Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32*/

val |= fls(div) << pdat->shift;

val |= mask << (pdat->shift + 16);

write32(pdat->virt, val);

}

5,clk-link仅仅做父子绑定,通路使用

比如G0_3作为aclk_bus_pre的parent做一个link

6,divider和ratio的区别

两者的区别可以类比为:‌

‌Divider‌ 是"‌做什么‌"------ 它是执行分频功能的‌硬件电路‌本身。

‌Clk Ratio‌ 是"‌怎么做‌"------ 它是控制这个电路如何工作的‌配置参数‌。

简单理解,‌分频器(divider)是实现分频功能的模块,而分频比(clk ratio)是这个模块的一个关键设定值,决定了分频的倍数

7,clk-factor

clk-factor分数分频时钟‌(Fractional Divider Clock),这是一种能够产生非整数倍分频时钟信号的技术。与只能输出整数分频(如2分频、5分频)的简单计数器不同,分数分频器可以实现如3.5分频、13/3分频等精确的非整数分频比,这对于需要高精度时钟频率的系统(如通信、音频处理、高速串行接口)至关重要,比如图中S17

clk_gcd 求prate和rate的最大公因数

{

u64_t c;

while(b != 0)

{

c = a % b;

a = b;

b = c;

}

return a;

}

clk_factor_set_rate

{

cdiv = clk_gcd(prate, rate);求prate和rate的最大公因数

div = (prate / cdiv) & 0xffff;

mult = (rate / cdiv) & 0xffff;

write32(pdat->virt, (mult << 16) | (div << 0));

}

三,clk配置,包含配置parent rate和使能

在dts中分散在各个node中

比如

{ "name": "mux-dclk-vop0", "parent": "gpll", "enable": true },

{ "name": "div-dclk-vop0", "rate": 45000000, "enable": true },

关联这几个函数,就是配置和使能

clk_set_parent(name, parent);有些多路选择指定parent

clk_set_rate(name, rate);配置帧率

clk_enable(name)或clk_disable(name);使能

相关推荐
zlinear数据采集卡5 分钟前
D223的PWM电机控制:6路独立脉冲+加减速算法深度解析
arm开发·stm32·嵌入式硬件·算法·fpga开发·架构
Kuakewei8881 小时前
平芯微42V热拔插OVP过压保护芯片:PW1600
嵌入式硬件
wengqidaifeng1 小时前
1.从“会敲命令”到理解 Linux:15 个基础指令、文件树与命令执行的本质
linux·运维·服务器·ubuntu
ACP广源盛139246256731 小时前
WAIC2026 国产超节点算力浪潮下@ACP#IX9104 在算力矩阵中的定位与落地场景
大数据·数据库·人工智能·嵌入式硬件·线性代数·矩阵
z20348315202 小时前
STM32单片机控制无源蜂鸣器播放《晴天》
stm32·单片机·嵌入式硬件
奔跑的架构师3 小时前
[A-49]ARMv9/v8-PSCI接口规范与工作流程简介
android·linux·arm开发·arm
国科安芯3 小时前
详解ADC 规则组外部触发:CH2、CH3 与 TRGO2
运维·网络·单片机·嵌入式硬件·mcu·系统架构
ACP广源盛139246256734 小时前
WAIC2026 国产算力浪潮@ACP#YLB3118 在算力矩阵中的存储定位与落地场景
大数据·人工智能·分布式·单片机·嵌入式硬件
ACP广源盛139246256734 小时前
WAIC2026 国产算力浪潮下@ACP#IX8024 在算力矩阵中的定位与落地场景
大数据·数据库·人工智能·嵌入式硬件·线性代数·矩阵
(╹◡╹)4 小时前
11.RK3588本地大模型内存评估优化
java·linux·前端