u32 *flash_cache = (u32 *)ctrl->flash_cache;
int i;
- brcmnand_soc_data_bus_prepare(ctrl->soc);
+ brcmnand_soc_data_bus_prepare(ctrl->soc, true);
/*
* Must cache the FLASH_CACHE now, since changes in
*/
flash_cache[i] = be32_to_cpu(brcmnand_read_fc(ctrl, i));
- brcmnand_soc_data_bus_unprepare(ctrl->soc);
+ brcmnand_soc_data_bus_unprepare(ctrl->soc, true);
/* Cleanup from HW quirk: restore SECTOR_SIZE_1K */
if (host->hwcfg.sector_size_1k)
brcmnand_waitfunc(mtd, chip);
if (likely(buf)) {
- brcmnand_soc_data_bus_prepare(ctrl->soc);
+ brcmnand_soc_data_bus_prepare(ctrl->soc, false);
for (j = 0; j < FC_WORDS; j++, buf++)
*buf = brcmnand_read_fc(ctrl, j);
- brcmnand_soc_data_bus_unprepare(ctrl->soc);
+ brcmnand_soc_data_bus_unprepare(ctrl->soc, false);
}
if (oob)
(void)brcmnand_read_reg(ctrl, BRCMNAND_CMD_ADDRESS);
if (buf) {
- brcmnand_soc_data_bus_prepare(ctrl->soc);
+ brcmnand_soc_data_bus_prepare(ctrl->soc, false);
for (j = 0; j < FC_WORDS; j++, buf++)
brcmnand_write_fc(ctrl, j, *buf);
- brcmnand_soc_data_bus_unprepare(ctrl->soc);
+ brcmnand_soc_data_bus_unprepare(ctrl->soc, false);
} else if (oob) {
for (j = 0; j < FC_WORDS; j++)
brcmnand_write_fc(ctrl, j, 0xffffffff);
struct brcmnand_soc {
bool (*ctlrdy_ack)(struct brcmnand_soc *soc);
void (*ctlrdy_set_enabled)(struct brcmnand_soc *soc, bool en);
- void (*prepare_data_bus)(struct brcmnand_soc *soc, bool prepare);
+ void (*prepare_data_bus)(struct brcmnand_soc *soc, bool prepare,
+ bool is_param);
};
-static inline void brcmnand_soc_data_bus_prepare(struct brcmnand_soc *soc)
+static inline void brcmnand_soc_data_bus_prepare(struct brcmnand_soc *soc,
+ bool is_param)
{
if (soc && soc->prepare_data_bus)
- soc->prepare_data_bus(soc, true);
+ soc->prepare_data_bus(soc, true, is_param);
}
-static inline void brcmnand_soc_data_bus_unprepare(struct brcmnand_soc *soc)
+static inline void brcmnand_soc_data_bus_unprepare(struct brcmnand_soc *soc,
+ bool is_param)
{
if (soc && soc->prepare_data_bus)
- soc->prepare_data_bus(soc, false);
+ soc->prepare_data_bus(soc, false, is_param);
}
static inline u32 brcmnand_readl(void __iomem *addr)
spin_unlock_irqrestore(&priv->idm_lock, flags);
}
-static void iproc_nand_apb_access(struct brcmnand_soc *soc, bool prepare)
+static void iproc_nand_apb_access(struct brcmnand_soc *soc, bool prepare,
+ bool is_param)
{
struct iproc_nand_soc *priv =
container_of(soc, struct iproc_nand_soc, soc);
val = brcmnand_readl(mmio);
- if (prepare)
- val |= IPROC_NAND_APB_LE_MODE;
- else
+ /*
+ * In the case of BE or when dealing with NAND data, alway configure
+ * the APB bus to LE mode before accessing the FIFO and back to BE mode
+ * after the access is done
+ */
+ if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) || !is_param) {
+ if (prepare)
+ val |= IPROC_NAND_APB_LE_MODE;
+ else
+ val &= ~IPROC_NAND_APB_LE_MODE;
+ } else { /* when in LE accessing the parameter page, keep APB in BE */
val &= ~IPROC_NAND_APB_LE_MODE;
+ }
brcmnand_writel(val, mmio);