第十章 时钟
时钟是同步工作系统的同步节拍。
SOC内部有很多器件,比如CPU,串口,DRAM控制器,GPIO等内部外设,这些参数要彼此协同能力,需要一个同步的时钟系统来指挥。这个就是SOC的时钟系统。
时钟的获取:
◾外部直接输入时钟信号,soc有引脚用来输入内部时钟信号。
◾外部晶振+内部时钟信号发生器产生时钟。
◾外部晶振+内部时钟发生器+内部PLL产生高频时钟+内部分频器分频得到各种频率时钟。
因为SOC内部有很多器件都需要时钟,而且各自需要的时钟频率不一样,没法统一供应。因此设计思路是PLL后先得到一个最高的频率(1Ghz,1.2Ghz),然后外设使用自己的分频器再来分频得到外设需要的始终频率。
时钟和外设编程的关联:
每个外设工作都需要一定频率的时钟,这些时钟都是由时钟系统提供的。时钟系统可以编程控制工作模式,因此我们程序员可以为每个外设指定时钟来源、时钟分频系统、可以制定这个外设的工作时钟。
这一章代码,查看我的github网站: https://github.com/weiqi7777/...
1、210的时钟域
有3个时钟域:
1) MSYS(主系统):提供时钟给内核,DRAM控制器(DMC0,DMC1),3D,内部SRAM(IROM,IRAM),INTC和配置接口(SPERI)。Cortex-A8只支持同步模式,因为必须工作在同步的200MHZ的AXI总线模式。
2) DSYS(显示系统):提供时钟给和显示有关的模块,如FIMC,FIMD,JPEG和多媒体IP。也就是和视频显示、编解码等有关的模块。
3) PSYS(外设系统):提供时钟给安全,I/O外设(SD接口,IIC,串口等),低功耗的音频播放(AC97)。
每种总线工作在200M(最大),166M,133M。两个时钟域间,使用的是异步总线桥(BRG)。
2、210的时钟来源
210的时钟,有多个来源:
2.1 Clocks from clock pads
时钟从时钟管脚上来。以下是提供的时钟管脚。
从图上看出,有4个时钟发生器,RTC,system timer,USB PHY, HDMI PHY。外部的4个时钟,只需要提供XUSBXTI和XRTCXTI两个时钟源就可以让210工作了。
对于X210开发板,外接的是XUSBXTI和XRTCXTI。因此需要将SYSCON中的选择器设置为1,表示选择XUSBXTI作为后面PLL的输入原始时钟源。原始时钟源经过PLL后产生倍频后的高频时钟。高频时钟再经过分频到达芯片个模块上。
2.2 Clocks from cmu
CMU通过外部时钟输入,4个PLL,USB PHY, HDMI PHY产生内部的时钟。
推荐对于4个PLL的输入时钟源频率是24M。
对于210来说,
◾内核和MSYS时钟域使用APLL(也就是ARMCLK,HCLK_MSYS,和PCLK_MSYS)
◾DSYS和PSYS时钟域(也就是HCLK_DSYS,HCLK_PSYS,PCLK_DSYS,PCLK_PSYS)和其他的外设时钟(也就是音频IP,SPI等等)使用MPLL和EPLL。
◾视频时钟使用VPLL
2.3 时钟之间的关系
时钟有以下的一些关系
3个时钟域:
1) MSYS域
ARMCLK: CPU内核工作的时钟,也就是所谓的主频(重要)
HCLK_MSYS: MSYS域的高频时钟,给DMC0和DMC1使用(也很重要)
PCLK_MSYS: MSYS域的低频时钟
HCLK_MSYS: 给IROM,IRAM(合称IMEM)使用
2) DSYS域
HCLK_DSYS : DSYS域的高频时钟
PCLK_DSYS : DSYS域的低频时钟
3) PSYS域
HCLK_PSYS : PSYS域的高频时钟
PCLK_PSYS : DSYS域的低频时钟
SCLK_ONENAND : 提供给ONENAND的时钟
210内部的各个外设都是接在(内部AMBA总线)总线上面的,AMBA总线有一条高频分支叫AXI,有一条低频分支叫APB。上面的各个域都由各自对应的HCLK_XXX和PCLK_XXX,其中HCLK_XXX就是XXX这个域中AXI总线的工作频率;PCLK_XXX就是XXX这个域中APB总线的工作频率。
Soc内部的各个外设其实是挂在总线上工作,也就是说这个外设的时钟来自于他挂载的总线,比如串口UART是挂在PSYS域下的APB总线上,因此串口的时钟来源是PCLK_PSYS。
各时钟默认值(IROM中设置的值)
1) 210刚上电时,默认是外部晶振+内部时钟发生器产生的24MHz的频率的时钟直接给ARMCLK的,这时系统的主频是24MHz,运行非常慢。
2) IROM代码执行第6步中初始化了时钟系统,这时给了系统一个默认推荐运行频率。这个时钟频率是三星推荐的210的工作性能和稳定性最佳的频率
2.4 推荐的时钟运行频率
以下是210的推荐时钟,我们程序开发,最好选择210推荐的时钟设置。
APLL的设置推荐值列表:
MPLL的设置推荐值列表:
EPLL的设置推荐值列表:
VPLL的设置推荐值列表:
3、210的时钟体系框图
时钟体系框图(361页),得到三个时钟域的各个时钟。
从这张图,可以从原始时钟选择->PLL倍频后得到的高频时钟->初次分频得到各总线时钟。
图中灰色的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的输出频率很不稳定,因此,ARM core的工作也是很不稳定的,为了解决这个问题,210提供LOCK_TIME(锁定时间)模块(设置相应的LOCK_TIME寄存器可以设定锁定的时间长度),当PLL控制寄存器的值发生改变时,系统会锁定ARM core,锁定时CPU不工作,因此锁定模块会根据LOCK_TIME设定的值进行计时,计时完成后CPU才会继续工作。
因此,在设定PLL前,MUX不能选择PLL的输出作为输入。在设置PLL参数及开启后,CPU会暂停工作,直到PLL锁定时间到达后,CPU继续工作,所以程序中,不用查询PLL是否锁定结束。CPU一旦继续工作,说明PLL锁定结束,就可以切换MUX选择PLL作为输入了。因为PLL后的MUX都是毛刺不敏感的MUX,所以可以直接选择,也不用检测MUX是否选择成功。
还有一个需要注意的是,选通MUX的PLL输入之前,要先设置各个分频器的分频值。
4、寄存器
对于XPLL_LOCK对应XXX的PLL锁定时间配置。这个PLL的LOCK寄存器配置PLL的锁定时间。即将输入时钟给倍频到输出的稳定时钟需要的时间。
对于XPLL_CON,对PLL进行配置的以及获取PLL的锁定状态
计算的公式如下,可以看出和CON寄存器的M,P,S参数有关。
CLK_SRCn(n:0-6),设置时钟体系框图的MUX的时钟选择。
通过配置寄存器,来设置MUX的选择。
CLK_SRC_MASKx(x = 0-1),用来配置MUX输出的时钟是否有效的。主要是配置外设的时钟,默认都是开启的。当不需要使用一些外设的时候,要将对应外设的时钟给关闭掉,以节省功耗。
CLK_DIVn(n=0-7),设置各模块的分频器的分频系数,用来对源时钟分频,得到各个时钟。
通过配置寄存器的参数,可以得到各个时钟
CLK_GATE_SCLK,配置SCLK_FIMC_LCLK时钟是否有效。
CLK_GATE_IPx(x=0-4)时钟的门控开关,控制某些输出时钟是否时能,默认为都是使能的。
CLK_DIV_STATn(n = 0-1),查看DIV分频器的状态。
查看寄存器对应位的值,为0表示分频出来的时钟是稳定的。当要使用一个分频时钟,需要检查分频时钟是否稳定。
CLK_MUX_STATn(n=0-1) MUX的输出时钟选择是否稳定。
查看寄存器的对应位的值,为对应的值,表示选择时钟稳定。
输出时钟选择:
内部的时钟是可以通过CLK_OUT寄存器配置输出到一个管脚XCLKOUT_PAD上的。输出时钟的频率为:
输出时钟的波形:
以上的寄存器,最重要的寄存器有3类,CON、SRC、DIV。其中CON决定PLL倍频到多少,SRC决定时钟走哪一路,DIV决定分频多少。
5、汇编代码的时钟设置步骤
1) 先选择不使用PLL,让外部24M原始时钟直接过去,绕过PLL。
2) 设置锁定时间,默认值是0X0FFF,保险起见可以设置为0XFFFF。
3) 设置分频系数,决定由MUX出来的时钟如何分频得到各个时钟
4) 设置PLL并打开PLL,设置PLL的倍频系数,决定由输入时钟的24M得到多大的PLL输出频率。
5) 在设置时钟选择寄存器,使MUX的输入源为PLL的输出。
系列其他篇
原文首发于骏的世界博客
作者:卢骏.
更多Arm技术相关的文章请关注Arm技术博客极术专栏,每日更新。