S3C2410 CPU默认的工作主频为12MHz,使用PLL电路可以产生更高的主频供CPU及外围器件使用。
S3C2410有两个PLL:MPLL和UPLL,UPLL专用与USB设备。MPLL用于CPU及其他外围器件。
通过MPLL会产生三个部分的时钟频率:FCLK、HCLK、PLCK。
FCLK用于CPU核,HCLK用于AHB总线的设备(比如SDRAM),PCLK用于APB总线的设备(比如UART)。
从时钟结构图中可以查看到使用不同时钟频率的硬件。
下面是MPLL的启动流程:
请跟随FCLK的图像了解启动过程:
1、上电几毫秒后,晶振输出稳定,FCLK=晶振频率,nRESET信号恢复高电平后,CPU开始执行指令。
2、我们可以在程序开头启动MPLL,在设置MPLL的几个寄存器后,需要等待一段时间(Lock Time),MPLL的输出才稳定。在这段时间(Lock Time)内,FCLK停振,CPU停止工作。Lock Time的长短由寄存器LOCKTIME设定。
3、Lock Time之后,MPLL输出正常,CPU工作在新的FCLK下。
设置S3c2410的时钟频率就是设置MPLL的几个寄存器:
1、LOCKTIME:设为0x00ffffff
前面说过,MPLL启动后需要等待一段时间(Lock Time),使得其输出稳定。位[23:12]用于UPLL,位[11:0]用于MPLL。使用确省值0x00ffffff即可。
2、FCLK的设置:
MPLLCON设为(0x5c<<12)|(0x04<<4)|(0x00),可得到输出频率为200MHz。
其中,MDIV=0x5c,PDIV=0x04,SDIV=0x00。
公式Mpll(Fclk)=(m×Fin)/(p×(2^s))
【m=MDIV+8, p=PDIV+2, s=SDIV】
3、CLKDIVN:用来设置FCLK:HCLK:PCLK的比例关系,默认为1:1:1。
这里值设为0x03,即FCLK:HCLK:PCLK=1:2:4。
CLKDIVN不同的设置及对应的时钟比例关系如下图:
与MPLL的设置类似。UPLLCON设为(0x48<<12)|(0x03<<4)|(0x02),即48032,可得到输出频率为48MHz。
汇编:
1 ;To reduce PLL lock time, adjust the LOCKTIME register. ldr r0,=LOCKTIME ldr r1,=0xffffff str r1,[r0] ; delay mov r0, #DELAY 5 subs r0, r0, #1 bne %B5 ;Configure MPLL ldr r0,=MPLLCON ldr r1,=((0x5c<<12)+(0x4<<4)+0x0) ;Fin=12MHz,Fout=200MHz str r1,[r0] ; delay mov r0, #DELAY 5 subs r0, r0, #1 bne %B5 ;Configure UPLL ldr r0, =UPLLCON ldr r1, =((0x48<<12)+(0x3<<4)+0x2) ;Fin=12MHz, Fout=48MHz str r1, [r0] ; delay mov r0, #0x200 5 subs r0, r0, #1 bne %B5
C:
#define FCLK_SPEED 1 #define M_MDIV 0x5C #define M_PDIV 0x4 #define M_SDIV 0x0 #define U_M_MDIV 0x48 #define U_M_PDIV 0x3 #define U_M_SDIV 0x2 static inline void delay (unsigned long loops) { __asm__ volatile ("1:/n" "subs %0, %1, #1/n" "bne 1b":"=r" (loops):"0" (loops)); } int board_init (void) { DECLARE_GLOBAL_DATA_PTR; S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER(); S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO(); /* to reduce PLL lock time, adjust the LOCKTIME register */ clk_power->LOCKTIME = 0xFFFFFF; /* configure MPLL */ clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV); /* some delay between MPLL and UPLL */ delay (4000); /* configure UPLL */ clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV); /* some delay between MPLL and UPLL */ delay (8000) }