board: 8064: 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: I8740dd5bb86fe8cfbf6a294850d378a3c6692f40
Signed-off-by: Oluwafemi Adeyemi <aadeyemi@codeaurora.org>
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-8064-storage.c b/arch/arm/mach-msm/board-8064-storage.c
index e9c455d..cdafdfc 100644
--- a/arch/arm/mach-msm/board-8064-storage.c
+++ b/arch/arm/mach-msm/board-8064-storage.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -263,6 +263,14 @@
apq8064_sdc3_pdata->disable_cmd23 = true;
}
}
- apq8064_add_sdcc(1, apq8064_sdc1_pdata);
- apq8064_add_sdcc(3, apq8064_sdc3_pdata);
+ if (apq8064_sdc1_pdata) {
+ apq8064_sdc1_pdata->swfi_latency =
+ apq8064_rpm_get_swfi_latency();
+ apq8064_add_sdcc(1, apq8064_sdc1_pdata);
+ }
+ if (apq8064_sdc3_pdata) {
+ apq8064_sdc3_pdata->swfi_latency =
+ apq8064_rpm_get_swfi_latency();
+ apq8064_add_sdcc(3, apq8064_sdc3_pdata);
+ }
}
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 35f17ce..2bb2702 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1191,7 +1191,7 @@
},
};
-static struct msm_rpmrs_level msm_rpmrs_levels[] __initdata = {
+static struct msm_rpmrs_level msm_rpmrs_levels[] = {
{
MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT,
MSM_RPMRS_LIMITS(ON, ACTIVE, MAX, ACTIVE),
@@ -1255,6 +1255,19 @@
},
};
+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 e8c8144..c19a039 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -72,6 +72,7 @@
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 apq8064_init_gpu(void);
void apq8064_pm8xxx_gpio_mpp_init(void);