Commit c1759992 authored by Russell King's avatar Russell King

[ARM] Update SA11x0 cpufreq code to reflect CVS version.

This covers the changes Dominik's made to the core cpufreq code.
parent 32b3f93f
/*
* linux/arch/arm/mach-integrator/cpu.c
*
* Copyright (C) 2001 Deep Blue Solutions Ltd.
* Copyright (C) 2001-2002 Deep Blue Solutions Ltd.
*
* $Id: cpu.c,v 1.5 2002/07/06 16:53:17 rmk Exp $
* $Id: cpu.c,v 1.6 2002/07/18 13:58:51 rmk Exp $
*
* 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
......@@ -15,6 +15,9 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/cpufreq.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/init.h>
#include <asm/hardware.h>
......@@ -42,7 +45,7 @@ static unsigned int vco_to_freq(struct vco vco, int factor)
#ifdef CONFIG_CPU_FREQ
/*
* Divisor indexes for in ascending divisor order
* Divisor indexes in ascending divisor order
*/
static unsigned char s2od[] = { 1, 3, 4, 7, 5, 2, 6, 0 };
......@@ -70,7 +73,8 @@ static struct vco freq_to_vco(unsigned int freq_khz, int factor)
* Validate the speed in khz. If it is outside our
* range, then return the lowest.
*/
unsigned int integrator_validatespeed(unsigned int freq_khz)
static unsigned int
integrator_validatespeed(unsigned int cpu, unsigned int freq_khz)
{
struct vco vco;
......@@ -87,11 +91,21 @@ unsigned int integrator_validatespeed(unsigned int freq_khz)
return vco_to_freq(vco, 1);
}
void integrator_setspeed(unsigned int freq_khz)
static void integrator_setspeed(unsigned int cpu, unsigned int freq_khz)
{
struct vco vco = freq_to_vco(freq_khz, 1);
unsigned long cpus_allowed;
u_int cm_osc;
/*
* Save this threads cpus_allowed mask, and bind to the
* specified CPU. When this call returns, we should be
* running on the right CPU.
*/
cpus_allowed = current->cpus_allowed;
set_cpus_allowed(current, 1 << cpu);
BUG_ON(cpu != smp_processor_id());
cm_osc = __raw_readl(CM_OSC);
cm_osc &= 0xfffff800;
cm_osc |= vco.vdw | vco.od << 8;
......@@ -99,44 +113,72 @@ void integrator_setspeed(unsigned int freq_khz)
__raw_writel(0xa05f, CM_LOCK);
__raw_writel(cm_osc, CM_OSC);
__raw_writel(0, CM_LOCK);
/*
* Restore the CPUs allowed mask.
*/
set_cpus_allowed(current, cpus_allowed);
}
static struct cpufreq_driver integrator_driver = {
.validate = integrator_validatespeed,
.setspeed = integrator_setspeed,
.sync = 1,
};
#endif
static int __init cpu_init(void)
static int __init integrator_cpu_init(void)
{
u_int cm_osc, cm_stat, cpu_freq_khz, mem_freq_khz;
struct cpufreq_freqs *freqs;
unsigned long cpus_allowed;
int cpu;
freqs = kmalloc(sizeof(struct cpufreq_freqs) * NR_CPUS,
GFP_KERNEL);
if (!freqs) {
printk(KERN_ERR "CPU: unable to allocate cpufreqs structure\n");
return -ENOMEM;
}
cpus_allowed = current->cpus_allowed;
for (cpu = 0; cpu < NR_CPUS; cpu++) {
u_int cm_osc, cm_stat, mem_freq_khz;
struct vco vco;
cm_osc = __raw_readl(CM_OSC);
if (!cpu_online(cpu))
continue;
set_cpus_allowed(current, 1 << cpu);
BUG_ON(cpu != smp_processor_id());
cm_stat = __raw_readl(CM_STAT);
cm_osc = __raw_readl(CM_OSC);
vco.od = (cm_osc >> 20) & 7;
vco.vdw = (cm_osc >> 12) & 255;
mem_freq_khz = vco_to_freq(vco, 2);
printk(KERN_INFO "Memory clock = %d.%03d MHz\n",
mem_freq_khz / 1000, mem_freq_khz % 1000);
printk(KERN_INFO "CPU%d: Module id: %d\n", cpu, cm_stat & 255);
printk(KERN_INFO "CPU%d: Memory clock = %d.%03d MHz\n",
cpu, mem_freq_khz / 1000, mem_freq_khz % 1000);
vco.od = (cm_osc >> 8) & 7;
vco.vdw = cm_osc & 255;
cpu_freq_khz = vco_to_freq(vco, 1);
#ifdef CONFIG_CPU_FREQ
{
struct cpufreq_driver cpufreq_driver;
cpufreq_driver.freq.min = 12000;
cpufreq_driver.freq.max = 160000;
cpufreq_driver.freq.cur = cpu_freq_khz;
cpufreq_driver.validate = &integrator_validatespeed;
cpufreq_driver.setspeed = &integrator_setspeed;
cpufreq_register(cpufreq_driver);
freqs[cpu].min = 12000;
freqs[cpu].max = 160000;
freqs[cpu].cur = vco_to_freq(vco, 1);
}
#endif
cm_stat = __raw_readl(CM_STAT);
printk("Module id: %d\n", cm_stat & 255);
set_cpus_allowed(current, cpus_allowed);
#ifdef CONFIG_CPU_FREQ
integrator_driver.freq = freqs;
cpufreq_register(&integrator_driver);
#else
kfree(freqs);
#endif
return 0;
}
__initcall(cpu_init);
__initcall(integrator_cpu_init);
......@@ -91,7 +91,7 @@
#include <asm/hardware.h>
extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz);
extern unsigned int sa11x0_validatespeed(unsigned int khz);
extern unsigned int sa11x0_validatespeed(unsigned int cpu, unsigned int khz);
extern unsigned int sa11x0_getspeed(void);
typedef struct {
......@@ -220,29 +220,35 @@ static struct notifier_block sa1100_dram_block = {
};
static void sa1100_setspeed(unsigned int khz)
static void sa1100_setspeed(unsigned int cpu, unsigned int khz)
{
PPCR = sa11x0_freq_to_ppcr(khz);
}
static struct cpufreq_freqs sa1100_freqs = {
.min = 59000,
.max = 287000,
};
static struct cpufreq_driver sa1100_driver = {
.freq = &sa1100_freqs,
.validate = sa11x0_validatespeed,
.setspeed = sa1100_setspeed,
.sync = 1,
};
static int __init sa1100_dram_init(void)
{
int ret = -ENODEV;
if ((processor_id & CPU_SA1100_MASK) == CPU_SA1100_ID) {
cpufreq_driver_t cpufreq_driver;
ret = cpufreq_register_notifier(&sa1100_dram_block);
if (ret)
return ret;
cpufreq_driver.freq.min = 59000;
cpufreq_driver.freq.max = 287000;
cpufreq_driver.freq.cur = sa11x0_getspeed();
cpufreq_driver.validate = &sa11x0_validatespeed;
cpufreq_driver.setspeed = &sa1100_setspeed;
sa1100_freqs.cur = sa11x0_getspeed();
ret = cpufreq_register(cpufreq_driver);<
ret = cpufreq_register(&sa1100_driver);
}
return ret;
......
......@@ -24,13 +24,14 @@
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/io.h>
#include <asm/system.h>
#undef DEBUG
extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz);
extern unsigned int sa11x0_validatespeed(unsigned int khz);
extern unsigned int sa11x0_validatespeed(unsigned int cpu, unsigned int khz);
extern unsigned int sa11x0_getspeed(void);
struct sdram_params {
......@@ -213,7 +214,7 @@ sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram)
* above, we can match for an exact frequency. If we don't find
* an exact match, we will to set the lowest frequency to be safe.
*/
static void sa1110_setspeed(unsigned int khz)
static void sa1110_setspeed(unsigned int cpu, unsigned int khz)
{
struct sdram_params *sdram = &sdram_params;
struct sdram_info sd;
......@@ -284,6 +285,18 @@ static void sa1110_setspeed(unsigned int khz)
sdram_update_refresh(khz, sdram);
}
static struct cpufreq_freqs sa1110_freqs = {
.min = 59000,
.max = 287000,
};
static struct cpufreq_driver sa1110_driver = {
.freq = &sa1110_freqs,
.validate = sa11x0_validatespeed,
.setspeed = sa1110_setspeed,
.sync = 1,
};
static int __init sa1110_clk_init(void)
{
struct sdram_params *sdram = NULL;
......@@ -298,8 +311,6 @@ static int __init sa1110_clk_init(void)
sdram = &samsung_km416s4030ct;
if (sdram) {
struct cpufreq_driver cpufreq_driver;
printk(KERN_DEBUG "SDRAM: tck: %d trcd: %d trp: %d"
" twr: %d refresh: %d cas_latency: %d\n",
sdram->tck, sdram->trcd, sdram->trp,
......@@ -307,15 +318,10 @@ static int __init sa1110_clk_init(void)
memcpy(&sdram_params, sdram, sizeof(sdram_params));
sa1110_setspeed(sa11x0_getspeed());
cpufreq_driver.freq.min = 59000;
cpufreq_driver.freq.max = 287000;
cpufreq_driver.freq.cur = sa11x0_getspeed();
cpufreq_driver.validate = &sa11x0_validatespeed;
cpufreq_driver.setspeed = &sa1110_setspeed;
sa1110_freqs.cur = sa11x0_getspeed();
sa1110_setspeed(0, sa1110_freqs.cur);
return cpufreq_register(cpufreq_driver);
return cpufreq_register(&sa1110_driver);
}
return 0;
......
......@@ -71,7 +71,7 @@ unsigned int sa11x0_freq_to_ppcr(unsigned int khz)
* Validate the speed in khz. If we can't generate the precise
* frequency requested, round it down (to be on the safe side).
*/
unsigned int sa11x0_validatespeed(unsigned int khz)
unsigned int sa11x0_validatespeed(unsigned int cpu, unsigned int khz)
{
return cclk_frequency_100khz[sa11x0_freq_to_ppcr(khz)] * 100;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment