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;
+
+ nor->upage_prev = upage_curr;
cmd = nor->bank_write_cmd;
write_enable(nor);
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:
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