From 75d1ea7f6aa00c280c495a1ff6502f091c4244fe Mon Sep 17 00:00:00 2001 From: wdenk Date: Sat, 31 Jan 2004 20:06:54 +0000 Subject: Fix variable CPU clock for MPC859/866 systems for low CPU clocks --- CHANGELOG | 2 ++ README | 18 +++++++++++++++++- board/tqm8xx/tqm8xx.c | 8 -------- cpu/mpc8xx/cpu.c | 18 +++++++++++++++--- cpu/mpc8xx/serial.c | 4 ++-- cpu/mpc8xx/speed.c | 29 ++++++++++++++++++++++++----- doc/README.MPC866 | 4 ++++ include/configs/TQM866M.h | 9 ++++++++- 8 files changed, 72 insertions(+), 20 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 316e47f99..6a14d025f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -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 diff --git a/README b/README index 58267f1eb..61d55d4f9 100644 --- a/README +++ b/README @@ -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 diff --git a/board/tqm8xx/tqm8xx.c b/board/tqm8xx/tqm8xx.c index 8cc86fcaf..9e9cbd3df 100644 --- a/board/tqm8xx/tqm8xx.c +++ b/board/tqm8xx/tqm8xx.c @@ -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); diff --git a/cpu/mpc8xx/cpu.c b/cpu/mpc8xx/cpu.c index 3fb97b07c..81d2047c9 100644 --- a/cpu/mpc8xx/cpu.c +++ b/cpu/mpc8xx/cpu.c @@ -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)? */ diff --git a/cpu/mpc8xx/serial.c b/cpu/mpc8xx/serial.c index a875963df..71f3ae1f4 100644 --- a/cpu/mpc8xx/serial.c +++ b/cpu/mpc8xx/serial.c @@ -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 diff --git a/cpu/mpc8xx/speed.c b/cpu/mpc8xx/speed.c index 8583eef63..8f8efce50 100644 --- a/cpu/mpc8xx/speed.c +++ b/cpu/mpc8xx/speed.c @@ -25,7 +25,7 @@ #include #include -#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) diff --git a/doc/README.MPC866 b/doc/README.MPC866 index 1464a408c..42abac805 100644 --- a/doc/README.MPC866 +++ b/doc/README.MPC866 @@ -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 diff --git a/include/configs/TQM866M.h b/include/configs/TQM866M.h index a5a759f2d..3aabfe687 100644 --- a/include/configs/TQM866M.h +++ b/include/configs/TQM866M.h @@ -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 */ -- cgit v1.2.3