From 348487cb28e66b032bae1b38424d81bf5b444408 Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Tue, 9 Dec 2014 17:04:05 +0800 Subject: mmc: sdhci: use pipeline mmc requests to improve performance This patch is based on the patches by Per Forlin, Tony Lin and Ryan QIAN. This patch complete the API 'post_req' and 'pre_req' in sdhci host side, Test Env: 1. i.MX6Q-SABREAUTO board, CPU @ 996MHz, use ADMA in uSDHC controller. 2. Test command: $ echo 1 > /proc/sys/vm/drop_caches write to sd card: $ dd if=/dev/zero of=/dev/mmcblk0 bs=1M count=2000 conv=fsync read the sd card: $ dd if=/dev/mmcblk0 of=/dev/null bs=1M count=2000 3. TOSHIBA 16GB SD3.0 card, running at 4 bit, SDR104 @ 198MHZ Performance with and without this patch: ------------------------------------------------- | | read speed | write speed | |------------------------------------------------ | with this patch | ~76.7 MB/s | ~23.3 MB/s | |------------------------------------------------ |without this patch | ~60.5 MB/s | ~22.5 MB/s | ------------------------------------------------- 4. SanDisk 8GB SD3.0 card, running at 4 bit, DDR50 @ 50MHZ Performance with and without this patch: ------------------------------------------------- | | read speed | write speed | |------------------------------------------------ | with this patch | ~40.5 MB/s | ~15.6 MB/s | |------------------------------------------------ |without this patch | ~36.1 MB/s | ~14.1 MB/s | ------------------------------------------------- 5. Kingston 8GB SD2.0 card, running at 4 bit, High-speed @ 50MHZ Performance with and without this patch: ------------------------------------------------- | | read speed | write speed | |------------------------------------------------ | with this patch | ~22.7 MB/s | ~8.2 MB/s | |------------------------------------------------ |without this patch | ~21.3 MB/s | ~8.0 MB/s | ------------------------------------------------- 6. About eMMC, Sandisk 8GB eMMC on i.MX6DL-sabresd board, CPU @ 792MHZ, eMMC running at 8 bit, DDR52 @ 52MHZ. Performance with and without this patch: ------------------------------------------------- | | read speed | write speed | |------------------------------------------------ | with this patch | ~37.3 MB/s | ~10.5 MB/s | |------------------------------------------------ |without this patch | ~33.4 MB/s | ~10.5 MB/s | ------------------------------------------------- Signed-off-by: Haibo Chen Signed-off-by: Ulf Hansson --- include/linux/mmc/sdhci.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux/mmc/sdhci.h') diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index f767a0de611..cb8b94ff6a2 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -17,6 +17,11 @@ #include #include +struct sdhci_host_next { + unsigned int sg_count; + s32 cookie; +}; + struct sdhci_host { /* Data set by hardware interface driver */ const char *hw_name; /* Hardware bus name */ @@ -203,6 +208,7 @@ struct sdhci_host { #define SDHCI_TUNING_MODE_1 0 struct timer_list tuning_timer; /* Timer for tuning */ + struct sdhci_host_next next_data; unsigned long private[0] ____cacheline_aligned; }; #endif /* LINUX_MMC_SDHCI_H */ -- cgit v1.2.3-70-g09d2 From 67d0d04a762db4bd610fd628ad683b5d7dc905e7 Mon Sep 17 00:00:00 2001 From: Vincent Yang Date: Tue, 20 Jan 2015 16:05:16 +0800 Subject: mmc: sdhci: add a quirk for tuning work around This patch defines a quirk for tuning work around for some sdhci host controller. It sets both SDHCI_CTRL_EXEC_TUNING and SDHCI_CTRL_TUNED_CLK for tuning. It is a preparation and will be used by Fujitsu SDHCI controller f_sdh30 driver. Signed-off-by: Vincent Yang Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci.c | 2 ++ include/linux/mmc/sdhci.h | 2 ++ 2 files changed, 4 insertions(+) (limited to 'include/linux/mmc/sdhci.h') diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 3e4fe967d7e..a3ecd20e551 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1961,6 +1961,8 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); ctrl |= SDHCI_CTRL_EXEC_TUNING; + if (host->quirks2 & SDHCI_QUIRK2_TUNING_WORK_AROUND) + ctrl |= SDHCI_CTRL_TUNED_CLK; sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); /* diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index cb8b94ff6a2..933b897ca09 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -111,6 +111,8 @@ struct sdhci_host { #define SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD (1<<10) /* Capability register bit-63 indicates HS400 support */ #define SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 (1<<11) +/* forced tuned clock */ +#define SDHCI_QUIRK2_TUNING_WORK_AROUND (1<<12) int irq; /* Device IRQ */ void __iomem *ioaddr; /* Mapped address */ -- cgit v1.2.3-70-g09d2 From d3fc5d71ac4dfd28a66689cfd1eea84c4dba8bde Mon Sep 17 00:00:00 2001 From: Vincent Yang Date: Tue, 20 Jan 2015 16:05:17 +0800 Subject: mmc: sdhci: add a quirk for single block transactions This patch defines a quirk to disable the block count for single block transactions. It is a preparation and will be used by Fujitsu SDHCI controller f_sdh30 driver. Signed-off-by: Vincent Yang Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci.c | 8 +++++--- include/linux/mmc/sdhci.h | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'include/linux/mmc/sdhci.h') diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index a3ecd20e551..c9881ca131d 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -904,7 +904,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) static void sdhci_set_transfer_mode(struct sdhci_host *host, struct mmc_command *cmd) { - u16 mode; + u16 mode = 0; struct mmc_data *data = cmd->data; if (data == NULL) { @@ -922,9 +922,11 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host, WARN_ON(!host->data); - mode = SDHCI_TRNS_BLK_CNT_EN; + if (!(host->quirks2 & SDHCI_QUIRK2_SUPPORT_SINGLE)) + mode = SDHCI_TRNS_BLK_CNT_EN; + if (mmc_op_multi(cmd->opcode) || data->blocks > 1) { - mode |= SDHCI_TRNS_MULTI; + mode = SDHCI_TRNS_BLK_CNT_EN | SDHCI_TRNS_MULTI; /* * If we are sending CMD23, CMD12 never gets sent * on successful completion (so no Auto-CMD12). diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index 933b897ca09..c3e3db19673 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -113,6 +113,8 @@ struct sdhci_host { #define SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 (1<<11) /* forced tuned clock */ #define SDHCI_QUIRK2_TUNING_WORK_AROUND (1<<12) +/* disable the block count for single block transactions */ +#define SDHCI_QUIRK2_SUPPORT_SINGLE (1<<13) int irq; /* Device IRQ */ void __iomem *ioaddr; /* Mapped address */ -- cgit v1.2.3-70-g09d2