Thread (9 messages) 9 messages, 6 authors, 2024-10-30

Re: [PATCH] spi: atmel-quadspi: Add support for sama7g5 QSPI

From: <hidden>
Date: 2021-12-23 13:54:59
Also in: linux-spi, lkml

On 12/14/21 3:34 PM, Tudor Ambarus wrote:
quoted hunk ↗ jump to hunk
The sama7g5 QSPI controller uses dedicated clocks for the
QSPI Controller Interface and the QSPI Controller Core, and
requires synchronization before accessing registers or bit
fields.

QSPI_SR.SYNCBSY must be zero before accessing any of the bits:
QSPI_CR.QSPIEN, QSPI_CR.QSPIDIS, QSPI_CR.SRFRSH, QSPI_CR.SWRST,
QSPI_CR.UPDCFG, QSPI_CR.STTFR, QSPI_CR.RTOUT, QSPI_CR.LASTXFER.

Also, the QSPI controller core configuration can be updated by
writing the QSPI_CR.UPDCFG bit to ‘1’. This is needed by the
following registers: QSPI_MR, QSPI_SCR, QSPI_IAR, QSPI_WICR,
QSPI_IFR, QSPI_RICR, QSPI_SMR, QSPI_SKR,QSPI_REFRESH, QSPI_WRACNT
QSPI_PCALCFG.

The Octal SPI supports frequencies up to 200 MHZ DDR. The need
for output impedance calibration arises. To avoid the degradation
of the signal quality, a PAD calibration cell is used to adjust
the output impedance to the driven I/Os.

The transmission flow requires different sequences for setting
the configuration and for the actual transfer, than what is in
the sama5d2 and sam9x60 versions of the IP. Different interrupts
are handled. aq->ops->set_cfg() and aq->ops->transfer() are
introduced to help differentiating the flows.

Tested single and octal SPI mode with mx66lm1g45g.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/spi/atmel-quadspi.c | 921 ++++++++++++++++++++++++++++++++++--
 1 file changed, 869 insertions(+), 52 deletions(-)
diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c
index 92d9610df1fd..8980a729dd53 100644
--- a/drivers/spi/atmel-quadspi.c
+++ b/drivers/spi/atmel-quadspi.c
@@ -11,11 +11,15 @@
cut
+static int atmel_qspi_reg_sync(struct atmel_qspi *aq)
+{
+	u32 val;
+	int ret;
+
+	ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
+				 !(val & QSPI_SR2_SYNCBSY), 40,
+				 ATMEL_QSPI_SYNC_TIMEOUT);
+	return ret;
return readl_poll_timeout();
+}
cut
+static int atmel_qspi_dma_xfer(struct atmel_qspi *aq, struct dma_chan *chan,
+			       dma_addr_t dma_dst, dma_addr_t dma_src,
+			       unsigned int len)
+{
+	struct dma_async_tx_descriptor *tx;
+	dma_cookie_t cookie;
+	int ret;
+
+	tx = dmaengine_prep_dma_memcpy(chan, dma_dst, dma_src, len,
+				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!tx) {
+		dev_err(&aq->pdev->dev, "device_prep_dma_memcpy error\n");
+		return -EIO;
+	}
+
+	reinit_completion(&aq->dma_completion);
+	tx->callback = atmel_qspi_dma_callback;
+	tx->callback_param = aq;
+	cookie = tx->tx_submit(tx);
+	ret = dma_submit_error(cookie);
+	if (ret) {
+		dev_err(&aq->pdev->dev, "dma_submit_error %d\n", cookie);
+		return ret;
+	}
+
+	dma_async_issue_pending(chan);
+	ret = wait_for_completion_timeout(&aq->dma_completion,
+					  msecs_to_jiffies(20 * ATMEL_QSPI_TIMEOUT));
20 * ATMEL_QSPI_TIMEOUT, this is a leftover from a debug session.

I'll send a new version to fix these small issues.

Cheers,
ta
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help