diff options
Diffstat (limited to 'board/cpc45/flash.c')
| -rw-r--r-- | board/cpc45/flash.c | 311 | 
1 files changed, 170 insertions, 141 deletions
| diff --git a/board/cpc45/flash.c b/board/cpc45/flash.c index 904923543..37dd182ba 100644 --- a/board/cpc45/flash.c +++ b/board/cpc45/flash.c @@ -41,12 +41,12 @@  #define MAIN_SECT_SIZE  0x40000  #define PARAM_SECT_SIZE 0x8000 -flash_info_t    flash_info[CFG_MAX_FLASH_BANKS]; +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; -static int write_data (flash_info_t *info, ulong dest, ulong *data); -static void write_via_fpu(vu_long *addr, ulong *data); -static __inline__ unsigned long get_msr(void); -static __inline__ void set_msr(unsigned long msr); +static int write_data (flash_info_t * info, ulong dest, ulong * data); +static void write_via_fpu (vu_long * addr, ulong * data); +static __inline__ unsigned long get_msr (void); +static __inline__ void set_msr (unsigned long msr);  /*---------------------------------------------------------------------*/  #undef	DEBUG_FLASH @@ -62,102 +62,132 @@ static __inline__ void set_msr(unsigned long msr);  /*-----------------------------------------------------------------------   */ -unsigned long flash_init(void) +unsigned long flash_init (void)  { -    int i, j; -    ulong size = 0; -    uchar tempChar; +	int i, j; +	ulong size = 0; +	uchar tempChar; +	vu_long *tmpaddr; -   /* Enable flash writes on CPC45 */ +	/* Enable flash writes on CPC45 */ -    tempChar = BOARD_CTRL; +	tempChar = BOARD_CTRL; -    tempChar |= (B_CTRL_FWPT_1 | B_CTRL_FWRE_1); +	tempChar |= (B_CTRL_FWPT_1 | B_CTRL_FWRE_1); -    tempChar &= ~(B_CTRL_FWPT_0 | B_CTRL_FWRE_0); +	tempChar &= ~(B_CTRL_FWPT_0 | B_CTRL_FWRE_0); -    BOARD_CTRL = tempChar; +	BOARD_CTRL = tempChar; +	__asm__ volatile ("sync\n eieio"); -    for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { -	vu_long *addr = (vu_long *)(CFG_FLASH_BASE + i * FLASH_BANK_SIZE); +	for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { +		vu_long *addr = (vu_long *) (CFG_FLASH_BASE + i * FLASH_BANK_SIZE); -	addr[0] = 0x00900090; +		addr[0] = 0x00900090; -	DEBUGF ("Flash bank # %d:\n" -		"\tManuf. ID @ 0x%08lX: 0x%08lX\n" -		"\tDevice ID @ 0x%08lX: 0x%08lX\n", -		i, -		(ulong)(&addr[0]), addr[0], -		(ulong)(&addr[2]), addr[2]); +		__asm__ volatile ("sync\n eieio"); +		udelay (100); -	if ((addr[0] == addr[1]) && (addr[0] == INTEL_MANUFACT) && -	    (addr[2] == addr[3]) && (addr[2] == INTEL_ID_28F160F3T)) -	{ +		DEBUGF ("Flash bank # %d:\n" +			"\tManuf. ID @ 0x%08lX: 0x%08lX\n" +			"\tDevice ID @ 0x%08lX: 0x%08lX\n", +			i, +			(ulong) (&addr[0]), addr[0], +			(ulong) (&addr[2]), addr[2]); -	    flash_info[i].flash_id = (FLASH_MAN_INTEL & FLASH_VENDMASK) | -				     (INTEL_ID_28F160F3T & FLASH_TYPEMASK); -	} else { -	    flash_info[i].flash_id = FLASH_UNKNOWN; -	    addr[0] = 0xFFFFFFFF; -	    goto Done; -	} +		if ((addr[0] == addr[1]) && (addr[0] == INTEL_MANUFACT) && +		    (addr[2] == addr[3]) && (addr[2] == INTEL_ID_28F160F3T)) { -	DEBUGF ("flash_id = 0x%08lX\n", flash_info[i].flash_id); +			flash_info[i].flash_id = +				(FLASH_MAN_INTEL & FLASH_VENDMASK) | +				(INTEL_ID_28F160F3T & FLASH_TYPEMASK); -	addr[0] = 0xFFFFFFFF; +		} else if ((addr[0] == addr[1]) && (addr[0] == INTEL_MANUFACT) +			 && (addr[2] == addr[3]) +			 && (addr[2] == INTEL_ID_28F160C3T)) { + +			flash_info[i].flash_id = +				(FLASH_MAN_INTEL & FLASH_VENDMASK) | +				(INTEL_ID_28F160C3T & FLASH_TYPEMASK); -	flash_info[i].size = FLASH_BANK_SIZE; -	flash_info[i].sector_count = CFG_MAX_FLASH_SECT; -	memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT); -	for (j = 0; j < flash_info[i].sector_count; j++) { -		if (j > 30) { -			flash_info[i].start[j] = CFG_FLASH_BASE + -						 i * FLASH_BANK_SIZE + -						 (MAIN_SECT_SIZE * 31) + (j - 31) * PARAM_SECT_SIZE;  		} else { -			flash_info[i].start[j] = CFG_FLASH_BASE + -						 i * FLASH_BANK_SIZE + -						 j * MAIN_SECT_SIZE; +			flash_info[i].flash_id = FLASH_UNKNOWN; +			addr[0] = 0xFFFFFFFF; +			goto Done; +		} + +		DEBUGF ("flash_id = 0x%08lX\n", flash_info[i].flash_id); + +		addr[0] = 0xFFFFFFFF; + +		flash_info[i].size = FLASH_BANK_SIZE; +		flash_info[i].sector_count = CFG_MAX_FLASH_SECT; +		memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT); +		for (j = 0; j < flash_info[i].sector_count; j++) { +			if (j > 30) { +				flash_info[i].start[j] = CFG_FLASH_BASE + +					i * FLASH_BANK_SIZE + +					(MAIN_SECT_SIZE * 31) + (j - +								 31) * +					PARAM_SECT_SIZE; +			} else { +				flash_info[i].start[j] = CFG_FLASH_BASE + +					i * FLASH_BANK_SIZE + +					j * MAIN_SECT_SIZE; +			}  		} + +		/* unlock sectors, if 160C3T */ + +		for (j = 0; j < flash_info[i].sector_count; j++) { +			tmpaddr = (vu_long *) flash_info[i].start[j]; + +			if ((flash_info[i].flash_id & FLASH_TYPEMASK) == +			    (INTEL_ID_28F160C3T & FLASH_TYPEMASK)) { +				tmpaddr[0] = 0x00600060; +				tmpaddr[0] = 0x00D000D0; +				tmpaddr[1] = 0x00600060; +				tmpaddr[1] = 0x00D000D0; +			} +		} + +		size += flash_info[i].size; + +		addr[0] = 0x00FF00FF; +		addr[1] = 0x00FF00FF;  	} -	size += flash_info[i].size; -    } -    /* Protect monitor and environment sectors -     */ -#if CFG_MONITOR_BASE >= CFG_FLASH_BASE +	/* Protect monitor and environment sectors +	 */  #if CFG_MONITOR_BASE >= CFG_FLASH_BASE + FLASH_BANK_SIZE -    flash_protect(FLAG_PROTECT_SET, -	      CFG_MONITOR_BASE, -	      CFG_MONITOR_BASE + monitor_flash_len - 1, -	      &flash_info[1]); +	flash_protect (FLAG_PROTECT_SET, +		       CFG_MONITOR_BASE, +		       CFG_MONITOR_BASE + monitor_flash_len - 1, +		       &flash_info[1]);  #else -    flash_protect(FLAG_PROTECT_SET, -	      CFG_MONITOR_BASE, -	      CFG_MONITOR_BASE + monitor_flash_len - 1, -	      &flash_info[0]); -#endif +	flash_protect (FLAG_PROTECT_SET, +		       CFG_MONITOR_BASE, +		       CFG_MONITOR_BASE + monitor_flash_len - 1, +		       &flash_info[0]);  #endif  #if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)  #if CFG_ENV_ADDR >= CFG_FLASH_BASE + FLASH_BANK_SIZE -    flash_protect(FLAG_PROTECT_SET, -	      CFG_ENV_ADDR, -	      CFG_ENV_ADDR + CFG_ENV_SIZE - 1, -	      &flash_info[1]); +	flash_protect (FLAG_PROTECT_SET, +		       CFG_ENV_ADDR, +		       CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[1]);  #else -    flash_protect(FLAG_PROTECT_SET, -	      CFG_ENV_ADDR, -	      CFG_ENV_ADDR + CFG_ENV_SIZE - 1, -	      &flash_info[0]); +	flash_protect (FLAG_PROTECT_SET, +		       CFG_ENV_ADDR, +		       CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);  #endif  #endif  Done: -    return size; +	return size;  }  /*----------------------------------------------------------------------- @@ -179,6 +209,11 @@ void flash_print_info (flash_info_t * info)  	case (INTEL_ID_28F160F3T & FLASH_TYPEMASK):  		printf ("28F160F3T (16Mbit)\n");  		break; + +	case (INTEL_ID_28F160C3T & FLASH_TYPEMASK): +		printf ("28F160C3T (16Mbit)\n"); +		break; +  	default:  		printf ("Unknown Chip Type 0x%04x\n", i);  		goto Done; @@ -186,7 +221,7 @@ void flash_print_info (flash_info_t * info)  	}  	printf ("  Size: %ld MB in %d Sectors\n", -			info->size >> 20, info->sector_count); +		info->size >> 20, info->sector_count);  	printf ("  Sector Start Addresses:");  	for (i = 0; i < info->sector_count; i++) { @@ -194,7 +229,7 @@ void flash_print_info (flash_info_t * info)  			printf ("\n   ");  		}  		printf (" %08lX%s", info->start[i], -				info->protect[i] ? " (RO)" : "     "); +			info->protect[i] ? " (RO)" : "     ");  	}  	printf ("\n"); @@ -205,7 +240,7 @@ Done:  /*-----------------------------------------------------------------------   */ -int	flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t * info, int s_first, int s_last)  {  	int flag, prot, sect;  	ulong start, now, last; @@ -229,33 +264,32 @@ int	flash_erase (flash_info_t *info, int s_first, int s_last)  	}  	prot = 0; -	for (sect=s_first; sect<=s_last; ++sect) { +	for (sect = s_first; sect <= s_last; ++sect) {  		if (info->protect[sect]) {  			prot++;  		}  	}  	if (prot) { -		printf ("- Warning: %d protected sectors will not be erased!\n", -			prot); +		printf ("- Warning: %d protected sectors will not be erased!\n", prot);  	} else {  		printf ("\n");  	}  	start = get_timer (0); -	last  = start; +	last = start;  	/* Start erase on unprotected sectors */ -	for (sect = s_first; sect<=s_last; sect++) { +	for (sect = s_first; sect <= s_last; sect++) {  		if (info->protect[sect] == 0) {	/* not protected */ -			vu_long *addr = (vu_long *)(info->start[sect]); +			vu_long *addr = (vu_long *) (info->start[sect]);  			DEBUGF ("Erase sect %d @ 0x%08lX\n", -				sect, (ulong)addr); +				sect, (ulong) addr);  			/* Disable interrupts which might cause a timeout  			 * here.  			 */ -			flag = disable_interrupts(); +			flag = disable_interrupts ();  			addr[0] = 0x00500050;	/* clear status register */  			addr[0] = 0x00200020;	/* erase setup */ @@ -267,23 +301,23 @@ int	flash_erase (flash_info_t *info, int s_first, int s_last)  			/* re-enable interrupts if necessary */  			if (flag) -				enable_interrupts(); +				enable_interrupts ();  			/* wait at least 80us - let's wait 1 ms */  			udelay (1000);  			while (((addr[0] & 0x00800080) != 0x00800080) || -			       ((addr[1] & 0x00800080) != 0x00800080) ) { -				if ((now=get_timer(start)) > -					   CFG_FLASH_ERASE_TOUT) { +			       ((addr[1] & 0x00800080) != 0x00800080)) { +				if ((now = get_timer (start)) > +				    CFG_FLASH_ERASE_TOUT) {  					printf ("Timeout\n"); -					addr[0] = 0x00B000B0; /* suspend erase */ -					addr[0] = 0x00FF00FF; /* to read mode  */ +					addr[0] = 0x00B000B0;	/* suspend erase */ +					addr[0] = 0x00FF00FF;	/* to read mode  */  					return 1;  				}  				/* show that we're waiting */ -				if ((now - last) > 1000) {  /* every second  */ +				if ((now - last) > 1000) {	/* every second  */  					putc ('.');  					last = now;  				} @@ -306,7 +340,7 @@ int	flash_erase (flash_info_t *info, int s_first, int s_last)  #define	FLASH_WIDTH	8	/* flash bus width in bytes */ -int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)  {  	ulong wp, cp, msr;  	int l, rc, i; @@ -315,16 +349,16 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)  	ulong *datal = &data[1];  	DEBUGF ("Flash write_buff: @ 0x%08lx, src 0x%08lx len %ld\n", -		addr, (ulong)src, cnt); +		addr, (ulong) src, cnt);  	if (info->flash_id == FLASH_UNKNOWN) {  		return 4;  	} -	msr = get_msr(); -	set_msr(msr | MSR_FP); +	msr = get_msr (); +	set_msr (msr | MSR_FP); -	wp = (addr & ~(FLASH_WIDTH-1));	/* get lower aligned address */ +	wp = (addr & ~(FLASH_WIDTH - 1));	/* get lower aligned address */  	/*  	 * handle unaligned start bytes @@ -335,39 +369,35 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)  		for (i = 0, cp = wp; i < l; i++, cp++) {  			if (i >= 4) {  				*datah = (*datah << 8) | -						((*datal & 0xFF000000) >> 24); +					((*datal & 0xFF000000) >> 24);  			} -			*datal = (*datal << 8) | (*(uchar *)cp); +			*datal = (*datal << 8) | (*(uchar *) cp);  		}  		for (; i < FLASH_WIDTH && cnt > 0; ++i) { -			char tmp; - -			tmp = *src; - -			src++; +			char tmp = *src++;  			if (i >= 4) {  				*datah = (*datah << 8) | -						((*datal & 0xFF000000) >> 24); +					((*datal & 0xFF000000) >> 24);  			}  			*datal = (*datal << 8) | tmp; - -			--cnt; ++cp; +			--cnt; +			++cp;  		}  		for (; cnt == 0 && i < FLASH_WIDTH; ++i, ++cp) {  			if (i >= 4) {  				*datah = (*datah << 8) | -						((*datal & 0xFF000000) >> 24); +					((*datal & 0xFF000000) >> 24);  			} -			*datal = (*datah << 8) | (*(uchar *)cp); +			*datal = (*datah << 8) | (*(uchar *) cp);  		} -		if ((rc = write_data(info, wp, data)) != 0) { -			set_msr(msr); +		if ((rc = write_data (info, wp, data)) != 0) { +			set_msr (msr);  			return (rc);  		} @@ -378,19 +408,19 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)  	 * handle FLASH_WIDTH aligned part  	 */  	while (cnt >= FLASH_WIDTH) { -		*datah = *(ulong *)src; -		*datal = *(ulong *)(src + 4); -		if ((rc = write_data(info, wp, data)) != 0) { -			set_msr(msr); +		*datah = *(ulong *) src; +		*datal = *(ulong *) (src + 4); +		if ((rc = write_data (info, wp, data)) != 0) { +			set_msr (msr);  			return (rc);  		} -		wp  += FLASH_WIDTH; +		wp += FLASH_WIDTH;  		cnt -= FLASH_WIDTH;  		src += FLASH_WIDTH;  	}  	if (cnt == 0) { -		set_msr(msr); +		set_msr (msr);  		return (0);  	} @@ -399,31 +429,28 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)  	 */  	*datah = *datal = 0;  	for (i = 0, cp = wp; i < FLASH_WIDTH && cnt > 0; ++i, ++cp) { -		char tmp; - -		tmp = *src; - -		src++; +		char tmp = *src++;  		if (i >= 4) { -			*datah = (*datah << 8) | ((*datal & 0xFF000000) >> 24); +			*datah = (*datah << 8) | ((*datal & 0xFF000000) >> +						  24);  		}  		*datal = (*datal << 8) | tmp; -  		--cnt;  	}  	for (; i < FLASH_WIDTH; ++i, ++cp) {  		if (i >= 4) { -			*datah = (*datah << 8) | ((*datal & 0xFF000000) >> 24); +			*datah = (*datah << 8) | ((*datal & 0xFF000000) >> +						  24);  		} -		*datal = (*datal << 8) | (*(uchar *)cp); +		*datal = (*datal << 8) | (*(uchar *) cp);  	} -	rc = write_data(info, wp, data); -	set_msr(msr); +	rc = write_data (info, wp, data); +	set_msr (msr);  	return (rc);  } @@ -434,32 +461,32 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)   * 1 - write timeout   * 2 - Flash not erased   */ -static int write_data (flash_info_t *info, ulong dest, ulong *data) +static int write_data (flash_info_t * info, ulong dest, ulong * data)  { -	vu_long *addr = (vu_long *)dest; +	vu_long *addr = (vu_long *) dest;  	ulong start;  	int flag;  	/* Check if Flash is (sufficiently) erased */  	if (((addr[0] & data[0]) != data[0]) || -	    ((addr[1] & data[1]) != data[1]) ) { +	    ((addr[1] & data[1]) != data[1])) {  		return (2);  	}  	/* Disable interrupts which might cause a timeout here */ -	flag = disable_interrupts(); +	flag = disable_interrupts (); -	addr[0] = 0x00400040;		/* write setup */ -	write_via_fpu(addr, data); +	addr[0] = 0x00400040;	/* write setup */ +	write_via_fpu (addr, data);  	/* re-enable interrupts if necessary */  	if (flag) -		enable_interrupts(); +		enable_interrupts ();  	start = get_timer (0);  	while (((addr[0] & 0x00800080) != 0x00800080) || -	       ((addr[1] & 0x00800080) != 0x00800080) ) { -		if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { +	       ((addr[1] & 0x00800080) != 0x00800080)) { +		if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {  			addr[0] = 0x00FF00FF;	/* restore read mode */  			return (1);  		} @@ -472,22 +499,24 @@ static int write_data (flash_info_t *info, ulong dest, ulong *data)  /*-----------------------------------------------------------------------   */ -static void write_via_fpu(vu_long *addr, ulong *data) +static void write_via_fpu (vu_long * addr, ulong * data)  { -	__asm__ __volatile__ ("lfd  1, 0(%0)" : : "r" (data)); -	__asm__ __volatile__ ("stfd 1, 0(%0)" : : "r" (addr)); +	__asm__ __volatile__ ("lfd  1, 0(%0)"::"r" (data)); +	__asm__ __volatile__ ("stfd 1, 0(%0)"::"r" (addr));  } +  /*-----------------------------------------------------------------------   */ -static __inline__ unsigned long get_msr(void) +static __inline__ unsigned long get_msr (void)  { -    unsigned long msr; +	unsigned long msr; + +	__asm__ __volatile__ ("mfmsr %0":"=r" (msr):); -    __asm__ __volatile__ ("mfmsr %0" : "=r" (msr) :); -    return msr; +	return msr;  } -static __inline__ void set_msr(unsigned long msr) +static __inline__ void set_msr (unsigned long msr)  { -    __asm__ __volatile__ ("mtmsr %0" : : "r" (msr)); +	__asm__ __volatile__ ("mtmsr %0"::"r" (msr));  } |