mmc: msm_sdcc: Set CPU_DMA latency for acceptable QOS
To prevent speed degradation in high throughput
scenarios, specify CPU_DMA latency which gives
acceptable QOS. This should be derived without
knowledge of specific low power mode latencies.
For MMC/SD cards, reads tend to be the fastest
transactions, and suffer most from latency. To
ensure acceptable QOS, the average chunk size read
is used with typical best-in-class read speeds
seen across targets and cards.
With an average chunk size of 128KiB transferred
at 30MB/s, a 5% degradation in speed allows for
an additional 200us latency. This default can
be overridden by newer targets with more stringent
latency requirements.
Change-Id: I77d320d2b5e34e3b72ba41ed25454ece042eeddb
Signed-off-by: Oluwafemi Adeyemi <aadeyemi@codeaurora.org>
diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h
index 7a5b21a..dabd390 100644
--- a/arch/arm/include/asm/mach/mmc.h
+++ b/arch/arm/include/asm/mach/mmc.h
@@ -152,7 +152,7 @@
bool disable_bam;
bool disable_runtime_pm;
bool disable_cmd23;
- u32 swfi_latency;
+ u32 cpu_dma_latency;
};
#endif
diff --git a/arch/arm/mach-msm/board-8064-storage.c b/arch/arm/mach-msm/board-8064-storage.c
index 275c893..d91408a 100644
--- a/arch/arm/mach-msm/board-8064-storage.c
+++ b/arch/arm/mach-msm/board-8064-storage.c
@@ -271,14 +271,11 @@
apq8064_sdc3_pdata->disable_cmd23 = true;
}
}
- if (apq8064_sdc1_pdata) {
- apq8064_sdc1_pdata->swfi_latency =
- apq8064_rpm_get_swfi_latency();
+
+ if (apq8064_sdc1_pdata)
apq8064_add_sdcc(1, apq8064_sdc1_pdata);
- }
+
if (apq8064_sdc3_pdata) {
- apq8064_sdc3_pdata->swfi_latency =
- apq8064_rpm_get_swfi_latency();
if (!machine_is_apq8064_cdp()) {
apq8064_sdc3_pdata->wpswitch_gpio = 0;
apq8064_sdc3_pdata->wpswitch_polarity = 0;
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 322b353..2fa4973 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1602,19 +1602,6 @@
},
};
-uint32_t apq8064_rpm_get_swfi_latency(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(msm_rpmrs_levels); i++) {
- if (msm_rpmrs_levels[i].sleep_mode ==
- MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)
- return msm_rpmrs_levels[i].latency_us;
- }
-
- return 0;
-}
-
static struct msm_pm_boot_platform_data msm_pm_boot_pdata __initdata = {
.mode = MSM_PM_BOOT_CONFIG_TZ,
};
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index f62a9fb..3729385 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -86,7 +86,6 @@
void apq8064_init_fb(void);
void apq8064_allocate_fb_region(void);
void apq8064_mdp_writeback(struct memtype_reserve *reserve_table);
-uint32_t apq8064_rpm_get_swfi_latency(void);
void __init apq8064_set_display_params(char *prim_panel, char *ext_panel);
void apq8064_init_gpu(void);
diff --git a/arch/arm/mach-msm/board-8960-storage.c b/arch/arm/mach-msm/board-8960-storage.c
index cd53f83..f39a691 100644
--- a/arch/arm/mach-msm/board-8960-storage.c
+++ b/arch/arm/mach-msm/board-8960-storage.c
@@ -266,12 +266,10 @@
void __init msm8960_init_mmc(void)
{
#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
- msm8960_sdc1_data.swfi_latency = msm_rpm_get_swfi_latency();
/* SDC1 : eMMC card connected */
msm_add_sdcc(1, &msm8960_sdc1_data);
#endif
#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
- msm8960_sdc3_data.swfi_latency = msm_rpm_get_swfi_latency();
/* SDC3: External card slot */
msm_add_sdcc(3, &msm8960_sdc3_data);
#endif
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index c294919..0f83b53 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -2824,19 +2824,6 @@
.mode = MSM_PM_BOOT_CONFIG_TZ,
};
-uint32_t msm_rpm_get_swfi_latency(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(msm_rpmrs_levels); i++) {
- if (msm_rpmrs_levels[i].sleep_mode ==
- MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)
- return msm_rpmrs_levels[i].latency_us;
- }
-
- return 0;
-}
-
#ifdef CONFIG_I2C
#define I2C_SURF 1
#define I2C_FFA (1 << 1)
diff --git a/arch/arm/mach-msm/board-8960.h b/arch/arm/mach-msm/board-8960.h
index dea957c..3824cfd 100644
--- a/arch/arm/mach-msm/board-8960.h
+++ b/arch/arm/mach-msm/board-8960.h
@@ -84,7 +84,6 @@
void msm8960_set_display_params(char *prim_panel, char *ext_panel);
void msm8960_pm8921_gpio_mpp_init(void);
void msm8960_mdp_writeback(struct memtype_reserve *reserve_table);
-uint32_t msm_rpm_get_swfi_latency(void);
#define PLATFORM_IS_CHARM25() \
(machine_is_msm8960_cdp() && \
(socinfo_get_platform_subtype() == 1) \
diff --git a/arch/arm/mach-msm/board-9615-storage.c b/arch/arm/mach-msm/board-9615-storage.c
index 6bf7c69..7580cc3 100644
--- a/arch/arm/mach-msm/board-9615-storage.c
+++ b/arch/arm/mach-msm/board-9615-storage.c
@@ -214,19 +214,13 @@
void __init msm9615_init_mmc(void)
{
- if (msm9615_sdc1_pdata) {
- msm9615_sdc1_pdata->swfi_latency =
- msm9615_rpm_get_swfi_latency();
+ if (msm9615_sdc1_pdata)
/* SDC1: External card slot for SD/MMC cards */
msm_add_sdcc(1, msm9615_sdc1_pdata);
- }
- if (msm9615_sdc2_pdata) {
- msm9615_sdc2_pdata->swfi_latency =
- msm9615_rpm_get_swfi_latency();
+ if (msm9615_sdc2_pdata)
/* SDC2: External card slot used for WLAN */
msm_add_sdcc(2, msm9615_sdc2_pdata);
- }
}
#else
void __init msm9615_init_mmc(void)
diff --git a/arch/arm/mach-msm/board-9615.h b/arch/arm/mach-msm/board-9615.h
index 239453f..7dd003f 100644
--- a/arch/arm/mach-msm/board-9615.h
+++ b/arch/arm/mach-msm/board-9615.h
@@ -36,7 +36,6 @@
#define GPIO_VREG_ID_EXT_2P95V 0
extern struct gpio_regulator_platform_data msm_gpio_regulator_pdata[];
-uint32_t msm9615_rpm_get_swfi_latency(void);
int msm9615_init_gpiomux(void);
void msm9615_init_mmc(void);
diff --git a/arch/arm/mach-msm/board-msm7627a-storage.c b/arch/arm/mach-msm/board-msm7627a-storage.c
index 11d9a21..946e109 100644
--- a/arch/arm/mach-msm/board-msm7627a-storage.c
+++ b/arch/arm/mach-msm/board-msm7627a-storage.c
@@ -374,8 +374,6 @@
if (!(machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7())) {
if (mmc_regulator_init(3, "emmc", 3000000))
return;
- sdc3_plat_data.swfi_latency = msm7627a_power_collapse_latency(
- MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT);
msm_add_sdcc(3, &sdc3_plat_data);
}
#endif
@@ -385,8 +383,6 @@
if (mmc_regulator_init(1, "mmc", 2850000))
return;
sdc1_plat_data.status_irq = MSM_GPIO_TO_INT(gpio_sdc1_hw_det);
- sdc1_plat_data.swfi_latency = msm7627a_power_collapse_latency(
- MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT);
msm_add_sdcc(1, &sdc1_plat_data);
#endif
/* SDIO WLAN slot */
diff --git a/arch/arm/mach-msm/board-msm7627a.h b/arch/arm/mach-msm/board-msm7627a.h
index 68e333f..413a28c 100644
--- a/arch/arm/mach-msm/board-msm7627a.h
+++ b/arch/arm/mach-msm/board-msm7627a.h
@@ -103,7 +103,6 @@
#endif
void __init msm7627a_camera_init(void);
-u32 msm7627a_power_collapse_latency(enum msm_pm_sleep_mode);
void __init msm7627a_add_io_devices(void);
void __init qrd7627a_add_io_devices(void);
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index c3650fa..f1960ce 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -360,26 +360,6 @@
},
};
-u32 msm7627a_power_collapse_latency(enum msm_pm_sleep_mode mode)
-{
- switch (mode) {
- case MSM_PM_SLEEP_MODE_POWER_COLLAPSE:
- return msm7x27a_pm_data
- [MSM_PM_SLEEP_MODE_POWER_COLLAPSE].latency;
- case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN:
- return msm7x27a_pm_data
- [MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN].latency;
- case MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT:
- return msm7x27a_pm_data
- [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].latency;
- case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
- return msm7x27a_pm_data
- [MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT].latency;
- default:
- return 0;
- }
-}
-
static struct msm_pm_boot_platform_data msm_pm_boot_pdata __initdata = {
.mode = MSM_PM_BOOT_CONFIG_RESET_VECTOR_PHYS,
.p_addr = 0,
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index 3973bd1..6bc21bb 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -3173,26 +3173,6 @@
},
};
-u32 msm7x30_power_collapse_latency(enum msm_pm_sleep_mode mode)
-{
- switch (mode) {
- case MSM_PM_SLEEP_MODE_POWER_COLLAPSE:
- return msm_pm_data
- [MSM_PM_SLEEP_MODE_POWER_COLLAPSE].latency;
- case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN:
- return msm_pm_data
- [MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN].latency;
- case MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT:
- return msm_pm_data
- [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].latency;
- case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
- return msm_pm_data
- [MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT].latency;
- default:
- return 0;
- }
-}
-
static struct msm_pm_boot_platform_data msm_pm_boot_pdata __initdata = {
.mode = MSM_PM_BOOT_CONFIG_RESET_VECTOR_VIRT,
.v_addr = (uint32_t *)PAGE_OFFSET,
@@ -6401,8 +6381,6 @@
#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
if (mmc_regulator_init(1, "s3", 1800000))
goto out1;
- msm7x30_sdc1_data.swfi_latency = msm7x30_power_collapse_latency(
- MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT);
if (machine_is_msm7x30_fluid()) {
msm7x30_sdc1_data.ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29;
@@ -6418,8 +6396,6 @@
#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
if (mmc_regulator_init(2, "s3", 1800000))
goto out2;
- msm7x30_sdc2_data.swfi_latency = msm7x30_power_collapse_latency(
- MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT);
if (machine_is_msm8x55_svlte_surf())
msm7x30_sdc2_data.msmsdcc_fmax = 24576000;
@@ -6435,8 +6411,6 @@
#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
if (mmc_regulator_init(3, "s3", 1800000))
goto out3;
- msm7x30_sdc3_data.swfi_latency = msm7x30_power_collapse_latency(
- MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT);
msm_sdcc_setup_gpio(3, 1);
msm_add_sdcc(3, &msm7x30_sdc3_data);
@@ -6445,8 +6419,6 @@
#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
if (mmc_regulator_init(4, "mmc", 2850000))
return;
- msm7x30_sdc4_data.swfi_latency = msm7x30_power_collapse_latency(
- MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT);
msm_add_sdcc(4, &msm7x30_sdc4_data);
#endif
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index 60bcdce..34298c5 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -1247,18 +1247,6 @@
},
};
-uint32_t __init msm9615_rpm_get_swfi_latency(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(msm_rpmrs_levels); i++) {
- if (msm_rpmrs_levels[i].sleep_mode ==
- MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)
- return msm_rpmrs_levels[i].latency_us;
- }
- return 0;
-}
-
void __init msm9615_device_init(void)
{
msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 318c319..0e096eb 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -168,16 +168,12 @@
/* Prevent idle power collapse(pc) while operating in peripheral mode */
static void msmsdcc_pm_qos_update_latency(struct msmsdcc_host *host, int vote)
{
- u32 swfi_latency = 0;
-
- if (!host->plat->swfi_latency)
+ if (!host->cpu_dma_latency)
return;
- swfi_latency = host->plat->swfi_latency + 1;
-
if (vote)
pm_qos_update_request(&host->pm_qos_req_dma,
- swfi_latency);
+ host->cpu_dma_latency);
else
pm_qos_update_request(&host->pm_qos_req_dma,
PM_QOS_DEFAULT_VALUE);
@@ -4543,9 +4539,13 @@
/* Apply Hard reset to SDCC to put it in power on default state */
msmsdcc_hard_reset(host);
+#define MSM_MMC_DEFAULT_CPUDMA_LATENCY 200 /* usecs */
/* pm qos request to prevent apps idle power collapse */
- if (host->plat->swfi_latency)
- pm_qos_add_request(&host->pm_qos_req_dma,
+ if (host->plat->cpu_dma_latency)
+ host->cpu_dma_latency = host->plat->cpu_dma_latency;
+ else
+ host->cpu_dma_latency = MSM_MMC_DEFAULT_CPUDMA_LATENCY;
+ pm_qos_add_request(&host->pm_qos_req_dma,
PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
ret = msmsdcc_vreg_init(host, true);
@@ -4831,7 +4831,7 @@
msmsdcc_vreg_init(host, false);
clk_disable:
clk_disable(host->clk);
- if (host->plat->swfi_latency)
+ if (host->cpu_dma_latency)
pm_qos_remove_request(&host->pm_qos_req_dma);
clk_put:
clk_put(host->clk);
@@ -4905,7 +4905,7 @@
if (!IS_ERR_OR_NULL(host->dfab_pclk))
clk_put(host->dfab_pclk);
- if (host->plat->swfi_latency)
+ if (host->cpu_dma_latency)
pm_qos_remove_request(&host->pm_qos_req_dma);
msmsdcc_vreg_init(host, false);
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index 406af4f..50477da 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -395,6 +395,7 @@
bool sdio_gpio_lpm;
bool irq_wake_enabled;
struct pm_qos_request_list pm_qos_req_dma;
+ u32 cpu_dma_latency;
bool sdcc_suspending;
bool sdcc_irq_disabled;
bool sdcc_suspended;