From f6b96e3b9e31da193189d92320b3dd9fac7c9ba9 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Mon, 10 Nov 2008 17:00:25 +0530 Subject: [PATCH 04/20] OMAP3 PM: CPUFreq driver for OMAP3 CPUFreq driver for OMAP3 With additional fixes and cleanups from Tero Kristo: - Fix rate calculation bug in omap3_select_table_rate - Refreshed DVFS VDD1 control against latest clock fw Signed-off-by: Tero Kristo Signed-off-by: Rajendra Nayak OMAP3: PM: CPUFreq: Fix omap_getspeed. Signed-off-by: Peter 'p2' De Schrijver Make sure omap cpufreq driver initializes after cpufreq framework and governors Signed-off-by: Peter 'p2' De Schrijver merge: CPUFreq: remove obsolete funcs OMAP3 clock: Update cpufreq driver This patch removes all refrences to virtual clock nodes in CPUFreq driver. Signed-off-by: Rajendra Nayak Signed-off-by: Tero Kristo Signed-off-by: Jean Pihet PM: Prevent direct cpufreq scaling during initialization It is seen that the OMAP specific cpufreq initialization code tries to scale the MPU frequency to the highest possible without taking care of the voltage level. On power on reset the power IC does not provide the necessary voltage for the highest available MPU frequency (that would satisfy all Si families). This potentially is an window of opportunity for things to go wrong. Signed-off-by: Romit Dasgupta Signed-off-by: Kevin Hilman OMAP3: PM: enable 600MHz (overdrive) OPP Signed-off-by: Kevin Hilman omap3: introduce cpufreq OMAP OPP layer functions now have dependencies of CONFIG_CPU_FREQ only. With this patch, omap opp layer now has its compilation flags bound to CONFIG_CPU_FREQ. Also its code has been removed from pm34xx.c. A new file has been created to contain cpu freq code related to OMAP3: cpufreq34xx.c OMAP34xx and OMAP36xx family OPPs are made available Signed-off-by: Eduardo Valentin Signed-off-by: Paul Walmsley Signed-off-by: Nishanth Menon Signed-off-by: Vishwanath BS Signed-off-by: Kevin Hilman Signed-off-by: Romit Dasgupta Signed-off-by: Rajendra Nayak omap3: cpufreq: allow default opp table init For board files which choose to override the defaults, the existing mechanism will work, for boards that would like to work with defaults, allow init_common_hw to call init_opp_table to initialize if not already initialized. this will allow all omap boards which have opp tables predefined for a silicon to use the same. Originally reported for overo: http://marc.info/?t=127265269400004&r=1&w=2 Signed-off-by: Nishanth Menon Reported-by: Peter Tseng Cc: Cliff Brake Cc: Kevin Hilman OMAP2: update OPP data to be device based Cc: Nishanth Menon Signed-off-by: Kevin Hilman OMAP3: CPUfreq: update to device-based OPP API Update usage of OPP API to use new device-based API. This requires getting the 'struct device' for the MPU and using that with the OPP API. Signed-off-by: Kevin Hilman omap3: opp: make independent of cpufreq Make opp3xx data which is registered with the opp layer dependent purely on CONFIG_PM as opp layer and pm.c users are CONFIG_PM dependent not cpufreq dependent. so we rename the data definition to opp3xxx_data.c (inline with what we have for omap2), also move the build definition to be under the existing CONFIG_PM build instead of CPUFREQ. Cc: Eduardo Valentin Cc: Kevin Hilman Cc: Paul Walmsley Cc: Rajendra Nayak Cc: Sanjeev Premi Cc: Thara Gopinath Cc: Tony Lindgren Signed-off-by: Nishanth Menon --- arch/arm/mach-omap2/clock.h | 14 +++++++++++++- arch/arm/mach-omap2/clock34xx.c | 2 ++ arch/arm/plat-omap/cpu-omap.c | 35 ++++++++++++++++++++++++++++++++--- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 896584e..29b5cf0 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -137,7 +137,9 @@ extern const struct clksel_rate gpt_32k_rates[]; extern const struct clksel_rate gpt_sys_rates[]; extern const struct clksel_rate gfx_l3_rates[]; -#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_CPU_FREQ) +#ifdef CONFIG_CPU_FREQ + +#ifdef CONFIG_ARCH_OMAP2 extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table); extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table); #else @@ -145,6 +147,16 @@ extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table) #define omap2_clk_exit_cpufreq_table 0 #endif +#ifdef CONFIG_ARCH_OMAP3 +extern void omap3_clk_init_cpufreq_table(struct cpufreq_frequency_table **table); +extern void omap3_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table); +#else +#define omap3_clk_init_cpufreq_table 0 +#define omap3_clk_exit_cpufreq_table 0 +#endif + +#endif /* CONFIG_CPU_FREQ */ + extern const struct clkops clkops_omap3_noncore_dpll_ops; #endif diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index 287abc4..85d3877 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c index bfa063b..608216b 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,17 +25,25 @@ #include #include #include +#include #include #include +#include #include +#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE) +#include +#endif + #define VERY_HI_RATE 900000000 static struct cpufreq_frequency_table *freq_table; #ifdef CONFIG_ARCH_OMAP1 #define MPU_CLK "mpu" +#elif CONFIG_ARCH_OMAP3 +#define MPU_CLK "arm_fck" #else #define MPU_CLK "virt_prcm_set" #endif @@ -73,7 +85,13 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation) { +#ifdef CONFIG_ARCH_OMAP1 struct cpufreq_freqs freqs; +#endif +#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE) + unsigned long freq; + struct device *mpu_dev = omap2_get_mpuss_device(); +#endif int ret = 0; /* Ensure desired rate is within allowed range. Some govenors @@ -83,13 +101,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 +115,11 @@ 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) + freq = target_freq * 1000; + if (opp_find_freq_ceil(mpu_dev, &freq)) + omap_pm_cpu_set_freq(freq); +#endif return ret; } @@ -114,7 +136,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) -- 1.6.6.1