From b1597c9ad4aec5f9609b4d9a311ea5769407664f Mon Sep 17 00:00:00 2001 From: Markus Stockhausen Date: Fri, 13 Jun 2025 02:42:39 -0400 Subject: [PATCH 01/10] realtek: convert RTL838x toolchain to 24kc The Realtek RTL838x devices have a MIPS 4Kec core. This has a very simple pipeline. OpenWrt uses CPU_TYPE:=4kec to honour this and adds a dedicated toolchain with some GB of extra space. There would be no problem if that toolchain would do what it is expected to do. Looking at the build process one can see: during kernel builds: ps -ef | grep mtune ... -march=mips32r2 -mtune=34kc ... during package builds ps -ef | grep mtune ... -mips32r2 -mtune=4kec ... So the kernel is optimized for the wrong cpu type while the applications fit fine. Explanation for this is the generic/308-mips32r2_tune.patch. This forces kernel builds to -mtune=34kc. Nevertheless everything runs fine since years on the RTL838x targets. It does not make sense to provide a dedicated 4kec toolchain for this mess. So change the setup as follows: - switch CPU type to mips24kc for RTL838x -> This drops one toolchain and saves space - Add a RTl838x specific mtune=4kec patch -> Builds kernel with the proper setting Downside is packages will be built with -mtune=24kc. So a look at a simple benchmark should give insight if this has really a big impact. See numbers attached. To sum it up in two sentences - All non RSA benchmarks are within expectation - RSA benchmarks show large deviations (before and after) The normal usecase for these switches is definetly not a CPU intensive workload so this is ok for now. Before: kernel 6.12 (mtune=34kc) + apps (mtune=4kec) root@OpenWrt:/usr/bin# ./wolfssl-benchmark ------------------------------------------------------------------------------ wolfSSL version 5.7.6 ------------------------------------------------------------------------------ wolfCrypt Benchmark (block bytes 1048576, min 1.0 sec each) RNG 5 MiB took 1.426 seconds, 3.507 MiB/s AES-128-CBC-enc 5 MiB took 1.178 seconds, 4.243 MiB/s AES-128-CBC-dec 5 MiB took 1.171 seconds, 4.270 MiB/s AES-192-CBC-enc 5 MiB took 1.307 seconds, 3.824 MiB/s AES-192-CBC-dec 5 MiB took 1.311 seconds, 3.815 MiB/s AES-256-CBC-enc 5 MiB took 1.447 seconds, 3.455 MiB/s AES-256-CBC-dec 5 MiB took 1.421 seconds, 3.519 MiB/s AES-128-GCM-enc 5 MiB took 3.772 seconds, 1.325 MiB/s AES-128-GCM-dec 5 MiB took 3.756 seconds, 1.331 MiB/s AES-192-GCM-enc 5 MiB took 3.939 seconds, 1.269 MiB/s AES-192-GCM-dec 5 MiB took 3.932 seconds, 1.272 MiB/s AES-256-GCM-enc 5 MiB took 4.043 seconds, 1.237 MiB/s AES-256-GCM-dec 5 MiB took 4.033 seconds, 1.240 MiB/s GMAC Default 2 MiB took 1.056 seconds, 1.895 MiB/s AES-128-CTR 5 MiB took 1.195 seconds, 4.185 MiB/s AES-192-CTR 5 MiB took 1.319 seconds, 3.791 MiB/s AES-256-CTR 5 MiB took 1.460 seconds, 3.425 MiB/s AES-CCM-enc 5 MiB took 2.279 seconds, 2.194 MiB/s AES-CCM-dec 5 MiB took 2.273 seconds, 2.200 MiB/s ARC4 20 MiB took 1.226 seconds, 16.315 MiB/s CHACHA 15 MiB took 1.001 seconds, 14.982 MiB/s CHA-POLY 15 MiB took 1.440 seconds, 10.416 MiB/s 3DES 5 MiB took 4.364 seconds, 1.146 MiB/s MD5 25 MiB took 1.034 seconds, 24.173 MiB/s POLY1305 35 MiB took 1.015 seconds, 34.467 MiB/s SHA 25 MiB took 1.127 seconds, 22.183 MiB/s SHA-256 10 MiB took 1.104 seconds, 9.056 MiB/s SHA-384 5 MiB took 1.324 seconds, 3.775 MiB/s SHA-512 5 MiB took 1.325 seconds, 3.774 MiB/s SHA-512/224 5 MiB took 1.319 seconds, 3.791 MiB/s SHA-512/256 5 MiB took 1.333 seconds, 3.751 MiB/s AES-128-CMAC 5 MiB took 1.145 seconds, 4.366 MiB/s AES-256-CMAC 5 MiB took 1.413 seconds, 3.539 MiB/s HMAC-MD5 25 MiB took 1.034 seconds, 24.186 MiB/s HMAC-SHA 25 MiB took 1.122 seconds, 22.272 MiB/s HMAC-SHA256 10 MiB took 1.104 seconds, 9.059 MiB/s HMAC-SHA384 5 MiB took 1.329 seconds, 3.762 MiB/s HMAC-SHA512 5 MiB took 1.323 seconds, 3.778 MiB/s PBKDF2 1 KiB took 1.018 seconds, 1.136 KiB/s RSA 2048 key gen 1 ops took 15.547 sec, avg 15547.322 ms, 0.064 ops/sec RSA 3072 key gen 1 ops took 66.131 sec, avg 66131.134 ms, 0.015 ops/sec RSA 4096 key gen 1 ops took 563.611 sec, avg 563611.230 ms, 0.002 ops/sec RSA 2048 public 200 ops took 1.403 sec, avg 7.015 ms, 142.542 ops/sec RSA 2048 private 100 ops took 39.099 sec, avg 390.991 ms, 2.558 ops/sec DH 2048 key gen 14 ops took 1.009 sec, avg 72.094 ms, 13.871 ops/sec DH 2048 agree 100 ops took 15.714 sec, avg 157.139 ms, 6.364 ops/sec ECC [ SECP256R1] 256 key gen 100 ops took 5.590 sec, avg 55.901 ms, 17.889 ops/sec ECDHE [ SECP256R1] 256 agree 100 ops took 5.555 sec, avg 55.554 ms, 18.001 ops/sec ECDSA [ SECP256R1] 256 sign 100 ops took 5.705 sec, avg 57.048 ms, 17.529 ops/sec ECDSA [ SECP256R1] 256 verify 100 ops took 4.396 sec, avg 43.963 ms, 22.746 ops/sec CURVE 25519 key gen 320 ops took 1.000 sec, avg 3.127 ms, 319.841 ops/sec CURVE 25519 agree 400 ops took 1.214 sec, avg 3.034 ms, 329.546 ops/sec Benchmark complete After: kernel 6.12 (mtune=4kec) + apps (mtune=24kc) root@OpenWrt:~# wolfssl-benchmark ------------------------------------------------------------------------------ wolfSSL version 5.7.6 ------------------------------------------------------------------------------ wolfCrypt Benchmark (block bytes 1048576, min 1.0 sec each) RNG 5 MiB took 1.428 seconds, 3.501 MiB/s AES-128-CBC-enc 5 MiB took 1.174 seconds, 4.258 MiB/s AES-128-CBC-dec 5 MiB took 1.162 seconds, 4.301 MiB/s AES-192-CBC-enc 5 MiB took 1.307 seconds, 3.826 MiB/s AES-192-CBC-dec 5 MiB took 1.313 seconds, 3.809 MiB/s AES-256-CBC-enc 5 MiB took 1.432 seconds, 3.491 MiB/s AES-256-CBC-dec 5 MiB took 1.426 seconds, 3.506 MiB/s AES-128-GCM-enc 5 MiB took 3.761 seconds, 1.329 MiB/s AES-128-GCM-dec 5 MiB took 3.748 seconds, 1.334 MiB/s AES-192-GCM-enc 5 MiB took 3.918 seconds, 1.276 MiB/s AES-192-GCM-dec 5 MiB took 3.922 seconds, 1.275 MiB/s AES-256-GCM-enc 5 MiB took 4.019 seconds, 1.244 MiB/s AES-256-GCM-dec 5 MiB took 4.014 seconds, 1.246 MiB/s GMAC Default 2 MiB took 1.052 seconds, 1.900 MiB/s AES-128-CTR 5 MiB took 1.189 seconds, 4.205 MiB/s AES-192-CTR 5 MiB took 1.315 seconds, 3.804 MiB/s AES-256-CTR 5 MiB took 1.455 seconds, 3.436 MiB/s AES-CCM-enc 5 MiB took 2.257 seconds, 2.215 MiB/s AES-CCM-dec 5 MiB took 2.269 seconds, 2.204 MiB/s ARC4 15 MiB took 1.062 seconds, 14.124 MiB/s CHACHA 15 MiB took 1.008 seconds, 14.880 MiB/s CHA-POLY 15 MiB took 1.461 seconds, 10.266 MiB/s 3DES 5 MiB took 4.347 seconds, 1.150 MiB/s MD5 25 MiB took 1.029 seconds, 24.291 MiB/s POLY1305 35 MiB took 1.024 seconds, 34.181 MiB/s SHA 25 MiB took 1.115 seconds, 22.418 MiB/s SHA-256 10 MiB took 1.154 seconds, 8.664 MiB/s SHA-384 5 MiB took 1.345 seconds, 3.718 MiB/s SHA-512 5 MiB took 1.343 seconds, 3.723 MiB/s SHA-512/224 5 MiB took 1.350 seconds, 3.703 MiB/s SHA-512/256 5 MiB took 1.345 seconds, 3.718 MiB/s AES-128-CMAC 5 MiB took 1.143 seconds, 4.376 MiB/s AES-256-CMAC 5 MiB took 1.405 seconds, 3.559 MiB/s HMAC-MD5 25 MiB took 1.027 seconds, 24.334 MiB/s HMAC-SHA 25 MiB took 1.112 seconds, 22.490 MiB/s HMAC-SHA256 10 MiB took 1.096 seconds, 9.125 MiB/s HMAC-SHA384 5 MiB took 1.344 seconds, 3.721 MiB/s HMAC-SHA512 5 MiB took 1.347 seconds, 3.712 MiB/s PBKDF2 1 KiB took 1.012 seconds, 1.142 KiB/s RSA 2048 key gen 1 ops took 27.136 sec, avg 27136.046 ms, 0.037 ops/sec RSA 3072 key gen 1 ops took 39.922 sec, avg 39922.464 ms, 0.025 ops/sec RSA 4096 key gen 1 ops took 519.483 sec, avg 519482.959 ms, 0.002 ops/sec RSA 2048 public 200 ops took 1.398 sec, avg 6.989 ms, 143.073 ops/sec RSA 2048 private 100 ops took 40.412 sec, avg 404.121 ms, 2.475 ops/sec DH 2048 key gen 14 ops took 1.033 sec, avg 73.764 ms, 13.557 ops/sec DH 2048 agree 100 ops took 16.401 sec, avg 164.009 ms, 6.097 ops/sec ECC [ SECP256R1] 256 key gen 100 ops took 5.583 sec, avg 55.830 ms, 17.912 ops/sec ECDHE [ SECP256R1] 256 agree 100 ops took 5.555 sec, avg 55.549 ms, 18.002 ops/sec ECDSA [ SECP256R1] 256 sign 100 ops took 5.703 sec, avg 57.032 ms, 17.534 ops/sec ECDSA [ SECP256R1] 256 verify 100 ops took 4.203 sec, avg 42.030 ms, 23.792 ops/sec CURVE 25519 key gen 315 ops took 1.001 sec, avg 3.176 ms, 314.822 ops/sec CURVE 25519 agree 400 ops took 1.244 sec, avg 3.110 ms, 321.579 ops/sec Benchmark complete Signed-off-by: Markus Stockhausen Link: https://github.com/openwrt/openwrt/pull/19117 Signed-off-by: Robert Marko --- .../patches-6.12/308-tune-switch-4kec.patch | 24 +++++++++++++++++++ target/linux/realtek/rtl838x/target.mk | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 target/linux/realtek/patches-6.12/308-tune-switch-4kec.patch diff --git a/target/linux/realtek/patches-6.12/308-tune-switch-4kec.patch b/target/linux/realtek/patches-6.12/308-tune-switch-4kec.patch new file mode 100644 index 0000000000..87cd76d462 --- /dev/null +++ b/target/linux/realtek/patches-6.12/308-tune-switch-4kec.patch @@ -0,0 +1,24 @@ +From: Markus Stockhausen +Date: Fri, 13 Jun 2025 20:25:37 +0100 +Subject: [PATCH] realtek: set mtune 4kec for RTL838x targets + +Generic patches will always force the gcc kernel tuning to 34kc. With RTL838x +being only 4kec this does not harm but is not right. Match the tuning properly. + +Signed-off-by: Markus Stockhausen +--- + +--- a/arch/mips/Makefile ++++ b/arch/mips/Makefile +@@ -164,6 +164,11 @@ cflags-$(CONFIG_CPU_R4X00) += $(call cc- + cflags-$(CONFIG_CPU_TX49XX) += $(call cc-option,-march=r4600,-march=mips3) -Wa,--trap + cflags-$(CONFIG_CPU_MIPS32_R1) += -march=mips32 -Wa,--trap + cflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -mtune=34kc -Wa,--trap ++ ++#ifdef CONFIG_RTL838X ++cflags-$(CONFIG_CPU_MIPS32_R2) := $(subst 34kc,4kec,$(cflags-$(CONFIG_CPU_MIPS32_R2))) ++#endif ++ + cflags-$(CONFIG_CPU_MIPS32_R5) += -march=mips32r5 -Wa,--trap -modd-spreg + cflags-$(CONFIG_CPU_MIPS32_R6) += -march=mips32r6 -Wa,--trap -modd-spreg + cflags-$(CONFIG_CPU_MIPS64_R1) += -march=mips64 -Wa,--trap diff --git a/target/linux/realtek/rtl838x/target.mk b/target/linux/realtek/rtl838x/target.mk index e776676f66..508298c327 100644 --- a/target/linux/realtek/rtl838x/target.mk +++ b/target/linux/realtek/rtl838x/target.mk @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only ARCH:=mips SUBTARGET:=rtl838x -CPU_TYPE:=4kec +CPU_TYPE:=24kc BOARD:=realtek BOARDNAME:=Realtek MIPS RTL838X From c20f4d6637a4daf66af84d786d002a6382ce3e58 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Wed, 30 Jul 2025 10:56:57 +0200 Subject: [PATCH 02/10] tools: util-linux: refresh patches util-linux needs to be refreshed, so do so. Fixes: 4fd61171294d ("tools/util-linux: fix libuuid linking") Signed-off-by: Robert Marko --- tools/util-linux/patches/110-move-libpthread-to-libs.patch | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tools/util-linux/patches/110-move-libpthread-to-libs.patch b/tools/util-linux/patches/110-move-libpthread-to-libs.patch index e054778b18..996402d143 100644 --- a/tools/util-linux/patches/110-move-libpthread-to-libs.patch +++ b/tools/util-linux/patches/110-move-libpthread-to-libs.patch @@ -12,8 +12,6 @@ Signed-off-by: Rosen Penev libuuid/uuid.pc.in | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) -diff --git a/libuuid/uuid.pc.in b/libuuid/uuid.pc.in -index 51929fe80d72..9fe908b61f12 100644 --- a/libuuid/uuid.pc.in +++ b/libuuid/uuid.pc.in @@ -7,5 +7,4 @@ Name: uuid @@ -23,6 +21,3 @@ index 51929fe80d72..9fe908b61f12 100644 -Libs.private: @SOCKET_LIBS@ -lpthread -Libs: -L${libdir} -luuid +Libs: -L${libdir} -luuid @SOCKET_LIBS@ -lpthread --- -2.50.1 - From 848887b491fdb252ac888c353c4d8fef38b6b741 Mon Sep 17 00:00:00 2001 From: Harshal Gohel Date: Mon, 14 Jul 2025 11:35:00 +0200 Subject: [PATCH 03/10] realtek: rtl931x: Fix SDS field modifications A RTL930x function to read the value from an SDS register must not used on an RTL931x SoC. Doing it with rtl930x_read_sds_phy() would corrupt the written results when only parts of the bits are written. Fixes: 7026084066fb ("realtek: Add SDS configuration routines for the RTL93XX platforms") Signed-off-by: Harshal Gohel Signed-off-by: Sharadanand Karanjkar Link: https://github.com/openwrt/openwrt/pull/19603 Signed-off-by: Robert Marko --- target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c index 439ba9aa37..65e7e12117 100644 --- a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c +++ b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c @@ -3048,7 +3048,7 @@ static void rtl9310_sds_field_w(int sds, u32 page, u32 reg, int end_bit, int sta if (l < 32) { u32 mask = BIT(l) - 1; - data = rtl930x_read_sds_phy(sds, page, reg); + data = rtl931x_read_sds_phy(sds, page, reg); data &= ~(mask << start_bit); data |= (v & mask) << start_bit; } From d802e6310a013a4255392c73967a243a773c8799 Mon Sep 17 00:00:00 2001 From: Harshal Gohel Date: Tue, 17 Jun 2025 13:03:47 +0000 Subject: [PATCH 04/10] realtek: rtl931x: Support enable/disable SMI Polling for SerDes ports During PHY matching, the SMI polling must be disabled to avoid conflicts during the complex detection routine. Only after this finished, SMI polling is allowed again. This was implemented for all realtek families besides RTL931x. Signed-off-by: Harshal Gohel Signed-off-by: Sharadanand Karanjkar Link: https://github.com/openwrt/openwrt/pull/19603 Signed-off-by: Robert Marko --- .../realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c index 65e7e12117..85399151db 100644 --- a/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c +++ b/target/linux/realtek/files-6.12/drivers/net/phy/rtl83xx-phy.c @@ -120,7 +120,10 @@ static u64 disable_polling(int port) sw_w32_mask(BIT(port), 0, RTL930X_SMI_POLL_CTRL); break; case RTL9310_FAMILY_ID: - pr_warn("%s not implemented for RTL931X\n", __func__); + saved_state = sw_r32(RTL931X_SMI_PORT_POLLING_CTRL + 4); + saved_state <<= 32; + saved_state |= sw_r32(RTL931X_SMI_PORT_POLLING_CTRL); + sw_w32_mask(BIT(port % 32), 0, RTL931X_SMI_PORT_POLLING_CTRL + ((port >> 5) << 2)); break; } @@ -145,7 +148,8 @@ static int resume_polling(u64 saved_state) sw_w32(saved_state, RTL930X_SMI_POLL_CTRL); break; case RTL9310_FAMILY_ID: - pr_warn("%s not implemented for RTL931X\n", __func__); + sw_w32(saved_state >> 32, RTL931X_SMI_PORT_POLLING_CTRL + 4); + sw_w32(saved_state, RTL931X_SMI_PORT_POLLING_CTRL); break; } From 66916096f3804f8c424828be9ad67f7812569a16 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Wed, 30 Jul 2025 14:44:16 -0400 Subject: [PATCH 05/10] tools: bison: do not install or uninstall macros There is a clobbering between bison and gnulib for installing the macro file bison-i18n.m4 where gnulib has a newer version while bison will replace it with an outdated version if built afterward. Other builds depend on the changes made to the bison-i18n.m4 file and are only included using aclocal unless other modifications are made in each case in order to force imported macros from gnulib to override aclocal macros. Gnulib is integrated within bison, however it is not with a bootstrap script and there is already a reverse dependency between the two, where bison is indirectly required for gnulib to start building. Therefore, do not allow the building or cleaning of bison to install or uninstall m4 files. Reported-by: Tianling Shen Fixes: d19f8bc199 ("tools/gnulib: update to branch stable-202501") Signed-off-by: Michael Pratt Link: https://github.com/openwrt/openwrt/pull/19606 Signed-off-by: Nick Hainke --- tools/bison/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/bison/Makefile b/tools/bison/Makefile index 97d34b5a16..4cb0faf336 100644 --- a/tools/bison/Makefile +++ b/tools/bison/Makefile @@ -21,13 +21,13 @@ include $(INCLUDE_DIR)/host-build.mk HOST_CONFIGURE_ARGS += --enable-threads=posix --disable-nls define Host/Install - $(call Host/Install/Default) + $(call Host/Compile/Default,install aclocal_DATA=) # Macro provided by gnulib $(INSTALL_BIN) ./scripts/yacc $(STAGING_DIR_HOST)/bin/yacc endef define Host/Uninstall rm -f $(STAGING_DIR_HOST)/bin/yacc - -$(call Host/Compile/Default,uninstall) + -$(call Host/Compile/Default,uninstall aclocal_DATA=) # Macro provided by gnulib endef $(eval $(call HostBuild)) From 41b0340ff084321a4b39df8cb2cf624dd7acc57f Mon Sep 17 00:00:00 2001 From: Markus Stockhausen Date: Mon, 28 Jul 2025 10:13:26 -0400 Subject: [PATCH 06/10] realtek: backport NAND driver for RTL93xx RTL93xx devices have a NAND controller built in. Upstream already has a driver in place. Include it downstream. Activate it in the RTL93xx builds and disable it for the RTL83xx builds. Signed-off-by: Markus Stockhausen Link: https://github.com/openwrt/openwrt/pull/19583 Signed-off-by: Robert Marko --- ...-spi-mem-add-realtek-nand-controller.patch | 481 ++++++++++++++++++ ...snand-correctly-handle-dma-transfers.patch | 96 ++++ target/linux/realtek/rtl838x/config-6.12 | 1 + target/linux/realtek/rtl839x/config-6.12 | 1 + target/linux/realtek/rtl930x/config-6.12 | 2 + target/linux/realtek/rtl931x/config-6.12 | 2 + 6 files changed, 583 insertions(+) create mode 100644 target/linux/realtek/patches-6.12/001-v6.13-spi-mem-add-realtek-nand-controller.patch create mode 100644 target/linux/realtek/patches-6.12/002-v6.13-spi-mem-rtl-snand-correctly-handle-dma-transfers.patch diff --git a/target/linux/realtek/patches-6.12/001-v6.13-spi-mem-add-realtek-nand-controller.patch b/target/linux/realtek/patches-6.12/001-v6.13-spi-mem-add-realtek-nand-controller.patch new file mode 100644 index 0000000000..ab630a0ee4 --- /dev/null +++ b/target/linux/realtek/patches-6.12/001-v6.13-spi-mem-add-realtek-nand-controller.patch @@ -0,0 +1,481 @@ +From 42d20a6a61b8fccbb57d80df1ccde7dd82d5bbd6 Mon Sep 17 00:00:00 2001 +From: Chris Packham +Date: Wed, 16 Oct 2024 11:54:34 +1300 +Subject: [PATCH] spi: spi-mem: Add Realtek SPI-NAND controller + +Add a driver for the SPI-NAND controller on the RTL9300 family of +devices. + +The controller supports +* Serial/Dual/Quad data with +* PIO and DMA data read/write operation +* Configurable flash access timing + +There is a separate ECC controller on the RTL9300 which isn't currently +supported (instead we rely on the on-die ECC supported by most SPI-NAND +chips). + +Signed-off-by: Chris Packham +Link: https://patch.msgid.link/20241015225434.3970360-4-chris.packham@alliedtelesis.co.nz +Signed-off-by: Mark Brown +--- + MAINTAINERS | 6 + + drivers/spi/Kconfig | 11 + + drivers/spi/Makefile | 1 + + drivers/spi/spi-realtek-rtl-snand.c | 405 ++++++++++++++++++++++++++++ + 4 files changed, 423 insertions(+) + create mode 100644 drivers/spi/spi-realtek-rtl-snand.c + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -19494,6 +19494,12 @@ S: Maintained + F: Documentation/devicetree/bindings/net/dsa/realtek.yaml + F: drivers/net/dsa/realtek/* + ++REALTEK SPI-NAND ++M: Chris Packham ++S: Maintained ++F: Documentation/devicetree/bindings/spi/realtek,rtl9301-snand.yaml ++F: drivers/spi/spi-realtek-rtl-snand.c ++ + REALTEK WIRELESS DRIVER (rtlwifi family) + M: Ping-Ke Shih + L: linux-wireless@vger.kernel.org +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -843,6 +843,17 @@ config SPI_PXA2XX + config SPI_PXA2XX_PCI + def_tristate SPI_PXA2XX && PCI && COMMON_CLK + ++config SPI_REALTEK_SNAND ++ tristate "Realtek SPI-NAND Flash Controller" ++ depends on MACH_REALTEK_RTL || COMPILE_TEST ++ select REGMAP ++ help ++ This enables support for the SPI-NAND Flash controller on ++ Realtek SoCs. ++ ++ This driver does not support generic SPI. The implementation ++ only supports the spi-mem interface. ++ + config SPI_ROCKCHIP + tristate "Rockchip SPI controller driver" + depends on ARCH_ROCKCHIP || COMPILE_TEST +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -120,6 +120,7 @@ obj-$(CONFIG_SPI_ROCKCHIP) += spi-rockc + obj-$(CONFIG_SPI_ROCKCHIP_SFC) += spi-rockchip-sfc.o + obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o + obj-$(CONFIG_MACH_REALTEK_RTL) += spi-realtek-rtl.o ++obj-$(CONFIG_SPI_REALTEK_SNAND) += spi-realtek-rtl-snand.o + obj-$(CONFIG_SPI_RPCIF) += spi-rpc-if.o + obj-$(CONFIG_SPI_RSPI) += spi-rspi.o + obj-$(CONFIG_SPI_RZV2M_CSI) += spi-rzv2m-csi.o +--- /dev/null ++++ b/drivers/spi/spi-realtek-rtl-snand.c +@@ -0,0 +1,405 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define SNAFCFR 0x00 ++#define SNAFCFR_DMA_IE BIT(20) ++#define SNAFCCR 0x04 ++#define SNAFWCMR 0x08 ++#define SNAFRCMR 0x0c ++#define SNAFRDR 0x10 ++#define SNAFWDR 0x14 ++#define SNAFDTR 0x18 ++#define SNAFDRSAR 0x1c ++#define SNAFDIR 0x20 ++#define SNAFDIR_DMA_IP BIT(0) ++#define SNAFDLR 0x24 ++#define SNAFSR 0x40 ++#define SNAFSR_NFCOS BIT(3) ++#define SNAFSR_NFDRS BIT(2) ++#define SNAFSR_NFDWS BIT(1) ++ ++#define CMR_LEN(len) ((len) - 1) ++#define CMR_WID(width) (((width) >> 1) << 28) ++ ++struct rtl_snand { ++ struct device *dev; ++ struct regmap *regmap; ++ struct completion comp; ++}; ++ ++static irqreturn_t rtl_snand_irq(int irq, void *data) ++{ ++ struct rtl_snand *snand = data; ++ u32 val = 0; ++ ++ regmap_read(snand->regmap, SNAFSR, &val); ++ if (val & (SNAFSR_NFCOS | SNAFSR_NFDRS | SNAFSR_NFDWS)) ++ return IRQ_NONE; ++ ++ regmap_write(snand->regmap, SNAFDIR, SNAFDIR_DMA_IP); ++ complete(&snand->comp); ++ ++ return IRQ_HANDLED; ++} ++ ++static bool rtl_snand_supports_op(struct spi_mem *mem, ++ const struct spi_mem_op *op) ++{ ++ if (!spi_mem_default_supports_op(mem, op)) ++ return false; ++ if (op->cmd.nbytes != 1 || op->cmd.buswidth != 1) ++ return false; ++ return true; ++} ++ ++static void rtl_snand_set_cs(struct rtl_snand *snand, int cs, bool active) ++{ ++ u32 val; ++ ++ if (active) ++ val = ~(1 << (4 * cs)); ++ else ++ val = ~0; ++ ++ regmap_write(snand->regmap, SNAFCCR, val); ++} ++ ++static int rtl_snand_wait_ready(struct rtl_snand *snand) ++{ ++ u32 val; ++ ++ return regmap_read_poll_timeout(snand->regmap, SNAFSR, val, !(val & SNAFSR_NFCOS), ++ 0, 2 * USEC_PER_MSEC); ++} ++ ++static int rtl_snand_xfer_head(struct rtl_snand *snand, int cs, const struct spi_mem_op *op) ++{ ++ int ret; ++ u32 val, len = 0; ++ ++ rtl_snand_set_cs(snand, cs, true); ++ ++ val = op->cmd.opcode << 24; ++ len = 1; ++ if (op->addr.nbytes && op->addr.buswidth == 1) { ++ val |= op->addr.val << ((3 - op->addr.nbytes) * 8); ++ len += op->addr.nbytes; ++ } ++ ++ ret = rtl_snand_wait_ready(snand); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(snand->regmap, SNAFWCMR, CMR_LEN(len)); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(snand->regmap, SNAFWDR, val); ++ if (ret) ++ return ret; ++ ++ ret = rtl_snand_wait_ready(snand); ++ if (ret) ++ return ret; ++ ++ if (op->addr.buswidth > 1) { ++ val = op->addr.val << ((3 - op->addr.nbytes) * 8); ++ len = op->addr.nbytes; ++ ++ ret = regmap_write(snand->regmap, SNAFWCMR, ++ CMR_WID(op->addr.buswidth) | CMR_LEN(len)); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(snand->regmap, SNAFWDR, val); ++ if (ret) ++ return ret; ++ ++ ret = rtl_snand_wait_ready(snand); ++ if (ret) ++ return ret; ++ } ++ ++ if (op->dummy.nbytes) { ++ val = 0; ++ ++ ret = regmap_write(snand->regmap, SNAFWCMR, ++ CMR_WID(op->dummy.buswidth) | CMR_LEN(op->dummy.nbytes)); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(snand->regmap, SNAFWDR, val); ++ if (ret) ++ return ret; ++ ++ ret = rtl_snand_wait_ready(snand); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void rtl_snand_xfer_tail(struct rtl_snand *snand, int cs) ++{ ++ rtl_snand_set_cs(snand, cs, false); ++} ++ ++static int rtl_snand_xfer(struct rtl_snand *snand, int cs, const struct spi_mem_op *op) ++{ ++ unsigned int pos, nbytes; ++ int ret; ++ u32 val, len = 0; ++ ++ ret = rtl_snand_xfer_head(snand, cs, op); ++ if (ret) ++ goto out_deselect; ++ ++ if (op->data.dir == SPI_MEM_DATA_IN) { ++ pos = 0; ++ len = op->data.nbytes; ++ ++ while (pos < len) { ++ nbytes = len - pos; ++ if (nbytes > 4) ++ nbytes = 4; ++ ++ ret = rtl_snand_wait_ready(snand); ++ if (ret) ++ goto out_deselect; ++ ++ ret = regmap_write(snand->regmap, SNAFRCMR, ++ CMR_WID(op->data.buswidth) | CMR_LEN(nbytes)); ++ if (ret) ++ goto out_deselect; ++ ++ ret = rtl_snand_wait_ready(snand); ++ if (ret) ++ goto out_deselect; ++ ++ ret = regmap_read(snand->regmap, SNAFRDR, &val); ++ if (ret) ++ goto out_deselect; ++ ++ memcpy(op->data.buf.in + pos, &val, nbytes); ++ ++ pos += nbytes; ++ } ++ } else if (op->data.dir == SPI_MEM_DATA_OUT) { ++ pos = 0; ++ len = op->data.nbytes; ++ ++ while (pos < len) { ++ nbytes = len - pos; ++ if (nbytes > 4) ++ nbytes = 4; ++ ++ memcpy(&val, op->data.buf.out + pos, nbytes); ++ ++ pos += nbytes; ++ ++ ret = regmap_write(snand->regmap, SNAFWCMR, CMR_LEN(nbytes)); ++ if (ret) ++ goto out_deselect; ++ ++ ret = regmap_write(snand->regmap, SNAFWDR, val); ++ if (ret) ++ goto out_deselect; ++ ++ ret = rtl_snand_wait_ready(snand); ++ if (ret) ++ goto out_deselect; ++ } ++ } ++ ++out_deselect: ++ rtl_snand_xfer_tail(snand, cs); ++ ++ if (ret) ++ dev_err(snand->dev, "transfer failed %d\n", ret); ++ ++ return ret; ++} ++ ++static int rtl_snand_dma_xfer(struct rtl_snand *snand, int cs, const struct spi_mem_op *op) ++{ ++ int ret; ++ dma_addr_t buf_dma; ++ enum dma_data_direction dir; ++ u32 trig; ++ ++ ret = rtl_snand_xfer_head(snand, cs, op); ++ if (ret) ++ goto out_deselect; ++ ++ if (op->data.dir == SPI_MEM_DATA_IN) { ++ dir = DMA_FROM_DEVICE; ++ trig = 0; ++ } else if (op->data.dir == SPI_MEM_DATA_OUT) { ++ dir = DMA_TO_DEVICE; ++ trig = 1; ++ } else { ++ ret = -EOPNOTSUPP; ++ goto out_deselect; ++ } ++ ++ buf_dma = dma_map_single(snand->dev, op->data.buf.in, op->data.nbytes, dir); ++ ret = dma_mapping_error(snand->dev, buf_dma); ++ if (ret) ++ goto out_deselect; ++ ++ ret = regmap_write(snand->regmap, SNAFDIR, SNAFDIR_DMA_IP); ++ if (ret) ++ goto out_unmap; ++ ++ ret = regmap_update_bits(snand->regmap, SNAFCFR, SNAFCFR_DMA_IE, SNAFCFR_DMA_IE); ++ if (ret) ++ goto out_unmap; ++ ++ reinit_completion(&snand->comp); ++ ++ ret = regmap_write(snand->regmap, SNAFDRSAR, buf_dma); ++ if (ret) ++ goto out_disable_int; ++ ++ ret = regmap_write(snand->regmap, SNAFDLR, ++ CMR_WID(op->data.buswidth) | (op->data.nbytes & 0xffff)); ++ if (ret) ++ goto out_disable_int; ++ ++ ret = regmap_write(snand->regmap, SNAFDTR, trig); ++ if (ret) ++ goto out_disable_int; ++ ++ if (!wait_for_completion_timeout(&snand->comp, usecs_to_jiffies(20000))) ++ ret = -ETIMEDOUT; ++ ++ if (ret) ++ goto out_disable_int; ++ ++out_disable_int: ++ regmap_update_bits(snand->regmap, SNAFCFR, SNAFCFR_DMA_IE, 0); ++out_unmap: ++ dma_unmap_single(snand->dev, buf_dma, op->data.nbytes, dir); ++out_deselect: ++ rtl_snand_xfer_tail(snand, cs); ++ ++ if (ret) ++ dev_err(snand->dev, "transfer failed %d\n", ret); ++ ++ return ret; ++} ++ ++static bool rtl_snand_dma_op(const struct spi_mem_op *op) ++{ ++ switch (op->data.dir) { ++ case SPI_MEM_DATA_IN: ++ case SPI_MEM_DATA_OUT: ++ return op->data.nbytes > 32; ++ default: ++ return false; ++ } ++} ++ ++static int rtl_snand_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) ++{ ++ struct rtl_snand *snand = spi_controller_get_devdata(mem->spi->controller); ++ int cs = spi_get_chipselect(mem->spi, 0); ++ ++ dev_dbg(snand->dev, "cs %d op cmd %02x %d:%d, dummy %d:%d, addr %08llx@%d:%d, data %d:%d\n", ++ cs, op->cmd.opcode, ++ op->cmd.buswidth, op->cmd.nbytes, op->dummy.buswidth, ++ op->dummy.nbytes, op->addr.val, op->addr.buswidth, ++ op->addr.nbytes, op->data.buswidth, op->data.nbytes); ++ ++ if (rtl_snand_dma_op(op)) ++ return rtl_snand_dma_xfer(snand, cs, op); ++ else ++ return rtl_snand_xfer(snand, cs, op); ++} ++ ++static const struct spi_controller_mem_ops rtl_snand_mem_ops = { ++ .supports_op = rtl_snand_supports_op, ++ .exec_op = rtl_snand_exec_op, ++}; ++ ++static const struct of_device_id rtl_snand_match[] = { ++ { .compatible = "realtek,rtl9301-snand" }, ++ { .compatible = "realtek,rtl9302b-snand" }, ++ { .compatible = "realtek,rtl9302c-snand" }, ++ { .compatible = "realtek,rtl9303-snand" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, rtl_snand_match); ++ ++static int rtl_snand_probe(struct platform_device *pdev) ++{ ++ struct rtl_snand *snand; ++ struct device *dev = &pdev->dev; ++ struct spi_controller *ctrl; ++ void __iomem *base; ++ const struct regmap_config rc = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = 4, ++ .cache_type = REGCACHE_NONE, ++ }; ++ int irq, ret; ++ ++ ctrl = devm_spi_alloc_host(dev, sizeof(*snand)); ++ if (!ctrl) ++ return -ENOMEM; ++ ++ snand = spi_controller_get_devdata(ctrl); ++ snand->dev = dev; ++ ++ base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ snand->regmap = devm_regmap_init_mmio(dev, base, &rc); ++ if (IS_ERR(snand->regmap)) ++ return PTR_ERR(snand->regmap); ++ ++ init_completion(&snand->comp); ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) ++ return irq; ++ ++ ret = dma_set_mask(snand->dev, DMA_BIT_MASK(32)); ++ if (ret) ++ return dev_err_probe(dev, ret, "failed to set DMA mask\n"); ++ ++ ret = devm_request_irq(dev, irq, rtl_snand_irq, 0, "rtl-snand", snand); ++ if (ret) ++ return dev_err_probe(dev, ret, "failed to request irq\n"); ++ ++ ctrl->num_chipselect = 2; ++ ctrl->mem_ops = &rtl_snand_mem_ops; ++ ctrl->bits_per_word_mask = SPI_BPW_MASK(8); ++ ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_DUAL | SPI_TX_QUAD; ++ device_set_node(&ctrl->dev, dev_fwnode(dev)); ++ ++ return devm_spi_register_controller(dev, ctrl); ++} ++ ++static struct platform_driver rtl_snand_driver = { ++ .driver = { ++ .name = "realtek-rtl-snand", ++ .of_match_table = rtl_snand_match, ++ }, ++ .probe = rtl_snand_probe, ++}; ++module_platform_driver(rtl_snand_driver); ++ ++MODULE_DESCRIPTION("Realtek SPI-NAND Flash Controller Driver"); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/realtek/patches-6.12/002-v6.13-spi-mem-rtl-snand-correctly-handle-dma-transfers.patch b/target/linux/realtek/patches-6.12/002-v6.13-spi-mem-rtl-snand-correctly-handle-dma-transfers.patch new file mode 100644 index 0000000000..a929c67097 --- /dev/null +++ b/target/linux/realtek/patches-6.12/002-v6.13-spi-mem-rtl-snand-correctly-handle-dma-transfers.patch @@ -0,0 +1,96 @@ +From 25d284715845a465a1a3693a09cf8b6ab8bd9caf Mon Sep 17 00:00:00 2001 +From: Chris Packham +Date: Thu, 31 Oct 2024 08:49:20 +1300 +Subject: [PATCH] spi: spi-mem: rtl-snand: Correctly handle DMA transfers + +The RTL9300 has some limitations on the maximum DMA transfers possible. +For reads this is 2080 bytes (520*4) for writes this is 520 bytes. Deal +with this by splitting transfers into appropriately sized parts. + +Fixes: 42d20a6a61b8 ("spi: spi-mem: Add Realtek SPI-NAND controller") +Signed-off-by: Chris Packham +Link: https://patch.msgid.link/20241030194920.3202282-1-chris.packham@alliedtelesis.co.nz +Signed-off-by: Mark Brown +--- + drivers/spi/spi-realtek-rtl-snand.c | 46 +++++++++++++++++++---------- + 1 file changed, 30 insertions(+), 16 deletions(-) + +--- a/drivers/spi/spi-realtek-rtl-snand.c ++++ b/drivers/spi/spi-realtek-rtl-snand.c +@@ -231,19 +231,22 @@ out_deselect: + + static int rtl_snand_dma_xfer(struct rtl_snand *snand, int cs, const struct spi_mem_op *op) + { ++ unsigned int pos, nbytes; + int ret; + dma_addr_t buf_dma; + enum dma_data_direction dir; +- u32 trig; ++ u32 trig, len, maxlen; + + ret = rtl_snand_xfer_head(snand, cs, op); + if (ret) + goto out_deselect; + + if (op->data.dir == SPI_MEM_DATA_IN) { ++ maxlen = 2080; + dir = DMA_FROM_DEVICE; + trig = 0; + } else if (op->data.dir == SPI_MEM_DATA_OUT) { ++ maxlen = 520; + dir = DMA_TO_DEVICE; + trig = 1; + } else { +@@ -264,26 +267,37 @@ static int rtl_snand_dma_xfer(struct rtl + if (ret) + goto out_unmap; + +- reinit_completion(&snand->comp); ++ pos = 0; ++ len = op->data.nbytes; + +- ret = regmap_write(snand->regmap, SNAFDRSAR, buf_dma); +- if (ret) +- goto out_disable_int; ++ while (pos < len) { ++ nbytes = len - pos; ++ if (nbytes > maxlen) ++ nbytes = maxlen; + +- ret = regmap_write(snand->regmap, SNAFDLR, +- CMR_WID(op->data.buswidth) | (op->data.nbytes & 0xffff)); +- if (ret) +- goto out_disable_int; ++ reinit_completion(&snand->comp); + +- ret = regmap_write(snand->regmap, SNAFDTR, trig); +- if (ret) +- goto out_disable_int; ++ ret = regmap_write(snand->regmap, SNAFDRSAR, buf_dma + pos); ++ if (ret) ++ goto out_disable_int; + +- if (!wait_for_completion_timeout(&snand->comp, usecs_to_jiffies(20000))) +- ret = -ETIMEDOUT; ++ pos += nbytes; + +- if (ret) +- goto out_disable_int; ++ ret = regmap_write(snand->regmap, SNAFDLR, ++ CMR_WID(op->data.buswidth) | nbytes); ++ if (ret) ++ goto out_disable_int; ++ ++ ret = regmap_write(snand->regmap, SNAFDTR, trig); ++ if (ret) ++ goto out_disable_int; ++ ++ if (!wait_for_completion_timeout(&snand->comp, usecs_to_jiffies(20000))) ++ ret = -ETIMEDOUT; ++ ++ if (ret) ++ goto out_disable_int; ++ } + + out_disable_int: + regmap_update_bits(snand->regmap, SNAFCFR, SNAFCFR_DMA_IE, 0); diff --git a/target/linux/realtek/rtl838x/config-6.12 b/target/linux/realtek/rtl838x/config-6.12 index 6676ae9660..a7cd07212c 100644 --- a/target/linux/realtek/rtl838x/config-6.12 +++ b/target/linux/realtek/rtl838x/config-6.12 @@ -226,6 +226,7 @@ CONFIG_SFP=y CONFIG_SPI=y CONFIG_SPI_MASTER=y CONFIG_SPI_MEM=y +# CONFIG_SPI_REALTEK_SNAND is not set CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y CONFIG_SRAM=y CONFIG_SWPHY=y diff --git a/target/linux/realtek/rtl839x/config-6.12 b/target/linux/realtek/rtl839x/config-6.12 index de849a41c1..15a01c87da 100644 --- a/target/linux/realtek/rtl839x/config-6.12 +++ b/target/linux/realtek/rtl839x/config-6.12 @@ -239,6 +239,7 @@ CONFIG_SOCK_RX_QUEUE_MAPPING=y CONFIG_SPI=y CONFIG_SPI_MASTER=y CONFIG_SPI_MEM=y +# CONFIG_SPI_REALTEK_SNAND is not set CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y CONFIG_SRAM=y CONFIG_SWPHY=y diff --git a/target/linux/realtek/rtl930x/config-6.12 b/target/linux/realtek/rtl930x/config-6.12 index 531360df5f..74eeac1f00 100644 --- a/target/linux/realtek/rtl930x/config-6.12 +++ b/target/linux/realtek/rtl930x/config-6.12 @@ -137,6 +137,7 @@ CONFIG_MTD_CFI_ADV_OPTIONS=y CONFIG_MTD_CFI_GEOMETRY=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_SPI_NAND=y CONFIG_MTD_SPI_NOR=y CONFIG_MTD_SPLIT_BRNIMAGE_FW=y CONFIG_MTD_SPLIT_EVA_FW=y @@ -206,6 +207,7 @@ CONFIG_SFP=y CONFIG_SPI=y CONFIG_SPI_MASTER=y CONFIG_SPI_MEM=y +CONFIG_SPI_REALTEK_SNAND=y CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y CONFIG_SWPHY=y CONFIG_SYSCTL_EXCEPTION_TRACE=y diff --git a/target/linux/realtek/rtl931x/config-6.12 b/target/linux/realtek/rtl931x/config-6.12 index 8d79bcbec2..8d2a3553b4 100644 --- a/target/linux/realtek/rtl931x/config-6.12 +++ b/target/linux/realtek/rtl931x/config-6.12 @@ -153,6 +153,7 @@ CONFIG_MTD_CFI_ADV_OPTIONS=y CONFIG_MTD_CFI_GEOMETRY=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_SPI_NAND=y CONFIG_MTD_SPI_NOR=y CONFIG_MTD_SPLIT_BRNIMAGE_FW=y CONFIG_MTD_SPLIT_EVA_FW=y @@ -227,6 +228,7 @@ CONFIG_SOCK_RX_QUEUE_MAPPING=y CONFIG_SPI=y CONFIG_SPI_MASTER=y CONFIG_SPI_MEM=y +CONFIG_SPI_REALTEK_SNAND=y CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y CONFIG_SWPHY=y CONFIG_SYNC_R4K=y From 9b5d0550769cb16a892febef472082fb22b4441b Mon Sep 17 00:00:00 2001 From: Markus Stockhausen Date: Mon, 28 Jul 2025 10:16:24 -0400 Subject: [PATCH 07/10] realtek: add NAND hardware description to RTL93xx Include the NAND specs into the DTS. It is unclear which devices really need it. Keep it disabled for now. As the SoC register area is defined too small until now, increase the size to an appropriate value. If enabled one can see the following log messages (e.g. Linksys LGS328C or LGS352C). [ 1.206600] spi-nand spi1.0: Macronix SPI NAND was found. [ 1.212795] spi-nand spi1.0: 128 MiB, block size: 128 KiB, page size: 2048, OOB size: 64 [ 1.222217] 3 fixed-partitions partitions found on MTD device spi1.0 [ 1.229466] OF: Bad cell count for /soc/spi@1a400/flash@0/partitions [ 1.236617] OF: Bad cell count for /soc/spi@1a400/flash@0/partitions [ 1.244164] Creating 3 MTD partitions on "spi1.0": [ 1.249620] 0x000000000000-0x000004000000 : "ubifs" [ 1.423593] 0x000004000000-0x000005e00000 : "firmware" [ 1.738268] mtdsplit_uimage: no uImage found in "firmware" [ 1.744577] 0x000005e00000-0x000007c00000 : "runtime2" Signed-off-by: Markus Stockhausen Link: https://github.com/openwrt/openwrt/pull/19583 Signed-off-by: Robert Marko --- target/linux/realtek/dts/rtl930x.dtsi | 14 +++++++++++++- target/linux/realtek/dts/rtl931x.dtsi | 14 +++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/target/linux/realtek/dts/rtl930x.dtsi b/target/linux/realtek/dts/rtl930x.dtsi index 947f0d9be5..31fe3ffd8b 100644 --- a/target/linux/realtek/dts/rtl930x.dtsi +++ b/target/linux/realtek/dts/rtl930x.dtsi @@ -59,7 +59,7 @@ compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; - ranges = <0x0 0x18000000 0x10000>; + ranges = <0x0 0x18000000 0x20000>; intc: interrupt-controller@3000 { compatible = "realtek,rtl9300-intc", "realtek,rtl-intc"; @@ -71,6 +71,18 @@ interrupts = <2>, <3>, <4>, <5>, <6>, <7>; }; + snand: spi@1a400 { + compatible = "realtek,rtl9301-snand"; + reg = <0x1a400 0x44>; + interrupt-parent = <&intc>; + interrupts = <19 2>; + clocks = <&lx_clk>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + spi0: spi@1200 { compatible = "realtek,rtl8380-spi"; reg = <0x1200 0x100>; diff --git a/target/linux/realtek/dts/rtl931x.dtsi b/target/linux/realtek/dts/rtl931x.dtsi index df85112464..86634d6c16 100644 --- a/target/linux/realtek/dts/rtl931x.dtsi +++ b/target/linux/realtek/dts/rtl931x.dtsi @@ -95,7 +95,7 @@ compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; - ranges = <0x0 0x18000000 0x10000>; + ranges = <0x0 0x18000000 0x20000>; spi0: spi@1200 { status = "okay"; @@ -107,6 +107,18 @@ #size-cells = <0>; }; + snand: spi@1a400 { + compatible = "realtek,rtl9301-snand"; + reg = <0x1a400 0x44>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&lx_clk>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + watchdog0: watchdog@3260 { compatible = "realtek,rtl9310-wdt"; reg = <0x3260 0xc>; From b5acf84635e61d8414d8398461f48cea208d5ce9 Mon Sep 17 00:00:00 2001 From: Chukun Pan Date: Tue, 8 Jul 2025 22:20:19 +0800 Subject: [PATCH 08/10] qualcommax: cleanup device tree for GL-B3000 Remove extra blank lines. Fixes typo for label and status. Signed-off-by: Chukun Pan Link: https://github.com/openwrt/openwrt/pull/19400 Signed-off-by: Robert Marko --- .../arm64/boot/dts/qcom/ipq5018-gl-b3000.dts | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-gl-b3000.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-gl-b3000.dts index 3fd16bdc9d..1e60ed8c97 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-gl-b3000.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq5018-gl-b3000.dts @@ -9,7 +9,7 @@ / { model = "GL.iNet GL-B3000"; - compatible ="glinet,gl-b3000", "qcom,ipq5018"; + compatible = "glinet,gl-b3000", "qcom,ipq5018"; aliases { ethernet1 = &dp2; @@ -31,7 +31,7 @@ pinctrl-0 = <&button_pins>; pinctrl-names = "default"; - button_reset { + button-reset { label = "reset"; gpios = <&tlmm 27 GPIO_ACTIVE_LOW>; linux,code = ; @@ -43,23 +43,20 @@ pinctrl-0 = <&leds_pins>; pinctrl-names = "default"; - led_system_blue: led_system_blue { + led_system_blue: system-blue { color = ; - function = LED_FUNCTION_POWER; + function = LED_FUNCTION_STATUS; gpio = <&tlmm 24 GPIO_ACTIVE_HIGH>; - default-state = "on"; }; - led_status_white: led_status_white { + led_status_white: status-white { color = ; - function = LED_FUNCTION_POWER; + function = LED_FUNCTION_STATUS; gpio = <&tlmm 23 GPIO_ACTIVE_HIGH>; - default-state = "off"; }; }; reserved-memory { - q6_mem_regions: q6_mem_regions@4b000000 { no-map; reg = <0x0 0x4b000000 0x0 0x3000000>; @@ -72,7 +69,6 @@ switch_mac_mode = ; qcom,port_phyinfo { - // MAC0 -> GE Phy -> QCA8337 Phy2 port@0 { port_id = <1>; @@ -189,9 +185,9 @@ }; &blsp1_uart1 { - status = "okay"; pinctrl-0 = <&serial_0_pins>; pinctrl-names = "default"; + status = "okay"; }; &crypto { @@ -256,7 +252,6 @@ &tlmm { mdio1_pins: mdio-state { - mdc-pins { pins = "gpio36"; function = "mdc"; @@ -287,7 +282,6 @@ }; qpic_pins: qpic-state { - clock-pins { pins = "gpio9"; function = "qspi_clk"; @@ -311,9 +305,7 @@ }; serial_0_pins: uart0-state { - pins = - "gpio20", // RX - "gpio21"; // TX + pins = "gpio20", "gpio21"; function = "blsp0_uart0"; drive-strength = <8>; bias-disable; From 2684fe31d02e2c88ead04bca7c464e7906682c3c Mon Sep 17 00:00:00 2001 From: Sven Wegener Date: Sun, 6 Jul 2025 19:28:36 +0200 Subject: [PATCH 09/10] build: use --no-print-directory for dumping subtargets Or else we end up with "Entering directory" and "Leaving directory" from make in tmp/.targetinfo Signed-off-by: Sven Wegener Link: https://github.com/openwrt/openwrt/pull/19326 Signed-off-by: Robert Marko --- include/target.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/target.mk b/include/target.mk index b6c5e29d45..8ea6fff299 100644 --- a/include/target.mk +++ b/include/target.mk @@ -389,7 +389,7 @@ define BuildTargets/DumpCurrent echo 'Default-Packages: $(DEFAULT_PACKAGES) $(call extra_packages,$(DEFAULT_PACKAGES))'; \ $(DUMPINFO) $(if $(CUR_SUBTARGET),$(SUBMAKE) -r --no-print-directory -C image -s DUMP=1 SUBTARGET=$(CUR_SUBTARGET)) - $(if $(SUBTARGET),,@$(foreach SUBTARGET,$(SUBTARGETS),$(SUBMAKE) -s DUMP=1 SUBTARGET=$(SUBTARGET); )) + $(if $(SUBTARGET),,@$(foreach SUBTARGET,$(SUBTARGETS),$(SUBMAKE) --no-print-directory -s DUMP=1 SUBTARGET=$(SUBTARGET); )) endef include $(INCLUDE_DIR)/kernel.mk From fd123d6d13979c30b58262c4e0ee24e8cd7aba3a Mon Sep 17 00:00:00 2001 From: Coia Prant Date: Sat, 5 Jul 2025 07:53:09 +0000 Subject: [PATCH 10/10] qualcommax: ipq6018: remove unused reserved memory Deleted useless content, since it is the same as the mainline kernel Signed-off-by: Coia Prant Link: https://github.com/openwrt/openwrt/pull/19300 Signed-off-by: Robert Marko --- .../arch/arm64/boot/dts/qcom/ipq6018-512m.dtsi | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-512m.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-512m.dtsi index d46a852404..6ea3291026 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-512m.dtsi +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-512m.dtsi @@ -2,22 +2,6 @@ #include "ipq6018.dtsi" -&rpm_msg_ram { - reg = <0x0 0x00060000 0x0 0x6000>; - no-map; -}; - -&tz { - reg = <0x0 0x4a600000 0x0 0x00400000>; - no-map; -}; - -&smem_region { - reg = <0x0 0x4aa00000 0x0 0x00100000>; - no-map; -}; - &q6_region { - reg = <0x0 0x4ab00000 0x0 0x03700000>; - no-map; + reg = <0x0 0x4ab00000 0x0 0x3700000>; };