汇编实现时钟设置代码详解:
经过前面的基础了解,现在开始用汇编来初始化时钟(我们这里只是比较简单的设置相应的寄存器来进行初始化,主要目的就是为了通过S5PV210数据手册来分析时钟系统初始化过程)。
代码如下:
// 时钟控制器基地址
#define ELFIN_CLOCK_POWER_BASE 0xE01000000
// 时钟相关的寄存器相对时钟控制器基地址的偏移值
#define APLL_LOCK_OFFSET 0x00
#define MPLL_LOCK_OFFSET 0x08
#define APLL_CON0_OFFSET 0x100
#define APLL_CON1_OFFSET 0x104
#define MPLL_CON_OFFSET 0x108
#define CLK_SRC0_OFFSET 0x200
#define CLK_SRC1_OFFSET 0x204
#define CLK_SRC2_OFFSET 0x208
#define CLK_SRC3_OFFSET 0x20c
#define CLK_SRC4_OFFSET 0x210
#define CLK_SRC5_OFFSET 0x214
#define CLK_SRC6_OFFSET 0x218
#define CLK_SRC_MASK0_OFFSET 0x280
#define CLK_SRC_MASK1_OFFSET 0x284
#define CLK_DIV0_OFFSET 0x300
#define CLK_DIV1_OFFSET 0x304
#define CLK_DIV2_OFFSET 0x308
#define CLK_DIV3_OFFSET 0x30c
#define CLK_DIV4_OFFSET 0x310
#define CLK_DIV5_OFFSET 0x314
#define CLK_DIV6_OFFSET 0x318
#define CLK_DIV7_OFFSET 0x31c
#define CLK_DIV0_MASK 0x7fffffff
// 上面这些都是我们下面用到的时钟设置相关的寄存器宏定义
// 结合之前的文章中关于时钟系统的框图我们来往寄存器写值
// 这三个宏可以让FOUTAPLL 输出1000MHz(值的相关设置我们可以参考S5PV210数据手册)
#define APLL_MDIV 0x7d
#define APLL_PDIV 0x3
#define APLL_SDIV 0x1
// 这三个宏可以让FOUTMPLL 输出667MHz
#define MPLL_MDIV 0x29b
#define MPLL_PDIV 0xc
#define MPLL_SDIV 0x1
// 这三个宏相当于将上面的宏定义值经过位或后合成一个值然后好写进响应的寄存器
// 里面相应的位设置可以查看相应寄存器。
#define set(mdiv,pdiv,sdiv) (1<<31 | mdiv<<16 | pdiv<<8 | sdiv)
#define APLL_VAL set_pll(APLL_MDIV | APLL_PDIV | APLL_SDIV)
#define MPLL_VAL set_pll(MPLL_MDIV | MPLL_PDIV | MPLL_SDIV)
.global clock_init
clock_init:
ldr r0, =ELFIN_CLOCK_POWER_BASE
// 1.设置各种时钟开关,暂时不使用PLL,此时使用主频为FINpll 24MHz
ldr r1, =0x0
str r1,[r0,#CLK_SRC0_OFFSET]
// 2. 设置锁定时间,默认值为0xfff,我们这里使用0xffff
// 设置PLL后,时钟从FINpll提升到目标频率需要一定的时间,这段时间即所说的锁定时间
ldr r1, =0x0000ffff
str r1,[r0, #APLL_LOCK_OFFSET]
str r1,[r0, #MPLL_LOCK_OFFSET]
// 3. 设置分频,先给寄存器位全清0,然后把DIV0寄存器写入0x14131440
ldr r1, [r0, #CLK_DIV0_OFFSET]
ldr r2, =CLK_DIV0_MASK
bic r1,r1,r2
ldr r2, =0x14131440
orr r1,r1,r2
str r1,[r0, #CLK_DIV0_OFFSET]
// 4. 设置PLL,经过倍频后,生成相应的时钟频率
// 设置APLL
ldr r1, =APLL_VAL
str r1, [r0, #APLL_CON0_OFFSET]
// 设置MPLL
ldr r1, =MPLL_VAL
str r1, [r0, #MPLL_CON_OFFSET]
// 5.上面关于PLL设置完毕后,最后使用PLL转换后的时钟频率
ldr r1,[r0,#CLK_SRC0_OFFSET]
ldr r2, =0x10001111
orr r1,r1,r2
str r1,[r0,#CLK_SRC0_OFFSET]
mov pc,lr