mirror of
https://git.openwrt.org/openwrt/openwrt.git
synced 2025-12-10 06:24:40 +01:00
Add a new microchipsw target aimed add supporting Microchip switch SoC-s. Start by supporting LAN969x SoC-s as the first subtarget. Signed-off-by: Robert Marko <robert.marko@sartura.hr>
181 lines
5.1 KiB
Diff
181 lines
5.1 KiB
Diff
From 36087601ba5fed2fe42134bf59f6ba75029fd7f7 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Bence=20Cs=C3=B3k=C3=A1s?= <csokas.bence@prolan.hu>
|
|
Date: Wed, 18 Dec 2024 16:17:54 +0100
|
|
Subject: [PATCH 099/112] spi: atmel-quadspi: Factor out switching to Serial
|
|
Memory Mode to function
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
SAMA7G5 support (that was forward-ported from v6.1) re-introduced
|
|
a bug that was fixed in v6.12, thankfully only in the codepath of
|
|
the new SoC. But to prevent similar mistakes in the future, we
|
|
split out the offending code to a function, and use this, fixed
|
|
version everywhere.
|
|
|
|
To facilitate this, support function `atmel_qspi_update_config()`
|
|
also had to be moved upwards. For best viewing experience, use
|
|
`--color-moved-ws="allow-indentation-change" --color-moved`.
|
|
|
|
Fixes: 5af42209a4d2 ("spi: atmel-quadspi: Add support for sama7g5 QSPI")
|
|
Reported-by: Alexander Dahl <ada@thorsis.com>
|
|
Closes: https://lore.kernel.org/linux-spi/20241218-appliance-jaws-90773405977a@thorsis.com/
|
|
Signed-off-by: Bence Csókás <csokas.bence@prolan.hu>
|
|
Link: https://patch.msgid.link/20241218151754.365519-1-csokas.bence@prolan.hu
|
|
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
---
|
|
drivers/spi/atmel-quadspi.c | 101 +++++++++++++++++++-----------------
|
|
1 file changed, 53 insertions(+), 48 deletions(-)
|
|
|
|
--- a/drivers/spi/atmel-quadspi.c
|
|
+++ b/drivers/spi/atmel-quadspi.c
|
|
@@ -414,6 +414,28 @@ static void atmel_qspi_write(u32 value,
|
|
writel_relaxed(value, aq->regs + offset);
|
|
}
|
|
|
|
+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;
|
|
+}
|
|
+
|
|
+static int atmel_qspi_update_config(struct atmel_qspi *aq)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ ret = atmel_qspi_reg_sync(aq);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ atmel_qspi_write(QSPI_CR_UPDCFG, aq, QSPI_CR);
|
|
+ return atmel_qspi_reg_sync(aq);
|
|
+}
|
|
+
|
|
static inline bool atmel_qspi_is_compatible(const struct spi_mem_op *op,
|
|
const struct atmel_qspi_mode *mode)
|
|
{
|
|
@@ -476,6 +498,25 @@ static bool atmel_qspi_supports_op(struc
|
|
return true;
|
|
}
|
|
|
|
+/*
|
|
+ * If the QSPI controller is set in regular SPI mode, set it in
|
|
+ * Serial Memory Mode (SMM).
|
|
+ */
|
|
+static int atmel_qspi_set_serial_memory_mode(struct atmel_qspi *aq)
|
|
+{
|
|
+ int ret = 0;
|
|
+
|
|
+ if (!(aq->mr & QSPI_MR_SMM)) {
|
|
+ aq->mr |= QSPI_MR_SMM;
|
|
+ atmel_qspi_write(aq->mr, aq, QSPI_MR);
|
|
+
|
|
+ if (aq->caps->has_gclk)
|
|
+ ret = atmel_qspi_update_config(aq);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static int atmel_qspi_set_cfg(struct atmel_qspi *aq,
|
|
const struct spi_mem_op *op, u32 *offset)
|
|
{
|
|
@@ -555,14 +596,9 @@ static int atmel_qspi_set_cfg(struct atm
|
|
ifr |= QSPI_IFR_TFRTYP_MEM;
|
|
}
|
|
|
|
- /*
|
|
- * If the QSPI controller is set in regular SPI mode, set it in
|
|
- * Serial Memory Mode (SMM).
|
|
- */
|
|
- if (!(aq->mr & QSPI_MR_SMM)) {
|
|
- aq->mr |= QSPI_MR_SMM;
|
|
- atmel_qspi_write(aq->mr, aq, QSPI_MR);
|
|
- }
|
|
+ mode = atmel_qspi_set_serial_memory_mode(aq);
|
|
+ if (mode < 0)
|
|
+ return mode;
|
|
|
|
/* Clear pending interrupts */
|
|
(void)atmel_qspi_read(aq, QSPI_SR);
|
|
@@ -645,28 +681,6 @@ static int atmel_qspi_transfer(struct sp
|
|
return atmel_qspi_wait_for_completion(aq, QSPI_SR_CMD_COMPLETED);
|
|
}
|
|
|
|
-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;
|
|
-}
|
|
-
|
|
-static int atmel_qspi_update_config(struct atmel_qspi *aq)
|
|
-{
|
|
- int ret;
|
|
-
|
|
- ret = atmel_qspi_reg_sync(aq);
|
|
- if (ret)
|
|
- return ret;
|
|
- atmel_qspi_write(QSPI_CR_UPDCFG, aq, QSPI_CR);
|
|
- return atmel_qspi_reg_sync(aq);
|
|
-}
|
|
-
|
|
static int atmel_qspi_sama7g5_set_cfg(struct atmel_qspi *aq,
|
|
const struct spi_mem_op *op, u32 *offset)
|
|
{
|
|
@@ -720,18 +734,9 @@ static int atmel_qspi_sama7g5_set_cfg(st
|
|
ifr |= QSPI_IFR_TFRTYP_MEM;
|
|
}
|
|
|
|
- /*
|
|
- * If the QSPI controller is set in regular SPI mode, set it in
|
|
- * Serial Memory Mode (SMM).
|
|
- */
|
|
- if (aq->mr != QSPI_MR_SMM) {
|
|
- atmel_qspi_write(QSPI_MR_SMM | QSPI_MR_DQSDLYEN, aq, QSPI_MR);
|
|
- aq->mr = QSPI_MR_SMM;
|
|
-
|
|
- ret = atmel_qspi_update_config(aq);
|
|
- if (ret)
|
|
- return ret;
|
|
- }
|
|
+ ret = atmel_qspi_set_serial_memory_mode(aq);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
|
|
/* Clear pending interrupts */
|
|
(void)atmel_qspi_read(aq, QSPI_SR);
|
|
@@ -1099,10 +1104,9 @@ static int atmel_qspi_sama7g5_init(struc
|
|
}
|
|
|
|
/* Set the QSPI controller by default in Serial Memory Mode */
|
|
- atmel_qspi_write(QSPI_MR_SMM | QSPI_MR_DQSDLYEN, aq, QSPI_MR);
|
|
- aq->mr = QSPI_MR_SMM;
|
|
- ret = atmel_qspi_update_config(aq);
|
|
- if (ret)
|
|
+ aq->mr |= QSPI_MR_DQSDLYEN;
|
|
+ ret = atmel_qspi_set_serial_memory_mode(aq);
|
|
+ if (ret < 0)
|
|
return ret;
|
|
|
|
/* Enable the QSPI controller. */
|
|
@@ -1223,8 +1227,9 @@ static int atmel_qspi_init(struct atmel_
|
|
atmel_qspi_write(QSPI_CR_SWRST, aq, QSPI_CR);
|
|
|
|
/* Set the QSPI controller by default in Serial Memory Mode */
|
|
- aq->mr |= QSPI_MR_SMM;
|
|
- atmel_qspi_write(aq->mr, aq, QSPI_MR);
|
|
+ ret = atmel_qspi_set_serial_memory_mode(aq);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
|
|
/* Enable the QSPI controller */
|
|
atmel_qspi_write(QSPI_CR_QSPIEN, aq, QSPI_CR);
|