From 546e425991205f59281e160a0d0daed47b7ca9b3 Mon Sep 17 00:00:00 2001 From: William Zhang Date: Thu, 22 Feb 2024 19:47:56 -0800 Subject: mtd: rawnand: brcmnand: Add BCMBCA read data bus interface 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. Signed-off-by: William Zhang Reviewed-by: David Regan Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20240223034758.13753-12-william.zhang@broadcom.com --- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'drivers/mtd/nand/raw/brcmnand/brcmnand.c') diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index f1f0de50b5f7..ef7d340475be 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -851,6 +851,20 @@ static inline u32 edu_readl(struct brcmnand_controller *ctrl, return brcmnand_readl(ctrl->edu_base + offs); } +static inline void brcmnand_read_data_bus(struct brcmnand_controller *ctrl, + void __iomem *flash_cache, u32 *buffer, int fc_words) +{ + struct brcmnand_soc *soc = ctrl->soc; + int i; + + if (soc->read_data_bus) { + soc->read_data_bus(soc, flash_cache, buffer, fc_words); + } else { + for (i = 0; i < fc_words; i++) + buffer[i] = brcmnand_read_fc(ctrl, i); + } +} + static void brcmnand_clear_ecc_addr(struct brcmnand_controller *ctrl) { @@ -1975,7 +1989,7 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip, { struct brcmnand_host *host = nand_get_controller_data(chip); struct brcmnand_controller *ctrl = host->ctrl; - int i, j, ret = 0; + int i, ret = 0; brcmnand_clear_ecc_addr(ctrl); @@ -1988,8 +2002,8 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip, if (likely(buf)) { brcmnand_soc_data_bus_prepare(ctrl->soc, false); - for (j = 0; j < FC_WORDS; j++, buf++) - *buf = brcmnand_read_fc(ctrl, j); + brcmnand_read_data_bus(ctrl, ctrl->nand_fc, buf, FC_WORDS); + buf += FC_WORDS; brcmnand_soc_data_bus_unprepare(ctrl->soc, false); } -- cgit