Chinaunix首页 | 论坛 | 博客
  • 博客访问: 132680
  • 博文数量: 38
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 191
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-16 11:31
个人简介

嵌入式新人

文章分类

全部博文(38)

文章存档

2016年(38)

我的朋友

分类: 嵌入式

2016-06-02 20:55:14

        
        时钟系统是SoC的节拍器,掌握和理解它就显得十分重要,本文首先对
S5PV210的时钟系统(位于S5PV210 UM V1.1 section 2-3)进行整体性介绍(包括时钟域、A/M/V/E PLL、时钟分配路径、时钟系统相关寄存器等),然后以UART、SPI、IIC和DMC0/1的时钟为例,给出这些模块时钟路径和寄存器设置,最后给出时钟系统初始化例程代码(基于九鼎科技的
S5PV210开发板和朱有鹏老师的课件),希望能够举一反三地掌握时钟系统的知识。


1  S5PV210的晶体源
       S5PV210可以外接4个石英晶体分别是XRTCXTI、XXTI、XUSBXTI和XHDMIXTI,主输入时钟是在XXTI和XUSBXTI中选择一个,如果不使用USB PHY时,可以选择XXTI,当然也可以选择XUSBXTI;使用USB PHY 时,选用XUSBXTI,因此通常选择XUSBXTI作为主输入时钟(S5PV210推荐时钟频率为24MHz),推荐九鼎科技的S5PV210开发板就是这样做的。S5PV210 UM V1.1 section 2 中6.2.4节给出,OM[0]=0时,使用XXTI作为输入源;OM[0]=1时,使用XUSBTI 作为输入源。


  • XRTCXTI: Specifies a clock from 32.768 KHz crystal pad with XRTCXTI and XRTCXTO pins. RTC uses this clock as the source of a real-time clock.
  • XXTI: Specifies a clock from crystal pad with XXTI and XXTO pins. When USB PHY is not used in commercial set, CMU and PLL use this clock to generate other clocks to modules (APLL, MPLL, VPLL, and EPLL.). The input frequency ranges from 12 ~ 50 MHz. It is recommended to use 24MHz crystal because iROM was designed based on the 24MHz input clock.
  • XUSBXTI: Specifies a clock from a crystal pad with XUSBXTI and XUSBXTO pins. This clock is supplied to APLL, MPLL, VPLL, ELL, and USB PHY. For more information on USB PHY clock, refer to Chapter 8.4 " USB 2.0 HOST Controller " and 8.5 " USB2.0 HS OTG ". It is recommended to use 24MHz crystal because iROM was designed based on the 24MHz input clock.
  • XHDMIXTI: Specifies a clock from 27MHz crystal pad with XHDMIXTI and XHDMIXTO pins. VPLL or HDMI PHY generates 54MHz clock for TV encoder.



 
2 S5PV210时钟域和时钟路径
   
     S5PV210将时钟分为3个时钟域,分别是MSYS(Main System)、DSYS(Display System和PSYS(Peripheral System),每个时钟域控制某些模块的时钟,具体见下图(From Fig 3-1)和下表(From Table 3-5 ),例如UART、SPI、IIC和USB的时钟都在PSYS域;DMC0和DMC1、IRAM和IROM以及CortexA8的时钟都在MSYS域;显示和图形处理相关模块的时钟都在DSYS域。

 

 时钟域

最高工作频率 

 功能模块

 MSYS

 200MHz

 MFC, G3D ;TZIC0, TZIC1, TZIC2, TZIC3, VIC0, VIC1, VIC2, VIC3 ;DMC0, DMC1 ;AXI_MSYS, AXI_MSFR, AXI_MEM

 100MHz

 IRAM, IROM, TZPC0

 DSYS

 166 MHz

 FIMC0, FIMC1, FIMC2, FIMD, DSIM, CSIS, JPEG, Rotator,  VP, MIXER, TVENC, HDMI, MDMA, G2D  DSYS

 83 MHz

 DSIM, CSIS, I2C_HDMI_PHY, I2C_HDMI_DDC

 PSYS

 133 MHz

 CSSYS, JTAG, MODEM I/F ,CFCON, NFCON, SROMC, ONENAND ,PDMA0, PDMA1 ,SECSS ,HSMMC0,
HSMMC1, HSMMC2, HSMMC3 
USB OTG, USB HOST ,PSYS

66MHz

SYSCON, GPIO, CHIPID, APC, IEC, TZPC1, SPI0, SPI1, I2S1, I2S2, PCM0, PCM1, PCM2, AC97, SPDIF,
I2C0, I2C2, KEYIF, TSADC, PWM, ST, WDT, RTC, UART
   
        
例如我们需要设置UART、SPI、I2C、DMC0/1和ONENAND的时钟,我们可以先从下图(From Fig 3-3)中查找该模块有哪些时钟源,然后再在该模块的具体章节中查看还有没有其他时钟源,例如下图中UART的时钟源有XXTI、XUSBXTI、SCLK_HDMI27M、SCLK_USBPHY0、SCLK_USBPHY1、SCLK_HDMIPHY、SCLK_MPLL、SCLK_EPLL和SCLK_VPLL在UART章节(位于S5PV210 UM V1.1 section 8-1)发现UART还有一个时钟源PCLK(注:即PCLK_PSYS),因此UART的时钟就需要从这些时钟源中选择一个,通常我们现在选择PCLK。
 
 
 

     为保证CPU高性能地稳定工作,S5PV210推荐了各个时钟的工作频率,见下表(From 3.3 CLOCK RELATIONSHIP ,为了实现这样的工作频率,我们需要按照S5PV210的推荐设置PLL,PLL的PMS值设定见:APLL ---->Table 3-1;MPLL ---->Table 3-2;EPLL ---->Table 3-3;APLL ---->Table 3-4。 

 序号

 时钟

 推荐工作频率

 1

 ARMCLK

 1000 MHz

 2

 HCLK_MSYS

 200 MHz

 3

 HCLK_IMEM

 100 MHz

 4

 PCLK_MSYS

 100 MHz

 5

 HCLK_DSYS

 166 MHz

 6

 PCLK_DSYS

 83 MHz

 7

 HCLK_PSYS

 133 MHz

 8

 PCLK_PSYS

 66 MHz

 9

 SCLK_ONENAND

 133 MHz, 166 MHz

      
 
 
 3 S5PV210的时钟寄存器
      S5PV210的寄存器主要分为以下几类

  序号

 寄存器分类

寄存器的作用 

 1

 APLL/MPLL/EPLL/VPLL  _LOCK

 设定PLL的锁定周期数

 2

 APLL/MPLL/EPLL/VPLL  _CON

 设定PLL的输出频率

 3

 APLL_CON0_L[1-8]

 设置APLL的Performance Level

4

 CLK_SRC[0-7] 

 时钟源的选择

 5

 CLK_DIV[0-7]   

 设定时钟分频系数

 6

 CLK_DIV_STAT[0-1]

 时钟分频器的状态(只读)

 7

 CLK_DIV_ITEM[1-8]

 时钟分频器的状态(只读

 8

 CLK_GATE_XXX

 

 9

 CLK_OUT

 

 10

 CLK_DIV_STAT[0-1]  

时钟选择器的状态(只读


                             
时钟系统初始化例程代码
S5PV210的时钟配置步骤如下(From3.5  CLOCK CONFIGURATION PROCEDURE )
 
  1. Rules to follow when the clock configuration changes:
  2.  **** All inputs of a glitch-free mux must run.
  3.  **** When a PLL is power-off, you should not select the output of PLL.
  4.   Basic SFR configuration flows:
  5.  //Turn on a PLL
  6.  (A,M,E,V)PLL_CON[31] = 1; // Power on a PLL (Refer to (A, M, E, V) PLL_CON SFR) 
      
  7.  wait_lock_time; // Wait until the PLL is locked 
  8.  (A, M, E, V)PLL_SEL = 1; // Select the PLL output clock instead of input reference clock, after PLL output clock is stabilized.
  9.                           // (Refer to 0, 4, 8, 12th bit of CLK_SRC0 SFR) 
      
  10.  //Once you turned on any PLL, do not turn off that. 

     //Change PLL’s PMS values
  11.  Set PMS values; // Set PDIV, MDIV, and SDIV values (Refer to (A, M, E, V) PLL_CON SFR)
  12.   
  13.  //Change the system clock divider values
  14.  CLK_DIV0 [31:0] = target value0;
  15.   
  16.  //Change the divider values for special clocks
  17.  CLK_DIV1 [31:0] = target value1;
  18.  CLK_DIV2 [31:0] = target value2

  
 4.1 汇编语言代码
S5PV210 UM 中推荐PLL的输出频率FOUT(APLL )=1000MHz,FOUT(MPLL )=667MHz和其他时钟频率
ARMCLK=1000Mz,HCLK_MSYS=200MHz,PCLK_MSYS=100MHz,
HCLK_DSYS=166MHz,PCLK_DSYS=83MHz,
HCLK_PSYS=133MHz,PCLK_PSYS=66MHz,
SCLKA2M=200MHz 
我们用汇编语言实现这些频率的设置,为了方便,我们把这些频率和分频系数标示在下图中。



点击(此处)折叠或打开

  1. ///define clock register base address
  2. #define ELFIN_CLOCK_REG_BASE    0xE0100000    

  3. // define clock register offset address
  4. #define APLL_LOCK_OFFSET        0x00        
  5. #define MPLL_LOCK_OFFSET        0x08
  6. #define EPLL_LOCK_OFFSET 0x10
  7. #define VPLL_LOCK_OFFSET 0x20

  8. #define APLL_CON0_OFFSET        0x100
  9. #define APLL_CON1_OFFSET        0x104
  10. #define MPLL_CON_OFFSET            0x108
  11. #define EPLL_CON0_OFFSET        0x110
  12. #define EPLL_CON1_OFFSET        0x114
  13. #define VPLL_CON_OFFSET            0x120

  14. #define CLK_SRC0_OFFSET            0x200
  15. #define CLK_SRC1_OFFSET            0x204
  16. #define CLK_SRC2_OFFSET            0x208
  17. #define CLK_SRC3_OFFSET            0x20c
  18. #define CLK_SRC4_OFFSET            0x210
  19. #define CLK_SRC5_OFFSET            0x214
  20. #define CLK_SRC6_OFFSET            0x218
  21. #define CLK_SRC_MASK0_OFFSET    0x280
  22. #define CLK_SRC_MASK1_OFFSET    0x284

  23. #define CLK_DIV0_OFFSET            0x300
  24. #define CLK_DIV1_OFFSET            0x304
  25. #define CLK_DIV2_OFFSET            0x308
  26. #define CLK_DIV3_OFFSET            0x30c
  27. #define CLK_DIV4_OFFSET            0x310
  28. #define CLK_DIV5_OFFSET            0x314
  29. #define CLK_DIV6_OFFSET            0x318
  30. #define CLK_DIV7_OFFSET            0x31c

  31. #define CLK_GATE_SCLK 0x444
  32. #define CLK_GATE_IP0 0x460
  33. #define CLK_GATE_IP1 0x464
  34. #define CLK_GATE_IP2 0x468
  35. #define CLK_GATE_IP3 0x46c
  36. #define CLK_GATE_IP4 0x470
  37. #define CLK_GATE_IP5 0x484
  38. #define CLK_GATE_BLOCK 0x480
  39. #define CLK_OUT 0x500
  40. #define CLK_DIV_STAT0 0x1000
  41. #define CLK_DIV_STAT1 0x1004
  42. #define CLK_MUX_STAT0 0x1100
  43. #define CLK_MUX_STAT1 0x1104

  44. #define SWRESET 0x2000

  45. #define DCGIDX_MAP0 0x3000
  46. #define DCGIDX_MAP1 0x3004
  47. #define DCGIDX_MAP2 0x3008
  48. #define DCGPERF_MAP0 0x3020
  49. #define DCGPERF_MAP1 0x3024

  50. #define DVCIDX_MAP 0x3040

  51. #define FREQ_CPU                0x3060
  52. #define FREQ_DPM 0x3064

  53. #define DVSEMCLK_EN 0x3080
  54. #define MAXPERF 0x3084

  55. #define APLL_CON0_L8 0x3100
  56. #define APLL_CON0_L7 0x3104
  57. #define APLL_CON0_L6 0x3108
  58. #define APLL_CON0_L5 0x310c
  59. #define APLL_CON0_L4 0x3110
  60. #define APLL_CON0_L3 0x3114
  61. #define APLL_CON0_L2 0x3118
  62. #define APLL_CON0_L1 0x311c

  63. #define APLL_CON1_L8 0x3300
  64. #define APLL_CON1_L7 0x3304
  65. #define APLL_CON1_L6 0x3308
  66. #define APLL_CON1_L5 0x330c
  67. #define APLL_CON1_L4 0x3310
  68. #define APLL_CON1_L3 0x3314
  69. #define APLL_CON1_L2 0x3318
  70. #define APLL_CON1_L1 0x331c

  71. #define CLKDIV_IEM_L8 0x3200
  72. #define CLKDIV_IEM_L7 0x3204
  73. #define CLKDIV_IEM_L6 0x3208
  74. #define CLKDIV_IEM_L5 0x320c
  75. #define CLKDIV_IEM_L4 0x3210
  76. #define CLKDIV_IEM_L3 0x3214
  77. #define CLKDIV_IEM_L2 0x3218
  78. #define CLKDIV_IEM_L1 0x321c

  79. #define GENERAL_CTRL 0x6100
  80. #define DISPLAY_CONTROL 0x7008
  81. #define AUDIO_ENDIAN 0x700c

  82. #define CLK_DIV0_MASK            


  83. // define a/m/e/v pll pms value -->from page 371
  84. //set APLL fout 1000mhz
  85. #define APLL_P             0x3
  86. #define APLL_M                  0x7d        
  87. #define APLL_S             0x1

  88. //set mpll fout 667mhz
  89. #define MPLL_P                    0xc
  90. #define MPLL_M                    0x29b        
  91. #define MPLL_S                    0x1

  92. //set epll fout 96mhz
  93. #define EPLL_P                    0x3
  94. #define EPLL_M                    0x30        
  95. #define EPLL_S                    0x2
  96. #define EPLL_K                    0x0

  97. //set vpll fout 54mhz
  98. #define VPLL_P                    0x6
  99. #define VPLL_M                    0x6c        
  100. #define VPLL_S                    0x3

  101. #define set_pll(p, m, s)    (1<<31 | p<<8 | m<<16 | s<<0)
  102. #define APLL_FOUT            set_pll(APLL_P,APLL_M,APLL_S)
  103. #define MPLL_FOUT            set_pll(MPLL_P,MPLL_M,MPLL_S)
  104. #define EPLL_FOUT            set_pll(EPLL_P,EPLL_M,EPLL_S)
  105. #define VPLL_FOUT            set_pll(VPLL_P,VPLL_M,VPLL_S)

  106. //PLL的设置步骤
  107. //
  108. .global clock_init
  109. clock_init:
  110. //------------------SET APLL------------------------
  111.     
  112.     ldr    r0, =ELFIN_CLOCK_REG_BASE
  113.     
  114.     //1 turn on APLL;    //2 set APLL_lock time ;    //3 select APLL
  115.     
  116.     //1 turn on APLL
  117.     ldr    r1, =0x80000000
  118.     str    r1, [r0, #APLL_CON0_OFFSET]                
  119.     str    r1, [r0, #MPLL_CON_OFFSET]    
  120.     
  121.     
  122.     // 2 set APLL and MPLL lock time
  123.     ldr    r1,    =0x0000FFFF                    
  124.     str    r1,    [r0, #APLL_LOCK_OFFSET]                
  125.     str r1, [r0, #MPLL_LOCK_OFFSET]

  126.     //3 set mux
  127.     ldr    r1, [r0, #CLK_SRC0_OFFSET]
  128.     ldr r2, =0x10000011 // MUXAPLL=1,MUXMPLL=1, MUXMSYS=0,MUXDSYS=0,MUXPSYS=0,MUXFLASH=1
  129.     orr    r1, r1, r2 //orr 或运算指令
  130.     str r1, [r0,#CLK_SRC0_OFFSET]
  131.     
  132.     
  133.         
  134.     //4 set APLL fout frequency,set PMS value
  135.     // FOUT = M*FIN/(P*2^(S-1))=0x7d*24/(0x3*2^(1-1))=1000 MHz
  136.     ldr    r1, =APLL_FOUT                        
  137.     str    r1, [r0, #APLL_CON0_OFFSET]
  138.     // FOUT = M*FIN/(P*2^S)=0x29b*24/(0xc*2^1)= 667 MHz
  139.     ldr    r1, =MPLL_FOUT                        
  140.     str    r1, [r0, #MPLL_CON_OFFSET]
  141.         
  142.     
  143.     
  144.     // 5 set divider value
  145.     ldr r1, [r0, #CLK_DIV0_OFFSET]                    
  146.     ldr    r2, =0x7fffffff                    
  147.     bic    r1, r1, r2 //bic 位清零指令,将r2中等于1的位清零
  148.     ldr    r2, =0x14131440  
  149. //ARMCLK=1000Mz,HCLK_MSYS=200MHz,PCLK_MSYS=100MHz,HCLK_DSYS=166MHz, 
  150. //PCLK_DSYS=83MHz,HCLK_PSYS=133MHz,PCLK_PSYS=66MHz, SCLKA2M=200MHz             
  151.     orr    r1, r1, r2
  152.     str    r1, [r0, #CLK_DIV0_OFFSET]
  153.         
  154.     mov    pc, lr
 
阅读(1381) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~