德馨轩

斯是陋室,惟吾德馨。QQ:275000205

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
   最近正在看任哲《嵌入式操作系统基础》,里面的一节内容标题是:“操作系统的内核是由中断驱动的”,所以研究一个新的系统,首先要从系统时钟和定时器的实现开始。
   下面一段内容主要来自s3c6410数据手册:
   s3c6410的系统控制器(System Controller)分为两大部分组成,系统时钟控制器(System Clock Control)和系统电源管理控制器(System Powet-management Control).系统时钟控制器通过三个PLL(Phase Locked Loop锁相环)生成系统需要的时钟信号,如APLL仅生成用于cpu的ARMCLK,MPLL生成HCLK和PCLK(HCLK用于AXI/AHB总线外设,PCLK用于APB总线外设),EPLL生成的时钟主要用于外设IP,例如UART,IIS,IIC等。
   关于系统时钟的配置和使用,我们先从其调用接口来分析,切入实现文件:
   cpu\s3c64xx\s3c6410\speed.c
    我们这里先分析其使用,再分析其配置。
    这里实现了对外的接口:get_ARMCLK() get_FCLK() get_HCLK() get_PCLK() get_UCLK()
    除了print_cpuinfo函数调用之外,对外被用到的接口是get_HCLK和get_PCLK.
    用到get_HCLK的文件为cpu\s3c64xx\ata.c和cpu\s3c64xx\hs_mmc.c
    用到get_PCLK的文件为cpu\s3c64xx\i2c.c和cpu\s3c64xx\interrupts.c
    通过查看makefile,ata.c没有编译到。
    hs_mmc.c为高速mmc控制器(SD卡)相关功能,需要学习的相关文件为common\Cmd_movi.c和cpu\s3c64xx\movi.c,开启sd卡启动宏CONFIG_BOOT_MOVINAND后,初始化顺序为:start_armboot->movi_init->hsmmc_init
    i2c.c实现i2c,在CONFIG_HARD_I2C功能下,uboot下未进行i2c_init,后续实验来研究。
    Interrupts.c初始化顺序为:start_armboot->init_sequence[]->interrupt_init,initial PWM Timer ,uboot主干框架太简单了,只有一个主循环程序和一个定时器来检测输入超时则启动kernel,即reset_cmd_timeout使用到pwm的get_ticks和get_tbclk函数。

   此时再去看datasheet 3.4.2.1 PLL Control Registers  3.4.2.2 Clock Source Control Registers 3.4.2.3 Clock Divider Control Registers以及启动代码

 board\samsung\smdk6410\

lowlevel_init.S中system_clock_init:段代码,

 

  1 /*
  2  * system_clock_init: Initialize core clock and bus clock.
  3  * void system_clock_init(void)
  4  */
  5 system_clock_init:
  6     ldr    r0, =ELFIN_CLOCK_POWER_BASE    /* 0x7e00f000 */
  7 
  8 #ifdef CONFIG_SYNC_MODE
  9     ldr    r1, [r0, #OTHERS_OFFSET]
 10     mov    r2, #0x40
 11     orr    r1, r1, r2
 12     str    r1, [r0, #OTHERS_OFFSET]
 13 
 14     nop
 15     nop
 16     nop
 17     nop
 18     nop
 19 
 20     ldr    r2, =0x80
 21     orr    r1, r1, r2
 22     str    r1, [r0, #OTHERS_OFFSET]
 23 
 24 check_syncack:
 25     ldr    r1, [r0, #OTHERS_OFFSET]
 26     ldr    r2, =0xf00
 27     and    r1, r1, r2
 28     cmp    r1, #0xf00
 29     bne    check_syncack
 30 #else    /* ASYNC Mode */
 31     nop
 32     nop
 33     nop
 34     nop
 35     nop
 36 
 37     /*
 38      * This was unconditional in original Samsung sources, but it doesn't
 39      * seem to make much sense on S3C6400.
 40      */
 41 #ifndef CONFIG_S3C6400
 42     ldr    r1, [r0, #OTHERS_OFFSET]
 43     bic    r1, r1, #0xC0
 44     orr    r1, r1, #0x40
 45     str    r1, [r0, #OTHERS_OFFSET]
 46 
 47 wait_for_async:
 48     ldr    r1, [r0, #OTHERS_OFFSET]
 49     and    r1, r1, #0xf00
 50     cmp    r1, #0x0
 51     bne    wait_for_async
 52 #endif
 53 
 54     ldr    r1, [r0, #OTHERS_OFFSET]
 55     bic    r1, r1, #0x40
 56     str    r1, [r0, #OTHERS_OFFSET]
 57 #endif
 58 
 59     mov    r1, #0xff00
 60     orr    r1, r1, #0xff
 61     str    r1, [r0, #APLL_LOCK_OFFSET]
 62     str    r1, [r0, #MPLL_LOCK_OFFSET]
 63 
 64     /* Set Clock Divider */
 65     ldr    r1, [r0, #CLK_DIV0_OFFSET]
 66     bic    r1, r1, #0x30000
 67     bic    r1, r1, #0xff00
 68     bic    r1, r1, #0xff
 69     ldr    r2, =CLK_DIV_VAL
 70     orr    r1, r1, r2
 71     str    r1, [r0, #CLK_DIV0_OFFSET]
 72 
 73     ldr    r1, =APLL_VAL
 74     str    r1, [r0, #APLL_CON_OFFSET]
 75     ldr    r1, =MPLL_VAL
 76     str    r1, [r0, #MPLL_CON_OFFSET]
 77 
 78     /* FOUT of EPLL is 96MHz */
 79     ldr    r1, =0x200203
 80     str    r1, [r0, #EPLL_CON0_OFFSET]
 81     ldr    r1, =0x0
 82     str    r1, [r0, #EPLL_CON1_OFFSET]
 83 
 84     /* APLL, MPLL, EPLL select to Fout */
 85     ldr    r1, [r0, #CLK_SRC_OFFSET]
 86     orr    r1, r1, #0x7
 87     str    r1, [r0, #CLK_SRC_OFFSET]
 88 
 89     /* wait at least 200us to stablize all clock */
 90     mov    r1, #0x10000
 91 1:    subs    r1, r1, #1
 92     bne    1b
 93 
 94     /* Synchronization for VIC port */
 95 #if defined(CONFIG_SYNC_MODE)
 96     ldr    r1, [r0, #OTHERS_OFFSET]
 97     orr    r1, r1, #0x20
 98     str    r1, [r0, #OTHERS_OFFSET]
 99 #elif !defined(CONFIG_S3C6400)
100     /* According to 661558um_S3C6400X_rev10.pdf 0x20 is reserved */
101     ldr    r1, [r0, #OTHERS_OFFSET]
102     bic    r1, r1, #0x20
103     str    r1, [r0, #OTHERS_OFFSET]
104 #endif
105     mov    pc, lr

 

 1 #if defined(CONFIG_CLK_400_100_50)
 2 #define STARTUP_AMDIV        400
 3 #define STARTUP_MDIV        400
 4 #define STARTUP_PDIV        6
 5 #define STARTUP_SDIV        1
 6 #elif defined(CONFIG_CLK_400_133_66)
 7 #define STARTUP_AMDIV        400
 8 #define STARTUP_MDIV        533
 9 #define STARTUP_PDIV        6
10 #define STARTUP_SDIV        1
11 #elif defined(CONFIG_CLK_533_133_66)
12 #define STARTUP_AMDIV        533
13 #define STARTUP_MDIV        533
14 #define STARTUP_PDIV        6
15 #define STARTUP_SDIV        1
16 #elif defined(CONFIG_CLK_667_133_66)
17 #define STARTUP_AMDIV        667
18 #define STARTUP_MDIV        533
19 #define STARTUP_PDIV        6
20 #define STARTUP_SDIV        1
21 #endif
22 
23 #define    STARTUP_PCLKDIV        3
24 #define STARTUP_HCLKX2DIV    1
25 #define STARTUP_HCLKDIV        1
26 #define STARTUP_MPLLDIV        1
27 #define STARTUP_APLLDIV        0
28 
29 #define CLK_DIV_VAL    ((STARTUP_PCLKDIV << 12) | (STARTUP_HCLKX2DIV << 9) | \
30     (STARTUP_HCLKDIV << 8| (STARTUP_MPLLDIV<<4| STARTUP_APLLDIV)
31 #define MPLL_VAL    ((1 << 31) | (STARTUP_MDIV << 16) | \
32     (STARTUP_PDIV << 8| STARTUP_SDIV)
33 #define STARTUP_MPLL    (((CONFIG_SYS_CLK_FREQ >> STARTUP_SDIV) / \
34     STARTUP_PDIV) * STARTUP_MDIV)
35 
36 #if defined(CONFIG_SYNC_MODE)
37 #define APLL_VAL    ((1 << 31) | (STARTUP_MDIV << 16) | \
38     (STARTUP_PDIV << 8| STARTUP_SDIV)
39 #define STARTUP_APLL    (((CONFIG_SYS_CLK_FREQ >> STARTUP_SDIV) / \
40     STARTUP_PDIV) * STARTUP_MDIV)
41 #define STARTUP_HCLK    (STARTUP_MPLL / (STARTUP_HCLKX2DIV + 1) / \
42     (STARTUP_HCLKDIV + 1))
43 #else
44 #define APLL_VAL    ((1 << 31) | (STARTUP_AMDIV << 16) | \
45     (STARTUP_PDIV << 8| STARTUP_SDIV)
46 #define STARTUP_APLL    (((CONFIG_SYS_CLK_FREQ >> STARTUP_SDIV) / \
47     STARTUP_PDIV) * STARTUP_AMDIV)
48 #define STARTUP_HCLK    (STARTUP_MPLL / (STARTUP_HCLKX2DIV + 1) / \
49     (STARTUP_HCLKDIV + 1))
50 #endif

 

参考

http://www.linuxidc.com/Linux/2011-09/42027.htm
和下面datasheet图进行理解。

 


 

(上图:关键信息,fin相关内容见:

http://bbs.eeworld.com.cn/thread-133065-1-1.html
)

 

 

 

 

 

 

posted on 2011-09-07 10:13  Anpher Zhang  阅读(2482)  评论(0编辑  收藏  举报