The BCMBCA broadband SoC integrates the NAND controller differently than
STB, iProc and other SoCs.  It has different endianness for NAND cache
data.

Add a SoC read data bus shim for BCMBCA to meet the specific SoC need
and performance improvement using the optimized memcpy function on NAND
cache memory.

This is a port of the upstream Linux patch to U-Boot.

https://lore.kernel.org/linux-mtd/[email protected]/

Signed-off-by: david regan <[email protected]>
---
 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 17 ++---------------
 drivers/mtd/nand/raw/brcmnand/brcmnand.h | 18 ++++++++++++++++++
 2 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c 
b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 749553c9df90..6eb2fa65cc1e 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -1640,7 +1640,6 @@ static void brcmnand_cmdfunc(struct mtd_info *mtd, 
unsigned command,
                        native_cmd == CMD_PARAMETER_CHANGE_COL) {
                /* Copy flash cache word-wise */
                u32 *flash_cache = (u32 *)ctrl->flash_cache;
-               int i;
 
                brcmnand_soc_data_bus_prepare(ctrl->soc, true);
 
@@ -1648,20 +1647,8 @@ static void brcmnand_cmdfunc(struct mtd_info *mtd, 
unsigned command,
                 * Must cache the FLASH_CACHE now, since changes in
                 * SECTOR_SIZE_1K may invalidate it
                 */
-               for (i = 0; i < FC_WORDS; i++) {
-                       u32 fc;
-
-                       fc = brcmnand_read_fc(ctrl, i);
-
-                       /*
-                        * Flash cache is big endian for parameter pages, at
-                        * least on STB SoCs
-                        */
-                       if (ctrl->parameter_page_big_endian)
-                               flash_cache[i] = be32_to_cpu(fc);
-                       else
-                               flash_cache[i] = le32_to_cpu(fc);
-               }
+               brcmnand_soc_data_bus_read(ctrl->soc, ctrl->nand_fc, 
flash_cache,
+                                          FC_WORDS);
 
                brcmnand_soc_data_bus_unprepare(ctrl->soc, true);
 
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.h 
b/drivers/mtd/nand/raw/brcmnand/brcmnand.h
index 3a1d60471361..72f18c3a86f7 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.h
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.h
@@ -30,6 +30,24 @@ static inline void brcmnand_soc_data_bus_unprepare(struct 
brcmnand_soc *soc,
                soc->prepare_data_bus(soc, false, is_param);
 }
 
+static inline void brcmnand_soc_data_bus_read(struct brcmnand_soc *soc,
+                                             void __iomem *flash_cache, u32 
*buffer,
+                                             int fc_words)
+{
+       int i;
+
+       if (soc->read_data_bus)
+               soc->read_data_bus(soc, flash_cache, buffer, fc_words);
+       else {
+               /*
+                * Flash cache is big endian for parameter pages, at
+                * least on STB SoCs
+                */
+               for (i = 0; i < fc_words; i++, buffer++)
+                       *buffer = be32_to_cpu(__raw_readl(flash_cache + i * 4));
+       }
+}
+
 static inline u32 brcmnand_readl(void __iomem *addr)
 {
        /*
-- 
2.37.3

Reply via email to