mirror of
https://github.com/OpenVoiceOS/OpenVoiceOS
synced 2025-01-10 16:33:06 +01:00
102 lines
3.9 KiB
Diff
102 lines
3.9 KiB
Diff
|
From 79e6ac0d94c3f60efbf9720b4df8f9313a689441 Mon Sep 17 00:00:00 2001
|
||
|
From: CTCaer <ctcaer@gmail.com>
|
||
|
Date: Thu, 10 Aug 2023 21:00:51 +0100
|
||
|
Subject: [PATCH] mmc: sdhci: fix max req size based on spec
|
||
|
|
||
|
For almost 2 decades, the max allowed requests were limited to 512KB because of
|
||
|
SDMA's max 512KiB boundary limit.
|
||
|
|
||
|
ADMA2 and ADMA3 do not have such limits and were effectively made so any
|
||
|
kind of block count would not impose interrupt and managing stress to the host.
|
||
|
|
||
|
By limiting that to 512KiB, it effectively downgrades these DMA modes to SDMA.
|
||
|
|
||
|
Fix that by actually following the spec:
|
||
|
When ADMA is selected tuning mode is advised.
|
||
|
On lesser modes 4MiB transfers is selected as max, so re-tuning if timer trigger
|
||
|
or if requested by host interrupt, can be done in time.
|
||
|
Otherwise, the only limit is the variable size of types used.
|
||
|
In this implementation, 16MiB is used as maximum since tests showed that after
|
||
|
that point, there are diminishing returns.
|
||
|
|
||
|
Also 16MiB in worst case scenarios, when card is eMMC and its max speed is a
|
||
|
generous 350MiB/s, will generate interrupts every 45ms on huge data transfers.
|
||
|
|
||
|
A new `adma_get_req_limit` sdhci host function was also introduced, to let
|
||
|
vendors override imposed limits by the generic implementation if needed.
|
||
|
|
||
|
For example, on local tests with rigorous CPU/GPU burn-in tests and abrupt
|
||
|
cut-offs to generate huge temperature changes (upwards/downwards) to the card,
|
||
|
tested host was fine up to 128MB/s transfers on slow cards that used SDR104
|
||
|
bus timing without re-tuning.
|
||
|
In that case the 4MiB limit was overridden with a more than safe 8MiB value.
|
||
|
|
||
|
In all testing cases and boards, that change brought the following:
|
||
|
|
||
|
Depending on bus timing and eMMC/SD specs:
|
||
|
* Max Read throughput increased by 2-20%
|
||
|
* Max Write throughput increased by 50-200%
|
||
|
Depending on CPU frequency and transfer sizes:
|
||
|
* Reduced mmcqd cpu core usage by 4-50%
|
||
|
|
||
|
Signed-off-by: CTCaer <ctcaer@gmail.com>
|
||
|
---
|
||
|
drivers/mmc/host/sdhci.c | 17 ++++++++++++-----
|
||
|
drivers/mmc/host/sdhci.h | 4 ++--
|
||
|
2 files changed, 14 insertions(+), 7 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
|
||
|
index 84d0d7ac0ae65..518fbaa62e092 100644
|
||
|
--- a/drivers/mmc/host/sdhci.c
|
||
|
+++ b/drivers/mmc/host/sdhci.c
|
||
|
@@ -1095,7 +1095,7 @@ static void sdhci_initialize_data(struct sdhci_host *host,
|
||
|
WARN_ON(host->data);
|
||
|
|
||
|
/* Sanity checks */
|
||
|
- BUG_ON(data->blksz * data->blocks > 524288);
|
||
|
+ BUG_ON(data->blksz * data->blocks > host->mmc->max_req_size);
|
||
|
BUG_ON(data->blksz > host->mmc->max_blk_size);
|
||
|
BUG_ON(data->blocks > 65535);
|
||
|
|
||
|
@@ -4720,11 +4720,18 @@ int sdhci_setup_host(struct sdhci_host *host)
|
||
|
|
||
|
/*
|
||
|
* Maximum number of sectors in one transfer. Limited by SDMA boundary
|
||
|
- * size (512KiB). Note some tuning modes impose a 4MiB limit, but this
|
||
|
- * is less anyway.
|
||
|
+ * size and by tuning modes on ADMA. On tuning mode 3 16MiB is more than
|
||
|
+ * enough to cover big data transfers.
|
||
|
*/
|
||
|
- mmc->max_req_size = 524288;
|
||
|
-
|
||
|
+ if (host->flags & SDHCI_USE_ADMA) {
|
||
|
+ if (host->tuning_mode != SDHCI_TUNING_MODE_3)
|
||
|
+ mmc->max_req_size = 4194304;
|
||
|
+ else
|
||
|
+ mmc->max_req_size = 16777216;
|
||
|
+ } else {
|
||
|
+ /* On PIO/SDMA use SDMA boundary size (512KiB). */
|
||
|
+ mmc->max_req_size = 524288;
|
||
|
+ }
|
||
|
/*
|
||
|
* Maximum number of segments. Depends on if the hardware
|
||
|
* can do scatter/gather or not.
|
||
|
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
|
||
|
index 5ce7cdcc192fd..7c85aeee814d6 100644
|
||
|
--- a/drivers/mmc/host/sdhci.h
|
||
|
+++ b/drivers/mmc/host/sdhci.h
|
||
|
@@ -339,11 +339,11 @@ struct sdhci_adma2_64_desc {
|
||
|
#define ADMA2_END 0x2
|
||
|
|
||
|
/*
|
||
|
- * Maximum segments assuming a 512KiB maximum requisition size and a minimum
|
||
|
+ * Maximum segments assuming a 16MiB maximum requisition size and a minimum
|
||
|
* 4KiB page size. Note this also allows enough for multiple descriptors in
|
||
|
* case of PAGE_SIZE >= 64KiB.
|
||
|
*/
|
||
|
-#define SDHCI_MAX_SEGS 128
|
||
|
+#define SDHCI_MAX_SEGS 4096
|
||
|
|
||
|
/* Allow for a a command request and a data request at the same time */
|
||
|
#define SDHCI_MAX_MRQS 2
|