Fix variable CPU clock for MPC859/866 systems for low CPU clocks

This commit is contained in:
wdenk 2004-01-31 20:06:54 +00:00
parent 6876609446
commit 75d1ea7f6a
8 changed files with 72 additions and 20 deletions

View File

@ -2,6 +2,8 @@
Changes since U-Boot 1.0.1:
======================================================================
* Fix variable CPU clock for MPC859/866 systems for low CPU clocks
* Implement adaptive SDRAM timing configuration based on actual CPU
clock frequency for INCA-IP; fix problem with board hanging when
switching from 150MHz to 100MHz

18
README
View File

@ -415,12 +415,28 @@ The following options need to be configured:
Define exactly one of
CONFIG_MPC8240, CONFIG_MPC8245
- 8xx CPU Options: (if using an 8xx cpu)
- 8xx CPU Options: (if using an MPC8xx cpu)
Define one or more of
CONFIG_8xx_GCLK_FREQ - if get_gclk_freq() cannot work
e.g. if there is no 32KHz
reference PIT/RTC clock
- 859/866 CPU options: (if using a MPC859 or MPC866 CPU):
CFG_866_OSCCLK
CFG_866_CPUCLK_MIN
CFG_866_CPUCLK_MAX
CFG_866_CPUCLK_DEFAULT
See doc/README.MPC866
CFG_MEASURE_CPUCLK
Define this to measure the actual CPU clock instead
of relying on the correctness of the configured
values. Mostly useful for board bringup to make sure
the PLL is locked at the intended frequency. Note
that this requires a (stable) reference clock (32 kHz
RTC clock),
- Linux Kernel Interface:
CONFIG_CLOCKS_IN_MHZ

View File

@ -128,14 +128,6 @@ int checkboard (void)
break;
putc (*s);
}
#if defined(CFG_866_CPUCLK_MIN) && defined(CFG_866_CPUCLK_MAX)
printf (" [%d.%d...%d.%d MHz]",
CFG_866_CPUCLK_MIN / 1000000,
((CFG_866_CPUCLK_MIN % 1000000) + 50000) / 100000,
CFG_866_CPUCLK_MAX / 1000000,
((CFG_866_CPUCLK_MAX % 1000000) + 50000) / 100000
);
#endif
putc ('\n');
return (0);

View File

@ -123,10 +123,22 @@ static int check_CPU (long clock, uint pvr, uint immr)
else
printf ("unknown M%s (0x%08x)", id_str, k);
printf (" at %s MHz:", strmhz (buf, clock));
printf (" %u kB I-Cache", checkicache () >> 10);
printf (" %u kB D-Cache", checkdcache () >> 10);
#if defined(CFG_866_CPUCLK_MIN) && defined(CFG_866_CPUCLK_MAX)
printf (" at %s MHz [%d.%d...%d.%d MHz]\n ",
strmhz (buf, clock),
CFG_866_CPUCLK_MIN / 1000000,
((CFG_866_CPUCLK_MIN % 1000000) + 50000) / 100000,
CFG_866_CPUCLK_MAX / 1000000,
((CFG_866_CPUCLK_MAX % 1000000) + 50000) / 100000
);
#else
printf (" at %s MHz: ", strmhz (buf, clock));
#endif
printf ("%u kB I-Cache %u kB D-Cache",
checkicache () >> 10,
checkdcache () >> 10
);
/* do we have a FEC (860T/P or 852/859/866)? */

View File

@ -71,11 +71,11 @@
static void serial_setdivisor(volatile cpm8xx_t *cp)
{
DECLARE_GLOBAL_DATA_PTR;
int divisor=gd->cpu_clk/16/gd->baudrate;
int divisor=(gd->cpu_clk + 8*gd->baudrate)/16/gd->baudrate;
if(divisor/16>0x1000) {
/* bad divisor, assume 50Mhz clock and 9600 baud */
divisor=(50*1000*1000)/16/9600;
divisor=(50*1000*1000 + 8*9600)/16/9600;
}
#ifdef CFG_BRGCLK_PRESCALE

View File

@ -25,7 +25,7 @@
#include <mpc8xx.h>
#include <asm/processor.h>
#ifndef CONFIG_TQM866M
#if !defined(CONFIG_TQM866M) || defined(CFG_MEASURE_CPUCLK)
#define PITC_SHIFT 16
#define PITR_SHIFT 16
@ -170,6 +170,10 @@ unsigned long measure_gclk(void)
#endif
}
#endif
#if !defined(CONFIG_TQM866M)
/*
* get_clocks() fills in gd->cpu_clock depending on CONFIG_8xx_GCLK_FREQ
* or (if it is not defined) measure_gclk() (which uses the ref clock)
@ -230,6 +234,9 @@ int get_clocks_866 (void)
cpuclk = CFG_866_CPUCLK_DEFAULT;
gd->cpu_clk = init_pll_866 (cpuclk);
#if defined(CFG_MEASURE_CPUCLK)
gd->cpu_clk = measure_gclk ();
#endif
if ((immr->im_clkrst.car_sccr & SCCR_EBDF11) == 0)
gd->bus_clk = gd->cpu_clk;
@ -269,8 +276,19 @@ static long init_pll_866 (long clk)
char mfi, mfn, mfd, s, pdf;
long step_mfi, step_mfn;
pdf = 0;
if (clk < 80000000) {
if (clk < 20000000) {
clk *= 2;
pdf = 1;
} else {
pdf = 0;
}
if (clk < 40000000) {
s = 2;
step_mfi = CFG_866_OSCCLK / 4;
mfd = 7;
step_mfn = CFG_866_OSCCLK / 30;
} else if (clk < 80000000) {
s = 1;
step_mfi = CFG_866_OSCCLK / 2;
mfd = 14;
@ -294,13 +312,14 @@ static long init_pll_866 (long clk)
/* Calculate effective clk
*/
n = (mfi * step_mfi) + (mfn * step_mfn);
n = ((mfi * step_mfi) + (mfn * step_mfn)) / (pdf + 1);
immr->im_clkrstk.cark_plprcrk = KAPWR_KEY;
plprcr = (immr->im_clkrst.car_plprcr & ~(PLPRCR_MFN_MSK
| PLPRCR_MFD_MSK | PLPRCR_S_MSK
| PLPRCR_MFI_MSK | PLPRCR_DBRMO))
| PLPRCR_MFI_MSK | PLPRCR_DBRMO
| PLPRCR_PDF_MSK))
| (mfn << PLPRCR_MFN_SHIFT)
| (mfd << PLPRCR_MFD_SHIFT)
| (s << PLPRCR_S_SHIFT)

View File

@ -12,6 +12,10 @@ If the "cpuclk" environment variable value is within the CPUCLK_MIN /
CPUCLK_MAX limits, the specified value is used. Otherwise, the
default CPU clock value is set.
Please make sure you understand what you are doing, and understand
the restrictions of your hardware (board, processor). For example,
ethernet will stop working for CPU clock frequencies below 25 MHz.
Please note that for now the new clock-handling code has been enabled
for the TQM866M board only, even though it should be pretty much
common for other MPC859 / MPC866 based boards also. Our intention

View File

@ -37,12 +37,19 @@
#define CONFIG_TQM866M 1 /* ...on a TQM8xxM module */
#define CFG_866_OSCCLK 10000000 /* 10 MHz - PLL input clock */
#define CFG_866_CPUCLK_MIN 10000000 /* 10 MHz - CPU minimum clock */
#define CFG_866_CPUCLK_MIN 15000000 /* 15 MHz - CPU minimum clock */
#define CFG_866_CPUCLK_MAX 133000000 /* 133 MHz - CPU maximum clock */
#define CFG_866_CPUCLK_DEFAULT 50000000 /* 50 MHz - CPU default clock */
/* (it will be used if there is no */
/* 'cpuclk' variable with valid value) */
#undef CFG_MEASURE_CPUCLK /* Measure real cpu clock */
/* (function measure_gclk() */
/* will be called) */
#ifdef CFG_MEASURE_CPUCLK
#define CFG_8XX_XIN 10000000 /* measure_gclk() needs this */
#endif
#define CONFIG_8xx_CONS_SMC1 1 /* Console is on SMC1 */
#define CONFIG_BAUDRATE 115200 /* console baudrate = 115kbps */