diff options
Diffstat (limited to 'drivers/mtd/cfi_flash.c')
| -rw-r--r-- | drivers/mtd/cfi_flash.c | 289 | 
1 files changed, 175 insertions, 114 deletions
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index 0d1ee8a45..a66feac14 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -57,12 +57,12 @@   * AMD/Spansion Application Note: Migration from Single-byte to Three-byte   *   Device IDs, Publication Number 25538 Revision A, November 8, 2001   * - * Define CFG_WRITE_SWAPPED_DATA, if you have to swap the Bytes between + * Define CONFIG_SYS_WRITE_SWAPPED_DATA, if you have to swap the Bytes between   * reading and writing ... (yes there is such a Hardware).   */ -#ifndef CFG_FLASH_BANKS_LIST -#define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } +#ifndef CONFIG_SYS_FLASH_BANKS_LIST +#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE }  #endif  #define FLASH_CMD_CFI			0x98 @@ -143,7 +143,7 @@  #define CFI_CMDSET_SST			258  #define CFI_CMDSET_INTEL_PROG_REGIONS	512 -#ifdef CFG_FLASH_CFI_AMD_RESET /* needed for STM_ID_29W320DB on UC100 */ +#ifdef CONFIG_SYS_FLASH_CFI_AMD_RESET /* needed for STM_ID_29W320DB on UC100 */  # undef  FLASH_CMD_RESET  # define FLASH_CMD_RESET	AMD_CMD_RESET /* use AMD-Reset instead */  #endif @@ -158,12 +158,13 @@ typedef union {  #define NUM_ERASE_REGIONS	4 /* max. number of erase regions */  static uint flash_offset_cfi[2] = { FLASH_OFFSET_CFI, FLASH_OFFSET_CFI_ALT }; +static uint flash_verbose = 1; -/* use CFG_MAX_FLASH_BANKS_DETECT if defined */ -#ifdef CFG_MAX_FLASH_BANKS_DETECT -# define CFI_MAX_FLASH_BANKS	CFG_MAX_FLASH_BANKS_DETECT +/* use CONFIG_SYS_MAX_FLASH_BANKS_DETECT if defined */ +#ifdef CONFIG_SYS_MAX_FLASH_BANKS_DETECT +# define CFI_MAX_FLASH_BANKS	CONFIG_SYS_MAX_FLASH_BANKS_DETECT  #else -# define CFI_MAX_FLASH_BANKS	CFG_MAX_FLASH_BANKS +# define CFI_MAX_FLASH_BANKS	CONFIG_SYS_MAX_FLASH_BANKS  #endif  flash_info_t flash_info[CFI_MAX_FLASH_BANKS];	/* FLASH chips info */ @@ -171,12 +172,10 @@ flash_info_t flash_info[CFI_MAX_FLASH_BANKS];	/* FLASH chips info */  /*   * Check if chip width is defined. If not, start detecting with 8bit.   */ -#ifndef CFG_FLASH_CFI_WIDTH -#define CFG_FLASH_CFI_WIDTH	FLASH_CFI_8BIT +#ifndef CONFIG_SYS_FLASH_CFI_WIDTH +#define CONFIG_SYS_FLASH_CFI_WIDTH	FLASH_CFI_8BIT  #endif -typedef unsigned long flash_sect_t; -  /* CFI standard query structure */  struct cfi_qry {  	u8	qry[3]; @@ -209,38 +208,38 @@ struct cfi_pri_hdr {  	u8	minor_version;  } __attribute__((packed)); -static void flash_write8(u8 value, void *addr) +static void __flash_write8(u8 value, void *addr)  {  	__raw_writeb(value, addr);  } -static void flash_write16(u16 value, void *addr) +static void __flash_write16(u16 value, void *addr)  {  	__raw_writew(value, addr);  } -static void flash_write32(u32 value, void *addr) +static void __flash_write32(u32 value, void *addr)  {  	__raw_writel(value, addr);  } -static void flash_write64(u64 value, void *addr) +static void __flash_write64(u64 value, void *addr)  {  	/* No architectures currently implement __raw_writeq() */  	*(volatile u64 *)addr = value;  } -static u8 flash_read8(void *addr) +static u8 __flash_read8(void *addr)  {  	return __raw_readb(addr);  } -static u16 flash_read16(void *addr) +static u16 __flash_read16(void *addr)  {  	return __raw_readw(addr);  } -static u32 flash_read32(void *addr) +static u32 __flash_read32(void *addr)  {  	return __raw_readl(addr);  } @@ -251,24 +250,42 @@ static u64 __flash_read64(void *addr)  	return *(volatile u64 *)addr;  } +#ifdef CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS +void flash_write8(u8 value, void *addr)__attribute__((weak, alias("__flash_write8"))); +void flash_write16(u16 value, void *addr)__attribute__((weak, alias("__flash_write16"))); +void flash_write32(u32 value, void *addr)__attribute__((weak, alias("__flash_write32"))); +void flash_write64(u64 value, void *addr)__attribute__((weak, alias("__flash_write64"))); +u8 flash_read8(void *addr)__attribute__((weak, alias("__flash_read8"))); +u16 flash_read16(void *addr)__attribute__((weak, alias("__flash_read16"))); +u32 flash_read32(void *addr)__attribute__((weak, alias("__flash_read32")));  u64 flash_read64(void *addr)__attribute__((weak, alias("__flash_read64"))); +#else +#define flash_write8	__flash_write8 +#define flash_write16	__flash_write16 +#define flash_write32	__flash_write32 +#define flash_write64	__flash_write64 +#define flash_read8	__flash_read8 +#define flash_read16	__flash_read16 +#define flash_read32	__flash_read32 +#define flash_read64	__flash_read64 +#endif  /*-----------------------------------------------------------------------   */ -#if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CFG_MONITOR_BASE >= CFG_FLASH_BASE) -static flash_info_t *flash_get_info(ulong base) +#if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE) +flash_info_t *flash_get_info(ulong base)  {  	int i;  	flash_info_t * info = 0; -	for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { +	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {  		info = & flash_info[i];  		if (info->size && info->start[0] <= base &&  		    base <= info->start[0] + info->size - 1)  			break;  	} -	return i == CFG_MAX_FLASH_BANKS ? 0 : info; +	return i == CONFIG_SYS_MAX_FLASH_BANKS ? 0 : info;  }  #endif @@ -288,17 +305,12 @@ flash_map (flash_info_t * info, flash_sect_t sect, uint offset)  {  	unsigned int byte_offset = offset * info->portwidth; -	return map_physmem(info->start[sect] + byte_offset, -			flash_sector_size(info, sect) - byte_offset, -			MAP_NOCACHE); +	return (void *)(info->start[sect] + byte_offset);  }  static inline void flash_unmap(flash_info_t *info, flash_sect_t sect,  		unsigned int offset, void *addr)  { -	unsigned int byte_offset = offset * info->portwidth; - -	unmap_physmem(addr, flash_sector_size(info, sect) - byte_offset);  }  /*----------------------------------------------------------------------- @@ -309,7 +321,7 @@ static void flash_make_cmd(flash_info_t *info, u32 cmd, void *cmdbuf)  	int i;  	int cword_offset;  	int cp_offset; -#if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA) +#if defined(__LITTLE_ENDIAN) || defined(CONFIG_SYS_WRITE_SWAPPED_DATA)  	u32 cmd_le = cpu_to_le32(cmd);  #endif  	uchar val; @@ -317,7 +329,7 @@ static void flash_make_cmd(flash_info_t *info, u32 cmd, void *cmdbuf)  	for (i = info->portwidth; i > 0; i--){  		cword_offset = (info->portwidth-i)%info->chipwidth; -#if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA) +#if defined(__LITTLE_ENDIAN) || defined(CONFIG_SYS_WRITE_SWAPPED_DATA)  		cp_offset = info->portwidth - i;  		val = *((uchar*)&cmd_le + cword_offset);  #else @@ -337,7 +349,7 @@ static void print_longlong (char *str, unsigned long long data)  	int i;  	char *cp; -	cp = (unsigned char *) &data; +	cp = (char *) &data;  	for (i = 0; i < 8; i++)  		sprintf (&str[i * 2], "%2.2x", *cp++);  } @@ -374,7 +386,7 @@ static inline uchar flash_read_uchar (flash_info_t * info, uint offset)  	uchar retval;  	cp = flash_map (info, 0, offset); -#if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA) +#if defined(__LITTLE_ENDIAN) || defined(CONFIG_SYS_WRITE_SWAPPED_DATA)  	retval = flash_read8(cp);  #else  	retval = flash_read8(cp + info->portwidth - 1); @@ -419,7 +431,7 @@ static ulong flash_read_long (flash_info_t * info, flash_sect_t sect,  		debug ("addr[%x] = 0x%x\n", x, flash_read8(addr + x));  	}  #endif -#if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA) +#if defined(__LITTLE_ENDIAN) || defined(CONFIG_SYS_WRITE_SWAPPED_DATA)  	retval = ((flash_read8(addr) << 16) |  		  (flash_read8(addr + info->portwidth) << 24) |  		  (flash_read8(addr + 2 * info->portwidth)) | @@ -596,7 +608,8 @@ static int flash_toggle (flash_info_t * info, flash_sect_t sect,  		retval = flash_read32(addr) != flash_read32(addr);  		break;  	case FLASH_CFI_64BIT: -		retval = flash_read64(addr) != flash_read64(addr); +		retval = ( (flash_read32( addr ) != flash_read32( addr )) || +			   (flash_read32(addr+4) != flash_read32(addr+4)) );  		break;  	default:  		retval = 0; @@ -646,8 +659,8 @@ static int flash_status_check (flash_info_t * info, flash_sect_t sector,  {  	ulong start; -#if CFG_HZ != 1000 -	tout *= CFG_HZ/1000; +#if CONFIG_SYS_HZ != 1000 +	tout *= CONFIG_SYS_HZ/1000;  #endif  	/* Wait for command completion */ @@ -681,7 +694,7 @@ static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,  	case CFI_CMDSET_INTEL_PROG_REGIONS:  	case CFI_CMDSET_INTEL_EXTENDED:  	case CFI_CMDSET_INTEL_STANDARD: -		if ((retcode == ERR_OK) +		if ((retcode != ERR_OK)  		    && !flash_isequal (info, sector, 0, FLASH_STATUS_DONE)) {  			retcode = ERR_INVAL;  			printf ("Flash %s error at address %lx\n", prompt, @@ -716,7 +729,7 @@ static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,   */  static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c)  { -#if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA) +#if defined(__LITTLE_ENDIAN) && !defined(CONFIG_SYS_WRITE_SWAPPED_DATA)  	unsigned short	w;  	unsigned int	l;  	unsigned long long ll; @@ -727,7 +740,7 @@ static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c)  		cword->c = c;  		break;  	case FLASH_CFI_16BIT: -#if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA) +#if defined(__LITTLE_ENDIAN) && !defined(CONFIG_SYS_WRITE_SWAPPED_DATA)  		w = c;  		w <<= 8;  		cword->w = (cword->w >> 8) | w; @@ -736,7 +749,7 @@ static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c)  #endif  		break;  	case FLASH_CFI_32BIT: -#if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA) +#if defined(__LITTLE_ENDIAN) && !defined(CONFIG_SYS_WRITE_SWAPPED_DATA)  		l = c;  		l <<= 24;  		cword->l = (cword->l >> 8) | l; @@ -745,7 +758,7 @@ static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c)  #endif  		break;  	case FLASH_CFI_64BIT: -#if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA) +#if defined(__LITTLE_ENDIAN) && !defined(CONFIG_SYS_WRITE_SWAPPED_DATA)  		ll = c;  		ll <<= 56;  		cword->ll = (cword->ll >> 8) | ll; @@ -756,17 +769,26 @@ static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c)  	}  } -/* loop through the sectors from the highest address when the passed - * address is greater or equal to the sector address we have a match +/* + * Loop through the sector table starting from the previously found sector. + * Searches forwards or backwards, dependent on the passed address.   */  static flash_sect_t find_sector (flash_info_t * info, ulong addr)  { -	flash_sect_t sector; +	static flash_sect_t saved_sector = 0; /* previously found sector */ +	flash_sect_t sector = saved_sector; -	for (sector = info->sector_count - 1; sector >= 0; sector--) { -		if (addr >= info->start[sector]) -			break; -	} +	while ((info->start[sector] < addr) +			&& (sector < info->sector_count - 1)) +		sector++; +	while ((info->start[sector] > addr) && (sector > 0)) +		/* +		 * also decrements the sector in case of an overshot +		 * in the first loop +		 */ +		sector--; + +	saved_sector = sector;  	return sector;  } @@ -775,10 +797,10 @@ static flash_sect_t find_sector (flash_info_t * info, ulong addr)  static int flash_write_cfiword (flash_info_t * info, ulong dest,  				cfiword_t cword)  { -	void *dstaddr; +	void *dstaddr = (void *)dest;  	int flag; - -	dstaddr = map_physmem(dest, info->portwidth, MAP_NOCACHE); +	flash_sect_t sect = 0; +	char sect_found = 0;  	/* Check if Flash is (sufficiently) erased */  	switch (info->portwidth) { @@ -798,10 +820,8 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,  		flag = 0;  		break;  	} -	if (!flag) { -		unmap_physmem(dstaddr, info->portwidth); +	if (!flag)  		return ERR_NOT_ERASED; -	}  	/* Disable interrupts which might cause a timeout here */  	flag = disable_interrupts (); @@ -818,8 +838,10 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,  #ifdef CONFIG_FLASH_CFI_LEGACY  	case CFI_CMDSET_AMD_LEGACY:  #endif -		flash_unlock_seq (info, 0); -		flash_write_cmd (info, 0, info->addr_unlock1, AMD_CMD_WRITE); +		sect = find_sector(info, dest); +		flash_unlock_seq (info, sect); +		flash_write_cmd (info, sect, info->addr_unlock1, AMD_CMD_WRITE); +		sect_found = 1;  		break;  	} @@ -842,13 +864,13 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,  	if (flag)  		enable_interrupts (); -	unmap_physmem(dstaddr, info->portwidth); +	if (!sect_found) +		sect = find_sector (info, dest); -	return flash_full_status_check (info, find_sector (info, dest), -					info->write_tout, "write"); +	return flash_full_status_check (info, sect, info->write_tout, "write");  } -#ifdef CFG_FLASH_USE_BUFFER_WRITE +#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE  static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,  				  int len) @@ -857,7 +879,7 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,  	int cnt;  	int retcode;  	void *src = cp; -	void *dst = map_physmem(dest, len, MAP_NOCACHE); +	void *dst = (void *)dest;  	void *dst2 = dst;  	int flag = 0;  	uint offset = 0; @@ -1019,10 +1041,9 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,  	}  out_unmap: -	unmap_physmem(dst, len);  	return retcode;  } -#endif /* CFG_FLASH_USE_BUFFER_WRITE */ +#endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */  /*----------------------------------------------------------------------- @@ -1051,7 +1072,7 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)  	if (prot) {  		printf ("- Warning: %d protected sectors will not be erased!\n",  			prot); -	} else { +	} else if (flash_verbose) {  		putc ('\n');  	} @@ -1098,11 +1119,14 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)  			if (flash_full_status_check  			    (info, sect, info->erase_blk_tout, "erase")) {  				rcode = 1; -			} else +			} else if (flash_verbose)  				putc ('.');  		}  	} -	puts (" done\n"); + +	if (flash_verbose) +		puts (" done\n"); +  	return rcode;  } @@ -1171,7 +1195,7 @@ void flash_print_info (flash_info_t * info)  	for (i = 0; i < info->sector_count; ++i) {  		if ((i % 5) == 0)  			printf ("\n"); -#ifdef CFG_FLASH_EMPTY_INFO +#ifdef CONFIG_SYS_FLASH_EMPTY_INFO  		int k;  		int size;  		int erased; @@ -1196,7 +1220,7 @@ void flash_print_info (flash_info_t * info)  			info->start[i],  			erased ? 'E' : ' ',  			info->protect[i] ? "RO" : "  "); -#else	/* ! CFG_FLASH_EMPTY_INFO */ +#else	/* ! CONFIG_SYS_FLASH_EMPTY_INFO */  		printf ("  %08lX   %s ",  			info->start[i],  			info->protect[i] ? "RO" : "  "); @@ -1214,14 +1238,16 @@ void flash_print_info (flash_info_t * info)   */  #ifdef CONFIG_FLASH_SHOW_PROGRESS  #define FLASH_SHOW_PROGRESS(scale, dots, digit, dots_sub) \ -	dots -= dots_sub; \ -	if ((scale > 0) && (dots <= 0)) { \ -		if ((digit % 5) == 0) \ -			printf ("%d", digit / 5); \ -		else \ -			putc ('.'); \ -		digit--; \ -		dots += scale; \ +	if (flash_verbose) { \ +		dots -= dots_sub; \ +		if ((scale > 0) && (dots <= 0)) { \ +			if ((digit % 5) == 0) \ +				printf ("%d", digit / 5); \ +			else \ +				putc ('.'); \ +			digit--; \ +			dots += scale; \ +		} \  	}  #else  #define FLASH_SHOW_PROGRESS(scale, dots, digit, dots_sub) @@ -1240,7 +1266,7 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)  	int aln;  	cfiword_t cword;  	int i, rc; -#ifdef CFG_FLASH_USE_BUFFER_WRITE +#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE  	int buffered_size;  #endif  #ifdef CONFIG_FLASH_SHOW_PROGRESS @@ -1263,7 +1289,7 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)  	/* handle unaligned start */  	if ((aln = addr - wp) != 0) {  		cword.l = 0; -		p = map_physmem(wp, info->portwidth, MAP_NOCACHE); +		p = (uchar *)wp;  		for (i = 0; i < aln; ++i)  			flash_add_byte (info, &cword, flash_read8(p + i)); @@ -1275,7 +1301,6 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)  			flash_add_byte (info, &cword, flash_read8(p + i));  		rc = flash_write_cfiword (info, wp, cword); -		unmap_physmem(p, info->portwidth);  		if (rc != 0)  			return rc; @@ -1284,7 +1309,7 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)  	}  	/* handle the aligned part */ -#ifdef CFG_FLASH_USE_BUFFER_WRITE +#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE  	buffered_size = (info->portwidth / info->chipwidth);  	buffered_size *= info->buffer_size;  	while (cnt >= info->portwidth) { @@ -1324,7 +1349,7 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)  		cnt -= info->portwidth;  		FLASH_SHOW_PROGRESS(scale, dots, digit, info->portwidth);  	} -#endif /* CFG_FLASH_USE_BUFFER_WRITE */ +#endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */  	if (cnt == 0) {  		return (0); @@ -1334,21 +1359,20 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)  	 * handle unaligned tail bytes  	 */  	cword.l = 0; -	p = map_physmem(wp, info->portwidth, MAP_NOCACHE); +	p = (uchar *)wp;  	for (i = 0; (i < info->portwidth) && (cnt > 0); ++i) {  		flash_add_byte (info, &cword, *src++);  		--cnt;  	}  	for (; i < info->portwidth; ++i)  		flash_add_byte (info, &cword, flash_read8(p + i)); -	unmap_physmem(p, info->portwidth);  	return flash_write_cfiword (info, wp, cword);  }  /*-----------------------------------------------------------------------   */ -#ifdef CFG_FLASH_PROTECTION +#ifdef CONFIG_SYS_FLASH_PROTECTION  int flash_real_protect (flash_info_t * info, long sector, int prot)  { @@ -1455,7 +1479,7 @@ void flash_read_factory_serial (flash_info_t * info, void *buffer, int offset,  	flash_unmap(info, 0, FLASH_OFFSET_INTEL_PROTECTION, src);  } -#endif /* CFG_FLASH_PROTECTION */ +#endif /* CONFIG_SYS_FLASH_PROTECTION */  /*-----------------------------------------------------------------------   * Reverse the order of the erase regions in the CFI QRY structure. @@ -1499,7 +1523,7 @@ static int cmdset_intel_init(flash_info_t *info, struct cfi_qry *qry)  	cmdset_intel_read_jedec_ids(info);  	flash_write_cmd(info, 0, info->cfi_offset, FLASH_CMD_CFI); -#ifdef CFG_FLASH_PROTECTION +#ifdef CONFIG_SYS_FLASH_PROTECTION  	/* read legacy lock/unlock bit from intel flash */  	if (info->ext_addr) {  		info->legacy_unlock = flash_read_uchar (info, @@ -1580,7 +1604,7 @@ static void flash_read_jedec_ids (flash_info_t * info)   * board_flash_get_legacy needs to fill in at least:   * info->portwidth, info->chipwidth and info->interface for Jedec probing.   */ -static int flash_detect_legacy(ulong base, int banknum) +static int flash_detect_legacy(phys_addr_t base, int banknum)  {  	flash_info_t *info = &flash_info[banknum]; @@ -1596,7 +1620,10 @@ static int flash_detect_legacy(ulong base, int banknum)  			for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++) {  				info->vendor = modes[i]; -				info->start[0] = base; +				info->start[0] = +					(ulong)map_physmem(base, +							   info->portwidth, +							   MAP_NOCACHE);  				if (info->portwidth == FLASH_CFI_8BIT  					&& info->interface == FLASH_CFI_X8X16) {  					info->addr_unlock1 = 0x2AAA; @@ -1610,8 +1637,11 @@ static int flash_detect_legacy(ulong base, int banknum)  						info->manufacturer_id,  						info->device_id,  						info->device_id2); -				if (jedec_flash_match(info, base)) +				if (jedec_flash_match(info, info->start[0]))  					break; +				else +					unmap_physmem((void *)info->start[0], +						      MAP_NOCACHE);  			}  		} @@ -1633,7 +1663,7 @@ static int flash_detect_legacy(ulong base, int banknum)  	return 0; /* use CFI */  }  #else -static inline int flash_detect_legacy(ulong base, int banknum) +static inline int flash_detect_legacy(phys_addr_t base, int banknum)  {  	return 0; /* use CFI */  } @@ -1715,7 +1745,7 @@ static int flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)  {  	debug ("flash detect cfi\n"); -	for (info->portwidth = CFG_FLASH_CFI_WIDTH; +	for (info->portwidth = CONFIG_SYS_FLASH_CFI_WIDTH;  	     info->portwidth <= FLASH_CFI_64BIT; info->portwidth <<= 1) {  		for (info->chipwidth = FLASH_CFI_BY8;  		     info->chipwidth <= info->portwidth; @@ -1770,16 +1800,30 @@ static void flash_fixup_atmel(flash_info_t *info, struct cfi_qry *qry)  		cfi_reverse_geometry(qry);  } +static void flash_fixup_stm(flash_info_t *info, struct cfi_qry *qry) +{ +	/* check if flash geometry needs reversal */ +	if (qry->num_erase_regions > 1) { +		/* reverse geometry if top boot part */ +		if (info->cfi_version < 0x3131) { +			/* CFI < 1.1, guess by device id (only M29W320ET now) */ +			if (info->device_id == 0x2256) { +				cfi_reverse_geometry(qry); +			} +		} +	} +} +  /*   * The following code cannot be run from FLASH!   *   */ -ulong flash_get_size (ulong base, int banknum) +ulong flash_get_size (phys_addr_t base, int banknum)  {  	flash_info_t *info = &flash_info[banknum];  	int i, j;  	flash_sect_t sect_cnt; -	unsigned long sector; +	phys_addr_t sector;  	unsigned long tmp;  	int size_ratio;  	uchar num_erase_regions; @@ -1791,11 +1835,11 @@ ulong flash_get_size (ulong base, int banknum)  	info->ext_addr = 0;  	info->cfi_version = 0; -#ifdef CFG_FLASH_PROTECTION +#ifdef CONFIG_SYS_FLASH_PROTECTION  	info->legacy_unlock = 0;  #endif -	info->start[0] = base; +	info->start[0] = (ulong)map_physmem(base, info->portwidth, MAP_NOCACHE);  	if (flash_detect_cfi (info, &qry)) {  		info->vendor = le16_to_cpu(qry.p_id); @@ -1843,6 +1887,9 @@ ulong flash_get_size (ulong base, int banknum)  		case 0x001f:  			flash_fixup_atmel(info, &qry);  			break; +		case 0x0020: +			flash_fixup_stm(info, &qry); +			break;  		}  		debug ("manufacturer is %d\n", info->vendor); @@ -1880,11 +1927,14 @@ ulong flash_get_size (ulong base, int banknum)  			debug ("erase_region_count = %d erase_region_size = %d\n",  				erase_region_count, erase_region_size);  			for (j = 0; j < erase_region_count; j++) { -				if (sect_cnt >= CFG_MAX_FLASH_SECT) { +				if (sect_cnt >= CONFIG_SYS_MAX_FLASH_SECT) {  					printf("ERROR: too many flash sectors\n");  					break;  				} -				info->start[sect_cnt] = sector; +				info->start[sect_cnt] = +					(ulong)map_physmem(sector, +							   info->portwidth, +							   MAP_NOCACHE);  				sector += (erase_region_size * size_ratio);  				/* @@ -1932,53 +1982,59 @@ ulong flash_get_size (ulong base, int banknum)  			/* XXX - Need to test on x8/x16 in parallel. */  			info->portwidth >>= 1;  		} + +		flash_write_cmd (info, 0, 0, info->cmd_reset);  	} -	flash_write_cmd (info, 0, 0, info->cmd_reset);  	return (info->size);  } +void flash_set_verbose(uint v) +{ +	flash_verbose = v; +} +  /*-----------------------------------------------------------------------   */  unsigned long flash_init (void)  {  	unsigned long size = 0;  	int i; -#if defined(CFG_FLASH_AUTOPROTECT_LIST) +#if defined(CONFIG_SYS_FLASH_AUTOPROTECT_LIST)  	struct apl_s {  		ulong start;  		ulong size; -	} apl[] = CFG_FLASH_AUTOPROTECT_LIST; +	} apl[] = CONFIG_SYS_FLASH_AUTOPROTECT_LIST;  #endif -#ifdef CFG_FLASH_PROTECTION +#ifdef CONFIG_SYS_FLASH_PROTECTION  	char *s = getenv("unlock");  #endif -#define BANK_BASE(i)	(((unsigned long [CFI_MAX_FLASH_BANKS])CFG_FLASH_BANKS_LIST)[i]) +#define BANK_BASE(i)	(((phys_addr_t [CFI_MAX_FLASH_BANKS])CONFIG_SYS_FLASH_BANKS_LIST)[i])  	/* Init: no FLASHes known */ -	for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) { +	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {  		flash_info[i].flash_id = FLASH_UNKNOWN;  		if (!flash_detect_legacy (BANK_BASE(i), i))  			flash_get_size (BANK_BASE(i), i);  		size += flash_info[i].size;  		if (flash_info[i].flash_id == FLASH_UNKNOWN) { -#ifndef CFG_FLASH_QUIET_TEST +#ifndef CONFIG_SYS_FLASH_QUIET_TEST  			printf ("## Unknown FLASH on Bank %d "  				"- Size = 0x%08lx = %ld MB\n",  				i+1, flash_info[i].size,  				flash_info[i].size << 20); -#endif /* CFG_FLASH_QUIET_TEST */ +#endif /* CONFIG_SYS_FLASH_QUIET_TEST */  		} -#ifdef CFG_FLASH_PROTECTION +#ifdef CONFIG_SYS_FLASH_PROTECTION  		else if ((s != NULL) && (strcmp(s, "yes") == 0)) {  			/*  			 * Only the U-Boot image and it's environment  			 * is protected, all other sectors are  			 * unprotected (unlocked) if flash hardware -			 * protection is used (CFG_FLASH_PROTECTION) +			 * protection is used (CONFIG_SYS_FLASH_PROTECTION)  			 * and the environment variable "unlock" is  			 * set to "yes".  			 */ @@ -2019,15 +2075,15 @@ unsigned long flash_init (void)  					       &flash_info[i]);  			}  		} -#endif /* CFG_FLASH_PROTECTION */ +#endif /* CONFIG_SYS_FLASH_PROTECTION */  	}  	/* Monitor protection ON by default */ -#if (CFG_MONITOR_BASE >= CFG_FLASH_BASE) +#if (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)  	flash_protect (FLAG_PROTECT_SET, -		       CFG_MONITOR_BASE, -		       CFG_MONITOR_BASE + monitor_flash_len  - 1, -		       flash_get_info(CFG_MONITOR_BASE)); +		       CONFIG_SYS_MONITOR_BASE, +		       CONFIG_SYS_MONITOR_BASE + monitor_flash_len  - 1, +		       flash_get_info(CONFIG_SYS_MONITOR_BASE));  #endif  	/* Environment protection ON by default */ @@ -2046,7 +2102,7 @@ unsigned long flash_init (void)  		       flash_get_info(CONFIG_ENV_ADDR_REDUND));  #endif -#if defined(CFG_FLASH_AUTOPROTECT_LIST) +#if defined(CONFIG_SYS_FLASH_AUTOPROTECT_LIST)  	for (i = 0; i < (sizeof(apl) / sizeof(struct apl_s)); i++) {  		debug("autoprotecting from %08x to %08x\n",  		      apl[i].start, apl[i].start + apl[i].size - 1); @@ -2056,5 +2112,10 @@ unsigned long flash_init (void)  			       flash_get_info(apl[i].start));  	}  #endif + +#ifdef CONFIG_FLASH_CFI_MTD +	cfi_mtd_init(); +#endif +  	return (size);  }  |