diff options
Diffstat (limited to 'cpu/mpc8xx')
-rw-r--r-- | cpu/mpc8xx/cpu.c | 54 | ||||
-rw-r--r-- | cpu/mpc8xx/cpu_init.c | 1 | ||||
-rw-r--r-- | cpu/mpc8xx/fec.c | 3 | ||||
-rw-r--r-- | cpu/mpc8xx/interrupts.c | 4 | ||||
-rw-r--r-- | cpu/mpc8xx/scc.c | 6 | ||||
-rw-r--r-- | cpu/mpc8xx/serial.c | 28 | ||||
-rw-r--r-- | cpu/mpc8xx/speed.c | 35 |
7 files changed, 99 insertions, 32 deletions
diff --git a/cpu/mpc8xx/cpu.c b/cpu/mpc8xx/cpu.c index 4e23228..b95e06f 100644 --- a/cpu/mpc8xx/cpu.c +++ b/cpu/mpc8xx/cpu.c @@ -42,12 +42,23 @@ static char *cpu_warning = "\n " \ "*** Warning: CPU Core has Silicon Bugs -- Check the Errata ***"; -#if ((defined(CONFIG_MPC860) || defined(CONFIG_MPC855)) && \ +#if ((defined(CONFIG_MPC86x) || defined(CONFIG_MPC855)) && \ !defined(CONFIG_MPC862)) -# ifdef CONFIG_MPC855 + +# if defined(CONFIG_MPC855) # define ID_STR "PC855" +# elif defined(CONFIG_MPC852T) +# define ID_STR "PC852T" +# elif defined(CONFIG_MPC859T) +# define ID_STR "PC859T" +# elif defined(CONFIG_MPC859DSL) +# define ID_STR "PC859DSL" +# elif defined(CONFIG_MPC860P) +# define ID_STR "PC860P" +# elif defined(CONFIG_MPC866T) +# define ID_STR "PC866T" # else -# define ID_STR "PC860" +# define ID_STR "PC86x" /* unknown 86x chip */ # endif static int check_CPU (long clock, uint pvr, uint immr) @@ -68,6 +79,10 @@ static int check_CPU (long clock, uint pvr, uint immr) m = 0; switch (k) { +#ifdef CONFIG_MPC866_et_al + /* MPC866P/MPC866T/MPC859T/MPC859DSL/MPC852T */ + case 0x08000003: pre = 'M'; suf = ""; m = 1; break; +#else case 0x00020001: pre = 'p'; suf = ""; break; case 0x00030001: suf = ""; break; case 0x00120003: suf = "A"; break; @@ -76,17 +91,16 @@ static int check_CPU (long clock, uint pvr, uint immr) case 0x00200004: suf = "B"; break; case 0x00300004: suf = "C"; break; - case 0x00310004: suf = "C1"; m = 1; - break; + case 0x00310004: suf = "C1"; m = 1; break; case 0x00200064: mid = "SR"; suf = "B"; break; case 0x00300065: mid = "SR"; suf = "C"; break; case 0x00310065: mid = "SR"; suf = "C1"; m = 1; break; case 0x05010000: suf = "D3"; m = 1; break; case 0x05020000: suf = "D4"; m = 1; break; - /* this value is not documented anywhere */ case 0x40000000: pre = 'P'; suf = "D"; m = 1; break; +#endif default: suf = NULL; break; } @@ -101,7 +115,7 @@ static int check_CPU (long clock, uint pvr, uint immr) printf (" %u kB I-Cache", checkicache () >> 10); printf (" %u kB D-Cache", checkdcache () >> 10); - /* lets check and see if we're running on a 860T (or P?) */ + /* do we have a FEC (860T/P or 852/859/866)? */ immap->im_cpm.cp_fec.fec_addr_low = 0x12345678; if (immap->im_cpm.cp_fec.fec_addr_low == 0x12345678) { @@ -114,6 +128,12 @@ static int check_CPU (long clock, uint pvr, uint immr) putc ('\n'); +#ifdef DEBUG + if(clock != measure_gclk()) { + printf ("clock %ldHz != %dHz\n", clock, measure_gclk()); + } +#endif + return 0; } @@ -316,7 +336,7 @@ int checkicache (void) volatile memctl8xx_t *memctl = &immap->im_memctl; u32 cacheon = rd_ic_cst () & IDC_ENABLED; -#ifdef CONFIG_IP860 +#ifdef CONFIG_IP86x u32 k = memctl->memc_br1 & ~0x00007fff; /* probe in flash memoryarea */ #else u32 k = memctl->memc_br0 & ~0x00007fff; /* probe in flash memoryarea */ @@ -363,7 +383,7 @@ int checkdcache (void) volatile memctl8xx_t *memctl = &immap->im_memctl; u32 cacheon = rd_dc_cst () & IDC_ENABLED; -#ifdef CONFIG_IP860 +#ifdef CONFIG_IP86x u32 k = memctl->memc_br1 & ~0x00007fff; /* probe in flash memoryarea */ #else u32 k = memctl->memc_br0 & ~0x00007fff; /* probe in flash memoryarea */ @@ -462,8 +482,20 @@ unsigned long get_tbclk (void) if (immr->im_clkrst.car_sccr & SCCR_TBS) { return (gd->cpu_clk / 16); } - - factor = (((CFG_PLPRCR) & PLPRCR_MF_MSK) >> PLPRCR_MF_SHIFT) + 1; +#define PLPRCR_val(a) (((CFG_PLPRCR) & PLPRCR_ ## a ## _MSK) >> PLPRCR_ ## a ## _SHIFT) +#ifdef CONFIG_MPC866_et_al + /* MFN + MFI + ------- + MFD + 1 + factor = ----------------- + (PDF + 1) * 2^S + */ + + factor = (PLPRCR_val(MFI) + PLPRCR_val(MFN)/(PLPRCR_val(MFD)+1))/ + (PLPRCR_val(PDF)+1) / (1<<PLPRCR_val(S)); +#else + factor = PLPRCR_val(MF)+1; +#endif oscclk = gd->cpu_clk / factor; diff --git a/cpu/mpc8xx/cpu_init.c b/cpu/mpc8xx/cpu_init.c index 83ff66a..80f763d 100644 --- a/cpu/mpc8xx/cpu_init.c +++ b/cpu/mpc8xx/cpu_init.c @@ -145,6 +145,7 @@ void cpu_init_f (volatile immap_t * immr) defined(CONFIG_RPXCLASSIC) || \ defined(CONFIG_RPXLITE) || \ defined(CONFIG_SPD823TS) || \ + defined(CONFIG_MPC86xADS) || \ (defined(CONFIG_MPC860T) && defined(CONFIG_FADS)) memctl->memc_br0 = CFG_BR0_PRELIM; diff --git a/cpu/mpc8xx/fec.c b/cpu/mpc8xx/fec.c index 85ba6b2..8ac7842 100644 --- a/cpu/mpc8xx/fec.c +++ b/cpu/mpc8xx/fec.c @@ -217,7 +217,8 @@ static int fec_init(struct eth_device* dev, bd_t * bd) volatile immap_t *immr = (immap_t *) CFG_IMMR; volatile fec_t *fecp = &(immr->im_cpm.cp_fec); -#if defined(CONFIG_FADS) && defined(CONFIG_MPC860T) +#if defined(CONFIG_FADS) && \ + ( defined(CONFIG_MPC860T) || defined(CONFIG_MPC866_et_al) ) /* configure FADS for fast (FEC) ethernet, half-duplex */ /* The LXT970 needs about 50ms to recover from reset, so * wait for it by discovering the PHY before leaving eth_init(). diff --git a/cpu/mpc8xx/interrupts.c b/cpu/mpc8xx/interrupts.c index 8664826..8bc0a1af 100644 --- a/cpu/mpc8xx/interrupts.c +++ b/cpu/mpc8xx/interrupts.c @@ -334,7 +334,11 @@ void timer_interrupt (struct pt_regs *regs) /* Reset Timer Expired and Timers Interrupt Status */ immr->im_clkrstk.cark_plprcrk = KAPWR_KEY; __asm__ ("nop"); +#ifdef CONFIG_MPC866_et_al + immr->im_clkrst.car_plprcr |= PLPRCR_TEXPS; +#else immr->im_clkrst.car_plprcr |= PLPRCR_TEXPS | PLPRCR_TMIST; +#endif /* Restore Decrementer Count */ set_dec (decrementer_count); diff --git a/cpu/mpc8xx/scc.c b/cpu/mpc8xx/scc.c index d711a63..e0fae5d 100644 --- a/cpu/mpc8xx/scc.c +++ b/cpu/mpc8xx/scc.c @@ -192,9 +192,9 @@ static int scc_init(struct eth_device* dev, bd_t *bis) volatile immap_t *immr = (immap_t *)CFG_IMMR; -#if defined(CONFIG_FADS) -#if defined(CONFIG_MPC860T) - /* The FADS860T doesn't use the MODEM_EN or DATA_VOICE signals. */ +#ifdef CONFIG_FADS +#if defined(CONFIG_MPC86xADS) || defined(CONFIG_MPC860T) + /* The MPC86xADS/FADS860T don't use the MODEM_EN or DATA_VOICE signals. */ *((uint *) BCSR4) &= ~BCSR4_ETHLOOP; *((uint *) BCSR4) |= BCSR4_TFPLDL|BCSR4_TPSQEL; *((uint *) BCSR1) &= ~BCSR1_ETHEN; diff --git a/cpu/mpc8xx/serial.c b/cpu/mpc8xx/serial.c index 81c0279..5ca4d90 100644 --- a/cpu/mpc8xx/serial.c +++ b/cpu/mpc8xx/serial.c @@ -68,6 +68,23 @@ #error "console not correctly defined" #endif +static void serial_setdivisor(volatile cpm8xx_t *cp) +{ + DECLARE_GLOBAL_DATA_PTR; + int divisor=gd->cpu_clk/16/gd->baudrate; + + if(divisor/16>0x1000) { + /* bad divisor, assume 50Mhz clock and 9600 baud */ + divisor=(50*1000*1000)/16/9600; + } + + if(divisor<=0x1000) { + cp->cp_brgc1=((divisor-1)<<1) | CPM_BRG_EN; + } else { + cp->cp_brgc1=((divisor/16-1)<<1) | CPM_BRG_EN | CPM_BRG_DIV16; + } +} + #if (defined (CONFIG_8xx_CONS_SMC1) || defined (CONFIG_8xx_CONS_SMC2)) /* @@ -229,8 +246,6 @@ int serial_init (void) void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *im = (immap_t *)CFG_IMMR; volatile cpm8xx_t *cp = &(im->im_cpm); @@ -242,8 +257,7 @@ serial_setbrg (void) cp->cp_simode = 0x00000000; - cp->cp_brgc1 = - (((gd->cpu_clk / 16 / gd->baudrate)-1) << 1) | CPM_BRG_EN; + serial_setdivisor(cp); } #ifdef CONFIG_MODEM_SUPPORT @@ -506,8 +520,6 @@ int serial_init (void) void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *im = (immap_t *)CFG_IMMR; volatile cpm8xx_t *cp = &(im->im_cpm); @@ -518,10 +530,8 @@ serial_setbrg (void) */ cp->cp_sicr &= ~(0x000000FF << (8 * SCC_INDEX)); - /* no |= needed, since BRG1 is 000 */ - cp->cp_brgc1 = - (((gd->cpu_clk / 16 / gd->baudrate)-1) << 1) | CPM_BRG_EN; + serial_setdivisor(cp); } void diff --git a/cpu/mpc8xx/speed.c b/cpu/mpc8xx/speed.c index e1c3400..ae97d97 100644 --- a/cpu/mpc8xx/speed.c +++ b/cpu/mpc8xx/speed.c @@ -32,7 +32,6 @@ #define SPEED_PITC ((SPEED_PIT_COUNTS - 1) << PITC_SHIFT) #define SPEED_PITC_INIT ((SPEED_PIT_COUNTS + 1) << PITC_SHIFT) -#if !defined(CONFIG_8xx_GCLK_FREQ) /* Access functions for the Machine State Register */ static __inline__ unsigned long get_msr(void) { @@ -46,7 +45,6 @@ static __inline__ void set_msr(unsigned long msr) { asm volatile("mtmsr %0" : : "r" (msr)); } -#endif /* ------------------------------------------------------------------------- */ @@ -83,16 +81,20 @@ static __inline__ void set_msr(unsigned long msr) * CPU clock that is an even multiple of 0.1 MHz. */ -int get_clocks (void) +unsigned long measure_gclk(void) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *immr = (immap_t *) CFG_IMMR; -#ifndef CONFIG_8xx_GCLK_FREQ volatile cpmtimer8xx_t *timerp = &immr->im_cpmtimer; ulong timer2_val; ulong msr_val; +#ifdef CONFIG_MPC866_et_al + /* dont use OSCM, only use EXTCLK/512 */ + immr->im_clkrst.car_sccr |= SCCR_RTSEL | SCCR_RTDIV; +#else + immr->im_clkrst.car_sccr &= ~(SCCR_RTSEL | SCCR_RTDIV); +#endif + /* Reset + Stop Timer 2, no cascading */ timerp->cpmt_tgcr &= ~(TGCR_CAS2 | TGCR_RST2); @@ -158,10 +160,27 @@ int get_clocks (void) timerp->cpmt_tgcr &= ~(TGCR_RST2 | TGCR_FRZ2 | TGCR_STP2); immr->im_sit.sit_piscr &= ~PISCR_PTE; - gd->cpu_clk = ((timer2_val + 2) / 4) * 100000L; /* convert to Hz */ +#ifdef CONFIG_MPC866_et_al + /* not using OSCM, using XIN, so scale appropriately */ + return (((timer2_val + 2) / 4) * (CFG_8XX_XIN/512))/8192 * 100000L; +#else + return ((timer2_val + 2) / 4) * 100000L; /* convert to Hz */ +#endif +} + +/* + * 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) + * from above. + */ +int get_clocks (void) +{ + DECLARE_GLOBAL_DATA_PTR; + volatile immap_t *immr = (immap_t *) CFG_IMMR; +#ifndef CONFIG_8xx_GCLK_FREQ + gd->cpu_clk = measure_gclk(); #else /* CONFIG_8xx_GCLK_FREQ */ - /* * If for some reason measuring the gclk frequency won't * work, we return the hardwired value. |