我们打算将ARM内核时钟设置为官方推荐的稳定的533MHz,让APLL为AHB,APB输出工作频率。让MPLL为UART等外设提供工作频率,EPLL不工作。同时设置HCLKX2 为266MHz,HCLK为133MHz,PCLK为66.5MHz,UART工作时钟为66.5MHz。
1. 选择HCLKX2, HCLK, PCLK的时钟源,由图1-2可知其时钟源可以通过OTHER[6]选择是由DOUT_APLL还是MOUT_MPLL,我们选择从DOUT_APLL。
ldr r0, =CLOCK_BASE ;0x7e00f000
ldr r1, [r0, #OTHERS_OFFSET] ; 选择MPLL的时钟源
mov r2, #0x40
orr r1, r1, r2
str r1, [r0, #OTHERS_OFFSET]
nop
nop
nop
nop
; 选择CPU的同步工作模式
ldr r2, =0x80
orr r1, r1, r2
str r1, [r0, #OTHERS_OFFSET]
; 测试是否已经工作在同步模式下
check_syncack
ldr r1, [r0, #OTHERS_OFFSET]
ldr r2, =0xf00
and r1, r1, r2
cmp r1, #0xf00
bne check_syncack
2. 设置变频锁定时间,当系统时钟修改之后要经过段LOCK时间
; 设置变频锁定时间
mov r1, #0xff00
orr r1, r1, #0xff
str r1, [r0, #APLL_LOCK_OFFSET]
str r1, [r0, #MPLL_LOCK_OFFSET]
str r1, [r0, #EPLL_LOCK_OFFSET]
3. 设置ARMCLK, HCLKX2, HCLK, PCLK的分频
各种频率的关系如图1-3所述:
APLL或MPLL产生的输出频率经过OTHER[6]选择之后再经过MISC_CON[19]选择是否被1/5分频,产生的输出频率进入DIV_HCLKx2,根据CLK_DIV0的不同位设置HCLKX2,HCLK,PCLK,CLKJPEG,CLKSECUR的输出频率。其值设置情况如CLK_DIV0寄存器描述内容所述。
l 我们将MPLL选择DOUT_APLL,MISC_ON[19]不进行分频,DOUT_APLL产生的时钟(533MHz)直接进入到DIV_HCLKX2分频器中。
l 根据硬件手册可知,HCLKX2的频率固定为266MHz,所以HCLKX2_RATIO设置为0b1
l HCLK上挂接有内存,Mobile DDR内存最高工作在133MHz,所以HCLK最高主频设置为HCLKX2的1/2,即:HCLK_RATIO = 0b1
l 设置PCLK上的工作频率为66.5MHz,即:PCLK_RATIO = 0b11
l 设置ARM内核工作频率为553MHz,即:ARM_RATIO = 0b0
l 设置DOUT_MPLL为266MHz,为后面UART提供时钟源,即:MPLL_RATIO = 0b0
l 其它时钟频率保持默认值
; MPLL_RATIO = 0<<4, ARM_RATIO = 0
; DOUT_MPLL = MOUT_MPLL/(MPLL_RATIO + 1)
; 即 ARMCLK = DOUT_APLL / (ARM_RATIO + 1)
; 即 ARMCLK = 533MHz, DOUT_MPLL = 266MHz
; HCLKX2_RATIO = 1<<9 , HCLK_RATIO = 1<<8, PCLK_RATIO = 3<<12, HCLKX2IN = 533
; 即 HCLKX2 = HCLKX2IN / (HCLKX2_RATIO + 1) = 266
; 即 HCLK = HCLKX2 / (HCLK_RATIO + 1) = 133
; 即 PCLK = HCLKX2 / (PCLK_RATIO + 1) = 66.5
ldr r1, [r0, #CLK_DIV0_OFFSET]
bic r1, r1, #0xff00
bic r1, r1, #0xff
ldr r2, =0x3300
orr r1, r1, r2
str r1, [r0, #CLK_DIV0_OFFSET]
4. 设置UART工作时钟
由图1-6可知,通过设置CLK_SRC[1]选择DOUT_MPLL的工作时钟是否进行倍频,通过设置CLK_DIV0[4]对时钟进行分频,再通过CLK_SRC[13]选择UART的工作时钟源,设置CLK_DIV2[19:16]位用于分频UART工作时钟。由前面可知DOUT_MPLL = 266MHz, UART选择其作为自己工作时钟源,则对其进行1/4分频可以得到66.5MHz。
如下表可知:设置寄存器CLK_DIV2[19:16] = 0b11,同时还要设置CLK_SRC[13] = 0b1即可。
; 设置UART串口的分频数寄存器CLK_DIV2
ldr r1, [r0, #CLK_DIV2_OFFSET]
bic r1, r1, #0x70000
orr r1, r1, #0x30000 ; 设置其值为3,即CLKUART = CLKUARTIN / 4
str r1, [r0, #CLK_DIV2_OFFSET]
5. 使能APLL,EPLL锁相环
根据硬件手册上的说明设置APLL, EPLL的M,D,S分频数。
APLL产生533MHz的FOUT_APLL
EPLL产生266MHz的MOUT_EPLL
; 使能APLL锁相环,配置M,D,S分频数, according to Datasheet FOUT_APLL = 533 then
; APLL_EN = 1<<31, MDIV = 266<<16, PDIV = 3<<8, SDIV = 1
ldr r1, = 0x810a0301
str r1, [r0, #APLL_CON_OFFSET]
; 使能MPLL锁相环,配置M,D,S分频数
; MPLL_EN = 1<<31, MDIV = 266<<16, PDIV = 3<<8, SDIV = 2
ldr r1, = 0x810a0302
str r1, [r0, #MPLL_CON_OFFSET]
6. 设置对应时钟源寄存器,为各种外设提供时钟频率
; UART_SEL = 0b1
; MPLL_SEL = 0b1, APLL_SEL = 0b1
ldr r1, [r0, #CLK_SRC_OFFSET]
ldr r2, =0x2005 ; 同时设置UART的时钟源来自MPLL
orr r1, r1, r2
str r1, [r0, #CLK_SRC_OFFSET]