It's required to handling opcode in spi drivers
interface layer, m25p80 from spi-nor, becuase some
spi-nor controller drivers like fsl_qspi have separate
opcode's to handling the same operations.

Cc: Simon Glass <s...@chromium.org>
Cc: Bin Meng <bmeng...@gmail.com>
Cc: Mugunthan V N <mugunthan...@ti.com>
Cc: Michal Simek <michal.si...@xilinx.com>
Cc: Siva Durga Prasad Paladugu <siva...@xilinx.com>
Signed-off-by: Jagan Teki <jt...@openedev.com>
---
 drivers/mtd/spi-nor/m25p80.c  | 53 ++++++++++++++++++++++++++++--------
 drivers/mtd/spi-nor/spi-nor.c | 62 +++++++------------------------------------
 include/linux/mtd/spi-nor.h   | 10 +++----
 3 files changed, 56 insertions(+), 69 deletions(-)

diff --git a/drivers/mtd/spi-nor/m25p80.c b/drivers/mtd/spi-nor/m25p80.c
index cf27ba0..560e5b2 100644
--- a/drivers/mtd/spi-nor/m25p80.c
+++ b/drivers/mtd/spi-nor/m25p80.c
@@ -17,14 +17,24 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/spi-nor.h>
 
+#define MAX_CMD_SIZE           6
 struct m25p {
        struct spi_slave        *spi;
        struct spi_nor          spi_nor;
 #ifndef CONFIG_DM_MTD_SPI_NOR
        struct mtd_info         mtd;
 #endif
+       u8                      command[MAX_CMD_SIZE];
 };
 
+static void spi_nor_addr(u32 addr, u8 *cmd)
+{
+       /* cmd[0] is actual command */
+       cmd[1] = addr >> 16;
+       cmd[2] = addr >> 8;
+       cmd[3] = addr >> 0;
+}
+
 static int m25p80_read_reg(struct spi_nor *nor, u8 cmd, u8 *val, int len)
 {
        struct m25p *flash = nor->priv;
@@ -112,8 +122,8 @@ static int m25p80_read_mmap(struct spi_nor *nor, void *data,
        return ret;
 }
 
-static int m25p80_read(struct spi_nor *nor, const u8 *cmd, size_t cmd_len,
-                               void *data, size_t data_len)
+static int m25p80_read(struct spi_nor *nor, loff_t from, size_t len,
+                      u_char *buf)
 {
        struct m25p *flash = nor->priv;
        struct spi_slave *spi = flash->spi;
@@ -125,12 +135,16 @@ static int m25p80_read(struct spi_nor *nor, const u8 
*cmd, size_t cmd_len,
                return ret;
        }
 
+       flash->command[0] = nor->read_opcode;
+       spi_nor_addr(from, flash->command);
+
        if (nor->flags & SNOR_F_U_PAGE)
                spi->flags |= SPI_XFER_U_PAGE;
 
-       ret = spi_write_then_read(spi, cmd, cmd_len, NULL, data, data_len);
+       ret = spi_write_then_read(spi, flash->command, 4 + nor->read_dummy,
+                                 NULL, buf, len);
        if (ret < 0) {
-               debug("m25p80: error %d reading %x\n", ret, *cmd);
+               debug("m25p80: error %d reading %x\n", ret, flash->command[0]);
                return ret;
        }
 
@@ -139,11 +153,12 @@ static int m25p80_read(struct spi_nor *nor, const u8 
*cmd, size_t cmd_len,
        return ret;
 }
 
-static int m25p80_write(struct spi_nor *nor, const u8 *cmd, size_t cmd_len,
-                               const void *data, size_t data_len)
+static int m25p80_write(struct spi_nor *nor, loff_t to, size_t len,
+                       const u_char *buf)
 {
        struct m25p *flash = nor->priv;
        struct spi_slave *spi = flash->spi;
+       int cmd_sz = 4;
        int ret;
 
        ret = spi_claim_bus(spi);
@@ -152,12 +167,22 @@ static int m25p80_write(struct spi_nor *nor, const u8 
*cmd, size_t cmd_len,
                return ret;
        }
 
+       if (nor->program_opcode == SNOR_OP_AAI_WP)
+               cmd_sz = 1;
+
+       flash->command[0] = nor->program_opcode;
+       spi_nor_addr(to, flash->command);
+
        if (nor->flags & SNOR_F_U_PAGE)
                spi->flags |= SPI_XFER_U_PAGE;
 
-       ret = spi_write_then_read(spi, cmd, cmd_len, data, NULL, data_len);
+       debug("m25p80: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = 
%zu\n",
+              buf, flash->command[0], flash->command[1], flash->command[2],
+              flash->command[3], len);
+
+       ret = spi_write_then_read(spi, flash->command, cmd_sz, buf, NULL, len);
        if (ret < 0) {
-               debug("m25p80: error %d writing %x\n", ret, *cmd);
+               debug("m25p80: error %d writing %x\n", ret, flash->command[0]);
                return ret;
        }
 
@@ -166,7 +191,7 @@ static int m25p80_write(struct spi_nor *nor, const u8 *cmd, 
size_t cmd_len,
        return ret;
 }
 
-static int m25p80_erase(struct spi_nor *nor, const u8 *cmd, size_t cmd_len)
+static int m25p80_erase(struct spi_nor *nor, loff_t offset)
 {
        struct m25p *flash = nor->priv;
        struct spi_slave *spi = flash->spi;
@@ -178,12 +203,18 @@ static int m25p80_erase(struct spi_nor *nor, const u8 
*cmd, size_t cmd_len)
                return ret;
        }
 
+       flash->command[0] = nor->erase_opcode;
+       spi_nor_addr(offset, flash->command);
+
        if (nor->flags & SNOR_F_U_PAGE)
                spi->flags |= SPI_XFER_U_PAGE;
 
-       ret = spi_write_then_read(spi, cmd, cmd_len, NULL, NULL, 0);
+       debug("m25p80: erase %2x %2x %2x %2x (%llx)\n", flash->command[0],
+              flash->command[1], flash->command[2], flash->command[3], offset);
+
+       ret = spi_write_then_read(spi, flash->command, 4, NULL, NULL, 0);
        if (ret < 0) {
-               debug("m25p80: error %d writing %x\n", ret, *cmd);
+               debug("m25p80: error %d writing %x\n", ret, flash->command[0]);
                return ret;
        }
 
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 97f5eaa..cb9ab21 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -32,14 +32,6 @@ static inline int write_disable(struct spi_nor *nor)
        return nor->write_reg(nor, SNOR_OP_WRDI, NULL, 0);
 }
 
-static void spi_nor_addr(u32 addr, u8 *cmd)
-{
-       /* cmd[0] is actual command */
-       cmd[1] = addr >> 16;
-       cmd[2] = addr >> 8;
-       cmd[3] = addr >> 0;
-}
-
 static int read_sr(struct spi_nor *nor)
 {
        u8 sr;
@@ -487,7 +479,6 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
 {
        struct spi_nor *nor = mtd->priv;
        u32 addr, len, erase_addr;
-       u8 cmd[SNOR_MAX_CMD_SIZE];
        uint32_t rem;
        int ret = -1;
 
@@ -506,7 +497,6 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
                }
        }
 
-       cmd[0] = nor->erase_opcode;
        while (len) {
                erase_addr = addr;
 
@@ -519,14 +509,9 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
                if (ret < 0)
                        return ret;
 #endif
-               spi_nor_addr(erase_addr, cmd);
-
-               debug("spi-nor: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
-                     cmd[2], cmd[3], erase_addr);
-
                write_enable(nor);
 
-               ret = nor->erase(nor, cmd, sizeof(cmd));
+               ret = nor->erase(nor, erase_addr);
                if (ret < 0)
                        goto erase_err;
 
@@ -556,7 +541,6 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t 
offset, size_t len,
        struct spi_nor *nor = mtd->priv;
        u32 byte_addr, page_size, write_addr;
        size_t chunk_len, actual;
-       u8 cmd[SNOR_MAX_CMD_SIZE];
        int ret = -1;
 
        if (mtd->_is_locked) {
@@ -569,7 +553,6 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t 
offset, size_t len,
 
        page_size = nor->page_size;
 
-       cmd[0] = nor->program_opcode;
        for (actual = 0; actual < len; actual += chunk_len) {
                write_addr = offset;
 
@@ -589,15 +572,9 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t 
offset, size_t len,
                        chunk_len = min(chunk_len,
                                        (size_t)nor->max_write_size);
 
-               spi_nor_addr(write_addr, cmd);
-
-               debug("spi-nor: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } 
chunk_len = %zu\n",
-                     buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
-
                write_enable(nor);
 
-               ret = nor->write(nor, cmd, sizeof(cmd),
-                                buf + actual, chunk_len);
+               ret = nor->write(nor, write_addr, chunk_len, buf + actual);
                if (ret < 0)
                        break;
 
@@ -617,7 +594,6 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, 
size_t len,
 {
        struct spi_nor *nor = mtd->priv;
        u32 remain_len, read_len, read_addr;
-       u8 cmd[SNOR_MAX_CMD_SIZE], cmdsz;
        int bank_sel = 0;
        int ret = -1;
 
@@ -632,8 +608,6 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, 
size_t len,
                return ret;
        }
 
-       cmdsz = SNOR_MAX_CMD_SIZE + nor->read_dummy;
-       cmd[0] = nor->read_opcode;
        while (len) {
                read_addr = from;
 
@@ -654,9 +628,7 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, 
size_t len,
                else
                        read_len = remain_len;
 
-               spi_nor_addr(read_addr, cmd);
-
-               ret = nor->read(nor, cmd, cmdsz, buf, read_len);
+               ret = nor->read(nor, read_addr, read_len, buf);
                if (ret < 0)
                        break;
 
@@ -674,21 +646,14 @@ static int sst_byte_write(struct spi_nor *nor, u32 offset,
                          const void *buf, size_t *retlen)
 {
        int ret;
-       u8 cmd[4] = {
-               SNOR_OP_BP,
-               offset >> 16,
-               offset >> 8,
-               offset,
-       };
-
-       debug("spi-nor: 0x%p => cmd = { 0x%02x 0x%06x }\n",
-             buf, cmd[0], offset);
 
        ret = write_enable(nor);
        if (ret)
                return ret;
 
-       ret = nor->write(nor, cmd, sizeof(cmd), buf, 1);
+       nor->program_opcode = SNOR_OP_BP;
+
+       ret = nor->write(nor, offset, 1, buf);
        if (ret)
                return ret;
 
@@ -701,9 +666,8 @@ static int sst_write_wp(struct mtd_info *mtd, loff_t 
offset, size_t len,
                        size_t *retlen, const u_char *buf)
 {
        struct spi_nor *nor = mtd->priv;
-       size_t actual, cmd_len;
+       size_t actual;
        int ret;
-       u8 cmd[4];
 
        /* If the data is not word aligned, write out leading single byte */
        actual = offset % 2;
@@ -718,17 +682,10 @@ static int sst_write_wp(struct mtd_info *mtd, loff_t 
offset, size_t len,
        if (ret)
                goto done;
 
-       cmd_len = 4;
-       cmd[0] = SNOR_OP_AAI_WP;
-       cmd[1] = offset >> 16;
-       cmd[2] = offset >> 8;
-       cmd[3] = offset;
-
        for (; actual < len - 1; actual += 2) {
-               debug("spi-nor: 0x%p => cmd = { 0x%02x 0x%06llx }\n",
-                     buf + actual, cmd[0], offset);
+               nor->program_opcode = SNOR_OP_AAI_WP;
 
-               ret = nor->write(nor, cmd, cmd_len, buf + actual, 2);
+               ret = nor->write(nor, offset, 2, buf + actual);
                if (ret) {
                        debug("spi-nor: sst word program failed\n");
                        break;
@@ -738,7 +695,6 @@ static int sst_write_wp(struct mtd_info *mtd, loff_t 
offset, size_t len,
                if (ret)
                        break;
 
-               cmd_len = 1;
                offset += 2;
                *retlen += 2;
        }
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 4749ff4..19a5dd0 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -224,11 +224,11 @@ struct spi_nor {
 
        int (*read_mmap)(struct spi_nor *nor, void *data, void *offset,
                        size_t len);
-       int (*read)(struct spi_nor *nor, const u8 *opcode, size_t cmd_len,
-                       void *data, size_t data_len);
-       int (*write)(struct spi_nor *nor, const u8 *cmd, size_t cmd_len,
-                       const void *data, size_t data_len);
-       int (*erase)(struct spi_nor *nor, const u8 *cmd, size_t cmd_len);
+       int (*read)(struct spi_nor *nor, loff_t from, size_t len,
+                   u_char *read_buf);
+       int (*write)(struct spi_nor *nor, loff_t to, size_t len,
+                    const u_char *write_buf);
+       int (*erase)(struct spi_nor *nor, loff_t offs);
 
        int (*flash_lock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
        int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
-- 
1.9.1

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to