Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 137325
b: refs/heads/master
c: aeec299
h: refs/heads/master
i:
  137323: ebae31f
v: v3
  • Loading branch information
Kevin Hilman authored and Russell King committed Feb 8, 2009
1 parent dc45d71 commit da47602
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ae8578c0194695bd37435249dfed720769a6bbf3
refs/heads/master: aeec299011da8c3f07a47fe5d988f0eafda53906
42 changes: 42 additions & 0 deletions trunk/arch/arm/mach-omap2/clock24xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -574,13 +574,55 @@ static int omap2_select_table_rate(struct clk *clk, unsigned long rate)
return 0;
}

#ifdef CONFIG_CPU_FREQ
/*
* Walk PRCM rate table and fillout cpufreq freq_table
*/
static struct cpufreq_frequency_table freq_table[ARRAY_SIZE(rate_table)];

void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
{
struct prcm_config *prcm;
int i = 0;

for (prcm = rate_table; prcm->mpu_speed; prcm++) {
if (!(prcm->flags & cpu_mask))
continue;
if (prcm->xtal_speed != sys_ck.rate)
continue;

/* don't put bypass rates in table */
if (prcm->dpll_speed == prcm->xtal_speed)
continue;

freq_table[i].index = i;
freq_table[i].frequency = prcm->mpu_speed / 1000;
i++;
}

if (i == 0) {
printk(KERN_WARNING "%s: failed to initialize frequency "
"table\n", __func__);
return;
}

freq_table[i].index = i;
freq_table[i].frequency = CPUFREQ_TABLE_END;

*table = &freq_table[0];
}
#endif

static struct clk_functions omap2_clk_functions = {
.clk_enable = omap2_clk_enable,
.clk_disable = omap2_clk_disable,
.clk_round_rate = omap2_clk_round_rate,
.clk_set_rate = omap2_clk_set_rate,
.clk_set_parent = omap2_clk_set_parent,
.clk_disable_unused = omap2_clk_disable_unused,
#ifdef CONFIG_CPU_FREQ
.clk_init_cpufreq_table = omap2_clk_init_cpufreq_table,
#endif
};

static u32 omap2_get_apll_clkin(void)
Expand Down
57 changes: 53 additions & 4 deletions trunk/arch/arm/plat-omap/cpu-omap.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@
#include <linux/io.h>

#include <mach/hardware.h>
#include <mach/clock.h>
#include <asm/system.h>

#define VERY_HI_RATE 900000000

static struct cpufreq_frequency_table *freq_table;

#ifdef CONFIG_ARCH_OMAP1
#define MPU_CLK "mpu"
#else
Expand All @@ -39,6 +42,9 @@ static struct clk *mpu_clk;

int omap_verify_speed(struct cpufreq_policy *policy)
{
if (freq_table)
return cpufreq_frequency_table_verify(policy, freq_table);

if (policy->cpu)
return -EINVAL;

Expand Down Expand Up @@ -70,29 +76,58 @@ static int omap_target(struct cpufreq_policy *policy,
struct cpufreq_freqs freqs;
int ret = 0;

/* Ensure desired rate is within allowed range. Some govenors
* (ondemand) will just pass target_freq=0 to get the minimum. */
if (target_freq < policy->cpuinfo.min_freq)
target_freq = policy->cpuinfo.min_freq;
if (target_freq > policy->cpuinfo.max_freq)
target_freq = policy->cpuinfo.max_freq;

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);
ret = clk_set_rate(mpu_clk, target_freq * 1000);
#ifdef CONFIG_CPU_FREQ_DEBUG
printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n",
freqs.old, freqs.new);
#endif
ret = clk_set_rate(mpu_clk, freqs.new * 1000);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);

return ret;
}

static int __init omap_cpu_init(struct cpufreq_policy *policy)
{
int result = 0;

mpu_clk = clk_get(NULL, MPU_CLK);
if (IS_ERR(mpu_clk))
return PTR_ERR(mpu_clk);

if (policy->cpu != 0)
return -EINVAL;

policy->cur = policy->min = policy->max = omap_getspeed(0);
policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, VERY_HI_RATE) / 1000;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;

clk_init_cpufreq_table(&freq_table);
if (freq_table) {
result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
if (!result)
cpufreq_frequency_table_get_attr(freq_table,
policy->cpu);
} else {
policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
VERY_HI_RATE) / 1000;
}

/* FIXME: what's the actual transition time? */
policy->cpuinfo.transition_latency = 10 * 1000 * 1000;

return 0;
}
Expand All @@ -103,6 +138,11 @@ static int omap_cpu_exit(struct cpufreq_policy *policy)
return 0;
}

static struct freq_attr *omap_cpufreq_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
NULL,
};

static struct cpufreq_driver omap_driver = {
.flags = CPUFREQ_STICKY,
.verify = omap_verify_speed,
Expand All @@ -111,6 +151,7 @@ static struct cpufreq_driver omap_driver = {
.init = omap_cpu_init,
.exit = omap_cpu_exit,
.name = "omap",
.attr = omap_cpufreq_attr,
};

static int __init omap_cpufreq_init(void)
Expand All @@ -119,3 +160,11 @@ static int __init omap_cpufreq_init(void)
}

arch_initcall(omap_cpufreq_init);

/*
* if ever we want to remove this, upon cleanup call:
*
* cpufreq_unregister_driver()
* cpufreq_frequency_table_put_attr()
*/

3 changes: 3 additions & 0 deletions trunk/arch/arm/plat-omap/include/mach/clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ extern void recalculate_root_clocks(void);
extern void followparent_recalc(struct clk *clk);
extern int clk_get_usecount(struct clk *clk);
extern void clk_enable_init_clocks(void);
#ifdef CONFIG_CPU_FREQ
extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
#endif

extern const struct clkops clkops_null;

Expand Down

0 comments on commit da47602

Please sign in to comment.