[openwrt/openwrt] ramips: mtk-sd: backport Host Software Queue support

LEDE Commits lede-commits at lists.infradead.org
Mon Jun 16 10:33:24 PDT 2025


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

commit db76fe6a02ed5bf3b545a8a09d6112ed4039edaf
Author: Shiji Yang <yangshiji66 at outlook.com>
AuthorDate: Fri Jun 13 21:05:31 2025 +0800

    ramips: mtk-sd: backport Host Software Queue support
    
    This new feature has some improvements for random RW performance.
    
    Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
    Link: https://github.com/openwrt/openwrt/pull/18896
    Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 target/linux/ramips/modules.mk                     |   8 +-
 ...sd-Implement-Host-Software-Queue-for-eMMC.patch | 188 +++++++++++++++++++++
 ...mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch |   2 +-
 ...d-initialize-pad-delay-and-drive-strength.patch |  10 +-
 ...sd-Implement-Host-Software-Queue-for-eMMC.patch | 188 +++++++++++++++++++++
 ...mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch |   2 +-
 ...d-initialize-pad-delay-and-drive-strength.patch |  10 +-
 7 files changed, 393 insertions(+), 15 deletions(-)

diff --git a/target/linux/ramips/modules.mk b/target/linux/ramips/modules.mk
index 22a9660b0f..286457c25e 100644
--- a/target/linux/ramips/modules.mk
+++ b/target/linux/ramips/modules.mk
@@ -10,12 +10,14 @@ define KernelPackage/mmc-mtk
   DEPENDS:=@(TARGET_ramips_mt7620||TARGET_ramips_mt76x8||TARGET_ramips_mt7621) +kmod-mmc
   KCONFIG:= \
 	CONFIG_MMC \
-	CONFIG_MMC_MTK \
-	CONFIG_MMC_CQHCI
+	CONFIG_MMC_CQHCI \
+	CONFIG_MMC_HSQ \
+	CONFIG_MMC_MTK
   FILES:= \
 	$(LINUX_DIR)/drivers/mmc/host/cqhci.ko \
+	$(LINUX_DIR)/drivers/mmc/host/mmc_hsq.ko \
 	$(LINUX_DIR)/drivers/mmc/host/mtk-sd.ko
-  AUTOLOAD:=$(call AutoProbe,cqhci mtk-sd,1)
+  AUTOLOAD:=$(call AutoProbe,cqhci mmc_hsq mtk-sd,1)
 endef
 
 define KernelPackage/mmc-mtk/description
diff --git a/target/linux/ramips/patches-6.12/003-v6.13-mmc-mtk-sd-Implement-Host-Software-Queue-for-eMMC.patch b/target/linux/ramips/patches-6.12/003-v6.13-mmc-mtk-sd-Implement-Host-Software-Queue-for-eMMC.patch
new file mode 100644
index 0000000000..61018cad2c
--- /dev/null
+++ b/target/linux/ramips/patches-6.12/003-v6.13-mmc-mtk-sd-Implement-Host-Software-Queue-for-eMMC.patch
@@ -0,0 +1,188 @@
+From 7e9ddd7d45897b15a64c4a3c88f2f7909bf49749 Mon Sep 17 00:00:00 2001
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
+Date: Mon, 30 Sep 2024 11:01:56 +0200
+Subject: [PATCH] mmc: mtk-sd: Implement Host Software Queue for eMMC and SD
+ Card
+
+Add support for Host Software Queue (HSQ) and enable it when the
+controller instance does not have Command Queue Engine HW support.
+
+It was chosen to enable HSQ only for eMMC and SD/MicroSD cards
+and not for SDIO as performance improvements are seen only for
+the former.
+
+Performance was measured with a SanDisk Extreme Ultra A2 MicroSD
+card in a MediaTek MT8195T Acer Chromebook Spin 513 (CP513-2H),
+by running FIO (bs=4k) on an ArchLinux userspace.
+
+.... Summarizing ....
+Random read:     +24.28% IOPS, +24.29% BW
+Sequential read: +3.14%  IOPS, +3.49%  BW
+Random RW (avg): +50.53% IOPS, +50.68% BW
+
+Below, more data from the benchmarks.
+
+Before:
+ - Random read: IOPS=1643, BW=6574KiB/s
+   bw (  KiB/s): min= 4578, max= 7440, per=99.95%, avg=6571.55, stdev=74.16, samples=953
+   iops        : min= 1144, max= 1860, avg=1642.14, stdev=18.54, samples=953
+   lat (msec)  : 100=0.01%, 250=0.12%, 500=0.38%, 750=97.89%, 1000=1.44%, 2000=0.16%
+ - Sequential read: IOPS=19.1k, BW=74.4MiB/s
+   bw (  KiB/s): min=12288, max=118483, per=100.00%, avg=76293.38, stdev=1971.42, samples=956
+   iops        : min= 3072, max=29620, avg=19072.14, stdev=492.87, samples=956
+   lat (msec)  : 4=0.01%, 10=0.01%, 20=0.21%, 50=23.95%, 100=75.67%, 250=0.05%, 500=0.03%, 750=0.08%
+ - Random R/W: read: IOPS=282, BW=1129KiB/s (1156kB/s)  write: IOPS=284, BW=1136KiB/s
+   read bw (  KiB/s): min=   31, max= 3496, per=100.00%, avg=1703.67, stdev=155.42, samples=630
+   read iops        : min=    7, max=  873, avg=425.22, stdev=38.85, samples=630
+   wri  bw (  KiB/s): min=   31, max= 3443, per=100.00%, avg=1674.27, stdev=164.23, samples=644
+   wri  iops        : min=    7, max=  860, avg=417.87, stdev=41.03, samples=644
+   lat (msec)   : 250=0.13%, 500=0.44%, 750=0.84%, 1000=22.29%, 2000=74.01%, >=2000=2.30%
+
+After:
+ - Random read: IOPS=2042, BW=8171KiB/s
+   bw (  KiB/s): min= 4907, max= 9072, per=99.94%, avg=8166.80, stdev=93.77, samples=954
+   iops        : min= 1226, max= 2268, avg=2040.78, stdev=23.41, samples=954
+   lat (msec)   : 100=0.03%, 250=0.13%, 500=52.88%, 750=46.64%, 1000=0.32%
+ - Sequential read: IOPS=19.7k, BW=77.0MiB/s
+   bw (  KiB/s): min=67980, max=94248, per=100.00%, avg=78894.27, stdev=1475.07, samples=956
+   iops        : min=16994, max=23562, avg=19722.45, stdev=368.76, samples=956
+   lat (msec)   : 4=0.01%, 10=0.01%, 20=0.05%, 50=28.78%, 100=71.14%, 250=0.01%, 500=0.02%
+ - Random R/W: read: IOPS=424, BW=1699KiB/s  write: IOPS=428, BW=1714KiB/s
+   read bw (  KiB/s): min=  228, max= 2856, per=100.00%, avg=1796.60, stdev=112.59, samples=901
+   read iops        : min=   54, max=  712, avg=447.81, stdev=28.21, samples=901
+   wri  bw (  KiB/s): min=   28, max= 2904, per=100.00%, avg=1780.11, stdev=128.27, samples=916
+   wri  iops        : min=    4, max=  724, avg=443.69, stdev=32.14, samples=916
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
+Link: https://lore.kernel.org/r/20240930090156.33537-1-angelogioacchino.delregno@collabora.com
+Signed-off-by: Ulf Hansson <ulf.hansson at linaro.org>
+---
+ drivers/mmc/host/Kconfig  |  1 +
+ drivers/mmc/host/mtk-sd.c | 49 +++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 48 insertions(+), 2 deletions(-)
+
+--- a/drivers/mmc/host/Kconfig
++++ b/drivers/mmc/host/Kconfig
+@@ -1009,6 +1009,7 @@ config MMC_MTK
+ 	depends on COMMON_CLK
+ 	select REGULATOR
+ 	select MMC_CQHCI
++	select MMC_HSQ
+ 	help
+ 	  This selects the MediaTek(R) Secure digital and Multimedia card Interface.
+ 	  If you have a machine with a integrated SD/MMC card reader, say Y or M here.
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -33,6 +33,7 @@
+ #include <linux/mmc/slot-gpio.h>
+ 
+ #include "cqhci.h"
++#include "mmc_hsq.h"
+ 
+ #define MAX_BD_NUM          1024
+ #define MSDC_NR_CLOCKS      3
+@@ -475,6 +476,7 @@ struct msdc_host {
+ 	bool hs400_tuning;	/* hs400 mode online tuning */
+ 	bool internal_cd;	/* Use internal card-detect logic */
+ 	bool cqhci;		/* support eMMC hw cmdq */
++	bool hsq_en;		/* Host Software Queue is enabled */
+ 	struct msdc_save_para save_para; /* used when gate HCLK */
+ 	struct msdc_tune_para def_tune_para; /* default tune setting */
+ 	struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */
+@@ -1165,7 +1167,9 @@ static void msdc_track_cmd_data(struct m
+ 
+ static void msdc_request_done(struct msdc_host *host, struct mmc_request *mrq)
+ {
++	struct mmc_host *mmc = mmc_from_priv(host);
+ 	unsigned long flags;
++	bool hsq_req_done;
+ 
+ 	/*
+ 	 * No need check the return value of cancel_delayed_work, as only ONE
+@@ -1173,6 +1177,27 @@ static void msdc_request_done(struct msd
+ 	 */
+ 	cancel_delayed_work(&host->req_timeout);
+ 
++	/*
++	 * If the request was handled from Host Software Queue, there's almost
++	 * nothing to do here, and we also don't need to reset mrq as any race
++	 * condition would not have any room to happen, since HSQ stores the
++	 * "scheduled" mrqs in an internal array of mrq slots anyway.
++	 * However, if the controller experienced an error, we still want to
++	 * reset it as soon as possible.
++	 *
++	 * Note that non-HSQ requests will still be happening at times, even
++	 * though it is enabled, and that's what is going to reset host->mrq.
++	 * Also, msdc_unprepare_data() is going to be called by HSQ when needed
++	 * as HSQ request finalization will eventually call the .post_req()
++	 * callback of this driver which, in turn, unprepares the data.
++	 */
++	hsq_req_done = host->hsq_en ? mmc_hsq_finalize_request(mmc, mrq) : false;
++	if (hsq_req_done) {
++		if (host->error)
++			msdc_reset_hw(host);
++		return;
++	}
++
+ 	spin_lock_irqsave(&host->lock, flags);
+ 	host->mrq = NULL;
+ 	spin_unlock_irqrestore(&host->lock, flags);
+@@ -1182,7 +1207,7 @@ static void msdc_request_done(struct msd
+ 		msdc_unprepare_data(host, mrq->data);
+ 	if (host->error)
+ 		msdc_reset_hw(host);
+-	mmc_request_done(mmc_from_priv(host), mrq);
++	mmc_request_done(mmc, mrq);
+ 	if (host->dev_comp->recheck_sdio_irq)
+ 		msdc_recheck_sdio_irq(host);
+ }
+@@ -1342,7 +1367,7 @@ static void msdc_ops_request(struct mmc_
+ 	struct msdc_host *host = mmc_priv(mmc);
+ 
+ 	host->error = 0;
+-	WARN_ON(host->mrq);
++	WARN_ON(!host->hsq_en && host->mrq);
+ 	host->mrq = mrq;
+ 
+ 	if (mrq->data)
+@@ -2908,6 +2933,19 @@ static int msdc_drv_probe(struct platfor
+ 		mmc->max_seg_size = 64 * 1024;
+ 		/* Reduce CIT to 0x40 that corresponds to 2.35us */
+ 		msdc_cqe_cit_cal(host, 2350);
++	} else if (mmc->caps2 & MMC_CAP2_NO_SDIO) {
++		/* Use HSQ on eMMC/SD (but not on SDIO) if HW CQE not supported */
++		struct mmc_hsq *hsq = devm_kzalloc(&pdev->dev, sizeof(*hsq), GFP_KERNEL);
++		if (!hsq) {
++			ret = -ENOMEM;
++			goto release;
++		}
++
++		ret = mmc_hsq_init(hsq, mmc);
++		if (ret)
++			goto release;
++
++		host->hsq_en = true;
+ 	}
+ 
+ 	ret = devm_request_irq(&pdev->dev, host->irq, msdc_irq,
+@@ -3033,6 +3071,9 @@ static int __maybe_unused msdc_runtime_s
+ 	struct mmc_host *mmc = dev_get_drvdata(dev);
+ 	struct msdc_host *host = mmc_priv(mmc);
+ 
++	if (host->hsq_en)
++		mmc_hsq_suspend(mmc);
++
+ 	msdc_save_reg(host);
+ 
+ 	if (sdio_irq_claimed(mmc)) {
+@@ -3063,6 +3104,10 @@ static int __maybe_unused msdc_runtime_r
+ 		pinctrl_select_state(host->pinctrl, host->pins_uhs);
+ 		enable_irq(host->irq);
+ 	}
++
++	if (host->hsq_en)
++		mmc_hsq_resume(mmc);
++
+ 	return 0;
+ }
+ 
diff --git a/target/linux/ramips/patches-6.12/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch b/target/linux/ramips/patches-6.12/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch
index 42620e6105..c4cf5ddcde 100644
--- a/target/linux/ramips/patches-6.12/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch
+++ b/target/linux/ramips/patches-6.12/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch
@@ -25,7 +25,7 @@ Signed-off-by: John Crispin <blogic at openwrt.org>
 
 --- a/drivers/mmc/host/Kconfig
 +++ b/drivers/mmc/host/Kconfig
-@@ -1089,6 +1089,8 @@ config MMC_OWL
+@@ -1090,6 +1090,8 @@ config MMC_OWL
  config MMC_SDHCI_EXTERNAL_DMA
  	bool
  
diff --git a/target/linux/ramips/patches-6.12/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch b/target/linux/ramips/patches-6.12/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch
index 85159019b6..a1e92560c1 100644
--- a/target/linux/ramips/patches-6.12/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch
+++ b/target/linux/ramips/patches-6.12/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch
@@ -9,7 +9,7 @@ Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
 
 --- a/drivers/mmc/host/mtk-sd.c
 +++ b/drivers/mmc/host/mtk-sd.c
-@@ -74,8 +74,12 @@
+@@ -75,8 +75,12 @@
  #define MSDC_PATCH_BIT   0xb0
  #define MSDC_PATCH_BIT1  0xb4
  #define MSDC_PATCH_BIT2  0xb8
@@ -22,7 +22,7 @@ Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
  #define PAD_DS_TUNE      0x188
  #define PAD_CMD_TUNE     0x18c
  #define EMMC51_CFG0	 0x204
-@@ -407,6 +411,7 @@ struct mtk_mmc_compatible {
+@@ -408,6 +412,7 @@ struct mtk_mmc_compatible {
  	bool enhance_rx;
  	bool support_64g;
  	bool use_internal_cd;
@@ -30,7 +30,7 @@ Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
  };
  
  struct msdc_tune_para {
-@@ -545,6 +550,7 @@ static const struct mtk_mmc_compatible m
+@@ -547,6 +552,7 @@ static const struct mtk_mmc_compatible m
  	.stop_clk_fix = false,
  	.enhance_rx = false,
  	.use_internal_cd = true,
@@ -38,7 +38,7 @@ Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
  };
  
  static const struct mtk_mmc_compatible mt7622_compat = {
-@@ -1738,9 +1744,11 @@ static void msdc_init_hw(struct msdc_hos
+@@ -1763,9 +1769,11 @@ static void msdc_init_hw(struct msdc_hos
  	}
  	writel(0, host->base + MSDC_IOCON);
  	sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0);
@@ -53,7 +53,7 @@ Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
  	sdr_set_bits(host->base + EMMC50_CFG0, EMMC50_CFG_CFCSTS_SEL);
  
  	if (host->dev_comp->stop_clk_fix) {
-@@ -1814,6 +1822,18 @@ static void msdc_init_hw(struct msdc_hos
+@@ -1839,6 +1847,18 @@ static void msdc_init_hw(struct msdc_hos
  				     MSDC_PAD_TUNE_RXDLYSEL);
  	}
  
diff --git a/target/linux/ramips/patches-6.6/003-v6.13-mmc-mtk-sd-Implement-Host-Software-Queue-for-eMMC.patch b/target/linux/ramips/patches-6.6/003-v6.13-mmc-mtk-sd-Implement-Host-Software-Queue-for-eMMC.patch
new file mode 100644
index 0000000000..38b6959a13
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/003-v6.13-mmc-mtk-sd-Implement-Host-Software-Queue-for-eMMC.patch
@@ -0,0 +1,188 @@
+From 7e9ddd7d45897b15a64c4a3c88f2f7909bf49749 Mon Sep 17 00:00:00 2001
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
+Date: Mon, 30 Sep 2024 11:01:56 +0200
+Subject: [PATCH] mmc: mtk-sd: Implement Host Software Queue for eMMC and SD
+ Card
+
+Add support for Host Software Queue (HSQ) and enable it when the
+controller instance does not have Command Queue Engine HW support.
+
+It was chosen to enable HSQ only for eMMC and SD/MicroSD cards
+and not for SDIO as performance improvements are seen only for
+the former.
+
+Performance was measured with a SanDisk Extreme Ultra A2 MicroSD
+card in a MediaTek MT8195T Acer Chromebook Spin 513 (CP513-2H),
+by running FIO (bs=4k) on an ArchLinux userspace.
+
+.... Summarizing ....
+Random read:     +24.28% IOPS, +24.29% BW
+Sequential read: +3.14%  IOPS, +3.49%  BW
+Random RW (avg): +50.53% IOPS, +50.68% BW
+
+Below, more data from the benchmarks.
+
+Before:
+ - Random read: IOPS=1643, BW=6574KiB/s
+   bw (  KiB/s): min= 4578, max= 7440, per=99.95%, avg=6571.55, stdev=74.16, samples=953
+   iops        : min= 1144, max= 1860, avg=1642.14, stdev=18.54, samples=953
+   lat (msec)  : 100=0.01%, 250=0.12%, 500=0.38%, 750=97.89%, 1000=1.44%, 2000=0.16%
+ - Sequential read: IOPS=19.1k, BW=74.4MiB/s
+   bw (  KiB/s): min=12288, max=118483, per=100.00%, avg=76293.38, stdev=1971.42, samples=956
+   iops        : min= 3072, max=29620, avg=19072.14, stdev=492.87, samples=956
+   lat (msec)  : 4=0.01%, 10=0.01%, 20=0.21%, 50=23.95%, 100=75.67%, 250=0.05%, 500=0.03%, 750=0.08%
+ - Random R/W: read: IOPS=282, BW=1129KiB/s (1156kB/s)  write: IOPS=284, BW=1136KiB/s
+   read bw (  KiB/s): min=   31, max= 3496, per=100.00%, avg=1703.67, stdev=155.42, samples=630
+   read iops        : min=    7, max=  873, avg=425.22, stdev=38.85, samples=630
+   wri  bw (  KiB/s): min=   31, max= 3443, per=100.00%, avg=1674.27, stdev=164.23, samples=644
+   wri  iops        : min=    7, max=  860, avg=417.87, stdev=41.03, samples=644
+   lat (msec)   : 250=0.13%, 500=0.44%, 750=0.84%, 1000=22.29%, 2000=74.01%, >=2000=2.30%
+
+After:
+ - Random read: IOPS=2042, BW=8171KiB/s
+   bw (  KiB/s): min= 4907, max= 9072, per=99.94%, avg=8166.80, stdev=93.77, samples=954
+   iops        : min= 1226, max= 2268, avg=2040.78, stdev=23.41, samples=954
+   lat (msec)   : 100=0.03%, 250=0.13%, 500=52.88%, 750=46.64%, 1000=0.32%
+ - Sequential read: IOPS=19.7k, BW=77.0MiB/s
+   bw (  KiB/s): min=67980, max=94248, per=100.00%, avg=78894.27, stdev=1475.07, samples=956
+   iops        : min=16994, max=23562, avg=19722.45, stdev=368.76, samples=956
+   lat (msec)   : 4=0.01%, 10=0.01%, 20=0.05%, 50=28.78%, 100=71.14%, 250=0.01%, 500=0.02%
+ - Random R/W: read: IOPS=424, BW=1699KiB/s  write: IOPS=428, BW=1714KiB/s
+   read bw (  KiB/s): min=  228, max= 2856, per=100.00%, avg=1796.60, stdev=112.59, samples=901
+   read iops        : min=   54, max=  712, avg=447.81, stdev=28.21, samples=901
+   wri  bw (  KiB/s): min=   28, max= 2904, per=100.00%, avg=1780.11, stdev=128.27, samples=916
+   wri  iops        : min=    4, max=  724, avg=443.69, stdev=32.14, samples=916
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
+Link: https://lore.kernel.org/r/20240930090156.33537-1-angelogioacchino.delregno@collabora.com
+Signed-off-by: Ulf Hansson <ulf.hansson at linaro.org>
+---
+ drivers/mmc/host/Kconfig  |  1 +
+ drivers/mmc/host/mtk-sd.c | 49 +++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 48 insertions(+), 2 deletions(-)
+
+--- a/drivers/mmc/host/Kconfig
++++ b/drivers/mmc/host/Kconfig
+@@ -979,6 +979,7 @@ config MMC_MTK
+ 	depends on COMMON_CLK
+ 	select REGULATOR
+ 	select MMC_CQHCI
++	select MMC_HSQ
+ 	help
+ 	  This selects the MediaTek(R) Secure digital and Multimedia card Interface.
+ 	  If you have a machine with a integrated SD/MMC card reader, say Y or M here.
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -34,6 +34,7 @@
+ #include <linux/mmc/slot-gpio.h>
+ 
+ #include "cqhci.h"
++#include "mmc_hsq.h"
+ 
+ #define MAX_BD_NUM          1024
+ #define MSDC_NR_CLOCKS      3
+@@ -469,6 +470,7 @@ struct msdc_host {
+ 	bool hs400_tuning;	/* hs400 mode online tuning */
+ 	bool internal_cd;	/* Use internal card-detect logic */
+ 	bool cqhci;		/* support eMMC hw cmdq */
++	bool hsq_en;		/* Host Software Queue is enabled */
+ 	struct msdc_save_para save_para; /* used when gate HCLK */
+ 	struct msdc_tune_para def_tune_para; /* default tune setting */
+ 	struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */
+@@ -1158,7 +1160,9 @@ static void msdc_track_cmd_data(struct m
+ 
+ static void msdc_request_done(struct msdc_host *host, struct mmc_request *mrq)
+ {
++	struct mmc_host *mmc = mmc_from_priv(host);
+ 	unsigned long flags;
++	bool hsq_req_done;
+ 
+ 	/*
+ 	 * No need check the return value of cancel_delayed_work, as only ONE
+@@ -1166,6 +1170,27 @@ static void msdc_request_done(struct msd
+ 	 */
+ 	cancel_delayed_work(&host->req_timeout);
+ 
++	/*
++	 * If the request was handled from Host Software Queue, there's almost
++	 * nothing to do here, and we also don't need to reset mrq as any race
++	 * condition would not have any room to happen, since HSQ stores the
++	 * "scheduled" mrqs in an internal array of mrq slots anyway.
++	 * However, if the controller experienced an error, we still want to
++	 * reset it as soon as possible.
++	 *
++	 * Note that non-HSQ requests will still be happening at times, even
++	 * though it is enabled, and that's what is going to reset host->mrq.
++	 * Also, msdc_unprepare_data() is going to be called by HSQ when needed
++	 * as HSQ request finalization will eventually call the .post_req()
++	 * callback of this driver which, in turn, unprepares the data.
++	 */
++	hsq_req_done = host->hsq_en ? mmc_hsq_finalize_request(mmc, mrq) : false;
++	if (hsq_req_done) {
++		if (host->error)
++			msdc_reset_hw(host);
++		return;
++	}
++
+ 	spin_lock_irqsave(&host->lock, flags);
+ 	host->mrq = NULL;
+ 	spin_unlock_irqrestore(&host->lock, flags);
+@@ -1175,7 +1200,7 @@ static void msdc_request_done(struct msd
+ 		msdc_unprepare_data(host, mrq->data);
+ 	if (host->error)
+ 		msdc_reset_hw(host);
+-	mmc_request_done(mmc_from_priv(host), mrq);
++	mmc_request_done(mmc, mrq);
+ 	if (host->dev_comp->recheck_sdio_irq)
+ 		msdc_recheck_sdio_irq(host);
+ }
+@@ -1335,7 +1360,7 @@ static void msdc_ops_request(struct mmc_
+ 	struct msdc_host *host = mmc_priv(mmc);
+ 
+ 	host->error = 0;
+-	WARN_ON(host->mrq);
++	WARN_ON(!host->hsq_en && host->mrq);
+ 	host->mrq = mrq;
+ 
+ 	if (mrq->data)
+@@ -2846,6 +2871,19 @@ static int msdc_drv_probe(struct platfor
+ 		mmc->max_seg_size = 64 * 1024;
+ 		/* Reduce CIT to 0x40 that corresponds to 2.35us */
+ 		msdc_cqe_cit_cal(host, 2350);
++	} else if (mmc->caps2 & MMC_CAP2_NO_SDIO) {
++		/* Use HSQ on eMMC/SD (but not on SDIO) if HW CQE not supported */
++		struct mmc_hsq *hsq = devm_kzalloc(&pdev->dev, sizeof(*hsq), GFP_KERNEL);
++		if (!hsq) {
++			ret = -ENOMEM;
++			goto release;
++		}
++
++		ret = mmc_hsq_init(hsq, mmc);
++		if (ret)
++			goto release;
++
++		host->hsq_en = true;
+ 	}
+ 
+ 	ret = devm_request_irq(&pdev->dev, host->irq, msdc_irq,
+@@ -2971,6 +3009,9 @@ static int __maybe_unused msdc_runtime_s
+ 	struct mmc_host *mmc = dev_get_drvdata(dev);
+ 	struct msdc_host *host = mmc_priv(mmc);
+ 
++	if (host->hsq_en)
++		mmc_hsq_suspend(mmc);
++
+ 	msdc_save_reg(host);
+ 
+ 	if (sdio_irq_claimed(mmc)) {
+@@ -3001,6 +3042,10 @@ static int __maybe_unused msdc_runtime_r
+ 		pinctrl_select_state(host->pinctrl, host->pins_uhs);
+ 		enable_irq(host->irq);
+ 	}
++
++	if (host->hsq_en)
++		mmc_hsq_resume(mmc);
++
+ 	return 0;
+ }
+ 
diff --git a/target/linux/ramips/patches-6.6/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch b/target/linux/ramips/patches-6.6/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch
index c19b0606a1..e80b988234 100644
--- a/target/linux/ramips/patches-6.6/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch
+++ b/target/linux/ramips/patches-6.6/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch
@@ -25,7 +25,7 @@ Signed-off-by: John Crispin <blogic at openwrt.org>
 
 --- a/drivers/mmc/host/Kconfig
 +++ b/drivers/mmc/host/Kconfig
-@@ -1059,6 +1059,8 @@ config MMC_OWL
+@@ -1060,6 +1060,8 @@ config MMC_OWL
  config MMC_SDHCI_EXTERNAL_DMA
  	bool
  
diff --git a/target/linux/ramips/patches-6.6/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch b/target/linux/ramips/patches-6.6/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch
index 7fd7b3af43..3b5b5eb93d 100644
--- a/target/linux/ramips/patches-6.6/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch
+++ b/target/linux/ramips/patches-6.6/831-mmc-mtk-sd-initialize-pad-delay-and-drive-strength.patch
@@ -9,7 +9,7 @@ Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
 
 --- a/drivers/mmc/host/mtk-sd.c
 +++ b/drivers/mmc/host/mtk-sd.c
-@@ -75,8 +75,12 @@
+@@ -76,8 +76,12 @@
  #define MSDC_PATCH_BIT   0xb0
  #define MSDC_PATCH_BIT1  0xb4
  #define MSDC_PATCH_BIT2  0xb8
@@ -22,7 +22,7 @@ Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
  #define PAD_DS_TUNE      0x188
  #define PAD_CMD_TUNE     0x18c
  #define EMMC51_CFG0	 0x204
-@@ -402,6 +406,7 @@ struct mtk_mmc_compatible {
+@@ -403,6 +407,7 @@ struct mtk_mmc_compatible {
  	bool enhance_rx;
  	bool support_64g;
  	bool use_internal_cd;
@@ -30,7 +30,7 @@ Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
  };
  
  struct msdc_tune_para {
-@@ -539,6 +544,7 @@ static const struct mtk_mmc_compatible m
+@@ -541,6 +546,7 @@ static const struct mtk_mmc_compatible m
  	.stop_clk_fix = false,
  	.enhance_rx = false,
  	.use_internal_cd = true,
@@ -38,7 +38,7 @@ Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
  };
  
  static const struct mtk_mmc_compatible mt7622_compat = {
-@@ -1731,9 +1737,11 @@ static void msdc_init_hw(struct msdc_hos
+@@ -1756,9 +1762,11 @@ static void msdc_init_hw(struct msdc_hos
  	}
  	writel(0, host->base + MSDC_IOCON);
  	sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0);
@@ -53,7 +53,7 @@ Signed-off-by: Shiji Yang <yangshiji66 at outlook.com>
  	sdr_set_bits(host->base + EMMC50_CFG0, EMMC50_CFG_CFCSTS_SEL);
  
  	if (host->dev_comp->stop_clk_fix) {
-@@ -1797,6 +1805,18 @@ static void msdc_init_hw(struct msdc_hos
+@@ -1822,6 +1830,18 @@ static void msdc_init_hw(struct msdc_hos
  				     MSDC_PAD_TUNE_RXDLYSEL);
  	}
  




More information about the lede-commits mailing list