Commit bdbda1c4 authored by Dave Jones's avatar Dave Jones

Merge delerium.codemonkey.org.uk:/mnt/data/src/bk/bk-linus

into delerium.codemonkey.org.uk:/mnt/data/src/bk/cpufreq
parents afb7238d d883263c
...@@ -6,8 +6,6 @@ ...@@ -6,8 +6,6 @@
* Licensed under the terms of the GNU GPL License version 2. * Licensed under the terms of the GNU GPL License version 2.
* Based upon datasheets & sample CPUs kindly provided by AMD. * Based upon datasheets & sample CPUs kindly provided by AMD.
* *
* BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
*
* Errata 5: Processor may fail to execute a FID/VID change in presence of interrupt. * Errata 5: Processor may fail to execute a FID/VID change in presence of interrupt.
* - We cli/sti on stepping A0 CPUs around the FID/VID transition. * - We cli/sti on stepping A0 CPUs around the FID/VID transition.
* Errata 15: Processors with half frequency multipliers may hang upon wakeup from disconnect. * Errata 15: Processors with half frequency multipliers may hang upon wakeup from disconnect.
...@@ -36,14 +34,6 @@ ...@@ -36,14 +34,6 @@
#include "powernow-k7.h" #include "powernow-k7.h"
#define DEBUG
#ifdef DEBUG
#define dprintk(msg...) printk(msg)
#else
#define dprintk(msg...) do { } while(0)
#endif
#define PFX "powernow: " #define PFX "powernow: "
...@@ -97,6 +87,7 @@ static int fid_codes[32] = { ...@@ -97,6 +87,7 @@ static int fid_codes[32] = {
*/ */
static int acpi_force; static int acpi_force;
static int debug;
static struct cpufreq_frequency_table *powernow_table; static struct cpufreq_frequency_table *powernow_table;
...@@ -109,6 +100,21 @@ static unsigned int fsb; ...@@ -109,6 +100,21 @@ static unsigned int fsb;
static unsigned int latency; static unsigned int latency;
static char have_a0; static char have_a0;
static void dprintk(const char *fmt, ...)
{
char s[256];
va_list args;
if (debug==0)
return;
va_start(args,fmt);
vsprintf(s, fmt, args);
printk(s);
va_end(args);
}
static int check_fsb(unsigned int fsbspeed) static int check_fsb(unsigned int fsbspeed)
{ {
int delta; int delta;
...@@ -196,7 +202,7 @@ static int get_ranges (unsigned char *pst) ...@@ -196,7 +202,7 @@ static int get_ranges (unsigned char *pst)
#endif #endif
} }
dprintk (KERN_INFO PFX " FID: 0x%x (%d.%dx [%dMHz])\t", fid, dprintk (KERN_INFO PFX " FID: 0x%x (%d.%dx [%dMHz]) ", fid,
fid_codes[fid] / 10, fid_codes[fid] % 10, speed/1000); fid_codes[fid] / 10, fid_codes[fid] % 10, speed/1000);
if (speed < minimum_speed) if (speed < minimum_speed)
...@@ -377,7 +383,7 @@ static int powernow_acpi_init(void) ...@@ -377,7 +383,7 @@ static int powernow_acpi_init(void)
powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
} }
dprintk (KERN_INFO PFX " FID: 0x%x (%d.%dx [%dMHz])\t", fid, dprintk (KERN_INFO PFX " FID: 0x%x (%d.%dx [%dMHz]) ", fid,
fid_codes[fid] / 10, fid_codes[fid] % 10, speed/1000); fid_codes[fid] / 10, fid_codes[fid] % 10, speed/1000);
dprintk ("VID: 0x%x (%d.%03dV)\n", vid, mobile_vid_table[vid]/1000, dprintk ("VID: 0x%x (%d.%03dV)\n", vid, mobile_vid_table[vid]/1000,
mobile_vid_table[vid]%1000); mobile_vid_table[vid]%1000);
...@@ -467,9 +473,9 @@ static int powernow_decode_bios (int maxfid, int startvid) ...@@ -467,9 +473,9 @@ static int powernow_decode_bios (int maxfid, int startvid)
(maxfid==pst->maxfid) && (startvid==pst->startvid)) (maxfid==pst->maxfid) && (startvid==pst->startvid))
{ {
dprintk (KERN_INFO PFX "PST:%d (@%p)\n", i, pst); dprintk (KERN_INFO PFX "PST:%d (@%p)\n", i, pst);
dprintk (KERN_INFO PFX " cpuid: 0x%x\t", pst->cpuid); dprintk (KERN_INFO PFX " cpuid: 0x%x ", pst->cpuid);
dprintk ("fsb: %d\t", pst->fsbspeed); dprintk ("fsb: %d ", pst->fsbspeed);
dprintk ("maxFID: 0x%x\t", pst->maxfid); dprintk ("maxFID: 0x%x ", pst->maxfid);
dprintk ("startvid: 0x%x\n", pst->startvid); dprintk ("startvid: 0x%x\n", pst->startvid);
ret = get_ranges ((char *) pst + sizeof (struct pst_s)); ret = get_ranges ((char *) pst + sizeof (struct pst_s));
...@@ -591,7 +597,7 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy) ...@@ -591,7 +597,7 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
/* A K7 with powernow technology is set to max frequency by BIOS */ /* A K7 with powernow technology is set to max frequency by BIOS */
fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID]; fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.MFID];
if (!fsb) { if (!fsb) {
printk(KERN_WARNING PFX "can not determine bus frequency\n"); printk(KERN_WARNING PFX "can not determine bus frequency\n");
return -EINVAL; return -EINVAL;
...@@ -679,8 +685,10 @@ static void __exit powernow_exit (void) ...@@ -679,8 +685,10 @@ static void __exit powernow_exit (void)
kfree(powernow_table); kfree(powernow_table);
} }
module_param(debug, int, 0444);
MODULE_PARM_DESC(debug, "enable debug output.");
module_param(acpi_force, int, 0444); module_param(acpi_force, int, 0444);
MODULE_PARM_DESC(acpi_force, "Force ACPI to be used"); MODULE_PARM_DESC(acpi_force, "Force ACPI to be used.");
MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>"); MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors."); MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors.");
......
...@@ -60,6 +60,13 @@ static const struct cpu_id cpu_id_dothan_a1 = { ...@@ -60,6 +60,13 @@ static const struct cpu_id cpu_id_dothan_a1 = {
.x86_mask = 1, .x86_mask = 1,
}; };
static const struct cpu_id cpu_id_dothan_b0 = {
.x86_vendor = X86_VENDOR_INTEL,
.x86 = 6,
.x86_model = 13,
.x86_mask = 6,
};
struct cpu_model struct cpu_model
{ {
const struct cpu_id *cpu_id; const struct cpu_id *cpu_id;
...@@ -214,7 +221,7 @@ static struct cpu_model models[] = ...@@ -214,7 +221,7 @@ static struct cpu_model models[] =
BANIAS(1500), BANIAS(1500),
BANIAS(1600), BANIAS(1600),
BANIAS(1700), BANIAS(1700),
{ 0, } { NULL, }
}; };
#undef _BANIAS #undef _BANIAS
#undef BANIAS #undef BANIAS
...@@ -400,7 +407,8 @@ static int centrino_cpu_init(struct cpufreq_policy *policy) ...@@ -400,7 +407,8 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
return -ENODEV; return -ENODEV;
if ((centrino_verify_cpu_id(cpu, &cpu_id_banias)) && if ((centrino_verify_cpu_id(cpu, &cpu_id_banias)) &&
(centrino_verify_cpu_id(cpu, &cpu_id_dothan_a1))) { (centrino_verify_cpu_id(cpu, &cpu_id_dothan_a1)) &&
(centrino_verify_cpu_id(cpu, &cpu_id_dothan_b0))) {
printk(KERN_INFO PFX "found unsupported CPU with Enhanced SpeedStep: " printk(KERN_INFO PFX "found unsupported CPU with Enhanced SpeedStep: "
"send /proc/cpuinfo to " MAINTAINER "\n"); "send /proc/cpuinfo to " MAINTAINER "\n");
return -ENODEV; return -ENODEV;
......
...@@ -617,8 +617,8 @@ static int cpufreq_resume(struct sys_device * sysdev) ...@@ -617,8 +617,8 @@ static int cpufreq_resume(struct sys_device * sysdev)
if (cpufreq_driver->flags & CPUFREQ_PANIC_RESUME_OUTOFSYNC) if (cpufreq_driver->flags & CPUFREQ_PANIC_RESUME_OUTOFSYNC)
panic("CPU Frequency is out of sync."); panic("CPU Frequency is out of sync.");
printk(KERN_WARNING "Warning: CPU frequency out of sync: cpufreq and timing" printk(KERN_WARNING "Warning: CPU frequency is %u, "
"core thinks of %u, is %u kHz.\n", cpu_policy->cur, cur_freq); "cpufreq assumed %u kHz.\n", cur_freq, cpu_policy->cur);
freqs.cpu = cpu; freqs.cpu = cpu;
freqs.old = cpu_policy->cur; freqs.old = cpu_policy->cur;
...@@ -626,6 +626,8 @@ static int cpufreq_resume(struct sys_device * sysdev) ...@@ -626,6 +626,8 @@ static int cpufreq_resume(struct sys_device * sysdev)
notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_RESUMECHANGE, &freqs); notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_RESUMECHANGE, &freqs);
adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs); adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs);
cpu_policy->cur = cur_freq;
} }
} }
...@@ -1065,9 +1067,8 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) ...@@ -1065,9 +1067,8 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
if (cpufreq_driver->flags & CPUFREQ_PANIC_OUTOFSYNC) if (cpufreq_driver->flags & CPUFREQ_PANIC_OUTOFSYNC)
panic("CPU Frequency is out of sync."); panic("CPU Frequency is out of sync.");
printk(KERN_WARNING "Warning: CPU frequency out of sync: " printk(KERN_WARNING "Warning: CPU frequency is %u, "
"cpufreq and timing core thinks of %u, is %u kHz.\n", "cpufreq assumed %u kHz.\n", freqs->old, cpufreq_cpu_data[freqs->cpu]->cur);
cpufreq_cpu_data[freqs->cpu]->cur, freqs->old);
freqs->old = cpufreq_cpu_data[freqs->cpu]->cur; freqs->old = cpufreq_cpu_data[freqs->cpu]->cur;
} }
} }
......
...@@ -82,6 +82,13 @@ userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val, ...@@ -82,6 +82,13 @@ userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
{ {
struct cpufreq_freqs *freq = data; struct cpufreq_freqs *freq = data;
/* Don't update cur_freq if CPU is managed and we're
* waking up: else we won't remember what frequency
* we need to set the CPU to.
*/
if (cpu_is_managed[freq->cpu] && (val == CPUFREQ_RESUMECHANGE))
return 0;
cpu_cur_freq[freq->cpu] = freq->new; cpu_cur_freq[freq->cpu] = freq->new;
return 0; return 0;
...@@ -522,6 +529,9 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, ...@@ -522,6 +529,9 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
else if (policy->min > cpu_cur_freq[cpu]) else if (policy->min > cpu_cur_freq[cpu])
__cpufreq_driver_target(&current_policy[cpu], policy->min, __cpufreq_driver_target(&current_policy[cpu], policy->min,
CPUFREQ_RELATION_L); CPUFREQ_RELATION_L);
else
__cpufreq_driver_target(&current_policy[cpu], cpu_cur_freq[cpu],
CPUFREQ_RELATION_L);
memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy)); memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
up(&userspace_sem); up(&userspace_sem);
break; break;
......
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