* [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®