mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/12] cfi_flash: improvment
@ 2010-11-26 19:43 Jean-Christophe PLAGNIOL-VILLARD
  2010-11-26 19:52 ` [PATCH 01/12] cfi_flash: move intel real protect flash support to cfi_flash_intel.c Jean-Christophe PLAGNIOL-VILLARD
                   ` (12 more replies)
  0 siblings, 13 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-11-26 19:43 UTC (permalink / raw)
  To: barebox; +Cc: Patrice Vilchez, Nicolas Ferre

Hi,

	the following patch series improve the current flash
	by adding the atmel flash supportm fixing some issues and factorising
	more the code

	Found during the adding of the at91rm9200ek

please pull
The following changes since commit 53dbaf3fc7b8371ed1e24ef96715e41d60b8ebc3:

  Merge branch 'master' into next (2010-11-19 09:35:15 +0100)

are available in the git repository at:

  git://git.jcrosoft.org/barebox.git cfi

Jean-Christophe PLAGNIOL-VILLARD (12):
      cfi_flash: move intel real protect flash support to cfi_flash_intel.c
      cfi_flash: add Atmel real protect flash support
      cfi_flash: move flash_read_uchar from inline to noinline
      cfi_flash: use amd and standard reset flash command at probing
      cfi_flash: synchronize command offsets with Linux CFI driver
      cfi_flash: update manufacturer id flash support
      cfi_flash: Introduce read and write accessors
      cfi_flash: Read whole QRY structure in one go
      cfi_flash: do not reset flash when probe fails
      cfi_flash: move reset command assigment to specific chipset init function
      cfi_flash: introduce flash cmdset fixup
      cfi_flash_amd: Add manufacturer-specific fixups

 drivers/nor/cfi_flash.c       |  303 +++++++++++++++++++----------------------
 drivers/nor/cfi_flash.h       |  120 +++++++++++++----
 drivers/nor/cfi_flash_amd.c   |  172 ++++++++++++++++++++----
 drivers/nor/cfi_flash_intel.c |   52 ++++++--
 4 files changed, 420 insertions(+), 227 deletions(-)

Best Regards,
J.

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 01/12] cfi_flash: move intel real protect flash support to cfi_flash_intel.c
  2010-11-26 19:43 [PATCH 0/12] cfi_flash: improvment Jean-Christophe PLAGNIOL-VILLARD
@ 2010-11-26 19:52 ` Jean-Christophe PLAGNIOL-VILLARD
  2010-11-26 19:52 ` [PATCH 02/12] cfi_flash: add Atmel real protect flash support Jean-Christophe PLAGNIOL-VILLARD
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-11-26 19:52 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre, Patrice Vilchez

let an empty function for amd as we will add later atmel real protect flash

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/nor/cfi_flash.c       |   10 ++++------
 drivers/nor/cfi_flash.h       |    1 +
 drivers/nor/cfi_flash_amd.c   |    6 ++++++
 drivers/nor/cfi_flash_intel.c |   13 +++++++++++++
 4 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index fa5e5ee..08e45ef 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -638,12 +638,10 @@ static int flash_real_protect (struct flash_info *info, long sector, int prot)
 {
 	int retcode = 0;
 
-	flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
-	flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT);
-	if (prot)
-		flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_SET);
-	else
-		flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_CLEAR);
+	retcode = info->cfi_cmd_set->flash_real_protect(info, sector, prot);
+
+	if (retcode)
+		return retcode;
 
 	if ((retcode =
 	     flash_status_check (info, sector, info->erase_blk_tout,
diff --git a/drivers/nor/cfi_flash.h b/drivers/nor/cfi_flash.h
index 057e56c..ee1a6f0 100644
--- a/drivers/nor/cfi_flash.h
+++ b/drivers/nor/cfi_flash.h
@@ -76,6 +76,7 @@ struct cfi_cmd_set {
 	void (*flash_read_jedec_ids) (struct flash_info *info);
 	void (*flash_prepare_write) (struct flash_info *info);
 	int (*flash_status_check) (struct flash_info *info, flash_sect_t sector, uint64_t tout, char *prompt);
+	int (*flash_real_protect) (struct flash_info *info, long sector, int prot);
 };
 
 extern struct cfi_cmd_set cfi_cmd_set_intel;
diff --git a/drivers/nor/cfi_flash_amd.c b/drivers/nor/cfi_flash_amd.c
index 45b7e5c..b10f7b2 100644
--- a/drivers/nor/cfi_flash_amd.c
+++ b/drivers/nor/cfi_flash_amd.c
@@ -133,6 +133,11 @@ static int amd_flash_write_cfibuffer (struct flash_info *info, ulong dest, const
 #define amd_flash_write_cfibuffer NULL
 #endif /* CONFIG_CFI_BUFFER_WRITE */
 
+static int amd_flash_real_protect (struct flash_info *info, long sector, int prot)
+{
+	return 0;
+}
+
 struct cfi_cmd_set cfi_cmd_set_amd = {
 	.flash_write_cfibuffer = amd_flash_write_cfibuffer,
 	.flash_erase_one = amd_flash_erase_one,
@@ -140,5 +145,6 @@ struct cfi_cmd_set cfi_cmd_set_amd = {
 	.flash_read_jedec_ids = amd_read_jedec_ids,
 	.flash_prepare_write = amd_flash_prepare_write,
 	.flash_status_check = flash_generic_status_check,
+	.flash_real_protect = amd_flash_real_protect,
 };
 
diff --git a/drivers/nor/cfi_flash_intel.c b/drivers/nor/cfi_flash_intel.c
index 4344760..a71f7c4 100644
--- a/drivers/nor/cfi_flash_intel.c
+++ b/drivers/nor/cfi_flash_intel.c
@@ -126,6 +126,18 @@ static int intel_flash_status_check (struct flash_info *info, flash_sect_t secto
 	return retcode;
 }
 
+static int intel_flash_real_protect (struct flash_info *info, long sector, int prot)
+{
+	flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
+	flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT);
+	if (prot)
+		flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_SET);
+	else
+		flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_CLEAR);
+
+	return 0;
+}
+
 struct cfi_cmd_set cfi_cmd_set_intel = {
 	.flash_write_cfibuffer = intel_flash_write_cfibuffer,
 	.flash_erase_one = intel_flash_erase_one,
@@ -133,5 +145,6 @@ struct cfi_cmd_set cfi_cmd_set_intel = {
 	.flash_read_jedec_ids = intel_read_jedec_ids,
 	.flash_prepare_write = intel_flash_prepare_write,
 	.flash_status_check = intel_flash_status_check,
+	.flash_real_protect = intel_flash_real_protect,
 };
 
-- 
1.7.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 02/12] cfi_flash: add Atmel real protect flash support
  2010-11-26 19:43 [PATCH 0/12] cfi_flash: improvment Jean-Christophe PLAGNIOL-VILLARD
  2010-11-26 19:52 ` [PATCH 01/12] cfi_flash: move intel real protect flash support to cfi_flash_intel.c Jean-Christophe PLAGNIOL-VILLARD
@ 2010-11-26 19:52 ` Jean-Christophe PLAGNIOL-VILLARD
  2010-11-26 19:52 ` [PATCH 03/12] cfi_flash: move flash_read_uchar from inline to noinline Jean-Christophe PLAGNIOL-VILLARD
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-11-26 19:52 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre, Patrice Vilchez

based on U-Boot

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/nor/cfi_flash.h     |    4 ++++
 drivers/nor/cfi_flash_amd.c |   17 +++++++++++++++++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/drivers/nor/cfi_flash.h b/drivers/nor/cfi_flash.h
index ee1a6f0..047a035 100644
--- a/drivers/nor/cfi_flash.h
+++ b/drivers/nor/cfi_flash.h
@@ -121,6 +121,10 @@ extern struct cfi_cmd_set cfi_cmd_set_amd;
 #define AMD_ADDR_START		((info->portwidth == FLASH_CFI_8BIT) ? 0xAAA : 0x555)
 #define AMD_ADDR_ACK		((info->portwidth == FLASH_CFI_8BIT) ? 0x555 : 0x2AA)
 
+#define ATM_CMD_UNLOCK_SECT		0x70
+#define ATM_CMD_SOFTLOCK_START		0x80
+#define ATM_CMD_LOCK_SECT		0x40
+
 #define FLASH_OFFSET_MANUFACTURER_ID	0x00
 #define FLASH_OFFSET_DEVICE_ID		0x01
 #define FLASH_OFFSET_DEVICE_ID2		0x0E
diff --git a/drivers/nor/cfi_flash_amd.c b/drivers/nor/cfi_flash_amd.c
index b10f7b2..dffd6f0 100644
--- a/drivers/nor/cfi_flash_amd.c
+++ b/drivers/nor/cfi_flash_amd.c
@@ -135,6 +135,23 @@ static int amd_flash_write_cfibuffer (struct flash_info *info, ulong dest, const
 
 static int amd_flash_real_protect (struct flash_info *info, long sector, int prot)
 {
+	if (info->manufacturer_id != (uchar)ATM_MANUFACT)
+		return 0;
+
+	if (prot) {
+		flash_unlock_seq (info);
+		flash_write_cmd (info, 0, AMD_ADDR_START,
+				 ATM_CMD_SOFTLOCK_START);
+		flash_unlock_seq (info);
+		flash_write_cmd (info, sector, 0, ATM_CMD_LOCK_SECT);
+	} else {
+		flash_write_cmd (info, 0, AMD_ADDR_START,
+				 AMD_CMD_UNLOCK_START);
+		if (info->device_id == ATM_ID_BV6416)
+			flash_write_cmd (info, sector, 0,
+					 ATM_CMD_UNLOCK_SECT);
+	}
+
 	return 0;
 }
 
-- 
1.7.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 03/12] cfi_flash: move flash_read_uchar from inline to noinline
  2010-11-26 19:43 [PATCH 0/12] cfi_flash: improvment Jean-Christophe PLAGNIOL-VILLARD
  2010-11-26 19:52 ` [PATCH 01/12] cfi_flash: move intel real protect flash support to cfi_flash_intel.c Jean-Christophe PLAGNIOL-VILLARD
  2010-11-26 19:52 ` [PATCH 02/12] cfi_flash: add Atmel real protect flash support Jean-Christophe PLAGNIOL-VILLARD
@ 2010-11-26 19:52 ` Jean-Christophe PLAGNIOL-VILLARD
  2010-11-26 19:52 ` [PATCH 04/12] cfi_flash: use amd and standard reset flash command at probing Jean-Christophe PLAGNIOL-VILLARD
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-11-26 19:52 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre, Patrice Vilchez

it will reduce the binary size of 28 bytes
and fix some issue observerd during the porting of the at91rm9200ek
when reading the device_id and manufacturor_id

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/nor/cfi_flash.c |   15 +++++++++++++++
 drivers/nor/cfi_flash.h |   15 +--------------
 2 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index 08e45ef..0efe0d4 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -186,6 +186,21 @@ static void flash_printqry (struct flash_info *info, flash_sect_t sect)
 #endif
 
 /*
+ * read a character at a port width address
+ */
+uchar flash_read_uchar (struct flash_info *info, uint offset)
+{
+	uchar *cp;
+
+	cp = flash_make_addr (info, 0, offset);
+#if defined(__LITTLE_ENDIAN)
+	return (cp[0]);
+#else
+	return (cp[info->portwidth - 1]);
+#endif
+}
+
+/*
  * read a short word by swapping for ppc format.
  */
 static ushort flash_read_ushort (struct flash_info *info, flash_sect_t sect, uint offset)
diff --git a/drivers/nor/cfi_flash.h b/drivers/nor/cfi_flash.h
index 047a035..9a299db 100644
--- a/drivers/nor/cfi_flash.h
+++ b/drivers/nor/cfi_flash.h
@@ -211,20 +211,7 @@ static inline uchar *flash_make_addr (struct flash_info *info, flash_sect_t sect
 	return ((uchar *) (info->start[sect] + (offset * info->portwidth)));
 }
 
-/*
- * read a character at a port width address
- */
-static inline uchar flash_read_uchar (struct flash_info *info, uint offset)
-{
-	uchar *cp;
-
-	cp = flash_make_addr (info, 0, offset);
-#if defined(__LITTLE_ENDIAN)
-	return (cp[0]);
-#else
-	return (cp[info->portwidth - 1]);
-#endif
-}
+uchar flash_read_uchar (struct flash_info *info, uint offset);
 
 #ifdef CONFIG_DRIVER_CFI_BANK_WIDTH_1
 #define bankwidth_is_1(info) (info->portwidth == 1)
-- 
1.7.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 04/12] cfi_flash: use amd and standard reset flash command at probing
  2010-11-26 19:43 [PATCH 0/12] cfi_flash: improvment Jean-Christophe PLAGNIOL-VILLARD
                   ` (2 preceding siblings ...)
  2010-11-26 19:52 ` [PATCH 03/12] cfi_flash: move flash_read_uchar from inline to noinline Jean-Christophe PLAGNIOL-VILLARD
@ 2010-11-26 19:52 ` Jean-Christophe PLAGNIOL-VILLARD
  2010-11-26 19:52 ` [PATCH 05/12] cfi_flash: synchronize command offsets with Linux CFI driver Jean-Christophe PLAGNIOL-VILLARD
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-11-26 19:52 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre, Patrice Vilchez

as we do not known which flash we have yet

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/nor/cfi_flash.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index 0efe0d4..fb5935e 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -279,7 +279,8 @@ static int flash_detect_cfi (struct flash_info *info)
 		for (info->chipwidth = FLASH_CFI_BY8;
 		     info->chipwidth <= info->portwidth;
 		     info->chipwidth <<= 1) {
-			flash_write_cmd (info, 0, 0, info->cmd_reset);
+			flash_write_cmd (info, 0, 0, AMD_CMD_RESET);
+			flash_write_cmd (info, 0, 0, FLASH_CMD_RESET);
 			for (cfi_offset=0; cfi_offset < sizeof(flash_offset_cfi)/sizeof(uint); cfi_offset++) {
 				flash_write_cmd (info, 0, flash_offset_cfi[cfi_offset], FLASH_CMD_CFI);
 				if (flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP, 'Q')
-- 
1.7.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 05/12] cfi_flash: synchronize command offsets with Linux CFI driver
  2010-11-26 19:43 [PATCH 0/12] cfi_flash: improvment Jean-Christophe PLAGNIOL-VILLARD
                   ` (3 preceding siblings ...)
  2010-11-26 19:52 ` [PATCH 04/12] cfi_flash: use amd and standard reset flash command at probing Jean-Christophe PLAGNIOL-VILLARD
@ 2010-11-26 19:52 ` Jean-Christophe PLAGNIOL-VILLARD
  2010-11-26 19:52 ` [PATCH 06/12] cfi_flash: update manufacturer id flash support Jean-Christophe PLAGNIOL-VILLARD
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-11-26 19:52 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre, Patrice Vilchez

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/nor/cfi_flash.h     |    7 +++----
 drivers/nor/cfi_flash_amd.c |   32 +++++++++++++++++++++++++-------
 2 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/drivers/nor/cfi_flash.h b/drivers/nor/cfi_flash.h
index 9a299db..4094b02 100644
--- a/drivers/nor/cfi_flash.h
+++ b/drivers/nor/cfi_flash.h
@@ -59,6 +59,8 @@ struct flash_info {
 	ushort	ext_addr;		/* extended query table address		*/
 	ushort	cfi_version;		/* cfi version				*/
 	ushort	cfi_offset;		/* offset for cfi query 		*/
+	ulong	addr_unlock1;		/* unlock address 1 for AMD flash roms	*/
+	ulong	addr_unlock2;		/* unlock address 2 for AMD flash roms	*/
 	struct cfi_cmd_set *cfi_cmd_set;
 	struct cdev cdev;
 #ifdef CONFIG_PARTITION_NEED_MTD
@@ -117,10 +119,6 @@ extern struct cfi_cmd_set cfi_cmd_set_amd;
 #define AMD_STATUS_TOGGLE		0x40
 #define AMD_STATUS_ERROR		0x20
 
-#define AMD_ADDR_ERASE_START	((info->portwidth == FLASH_CFI_8BIT) ? 0xAAA : 0x555)
-#define AMD_ADDR_START		((info->portwidth == FLASH_CFI_8BIT) ? 0xAAA : 0x555)
-#define AMD_ADDR_ACK		((info->portwidth == FLASH_CFI_8BIT) ? 0x555 : 0x2AA)
-
 #define ATM_CMD_UNLOCK_SECT		0x70
 #define ATM_CMD_SOFTLOCK_START		0x80
 #define ATM_CMD_LOCK_SECT		0x40
@@ -187,6 +185,7 @@ extern struct cfi_cmd_set cfi_cmd_set_amd;
 #define FLASH_CFI_X8		0x00
 #define FLASH_CFI_X16		0x01
 #define FLASH_CFI_X8X16		0x02
+#define FLASH_CFI_X16X32	0x05
 
 /* convert between bit value and numeric value */
 #define CFI_FLASH_SHIFT_WIDTH	3
diff --git a/drivers/nor/cfi_flash_amd.c b/drivers/nor/cfi_flash_amd.c
index dffd6f0..c64377b 100644
--- a/drivers/nor/cfi_flash_amd.c
+++ b/drivers/nor/cfi_flash_amd.c
@@ -4,8 +4,8 @@
 
 static void flash_unlock_seq (struct flash_info *info)
 {
-	flash_write_cmd (info, 0, AMD_ADDR_START, AMD_CMD_UNLOCK_START);
-	flash_write_cmd (info, 0, AMD_ADDR_ACK, AMD_CMD_UNLOCK_ACK);
+	flash_write_cmd (info, 0, info->addr_unlock1, AMD_CMD_UNLOCK_START);
+	flash_write_cmd (info, 0, info->addr_unlock2, AMD_CMD_UNLOCK_ACK);
 }
 
 /*
@@ -20,9 +20,27 @@ static void amd_read_jedec_ids (struct flash_info *info)
 	info->device_id       = 0;
 	info->device_id2      = 0;
 
+	/* calculate command offsets as in the Linux driver */
+	info->addr_unlock1 = 0x555;
+	info->addr_unlock2 = 0x2AA;
+
+	/*
+	 * modify the unlock address if we are in compatibility mode
+	 */
+	if (	/* x8/x16 in x8 mode */
+		((info->chipwidth == FLASH_CFI_BY8) &&
+			(info->interface == FLASH_CFI_X8X16)) ||
+		/* x16/x32 in x16 mode */
+		((info->chipwidth == FLASH_CFI_BY16) &&
+			(info->interface == FLASH_CFI_X16X32)))
+	{
+		info->addr_unlock1 = 0xaaa;
+		info->addr_unlock2 = 0x555;
+	}
+
 	flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
 	flash_unlock_seq(info);
-	flash_write_cmd(info, 0, AMD_ADDR_START, FLASH_CMD_READ_ID);
+	flash_write_cmd(info, 0, info->addr_unlock1, FLASH_CMD_READ_ID);
 	udelay(1000); /* some flash are slow to respond */
 	info->manufacturer_id = flash_read_uchar (info,
 					FLASH_OFFSET_MANUFACTURER_ID);
@@ -74,7 +92,7 @@ static int amd_flash_is_busy (struct flash_info *info, flash_sect_t sect)
 static int amd_flash_erase_one (struct flash_info *info, long sect)
 {
 	flash_unlock_seq(info);
-	flash_write_cmd (info, 0, AMD_ADDR_ERASE_START, AMD_CMD_ERASE_START);
+	flash_write_cmd (info, 0, info->addr_unlock1, AMD_CMD_ERASE_START);
 	flash_unlock_seq(info);
 	flash_write_cmd (info, sect, 0, AMD_CMD_ERASE_SECTOR);
 
@@ -84,7 +102,7 @@ static int amd_flash_erase_one (struct flash_info *info, long sect)
 static void amd_flash_prepare_write(struct flash_info *info)
 {
 	flash_unlock_seq(info);
-	flash_write_cmd (info, 0, AMD_ADDR_START, AMD_CMD_WRITE);
+	flash_write_cmd (info, 0, info->addr_unlock1, AMD_CMD_WRITE);
 }
 
 #ifdef CONFIG_CFI_BUFFER_WRITE
@@ -140,12 +158,12 @@ static int amd_flash_real_protect (struct flash_info *info, long sector, int pro
 
 	if (prot) {
 		flash_unlock_seq (info);
-		flash_write_cmd (info, 0, AMD_ADDR_START,
+		flash_write_cmd (info, 0, info->addr_unlock1,
 				 ATM_CMD_SOFTLOCK_START);
 		flash_unlock_seq (info);
 		flash_write_cmd (info, sector, 0, ATM_CMD_LOCK_SECT);
 	} else {
-		flash_write_cmd (info, 0, AMD_ADDR_START,
+		flash_write_cmd (info, 0, info->addr_unlock1,
 				 AMD_CMD_UNLOCK_START);
 		if (info->device_id == ATM_ID_BV6416)
 			flash_write_cmd (info, sector, 0,
-- 
1.7.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 06/12] cfi_flash: update manufacturer id flash support
  2010-11-26 19:43 [PATCH 0/12] cfi_flash: improvment Jean-Christophe PLAGNIOL-VILLARD
                   ` (4 preceding siblings ...)
  2010-11-26 19:52 ` [PATCH 05/12] cfi_flash: synchronize command offsets with Linux CFI driver Jean-Christophe PLAGNIOL-VILLARD
@ 2010-11-26 19:52 ` Jean-Christophe PLAGNIOL-VILLARD
  2010-11-26 19:52 ` [PATCH 07/12] cfi_flash: Introduce read and write accessors Jean-Christophe PLAGNIOL-VILLARD
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-11-26 19:52 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre, Patrice Vilchez

several first banks can contain 0x7f instead of actual ID

support as done in linux

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/nor/cfi_flash.c       |   18 ++++++++++++++++++
 drivers/nor/cfi_flash.h       |    3 +++
 drivers/nor/cfi_flash_amd.c   |    4 ++--
 drivers/nor/cfi_flash_intel.c |    4 ++--
 4 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index fb5935e..a1e0726 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -269,6 +269,24 @@ static ulong flash_read_long (struct flash_info *info, flash_sect_t sect, uint o
  * http://www.jedec.org/download/search/jesd68.pdf
  *
 */
+u32 jedec_read_mfr(struct flash_info *info)
+{
+	int bank = 0;
+	uchar mfr;
+
+	/* According to JEDEC "Standard Manufacturer's Identification Code"
+	 * (http://www.jedec.org/download/search/jep106W.pdf)
+	 * several first banks can contain 0x7f instead of actual ID
+	 */
+	do {
+		mfr = flash_read_uchar (info,
+				(bank << 8) | FLASH_OFFSET_MANUFACTURER_ID);
+		bank++;
+	} while (mfr == FLASH_ID_CONTINUATION);
+
+	return mfr;
+}
+
 static int flash_detect_cfi (struct flash_info *info)
 {
 	int cfi_offset;
diff --git a/drivers/nor/cfi_flash.h b/drivers/nor/cfi_flash.h
index 4094b02..877822a 100644
--- a/drivers/nor/cfi_flash.h
+++ b/drivers/nor/cfi_flash.h
@@ -107,6 +107,8 @@ extern struct cfi_cmd_set cfi_cmd_set_amd;
 #define FLASH_STATUS_R			0x01
 #define FLASH_STATUS_PROTECT		0x01
 
+#define FLASH_ID_CONTINUATION		0x7F
+
 #define AMD_CMD_RESET			0xF0
 #define AMD_CMD_WRITE			0xA0
 #define AMD_CMD_ERASE_START		0x80
@@ -211,6 +213,7 @@ static inline uchar *flash_make_addr (struct flash_info *info, flash_sect_t sect
 }
 
 uchar flash_read_uchar (struct flash_info *info, uint offset);
+u32 jedec_read_mfr(struct flash_info *info);
 
 #ifdef CONFIG_DRIVER_CFI_BANK_WIDTH_1
 #define bankwidth_is_1(info) (info->portwidth == 1)
diff --git a/drivers/nor/cfi_flash_amd.c b/drivers/nor/cfi_flash_amd.c
index c64377b..54e764d 100644
--- a/drivers/nor/cfi_flash_amd.c
+++ b/drivers/nor/cfi_flash_amd.c
@@ -42,8 +42,8 @@ static void amd_read_jedec_ids (struct flash_info *info)
 	flash_unlock_seq(info);
 	flash_write_cmd(info, 0, info->addr_unlock1, FLASH_CMD_READ_ID);
 	udelay(1000); /* some flash are slow to respond */
-	info->manufacturer_id = flash_read_uchar (info,
-					FLASH_OFFSET_MANUFACTURER_ID);
+
+	info->manufacturer_id = jedec_read_mfr(info);
 	info->device_id = flash_read_uchar (info,
 					FLASH_OFFSET_DEVICE_ID);
 	if (info->device_id == 0x7E) {
diff --git a/drivers/nor/cfi_flash_intel.c b/drivers/nor/cfi_flash_intel.c
index a71f7c4..649f83b 100644
--- a/drivers/nor/cfi_flash_intel.c
+++ b/drivers/nor/cfi_flash_intel.c
@@ -16,8 +16,8 @@ static void intel_read_jedec_ids (struct flash_info *info)
 	flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
 	flash_write_cmd(info, 0, 0, FLASH_CMD_READ_ID);
 	udelay(1000); /* some flash are slow to respond */
-	info->manufacturer_id = flash_read_uchar (info,
-					FLASH_OFFSET_MANUFACTURER_ID);
+
+	info->manufacturer_id = jedec_read_mfr(info);
 	info->device_id = flash_read_uchar (info,
 					FLASH_OFFSET_DEVICE_ID);
 	flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
-- 
1.7.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 07/12] cfi_flash: Introduce read and write accessors
  2010-11-26 19:43 [PATCH 0/12] cfi_flash: improvment Jean-Christophe PLAGNIOL-VILLARD
                   ` (5 preceding siblings ...)
  2010-11-26 19:52 ` [PATCH 06/12] cfi_flash: update manufacturer id flash support Jean-Christophe PLAGNIOL-VILLARD
@ 2010-11-26 19:52 ` Jean-Christophe PLAGNIOL-VILLARD
  2010-11-26 19:52 ` [PATCH 08/12] cfi_flash: Read whole QRY structure in one go Jean-Christophe PLAGNIOL-VILLARD
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-11-26 19:52 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre, Patrice Vilchez, Haavard Skinnemoen

Introduce flash_read{8,16,32,64) and flash_write{8,16,32,64} and use
them to access the flash memory. This makes it clearer when the flash
is actually being accessed; merely dereferencing a volatile pointer
looks just like any other kind of access.

based on U-Boot

Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/nor/cfi_flash.c       |   93 +++++++++++++++++++++--------------------
 drivers/nor/cfi_flash.h       |   58 +++++++++++++++++++++-----
 drivers/nor/cfi_flash_amd.c   |   39 +++++++++++-------
 drivers/nor/cfi_flash_intel.c |   18 ++++----
 4 files changed, 129 insertions(+), 79 deletions(-)

diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index a1e0726..2ac4e7c 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -117,20 +117,20 @@ static void flash_add_byte (struct flash_info *info, cfiword_t * cword, uchar c)
 static int flash_write_cfiword (struct flash_info *info, ulong dest,
 				cfiword_t cword)
 {
-	cfiptr_t cptr;
+	void *dstaddr;
 	int flag;
 
-	cptr.cp = (uchar *) dest;
+	dstaddr = (uchar *) dest;
 
 	/* Check if Flash is (sufficiently) erased */
 	if (bankwidth_is_1(info)) {
-		flag = ((cptr.cp[0] & cword.c) == cword.c);
+		flag = ((flash_read8(dstaddr) & cword.c) == cword.c);
 	} else if (bankwidth_is_2(info)) {
-		flag = ((cptr.wp[0] & cword.w) == cword.w);
+		flag = ((flash_read16(dstaddr) & cword.w) == cword.w);
 	} else if (bankwidth_is_4(info)) {
-		flag = ((cptr.lp[0] & cword.l) == cword.l);
+		flag = ((flash_read32(dstaddr) & cword.l) == cword.l);
 	} else if (bankwidth_is_8(info)) {
-		flag = ((cptr.llp[0] & cword.ll) == cword.ll);
+		flag = ((flash_read64(dstaddr) & cword.ll) == cword.ll);
 	} else
 		return 2;
 
@@ -163,6 +163,7 @@ static void flash_printqry (struct flash_info *info, flash_sect_t sect)
 {
 	cfiptr_t cptr;
 	int x, y;
+	unsigned char c;
 
 	for (x = 0; x < 0x40; x += 16U / info->portwidth) {
 		cptr.cp =
@@ -194,9 +195,9 @@ uchar flash_read_uchar (struct flash_info *info, uint offset)
 
 	cp = flash_make_addr (info, 0, offset);
 #if defined(__LITTLE_ENDIAN)
-	return (cp[0]);
+	return flash_read8(cp);
 #else
-	return (cp[info->portwidth - 1]);
+	return flash_read8(cp + info->portwidth - 1);
 #endif
 }
 
@@ -249,17 +250,19 @@ static ulong flash_read_long (struct flash_info *info, flash_sect_t sect, uint o
 	debug ("long addr is at %p info->portwidth = %d\n", addr,
 	       info->portwidth);
 	for (x = 0; x < 4 * info->portwidth; x++) {
-		debug ("addr[%x] = 0x%x\n", x, addr[x]);
+		debug ("addr[%x] = 0x%x\n", x, flash_read8(addr + x));
 	}
 #endif
 #if defined(__LITTLE_ENDIAN)
-	retval = (addr[0] << 16) | (addr[(info->portwidth)] << 24) |
-		(addr[(2 * info->portwidth)]) | (addr[(3 * info->portwidth)] << 8);
+	retval = ((flash_read8(addr) << 16) |
+		  (flash_read8(addr + info->portwidth) << 24) |
+		  (flash_read8(addr + 2 * info->portwidth)) |
+		  (flash_read8(addr + 3 * info->portwidth) << 8));
 #else
-	retval = (addr[(2 * info->portwidth) - 1] << 24) |
-		(addr[(info->portwidth) - 1] << 16) |
-		(addr[(4 * info->portwidth) - 1] << 8) |
-		addr[(3 * info->portwidth) - 1];
+	retval = ((flash_read8(addr + 2 * info->portwidth - 1) << 24) |
+		  (flash_read8(addr + info->portwidth - 1) << 16) |
+		  (flash_read8(addr + 4 * info->portwidth - 1) << 8) |
+		  (flash_read8(addr + 3 * info->portwidth - 1)));
 #endif
 	return retval;
 }
@@ -576,7 +579,7 @@ static int cfi_erase(struct cdev *cdev, size_t count, unsigned long offset)
 static int write_buff (struct flash_info *info, const uchar * src, ulong addr, ulong cnt)
 {
 	ulong wp;
-	ulong cp;
+	uchar *p;
 	int aln;
 	cfiword_t cword;
 	int i, rc;
@@ -585,28 +588,27 @@ static int write_buff (struct flash_info *info, const uchar * src, ulong addr, u
 	int buffered_size;
 #endif
 	/* get lower aligned address */
-	/* get lower aligned address */
 	wp = (addr & ~(info->portwidth - 1));
 
 	/* handle unaligned start */
 	if ((aln = addr - wp) != 0) {
 		cword.l = 0;
-		cp = wp;
-		for (i = 0; i < aln; ++i, ++cp)
-			flash_add_byte (info, &cword, (*(uchar *) cp));
+		p = (uchar*)wp;
+		for (i = 0; i < aln; ++i)
+			flash_add_byte (info, &cword, flash_read8(p + i));
 
 		for (; (i < info->portwidth) && (cnt > 0); i++) {
 			flash_add_byte (info, &cword, *src++);
 			cnt--;
-			cp++;
 		}
-		for (; (cnt == 0) && (i < info->portwidth); ++i, ++cp)
-			flash_add_byte (info, &cword, (*(uchar *) cp));
+		for (; (cnt == 0) && (i < info->portwidth); ++i)
+			flash_add_byte (info, &cword, flash_read8(p + i));
 
 		rc = flash_write_cfiword (info, wp, cword);
-		if (rc)
+		if (rc != 0)
 			return rc;
-		wp = cp;
+
+		wp += i;
 	}
 
 	/* handle the aligned part */
@@ -657,12 +659,13 @@ static int write_buff (struct flash_info *info, const uchar * src, ulong addr, u
 	 * handle unaligned tail bytes
 	 */
 	cword.l = 0;
-	for (i = 0, cp = wp; (i < info->portwidth) && (cnt > 0); ++i, ++cp) {
+	p = (uchar*)wp;
+	for (i = 0; (i < info->portwidth) && (cnt > 0); ++i) {
 		flash_add_byte (info, &cword, *src++);
 		--cnt;
 	}
-	for (; i < info->portwidth; ++i, ++cp) {
-		flash_add_byte (info, &cword, (*(uchar *) cp));
+	for (; i < info->portwidth; ++i) {
+		flash_add_byte (info, &cword, flash_read8(p + i));
 	}
 
 	return flash_write_cfiword (info, wp, cword);
@@ -920,35 +923,35 @@ void flash_write_cmd (struct flash_info *info, flash_sect_t sect, uint offset, u
 
 int flash_isequal (struct flash_info *info, flash_sect_t sect, uint offset, uchar cmd)
 {
-	cfiptr_t cptr;
+	void *addr;
 	cfiword_t cword;
 	int retval;
 
-	cptr.cp = flash_make_addr (info, sect, offset);
+	addr = flash_make_addr (info, sect, offset);
 	flash_make_cmd (info, cmd, &cword);
 
-	debug ("is= cmd %x(%c) addr %p ", cmd, cmd, cptr.cp);
+	debug ("is= cmd %x(%c) addr %p ", cmd, cmd, addr);
 	if (bankwidth_is_1(info)) {
-		debug ("is= %x %x\n", cptr.cp[0], cword.c);
-		retval = (cptr.cp[0] == cword.c);
+		debug ("is= %x %x\n", flash_read8(addr), cword.c);
+		retval = (flash_read8(addr) == cword.c);
 	} else if (bankwidth_is_2(info)) {
-		debug ("is= %4.4x %4.4x\n", cptr.wp[0], cword.w);
-		retval = (cptr.wp[0] == cword.w);
+		debug ("is= %4.4x %4.4x\n", flash_read16(addr), cword.w);
+		retval = (flash_read16(addr) == cword.w);
 	} else if (bankwidth_is_4(info)) {
-		debug ("is= %8.8lx %8.8lx\n", cptr.lp[0], cword.l);
-		retval = (cptr.lp[0] == cword.l);
+		debug ("is= %8.8lx %8.8lx\n", flash_read32(addr), cword.l);
+		retval = (flash_read32(addr) == cword.l);
 	} else if (bankwidth_is_8(info)) {
 #ifdef DEBUG
 		{
 			char str1[20];
 			char str2[20];
 
-			print_longlong (str1, cptr.llp[0]);
+			print_longlong (str1, flash_read32(addr));
 			print_longlong (str2, cword.ll);
 			debug ("is= %s %s\n", str1, str2);
 		}
 #endif
-		retval = (cptr.llp[0] == cword.ll);
+		retval = (flash_read32(addr) == cword.ll);
 	} else
 		retval = 0;
 
@@ -957,20 +960,20 @@ int flash_isequal (struct flash_info *info, flash_sect_t sect, uint offset, ucha
 
 int flash_isset (struct flash_info *info, flash_sect_t sect, uint offset, uchar cmd)
 {
-	cfiptr_t cptr;
+	void *addr;
 	cfiword_t cword;
 	int retval;
 
-	cptr.cp = flash_make_addr (info, sect, offset);
+	addr = flash_make_addr (info, sect, offset);
 	flash_make_cmd (info, cmd, &cword);
 	if (bankwidth_is_1(info)) {
-		retval = ((cptr.cp[0] & cword.c) == cword.c);
+		retval = ((flash_read8(addr) & cword.c) == cword.c);
 	} else if (bankwidth_is_2(info)) {
-		retval = ((cptr.wp[0] & cword.w) == cword.w);
+		retval = ((flash_read16(addr) & cword.w) == cword.w);
 	} else if (bankwidth_is_4(info)) {
-		retval = ((cptr.lp[0] & cword.l) == cword.l);
+		retval = ((flash_read32(addr) & cword.l) == cword.l);
 	} else if (bankwidth_is_8(info)) {
-		retval = ((cptr.llp[0] & cword.ll) == cword.ll);
+		retval = ((flash_read64(addr) & cword.ll) == cword.ll);
 	} else
 		retval = 0;
 
diff --git a/drivers/nor/cfi_flash.h b/drivers/nor/cfi_flash.h
index 877822a..026654c 100644
--- a/drivers/nor/cfi_flash.h
+++ b/drivers/nor/cfi_flash.h
@@ -71,6 +71,8 @@ struct flash_info {
 	void *base;
 };
 
+#define NUM_ERASE_REGIONS	4 /* max. number of erase regions */
+
 struct cfi_cmd_set {
 	int (*flash_write_cfibuffer) (struct flash_info *info, ulong dest, const uchar * cp, int len);
 	int (*flash_erase_one) (struct flash_info *info, long sect);
@@ -204,6 +206,47 @@ int flash_generic_status_check (struct flash_info *info, flash_sect_t sector,
 int flash_isequal (struct flash_info *info, flash_sect_t sect, uint offset, uchar cmd);
 void flash_make_cmd (struct flash_info *info, uchar cmd, void *cmdbuf);
 
+static void flash_write8(u8 value, void *addr)
+{
+	__raw_writeb(value, addr);
+}
+
+static void flash_write16(u16 value, void *addr)
+{
+	__raw_writew(value, addr);
+}
+
+static void flash_write32(u32 value, void *addr)
+{
+	__raw_writel(value, addr);
+}
+
+static void flash_write64(u64 value, void *addr)
+{
+	memcpy((void *)addr, &value, 8);
+}
+
+static u8 flash_read8(void *addr)
+{
+	return __raw_readb(addr);
+}
+
+static u16 flash_read16(void *addr)
+{
+	return __raw_readw(addr);
+}
+
+static u32 flash_read32(void *addr)
+{
+	return __raw_readl(addr);
+}
+
+static u64 flash_read64(void *addr)
+{
+	/* No architectures currently implement __raw_readq() */
+	return *(volatile u64 *)addr;
+}
+
 /*
  * create an address based on the offset and the port width
  */
@@ -246,26 +289,19 @@ typedef union {
 	unsigned long long ll;
 } cfiword_t;
 
-typedef union {
-	volatile unsigned char *cp;
-	volatile unsigned short *wp;
-	volatile unsigned long *lp;
-	volatile unsigned long long *llp;
-} cfiptr_t;
-
 static inline void flash_write_word(struct flash_info *info, cfiword_t datum, void *addr)
 {
 	if (bankwidth_is_1(info)) {
 		debug("fw addr %p val %02x\n", addr, datum.c);
-		writeb(datum.c, addr);
+		flash_write8(datum.c, addr);
 	} else if (bankwidth_is_2(info)) {
 		debug("fw addr %p val %04x\n", addr, datum.w);
-		writew(datum.w, addr);
+		flash_write16(datum.w, addr);
 	} else if (bankwidth_is_4(info)) {
 		debug("fw addr %p val %08x\n", addr, datum.l);
-		writel(datum.l, addr);
+		flash_write32(datum.l, addr);
 	} else if (bankwidth_is_8(info)) {
-		memcpy((void *)addr, &datum.ll, 8);
+		flash_write64(datum.ll, addr);
 	}
 }
 
diff --git a/drivers/nor/cfi_flash_amd.c b/drivers/nor/cfi_flash_amd.c
index 54e764d..e9319b6 100644
--- a/drivers/nor/cfi_flash_amd.c
+++ b/drivers/nor/cfi_flash_amd.c
@@ -59,21 +59,20 @@ static void amd_read_jedec_ids (struct flash_info *info)
 
 static int flash_toggle (struct flash_info *info, flash_sect_t sect, uint offset, uchar cmd)
 {
-	cfiptr_t cptr;
+	void *addr;
 	cfiword_t cword;
 	int retval;
 
-	cptr.cp = flash_make_addr (info, sect, offset);
+	addr = flash_make_addr (info, sect, offset);
 	flash_make_cmd (info, cmd, &cword);
 	if (bankwidth_is_1(info)) {
-		retval = ((cptr.cp[0] & cword.c) != (cptr.cp[0] & cword.c));
+		retval = flash_read8(addr) != flash_read8(addr);
 	} else if (bankwidth_is_2(info)) {
-		retval = ((cptr.wp[0] & cword.w) != (cptr.wp[0] & cword.w));
+		retval = flash_read16(addr) != flash_read16(addr);
 	} else if (bankwidth_is_4(info)) {
-		retval = ((cptr.lp[0] & cword.l) != (cptr.lp[0] & cword.l));
+		retval = flash_read32(addr) != flash_read32(addr);
 	} else if (bankwidth_is_8(info)) {
-		retval = ((cptr.llp[0] & cword.ll) !=
-			  (cptr.llp[0] & cword.ll));
+		retval = flash_read64(addr) != flash_read64(addr);
 	} else
 		retval = 0;
 
@@ -112,12 +111,10 @@ static int amd_flash_write_cfibuffer (struct flash_info *info, ulong dest, const
 	flash_sect_t sector;
 	int cnt;
 	int retcode;
-	volatile cfiptr_t src;
-	volatile cfiptr_t dst;
+	void *src = (void*)cp;
+	void *dst = (void *)dest;
 	cfiword_t cword;
 
-	src.cp = (uchar *)cp;
-	dst.cp = (uchar *) dest;
 	sector = find_sector (info, dest);
 
 	flash_unlock_seq(info);
@@ -127,19 +124,31 @@ static int amd_flash_write_cfibuffer (struct flash_info *info, ulong dest, const
 	if (bankwidth_is_1(info)) {
 		cnt = len;
 		flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
-		while (cnt-- > 0) *dst.cp++ = *src.cp++;
+		while (cnt-- > 0) {
+			flash_write8(flash_read8(src), dst);
+			src += 1, dst += 1;
+		}
 	} else if (bankwidth_is_2(info)) {
 		cnt = len >> 1;
 		flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
-		while (cnt-- > 0) *dst.wp++ = *src.wp++;
+		while (cnt-- > 0) {
+			flash_write16(flash_read16(src), dst);
+			src += 2, dst += 2;
+		}
 	} else if (bankwidth_is_4(info)) {
 		cnt = len >> 2;
 		flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
-		while (cnt-- > 0) *dst.lp++ = *src.lp++;
+		while (cnt-- > 0) {
+			flash_write32(flash_read32(src), dst);
+			src += 4, dst += 4;
+		}
 	} else if (bankwidth_is_8(info)) {
 		cnt = len >> 3;
 		flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
-		while (cnt-- > 0) *dst.llp++ = *src.llp++;
+		while (cnt-- > 0) {
+			flash_write64(flash_read64(src), dst);
+			src += 8, dst += 8;
+		}
 	}
 
 	flash_write_cmd (info, sector, 0, AMD_CMD_WRITE_BUFFER_CONFIRM);
diff --git a/drivers/nor/cfi_flash_intel.c b/drivers/nor/cfi_flash_intel.c
index 649f83b..f28301d 100644
--- a/drivers/nor/cfi_flash_intel.c
+++ b/drivers/nor/cfi_flash_intel.c
@@ -54,11 +54,9 @@ static int intel_flash_write_cfibuffer (struct flash_info *info, ulong dest, con
 	flash_sect_t sector;
 	int cnt;
 	int retcode;
-	volatile cfiptr_t src;
-	volatile cfiptr_t dst;
+	void *src = (void*)cp;
+	void *dst = (void *)dest;
 
-	src.cp = (uchar *)cp;
-	dst.cp = (uchar *) dest;
 	sector = find_sector (info, dest);
 	flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
 	flash_write_cmd (info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER);
@@ -74,13 +72,17 @@ static int intel_flash_write_cfibuffer (struct flash_info *info, ulong dest, con
 	flash_write_cmd (info, sector, 0, (uchar) cnt - 1);
 	while (cnt-- > 0) {
 		if (bankwidth_is_1(info)) {
-			*dst.cp++ = *src.cp++;
+			flash_write8(flash_read8(src), dst);
+			src += 1, dst += 1;
 		} else if (bankwidth_is_2(info)) {
-			*dst.wp++ = *src.wp++;
+			flash_write16(flash_read16(src), dst);
+			src += 2, dst += 2;
 		} else if (bankwidth_is_4(info)) {
-			*dst.lp++ = *src.lp++;
+			flash_write32(flash_read32(src), dst);
+			src += 4, dst += 4;
 		} else if (bankwidth_is_8(info)) {
-			*dst.llp++ = *src.llp++;
+			flash_write64(flash_read64(src), dst);
+			src += 8, dst += 8;
 		}
 	}
 
-- 
1.7.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 08/12] cfi_flash: Read whole QRY structure in one go
  2010-11-26 19:43 [PATCH 0/12] cfi_flash: improvment Jean-Christophe PLAGNIOL-VILLARD
                   ` (6 preceding siblings ...)
  2010-11-26 19:52 ` [PATCH 07/12] cfi_flash: Introduce read and write accessors Jean-Christophe PLAGNIOL-VILLARD
@ 2010-11-26 19:52 ` Jean-Christophe PLAGNIOL-VILLARD
  2010-11-26 19:52 ` [PATCH 09/12] cfi_flash: do not reset flash when probe fails Jean-Christophe PLAGNIOL-VILLARD
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-11-26 19:52 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre, Patrice Vilchez, Haavard Skinnemoen

Read out the whole CFI Standard Query structure after successful cfi
identification. This allows subsequent code to access this information
directly without having to go through flash_read_uchar() and friends.

based on U-Boot

Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/nor/cfi_flash.c     |  149 ++++++++++++++++++------------------------
 drivers/nor/cfi_flash.h     |   33 ++++++++++
 drivers/nor/cfi_flash_amd.c |    3 +-
 3 files changed, 99 insertions(+), 86 deletions(-)

diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index 2ac4e7c..041fb92 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -61,8 +61,6 @@
  *
  */
 
-#define NUM_ERASE_REGIONS	4 /* max. number of erase regions */
-
 static uint flash_offset_cfi[2]={FLASH_OFFSET_CFI,FLASH_OFFSET_CFI_ALT};
 
 /*
@@ -159,29 +157,25 @@ void print_longlong (char *str, unsigned long long data)
 		sprintf (&str[i * 2], "%2.2x", *cp++);
 }
 
-static void flash_printqry (struct flash_info *info, flash_sect_t sect)
+static void flash_printqry (struct cfi_qry *qry)
 {
-	cfiptr_t cptr;
+	u8 *p = (u8 *)qry;
 	int x, y;
 	unsigned char c;
 
-	for (x = 0; x < 0x40; x += 16U / info->portwidth) {
-		cptr.cp =
-			flash_make_addr (info, sect,
-					 x + FLASH_OFFSET_CFI_RESP);
-		debug ("%p : ", cptr.cp);
-		for (y = 0; y < 16; y++) {
-			debug ("%2.2x ", cptr.cp[y]);
-		}
-		debug (" ");
+	for (x = 0; x < sizeof(struct cfi_qry); x += 16) {
+		debug("%02x : ", x);
+		for (y = 0; y < 16; y++)
+			debug("%2.2x ", p[x + y]);
+		debug(" ");
 		for (y = 0; y < 16; y++) {
-			if (cptr.cp[y] >= 0x20 && cptr.cp[y] <= 0x7e) {
-				debug ("%c", cptr.cp[y]);
-			} else {
-				debug (".");
-			}
+			c = p[x + y];
+			if (c >= 0x20 && c <= 0x7e)
+				debug("%c", c);
+			else
+				debug(".");
 		}
-		debug ("\n");
+		debug("\n");
 	}
 }
 #endif
@@ -202,37 +196,6 @@ uchar flash_read_uchar (struct flash_info *info, uint offset)
 }
 
 /*
- * read a short word by swapping for ppc format.
- */
-static ushort flash_read_ushort (struct flash_info *info, flash_sect_t sect, uint offset)
-{
-	uchar *addr;
-	ushort retval;
-
-#ifdef DEBUG
-	int x;
-#endif
-	addr = flash_make_addr (info, sect, offset);
-
-#ifdef DEBUG
-	debug ("ushort addr is at %p info->portwidth = %d\n", addr,
-	       info->portwidth);
-	for (x = 0; x < 2 * info->portwidth; x++) {
-		debug ("addr[%x] = 0x%x\n", x, addr[x]);
-	}
-#endif
-#if defined(__LITTLE_ENDIAN)
-	retval = ((addr[(info->portwidth)] << 8) | addr[0]);
-#else
-	retval = ((addr[(2 * info->portwidth) - 1] << 8) |
-		  addr[info->portwidth - 1]);
-#endif
-
-	debug ("retval = 0x%x\n", retval);
-	return retval;
-}
-
-/*
  * read a long word by picking the least significant byte of each maximum
  * port size word. Swap for ppc format.
  */
@@ -290,7 +253,17 @@ u32 jedec_read_mfr(struct flash_info *info)
 	return mfr;
 }
 
-static int flash_detect_cfi (struct flash_info *info)
+static void flash_read_cfi (struct flash_info *info, void *buf,
+		unsigned int start, size_t len)
+{
+	u8 *p = buf;
+	unsigned int i;
+
+	for (i = 0; i < len; i++)
+		p[i] = flash_read_uchar(info, start + i);
+}
+
+static int flash_detect_cfi (struct flash_info *info, struct cfi_qry *qry)
 {
 	int cfi_offset;
 	debug ("flash detect cfi\n");
@@ -307,7 +280,10 @@ static int flash_detect_cfi (struct flash_info *info)
 				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')) {
-					info->interface = flash_read_ushort (info, 0, FLASH_OFFSET_INTERFACE);
+					flash_read_cfi(info, qry, FLASH_OFFSET_CFI_RESP,
+						       sizeof(struct cfi_qry));
+					info->interface = le16_to_cpu(qry->interface_desc);
+
 					info->cfi_offset=flash_offset_cfi[cfi_offset];
 					debug ("device interface is %d\n",
 						info->interface);
@@ -340,6 +316,9 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
 	int erase_region_count;
 	int geometry_reversed = 0;
 	int cur_offset = 0;
+	struct cfi_qry qry;
+
+	memset(&qry, 0, sizeof(qry));
 
 	info->ext_addr = 0;
 	info->cfi_version = 0;
@@ -353,9 +332,22 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
 	info->start[0] = base;
 	info->protect = 0;
 
-	if (flash_detect_cfi (info)) {
-		info->vendor = flash_read_ushort (info, 0,
-					FLASH_OFFSET_PRIMARY_VENDOR);
+	if (flash_detect_cfi (info, &qry)) {
+		info->vendor = le16_to_cpu(qry.p_id);
+		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 + 3) << 8;
+			info->cfi_version |= (ushort) flash_read_uchar (info,
+						info->ext_addr + 4);
+		}
+
+#ifdef DEBUG
+		flash_printqry (&qry);
+#endif
+
 		switch (info->vendor) {
 #ifdef CONFIG_DRIVER_CFI_INTEL
 		case CFI_CMDSET_INTEL_EXTENDED:
@@ -375,19 +367,7 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
 		}
 		info->cfi_cmd_set->flash_read_jedec_ids (info);
 		flash_write_cmd (info, 0, info->cfi_offset, FLASH_CMD_CFI);
-		num_erase_regions = flash_read_uchar (info,
-					FLASH_OFFSET_NUM_ERASE_REGIONS);
-		info->ext_addr = flash_read_ushort (info, 0,
-					FLASH_OFFSET_EXT_QUERY_T_P_ADDR);
-		if (info->ext_addr) {
-			info->cfi_version = (ushort) flash_read_uchar (info,
-						info->ext_addr + 3) << 8;
-			info->cfi_version |= (ushort) flash_read_uchar (info,
-						info->ext_addr + 4);
-		}
-#ifdef DEBUG
-		flash_printqry (info, 0);
-#endif
+
 		switch (info->vendor) {
 		case CFI_CMDSET_INTEL_STANDARD:
 		case CFI_CMDSET_INTEL_EXTENDED:
@@ -445,6 +425,7 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
 		sector = base;
 
 		for (i = 0; i < num_erase_regions; i++) {
+			unsigned int __region = i;
 			struct mtd_erase_region_info *region = &info->eraseregions[i];
 
 			if (i > NUM_ERASE_REGIONS) {
@@ -453,17 +434,15 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
 				break;
 			}
 			if (geometry_reversed)
-				tmp = flash_read_long (info, 0,
-					       FLASH_OFFSET_ERASE_REGIONS +
-					       (num_erase_regions - 1 - i) * 4);
-			else
-				tmp = flash_read_long (info, 0,
-					       FLASH_OFFSET_ERASE_REGIONS +
-					       i * 4);
+				__region = num_erase_regions - 1 - i;
+			
+			tmp = le32_to_cpu(qry.erase_region_info[__region]);
+			debug("erase region %u: 0x%08lx\n", __region, tmp);
+
+			erase_region_count = (tmp & 0xffff) + 1;
+			tmp >>= 16;
 			erase_region_size =
 				(tmp & 0xffff) ? ((tmp & 0xffff) * 256) : 128;
-			tmp >>= 16;
-			erase_region_count = (tmp & 0xffff) + 1;
 			debug ("erase_region_count = %d erase_region_size = %d\n",
 				erase_region_count, erase_region_size);
 
@@ -501,15 +480,15 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
 
 		info->sector_count = sect_cnt;
 		/* multiply the size by the number of chips */
-		info->size = (1 << flash_read_uchar (info, FLASH_OFFSET_SIZE)) * size_ratio;
-		info->buffer_size = (1 << flash_read_ushort (info, 0, FLASH_OFFSET_BUFFER_SIZE));
-		tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_ETOUT);
-		info->erase_blk_tout = (tmp * (1 << flash_read_uchar (info, FLASH_OFFSET_EMAX_TOUT)));
-		tmp = (1 << flash_read_uchar (info, FLASH_OFFSET_WBTOUT)) *
-			(1 << flash_read_uchar (info, FLASH_OFFSET_WBMAX_TOUT));
+		info->size = (1 << qry.dev_size) * size_ratio;
+		info->buffer_size = (1 << le16_to_cpu(qry.max_buf_write_size));
+		tmp = 1 << qry.block_erase_timeout_typ;
+		info->erase_blk_tout = (tmp * (1 << qry.block_erase_timeout_max));
+		tmp = (1 << qry.buf_write_timeout_typ) *
+			(1 << qry.buf_write_timeout_max);
 		info->buffer_write_tout = tmp * 1000;
-		tmp = (1 << flash_read_uchar (info, FLASH_OFFSET_WTOUT)) *
-		      (1 << flash_read_uchar (info, FLASH_OFFSET_WMAX_TOUT));
+		tmp = (1 << qry.word_write_timeout_typ) *
+		      (1 << qry.word_write_timeout_max);
 		info->write_tout = tmp * 1000;
 		info->flash_id = FLASH_MAN_CFI;
 		if ((info->interface == FLASH_CFI_X8X16) && (info->chipwidth == FLASH_CFI_BY8)) {
diff --git a/drivers/nor/cfi_flash.h b/drivers/nor/cfi_flash.h
index 026654c..4b3bd25 100644
--- a/drivers/nor/cfi_flash.h
+++ b/drivers/nor/cfi_flash.h
@@ -73,6 +73,39 @@ struct flash_info {
 
 #define NUM_ERASE_REGIONS	4 /* max. number of erase regions */
 
+/* CFI standard query structure */
+struct cfi_qry {
+	u8	qry[3];
+	u16	p_id;
+	u16	p_adr;
+	u16	a_id;
+	u16	a_adr;
+	u8	vcc_min;
+	u8	vcc_max;
+	u8	vpp_min;
+	u8	vpp_max;
+	u8	word_write_timeout_typ;
+	u8	buf_write_timeout_typ;
+	u8	block_erase_timeout_typ;
+	u8	chip_erase_timeout_typ;
+	u8	word_write_timeout_max;
+	u8	buf_write_timeout_max;
+	u8	block_erase_timeout_max;
+	u8	chip_erase_timeout_max;
+	u8	dev_size;
+	u16	interface_desc;
+	u16	max_buf_write_size;
+	u8	num_erase_regions;
+	u32	erase_region_info[NUM_ERASE_REGIONS];
+} __attribute__((packed));
+
+struct cfi_pri_hdr {
+	u8	pri[3];
+	u8	major_version;
+	u8	minor_version;
+} __attribute__((packed));
+
+
 struct cfi_cmd_set {
 	int (*flash_write_cfibuffer) (struct flash_info *info, ulong dest, const uchar * cp, int len);
 	int (*flash_erase_one) (struct flash_info *info, long sect);
diff --git a/drivers/nor/cfi_flash_amd.c b/drivers/nor/cfi_flash_amd.c
index e9319b6..738389c 100644
--- a/drivers/nor/cfi_flash_amd.c
+++ b/drivers/nor/cfi_flash_amd.c
@@ -72,7 +72,8 @@ static int flash_toggle (struct flash_info *info, flash_sect_t sect, uint offset
 	} else if (bankwidth_is_4(info)) {
 		retval = flash_read32(addr) != flash_read32(addr);
 	} else if (bankwidth_is_8(info)) {
-		retval = flash_read64(addr) != flash_read64(addr);
+		retval = ( (flash_read32( addr ) != flash_read32( addr )) ||
+			   (flash_read32(addr+4) != flash_read32(addr+4)) );
 	} else
 		retval = 0;
 
-- 
1.7.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 09/12] cfi_flash: do not reset flash when probe fails
  2010-11-26 19:43 [PATCH 0/12] cfi_flash: improvment Jean-Christophe PLAGNIOL-VILLARD
                   ` (7 preceding siblings ...)
  2010-11-26 19:52 ` [PATCH 08/12] cfi_flash: Read whole QRY structure in one go Jean-Christophe PLAGNIOL-VILLARD
@ 2010-11-26 19:52 ` Jean-Christophe PLAGNIOL-VILLARD
  2010-11-26 19:52 ` [PATCH 10/12] cfi_flash: move reset command assigment to specific chipset init function Jean-Christophe PLAGNIOL-VILLARD
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-11-26 19:52 UTC (permalink / raw)
  To: barebox; +Cc: Mike Frysinger, Nicolas Ferre, Patrice Vilchez

The CFI flash driver starts at flash_init() which calls down into
flash_get_size().  This starts by calling flash_detect_cfi().  If said
function fails, flash_get_size() finishes by attempting to reset the
flash.  Unfortunately, it does this with an info->portwidth set to 0x10
which filters down into flash_make_cmd() and that happily smashes the
stack by sticking info->portwidth bytes into a cfiword_t variable that
lives on the stack.  On a 64bit system you probably won't notice, but
killing the last 8 bytes on a 32bit system usually leads to a corrupt
return address.  Which is what happens on a Blackfin system.

based on U-Boot

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/nor/cfi_flash.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index 041fb92..a7df3b4 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -494,9 +494,9 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
 		if ((info->interface == FLASH_CFI_X8X16) && (info->chipwidth == FLASH_CFI_BY8)) {
 			info->portwidth >>= 1;	/* XXX - Need to test on x8/x16 in parallel. */
 		}
+		flash_write_cmd (info, 0, 0, info->cmd_reset);
 	}
 
-	flash_write_cmd (info, 0, 0, info->cmd_reset);
 	return info->size;
 }
 
-- 
1.7.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 10/12] cfi_flash: move reset command assigment to specific chipset init function
  2010-11-26 19:43 [PATCH 0/12] cfi_flash: improvment Jean-Christophe PLAGNIOL-VILLARD
                   ` (8 preceding siblings ...)
  2010-11-26 19:52 ` [PATCH 09/12] cfi_flash: do not reset flash when probe fails Jean-Christophe PLAGNIOL-VILLARD
@ 2010-11-26 19:52 ` Jean-Christophe PLAGNIOL-VILLARD
  2010-11-26 19:52 ` [PATCH 11/12] cfi_flash: introduce flash cmdset fixup Jean-Christophe PLAGNIOL-VILLARD
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-11-26 19:52 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre, Patrice Vilchez

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/nor/cfi_flash.c       |    2 --
 drivers/nor/cfi_flash_amd.c   |    5 +++--
 drivers/nor/cfi_flash_intel.c |    5 +++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index a7df3b4..6d22a53 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -372,7 +372,6 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
 		case CFI_CMDSET_INTEL_STANDARD:
 		case CFI_CMDSET_INTEL_EXTENDED:
 		default:
-			info->cmd_reset = FLASH_CMD_RESET;
 #ifdef CFG_FLASH_PROTECTION
 			/* read legacy lock/unlock bit from intel flash */
 			if (info->ext_addr) {
@@ -383,7 +382,6 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
 			break;
 		case CFI_CMDSET_AMD_STANDARD:
 		case CFI_CMDSET_AMD_EXTENDED:
-			info->cmd_reset = AMD_CMD_RESET;
 			/* check if flash geometry needs reversal */
 			if (num_erase_regions <= 1)
 				break;
diff --git a/drivers/nor/cfi_flash_amd.c b/drivers/nor/cfi_flash_amd.c
index 738389c..f225757 100644
--- a/drivers/nor/cfi_flash_amd.c
+++ b/drivers/nor/cfi_flash_amd.c
@@ -16,6 +16,7 @@ static void flash_unlock_seq (struct flash_info *info)
 */
 static void amd_read_jedec_ids (struct flash_info *info)
 {
+	info->cmd_reset		= AMD_CMD_RESET;
 	info->manufacturer_id = 0;
 	info->device_id       = 0;
 	info->device_id2      = 0;
@@ -38,7 +39,7 @@ static void amd_read_jedec_ids (struct flash_info *info)
 		info->addr_unlock2 = 0x555;
 	}
 
-	flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
+	flash_write_cmd(info, 0, 0, info->cmd_reset);
 	flash_unlock_seq(info);
 	flash_write_cmd(info, 0, info->addr_unlock1, FLASH_CMD_READ_ID);
 	udelay(1000); /* some flash are slow to respond */
@@ -54,7 +55,7 @@ static void amd_read_jedec_ids (struct flash_info *info)
 		info->device_id2 |= flash_read_uchar (info,
 					FLASH_OFFSET_DEVICE_ID3);
 	}
-	flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
+	flash_write_cmd(info, 0, 0, info->cmd_reset);
 }
 
 static int flash_toggle (struct flash_info *info, flash_sect_t sect, uint offset, uchar cmd)
diff --git a/drivers/nor/cfi_flash_intel.c b/drivers/nor/cfi_flash_intel.c
index f28301d..8e8a820 100644
--- a/drivers/nor/cfi_flash_intel.c
+++ b/drivers/nor/cfi_flash_intel.c
@@ -9,18 +9,19 @@
 */
 static void intel_read_jedec_ids (struct flash_info *info)
 {
+	info->cmd_reset		= FLASH_CMD_RESET;
 	info->manufacturer_id = 0;
 	info->device_id       = 0;
 	info->device_id2      = 0;
 
-	flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
+	flash_write_cmd(info, 0, 0, info->cmd_reset);
 	flash_write_cmd(info, 0, 0, FLASH_CMD_READ_ID);
 	udelay(1000); /* some flash are slow to respond */
 
 	info->manufacturer_id = jedec_read_mfr(info);
 	info->device_id = flash_read_uchar (info,
 					FLASH_OFFSET_DEVICE_ID);
-	flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
+	flash_write_cmd(info, 0, 0, info->cmd_reset);
 }
 
 /*
-- 
1.7.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 11/12] cfi_flash: introduce flash cmdset fixup
  2010-11-26 19:43 [PATCH 0/12] cfi_flash: improvment Jean-Christophe PLAGNIOL-VILLARD
                   ` (9 preceding siblings ...)
  2010-11-26 19:52 ` [PATCH 10/12] cfi_flash: move reset command assigment to specific chipset init function Jean-Christophe PLAGNIOL-VILLARD
@ 2010-11-26 19:52 ` Jean-Christophe PLAGNIOL-VILLARD
  2010-11-26 19:52 ` [PATCH 12/12] cfi_flash_amd: Add manufacturer-specific fixups Jean-Christophe PLAGNIOL-VILLARD
  2010-11-29 20:53 ` [PATCH 0/12] cfi_flash: improvment Sascha Hauer
  12 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-11-26 19:52 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre, Patrice Vilchez, Haavard Skinnemoen

Move fixing up like geometry reversal into separate functions.
The geometry reversal fixup is now performed
by altering the qry structure directly, which makes the sector init
code slightly cleaner.

based on U-Boot

Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/nor/cfi_flash.c       |   43 +++-------------------------------------
 drivers/nor/cfi_flash.h       |    1 +
 drivers/nor/cfi_flash_amd.c   |   35 +++++++++++++++++++++++++++++++++
 drivers/nor/cfi_flash_intel.c |   12 +++++++++++
 4 files changed, 52 insertions(+), 39 deletions(-)

diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index 6d22a53..2fa2c6b 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -314,7 +314,6 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
 	uchar num_erase_regions;
 	int erase_region_size;
 	int erase_region_count;
-	int geometry_reversed = 0;
 	int cur_offset = 0;
 	struct cfi_qry qry;
 
@@ -368,38 +367,7 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
 		info->cfi_cmd_set->flash_read_jedec_ids (info);
 		flash_write_cmd (info, 0, info->cfi_offset, FLASH_CMD_CFI);
 
-		switch (info->vendor) {
-		case CFI_CMDSET_INTEL_STANDARD:
-		case CFI_CMDSET_INTEL_EXTENDED:
-		default:
-#ifdef CFG_FLASH_PROTECTION
-			/* read legacy lock/unlock bit from intel flash */
-			if (info->ext_addr) {
-				info->legacy_unlock = flash_read_uchar (info,
-						info->ext_addr + 5) & 0x08;
-			}
-#endif
-			break;
-		case CFI_CMDSET_AMD_STANDARD:
-		case CFI_CMDSET_AMD_EXTENDED:
-			/* check if flash geometry needs reversal */
-			if (num_erase_regions <= 1)
-				break;
-			/* reverse geometry if top boot part */
-			if (info->cfi_version < 0x3131) {
-				/* CFI < 1.1, try to guess from device id */
-				if ((info->device_id & 0x80) != 0) {
-					geometry_reversed = 1;
-				}
-				break;
-			}
-			/* CFI >= 1.1, deduct from top/bottom flag */
-			/* note: ext_addr is valid since cfi_version > 0 */
-			if (flash_read_uchar(info, info->ext_addr + 0xf) == 3) {
-				geometry_reversed = 1;
-			}
-			break;
-		}
+		info->cfi_cmd_set->flash_fixup (info, &qry);
 
 		debug ("manufacturer is %d\n", info->vendor);
 		debug ("manufacturer id is 0x%x\n", info->manufacturer_id);
@@ -423,7 +391,6 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
 		sector = base;
 
 		for (i = 0; i < num_erase_regions; i++) {
-			unsigned int __region = i;
 			struct mtd_erase_region_info *region = &info->eraseregions[i];
 
 			if (i > NUM_ERASE_REGIONS) {
@@ -431,11 +398,9 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
 					num_erase_regions, NUM_ERASE_REGIONS);
 				break;
 			}
-			if (geometry_reversed)
-				__region = num_erase_regions - 1 - i;
-			
-			tmp = le32_to_cpu(qry.erase_region_info[__region]);
-			debug("erase region %u: 0x%08lx\n", __region, tmp);
+
+			tmp = le32_to_cpu(qry.erase_region_info[i]);
+			debug("erase region %u: 0x%08lx\n", i, tmp);
 
 			erase_region_count = (tmp & 0xffff) + 1;
 			tmp >>= 16;
diff --git a/drivers/nor/cfi_flash.h b/drivers/nor/cfi_flash.h
index 4b3bd25..1a3847d 100644
--- a/drivers/nor/cfi_flash.h
+++ b/drivers/nor/cfi_flash.h
@@ -114,6 +114,7 @@ struct cfi_cmd_set {
 	void (*flash_prepare_write) (struct flash_info *info);
 	int (*flash_status_check) (struct flash_info *info, flash_sect_t sector, uint64_t tout, char *prompt);
 	int (*flash_real_protect) (struct flash_info *info, long sector, int prot);
+	void (*flash_fixup) (struct flash_info *info, struct cfi_qry *qry);
 };
 
 extern struct cfi_cmd_set cfi_cmd_set_intel;
diff --git a/drivers/nor/cfi_flash_amd.c b/drivers/nor/cfi_flash_amd.c
index f225757..b50de22 100644
--- a/drivers/nor/cfi_flash_amd.c
+++ b/drivers/nor/cfi_flash_amd.c
@@ -2,6 +2,23 @@
 #include <stdio.h>
 #include "cfi_flash.h"
 
+/*-----------------------------------------------------------------------
+ * Reverse the order of the erase regions in the CFI QRY structure.
+ * This is needed for chips that are either a) correctly detected as
+ * top-boot, or b) buggy.
+ */
+static void cfi_reverse_geometry(struct cfi_qry *qry)
+{
+	unsigned int i, j;
+	u32 tmp;
+
+	for (i = 0, j = qry->num_erase_regions - 1; i < j; i++, j--) {
+		tmp = qry->erase_region_info[i];
+		qry->erase_region_info[i] = qry->erase_region_info[j];
+		qry->erase_region_info[j] = tmp;
+	}
+}
+
 static void flash_unlock_seq (struct flash_info *info)
 {
 	flash_write_cmd (info, 0, info->addr_unlock1, AMD_CMD_UNLOCK_START);
@@ -184,6 +201,23 @@ static int amd_flash_real_protect (struct flash_info *info, long sector, int pro
 	return 0;
 }
 
+static void amd_flash_fixup (struct flash_info *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, 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 + 0xf) == 3) {
+			/* CFI >= 1.1, deduct from top/bottom flag */
+			/* note: ext_addr is valid since cfi_version > 0 */
+			cfi_reverse_geometry(qry);
+		}
+	}
+}
+
 struct cfi_cmd_set cfi_cmd_set_amd = {
 	.flash_write_cfibuffer = amd_flash_write_cfibuffer,
 	.flash_erase_one = amd_flash_erase_one,
@@ -192,5 +226,6 @@ struct cfi_cmd_set cfi_cmd_set_amd = {
 	.flash_prepare_write = amd_flash_prepare_write,
 	.flash_status_check = flash_generic_status_check,
 	.flash_real_protect = amd_flash_real_protect,
+	.flash_fixup = amd_flash_fixup,
 };
 
diff --git a/drivers/nor/cfi_flash_intel.c b/drivers/nor/cfi_flash_intel.c
index 8e8a820..c3cbad5 100644
--- a/drivers/nor/cfi_flash_intel.c
+++ b/drivers/nor/cfi_flash_intel.c
@@ -141,6 +141,17 @@ static int intel_flash_real_protect (struct flash_info *info, long sector, int p
 	return 0;
 }
 
+static void intel_flash_fixup (struct flash_info *info, struct cfi_qry *qry)
+{
+#ifdef CFG_FLASH_PROTECTION
+	/* read legacy lock/unlock bit from intel flash */
+	if (info->ext_addr) {
+		info->legacy_unlock = flash_read_uchar (info,
+				info->ext_addr + 5) & 0x08;
+	}
+#endif
+}
+
 struct cfi_cmd_set cfi_cmd_set_intel = {
 	.flash_write_cfibuffer = intel_flash_write_cfibuffer,
 	.flash_erase_one = intel_flash_erase_one,
@@ -149,5 +160,6 @@ struct cfi_cmd_set cfi_cmd_set_intel = {
 	.flash_prepare_write = intel_flash_prepare_write,
 	.flash_status_check = intel_flash_status_check,
 	.flash_real_protect = intel_flash_real_protect,
+	.flash_fixup = intel_flash_fixup,
 };
 
-- 
1.7.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 12/12] cfi_flash_amd: Add manufacturer-specific fixups
  2010-11-26 19:43 [PATCH 0/12] cfi_flash: improvment Jean-Christophe PLAGNIOL-VILLARD
                   ` (10 preceding siblings ...)
  2010-11-26 19:52 ` [PATCH 11/12] cfi_flash: introduce flash cmdset fixup Jean-Christophe PLAGNIOL-VILLARD
@ 2010-11-26 19:52 ` Jean-Christophe PLAGNIOL-VILLARD
  2010-11-29 20:53 ` [PATCH 0/12] cfi_flash: improvment Sascha Hauer
  12 siblings, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-11-26 19:52 UTC (permalink / raw)
  To: barebox; +Cc: Nicolas Ferre, Patrice Vilchez, Haavard Skinnemoen

Run fixups based on the JEDEC manufacturer ID independent of the
command set ID.

This changes current behaviour: Previously, geometry reversal for AMD
chips were done based on the command set ID, while they are now done
based on the JEDEC manufacturer and device ID.

Also add fixup for top-boot Atmel chips.

based on U-Boot

Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 drivers/nor/cfi_flash_amd.c |   39 ++++++++++++++++++++++++++++++++++++++-
 1 files changed, 38 insertions(+), 1 deletions(-)

diff --git a/drivers/nor/cfi_flash_amd.c b/drivers/nor/cfi_flash_amd.c
index b50de22..b1d7070 100644
--- a/drivers/nor/cfi_flash_amd.c
+++ b/drivers/nor/cfi_flash_amd.c
@@ -201,7 +201,11 @@ static int amd_flash_real_protect (struct flash_info *info, long sector, int pro
 	return 0;
 }
 
-static void amd_flash_fixup (struct flash_info *info, struct cfi_qry *qry)
+/*
+ * Manufacturer-specific quirks. Add workarounds for geometry
+ * reversal, etc. here.
+ */
+static void flash_fixup_amd (struct flash_info *info, struct cfi_qry *qry)
 {
 	/* check if flash geometry needs reversal */
 	if (qry->num_erase_regions > 1) {
@@ -218,6 +222,39 @@ static void amd_flash_fixup (struct flash_info *info, struct cfi_qry *qry)
 	}
 }
 
+static void flash_fixup_atmel(struct flash_info *info, struct cfi_qry *qry)
+{
+	int reverse_geometry = 0;
+
+	/* Check the "top boot" bit in the PRI */
+	if (info->ext_addr && !(flash_read_uchar(info, info->ext_addr + 6) & 1))
+		reverse_geometry = 1;
+
+	/* AT49BV6416(T) list the erase regions in the wrong order.
+	 * However, the device ID is identical with the non-broken
+	 * AT49BV642D since u-boot only reads the low byte (they
+	 * differ in the high byte.) So leave out this fixup for now.
+	 */
+	if (info->device_id == 0xd6 || info->device_id == 0xd2)
+		reverse_geometry = !reverse_geometry;
+
+	if (reverse_geometry)
+		cfi_reverse_geometry(qry);
+}
+
+static void amd_flash_fixup(struct flash_info *info, struct cfi_qry *qry)
+{
+	/* Do manufacturer-specific fixups */
+	switch (info->manufacturer_id) {
+	case 0x0001:
+		flash_fixup_amd(info, qry);
+		break;
+	case 0x001f:
+		flash_fixup_atmel(info, qry);
+		break;
+        }
+}
+
 struct cfi_cmd_set cfi_cmd_set_amd = {
 	.flash_write_cfibuffer = amd_flash_write_cfibuffer,
 	.flash_erase_one = amd_flash_erase_one,
-- 
1.7.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* Re: [PATCH 0/12] cfi_flash: improvment
  2010-11-26 19:43 [PATCH 0/12] cfi_flash: improvment Jean-Christophe PLAGNIOL-VILLARD
                   ` (11 preceding siblings ...)
  2010-11-26 19:52 ` [PATCH 12/12] cfi_flash_amd: Add manufacturer-specific fixups Jean-Christophe PLAGNIOL-VILLARD
@ 2010-11-29 20:53 ` Sascha Hauer
  2010-11-30 13:44   ` Jean-Christophe PLAGNIOL-VILLARD
  2010-12-02 17:52   ` Jean-Christophe PLAGNIOL-VILLARD
  12 siblings, 2 replies; 16+ messages in thread
From: Sascha Hauer @ 2010-11-29 20:53 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox, Patrice Vilchez, Nicolas Ferre

Hi J,

On Fri, Nov 26, 2010 at 08:43:53PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> Hi,
> 
> 	the following patch series improve the current flash
> 	by adding the atmel flash supportm fixing some issues and factorising
> 	more the code
> 
> 	Found during the adding of the at91rm9200ek
> 
> please pull
> The following changes since commit 53dbaf3fc7b8371ed1e24ef96715e41d60b8ebc3:
> 
>   Merge branch 'master' into next (2010-11-19 09:35:15 +0100)

Nice. I like this series.

Can we use readl/writel instead? The __raw_ versions do not exist on
architectures other than ARM.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* Re: [PATCH 0/12] cfi_flash: improvment
  2010-11-29 20:53 ` [PATCH 0/12] cfi_flash: improvment Sascha Hauer
@ 2010-11-30 13:44   ` Jean-Christophe PLAGNIOL-VILLARD
  2010-12-02 17:52   ` Jean-Christophe PLAGNIOL-VILLARD
  1 sibling, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-11-30 13:44 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox, Patrice Vilchez, Nicolas Ferre

On 21:53 Mon 29 Nov     , Sascha Hauer wrote:
> Hi J,
> 
> On Fri, Nov 26, 2010 at 08:43:53PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > Hi,
> > 
> > 	the following patch series improve the current flash
> > 	by adding the atmel flash supportm fixing some issues and factorising
> > 	more the code
> > 
> > 	Found during the adding of the at91rm9200ek
> > 
> > please pull
> > The following changes since commit 53dbaf3fc7b8371ed1e24ef96715e41d60b8ebc3:
> > 
> >   Merge branch 'master' into next (2010-11-19 09:35:15 +0100)
> 
> Nice. I like this series.
> 
> Can we use readl/writel instead? The __raw_ versions do not exist on
> architectures other than ARM.
yeah we can but __raw_ is supposed to exist on all arch IIRC
as u which

Best Regards,
J.

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* Re: [PATCH 0/12] cfi_flash: improvment
  2010-11-29 20:53 ` [PATCH 0/12] cfi_flash: improvment Sascha Hauer
  2010-11-30 13:44   ` Jean-Christophe PLAGNIOL-VILLARD
@ 2010-12-02 17:52   ` Jean-Christophe PLAGNIOL-VILLARD
  1 sibling, 0 replies; 16+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2010-12-02 17:52 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox, Patrice Vilchez, Nicolas Ferre

Hi,

	update without the __raw_

please pull
The following changes since commit 4a7f56056d6aa12a0449f03eb038e4d2bf7fdd49:

  scripts: Adapt checkpatch.pl for barebox. (2010-11-29 21:56:05 +0100)

are available in the git repository at:
  git://git.jcrosoft.org/barebox.git cfi

Jean-Christophe PLAGNIOL-VILLARD (12):
      cfi_flash: move intel real protect flash support to cfi_flash_intel.c
      cfi_flash: add Atmel real protect flash support
      cfi_flash: move flash_read_uchar from inline to noinline
      cfi_flash: use amd and standard reset flash command at probing
      cfi_flash: synchronize command offsets with Linux CFI driver
      cfi_flash: update manufacturer id flash support
      cfi_flash: Introduce read and write accessors
      cfi_flash: Read whole QRY structure in one go
      cfi_flash: do not reset flash when probe fails
      cfi_flash: move reset command assigment to specific chipset init function
      cfi_flash: introduce flash cmdset fixup
      cfi_flash_amd: Add manufacturer-specific fixups

 drivers/nor/cfi_flash.c       |  303 +++++++++++++++++++----------------------
 drivers/nor/cfi_flash.h       |  120 +++++++++++++----
 drivers/nor/cfi_flash_amd.c   |  172 ++++++++++++++++++++----
 drivers/nor/cfi_flash_intel.c |   52 ++++++--
 4 files changed, 420 insertions(+), 227 deletions(-)

Best Regards,
J.
On 21:53 Mon 29 Nov     , Sascha Hauer wrote:
> Hi J,
> 
> On Fri, Nov 26, 2010 at 08:43:53PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > Hi,
> > 
> > 	the following patch series improve the current flash
> > 	by adding the atmel flash supportm fixing some issues and factorising
> > 	more the code
> > 
> > 	Found during the adding of the at91rm9200ek
> > 
> > please pull
> > The following changes since commit 53dbaf3fc7b8371ed1e24ef96715e41d60b8ebc3:
> > 
> >   Merge branch 'master' into next (2010-11-19 09:35:15 +0100)
> 
> Nice. I like this series.
> 
> Can we use readl/writel instead? The __raw_ versions do not exist on
> architectures other than ARM.
> 
> Sascha
> 
> 
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

end of thread, other threads:[~2010-12-02 18:02 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-26 19:43 [PATCH 0/12] cfi_flash: improvment Jean-Christophe PLAGNIOL-VILLARD
2010-11-26 19:52 ` [PATCH 01/12] cfi_flash: move intel real protect flash support to cfi_flash_intel.c Jean-Christophe PLAGNIOL-VILLARD
2010-11-26 19:52 ` [PATCH 02/12] cfi_flash: add Atmel real protect flash support Jean-Christophe PLAGNIOL-VILLARD
2010-11-26 19:52 ` [PATCH 03/12] cfi_flash: move flash_read_uchar from inline to noinline Jean-Christophe PLAGNIOL-VILLARD
2010-11-26 19:52 ` [PATCH 04/12] cfi_flash: use amd and standard reset flash command at probing Jean-Christophe PLAGNIOL-VILLARD
2010-11-26 19:52 ` [PATCH 05/12] cfi_flash: synchronize command offsets with Linux CFI driver Jean-Christophe PLAGNIOL-VILLARD
2010-11-26 19:52 ` [PATCH 06/12] cfi_flash: update manufacturer id flash support Jean-Christophe PLAGNIOL-VILLARD
2010-11-26 19:52 ` [PATCH 07/12] cfi_flash: Introduce read and write accessors Jean-Christophe PLAGNIOL-VILLARD
2010-11-26 19:52 ` [PATCH 08/12] cfi_flash: Read whole QRY structure in one go Jean-Christophe PLAGNIOL-VILLARD
2010-11-26 19:52 ` [PATCH 09/12] cfi_flash: do not reset flash when probe fails Jean-Christophe PLAGNIOL-VILLARD
2010-11-26 19:52 ` [PATCH 10/12] cfi_flash: move reset command assigment to specific chipset init function Jean-Christophe PLAGNIOL-VILLARD
2010-11-26 19:52 ` [PATCH 11/12] cfi_flash: introduce flash cmdset fixup Jean-Christophe PLAGNIOL-VILLARD
2010-11-26 19:52 ` [PATCH 12/12] cfi_flash_amd: Add manufacturer-specific fixups Jean-Christophe PLAGNIOL-VILLARD
2010-11-29 20:53 ` [PATCH 0/12] cfi_flash: improvment Sascha Hauer
2010-11-30 13:44   ` Jean-Christophe PLAGNIOL-VILLARD
2010-12-02 17:52   ` Jean-Christophe PLAGNIOL-VILLARD

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