msm: 9615: storage: vote against IDLE power collapse
During the SDCC DMA transfer, if DMA transfer time is
long enough to do IDLE power collapse then system may
go into IDLE power collapse and once SDCC DMA transfer
is completed, system wakes up from Idle Power Collapse
due to SDCC DMA interrupt. But delay for waking up
from Idle Power collapse could be as large as 5 ms which
really degrades the overall read & write throughputs
for SD/eMMC/SDIO cards.
For example, following are the performance numbers with
eMMC card on MSM8960 platform with and without Idle Power
Collapse.
Idle Power collapse enabled:
LMDD Read throughput = ~14 MB/s
LMDD Write throughput = ~6 MB/s
Idle Power Collapse disabled:
LMDD Read throughput = ~25 MB/s
LMDD Write throughput = ~8 MB/s
So this change votes against the Idle power collapse by registering
with PM QOS about it's acceptable DMA latency when SDCC transfer is
active. This latency value is one more than the latency of SWFI
which means system can go into SWFI but not in any of the other
low power modes (including Idle power collapse).
Change-Id: I2c8de5e9b4204468f9166aea7bcdee5b70ed62b1
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
Signed-off-by: Krishna Konda <kkonda@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-9615-storage.c b/arch/arm/mach-msm/board-9615-storage.c
index 95c87bf..5a795c0 100644
--- a/arch/arm/mach-msm/board-9615-storage.c
+++ b/arch/arm/mach-msm/board-9615-storage.c
@@ -21,6 +21,8 @@
#include <mach/gpiomux.h>
#include "devices.h"
+#include "board-9615.h"
+
#if (defined(CONFIG_MMC_MSM_SDC1_SUPPORT) \
|| defined(CONFIG_MMC_MSM_SDC2_SUPPORT))
@@ -212,11 +214,15 @@
void __init msm9615_init_mmc(void)
{
if (msm9615_sdc1_pdata) {
+ msm9615_sdc1_pdata->swfi_latency =
+ msm9615_rpm_get_swfi_latency();
/* 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();
/* SDC2: External card slot used for WLAN */
msm_add_sdcc(2, msm9615_sdc2_pdata);
}
diff --git a/arch/arm/mach-msm/board-9615.h b/arch/arm/mach-msm/board-9615.h
index 4759f8c..27f5d81 100644
--- a/arch/arm/mach-msm/board-9615.h
+++ b/arch/arm/mach-msm/board-9615.h
@@ -36,6 +36,7 @@
#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/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index 8894b4b..331fc26 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -1098,6 +1098,18 @@
},
};
+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));