七路PLL:
root@(none):/sys/kernel/debug/clk# cat clk_summary
clock enable_cnt prepare_cnt rate accuracy phase
----------------------------------------------------------------------------------------
osc48m 0 0 48000000 0 0
osc48md4 0 0 12000000 0 0
usbohci0_12m 0 0 12000000 0 0
pll_periph0div25m 0 0 25000000 0 0
ephy_25m 0 0 25000000 0 0
hosc 11 11 24000000 0 0
csi_master0 0 0 24000000 0 0
sdmmc0_mod 0 0 800000 0 0
dcxo_out 0 0 24000000 0 0
spwm 0 0 24000000 0 0
cpurapbs2 0 0 24000000 0 0
cpurcpus 1 1 24000000 0 0
cpurahbs 1 1 24000000 0 0
cpurapbs1 2 2 24000000 0 0
cpurpio 1 1 24000000 0 0
stwi 1 1 24000000 0 0
csi_master1 0 0 24000000 0 0
mipi_host0 1 1 24000000 0 0
usbphy0 1 1 24000000 0 0
ths 1 1 24000000 0 0
gpadc 1 1 24000000 0 0
spi2 0 0 24000000 0 0
spi1 0 0 24000000 0 0
sdmmc2_rst 0 0 24000000 0 0
sdmmc2_bus 0 0 24000000 0 0
sdmmc2_mod 0 0 24000000 0 0
sdmmc1_rst 0 0 24000000 0 0
sdmmc1_bus 0 0 24000000 0 0
sdmmc1_mod 0 0 24000000 0 0
sdmmc0_rst 0 0 24000000 0 0
sdmmc0_bus 0 0 24000000 0 0
dbgsys 0 0 24000000 0 0
avs 0 0 24000000 0 0
apb2 1 1 24000000 0 0
twi3 0 0 24000000 0 0
twi2 0 0 24000000 0 0
twi1 0 0 24000000 0 0
twi0 0 0 24000000 0 0
uart3 0 0 24000000 0 0
uart2 0 0 24000000 0 0
uart1 0 0 24000000 0 0
uart0 1 1 24000000 0 0
hoscd2 0 0 12000000 0 0
pll_csi 0 0 336000000 0 0
csi_top 0 0 336000000 0 0
pll_audio 4 4 22579200 0 0
codec_1x 1 1 22579200 0 0
i2s0 1 1 22579200 0 0
codec_4x 0 0 22579200 0 0
i2s1 0 0 22579200 0 0
pll_audiox2 0 0 45158400 0 0
pll_audiox4 0 0 90316800 0 0
pll_video0 2 2 99000000 0 0
dspo 0 0 99000000 0 0
tcon_lcd 1 1 99000000 0 0
mipi_dphy0 1 1 24750000 0 0
pll_video0x4 0 0 396000000 0 0
pll_uni 2 3 600000000 0 0
eise 0 0 600000000 0 0
isp 0 0 300000000 0 0
ve 0 1 600000000 0 0
de 1 1 300000000 0 0
g2d 1 1 300000000 0 0
pll_unix2 0 0 1200000000 0 0
pll_periph0 4 4 600000000 0 0
spi0 1 1 100000000 0 0
cpurapbs2_pll 0 0 600000000 0 0
cpurcpus_pll 0 0 600000000 0 0
nna_rst 0 0 600000000 0 0
apb1 2 2 100000000 0 0
pio 1 1 100000000 0 0
pwm 1 1 100000000 0 0
ahb3 2 2 200000000 0 0
display_top 1 1 200000000 0 0
usbotg 1 1 200000000 0 0
usbehci0 0 0 200000000 0 0
usbohci0 0 0 200000000 0 0
gmac 0 0 200000000 0 0
psi 1 1 200000000 0 0
ahb2 0 0 200000000 0 0
ahb1 2 2 200000000 0 0
iommu 1 1 200000000 0 0
hstimer 0 0 200000000 0 0
dma 1 1 200000000 0 0
periph32k 0 0 32768 0 0
pll_periph0x2 0 0 1200000000 0 0
nna 0 0 1200000000 0 0
ce 0 0 300000000 0 0
pll_ddr0 0 0 1584000000 0 0
sdram 0 0 1584000000 0 0
mbus 0 0 396000000 0 0
pll_cpu 0 0 600000000 0 0
cpu 0 0 600000000 0 0
cpuapb 0 0 150000000 0 0
axi 0 0 200000000 0 0
iosc 0 0 16000000 0 0
losc 1 1 32768 0 0
losc_out 1 1 32768 0 0
cpurowc 0 0 32768 0 0
root@(none):/sys/kernel/debug/clk#
下图是Melis的时钟分布:
一般都有多路PLL,这多路PLL是由同一个晶振源驱动的,都是参考24M晶振时钟驱动的,一带多的哪种,后面那个其实是一个pll输出两个频率.还是一个PLL。
FIX_SRC是表示固定时钟源24M这些,FIX_FACTOR是指pllx4/pllx2这种由pll固定分频的时钟源
Melis下的实际分析:
在Tina上进行以下分析时,需要注意需要先通过DS5 关闭MMU功能,否则无法直接读取CCMU物理地址.
CPU主频获取:
CCMU基地址是0x03001000,PLL_CPUX控制寄存器偏移为0,读出来是0x8A003100,解析出N,M值分别为0x31和0x0,外部激励时钟是HOSC=24M,所以 CPU主频跑
Tina上则不同,由于Tina支持动态调频调压,在系统负荷不重的情况下,得到的寄存器如下图所示:
解析出N,M值分别为0x18和0x0,外部激励时钟是HOSC=24M,所以 CPU主频跑
和上文的clk_summary的输出是吻合的。
但是当执行
dd if=/dev/zero of=/dev/null
后,DS5连接获取到的寄存器如下图所示:
这个值和上面melis的分析是一致的,所以,它是1.2G.也就是这个时候随着负荷变重,CPU 满负荷运行。如下图所示.
root@(none):/sys/kernel/debug/clk# cat clk_summary
clock enable_cnt prepare_cnt rate accuracy phase
----------------------------------------------------------------------------------------
osc48m 0 0 48000000 0 0
osc48md4 0 0 12000000 0 0
usbohci0_12m 0 0 12000000 0 0
pll_periph0div25m 0 0 25000000 0 0
ephy_25m 0 0 25000000 0 0
hosc 11 11 24000000 0 0
csi_master0 0 0 24000000 0 0
sdmmc0_mod 0 0 800000 0 0
dcxo_out 0 0 24000000 0 0
spwm 0 0 24000000 0 0
cpurapbs2 0 0 24000000 0 0
cpurcpus 1 1 24000000 0 0
cpurahbs 1 1 24000000 0 0
cpurapbs1 2 2 24000000 0 0
cpurpio 1 1 24000000 0 0
stwi 1 1 24000000 0 0
csi_master1 0 0 24000000 0 0
mipi_host0 1 1 24000000 0 0
usbphy0 1 1 24000000 0 0
ths 1 1 24000000 0 0
gpadc 1 1 24000000 0 0
spi2 0 0 24000000 0 0
spi1 0 0 24000000 0 0
sdmmc2_rst 0 0 24000000 0 0
sdmmc2_bus 0 0 24000000 0 0
sdmmc2_mod 0 0 24000000 0 0
sdmmc1_rst 0 0 24000000 0 0
sdmmc1_bus 0 0 24000000 0 0
sdmmc1_mod 0 0 24000000 0 0
sdmmc0_rst 0 0 24000000 0 0
sdmmc0_bus 0 0 24000000 0 0
dbgsys 0 0 24000000 0 0
avs 0 0 24000000 0 0
apb2 1 1 24000000 0 0
twi3 0 0 24000000 0 0
twi2 0 0 24000000 0 0
twi1 0 0 24000000 0 0
twi0 0 0 24000000 0 0
uart3 0 0 24000000 0 0
uart2 0 0 24000000 0 0
uart1 0 0 24000000 0 0
uart0 1 1 24000000 0 0
hoscd2 0 0 12000000 0 0
pll_csi 0 0 336000000 0 0
csi_top 0 0 336000000 0 0
pll_audio 4 4 22579200 0 0
codec_1x 1 1 22579200 0 0
i2s0 1 1 22579200 0 0
codec_4x 0 0 22579200 0 0
i2s1 0 0 22579200 0 0
pll_audiox2 0 0 45158400 0 0
pll_audiox4 0 0 90316800 0 0
pll_video0 2 2 99000000 0 0
dspo 0 0 99000000 0 0
tcon_lcd 1 1 99000000 0 0
mipi_dphy0 1 1 24750000 0 0
pll_video0x4 0 0 396000000 0 0
pll_uni 2 3 600000000 0 0
eise 0 0 600000000 0 0
isp 0 0 300000000 0 0
ve 0 1 600000000 0 0
de 1 1 300000000 0 0
g2d 1 1 300000000 0 0
pll_unix2 0 0 1200000000 0 0
pll_periph0 4 4 600000000 0 0
spi0 1 1 100000000 0 0
cpurapbs2_pll 0 0 600000000 0 0
cpurcpus_pll 0 0 600000000 0 0
nna_rst 0 0 600000000 0 0
apb1 2 2 100000000 0 0
pio 1 1 100000000 0 0
pwm 1 1 100000000 0 0
ahb3 2 2 200000000 0 0
display_top 1 1 200000000 0 0
usbotg 1 1 200000000 0 0
usbehci0 0 0 200000000 0 0
usbohci0 0 0 200000000 0 0
gmac 0 0 200000000 0 0
psi 1 1 200000000 0 0
ahb2 0 0 200000000 0 0
ahb1 2 2 200000000 0 0
iommu 1 1 200000000 0 0
hstimer 0 0 200000000 0 0
dma 1 1 200000000 0 0
periph32k 0 0 32768 0 0
pll_periph0x2 0 0 1200000000 0 0
nna 0 0 1200000000 0 0
ce 0 0 300000000 0 0
pll_ddr0 0 0 1584000000 0 0
sdram 0 0 1584000000 0 0
mbus 0 0 396000000 0 0
pll_cpu 0 0 1200000000 0 0
cpu 0 0 1200000000 0 0
cpuapb 0 0 300000000 0 0
axi 0 0 400000000 0 0
iosc 0 0 16000000 0 0
losc 1 1 32768 0 0
losc_out 1 1 32768 0 0
cpurowc 0 0 32768 0 0
root@(none):/sys/kernel/debug/clk#
当杀掉dd测试, 重新获取clk_summary信息:
root@(none):/sys/kernel/debug/clk# cat clk_summary
clock enable_cnt prepare_cnt rate accuracy phase
----------------------------------------------------------------------------------------
osc48m 0 0 48000000 0 0
osc48md4 0 0 12000000 0 0
usbohci0_12m 0 0 12000000 0 0
pll_periph0div25m 0 0 25000000 0 0
ephy_25m 0 0 25000000 0 0
hosc 11 11 24000000 0 0
csi_master0 0 0 24000000 0 0
sdmmc0_mod 0 0 800000 0 0
dcxo_out 0 0 24000000 0 0
spwm 0 0 24000000 0 0
cpurapbs2 0 0 24000000 0 0
cpurcpus 1 1 24000000 0 0
cpurahbs 1 1 24000000 0 0
cpurapbs1 2 2 24000000 0 0
cpurpio 1 1 24000000 0 0
stwi 1 1 24000000 0 0
csi_master1 0 0 24000000 0 0
mipi_host0 1 1 24000000 0 0
usbphy0 1 1 24000000 0 0
ths 1 1 24000000 0 0
gpadc 1 1 24000000 0 0
spi2 0 0 24000000 0 0
spi1 0 0 24000000 0 0
sdmmc2_rst 0 0 24000000 0 0
sdmmc2_bus 0 0 24000000 0 0
sdmmc2_mod 0 0 24000000 0 0
sdmmc1_rst 0 0 24000000 0 0
sdmmc1_bus 0 0 24000000 0 0
sdmmc1_mod 0 0 24000000 0 0
sdmmc0_rst 0 0 24000000 0 0
sdmmc0_bus 0 0 24000000 0 0
dbgsys 0 0 24000000 0 0
avs 0 0 24000000 0 0
apb2 1 1 24000000 0 0
twi3 0 0 24000000 0 0
twi2 0 0 24000000 0 0
twi1 0 0 24000000 0 0
twi0 0 0 24000000 0 0
uart3 0 0 24000000 0 0
uart2 0 0 24000000 0 0
uart1 0 0 24000000 0 0
uart0 1 1 24000000 0 0
hoscd2 0 0 12000000 0 0
pll_csi 0 0 336000000 0 0
csi_top 0 0 336000000 0 0
pll_audio 4 4 22579200 0 0
codec_1x 1 1 22579200 0 0
i2s0 1 1 22579200 0 0
codec_4x 0 0 22579200 0 0
i2s1 0 0 22579200 0 0
pll_audiox2 0 0 45158400 0 0
pll_audiox4 0 0 90316800 0 0
pll_video0 2 2 99000000 0 0
dspo 0 0 99000000 0 0
tcon_lcd 1 1 99000000 0 0
mipi_dphy0 1 1 24750000 0 0
pll_video0x4 0 0 396000000 0 0
pll_uni 2 3 600000000 0 0
eise 0 0 600000000 0 0
isp 0 0 300000000 0 0
ve 0 1 600000000 0 0
de 1 1 300000000 0 0
g2d 1 1 300000000 0 0
pll_unix2 0 0 1200000000 0 0
pll_periph0 4 4 600000000 0 0
spi0 1 1 100000000 0 0
cpurapbs2_pll 0 0 600000000 0 0
cpurcpus_pll 0 0 600000000 0 0
nna_rst 0 0 600000000 0 0
apb1 2 2 100000000 0 0
pio 1 1 100000000 0 0
pwm 1 1 100000000 0 0
ahb3 2 2 200000000 0 0
display_top 1 1 200000000 0 0
usbotg 1 1 200000000 0 0
usbehci0 0 0 200000000 0 0
usbohci0 0 0 200000000 0 0
gmac 0 0 200000000 0 0
psi 1 1 200000000 0 0
ahb2 0 0 200000000 0 0
ahb1 2 2 200000000 0 0
iommu 1 1 200000000 0 0
hstimer 0 0 200000000 0 0
dma 1 1 200000000 0 0
periph32k 0 0 32768 0 0
pll_periph0x2 0 0 1200000000 0 0
nna 0 0 1200000000 0 0
ce 0 0 300000000 0 0
pll_ddr0 0 0 1584000000 0 0
sdram 0 0 1584000000 0 0
mbus 0 0 396000000 0 0
pll_cpu 0 0 600000000 0 0
cpu 0 0 600000000 0 0
cpuapb 0 0 150000000 0 0
axi 0 0 200000000 0 0
iosc 0 0 16000000 0 0
losc 1 1 32768 0 0
losc_out 1 1 32768 0 0
cpurowc 0 0 32768 0 0
root@(none):/sys/kernel/debug/clk#
对比后,发现只有PLL_CPU这路PLL发生了调压调频的变化:
所以,以上我们直观的感受了动态调频调压.
关于如何关闭Tina的动态调频调压,可以看这篇博客:
Tina关闭动态调压调频_tugouxp的专栏-CSDN博客
通过修改配置的方式实际上是将CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND关闭,并且打开CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE.
手动超频:
可以通过直接修改CCMU寄存器的方式手动超频,根据上面的公式,超频有两条路,要么提高坟墓N的值,要么减小分子M的值。
可以看到,M值已经很小了,不能再小,所以超频的路只有一条,提升N值。
比如我们像超频到1440M,也就是1.44GHZ.根据公式,1440/24=60=0x3c.
所以N的值可以设置为0x3b.我们直接在DS5中修改,修改之前同样关闭SCTLR.M MMU的使能位修改后在打开。
然后,通过/sys/kernel/debug/clk/clk_summary节点查看修改后的主频信息:
可以看到,频率值是我们设置的超频频率1440MHZ,超频成功.
配置超频:
直接修改寄存器的方式超频毕竟不是最安全的做法,通过修改启动配置文件的方式安全性上要好很多, 在tina上面,启动分为boot0,boot1,uboot以及内核几个阶段,每个阶段都有对频率的设置,如果在前面修改了,可能会被后一阶段的修改覆盖,所以,最好的办法是在kernel阶段修改。
kernel阶段的频率信息来自于devicetree配置,我们看最终反编译的device tree文件:
之后寻线追踪,源头在:
修改为1440M,重新编译打包:device tree发生了变化:
不过经过测试发现,这样修改后对V831无效,可能是V831上从根儿上关闭了动态调压调频机制(关闭了CONFIG_CPU_FREQ和CONFIG_ARM_SUNXI_CPUFREQ),直接使用了UBOOT中的CPU频率设定。
以上是失败的记录,记录备查。
V831上如何超频呢? 忘掉内核吧,直接修uboot就可以了:
第一步,关闭UBOOT上的超频检查逻辑
第二步 UBOOT识别的是sys_config配置文件,而非devicetree,所以这里要修改devicetree:
第三步:重新编译UBOOT,项目,并且打包,烧录,看时钟树信息:
V831超频成功,实际测试发现V831上超频1440M可以开机,但跑多媒体应用直接crash,但是超到1200M没有发现问题。
接下来看V833上的超频,我完全没有经验,但尝试先寻找线索,经过查看内核信息,发现V833默认主频是1.2G
转换为16进制,是0x47868C00,对应查找反编译的dtb文件,果然有所有发现
对用于原始配置文件在board.dts中的opp_dvfs_table设定里面,opp-hz选项,这一点和前面CPUS中的clock-frequency节点不同。
或者再增加一个调频调压选项:
注意其中的opp-microvolt项要认真填写,既不能超出CPU标称电压,也不能低于频点所需电压,否则都会带来稳定性问题。
对应的内核中的解析位置下图所示:
修改,编译,打包:
烧录后查看发现,主频并非预期的1.44G,而是一个没有包含在table中的值,怀疑是电压不够,软件调频策略生效。
增加电压值:
还不行,估计是软件的逻辑锁死了限制在某个范围之内,只能通过内核才能追查了。
追踪内核逻辑,看内核的频率设置的具体逻辑是什么
在右图最后一层调用get_factors_pll_cpu中,我们定位到了设置频率失败的原因,看下图,get_factors_pll_cpu函数的参数中,包含上面设置的预期频率1.44G,这说明我们的配置确实生效了,但是为什么设置的最终不是1.44G而是一个不知道从哪里来的1296Mhz呢?
下面开始揭晓答案,原来内核函数get_factors_pll_cpu的实现中,会检查当前设置的频率是否超过上限pllcpu_max,如果超过了,则会设置此上限值为最终的频率,而由pllcpu_max表示的上限值就恰好是1296MHZ.
如下图,根据宏定义的展开,这里设置了cpu.ddr0,periph0,video0以及audio的主频上限,分别为factor_pllcpu_tbl,factor_pllddr0_tbl以及factor_pllperiph0_tbl,factor_pllvideo0_tbl,factor_pllaudio_tbl数组的最后一个频点,分别为:
PLLCPU(53, 0, 0, 1296000000U)
PLLDDR0(104, 0, 0, 2520000000U)
PLLPERIPH0(82, 0, 0, 996000000U)
PLLVIDEO0(104, 0, 630000000U)
PLLAUDIO(11, 0, 0, 0, 288000000U)
所以,设置为1.44G失败的原因也清楚了,我们在数组中再添加一项,将上限改为1.44G再看:
之后,重新编译系统,打包,烧录。
发现还是不行,后面询问同事才知道,PLLCPU后面的数字并不是代表序号,而是N值,而第三个域代表M值,所以上面设置为54是错误的。我开始还以为是序号。
所以,如果想调频到1440MHZ, PLLCPU宏的第一个参数应当是 1440/24-1=59=0x3b
所以,应该这样写
PLLCPU(59, 0, 0, 1440000000U),
最后,默认的M值和宏的第三个参数有关,如果为0,则M=1, M=1的话细的调频粒度是24MHZ,如果想要更小HZ的粒度,可以M,N一起调整,比如我想调整到1404000000U HZ,这次的调整力度是12MHZ,比24MHZ小,所以必须M,N一起调整才能达到。所以应该这样调整参数:
PLLCPU(116, 0, 1, 1404000000U),
很重要的一个函数,同步修改电压和频率的接口是这个 dev_pm_opp_set_rate, opp模块是内核负责调压调频,维护电压和频率对应关系的一个模块.OPP全称是 Operating Performance Points,代表频率/电压对。
调频声明:
无论在V831还是在V833上,默认启动是boot设置为1008M,但是,由于V833开启了动态调频调压,然后到了内核就有cpufreq控制,cpufreq会有多个策略
powersave;最低频
performance;最高频
userspace;用户态自己设置
schedutil ;根据调度任务
ondemond;根据负载,对应如下的几个CONFIG.
android一般schedutil,linux一般用ondemond,如果我们选择的是performance ,所以调频后默认按照最大频率运行。
DDR频率获取:
CCMU基地址是0x03001000,PLL_DDR0控制寄存器偏移为0x10,值为0xB8004100(看上一幅图),计算公式是
,这个频率看起来是DDR3.
VE频率的获取:
CCMU基地址是0x03001000,VE Clock控制寄存器偏移为0x690,值为0x81000003
根据寄存器的定义
其中clocksource选择的是PLL_UNI(2X).(bit [25:24] = 0b01).
所以,要算出VE的工作频率,首先要得到clocksource的工作频率,而VE在V833上最多有4个clock source,根据当前配置,选择的是PLL_UNI(2X)
PLL_UNI的寄存器偏移为:0x0028
PLL_UNI(1X)的计算公式为:
根据配置信息,N=0x31,M0=M1=0
相应的PLL_UNI(2X)为
所以
所以,VPU在V833项目中跑的频率是300M.
PLL_PERI0频率获取:
PLL_PERI0_1X =
PLL_PERI0_2X =
参考spec,PLL_PERI0寄存器地址偏移是0x0020
N=50,M0=1,M1=1
所以
PLL_PERI0_1X主频是600M
PLL_PERI0_2X主频是1.2G
PLL_VIDEO频率获取:
计算公式:
PLL_VIDEO_1X=
PLL_VIDEO_4X=
N=33,M=2
所以
PLL_VIDOE_1X=24*33/2/4=99M;
PLL_VIDEO_4X=24*33/2=396M.
PLL_CSI频率获取:
计算公式
PLL_CSI=24*N/M0/M1
N=28,M1=1,M0=2;
PLL_CSI=24*28/2/1 = 336M;
PLL_AUDIO频率获取:
PLL_AUDIO=24*N/M0/M1/P
PLL_AUDIO_4X=24*N/M1/2
PLL_AUDIO_2X=24*N/M1/4
N=43,P=21,M0=2,M1=1;
所以
PLL_AUDIO=24*43/2/1/21 = 24.5714MHZ.
PLL_AUDIO_4X=24*43/1/2=516MHZ.
PLL_AUDIO_2X=24*43/1/4=258MHZ.
NNA时钟统计:
NNA挂在pll_periph0x2时钟源上,寄存器信息如下:
根据bit24~26给出的信息,确认当前使用的是pll_periph0x2 1.2HZ的时钟源.
M=2;
所以,根据计算公式,NNA的时钟速度是
以上所有这些时钟树的主干时钟均在 boot0阶段都已配好。