Commit 75d1ea7f authored by wdenk's avatar wdenk

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

parent 68766094
......@@ -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
......
......@@ -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
......
......@@ -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);
......
......@@ -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)? */
......
......@@ -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
......
......@@ -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)
......
......@@ -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
......
......@@ -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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment