Re: [U-Boot] [PATCH 3/4] sf: Add extended address access support

2013-02-27 Thread Jagannadha Sutradharudu Teki


 -Original Message-
 From: Langer Thomas (LQDE RD ST PON SW)
 [mailto:thomas.lan...@lantiq.com]
 Sent: 24 February 2013 21:21
 To: Jagannadha Sutradharudu Teki; u-boot@lists.denx.de
 Cc: mic...@theia.denx.de; Jagannadha Sutradharudu Teki
 Subject: AW: [U-Boot] [PATCH 3/4] sf: Add extended address access support

 Hello Jagan,

 Am 23.02.2013 12:39, schrieb Jagannadha Sutradharudu Teki:
  This patch provides support to access an extended addressing in 3-byte
  address mode.
 
  The current implementation in spi_flash supports 3-byte address mode
  due to this up to 16MB amount of flash is able to access for those
  flashes which has an actual size of  16MB.
 
  extended/bank address register contains an information to access the
  4th byte addressing hence the flashes which has  16MB can be accessible.
 
  Signed-off-by: Jagannadha Sutradharudu Teki jaga...@xilinx.com
  ---
drivers/mtd/spi/spi_flash.c  |   81
 ++
drivers/mtd/spi/spi_flash_internal.h |8 +++
2 files changed, 89 insertions(+), 0 deletions(-)
 
  diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
  index c168c1c..16e5f59 100644
  --- a/drivers/mtd/spi/spi_flash.c
  +++ b/drivers/mtd/spi/spi_flash.c
  @@ -23,6 +23,30 @@ static void spi_flash_addr(u32 addr, u8 *cmd)
  cmd[3] = addr  0;
}
 
  +static int spi_flash_check_extaddr_access(struct spi_flash *flash,
  +u32 *offset) {
  +   int ret;
  +
  +   if (*offset = 0x100) {
  +   ret = spi_flash_extaddr_access(flash,
 STATUS_EXTADDR_ENABLE);
 Restricting this to a single bit here would give the next size limit at 32M.
 Please make it future-prov as much as possible: Why not directly use the
 upper byte of the offset as parameter?

I didn't get you clearly, can you please elaborate.


  +   if (ret) {
  +   debug(SF: fail to %s ext addr bit\n,
  +   STATUS_EXTADDR_ENABLE ? set : reset);
  +   return ret;
  +   }
  +   *offset -= 0x100;
 Are you sure that manipulating the value of the caller has no side-effect?
 Is it even necessary, if the callers only do 3-byte-addressing and probably
 ignore the upper byte?

May be you are not getting my exact code context.

From the current implementation on spi, we have 3-byte addressing means we are 
able to access
only up to 16MB-- means 0 to 0x FF

If the flash has 32MB, if the user is giving an offset 0x100 it will again 
pointing to 0x0.
Because we have 3-byte addressing able to access only first 16MB of flash but 
the actual flash size is 32MB.

So, from my implementation if user is giving an offset of 0x100 then we 
have enable the bank register
for pointing to second 16MB area on 32 MB flash and we must subtract the offset 
from 16MB as we are using 3-byte
addressing. Means we are accessing 4-byte addressing in 3-byte address mode. Ie 
is the reason I am subtracting it from16MB.

Please comment and let me know if you're not clear.


  +   } else {
  +   ret = spi_flash_extaddr_access(flash,
 STATUS_EXTADDR_DISABLE);
  +   if (ret) {
  +   debug(SF: fail to %s ext addr bit\n,
  +   STATUS_EXTADDR_DISABLE ? set : reset);
  +   return ret;
  +   }
  +   }
  +
  +   return ret;
  +}
  +
static int spi_flash_read_write(struct spi_slave *spi,
  const u8 *cmd, size_t cmd_len,
  const u8 *data_out, u8 *data_in, @@ -73,6
 +97,14 @@ int
  spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset,
  int ret;
  u8 cmd[4];
 
  +   if (flash-size  0x100) {

 As already said in my comments to patch 1/4, this check (and the check for
 manufacturer ID) should be done only once once during probing of the flash.
 Then, if necessary, adapted functions for read, write and erase should be
 assigned to the function-pointers.
 Or use an additional function-pointer, which can be set to this or a similar
 function.
 Then the call of this function should be included in the loops, which all 
 these
 functions have.
 Otherwise, as with your current code, you have a problem if the current
 accessed block crosses the boundary at 16M. Have you ever tried this?

Means this check should be in probe call, by adding one member in spi_flash 
structure, is it?.
I am not understanding extra function pointers concept, will you please explain.


  +   ret = spi_flash_check_extaddr_access(flash, offset);
  +   if (ret) {
  +   debug(SF: fail to acess ext_addr\n);
  +   return ret;
  +   }
  +   }
  +
  page_size = flash-page_size;
  page_addr = offset / page_size;
  byte_addr = offset % page_size;
  @@ -139,6 +171,15 @@ int spi_flash_cmd_read_fast(struct spi_flash
 *flash, u32 offset,
  size_t len, void *data)
{
  u8 cmd[5];
  +   int ret

Re: [U-Boot] [PATCH 3/4] sf: Add extended address access support

2013-02-24 Thread Langer Thomas (LQDE RD ST PON SW)
Hello Jagan,

Am 23.02.2013 12:39, schrieb Jagannadha Sutradharudu Teki:
 This patch provides support to access an extended addressing
 in 3-byte address mode.
 
 The current implementation in spi_flash supports 3-byte address mode
 due to this up to 16MB amount of flash is able to access for those
 flashes which has an actual size of  16MB.
 
 extended/bank address register contains an information to access the
 4th byte addressing hence the flashes which has  16MB can be accessible.
 
 Signed-off-by: Jagannadha Sutradharudu Teki jaga...@xilinx.com
 ---
   drivers/mtd/spi/spi_flash.c  |   81 
 ++
   drivers/mtd/spi/spi_flash_internal.h |8 +++
   2 files changed, 89 insertions(+), 0 deletions(-)
 
 diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
 index c168c1c..16e5f59 100644
 --- a/drivers/mtd/spi/spi_flash.c
 +++ b/drivers/mtd/spi/spi_flash.c
 @@ -23,6 +23,30 @@ static void spi_flash_addr(u32 addr, u8 *cmd)
   cmd[3] = addr  0;
   }
   
 +static int spi_flash_check_extaddr_access(struct spi_flash *flash, u32 
 *offset)
 +{
 + int ret;
 +
 + if (*offset = 0x100) {
 + ret = spi_flash_extaddr_access(flash, STATUS_EXTADDR_ENABLE);
Restricting this to a single bit here would give the next size limit at 32M.
Please make it future-prov as much as possible: Why not directly use the upper 
byte of the offset as parameter?

 + if (ret) {
 + debug(SF: fail to %s ext addr bit\n,
 + STATUS_EXTADDR_ENABLE ? set : reset);
 + return ret;
 + }
 + *offset -= 0x100;
Are you sure that manipulating the value of the caller has no side-effect?
Is it even necessary, if the callers only do 3-byte-addressing and probably 
ignore the upper byte?

 + } else {
 + ret = spi_flash_extaddr_access(flash, STATUS_EXTADDR_DISABLE);
 + if (ret) {
 + debug(SF: fail to %s ext addr bit\n,
 + STATUS_EXTADDR_DISABLE ? set : reset);
 + return ret;
 + }
 + }
 +
 + return ret;
 +}
 +
   static int spi_flash_read_write(struct spi_slave *spi,
   const u8 *cmd, size_t cmd_len,
   const u8 *data_out, u8 *data_in,
 @@ -73,6 +97,14 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 
 offset,
   int ret;
   u8 cmd[4];
   
 + if (flash-size  0x100) {

As already said in my comments to patch 1/4, this check (and the check for 
manufacturer ID) should be done 
only once once during probing of the flash.
Then, if necessary, adapted functions for read, write and erase should be 
assigned to the function-pointers.
Or use an additional function-pointer, which can be set to this or a similar 
function.
Then the call of this function should be included in the loops, which all these 
functions have.
Otherwise, as with your current code, you have a problem if the current 
accessed block crosses the boundary
at 16M. Have you ever tried this?

 + ret = spi_flash_check_extaddr_access(flash, offset);
 + if (ret) {
 + debug(SF: fail to acess ext_addr\n);
 + return ret;
 + }
 + }
 +
   page_size = flash-page_size;
   page_addr = offset / page_size;
   byte_addr = offset % page_size;
 @@ -139,6 +171,15 @@ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 
 offset,
   size_t len, void *data)
   {
   u8 cmd[5];
 + int ret;
 +
 + if (flash-size  0x100) {
 + ret = spi_flash_check_extaddr_access(flash, offset);
 + if (ret) {
 + debug(SF: fail to acess ext_addr\n);
 + return ret;
 + }
 + }
   
   cmd[0] = CMD_READ_ARRAY_FAST;
   spi_flash_addr(offset, cmd);
 @@ -196,6 +237,14 @@ int spi_flash_cmd_erase(struct spi_flash *flash, u32 
 offset, size_t len)
   int ret;
   u8 cmd[4];
   
 + if (flash-size  0x100) {
 + ret = spi_flash_check_extaddr_access(flash, offset);
 + if (ret) {
 + debug(SF: fail to acess ext_addr\n);
 + return ret;
 + }
 + }
 +
   erase_size = flash-sector_size;
   if (offset % erase_size || len % erase_size) {
   debug(SF: Erase offset/length not multiple of erase size\n);
 @@ -333,6 +382,38 @@ int spi_flash_cmd_extaddr_read(struct spi_flash *flash, 
 void *data)
   return spi_flash_read_common(flash, cmd, 1, data, 1);
   }
   
 +int spi_flash_extaddr_access(struct spi_flash *flash, u8 status)
 +{
 + int ret, pass;
 + u8 data = 0, write_done = 0;
 +
 + for (pass = 0; pass  2; pass++) {
Why this is required??

 + ret = spi_flash_cmd_extaddr_read(flash, (void *)data);
 + if (ret  0) {
 +  

[U-Boot] [PATCH 3/4] sf: Add extended address access support

2013-02-23 Thread Jagannadha Sutradharudu Teki
This patch provides support to access an extended addressing
in 3-byte address mode.

The current implementation in spi_flash supports 3-byte address mode
due to this up to 16MB amount of flash is able to access for those
flashes which has an actual size of  16MB.

extended/bank address register contains an information to access the
4th byte addressing hence the flashes which has  16MB can be accessible.

Signed-off-by: Jagannadha Sutradharudu Teki jaga...@xilinx.com
---
 drivers/mtd/spi/spi_flash.c  |   81 ++
 drivers/mtd/spi/spi_flash_internal.h |8 +++
 2 files changed, 89 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index c168c1c..16e5f59 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -23,6 +23,30 @@ static void spi_flash_addr(u32 addr, u8 *cmd)
cmd[3] = addr  0;
 }
 
+static int spi_flash_check_extaddr_access(struct spi_flash *flash, u32 *offset)
+{
+   int ret;
+
+   if (*offset = 0x100) {
+   ret = spi_flash_extaddr_access(flash, STATUS_EXTADDR_ENABLE);
+   if (ret) {
+   debug(SF: fail to %s ext addr bit\n,
+   STATUS_EXTADDR_ENABLE ? set : reset);
+   return ret;
+   }
+   *offset -= 0x100;
+   } else {
+   ret = spi_flash_extaddr_access(flash, STATUS_EXTADDR_DISABLE);
+   if (ret) {
+   debug(SF: fail to %s ext addr bit\n,
+   STATUS_EXTADDR_DISABLE ? set : reset);
+   return ret;
+   }
+   }
+
+   return ret;
+}
+
 static int spi_flash_read_write(struct spi_slave *spi,
const u8 *cmd, size_t cmd_len,
const u8 *data_out, u8 *data_in,
@@ -73,6 +97,14 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 
offset,
int ret;
u8 cmd[4];
 
+   if (flash-size  0x100) {
+   ret = spi_flash_check_extaddr_access(flash, offset);
+   if (ret) {
+   debug(SF: fail to acess ext_addr\n);
+   return ret;
+   }
+   }
+
page_size = flash-page_size;
page_addr = offset / page_size;
byte_addr = offset % page_size;
@@ -139,6 +171,15 @@ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 
offset,
size_t len, void *data)
 {
u8 cmd[5];
+   int ret;
+
+   if (flash-size  0x100) {
+   ret = spi_flash_check_extaddr_access(flash, offset);
+   if (ret) {
+   debug(SF: fail to acess ext_addr\n);
+   return ret;
+   }
+   }
 
cmd[0] = CMD_READ_ARRAY_FAST;
spi_flash_addr(offset, cmd);
@@ -196,6 +237,14 @@ int spi_flash_cmd_erase(struct spi_flash *flash, u32 
offset, size_t len)
int ret;
u8 cmd[4];
 
+   if (flash-size  0x100) {
+   ret = spi_flash_check_extaddr_access(flash, offset);
+   if (ret) {
+   debug(SF: fail to acess ext_addr\n);
+   return ret;
+   }
+   }
+
erase_size = flash-sector_size;
if (offset % erase_size || len % erase_size) {
debug(SF: Erase offset/length not multiple of erase size\n);
@@ -333,6 +382,38 @@ int spi_flash_cmd_extaddr_read(struct spi_flash *flash, 
void *data)
return spi_flash_read_common(flash, cmd, 1, data, 1);
 }
 
+int spi_flash_extaddr_access(struct spi_flash *flash, u8 status)
+{
+   int ret, pass;
+   u8 data = 0, write_done = 0;
+
+   for (pass = 0; pass  2; pass++) {
+   ret = spi_flash_cmd_extaddr_read(flash, (void *)data);
+   if (ret  0) {
+   debug(SF: fail to read ext addr register\n);
+   return ret;
+   }
+
+   if ((data != status)  !write_done) {
+   debug(SF: need to %s ext addr bit\n,
+   status ? set : reset);
+
+   write_done = 1;
+   ret = spi_flash_cmd_extaddr_write(flash, status);
+   if (ret  0) {
+   debug(SF: fail to write ext addr bit\n);
+   return ret;
+   }
+   } else {
+   debug(SF: ext addr bit is %s.\n,
+   status ? set : reset);
+   return ret;
+   }
+   }
+
+   return -1;
+}
+
 /*
  * The following table holds all device probe functions
  *
diff --git a/drivers/mtd/spi/spi_flash_internal.h 
b/drivers/mtd/spi/spi_flash_internal.h
index 65960ad..a6b04d7 100644
--- a/drivers/mtd/spi/spi_flash_internal.h