diff options
author | Wen Yi <wyi@nvidia.com> | 2011-04-18 14:21:25 -0700 |
---|---|---|
committer | Manish Tuteja <mtuteja@nvidia.com> | 2011-07-20 04:12:17 -0700 |
commit | c4d1c6a62dba8e530132f799fa65bd8bad28c25d (patch) | |
tree | d0fb2fc83dbcab3324c49a75f9ff226b81b412e4 /arch | |
parent | 2f0bf1bcfce76eb5ea460e32dd2eb826695718c8 (diff) |
arm: tegra: whistler/ventana: dynamic cpufreq governor
To improve the power consumption situation for MP3 playback
the scaling governor is set to conservative when display
is turned off and the default governor is saved. The governor
is restored when display is turned on.
Bug 817727
Change-Id: I2184b422b6e25504a0fb7d78573c748599256908
Reviewed-on: http://git-master/r/28270
Reviewed-on: http://git-master/r/37936
Reviewed-by: Manish Tuteja <mtuteja@nvidia.com>
Tested-by: Manish Tuteja <mtuteja@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/board-ventana-panel.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-whistler-panel.c | 10 | ||||
-rwxr-xr-x | arch/arm/mach-tegra/common.c | 72 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/tegra_cpufreq.h | 26 |
4 files changed, 116 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-ventana-panel.c b/arch/arm/mach-tegra/board-ventana-panel.c index 7b1b48529542..7cdd499ac93f 100644 --- a/arch/arm/mach-tegra/board-ventana-panel.c +++ b/arch/arm/mach-tegra/board-ventana-panel.c @@ -32,6 +32,7 @@ #include <mach/iomap.h> #include <mach/dc.h> #include <mach/fb.h> +#include <mach/tegra_cpufreq.h> #include "devices.h" #include "gpio-names.h" @@ -337,6 +338,10 @@ static void ventana_panel_early_suspend(struct early_suspend *h) unsigned i; for (i = 0; i < num_registered_fb; i++) fb_blank(registered_fb[i], FB_BLANK_POWERDOWN); +#ifdef CONFIG_CPU_FREQ + cpufreq_save_default_governor(); + cpufreq_set_conservative_governor(); +#endif } static void ventana_panel_late_resume(struct early_suspend *h) @@ -344,6 +349,9 @@ static void ventana_panel_late_resume(struct early_suspend *h) unsigned i; for (i = 0; i < num_registered_fb; i++) fb_blank(registered_fb[i], FB_BLANK_UNBLANK); +#ifdef CONFIG_CPU_FREQ + cpufreq_restore_default_governor(); +#endif } #endif diff --git a/arch/arm/mach-tegra/board-whistler-panel.c b/arch/arm/mach-tegra/board-whistler-panel.c index ddcc611e9a65..2e9e6a833155 100644 --- a/arch/arm/mach-tegra/board-whistler-panel.c +++ b/arch/arm/mach-tegra/board-whistler-panel.c @@ -25,6 +25,7 @@ #include <asm/mach-types.h> #include <linux/platform_device.h> #include <linux/earlysuspend.h> +#include <linux/kernel.h> #include <linux/pwm_backlight.h> #include <linux/tegra_pwm_bl.h> #include <mach/nvhost.h> @@ -33,6 +34,7 @@ #include <mach/iomap.h> #include <mach/dc.h> #include <mach/fb.h> +#include <mach/tegra_cpufreq.h> #include "devices.h" #include "gpio-names.h" @@ -298,12 +300,20 @@ static void whistler_panel_early_suspend(struct early_suspend *h) { if (num_registered_fb > 0) fb_blank(registered_fb[0], FB_BLANK_POWERDOWN); +#ifdef CONFIG_CPU_FREQ + cpufreq_save_default_governor(); + cpufreq_set_conservative_governor(); +#endif } static void whistler_panel_late_resume(struct early_suspend *h) { if (num_registered_fb > 0) fb_blank(registered_fb[0], FB_BLANK_UNBLANK); + +#ifdef CONFIG_CPU_FREQ + cpufreq_restore_default_governor(); +#endif } #endif diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index 08378e96f686..c0357c09a17b 100755 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c @@ -36,6 +36,7 @@ #include <mach/dma.h> #include <mach/powergate.h> #include <mach/system.h> +#include <mach/tegra_cpufreq.h> #include "apbio.h" #include "board.h" @@ -499,3 +500,74 @@ void __init tegra_reserve(unsigned long carveout_size, unsigned long fb_size, tegra_carveout_start, tegra_carveout_start + tegra_carveout_size - 1); } + +#if defined CONFIG_HAS_EARLYSUSPEND && defined CONFIG_CPU_FREQ +static char cpufreq_gov_default[32]; +static char *cpufreq_gov_conservative = "conservative"; +static char *cpufreq_sysfs_place_holder="/sys/devices/system/cpu/cpu%i/cpufreq/scaling_governor"; + +static void cpufreq_set_governor(char *governor) +{ + struct file *scaling_gov = NULL; + char buf[128]; + int i; + loff_t offset = 0; + + if (governor == NULL) + return; + + for_each_cpu(i, cpu_present_mask) { + sprintf(buf, cpufreq_sysfs_place_holder, i); + scaling_gov = filp_open(buf, O_RDWR, 0); + if (scaling_gov != NULL) { + if (scaling_gov->f_op != NULL && + scaling_gov->f_op->write != NULL) + scaling_gov->f_op->write(scaling_gov, + governor, + strlen(governor), + &offset); + else + pr_err("f_op might be null\n"); + + filp_close(scaling_gov, NULL); + } else { + pr_err("%s. Can't open %s\n", __func__, buf); + } + } +} + +void cpufreq_save_default_governor(void) +{ + struct file *scaling_gov = NULL; + char buf[128]; + loff_t offset = 0; + + buf[127] = 0; + sprintf(buf, cpufreq_sysfs_place_holder,0); + scaling_gov = filp_open(buf, O_RDONLY, 0); + if (scaling_gov != NULL) { + if (scaling_gov->f_op != NULL && + scaling_gov->f_op->read != NULL) + scaling_gov->f_op->read(scaling_gov, + cpufreq_gov_default, + 127, + &offset); + else + pr_err("f_op might be null\n"); + + filp_close(scaling_gov, NULL); + } else { + pr_err("%s. Can't open %s\n", __func__, buf); + } +} + +void cpufreq_restore_default_governor(void) +{ + cpufreq_set_governor(cpufreq_gov_default); +} + +void cpufreq_set_conservative_governor(void) +{ + cpufreq_set_governor(cpufreq_gov_conservative); +} +#endif diff --git a/arch/arm/mach-tegra/include/mach/tegra_cpufreq.h b/arch/arm/mach-tegra/include/mach/tegra_cpufreq.h new file mode 100644 index 000000000000..63ba3a056f75 --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/tegra_cpufreq.h @@ -0,0 +1,26 @@ +/* + * arch/arm/mach-tegra/include/mach/tegra_cpufreq.h + * + * Copyright (c) 2011, NVIDIA Corporation. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __MACH_TEGRA_CPUFREQ_H +#define __MACH_TEGRA_CPUFREQ_H + +#if defined CONFIG_HAS_EARLYSUSPEND && defined CONFIG_CPU_FREQ +void cpufreq_save_default_governor(void); +void cpufreq_restore_default_governor(void); +void cpufreq_set_conservative_governor(void); +#endif + +#endif |