0 原理
0.1 时钟源自哪里
所谓的时钟,就是电压高低的变化,只有不断的0,1交替变化,CPU才能被驱动运行。S3C2440支持多种时钟源,这通过CPU针脚OM3和OM3来选择。对于QT2440板子来说,OM3和OM2均直接接地,这就意味着时钟源来自针脚XTIpll和XTOpll,这两个针脚在TQ2440的核心板上被连接上了一个12MHz的晶振。
0.2 S3C2440的时钟原理与设置
CPU、RAM、UART等不同的设备运行时需要不同的时钟频率,这些不同的频率需要通过变频电路来提供,在电子行业这个变频电路叫做PLL(Phase Locked Loop)。作为软件出身的程序员,不太可能精通电路设计,只需要知道这个PLL可以把输入的时钟转换为很多其他不同的时钟供系统使用。
Fin(12MHz)——>(PLL变频)——–>FCLK、HCLK、PCLK
而输出频率和输入频率的关系则通过响应的寄存器进行控制。控制参数的设置在s3c2440数据手册上有详细说明。这里只列出特别需要注意的地方。
- If HDIVN is not 0, the CPU bus mode has to be changed from the fast bus mode to the asynchronous
bus mode using following instructions(S3C2440 does not support synchronous bus mode).
MMU_SetAsyncBusMode
mrc p15,0,r0,c1,c0,0
orr r0,r0,#R1_nF:OR:R1_iA
mcr p15,0,r0,c1,c0,0
If HDIVN is not 0 and the CPU bus mode is the fast bus mode, the CPU will operate by the HCLK.
This feature can be used to change the CPU frequency as a half or more without affecting the HCLK
and PCLK.
也就是说,S3C2440不支持异步总线模式(S3C2440A支持)。所以只能工作在fast bus模式下,此时如果HDIVN不是0的的话,驱动CPU工作的将不是FCLK,而是HCLK。
- FCLKOUT must be bigger than 200MHz (It does not mean that the ARM core has to run more than 200MHz).因为CPU可能以HCLK工作,如第一条所示。
- When you set MPLL&UPLL values, you have to set the UPLL value first and then the MPLL value. (Needs intervals
approximately 7 NOP。即是说,UPLL设置要在MPLL设置之前,切之间间隔至少7个NOP。
- 如果没有设置MPLL,那么CPU会一直以Fin的频率时钟运行。
- MPLL和UPLL的计算公式并不完全相同。
MPLL Control Register
Mpll = (2 * m * Fin) / (p * 2S)
m = (MDIV + 8), p = (PDIV + 2), s = SDIV
UPLL Control Register
Upll = (m * Fin) / (p * 2S)
m = (MDIV + 8), p = (PDIV + 2), s = SDIV
1 关键代码说明
尽管理论稍显复杂,实际设置代码非常简单。我们要设置的最终结果是:FCLK=200MHz,并且CPU以此来运行。当然可以根据手册上的数据,设置成更高的频率,只不过尝试后发现高频率下CPU发热明显,为保护好测试板子,采用了一个较低的FCLK。
/* Fin=12MHz, FCLK=200MHz */
.equ MPLLCON, 0x4c000004
.equ M_MDIV, 92
.equ M_PDIV, 4
.equ M_SDIV, 1
/* Fin=12MHz, UPLLCLK = 48MHz */
.equ UPLLCON, 0x4c000008
.equ U_MDIV, 56
.equ U_PDIV, 2
.equ U_SDIV, 2
/* HCLK=FCLK, PCLK=FCLK, UCLK=UPLLCLK */
.equ CLKDIVN, 0x4c000014
/*
if If HDIVN is not 0 and the CPU bus mode is the fast bus mode,
the CPU will operate by the HCLK
*/
.equ HDIVN, 0
.equ DIVN_UPLL, 0
.equ PDIVN, 0
ldr r0, =CLKDIVN
ldr r1, =(DIVN_UPLL<<3) + (HDIVN<<1) + PDIVN
str r1, [r0]
ldr r0, =UPLLCON
ldr r1, =(U_MDIV<<12) + (U_PDIV<<4) + U_SDIV
str r1, [r0]
nop
nop
nop
nop
nop
nop
nop
ldr r0, =MPLLCON
ldr r1, =(M_MDIV<<12) + (M_PDIV<<4) + M_SDIV
str r1, [r0]
2 测试说明
我们还是使用了与上一篇博文同样的一个LED流水灯C程序,不过由于CPU工作频率由12MHz提高到了200MHz,流水灯的速度较上一版本变化非常明显,这也直观上验证了我们设置CPU时钟成功了。
3 源码下载
版本v0.4。