Fix variable CPU clock for MPC859/866 systems for low CPU clocks
authorwdenk <wdenk>
Sat, 31 Jan 2004 20:06:54 +0000 (20:06 +0000)
committerwdenk <wdenk>
Sat, 31 Jan 2004 20:06:54 +0000 (20:06 +0000)
CHANGELOG
README
board/tqm8xx/tqm8xx.c
cpu/mpc8xx/cpu.c
cpu/mpc8xx/serial.c
cpu/mpc8xx/speed.c
doc/README.MPC866
include/configs/TQM866M.h

index 316e47f992a9620212e7c37e96f0fe3d60ab97fb..6a14d025faf463c0547e294984f3451f07be8d30 100644 (file)
--- 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 58267f1ebfa7f1c59dcf8e1b92fcf5772ecbd367..61d55d4f92134792f5190ab2596b86a12606e416 100644 (file)
--- 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
 
index 8cc86fcaf02ec308711c7733207946c64ddb87ac..9e9cbd3dfbb413d4d6a65757e5cd51483a9c34ee 100644 (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);
index 3fb97b07ca7df092e61a584f891e09200a5388e4..81d2047c9ccbf1e5281403d9aaf69474e796bdce 100644 (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)? */
 
index a875963df36e790bafe4ce3ce6dfe4b423446bd2..71f3ae1f458f1709a69f59a998e51d0fb02f08ad 100644 (file)
 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
index 8583eef63c75500a9aab64bd25108e79d0b45c6d..8f8efce50521ebc969573e485d1b5507ad45556b 100644 (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)
index 1464a408ca0fc65e7859f763660e0d0291f4f048..42abac8053a355b5c2e63413c38989e1241c6e33 100644 (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
index a5a759f2d71aa3cb8a7ca0a361142b897da55c1b..3aabfe687a1e5f704f44b29f4cd198450c732244 100644 (file)
 #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   */