S3C2440时钟和电源管理

2019-07-13 21:59发布

一、时钟 1.系统架构          时钟源:为了减少外界环境对开发板电磁干扰,降低制作成本,通常开发板的外部晶振时钟频率都很低,TX2440开发板由12MHz的晶振来提供时钟源,要想让CPU运行在更高的频率就要通过时钟控制逻辑单元PLL(锁相环)来提高主频。       S3C2440里有两个PLL:MPLL和UPLL,MPLL用来产生FCLK的高频工作时钟(而HCLK和PCLK通过FCLK分频获取),UPLL用来为USB提供工作频率。
  •   FCLK为ARM920T内核提供时钟,详见下图
  •   HCLK主要为S3C2440 AHB总线(Advanced High performance Bus)上挂接硬件提供工作频率,AHB总线主要挂接有内存,NAND,LCD控制器等硬件,详见下图.
  •   PCLK主要为APB总线提供工作频率,由图2-46所示,APB总线主要挂接UART串口,定时器、GPIO、AD、Watchdog等硬件控制器。
                   由上图可知            1、时钟源选择:由OM[3:2]决定。                      由下面电路图可知:OM[3:2]=00,主时钟源=晶振12M,USB时钟源=晶振12M                    2、时钟初始化设置      开发板上电后,晶振OSC开始为ARM提供系统时钟FCLK。这时复位信号(nRESET)拉低,这时MPLL虽然默认启动,但是如果不向MPLLCON中写入值,那么外部晶振则直接作为系统时钟FCLK,过几毫秒后,复位信号上拉,CPU开始取指运行,这时可以通过代码设置启动MPLLMPLL启动需要一定锁定时间(LockTime),这是因为MPLL输出频率还没有稳定,在这期间FCLK都停止输出,CPU停止工作,过了LockTime后时钟稳定输出,CPU工作在新设置的频率下,这时可以通过设置FCLKHCLKPCLK三者的频率比例来产生不同总线上需要的不同频率。              下面详细介绍开启MPLL的过程:
  •  设置LockTime变频锁定时间
  •  设置FCLK与晶振输入频率(Fin)的倍数
  •  设置FCLK,HCLK,PCLK三者之间的比例
  1、设置locktime 即设置寄存器LOCKTIME      由于变频后开发板所有依赖时钟工作的硬件都需要一小段调整时间,该时间计数通过设置LOCKTIME寄存器[31:16]来设置UPLL(USB时钟锁相环)调整时间,通过设置LOCKTIME寄存器 [15:0]设置MPLL调整时间,这两个调整时间数值一般用其默认值。              2、设置FCLK、UCLK于晶振输入频率倍数 即倍频设置MPLL、UPLL寄存器                  公式:其中MPLLCON寄存器用于设置处理器内核时钟主频FCLK,而UPLLCON寄存器用于设置USB时钟UCLK 。                       1、FCLK=MPLL=(2*m*Fin)/(p*2^s)  其中m=(MDIV+8), p=(PDIV+2), s=SDIV。
                      2、UCLK=UPLL=(*m*Fin)/(p*2^s)  , 其中m=(MDIV+8), p=(PDIV+2), s=SDIV。                         下面以TX2440开发板:Fin=12M,需要设置FCLK=400MHz为例。  设置MDIV= 92  PDIV= 1  SDIV=1                        FCLK=MPLL=(2*m*Fin)/(p*2^s) =(2*(MDIV+8)*12/((PDIV+2)*2^SDIV)=24*100/(3*2)=400MHz,与需要设置一样。             MDIV、PDIV、SDIV设置值可以参考datasheet提供推荐值               3、设置FCLK,HCLK,PCLK三者之间的比例 即设置时钟分频寄存器CLKDIVN和摄像头分频寄存器CAMDIVN    
         详细FCLK:HCLK:PCLK分频配置如下表:               例如已知FCLK=400MHz,需要设置HCLK=50MHz,PCLK=25MHz,则FCLK:HCLK:PCLK=1:8:16,           由上表可知:HDIVN=2,PDIVN=1,HCLK3_HALF=0,HCLK4_HALF=1,                              即CLKDIVN=(HDIVN<<1)| PDIVN,  CAMDIVN=(CAMDIVN & ~(3<<8))  |  (HCLK4_HALF<<9)          注:1、谨慎设置CLKDIVN,不要使HCLK和PCLK低于最小值                  2、时钟控制寄存器CLKCON,使能/禁止 硬件模块和工作模式时的时钟源    3、程序          分析TX2440提供源码。 //选择系统时钟频率,用SetSysFclk() #define FCLK_200M ((94<<12)|(4<<4)|1) #define FCLK_300M ((67<<12)|(1<<4)|1) #define FCLK_400M ((92<<12)|(1<<4)|1) #define FCLK_440M ((102<<12)|(1<<4)|1) #define FCLK_220M ((102<<12)|(4<<4)|1) void Main(void) { SetSysFclk(FCLK_400M); //设置系统时钟 400M ChangeClockDivider(2, 1); //设置分频 1:8:16 CalcBusClk(); //计算总线频率,其中未设置locktime,使用默认值 Uart_Select(0); Uart_Init(0, 115200); Uart_Printf(" FCLK = %d MHz ", FCLK/1000000); Uart_Printf(" HCLK = %d MHz ", HCLK/1000000); Uart_Printf(" PCLK = %d MHz ", PCLK/1000000); }void SetSysFclk(int val) //设置系统时钟 { rMPLLCON = val; } void ChangeClockDivider(int hdivn,int pdivn) //设置分频寄存器 { // hdivn,pdivn FCLK:HCLK:PCLK // 0,0 1:1:1 // 0,1 1:1:2 // 1,0 1:2:2 // 1,1 1:2:4 // 2,0 1:4:4或1:8:8 由HCLK4_HALF决定,这里默认HCLK4_HALF=1,即1:8:8 // 2,1 1:4:8或1:8:16由HCLK4_HALF决定,这里默认HCLK4_HALF=1,即1:8:16 // 3,0 1:3:3或1:6:6由HCLK3_HALF决定,这里默认HCLK3_HALF=1,即1:6:6 // 3,1 1:3:6或1:6:12由HCLK3_HALF决定,这里默认HCLK3_HALF=1,即1:6:12 rCLKDIVN = (hdivn<<1) | pdivn; if (hdivn == 2) rCAMDIVN = (rCAMDIVN & ~(3<<8)) | (1<<9);//(1<<9)即HCLK4_HALF=1 if (hdivn == 3) rCAMDIVN = (rCAMDIVN & ~(3<<8)) | (1<<8); } void CalcBusClk(void) //计算总线频率 { U32 val; U8 m, p, s; val = rMPLLCON; m = (val >> 12) & 0xff;//读取MDIV p = (val >> 4) & 0x3f;//读取PDIV s = val & 3; //读取SDIV FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<> 1) & 3; //获取m=HDIVN p = val & 1; //获取m=PDIVN val = rCAMDIVN; s = val >> 8; //获取s=由HCLK4_HALF和由HCLK3_HALF /*下面分频计算方法参考CLKDIVN寄存器说明 HDIVN [2:1] 00:HCLK = FCLK/1 01:HCLK = FCLK/2 10:HCLK = FCLK/4 当CAMDIVN[9] = 0 时 HCLK = FCLK/8 当CAMDIVN[9] = 1 时 11:HCLK = FCLK/3 当CAMDIVN[8] = 0 时 HCLK = FCLK/6 当CAMDIVN[8] = 1 时 PDIVN [0] 0:PCLK 是和HCLK/1 相同的时钟 1:PCLK 是和HCLK/2 相同的时钟 */ switch (m) { case 0: HCLK = FCLK; break; case 1: HCLK = FCLK >> 1; break; case 2: if(s & 2) HCLK = FCLK >> 3; else HCLK = FCLK >> 2; break; case 3: if(s & 1) HCLK = FCLK / 6; else HCLK = FCLK / 3; break; } if(p) PCLK = HCLK >> 1; else PCLK = HCLK; val = rUPLLCON; m = (val >> 12) & 0xff; p = (val >> 4) & 0x3f; s = val & 3; UPLL = ((m+8)*FIN)/((p+2)*(1<>1):UPLL;//判断CLKDIVN[3]中UCLK选择位? //若为1,UCLK=UPLL/2;若为0,UCLK=UPLL } void ChangeMPllValue(int mdiv,int pdiv,int sdiv) //修改MPLL { rMPLLCON = (mdiv<<12) | (pdiv<<4) | sdiv; } void ChangeUPllValue(int mdiv,int pdiv,int sdiv)//修改UPLL { rUPLLCON = (mdiv<<12) | (pdiv<<4) | sdiv; }
二、电源管理(待完善)            关于电源控制逻辑,S3C2440A 包含了各种电源管理方案来保证对给定任务的最佳功耗。S3C2440A 中的电源管理模块可以激活成四种模式:正常(NORMAL)模式、慢速(SLOW)模式、空闲(IDLE)模式和睡眠(SLEEP)模式。
    普通(NORMAL)模式:这个模式提供时钟给CPU,也提供给所有S3C2440A 的外设。在此模式中,当所有外设都开启时功耗将将达到最大。它允许用户用软件控制外设的运行。例如如果一个定时器不是必须的,用户可以断开连接到定时器的时钟(CLKCON 寄存器),以降低功耗。
   慢速(SLOW)模式:无PLL 模式。不像普通模式,慢速模式使用一个外部时钟(XTIpll 或EXTCLK)直接作为FCLK 给S3C2440A,而没有使用PLL。在此模式中,功耗只取决于外部时钟的频率。排除了因PLL 而产生的功耗。
   空闲(IDLE)模式:这个模块只断开了CPU 内核的时钟(FCLK),但它提供时钟给所有其它外设。空闲模式产生了因CPU 内核而产生的功耗减少的结果。任何中断请求给CPU 都可以使其从空闲模式中唤醒。
  睡眠(SLEEP)模式:这个模块与内部供电是分离的。因此在此模式中发生了没有因CPU 和除唤醒逻辑以外的内部逻辑的功耗。要激活睡眠模式需要两个独立的供电电源。两个电源之一提供电源给唤醒逻辑。另一个提供电源给包括CPU 在内的其它内部逻辑,而且应当能够控制供电的开和关。在睡眠模式中,第二个为CPU 和内部逻辑供电电源将被关闭。可以由EINT[15:0]或RTC 闹铃中断产生从睡眠模式中唤醒。