S3C2440有兩個PLL(phase locked loop)一個是MPLL,一個是UPLL。MPLL用于CPU及其他外圍器件,UPLL用于USB。用于產(chǎn)生FCLK, HCLK, PCLK三種頻率,這三種頻率分別有不同的用途:
FCLK是CPU提供的時鐘信號。
HCLK是為AHB總線提供的時鐘信號, Advanced High-performance Bus,主要用于高速外設(shè),比如內(nèi)存控制器,中斷控制器,LCD控制器, DMA 等。
本文引用地址:http://m.butianyuan.cn/article/201611/320223.htmPCLK是提供給用于外設(shè)如WDT,IIS,I2C,PWM,MMC/SD,ADC,UART,GPIO,RTC,SPI的APB總線的時鐘。
從S3C2440的DATASHEET里可以看到,S3C2440最大支持400MHz的主頻,但是這并不意味著一定工作在400MHz下面,可以通過設(shè)定MPLL, UPLL寄存器來設(shè)定CPU的工作頻率。
盡管在CPU上電(power-on)或者復位(reset)后,MPLL就開始進入工作狀態(tài),但是此時MPLL的輸(Mpll)并不作為系統(tǒng)的時鐘,而是直接使用外部信號EXTCLK或者外部時鐘晶振作為系統(tǒng)時鐘。直到軟件初始化MPLL寄存器(rMPLLCON),寫入了有效的值過后,系統(tǒng)才開始使用MPLL的輸出(Mpll)作為系統(tǒng)時鐘。雖然很多時候我們不必重新設(shè)置MPLL寄存器(rMPLLCON)新的值,但是為了使系統(tǒng)使用其輸出作為時鐘信號,在軟件初始化系統(tǒng)部分,還是要向rMPLLCON寫入一個有效的舊的值。這樣子才使系統(tǒng)處于正確的工作狀態(tài)。
TQ2440程序中FCLK=400MHz,MDIV=92=0x5C、PDIV=1、SDIV=1
#define FIN (12000000)
rMPLLCON =(92<<12)|(1<<4)|1; //設(shè)置FCLK為400M
ChangeClockDivider(14,12); //這個函數(shù)在2440lib.c中定義的,設(shè)置分頻比為1:4:8
CalcBusClk(); //計算總線頻率
下面是被調(diào)用的兩個函數(shù)
//************************[ HCLK, PCLK ]***************************
void ChangeClockDivider(int hdivn_val,int pdivn_val)//兩個參數(shù)分別為FCLK:HCLK,HCLK:PCLK的比值
{
int hdivn=2, pdivn=0;
// hdivn_val (FCLK:HCLK)ratio hdivn
// 11 1:1 (0)
// 12 1:2 (1)
// 13 1:3 (3)
// 14 1:4 (2)
// pdivn_val (HCLK:PCLK)ratio pdivn
// 11 1:1 (0)
// 12 1:2 (1)
switch(hdivn_val) {
case 11: hdivn=0; break;
case 12: hdivn=1; break;
case 13:
case 16: hdivn=3; break;
case 14:
case 18: hdivn=2; break;
}
switch(pdivn_val) {
case 11: pdivn=0; break;
case 12: pdivn=1; break;
}
//Uart_Printf("Clock division change [hdiv:%x, pdiv:%x]", hdivn, pdivn);
rCLKDIVN = (hdivn<<1) | pdivn;
switch(hdivn_val) {
case 16:// when 1, HCLK=FCLK/8.
rCAMDIVN = (rCAMDIVN & ~(3<<8)) | (1<<8);
break;
case 18: // when 1, HCLK=FCLK/6.
rCAMDIVN = (rCAMDIVN & ~(3<<8)) | (1<<9);
break;
}
if(hdivn!=0)
MMU_SetAsyncBusMode();
else
MMU_SetFastBusMode();
}
void CalcBusClk(void) //計算總線頻率
{
U32 val,UPLL;
U8 m, p, s;
val = rMPLLCON;
m = (val >> 12) & 0xff;
p = (val >> 4) & 0x3f;
s = val & 3;
FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<
val = rCLKDIVN;
m = (val >> 1) & 3;
p = val & 1;
val = rCAMDIVN;
s = val >> 8;
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;
//rUPLLCON內(nèi)存的值為0x00038022,求出UPLL的值為48MHz;時鐘分頻控制寄存器CLKDIVN[3]=0時UCLK=UPLL
val = rUPLLCON;
m = (val >> 12) & 0xff;
p = (val >> 4) & 0x3f;
s = val & 3;
UPLL = ((m+8)*FIN)/((p+2)*(1<UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;
}
評論