diff options
| author | wdenk <wdenk> | 2003-06-27 21:31:46 +0000 | 
|---|---|---|
| committer | wdenk <wdenk> | 2003-06-27 21:31:46 +0000 | 
| commit | 8bde7f776c77b343aca29b8c7b58464d915ac245 (patch) | |
| tree | 20f1fd99975215e7c658454a15cdb4ed4694e2d4 /board/sc520_spunk/flash.c | |
| parent | 993cad9364c6b87ae429d1ed1130d8153f6f027e (diff) | |
| download | olio-uboot-2014.01-8bde7f776c77b343aca29b8c7b58464d915ac245.tar.xz olio-uboot-2014.01-8bde7f776c77b343aca29b8c7b58464d915ac245.zip | |
* Code cleanup:LABEL_2003_06_27_2340
  - remove trailing white space, trailing empty lines, C++ comments, etc.
  - split cmd_boot.c (separate cmd_bdinfo.c and cmd_load.c)
* Patches by Kenneth Johansson, 25 Jun 2003:
  - major rework of command structure
    (work done mostly by Michal Cendrowski and Joakim Kristiansen)
Diffstat (limited to 'board/sc520_spunk/flash.c')
| -rw-r--r-- | board/sc520_spunk/flash.c | 316 | 
1 files changed, 156 insertions, 160 deletions
| diff --git a/board/sc520_spunk/flash.c b/board/sc520_spunk/flash.c index 66ef72066..d97dc2186 100644 --- a/board/sc520_spunk/flash.c +++ b/board/sc520_spunk/flash.c @@ -1,7 +1,7 @@  /*   * (C) Copyright 2002, 2003   * Daniel Engström, Omicron Ceti AB, daniel@omicron.se - *  + *   * (C) Copyright 2002   * Sysgo Real-Time Solutions, GmbH <www.elinos.com>   * Alex Zuepke <azu@sysgo.de> @@ -66,122 +66,121 @@ flash_info_t    flash_info[SC520_MAX_FLASH_BANKS];  static u32 _probe_flash(u32 addr, u32 bw, int il)  {  	u32 result=0; -	 +  	/* First do an unlock cycle for the benefit of  	 * devices that need it */ -	 +  	switch (bw) { -		 +  	case 1:  		*(volatile u8*)(addr+0x5555) = 0xaa;  		*(volatile u8*)(addr+0x2aaa) = 0x55;  		*(volatile u8*)(addr+0x5555) = 0x90; -		 +  		/* Read vendor */  		result = *(volatile u8*)addr;  		result <<= 16; -		 +  		/* Read device */  		result |= *(volatile u8*)(addr+2); -		 +  		/* Return device to data mode */  		*(volatile u8*)addr = 0xff; -		*(volatile u8*)(addr+0x5555), 0xf0;   +		*(volatile u8*)(addr+0x5555), 0xf0;  		break; -		 +  	case 2:  		*(volatile u16*)(addr+0xaaaa) = 0xaaaa;  		*(volatile u16*)(addr+0x5554) = 0x5555; -		 +  		/* Issue identification command */  		if (il == 2) {  			*(volatile u16*)(addr+0xaaaa) = 0x9090; -			 +  			/* Read vendor */  			result = *(volatile u8*)addr;  			result <<= 16; -			 +  			/* Read device */  			result |= *(volatile u8*)(addr+2); -			 +  			/* Return device to data mode */  			*(volatile u16*)addr =  0xffff; -			*(volatile u16*)(addr+0xaaaa), 0xf0f0;   -			 +			*(volatile u16*)(addr+0xaaaa), 0xf0f0; +  		} else {  			*(volatile u8*)(addr+0xaaaa) = 0x90;  			/* Read vendor */  			result = *(volatile u16*)addr;  			result <<= 16; -			 +  			/* Read device */  			result |= *(volatile u16*)(addr+2); -			 +  			/* Return device to data mode */  			*(volatile u8*)addr = 0xff; -			*(volatile u8*)(addr+0xaaaa), 0xf0;  			 +			*(volatile u8*)(addr+0xaaaa), 0xf0;  		} -		 +  		break; -		 +  	 case 4:  		*(volatile u32*)(addr+0x5554) = 0xaaaaaaaa;  		*(volatile u32*)(addr+0xaaa8) = 0x55555555; -		 +  		switch (il) {  		case 1:  			/* Issue identification command */  			*(volatile u8*)(addr+0x5554) = 0x90; -			 +  			/* Read vendor */  			result = *(volatile u16*)addr;  			result <<= 16; -		 +  			/* Read device */  			result |= *(volatile u16*)(addr+4); -			 +  			/* Return device to data mode */  			*(volatile u8*)addr =  0xff; -			*(volatile u8*)(addr+0x5554), 0xf0;   +			*(volatile u8*)(addr+0x5554), 0xf0;  			break; -			 +  		case 2:  			/* Issue identification command */  			*(volatile u32*)(addr + 0x5554) = 0x00900090; -			 +  			/* Read vendor */  			result = *(volatile u16*)addr;  			result <<= 16; -			 +  			/* Read device */  			result |= *(volatile u16*)(addr+4); -			 +  			/* Return device to data mode */  			*(volatile u32*)addr =  0x00ff00ff; -			*(volatile u32*)(addr+0x5554), 0x00f000f0;   +			*(volatile u32*)(addr+0x5554), 0x00f000f0;  			break; -			 +  		case 4:  			/* Issue identification command */  			*(volatile u32*)(addr+0x5554) = 0x90909090; -			 +  			/* Read vendor */  			result = *(volatile u8*)addr;  			result <<= 16; -			 +  			/* Read device */  			result |= *(volatile u8*)(addr+4); -			 +  			/* Return device to data mode */  			*(volatile u32*)addr =  0xffffffff; -			*(volatile u32*)(addr+0x5554), 0xf0f0f0f0;  +			*(volatile u32*)(addr+0x5554), 0xf0f0f0f0;  			break;  		}  		break;  	} -	 -	 -	 + +  	return result;  } @@ -191,36 +190,36 @@ asm ("_probe_flash_end:\n"  static int identify_flash(unsigned address, int width)  { -	int is;	 +	int is;  	int device; -	int vendor;	 +	int vendor;  	int size;  	unsigned res; -	 +  	u32 (*_probe_flash_ptr)(u32 a, u32 bw, int il); -	 -	size = (unsigned)&_probe_flash_end - (unsigned)_probe_flash;  -	 + +	size = (unsigned)&_probe_flash_end - (unsigned)_probe_flash; +  	if (size > PROBE_BUFFER_SIZE) {  		printf("_probe_flash() routine too large (%d) %p - %p\n",  		       size, &_probe_flash_end, _probe_flash);  		return 0;  	} -	 +  	memcpy(buffer, _probe_flash, size);  	_probe_flash_ptr = (void*)buffer; -	 +  	is = disable_interrupts();  	res = _probe_flash_ptr(address, width, 1);  	if (is) {  		enable_interrupts();  	} -	 -	 -        vendor = res >> 16; + + +	vendor = res >> 16;  	device = res & 0xffff; -	 -		 + +  	return res;  } @@ -228,12 +227,12 @@ ulong flash_init(void)  {  	int i, j;  	ulong size = 0; -	 +  	for (i = 0; i < SC520_MAX_FLASH_BANKS; i++) {  		unsigned id;  		ulong flashbase = 0; -		int sectsize = 0;  -		 +		int sectsize = 0; +  		memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);  		switch (i) {  		case 0: @@ -242,7 +241,7 @@ ulong flash_init(void)  		default:  			panic("configured to many flash banks!\n");  		} -		 +  		id = identify_flash(flashbase, 2);  		switch (id) {  		case 0x000122d7: @@ -250,78 +249,78 @@ ulong flash_init(void)  			flash_info[i].flash_id =  				(AMD_MANUFACT & FLASH_VENDMASK) |  				(AMD_ID_LV640U & FLASH_TYPEMASK); -			 +  			flash_info[i].size = A29LV641DH_SIZE;  			flash_info[i].sector_count = A29LV641DH_SECTORS;  			sectsize = A29LV641DH_SIZE/A29LV641DH_SECTORS;  			printf("Bank %d: AMD 29LV641DH\n", i);  			break; -			 +  		case 0x0001227E:  			/* 29LV641MH */  			flash_info[i].flash_id =  				(AMD_MANUFACT & FLASH_VENDMASK) |  				(AMD_ID_DL640 & FLASH_TYPEMASK); -			 +  			flash_info[i].size = A29LV641MH_SIZE;  			flash_info[i].sector_count = A29LV641MH_SECTORS;  			sectsize = A29LV641MH_SIZE/A29LV641MH_SECTORS;  			printf("Bank %d: AMD 29LV641MH\n", i);  			break; -			 +  		case 0x00890016:  			/* 28F320J3A */  			flash_info[i].flash_id =  				(INTEL_MANUFACT & FLASH_VENDMASK) |  				(INTEL_ID_28F320J3A & FLASH_TYPEMASK); -			 +  			flash_info[i].size = I28F320J3A_SIZE;  			flash_info[i].sector_count = I28F320J3A_SECTORS;  			sectsize = I28F320J3A_SIZE/I28F320J3A_SECTORS;  			printf("Bank %d: Intel 28F320J3A\n", i);  			break; -			 +  		case 0x00890017:  			/* 28F640J3A */  			flash_info[i].flash_id =  				(INTEL_MANUFACT & FLASH_VENDMASK) |  				(INTEL_ID_28F640J3A & FLASH_TYPEMASK); -			 +  			flash_info[i].size = I28F640J3A_SIZE;  			flash_info[i].sector_count = I28F640J3A_SECTORS;  			sectsize = I28F640J3A_SIZE/I28F640J3A_SECTORS;  			printf("Bank %d: Intel 28F640J3A\n", i);  			break; -			 +  		case 0x00890018:  			/* 28F128J3A */  			flash_info[i].flash_id =  				(INTEL_MANUFACT & FLASH_VENDMASK) |  				(INTEL_ID_28F128J3A & FLASH_TYPEMASK); -			 +  			flash_info[i].size = I28F128J3A_SIZE;  			flash_info[i].sector_count = I28F128J3A_SECTORS;  			sectsize = I28F128J3A_SIZE/I28F128J3A_SECTORS;  			printf("Bank %d: Intel 28F128J3A\n", i);  			break; -			 +  		default:  			printf("Bank %d have unknown flash %08x\n", i, id);  			flash_info[i].flash_id = FLASH_UNKNOWN;  			continue;  		} -		 +  		for (j = 0; j < flash_info[i].sector_count; j++) {  			flash_info[i].start[j] = flashbase + j * sectsize;  		}  		size += flash_info[i].size; -		 +  		flash_protect(FLAG_PROTECT_CLEAR,  			      flash_info[i].start[0],  			       flash_info[i].start[0] + flash_info[i].size - 1,  			      &flash_info[i]);  	} -	 +  	/*  	 * Protect monitor and environment sectors  	 */ @@ -334,7 +333,7 @@ ulong flash_init(void)  		      CFG_ENV_ADDR,  		      CFG_ENV_ADDR + CFG_ENV_SIZE - 1,  		      &flash_info[0]); -#endif	 +#endif  	return size;  } @@ -343,7 +342,7 @@ ulong flash_init(void)  void flash_print_info(flash_info_t *info)  {  	int i; -	 +  	switch (info->flash_id & FLASH_VENDMASK) {  	case (INTEL_MANUFACT & FLASH_VENDMASK):  		printf("INTEL: "); @@ -362,9 +361,9 @@ void flash_print_info(flash_info_t *info)  			goto done;  			break;  		} -		 +  		break; -		 +  	case (AMD_MANUFACT & FLASH_VENDMASK):  		printf("AMD:   ");  		switch (info->flash_id & FLASH_TYPEMASK) { @@ -379,17 +378,17 @@ void flash_print_info(flash_info_t *info)  			goto done;  			break;  		} -		 +  		break;  	default:  		printf("Unknown Vendor ");  		break;  	} -	 -	 + +  	printf("  Size: %ld MB in %d Sectors\n",  	       info->size >> 20, info->sector_count); -	 +  	printf("  Sector Start Addresses:");  	for (i = 0; i < info->sector_count; i++) {  		if ((i % 5) == 0) { @@ -399,7 +398,7 @@ void flash_print_info(flash_info_t *info)  			info->protect[i] ? " (RO)" : "     ");  	}  	printf ("\n"); -	 +  	done:  } @@ -410,7 +409,7 @@ void flash_print_info(flash_info_t *info)  static u32 _amd_erase_flash(u32 addr, u32 sector)  {  	unsigned elapsed; -	 +  	/* Issue erase */  	*(volatile u16*)(addr + 0xaaaa) = 0x00AA;  	*(volatile u16*)(addr + 0x5554) = 0x0055; @@ -420,20 +419,20 @@ static u32 _amd_erase_flash(u32 addr, u32 sector)  	*(volatile u16*)(addr + 0x5554) = 0x0055;  	/* Sector erase command comes last */  	*(volatile u16*)(addr + sector) = 0x0030; -	 +  	elapsed = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); /* dummy read */  	elapsed = 0;  	while (((*(volatile u16*)(addr + sector)) & 0x0080) != 0x0080) { -		 +  		elapsed += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI);  		if (elapsed > ((CFG_FLASH_ERASE_TOUT/CFG_HZ) * 1000)) {  			*(volatile u16*)(addr) = 0x00f0; -			return 1;			 +			return 1;  		}  	} -	 +  	*(volatile u16*)(addr) = 0x00f0; -	 +  	return 0;  } @@ -448,7 +447,7 @@ asm ("_amd_erase_flash_end:\n"  	unsigned milli=0; \  	\  	micro = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); \ -         \ +	 \  	for (;;) { \  		\  		milli += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); \ @@ -458,32 +457,32 @@ asm ("_amd_erase_flash_end:\n"  			break; \  		} \  	} \ -} while (0)  +} while (0)  static u32 _intel_erase_flash(u32 addr, u32 sector) -{	 +{  	unsigned elapsed; -	 +  	*(volatile u16*)(addr + sector) = 0x0050;   /* clear status register */  	*(volatile u16*)(addr + sector) = 0x0020;   /* erase setup */  	*(volatile u16*)(addr + sector) = 0x00D0;   /* erase confirm */ -	 +  	/* Wait at least 80us - let's wait 1 ms */  	__udelay(1000); -	 +  	elapsed = 0;  	while (((*(volatile u16*)(addr + sector)) & 0x0080) != 0x0080) {  		elapsed += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI);  		if (elapsed > ((CFG_FLASH_ERASE_TOUT/CFG_HZ) * 1000)) {  			*(volatile u16*)(addr + sector) = 0x00B0;  /* suspend erase      */  			*(volatile u16*)(addr + sector) = 0x00FF;  /* reset to read mode */ -			return 1;			 +			return 1;  		}  	} -	 +  	*(volatile u16*)(addr + sector) = 0x00FF;  /* reset to read mode */ -	 +  	return 0;  } @@ -498,7 +497,7 @@ int flash_erase(flash_info_t *info, int s_first, int s_last)  	int prot;  	int sect;  	unsigned size; -	 +  	if ((s_first < 0) || (s_first > s_last)) {  		if (info->flash_id == FLASH_UNKNOWN) {  			printf("- missing\n"); @@ -507,77 +506,77 @@ int flash_erase(flash_info_t *info, int s_first, int s_last)  		}  		return 1;  	} -	 +  	if ((info->flash_id & FLASH_VENDMASK) == (AMD_MANUFACT & FLASH_VENDMASK)) { -		size = (unsigned)&_amd_erase_flash_end - (unsigned)_amd_erase_flash;  -		 +		size = (unsigned)&_amd_erase_flash_end - (unsigned)_amd_erase_flash; +  		if (size > PROBE_BUFFER_SIZE) {  			printf("_amd_erase_flash() routine too large (%d) %p - %p\n",  			       size, &_amd_erase_flash_end, _amd_erase_flash);  			return 0;  		} -		 +  		memcpy(buffer, _amd_erase_flash, size);  		_erase_flash_ptr = (void*)buffer; -	 +  	} else if ((info->flash_id & FLASH_VENDMASK) == (INTEL_MANUFACT & FLASH_VENDMASK)) { -		size = (unsigned)&_intel_erase_flash_end - (unsigned)_intel_erase_flash;  -		 +		size = (unsigned)&_intel_erase_flash_end - (unsigned)_intel_erase_flash; +  		if (size > PROBE_BUFFER_SIZE) {  			printf("_intel_erase_flash() routine too large (%d) %p - %p\n",  			       size, &_intel_erase_flash_end, _intel_erase_flash);  			return 0;  		} -		 +  		memcpy(buffer, _intel_erase_flash, size);  		_erase_flash_ptr = (void*)buffer;  	} else {  		printf ("Can't erase unknown flash type - aborted\n");  		return 1;  	} -	 +  	prot = 0;  	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);  	} else {  		printf ("\n");  	} -		 -	 + +  	/* Start erase on unprotected sectors */  	for (sect = s_first; sect<=s_last; sect++) { -		 +  		if (info->protect[sect] == 0) { /* not protected */  			int res;  			int flag; -			 +  			/* Disable interrupts which might cause a timeout here */  			flag = disable_interrupts(); -			 +  			res = _erase_flash_ptr(info->start[0], info->start[sect]-info->start[0]); -			 +  			/* re-enable interrupts if necessary */  			if (flag) {  				enable_interrupts();  			} -			 -			 + +  			if (res) {  				printf("Erase timed out, sector %d\n", sect);  				return res;  			} -			 -			putc('.');			 -		}		 + +			putc('.'); +		}  	} -	 +  	return 0;  } @@ -594,36 +593,36 @@ static int _amd_write_word(unsigned start, unsigned dest, unsigned data)  	volatile u16 *data2 = (u16*)&data;  	int i;  	unsigned elapsed; -	 +  	/* Check if Flash is (sufficiently) erased */  	if ((*((volatile u16*)dest) & (u16)data) != (u16)data) {  		return 2;  	} -	 +  	for (i = 0; i < 2; i++) { -		 -		 + +  		addr2[0x5555] = 0x00AA;  		addr2[0x2aaa] = 0x0055;  		addr2[0x5555] = 0x00A0; -		 +  		dest2[i] = (data >> (i*16)) & 0xffff; -		 +  		elapsed = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); /* dummy read */  		elapsed = 0; -		 +  		/* data polling for D7 */  		while ((dest2[i] & 0x0080) != (data2[i] & 0x0080)) {  			elapsed += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI);  			if (elapsed > ((CFG_FLASH_WRITE_TOUT/CFG_HZ) * 1000)) {  				addr2[i] = 0x00f0; -				return 1;			 +				return 1;  			}  		}  	} -	 +  	addr2[i] = 0x00f0; -	 +  	return 0;  } @@ -632,38 +631,37 @@ asm ("_amd_write_word_end:\n"       ".long 0\n"); -  static int _intel_write_word(unsigned start, unsigned dest, unsigned data)  {  	int i;  	unsigned elapsed; -	 +  	/* Check if Flash is (sufficiently) erased */  	if ((*((volatile u16*)dest) & (u16)data) != (u16)data) {  		return 2;  	} -	 +  	for (i = 0; i < 2; i++) { -		 -		*(volatile u16*)(dest+2*i) = 0x0040; /* write setup */		 + +		*(volatile u16*)(dest+2*i) = 0x0040; /* write setup */  		*(volatile u16*)(dest+2*i) = (data >> (i*16)) & 0xffff; -		 +  		elapsed = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); /* dummy read */  		elapsed = 0; -		 +  		/* data polling for D7 */  		while ((*(volatile u16*)dest & 0x0080) != 0x0080) {  			elapsed += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI);  			if (elapsed > ((CFG_FLASH_WRITE_TOUT/CFG_HZ) * 1000)) {  				*(volatile u16*)dest = 0x00ff; -				return 1;			 +				return 1;  			}  		}  	} -	 +  	*(volatile u16*)dest = 0x00ff; -	 -	 + +  	return 0;  } @@ -688,28 +686,28 @@ int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)  	int flag;  	u32 (*_write_word_ptr)(unsigned start, unsigned dest, unsigned data);  	unsigned size; -	 +  	if ((info->flash_id & FLASH_VENDMASK) == (AMD_MANUFACT & FLASH_VENDMASK)) { -		size = (unsigned)&_amd_write_word_end - (unsigned)_amd_write_word;  -		 +		size = (unsigned)&_amd_write_word_end - (unsigned)_amd_write_word; +  		if (size > PROBE_BUFFER_SIZE) {  			printf("_amd_write_word() routine too large (%d) %p - %p\n",  			       size, &_amd_write_word_end, _amd_write_word);  			return 0;  		} -		 +  		memcpy(buffer, _amd_write_word, size);  		_write_word_ptr = (void*)buffer; -	 +  	} else if ((info->flash_id & FLASH_VENDMASK) == (INTEL_MANUFACT & FLASH_VENDMASK)) { -		size = (unsigned)&_intel_write_word_end - (unsigned)_intel_write_word;  -		 +		size = (unsigned)&_intel_write_word_end - (unsigned)_intel_write_word; +  		if (size > PROBE_BUFFER_SIZE) {  			printf("_intel_write_word() routine too large (%d) %p - %p\n",  			       size, &_intel_write_word_end, _intel_write_word);  			return 0;  		} -		 +  		memcpy(buffer, _intel_write_word, size);  		_write_word_ptr = (void*)buffer;  	} else { @@ -719,7 +717,7 @@ int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)  	wp = (addr & ~3);	/* get lower word aligned address */ -	 +  	/*  	 * handle unaligned start bytes @@ -737,12 +735,12 @@ int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)  		for (; cnt==0 && i<4; ++i, ++cp) {  			data |= (*(uchar *)cp)  << (8*i);  		} -		 +  		/* Disable interrupts which might cause a timeout here */  		flag = disable_interrupts(); -		 +  		rc = _write_word_ptr(info->start[0], wp, data); -		 +  		/* re-enable interrupts if necessary */  		if (flag) {  			enable_interrupts(); @@ -752,22 +750,22 @@ int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)  		}  		wp += 4;  	} -	 +  	/*  	 * handle word aligned part  	 */  	while (cnt >= 4) {  		data = 0; -			        +  		for (i=0; i<4; ++i) {  			data |= *src++ << (8*i);  		} -		 +  		/* Disable interrupts which might cause a timeout here */  		flag = disable_interrupts();  		rc = _write_word_ptr(info->start[0], wp, data); -		 +  		/* re-enable interrupts if necessary */  		if (flag) {  			enable_interrupts(); @@ -778,11 +776,11 @@ int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)  		wp  += 4;  		cnt -= 4;  	} -	 +  	if (cnt == 0) {  		return 0;  	} -	 +  	/*  	 * handle unaligned tail bytes  	 */ @@ -791,7 +789,7 @@ int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)  		data |= *src++ << (8*i);  		--cnt;  	} -	 +  	for (; i<4; ++i, ++cp) {  		data |= (*(uchar *)cp) << (8*i);  	} @@ -800,14 +798,12 @@ int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)  	flag = disable_interrupts();  	rc = _write_word_ptr(info->start[0], wp, data); -	 +  	/* re-enable interrupts if necessary */  	if (flag) {  		enable_interrupts();  	} -	 -	return rc; -	 -} +	return rc; +} |