[go: nahoru, domu]

1/*
2 *  AMD K7 Powernow driver.
3 *  (C) 2003 Dave Jones on behalf of SuSE Labs.
4 *  (C) 2003-2004 Dave Jones <davej@redhat.com>
5 *
6 *  Licensed under the terms of the GNU GPL License version 2.
7 *  Based upon datasheets & sample CPUs kindly provided by AMD.
8 *
9 * Errata 5:
10 *  CPU may fail to execute a FID/VID change in presence of interrupt.
11 *  - We cli/sti on stepping A0 CPUs around the FID/VID transition.
12 * Errata 15:
13 *  CPU with half frequency multipliers may hang upon wakeup from disconnect.
14 *  - We disable half multipliers if ACPI is used on A0 stepping CPUs.
15 */
16
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/init.h>
21#include <linux/cpufreq.h>
22#include <linux/slab.h>
23#include <linux/string.h>
24#include <linux/dmi.h>
25#include <linux/timex.h>
26#include <linux/io.h>
27
28#include <asm/timer.h>		/* Needed for recalibrate_cpu_khz() */
29#include <asm/msr.h>
30#include <asm/cpu_device_id.h>
31
32#ifdef CONFIG_X86_POWERNOW_K7_ACPI
33#include <linux/acpi.h>
34#include <acpi/processor.h>
35#endif
36
37#include "powernow-k7.h"
38
39#define PFX "powernow: "
40
41
42struct psb_s {
43	u8 signature[10];
44	u8 tableversion;
45	u8 flags;
46	u16 settlingtime;
47	u8 reserved1;
48	u8 numpst;
49};
50
51struct pst_s {
52	u32 cpuid;
53	u8 fsbspeed;
54	u8 maxfid;
55	u8 startvid;
56	u8 numpstates;
57};
58
59#ifdef CONFIG_X86_POWERNOW_K7_ACPI
60union powernow_acpi_control_t {
61	struct {
62		unsigned long fid:5,
63			vid:5,
64			sgtc:20,
65			res1:2;
66	} bits;
67	unsigned long val;
68};
69#endif
70
71/* divide by 1000 to get VCore voltage in V. */
72static const int mobile_vid_table[32] = {
73    2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
74    1600, 1550, 1500, 1450, 1400, 1350, 1300, 0,
75    1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
76    1075, 1050, 1025, 1000, 975, 950, 925, 0,
77};
78
79/* divide by 10 to get FID. */
80static const int fid_codes[32] = {
81    110, 115, 120, 125, 50, 55, 60, 65,
82    70, 75, 80, 85, 90, 95, 100, 105,
83    30, 190, 40, 200, 130, 135, 140, 210,
84    150, 225, 160, 165, 170, 180, -1, -1,
85};
86
87/* This parameter is used in order to force ACPI instead of legacy method for
88 * configuration purpose.
89 */
90
91static int acpi_force;
92
93static struct cpufreq_frequency_table *powernow_table;
94
95static unsigned int can_scale_bus;
96static unsigned int can_scale_vid;
97static unsigned int minimum_speed = -1;
98static unsigned int maximum_speed;
99static unsigned int number_scales;
100static unsigned int fsb;
101static unsigned int latency;
102static char have_a0;
103
104static int check_fsb(unsigned int fsbspeed)
105{
106	int delta;
107	unsigned int f = fsb / 1000;
108
109	delta = (fsbspeed > f) ? fsbspeed - f : f - fsbspeed;
110	return delta < 5;
111}
112
113static const struct x86_cpu_id powernow_k7_cpuids[] = {
114	{ X86_VENDOR_AMD, 6, },
115	{}
116};
117MODULE_DEVICE_TABLE(x86cpu, powernow_k7_cpuids);
118
119static int check_powernow(void)
120{
121	struct cpuinfo_x86 *c = &cpu_data(0);
122	unsigned int maxei, eax, ebx, ecx, edx;
123
124	if (!x86_match_cpu(powernow_k7_cpuids))
125		return 0;
126
127	/* Get maximum capabilities */
128	maxei = cpuid_eax(0x80000000);
129	if (maxei < 0x80000007) {	/* Any powernow info ? */
130#ifdef MODULE
131		printk(KERN_INFO PFX "No powernow capabilities detected\n");
132#endif
133		return 0;
134	}
135
136	if ((c->x86_model == 6) && (c->x86_mask == 0)) {
137		printk(KERN_INFO PFX "K7 660[A0] core detected, "
138				"enabling errata workarounds\n");
139		have_a0 = 1;
140	}
141
142	cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
143
144	/* Check we can actually do something before we say anything.*/
145	if (!(edx & (1 << 1 | 1 << 2)))
146		return 0;
147
148	printk(KERN_INFO PFX "PowerNOW! Technology present. Can scale: ");
149
150	if (edx & 1 << 1) {
151		printk("frequency");
152		can_scale_bus = 1;
153	}
154
155	if ((edx & (1 << 1 | 1 << 2)) == 0x6)
156		printk(" and ");
157
158	if (edx & 1 << 2) {
159		printk("voltage");
160		can_scale_vid = 1;
161	}
162
163	printk(".\n");
164	return 1;
165}
166
167#ifdef CONFIG_X86_POWERNOW_K7_ACPI
168static void invalidate_entry(unsigned int entry)
169{
170	powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
171}
172#endif
173
174static int get_ranges(unsigned char *pst)
175{
176	unsigned int j;
177	unsigned int speed;
178	u8 fid, vid;
179
180	powernow_table = kzalloc((sizeof(*powernow_table) *
181				(number_scales + 1)), GFP_KERNEL);
182	if (!powernow_table)
183		return -ENOMEM;
184
185	for (j = 0 ; j < number_scales; j++) {
186		fid = *pst++;
187
188		powernow_table[j].frequency = (fsb * fid_codes[fid]) / 10;
189		powernow_table[j].driver_data = fid; /* lower 8 bits */
190
191		speed = powernow_table[j].frequency;
192
193		if ((fid_codes[fid] % 10) == 5) {
194#ifdef CONFIG_X86_POWERNOW_K7_ACPI
195			if (have_a0 == 1)
196				invalidate_entry(j);
197#endif
198		}
199
200		if (speed < minimum_speed)
201			minimum_speed = speed;
202		if (speed > maximum_speed)
203			maximum_speed = speed;
204
205		vid = *pst++;
206		powernow_table[j].driver_data |= (vid << 8); /* upper 8 bits */
207
208		pr_debug("   FID: 0x%x (%d.%dx [%dMHz])  "
209			 "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
210			 fid_codes[fid] % 10, speed/1000, vid,
211			 mobile_vid_table[vid]/1000,
212			 mobile_vid_table[vid]%1000);
213	}
214	powernow_table[number_scales].frequency = CPUFREQ_TABLE_END;
215	powernow_table[number_scales].driver_data = 0;
216
217	return 0;
218}
219
220
221static void change_FID(int fid)
222{
223	union msr_fidvidctl fidvidctl;
224
225	rdmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
226	if (fidvidctl.bits.FID != fid) {
227		fidvidctl.bits.SGTC = latency;
228		fidvidctl.bits.FID = fid;
229		fidvidctl.bits.VIDC = 0;
230		fidvidctl.bits.FIDC = 1;
231		wrmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
232	}
233}
234
235
236static void change_VID(int vid)
237{
238	union msr_fidvidctl fidvidctl;
239
240	rdmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
241	if (fidvidctl.bits.VID != vid) {
242		fidvidctl.bits.SGTC = latency;
243		fidvidctl.bits.VID = vid;
244		fidvidctl.bits.FIDC = 0;
245		fidvidctl.bits.VIDC = 1;
246		wrmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
247	}
248}
249
250
251static int powernow_target(struct cpufreq_policy *policy, unsigned int index)
252{
253	u8 fid, vid;
254	struct cpufreq_freqs freqs;
255	union msr_fidvidstatus fidvidstatus;
256	int cfid;
257
258	/* fid are the lower 8 bits of the index we stored into
259	 * the cpufreq frequency table in powernow_decode_bios,
260	 * vid are the upper 8 bits.
261	 */
262
263	fid = powernow_table[index].driver_data & 0xFF;
264	vid = (powernow_table[index].driver_data & 0xFF00) >> 8;
265
266	rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
267	cfid = fidvidstatus.bits.CFID;
268	freqs.old = fsb * fid_codes[cfid] / 10;
269
270	freqs.new = powernow_table[index].frequency;
271
272	/* Now do the magic poking into the MSRs.  */
273
274	if (have_a0 == 1)	/* A0 errata 5 */
275		local_irq_disable();
276
277	if (freqs.old > freqs.new) {
278		/* Going down, so change FID first */
279		change_FID(fid);
280		change_VID(vid);
281	} else {
282		/* Going up, so change VID first */
283		change_VID(vid);
284		change_FID(fid);
285	}
286
287
288	if (have_a0 == 1)
289		local_irq_enable();
290
291	return 0;
292}
293
294
295#ifdef CONFIG_X86_POWERNOW_K7_ACPI
296
297static struct acpi_processor_performance *acpi_processor_perf;
298
299static int powernow_acpi_init(void)
300{
301	int i;
302	int retval = 0;
303	union powernow_acpi_control_t pc;
304
305	if (acpi_processor_perf != NULL && powernow_table != NULL) {
306		retval = -EINVAL;
307		goto err0;
308	}
309
310	acpi_processor_perf = kzalloc(sizeof(*acpi_processor_perf), GFP_KERNEL);
311	if (!acpi_processor_perf) {
312		retval = -ENOMEM;
313		goto err0;
314	}
315
316	if (!zalloc_cpumask_var(&acpi_processor_perf->shared_cpu_map,
317								GFP_KERNEL)) {
318		retval = -ENOMEM;
319		goto err05;
320	}
321
322	if (acpi_processor_register_performance(acpi_processor_perf, 0)) {
323		retval = -EIO;
324		goto err1;
325	}
326
327	if (acpi_processor_perf->control_register.space_id !=
328			ACPI_ADR_SPACE_FIXED_HARDWARE) {
329		retval = -ENODEV;
330		goto err2;
331	}
332
333	if (acpi_processor_perf->status_register.space_id !=
334			ACPI_ADR_SPACE_FIXED_HARDWARE) {
335		retval = -ENODEV;
336		goto err2;
337	}
338
339	number_scales = acpi_processor_perf->state_count;
340
341	if (number_scales < 2) {
342		retval = -ENODEV;
343		goto err2;
344	}
345
346	powernow_table = kzalloc((sizeof(*powernow_table) *
347				(number_scales + 1)), GFP_KERNEL);
348	if (!powernow_table) {
349		retval = -ENOMEM;
350		goto err2;
351	}
352
353	pc.val = (unsigned long) acpi_processor_perf->states[0].control;
354	for (i = 0; i < number_scales; i++) {
355		u8 fid, vid;
356		struct acpi_processor_px *state =
357			&acpi_processor_perf->states[i];
358		unsigned int speed, speed_mhz;
359
360		pc.val = (unsigned long) state->control;
361		pr_debug("acpi:  P%d: %d MHz %d mW %d uS control %08x SGTC %d\n",
362			 i,
363			 (u32) state->core_frequency,
364			 (u32) state->power,
365			 (u32) state->transition_latency,
366			 (u32) state->control,
367			 pc.bits.sgtc);
368
369		vid = pc.bits.vid;
370		fid = pc.bits.fid;
371
372		powernow_table[i].frequency = fsb * fid_codes[fid] / 10;
373		powernow_table[i].driver_data = fid; /* lower 8 bits */
374		powernow_table[i].driver_data |= (vid << 8); /* upper 8 bits */
375
376		speed = powernow_table[i].frequency;
377		speed_mhz = speed / 1000;
378
379		/* processor_perflib will multiply the MHz value by 1000 to
380		 * get a KHz value (e.g. 1266000). However, powernow-k7 works
381		 * with true KHz values (e.g. 1266768). To ensure that all
382		 * powernow frequencies are available, we must ensure that
383		 * ACPI doesn't restrict them, so we round up the MHz value
384		 * to ensure that perflib's computed KHz value is greater than
385		 * or equal to powernow's KHz value.
386		 */
387		if (speed % 1000 > 0)
388			speed_mhz++;
389
390		if ((fid_codes[fid] % 10) == 5) {
391			if (have_a0 == 1)
392				invalidate_entry(i);
393		}
394
395		pr_debug("   FID: 0x%x (%d.%dx [%dMHz])  "
396			 "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
397			 fid_codes[fid] % 10, speed_mhz, vid,
398			 mobile_vid_table[vid]/1000,
399			 mobile_vid_table[vid]%1000);
400
401		if (state->core_frequency != speed_mhz) {
402			state->core_frequency = speed_mhz;
403			pr_debug("   Corrected ACPI frequency to %d\n",
404				speed_mhz);
405		}
406
407		if (latency < pc.bits.sgtc)
408			latency = pc.bits.sgtc;
409
410		if (speed < minimum_speed)
411			minimum_speed = speed;
412		if (speed > maximum_speed)
413			maximum_speed = speed;
414	}
415
416	powernow_table[i].frequency = CPUFREQ_TABLE_END;
417	powernow_table[i].driver_data = 0;
418
419	/* notify BIOS that we exist */
420	acpi_processor_notify_smm(THIS_MODULE);
421
422	return 0;
423
424err2:
425	acpi_processor_unregister_performance(acpi_processor_perf, 0);
426err1:
427	free_cpumask_var(acpi_processor_perf->shared_cpu_map);
428err05:
429	kfree(acpi_processor_perf);
430err0:
431	printk(KERN_WARNING PFX "ACPI perflib can not be used on "
432			"this platform\n");
433	acpi_processor_perf = NULL;
434	return retval;
435}
436#else
437static int powernow_acpi_init(void)
438{
439	printk(KERN_INFO PFX "no support for ACPI processor found."
440	       "  Please recompile your kernel with ACPI processor\n");
441	return -EINVAL;
442}
443#endif
444
445static void print_pst_entry(struct pst_s *pst, unsigned int j)
446{
447	pr_debug("PST:%d (@%p)\n", j, pst);
448	pr_debug(" cpuid: 0x%x  fsb: %d  maxFID: 0x%x  startvid: 0x%x\n",
449		pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid);
450}
451
452static int powernow_decode_bios(int maxfid, int startvid)
453{
454	struct psb_s *psb;
455	struct pst_s *pst;
456	unsigned int i, j;
457	unsigned char *p;
458	unsigned int etuple;
459	unsigned int ret;
460
461	etuple = cpuid_eax(0x80000001);
462
463	for (i = 0xC0000; i < 0xffff0 ; i += 16) {
464
465		p = phys_to_virt(i);
466
467		if (memcmp(p, "AMDK7PNOW!",  10) == 0) {
468			pr_debug("Found PSB header at %p\n", p);
469			psb = (struct psb_s *) p;
470			pr_debug("Table version: 0x%x\n", psb->tableversion);
471			if (psb->tableversion != 0x12) {
472				printk(KERN_INFO PFX "Sorry, only v1.2 tables"
473						" supported right now\n");
474				return -ENODEV;
475			}
476
477			pr_debug("Flags: 0x%x\n", psb->flags);
478			if ((psb->flags & 1) == 0)
479				pr_debug("Mobile voltage regulator\n");
480			else
481				pr_debug("Desktop voltage regulator\n");
482
483			latency = psb->settlingtime;
484			if (latency < 100) {
485				printk(KERN_INFO PFX "BIOS set settling time "
486						"to %d microseconds. "
487						"Should be at least 100. "
488						"Correcting.\n", latency);
489				latency = 100;
490			}
491			pr_debug("Settling Time: %d microseconds.\n",
492					psb->settlingtime);
493			pr_debug("Has %d PST tables. (Only dumping ones "
494					"relevant to this CPU).\n",
495					psb->numpst);
496
497			p += sizeof(*psb);
498
499			pst = (struct pst_s *) p;
500
501			for (j = 0; j < psb->numpst; j++) {
502				pst = (struct pst_s *) p;
503				number_scales = pst->numpstates;
504
505				if ((etuple == pst->cpuid) &&
506				    check_fsb(pst->fsbspeed) &&
507				    (maxfid == pst->maxfid) &&
508				    (startvid == pst->startvid)) {
509					print_pst_entry(pst, j);
510					p = (char *)pst + sizeof(*pst);
511					ret = get_ranges(p);
512					return ret;
513				} else {
514					unsigned int k;
515					p = (char *)pst + sizeof(*pst);
516					for (k = 0; k < number_scales; k++)
517						p += 2;
518				}
519			}
520			printk(KERN_INFO PFX "No PST tables match this cpuid "
521					"(0x%x)\n", etuple);
522			printk(KERN_INFO PFX "This is indicative of a broken "
523					"BIOS.\n");
524
525			return -EINVAL;
526		}
527		p++;
528	}
529
530	return -ENODEV;
531}
532
533
534/*
535 * We use the fact that the bus frequency is somehow
536 * a multiple of 100000/3 khz, then we compute sgtc according
537 * to this multiple.
538 * That way, we match more how AMD thinks all of that work.
539 * We will then get the same kind of behaviour already tested under
540 * the "well-known" other OS.
541 */
542static int fixup_sgtc(void)
543{
544	unsigned int sgtc;
545	unsigned int m;
546
547	m = fsb / 3333;
548	if ((m % 10) >= 5)
549		m += 5;
550
551	m /= 10;
552
553	sgtc = 100 * m * latency;
554	sgtc = sgtc / 3;
555	if (sgtc > 0xfffff) {
556		printk(KERN_WARNING PFX "SGTC too large %d\n", sgtc);
557		sgtc = 0xfffff;
558	}
559	return sgtc;
560}
561
562static unsigned int powernow_get(unsigned int cpu)
563{
564	union msr_fidvidstatus fidvidstatus;
565	unsigned int cfid;
566
567	if (cpu)
568		return 0;
569	rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
570	cfid = fidvidstatus.bits.CFID;
571
572	return fsb * fid_codes[cfid] / 10;
573}
574
575
576static int acer_cpufreq_pst(const struct dmi_system_id *d)
577{
578	printk(KERN_WARNING PFX
579		"%s laptop with broken PST tables in BIOS detected.\n",
580		d->ident);
581	printk(KERN_WARNING PFX
582		"You need to downgrade to 3A21 (09/09/2002), or try a newer "
583		"BIOS than 3A71 (01/20/2003)\n");
584	printk(KERN_WARNING PFX
585		"cpufreq scaling has been disabled as a result of this.\n");
586	return 0;
587}
588
589/*
590 * Some Athlon laptops have really fucked PST tables.
591 * A BIOS update is all that can save them.
592 * Mention this, and disable cpufreq.
593 */
594static struct dmi_system_id powernow_dmi_table[] = {
595	{
596		.callback = acer_cpufreq_pst,
597		.ident = "Acer Aspire",
598		.matches = {
599			DMI_MATCH(DMI_SYS_VENDOR, "Insyde Software"),
600			DMI_MATCH(DMI_BIOS_VERSION, "3A71"),
601		},
602	},
603	{ }
604};
605
606static int powernow_cpu_init(struct cpufreq_policy *policy)
607{
608	union msr_fidvidstatus fidvidstatus;
609	int result;
610
611	if (policy->cpu != 0)
612		return -ENODEV;
613
614	rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
615
616	recalibrate_cpu_khz();
617
618	fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID];
619	if (!fsb) {
620		printk(KERN_WARNING PFX "can not determine bus frequency\n");
621		return -EINVAL;
622	}
623	pr_debug("FSB: %3dMHz\n", fsb/1000);
624
625	if (dmi_check_system(powernow_dmi_table) || acpi_force) {
626		printk(KERN_INFO PFX "PSB/PST known to be broken.  "
627				"Trying ACPI instead\n");
628		result = powernow_acpi_init();
629	} else {
630		result = powernow_decode_bios(fidvidstatus.bits.MFID,
631				fidvidstatus.bits.SVID);
632		if (result) {
633			printk(KERN_INFO PFX "Trying ACPI perflib\n");
634			maximum_speed = 0;
635			minimum_speed = -1;
636			latency = 0;
637			result = powernow_acpi_init();
638			if (result) {
639				printk(KERN_INFO PFX
640					"ACPI and legacy methods failed\n");
641			}
642		} else {
643			/* SGTC use the bus clock as timer */
644			latency = fixup_sgtc();
645			printk(KERN_INFO PFX "SGTC: %d\n", latency);
646		}
647	}
648
649	if (result)
650		return result;
651
652	printk(KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n",
653				minimum_speed/1000, maximum_speed/1000);
654
655	policy->cpuinfo.transition_latency =
656		cpufreq_scale(2000000UL, fsb, latency);
657
658	return cpufreq_table_validate_and_show(policy, powernow_table);
659}
660
661static int powernow_cpu_exit(struct cpufreq_policy *policy)
662{
663#ifdef CONFIG_X86_POWERNOW_K7_ACPI
664	if (acpi_processor_perf) {
665		acpi_processor_unregister_performance(acpi_processor_perf, 0);
666		free_cpumask_var(acpi_processor_perf->shared_cpu_map);
667		kfree(acpi_processor_perf);
668	}
669#endif
670
671	kfree(powernow_table);
672	return 0;
673}
674
675static struct cpufreq_driver powernow_driver = {
676	.verify		= cpufreq_generic_frequency_table_verify,
677	.target_index	= powernow_target,
678	.get		= powernow_get,
679#ifdef CONFIG_X86_POWERNOW_K7_ACPI
680	.bios_limit	= acpi_processor_get_bios_limit,
681#endif
682	.init		= powernow_cpu_init,
683	.exit		= powernow_cpu_exit,
684	.name		= "powernow-k7",
685	.attr		= cpufreq_generic_attr,
686};
687
688static int __init powernow_init(void)
689{
690	if (check_powernow() == 0)
691		return -ENODEV;
692	return cpufreq_register_driver(&powernow_driver);
693}
694
695
696static void __exit powernow_exit(void)
697{
698	cpufreq_unregister_driver(&powernow_driver);
699}
700
701module_param(acpi_force,  int, 0444);
702MODULE_PARM_DESC(acpi_force, "Force ACPI to be used.");
703
704MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
705MODULE_DESCRIPTION("Powernow driver for AMD K7 processors.");
706MODULE_LICENSE("GPL");
707
708late_initcall(powernow_init);
709module_exit(powernow_exit);
710
711