Uboot24之时钟初始化

时间:2018.4.6  作者:Tom   工作:HWE 说明:如需转载,请注明出处。已注明转载

在前面的lowlevel_init文章中,分析了一部分的时钟代码,但是感觉稀里糊涂的。今天专门把时钟的代码拿出来分析一下。

/*

* system_clock_init: Initialize core clock and bus clock.

* void system_clock_init(void)

*/

system_clock_init:

 

    ldr    r0, =ELFIN_CLOCK_POWER_BASE    @0xe0100000

#define     ELFIN_CLOCK_POWER_BASE        0xE0100000

从上图中可以看出使用的外部时钟均是24MHz的。

    /* Set Mux to FIN */1.时钟源使用外部晶振,

    ldr    r1, =0x0

    str    r1, [r0, #CLK_SRC0_OFFSET]     即所有时钟来源于外部时钟。

#define     CLK_SRC0_OFFSET            0x200

    ldr    r1,    =APLL_LOCKTIME_VAL

#define     APLL_LOCKTIME_VAL        0xe10

    str    r1,    [r0, #APLL_LOCK_OFFSET]

#define APLL_LOCK_OFFSET    0x00

将这个3600写入APLL_LOCK中。也就是分频系数设置成3600。

    /********lxg added*********************/

    ldr    r0, =ELFIN_CLOCK_POWER_BASE    @0xe0100000

#define     ELFIN_CLOCK_POWER_BASE        0xE0100000

    ldr    r1,    =MPLL_LOCKTIME_VAL

#define     MPLL_LOCKTIME_VAL            0xe10    

str    r1,    [r0, #MPLL_LOCK_OFFSET]

#define     MPLL_LOCK_OFFSET            0x04

和上面一样设置MPLL的分频系数为3600。但是0xE0100004这个寄存器在数据手册中属于保留的寄存器。没有用。

估计是后面加上的,我们不管。

    /********end*********************/

    /* Disable PLL */禁用PLL

#if defined(CONFIG_CHECK_MPLL_LOCK)

这个宏我们在X210_sd中定义了。不过是个空函数,可能只是做个标记而已。

retryloop:

#endif

继续分析—》

    ldr    r1, =0x0

    str    r1, [r0, #APLL_CON0_OFFSET]

#define     APLL_CON0_OFFSET            0x100

第31位设置为0,禁止APLL功能

    ldr    r1, =0x0

    str    r1, [r0, #MPLL_CON_OFFSET]

#define     MPLL_CON_OFFSET            0x108

这个功能一样的: 第31位设置为0,禁止MPLL功能

    ldr     r1, [r0, #CLK_DIV0_OFFSET]    1.读

#define     CLK_DIV0_OFFSET            0x300

    ldr    r2, =CLK_DIV0_MASK

#define     CLK_DIV0_MASK    0x7fffffff

    bic    r1, r1, r2    2.清零

将r1中的31位保留,其他均清0。

    ldr    r2, =CLK_DIV0_VAL

#define     CLK_DIV0_VAL     ((0<<APLL_RATIO)|(4<<A2M_RATIO)|(4<<HCLK_MSYS_RATIO)|(1<<PCLK_MSYS_RATIO)\

            |(3<<HCLK_DSYS_RATIO)|(1<<PCLK_DSYS_RATIO)|(4<<HCLK_PSYS_RATIO)|(1<<PCLK_PSYS_RATIO))

#define APLL_RATIO        0

#define A2M_RATIO        4

#define HCLK_MSYS_RATIO    8

#define PCLK_MSYS_RATIO    12

#define HCLK_DSYS_RATIO    16

#define PCLK_DSYS_RATIO     20

#define HCLK_PSYS_RATIO    24

#define PCLK_PSYS_RATIO     28

    orr    r1, r1, r2    3.改

对r1中的寄存器进行改。

    str    r1, [r0, #CLK_DIV0_OFFSET]    4.写

我们来看下结果:

ARMCLK = MOUT_MSYS

SCLKA2M = SCLKAPLL/5

HCLK_MSYS = ARMCLK/5

PCLK_MSYS = HCLK_MSYS/2

HCLK_DSYS = MOUT_DSYS/4

PCLK_DSYS = HCLK_DSYS/2

HCLK_PSYS = MOUT_PSYS/5

PCLK_PSYS = SCLK_PSYS/2

对照一下推荐的值:是一样的!!!

    ldr    r1, =APLL_VAL

#define APLL_VAL    set_pll(APLL_MDIV,APLL_PDIV,APLL_SDIV)

#define set_pll(mdiv, pdiv, sdiv)    (1<<31 | mdiv<<16 | pdiv<<8 | sdiv)

#elif defined(CONFIG_CLK_1000_200_166_133)

#define APLL_MDIV 0x7d

#define APLL_PDIV 0x3

#define APLL_SDIV 0x1    

使用的是推荐值:1G。

str    r1, [r0, #APLL_CON0_OFFSET]

#define APLL_CON0_OFFSET        0x100

设置ARMCLK为1G。

下面也就是设置MPLL和EPLL,VPLL

    ldr    r1, =MPLL_VAL

#define     MPLL_VAL    set_pll(MPLL_MDIV,MPLL_PDIV,MPLL_SDIV)

#define     set_pll(mdiv, pdiv, sdiv)    (1<<31 | mdiv<<16 | pdiv<<8 | sdiv)

#define MPLL_MDIV    0x29b

#define MPLL_PDIV    0xc

#define MPLL_SDIV    0x1

    str    r1, [r0, #MPLL_CON_OFFSET]

 

    ldr    r1, =VPLL_VAL

    str    r1, [r0, #VPLL_CON_OFFSET]

 

    /*******lxg added***********************/

    ldr    r1, =EPLL_VAL

    str    r1, [r0, #EPLL_CON_OFFSET]

这个查不到。

    /*******lxg added***********************/

    ldr     r1, [r0, #CLK_DIV1_OFFSET]

#define     CLK_DIV1_OFFSET            0x304

    ldr    r2, =CLK_DIV1_MASK

#define CLK_DIV1_MASK    0xffffffff

    bic    r1, r1, r2

清零。

    ldr    r2, =CLK_DIV1_VAL

#define     CLK_DIV1_VAL        ((1<<16)|(1<<12)|(1<<8)|(1<<4))

    orr    r1, r1, r2

    str    r1, [r0, #CLK_DIV1_OFFSET]

上述设置一样,但目前我们不给出结果,暂时用不到。下面一样的,都是设置一些分频系数。

    ldr     r1, [r0, #CLK_DIV2_OFFSET]

    ldr    r2, =CLK_DIV2_MASK

    bic    r1, r1, r2

 

    ldr    r2, =CLK_DIV2_VAL

    orr    r1, r1, r2

    str    r1, [r0, #CLK_DIV2_OFFSET]

 

    ldr     r1, [r0, #CLK_DIV4_OFFSET]

    ldr    r2, =CLK_DIV4_MASK

    bic    r1, r1, r2

 

    ldr    r2, =CLK_DIV4_VAL

#define     CLK_DIV4_VAL        0x99990000

    orr    r1, r1, r2

    str    r1, [r0, #CLK_DIV4_OFFSET]

 

    ldr     r1, [r0, #CLK_DIV6_OFFSET]

    ldr    r2, =CLK_DIV6_MASK

    bic    r1, r1, r2

 

    ldr    r2, =CLK_DIV6_VAL

    orr    r1, r1, r2

    str    r1, [r0, #CLK_DIV6_OFFSET]

上述是设置各种分频因子。对于特殊功能的时钟,我们需要的时候再看。

    /*******end*****************/

    /*******end*****************/

#if defined(CONFIG_EVT1)

我们在x210_sd.h中定义了。

    ldr    r1, =AFC_ON

#define     AFC_ON        0x00000000

    str    r1, [r0, #APLL_CON1_OFFSET]

#define     APLL_CON1_OFFSET        0x104

时钟校准。

#endif

    mov    r1, #0x10000

1:    subs    r1, r1, #1

    bne    1b

等待上述设置稳定,倒数65536个数。

#if defined(CONFIG_CHECK_MPLL_LOCK)

我们在x210_sd.h中定义了。

    /* MPLL software workaround */

    ldr    r1, [r0, #MPLL_CON_OFFSET]

#define     MPLL_CON_OFFSET            0x108

    orr r1, r1, #(1<<28)

    str    r1, [r0, #MPLL_CON_OFFSET]

将28位置1,不知道啥作用,不用管。打开上锁检测功能。

    mov    r1, #0x100

1:    subs    r1, r1, #1

    bne    1b

还是等待设置完成。

    ldr    r1, [r0, #MPLL_CON_OFFSET]

    and    r1, r1, #(1<<29)

    cmp    r1, #(1<<29)

    bne     retryloop

设置29位,将时钟锁定下来。

    /* H/W lock detect disable */

    ldr    r1, [r0, #MPLL_CON_OFFSET]

    bic r1, r1, #(1<<28)

    str    r1, [r0, #MPLL_CON_OFFSET]

将28位清0,不知道啥作用,不用管。禁用上锁检测功能。

#endif

 

    ldr    r1, [r0, #CLK_SRC0_OFFSET]

#define     CLK_SRC0_OFFSET            0x200

    //ldr    r2, =0x10001111 //lxg changed.

    ldr    r2, =0x00000111

    orr    r1, r1, r2

    str    r1, [r0, #CLK_SRC0_OFFSET]

打开时钟输出。

    // added by terry 2012.12.4 for camera

    ldr r1, [r0, #CLK_SRC1_OFFSET]

    bic r1, r1, #(0xf<<12)

    orr r1, r1, #(0x1<<12) //0001 XusbXTI

    str r1, [r0, #CLK_SRC1_OFFSET]

camera的时钟,我们暂时不分析。

 

#elif defined (CONFIG_MCP_SINGLE)

我们在x210_sd.h中定义了。

    /* CLK_DIV6 */

    /*ldr    r1, [r0, #CLK_DIV6_OFFSET]

    bic    r1, r1, #(0x7<<12)    @; ONENAND_RATIO: 0

    str    r1, [r0, #CLK_DIV6_OFFSET]*/ //lxg mask

没啥用,我们没有使用onenand。

#endif    

    mov    pc, lr

总结:

1.设置时钟源为外部晶振。

2.设置APLL,MPLL的分频系数。

3.设置各级子分频系数。

4.根据APLL获取主时钟的时钟频率ARMCLK为1G。

5.设置其他功能的分频系数。

6.等待设置稳定,上锁。

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值