📄 pll.c
字号:
/*****************************************
NAME: pll.c
DESC: PLL & Maximum frequency test.
HISTORY:
03.21.2002:purnnamu: first release for S3C2410X
06.02.2003:DonGo: Modified for S3C2440X
Jan.e.2004:DonGo: Modified for S3C2440A
*****************************************/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include "option.h"
#include "2460addr.h"
#include "2460lib.h"
#include "2460slib.h"
#include "DRAM.h"
#include "PLL.h"
//#include "memtest.h"
//******************[ Test_Pll ]**************************************
void * func_pll_test[][2]=
{
// "123456789012345678"
(void *)Basic_test, "Basic Test ",
(void *)ChangeFCLK, "MPLL running change ",
(void *)Manual_Change_Pll, "MPLL manual change ",
(void *)Test_PLL, "MPLL change test ",
(void *)Test_Locktime, "Lock time test ",
(void *)Test_PllOnOff, "Pll On/Off test ",
(void *)Test_ARMClock, "ARM clock test ",
(void *)Test_Clk_divide, "Clock divide test ",
(void *)Test_HoldMode, "Hold mode test ",
(void *)Test_Dclk, "Dclk test ",
0,0
};
void Ch3_Pll_Test(void)
{
int i;
printf("\nPLL test.\n");
while(1)
{
i=0;
printf("\n\n");
while(1)
{ //display menu
printf("%2d:%s",i,func_pll_test[i][1]);
i++;
if((int)(func_pll_test[i][0])==0)
{
printf("\n");
break;
}
if((i%3)==0)
printf("\n");
}
printf("\nSelect (\"-1\" to exit) : ");
i = GetIntNum();
if(i==-1)
break; // return.
if(i>=0 && (i<((sizeof(func_pll_test)-1)/8)) ) // select and execute...
( (void (*)(void)) (func_pll_test[i][0]) )();
}
printf("\nPLL Test program end.\n");
}
volatile unsigned int Mps_Val[][4]={
// FCLK, M, P, S.
{80000000, 32, 1, 1},
{90000000, 37, 1, 1},
{100000000, 42, 1, 1},
{120000000, 52, 1, 1},
{140000000, 62, 1, 1},
{160000000, 32, 1, 0},
{180000000, 37, 1, 0},
{200000000, 42, 1, 0},
{220000000, 47, 1, 0},
{240000000, 52, 1, 0},
// {260000000, 57, 1, 0},
// {280000000, 62, 1, 0},
// {296000000, 66, 1, 0},
};
void Basic_test( void)
{
/*
int j,i;
int m,p,s,ARM,H,P;
float Pll;
// XCLKOUT en/disable
rSPCON = rSPCON&~(1<<17) | (0<<17);
// 0:MPLL, 1:UPLL, 2:ARMCLK, 3:HCLK, 4:PCLK, 5:DCLK
rCLKOUTCON = rCLKOUTCON&~(7<<12) | (2<<12);
while(1) {
PreChangeSDRAMParameter();
SetMLockTime(0xffff);
SetMPLL( 64, 4, 1);
SetCLKDIV(0,1,1);
m=(rMPLLCON>>16)&0xff; p=(rMPLLCON>>8)&0x3f; s=rMPLLCON&0x3;
Pll=(((m+8)*FIN)/(p+2)); for(i=0;i<s;i++) Pll/=2;
ARM=Pll/(((rCLKDIVCON>>16)&1)+1);
H=ARM/((rCLKDIVCON&3)+1);
P=H/(((rCLKDIVCON>>2)&1)+1);
ChangeSDRAMParameter(H);
Uart_Init(P,115200);
printf("\n\nSet MPLL running at %6.2fMHz, ARM: %6.2fMHz, H: %6.2fMHz, PCLK: %6.2fMHz \n",(float)Pll/1.0e6,(float)ARM/1.0e6,(float)H/1.0e6,(float)P/1.0e6);
getchar();
PreChangeSDRAMParameter();
SetMLockTime(40);
rGPIDAT=0xa;
SetMPLL(52, 2, 1);
SetCLKDIV(0,1,0);
m=(rMPLLCON>>16)&0xff; p=(rMPLLCON>>8)&0x3f; s=rMPLLCON&0x3;
Pll=(((m+8)*FIN)/(p+2)); for(i=0;i<s;i++) Pll/=2;
ARM=Pll/(((rCLKDIVCON>>16)&1)+1);
H=ARM/((rCLKDIVCON&3)+1);
P=H/(((rCLKDIVCON>>2)&1)+1);
ChangeSDRAMParameter(H);
Uart_Init(P,115200);
printf("\n\nSet MPLL running at %6.2fMHz, ARM: %6.2fMHz, H: %6.2fMHz, PCLK: %6.2fMHz \n",(float)Pll/1.0e6,(float)ARM/1.0e6,(float)H/1.0e6,(float)P/1.0e6);
getchar();
}
*/
}
void ChangeFCLK(void)
{
unsigned int i, j,k;
SetMLockTime(0x0e1);
PreChangeSDRAMParameter();
i=j=0;
printf("\nStart PLL running change test.\n");
while(1) {
SetMPLL(52,1,1); // MPLL 120 MHz
SetCLKDIV(0,1,1); // 1:2:4
SetCLKDIV(0,1,1); // 1:2:4
SetMPLL(42,1,0); // MPLL 200 MHz
Led_Display(1<<((i>>12)%4));
if(i==100000) {
i=0;
printf("count:%d\n", j++);
}
i++;
}
SetMPLL(42,1,0); // MPLL 200 MHz
ChangeSDRAMParameter(HCLK);
}
int No_Of_Mps_Val=sizeof(Mps_Val)/16;
void Test_PLL(void)
{
int temp;
int i,j, mdiv, pdiv, sdiv, sval, fclk, hdiv_val, pdiv_val;
unsigned int prev_fclk;
unsigned int mpllcon_bk, clkdivn_bk, camdivn_bk;
// clock register backup.
mpllcon_bk = rMPLLCON;
clkdivn_bk = rCLKDIVCON;
printf("[PLL frequency change test 100,00times]\n");
printf("Hit the 'q' to exit the test!!!\n");
//Uart_TxEmpty(1);
rLOCKTIME0=((unsigned int)(1807*0.8)<<16)|((unsigned int)(1807*0.8)<<0);
//rLOCKTIME=((unsigned int)(12048)<<16)|((unsigned int)(12048)<<0);
// 1807 is 150us at 12Mhz
j=0;
while(1)
{
if(Uart_GetKey()=='q')
break;
if(j>100000)
break;
i= j%No_Of_Mps_Val;
fclk = Mps_Val[i][0];
//printf("[%d]FCLK=%d [Mps_Val=%xh,%xh,%xh]\n", j, Mps_Val[i][0],Mps_Val[i][1],Mps_Val[i][2],Mps_Val[i][3]);
printf("[%d] ", j);
// Uart_TxEmpty(1);
if(Mps_Val[i][0]<=120000000)
{
hdiv_val=1;
pdiv_val=0;
}
else //(Mps_Val[i][0]<= 240000000)
{
hdiv_val=1;
pdiv_val=1;
}
Led_Display(j%2);
//printf("[FCLK:HCLK:PCLK=1:%d:%d=", hdiv_val%10, (hdiv_val%10)*(pdiv_val%10));
//printf("%4.1f:%4.1f:%4.1f MHz]\n", (float)fclk/1.0e6, (float)fclk/1.0e6/(hdiv_val%10), (float)fclk/1.0e6/((hdiv_val%10)*(pdiv_val%10)));
if(prev_fclk<Mps_Val[i][0]) {
Led_Display(0x1);
rCLKDIVCON=rCLKDIVCON&~(0x7)|(pdiv_val<<2)|(hdiv_val);
Led_Display(0x2);
SetMPLL(Mps_Val[i][1],Mps_Val[i][2],Mps_Val[i][3]);
}
else
{
Led_Display(0x2);
SetMPLL(Mps_Val[i][1],Mps_Val[i][2],Mps_Val[i][3]);
Led_Display(0x1);
rCLKDIVCON=rCLKDIVCON&~(0x7)|(pdiv_val<<2)|(hdiv_val);
}
GlobalCLK();
Init_LogicalConsole();
printf("MPLL=%.2fMHz, ARMCLK=%.2fMHz (%d:%d:%d), HCLK=%.2fMHz, PCLK=%.2fMHz\n\n",(float)MPLL/1.0e6,(float)ARMCLK/1.0e6,ARMCLKdiv+1,HCLKdiv+1,(HCLKdiv+1)*(PCLKdiv+1),(float)HCLK/1.0e6,(float)PCLK/1.0e6);
Led_Display(0x4);
ChangeSDRAMParameter(HCLK);
Led_Display(0x8);
#if 1
Mem_Test(1);
#endif
prev_fclk = Mps_Val[i][0];
j++;
}
printf("\nMPLL change test OK.\n");
printf("\nReturn to Previous setting.\n");
rMPLLCON = mpllcon_bk;
rCLKDIVCON= clkdivn_bk;
// rCAMDIVN = camdivn_bk;
GlobalCLK();
Init_LogicalConsole();
printf("MPLL=%.2fMHz, ARMCLK=%.2fMHz (%d:%d:%d), HCLK=%.2fMHz, PCLK=%.2fMHz\n\n",(float)MPLL/1.0e6,(float)ARMCLK/1.0e6,ARMCLKdiv+1,HCLKdiv+1,(HCLKdiv+1)*(PCLKdiv+1),(float)HCLK/1.0e6,(float)PCLK/1.0e6);
}
// lock time: user lock time setting time[us],
// lock_count: register setting value for wanted locktime.
#define TIME_OF_XTAL (1.0e6/(float)FIN) //us
unsigned int Calc_Locktime(unsigned int lock_time)
{
unsigned int lock_count=0;
lock_count = (unsigned int)((float)lock_time/((float)TIME_OF_XTAL));
return lock_count;
}
void Test_Locktime(void) // It's not meaningful for S3C2460X01
{
int temp;
int i,j, mdiv, pdiv, sdiv, sval, fclk, hdiv_val, pdiv_val;
unsigned int lock_time=300, lock_count=12048; //Unit is us.
unsigned int mpllcon_bk;
// clock register backup.
mpllcon_bk = rMPLLCON;
printf("[PLL Lock time test 100,000 times]\n");
printf("Lock time range: 300us - %d [us]\n", (unsigned int)(0xffff*TIME_OF_XTAL));
printf("Input Lock time[us]: ");
lock_time = GetIntNum();
lock_count = Calc_Locktime(lock_time); // lock_time [us]
rLOCKTIME0=((unsigned int)(lock_count)<<16)|((unsigned int)(lock_count)<<0);
printf("Locktime register value is %d(%xh).\n", rLOCKTIME0&0xffff, rLOCKTIME0&0xffff);
printf("Clock will be locked after LED6 is ON.\n");
i=0;
//ChangeClockDivider(12,12); // 1:2:4
while(1)
{
if(Uart_GetKey()!=0x0) break;
if(i>100000) break;
if(i%2)
{
Led_Display(0x8);
// rMPLLCON = mpllcon_bk; // if you write same mps value in rMPLLCON, don't need the PLL Lock time
SetMPLL(Mps_Val[0][1],Mps_Val[0][2],Mps_Val[0][3]);
Delay(5);
}
else
{
Led_Display(0x0);
// rMPLLCON = mpllcon_bk;
SetMPLL(Mps_Val[9][1],Mps_Val[9][2],Mps_Val[9][3]);
Delay(5);
}
// Delay(1000);
i++;
}
rMPLLCON = mpllcon_bk;
}
void Manual_Change_Pll(void)
{
unsigned int pdiv, mdiv, sdiv, fclk, armdiv_val, hdiv_val, pdiv_val;
int i, fclk_sel;
float ffclk;
printf("[Running change test of M/P/S value]\n");
for(i=0; i<sizeof(Mps_Val)/16; i++) {
if(i%2==0) printf("\n");
printf("%2d: FCLK=%4.1f [%xh(%d),%xh,%xh] ", i, (float)Mps_Val[i][0]/1.0e6,Mps_Val[i][1],Mps_Val[i][1],Mps_Val[i][2],Mps_Val[i][3]);
}
printf("\n");
printf("Select FCLK No(0-%d): ", sizeof(Mps_Val)/16-1);
fclk_sel=GetIntNum();
if ((fclk_sel>=0)&&(fclk_sel<= sizeof(Mps_Val)/16-1)) {
mdiv = Mps_Val[fclk_sel][1];
pdiv = Mps_Val[fclk_sel][2];
sdiv = Mps_Val[fclk_sel][3];
} else {
printf("Input M vlaue : ");
mdiv=GetIntNum();
printf("Input P vlaue : ");
pdiv=GetIntNum();
printf("Input S vlaue : ");
sdiv=GetIntNum();
}
printf("Input ARMCLK div valaue (0='/1',1='/2') : ");
armdiv_val=GetIntNum();
printf("Input HCLK div valaue (0='/1',1='/2',2='/3',3='/4') : ");
hdiv_val=GetIntNum();
printf("Input PCLK div valaue (0='/1',1='/2') : ");
pdiv_val=GetIntNum();
ffclk = (unsigned int) ( (((float)mdiv+8)*FIN)/(((float)pdiv+2)*(1<<sdiv))); // pll2188x.
printf("Now change MPLL value...(%.2fMHz)[mps=%xh(%d), %d, %d]\n", (float)ffclk/1.0e6, mdiv,mdiv, pdiv, sdiv);
Delay(10);
PreChangeSDRAMParameter();
SetCLKDIV(armdiv_val, hdiv_val, pdiv_val);
SetMPLL(mdiv,pdiv,sdiv);
GlobalCLK();
ChangeSDRAMParameter(HCLK);
Init_LogicalConsole();
printf("MPLL=%.2fMHz, ARMCLK=%.2fMHz (%d:%d:%d), HCLK=%.2fMHz, PCLK=%.2fMHz\n\n",(float)MPLL/1.0e6,(float)ARMCLK/1.0e6,ARMCLKdiv+1,(ARMCLKdiv+1)*(HCLKdiv+1),(ARMCLKdiv+1)*(HCLKdiv+1)*(PCLKdiv+1),(float)HCLK/1.0e6,(float)PCLK/1.0e6);
}
void Test_PllOnOff(void)
{
int i,j;
printf("[PLL On/Off test, 10000 times]\n");
// Uart_TxEmpty(1); //To avoid being crushed the character
// rLOCKTIME0=((unsigned int)(1807*0.8)<<12)|((unsigned int)(1807*0.8)<<0);
rLOCKTIME0=((unsigned int)(10*0.8)<<12)|((unsigned int)(10*0.8)<<0);
// 1807 is 150us at 12Mhz
printf("count: ");
for(j=0;j<10000;j++) {
PreChangeSDRAMParameter();
rCLKSRCCON &= ~(1<<4); // Mpll clock out: external clock
rMPLLCON |= (1<<24); // Mpll off
rUPLLCON |= (1<<24); // Upll off
Led_Display(0x2);
for(i=0;i<100000;i++);
rMPLLCON &= ~(1<<24); // Mpll on
rUPLLCON &= ~(1<<24); // Upll on
rCLKSRCCON |= (1<<4); // Mpll clock out: Mpll clk
Led_Display(0x0);
for(i=0;i<100000;i++);
ChangeSDRAMParameter(HCLK);
printf("!");
if ((j%1000)==0) printf("\n%d\n", j);
Delay(10);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -