瀏覽代碼

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

wdenk 21 年之前
父節點
當前提交
75d1ea7f6a
共有 8 個文件被更改,包括 72 次插入20 次删除
  1. 2 0
      CHANGELOG
  2. 17 1
      README
  3. 0 8
      board/tqm8xx/tqm8xx.c
  4. 15 3
      cpu/mpc8xx/cpu.c
  5. 2 2
      cpu/mpc8xx/serial.c
  6. 24 5
      cpu/mpc8xx/speed.c
  7. 4 0
      doc/README.MPC866
  8. 8 1
      include/configs/TQM866M.h

+ 2 - 0
CHANGELOG

@@ -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

+ 17 - 1
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
 
 

+ 0 - 8
board/tqm8xx/tqm8xx.c

@@ -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);

+ 15 - 3
cpu/mpc8xx/cpu.c

@@ -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);
-	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)? */
 	/* do we have a FEC (860T/P or 852/859/866)? */
 
 

+ 2 - 2
cpu/mpc8xx/serial.c

@@ -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

+ 24 - 5
cpu/mpc8xx/speed.c

@@ -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 < 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;
 		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)

+ 4 - 0
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
 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

+ 8 - 1
include/configs/TQM866M.h

@@ -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	*/