diff options
| -rw-r--r-- | drivers/mtd/cfi_flash.c | 78 | ||||
| -rw-r--r-- | include/mtd/cfi_flash.h | 41 | 
2 files changed, 43 insertions, 76 deletions
| diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index 328c76d29..22d84407d 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -210,11 +210,9 @@ unsigned long flash_sector_size(flash_info_t *info, flash_sect_t sect)  static inline void *  flash_map (flash_info_t * info, flash_sect_t sect, uint offset)  { -	unsigned int byte_offset = offset * info->portwidth / info->chipwidth; -	unsigned int addr = (info->start[sect] + byte_offset); -	unsigned int mask = 0xffffffff << (info->portwidth - 1); +	unsigned int byte_offset = offset * info->portwidth; -	return (void *)(addr & mask); +	return (void *)(info->start[sect] + byte_offset);  }  static inline void flash_unmap(flash_info_t *info, flash_sect_t sect, @@ -400,8 +398,6 @@ void flash_write_cmd (flash_info_t * info, flash_sect_t sect,  #endif  		flash_write64(cword.ll, addr);  		break; -	default: -		printf("fwc: Unknown port width %d\n", info->portwidth);  	}  	/* Ensure all the instructions are fully finished */ @@ -589,6 +585,7 @@ static int flash_status_check (flash_info_t * info, flash_sect_t sector,  				prompt, info->start[sector],  				flash_read_long (info, sector, 0));  			flash_write_cmd (info, sector, 0, info->cmd_reset); +			udelay(1);  			return ERR_TIMOUT;  		}  		udelay (1);		/* also triggers watchdog */ @@ -756,8 +753,12 @@ static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c)  static flash_sect_t find_sector (flash_info_t * info, ulong addr)  {  	static flash_sect_t saved_sector; /* previously found sector */ +	static flash_info_t *saved_info; /* previously used flash bank */  	flash_sect_t sector = saved_sector; +	if ((info != saved_info) || (sector >= info->sector_count)) +		sector = 0; +  	while ((info->start[sector] < addr)  			&& (sector < info->sector_count - 1))  		sector++; @@ -769,6 +770,7 @@ static flash_sect_t find_sector (flash_info_t * info, ulong addr)  		sector--;  	saved_sector = sector; +	saved_info = info;  	return sector;  } @@ -785,15 +787,12 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,  	/* Check if Flash is (sufficiently) erased */  	switch (info->portwidth) {  	case FLASH_CFI_8BIT: -		debug("%s: 8-bit 0x%02x\n", __func__, cword.c);  		flag = ((flash_read8(dstaddr) & cword.c) == cword.c);  		break;  	case FLASH_CFI_16BIT: -		debug("%s: 16-bit 0x%04x\n", __func__, cword.w);  		flag = ((flash_read16(dstaddr) & cword.w) == cword.w);  		break;  	case FLASH_CFI_32BIT: -		debug("%s: 32-bit 0x%08lx\n", __func__, cword.l);  		flag = ((flash_read32(dstaddr) & cword.l) == cword.l);  		break;  	case FLASH_CFI_64BIT: @@ -1054,8 +1053,6 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)  	flash_sect_t sect;  	int st; -	debug("%s: erasing sectors %d to %d\n", __func__, s_first, s_last); -  	if (info->flash_id != FLASH_MAN_CFI) {  		puts ("Can't erase unknown flash type - aborted\n");  		return 1; @@ -1165,9 +1162,6 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)  				rcode = 1;  			else if (flash_verbose)  				putc ('.'); -		} else { -			debug("\nSector %d is protected.\n", -						info->protect[sect]);  		}  	} @@ -1863,7 +1857,7 @@ static void flash_read_cfi (flash_info_t *info, void *buf,  	unsigned int i;  	for (i = 0; i < len; i++) -		p[i] = flash_read_uchar(info, start + (i * 2)); +		p[i] = flash_read_uchar(info, start + i);  }  static void __flash_cmd_reset(flash_info_t *info) @@ -1884,40 +1878,21 @@ static int __flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)  {  	int cfi_offset; +	/* Issue FLASH reset command */ +	flash_cmd_reset(info); +  	for (cfi_offset=0;  	     cfi_offset < sizeof(flash_offset_cfi) / sizeof(uint);  	     cfi_offset++) { -		/* Issue FLASH reset command */ -		flash_cmd_reset(info);  		flash_write_cmd (info, 0, flash_offset_cfi[cfi_offset],  				 FLASH_CMD_CFI); -		if (flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP, 'Q') && -			flash_isequal(info, 0, -					FLASH_OFFSET_CFI_RESP + 2, 'R') && -			flash_isequal(info, 0, -					FLASH_OFFSET_CFI_RESP + 4, 'Y')) { +		if (flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP, 'Q') +		    && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R') +		    && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) {  			flash_read_cfi(info, qry, FLASH_OFFSET_CFI_RESP,  					sizeof(struct cfi_qry)); -#ifdef CONFIG_SYS_FLASH_INTERFACE_WIDTH -			info->interface = CONFIG_SYS_FLASH_INTERFACE_WIDTH; -#else  			info->interface	= le16_to_cpu(qry->interface_desc); -			/* Some flash chips can support multiple bus widths. -			 * In this case, override the interface width and -			 * limit it to the port width. -			 */ -			if ((info->interface == FLASH_CFI_X8X16) && -				(info->portwidth == FLASH_CFI_8BIT)) { -					debug("Overriding 16-bit interface" -						" width to 8-bit port width.\n"); -				info->interface = FLASH_CFI_X8; -			} else if ((info->interface == FLASH_CFI_X16X32) && -				(info->portwidth == FLASH_CFI_16BIT)) { -					debug("Overriding 16-bit interface" -						" width to 16-bit port width.\n"); -				info->interface = FLASH_CFI_X16; -			} -#endif +  			info->cfi_offset = flash_offset_cfi[cfi_offset];  			debug ("device interface is %d\n",  			       info->interface); @@ -1928,8 +1903,8 @@ static int __flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)  			       info->chipwidth << CFI_FLASH_SHIFT_WIDTH);  			/* calculate command offsets as in the Linux driver */ -			info->addr_unlock1 = 0xaaa; -			info->addr_unlock2 = 0x555; +			info->addr_unlock1 = 0x555; +			info->addr_unlock2 = 0x2aa;  			/*  			 * modify the unlock address if we are @@ -1963,12 +1938,8 @@ static int flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)  		for (info->chipwidth = FLASH_CFI_BY8;  		     info->chipwidth <= info->portwidth;  		     info->chipwidth <<= 1) -			if (__flash_detect_cfi(info, qry)) { -				debug("Found CFI flash, portwidth %d," -					" chipwidth %d\n", -					info->portwidth, info->chipwidth); +			if (__flash_detect_cfi(info, qry))  				return 1; -			}  	}  	debug ("not found\n");  	return 0; @@ -1987,7 +1958,7 @@ static void flash_fixup_amd(flash_info_t *info, struct cfi_qry *qry)  			/* CFI < 1.1, try to guess from device id */  			if ((info->device_id & 0x80) != 0)  				cfi_reverse_geometry(qry); -		} else if (flash_read_uchar(info, info->ext_addr + 0x1e) == 3) { +		} else if (flash_read_uchar(info, info->ext_addr + 0xf) == 3) {  			/* CFI >= 1.1, deduct from top/bottom flag */  			/* note: ext_addr is valid since cfi_version > 0 */  			cfi_reverse_geometry(qry); @@ -2103,15 +2074,14 @@ ulong flash_get_size (phys_addr_t base, int banknum)  	if (flash_detect_cfi (info, &qry)) {  		info->vendor = le16_to_cpu(qry.p_id); -		info->ext_addr = le16_to_cpu(qry.p_adr) * 2; -		debug("extended address is 0x%x\n", info->ext_addr); +		info->ext_addr = le16_to_cpu(qry.p_adr);  		num_erase_regions = qry.num_erase_regions;  		if (info->ext_addr) {  			info->cfi_version = (ushort) flash_read_uchar (info, -						info->ext_addr + 6) << 8; +						info->ext_addr + 3) << 8;  			info->cfi_version |= (ushort) flash_read_uchar (info, -						info->ext_addr + 8); +						info->ext_addr + 4);  		}  #ifdef DEBUG @@ -2165,8 +2135,6 @@ ulong flash_get_size (phys_addr_t base, int banknum)  		debug ("device id is 0x%x\n", info->device_id);  		debug ("device id2 is 0x%x\n", info->device_id2);  		debug ("cfi version is 0x%04x\n", info->cfi_version); -		debug("port width: %d, chipwidth: %d, interface: %d\n", -			info->portwidth, info->chipwidth, info->interface);  		size_ratio = info->portwidth / info->chipwidth;  		/* if the chip is x8/x16 reduce the ratio by half */ diff --git a/include/mtd/cfi_flash.h b/include/mtd/cfi_flash.h index 9bd76eb97..966b5e00c 100644 --- a/include/mtd/cfi_flash.h +++ b/include/mtd/cfi_flash.h @@ -78,30 +78,29 @@  #define FLASH_CONTINUATION_CODE		0x7F  #define FLASH_OFFSET_MANUFACTURER_ID	0x00 -#define FLASH_OFFSET_DEVICE_ID		0x02 -#define FLASH_OFFSET_DEVICE_ID2		0x1C -#define FLASH_OFFSET_DEVICE_ID3		0x1E -#define FLASH_OFFSET_CFI		0xAA - +#define FLASH_OFFSET_DEVICE_ID		0x01 +#define FLASH_OFFSET_DEVICE_ID2		0x0E +#define FLASH_OFFSET_DEVICE_ID3		0x0F +#define FLASH_OFFSET_CFI		0x55  #define FLASH_OFFSET_CFI_ALT		0x555 -#define FLASH_OFFSET_CFI_RESP          0x20 -#define FLASH_OFFSET_PRIMARY_VENDOR    0x26 +#define FLASH_OFFSET_CFI_RESP		0x10 +#define FLASH_OFFSET_PRIMARY_VENDOR	0x13  /* extended query table primary address */ -#define FLASH_OFFSET_EXT_QUERY_T_P_ADDR   0x2A +#define FLASH_OFFSET_EXT_QUERY_T_P_ADDR	0x15  #define FLASH_OFFSET_WTOUT		0x1F -#define FLASH_OFFSET_WBTOUT            0x40 -#define FLASH_OFFSET_ETOUT             0x4A -#define FLASH_OFFSET_CETOUT            0x44 -#define FLASH_OFFSET_WMAX_TOUT         0x46 -#define FLASH_OFFSET_WBMAX_TOUT		0x48 -#define FLASH_OFFSET_EMAX_TOUT         0x4A -#define FLASH_OFFSET_CEMAX_TOUT		0x4C -#define FLASH_OFFSET_SIZE              0x4E -#define FLASH_OFFSET_INTERFACE         0x50 -#define FLASH_OFFSET_BUFFER_SIZE       0x54 -#define FLASH_OFFSET_NUM_ERASE_REGIONS 0x58 -#define FLASH_OFFSET_ERASE_REGIONS     0x5A -#define FLASH_OFFSET_PROTECT           0x04 +#define FLASH_OFFSET_WBTOUT		0x20 +#define FLASH_OFFSET_ETOUT		0x21 +#define FLASH_OFFSET_CETOUT		0x22 +#define FLASH_OFFSET_WMAX_TOUT		0x23 +#define FLASH_OFFSET_WBMAX_TOUT		0x24 +#define FLASH_OFFSET_EMAX_TOUT		0x25 +#define FLASH_OFFSET_CEMAX_TOUT		0x26 +#define FLASH_OFFSET_SIZE		0x27 +#define FLASH_OFFSET_INTERFACE		0x28 +#define FLASH_OFFSET_BUFFER_SIZE	0x2A +#define FLASH_OFFSET_NUM_ERASE_REGIONS	0x2C +#define FLASH_OFFSET_ERASE_REGIONS	0x2D +#define FLASH_OFFSET_PROTECT		0x02  #define FLASH_OFFSET_USER_PROTECTION	0x85  #define FLASH_OFFSET_INTEL_PROTECTION	0x81 |