diff options
-rw-r--r-- | arch/arm/mach-tegra/board-nvodm.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-tegra/cpuidle.c | 36 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_clock_config.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_power_dfs.h | 4 |
5 files changed, 34 insertions, 15 deletions
diff --git a/arch/arm/mach-tegra/board-nvodm.c b/arch/arm/mach-tegra/board-nvodm.c index bcaaef41864a..44a9863d8f37 100644 --- a/arch/arm/mach-tegra/board-nvodm.c +++ b/arch/arm/mach-tegra/board-nvodm.c @@ -1408,6 +1408,7 @@ static void __init tegra_setup_suspend(void) do_register: tegra_init_suspend(plat); + tegra_init_idle(plat); } void __init tegra_setup_nvodm(bool standard_i2c, bool standard_spi) diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h index a5cf92369052..d3e4f7e67fc4 100644 --- a/arch/arm/mach-tegra/board.h +++ b/arch/arm/mach-tegra/board.h @@ -32,6 +32,12 @@ void __init tegra_init_irq(void); void __init tegra_init_clock(void); void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat); +#ifdef CONFIG_CPU_IDLE +void __init tegra_init_idle(struct tegra_suspend_platform_data *plat); +#else +#define tegra_init_idle(plat) (0) +#endif + #ifdef CONFIG_CPU_FREQ int tegra_start_dvfsd(void); #else diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c index f2b98f496885..bd752459924b 100644 --- a/arch/arm/mach-tegra/cpuidle.c +++ b/arch/arm/mach-tegra/cpuidle.c @@ -33,7 +33,12 @@ #include <mach/iomap.h> #include <linux/suspend.h> -static unsigned int latency_factor __read_mostly = 2; +#include "power.h" + +#define LATENCY_FACTOR_SHIFT 8 + +static unsigned int latency_factor __read_mostly = 80; // factor ~ 0.3 +static unsigned int pwrgood_latency = 2000; static unsigned int system_is_suspending = 0; module_param(latency_factor, uint, 0644); @@ -56,6 +61,11 @@ static int lp2_supported = 0; #define CLK_RESET_CLK_MASK_ARM 0x44 +void __init tegra_init_idle(struct tegra_suspend_platform_data *plat) +{ + pwrgood_latency = plat->cpu_timer; +} + static int tegra_idle_enter_lp3(struct cpuidle_device *dev, struct cpuidle_state *state) { @@ -93,16 +103,17 @@ extern unsigned int tegra_suspend_lp2(unsigned int); static int tegra_idle_enter_lp2(struct cpuidle_device *dev, struct cpuidle_state *state) { - ktime_t enter, exit; - s64 request, us, latency; + ktime_t enter; + s64 request, us, latency, idle_us; unsigned long log_us; void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); unsigned int last_sample = (unsigned int)cpuidle_get_statedata(state); /* LP2 not possible when running in SMP mode */ smp_rmb(); + idle_us = state->exit_latency + state->target_residency; request = ktime_to_us(tick_nohz_get_sleep_length()); - if (!lp2_supported || request <= state->exit_latency || + if (!lp2_supported || request <= idle_us || system_is_suspending || (!tegra_nvrm_lp2_allowed())) { dev->last_state = &dev->states[0]; return tegra_idle_enter_lp3(dev, &dev->states[0]); @@ -112,19 +123,19 @@ static int tegra_idle_enter_lp2(struct cpuidle_device *dev, enter = ktime_get(); request -= state->exit_latency; us = tegra_suspend_lp2((unsigned int)max_t(s64, 200, request)); - exit = ktime_sub(ktime_get(), enter); - latency = ktime_to_us(exit) - us; - /* FIXME: un-hardcode the powergood timer latency */ - latency += 2000; + idle_us = ktime_to_us(ktime_sub(ktime_get(), enter)); + + latency = pwrgood_latency + idle_us - us; cpuidle_set_statedata(state, (void*)(unsigned int)(latency)); state->exit_latency = (12*latency + 4*last_sample) >> 4; + state->target_residency = (latency_factor*state->exit_latency) >> + LATENCY_FACTOR_SHIFT; log_us = (unsigned long)us + __raw_readl(pmc + PMC_SCRATCH_21); __raw_writel(log_us, pmc + PMC_SCRATCH_21); - state->target_residency = latency_factor*state->exit_latency; local_irq_enable(); - return (int)us; + return (int)idle_us; } static int tegra_idle_lp2_allowed(struct notifier_block *nfb, @@ -183,7 +194,7 @@ static int tegra_idle_enter(unsigned int cpu) snprintf(state->name, CPUIDLE_NAME_LEN, "LP3"); snprintf(state->desc, CPUIDLE_DESC_LEN, "CPU flow-controlled"); state->exit_latency = 10; - state->target_residency = 10; + state->target_residency = 0; state->power_usage = 600; state->flags = CPUIDLE_FLAG_SHALLOW | CPUIDLE_FLAG_TIME_VALID; state->enter = tegra_idle_enter_lp3; @@ -196,7 +207,8 @@ static int tegra_idle_enter(unsigned int cpu) snprintf(state->desc, CPUIDLE_DESC_LEN, "CPU power-gate"); state->exit_latency = 2500; - state->target_residency = state->exit_latency * latency_factor; + state->target_residency = (state->exit_latency * + latency_factor) >> LATENCY_FACTOR_SHIFT; state->power_usage = 0; state->flags = CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_TIME_VALID; state->enter = tegra_idle_enter_lp2; diff --git a/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_clock_config.c b/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_clock_config.c index 76153ab71602..8a86fc2776aa 100644 --- a/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_clock_config.c +++ b/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_clock_config.c @@ -300,7 +300,7 @@ static NvRmFreqKHz Ap20CpuToEmcRatio(NvRmFreqKHz Emc2xKHz) 7, 10, 11, 13, 14, 15, 17, 18, 18, 19, 20, 21, 22, 22, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32 }; - #define CPU_TO_EMC_MAX_RATIO (10) + #define CPU_TO_EMC_MAX_RATIO (12) NvRmFreqKHz CpuKHz; NvRmFreqKHz CpuMaxKHz = NvRmPrivGetSocClockLimits(NvRmModuleID_Cpu)->MaxKHz; diff --git a/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_power_dfs.h b/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_power_dfs.h index 7b387a61c07f..8b5c9d4ded39 100644 --- a/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_power_dfs.h +++ b/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_power_dfs.h @@ -58,7 +58,7 @@ extern "C" */ #define NVRM_DFS_PARAM_CPU_AP20 \ NvRmFreqMaximum, /* Maximum domain frequency set to h/w limit */ \ - 40000, /* Minimum domain frequency 40 MHz */ \ + 216000, /* Minimum domain frequency 216 MHz */ \ 1000, /* Frequency change upper band 1 MHz */ \ 1000, /* Frequency change lower band 1 MHz */ \ { /* RT starvation control parameters */ \ @@ -71,7 +71,7 @@ extern "C" 255, /* Proportional frequency boost increase 255/256 ~ 100% */ \ 32, /* Proportional frequency boost decrease 32/256 ~ 12% */ \ },\ - 3, /* Relative adjustement of average freqiency 1/2^3 ~ 12% */ \ + 2, /* Relative adjustement of average freqiency 1/2^2 ~ 25% */ \ 1, /* Number of smaple intervals with NRT to trigger boost = 2 */ \ 1 /* NRT idle cycles threshold = 1 */ |