Fix variable CPU clock for MPC859/866 systems for low CPU clocks
This commit is contained in:
parent
6876609446
commit
75d1ea7f6a
|
@ -2,6 +2,8 @@
|
||||||
Changes since U-Boot 1.0.1:
|
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
|
* Implement adaptive SDRAM timing configuration based on actual CPU
|
||||||
clock frequency for INCA-IP; fix problem with board hanging when
|
clock frequency for INCA-IP; fix problem with board hanging when
|
||||||
switching from 150MHz to 100MHz
|
switching from 150MHz to 100MHz
|
||||||
|
|
18
README
18
README
|
@ -415,12 +415,28 @@ The following options need to be configured:
|
||||||
Define exactly one of
|
Define exactly one of
|
||||||
CONFIG_MPC8240, CONFIG_MPC8245
|
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
|
Define one or more of
|
||||||
CONFIG_8xx_GCLK_FREQ - if get_gclk_freq() cannot work
|
CONFIG_8xx_GCLK_FREQ - if get_gclk_freq() cannot work
|
||||||
e.g. if there is no 32KHz
|
e.g. if there is no 32KHz
|
||||||
reference PIT/RTC clock
|
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:
|
- Linux Kernel Interface:
|
||||||
CONFIG_CLOCKS_IN_MHZ
|
CONFIG_CLOCKS_IN_MHZ
|
||||||
|
|
||||||
|
|
|
@ -128,14 +128,6 @@ int checkboard (void)
|
||||||
break;
|
break;
|
||||||
putc (*s);
|
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');
|
putc ('\n');
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
|
|
@ -123,10 +123,22 @@ static int check_CPU (long clock, uint pvr, uint immr)
|
||||||
else
|
else
|
||||||
printf ("unknown M%s (0x%08x)", id_str, k);
|
printf ("unknown M%s (0x%08x)", id_str, k);
|
||||||
|
|
||||||
printf (" at %s MHz:", strmhz (buf, clock));
|
|
||||||
|
|
||||||
printf (" %u kB I-Cache", checkicache () >> 10);
|
#if defined(CFG_866_CPUCLK_MIN) && defined(CFG_866_CPUCLK_MAX)
|
||||||
printf (" %u kB D-Cache", checkdcache () >> 10);
|
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)? */
|
/* do we have a FEC (860T/P or 852/859/866)? */
|
||||||
|
|
||||||
|
|
|
@ -71,11 +71,11 @@
|
||||||
static void serial_setdivisor(volatile cpm8xx_t *cp)
|
static void serial_setdivisor(volatile cpm8xx_t *cp)
|
||||||
{
|
{
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
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) {
|
if(divisor/16>0x1000) {
|
||||||
/* bad divisor, assume 50Mhz clock and 9600 baud */
|
/* 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
|
#ifdef CFG_BRGCLK_PRESCALE
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include <mpc8xx.h>
|
#include <mpc8xx.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
|
|
||||||
#ifndef CONFIG_TQM866M
|
#if !defined(CONFIG_TQM866M) || defined(CFG_MEASURE_CPUCLK)
|
||||||
|
|
||||||
#define PITC_SHIFT 16
|
#define PITC_SHIFT 16
|
||||||
#define PITR_SHIFT 16
|
#define PITR_SHIFT 16
|
||||||
|
@ -170,6 +170,10 @@ unsigned long measure_gclk(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(CONFIG_TQM866M)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get_clocks() fills in gd->cpu_clock depending on CONFIG_8xx_GCLK_FREQ
|
* 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)
|
* 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;
|
cpuclk = CFG_866_CPUCLK_DEFAULT;
|
||||||
|
|
||||||
gd->cpu_clk = init_pll_866 (cpuclk);
|
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)
|
if ((immr->im_clkrst.car_sccr & SCCR_EBDF11) == 0)
|
||||||
gd->bus_clk = gd->cpu_clk;
|
gd->bus_clk = gd->cpu_clk;
|
||||||
|
@ -269,8 +276,19 @@ static long init_pll_866 (long clk)
|
||||||
char mfi, mfn, mfd, s, pdf;
|
char mfi, mfn, mfd, s, pdf;
|
||||||
long step_mfi, step_mfn;
|
long step_mfi, step_mfn;
|
||||||
|
|
||||||
pdf = 0;
|
if (clk < 20000000) {
|
||||||
if (clk < 80000000) {
|
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;
|
s = 1;
|
||||||
step_mfi = CFG_866_OSCCLK / 2;
|
step_mfi = CFG_866_OSCCLK / 2;
|
||||||
mfd = 14;
|
mfd = 14;
|
||||||
|
@ -294,13 +312,14 @@ static long init_pll_866 (long clk)
|
||||||
|
|
||||||
/* Calculate effective 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;
|
immr->im_clkrstk.cark_plprcrk = KAPWR_KEY;
|
||||||
|
|
||||||
plprcr = (immr->im_clkrst.car_plprcr & ~(PLPRCR_MFN_MSK
|
plprcr = (immr->im_clkrst.car_plprcr & ~(PLPRCR_MFN_MSK
|
||||||
| PLPRCR_MFD_MSK | PLPRCR_S_MSK
|
| PLPRCR_MFD_MSK | PLPRCR_S_MSK
|
||||||
| PLPRCR_MFI_MSK | PLPRCR_DBRMO))
|
| PLPRCR_MFI_MSK | PLPRCR_DBRMO
|
||||||
|
| PLPRCR_PDF_MSK))
|
||||||
| (mfn << PLPRCR_MFN_SHIFT)
|
| (mfn << PLPRCR_MFN_SHIFT)
|
||||||
| (mfd << PLPRCR_MFD_SHIFT)
|
| (mfd << PLPRCR_MFD_SHIFT)
|
||||||
| (s << PLPRCR_S_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
|
CPUCLK_MAX limits, the specified value is used. Otherwise, the
|
||||||
default CPU clock value is set.
|
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
|
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
|
for the TQM866M board only, even though it should be pretty much
|
||||||
common for other MPC859 / MPC866 based boards also. Our intention
|
common for other MPC859 / MPC866 based boards also. Our intention
|
||||||
|
|
|
@ -37,12 +37,19 @@
|
||||||
#define CONFIG_TQM866M 1 /* ...on a TQM8xxM module */
|
#define CONFIG_TQM866M 1 /* ...on a TQM8xxM module */
|
||||||
|
|
||||||
#define CFG_866_OSCCLK 10000000 /* 10 MHz - PLL input clock */
|
#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_MAX 133000000 /* 133 MHz - CPU maximum clock */
|
||||||
#define CFG_866_CPUCLK_DEFAULT 50000000 /* 50 MHz - CPU default clock */
|
#define CFG_866_CPUCLK_DEFAULT 50000000 /* 50 MHz - CPU default clock */
|
||||||
/* (it will be used if there is no */
|
/* (it will be used if there is no */
|
||||||
/* 'cpuclk' variable with valid value) */
|
/* '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_8xx_CONS_SMC1 1 /* Console is on SMC1 */
|
||||||
|
|
||||||
#define CONFIG_BAUDRATE 115200 /* console baudrate = 115kbps */
|
#define CONFIG_BAUDRATE 115200 /* console baudrate = 115kbps */
|
||||||
|
|
Loading…
Reference in New Issue