diff options
| -rw-r--r-- | arch/powerpc/cpu/mpc83xx/cpu.c | 66 | ||||
| -rw-r--r-- | arch/powerpc/cpu/mpc85xx/cpu.c | 61 | ||||
| -rw-r--r-- | arch/powerpc/cpu/mpc8xxx/fsl_lbc.c | 50 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/fsl_lbc.h | 3 | 
4 files changed, 53 insertions, 127 deletions
| diff --git a/arch/powerpc/cpu/mpc83xx/cpu.c b/arch/powerpc/cpu/mpc83xx/cpu.c index 86a24fd33..663510987 100644 --- a/arch/powerpc/cpu/mpc83xx/cpu.c +++ b/arch/powerpc/cpu/mpc83xx/cpu.c @@ -126,72 +126,6 @@ int checkcpu(void)  	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 write - * to '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) -{ -	volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; -	volatile fsl_lbc_t *lbc = &immap->im_lbc; -	volatile uchar *dummy = NULL; -	const u32 msel = (upm + 4) << BR_MSEL_SHIFT;	/* What the MSEL field in BRn should be */ -	volatile u32 *mxmr = &lbc->mamr + upm;	/* ptr to mamr, mbmr, or mcmr */ -	uint i; - -	/* Find the address for the dummy write transaction */ -	for (i = 0; i < 8; i++) { -		if ((get_lbc_br(i) & BR_MSEL) == msel) { -			dummy = (uchar *) (get_lbc_br(i) & 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++) { -		lbc->mdr = table[i]; -		__asm__ __volatile__ ("sync"); -		*dummy = 0;	/* Write the value to memory and increment MAD */ -		__asm__ __volatile__ ("sync"); -		while(((*mxmr & 0x3f) != ((i + 1) & 0x3f))); -	} - -	/* Set the OP field in the MxMR to "normal" and the MAD field to 000000 */ -	*mxmr &= 0xCFFFFFC0; -} - -  int  do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])  { diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c index 790a6a4a4..fb8fa5ec5 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu.c +++ b/arch/powerpc/cpu/mpc85xx/cpu.c @@ -252,67 +252,6 @@ reset_85xx_watchdog(void)  #endif	/* CONFIG_WATCHDOG */  /* - * Configures a UPM. The function requires the respective MxMR to be set - * before calling this function. "size" is the number or entries, not a sizeof. - */ -void upmconfig (uint upm, uint * table, uint size) -{ -	int i, mdr, mad, old_mad = 0; -	volatile u32 *mxmr; -	volatile fsl_lbc_t *lbc = LBC_BASE_ADDR; -	volatile u8* dummy = NULL; -	int upmmask; - -	switch (upm) { -	case UPMA: -		mxmr = &lbc->mamr; -		upmmask = BR_MS_UPMA; -		break; -	case UPMB: -		mxmr = &lbc->mbmr; -		upmmask = BR_MS_UPMB; -		break; -	case UPMC: -		mxmr = &lbc->mcmr; -		upmmask = BR_MS_UPMC; -		break; -	default: -		printf("%s: Bad UPM index %d to configure\n", __FUNCTION__, upm); -		hang(); -	} - -	/* Find the address for the dummy write transaction */ -	for (i = 0; i < 8; i++) { -		if ((get_lbc_br(i) & (BR_V | BR_MSEL)) == (BR_V | upmmask)) { -			dummy = (volatile u8 *)(get_lbc_br(i) & BR_BA); -			break; -		} -	} - -	if (i == 8) { -		printf("Error: %s() could not find matching BR\n", __FUNCTION__); -		hang(); -	} - -	for (i = 0; i < size; i++) { -		/* 1 */ -		out_be32(mxmr,  (in_be32(mxmr) & 0x4fffffc0) | MxMR_OP_WARR | i); -		/* 2 */ -		out_be32(&lbc->mdr, table[i]); -		/* 3 */ -		mdr = in_be32(&lbc->mdr); -		/* 4 */ -		*(volatile u8 *)dummy = 0; -		/* 5 */ -		do { -			mad = in_be32(mxmr) & MxMR_MAD_MSK; -		} while (mad <= old_mad && !(!mad && i == (size-1))); -		old_mad = mad; -	} -	out_be32(mxmr, (in_be32(mxmr) & 0x4fffffc0) | MxMR_OP_NORM); -} - -/*   * Initializes on-chip MMC controllers.   * to override, implement board_mmc_init()   */ diff --git a/arch/powerpc/cpu/mpc8xxx/fsl_lbc.c b/arch/powerpc/cpu/mpc8xxx/fsl_lbc.c index e0a15c438..fcef40c5b 100644 --- a/arch/powerpc/cpu/mpc8xxx/fsl_lbc.c +++ b/arch/powerpc/cpu/mpc8xxx/fsl_lbc.c @@ -82,3 +82,53 @@ void init_early_memctl_regs(void)  	set_lbc_br(7, CONFIG_SYS_BR7_PRELIM);  #endif  } + +/* + * Configures a UPM. The function requires the respective MxMR to be set + * before calling this function. "size" is the number or entries, not a sizeof. + */ +void upmconfig(uint upm, uint *table, uint size) +{ +	fsl_lbc_t *lbc = LBC_BASE_ADDR; +	int i, mdr, mad, old_mad = 0; +	u32 mask = (~MxMR_OP_MSK & ~MxMR_MAD_MSK); +	u32 msel = BR_UPMx_TO_MSEL(upm); +	u32 *mxmr = &lbc->mamr + upm; +	volatile u8 *dummy = NULL; + +	if (upm < UPMA || upm > UPMC) { +		printf("Error: %s() Bad UPM index %d\n", __func__, upm); +		hang(); +	} + +	/* +	 * Find the address for the dummy write - scan all of the BRs until we +	 * find one matching the UPM and extract the base address bits from it. +	 */ +	for (i = 0; i < 8; i++) { +		if ((get_lbc_br(i) & (BR_V | BR_MSEL)) == (BR_V | msel)) { +			dummy = (volatile u8 *)(get_lbc_br(i) & BR_BA); +			break; +		} +	} + +	if (!dummy) { +		printf("Error: %s() No matching BR\n", __func__); +		hang(); +	} + +	/* Program UPM using steps outlined by the reference manual */ +	for (i = 0; i < size; i++) { +		out_be32(mxmr, (in_be32(mxmr) & mask) | MxMR_OP_WARR | i); +		out_be32(&lbc->mdr, table[i]); +		mdr = in_be32(&lbc->mdr); +		*dummy = 0; +		do { +			mad = in_be32(mxmr) & MxMR_MAD_MSK; +		} while (mad <= old_mad && !(!mad && i == (size-1))); +		old_mad = mad; +	} + +	/* Return to normal operation */ +	out_be32(mxmr, (in_be32(mxmr) & mask) | MxMR_OP_NORM); +} diff --git a/arch/powerpc/include/asm/fsl_lbc.h b/arch/powerpc/include/asm/fsl_lbc.h index 33e6dd996..82d24ab13 100644 --- a/arch/powerpc/include/asm/fsl_lbc.h +++ b/arch/powerpc/include/asm/fsl_lbc.h @@ -62,6 +62,8 @@  #define BR_V				0x00000001  #define BR_V_SHIFT			0 +#define BR_UPMx_TO_MSEL(x)		((x + 4) << BR_MSEL_SHIFT) +  #define UPMA			0  #define UPMB			1  #define UPMC			2 @@ -458,6 +460,7 @@  extern void print_lbc_regs(void);  extern void init_early_memctl_regs(void); +extern void upmconfig(uint upm, uint *table, uint size);  #define LBC_BASE_ADDR ((fsl_lbc_t *)CONFIG_SYS_LBC_ADDR)  #define get_lbc_br(i) (in_be32(&(LBC_BASE_ADDR)->bank[i].br)) |