* Re: [PATCH 00/02] OMAP3 clock: Remove virtual clock nodes
2009-04-03 16:59 ` Kevin Hilman
@ 2009-04-07 13:23 ` Jean Pihet
0 siblings, 0 replies; 5+ messages in thread
From: Jean Pihet @ 2009-04-07 13:23 UTC (permalink / raw)
To: Kevin Hilman; +Cc: Nayak, Rajendra, linux-omap@vger.kernel.org
[-- Attachment #1: Type: text/plain, Size: 998 bytes --]
Hi Rajendra, Kevin,
On Friday 03 April 2009 18:59:21 Kevin Hilman wrote:
> "Nayak, Rajendra" <rnayak@ti.com> writes:
...
> > Patches generated and apply on latest pm branch from Kevin's pm tree.
>
> Rajendra,
>
> This series does not apply against the PM branch.
>
> It seems your patches have TABs converted to spaces. For example, in
> 01/02 the first hunk which removes a bunch of code is trying to remove
> lines with spaces and the original code is all TABs, so the patch
> fails.
>
> Please resubmit with correct formatting so it applies cleanly.
Here are the reworked patches. Also the warnings have been removed from
arch/arm/plat-omap/cpu-omap.c and arch/arm/mach-omap2/resource34xx.c.
CPU_FREQ works on Beagleboard with those 2 patches applied.
Hope that helps,
Jean
>
> Kevin
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
[-- Attachment #2: 0002-This-patch-removes-all-refrences-to-virtual-clock.patch --]
[-- Type: text/x-diff, Size: 2145 bytes --]
From 7158beddca76bec162d9ce37e731451ea198b821 Mon Sep 17 00:00:00 2001
From: Rajendra Nayak <rnayak@ti.com>
Date: Tue, 7 Apr 2009 14:35:41 +0200
Subject: [PATCH] This patch removes all refrences to virtual clock
nodes in CPUFreq driver.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
Signed-off-by: Jean Pihet <jpihet@mvista.com>
---
arch/arm/plat-omap/cpu-omap.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
index a4b3392..929e5f7 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -40,7 +40,7 @@ static struct cpufreq_frequency_table *freq_table;
#ifdef CONFIG_ARCH_OMAP1
#define MPU_CLK "mpu"
#elif CONFIG_ARCH_OMAP3
-#define MPU_CLK "virt_vdd1_prcm_set"
+#define MPU_CLK "arm_fck"
#else
#define MPU_CLK "virt_prcm_set"
#endif
@@ -82,7 +82,9 @@ static int omap_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
+#ifdef CONFIG_ARCH_OMAP1
struct cpufreq_freqs freqs;
+#endif
int ret = 0;
/* Ensure desired rate is within allowed range. Some govenors
@@ -92,13 +94,13 @@ static int omap_target(struct cpufreq_policy *policy,
if (target_freq > policy->cpuinfo.max_freq)
target_freq = policy->cpuinfo.max_freq;
+#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;
-#ifdef CONFIG_ARCH_OMAP1
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
#ifdef CONFIG_CPU_FREQ_DEBUG
printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n",
@@ -110,7 +112,7 @@ static int omap_target(struct cpufreq_policy *policy,
if (mpu_opps) {
int ind;
for (ind = 1; ind <= MAX_VDD1_OPP; ind++) {
- if (mpu_opps[ind].rate/1000 >= freqs.new) {
+ if (mpu_opps[ind].rate/1000 >= target_freq) {
omap_pm_cpu_set_freq
(mpu_opps[ind].rate);
break;
--
1.6.1.2.MVISTA.50.gdf8fd
[-- Attachment #3: 0001-This-patch-removes-the-virtual-node-implementation-f.patch --]
[-- Type: text/x-diff, Size: 18777 bytes --]
From 1d629908f5712b7c12994064bbaf25a59d248edc Mon Sep 17 00:00:00 2001
From: Rajendra Nayak <rnayak@ti.com>
Date: Tue, 7 Apr 2009 14:32:25 +0200
Subject: [PATCH] This patch removes the virtual node implementation from clock f/w.
The resource framework which would use these nodes for DVFS
is been updated with most functionality internally, which was earlier
handled by virtual clock nodes.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
Signed-off-by: Jean Pihet <jpihet@mvista.com>
---
arch/arm/mach-omap2/clock34xx.c | 188 -------------------------------
arch/arm/mach-omap2/clock34xx.h | 26 -----
arch/arm/mach-omap2/resource34xx.c | 216 ++++++++++++++++++++++++------------
arch/arm/mach-omap2/resource34xx.h | 4 -
4 files changed, 146 insertions(+), 288 deletions(-)
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 6d4d4fe..3cee6b4 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -48,32 +48,6 @@
#define MAX_DPLL_WAIT_TRIES 1000000
-struct omap_opp *curr_vdd1_prcm_set;
-struct omap_opp *curr_vdd2_prcm_set;
-static struct clk *dpll1_clk, *dpll2_clk, *dpll3_clk;
-
-#ifndef CONFIG_CPU_FREQ
-static unsigned long compute_lpj(unsigned long ref, u_int div, u_int mult)
-{
- unsigned long new_jiffy_l, new_jiffy_h;
-
- /*
- * Recalculate loops_per_jiffy. We do it this way to
- * avoid math overflow on 32-bit machines. Maybe we
- * should make this architecture dependent? If you have
- * a better way of doing this, please replace!
- *
- * new = old * mult / div
- */
- new_jiffy_h = ref / div;
- new_jiffy_l = (ref % div) / 100;
- new_jiffy_h *= mult;
- new_jiffy_l = new_jiffy_l * mult / div;
-
- return new_jiffy_h + new_jiffy_l * 100;
-}
-#endif
-
#define MIN_SDRC_DLL_LOCK_FREQ 83000000
#define CYCLES_PER_MHZ 1000000
@@ -786,9 +760,6 @@ int __init omap2_clk_init(void)
struct clk **clkp;
/* u32 clkrate; */
u32 cpu_clkflg;
- unsigned long mpu_speed, core_speed;
- struct omap_opp *prcm_vdd;
-
/* REVISIT: Ultimately this will be used for multiboot */
#if 0
@@ -846,32 +817,6 @@ int __init omap2_clk_init(void)
recalculate_root_clocks();
- dpll1_clk = clk_get(NULL, "dpll1_ck");
- dpll2_clk = clk_get(NULL, "dpll2_ck");
- dpll3_clk = clk_get(NULL, "dpll3_m2_ck");
-
- mpu_speed = dpll1_clk->rate;
- if (mpu_opps) {
- prcm_vdd = mpu_opps + MAX_VDD1_OPP;
- for (; prcm_vdd->rate; prcm_vdd--) {
- if (prcm_vdd->rate <= mpu_speed) {
- curr_vdd1_prcm_set = prcm_vdd;
- break;
- }
- }
- }
-
- core_speed = dpll3_clk->rate;
- if (l3_opps) {
- prcm_vdd = l3_opps + MAX_VDD2_OPP;
- for (; prcm_vdd->rate; prcm_vdd--) {
- if (prcm_vdd->rate <= core_speed) {
- curr_vdd2_prcm_set = prcm_vdd;
- break;
- }
- }
- }
-
printk(KERN_INFO "Clocking rate (Crystal/DPLL/ARM core): "
"%ld.%01ld/%ld/%ld MHz\n",
(osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10,
@@ -886,137 +831,4 @@ int __init omap2_clk_init(void)
return 0;
}
-unsigned long get_freq(struct omap_opp *opp_freq_table,
- unsigned short opp)
-{
- struct omap_opp *prcm_config;
- prcm_config = opp_freq_table;
-
- for (; prcm_config->opp_id; prcm_config--)
- if (prcm_config->opp_id == opp)
- return prcm_config->rate;
- return 0;
-}
-
-unsigned short get_opp(struct omap_opp *opp_freq_table,
- unsigned long freq)
-{
- struct omap_opp *prcm_config;
- prcm_config = opp_freq_table;
-
- if (prcm_config->rate <= freq)
- return prcm_config->opp_id; /* Return the Highest OPP */
- for (; prcm_config->rate; prcm_config--)
- if (prcm_config->rate < freq)
- return (prcm_config+1)->opp_id;
- else if (prcm_config->rate == freq)
- return prcm_config->opp_id;
- /* Return the least OPP */
- return (prcm_config+1)->opp_id;
-}
-
-static void omap3_table_recalc(struct clk *clk)
-{
- if ((clk != &virt_vdd1_prcm_set) && (clk != &virt_vdd2_prcm_set))
- return;
-
- if ((curr_vdd1_prcm_set) && (clk == &virt_vdd1_prcm_set))
- clk->rate = curr_vdd1_prcm_set->rate;
- else if ((curr_vdd2_prcm_set) && (clk == &virt_vdd2_prcm_set))
- clk->rate = curr_vdd2_prcm_set->rate;
- pr_debug("CLK RATE:%lu\n", clk->rate);
-}
-
-static long omap3_round_to_table_rate(struct clk *clk, unsigned long rate)
-{
- struct omap_opp *ptr;
- long highest_rate;
-
- if ((clk != &virt_vdd1_prcm_set) && (clk != &virt_vdd2_prcm_set))
- return -EINVAL;
-
- if (!mpu_opps || !dsp_opps || !l3_opps)
- return -EINVAL;
-
- highest_rate = -EINVAL;
-
- if (clk == &virt_vdd1_prcm_set)
- ptr = mpu_opps + MAX_VDD1_OPP;
- else
- ptr = dsp_opps + MAX_VDD2_OPP;
-
- for (; ptr->rate; ptr--) {
- highest_rate = ptr->rate;
- pr_debug("Highest speed : %lu, rate: %lu\n", highest_rate,
- rate);
- if (ptr->rate <= rate)
- break;
- }
- return highest_rate;
-}
-
-static int omap3_select_table_rate(struct clk *clk, unsigned long rate)
-{
- struct omap_opp *prcm_vdd = NULL;
- unsigned long found_speed = 0, curr_mpu_speed;
- int index = 0;
- int l3_div;
- int ret;
-
- if ((clk != &virt_vdd1_prcm_set) && (clk != &virt_vdd2_prcm_set))
- return -EINVAL;
-
- if (!mpu_opps || !dsp_opps || !l3_opps)
- return -EINVAL;
-
- if (clk == &virt_vdd1_prcm_set) {
- prcm_vdd = mpu_opps + MAX_VDD1_OPP;
- index = MAX_VDD1_OPP;
- } else if (clk == &virt_vdd2_prcm_set) {
- prcm_vdd = l3_opps + MAX_VDD2_OPP;
- index = MAX_VDD2_OPP;
- }
-
- for (; prcm_vdd && prcm_vdd->rate; prcm_vdd--, index--) {
- if (prcm_vdd->rate <= rate) {
- found_speed = prcm_vdd->rate;
- pr_debug("Found speed = %lu\n", found_speed);
- break;
- }
- }
-
- if (!found_speed) {
- printk(KERN_INFO "Could not set table rate to %luMHz\n",
- rate / 1000000);
- return -EINVAL;
- }
-
-
- if (clk == &virt_vdd1_prcm_set) {
- curr_mpu_speed = curr_vdd1_prcm_set->rate;
- clk->rate = prcm_vdd->rate;
- clk_set_rate(dpll1_clk, prcm_vdd->rate);
- clk_set_rate(dpll2_clk, dsp_opps[index].rate);
- curr_vdd1_prcm_set = prcm_vdd;
-#ifndef CONFIG_CPU_FREQ
- /*Update loops_per_jiffy if processor speed is being changed*/
- loops_per_jiffy = compute_lpj(loops_per_jiffy,
- curr_mpu_speed/1000, found_speed/1000);
-#endif
- } else {
- l3_div = cm_read_mod_reg(CORE_MOD, CM_CLKSEL) &
- OMAP3430_CLKSEL_L3_MASK;
- ret = clk_set_rate(dpll3_clk, prcm_vdd->rate * l3_div);
- if (ret)
- return ret;
- curr_vdd2_prcm_set = prcm_vdd;
- }
-
-#ifdef CONFIG_PM
- omap3_save_scratchpad_contents();
-#endif
-
- return 0;
-}
-
#endif /* CONFIG_ARCH_OMAP3 */
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
index e0dd7f3..f00bdf7 100644
--- a/arch/arm/mach-omap2/clock34xx.h
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -39,9 +39,6 @@ static int omap3_noncore_dpll_enable(struct clk *clk);
static void omap3_noncore_dpll_disable(struct clk *clk);
static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate);
static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate);
-static void omap3_table_recalc(struct clk *clk);
-static long omap3_round_to_table_rate(struct clk *clk, unsigned long rate);
-static int omap3_select_table_rate(struct clk *clk, unsigned long rate);
/* Maximum DPLL multiplier, divider values for OMAP3 */
#define OMAP3_MAX_DPLL_MULT 2048
@@ -3345,26 +3342,6 @@ static struct clk wdt1_fck = {
.recalc = &followparent_recalc,
};
-static struct clk virt_vdd1_prcm_set = {
- .name = "virt_vdd1_prcm_set",
- .flags = CLOCK_IN_OMAP343X | ALWAYS_ENABLED,
- .parent = &mpu_ck, /* Indexed by mpu speed, no parent */
- .clkdm = { .name = "virt_opp_clkdm" },
- .recalc = &omap3_table_recalc, /*sets are keyed on mpu rate */
- .set_rate = &omap3_select_table_rate,
- .round_rate = &omap3_round_to_table_rate,
-};
-
-static struct clk virt_vdd2_prcm_set = {
- .name = "virt_vdd2_prcm_set",
- .flags = CLOCK_IN_OMAP343X | ALWAYS_ENABLED,
- .parent = &core_ck,
- .clkdm = { .name = "virt_opp_clkdm" },
- .recalc = &omap3_table_recalc,
- .set_rate = &omap3_select_table_rate,
- .round_rate = &omap3_round_to_table_rate,
-};
-
static struct clk *onchip_34xx_clks[] __initdata = {
&omap_32k_fck,
&virt_12m_ck,
@@ -3588,9 +3565,6 @@ static struct clk *onchip_34xx_clks[] __initdata = {
&secure_32k_fck,
&gpt12_fck,
&wdt1_fck,
- /* virtual group clock */
- &virt_vdd1_prcm_set,
- &virt_vdd2_prcm_set,
};
#endif
diff --git a/arch/arm/mach-omap2/resource34xx.c b/arch/arm/mach-omap2/resource34xx.c
index fd67c39..f9092d7 100644
--- a/arch/arm/mach-omap2/resource34xx.c
+++ b/arch/arm/mach-omap2/resource34xx.c
@@ -18,12 +18,16 @@
#include <linux/pm_qos_params.h>
#include <linux/cpufreq.h>
+#include <linux/delay.h>
#include <mach/powerdomain.h>
#include <mach/clockdomain.h>
+#include <mach/control.h>
#include <mach/omap34xx.h>
#include "smartreflex.h"
#include "resource34xx.h"
#include "pm.h"
+#include "cm.h"
+#include "cm-regbits-34xx.h"
/**
* init_latency - Initializes the mpu/core latency resource.
@@ -134,14 +138,34 @@ int set_pd_latency(struct shared_resource *resp, u32 latency)
return 0;
}
-static struct clk *vdd1_clk;
-static struct clk *vdd2_clk;
static struct shared_resource *vdd1_resp;
static struct shared_resource *vdd2_resp;
static struct device dummy_mpu_dev;
static struct device dummy_dsp_dev;
+static struct device vdd2_dev;
static int vdd1_lock;
static int vdd2_lock;
+static struct clk *dpll1_clk, *dpll2_clk, *dpll3_clk;
+static int curr_vdd1_opp;
+static int curr_vdd2_opp;
+static DEFINE_MUTEX(dvfs_mutex);
+
+static unsigned short get_opp(struct omap_opp *opp_freq_table,
+ unsigned long freq)
+{
+ struct omap_opp *prcm_config;
+ prcm_config = opp_freq_table;
+
+ if (prcm_config->rate <= freq)
+ return prcm_config->opp_id; /* Return the Highest OPP */
+ for (; prcm_config->rate; prcm_config--)
+ if (prcm_config->rate < freq)
+ return (prcm_config+1)->opp_id;
+ else if (prcm_config->rate == freq)
+ return prcm_config->opp_id;
+ /* Return the least OPP */
+ return (prcm_config+1)->opp_id;
+}
/**
* init_opp - Initialize the OPP resource
@@ -151,25 +175,28 @@ void init_opp(struct shared_resource *resp)
resp->no_of_users = 0;
if (!mpu_opps || !dsp_opps || !l3_opps)
- return 0;
+ return;
/* Initialize the current level of the OPP resource
* to the opp set by u-boot.
*/
if (strcmp(resp->name, "vdd1_opp") == 0) {
- resp->curr_level = curr_vdd1_prcm_set->opp_id;
- vdd1_clk = clk_get(NULL, "virt_vdd1_prcm_set");
vdd1_resp = resp;
+ dpll1_clk = clk_get(NULL, "dpll1_ck");
+ dpll2_clk = clk_get(NULL, "dpll2_ck");
+ resp->curr_level = get_opp(mpu_opps + MAX_VDD1_OPP,
+ dpll1_clk->rate);
+ curr_vdd1_opp = resp->curr_level;
} else if (strcmp(resp->name, "vdd2_opp") == 0) {
- resp->curr_level = curr_vdd2_prcm_set->opp_id;
- vdd2_clk = clk_get(NULL, "virt_vdd2_prcm_set");
vdd2_resp = resp;
+ dpll3_clk = clk_get(NULL, "dpll3_m2_ck");
+ resp->curr_level = get_opp(l3_opps + MAX_VDD2_OPP,
+ dpll2_clk->rate);
+ curr_vdd2_opp = resp->curr_level;
}
return;
}
-static struct device vdd2_dev;
-
int resource_access_opp_lock(int res, int delta)
{
if (res == VDD1_OPP) {
@@ -182,14 +209,94 @@ int resource_access_opp_lock(int res, int delta)
return -EINVAL;
}
+#ifndef CONFIG_CPU_FREQ
+static unsigned long compute_lpj(unsigned long ref, u_int div, u_int mult)
+{
+ unsigned long new_jiffy_l, new_jiffy_h;
+
+ /*
+ * Recalculate loops_per_jiffy. We do it this way to
+ * avoid math overflow on 32-bit machines. Maybe we
+ * should make this architecture dependent? If you have
+ * a better way of doing this, please replace!
+ *
+ * new = old * mult / div
+ */
+ new_jiffy_h = ref / div;
+ new_jiffy_l = (ref % div) / 100;
+ new_jiffy_h *= mult;
+ new_jiffy_l = new_jiffy_l * mult / div;
+
+ return new_jiffy_h + new_jiffy_l * 100;
+}
+#endif
+
+static int program_opp_freq(int res, int target_level, int current_level)
+{
+ int ret = 0, l3_div;
+ int *curr_opp;
+
+ if (res == VDD1_OPP) {
+ curr_opp = &curr_vdd1_opp;
+ clk_set_rate(dpll1_clk, mpu_opps[target_level].rate);
+ clk_set_rate(dpll2_clk, dsp_opps[target_level].rate);
+#ifndef CONFIG_CPU_FREQ
+ /*Update loops_per_jiffy if processor speed is being changed*/
+ loops_per_jiffy = compute_lpj(loops_per_jiffy,
+ mpu_opps[current_level].rate/1000,
+ mpu_opps[target_level].rate/1000);
+#endif
+ } else {
+ curr_opp = &curr_vdd2_opp;
+ l3_div = cm_read_mod_reg(CORE_MOD, CM_CLKSEL) &
+ OMAP3430_CLKSEL_L3_MASK;
+ ret = clk_set_rate(dpll3_clk,
+ l3_opps[target_level].rate * l3_div);
+ }
+ if (ret)
+ return current_level;
+#ifdef CONFIG_PM
+ omap3_save_scratchpad_contents();
+#endif
+ *curr_opp = target_level;
+ return target_level;
+}
+
+static int program_opp(int res, struct omap_opp *opp, int target_level,
+ int current_level)
+{
+ int i, ret = 0, raise;
+#ifdef CONFIG_OMAP_SMARTREFLEX
+ unsigned long t_opp;
+
+ t_opp = ID_VDD(res) | ID_OPP_NO(opp[target_level].opp_id);
+#endif
+ if (target_level > current_level)
+ raise = 1;
+ else
+ raise = 0;
+
+ for (i = 0; i < 2; i++) {
+ if (i == raise)
+ ret = program_opp_freq(res, target_level,
+ current_level);
+#ifdef CONFIG_OMAP_SMARTREFLEX
+ else
+ sr_voltagescale_vcbypass(t_opp,
+ opp[target_level].vsel);
+#endif
+ }
+
+ return ret;
+}
+
int resource_set_opp_level(int res, u32 target_level, int flags)
{
- unsigned long mpu_freq, mpu_old_freq, l3_freq, t_opp;
+ unsigned long mpu_freq, mpu_old_freq;
#ifdef CONFIG_CPU_FREQ
struct cpufreq_freqs freqs_notify;
#endif
struct shared_resource *resp;
- int ret;
if (res == VDD1_OPP)
resp = vdd1_resp;
@@ -204,13 +311,16 @@ int resource_set_opp_level(int res, u32 target_level, int flags)
if (!mpu_opps || !dsp_opps || !l3_opps)
return 0;
+ mutex_lock(&dvfs_mutex);
+
if (res == VDD1_OPP) {
- if (flags != OPP_IGNORE_LOCK && vdd1_lock)
+ if (flags != OPP_IGNORE_LOCK && vdd1_lock) {
+ mutex_unlock(&dvfs_mutex);
return 0;
- mpu_old_freq = get_freq(mpu_opps + MAX_VDD1_OPP,
- curr_vdd1_prcm_set->opp_id);
- mpu_freq = get_freq(mpu_opps + MAX_VDD1_OPP,
- target_level);
+ }
+ mpu_old_freq = mpu_opps[resp->curr_level].rate;
+ mpu_freq = mpu_opps[target_level].rate;
+
#ifdef CONFIG_CPU_FREQ
freqs_notify.old = mpu_old_freq/1000;
freqs_notify.new = mpu_freq/1000;
@@ -218,65 +328,22 @@ int resource_set_opp_level(int res, u32 target_level, int flags)
/* Send pre notification to CPUFreq */
cpufreq_notify_transition(&freqs_notify, CPUFREQ_PRECHANGE);
#endif
- t_opp = ID_VDD(PRCM_VDD1) |
- ID_OPP_NO(mpu_opps[target_level].opp_id);
- if (resp->curr_level > target_level) {
- /* Scale Frequency and then voltage */
- clk_set_rate(vdd1_clk, mpu_freq);
-#ifdef CONFIG_OMAP_SMARTREFLEX
- sr_voltagescale_vcbypass(t_opp,
- mpu_opps[target_level].vsel);
-#endif
- } else {
-#ifdef CONFIG_OMAP_SMARTREFLEX
- /* Scale Voltage and then frequency */
- sr_voltagescale_vcbypass(t_opp,
- mpu_opps[target_level].vsel);
-#endif
- clk_set_rate(vdd1_clk, mpu_freq);
- }
- resp->curr_level = curr_vdd1_prcm_set->opp_id;
+ resp->curr_level = program_opp(res, mpu_opps, target_level,
+ resp->curr_level);
#ifdef CONFIG_CPU_FREQ
/* Send a post notification to CPUFreq */
cpufreq_notify_transition(&freqs_notify, CPUFREQ_POSTCHANGE);
#endif
} else {
- if (flags != OPP_IGNORE_LOCK && vdd2_lock)
+ if (!(flags & OPP_IGNORE_LOCK) && vdd2_lock) {
+ mutex_unlock(&dvfs_mutex);
return 0;
- l3_freq = get_freq(l3_opps + MAX_VDD2_OPP,
- target_level);
- t_opp = ID_VDD(PRCM_VDD2) |
- ID_OPP_NO(l3_opps[target_level].opp_id);
- if (resp->curr_level > target_level) {
- /* Scale Frequency and then voltage */
- ret = clk_set_rate(vdd2_clk, l3_freq);
- if (ret)
- return ret;
-#ifdef CONFIG_OMAP_SMARTREFLEX
- sr_voltagescale_vcbypass(t_opp,
- l3_opps[target_level].vsel);
-#endif
- } else {
-#ifdef CONFIG_OMAP_SMARTREFLEX
- /* Scale Voltage and then frequency */
- sr_voltagescale_vcbypass(t_opp,
- l3_opps[target_level].vsel);
-#endif
- ret = clk_set_rate(vdd2_clk, l3_freq);
- if (ret) {
-#ifdef CONFIG_OMAP_SMARTREFLEX
- /* Setting clock failed, revert voltage */
- t_opp = ID_VDD(PRCM_VDD2) |
- ID_OPP_NO(l3_opps[resp->curr_level].
- opp_id);
- sr_voltagescale_vcbypass(t_opp,
- l3_opps[resp->curr_level].vsel);
-#endif
- return ret;
- }
}
- resp->curr_level = curr_vdd2_prcm_set->opp_id;
+
+ resp->curr_level = program_opp(res, l3_opps, target_level,
+ resp->curr_level);
}
+ mutex_unlock(&dvfs_mutex);
return 0;
}
@@ -288,6 +355,16 @@ int set_opp(struct shared_resource *resp, u32 target_level)
if (resp == vdd1_resp) {
resource_set_opp_level(VDD1_OPP, target_level, 0);
+ /*
+ * For VDD1 OPP3 and above, make sure the interconnect
+ * is at 100Mhz or above.
+ * throughput in KiB/s for 100 Mhz = 100 * 1000 * 4.
+ */
+ if (target_level >= 3)
+ resource_request("vdd2_opp", &vdd2_dev, 400000);
+ else
+ resource_release("vdd2_opp", &vdd2_dev);
+
} else if (resp == vdd2_resp) {
tput = target_level;
@@ -336,11 +413,10 @@ void init_freq(struct shared_resource *resp)
*/
if (strcmp(resp->name, "mpu_freq") == 0)
/* MPU freq in Mhz */
- resp->curr_level = curr_vdd1_prcm_set->rate;
+ resp->curr_level = mpu_opps[curr_vdd1_opp].rate;
else if (strcmp(resp->name, "dsp_freq") == 0)
/* DSP freq in Mhz */
- resp->curr_level = get_freq(dsp_opps + MAX_VDD2_OPP,
- curr_vdd1_prcm_set->opp_id);
+ resp->curr_level = dsp_opps[curr_vdd1_opp].rate;
return;
}
diff --git a/arch/arm/mach-omap2/resource34xx.h b/arch/arm/mach-omap2/resource34xx.h
index 543bb91..b847208 100644
--- a/arch/arm/mach-omap2/resource34xx.h
+++ b/arch/arm/mach-omap2/resource34xx.h
@@ -28,10 +28,6 @@
#include <mach/omap-pm.h>
#include <mach/omap34xx.h>
-extern struct omap_opp *curr_vdd1_prcm_set;
-extern struct omap_opp *curr_vdd2_prcm_set;
-extern unsigned long get_freq(struct omap_opp *, unsigned short);
-extern unsigned short get_opp(struct omap_opp *, unsigned long);
extern int sr_voltagescale_vcbypass(u32 target_opp, u8 vsel);
/*
--
1.6.1.2.MVISTA.50.gdf8fd
^ permalink raw reply related [flat|nested] 5+ messages in thread