mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/4] spi: sophgo: Fix SPI NOR errors and clock limits
@ 2026-09-17 14:29 Han Gao
  2026-09-17 14:29 ` [PATCH 1/4] spi: sg2044-nor: Return transfer errors Han Gao
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Han Gao @ 2026-09-17 14:29 UTC (permalink / raw)
  To: Mark Brown, Longbin Li, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Chen Wang, Inochi Amaoto, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti
  Cc: Han Gao, linux-spi, linux-kernel, devicetree, sophgo,
	linux-riscv, Han Gao, Hangfan Li

The SG204x SPI NOR driver ignores transfer errors and clock limits.
Fix both, enable SPI NOR on SRD3-10, and use 12.5 MHz on SRD3-10 and
SG2042 to match EDK2 and the vendor kernel, respectively.

Tested on SRD3-12 at 12.5 MHz: both flashes identify correctly, SFDP
reads succeed, and two full 64 MiB reads per flash match.

The SRD3-10 patch supersedes the earlier submission [1]. Please disregard
that version, which used a 133 MHz flash clock limit.

[1] https://lore.kernel.org/all/20260902-sg2044-dts-v1-1-aa1fd1a4ec0d@iscas.ac.cn/

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
Han Gao (3):
      spi: sg2044-nor: Return transfer errors
      spi: sg2044-nor: Honor SPI clock limits
      riscv: dts: sophgo: Limit SG2042 SPI NOR to 12.5 MHz

Hangfan Li (1):
      riscv: dts: sophgo: Enable SPI NOR on SRD3-10

 arch/riscv/boot/dts/sophgo/sg2042-evb-v1.dts       |  4 +-
 arch/riscv/boot/dts/sophgo/sg2042-evb-v2.dts       |  2 +-
 .../riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts |  4 +-
 .../boot/dts/sophgo/sg2044-sophgo-srd3-10.dts      | 24 ++++++++++
 drivers/spi/spi-sg2044-nor.c                       | 52 ++++++++++++++++++----
 5 files changed, 73 insertions(+), 13 deletions(-)
---
base-commit: fd73f4a6659897191fa0d40695fe370925dd3780
change-id: 20260917-fix-sg204xspi-dad286928b1c

Best regards,
-- 
Han Gao <gaohan@iscas.ac.cn>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] spi: sg2044-nor: Return transfer errors
  2026-09-17 14:29 [PATCH 0/4] spi: sophgo: Fix SPI NOR errors and clock limits Han Gao
@ 2026-09-17 14:29 ` Han Gao
  2026-09-17 14:29 ` [PATCH 2/4] spi: sg2044-nor: Honor SPI clock limits Han Gao
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Han Gao @ 2026-09-17 14:29 UTC (permalink / raw)
  To: Mark Brown, Longbin Li, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Chen Wang, Inochi Amaoto, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti
  Cc: Han Gao, linux-spi, linux-kernel, devicetree, sophgo,
	linux-riscv, Han Gao

The transfer helpers return errors, but both dispatchers discard them.
Return these errors to the SPI memory layer instead of reporting success.

Fixes: de16c322eefb ("spi: sophgo: add SG2044 SPI NOR controller driver")
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 drivers/spi/spi-sg2044-nor.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-sg2044-nor.c b/drivers/spi/spi-sg2044-nor.c
index f3bcb8a1b92bb1ceee298fa0b720f55f22cf20c3..ff026ca0f76635fee959d7502f457d43dbec0706 100644
--- a/drivers/spi/spi-sg2044-nor.c
+++ b/drivers/spi/spi-sg2044-nor.c
@@ -307,15 +307,15 @@ static ssize_t sg2044_spifmc_tran_cmd(struct sg2044_spifmc *spifmc,
 	return 0;
 }
 
-static void sg2044_spifmc_trans(struct sg2044_spifmc *spifmc,
-				const struct spi_mem_op *op)
+static int sg2044_spifmc_trans(struct sg2044_spifmc *spifmc,
+			       const struct spi_mem_op *op)
 {
 	if (op->data.dir == SPI_MEM_DATA_IN)
-		sg2044_spifmc_read(spifmc, op);
+		return sg2044_spifmc_read(spifmc, op);
 	else if (op->data.dir == SPI_MEM_DATA_OUT)
-		sg2044_spifmc_write(spifmc, op);
+		return sg2044_spifmc_write(spifmc, op);
 	else
-		sg2044_spifmc_tran_cmd(spifmc, op);
+		return sg2044_spifmc_tran_cmd(spifmc, op);
 }
 
 static ssize_t sg2044_spifmc_trans_reg(struct sg2044_spifmc *spifmc,
@@ -389,19 +389,20 @@ static int sg2044_spifmc_exec_op(struct spi_mem *mem,
 				 const struct spi_mem_op *op)
 {
 	struct sg2044_spifmc *spifmc;
+	int ret;
 
 	spifmc = spi_controller_get_devdata(mem->spi->controller);
 
 	mutex_lock(&spifmc->lock);
 
 	if (op->addr.nbytes == 0)
-		sg2044_spifmc_trans_reg(spifmc, op);
+		ret = sg2044_spifmc_trans_reg(spifmc, op);
 	else
-		sg2044_spifmc_trans(spifmc, op);
+		ret = sg2044_spifmc_trans(spifmc, op);
 
 	mutex_unlock(&spifmc->lock);
 
-	return 0;
+	return ret;
 }
 
 static const struct spi_controller_mem_ops sg2044_spifmc_mem_ops = {

-- 
2.47.3


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/4] spi: sg2044-nor: Honor SPI clock limits
  2026-09-17 14:29 [PATCH 0/4] spi: sophgo: Fix SPI NOR errors and clock limits Han Gao
  2026-09-17 14:29 ` [PATCH 1/4] spi: sg2044-nor: Return transfer errors Han Gao
@ 2026-09-17 14:29 ` Han Gao
  2026-09-17 20:38   ` Mark Brown
  2026-09-17 14:29 ` [PATCH 3/4] riscv: dts: sophgo: Enable SPI NOR on SRD3-10 Han Gao
  2026-09-17 14:29 ` [PATCH 4/4] riscv: dts: sophgo: Limit SG2042 SPI NOR to 12.5 MHz Han Gao
  3 siblings, 1 reply; 6+ messages in thread
From: Han Gao @ 2026-09-17 14:29 UTC (permalink / raw)
  To: Mark Brown, Longbin Li, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Chen Wang, Inochi Amaoto, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti
  Cc: Han Gao, linux-spi, linux-kernel, devicetree, sophgo,
	linux-riscv, Han Gao

The fixed divider ignores device and operation clock limits. Calculate
the divider before each transfer so SCK does not exceed either limit.

Fixes: de16c322eefb ("spi: sophgo: add SG2044 SPI NOR controller driver")
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 drivers/spi/spi-sg2044-nor.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/drivers/spi/spi-sg2044-nor.c b/drivers/spi/spi-sg2044-nor.c
index ff026ca0f76635fee959d7502f457d43dbec0706..f2a1074f68477cc6611fae09c5db7aaa405edf39 100644
--- a/drivers/spi/spi-sg2044-nor.c
+++ b/drivers/spi/spi-sg2044-nor.c
@@ -385,6 +385,29 @@ static ssize_t sg2044_spifmc_trans_reg(struct sg2044_spifmc *spifmc,
 	return 0;
 }
 
+static int sg2044_spifmc_set_speed(struct sg2044_spifmc *spifmc,
+				   unsigned int speed_hz)
+{
+	unsigned long rate = clk_get_rate(spifmc->clk);
+	u64 div;
+	u32 reg;
+
+	if (!rate || !speed_hz)
+		return -EINVAL;
+
+	/* SCK = HCLK / (2 * (SckDiv + 1)); round down the resulting SCK. */
+	div = DIV_ROUND_UP_ULL(rate, 2ULL * speed_hz);
+	if (div > SPIFMC_CTRL_SCK_DIV_MASK + 1)
+		return -EINVAL;
+
+	reg = readl(spifmc->io_base + SPIFMC_CTRL);
+	reg &= ~SPIFMC_CTRL_SCK_DIV_MASK;
+	reg |= div - 1;
+	writel(reg, spifmc->io_base + SPIFMC_CTRL);
+
+	return 0;
+}
+
 static int sg2044_spifmc_exec_op(struct spi_mem *mem,
 				 const struct spi_mem_op *op)
 {
@@ -395,11 +418,18 @@ static int sg2044_spifmc_exec_op(struct spi_mem *mem,
 
 	mutex_lock(&spifmc->lock);
 
+	ret = sg2044_spifmc_set_speed(spifmc, op->max_freq ?
+				    min(op->max_freq, mem->spi->max_speed_hz) :
+				    mem->spi->max_speed_hz);
+	if (ret)
+		goto out_unlock;
+
 	if (op->addr.nbytes == 0)
 		ret = sg2044_spifmc_trans_reg(spifmc, op);
 	else
 		ret = sg2044_spifmc_trans(spifmc, op);
 
+out_unlock:
 	mutex_unlock(&spifmc->lock);
 
 	return ret;
@@ -409,6 +439,10 @@ static const struct spi_controller_mem_ops sg2044_spifmc_mem_ops = {
 	.exec_op = sg2044_spifmc_exec_op,
 };
 
+static const struct spi_controller_mem_caps sg2044_spifmc_mem_caps = {
+	.per_op_freq = true,
+};
+
 static void sg2044_spifmc_init(struct sg2044_spifmc *spifmc)
 {
 	u32 tran_csr;
@@ -459,6 +493,7 @@ static int sg2044_spifmc_probe(struct platform_device *pdev)
 	ctrl->bits_per_word_mask = SPI_BPW_MASK(8);
 	ctrl->auto_runtime_pm = false;
 	ctrl->mem_ops = &sg2044_spifmc_mem_ops;
+	ctrl->mem_caps = &sg2044_spifmc_mem_caps;
 	ctrl->mode_bits = SPI_RX_DUAL | SPI_TX_DUAL | SPI_RX_QUAD | SPI_TX_QUAD;
 
 	ret = devm_mutex_init(dev, &spifmc->lock);

-- 
2.47.3


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 3/4] riscv: dts: sophgo: Enable SPI NOR on SRD3-10
  2026-09-17 14:29 [PATCH 0/4] spi: sophgo: Fix SPI NOR errors and clock limits Han Gao
  2026-09-17 14:29 ` [PATCH 1/4] spi: sg2044-nor: Return transfer errors Han Gao
  2026-09-17 14:29 ` [PATCH 2/4] spi: sg2044-nor: Honor SPI clock limits Han Gao
@ 2026-09-17 14:29 ` Han Gao
  2026-09-17 14:29 ` [PATCH 4/4] riscv: dts: sophgo: Limit SG2042 SPI NOR to 12.5 MHz Han Gao
  3 siblings, 0 replies; 6+ messages in thread
From: Han Gao @ 2026-09-17 14:29 UTC (permalink / raw)
  To: Mark Brown, Longbin Li, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Chen Wang, Inochi Amaoto, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti
  Cc: Han Gao, linux-spi, linux-kernel, devicetree, sophgo,
	linux-riscv, Han Gao, Hangfan Li

From: Hangfan Li <lihangfan@iscas.ac.cn>

Enable both SPI NOR controllers at 12.5 MHz, matching EDK2.

Signed-off-by: Hangfan Li <lihangfan@iscas.ac.cn>
Co-developed-by: Han Gao <gaohan@iscas.ac.cn>
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 .../boot/dts/sophgo/sg2044-sophgo-srd3-10.dts      | 24 ++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/riscv/boot/dts/sophgo/sg2044-sophgo-srd3-10.dts b/arch/riscv/boot/dts/sophgo/sg2044-sophgo-srd3-10.dts
index fed3d9a384a00ccfc91dfa1531f799aa397a5dde..88ddc8e793f62b4119b2df92ba6357c8e6e75c46 100644
--- a/arch/riscv/boot/dts/sophgo/sg2044-sophgo-srd3-10.dts
+++ b/arch/riscv/boot/dts/sophgo/sg2044-sophgo-srd3-10.dts
@@ -109,6 +109,30 @@ &sd {
 	status = "okay";
 };
 
+&spifmc0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <12500000>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <1>;
+	};
+};
+
+&spifmc1 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <12500000>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <1>;
+	};
+};
+
 &uart0 {
 	/* for firmware */
 	status = "reserved";

-- 
2.47.3


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 4/4] riscv: dts: sophgo: Limit SG2042 SPI NOR to 12.5 MHz
  2026-09-17 14:29 [PATCH 0/4] spi: sophgo: Fix SPI NOR errors and clock limits Han Gao
                   ` (2 preceding siblings ...)
  2026-09-17 14:29 ` [PATCH 3/4] riscv: dts: sophgo: Enable SPI NOR on SRD3-10 Han Gao
@ 2026-09-17 14:29 ` Han Gao
  3 siblings, 0 replies; 6+ messages in thread
From: Han Gao @ 2026-09-17 14:29 UTC (permalink / raw)
  To: Mark Brown, Longbin Li, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Chen Wang, Inochi Amaoto, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti
  Cc: Han Gao, linux-spi, linux-kernel, devicetree, sophgo,
	linux-riscv, Han Gao

Use 12.5 MHz on the SG2042 EVBs and Milk-V Pioneer to match the vendor
kernel. The existing 50 MHz limit raises SCK once the driver starts
honoring spi-max-frequency.

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 arch/riscv/boot/dts/sophgo/sg2042-evb-v1.dts        | 4 ++--
 arch/riscv/boot/dts/sophgo/sg2042-evb-v2.dts        | 2 +-
 arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/riscv/boot/dts/sophgo/sg2042-evb-v1.dts b/arch/riscv/boot/dts/sophgo/sg2042-evb-v1.dts
index b116dfa904cd982dc41c8cffdc770d4d0f81e0a7..9f403e564694eae14913f6ab23080a6333df15ae 100644
--- a/arch/riscv/boot/dts/sophgo/sg2042-evb-v1.dts
+++ b/arch/riscv/boot/dts/sophgo/sg2042-evb-v1.dts
@@ -256,7 +256,7 @@ &spifmc0 {
 	flash@0 {
 		compatible = "jedec,spi-nor";
 		reg = <0>;
-		spi-max-frequency = <50000000>;
+		spi-max-frequency = <12500000>;
 		spi-tx-bus-width = <1>;
 		spi-rx-bus-width = <1>;
 	};
@@ -268,7 +268,7 @@ &spifmc1 {
 	flash@0 {
 		compatible = "jedec,spi-nor";
 		reg = <0>;
-		spi-max-frequency = <50000000>;
+		spi-max-frequency = <12500000>;
 		spi-tx-bus-width = <1>;
 		spi-rx-bus-width = <1>;
 	};
diff --git a/arch/riscv/boot/dts/sophgo/sg2042-evb-v2.dts b/arch/riscv/boot/dts/sophgo/sg2042-evb-v2.dts
index b2ceae2d8829ec16c99c2ea2b040c433b819093e..d8c5814f22581076e6b5114f762d4fd090681b80 100644
--- a/arch/riscv/boot/dts/sophgo/sg2042-evb-v2.dts
+++ b/arch/riscv/boot/dts/sophgo/sg2042-evb-v2.dts
@@ -244,7 +244,7 @@ &spifmc1 {
 	flash@0 {
 		compatible = "jedec,spi-nor";
 		reg = <0>;
-		spi-max-frequency = <50000000>;
+		spi-max-frequency = <12500000>;
 		spi-tx-bus-width = <1>;
 		spi-rx-bus-width = <1>;
 	};
diff --git a/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts
index ecf8c1e290792c3a27651040eae3c603741cd0c7..4f39eb56b364894f17b97d482b6d9d867a32ad2e 100644
--- a/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts
+++ b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts
@@ -177,7 +177,7 @@ &spifmc0 {
 	flash@0 {
 		compatible = "jedec,spi-nor";
 		reg = <0>;
-		spi-max-frequency = <50000000>;
+		spi-max-frequency = <12500000>;
 		spi-tx-bus-width = <1>;
 		spi-rx-bus-width = <1>;
 	};
@@ -189,7 +189,7 @@ &spifmc1 {
 	flash@0 {
 		compatible = "jedec,spi-nor";
 		reg = <0>;
-		spi-max-frequency = <50000000>;
+		spi-max-frequency = <12500000>;
 		spi-tx-bus-width = <1>;
 		spi-rx-bus-width = <1>;
 	};

-- 
2.47.3


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/4] spi: sg2044-nor: Honor SPI clock limits
  2026-09-17 14:29 ` [PATCH 2/4] spi: sg2044-nor: Honor SPI clock limits Han Gao
@ 2026-09-17 20:38   ` Mark Brown
  0 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2026-09-17 20:38 UTC (permalink / raw)
  To: Han Gao
  Cc: Longbin Li, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Chen Wang, Inochi Amaoto, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Alexandre Ghiti, Han Gao, linux-spi, linux-kernel,
	devicetree, sophgo, linux-riscv

[-- Attachment #1: Type: text/plain, Size: 617 bytes --]

On Thu, Sep 17, 2026 at 10:29:20PM +0800, Han Gao wrote:
> The fixed divider ignores device and operation clock limits. Calculate
> the divider before each transfer so SCK does not exceed either limit.

> +static int sg2044_spifmc_set_speed(struct sg2044_spifmc *spifmc,
> +				   unsigned int speed_hz)
> +{
> +	unsigned long rate = clk_get_rate(spifmc->clk);
> +	u64 div;
> +	u32 reg;
> +
> +	if (!rate || !speed_hz)
> +		return -EINVAL;

Specifying a maximum speed is optional so we might have a currently
working setup with one omitted.  The driver should just go with the
maximum speed it supports in that case.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-09-17 20:38 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-17 14:29 [PATCH 0/4] spi: sophgo: Fix SPI NOR errors and clock limits Han Gao
2026-09-17 14:29 ` [PATCH 1/4] spi: sg2044-nor: Return transfer errors Han Gao
2026-09-17 14:29 ` [PATCH 2/4] spi: sg2044-nor: Honor SPI clock limits Han Gao
2026-09-17 20:38   ` Mark Brown
2026-09-17 14:29 ` [PATCH 3/4] riscv: dts: sophgo: Enable SPI NOR on SRD3-10 Han Gao
2026-09-17 14:29 ` [PATCH 4/4] riscv: dts: sophgo: Limit SG2042 SPI NOR to 12.5 MHz Han Gao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®