From: Ashok Reddy Soma <ashok.reddy.s...@amd.com>

Add support for parallel memories and stacked memories configuration
in read_bar and write_bar functions.

Signed-off-by: Ashok Reddy Soma <ashok.reddy.s...@amd.com>
Signed-off-by: Venkatesh Yadav Abbarapu <venkatesh.abbar...@amd.com>
---
 drivers/mtd/spi/spi-nor-core.c | 55 +++++++++++++++++++++++++++++-----
 1 file changed, 47 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index c1c9d007f9..d245d5e415 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -885,12 +885,32 @@ static int clean_bar(struct spi_nor *nor)
 
 static int write_bar(struct spi_nor *nor, u32 offset)
 {
-       u8 cmd, bank_sel;
+       u8 cmd, bank_sel, upage_curr;
        int ret;
+       struct mtd_info *mtd = &nor->mtd;
+
+       /* Wait until previous write command is finished */
+       if (spi_nor_wait_till_ready(nor))
+               return 1;
+
+       if (nor->flags & (SNOR_F_HAS_PARALLEL | SNOR_F_HAS_STACKED) &&
+           mtd->size <= SZ_32M)
+               return 0;
+
+       if (mtd->size <= SZ_16M)
+               return 0;
+
+       offset = offset % (u32)mtd->size;
+       bank_sel = offset >> 24;
 
-       bank_sel = offset / SZ_16M;
-       if (bank_sel == nor->bank_curr)
-               goto bar_end;
+       upage_curr = nor->spi->flags & SPI_XFER_U_PAGE;
+
+       if (!(nor->flags & SNOR_F_HAS_STACKED) && bank_sel == nor->bank_curr)
+               return 0;
+       else if (upage_curr == nor->upage_prev && bank_sel == nor->bank_curr)
+               return 0;
+       else
+               nor->upage_prev = upage_curr;
 
        cmd = nor->bank_write_cmd;
        write_enable(nor);
@@ -900,15 +920,19 @@ static int write_bar(struct spi_nor *nor, u32 offset)
                return ret;
        }
 
-bar_end:
        nor->bank_curr = bank_sel;
-       return nor->bank_curr;
+
+       return write_disable(nor);
 }
 
 static int read_bar(struct spi_nor *nor, const struct flash_info *info)
 {
        u8 curr_bank = 0;
        int ret;
+       struct mtd_info *mtd = &nor->mtd;
+
+       if (mtd->size <= SZ_16M)
+               return 0;
 
        switch (JEDEC_MFR(info)) {
        case SNOR_MFR_SPANSION:
@@ -920,15 +944,30 @@ static int read_bar(struct spi_nor *nor, const struct 
flash_info *info)
                nor->bank_write_cmd = SPINOR_OP_WREAR;
        }
 
+       if (nor->flags & SNOR_F_HAS_PARALLEL)
+               nor->spi->flags |= SPI_XFER_LOWER;
+
        ret = nor->read_reg(nor, nor->bank_read_cmd,
-                                   &curr_bank, 1);
+                           &curr_bank, 1);
        if (ret) {
                debug("SF: fail to read bank addr register\n");
                return ret;
        }
        nor->bank_curr = curr_bank;
 
-       return 0;
+       // Make sure both chips use the same BAR
+       if (nor->flags & SNOR_F_HAS_PARALLEL) {
+               write_enable(nor);
+               ret = nor->write_reg(nor, nor->bank_write_cmd, &curr_bank, 1);
+               if (ret)
+                       return ret;
+
+               ret = write_disable(nor);
+               if (ret)
+                       return ret;
+       }
+
+       return ret;
 }
 #endif
 
-- 
2.17.1

Reply via email to