diff options
Diffstat (limited to 'cpu/mpc83xx/cpu.c')
| -rw-r--r-- | cpu/mpc83xx/cpu.c | 160 | 
1 files changed, 136 insertions, 24 deletions
| diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c index 20bba6c66..1b5107881 100644 --- a/cpu/mpc83xx/cpu.c +++ b/cpu/mpc83xx/cpu.c @@ -1,5 +1,5 @@  /* - * Copyright 2004 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2006 Freescale Semiconductor, Inc.   *   * See file CREDITS for list of people who contributed to this   * project. @@ -18,11 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 59 Temple Place, Suite 330, Boston,   * MA 02111-1307 USA - * - * Change log: - * - * 20050101: Eran Liberty (liberty@freescale.com) - *	     Initial file creating (porting from 85XX & 8260)   */  /* @@ -43,35 +38,140 @@ DECLARE_GLOBAL_DATA_PTR;  int checkcpu(void)  { +	volatile immap_t *immr;  	ulong clock = gd->cpu_clk;  	u32 pvr = get_pvr(); +	u32 spridr;  	char buf[32]; +	immr = (immap_t *)CFG_IMMR; +  	if ((pvr & 0xFFFF0000) != PVR_83xx) {  		puts("Not MPC83xx Family!!!\n");  		return -1;  	} -	puts("CPU:   MPC83xx, "); -	switch(pvr) { -	case PVR_8349_REV10: +	spridr = immr->sysconf.spridr; +	puts("CPU: "); +	switch(spridr) { +	case SPR_8349E_REV10: +	case SPR_8349E_REV11: +		puts("MPC8349E, "); +		break; +	case SPR_8349_REV10: +	case SPR_8349_REV11: +		puts("MPC8349, "); +		break; +	case SPR_8347E_REV10_TBGA: +	case SPR_8347E_REV11_TBGA: +	case SPR_8347E_REV10_PBGA: +	case SPR_8347E_REV11_PBGA: +		puts("MPC8347E, "); +		break; +	case SPR_8347_REV10_TBGA: +	case SPR_8347_REV11_TBGA: +	case SPR_8347_REV10_PBGA: +	case SPR_8347_REV11_PBGA: +		puts("MPC8347, "); +		break; +	case SPR_8343E_REV10: +	case SPR_8343E_REV11: +		puts("MPC8343E, "); +		break; +	case SPR_8343_REV10: +	case SPR_8343_REV11: +		puts("MPC8343, ");  		break; -	case PVR_8349_REV11: +	case SPR_8360E_REV10: +	case SPR_8360E_REV11: +	case SPR_8360E_REV12: +		puts("MPC8360E, "); +		break; +	case SPR_8360_REV10: +	case SPR_8360_REV11: +	case SPR_8360_REV12: +		puts("MPC8360, ");  		break;  	default:  		puts("Rev: Unknown\n");  		return -1;	/* Not sure what this is */  	} -	printf("Rev: %d.%d at %s MHz\n", (pvr & 0xf0) >> 4, -		(pvr & 0x0f), strmhz(buf, clock)); +#if defined(CONFIG_MPC8349) +	printf("Rev: %02x at %s MHz\n", (spridr & 0x0000FFFF)>>4 |(spridr & 0x0000000F), strmhz(buf, clock)); +#else +	printf("Rev: %02x at %s MHz\n", spridr & 0x0000FFFF, strmhz(buf, clock)); +#endif  	return 0;  } +/* + * Program a UPM with the code supplied in the table. + * + * The 'dummy' variable is used to increment the MAD. 'dummy' is + * supposed to be a pointer to the memory of the device being + * programmed by the UPM.  The data in the MDR is written into + * memory and the MAD is incremented every time there's a read + * from 'dummy'. Unfortunately, the current prototype for this + * function doesn't allow for passing the address of this + * device, and changing the prototype will break a number lots + * of other code, so we need to use a round-about way of finding + * the value for 'dummy'. + * + * The value can be extracted from the base address bits of the + * Base Register (BR) associated with the specific UPM.  To find + * that BR, we need to scan all 8 BRs until we find the one that + * has its MSEL bits matching the UPM we want.  Once we know the + * right BR, we can extract the base address bits from it. + * + * The MxMR and the BR and OR of the chosen bank should all be + * configured before calling this function. + * + * Parameters: + * upm: 0=UPMA, 1=UPMB, 2=UPMC + * table: Pointer to an array of values to program + * size: Number of elements in the array.  Must be 64 or less. + */  void upmconfig (uint upm, uint *table, uint size)  { -	hang();		/* FIXME: upconfig() needed? */ +#if defined(CONFIG_MPC834X) +	volatile immap_t *immap = (immap_t *) CFG_IMMR; +	volatile lbus83xx_t *lbus = &immap->lbus; +	volatile uchar *dummy = NULL; +	const u32 msel = (upm + 4) << BR_MSEL_SHIFT;	/* What the MSEL field in BRn should be */ +	volatile u32 *mxmr = &lbus->mamr + upm;	/* Pointer to mamr, mbmr, or mcmr */ +	uint i; + +	/* Scan all the banks to determine the base address of the device */ +	for (i = 0; i < 8; i++) { +		if ((lbus->bank[i].br & BR_MSEL) == msel) { +			dummy = (uchar *) (lbus->bank[i].br & BR_BA); +			break; +		} +	} + +	if (!dummy) { +		printf("Error: %s() could not find matching BR\n", __FUNCTION__); +		hang(); +	} + +	/* Set the OP field in the MxMR to "write" and the MAD field to 000000 */ +	*mxmr = (*mxmr & 0xCFFFFFC0) | 0x10000000; + +	for (i = 0; i < size; i++) { +		lbus->mdr = table[i]; +		__asm__ __volatile__ ("sync"); +		*dummy;	/* Write the value to memory and increment MAD */ +		__asm__ __volatile__ ("sync"); +	} + +	/* Set the OP field in the MxMR to "normal" and the MAD field to 000000 */ +	*mxmr &= 0xCFFFFFC0; +#else +	printf("Error: %s() not defined for this configuration.\n", __FUNCTION__); +	hang(); +#endif  } @@ -83,7 +183,7 @@ do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  	ulong addr;  #endif -	volatile immap_t *immap = (immap_t *) CFG_IMMRBAR; +	volatile immap_t *immap = (immap_t *) CFG_IMMR;  #ifdef MPC83xx_RESET  	/* Interrupts and MMU off */ @@ -150,9 +250,21 @@ unsigned long get_tbclk(void)  #if defined(CONFIG_WATCHDOG)  void watchdog_reset (void)  { -	hang();		/* FIXME: implement watchdog_reset()? */ +#ifdef CONFIG_MPC834X +	int re_enable = disable_interrupts(); + +	/* Reset the 83xx watchdog */ +	volatile immap_t *immr = (immap_t *) CFG_IMMR; +	immr->wdt.swsrr = 0x556c; +	immr->wdt.swsrr = 0xaa39; + +	if (re_enable) +		enable_interrupts (); +#else +	hang(); +#endif  } -#endif /* CONFIG_WATCHDOG */ +#endif  #if defined(CONFIG_OF_FLAT_TREE)  void @@ -180,12 +292,12 @@ ft_cpu_setup(void *blob, bd_t *bd)  		*p = cpu_to_be32(clock);  #ifdef CONFIG_MPC83XX_TSEC1 -	p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/address", &len); +	p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/local-mac-address", &len);  		memcpy(p, bd->bi_enetaddr, 6);  #endif  #ifdef CONFIG_MPC83XX_TSEC2 -	p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/address", &len); +	p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/local-mac-address", &len);  		memcpy(p, bd->bi_enet1addr, 6);  #endif  } @@ -194,8 +306,8 @@ ft_cpu_setup(void *blob, bd_t *bd)  #if defined(CONFIG_DDR_ECC)  void dma_init(void)  { -	volatile immap_t *immap = (immap_t *)CFG_IMMRBAR; -	volatile dma8349_t *dma = &immap->dma; +	volatile immap_t *immap = (immap_t *)CFG_IMMR; +	volatile dma83xx_t *dma = &immap->dma;  	volatile u32 status = swab32(dma->dmasr0);  	volatile u32 dmamr0 = swab32(dma->dmamr0); @@ -225,8 +337,8 @@ void dma_init(void)  uint dma_check(void)  { -	volatile immap_t *immap = (immap_t *)CFG_IMMRBAR; -	volatile dma8349_t *dma = &immap->dma; +	volatile immap_t *immap = (immap_t *)CFG_IMMR; +	volatile dma83xx_t *dma = &immap->dma;  	volatile u32 status = swab32(dma->dmasr0);  	volatile u32 byte_count = swab32(dma->dmabcr0); @@ -244,8 +356,8 @@ uint dma_check(void)  int dma_xfer(void *dest, u32 count, void *src)  { -	volatile immap_t *immap = (immap_t *)CFG_IMMRBAR; -	volatile dma8349_t *dma = &immap->dma; +	volatile immap_t *immap = (immap_t *)CFG_IMMR; +	volatile dma83xx_t *dma = &immap->dma;  	volatile u32 dmamr0;  	/* initialize DMASARn, DMADAR and DMAABCRn */ |