[S5PV210] Clock
时钟域
S5PV210 clock划分3个域:
MSYS:Main System (200MHz)
DSYS:Display System (166MHz)
PSYS:Peripheral System (133MHz)
每个域又不同器件组成,每个域之间由异步的Birdge连接。如下图:
时钟源
S5PV210顶层的时钟源有4个,分别是:XRTCXTI、XXTI、XUSBXTI、XHDMIXTI,他们的频率和作用各不相同。
先看硬件电路图:
可以看到4个时钟源分别是2个24MHz、27MHz、32.768KHz,通过XRTCXTI、XXTI、XUSBXTI、XHDMIXTI这4根pin输入到S5PV210里面。
TODO:XRTCXTO、XXTO、XUSBXTO、XHDMIXTO作用是上电?
接着看一下4个时钟源进入S5PV210之后是怎么利用的:
首先,4个时钟源会被传送到RTC、System Timer、USB、HDMI等子系统中被使用;
除此之外,也有部分时钟源会被送入SYSCON(System Controller)里面,SYSCON会配置APLL、MPLL、VPLL、EPLL这些锁相环电路(倍频作用),并将时钟源输入到PLL中进行倍频,然后接收倍频后的clock,最后将这些clock分频,并输入到不同的子系统中。
在上图的右上角,可以看到一系列倍频和分频后的clock,大体分为3类:
ARMCLK:给CPU使用的时钟,最高可以达到1GHz,即CPU支持的最高频率。
(H/P)CLK_(M/D/P)SYS:H代表AHB、P代表APB。这6种clock可以对应 时钟域 章节的图看。
HCLK_MSYS = 200MHz;PCLK_MSYS = 100MHz;HCLK_DSYS = 166MHz;PCLK_DSYS = 83MHz;HCLK_PSYS = 133MHz;PCLK_PSYS = 66MHz (以上均为最大频率)
Special Clock:其它clock。
PLL、MUX、DIV
将一下时钟源从输入到SYSCON到输出一些列clock的过程,先看下图:
上图涉及到三种电路:
PLL:锁相环电路,用于倍频; MUX:选择电路; DIV:分频电路
根据SPEC的建议,几个PLL的功用如下:
APLL:提供MSYS的时钟,最高1GHz
MPLL:提供DSYS的时钟,最高2GHz
EPLL:提供Audio时钟
VPLL:提供Video时钟,54MHz
寄存器设定
PLL LOCK设定
当PLL的输入频率发生改变时,PLL需要一个lock time,根据PLL的寄存器参数不同,lock time也不同,相关寄存器:APLL_LOCK / MPLL_LOCK / EPLL_LOCK / VPLL_LOCK,使用默认值即可。
PLL设定
设定PLL的M、P、S参数,来决定倍频倍数。
参考SPEC:
DIV设定
(H/P)CLK_(M/D/P)SYS 的值之前已提到,根据上图中的公式计算即可。
MUX设定
这要根据上面的MUX图来设定,我们已经知道APLL提供MSYS的时钟,MPLL提供DSYS的时钟,其中:
A/M/E/VPLL_SEL:图中前半部分的MUX。
MUX_P/D/MSYS_SEL&ONENAND_SEL:图中后半部分的MUX。
Uboot Clock 初始化代码
#define APLL_CON (*(volatile unsigned int *)0xE0100100) #define MPLL_CON (*(volatile unsigned int *)0xE0100108) #define CLK_SRC0 (*(volatile unsigned int *)0xE0100200) #define CLK_DIV0 (*(volatile unsigned int *)0xE0100300) #define APLL_LOCK (*(volatile unsigned int *)0xE0100000) #define MPLL_LOCK (*(volatile unsigned int *)0xE0100008) /** * PLL - 只初始化 APLL 和 MPLL * APLL can drive MSYS domain and DSYS domain. It can generate up to 1 GHz, 49:51 duty ratio. * MPLL can drive MSYS domain and DSYS domain. It supplies clock, up to 2 GHz and 40:60 duty ratio. * EPLL is mainly used to generate audio clock. * VPLL is mainly used to generate video system operating clock, 54 MHz. * Typically, APLL drives MSYS domain and MPLL drives DSYS domain. */ /** * Values for the high-performance operation: * 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 */ void clock_init(void) { /* 1. 设置MUX,不使用PLL,待PLL设定完后再打开 */ CLK_SRC0 = 0; /* 2. 设置PLL_LOCK time: 时钟从Fin提升到Fout的时间, 使用默认值 */ APLL_LOCK = 0x00000FFF; MPLL_LOCK = 0x00000FFF; /** * 3. 设置 Divider * PCLK_PSYS_RATIO : [30:28] * PCLK_PSYS = HCLK_PSYS / (PCLK_PSYS_RATIO + 1) --> 66 = 133 / (PCLK_PSYS_RATIO + 1) * PCLK_PSYS_RATIO = 1 * HCLK_PSYS_RATIO : [27:24] * HCLK_PSYS = MOUT_PSYS / (HCLK_PSYS_RATIO + 1) --> 133 = 667 / (HCLK_PSYS_RATIO + 1) * HCLK_PSYS_RATIO = 4 * PCLK_DSYS_RATIO : [22:20] * PCLK_DSYS = HCLK_DSYS / (PCLK_DSYS_RATIO + 1) --> 83 = 166 / (PCLK_DSYS_RATIO + 1) * PCLK_DSYS_RATIO = 1 * HCLK_DSYS_RATIO : [19:16] * HCLK_DSYS = MOUT_DSYS / (HCLK_DSYS_RATIO + 1) --> 166 = 667 / (HCLK_DSYS_RATIO + 1) * HCLK_DSYS_RATIO = 3 * PCLK_MSYS_RATIO : [14:12] * PCLK_MSYS = HCLK_MSYS / (PCLK_MSYS_RATIO + 1) --> 100 = 200 / (PCLK_MSYS_RATIO + 1) * PCLK_MSYS_RATIO = 1 * HCLK_MSYS_RATIO : [10:8] * HCLK_MSYS = ARMCLK / (HCLK_MSYS_RATIO + 1) --> 200 = 1000 / (HCLK_MSYS_RATIO + 1) * HCLK_MSYS_RATIO = 4 * A2M_RATIO : [6:4] * SCLKA2M = SCLKAPLL / (A2M_RATIO + 1) --> (SCLKA2M<=400) = 1000 / (A2M_RATIO + 1) * A2M_RATIO = 3 * APLL_RATIO : [2:0] * ARMCLK = MOUT_MSYS / (APLL_RATIO + 1) --> 1000 = 1000 / (APLL_RATIO + 1) * APLL_RATIO = 0 */ CLK_DIV0 = (1 << 28) | (4 << 24) | (1 << 20) | (3 << 16) | (1 << 12) | (4 << 8) | (3 << 4) | (0 << 0); /* 4. 设置PLL */ /** * APLL: M=125, P=3, S=1 FOUT = (MDIV X FIN )/ (PDIV X 2 (SDIV-1) )) = 1000MHz * * ENABLED [31] : 1 = enable PLL controller * LOCKED [29] : 1 = LOCKED * MDIV [25:16] : 125 * PDIV [13:8] : 3 * SDIV [2:0] : 1 */ APLL_CON = (1 << 31) | (1 << 29) | (125 << 16) | (3 << 8) | (1 << 0); /** * MPLL: M=667, P=12, S=1 FOUT = (MDIV X FIN) / (PDIV X 2 SDIV ) = 667MHz * * ENABLED [31] : 1 = enable PLL controller * VSEL [27] : 0 * MDIV [25:16] : 667 * PDIV [13:8] : 12 * SDIV [2:0] : 1 */ MPLL_CON = (1 << 31) | (0 << 27) | (667 << 16) | (12 << 8) | (1 << 0); /** * 5. 设置MUX,选择PLLout * 下面4位表示MSYS,DSYS,PSYS选择哪个PLL作为输入原 * ONENAND_SEL [28] : 1 * MUX_PSYS_SEL [24] : 0 * MUX_DSYS_SEL [20] : 0 * MUX_MSYS_SEL [16] : 0 * 下面4位表示是否使用倍频后的时钟信号(PLL) * VPLL_SEL [12] : 1 * EPLL_SEL [8] : 1 * MPLL_SEL [4] : 1 * APLL_SEL [0] : 1 */ CLK_SRC0 = (1 << 28) | (1 << 12) | (1 << 8) | (1 << 4) | (1 << 0); }