Patchwork [U-Boot,04/12] cmd_sf: Add rd_inst argument to 'sf update' command

login
register
mail settings
Submitter Jagannadha Sutradharudu Teki
Date Dec. 31, 2012, 11:13 a.m.
Message ID <1356952428-19824-5-git-send-email-jagannadh.teki@gmail.com>
Download mbox | patch
Permalink /patch/208835/
State Superseded
Delegated to: Jagannadha Sutradharudu Teki
Headers show

Comments

Jagannadha Sutradharudu Teki - Dec. 31, 2012, 11:13 a.m.
This patch provides a support to add a read instruction(rd_inst)
argument to 'sf update' command.

User will dynamically use the specific read instruction while
reading the flash using 'sf update' command.
Currently added an existing read instruction called afr(Array Fast Read).

Example:
erase and write 0x2000 length bytes from memory at 0x10000 address to
flash offset at 0x0 using pp write instruction and afr read instruction.
u-boot> sf update pp afr 0x10000 0x0 0x2000

Signed-off-by: Jagannadha Sutradharudu Teki <jagannadh.teki@gmail.com>
---
 common/cmd_sf.c |   63 +++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 43 insertions(+), 20 deletions(-)

Patch

diff --git a/common/cmd_sf.c b/common/cmd_sf.c
index 0f4e440..4cfd48a 100644
--- a/common/cmd_sf.c
+++ b/common/cmd_sf.c
@@ -142,6 +142,7 @@  static int do_spi_flash_probe(int argc, char * const argv[])
  *
  * @param flash		flash context pointer
  * @param wr_inst	write instruction
+ * @param rd_inst	read instruction
  * @param offset	flash offset to write
  * @param len		number of bytes to write
  * @param buf		buffer to write from
@@ -150,12 +151,12 @@  static int do_spi_flash_probe(int argc, char * const argv[])
  * @return NULL if OK, else a string containing the stage which failed
  */
 static const char *spi_flash_update_block(struct spi_flash *flash, u8 wr_inst,
-		u32 offset, size_t len, const char *buf, char *cmp_buf,
-		size_t *skipped)
+		u8 rd_inst, u32 offset, size_t len, const char *buf,
+		char *cmp_buf, size_t *skipped)
 {
 	debug("offset=%#x, sector_size=%#x, len=%#zx\n",
 		offset, flash->sector_size, len);
-	if (spi_flash_read(flash, offset, len, cmp_buf))
+	if (spi_flash_read(flash, rd_inst, offset, len, cmp_buf))
 		return "read";
 	if (memcmp(cmp_buf, buf, len) == 0) {
 		debug("Skip region %x size %zx: no change\n",
@@ -176,13 +177,14 @@  static const char *spi_flash_update_block(struct spi_flash *flash, u8 wr_inst,
  *
  * @param flash		flash context pointer
  * @param wr_inst	write instruction
+ * @param rd_inst	read instruction
  * @param offset	flash offset to write
  * @param len		number of bytes to write
  * @param buf		buffer to write from
  * @return 0 if ok, 1 on error
  */
-static int spi_flash_update(struct spi_flash *flash, u8 wr_inst, u32 offset,
-		size_t len, const char *buf)
+static int spi_flash_update(struct spi_flash *flash, u8 wr_inst, u8 rd_inst,
+		u32 offset, size_t len, const char *buf)
 {
 	const char *err_oper = NULL;
 	char *cmp_buf;
@@ -210,8 +212,8 @@  static int spi_flash_update(struct spi_flash *flash, u8 wr_inst, u32 offset,
 				last_update = get_timer(0);
 			}
 			err_oper = spi_flash_update_block(flash, wr_inst,
-					offset, todo, buf, cmp_buf,
-					&skipped);
+					rd_inst, offset, todo, buf,
+					cmp_buf, &skipped);
 		}
 	} else {
 		err_oper = "malloc";
@@ -240,19 +242,29 @@  static int do_spi_flash_read_write(int argc, char * const argv[])
 	void *buf;
 	char *endp;
 	u8 wr_inst, rd_inst;
+	int update_rd_inst;
 	int ret;
 
-	if (argc < 5)
-		return -1;
+	if (strcmp(argv[0], "update") == 0) {
+		if (argc < 6)
+			return -1;
 
-	addr = simple_strtoul(argv[2], &endp, 16);
-	if (*argv[2] == 0 || *endp != 0)
+		update_rd_inst = 1;
+	} else {
+		if (argc < 5)
+			return -1;
+
+		update_rd_inst = 0;
+	}
+
+	addr = simple_strtoul(argv[update_rd_inst + 2], &endp, 16);
+	if (*argv[update_rd_inst + 2] == 0 || *endp != 0)
 		return -1;
-	offset = simple_strtoul(argv[3], &endp, 16);
-	if (*argv[3] == 0 || *endp != 0)
+	offset = simple_strtoul(argv[update_rd_inst + 3], &endp, 16);
+	if (*argv[update_rd_inst + 3] == 0 || *endp != 0)
 		return -1;
-	len = simple_strtoul(argv[4], &endp, 16);
-	if (*argv[4] == 0 || *endp != 0)
+	len = simple_strtoul(argv[update_rd_inst + 4], &endp, 16);
+	if (*argv[update_rd_inst + 4] == 0 || *endp != 0)
 		return -1;
 
 	/* Consistency checking */
@@ -277,7 +289,16 @@  static int do_spi_flash_read_write(int argc, char * const argv[])
 			return 1;
 		}
 
-		ret = spi_flash_update(flash, wr_inst, offset, len, buf);
+		if (strcmp(argv[2], "afr") == 0)
+			rd_inst = CMD_READ_ARRAY_FAST;
+		else {
+			printf("SF: Unknown %s rd_inst on 'sf update'\n",
+					argv[2]);
+			return 1;
+		}
+
+		ret = spi_flash_update(flash, wr_inst, rd_inst,
+					offset, len, buf);
 	} else if (strcmp(argv[0], "read") == 0) {
 		if (strcmp(argv[1], "afr") == 0)
 			rd_inst = CMD_READ_ARRAY_FAST;
@@ -551,7 +572,7 @@  usage:
 #endif
 
 U_BOOT_CMD(
-	sf,	6,	1,	do_spi_flash,
+	sf,	7,	1,	do_spi_flash,
 	"SPI flash sub-system",
 	"probe [[bus:]cs] [hz] [mode]	- init flash device on given SPI bus\n"
 	"				  and chip select\n"
@@ -567,10 +588,12 @@  U_BOOT_CMD(
 	"				  pp (Page Program, 02h)\n"
 	"sf erase offset [+]len		- erase `len' bytes from `offset'\n"
 	"				  `+len' round up `len' to block size\n"
-	"sf update wr_inst addr offset len\n"
+	"sf update wr_inst rd_inst addr offset len\n"
 	"				- erase and write `len' bytes from memory\n"
 	"				  at `addr' to flash at `offset' using\n"
-	"				  pp `wr_inst' write instruction\n"
-	"				  pp (Page Program, 02h)"
+	"				  pp `wr_inst' write instruction and\n"
+	"				  pp (Page Program, 02h)\n"
+	"				  afr `rd_inst' read instruction\n"
+	"				  afr (Array Fast Read, 0bh)"
 	SF_TEST_HELP
 );