
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/20240223034758.13753-12-william.zhang@broa...
Signed-off-by: david regan dregan@broadcom.com --- 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) { /*