public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH] cfi_flash: Fix detection of 8-bit bus flash devices via address shift
@ 2013-06-07 13:02 Jagannadha Sutradharudu Teki
  2013-06-08  9:46 ` Stefan Roese
  0 siblings, 1 reply; 4+ messages in thread
From: Jagannadha Sutradharudu Teki @ 2013-06-07 13:02 UTC (permalink / raw)
  To: u-boot

We had a problem detecting 8/16bit flash devices connected only via
8bits to the SoC for quite a while. Commit 239cb9d9
[mtd: cfi_flash: Fix CFI flash driver for 8-bit bus support] finally
fixed this 8-bit bus support. But also broke some other boards using
this cfi driver. So this patch had to be reverted.

I spotted a different, simpler approach for this 8-bit bus support
on the barebox mailing list posted by
Oleksij Rempel <bug-track@fisher-privat.net>:

http://www.spinics.net/lists/u-boot-v2/msg14687.html

Here the commit text:

"
Many cfi chips support 16 and 8 bit modes. Most important
difference is use of so called "Q15/A-1" pin. In 16bit mode this
pin is used for data IO. In 8bit mode, it is an address input
which add one more least significant bit (LSB). In this case
we should shift all adresses by one:
For example 0xaa << 1 = 0x154
"

This patch now is a port of this barebox patch to U-Boot.

Along with the change w.r.t from barebox,
Some flash chips can support multiple bus widths, override the
interface width and limit it to the port width.

Tested on 16-bit Spansion flash on sequoia.
Tested 8-bit flashes like 256M29EW, 512M29EW.

Signed-off-by: Stefan Roese <sr@denx.de>
Tested-by: Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
---
 drivers/mtd/cfi_flash.c | 37 +++++++++++++++++++++++++++++++++----
 include/flash.h         |  2 ++
 2 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index 22d8440..e23e394 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -212,7 +212,7 @@ flash_map (flash_info_t * info, flash_sect_t sect, uint offset)
 {
 	unsigned int byte_offset = offset * info->portwidth;
 
-	return (void *)(info->start[sect] + byte_offset);
+	return (void *)(info->start[sect] + (byte_offset << info->chip_lsb));
 }
 
 static inline void flash_unmap(flash_info_t *info, flash_sect_t sect,
@@ -1892,12 +1892,27 @@ static int __flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
 			flash_read_cfi(info, qry, FLASH_OFFSET_CFI_RESP,
 					sizeof(struct cfi_qry));
 			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;
+			}
 
 			info->cfi_offset = flash_offset_cfi[cfi_offset];
 			debug ("device interface is %d\n",
 			       info->interface);
-			debug ("found port %d chip %d ",
-			       info->portwidth, info->chipwidth);
+			debug("found port %d chip %d chip_lsb %d ",
+			      info->portwidth, info->chipwidth, info->chip_lsb);
 			debug ("port %d bits chip %d bits\n",
 			       info->portwidth << CFI_FLASH_SHIFT_WIDTH,
 			       info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
@@ -1937,9 +1952,23 @@ static int flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
 	     info->portwidth <= FLASH_CFI_64BIT; info->portwidth <<= 1) {
 		for (info->chipwidth = FLASH_CFI_BY8;
 		     info->chipwidth <= info->portwidth;
-		     info->chipwidth <<= 1)
+		     info->chipwidth <<= 1) {
+			/*
+			 * First, try detection without shifting the addresses
+			 * for 8bit devices (16bit wide connection)
+			 */
+			info->chip_lsb = 0;
+			if (__flash_detect_cfi(info, qry))
+				return 1;
+
+			/*
+			 * Not detected, so let's try with shifting
+			 * for 8bit devices
+			 */
+			info->chip_lsb = 1;
 			if (__flash_detect_cfi(info, qry))
 				return 1;
+		}
 	}
 	debug ("not found\n");
 	return 0;
diff --git a/include/flash.h b/include/flash.h
index c7acc97..af2fe41 100644
--- a/include/flash.h
+++ b/include/flash.h
@@ -38,6 +38,8 @@ typedef struct {
 #ifdef CONFIG_SYS_FLASH_CFI
 	uchar	portwidth;		/* the width of the port		*/
 	uchar	chipwidth;		/* the width of the chip		*/
+	uchar	chip_lsb;		/* extra Least Significant Bit in the */
+					/* address of chip	*/
 	ushort	buffer_size;		/* # of bytes in write buffer		*/
 	ulong	erase_blk_tout;		/* maximum block erase timeout		*/
 	ulong	write_tout;		/* maximum write timeout		*/
-- 
1.8.3

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2013-06-10 14:10 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-07 13:02 [U-Boot] [PATCH] cfi_flash: Fix detection of 8-bit bus flash devices via address shift Jagannadha Sutradharudu Teki
2013-06-08  9:46 ` Stefan Roese
2013-06-10 14:04   ` Wolfgang Denk
2013-06-10 14:10     ` Stefan Roese

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox