xref: /linux/drivers/cpufreq/powernow-k8.c (revision d63bd27fe953daa402a108e141c36dcc59c6931c)
1bb0a56ecSDave Jones /*
2b2bd68e1SAndreas Herrmann  *   (c) 2003-2012 Advanced Micro Devices, Inc.
3bb0a56ecSDave Jones  *  Your use of this code is subject to the terms and conditions of the
4bb0a56ecSDave Jones  *  GNU general public license version 2. See "COPYING" or
5bb0a56ecSDave Jones  *  http://www.gnu.org/licenses/gpl.html
6bb0a56ecSDave Jones  *
7b2bd68e1SAndreas Herrmann  *  Maintainer:
829c4bcddSAndreas Herrmann  *  Andreas Herrmann <herrmann.der.user@googlemail.com>
9bb0a56ecSDave Jones  *
10bb0a56ecSDave Jones  *  Based on the powernow-k7.c module written by Dave Jones.
11bb0a56ecSDave Jones  *  (C) 2003 Dave Jones on behalf of SuSE Labs
12bb0a56ecSDave Jones  *  (C) 2004 Dominik Brodowski <linux@brodo.de>
13bb0a56ecSDave Jones  *  (C) 2004 Pavel Machek <pavel@ucw.cz>
14bb0a56ecSDave Jones  *  Licensed under the terms of the GNU GPL License version 2.
15bb0a56ecSDave Jones  *  Based upon datasheets & sample CPUs kindly provided by AMD.
16bb0a56ecSDave Jones  *
17bb0a56ecSDave Jones  *  Valuable input gratefully received from Dave Jones, Pavel Machek,
18bb0a56ecSDave Jones  *  Dominik Brodowski, Jacob Shin, and others.
19bb0a56ecSDave Jones  *  Originally developed by Paul Devriendt.
20bb0a56ecSDave Jones  *
21b2bd68e1SAndreas Herrmann  *  Processor information obtained from Chapter 9 (Power and Thermal
22b2bd68e1SAndreas Herrmann  *  Management) of the "BIOS and Kernel Developer's Guide (BKDG) for
23b2bd68e1SAndreas Herrmann  *  the AMD Athlon 64 and AMD Opteron Processors" and section "2.x
24b2bd68e1SAndreas Herrmann  *  Power Management" in BKDGs for newer AMD CPU families.
25b2bd68e1SAndreas Herrmann  *
26b2bd68e1SAndreas Herrmann  *  Tables for specific CPUs can be inferred from AMD's processor
27b2bd68e1SAndreas Herrmann  *  power and thermal data sheets, (e.g. 30417.pdf, 30430.pdf, 43375.pdf)
28bb0a56ecSDave Jones  */
29bb0a56ecSDave Jones 
30bb0a56ecSDave Jones #include <linux/kernel.h>
31bb0a56ecSDave Jones #include <linux/smp.h>
32bb0a56ecSDave Jones #include <linux/module.h>
33bb0a56ecSDave Jones #include <linux/init.h>
34bb0a56ecSDave Jones #include <linux/cpufreq.h>
35bb0a56ecSDave Jones #include <linux/slab.h>
36bb0a56ecSDave Jones #include <linux/string.h>
37bb0a56ecSDave Jones #include <linux/cpumask.h>
38bb0a56ecSDave Jones #include <linux/io.h>
39bb0a56ecSDave Jones #include <linux/delay.h>
40bb0a56ecSDave Jones 
41bb0a56ecSDave Jones #include <asm/msr.h>
42fa8031aeSAndi Kleen #include <asm/cpu_device_id.h>
43bb0a56ecSDave Jones 
44bb0a56ecSDave Jones #include <linux/acpi.h>
45bb0a56ecSDave Jones #include <linux/mutex.h>
46bb0a56ecSDave Jones #include <acpi/processor.h>
47bb0a56ecSDave Jones 
48bb0a56ecSDave Jones #define PFX "powernow-k8: "
49bb0a56ecSDave Jones #define VERSION "version 2.20.00"
50bb0a56ecSDave Jones #include "powernow-k8.h"
51bb0a56ecSDave Jones 
52bb0a56ecSDave Jones /* serialize freq changes  */
53bb0a56ecSDave Jones static DEFINE_MUTEX(fidvid_mutex);
54bb0a56ecSDave Jones 
55bb0a56ecSDave Jones static DEFINE_PER_CPU(struct powernow_k8_data *, powernow_data);
56bb0a56ecSDave Jones 
57bb0a56ecSDave Jones static struct cpufreq_driver cpufreq_amd64_driver;
58bb0a56ecSDave Jones 
59bb0a56ecSDave Jones #ifndef CONFIG_SMP
60bb0a56ecSDave Jones static inline const struct cpumask *cpu_core_mask(int cpu)
61bb0a56ecSDave Jones {
62bb0a56ecSDave Jones 	return cpumask_of(0);
63bb0a56ecSDave Jones }
64bb0a56ecSDave Jones #endif
65bb0a56ecSDave Jones 
66bb0a56ecSDave Jones /* Return a frequency in MHz, given an input fid */
67bb0a56ecSDave Jones static u32 find_freq_from_fid(u32 fid)
68bb0a56ecSDave Jones {
69bb0a56ecSDave Jones 	return 800 + (fid * 100);
70bb0a56ecSDave Jones }
71bb0a56ecSDave Jones 
72bb0a56ecSDave Jones /* Return a frequency in KHz, given an input fid */
73bb0a56ecSDave Jones static u32 find_khz_freq_from_fid(u32 fid)
74bb0a56ecSDave Jones {
75bb0a56ecSDave Jones 	return 1000 * find_freq_from_fid(fid);
76bb0a56ecSDave Jones }
77bb0a56ecSDave Jones 
78bb0a56ecSDave Jones /* Return the vco fid for an input fid
79bb0a56ecSDave Jones  *
80bb0a56ecSDave Jones  * Each "low" fid has corresponding "high" fid, and you can get to "low" fids
81bb0a56ecSDave Jones  * only from corresponding high fids. This returns "high" fid corresponding to
82bb0a56ecSDave Jones  * "low" one.
83bb0a56ecSDave Jones  */
84bb0a56ecSDave Jones static u32 convert_fid_to_vco_fid(u32 fid)
85bb0a56ecSDave Jones {
86bb0a56ecSDave Jones 	if (fid < HI_FID_TABLE_BOTTOM)
87bb0a56ecSDave Jones 		return 8 + (2 * fid);
88bb0a56ecSDave Jones 	else
89bb0a56ecSDave Jones 		return fid;
90bb0a56ecSDave Jones }
91bb0a56ecSDave Jones 
92bb0a56ecSDave Jones /*
93bb0a56ecSDave Jones  * Return 1 if the pending bit is set. Unless we just instructed the processor
94bb0a56ecSDave Jones  * to transition to a new state, seeing this bit set is really bad news.
95bb0a56ecSDave Jones  */
96bb0a56ecSDave Jones static int pending_bit_stuck(void)
97bb0a56ecSDave Jones {
98bb0a56ecSDave Jones 	u32 lo, hi;
99bb0a56ecSDave Jones 
100bb0a56ecSDave Jones 	rdmsr(MSR_FIDVID_STATUS, lo, hi);
101bb0a56ecSDave Jones 	return lo & MSR_S_LO_CHANGE_PENDING ? 1 : 0;
102bb0a56ecSDave Jones }
103bb0a56ecSDave Jones 
104bb0a56ecSDave Jones /*
105bb0a56ecSDave Jones  * Update the global current fid / vid values from the status msr.
106bb0a56ecSDave Jones  * Returns 1 on error.
107bb0a56ecSDave Jones  */
108bb0a56ecSDave Jones static int query_current_values_with_pending_wait(struct powernow_k8_data *data)
109bb0a56ecSDave Jones {
110bb0a56ecSDave Jones 	u32 lo, hi;
111bb0a56ecSDave Jones 	u32 i = 0;
112bb0a56ecSDave Jones 
113bb0a56ecSDave Jones 	do {
114bb0a56ecSDave Jones 		if (i++ > 10000) {
115bb0a56ecSDave Jones 			pr_debug("detected change pending stuck\n");
116bb0a56ecSDave Jones 			return 1;
117bb0a56ecSDave Jones 		}
118bb0a56ecSDave Jones 		rdmsr(MSR_FIDVID_STATUS, lo, hi);
119bb0a56ecSDave Jones 	} while (lo & MSR_S_LO_CHANGE_PENDING);
120bb0a56ecSDave Jones 
121bb0a56ecSDave Jones 	data->currvid = hi & MSR_S_HI_CURRENT_VID;
122bb0a56ecSDave Jones 	data->currfid = lo & MSR_S_LO_CURRENT_FID;
123bb0a56ecSDave Jones 
124bb0a56ecSDave Jones 	return 0;
125bb0a56ecSDave Jones }
126bb0a56ecSDave Jones 
127bb0a56ecSDave Jones /* the isochronous relief time */
128bb0a56ecSDave Jones static void count_off_irt(struct powernow_k8_data *data)
129bb0a56ecSDave Jones {
130bb0a56ecSDave Jones 	udelay((1 << data->irt) * 10);
131bb0a56ecSDave Jones 	return;
132bb0a56ecSDave Jones }
133bb0a56ecSDave Jones 
134bb0a56ecSDave Jones /* the voltage stabilization time */
135bb0a56ecSDave Jones static void count_off_vst(struct powernow_k8_data *data)
136bb0a56ecSDave Jones {
137bb0a56ecSDave Jones 	udelay(data->vstable * VST_UNITS_20US);
138bb0a56ecSDave Jones 	return;
139bb0a56ecSDave Jones }
140bb0a56ecSDave Jones 
141bb0a56ecSDave Jones /* need to init the control msr to a safe value (for each cpu) */
142bb0a56ecSDave Jones static void fidvid_msr_init(void)
143bb0a56ecSDave Jones {
144bb0a56ecSDave Jones 	u32 lo, hi;
145bb0a56ecSDave Jones 	u8 fid, vid;
146bb0a56ecSDave Jones 
147bb0a56ecSDave Jones 	rdmsr(MSR_FIDVID_STATUS, lo, hi);
148bb0a56ecSDave Jones 	vid = hi & MSR_S_HI_CURRENT_VID;
149bb0a56ecSDave Jones 	fid = lo & MSR_S_LO_CURRENT_FID;
150bb0a56ecSDave Jones 	lo = fid | (vid << MSR_C_LO_VID_SHIFT);
151bb0a56ecSDave Jones 	hi = MSR_C_HI_STP_GNT_BENIGN;
152bb0a56ecSDave Jones 	pr_debug("cpu%d, init lo 0x%x, hi 0x%x\n", smp_processor_id(), lo, hi);
153bb0a56ecSDave Jones 	wrmsr(MSR_FIDVID_CTL, lo, hi);
154bb0a56ecSDave Jones }
155bb0a56ecSDave Jones 
156bb0a56ecSDave Jones /* write the new fid value along with the other control fields to the msr */
157bb0a56ecSDave Jones static int write_new_fid(struct powernow_k8_data *data, u32 fid)
158bb0a56ecSDave Jones {
159bb0a56ecSDave Jones 	u32 lo;
160bb0a56ecSDave Jones 	u32 savevid = data->currvid;
161bb0a56ecSDave Jones 	u32 i = 0;
162bb0a56ecSDave Jones 
163bb0a56ecSDave Jones 	if ((fid & INVALID_FID_MASK) || (data->currvid & INVALID_VID_MASK)) {
164bb0a56ecSDave Jones 		printk(KERN_ERR PFX "internal error - overflow on fid write\n");
165bb0a56ecSDave Jones 		return 1;
166bb0a56ecSDave Jones 	}
167bb0a56ecSDave Jones 
168bb0a56ecSDave Jones 	lo = fid;
169bb0a56ecSDave Jones 	lo |= (data->currvid << MSR_C_LO_VID_SHIFT);
170bb0a56ecSDave Jones 	lo |= MSR_C_LO_INIT_FID_VID;
171bb0a56ecSDave Jones 
172bb0a56ecSDave Jones 	pr_debug("writing fid 0x%x, lo 0x%x, hi 0x%x\n",
173bb0a56ecSDave Jones 		fid, lo, data->plllock * PLL_LOCK_CONVERSION);
174bb0a56ecSDave Jones 
175bb0a56ecSDave Jones 	do {
176bb0a56ecSDave Jones 		wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION);
177bb0a56ecSDave Jones 		if (i++ > 100) {
178bb0a56ecSDave Jones 			printk(KERN_ERR PFX
179bb0a56ecSDave Jones 				"Hardware error - pending bit very stuck - "
180bb0a56ecSDave Jones 				"no further pstate changes possible\n");
181bb0a56ecSDave Jones 			return 1;
182bb0a56ecSDave Jones 		}
183bb0a56ecSDave Jones 	} while (query_current_values_with_pending_wait(data));
184bb0a56ecSDave Jones 
185bb0a56ecSDave Jones 	count_off_irt(data);
186bb0a56ecSDave Jones 
187bb0a56ecSDave Jones 	if (savevid != data->currvid) {
188bb0a56ecSDave Jones 		printk(KERN_ERR PFX
189bb0a56ecSDave Jones 			"vid change on fid trans, old 0x%x, new 0x%x\n",
190bb0a56ecSDave Jones 			savevid, data->currvid);
191bb0a56ecSDave Jones 		return 1;
192bb0a56ecSDave Jones 	}
193bb0a56ecSDave Jones 
194bb0a56ecSDave Jones 	if (fid != data->currfid) {
195bb0a56ecSDave Jones 		printk(KERN_ERR PFX
196bb0a56ecSDave Jones 			"fid trans failed, fid 0x%x, curr 0x%x\n", fid,
197bb0a56ecSDave Jones 			data->currfid);
198bb0a56ecSDave Jones 		return 1;
199bb0a56ecSDave Jones 	}
200bb0a56ecSDave Jones 
201bb0a56ecSDave Jones 	return 0;
202bb0a56ecSDave Jones }
203bb0a56ecSDave Jones 
204bb0a56ecSDave Jones /* Write a new vid to the hardware */
205bb0a56ecSDave Jones static int write_new_vid(struct powernow_k8_data *data, u32 vid)
206bb0a56ecSDave Jones {
207bb0a56ecSDave Jones 	u32 lo;
208bb0a56ecSDave Jones 	u32 savefid = data->currfid;
209bb0a56ecSDave Jones 	int i = 0;
210bb0a56ecSDave Jones 
211bb0a56ecSDave Jones 	if ((data->currfid & INVALID_FID_MASK) || (vid & INVALID_VID_MASK)) {
212bb0a56ecSDave Jones 		printk(KERN_ERR PFX "internal error - overflow on vid write\n");
213bb0a56ecSDave Jones 		return 1;
214bb0a56ecSDave Jones 	}
215bb0a56ecSDave Jones 
216bb0a56ecSDave Jones 	lo = data->currfid;
217bb0a56ecSDave Jones 	lo |= (vid << MSR_C_LO_VID_SHIFT);
218bb0a56ecSDave Jones 	lo |= MSR_C_LO_INIT_FID_VID;
219bb0a56ecSDave Jones 
220bb0a56ecSDave Jones 	pr_debug("writing vid 0x%x, lo 0x%x, hi 0x%x\n",
221bb0a56ecSDave Jones 		vid, lo, STOP_GRANT_5NS);
222bb0a56ecSDave Jones 
223bb0a56ecSDave Jones 	do {
224bb0a56ecSDave Jones 		wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS);
225bb0a56ecSDave Jones 		if (i++ > 100) {
226bb0a56ecSDave Jones 			printk(KERN_ERR PFX "internal error - pending bit "
227bb0a56ecSDave Jones 					"very stuck - no further pstate "
228bb0a56ecSDave Jones 					"changes possible\n");
229bb0a56ecSDave Jones 			return 1;
230bb0a56ecSDave Jones 		}
231bb0a56ecSDave Jones 	} while (query_current_values_with_pending_wait(data));
232bb0a56ecSDave Jones 
233bb0a56ecSDave Jones 	if (savefid != data->currfid) {
234bb0a56ecSDave Jones 		printk(KERN_ERR PFX "fid changed on vid trans, old "
235bb0a56ecSDave Jones 			"0x%x new 0x%x\n",
236bb0a56ecSDave Jones 		       savefid, data->currfid);
237bb0a56ecSDave Jones 		return 1;
238bb0a56ecSDave Jones 	}
239bb0a56ecSDave Jones 
240bb0a56ecSDave Jones 	if (vid != data->currvid) {
241bb0a56ecSDave Jones 		printk(KERN_ERR PFX "vid trans failed, vid 0x%x, "
242bb0a56ecSDave Jones 				"curr 0x%x\n",
243bb0a56ecSDave Jones 				vid, data->currvid);
244bb0a56ecSDave Jones 		return 1;
245bb0a56ecSDave Jones 	}
246bb0a56ecSDave Jones 
247bb0a56ecSDave Jones 	return 0;
248bb0a56ecSDave Jones }
249bb0a56ecSDave Jones 
250bb0a56ecSDave Jones /*
251bb0a56ecSDave Jones  * Reduce the vid by the max of step or reqvid.
252bb0a56ecSDave Jones  * Decreasing vid codes represent increasing voltages:
253bb0a56ecSDave Jones  * vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of VID_OFF is off.
254bb0a56ecSDave Jones  */
255bb0a56ecSDave Jones static int decrease_vid_code_by_step(struct powernow_k8_data *data,
256bb0a56ecSDave Jones 		u32 reqvid, u32 step)
257bb0a56ecSDave Jones {
258bb0a56ecSDave Jones 	if ((data->currvid - reqvid) > step)
259bb0a56ecSDave Jones 		reqvid = data->currvid - step;
260bb0a56ecSDave Jones 
261bb0a56ecSDave Jones 	if (write_new_vid(data, reqvid))
262bb0a56ecSDave Jones 		return 1;
263bb0a56ecSDave Jones 
264bb0a56ecSDave Jones 	count_off_vst(data);
265bb0a56ecSDave Jones 
266bb0a56ecSDave Jones 	return 0;
267bb0a56ecSDave Jones }
268bb0a56ecSDave Jones 
269bb0a56ecSDave Jones /* Change Opteron/Athlon64 fid and vid, by the 3 phases. */
270bb0a56ecSDave Jones static int transition_fid_vid(struct powernow_k8_data *data,
271bb0a56ecSDave Jones 		u32 reqfid, u32 reqvid)
272bb0a56ecSDave Jones {
273bb0a56ecSDave Jones 	if (core_voltage_pre_transition(data, reqvid, reqfid))
274bb0a56ecSDave Jones 		return 1;
275bb0a56ecSDave Jones 
276bb0a56ecSDave Jones 	if (core_frequency_transition(data, reqfid))
277bb0a56ecSDave Jones 		return 1;
278bb0a56ecSDave Jones 
279bb0a56ecSDave Jones 	if (core_voltage_post_transition(data, reqvid))
280bb0a56ecSDave Jones 		return 1;
281bb0a56ecSDave Jones 
282bb0a56ecSDave Jones 	if (query_current_values_with_pending_wait(data))
283bb0a56ecSDave Jones 		return 1;
284bb0a56ecSDave Jones 
285bb0a56ecSDave Jones 	if ((reqfid != data->currfid) || (reqvid != data->currvid)) {
286bb0a56ecSDave Jones 		printk(KERN_ERR PFX "failed (cpu%d): req 0x%x 0x%x, "
287bb0a56ecSDave Jones 				"curr 0x%x 0x%x\n",
288bb0a56ecSDave Jones 				smp_processor_id(),
289bb0a56ecSDave Jones 				reqfid, reqvid, data->currfid, data->currvid);
290bb0a56ecSDave Jones 		return 1;
291bb0a56ecSDave Jones 	}
292bb0a56ecSDave Jones 
293bb0a56ecSDave Jones 	pr_debug("transitioned (cpu%d): new fid 0x%x, vid 0x%x\n",
294bb0a56ecSDave Jones 		smp_processor_id(), data->currfid, data->currvid);
295bb0a56ecSDave Jones 
296bb0a56ecSDave Jones 	return 0;
297bb0a56ecSDave Jones }
298bb0a56ecSDave Jones 
299bb0a56ecSDave Jones /* Phase 1 - core voltage transition ... setup voltage */
300bb0a56ecSDave Jones static int core_voltage_pre_transition(struct powernow_k8_data *data,
301bb0a56ecSDave Jones 		u32 reqvid, u32 reqfid)
302bb0a56ecSDave Jones {
303bb0a56ecSDave Jones 	u32 rvosteps = data->rvo;
304bb0a56ecSDave Jones 	u32 savefid = data->currfid;
305bb0a56ecSDave Jones 	u32 maxvid, lo, rvomult = 1;
306bb0a56ecSDave Jones 
307bb0a56ecSDave Jones 	pr_debug("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, "
308bb0a56ecSDave Jones 		"reqvid 0x%x, rvo 0x%x\n",
309bb0a56ecSDave Jones 		smp_processor_id(),
310bb0a56ecSDave Jones 		data->currfid, data->currvid, reqvid, data->rvo);
311bb0a56ecSDave Jones 
312bb0a56ecSDave Jones 	if ((savefid < LO_FID_TABLE_TOP) && (reqfid < LO_FID_TABLE_TOP))
313bb0a56ecSDave Jones 		rvomult = 2;
314bb0a56ecSDave Jones 	rvosteps *= rvomult;
315bb0a56ecSDave Jones 	rdmsr(MSR_FIDVID_STATUS, lo, maxvid);
316bb0a56ecSDave Jones 	maxvid = 0x1f & (maxvid >> 16);
317bb0a56ecSDave Jones 	pr_debug("ph1 maxvid=0x%x\n", maxvid);
318bb0a56ecSDave Jones 	if (reqvid < maxvid) /* lower numbers are higher voltages */
319bb0a56ecSDave Jones 		reqvid = maxvid;
320bb0a56ecSDave Jones 
321bb0a56ecSDave Jones 	while (data->currvid > reqvid) {
322bb0a56ecSDave Jones 		pr_debug("ph1: curr 0x%x, req vid 0x%x\n",
323bb0a56ecSDave Jones 			data->currvid, reqvid);
324bb0a56ecSDave Jones 		if (decrease_vid_code_by_step(data, reqvid, data->vidmvs))
325bb0a56ecSDave Jones 			return 1;
326bb0a56ecSDave Jones 	}
327bb0a56ecSDave Jones 
328bb0a56ecSDave Jones 	while ((rvosteps > 0) &&
329bb0a56ecSDave Jones 			((rvomult * data->rvo + data->currvid) > reqvid)) {
330bb0a56ecSDave Jones 		if (data->currvid == maxvid) {
331bb0a56ecSDave Jones 			rvosteps = 0;
332bb0a56ecSDave Jones 		} else {
333bb0a56ecSDave Jones 			pr_debug("ph1: changing vid for rvo, req 0x%x\n",
334bb0a56ecSDave Jones 				data->currvid - 1);
335bb0a56ecSDave Jones 			if (decrease_vid_code_by_step(data, data->currvid-1, 1))
336bb0a56ecSDave Jones 				return 1;
337bb0a56ecSDave Jones 			rvosteps--;
338bb0a56ecSDave Jones 		}
339bb0a56ecSDave Jones 	}
340bb0a56ecSDave Jones 
341bb0a56ecSDave Jones 	if (query_current_values_with_pending_wait(data))
342bb0a56ecSDave Jones 		return 1;
343bb0a56ecSDave Jones 
344bb0a56ecSDave Jones 	if (savefid != data->currfid) {
345bb0a56ecSDave Jones 		printk(KERN_ERR PFX "ph1 err, currfid changed 0x%x\n",
346bb0a56ecSDave Jones 				data->currfid);
347bb0a56ecSDave Jones 		return 1;
348bb0a56ecSDave Jones 	}
349bb0a56ecSDave Jones 
350bb0a56ecSDave Jones 	pr_debug("ph1 complete, currfid 0x%x, currvid 0x%x\n",
351bb0a56ecSDave Jones 		data->currfid, data->currvid);
352bb0a56ecSDave Jones 
353bb0a56ecSDave Jones 	return 0;
354bb0a56ecSDave Jones }
355bb0a56ecSDave Jones 
356bb0a56ecSDave Jones /* Phase 2 - core frequency transition */
357bb0a56ecSDave Jones static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
358bb0a56ecSDave Jones {
359bb0a56ecSDave Jones 	u32 vcoreqfid, vcocurrfid, vcofiddiff;
360bb0a56ecSDave Jones 	u32 fid_interval, savevid = data->currvid;
361bb0a56ecSDave Jones 
362bb0a56ecSDave Jones 	if (data->currfid == reqfid) {
363bb0a56ecSDave Jones 		printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n",
364bb0a56ecSDave Jones 				data->currfid);
365bb0a56ecSDave Jones 		return 0;
366bb0a56ecSDave Jones 	}
367bb0a56ecSDave Jones 
368bb0a56ecSDave Jones 	pr_debug("ph2 (cpu%d): starting, currfid 0x%x, currvid 0x%x, "
369bb0a56ecSDave Jones 		"reqfid 0x%x\n",
370bb0a56ecSDave Jones 		smp_processor_id(),
371bb0a56ecSDave Jones 		data->currfid, data->currvid, reqfid);
372bb0a56ecSDave Jones 
373bb0a56ecSDave Jones 	vcoreqfid = convert_fid_to_vco_fid(reqfid);
374bb0a56ecSDave Jones 	vcocurrfid = convert_fid_to_vco_fid(data->currfid);
375bb0a56ecSDave Jones 	vcofiddiff = vcocurrfid > vcoreqfid ? vcocurrfid - vcoreqfid
376bb0a56ecSDave Jones 	    : vcoreqfid - vcocurrfid;
377bb0a56ecSDave Jones 
378bb0a56ecSDave Jones 	if ((reqfid <= LO_FID_TABLE_TOP) && (data->currfid <= LO_FID_TABLE_TOP))
379bb0a56ecSDave Jones 		vcofiddiff = 0;
380bb0a56ecSDave Jones 
381bb0a56ecSDave Jones 	while (vcofiddiff > 2) {
382bb0a56ecSDave Jones 		(data->currfid & 1) ? (fid_interval = 1) : (fid_interval = 2);
383bb0a56ecSDave Jones 
384bb0a56ecSDave Jones 		if (reqfid > data->currfid) {
385bb0a56ecSDave Jones 			if (data->currfid > LO_FID_TABLE_TOP) {
386bb0a56ecSDave Jones 				if (write_new_fid(data,
387bb0a56ecSDave Jones 						data->currfid + fid_interval))
388bb0a56ecSDave Jones 					return 1;
389bb0a56ecSDave Jones 			} else {
390bb0a56ecSDave Jones 				if (write_new_fid
391bb0a56ecSDave Jones 				    (data,
392bb0a56ecSDave Jones 				     2 + convert_fid_to_vco_fid(data->currfid)))
393bb0a56ecSDave Jones 					return 1;
394bb0a56ecSDave Jones 			}
395bb0a56ecSDave Jones 		} else {
396bb0a56ecSDave Jones 			if (write_new_fid(data, data->currfid - fid_interval))
397bb0a56ecSDave Jones 				return 1;
398bb0a56ecSDave Jones 		}
399bb0a56ecSDave Jones 
400bb0a56ecSDave Jones 		vcocurrfid = convert_fid_to_vco_fid(data->currfid);
401bb0a56ecSDave Jones 		vcofiddiff = vcocurrfid > vcoreqfid ? vcocurrfid - vcoreqfid
402bb0a56ecSDave Jones 		    : vcoreqfid - vcocurrfid;
403bb0a56ecSDave Jones 	}
404bb0a56ecSDave Jones 
405bb0a56ecSDave Jones 	if (write_new_fid(data, reqfid))
406bb0a56ecSDave Jones 		return 1;
407bb0a56ecSDave Jones 
408bb0a56ecSDave Jones 	if (query_current_values_with_pending_wait(data))
409bb0a56ecSDave Jones 		return 1;
410bb0a56ecSDave Jones 
411bb0a56ecSDave Jones 	if (data->currfid != reqfid) {
412bb0a56ecSDave Jones 		printk(KERN_ERR PFX
413bb0a56ecSDave Jones 			"ph2: mismatch, failed fid transition, "
414bb0a56ecSDave Jones 			"curr 0x%x, req 0x%x\n",
415bb0a56ecSDave Jones 			data->currfid, reqfid);
416bb0a56ecSDave Jones 		return 1;
417bb0a56ecSDave Jones 	}
418bb0a56ecSDave Jones 
419bb0a56ecSDave Jones 	if (savevid != data->currvid) {
420bb0a56ecSDave Jones 		printk(KERN_ERR PFX "ph2: vid changed, save 0x%x, curr 0x%x\n",
421bb0a56ecSDave Jones 			savevid, data->currvid);
422bb0a56ecSDave Jones 		return 1;
423bb0a56ecSDave Jones 	}
424bb0a56ecSDave Jones 
425bb0a56ecSDave Jones 	pr_debug("ph2 complete, currfid 0x%x, currvid 0x%x\n",
426bb0a56ecSDave Jones 		data->currfid, data->currvid);
427bb0a56ecSDave Jones 
428bb0a56ecSDave Jones 	return 0;
429bb0a56ecSDave Jones }
430bb0a56ecSDave Jones 
431bb0a56ecSDave Jones /* Phase 3 - core voltage transition flow ... jump to the final vid. */
432bb0a56ecSDave Jones static int core_voltage_post_transition(struct powernow_k8_data *data,
433bb0a56ecSDave Jones 		u32 reqvid)
434bb0a56ecSDave Jones {
435bb0a56ecSDave Jones 	u32 savefid = data->currfid;
436bb0a56ecSDave Jones 	u32 savereqvid = reqvid;
437bb0a56ecSDave Jones 
438bb0a56ecSDave Jones 	pr_debug("ph3 (cpu%d): starting, currfid 0x%x, currvid 0x%x\n",
439bb0a56ecSDave Jones 		smp_processor_id(),
440bb0a56ecSDave Jones 		data->currfid, data->currvid);
441bb0a56ecSDave Jones 
442bb0a56ecSDave Jones 	if (reqvid != data->currvid) {
443bb0a56ecSDave Jones 		if (write_new_vid(data, reqvid))
444bb0a56ecSDave Jones 			return 1;
445bb0a56ecSDave Jones 
446bb0a56ecSDave Jones 		if (savefid != data->currfid) {
447bb0a56ecSDave Jones 			printk(KERN_ERR PFX
448bb0a56ecSDave Jones 			       "ph3: bad fid change, save 0x%x, curr 0x%x\n",
449bb0a56ecSDave Jones 			       savefid, data->currfid);
450bb0a56ecSDave Jones 			return 1;
451bb0a56ecSDave Jones 		}
452bb0a56ecSDave Jones 
453bb0a56ecSDave Jones 		if (data->currvid != reqvid) {
454bb0a56ecSDave Jones 			printk(KERN_ERR PFX
455bb0a56ecSDave Jones 			       "ph3: failed vid transition\n, "
456bb0a56ecSDave Jones 			       "req 0x%x, curr 0x%x",
457bb0a56ecSDave Jones 			       reqvid, data->currvid);
458bb0a56ecSDave Jones 			return 1;
459bb0a56ecSDave Jones 		}
460bb0a56ecSDave Jones 	}
461bb0a56ecSDave Jones 
462bb0a56ecSDave Jones 	if (query_current_values_with_pending_wait(data))
463bb0a56ecSDave Jones 		return 1;
464bb0a56ecSDave Jones 
465bb0a56ecSDave Jones 	if (savereqvid != data->currvid) {
466bb0a56ecSDave Jones 		pr_debug("ph3 failed, currvid 0x%x\n", data->currvid);
467bb0a56ecSDave Jones 		return 1;
468bb0a56ecSDave Jones 	}
469bb0a56ecSDave Jones 
470bb0a56ecSDave Jones 	if (savefid != data->currfid) {
471bb0a56ecSDave Jones 		pr_debug("ph3 failed, currfid changed 0x%x\n",
472bb0a56ecSDave Jones 			data->currfid);
473bb0a56ecSDave Jones 		return 1;
474bb0a56ecSDave Jones 	}
475bb0a56ecSDave Jones 
476bb0a56ecSDave Jones 	pr_debug("ph3 complete, currfid 0x%x, currvid 0x%x\n",
477bb0a56ecSDave Jones 		data->currfid, data->currvid);
478bb0a56ecSDave Jones 
479bb0a56ecSDave Jones 	return 0;
480bb0a56ecSDave Jones }
481bb0a56ecSDave Jones 
482fa8031aeSAndi Kleen static const struct x86_cpu_id powernow_k8_ids[] = {
483fa8031aeSAndi Kleen 	/* IO based frequency switching */
484fa8031aeSAndi Kleen 	{ X86_VENDOR_AMD, 0xf },
485fa8031aeSAndi Kleen 	{}
486fa8031aeSAndi Kleen };
487fa8031aeSAndi Kleen MODULE_DEVICE_TABLE(x86cpu, powernow_k8_ids);
488fa8031aeSAndi Kleen 
489bb0a56ecSDave Jones static void check_supported_cpu(void *_rc)
490bb0a56ecSDave Jones {
491bb0a56ecSDave Jones 	u32 eax, ebx, ecx, edx;
492bb0a56ecSDave Jones 	int *rc = _rc;
493bb0a56ecSDave Jones 
494bb0a56ecSDave Jones 	*rc = -ENODEV;
495bb0a56ecSDave Jones 
496bb0a56ecSDave Jones 	eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
497bb0a56ecSDave Jones 
498bb0a56ecSDave Jones 	if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) {
499bb0a56ecSDave Jones 		if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
500bb0a56ecSDave Jones 		    ((eax & CPUID_XMOD) > CPUID_XMOD_REV_MASK)) {
501bb0a56ecSDave Jones 			printk(KERN_INFO PFX
502bb0a56ecSDave Jones 				"Processor cpuid %x not supported\n", eax);
503bb0a56ecSDave Jones 			return;
504bb0a56ecSDave Jones 		}
505bb0a56ecSDave Jones 
506bb0a56ecSDave Jones 		eax = cpuid_eax(CPUID_GET_MAX_CAPABILITIES);
507bb0a56ecSDave Jones 		if (eax < CPUID_FREQ_VOLT_CAPABILITIES) {
508bb0a56ecSDave Jones 			printk(KERN_INFO PFX
509bb0a56ecSDave Jones 			       "No frequency change capabilities detected\n");
510bb0a56ecSDave Jones 			return;
511bb0a56ecSDave Jones 		}
512bb0a56ecSDave Jones 
513bb0a56ecSDave Jones 		cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx);
514bb0a56ecSDave Jones 		if ((edx & P_STATE_TRANSITION_CAPABLE)
515bb0a56ecSDave Jones 			!= P_STATE_TRANSITION_CAPABLE) {
516bb0a56ecSDave Jones 			printk(KERN_INFO PFX
517bb0a56ecSDave Jones 				"Power state transitions not supported\n");
518bb0a56ecSDave Jones 			return;
519bb0a56ecSDave Jones 		}
520bb0a56ecSDave Jones 		*rc = 0;
521bb0a56ecSDave Jones 	}
522e1f0b8e9SMatthew Garrett }
523bb0a56ecSDave Jones 
524bb0a56ecSDave Jones static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst,
525bb0a56ecSDave Jones 		u8 maxvid)
526bb0a56ecSDave Jones {
527bb0a56ecSDave Jones 	unsigned int j;
528bb0a56ecSDave Jones 	u8 lastfid = 0xff;
529bb0a56ecSDave Jones 
530bb0a56ecSDave Jones 	for (j = 0; j < data->numps; j++) {
531bb0a56ecSDave Jones 		if (pst[j].vid > LEAST_VID) {
532bb0a56ecSDave Jones 			printk(KERN_ERR FW_BUG PFX "vid %d invalid : 0x%x\n",
533bb0a56ecSDave Jones 			       j, pst[j].vid);
534bb0a56ecSDave Jones 			return -EINVAL;
535bb0a56ecSDave Jones 		}
536bb0a56ecSDave Jones 		if (pst[j].vid < data->rvo) {
537bb0a56ecSDave Jones 			/* vid + rvo >= 0 */
538bb0a56ecSDave Jones 			printk(KERN_ERR FW_BUG PFX "0 vid exceeded with pstate"
539bb0a56ecSDave Jones 			       " %d\n", j);
540bb0a56ecSDave Jones 			return -ENODEV;
541bb0a56ecSDave Jones 		}
542bb0a56ecSDave Jones 		if (pst[j].vid < maxvid + data->rvo) {
543bb0a56ecSDave Jones 			/* vid + rvo >= maxvid */
544bb0a56ecSDave Jones 			printk(KERN_ERR FW_BUG PFX "maxvid exceeded with pstate"
545bb0a56ecSDave Jones 			       " %d\n", j);
546bb0a56ecSDave Jones 			return -ENODEV;
547bb0a56ecSDave Jones 		}
548bb0a56ecSDave Jones 		if (pst[j].fid > MAX_FID) {
549bb0a56ecSDave Jones 			printk(KERN_ERR FW_BUG PFX "maxfid exceeded with pstate"
550bb0a56ecSDave Jones 			       " %d\n", j);
551bb0a56ecSDave Jones 			return -ENODEV;
552bb0a56ecSDave Jones 		}
553bb0a56ecSDave Jones 		if (j && (pst[j].fid < HI_FID_TABLE_BOTTOM)) {
554bb0a56ecSDave Jones 			/* Only first fid is allowed to be in "low" range */
555bb0a56ecSDave Jones 			printk(KERN_ERR FW_BUG PFX "two low fids - %d : "
556bb0a56ecSDave Jones 			       "0x%x\n", j, pst[j].fid);
557bb0a56ecSDave Jones 			return -EINVAL;
558bb0a56ecSDave Jones 		}
559bb0a56ecSDave Jones 		if (pst[j].fid < lastfid)
560bb0a56ecSDave Jones 			lastfid = pst[j].fid;
561bb0a56ecSDave Jones 	}
562bb0a56ecSDave Jones 	if (lastfid & 1) {
563bb0a56ecSDave Jones 		printk(KERN_ERR FW_BUG PFX "lastfid invalid\n");
564bb0a56ecSDave Jones 		return -EINVAL;
565bb0a56ecSDave Jones 	}
566bb0a56ecSDave Jones 	if (lastfid > LO_FID_TABLE_TOP)
567bb0a56ecSDave Jones 		printk(KERN_INFO FW_BUG PFX
568bb0a56ecSDave Jones 			"first fid not from lo freq table\n");
569bb0a56ecSDave Jones 
570bb0a56ecSDave Jones 	return 0;
571bb0a56ecSDave Jones }
572bb0a56ecSDave Jones 
573bb0a56ecSDave Jones static void invalidate_entry(struct cpufreq_frequency_table *powernow_table,
574bb0a56ecSDave Jones 		unsigned int entry)
575bb0a56ecSDave Jones {
576bb0a56ecSDave Jones 	powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
577bb0a56ecSDave Jones }
578bb0a56ecSDave Jones 
579bb0a56ecSDave Jones static void print_basics(struct powernow_k8_data *data)
580bb0a56ecSDave Jones {
581bb0a56ecSDave Jones 	int j;
582bb0a56ecSDave Jones 	for (j = 0; j < data->numps; j++) {
583bb0a56ecSDave Jones 		if (data->powernow_table[j].frequency !=
584bb0a56ecSDave Jones 				CPUFREQ_ENTRY_INVALID) {
585bb0a56ecSDave Jones 				printk(KERN_INFO PFX
586bb0a56ecSDave Jones 					"fid 0x%x (%d MHz), vid 0x%x\n",
58750701588SViresh Kumar 					data->powernow_table[j].driver_data & 0xff,
588bb0a56ecSDave Jones 					data->powernow_table[j].frequency/1000,
58950701588SViresh Kumar 					data->powernow_table[j].driver_data >> 8);
590bb0a56ecSDave Jones 		}
591bb0a56ecSDave Jones 	}
592bb0a56ecSDave Jones 	if (data->batps)
593bb0a56ecSDave Jones 		printk(KERN_INFO PFX "Only %d pstates on battery\n",
594bb0a56ecSDave Jones 				data->batps);
595bb0a56ecSDave Jones }
596bb0a56ecSDave Jones 
597bb0a56ecSDave Jones static int fill_powernow_table(struct powernow_k8_data *data,
598bb0a56ecSDave Jones 		struct pst_s *pst, u8 maxvid)
599bb0a56ecSDave Jones {
600bb0a56ecSDave Jones 	struct cpufreq_frequency_table *powernow_table;
601bb0a56ecSDave Jones 	unsigned int j;
602bb0a56ecSDave Jones 
603bb0a56ecSDave Jones 	if (data->batps) {
604bb0a56ecSDave Jones 		/* use ACPI support to get full speed on mains power */
605bb0a56ecSDave Jones 		printk(KERN_WARNING PFX
606bb0a56ecSDave Jones 			"Only %d pstates usable (use ACPI driver for full "
607bb0a56ecSDave Jones 			"range\n", data->batps);
608bb0a56ecSDave Jones 		data->numps = data->batps;
609bb0a56ecSDave Jones 	}
610bb0a56ecSDave Jones 
611bb0a56ecSDave Jones 	for (j = 1; j < data->numps; j++) {
612bb0a56ecSDave Jones 		if (pst[j-1].fid >= pst[j].fid) {
613bb0a56ecSDave Jones 			printk(KERN_ERR PFX "PST out of sequence\n");
614bb0a56ecSDave Jones 			return -EINVAL;
615bb0a56ecSDave Jones 		}
616bb0a56ecSDave Jones 	}
617bb0a56ecSDave Jones 
618bb0a56ecSDave Jones 	if (data->numps < 2) {
619bb0a56ecSDave Jones 		printk(KERN_ERR PFX "no p states to transition\n");
620bb0a56ecSDave Jones 		return -ENODEV;
621bb0a56ecSDave Jones 	}
622bb0a56ecSDave Jones 
623bb0a56ecSDave Jones 	if (check_pst_table(data, pst, maxvid))
624bb0a56ecSDave Jones 		return -EINVAL;
625bb0a56ecSDave Jones 
626d5b73cd8SViresh Kumar 	powernow_table = kmalloc((sizeof(*powernow_table)
627bb0a56ecSDave Jones 		* (data->numps + 1)), GFP_KERNEL);
628bb0a56ecSDave Jones 	if (!powernow_table) {
629bb0a56ecSDave Jones 		printk(KERN_ERR PFX "powernow_table memory alloc failure\n");
630bb0a56ecSDave Jones 		return -ENOMEM;
631bb0a56ecSDave Jones 	}
632bb0a56ecSDave Jones 
633bb0a56ecSDave Jones 	for (j = 0; j < data->numps; j++) {
634bb0a56ecSDave Jones 		int freq;
63550701588SViresh Kumar 		powernow_table[j].driver_data = pst[j].fid; /* lower 8 bits */
63650701588SViresh Kumar 		powernow_table[j].driver_data |= (pst[j].vid << 8); /* upper 8 bits */
637bb0a56ecSDave Jones 		freq = find_khz_freq_from_fid(pst[j].fid);
638bb0a56ecSDave Jones 		powernow_table[j].frequency = freq;
639bb0a56ecSDave Jones 	}
640bb0a56ecSDave Jones 	powernow_table[data->numps].frequency = CPUFREQ_TABLE_END;
64150701588SViresh Kumar 	powernow_table[data->numps].driver_data = 0;
642bb0a56ecSDave Jones 
643bb0a56ecSDave Jones 	if (query_current_values_with_pending_wait(data)) {
644bb0a56ecSDave Jones 		kfree(powernow_table);
645bb0a56ecSDave Jones 		return -EIO;
646bb0a56ecSDave Jones 	}
647bb0a56ecSDave Jones 
648bb0a56ecSDave Jones 	pr_debug("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid);
649bb0a56ecSDave Jones 	data->powernow_table = powernow_table;
650bb0a56ecSDave Jones 	if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
651bb0a56ecSDave Jones 		print_basics(data);
652bb0a56ecSDave Jones 
653bb0a56ecSDave Jones 	for (j = 0; j < data->numps; j++)
654bb0a56ecSDave Jones 		if ((pst[j].fid == data->currfid) &&
655bb0a56ecSDave Jones 		    (pst[j].vid == data->currvid))
656bb0a56ecSDave Jones 			return 0;
657bb0a56ecSDave Jones 
658bb0a56ecSDave Jones 	pr_debug("currfid/vid do not match PST, ignoring\n");
659bb0a56ecSDave Jones 	return 0;
660bb0a56ecSDave Jones }
661bb0a56ecSDave Jones 
662bb0a56ecSDave Jones /* Find and validate the PSB/PST table in BIOS. */
663bb0a56ecSDave Jones static int find_psb_table(struct powernow_k8_data *data)
664bb0a56ecSDave Jones {
665bb0a56ecSDave Jones 	struct psb_s *psb;
666bb0a56ecSDave Jones 	unsigned int i;
667bb0a56ecSDave Jones 	u32 mvs;
668bb0a56ecSDave Jones 	u8 maxvid;
669bb0a56ecSDave Jones 	u32 cpst = 0;
670bb0a56ecSDave Jones 	u32 thiscpuid;
671bb0a56ecSDave Jones 
672bb0a56ecSDave Jones 	for (i = 0xc0000; i < 0xffff0; i += 0x10) {
673bb0a56ecSDave Jones 		/* Scan BIOS looking for the signature. */
674bb0a56ecSDave Jones 		/* It can not be at ffff0 - it is too big. */
675bb0a56ecSDave Jones 
676bb0a56ecSDave Jones 		psb = phys_to_virt(i);
677bb0a56ecSDave Jones 		if (memcmp(psb, PSB_ID_STRING, PSB_ID_STRING_LEN) != 0)
678bb0a56ecSDave Jones 			continue;
679bb0a56ecSDave Jones 
680bb0a56ecSDave Jones 		pr_debug("found PSB header at 0x%p\n", psb);
681bb0a56ecSDave Jones 
682bb0a56ecSDave Jones 		pr_debug("table vers: 0x%x\n", psb->tableversion);
683bb0a56ecSDave Jones 		if (psb->tableversion != PSB_VERSION_1_4) {
684bb0a56ecSDave Jones 			printk(KERN_ERR FW_BUG PFX "PSB table is not v1.4\n");
685bb0a56ecSDave Jones 			return -ENODEV;
686bb0a56ecSDave Jones 		}
687bb0a56ecSDave Jones 
688bb0a56ecSDave Jones 		pr_debug("flags: 0x%x\n", psb->flags1);
689bb0a56ecSDave Jones 		if (psb->flags1) {
690bb0a56ecSDave Jones 			printk(KERN_ERR FW_BUG PFX "unknown flags\n");
691bb0a56ecSDave Jones 			return -ENODEV;
692bb0a56ecSDave Jones 		}
693bb0a56ecSDave Jones 
694bb0a56ecSDave Jones 		data->vstable = psb->vstable;
695bb0a56ecSDave Jones 		pr_debug("voltage stabilization time: %d(*20us)\n",
696bb0a56ecSDave Jones 				data->vstable);
697bb0a56ecSDave Jones 
698bb0a56ecSDave Jones 		pr_debug("flags2: 0x%x\n", psb->flags2);
699bb0a56ecSDave Jones 		data->rvo = psb->flags2 & 3;
700bb0a56ecSDave Jones 		data->irt = ((psb->flags2) >> 2) & 3;
701bb0a56ecSDave Jones 		mvs = ((psb->flags2) >> 4) & 3;
702bb0a56ecSDave Jones 		data->vidmvs = 1 << mvs;
703bb0a56ecSDave Jones 		data->batps = ((psb->flags2) >> 6) & 3;
704bb0a56ecSDave Jones 
705bb0a56ecSDave Jones 		pr_debug("ramp voltage offset: %d\n", data->rvo);
706bb0a56ecSDave Jones 		pr_debug("isochronous relief time: %d\n", data->irt);
707bb0a56ecSDave Jones 		pr_debug("maximum voltage step: %d - 0x%x\n", mvs, data->vidmvs);
708bb0a56ecSDave Jones 
709bb0a56ecSDave Jones 		pr_debug("numpst: 0x%x\n", psb->num_tables);
710bb0a56ecSDave Jones 		cpst = psb->num_tables;
711bb0a56ecSDave Jones 		if ((psb->cpuid == 0x00000fc0) ||
712bb0a56ecSDave Jones 		    (psb->cpuid == 0x00000fe0)) {
713bb0a56ecSDave Jones 			thiscpuid = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
714bb0a56ecSDave Jones 			if ((thiscpuid == 0x00000fc0) ||
715bb0a56ecSDave Jones 			    (thiscpuid == 0x00000fe0))
716bb0a56ecSDave Jones 				cpst = 1;
717bb0a56ecSDave Jones 		}
718bb0a56ecSDave Jones 		if (cpst != 1) {
719bb0a56ecSDave Jones 			printk(KERN_ERR FW_BUG PFX "numpst must be 1\n");
720bb0a56ecSDave Jones 			return -ENODEV;
721bb0a56ecSDave Jones 		}
722bb0a56ecSDave Jones 
723bb0a56ecSDave Jones 		data->plllock = psb->plllocktime;
724bb0a56ecSDave Jones 		pr_debug("plllocktime: 0x%x (units 1us)\n", psb->plllocktime);
725bb0a56ecSDave Jones 		pr_debug("maxfid: 0x%x\n", psb->maxfid);
726bb0a56ecSDave Jones 		pr_debug("maxvid: 0x%x\n", psb->maxvid);
727bb0a56ecSDave Jones 		maxvid = psb->maxvid;
728bb0a56ecSDave Jones 
729bb0a56ecSDave Jones 		data->numps = psb->numps;
730bb0a56ecSDave Jones 		pr_debug("numpstates: 0x%x\n", data->numps);
731bb0a56ecSDave Jones 		return fill_powernow_table(data,
732bb0a56ecSDave Jones 				(struct pst_s *)(psb+1), maxvid);
733bb0a56ecSDave Jones 	}
734bb0a56ecSDave Jones 	/*
735bb0a56ecSDave Jones 	 * If you see this message, complain to BIOS manufacturer. If
736bb0a56ecSDave Jones 	 * he tells you "we do not support Linux" or some similar
737bb0a56ecSDave Jones 	 * nonsense, remember that Windows 2000 uses the same legacy
738bb0a56ecSDave Jones 	 * mechanism that the old Linux PSB driver uses. Tell them it
739bb0a56ecSDave Jones 	 * is broken with Windows 2000.
740bb0a56ecSDave Jones 	 *
741bb0a56ecSDave Jones 	 * The reference to the AMD documentation is chapter 9 in the
742bb0a56ecSDave Jones 	 * BIOS and Kernel Developer's Guide, which is available on
743bb0a56ecSDave Jones 	 * www.amd.com
744bb0a56ecSDave Jones 	 */
745bb0a56ecSDave Jones 	printk(KERN_ERR FW_BUG PFX "No PSB or ACPI _PSS objects\n");
746bb0a56ecSDave Jones 	printk(KERN_ERR PFX "Make sure that your BIOS is up to date"
747bb0a56ecSDave Jones 		" and Cool'N'Quiet support is enabled in BIOS setup\n");
748bb0a56ecSDave Jones 	return -ENODEV;
749bb0a56ecSDave Jones }
750bb0a56ecSDave Jones 
751bb0a56ecSDave Jones static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data,
752bb0a56ecSDave Jones 		unsigned int index)
753bb0a56ecSDave Jones {
754bb0a56ecSDave Jones 	u64 control;
755bb0a56ecSDave Jones 
756e1f0b8e9SMatthew Garrett 	if (!data->acpi_data.state_count)
757bb0a56ecSDave Jones 		return;
758bb0a56ecSDave Jones 
759bb0a56ecSDave Jones 	control = data->acpi_data.states[index].control;
760bb0a56ecSDave Jones 	data->irt = (control >> IRT_SHIFT) & IRT_MASK;
761bb0a56ecSDave Jones 	data->rvo = (control >> RVO_SHIFT) & RVO_MASK;
762bb0a56ecSDave Jones 	data->exttype = (control >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK;
763bb0a56ecSDave Jones 	data->plllock = (control >> PLL_L_SHIFT) & PLL_L_MASK;
764bb0a56ecSDave Jones 	data->vidmvs = 1 << ((control >> MVS_SHIFT) & MVS_MASK);
765bb0a56ecSDave Jones 	data->vstable = (control >> VST_SHIFT) & VST_MASK;
766bb0a56ecSDave Jones }
767bb0a56ecSDave Jones 
768bb0a56ecSDave Jones static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
769bb0a56ecSDave Jones {
770bb0a56ecSDave Jones 	struct cpufreq_frequency_table *powernow_table;
771bb0a56ecSDave Jones 	int ret_val = -ENODEV;
772bb0a56ecSDave Jones 	u64 control, status;
773bb0a56ecSDave Jones 
774bb0a56ecSDave Jones 	if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) {
775bb0a56ecSDave Jones 		pr_debug("register performance failed: bad ACPI data\n");
776bb0a56ecSDave Jones 		return -EIO;
777bb0a56ecSDave Jones 	}
778bb0a56ecSDave Jones 
779bb0a56ecSDave Jones 	/* verify the data contained in the ACPI structures */
780bb0a56ecSDave Jones 	if (data->acpi_data.state_count <= 1) {
781bb0a56ecSDave Jones 		pr_debug("No ACPI P-States\n");
782bb0a56ecSDave Jones 		goto err_out;
783bb0a56ecSDave Jones 	}
784bb0a56ecSDave Jones 
785bb0a56ecSDave Jones 	control = data->acpi_data.control_register.space_id;
786bb0a56ecSDave Jones 	status = data->acpi_data.status_register.space_id;
787bb0a56ecSDave Jones 
788bb0a56ecSDave Jones 	if ((control != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
789bb0a56ecSDave Jones 	    (status != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
790bb0a56ecSDave Jones 		pr_debug("Invalid control/status registers (%llx - %llx)\n",
791bb0a56ecSDave Jones 			control, status);
792bb0a56ecSDave Jones 		goto err_out;
793bb0a56ecSDave Jones 	}
794bb0a56ecSDave Jones 
795bb0a56ecSDave Jones 	/* fill in data->powernow_table */
796d5b73cd8SViresh Kumar 	powernow_table = kmalloc((sizeof(*powernow_table)
797bb0a56ecSDave Jones 		* (data->acpi_data.state_count + 1)), GFP_KERNEL);
798bb0a56ecSDave Jones 	if (!powernow_table) {
799bb0a56ecSDave Jones 		pr_debug("powernow_table memory alloc failure\n");
800bb0a56ecSDave Jones 		goto err_out;
801bb0a56ecSDave Jones 	}
802bb0a56ecSDave Jones 
803bb0a56ecSDave Jones 	/* fill in data */
804bb0a56ecSDave Jones 	data->numps = data->acpi_data.state_count;
805bb0a56ecSDave Jones 	powernow_k8_acpi_pst_values(data, 0);
806bb0a56ecSDave Jones 
807bb0a56ecSDave Jones 	ret_val = fill_powernow_table_fidvid(data, powernow_table);
808bb0a56ecSDave Jones 	if (ret_val)
809bb0a56ecSDave Jones 		goto err_out_mem;
810bb0a56ecSDave Jones 
811bb0a56ecSDave Jones 	powernow_table[data->acpi_data.state_count].frequency =
812bb0a56ecSDave Jones 		CPUFREQ_TABLE_END;
81350701588SViresh Kumar 	powernow_table[data->acpi_data.state_count].driver_data = 0;
814bb0a56ecSDave Jones 	data->powernow_table = powernow_table;
815bb0a56ecSDave Jones 
816bb0a56ecSDave Jones 	if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
817bb0a56ecSDave Jones 		print_basics(data);
818bb0a56ecSDave Jones 
819bb0a56ecSDave Jones 	/* notify BIOS that we exist */
820bb0a56ecSDave Jones 	acpi_processor_notify_smm(THIS_MODULE);
821bb0a56ecSDave Jones 
822bb0a56ecSDave Jones 	if (!zalloc_cpumask_var(&data->acpi_data.shared_cpu_map, GFP_KERNEL)) {
823bb0a56ecSDave Jones 		printk(KERN_ERR PFX
824bb0a56ecSDave Jones 				"unable to alloc powernow_k8_data cpumask\n");
825bb0a56ecSDave Jones 		ret_val = -ENOMEM;
826bb0a56ecSDave Jones 		goto err_out_mem;
827bb0a56ecSDave Jones 	}
828bb0a56ecSDave Jones 
829bb0a56ecSDave Jones 	return 0;
830bb0a56ecSDave Jones 
831bb0a56ecSDave Jones err_out_mem:
832bb0a56ecSDave Jones 	kfree(powernow_table);
833bb0a56ecSDave Jones 
834bb0a56ecSDave Jones err_out:
835bb0a56ecSDave Jones 	acpi_processor_unregister_performance(&data->acpi_data, data->cpu);
836bb0a56ecSDave Jones 
837bb0a56ecSDave Jones 	/* data->acpi_data.state_count informs us at ->exit()
838bb0a56ecSDave Jones 	 * whether ACPI was used */
839bb0a56ecSDave Jones 	data->acpi_data.state_count = 0;
840bb0a56ecSDave Jones 
841bb0a56ecSDave Jones 	return ret_val;
842bb0a56ecSDave Jones }
843bb0a56ecSDave Jones 
844bb0a56ecSDave Jones static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
845bb0a56ecSDave Jones 		struct cpufreq_frequency_table *powernow_table)
846bb0a56ecSDave Jones {
847bb0a56ecSDave Jones 	int i;
848bb0a56ecSDave Jones 
849bb0a56ecSDave Jones 	for (i = 0; i < data->acpi_data.state_count; i++) {
850bb0a56ecSDave Jones 		u32 fid;
851bb0a56ecSDave Jones 		u32 vid;
852bb0a56ecSDave Jones 		u32 freq, index;
853bb0a56ecSDave Jones 		u64 status, control;
854bb0a56ecSDave Jones 
855bb0a56ecSDave Jones 		if (data->exttype) {
856bb0a56ecSDave Jones 			status =  data->acpi_data.states[i].status;
857bb0a56ecSDave Jones 			fid = status & EXT_FID_MASK;
858bb0a56ecSDave Jones 			vid = (status >> VID_SHIFT) & EXT_VID_MASK;
859bb0a56ecSDave Jones 		} else {
860bb0a56ecSDave Jones 			control =  data->acpi_data.states[i].control;
861bb0a56ecSDave Jones 			fid = control & FID_MASK;
862bb0a56ecSDave Jones 			vid = (control >> VID_SHIFT) & VID_MASK;
863bb0a56ecSDave Jones 		}
864bb0a56ecSDave Jones 
865bb0a56ecSDave Jones 		pr_debug("   %d : fid 0x%x, vid 0x%x\n", i, fid, vid);
866bb0a56ecSDave Jones 
867bb0a56ecSDave Jones 		index = fid | (vid<<8);
86850701588SViresh Kumar 		powernow_table[i].driver_data = index;
869bb0a56ecSDave Jones 
870bb0a56ecSDave Jones 		freq = find_khz_freq_from_fid(fid);
871bb0a56ecSDave Jones 		powernow_table[i].frequency = freq;
872bb0a56ecSDave Jones 
873bb0a56ecSDave Jones 		/* verify frequency is OK */
874bb0a56ecSDave Jones 		if ((freq > (MAX_FREQ * 1000)) || (freq < (MIN_FREQ * 1000))) {
875bb0a56ecSDave Jones 			pr_debug("invalid freq %u kHz, ignoring\n", freq);
876bb0a56ecSDave Jones 			invalidate_entry(powernow_table, i);
877bb0a56ecSDave Jones 			continue;
878bb0a56ecSDave Jones 		}
879bb0a56ecSDave Jones 
880bb0a56ecSDave Jones 		/* verify voltage is OK -
881bb0a56ecSDave Jones 		 * BIOSs are using "off" to indicate invalid */
882bb0a56ecSDave Jones 		if (vid == VID_OFF) {
883bb0a56ecSDave Jones 			pr_debug("invalid vid %u, ignoring\n", vid);
884bb0a56ecSDave Jones 			invalidate_entry(powernow_table, i);
885bb0a56ecSDave Jones 			continue;
886bb0a56ecSDave Jones 		}
887bb0a56ecSDave Jones 
888bb0a56ecSDave Jones 		if (freq != (data->acpi_data.states[i].core_frequency * 1000)) {
889bb0a56ecSDave Jones 			printk(KERN_INFO PFX "invalid freq entries "
890bb0a56ecSDave Jones 				"%u kHz vs. %u kHz\n", freq,
891bb0a56ecSDave Jones 				(unsigned int)
892bb0a56ecSDave Jones 				(data->acpi_data.states[i].core_frequency
893bb0a56ecSDave Jones 				 * 1000));
894bb0a56ecSDave Jones 			invalidate_entry(powernow_table, i);
895bb0a56ecSDave Jones 			continue;
896bb0a56ecSDave Jones 		}
897bb0a56ecSDave Jones 	}
898bb0a56ecSDave Jones 	return 0;
899bb0a56ecSDave Jones }
900bb0a56ecSDave Jones 
901bb0a56ecSDave Jones static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data)
902bb0a56ecSDave Jones {
903bb0a56ecSDave Jones 	if (data->acpi_data.state_count)
904bb0a56ecSDave Jones 		acpi_processor_unregister_performance(&data->acpi_data,
905bb0a56ecSDave Jones 				data->cpu);
906bb0a56ecSDave Jones 	free_cpumask_var(data->acpi_data.shared_cpu_map);
907bb0a56ecSDave Jones }
908bb0a56ecSDave Jones 
909bb0a56ecSDave Jones static int get_transition_latency(struct powernow_k8_data *data)
910bb0a56ecSDave Jones {
911bb0a56ecSDave Jones 	int max_latency = 0;
912bb0a56ecSDave Jones 	int i;
913bb0a56ecSDave Jones 	for (i = 0; i < data->acpi_data.state_count; i++) {
914bb0a56ecSDave Jones 		int cur_latency = data->acpi_data.states[i].transition_latency
915bb0a56ecSDave Jones 			+ data->acpi_data.states[i].bus_master_latency;
916bb0a56ecSDave Jones 		if (cur_latency > max_latency)
917bb0a56ecSDave Jones 			max_latency = cur_latency;
918bb0a56ecSDave Jones 	}
919bb0a56ecSDave Jones 	if (max_latency == 0) {
920e1f0b8e9SMatthew Garrett 		pr_err(FW_WARN PFX "Invalid zero transition latency\n");
921bb0a56ecSDave Jones 		max_latency = 1;
922bb0a56ecSDave Jones 	}
923bb0a56ecSDave Jones 	/* value in usecs, needs to be in nanoseconds */
924bb0a56ecSDave Jones 	return 1000 * max_latency;
925bb0a56ecSDave Jones }
926bb0a56ecSDave Jones 
927bb0a56ecSDave Jones /* Take a frequency, and issue the fid/vid transition command */
928bb0a56ecSDave Jones static int transition_frequency_fidvid(struct powernow_k8_data *data,
929bb0a56ecSDave Jones 		unsigned int index)
930bb0a56ecSDave Jones {
931b43a7ffbSViresh Kumar 	struct cpufreq_policy *policy;
932bb0a56ecSDave Jones 	u32 fid = 0;
933bb0a56ecSDave Jones 	u32 vid = 0;
934b43a7ffbSViresh Kumar 	int res;
935bb0a56ecSDave Jones 	struct cpufreq_freqs freqs;
936bb0a56ecSDave Jones 
937bb0a56ecSDave Jones 	pr_debug("cpu %d transition to index %u\n", smp_processor_id(), index);
938bb0a56ecSDave Jones 
939bb0a56ecSDave Jones 	/* fid/vid correctness check for k8 */
940bb0a56ecSDave Jones 	/* fid are the lower 8 bits of the index we stored into
941bb0a56ecSDave Jones 	 * the cpufreq frequency table in find_psb_table, vid
942bb0a56ecSDave Jones 	 * are the upper 8 bits.
943bb0a56ecSDave Jones 	 */
94450701588SViresh Kumar 	fid = data->powernow_table[index].driver_data & 0xFF;
94550701588SViresh Kumar 	vid = (data->powernow_table[index].driver_data & 0xFF00) >> 8;
946bb0a56ecSDave Jones 
947bb0a56ecSDave Jones 	pr_debug("table matched fid 0x%x, giving vid 0x%x\n", fid, vid);
948bb0a56ecSDave Jones 
949bb0a56ecSDave Jones 	if (query_current_values_with_pending_wait(data))
950bb0a56ecSDave Jones 		return 1;
951bb0a56ecSDave Jones 
952bb0a56ecSDave Jones 	if ((data->currvid == vid) && (data->currfid == fid)) {
953bb0a56ecSDave Jones 		pr_debug("target matches current values (fid 0x%x, vid 0x%x)\n",
954bb0a56ecSDave Jones 			fid, vid);
955bb0a56ecSDave Jones 		return 0;
956bb0a56ecSDave Jones 	}
957bb0a56ecSDave Jones 
958bb0a56ecSDave Jones 	pr_debug("cpu %d, changing to fid 0x%x, vid 0x%x\n",
959bb0a56ecSDave Jones 		smp_processor_id(), fid, vid);
960bb0a56ecSDave Jones 	freqs.old = find_khz_freq_from_fid(data->currfid);
961bb0a56ecSDave Jones 	freqs.new = find_khz_freq_from_fid(fid);
962bb0a56ecSDave Jones 
963b43a7ffbSViresh Kumar 	policy = cpufreq_cpu_get(smp_processor_id());
964b43a7ffbSViresh Kumar 	cpufreq_cpu_put(policy);
965b43a7ffbSViresh Kumar 
966b43a7ffbSViresh Kumar 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
967bb0a56ecSDave Jones 
968bb0a56ecSDave Jones 	res = transition_fid_vid(data, fid, vid);
969a9d3d206SKonrad Rzeszutek Wilk 	if (res)
9707f77a563SViresh Kumar 		freqs.new = freqs.old;
9717f77a563SViresh Kumar 	else
972bb0a56ecSDave Jones 		freqs.new = find_khz_freq_from_fid(data->currfid);
973bb0a56ecSDave Jones 
974b43a7ffbSViresh Kumar 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
975bb0a56ecSDave Jones 	return res;
976bb0a56ecSDave Jones }
977bb0a56ecSDave Jones 
9786889125bSTejun Heo struct powernowk8_target_arg {
9796889125bSTejun Heo 	struct cpufreq_policy		*pol;
9806889125bSTejun Heo 	unsigned			targfreq;
9816889125bSTejun Heo 	unsigned			relation;
9826889125bSTejun Heo };
9836889125bSTejun Heo 
9846889125bSTejun Heo static long powernowk8_target_fn(void *arg)
985bb0a56ecSDave Jones {
9866889125bSTejun Heo 	struct powernowk8_target_arg *pta = arg;
9876889125bSTejun Heo 	struct cpufreq_policy *pol = pta->pol;
9886889125bSTejun Heo 	unsigned targfreq = pta->targfreq;
9896889125bSTejun Heo 	unsigned relation = pta->relation;
990bb0a56ecSDave Jones 	struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
991bb0a56ecSDave Jones 	u32 checkfid;
992bb0a56ecSDave Jones 	u32 checkvid;
993bb0a56ecSDave Jones 	unsigned int newstate;
9946889125bSTejun Heo 	int ret;
995bb0a56ecSDave Jones 
996bb0a56ecSDave Jones 	if (!data)
997bb0a56ecSDave Jones 		return -EINVAL;
998bb0a56ecSDave Jones 
999bb0a56ecSDave Jones 	checkfid = data->currfid;
1000bb0a56ecSDave Jones 	checkvid = data->currvid;
1001bb0a56ecSDave Jones 
1002bb0a56ecSDave Jones 	if (pending_bit_stuck()) {
1003bb0a56ecSDave Jones 		printk(KERN_ERR PFX "failing targ, change pending bit set\n");
10046889125bSTejun Heo 		return -EIO;
1005bb0a56ecSDave Jones 	}
1006bb0a56ecSDave Jones 
1007bb0a56ecSDave Jones 	pr_debug("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n",
1008bb0a56ecSDave Jones 		pol->cpu, targfreq, pol->min, pol->max, relation);
1009bb0a56ecSDave Jones 
1010bb0a56ecSDave Jones 	if (query_current_values_with_pending_wait(data))
10116889125bSTejun Heo 		return -EIO;
1012bb0a56ecSDave Jones 
1013bb0a56ecSDave Jones 	pr_debug("targ: curr fid 0x%x, vid 0x%x\n",
1014bb0a56ecSDave Jones 		 data->currfid, data->currvid);
1015bb0a56ecSDave Jones 
1016bb0a56ecSDave Jones 	if ((checkvid != data->currvid) ||
1017bb0a56ecSDave Jones 	    (checkfid != data->currfid)) {
1018e1f0b8e9SMatthew Garrett 		pr_info(PFX
1019e1f0b8e9SMatthew Garrett 		       "error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n",
1020bb0a56ecSDave Jones 		       checkfid, data->currfid,
1021bb0a56ecSDave Jones 		       checkvid, data->currvid);
1022bb0a56ecSDave Jones 	}
1023bb0a56ecSDave Jones 
1024bb0a56ecSDave Jones 	if (cpufreq_frequency_table_target(pol, data->powernow_table,
1025bb0a56ecSDave Jones 				targfreq, relation, &newstate))
10266889125bSTejun Heo 		return -EIO;
1027bb0a56ecSDave Jones 
1028bb0a56ecSDave Jones 	mutex_lock(&fidvid_mutex);
1029bb0a56ecSDave Jones 
1030bb0a56ecSDave Jones 	powernow_k8_acpi_pst_values(data, newstate);
1031bb0a56ecSDave Jones 
1032bb0a56ecSDave Jones 	ret = transition_frequency_fidvid(data, newstate);
1033e1f0b8e9SMatthew Garrett 
1034bb0a56ecSDave Jones 	if (ret) {
1035bb0a56ecSDave Jones 		printk(KERN_ERR PFX "transition frequency failed\n");
1036bb0a56ecSDave Jones 		mutex_unlock(&fidvid_mutex);
10376889125bSTejun Heo 		return 1;
1038bb0a56ecSDave Jones 	}
1039bb0a56ecSDave Jones 	mutex_unlock(&fidvid_mutex);
1040bb0a56ecSDave Jones 
1041bb0a56ecSDave Jones 	pol->cur = find_khz_freq_from_fid(data->currfid);
1042bb0a56ecSDave Jones 
10436889125bSTejun Heo 	return 0;
10446889125bSTejun Heo }
10456889125bSTejun Heo 
10466889125bSTejun Heo /* Driver entry point to switch to the target frequency */
10476889125bSTejun Heo static int powernowk8_target(struct cpufreq_policy *pol,
10486889125bSTejun Heo 		unsigned targfreq, unsigned relation)
10496889125bSTejun Heo {
10506889125bSTejun Heo 	struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq,
10516889125bSTejun Heo 					     .relation = relation };
10526889125bSTejun Heo 
10536889125bSTejun Heo 	return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta);
1054bb0a56ecSDave Jones }
1055bb0a56ecSDave Jones 
1056bb0a56ecSDave Jones struct init_on_cpu {
1057bb0a56ecSDave Jones 	struct powernow_k8_data *data;
1058bb0a56ecSDave Jones 	int rc;
1059bb0a56ecSDave Jones };
1060bb0a56ecSDave Jones 
10612760984fSPaul Gortmaker static void powernowk8_cpu_init_on_cpu(void *_init_on_cpu)
1062bb0a56ecSDave Jones {
1063bb0a56ecSDave Jones 	struct init_on_cpu *init_on_cpu = _init_on_cpu;
1064bb0a56ecSDave Jones 
1065bb0a56ecSDave Jones 	if (pending_bit_stuck()) {
1066bb0a56ecSDave Jones 		printk(KERN_ERR PFX "failing init, change pending bit set\n");
1067bb0a56ecSDave Jones 		init_on_cpu->rc = -ENODEV;
1068bb0a56ecSDave Jones 		return;
1069bb0a56ecSDave Jones 	}
1070bb0a56ecSDave Jones 
1071bb0a56ecSDave Jones 	if (query_current_values_with_pending_wait(init_on_cpu->data)) {
1072bb0a56ecSDave Jones 		init_on_cpu->rc = -ENODEV;
1073bb0a56ecSDave Jones 		return;
1074bb0a56ecSDave Jones 	}
1075bb0a56ecSDave Jones 
1076bb0a56ecSDave Jones 	fidvid_msr_init();
1077bb0a56ecSDave Jones 
1078bb0a56ecSDave Jones 	init_on_cpu->rc = 0;
1079bb0a56ecSDave Jones }
1080bb0a56ecSDave Jones 
108156835e6cSBorislav Petkov static const char missing_pss_msg[] =
108256835e6cSBorislav Petkov 	KERN_ERR
108356835e6cSBorislav Petkov 	FW_BUG PFX "No compatible ACPI _PSS objects found.\n"
108456835e6cSBorislav Petkov 	FW_BUG PFX "First, make sure Cool'N'Quiet is enabled in the BIOS.\n"
108556835e6cSBorislav Petkov 	FW_BUG PFX "If that doesn't help, try upgrading your BIOS.\n";
108656835e6cSBorislav Petkov 
1087bb0a56ecSDave Jones /* per CPU init entry point to the driver */
10882760984fSPaul Gortmaker static int powernowk8_cpu_init(struct cpufreq_policy *pol)
1089bb0a56ecSDave Jones {
1090bb0a56ecSDave Jones 	struct powernow_k8_data *data;
1091bb0a56ecSDave Jones 	struct init_on_cpu init_on_cpu;
1092bb0a56ecSDave Jones 	int rc;
1093bb0a56ecSDave Jones 
1094bb0a56ecSDave Jones 	smp_call_function_single(pol->cpu, check_supported_cpu, &rc, 1);
1095bb0a56ecSDave Jones 	if (rc)
1096bb0a56ecSDave Jones 		return -ENODEV;
1097bb0a56ecSDave Jones 
1098d5b73cd8SViresh Kumar 	data = kzalloc(sizeof(*data), GFP_KERNEL);
1099bb0a56ecSDave Jones 	if (!data) {
1100bb0a56ecSDave Jones 		printk(KERN_ERR PFX "unable to alloc powernow_k8_data");
1101bb0a56ecSDave Jones 		return -ENOMEM;
1102bb0a56ecSDave Jones 	}
1103bb0a56ecSDave Jones 
1104bb0a56ecSDave Jones 	data->cpu = pol->cpu;
1105bb0a56ecSDave Jones 
1106bb0a56ecSDave Jones 	if (powernow_k8_cpu_init_acpi(data)) {
1107bb0a56ecSDave Jones 		/*
1108bb0a56ecSDave Jones 		 * Use the PSB BIOS structure. This is only available on
1109bb0a56ecSDave Jones 		 * an UP version, and is deprecated by AMD.
1110bb0a56ecSDave Jones 		 */
1111bb0a56ecSDave Jones 		if (num_online_cpus() != 1) {
111256835e6cSBorislav Petkov 			printk_once(missing_pss_msg);
1113bb0a56ecSDave Jones 			goto err_out;
1114bb0a56ecSDave Jones 		}
1115bb0a56ecSDave Jones 		if (pol->cpu != 0) {
1116bb0a56ecSDave Jones 			printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for "
1117bb0a56ecSDave Jones 			       "CPU other than CPU0. Complain to your BIOS "
1118bb0a56ecSDave Jones 			       "vendor.\n");
1119bb0a56ecSDave Jones 			goto err_out;
1120bb0a56ecSDave Jones 		}
1121bb0a56ecSDave Jones 		rc = find_psb_table(data);
1122bb0a56ecSDave Jones 		if (rc)
1123bb0a56ecSDave Jones 			goto err_out;
1124bb0a56ecSDave Jones 
1125bb0a56ecSDave Jones 		/* Take a crude guess here.
1126bb0a56ecSDave Jones 		 * That guess was in microseconds, so multiply with 1000 */
1127bb0a56ecSDave Jones 		pol->cpuinfo.transition_latency = (
1128bb0a56ecSDave Jones 			 ((data->rvo + 8) * data->vstable * VST_UNITS_20US) +
1129bb0a56ecSDave Jones 			 ((1 << data->irt) * 30)) * 1000;
1130bb0a56ecSDave Jones 	} else /* ACPI _PSS objects available */
1131bb0a56ecSDave Jones 		pol->cpuinfo.transition_latency = get_transition_latency(data);
1132bb0a56ecSDave Jones 
1133bb0a56ecSDave Jones 	/* only run on specific CPU from here on */
1134bb0a56ecSDave Jones 	init_on_cpu.data = data;
1135bb0a56ecSDave Jones 	smp_call_function_single(data->cpu, powernowk8_cpu_init_on_cpu,
1136bb0a56ecSDave Jones 				 &init_on_cpu, 1);
1137bb0a56ecSDave Jones 	rc = init_on_cpu.rc;
1138bb0a56ecSDave Jones 	if (rc != 0)
1139bb0a56ecSDave Jones 		goto err_out_exit_acpi;
1140bb0a56ecSDave Jones 
1141bb0a56ecSDave Jones 	cpumask_copy(pol->cpus, cpu_core_mask(pol->cpu));
1142bb0a56ecSDave Jones 	data->available_cores = pol->cpus;
1143bb0a56ecSDave Jones 
1144bb0a56ecSDave Jones 	pol->cur = find_khz_freq_from_fid(data->currfid);
1145bb0a56ecSDave Jones 	pr_debug("policy current frequency %d kHz\n", pol->cur);
1146bb0a56ecSDave Jones 
1147bb0a56ecSDave Jones 	/* min/max the cpu is capable of */
1148b147405aSViresh Kumar 	if (cpufreq_table_validate_and_show(pol, data->powernow_table)) {
1149bb0a56ecSDave Jones 		printk(KERN_ERR FW_BUG PFX "invalid powernow_table\n");
1150bb0a56ecSDave Jones 		powernow_k8_cpu_exit_acpi(data);
1151bb0a56ecSDave Jones 		kfree(data->powernow_table);
1152bb0a56ecSDave Jones 		kfree(data);
1153bb0a56ecSDave Jones 		return -EINVAL;
1154bb0a56ecSDave Jones 	}
1155bb0a56ecSDave Jones 
1156bb0a56ecSDave Jones 	pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n",
1157bb0a56ecSDave Jones 		 data->currfid, data->currvid);
1158bb0a56ecSDave Jones 
1159bb0a56ecSDave Jones 	per_cpu(powernow_data, pol->cpu) = data;
1160bb0a56ecSDave Jones 
1161bb0a56ecSDave Jones 	return 0;
1162bb0a56ecSDave Jones 
1163bb0a56ecSDave Jones err_out_exit_acpi:
1164bb0a56ecSDave Jones 	powernow_k8_cpu_exit_acpi(data);
1165bb0a56ecSDave Jones 
1166bb0a56ecSDave Jones err_out:
1167bb0a56ecSDave Jones 	kfree(data);
1168bb0a56ecSDave Jones 	return -ENODEV;
1169bb0a56ecSDave Jones }
1170bb0a56ecSDave Jones 
1171c0e61cb1SBill Pemberton static int powernowk8_cpu_exit(struct cpufreq_policy *pol)
1172bb0a56ecSDave Jones {
1173bb0a56ecSDave Jones 	struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
1174bb0a56ecSDave Jones 
1175bb0a56ecSDave Jones 	if (!data)
1176bb0a56ecSDave Jones 		return -EINVAL;
1177bb0a56ecSDave Jones 
1178bb0a56ecSDave Jones 	powernow_k8_cpu_exit_acpi(data);
1179bb0a56ecSDave Jones 
1180bb0a56ecSDave Jones 	cpufreq_frequency_table_put_attr(pol->cpu);
1181bb0a56ecSDave Jones 
1182bb0a56ecSDave Jones 	kfree(data->powernow_table);
1183bb0a56ecSDave Jones 	kfree(data);
1184bb0a56ecSDave Jones 	per_cpu(powernow_data, pol->cpu) = NULL;
1185bb0a56ecSDave Jones 
1186bb0a56ecSDave Jones 	return 0;
1187bb0a56ecSDave Jones }
1188bb0a56ecSDave Jones 
1189bb0a56ecSDave Jones static void query_values_on_cpu(void *_err)
1190bb0a56ecSDave Jones {
1191bb0a56ecSDave Jones 	int *err = _err;
1192bb0a56ecSDave Jones 	struct powernow_k8_data *data = __this_cpu_read(powernow_data);
1193bb0a56ecSDave Jones 
1194bb0a56ecSDave Jones 	*err = query_current_values_with_pending_wait(data);
1195bb0a56ecSDave Jones }
1196bb0a56ecSDave Jones 
1197bb0a56ecSDave Jones static unsigned int powernowk8_get(unsigned int cpu)
1198bb0a56ecSDave Jones {
1199bb0a56ecSDave Jones 	struct powernow_k8_data *data = per_cpu(powernow_data, cpu);
1200bb0a56ecSDave Jones 	unsigned int khz = 0;
1201bb0a56ecSDave Jones 	int err;
1202bb0a56ecSDave Jones 
1203bb0a56ecSDave Jones 	if (!data)
1204bb0a56ecSDave Jones 		return 0;
1205bb0a56ecSDave Jones 
1206bb0a56ecSDave Jones 	smp_call_function_single(cpu, query_values_on_cpu, &err, true);
1207bb0a56ecSDave Jones 	if (err)
1208bb0a56ecSDave Jones 		goto out;
1209bb0a56ecSDave Jones 
1210bb0a56ecSDave Jones 	khz = find_khz_freq_from_fid(data->currfid);
1211bb0a56ecSDave Jones 
1212bb0a56ecSDave Jones 
1213bb0a56ecSDave Jones out:
1214bb0a56ecSDave Jones 	return khz;
1215bb0a56ecSDave Jones }
1216bb0a56ecSDave Jones 
1217bb0a56ecSDave Jones static struct cpufreq_driver cpufreq_amd64_driver = {
1218*d63bd27fSViresh Kumar 	.verify		= cpufreq_generic_frequency_table_verify,
1219bb0a56ecSDave Jones 	.target		= powernowk8_target,
1220bb0a56ecSDave Jones 	.bios_limit	= acpi_processor_get_bios_limit,
1221bb0a56ecSDave Jones 	.init		= powernowk8_cpu_init,
1222ce2650d4SBill Pemberton 	.exit		= powernowk8_cpu_exit,
1223bb0a56ecSDave Jones 	.get		= powernowk8_get,
1224bb0a56ecSDave Jones 	.name		= "powernow-k8",
1225*d63bd27fSViresh Kumar 	.attr		= cpufreq_generic_attr,
1226bb0a56ecSDave Jones };
1227bb0a56ecSDave Jones 
12284827ea6eSBorislav Petkov static void __request_acpi_cpufreq(void)
12294827ea6eSBorislav Petkov {
12304827ea6eSBorislav Petkov 	const char *cur_drv, *drv = "acpi-cpufreq";
12314827ea6eSBorislav Petkov 
12324827ea6eSBorislav Petkov 	cur_drv = cpufreq_get_current_driver();
12334827ea6eSBorislav Petkov 	if (!cur_drv)
12344827ea6eSBorislav Petkov 		goto request;
12354827ea6eSBorislav Petkov 
12364827ea6eSBorislav Petkov 	if (strncmp(cur_drv, drv, min_t(size_t, strlen(cur_drv), strlen(drv))))
12374827ea6eSBorislav Petkov 		pr_warn(PFX "WTF driver: %s\n", cur_drv);
12384827ea6eSBorislav Petkov 
12394827ea6eSBorislav Petkov 	return;
12404827ea6eSBorislav Petkov 
12414827ea6eSBorislav Petkov  request:
12424827ea6eSBorislav Petkov 	pr_warn(PFX "This CPU is not supported anymore, using acpi-cpufreq instead.\n");
12434827ea6eSBorislav Petkov 	request_module(drv);
12444827ea6eSBorislav Petkov }
12454827ea6eSBorislav Petkov 
1246bb0a56ecSDave Jones /* driver entry point for init */
12472760984fSPaul Gortmaker static int powernowk8_init(void)
1248bb0a56ecSDave Jones {
1249e1f0b8e9SMatthew Garrett 	unsigned int i, supported_cpus = 0;
1250c0939e46SBorislav Petkov 	int ret;
1251bb0a56ecSDave Jones 
1252e1f0b8e9SMatthew Garrett 	if (static_cpu_has(X86_FEATURE_HW_PSTATE)) {
12534827ea6eSBorislav Petkov 		__request_acpi_cpufreq();
1254e1f0b8e9SMatthew Garrett 		return -ENODEV;
1255e1f0b8e9SMatthew Garrett 	}
1256e1f0b8e9SMatthew Garrett 
1257fa8031aeSAndi Kleen 	if (!x86_match_cpu(powernow_k8_ids))
1258fa8031aeSAndi Kleen 		return -ENODEV;
1259fa8031aeSAndi Kleen 
1260c0939e46SBorislav Petkov 	get_online_cpus();
1261bb0a56ecSDave Jones 	for_each_online_cpu(i) {
1262c0939e46SBorislav Petkov 		smp_call_function_single(i, check_supported_cpu, &ret, 1);
1263c0939e46SBorislav Petkov 		if (!ret)
1264bb0a56ecSDave Jones 			supported_cpus++;
1265bb0a56ecSDave Jones 	}
1266bb0a56ecSDave Jones 
1267c0939e46SBorislav Petkov 	if (supported_cpus != num_online_cpus()) {
1268c0939e46SBorislav Petkov 		put_online_cpus();
1269bb0a56ecSDave Jones 		return -ENODEV;
1270c0939e46SBorislav Petkov 	}
1271c0939e46SBorislav Petkov 	put_online_cpus();
1272bb0a56ecSDave Jones 
1273c0939e46SBorislav Petkov 	ret = cpufreq_register_driver(&cpufreq_amd64_driver);
1274c0939e46SBorislav Petkov 	if (ret)
1275c0939e46SBorislav Petkov 		return ret;
1276a2060958SAndre Przywara 
1277a2060958SAndre Przywara 	pr_info(PFX "Found %d %s (%d cpu cores) (" VERSION ")\n",
1278c0939e46SBorislav Petkov 		num_online_nodes(), boot_cpu_data.x86_model_id, supported_cpus);
1279a2060958SAndre Przywara 
1280c0939e46SBorislav Petkov 	return ret;
1281bb0a56ecSDave Jones }
1282bb0a56ecSDave Jones 
1283bb0a56ecSDave Jones /* driver entry point for term */
1284bb0a56ecSDave Jones static void __exit powernowk8_exit(void)
1285bb0a56ecSDave Jones {
1286bb0a56ecSDave Jones 	pr_debug("exit\n");
1287bb0a56ecSDave Jones 
1288bb0a56ecSDave Jones 	cpufreq_unregister_driver(&cpufreq_amd64_driver);
1289bb0a56ecSDave Jones }
1290bb0a56ecSDave Jones 
1291bb0a56ecSDave Jones MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and "
1292bb0a56ecSDave Jones 		"Mark Langsdorf <mark.langsdorf@amd.com>");
1293bb0a56ecSDave Jones MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver.");
1294bb0a56ecSDave Jones MODULE_LICENSE("GPL");
1295bb0a56ecSDave Jones 
1296bb0a56ecSDave Jones late_initcall(powernowk8_init);
1297bb0a56ecSDave Jones module_exit(powernowk8_exit);
1298