本内容来自S3C2440手册第7章Clock & Power management.
时钟和电源模块包括3个部分:时钟控制、USB控制和电源控制。
时钟控制逻辑能够产生:CPU用的FCLK、AHB总线用的HCLK、APB总线用的PCLK。包括两个锁相环(PLLs),一个用于FCLK、HCLK、PCLK。一个专用于USB时钟(48Mhz)。时钟控制逻辑不需要PLL可产生slow clocks。使用软件控制时钟是否连接到每个总线,这可以减少功率消耗。
功率控制逻辑有多种电源管理框架用于实现最优的电源消耗。能激活4种模式:NORMAL、Slow、IDLE、Sleep。
Normal mode
供应时钟给CPU和所有的总线。但是可以软件控制是否供应特定模块,如果该模块没有使用,可以这样做来减少电源消耗。
Slow mode
不使用PLL,直接使用外部时钟(XTIpll或者EXTCLK)。
Idle mode
只关闭CPU core时钟,即FCLK。其它总线仍供应。任何中断请求将导致从Idle中恢复。
Sleep mode
断开内部电源,只保留唤醒逻辑(wake-up logic)。激活睡眠模式需要两个独立的电源,其中一个供应唤醒逻辑单元。从睡眠模式唤醒可以通过EINT[15:0]或者RTC时钟中断。
主时钟源来自一个外部晶振 XTIpll或者一个外部时钟EXTCLK。时钟产生器包括一个振荡器,接到外部晶振。包括2个锁相环,产生高频率时钟。
时钟源选择,通过硬件引脚控制。
Mode OM[3:2] | MPLL state | UPLL state | Main Clock source | USB Clock Source |
00 | on | on | Crystal | Crystal |
01 | on | on | Crystal | EXTCLK |
10 | on | on | EXTCLK | Crystal |
11 | on | on | EXTCLK | EXTCLK |
注意:
尽管MPLL在复位后开始,但是必须在设置MPLLCON寄存器后才开始使用,即使和默认值一样,也需要设置。
锁相环 PLL
Mpll = (2*m + Fin) / (p * 2 ^s)
m = M + 8, p = P + 2
时钟控制逻辑
决定使用的时钟源,是PLL时钟,还是外部时钟(XTIpll或者EXTCLK)。当PLL配置成一个新的频率值时,时钟控制逻辑disable掉FCLK,直到PLL输出稳定。使用PLL locking time,来确保。
上电复位 (XTIpll)
上电时,PLL不稳定,所以Fin直接喂给FCLK,直到软件新配置了PLLCON,即使用户不改变PLLCON的值,也需要重设PLLCON寄存器。配置后经过lock time,FCLK使用PLL输出。
Normal模式改变PLL设置
改变PMS设置实现,经过一个自动的lock time后生效。
USB clock control
USB host interface和USB device需要48Mhz时钟,UPLL用于产生48Mhz时钟。UCLK直到配置UPLL才会喂(fed)。
FCLK, HCLK, PCLK
ARM920T使用FCLK
AHB总线使用HLCK,包括ARM920T, 内存控制器,中断控制器,LCD控制器,DMA和USB host block。
APB总线使用PLCK,包括相关总线,如WDT,IIS,I2C,PWM timer,MMC interface,ADC,UART,GPDIO,RTC和SPI。
支持FCLK,HCLK和PCLK的分频选择,通过设置CLKDIVN寄存器的HDIVN和PDIVN实现。
设置PMS后,要求设置CLKDIVN寄存器。
注意:
1 CLKDIVN要小心设置,不要超过HCLK和PCLK的限制。
2 如果HDIVN不是0,CPU总线模式需要从fast bus mode改为asynchronous bus mode,使用下列指令。
1 2 3 4 | MMU_SetAsyncBusMode mrc p15,0,r0,c1,c0,0 orr r0,r0,#R1_nF:OR:R1_iA mcr p15,0,r0,c1,c0,0 |
如果HDIVN不是0,CPU模式是快速总线模式,CPU将使用HCLK工作,这个特性用来改变CPU频率,而不影响HCLK和PCLK。
电源管理
电源管理模块通过软件控制系统时钟,用于减少电源消耗。这些框架和PLL,clock control logics和wakeup signals相关。
电源管理状态图:
每个电源模式的时钟和电源状态:
1 不包括USB host, LCD, NAND
2 不包括WDT,包括CPU访问的RTC接口。
3 SEL:可配。O:开启,X:关闭,OFF:电源关闭。
Normal模式
所有模块均处于工作状态,但是有些模块可以选择关闭。
Idle模式
除了CPU核停止,其它模块都工作,要退出Idle模式,EINT[23:0] 或者 RTC alarm中断,或者其它中断。EINT只有GPIO模块打开的时候才可用。
Slow模式
使用慢时钟,不使用PLL,使用XTIpll或EXTCLK,同时还支持分频。
用户通过disable CLKSLOW寄存器的SLOW位可以切换到Normal模式。
Sleep模式
关闭内部电源,需要另外一个电源来供应唤醒逻辑。从Sleep唤醒通过EINT[15:0]和RTC alarm中断。
具体的内容跳过。
进入Idle模式
设置CLKCON[2]为1进入IDLE模式,一些delay(直到电源控制逻辑收到CPU的ack信号)后进入IDLE模式。
PLL On/Off
只有在slow mode才能关闭,其它模式关闭,MCU操作不保证。当处理器想从SLow切换到其它模式时,应当在PLL初始化后关闭SLOW_BIT。
LOCK TIME COUNT REGISTER (LOCKTIME)
Register | Address | R/W | Description | Reset value |
LOCKTIME | 0x4C000000 | R/W | PLL lock time count register | 0xFFFFFFFF |
高16位用于设置UPLL,低16位用于设置MPLL。
几个确定下述寄存器的等式:
Mpll = (2*m*Fin)/(p*2^s)
m = (MDIV+8), p=(PDIV+2), s=SDIV
Upll = (m*Fin)(p*2^s)
m = (MDIV+8), p=(PDIV+2), s=SDIV
PLL value section guide (MPLLCON)
Fout = (2*m*Fin)/(p*2^s), Fvco = 2 *m *Fin / p
600Mhz <= Fvco <= 1.2 Ghz
200Mhz <= FCLKout <= 600Mhz
不要设置P或M为0
P和M的合适值:1 <=P<=62, 1<=M<=28
PLL control register (MPLLCON & UPLLCON)
Register | Address | R/W | Description | Reset value |
MPLLCON | 0x4C000004 | R/W | MPLL configuration register | 0x00096030 |
UPLLCON | 0x4C000008 | R/w | UPLL configuration register | 0x0004d030 |
MDIV [19:12] Main divider control
PDIV [9:4] pre-divider control
SDIV [1:0] post divider control
注意:要先设置UPLL再设置MPLL,需要内部大约7个NOP。
PLL VALUE selection table
找到合适的PLL不容易,所以我们推荐下述PLL VALUE RECOMMENDATION TABLE.
Input Freq | Output Freq | MDIV | PDIV | SDIV |
12MHz | 48MHz | 56 | 2 | 2 |
12MHz | 96MHz | 56 | 2 | 1 |
12MHz | 271.5MHz | 173 | 2 | 2 |
12MHz | 304MHz | 68 | 1 | 1 |
12MHz | 400MHz | 92 | 1 | 1 |
16.9344MHz | 47.98Mhz | 60 | 4 | 2 |
16.9344MHz | 95.96MHz | 60 | 4 | 1 |
16.9344MHz | 266.72Mhz | 118 | 2 | 2 |
16.9344MHz | 296.35MHz | 97 | 1 | 2 |
16.9344MHz | 399.65Mhz | 110 | 3 | 1 |
注意:48Mhz和96MHz用于UPLLCON寄存器。
CLOCK CONTROL register (CLKCON)
Register | Address | R/W | Description | Reset value |
CLKCON | 0x4C00000C | R/W | Clock generator control register | 0xFFFFF0 |
CLKCON | Bit | Desc | Initial state |
AC97 | 20 | Control PCLK into AC97 block 0 = disable, 1 = Enable | 1 |
Camera | 19 | Control PCLK into Camera block | 1 |
SPI | 18 | Control PCLK into SPI block | 1 |
IIS | 17 | Control PCLK into IIS block | 1 |
IIC | 16 | Control PCLK into IIC block | 1 |
ADC(&TOUCH SCREEN) | 15 | Control PCLK into ADC block | 1 |
RTC | 14 | Control PCLK into RTC block | 1 |
GPIO | 13 | Control PCLK into GPIO block | 1 |
UART2 | 12 | Control PCLK into UART2 block | 1 |
UART1 | 11 | Control PCLK into UART1 block | 1 |
UART0 | 10 | Control PCLK into UART0 block | 1 |
SDI | 9 | Control PCLK into SDI block | 1 |
PWMTIMER | 8 | Control PCLK into PWMTIMER block | 1 |
USB Device | 7 | Control PCLK into USB Device block | 1 |
USB Host | 6 | Control HCLK into USB Host block | 1 |
LCDC | 5 | Control HCLK into LCDC block | 1 |
NAND Flash Controller | 4 | Control HCLK into NFC block | 1 |
SLEEP | 3 | Control sleep mode of S3C2440A 0 = disable, 1 = Transition to Sleep mode | 0 |
IDLE BIT | 2 | Enter IDLE Mode, This bit is not cleared automatically. 0 = Disable, 1 = Transition to IDLE mode | 0 |
Reserved | 1:0 | Reserved | 0 |
CLOCK SLOW CONTROL (CLKSLOW) register
Register | Address | R/W | Description | Reset value |
CLKSLOW | 0x4C0000010 | R/W | Slow Clock control register | 0x4 |
CLKSLOW | Bit | Desc | Initial state |
UCLK_ON | [7] | 0: UCLK_ON (UPLL is also turned on and UPLL lock time is inserted automatically) 1: UCLK_OFF (UPLL is also turned of) | 0 |
Reserved | [6] | Reserved | - |
MPLL_OFF | [5] | 0: Turn on PLL after PLL stabilization time (minimum 300us), SLOW_BIT can be cleared to 0 1: Turn off PLL. PLL Is turned off only when SLOW_BIT is 1 | 0 |
SLOW_BIT | [4] | 0: FCLK= Mpll (MPLL output) 1: SLOW Mode FCLK = input clock / (2 x slow_val), when slow_val > 0 FCLK = input clock, when SLOW_VAL = 0. | 0 |
Reserved | [3] | - | - |
SLOW_VAL | [2:0] | The divider value for slow clock when SLOW_BIT is on | 0x4 |
CLOCK DIVIDER CONTROL (CLKDIVN) register
Register | Address | R/W | Description | Reset value |
CLKDIVN | 0x4C000014 | R/W | Clock divider control register | 0x0 |
CLKDIVN | Bit | Desc | Initial state |
DIVN_UPLL | 3 | UCLK select register (UCLK Must be 48MHz for USB) 0: UCLK = UPLL clock 1: UCLK = UPLL clock / 2 set to 0, when UPLL clock is set as 48MHz set to 1, when UPLL clock is set as 96MHz | 0 |
HDIVN | [2:1] | 00: HCLK = FCLK/1 01: HCLK = FCLK/2 10: HCLK = FCLK/4 when CAMDIVN[9] = 0 HCLK = FCLK/8 when CAMDIVN[9] = 1 11: HCLK = FCLK/3 when CAMDIVN[8] = 0 HCLK = FCLK/6 when CAMDIVN[8] = 1 | 00 |
PDIVN | 0 | 0: PCLK has the clock same as the HCLK/1 1: PCLK has the clock same as the HCLK/2 | 0 |
Camera clock divider (CAMDIVN) register
Register | Address | R/W | Description | Reset value |
CAMDIVN | 0x4C000018 | R/W | camera clock divider register | 0x0 |
CAMDIVN | Bit | Desc | Initial state |
DVS_EN | 12 | 0: DVS_OFF ARM core will run normally with FCLK(MPLL out). 1: DVS_ON ARM core will run at the same clock as system clock (HCLK) | 0 |
reserved | 11 | ||
reserved | 10 | ||
HCLK4_HALF | 9 | HDIVN division rate change bit, when CLKDIVN[2:1] =10b 0: HCLK = FCLK/4 1:HCLK=FCLK/8 | 0 |
HCLK3_HALF | 8 | HDIVN division rate change bit, when CLKDIVN[2:1] =11b 0: HCLK = FCLK/3 1:HCLK=FCLK/6 | 0 |
CAMCLK_SEL | 4 | 0: Use CAMCLK with UPLL Output (CAMCLK = UPLL output) 1: CAMCLK is divided by CAMCLK_DIV value | 0 |
CAMCLK_DIV | 3:0 | CAMCLK divide factor setting register (0-15) Camera clock = UPLL / [(CAMCLK_DIV + 1) *2] this bit is valid when CAMCLK_SEL=1 | 0 |
RESET之后运行在12MHz频率,实战目的让2440运行在最大频率,通过对比运行固定循环闪灯的频率来看看是否有效。JZ2440的供电电压1.3V,根据手册FCLK最大400Mhz,HCLK最大133Mhz,PCLK最大67Mhz。分频比为1:3:6。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | void clk_init() { clk->CLKDIVN = (0x3 << 1) | 0x1; // HDIVN:11b, PDIVN, 1 asm volatile ( "mrc p15, 0, r1, c1, c0, 0\n\t" "orr r1, r1, #0xc0000000\n\t" "mcr p15, 0, r1, c1, c0, 0" : : : "r1" ); // according to datasheet, should set UPLLCON firstly. clk->UPLLCON = (56 << 12) | (2 << 4) | 2; // 48MHz clk->MPLLCON = (92 << 12) | (1 << 4) | 1; // 400MHz } |
时钟提升到400Mhz后,led灯闪烁的频率快非常非常多。另外注意:SDRAM的刷新寄存器跟系统时钟相关,调整系统时钟后,需要修改初始化该寄存器的值。