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 * 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 * 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 * it under the terms of the GNU General Public License version 2 as
...@@ -15,6 +15,9 @@ ...@@ -15,6 +15,9 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/cpufreq.h> #include <linux/cpufreq.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/hardware.h> #include <asm/hardware.h>
...@@ -42,7 +45,7 @@ static unsigned int vco_to_freq(struct vco vco, int factor) ...@@ -42,7 +45,7 @@ static unsigned int vco_to_freq(struct vco vco, int factor)
#ifdef CONFIG_CPU_FREQ #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 }; 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) ...@@ -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 * Validate the speed in khz. If it is outside our
* range, then return the lowest. * 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; struct vco vco;
...@@ -87,11 +91,21 @@ unsigned int integrator_validatespeed(unsigned int freq_khz) ...@@ -87,11 +91,21 @@ unsigned int integrator_validatespeed(unsigned int freq_khz)
return vco_to_freq(vco, 1); 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); struct vco vco = freq_to_vco(freq_khz, 1);
unsigned long cpus_allowed;
u_int cm_osc; 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 = __raw_readl(CM_OSC);
cm_osc &= 0xfffff800; cm_osc &= 0xfffff800;
cm_osc |= vco.vdw | vco.od << 8; cm_osc |= vco.vdw | vco.od << 8;
...@@ -99,44 +113,72 @@ void integrator_setspeed(unsigned int freq_khz) ...@@ -99,44 +113,72 @@ void integrator_setspeed(unsigned int freq_khz)
__raw_writel(0xa05f, CM_LOCK); __raw_writel(0xa05f, CM_LOCK);
__raw_writel(cm_osc, CM_OSC); __raw_writel(cm_osc, CM_OSC);
__raw_writel(0, CM_LOCK); __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 #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;
struct vco vco; 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;
}
cm_osc = __raw_readl(CM_OSC); cpus_allowed = current->cpus_allowed;
for (cpu = 0; cpu < NR_CPUS; cpu++) {
u_int cm_osc, cm_stat, mem_freq_khz;
struct vco vco;
vco.od = (cm_osc >> 20) & 7; if (!cpu_online(cpu))
vco.vdw = (cm_osc >> 12) & 255; continue;
mem_freq_khz = vco_to_freq(vco, 2);
printk(KERN_INFO "Memory clock = %d.%03d MHz\n", set_cpus_allowed(current, 1 << cpu);
mem_freq_khz / 1000, mem_freq_khz % 1000); BUG_ON(cpu != smp_processor_id());
vco.od = (cm_osc >> 8) & 7; cm_stat = __raw_readl(CM_STAT);
vco.vdw = cm_osc & 255; cm_osc = __raw_readl(CM_OSC);
cpu_freq_khz = vco_to_freq(vco, 1); vco.od = (cm_osc >> 20) & 7;
vco.vdw = (cm_osc >> 12) & 255;
mem_freq_khz = vco_to_freq(vco, 2);
#ifdef CONFIG_CPU_FREQ printk(KERN_INFO "CPU%d: Module id: %d\n", cpu, cm_stat & 255);
{ printk(KERN_INFO "CPU%d: Memory clock = %d.%03d MHz\n",
struct cpufreq_driver cpufreq_driver; cpu, mem_freq_khz / 1000, mem_freq_khz % 1000);
cpufreq_driver.freq.min = 12000; vco.od = (cm_osc >> 8) & 7;
cpufreq_driver.freq.max = 160000; vco.vdw = cm_osc & 255;
cpufreq_driver.freq.cur = cpu_freq_khz;
cpufreq_driver.validate = &integrator_validatespeed; freqs[cpu].min = 12000;
cpufreq_driver.setspeed = &integrator_setspeed; freqs[cpu].max = 160000;
cpufreq_register(cpufreq_driver); freqs[cpu].cur = vco_to_freq(vco, 1);
} }
#endif
cm_stat = __raw_readl(CM_STAT); set_cpus_allowed(current, cpus_allowed);
printk("Module id: %d\n", cm_stat & 255);
#ifdef CONFIG_CPU_FREQ
integrator_driver.freq = freqs;
cpufreq_register(&integrator_driver);
#else
kfree(freqs);
#endif
return 0; return 0;
} }
__initcall(cpu_init); __initcall(integrator_cpu_init);
...@@ -91,7 +91,7 @@ ...@@ -91,7 +91,7 @@
#include <asm/hardware.h> #include <asm/hardware.h>
extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz); 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); extern unsigned int sa11x0_getspeed(void);
typedef struct { typedef struct {
...@@ -220,29 +220,35 @@ static struct notifier_block sa1100_dram_block = { ...@@ -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); 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) static int __init sa1100_dram_init(void)
{ {
int ret = -ENODEV; int ret = -ENODEV;
if ((processor_id & CPU_SA1100_MASK) == CPU_SA1100_ID) { if ((processor_id & CPU_SA1100_MASK) == CPU_SA1100_ID) {
cpufreq_driver_t cpufreq_driver;
ret = cpufreq_register_notifier(&sa1100_dram_block); ret = cpufreq_register_notifier(&sa1100_dram_block);
if (ret) if (ret)
return ret; return ret;
cpufreq_driver.freq.min = 59000; sa1100_freqs.cur = sa11x0_getspeed();
cpufreq_driver.freq.max = 287000;
cpufreq_driver.freq.cur = sa11x0_getspeed();
cpufreq_driver.validate = &sa11x0_validatespeed;
cpufreq_driver.setspeed = &sa1100_setspeed;
ret = cpufreq_register(cpufreq_driver);< ret = cpufreq_register(&sa1100_driver);
} }
return ret; return ret;
......
...@@ -24,13 +24,14 @@ ...@@ -24,13 +24,14 @@
#include <linux/init.h> #include <linux/init.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
#undef DEBUG #undef DEBUG
extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz); 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); extern unsigned int sa11x0_getspeed(void);
struct sdram_params { struct sdram_params {
...@@ -213,7 +214,7 @@ sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram) ...@@ -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 * 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. * 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_params *sdram = &sdram_params;
struct sdram_info sd; struct sdram_info sd;
...@@ -284,6 +285,18 @@ static void sa1110_setspeed(unsigned int khz) ...@@ -284,6 +285,18 @@ static void sa1110_setspeed(unsigned int khz)
sdram_update_refresh(khz, sdram); 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) static int __init sa1110_clk_init(void)
{ {
struct sdram_params *sdram = NULL; struct sdram_params *sdram = NULL;
...@@ -298,8 +311,6 @@ static int __init sa1110_clk_init(void) ...@@ -298,8 +311,6 @@ static int __init sa1110_clk_init(void)
sdram = &samsung_km416s4030ct; sdram = &samsung_km416s4030ct;
if (sdram) { if (sdram) {
struct cpufreq_driver cpufreq_driver;
printk(KERN_DEBUG "SDRAM: tck: %d trcd: %d trp: %d" printk(KERN_DEBUG "SDRAM: tck: %d trcd: %d trp: %d"
" twr: %d refresh: %d cas_latency: %d\n", " twr: %d refresh: %d cas_latency: %d\n",
sdram->tck, sdram->trcd, sdram->trp, sdram->tck, sdram->trcd, sdram->trp,
...@@ -307,15 +318,10 @@ static int __init sa1110_clk_init(void) ...@@ -307,15 +318,10 @@ static int __init sa1110_clk_init(void)
memcpy(&sdram_params, sdram, sizeof(sdram_params)); memcpy(&sdram_params, sdram, sizeof(sdram_params));
sa1110_setspeed(sa11x0_getspeed()); sa1110_freqs.cur = sa11x0_getspeed();
sa1110_setspeed(0, sa1110_freqs.cur);
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;
return cpufreq_register(cpufreq_driver); return cpufreq_register(&sa1110_driver);
} }
return 0; return 0;
......
...@@ -71,7 +71,7 @@ unsigned int sa11x0_freq_to_ppcr(unsigned int khz) ...@@ -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 * Validate the speed in khz. If we can't generate the precise
* frequency requested, round it down (to be on the safe side). * 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; 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