From de1c81cf2d50cba25e3ed399d3fe6c412781827f Mon Sep 17 00:00:00 2001 From: Vishwanath BS Date: Wed, 9 Feb 2011 16:27:44 +0530 Subject: OMAP3: cpufreq driver changes for DVFS support Changes in the omap cpufreq driver for DVFS support. Signed-off-by: Vishwanath BS --- arch/arm/plat-omap/cpu-omap.c | 69 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c index 11c54ec8d47..73452c700da 100644 --- a/arch/arm/plat-omap/cpu-omap.c +++ b/arch/arm/plat-omap/cpu-omap.c @@ -8,6 +8,10 @@ * * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King * + * Copyright (C) 2007-2008 Texas Instruments, Inc. + * Updated to support OMAP3 + * Rajendra Nayak + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. @@ -21,10 +25,18 @@ #include #include #include +#include #include #include #include +#include + +#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE) +#include +#include +#include +#endif #define VERY_HI_RATE 900000000 @@ -32,6 +44,8 @@ static struct cpufreq_frequency_table *freq_table; #ifdef CONFIG_ARCH_OMAP1 #define MPU_CLK "mpu" +#elif defined(CONFIG_ARCH_OMAP3) +#define MPU_CLK "arm_fck" #else #define MPU_CLK "virt_prcm_set" #endif @@ -74,6 +88,12 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int relation) { struct cpufreq_freqs freqs; +#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE) + unsigned long freq; + int i; + struct cpufreq_freqs freqs_notify; + struct device *mpu_dev = omap2_get_mpuss_device(); +#endif int ret = 0; /* Ensure desired rate is within allowed range. Some govenors @@ -83,13 +103,13 @@ static int omap_target(struct cpufreq_policy *policy, if (target_freq > policy->max) target_freq = policy->max; +#ifdef CONFIG_ARCH_OMAP1 freqs.old = omap_getspeed(0); freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; freqs.cpu = 0; if (freqs.old == freqs.new) return ret; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); #ifdef CONFIG_CPU_FREQ_DEBUG printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n", @@ -97,7 +117,39 @@ static int omap_target(struct cpufreq_policy *policy, #endif ret = clk_set_rate(mpu_clk, freqs.new * 1000); cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); +#elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE) + freqs.old = omap_getspeed(policy->cpu);; + freqs_notify.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; + freqs.cpu = policy->cpu; + if (freqs.old == freqs.new) + return ret; + + /* pre notifiers */ + for_each_cpu(i, policy->cpus) { + freqs.cpu = i; + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + } + + /* scale the frequency */ + freq = target_freq * 1000; + if (opp_find_freq_ceil(mpu_dev, &freq)) + omap_device_scale(mpu_dev, mpu_dev, freq); + +#ifdef CONFIG_SMP + /* Update loops per jiffy */ + freqs.new = omap_getspeed(policy->cpu); + for_each_cpu(i, policy->cpus) + per_cpu(cpu_data, i).loops_per_jiffy = + cpufreq_scale(per_cpu(cpu_data, i).loops_per_jiffy, + freqs.old, freqs.new); +#endif + /* post notifiers */ + for_each_cpu(i, policy->cpus) { + freqs.cpu = i; + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + } +#endif return ret; } @@ -114,7 +166,14 @@ static int __init omap_cpu_init(struct cpufreq_policy *policy) policy->cur = policy->min = policy->max = omap_getspeed(0); - clk_init_cpufreq_table(&freq_table); + if (!cpu_is_omap34xx()) { + clk_init_cpufreq_table(&freq_table); + } else { + struct device *mpu_dev = omap2_get_mpuss_device(); + + opp_init_cpufreq_table(mpu_dev, &freq_table); + } + if (freq_table) { result = cpufreq_frequency_table_cpuinfo(policy, freq_table); if (!result) @@ -126,6 +185,10 @@ static int __init omap_cpu_init(struct cpufreq_policy *policy) VERY_HI_RATE) / 1000; } + policy->min = policy->cpuinfo.min_freq; + policy->max = policy->cpuinfo.max_freq; + policy->cur = omap_getspeed(0); + /* FIXME: what's the actual transition time? */ policy->cpuinfo.transition_latency = 300 * 1000; @@ -160,7 +223,7 @@ static int __init omap_cpufreq_init(void) return cpufreq_register_driver(&omap_driver); } -arch_initcall(omap_cpufreq_init); +late_initcall(omap_cpufreq_init); /* * if ever we want to remove this, upon cleanup call: -- cgit v1.2.3