Commit 3496bea8 authored by Russell King's avatar Russell King

[ARM] Update cpufreq related sa1100 related drivers and CPU code

This cset updates sa1100 code for the now merged cpufreq next-gen.
parent a58cdfc6
...@@ -90,9 +90,7 @@ ...@@ -90,9 +90,7 @@
#include <asm/hardware.h> #include <asm/hardware.h>
extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz); #include "generic.h"
extern unsigned int sa11x0_validatespeed(unsigned int cpu, unsigned int khz);
extern unsigned int sa11x0_getspeed(void);
typedef struct { typedef struct {
int speed; int speed;
...@@ -107,7 +105,7 @@ typedef struct { ...@@ -107,7 +105,7 @@ typedef struct {
static sa1100_dram_regs_t sa1100_dram_settings[] = static sa1100_dram_regs_t sa1100_dram_settings[] =
{ {
/* { mdcnfg, mdcas0, mdcas1, mdcas2 } */ /* clock frequency */ /* speed, mdcnfg, mdcas0, mdcas1, mdcas2 clock frequency */
{ 59000, 0x00dc88a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 59.0 MHz */ { 59000, 0x00dc88a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 59.0 MHz */
{ 73700, 0x011490a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 73.7 MHz */ { 73700, 0x011490a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 73.7 MHz */
{ 88500, 0x014e90a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 88.5 MHz */ { 88500, 0x014e90a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 88.5 MHz */
...@@ -127,28 +125,25 @@ static sa1100_dram_regs_t sa1100_dram_settings[] = ...@@ -127,28 +125,25 @@ static sa1100_dram_regs_t sa1100_dram_settings[] =
{ 0, 0, 0, 0, 0 } /* last entry */ { 0, 0, 0, 0, 0 } /* last entry */
}; };
static void sa1100_update_dram_timings(int current_speed, int new_speed) static void sa1100_update_dram_timings(int current_speed, int new_speed)
{ {
sa1100_dram_regs_t *settings = sa1100_dram_settings; sa1100_dram_regs_t *settings = sa1100_dram_settings;
/* find speed */ /* find speed */
while(settings->speed != 0) { while (settings->speed != 0) {
if(new_speed == settings->speed) if(new_speed == settings->speed)
break; break;
settings++; settings++;
} }
if(settings->speed == 0) { if (settings->speed == 0) {
panic("%s: couldn't find dram setting for speed %d\n", panic("%s: couldn't find dram setting for speed %d\n",
__FUNCTION__, new_speed); __FUNCTION__, new_speed);
} }
/* No risk, no fun: run with interrupts on! */ /* No risk, no fun: run with interrupts on! */
if(new_speed > current_speed) { if (new_speed > current_speed) {
/* We're going FASTER, so first relax the memory /* We're going FASTER, so first relax the memory
* timings before changing the core frequency * timings before changing the core frequency
*/ */
...@@ -181,60 +176,39 @@ static void sa1100_update_dram_timings(int current_speed, int new_speed) ...@@ -181,60 +176,39 @@ static void sa1100_update_dram_timings(int current_speed, int new_speed)
} }
} }
static void sa1100_setspeed(struct cpufreq_policy *policy)
static int sa1100_dram_notifier(struct notifier_block *nb,
unsigned long val, void *data)
{ {
struct cpufreq_freqs *ci = data; unsigned int cur = sa11x0_getspeed();
struct cpufreq_freqs freqs;
switch(val) {
case CPUFREQ_MINMAX:
cpufreq_updateminmax(data, sa1100_dram_settings->speed, -1);
break;
case CPUFREQ_PRECHANGE:
if(ci->new > ci->cur)
sa1100_update_dram_timings(ci->cur, ci->new);
break;
case CPUFREQ_POSTCHANGE: freqs.old = cur;
if(ci->new < ci->cur) freqs.new = policy->max;
sa1100_update_dram_timings(ci->cur, ci->new); freqs.cpu = CPUFREQ_ALL_CPUS;
break;
default:
printk(KERN_INFO "%s: ignoring unknown notifier type (%ld)\n",
__FUNCTION__, val);
}
return 0;
}
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
if (policy->max > cur)
sa1100_update_dram_timings(cur, policy->max);
PPCR = sa11x0_freq_to_ppcr(policy->max);
static struct notifier_block sa1100_dram_block = { if (policy->max < cur)
.notifier_call = sa1100_dram_notifier, sa1100_update_dram_timings(cur, policy->max);
};
static void sa1100_setspeed(unsigned int cpu, unsigned int khz) cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
{
PPCR = sa11x0_freq_to_ppcr(khz);
} }
static struct cpufreq_freqs sa1100_freqs = { static struct cpufreq_policy sa1100_policy = {
.min = 59000, .cpu = 0,
.max = 287000, .policy = CPUFREQ_POLICY_POWERSAVE,
.max_cpu_freq = 287000,
}; };
static struct cpufreq_driver sa1100_driver = { static struct cpufreq_driver sa1100_driver = {
.freq = &sa1100_freqs, .verify = sa11x0_verify_speed,
.validate = sa11x0_validatespeed, .setpolicy = sa1100_setspeed,
.setspeed = sa1100_setspeed, .policy = &sa1100_policy,
.sync = 1, .cpu_min_freq = 59000,
}; };
static int __init sa1100_dram_init(void) static int __init sa1100_dram_init(void)
...@@ -242,11 +216,9 @@ static int __init sa1100_dram_init(void) ...@@ -242,11 +216,9 @@ 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) {
ret = cpufreq_register_notifier(&sa1100_dram_block); sa1100_driver.cpu_curr_freq[0] =
if (ret) sa1100_policy.min =
return ret; sa1100_policy.max = sa11x0_getspeed();
sa1100_freqs.cur = sa11x0_getspeed();
ret = cpufreq_register(&sa1100_driver); ret = cpufreq_register(&sa1100_driver);
} }
......
...@@ -28,11 +28,9 @@ ...@@ -28,11 +28,9 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
#undef DEBUG #include "generic.h"
extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz); #undef DEBUG
extern unsigned int sa11x0_validatespeed(unsigned int cpu, unsigned int khz);
extern unsigned int sa11x0_getspeed(void);
struct sdram_params { struct sdram_params {
u_char rows; /* bits */ u_char rows; /* bits */
...@@ -214,15 +212,16 @@ sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram) ...@@ -214,15 +212,16 @@ 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 cpu, unsigned int khz) static void sa1110_setspeed(struct cpufreq_policy *policy)
{ {
struct sdram_params *sdram = &sdram_params; struct sdram_params *sdram = &sdram_params;
struct cpufreq_freqs freqs;
struct sdram_info sd; struct sdram_info sd;
unsigned long flags; unsigned long flags;
unsigned int ppcr, unused; unsigned int ppcr, unused;
ppcr = sa11x0_freq_to_ppcr(khz); ppcr = sa11x0_freq_to_ppcr(policy->max);
sdram_calculate_timing(&sd, khz, sdram); sdram_calculate_timing(&sd, policy->max, sdram);
#if 0 #if 0
/* /*
...@@ -230,7 +229,7 @@ static void sa1110_setspeed(unsigned int cpu, unsigned int khz) ...@@ -230,7 +229,7 @@ static void sa1110_setspeed(unsigned int cpu, unsigned int khz)
* and errata, but they seem to work. Need to get a storage * and errata, but they seem to work. Need to get a storage
* scope on to the SDRAM signals to work out why. * scope on to the SDRAM signals to work out why.
*/ */
if (khz < 147500) { if (policy->max < 147500) {
sd.mdrefr |= MDREFR_K1DB2; sd.mdrefr |= MDREFR_K1DB2;
sd.mdcas[0] = 0xaaaaaa7f; sd.mdcas[0] = 0xaaaaaa7f;
} else { } else {
...@@ -240,6 +239,13 @@ static void sa1110_setspeed(unsigned int cpu, unsigned int khz) ...@@ -240,6 +239,13 @@ static void sa1110_setspeed(unsigned int cpu, unsigned int khz)
sd.mdcas[1] = 0xaaaaaaaa; sd.mdcas[1] = 0xaaaaaaaa;
sd.mdcas[2] = 0xaaaaaaaa; sd.mdcas[2] = 0xaaaaaaaa;
#endif #endif
freqs.old = sa11x0_getspeed();
freqs.new = policy->max;
freqs.cpu = CPUFREQ_ALL_CPUS;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
/* /*
* The clock could be going away for some time. Set the SDRAMs * The clock could be going away for some time. Set the SDRAMs
* to refresh rapidly (every 64 memory clock cycles). To get * to refresh rapidly (every 64 memory clock cycles). To get
...@@ -257,7 +263,7 @@ static void sa1110_setspeed(unsigned int cpu, unsigned int khz) ...@@ -257,7 +263,7 @@ static void sa1110_setspeed(unsigned int cpu, unsigned int khz)
* the programming. * the programming.
*/ */
local_irq_save(flags); local_irq_save(flags);
asm("mcr p15, 0, %0, c10, c4" : : "r" (0)); asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
udelay(10); udelay(10);
__asm__ __volatile__(" __asm__ __volatile__("
b 2f b 2f
...@@ -282,19 +288,22 @@ static void sa1110_setspeed(unsigned int cpu, unsigned int khz) ...@@ -282,19 +288,22 @@ static void sa1110_setspeed(unsigned int cpu, unsigned int khz)
/* /*
* Now, return the SDRAM refresh back to normal. * Now, return the SDRAM refresh back to normal.
*/ */
sdram_update_refresh(khz, sdram); sdram_update_refresh(policy->max, sdram);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
} }
static struct cpufreq_freqs sa1110_freqs = { static struct cpufreq_policy sa1110_policy = {
.min = 59000, .cpu = 0,
.max = 287000, .policy = CPUFREQ_POLICY_POWERSAVE,
.max_cpu_freq = 287000,
}; };
static struct cpufreq_driver sa1110_driver = { static struct cpufreq_driver sa1110_driver = {
.freq = &sa1110_freqs, .verify = sa11x0_verify_speed,
.validate = sa11x0_validatespeed, .setpolicy = sa1110_setspeed,
.setspeed = sa1110_setspeed, .policy = &sa1110_policy,
.sync = 1, .cpu_min_freq = 59000,
}; };
static int __init sa1110_clk_init(void) static int __init sa1110_clk_init(void)
...@@ -318,8 +327,11 @@ static int __init sa1110_clk_init(void) ...@@ -318,8 +327,11 @@ static int __init sa1110_clk_init(void)
memcpy(&sdram_params, sdram, sizeof(sdram_params)); memcpy(&sdram_params, sdram, sizeof(sdram_params));
sa1110_freqs.cur = sa11x0_getspeed(); sa1110_driver.cpu_cur_freq[0] =
sa1110_setspeed(0, sa1110_freqs.cur); sa1110_policy.min =
sa1110_policy.max = sa11x0_getspeed();
sa1110_setspeed(&sa1110_policy);
return cpufreq_register(&sa1110_driver); return cpufreq_register(&sa1110_driver);
} }
......
...@@ -55,20 +55,26 @@ unsigned int sa11x0_freq_to_ppcr(unsigned int khz) ...@@ -55,20 +55,26 @@ unsigned int sa11x0_freq_to_ppcr(unsigned int khz)
khz /= 100; khz /= 100;
for (i = NR_FREQS - 1; i > 0; i--) for (i = 0; i < ARRAY_SIZE(cclk_frequency_100khz); i--)
if (cclk_frequency_100khz[i] <= khz) if (cclk_frequency_100khz[i] >= khz)
break; break;
return i; return i;
} }
/* /*
* Validate the speed in khz. If we can't generate the precise * Validate the policy. We aren't able to do any fancy in-kernel
* frequency requested, round it down (to be on the safe side). * scaling, so we force min=max, and set the policy to "performance".
* If we can't generate the precise frequency requested, round it up.
*/ */
unsigned int sa11x0_validatespeed(unsigned int cpu, unsigned int khz) void sa11x0_verify_speed(struct cpufreq_policy *policy)
{ {
return cclk_frequency_100khz[sa11x0_freq_to_ppcr(khz)] * 100; if (policy->max > policy->max_cpu_freq)
policy->max = policy->max_cpu_freq;
policy->max = cclk_frequency_100khz[sa11x0_freq_to_ppcr(policy->max)] * 100;
policy->min = policy->max;
policy->policy = CPUFREQ_POLICY_POWERSAVE;
} }
unsigned int sa11x0_getspeed(void) unsigned int sa11x0_getspeed(void)
......
...@@ -17,3 +17,9 @@ extern void (*sa1100fb_lcd_power)(int on); ...@@ -17,3 +17,9 @@ extern void (*sa1100fb_lcd_power)(int on);
extern void sa1110_mb_enable(void); extern void sa1110_mb_enable(void);
extern void sa1110_mb_disable(void); extern void sa1110_mb_disable(void);
struct cpufreq_policy;
extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz);
extern void sa11x0_verify_speed(struct cpufreq_policy *policy);
extern unsigned int sa11x0_getspeed(void);
...@@ -110,12 +110,11 @@ sa1100_pcmcia_default_mecr_timing(unsigned int sock, unsigned int cpu_speed, ...@@ -110,12 +110,11 @@ sa1100_pcmcia_default_mecr_timing(unsigned int sock, unsigned int cpu_speed,
* Call board specific BS value calculation to allow boards * Call board specific BS value calculation to allow boards
* to tweak the BS values. * to tweak the BS values.
*/ */
static int sa1100_pcmcia_set_mecr(int sock) static int sa1100_pcmcia_set_mecr(int sock, unsigned int cpu_clock)
{ {
struct sa1100_pcmcia_socket *skt; struct sa1100_pcmcia_socket *skt;
u32 mecr; u32 mecr;
int clock; unsigned long flags;
long flags;
unsigned int bs; unsigned int bs;
if (sock < 0 || sock > SA1100_PCMCIA_MAX_SOCK) if (sock < 0 || sock > SA1100_PCMCIA_MAX_SOCK)
...@@ -125,8 +124,7 @@ static int sa1100_pcmcia_set_mecr(int sock) ...@@ -125,8 +124,7 @@ static int sa1100_pcmcia_set_mecr(int sock)
local_irq_save(flags); local_irq_save(flags);
clock = cpufreq_get(0); bs = pcmcia_low_level->socket_get_timing(sock, cpu_clock, skt->speed_io);
bs = pcmcia_low_level->socket_get_timing(sock, clock, skt->speed_io);
mecr = MECR; mecr = MECR;
MECR_FAST_SET(mecr, sock, 0); MECR_FAST_SET(mecr, sock, 0);
...@@ -652,7 +650,7 @@ sa1100_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map) ...@@ -652,7 +650,7 @@ sa1100_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
if ( map->speed == 0) if ( map->speed == 0)
map->speed = SA1100_PCMCIA_IO_ACCESS; map->speed = SA1100_PCMCIA_IO_ACCESS;
sa1100_pcmcia_set_mecr( sock ); sa1100_pcmcia_set_mecr(sock, cpufreq_get(0));
} }
if (map->stop == 1) if (map->stop == 1)
...@@ -741,7 +739,7 @@ sa1100_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map) ...@@ -741,7 +739,7 @@ sa1100_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map)
map->speed = SA1100_PCMCIA_5V_MEM_ACCESS; map->speed = SA1100_PCMCIA_5V_MEM_ACCESS;
} }
sa1100_pcmcia_set_mecr( sock ); sa1100_pcmcia_set_mecr(sock, cpufreq_get(0));
} }
...@@ -885,9 +883,8 @@ static void sa1100_pcmcia_update_mecr(unsigned int clock) ...@@ -885,9 +883,8 @@ static void sa1100_pcmcia_update_mecr(unsigned int clock)
{ {
unsigned int sock; unsigned int sock;
for (sock = 0; sock < SA1100_PCMCIA_MAX_SOCK; ++sock) { for (sock = 0; sock < SA1100_PCMCIA_MAX_SOCK; ++sock)
sa1100_pcmcia_set_mecr(sock); sa1100_pcmcia_set_mecr(sock, clock);
}
} }
/* sa1100_pcmcia_notifier() /* sa1100_pcmcia_notifier()
...@@ -904,26 +901,26 @@ static int ...@@ -904,26 +901,26 @@ static int
sa1100_pcmcia_notifier(struct notifier_block *nb, unsigned long val, sa1100_pcmcia_notifier(struct notifier_block *nb, unsigned long val,
void *data) void *data)
{ {
struct cpufreq_info *ci = data; struct cpufreq_freqs *freqs = data;
switch (val) { switch (val) {
case CPUFREQ_PRECHANGE: case CPUFREQ_PRECHANGE:
if (ci->new_freq > ci->old_freq) { if (freqs->new > freqs->old) {
DEBUG(2, "%s(): new frequency %u.%uMHz > %u.%uMHz, pre-updating\n", DEBUG(2, "%s(): new frequency %u.%uMHz > %u.%uMHz, "
__FUNCTION__, "pre-updating\n", __FUNCTION__,
ci->new_freq / 1000, (ci->new_freq / 100) % 10, freqs->new / 1000, (freqs->new / 100) % 10,
ci->old_freq / 1000, (ci->old_freq / 100) % 10); freqs->old / 1000, (freqs->old / 100) % 10);
sa1100_pcmcia_update_mecr(ci->new_freq); sa1100_pcmcia_update_mecr(freqs->new);
} }
break; break;
case CPUFREQ_POSTCHANGE: case CPUFREQ_POSTCHANGE:
if (ci->new_freq < ci->old_freq) { if (freqs->new < freqs->old) {
DEBUG(2, "%s(): new frequency %u.%uMHz < %u.%uMHz, post-updating\n", DEBUG(2, "%s(): new frequency %u.%uMHz < %u.%uMHz, "
__FUNCTION__, "post-updating\n", __FUNCTION__,
ci->new_freq / 1000, (ci->new_freq / 100) % 10, freqs->new / 1000, (freqs->new / 100) % 10,
ci->old_freq / 1000, (ci->old_freq / 100) % 10); freqs->old / 1000, (freqs->old / 100) % 10);
sa1100_pcmcia_update_mecr(ci->new_freq); sa1100_pcmcia_update_mecr(freqs->new);
} }
break; break;
} }
...@@ -946,7 +943,7 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops) ...@@ -946,7 +943,7 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops)
struct pcmcia_init pcmcia_init; struct pcmcia_init pcmcia_init;
struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK]; struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
struct pcmcia_state_array state_array; struct pcmcia_state_array state_array;
unsigned int i; unsigned int i, cpu_clock;
int ret; int ret;
/* /*
...@@ -986,6 +983,8 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops) ...@@ -986,6 +983,8 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops)
goto shutdown; goto shutdown;
} }
cpu_clock = cpufreq_get(0);
/* /*
* We initialize the MECR to default values here, because we are * We initialize the MECR to default values here, because we are
* not guaranteed to see a SetIOMap operation at runtime. * not guaranteed to see a SetIOMap operation at runtime.
...@@ -1019,7 +1018,7 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops) ...@@ -1019,7 +1018,7 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops)
goto out_err; goto out_err;
} }
sa1100_pcmcia_set_mecr( i ); sa1100_pcmcia_set_mecr(i, cpu_clock);
} }
...@@ -1110,7 +1109,7 @@ static int __init sa1100_pcmcia_init(void) ...@@ -1110,7 +1109,7 @@ static int __init sa1100_pcmcia_init(void)
servinfo_t info; servinfo_t info;
int ret, i; int ret, i;
printk(KERN_INFO "SA-1100 PCMCIA (CS release %s)\n", CS_RELEASE); printk(KERN_INFO "SA11x0 PCMCIA (CS release %s)\n", CS_RELEASE);
CardServices(GetCardServicesInfo, &info); CardServices(GetCardServicesInfo, &info);
if (info.Revision != CS_RELEASE_CODE) { if (info.Revision != CS_RELEASE_CODE) {
...@@ -1127,7 +1126,8 @@ static int __init sa1100_pcmcia_init(void) ...@@ -1127,7 +1126,8 @@ static int __init sa1100_pcmcia_init(void)
} }
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
ret = cpufreq_register_notifier(&sa1100_pcmcia_notifier_block); ret = cpufreq_register_notifier(&sa1100_pcmcia_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
if (ret < 0) { if (ret < 0) {
printk(KERN_ERR "Unable to register CPU frequency change " printk(KERN_ERR "Unable to register CPU frequency change "
"notifier (%d)\n", ret); "notifier (%d)\n", ret);
...@@ -1216,7 +1216,7 @@ static void __exit sa1100_pcmcia_exit(void) ...@@ -1216,7 +1216,7 @@ static void __exit sa1100_pcmcia_exit(void)
} }
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
cpufreq_unregister_notifier(&sa1100_pcmcia_notifier_block); cpufreq_unregister_notifier(&sa1100_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
#endif #endif
} }
......
...@@ -1593,33 +1593,42 @@ static unsigned int sa1100fb_min_dma_period(struct sa1100fb_info *fbi) ...@@ -1593,33 +1593,42 @@ static unsigned int sa1100fb_min_dma_period(struct sa1100fb_info *fbi)
* subsystem. * subsystem.
*/ */
static int static int
sa1100fb_clkchg_notifier(struct notifier_block *nb, unsigned long val, sa1100fb_freq_transition(struct notifier_block *nb, unsigned long val,
void *data) void *data)
{ {
struct sa1100fb_info *fbi = TO_INF(nb, clockchg); struct sa1100fb_info *fbi = TO_INF(nb, freq_transition);
struct cpufreq_minmax *mm = data; struct cpufreq_freqs *f = data;
u_int pcd; u_int pcd;
switch (val) { switch (val) {
case CPUFREQ_MINMAX:
printk(KERN_DEBUG "min dma period: %d ps, old clock %d kHz, "
"new clock %d kHz\n", sa1100fb_min_dma_period(fbi),
mm->cur_freq, mm->new_freq);
/* todo: fill in min/max values */
break;
case CPUFREQ_PRECHANGE: case CPUFREQ_PRECHANGE:
set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE); set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE);
break; break;
case CPUFREQ_POSTCHANGE: case CPUFREQ_POSTCHANGE:
pcd = get_pcd(fbi->fb.var.pixclock, cpufreq_get(0)); pcd = get_pcd(fbi->fb.var.pixclock, f->new);
fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd); fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd);
set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE); set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE);
break; break;
} }
return 0; return 0;
} }
static int
sa1100fb_freq_policy(struct notifier_block *nb, unsigned long val,
void *data)
{
struct sa1100fb_info *fbi = TO_INF(nb, freq_policy);
struct cpufreq_policy *policy = data;
if (val == CPUFREQ_INCOMPATIBLE) {
printk(KERN_DEBUG "min dma period: %d ps, "
"new clock %d kHz\n", sa1100fb_min_dma_period(fbi),
policy->max);
/* todo: fill in min/max values */
}
return 0;
}
#endif #endif
#ifdef CONFIG_PM #ifdef CONFIG_PM
...@@ -1831,8 +1840,10 @@ int __init sa1100fb_init(void) ...@@ -1831,8 +1840,10 @@ int __init sa1100fb_init(void)
fbi->pm->data = fbi; fbi->pm->data = fbi;
#endif #endif
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
fbi->clockchg.notifier_call = sa1100fb_clkchg_notifier; fbi->freq_transition.notifier_call = sa1100fb_freq_transition;
cpufreq_register_notifier(&fbi->clockchg); fbi->freq_policy.notifier_call = sa1100fb_freq_policy;
cpufreq_register_notifier(&fbi->freq_transition, CPUFREQ_TRANSITION_NOTIFIER);
cpufreq_register_notifier(&fbi->freq_policy, CPUFREQ_POLICY_NOTIFIER);
#endif #endif
/* /*
......
...@@ -107,7 +107,8 @@ struct sa1100fb_info { ...@@ -107,7 +107,8 @@ struct sa1100fb_info {
struct pm_dev *pm; struct pm_dev *pm;
#endif #endif
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
struct notifier_block clockchg; struct notifier_block freq_transition;
struct notifier_block freq_policy;
#endif #endif
}; };
......
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