ARM 裸机之时钟系统

时钟系统的基本概念,时钟的作用、来源,SoC的时钟体系

时钟系统的基本概念,时钟的作用、来源,SoC的时钟体系

SoC时钟系统简介

什么是时钟?SoC为什么需要时钟?

时钟是同步工作系统的同步节拍。SoC内部有很多器件,譬如CPU、串口、DRAM控制器、GPIO等内部外设,这些东西要彼此协同工作,需要一个同步的时钟系统来指挥。这个就是我们SoC的时钟系统。

时钟一般如何获得

  • 外部直接输入时钟信号,SoC有个引脚用来输入外部时钟信号,用的很少。
  • 外部晶振+内部时钟发生器产生时钟,大部分低频单片机都是这么工作的。
  • 外部晶振+内部时钟发生器+内部PLL产生高频时钟+内部分频器分频得到各种频率的时钟,210属于这种。

为什么这么设计?

因为芯片外部电路不适宜使用高频率,因为传导辐射比较难控制;高频率的晶振太贵了。SoC内部有很多部件都需要时钟,而且各自需要的时钟频率不同,没法统一供应。因此设计思路是PLL后先得到一个最高的频率(1GHz、1.2GHz),然后各外设都有自己的分频器再来分频得到自己想要的频率。

时钟和外设的关联

每个外设工作都需要一定频率的时钟(节拍),这些时钟都是由时钟系统提供的。时钟系统可以编程控制工作模式,因此我们程序员可以为每个外设指定时钟来源、时钟分频系统、从而制定这个外设的工作时钟。开关外设不是通过开关,而是通过时钟。也就是说我们给某个外设断掉时钟,这个外设就不工作了。

S5PV210的时钟系统简介

时钟域:MSYS、DSYS、PSYS

因为S5PV210的时钟体系比较复杂,内部外设模块太多,因此把整个内部的时钟划分为3大块,叫做3个域。它们分别是:主系统(MSYS: main system)、显示系统(DSYS:display system) 和外设系统(PSYS: peripheral system)。因为210内部的这些模块彼此工作时钟速率差异太大了,所以有必要把高速的放一起,相对低速的放一起。

  • MSYS域包括Cortex A8处理器、DRAM内存控制器(DMC0和DMC1)、3D、内部SRAM(IRAM和IROM)、INTC和配置接口(SPERI)。Cortex A8只支持同步模式,因此必须与200MHz AXI总线同步运行。
  • DSYS域包括显示相关模块,包括FIMC、FIMD、JPEG和多媒体IP(X、L和T块中提到的所有其他IP),如图3-1所示。
  • PSYS: PSYS域用于安全、低功耗音频播以及内部的各种外设时钟有关,譬如串口、SD接口、I2C、AC97、USB等。
  • 每个总线系统的工作频率分别为200兆赫(最大值)、166兆赫和133兆赫。在两个不同的域之间存在异步总线桥(BRG)。

clock

时钟分类

class

图3-2显示了S5PV210中时钟的分类。S5PV210中的顶层时钟包括:

  • 来自时钟电路板的时钟,即XTCXTI、XXTI、XUSBXTI和XHDMIXTI。
  • 来自CMU的时钟(如ARMCLK、HCLK、PCLK等)。
  • 来自USB PHY的时钟
  • 来自GPIO电路板的时钟

来自 CMU 的时钟

CMU利用来自时钟电路板(即XTCXTI、XXTI、XUSBXTI和XHDMIXTI)的时钟源、四个PLL(即APLL、MPLL、EPLL、EPL和VPLL)、USB PHY和HDMI PHY时钟产生中间频率的内部时钟。其中一些时钟可以选择、预分频,并提供给相应的模块。

建议APLL、MPLL、EPL和VPLL使用24MHz输入时钟源。

为了生成内部时钟,使用了以下组件:

  • APLL使用FINPLL(参考图3-1)作为输入,产生30MHz~1GHz。
  • MPLL使用FINPLL作为输入,产生50MHz~2GHz。
  • EPLL使用FINPLL作为输入,产生10MHz~600MHz。
  • VPLL使用FINPLL或SCLK_HDMI27M作为输入,产生10MHz~600MHz。该PLL产生54MHz的视频时钟。
  • USB OTG PHY使用XUSBXTI产生30MHz和48MHz的视频时钟。
  • HDMI PHY使用XUSBXTI或XHDMIXTI来产生54MHz的音频信号。

在典型的S5PV210应用中:

  • Cortex A8和MSYS时钟域使用APLL(即ARMCLK、HCLK_MSYS和PCLK_MSYS)。
  • DSYS和PSYS时钟域(即HCLK_DSYS、HCLK_PSYS、PCLK_DSYS、PCLK_PSYS)和其他外设时钟(即音频IP、SPI等)使用MPLL和EPLL。
  • 视频时钟使用的是VPLL。

时钟的产生

class

图3-3是时钟产生逻辑框图。外部晶振时钟与振荡放大器相连。PLL将低输入频率转换为S5PV210所需的高频时钟。由于时钟在稳定之前需要一定的时间,时钟产生器块还包括一个内置的逻辑,在每次系统复位后以稳定时钟频率。

图中灰色的MUX,是毛刺不敏感的,也就是当MUX选择改变后,输出是马上稳定的。而对于白色的MUX,是毛刺敏感的,当MUX选择改变后,输出会产生毛刺,不稳定。

对于白色的MUX,要改变选择的时候,要保证待选择的几个时钟源是运行稳定的,不然的话,输出选择不完全,输出的时钟会出现未知的状态。

白色的MUX有两个,一个由XOM[0]管脚控制,这个我们不用关心,因为这是硬件做好的。另外一个就是MUXVPLLSRC,这个MUX由CLK_SRC1[28]位决定。而这个默认值是0,也就是选择FINPLL,如果要切换该MUX的时钟选择的话,就需要将MUXVPLLSRC的输出给禁止,然后切换选择,然后再重新使能MUXVPLLSRC的输出使能。

对于白色的MUX,要改变选择的时候,要使MUX的输出不使能,然后改变MUX的选择,当选择完毕后,再重新使能MUX的输出

1、 设置XOM[0](这个是硬件的一个管脚,在上电的时候,210会读取这个管脚的值,判断外部时钟源是哪一个)为1,使FINpll选择外部时钟XUSBXTI

2、 设置APLL,MOLL,EPLL,VPLL的倍频值

3、 设置FINvpll,使VPLLSRC选择外部时钟XUSBXTI

4、 配置MUXAPLL,MUXMPLL,MUXEPLL,MUXVPLL,使SCLKAPLL选择FOUTAPLL,使SCLKMPLL选择FOUTMPLL,使SCLKEPLL选择FOUTEPLL,使SCLKVPLL选择FOUTVPLL。就是选择PLL的输出时钟为下一级的时钟输入源。

5、 对于MSYS时钟域,设置MOUTMSYS为0,选择SCLKAPLL,设置DIVAPLL,使ARMCLK的时钟频率为1000M。

6、 根据MSYS时钟域的各个时钟需要,设置DIVHCLKM(分频系数为5),DIVPCLKM­(分频系数为2),DIVIMEM­(分频系数为2)的分频系数,得到MSYS域的时钟,得到的结果就是HCLK_MSYS为200M,PCLK_MSYS为100M,HCLK_IMEM为100M为。

7、 对于DSYS域,设置MOUTDSYS为0,使DSYS域的时钟来源是SCLKMPLL。再配置后面的DIVHCLKD和DIVPCLKD的分频系数,得到DSYS域的两个时钟。

8、 对于PSYS域,设置MOUTPSYS为0,使PSYS域的时钟来源是SCLKMPLL。再配置后面的分频系数及MOUTFLASH为0就可以得到PSYS域的各个时钟了。

9、 再需要其他时钟,相应配置即可

为了系统稳定,设计电路一般不会使用太高频率的晶振(避免高频线间/层间干扰),但是,S5PV210的内核需要的工作频率很高(最高可以达到1G),这种情况下,通常是通过锁相环(PLL)来对外部时钟源进行倍频,然后供内核使用。因此,在210中提供了4个PLL,分别是APLL,MPLL,EPLL,VPLL,通过配置210提供的锁相环控制寄存器可以设置PLL的倍频系数,使内核工作频率达到800M或者1G。需要注意的是PLL设置完成之后并不能立刻稳定的工作,需要一个起振过程,在这段时间内PLL的输出频率很不稳定,因此,内核的工作也是很不稳定的,为了解决这个问题,210提供LOCK_TIME(锁定时间)模块(设置相应的LOCK_TIME寄存器可以设定锁定的时间长度),当PLL控制寄存器的值发生改变时,系统会锁定内核,锁定内核时CPU不工作,因此锁定模块会根据LOCK_TIME设定的值进行计时,计时完成后CPU才会继续工作。

​ 因此,在设定PLL前,MUX不能选择PLL的输出作为输入。在设置PLL参数及开启后,CPU会暂停工作,直到PLL锁定时间到达后,CPU继续工作,所以程序中,不用查询PLL是否锁定结束。CPU一旦继续工作,说明PLL锁定结束,就可以切换MUX选择PLL作为输入了。因为PLL后的MUX都是毛刺不敏感的MUX,所以可以直接选择,也不用检测MUX是否选择成功。

​ 还有一个需要注意的是,选通MUX的PLL输入之前,要先设置各个分频器的分频值。

时钟来源

晶振+时钟发生器+PLL+分频电路

S5PV210外部有4个晶振接口,设计板子硬件时可以根据需要来决定在哪里接晶振。接了晶振之后上电相应的模块就能产生振荡,产生原始时钟。原始时钟再经过一系列的筛选开关进入相应的PLL电路生成倍频后的高频时钟。高频时钟再经过分频到达芯片内部各模块上。(有些模块,譬如串口内部还有进一步的分频器进行再次分频使用)

S5PV210 中的 PLL 包括:

  • APLL:Cortex-A8内核 MSYS域
  • MPLL&EPLL:DSYS PSYS
  • VPLL:Video视频相关模块

S5PV210时钟域详解

MSYS域

时钟域 功能
ARMCLK 给cpu内核工作的时钟,也就是所谓的主频
HCLK_MSYS MSYS域的高频时钟,给DMC0和DMC1使用
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_XXXPCLK_XXX ,其中 HCLK_XXX 就是XXX这个域中AHB总线的工作频率;PCLK_XXX 就是XXX这个域中APB总线的工作频率。

SoC内部的各个外设其实是挂在总线上工作的,也就是说这个外设的时钟来自于他挂在的总线,譬如串口UART挂在PSYS域下的APB总线上,因此串口的时钟来源是 PCLK_PSYS。 我们可以通过记住和分析上面的这些时钟域和总线数值,来确定我们各个外设的具体时钟频率。

各时钟典型值

  • 当210刚上电时,默认是外部晶振+内部时钟发生器产生的24MHz频率的时钟直接给ARMCLK的,这时系统的主频就是24MHz,运行非常慢。

  • iROM代码执行时第6步中初始化了时钟系统,这时给了系统一个默认推荐运行频率。这个时钟频率是三星推荐的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
    

S5PV210时钟体系框图详解

S5PV210时钟体系局部框图如下

pll

分析

  • 时钟系统从左到右依次完成了原始时钟生成->PLL倍频得到高频时钟->初次分频得到各总线时钟
  • 2个符号很重要:一个是MUX开关,另一个是DIV分频器。
    • MUX开关就是个复用开关
    • DIV分频器,是一个硬件设备,可以对左边的频率进行n分频,分频后的低频时钟输出到右边。
    • 寄存器中的clock source x就是在设置MUX开关;clock divider control寄存器就是在设置分频器分频系数。

时钟设置的关键性寄存器

  • xPLL_LOCK`

    ``xPLL_LOCK` 寄存器主要控制PLL锁定周期的。

  • xPLL_CON/xPLL_CON0/xPLL_CON1

    PLL_CON` 寄存器主要用来打开/关闭PLL电路,设置PLL的倍频参数,查看PLL锁定状态等.

  • CLK_SRCn(n:0~6)

    CLK_SRC 寄存器是用来设置时钟来源的,对应时钟框图中的MUX开关。

  • CLK_SRC_MASKn

    CLK_SRC_MASK 决定MUX开关n选1后是否能继续通过。默认的时钟都是打开的,好处是不会因为某个模块的时钟关闭而导致莫名其妙的问题,坏处是功耗控制不精细、功耗高。

  • CLK_DIVn

    各模块的分频器参数配置

  • CLK_GATE_x

    类似于 CLK_SRC_MASK,对时钟进行开关控制

  • CLK_DIV_STATnCLK_MUX_STATn

    这两类状态位寄存器,用来查看DIV和MUX的状态是否已经完成还是在进行中

总结:其中最重要的寄存器有3类:CON、SRC、DIV。其中CON决定PLL倍频到多少,SRC决定走哪一路,DIV决定分频多少。

汇编实现时钟设置代码详解

时钟设置的步骤分析:

第1步:先选择不使用PLL。让外部24MHz原始时钟直接过去,绕过APLL那条路

第2步:设置锁定时间。默认值为0x0FFF,保险起见我们设置为0xFFFF

第3步:设置分频系统,决定由PLL出来的最高时钟如何分频得到各个分时钟

第4步:设置PLL,主要是设置PLL的倍频系统,决定由输入端24MHz的原始频率可以得到多大的输出频率。我们按照默认设置值设置输出为ARMCLK为1GHz

第5步:打开PLL。前面4步已经设置好了所有的开关和分频系数,本步骤打开PLL后PLL开始工作,锁定频率后输出,然后经过分频得到各个频率。

CLK_SRC寄存器的设置分析

CLK_SRC寄存器其实是用来设置MUX开关的。在这里先将该寄存器设置为全0,主要是bit0和bit4设置为0,表示APLL和MPLL暂时都不启用。

CLK_LOCK寄存器的设置分析

设置PLL锁定延时的。官方推荐值为0xFFF,我们设置为0xFFFF。

APLL和MPLL设置的关键都是M、P、S三个值,这三个值都来自于官方数据手册的推荐值

推荐《cortex-a8裸机系列:第十章 时钟》