mtd: rawnand: cadence: support 64-bit slave dma interface
Subsystems (3)
PATCH v3 1/1 mtd: rawnand: cadence: support 64-bit slave dma interface
32-bit accesses on 64-bit sdma trigger sdma_err in intr_status register.
Check dma capabilities before reading/writing from/to sdma interface.
Link to discussion:
https://lists.01.org/hyperkitty/list/[email protected]/thread/3NMACGIM5NDUBPXRT5RTBZON6LQE5A3B/
---
Changes v1 -> v2:
- Replaced ioread64_rep by cadence_nand_readsq (suggested by Arnd)
- Replaced iowrite64_rep by cadence_nand_writesq (suggested by Arnd)
- Do not try to access 64-bit sdma if __raw_readq/__raw_writeq are not defined
Changes v2 -> v3:
- Use readsq/writesq on 64-bit architectures (Arnd)
- Detect issue on init instead of 1st transfer
--- .../mtd/nand/raw/cadence-nand-controller.c | 70 +++++++++++++++---- 1 file changed, 58 insertions(+), 12 deletions(-)
drivers/mtd/nand/raw/cadence-nand-controller.c +58 -12
@@ -1184,6 +1184,14 @@ static int cadence_nand_hw_init(struct cdns_nand_ctrl *cdns_ctrl)if (cadence_nand_read_bch_caps (cdns_ctrl))return -EIO ; +#ifndef CONFIG_64BIT +if (cdns_ctrl->caps2.data_dma_width ==8 ) { +dev_err (cdns_ctrl->dev, +"cannot access 64-bit dma on !64-bit architectures" ); +return -EIO ; + } +#endif +/* * Set IO width access to 8. * It is because during SW device discovering width access
@@ -1882,17 +1890,36 @@ 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); +#ifdef CONFIG_64BIT + else + readsq(cdns_ctrl->io.virt, buf, len_in_words); +#endif +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); +#ifdef CONFIG_64BIT + else + readsq(cdns_ctrl->io.virt, cdns_ctrl->buf, + sdma_size / 8 - len_in_words); +#endif +/* 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 +1963,35 @@ 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); +#ifdef CONFIG_64BIT + else + writesq(cdns_ctrl->io.virt, buf, len_in_words); +#endif -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); +#ifdef CONFIG_64BIT + else + writesq(cdns_ctrl->io.virt, cdns_ctrl->buf, + sdma_size / 8 - len_in_words); +#endif }return 0 ;
Signature · 16 lines
2.20.1 -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you. ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
Quoted 6 lines · Valentin Korenblit
32-bit accesses on 64-bit sdma trigger
sdma_errinintr_statusregister.Check dma capabilities before reading/writing from/to sdma interface.
Link to discussion:
https://lists.01.org/hyperkitty/list/[email protected]/thread/3NMACGIM5NDUBPXRT5RTBZON6LQE5A3B/
Maybe make this
Quoted 1 line
Signed-off-by Valentin Korenblit <[email protected]>
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
Miquel Raynal
maintainerHello,
[email protected] wrote on Tue, 18 Oct 2022 11:10:44 +0200:
Quoted 11 lines · Valentin Korenblit
Quoted 6 lines
32-bit accesses on 64-bit sdma trigger
sdma_errinintr_statusregister.Check dma capabilities before reading/writing from/to sdma interface.
Link to discussion:
https://lists.01.org/hyperkitty/list/[email protected]/thread/3NMACGIM5NDUBPXRT5RTBZON6LQE5A3B/Maybe make this
I'll fix it while applying.
Quoted 3 lines
Quoted 1 line
Signed-off-by Valentin Korenblit <[email protected]>Reviewed-by Arnd Bergmann <[email protected]>
Thanks a lot for the help Arnd!
Cheers,
Miquèl
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/