mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-30 19:11:37 +00:00
ppc4xx: Fix problem in PLL clock calculation
This patch was originall provided by David Mitchell <dmitchell@amcc.com> and fixes a bug in the PLL clock calculation. Signed-off-by: Stefan Roese <sr@denx.de>
This commit is contained in:
parent
35d22f957a
commit
273db7e1bd
3 changed files with 26 additions and 18 deletions
|
@ -448,12 +448,17 @@ static void serial_divs (int baudrate, unsigned long *pudiv,
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
unsigned long est; /* current estimate */
|
unsigned long est; /* current estimate */
|
||||||
unsigned long plloutb;
|
unsigned long plloutb;
|
||||||
|
unsigned long cpr_pllc;
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
|
/* check the pll feedback source */
|
||||||
|
mfcpr(cprpllc, cpr_pllc);
|
||||||
|
|
||||||
get_sys_info(&sysinfo);
|
get_sys_info(&sysinfo);
|
||||||
|
|
||||||
plloutb = ((CONFIG_SYS_CLK_FREQ * sysinfo.pllFwdDiv * sysinfo.pllFbkDiv)
|
plloutb = ((CONFIG_SYS_CLK_FREQ * ((cpr_pllc & PLLC_SRC_MASK) ?
|
||||||
/ sysinfo.pllFwdDivB);
|
sysinfo.pllFwdDivB : sysinfo.pllFwdDiv) * sysinfo.pllFbkDiv) /
|
||||||
|
sysinfo.pllFwdDivB);
|
||||||
udiv = 256; /* Assume lowest possible serial clk */
|
udiv = 256; /* Assume lowest possible serial clk */
|
||||||
div = plloutb / (16 * baudrate); /* total divisor */
|
div = plloutb / (16 * baudrate); /* total divisor */
|
||||||
umin = (plloutb / get_OPB_freq()) << 1; /* 2 x OPB divisor */
|
umin = (plloutb / get_OPB_freq()) << 1; /* 2 x OPB divisor */
|
||||||
|
|
|
@ -771,6 +771,7 @@ ulong get_PCI_freq (void)
|
||||||
void get_sys_info (PPC405_SYS_INFO * sysInfo)
|
void get_sys_info (PPC405_SYS_INFO * sysInfo)
|
||||||
{
|
{
|
||||||
unsigned long cpr_plld;
|
unsigned long cpr_plld;
|
||||||
|
unsigned long cpr_pllc;
|
||||||
unsigned long cpr_primad;
|
unsigned long cpr_primad;
|
||||||
unsigned long sysClkPeriodPs = ONE_BILLION / (CONFIG_SYS_CLK_FREQ/1000);
|
unsigned long sysClkPeriodPs = ONE_BILLION / (CONFIG_SYS_CLK_FREQ/1000);
|
||||||
unsigned long primad_cpudv;
|
unsigned long primad_cpudv;
|
||||||
|
@ -780,6 +781,7 @@ void get_sys_info (PPC405_SYS_INFO * sysInfo)
|
||||||
* Read PLL Mode registers
|
* Read PLL Mode registers
|
||||||
*/
|
*/
|
||||||
mfcpr(cprplld, cpr_plld);
|
mfcpr(cprplld, cpr_plld);
|
||||||
|
mfcpr(cprpllc, cpr_pllc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine forward divider A
|
* Determine forward divider A
|
||||||
|
@ -787,20 +789,18 @@ void get_sys_info (PPC405_SYS_INFO * sysInfo)
|
||||||
sysInfo->pllFwdDiv = ((cpr_plld & PLLD_FWDVA_MASK) >> 16);
|
sysInfo->pllFwdDiv = ((cpr_plld & PLLD_FWDVA_MASK) >> 16);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine forward divider B (should be equal to A)
|
* Determine forward divider B
|
||||||
*/
|
*/
|
||||||
sysInfo->pllFwdDivB = ((cpr_plld & PLLD_FWDVB_MASK) >> 8);
|
sysInfo->pllFwdDivB = ((cpr_plld & PLLD_FWDVB_MASK) >> 8);
|
||||||
if (sysInfo->pllFwdDivB == 0) {
|
if (sysInfo->pllFwdDivB == 0)
|
||||||
sysInfo->pllFwdDivB = 8;
|
sysInfo->pllFwdDivB = 8;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine FBK_DIV.
|
* Determine FBK_DIV.
|
||||||
*/
|
*/
|
||||||
sysInfo->pllFbkDiv = ((cpr_plld & PLLD_FBDV_MASK) >> 24);
|
sysInfo->pllFbkDiv = ((cpr_plld & PLLD_FBDV_MASK) >> 24);
|
||||||
if (sysInfo->pllFbkDiv == 0) {
|
if (sysInfo->pllFbkDiv == 0)
|
||||||
sysInfo->pllFbkDiv = 256;
|
sysInfo->pllFbkDiv = 256;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read CPR_PRIMAD register
|
* Read CPR_PRIMAD register
|
||||||
|
@ -810,30 +810,30 @@ void get_sys_info (PPC405_SYS_INFO * sysInfo)
|
||||||
* Determine PLB_DIV.
|
* Determine PLB_DIV.
|
||||||
*/
|
*/
|
||||||
sysInfo->pllPlbDiv = ((cpr_primad & PRIMAD_PLBDV_MASK) >> 16);
|
sysInfo->pllPlbDiv = ((cpr_primad & PRIMAD_PLBDV_MASK) >> 16);
|
||||||
if (sysInfo->pllPlbDiv == 0) {
|
if (sysInfo->pllPlbDiv == 0)
|
||||||
sysInfo->pllPlbDiv = 16;
|
sysInfo->pllPlbDiv = 16;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine EXTBUS_DIV.
|
* Determine EXTBUS_DIV.
|
||||||
*/
|
*/
|
||||||
sysInfo->pllExtBusDiv = (cpr_primad & PRIMAD_EBCDV_MASK);
|
sysInfo->pllExtBusDiv = (cpr_primad & PRIMAD_EBCDV_MASK);
|
||||||
if (sysInfo->pllExtBusDiv == 0) {
|
if (sysInfo->pllExtBusDiv == 0)
|
||||||
sysInfo->pllExtBusDiv = 16;
|
sysInfo->pllExtBusDiv = 16;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine OPB_DIV.
|
* Determine OPB_DIV.
|
||||||
*/
|
*/
|
||||||
sysInfo->pllOpbDiv = ((cpr_primad & PRIMAD_OPBDV_MASK) >> 8);
|
sysInfo->pllOpbDiv = ((cpr_primad & PRIMAD_OPBDV_MASK) >> 8);
|
||||||
if (sysInfo->pllOpbDiv == 0) {
|
if (sysInfo->pllOpbDiv == 0)
|
||||||
sysInfo->pllOpbDiv = 16;
|
sysInfo->pllOpbDiv = 16;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine the M factor
|
* Determine the M factor
|
||||||
*/
|
*/
|
||||||
m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivB;
|
if (cpr_pllc & PLLC_SRC_MASK)
|
||||||
|
m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivB;
|
||||||
|
else
|
||||||
|
m = sysInfo->pllFbkDiv * sysInfo->pllFwdDiv;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine VCO clock frequency
|
* Determine VCO clock frequency
|
||||||
|
@ -845,16 +845,17 @@ void get_sys_info (PPC405_SYS_INFO * sysInfo)
|
||||||
* Determine CPU clock frequency
|
* Determine CPU clock frequency
|
||||||
*/
|
*/
|
||||||
primad_cpudv = ((cpr_primad & PRIMAD_CPUDV_MASK) >> 24);
|
primad_cpudv = ((cpr_primad & PRIMAD_CPUDV_MASK) >> 24);
|
||||||
if (primad_cpudv == 0) {
|
if (primad_cpudv == 0)
|
||||||
primad_cpudv = 16;
|
primad_cpudv = 16;
|
||||||
}
|
|
||||||
|
|
||||||
sysInfo->freqProcessor = (CONFIG_SYS_CLK_FREQ * sysInfo->pllFbkDiv) / primad_cpudv;
|
sysInfo->freqProcessor = (CONFIG_SYS_CLK_FREQ * m) /
|
||||||
|
sysInfo->pllFwdDiv / primad_cpudv;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine PLB clock frequency
|
* Determine PLB clock frequency
|
||||||
*/
|
*/
|
||||||
sysInfo->freqPLB = (CONFIG_SYS_CLK_FREQ * sysInfo->pllFbkDiv) / sysInfo->pllPlbDiv;
|
sysInfo->freqPLB = (CONFIG_SYS_CLK_FREQ * m) /
|
||||||
|
sysInfo->pllFwdDiv / sysInfo->pllPlbDiv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************
|
/********************************************
|
||||||
|
|
|
@ -617,6 +617,8 @@
|
||||||
#define CPR_CLKUPD_ENDVCH_EN 0x20000000 /* Enable CPR Sys. Div. Changes */
|
#define CPR_CLKUPD_ENDVCH_EN 0x20000000 /* Enable CPR Sys. Div. Changes */
|
||||||
#define CPR_PERD0_SPIDV_MASK 0x000F0000 /* SPI Clock Divider */
|
#define CPR_PERD0_SPIDV_MASK 0x000F0000 /* SPI Clock Divider */
|
||||||
|
|
||||||
|
#define PLLC_SRC_MASK 0x20000000 /* PLL feedback source */
|
||||||
|
|
||||||
#define PLLD_FBDV_MASK 0x1F000000 /* PLL feedback divider value */
|
#define PLLD_FBDV_MASK 0x1F000000 /* PLL feedback divider value */
|
||||||
#define PLLD_FWDVA_MASK 0x000F0000 /* PLL forward divider A value */
|
#define PLLD_FWDVA_MASK 0x000F0000 /* PLL forward divider A value */
|
||||||
#define PLLD_FWDVB_MASK 0x00000700 /* PLL forward divider B value */
|
#define PLLD_FWDVB_MASK 0x00000700 /* PLL forward divider B value */
|
||||||
|
|
Loading…
Add table
Reference in a new issue