@@ -1882,17 +1882,33 @@ static int cadence_nand_read_buf(struct cdns_nand_ctrl *cdns_ctrl,
return status;
if (!cdns_ctrl->caps1->has_dma) {
- int len_in_words = len >> 2;
+ u8 data_dma_width = cdns_ctrl->caps2.data_dma_width;
+
+ int len_in_words = (data_dma_width == 4) ? len >> 2 : len >> 3;
/* read alingment data */
- ioread32_rep(cdns_ctrl->io.virt, buf, len_in_words);
+ if (data_dma_width == 4)
+ ioread32_rep(cdns_ctrl->io.virt, buf, len_in_words);
+ else
+ ioread64_rep(cdns_ctrl->io.virt, buf, len_in_words);
+
if (sdma_size > len) {
+ int read_bytes = (data_dma_width == 4) ?
+ len_in_words << 2 : len_in_words << 3;
+
/* read rest data from slave DMA interface if any */
- ioread32_rep(cdns_ctrl->io.virt, cdns_ctrl->buf,
- sdma_size / 4 - len_in_words);
+ if (data_dma_width == 4)
+ ioread32_rep(cdns_ctrl->io.virt,
+ cdns_ctrl->buf,
+ sdma_size / 4 - len_in_words);
+ else
+ ioread64_rep(cdns_ctrl->io.virt,
+ cdns_ctrl->buf,
+ sdma_size / 8 - len_in_words);
+
/* copy rest of data */
- memcpy(buf + (len_in_words << 2), cdns_ctrl->buf,
- len - (len_in_words << 2));
+ memcpy(buf + read_bytes, cdns_ctrl->buf,
+ len - read_bytes);
}
return 0;
}
@@ -1936,16 +1952,32 @@ static int cadence_nand_write_buf(struct cdns_nand_ctrl *cdns_ctrl,
return status;
if (!cdns_ctrl->caps1->has_dma) {
- int len_in_words = len >> 2;
+ u8 data_dma_width = cdns_ctrl->caps2.data_dma_width;
+
+ int len_in_words = (data_dma_width == 4) ? len >> 2 : len >> 3;
+
+ if (data_dma_width == 4)
+ iowrite32_rep(cdns_ctrl->io.virt, buf, len_in_words);
+ else
+ iowrite64_rep(cdns_ctrl->io.virt, buf, len_in_words);
- iowrite32_rep(cdns_ctrl->io.virt, buf, len_in_words);
if (sdma_size > len) {
+ int written_bytes = (data_dma_width == 4) ?
+ len_in_words << 2 : len_in_words << 3;
+
/* copy rest of data */
- memcpy(cdns_ctrl->buf, buf + (len_in_words << 2),
- len - (len_in_words << 2));
+ memcpy(cdns_ctrl->buf, buf + written_bytes,
+ len - written_bytes);
+
/* write all expected by nand controller data */
- iowrite32_rep(cdns_ctrl->io.virt, cdns_ctrl->buf,
- sdma_size / 4 - len_in_words);
+ if (data_dma_width == 4)
+ iowrite32_rep(cdns_ctrl->io.virt,
+ cdns_ctrl->buf,
+ sdma_size / 4 - len_in_words);
+ else
+ iowrite64_rep(cdns_ctrl->io.virt,
+ cdns_ctrl->buf,
+ sdma_size / 8 - len_in_words);
}
return 0;
32-bit accesses on 64-bit sdma trigger sdma_err in intr_status register. Check dma capabilities before reading/writing from/to sdma interface. Signed-off-by: Valentin Korenblit <vkorenblit@sequans.com> --- .../mtd/nand/raw/cadence-nand-controller.c | 56 +++++++++++++++---- 1 file changed, 44 insertions(+), 12 deletions(-)