S5PV210的时钟系统
Posted Lewin~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了S5PV210的时钟系统相关的知识,希望对你有一定的参考价值。
3.0时钟简介
时钟是同步工作系统的工作节拍
例如:
工人按照工作时间上下班
舞者根据音乐节拍做出不同的动作
正步时教官念的121
为什么需要时钟?
SoC内部需要一个同步的时钟系统来协调各个内部外设和CPU的工作
SoC的时钟获得方式:
1.SoC有个引脚用于输入外部时钟源信号,用的很少。
2.外部晶振+内部时钟发生器产生时钟,大部分低频单片机常用。
3.外部晶振+内部时钟发生器+内部PLL产生高频时钟+内部分频器分频得到各种频率的时钟,ARM,stm32使用这些。
为什么外部不直接用高频晶振产生高频信号直接给CPU?
高频晶振易产生传导辐射影响周遭电路,因此SoC外围电路不宜使用高频;
高频率的晶振太贵了。
为什么要内部先高频然后再分频?
主要因为SoC内部各部件所需时钟频率不同,没法统一供应。
因此设计思路是PLL后先得到一个最高的频率(1GHz、1.2GHz)作为主频,然后各外设都有自己的分频器再来分频得到自己想要的频率。
3.1时钟域
210根据 “各设备所需时钟频率的高低和设备的类别” 将整个时钟体系分成三个时钟域,即主系统(MSYS)、显示系统(DSYS)和外围系统(PSYS),如图3-1所示。
•MSYS域包括CortexA8处理器、DRAM内存控制器(DMC0和DMC1)、IRAM和IROM…
•DSYS域都是和视频显示、编解码等有关的模块
•PSYS域和内部各种外设时钟有关,譬如串口、SD接口、I2C等。
3.2时钟声明
210时钟来源:晶振+时钟发生器+PLL+分频电路
S5PV210外部有4个晶振接口,设计板子硬件时可以根据需要来决定在哪里接晶振。接了晶振之后上电相应的模块就能产生振荡,产生原始时钟。原始时钟再经过一系列的筛选开关进入相应的PLL电路生成倍频后的高频时钟。高频时钟再经过分频到达芯片内部各模块上。(有些模块,譬如串口内部还有进一步的分频器进行再次分频使用)
在典型的210应用程序中,
•CortexA8和MSYS时钟域使用APLL(即ARMCLK、HCLK_MSYS和PCLK_MSYS)。
•DSYS和PSYS时钟域(即HCLK_DSYS、HCLK_PSYS、PCLK_DSYS和PCLK_PSYS)和其他外设时钟(即音频IP、SPI等)使用MPLL和EPLL。
•视频时钟使用VPLL。
3.3时钟关系
210时钟域详解
MSYS域:
ARMCLK: 给cpu内核工作的时钟,也就是主频
HCLK_MSYS: MSYS域的高频时钟,给DDR0和DDDR1使用
PCLK_MSYS: MSYS域的低频时钟
HCLK_IMEM:给iROM和iRAM(合称iMEM)使用
DSYS域:
HCLK_DSYS:DSYS域的高频时钟
PCLK_DSYS:DSYS域的低频时钟
PSYS域:
HCLK_PSYS:PSYS域的高频时钟
PCLK_PSYS:PSYS域的低频时钟
总结:
210内部的各个外设都是接在(内部AMBA总线)总线上面的,AMBA总线有1条高频分支叫AHB,有一条低频分支叫APB。上面的各个域都有各自对应的HCLK_XXX和PCLK_XXX,其中HCLK_XXX就是XXX这个域中AHB总线的工作频率;PCLK_XXX就是XXX这个域中APB总线的工作频率。
SoC内部的各个外设其实是挂在总线上工作的,也就是说这个外设的时钟来自于他挂在的总线,譬如串口UART挂在PSYS域下的APB总线上,因此串口的时钟来源是PCLK_PSYS。
我们可以通过记住和分析上面的这些时钟域和总线数值,来确定我们各个外设的具体时钟频率。
高性能的时钟值:
• freq(ARMCLK) = 1000 MHz
• freq(HCLK_MSYS) = 200 MHz
• freq(HCLK_IMEM) = 100 MHz
• freq(PCLK_MSYS) = 100 MHz
• freq(HCLK_DSYS) = 166 MHz
• freq(PCLK_DSYS) = 83 MHz
• freq(HCLK_PSYS) = 133 MHz
• freq(PCLK_PSYS) = 66 MHz
• freq(SCLK_ONENAND) = 133 MHz, 166 MHz
3.4时钟框图分析
(1)时钟框位置:数据手册P361&P362
(2)两张图之间是渐进的关系。第一张图从左到右依次完成了原始时钟生成->PLL倍频得到高频时钟->初次分频得到各总线时钟;第二张图是从各中间时钟(第一张图中某个步骤生成的时钟)到各外设自己使用的时钟(实际就是个别外设自己再额外分频的设置)。
(3)要看懂时钟体系框图,2个符号很重要:一个是MUX开关,另一个是DIV分频器。
(3.1)MUX开关是数据选择器,实际编程时对应某个寄存器的某几位的设置,设置值决定了不同的时钟来源。
(3.2)DIV分频器,是一个硬件设备,可以对频率进行n分频生成低频时钟,实际编程时对应某个寄存器中的某几位的设置,设置值决定了不同的分频系数(譬如左边进来的时钟是80MHz,分频系数设置为8,则分频器右边输出的时钟频率为10MHz)。
3.7寄存器分析
xPLL_LOCK寄存器用于控制PLL的锁定周期
xPLL_CONn寄存器用于打开/关闭PLL电路,设置PLL的倍频参数,查看PLL锁定状态等
CLK_SRCn寄存器用于选择时钟来源,对应时钟框图中的MUX开关。
CLK_DIVn寄存器用于设置时钟分频
210设置高性能时钟值的步骤
目的:(将对应时钟设置成如下数值)
• freq(ARMCLK) = 1000 MHz
• freq(HCLK_MSYS) = 200 MHz
• freq(HCLK_IMEM) = 100 MHz
• freq(PCLK_MSYS) = 100 MHz
• freq(HCLK_DSYS) = 166 MHz
• freq(PCLK_DSYS) = 83 MHz
• freq(HCLK_PSYS) = 133 MHz
• freq(PCLK_PSYS) = 66 MHz
• freq(SCLK_ONENAND) = 133 MHz, 166 MHz
第1步:先将所有MUX开关置0,保证设置完PLL后再设置为1导通倍频过的时钟。
寄存器查看:
这里设置值为0x0
第2步:设置PLL锁定时间。
寄存器查看:
默认值为0x0FFF,保险起见我们设置为0xFFFF。
第3步:设置分频系数,决定由PLL倍频后出来的最高时钟如何分频得到各个分时钟。
寄存器查看:
这里设置值为0x14131440
第4步:设置PLLL的倍频系数(M、P、S)并使能PLL,决定输入端24MHz的原始频率经倍频后能得到多大的时钟频率。
寄存器查看:
数据手册推荐的倍频系数的设置:
第5步:MUX开关置1,经PLL倍频后的时钟开始工作。
这里设置值为0x10001111。
clock.S:
#define CLOCK_START 0xE0100000
#define CLOCK_START 0xE0100000
#define CLK_SRC0_OFFSET 0x200
#define APLL_LOCK_OFFSET 0x0
#define MPLL_LOCK_OFFSET 0x8
#define CLK_DIV0_OFFSET 0x300
#define APLL_CON0_OFFSET 0x100
#define APLL_MDIV 0x7d
#define APLL_PDIV 0x3
#define APLL_SDIV 0x1
#define set_apll(mdiv , pdiv , sdiv) (1<<31 | mdiv<<16 | pdiv<<8 | sdiv<<0)
#define SET_APLL_DAT set_apll(APLL_MDIV , APLL_PDIV , APLL_SDIV)
#define MPLL_CON0_OFFSET 0x108
#define MPLL_MDIV 0x29b
#define MPLL_PDIV 0xc
#define MPLL_SDIV 0x1
#define set_mpll(mdiv , pdiv , sdiv) (1<<31 | mdiv<<16 | pdiv<<8 | sdiv<<0)
#define SET_MPLL_DAT set_mpll(MPLL_MDIV , MPLL_PDIV , MPLL_SDIV)
.global _setclock
_setclock:
/*所有mux置0*/
ldr r0, =CLOCK_START
ldr r1, =0x0
str r1, [r0, #CLK_SRC0_OFFSET]
/*设置PLL锁定时间*/
ldr r1, =0xFFFF
str r1, [r0, #APLL_LOCK_OFFSET]
str r1, [r0, #MPLL_LOCK_OFFSET]
/*分频*/
ldr r1, =0x14131440
str r1, [r0, #CLK_DIV0_OFFSET]
/*设置PLL倍频,并使能PLL*/
ldr r1, =SET_APLL_DAT
str r1, [r0, #APLL_CON0_OFFSET]
ldr r1, =SET_MPLL_DAT
str r1, [r0, #MPLL_CON0_OFFSET]
/*部分mux置1*/
ldr r1, [r0, #CLK_SRC0_OFFSET]
ldr r2, =0x10001111
orr r1, r1, r2
str r1, [r0, #CLK_SRC0_OFFSET]
mov pc, lr
clock.c:
#define CLOCK_START 0xE0100000
#define CLK_SRC0_OFFSET 0x200
#define APLL_LOCK_OFFSET 0x0
#define MPLL_LOCK_OFFSET 0x8
#define CLK_DIV0_OFFSET 0x300
#define APLL_CON0_OFFSET 0x100
#define MPLL_CON0_OFFSET 0x108
#define rClock_Start *((volatile unsigned int*)(SET_CLOCK_START))
#define rCLK_SRC0 *((volatile unsigned int*)(SET_CLOCK_START+CLK_SRC0_OFFSET))
#define rAPLL_LOCK *((volatile unsigned int*)(SET_CLOCK_START+APLL_LOCK_OFFSET))
#define rMPLL_LOCK *((volatile unsigned int*)(SET_CLOCK_START+MPLL_LOCK_OFFSET))
#define rCLK_DIV0 *((volatile unsigned int*)(SET_CLOCK_START+CLK_DIV0_OFFSET))
#define rAPLL_CON0 *((volatile unsigned int*)(SET_CLOCK_START+APLL_CON0_OFFSET))
#define rMPLL_CON0 *((volatile unsigned int*)(SET_CLOCK_START+MPLL_CON0_OFFSET))
#define APLL_MDIV 0x7d
#define APLL_PDIV 0x3
#define APLL_SDIV 0x1
#define set_apll(mdiv , pdiv , sdiv) (1<<31 | mdiv<<16 | pdiv<<8 | sdiv<<0)
#define SET_APLL_DAT set_apll(APLL_MDIV , APLL_PDIV , APLL_SDIV)
#define MPLL_MDIV 0x29b
#define MPLL_PDIV 0xc
#define MPLL_SDIV 0x1
#define set_mpll(mdiv , pdiv , sdiv) (1<<31 | mdiv<<16 | pdiv<<8 | sdiv<<0)
#define SET_MPLL_DAT set_mpll(MPLL_MDIV , MPLL_PDIV , MPLL_SDIV)
void clock_test(void)
/*关mux*/
rCLK_SRC0 = 0;
/*设置PLL锁定时间*/
rAPLL_LOCK = 0xFFFF;
rMPLL_LOCK = 0xFFFF;
/*分频*/
rCLK_DIV0 = 0x14131440;
/*设置PLL倍频,并开PLL*/
rAPLL_CON0 = SET_APLL_DAT;
rMPLL_CON0 = SET_MPLL_DAT;
/*开mux*/
rCLK_SRC0 = 0x10001111;
以上是关于S5PV210的时钟系统的主要内容,如果未能解决你的问题,请参考以下文章