[openwrt/openwrt] rockchip: backport MMC CQE fixes

LEDE Commits lede-commits at lists.infradead.org
Thu Dec 4 13:30:32 PST 2025


hauke pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/4582d25a660dee3ada921ae307fefb119faa7be1

commit 4582d25a660dee3ada921ae307fefb119faa7be1
Author: Tianling Shen <cnsztl at immortalwrt.org>
AuthorDate: Wed Dec 3 14:36:32 2025 +0800

    rockchip: backport MMC CQE fixes
    
    Added missing platform data struct for RK3576 to fix boot issues,
    fixed general stability issues and also improved random write
    performance.
    
    Signed-off-by: Tianling Shen <cnsztl at immortalwrt.org>
    Link: https://github.com/openwrt/openwrt/pull/21028
    Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 ...mshc-Fix-command-queue-support-for-RK3576.patch | 55 ++++++++++++++++++++++
 ...mshc-Disable-internal-clock-auto-gate-for.patch | 42 +++++++++++++++++
 ...dwcmshc-reduce-CIT-for-better-performance.patch | 44 +++++++++++++++++
 3 files changed, 141 insertions(+)

diff --git a/target/linux/rockchip/patches-6.12/037-05-v6.19-mmc-sdhci-of-dwcmshc-Fix-command-queue-support-for-RK3576.patch b/target/linux/rockchip/patches-6.12/037-05-v6.19-mmc-sdhci-of-dwcmshc-Fix-command-queue-support-for-RK3576.patch
new file mode 100644
index 0000000000..c4d9689507
--- /dev/null
+++ b/target/linux/rockchip/patches-6.12/037-05-v6.19-mmc-sdhci-of-dwcmshc-Fix-command-queue-support-for-RK3576.patch
@@ -0,0 +1,55 @@
+From 69cc9d4075855661268327c38c9b0e71ac37eb1c Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel at collabora.com>
+Date: Fri, 21 Nov 2025 17:26:59 +0100
+Subject: [PATCH] mmc: sdhci-of-dwcmshc: Fix command queue support for RK3576
+
+When I added command queue engine (CQE) support for the Rockchip eMMC
+controller, I missed that RK3576 has a separate platform data struct.
+While things are working fine on RK3588 (I tested the ROCK 5B) and
+the suspend issue is fixed on the RK3576 (I tested the Sige5), this
+results in stability issues. By also adding the necessary hooks for
+the RK3576 platform the following problems can be avoided:
+
+[   15.606895] mmc0: running CQE recovery
+[   15.616189] mmc0: running CQE recovery
+[...]
+[   25.911484] mmc0: running CQE recovery
+[   25.926305] mmc0: running CQE recovery
+[   25.927468] mmc0: running CQE recovery
+[...]
+[   26.255719] mmc0: running CQE recovery
+[   26.257162] ------------[ cut here ]------------
+[   26.257581] mmc0: cqhci: spurious TCN for tag 31
+[   26.258034] WARNING: CPU: 0 PID: 0 at drivers/mmc/host/cqhci-core.c:796 cqhci_irq+0x440/0x68c
+[   26.263786] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.18.0-rc6-gd984ebbf0d15 #1 PREEMPT
+[   26.264561] Hardware name: ArmSoM Sige5 (DT)
+[...]
+[   26.272748] Call trace:
+[   26.272964]  cqhci_irq+0x440/0x68c (P)
+[   26.273296]  dwcmshc_cqe_irq_handler+0x54/0x88
+[   26.273689]  sdhci_irq+0xbc/0x1200
+[   26.273991]  __handle_irq_event_percpu+0x54/0x1d0
+[...]
+
+Note that the above problems do not necessarily happen with every boot.
+
+Reported-by: Adrian Hunter <adrian.hunter at intel.com>
+Closes: https://lore.kernel.org/linux-rockchip/01949bc9-4873-498b-ac7d-f008393ccc4c@intel.com/
+Fixes: fda1e0af7c28f ("mmc: sdhci-of-dwcmshc: Add command queue support for rockchip SOCs")
+Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
+Reviewed-by: Shawn Lin <shawn.lin at rock-chips.com>
+Signed-off-by: Ulf Hansson <ulf.hansson at linaro.org>
+---
+ drivers/mmc/host/sdhci-of-dwcmshc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/mmc/host/sdhci-of-dwcmshc.c
++++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
+@@ -1333,6 +1333,7 @@ static const struct dwcmshc_pltfm_data s
+ 		.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
+ 			   SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN,
+ 	},
++	.cqhci_host_ops = &rk35xx_cqhci_ops,
+ 	.init = dwcmshc_rk35xx_init,
+ 	.postinit = dwcmshc_rk3576_postinit,
+ };
diff --git a/target/linux/rockchip/patches-6.12/037-06-v6.19-mmc-sdhci-of-dwcmshc-Disable-internal-clock-auto-gate-for.patch b/target/linux/rockchip/patches-6.12/037-06-v6.19-mmc-sdhci-of-dwcmshc-Disable-internal-clock-auto-gate-for.patch
new file mode 100644
index 0000000000..d8a0ed8d14
--- /dev/null
+++ b/target/linux/rockchip/patches-6.12/037-06-v6.19-mmc-sdhci-of-dwcmshc-Disable-internal-clock-auto-gate-for.patch
@@ -0,0 +1,42 @@
+From c7ce6453b769c45006ed4983762f81e130878171 Mon Sep 17 00:00:00 2001
+From: Shawn Lin <shawn.lin at rock-chips.com>
+Date: Wed, 26 Nov 2025 07:26:39 +0800
+Subject: [PATCH] mmc: sdhci-of-dwcmshc: Disable internal clock auto gate for
+ Rockchip SOCs
+
+Enabling CMDQ support can lead to random occurrences of the error log when
+there are RPMB access and data flush executed:
+
+"mmc2: Timeout waiting for hardware interrupt."
+
+Enabling CMDQ and then issuing a DCMD as the final command before disabling
+it causes the eMMC controller to auto-gate its internal clock. Chip simulation
+shows this results in a state machine mismatch after CMDQ mode exit, triggering
+data-timeout errors for all subsequent read and write operations.
+
+Therefore, the auto-clock-gate function must be disabled whenever CMDQ is
+enabled.
+
+Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
+Acked-by: Adrian Hunter <adrian.hunter at intel.com>
+Fixes: fda1e0af7c28 ("mmc: sdhci-of-dwcmshc: Add command queue support for rockchip SOCs")
+Signed-off-by: Ulf Hansson <ulf.hansson at linaro.org>
+---
+ drivers/mmc/host/sdhci-of-dwcmshc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/mmc/host/sdhci-of-dwcmshc.c
++++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
+@@ -696,10 +696,11 @@ static void dwcmshc_rk3568_set_clock(str
+ 
+ 	sdhci_set_clock(host, clock);
+ 
+-	/* Disable cmd conflict check */
++	/* Disable cmd conflict check and internal clock gate */
+ 	reg = dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3;
+ 	extra = sdhci_readl(host, reg);
+ 	extra &= ~BIT(0);
++	extra |= BIT(4);
+ 	sdhci_writel(host, extra, reg);
+ 
+ 	if (clock <= 52000000) {
diff --git a/target/linux/rockchip/patches-6.12/037-07-v6.19-mmc-sdhci-of-dwcmshc-reduce-CIT-for-better-performance.patch b/target/linux/rockchip/patches-6.12/037-07-v6.19-mmc-sdhci-of-dwcmshc-reduce-CIT-for-better-performance.patch
new file mode 100644
index 0000000000..90647d96c3
--- /dev/null
+++ b/target/linux/rockchip/patches-6.12/037-07-v6.19-mmc-sdhci-of-dwcmshc-reduce-CIT-for-better-performance.patch
@@ -0,0 +1,44 @@
+From 79cf71c0b177c0e23d411e2469435e2c2f83f563 Mon Sep 17 00:00:00 2001
+From: Shawn Lin <shawn.lin at rock-chips.com>
+Date: Wed, 26 Nov 2025 07:26:40 +0800
+Subject: [PATCH] mmc: sdhci-of-dwcmshc: reduce CIT for better performance
+
+CQHCI_SSC1.CIT indicates to the CQE the polling period to use for
+periodic SEND_QUEUE_STATUS (CMD13) polling. Some eMMCs have only one
+hardware queue, and CMD13 can only query one slot at a time for data
+transmission, which cannot be processed in parallel. Modifying the
+CMD13 query interval can increase the query frequency and improve
+random write performance.
+
+Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
+Acked-by: Adrian Hunter <adrian.hunter at intel.com>
+Signed-off-by: Ulf Hansson <ulf.hansson at linaro.org>
+---
+ drivers/mmc/host/cqhci.h            | 1 +
+ drivers/mmc/host/sdhci-of-dwcmshc.c | 5 +++++
+ 2 files changed, 6 insertions(+)
+
+--- a/drivers/mmc/host/cqhci.h
++++ b/drivers/mmc/host/cqhci.h
+@@ -93,6 +93,7 @@
+ /* send status config 1 */
+ #define CQHCI_SSC1			0x40
+ #define CQHCI_SSC1_CBC_MASK		GENMASK(19, 16)
++#define CQHCI_SSC1_CIT_MASK		GENMASK(15, 0)
+ 
+ /* send status config 2 */
+ #define CQHCI_SSC2			0x44
+--- a/drivers/mmc/host/sdhci-of-dwcmshc.c
++++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
+@@ -614,6 +614,11 @@ static void rk35xx_sdhci_cqe_pre_enable(
+ 	struct dwcmshc_priv *dwc_priv = sdhci_pltfm_priv(pltfm_host);
+ 	u32 reg;
+ 
++	/* Set Send Status Command Idle Timer to 10.66us (256 * 1 / 24) */
++	reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_SSC1);
++	reg = (reg & ~CQHCI_SSC1_CIT_MASK) | 0x0100;
++	sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_SSC1);
++
+ 	reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
+ 	reg |= CQHCI_ENABLE;
+ 	sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_CFG);




More information about the lede-commits mailing list