Commit | Line | Data |
---|---|---|
800f879a AT |
1 | /* |
2 | * Copyright 2010-2017 Intel Corporation. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License, version 2, | |
6 | * as published by the Free Software Foundation. | |
7 | * | |
8 | * This program is distributed in the hope that it will be useful, | |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
11 | * General Public License for more details. | |
12 | * | |
13 | * Disclaimer: The codes contained in these modules may be specific to | |
14 | * the Intel Software Development Platform codenamed Knights Ferry, | |
15 | * and the Intel product codenamed Knights Corner, and are not backward | |
16 | * compatible with other Intel products. Additionally, Intel will NOT | |
17 | * support the codes or instruction set in future products. | |
18 | * | |
19 | * Intel offers no warranty of any kind regarding the code. This code is | |
20 | * licensed on an "AS IS" basis and Intel is not obligated to provide | |
21 | * any support, assistance, installation, training, or other services | |
22 | * of any kind. Intel is also not obligated to provide any updates, | |
23 | * enhancements or extensions. Intel specifically disclaims any warranty | |
24 | * of merchantability, non-infringement, fitness for any particular | |
25 | * purpose, and any other warranty. | |
26 | * | |
27 | * Further, Intel disclaims all liability of any kind, including but | |
28 | * not limited to liability for infringement of any proprietary rights, | |
29 | * relating to the use of the code, even if Intel is notified of the | |
30 | * possibility of such liability. Except as expressly stated in an Intel | |
31 | * license agreement provided with this code and agreed upon with Intel, | |
32 | * no license, express or implied, by estoppel or otherwise, to any | |
33 | * intellectual property rights is granted herein. | |
34 | */ | |
35 | ||
36 | /* | |
37 | * RAS MT module driver | |
38 | * | |
39 | * Code and data structures to handle get/set tasks for KnC. | |
40 | * Parties accessing the data structures are supposed to use the | |
41 | * micras_mt_tsk() routines to ensure integrity and consistency. | |
42 | * Particularly important when handling sysfs nodes and actions | |
43 | * requested from SCIF connections must use that method in order | |
44 | * to guarantee serialized access. | |
45 | * | |
46 | * Even if read-only access to latest valid data is required, | |
47 | * it should go through micras_mt_tsk() using dedicated handlers | |
48 | * in this module. | |
49 | * | |
50 | * Apologies for the messy code, but hardware support to report | |
51 | * board properties at this time (Power-On of A0) is so erratic | |
52 | * that odd ways of obtaining the info had to replace the POR | |
53 | * methods. The SMC support is sporadic, A0 has issues with SVID | |
54 | * and some SBOX registers are invalid because they depend on | |
55 | * TMU telemetry transmissions from the SMC which some reason | |
56 | * has been forgotten/missed/defeatured (does not happen). | |
57 | * | |
58 | * TBD: Once the dust settles there will be code to remove. | |
59 | * But until then, lots of #ifdef's remains. | |
60 | */ | |
61 | ||
62 | #include <linux/types.h> | |
63 | #include <linux/errno.h> | |
64 | #include <linux/kernel.h> | |
65 | #include <linux/mm.h> | |
66 | #include <linux/mm_types.h> | |
67 | #include <linux/io.h> | |
68 | #include <linux/utsname.h> | |
69 | #include <linux/sched.h> | |
70 | #include <linux/time.h> | |
71 | #include <linux/jiffies.h> | |
72 | #include <linux/kernel_stat.h> | |
73 | #include <linux/bitmap.h> | |
74 | #include <asm/mic/mic_knc/autobaseaddress.h> | |
75 | #include <asm/mic/mic_knc/micsboxdefine.h> | |
76 | #include "micras.h" | |
77 | ||
78 | ||
79 | /* | |
80 | * Persistent data accessible through the CP api. | |
81 | * Some functions just read/modify hardware CSRs | |
82 | * and thus need no storage between invocations. | |
83 | */ | |
84 | ||
85 | extern struct mr_rsp_hwinf hwinf; | |
86 | extern struct mr_rsp_vers vers; | |
87 | extern struct mr_rsp_volt volt; | |
88 | extern struct mr_rsp_freq freq; | |
89 | extern struct mr_rsp_power power; | |
90 | extern struct mr_rsp_plim plim; | |
91 | extern struct mr_rsp_gddr gddr; | |
92 | extern struct mr_rsp_gvolt gvolt; | |
93 | extern struct mr_rsp_gfreq gfreq; | |
94 | extern struct mr_rsp_temp temp; | |
95 | extern struct mr_rsp_ecc ecc; | |
96 | extern struct mr_rsp_trbo trbo; | |
97 | extern struct mr_rsp_pmcfg pmcfg; | |
98 | ||
99 | #if USE_SVID | |
100 | static uint8_t vccp_cap, vddq_cap, vddg_cap; | |
101 | static uint8_t vccp_imax, vddq_imax, vddg_imax; | |
102 | #endif | |
103 | ||
104 | uint8_t xlat_cpu[NR_CPUS]; | |
105 | ||
106 | #define FIX_DBOX 1 | |
107 | ||
108 | #if FIX_DBOX | |
109 | /* | |
110 | * Pre-emptive restoring DBOX-0 register access. | |
111 | * A glitch during clock speed changes (PM or GPU_HOT) | |
112 | * may under some rare circumstances break access to DBOX | |
113 | * registers. It is very rare, requires hours of tailored | |
114 | * simulation to reproduce, never seen in the wild (yet). | |
115 | * The gmbus controller sits in the DBOX and is affected. | |
116 | * Calling this routine prior to every gmbus read/write | |
117 | * reduces risk of hitting this bug to a single SMC register, | |
118 | * which has been deemed acceptable for B-step KnCs. | |
119 | * Only alternative is to perform repeated transaction(s) | |
120 | * until a stable result is obtained, which will be costly | |
121 | * in performance. | |
122 | */ | |
123 | static void | |
124 | mr_smc_deglitch(void) | |
125 | { | |
126 | mr_dbox_rl(0, 0x600); | |
127 | mr_dbox_rl(0, 0x2440); | |
128 | } | |
129 | #else | |
130 | #define mr_smc_deglitch(); /* As nothing */ | |
131 | #endif | |
132 | ||
133 | ||
134 | /* | |
135 | ** | |
136 | ** Conversion between CP formats (uV, MHz, etc.) | |
137 | ** and hardware register formats (SMC and VRs mostly). | |
138 | ** | |
139 | */ | |
140 | ||
141 | ||
142 | /* | |
143 | * PLL tables used to map between hw scale register | |
144 | * value and actual frequencies given a fixed base. | |
145 | * | |
146 | * The core frequency (MCLK) formula is | |
147 | * freq = Icc * (Feedback / Feedforward) | |
148 | * where | |
149 | * Icc = Frequency generated from ICC, nominal 200 MHz | |
150 | * FeedBack = ratio bits 8:1 (valid range: 8 .. 16) | |
151 | * FeedForward = ratio bits 10:9 (01 -> 4, 10 -> 2, 11 -> 1) | |
152 | * | |
153 | * The gddr frequency (PGCLK) formula is | |
154 | * freq = (X / 2) * Feedback / Feedforward | |
155 | * where | |
156 | * X = SBPLL (ICC) Table 1, FB range 10..22 | |
157 | * X = LCVCO (ICC/2) Table 2, FB range 44..65 | |
158 | * X = Bypass (ICC/2) Table 3, FB range 20..44 | |
159 | * which is why there's three gddr tables. The divide by 2 of | |
160 | * 'X' is represented as doubling the FF dividers in the tables. | |
161 | * | |
162 | * Overlapping ranges over feedback and feedforward values are | |
163 | * handled by range table(s) below such that lower frequencies | |
164 | * can be selected at a finer granularity. The tables themselves | |
165 | * do not allow overlaps, i.e. two ways to specify the same | |
166 | * PLL output frequency. | |
167 | * | |
168 | * Note that ICC clocks have their own PLL built in which uses | |
169 | * the PCI-E 100 MHz clock, adds SSC and scale it by a pair of | |
170 | * dividers. One divider is (I'm told) fixed at 40, the other | |
171 | * is fused, and none of them can be read from uOS at runtime. | |
172 | * The fused dividers are nominally 20, which is what the | |
173 | * tables below is based on. Some SKUs tweak the core ICC PLL | |
174 | * by fuses, so to counter it that divider is reported in scr #4. | |
175 | * No means to know if gddr ICC PLL gets tweaked too. | |
176 | * | |
177 | *WARNING: there are overlabs on the divider codes for GDDR PLLs, | |
178 | * which theoretically can cause false reporting of GDDR | |
179 | * device speeds (example: FB dividers 20, 21, and 22 are | |
180 | * defined both in gddr_tab1 and gddr_tab3). Currently | |
181 | * there is no way to determine which table is used. | |
182 | */ | |
183 | ||
184 | struct pll_tab { | |
185 | uint8_t clk_div; /* Feed forward */ | |
186 | uint8_t min_mul; /* Lower feedback */ | |
187 | uint8_t max_mul; /* Upper feedback */ | |
188 | uint16_t min_clk; /* Lower frequency */ | |
189 | uint16_t max_clk; /* Upper frequency */ | |
190 | uint8_t step_size; /* Granularity */ | |
191 | } cpu_tab[] = { /* CPU PLL, ICC @ ~200 MHz */ | |
192 | {1, 8, 16, 1600, 3200, 200}, | |
193 | {2, 8, 15, 800, 1500, 100}, | |
194 | {4, 8, 15, 400, 750, 50}, | |
195 | }, gddr_tab1[] = { /* GDDR PLL, ICC @ 200 MHz */ | |
196 | {2, 10, 22, 1000, 2200, 100}, | |
197 | {4, 10, 22, 500, 1100, 50}, | |
198 | {8, 10, 22, 250, 550, 25}, | |
199 | }, gddr_tab2[] = { /* GDDR PLL, LCVCO @ 100 MHz */ | |
200 | {2, 44, 65, 2200, 3250, 50}, | |
201 | }, gddr_tab3[] = { /* GDDR PLL, ICC bypass @ 100 MHz */ | |
202 | {2, 20, 44, 1000, 2200, 100}, | |
203 | {4, 20, 44, 500, 1100, 50}, | |
204 | {8, 20, 44, 250, 550, 25}, | |
205 | }; | |
206 | ||
207 | #define ICC_NOM 20 /* Nominal ICC feed back divider */ | |
208 | ||
209 | static uint16_t | |
210 | ratio2freq(uint16_t ratio, struct pll_tab * tab, int tablen, uint16_t base) | |
211 | { | |
212 | uint16_t fwd, bck; | |
213 | ||
214 | fwd = GET_BITS(10, 9, ~ratio); | |
215 | bck = GET_BITS(8, 1, ratio); | |
216 | ||
217 | if (tab == gddr_tab3 && (bck & 1)) | |
218 | return 0; | |
219 | ||
220 | if (fwd < tablen && bck >= tab[fwd].min_mul && bck <= tab[fwd].max_mul) | |
221 | return (base * bck) / tab[fwd].clk_div; | |
222 | ||
223 | return 0; | |
224 | } | |
225 | ||
226 | static uint16_t | |
227 | freq2ratio(uint16_t freq, struct pll_tab * tab, int tablen, uint16_t base) | |
228 | { | |
229 | int fwd; | |
230 | ||
231 | for(fwd = tablen - 1; fwd >= 0; fwd--) { | |
232 | if (freq >= tab[fwd].min_clk && freq <= tab[fwd].max_clk) { | |
233 | /* | |
234 | * Why bother check for accurate input? | |
235 | * Ignoring it just rounds down to nearest supported! | |
236 | */ | |
237 | if (freq % tab[fwd].step_size) | |
238 | break; | |
239 | ||
240 | return PUT_BITS(10, 9, ~fwd) | | |
241 | PUT_BITS( 8, 1, (freq * tab[fwd].clk_div) / base); | |
242 | } | |
243 | } | |
244 | ||
245 | return 0; | |
246 | } | |
247 | ||
248 | static uint32_t | |
249 | icc_fwd(void) | |
250 | { | |
251 | uint32_t scr4, div; | |
252 | ||
253 | scr4 = mr_sbox_rl(0, SBOX_SCRATCH4); | |
254 | div = GET_BITS(29, 25, scr4); | |
255 | ||
256 | return div ? div : ICC_NOM; | |
257 | } | |
258 | ||
259 | static uint32_t | |
260 | mr_mt_gf_r2f(uint16_t pll) | |
261 | { | |
262 | uint64_t freq; | |
263 | ||
264 | /* | |
265 | * As per HSD 4118175, ICC clock at 200 MHz is currently not | |
266 | * used on any SKUs, and is unlikely to be used in the future. | |
267 | * Therefore, the 100 MHz tables are searched first. | |
268 | */ | |
269 | freq = ratio2freq(pll, gddr_tab3, ARRAY_SIZE(gddr_tab3), 100); | |
270 | if (! freq) | |
271 | freq = ratio2freq(pll, gddr_tab2, ARRAY_SIZE(gddr_tab2), 100); | |
272 | if (! freq) | |
273 | freq = ratio2freq(pll, gddr_tab1, ARRAY_SIZE(gddr_tab1), 200); | |
274 | ||
275 | return 1000 * freq; | |
276 | } | |
277 | ||
278 | static uint32_t | |
279 | mr_mt_cf_r2f(uint16_t pll) | |
280 | { | |
281 | uint64_t freq; | |
282 | ||
283 | freq = ratio2freq(pll, cpu_tab, ARRAY_SIZE(cpu_tab), 200); | |
284 | ||
285 | return (1000 * freq * ICC_NOM) / icc_fwd(); | |
286 | } | |
287 | ||
288 | ||
289 | #if USE_SVID | |
290 | /* | |
291 | * VRM12 voltage converters | |
292 | * Only bits 7:0 are being used as follows: | |
293 | * Volt = Min + Res * (Bits -1) | |
294 | * Bits = 1 + (Volt - Min) / Res | |
295 | * Bits value of 0 reserved for turning VR off. | |
296 | */ | |
297 | ||
298 | #define VRM12_MAX 1520000 /* 1.52 V */ | |
299 | #define VRM12_MIN 250000 /* 250 mV */ | |
300 | #define VRM12_RES 5000 /* 5.0 mV */ | |
301 | ||
302 | static uint32_t | |
303 | svid2volt(uint8_t svid) | |
304 | { | |
305 | uint32_t bits; | |
306 | ||
307 | bits = GET_BITS(7, 0, svid); | |
308 | if (bits) | |
309 | return VRM12_MIN + VRM12_RES * (bits - 1); | |
310 | else | |
311 | return 0; | |
312 | } | |
313 | ||
314 | static uint8_t | |
315 | volt2svid(uint32_t uv) | |
316 | { | |
317 | uint32_t delta, bits; | |
318 | ||
319 | bits = 0; | |
320 | if (uv >= VRM12_MIN && uv <= VRM12_MAX) { | |
321 | delta = uv - VRM12_MIN; | |
322 | /* | |
323 | * Why bother check for accurate input? | |
324 | * Ignoring it just rounds up to nearest! | |
325 | */ | |
326 | if (! (delta % VRM12_RES)) | |
327 | bits = 1 + delta / VRM12_RES; | |
328 | } | |
329 | return PUT_BITS(7, 0, bits); | |
330 | } | |
331 | ||
332 | ||
333 | /* | |
334 | * SVID register scaling: | |
335 | * | |
336 | * Vin = SVID_REG(0x1A) <unknown> | |
337 | * Iin = SVID_REG(0x19) 1:1 A | |
338 | * Pin = SVID_REG(0x1B) 1:1 W | |
339 | * Vout = SVID_REG(0x16) / 128 V | |
340 | * Iout = SVID_REG(0x15) 1:1 A | |
341 | * Pout = SVID_REG(0x18) 1:1 W | |
342 | * Iout = (SVID_REG(0x15) / ADCmax) * (SVID_REG(0x21) A | |
343 | * Temp = SVID_REG(0x17) 1:1 C | |
344 | * | |
345 | * Note: SVID_REG(0x06) bit 7 tells Iout formula. | |
346 | * Assuming 8-bit ADC => ADCmax to be 0xff. | |
347 | * | |
348 | * Inputs are SVID register values, outputs are u{V|A|W}. | |
349 | */ | |
350 | ||
351 | static uint32_t | |
352 | vout2volt(uint8_t vout) | |
353 | { | |
354 | /* | |
355 | * Linear range from 0 to 2 volt | |
356 | */ | |
357 | return (((uint32_t) vout) * 1000000) / 128; | |
358 | } | |
359 | ||
360 | static uint32_t | |
361 | vin2volt(uint8_t vin) | |
362 | { | |
363 | /* | |
364 | * Formula not known. | |
365 | */ | |
366 | return (((uint32_t) vin) * 1000000) / 128; | |
367 | } | |
368 | ||
369 | static uint32_t | |
370 | one2one(uint8_t in) | |
371 | { | |
372 | return ((uint32_t) in) * 1000000; | |
373 | } | |
374 | ||
375 | static uint32_t | |
376 | iout2amp(uint8_t iout, uint8_t cap, uint8_t imax) | |
377 | { | |
378 | if (GET_BITS(7, 7, cap)) | |
379 | return (((uint32_t) iout) * ((uint32_t) imax) * 1000000) / 256; | |
380 | else | |
381 | return one2one(iout); | |
382 | } | |
383 | ||
384 | #define iin2amp(iin) one2one(iin) | |
385 | #define pin2watt(pin) one2one(pin) | |
386 | #define pout2watt(pout) one2one(pout) | |
387 | ||
388 | ||
389 | ||
390 | /* | |
391 | ** | |
392 | ** Simple SVIDCONTROL interface. | |
393 | ** | |
394 | ** 0 Parity bit out | |
395 | ** 8:1 SVID data out | |
396 | ** 13:9 SVID command | |
397 | ** 17:14 SVID address | |
398 | ** 18 Parity bit in (if any) | |
399 | ** 26:19 SVID data in (if any) | |
400 | ** 27 ACK #0 | |
401 | ** 28 ACK #1 | |
402 | ** 29 SVID Error | |
403 | ** 30 CTL Idle | |
404 | ** 31 CMD Start | |
405 | ** | |
406 | ** See SBOX HAS for more details. | |
407 | ** One transaction is expected to finish | |
408 | ** in less than 2 uSec (15.625 MHz clock) | |
409 | ** and busy waiting here should be OK. | |
410 | ** | |
411 | ** Return values: | |
412 | ** 0 OK | |
413 | ** 1-7 Controller bits 29:27 | |
414 | ** 8 Parameter error (invalid device or opcode) | |
415 | ** | |
416 | */ | |
417 | ||
418 | /* | |
419 | * SVID command set | |
420 | * Source: SVID Protocol rev 1.5 | |
421 | */ | |
422 | #define VR12Cmd_Extend 0x00 /* Req */ | |
423 | #define VR12Cmd_SetVID_Fast 0x01 /* Req */ | |
424 | #define VR12Cmd_SetVID_Slow 0x02 /* Req */ | |
425 | #define VR12Cmd_SetVID_Decay 0x03 /* Req */ | |
426 | #define VR12Cmd_SetPS 0x04 /* Req */ | |
427 | #define VR12Cmd_SetRegADR 0x05 /* Req */ | |
428 | #define VR12Cmd_SetRegDAT 0x06 /* Req */ | |
429 | #define VR12Cmd_GetReg 0x07 /* Req */ | |
430 | #define VR12Cmd_TestMode 0x08 /* Req */ | |
431 | ||
432 | /* | |
433 | * SVID registers of interest | |
434 | * Source: SVID Protocol rev 1.5 | |
435 | * | |
436 | * Notes on the capability register: | |
437 | * bit 0 Iout (0x15) | |
438 | * bit 1 Vout (0x16) | |
439 | * bit 2 Pout (0x18) | |
440 | * bit 3 Iin (0x19) | |
441 | * bit 4 Vin (0x1a) | |
442 | * bit 5 Pin (0x1b) | |
443 | * bit 6 Temp (0x17) | |
444 | * bit 7 Iout format of register 0x15 | |
445 | * 0 -> value in Amps | |
446 | * 1 -> value scaled to Icc_Max | |
447 | */ | |
448 | ||
449 | #define VR12Reg_VendorID 0x00 /* Req */ | |
450 | #define VR12Reg_ProductID 0x01 /* Req */ | |
451 | #define VR12Reg_ProductRev 0x02 /* Req */ | |
452 | #define VR12Reg_ProductDate 0x03 /* Opt */ | |
453 | #define VR12Reg_LotCode 0x04 /* Opt */ | |
454 | #define VR12Reg_ProtocolID 0x05 /* Req */ | |
455 | #define VR12Reg_Capability 0x06 /* Req */ | |
456 | #define VR12Reg_Iout 0x15 /* Req */ | |
457 | #define VR12Reg_Vout 0x16 /* Opt */ | |
458 | #define VR12Reg_Temp 0x17 /* Opt */ | |
459 | #define VR12Reg_Pout 0x18 /* Opt */ | |
460 | #define VR12Reg_Iin 0x19 /* Opt */ | |
461 | #define VR12Reg_Vin 0x1a /* Opt */ | |
462 | #define VR12Reg_Pin 0x1b /* Opt */ | |
463 | #define VR12Reg_Icc_Max 0x21 /* Req */ | |
464 | #define VR12Reg_Temp_Max 0x22 /* Req */ | |
465 | #define VR12Reg_Vout_Max 0x30 /* Req */ | |
466 | #define VR12Reg_VID_Set 0x31 /* Req */ | |
467 | ||
468 | /* | |
469 | * SVID addresses on KnC | |
470 | */ | |
471 | #define SVID_VCCP 0x0 /* Core rail */ | |
472 | #define SVID_VDDQ 0x2 /* Memory rail (1st loop) */ | |
473 | #define SVID_VDDG 0x3 /* Uncore rail (2nd loop) */ | |
474 | ||
475 | static DEFINE_SPINLOCK(svidcontrol_lock); | |
476 | ||
477 | static int | |
478 | SvidCmd(uint8_t dev, uint8_t op, uint8_t in) | |
479 | { | |
480 | uint32_t cmd, ret, err; | |
481 | ||
482 | /* | |
483 | * The SVID Controller does not work in A0 (HSD 3498464) | |
484 | * Pretend success, but return 0 always | |
485 | */ | |
486 | return 0; | |
487 | ||
488 | /* | |
489 | * For now just check that command can be contructed. | |
490 | * | |
491 | *TBD: Add stricter parameter check? | |
492 | */ | |
493 | if (dev > GET_BITS(17, 14, ~0) || | |
494 | op > GET_BITS(13, 9, ~0)) | |
495 | return -MR_ERR_SMC; | |
496 | ||
497 | /* | |
498 | * Craft 18 bit command with even parity | |
499 | */ | |
500 | cmd = PUT_BITS( 8, 1, in) | | |
501 | PUT_BITS(13, 9, op) | | |
502 | PUT_BITS(17, 14, dev); | |
503 | if (bitmap_weight((unsigned long *) &cmd, 18) & 1) | |
504 | cmd |= 1; | |
505 | ||
506 | /* | |
507 | * Wait until controller in idle state, | |
508 | * write command + start bit and then | |
509 | * wait for controller to be idle again. | |
510 | */ | |
511 | spin_lock(&svidcontrol_lock); | |
512 | for( ;; ) { | |
513 | ret = mr_sbox_rl(0, SBOX_SVIDCONTROL); | |
514 | if (GET_BITS(31, 30, ret) == 0x1) | |
515 | break; | |
516 | } | |
517 | mr_sbox_wl(0, SBOX_SVIDCONTROL, cmd | PUT_BIT(31, 1)); | |
518 | for( ;; ) { | |
519 | ret = mr_sbox_rl(0, SBOX_SVIDCONTROL); | |
520 | if (GET_BITS(31, 30, ret) == 0x1) | |
521 | break; | |
522 | } | |
523 | spin_lock(&svidcontrol_lock); | |
524 | ||
525 | /* | |
526 | * Report command status | |
527 | * Only if SVID_Error = 0, Ack #1 = 1, and Ack #0 = 0 | |
528 | * did we have a successful transfer, and have data | |
529 | * to return (SBOX HAS table 9). | |
530 | */ | |
531 | err = GET_BITS(29, 27, ret); | |
532 | return (err == 0x2) ? GET_BITS(26, 19, ret) : -MR_ERR_SMC; | |
533 | } | |
534 | #endif | |
535 | ||
536 | ||
537 | ||
538 | /* | |
539 | ** | |
540 | ** SMC API | |
541 | ** | |
542 | ** See "Knights Corner System Managment Architecture Specification" | |
543 | ** for details on the SMC internals and supported APIs. | |
544 | ** | |
545 | ** This module is based on rev 0.31 | |
546 | ** | |
547 | */ | |
548 | ||
549 | #define MR_SMC_ADDR 0x28 /* SMC DVO-B Slave address */ | |
550 | ||
551 | #define MR_SMC_PCI_VID 0x00 /* PCI Vendor ID, 4 */ | |
552 | #define MR_SMC_PCI_DID 0x02 /* PCI Device ID, 4 */ | |
553 | #define MR_SMC_PCI_BCC 0x04 /* PCI Base Class Code, 4 */ | |
554 | #define MR_SMC_PCI_SCC 0x05 /* PCI Sub Class Code, 4 */ | |
555 | #define MR_SMC_PCI_PI 0x06 /* PCI Programming Interface, 4 */ | |
556 | #define MR_SMC_PCI_SMBA 0x07 /* PCI MBus Manageability Address, 4 */ | |
557 | #define MR_SMC_UUID 0x10 /* Universally Unique Identification, 16 */ | |
558 | #define MR_SMC_FW_VERSION 0x11 /* SMC Firmware Version, 4 */ | |
559 | #define MR_SMC_EXE_DOMAIN 0x12 /* SMC Execution Domain, 4 */ | |
560 | #define MR_SMC_STS_SELFTEST 0x13 /* SMC Self-Test Results, 4 */ | |
561 | #define MR_SMC_HW_REVISION 0x14 /* SMC Hardware Revision, 4 */ | |
562 | #define MR_SMC_SERIAL 0x15 /* Card serial number, 12 */ | |
563 | #define MR_SMC_SMB_RESTRT 0x17 /* Restart SMBus addr negotiation, 4 */ | |
564 | ||
565 | #define MR_SMC_CPU_POST 0x1a /* POST Register, 4 */ | |
566 | #define MR_SMC_ZOMBIE 0x1b /* Zombie Mode Enable, 4 */ | |
567 | #define MR_SMC_CPU_ID 0x1c /* CPU Identifier, 4 */ | |
568 | ||
569 | #define MR_SMC_SEL_ENTRY_SEL 0x20 /* SEL Entry Selection Register, 4 */ | |
570 | #define MR_SMC_SEL_DATA 0x21 /* SEL Data register, <N> */ | |
571 | #define MR_SMC_SDR_ENTRY_SEL 0x22 /* SDR Entry Selection Register, 4 */ | |
572 | #define MR_SMC_SDR_DATA 0x23 /* SDR Data register, <N> */ | |
573 | ||
574 | #define MR_SMC_PWR_PCIE 0x28 /* PCIe Power Reading, 4 */ | |
575 | #define MR_SMC_PWR_2X3 0x29 /* 2x3 Power Reading, 4 */ | |
576 | #define MR_SMC_PWR_2X4 0x2a /* 2x4 Power Reading, 4 */ | |
577 | #define MR_SMC_FORCE_TTL 0x2b /* Forced Throttle, 4 */ | |
578 | #define MR_SMC_PWR_LIM_0 0x2c /* Power Limit 0, 4 */ | |
579 | #define MR_SMC_TIME_WIN_0 0x2d /* Time Window 0, 4 */ | |
580 | #define MR_SMC_PWR_LIM0_GRD 0x2e /* Power Limit 0 Guardband, 4 */ | |
581 | #define MR_SMC_PWR_LIM_1 0x2f /* Power Limit 1, 4 */ | |
582 | #define MR_SMC_TIME_WIN_1 0x30 /* Time Window 1, 4 */ | |
583 | #define MR_SMC_INCL_3V3 0x31 /* Include 3.3 V, 4 */ | |
584 | #define MR_SMC_PWR_LIM_PERS 0x32 /* Power Limit Persistence, 4 */ | |
585 | #define MR_SMC_CLAMP_MODE 0x33 /* Clamp Mode, 4 */ | |
586 | #define MR_SMC_ENERGY_STS_0 0x34 /* Energy Status 0, 4 */ | |
587 | #define MR_SMC_AVG_PWR_0 0x35 /* Average Power 0, 4 */ | |
588 | #define MR_SMC_AVG_PWR_1 0x36 /* Average Power 1, 4 */ | |
589 | #define MR_SMC_MIN_PWR 0x37 /* Min Power, 4 */ | |
590 | #define MR_SMC_PWR_TTL_DUR 0x38 /* Power Throttle Duration, 4 */ | |
591 | #define MR_SMC_PWR_TTL 0x39 /* Power Throttling, 4 */ | |
592 | #define MR_SMC_PWR_INST 0x3a /* Instantaneous Power Reading, 4 */ | |
593 | #define MR_SMC_PWR_IMAX 0x3b /* Maximum Power Reading, 4 */ | |
594 | #define MR_SMC_VOLT_VCCP 0x3c /* VCCP VR Output Voltage, 4 */ | |
595 | #define MR_SMC_VOLT_VDDQ 0x3d /* VDDQ VR Output Voltage, 4 */ | |
596 | #define MR_SMC_VOLT_VDDG 0x3e /* VDDG VR Output Voltage, 4 */ | |
597 | ||
598 | #define MR_SMC_TEMP_CPU 0x40 /* CPU DIE Temperature, 4 */ | |
599 | #define MR_SMC_TEMP_EXHAUST 0x41 /* Card Exhaust Temperature, 4 */ | |
600 | #define MR_SMC_TEMP_INLET 0x42 /* Card Inlet Temperature, 4 */ | |
601 | #define MR_SMC_TEMP_VCCP 0x43 /* VCCP VR Temperature, 4 */ | |
602 | #define MR_SMC_TEMP_VDDG 0x44 /* VDDG VR Temperature, 4 */ | |
603 | #define MR_SMC_TEMP_VDDQ 0x45 /* VDDQ VR Temperature, 4 */ | |
604 | #define MR_SMC_TEMP_GDDR 0x46 /* GDDR Temperature, 4 */ | |
605 | #define MR_SMC_TEMP_EAST 0x47 /* East Temperature, 4 */ | |
606 | #define MR_SMC_TEMP_WEST 0x48 /* West Temperature, 4 */ | |
607 | #define MR_SMC_FAN_TACH 0x49 /* Fan RPM, 4 */ | |
608 | #define MR_SMC_FAN_PWM 0x4a /* Fan PWM Percent, 4 */ | |
609 | #define MR_SMC_FAN_PWM_ADD 0x4b /* Fan PWM Adder, 4 */ | |
610 | #define MR_SMC_TCRITICAL 0x4c /* KNC Tcritical temperature, 4 */ | |
611 | #define MR_SMC_TCONTROL 0x4d /* KNC Tcontrol temperature, 4 */ | |
612 | #define MR_SMC_TRM_TTL_DUR 0x4e /* Thermal Throttle Duration, 4 */ | |
613 | #define MR_SMC_TRM_TTL 0x4f /* Thermal Throttling, 4 */ | |
614 | #define MR_SMC_TRM_PUSH 0x50 /* Target for die temp push, 4 */ | |
615 | ||
616 | #define MR_SMC_PWR_VCCP 0x58 /* VCCP VR Output Power, 4 */ | |
617 | #define MR_SMC_PWR_VDDQ 0x59 /* VDDQ VR Output Power, 4 */ | |
618 | #define MR_SMC_PWR_VDDG 0x5a /* VDDG VR Output Power, 4 */ | |
619 | ||
620 | #define MR_SMC_LED_CODE 0x60 /* LED blink code, 4 */ | |
621 | ||
622 | ||
623 | /* | |
624 | * Simple I/O access routines for most SMC registers. | |
625 | * All but UUID & SERIAL are 4 bytes in size. | |
626 | */ | |
627 | #define SMC_TRACK 0 | |
628 | ||
629 | #if SMC_TRACK | |
630 | #define RL printk("%s: %2x -> %08x, rtn %d\n", __FUNCTION__, reg, *val, rl) | |
631 | #define WL printk("%s: %2x <- %08x, rtn %d\n", __FUNCTION__, reg, *val, rl) | |
632 | #else | |
633 | #define RL /* As nothing */ | |
634 | #define WL /* As nothing */ | |
635 | #endif | |
636 | ||
637 | #ifdef MIC_IS_EMULATION | |
638 | /* | |
639 | * Emulation does not handle I2C busses. | |
640 | * Therefore all code that deals with I2C needs to be | |
641 | * replaced with harmless substitutes in emulation. | |
642 | * The following stubs are for emulation only. | |
643 | */ | |
644 | int | |
645 | gmbus_i2c_read(uint8_t d, uint8_t a, uint8_t r, uint8_t * v, uint16_t l) | |
646 | { | |
647 | if (v && l) | |
648 | memset(v, 0, l); | |
649 | return l; | |
650 | } | |
651 | ||
652 | int | |
653 | gmbus_i2c_write(uint8_t d, uint8_t a, uint8_t r, uint8_t * v, uint16_t l) | |
654 | { | |
655 | return l; | |
656 | } | |
657 | #endif /* EMULATION */ | |
658 | ||
659 | static char * | |
660 | gm_err(int err) | |
661 | { | |
662 | char * str = "unknown"; | |
663 | ||
664 | switch(err) { | |
665 | case -1: str = "timeout"; break; | |
666 | case -2: str = "ack timeout"; break; | |
667 | case -3: str = "interrupted"; break; | |
668 | case -4: str = "invalid command"; break; | |
669 | } | |
670 | ||
671 | return str; | |
672 | } | |
673 | ||
674 | ||
675 | int | |
676 | mr_smc_rd(uint8_t reg, uint32_t * val) | |
677 | { | |
678 | int rl; | |
679 | ||
680 | mr_smc_deglitch(); | |
681 | rl = gmbus_i2c_read(2, MR_SMC_ADDR, reg, (uint8_t *) val, sizeof(*val)); | |
682 | RL; | |
683 | if (rl == sizeof(uint32_t)) | |
684 | return 0; | |
685 | ||
686 | /* | |
687 | * Something failed, do a dummy read to get I2C bus in a known good state. | |
688 | *TBD: Do retries, and if so how many? | |
689 | */ | |
690 | printk("smc_rd: error %d (%s), reg %02x\n", rl, gm_err(rl), reg); | |
691 | mr_smc_deglitch(); | |
692 | gmbus_i2c_read(2, MR_SMC_ADDR, MR_SMC_FW_VERSION, (uint8_t *) &rl, sizeof(rl)); | |
693 | *val = 0; | |
694 | return 1; | |
695 | } | |
696 | ||
697 | int | |
698 | mr_smc_wr(uint8_t reg, uint32_t * val) | |
699 | { | |
700 | int rl; | |
701 | ||
702 | WL; | |
703 | mr_smc_deglitch(); | |
704 | rl = gmbus_i2c_write(2, MR_SMC_ADDR, reg, (uint8_t *) val, sizeof(*val)); | |
705 | if (rl == sizeof(uint32_t)) | |
706 | return 0; | |
707 | ||
708 | /* | |
709 | * Something failed, do a dummy read to get I2C bus in a known good state. | |
710 | *TBD: Do retries, and if so how many? | |
711 | */ | |
712 | printk("smc_wr: error %d (%s), reg %02x\n", rl, gm_err(rl), reg); | |
713 | mr_smc_deglitch(); | |
714 | gmbus_i2c_read(2, MR_SMC_ADDR, MR_SMC_FW_VERSION, (uint8_t *) &rl, sizeof(rl)); | |
715 | return 0; | |
716 | } | |
717 | #undef RL | |
718 | #undef WL | |
719 | ||
720 | ||
721 | /* | |
722 | * Bypass for SMC access. | |
723 | * Kind of a backdoor really as it allows for raw access to the SMC which | |
724 | * may be device dependent and vary significantly between SMC firmware | |
725 | * revisions. This is intended for host side tools that (hopefully) know | |
726 | * what they are receiving through this interface. There is a 'set' command | |
727 | * too, which we screen heavily since the SMC controls board cooling and | |
728 | * therefore is critical for the cards safe operation envolope. | |
729 | */ | |
730 | ||
731 | int | |
732 | mr_get_smc(void * p) | |
733 | { | |
734 | int rtn; | |
735 | uint32_t parm; | |
736 | struct mr_rsp_smc * r; | |
737 | ||
738 | parm = * (uint32_t *) p; | |
739 | if (GET_BITS(31, 8, parm)) | |
740 | return -MR_ERR_RANGE; | |
741 | r = (struct mr_rsp_smc *) p; | |
742 | ||
743 | r->reg = GET_BITS(7, 0, parm); | |
744 | ||
745 | /* | |
746 | * These cannot be read by anybody | |
747 | */ | |
748 | if (r->reg > MR_SMC_LED_CODE || | |
749 | r->reg == MR_SMC_ZOMBIE) | |
750 | return -MR_ERR_PERM; | |
751 | ||
752 | /* | |
753 | * These can only be read by root | |
754 | */ | |
755 | if (! micras_priv) | |
756 | switch(r->reg) { | |
757 | case MR_SMC_SEL_ENTRY_SEL: | |
758 | case MR_SMC_SEL_DATA: | |
759 | case MR_SMC_SDR_ENTRY_SEL: | |
760 | case MR_SMC_SDR_DATA: | |
761 | return -MR_ERR_PERM; | |
762 | } | |
763 | ||
764 | /* | |
765 | * Determine how wide the SMC register is | |
766 | */ | |
767 | switch(r->reg) { | |
768 | case MR_SMC_UUID: | |
769 | r->width = 16; | |
770 | break; | |
771 | case MR_SMC_SERIAL: | |
772 | r->width = 12; | |
773 | break; | |
774 | default: | |
775 | r->width = 4; | |
776 | } | |
777 | ||
778 | mr_smc_deglitch(); | |
779 | rtn = gmbus_i2c_read(2, MR_SMC_ADDR, r->reg, (uint8_t *) &r->rtn, r->width); | |
780 | #if SMC_TRACK | |
781 | printk("%s: %2x -> %08x, rtn %d\n", __FUNCTION__, r->reg, r->rtn.val, rtn); | |
782 | #endif | |
783 | if (rtn != r->width) { | |
784 | /* | |
785 | * Failed once, try one more time | |
786 | *TBD: insert a known good read before the actual retry? | |
787 | */ | |
788 | mr_smc_deglitch(); | |
789 | rtn = gmbus_i2c_read(2, MR_SMC_ADDR, r->reg, (uint8_t *) &r->rtn, r->width); | |
790 | #if SMC_TRACK | |
791 | printk("%s: %2x -> %08x, rtn %d\n", __FUNCTION__, r->reg, r->rtn.val, rtn); | |
792 | #endif | |
793 | ||
794 | if (r->reg == MR_SMC_SERIAL) { | |
795 | memcpy((uint8_t *) &r->rtn, hwinf.serial, r->width); | |
796 | rtn = r->width; | |
797 | } | |
798 | } | |
799 | ||
800 | if (rtn != r->width) | |
801 | return -MR_ERR_SMC; | |
802 | ||
803 | return sizeof(*r); | |
804 | } | |
805 | ||
806 | ||
807 | int | |
808 | mr_set_smc(void * p) | |
809 | { | |
810 | uint8_t reg; | |
811 | uint16_t width; | |
812 | int rtn; | |
813 | uint32_t val, parm; | |
814 | ||
815 | parm = * (uint32_t *) p; | |
816 | reg = GET_BITS(31, 24, parm); | |
817 | ||
818 | /* | |
819 | * Screen for registers we allow setting. | |
820 | * POST register is accessible to everyone, | |
821 | * only root can 'SET' anything beyond that. | |
822 | */ | |
823 | if (micras_priv) { | |
824 | switch (reg) { | |
825 | case MR_SMC_CPU_POST: | |
826 | case MR_SMC_SEL_ENTRY_SEL: | |
827 | case MR_SMC_SDR_ENTRY_SEL: | |
828 | case MR_SMC_SMB_RESTRT: | |
829 | case MR_SMC_FORCE_TTL: | |
830 | case MR_SMC_PWR_LIM_0: | |
831 | case MR_SMC_TIME_WIN_0: | |
832 | case MR_SMC_PWR_LIM_1: | |
833 | case MR_SMC_TIME_WIN_1: | |
834 | case MR_SMC_INCL_3V3: | |
835 | case MR_SMC_PWR_LIM_PERS: | |
836 | case MR_SMC_CLAMP_MODE: | |
837 | case MR_SMC_FAN_PWM_ADD: | |
838 | case MR_SMC_LED_CODE: | |
839 | break; | |
840 | default: | |
841 | return -MR_ERR_PERM; | |
842 | } | |
843 | } | |
844 | else { | |
845 | switch (reg) { | |
846 | case MR_SMC_CPU_POST: | |
847 | break; | |
848 | default: | |
849 | return -MR_ERR_PERM; | |
850 | } | |
851 | } | |
852 | ||
853 | /* | |
854 | * Screen against known SMC register widths. | |
855 | * We insist that unused upper bits are zeros | |
856 | */ | |
857 | switch (reg) { | |
858 | case MR_SMC_SEL_ENTRY_SEL: | |
859 | case MR_SMC_SDR_ENTRY_SEL: | |
860 | case MR_SMC_FAN_PWM_ADD: | |
861 | val = GET_BITS(7, 0, parm); /* 8-bit registers */ | |
862 | break; | |
863 | case MR_SMC_PWR_LIM_0: | |
864 | case MR_SMC_TIME_WIN_0: | |
865 | case MR_SMC_PWR_LIM_1: | |
866 | case MR_SMC_TIME_WIN_1: | |
867 | val = GET_BITS(15, 0, parm); /* 16 bit registers */ | |
868 | break; | |
869 | case MR_SMC_CPU_POST: | |
870 | val = GET_BITS(23, 0, parm); /* 24 bit registers */ | |
871 | break; | |
872 | default: | |
873 | val = GET_BIT(0, parm); /* Booleans */ | |
874 | } | |
875 | if (val != GET_BITS(23, 0, parm)) | |
876 | return -MR_ERR_INVAUX; | |
877 | ||
878 | width = 4; | |
879 | mr_smc_deglitch(); | |
880 | rtn = gmbus_i2c_write(2, MR_SMC_ADDR, reg, (uint8_t *) & val, width); | |
881 | #if SMC_TRACK | |
882 | printk("%s: %2x <- %08x, rtn %d\n", __FUNCTION__, reg, val, rtn); | |
883 | #endif | |
884 | if (rtn != width) | |
885 | return -MR_ERR_SMC; | |
886 | ||
887 | return 0; | |
888 | } | |
889 | ||
890 | ||
891 | /* | |
892 | * IPMI interface. | |
893 | * The SMC has a connection to the host's board management software, which | |
894 | * usually resides in a dedicated Board Management Controller, of which the | |
895 | * SMC is supposed to be a registered satellite controller (aka. additional | |
896 | * management controller). As such the SMC can receive controls originating | |
897 | * from any valid IPMI session on things like power limits, but it can also | |
898 | * add events to the non-volatile IPMI System Events Log for things like | |
899 | * reporting catastrophic failures that otherwise might be lost because the | |
900 | * main processors might be disabled (section 1.7.6 in IPMI spec 2.0 E5). | |
901 | * In RAS context we'd want to let the SM know if fatal MC events occur | |
902 | * and possibly also if the uOS crashes, such that remote management can | |
903 | * be alerted via standard IPMI mechanisms. | |
904 | * | |
905 | * Input to this routine is an MceInfo record and an 'in-exception context' | |
906 | * flag. It is still TBD what exactly to tell the SMC, but it is expected | |
907 | * that all relevant info is in the MceInfo record. | |
908 | */ | |
909 | ||
910 | void | |
911 | micras_mc_ipmi(struct mce_info * mc, int ctx) | |
912 | { | |
913 | } | |
914 | ||
915 | ||
916 | #if !(USE_SVID || USE_SMC) | |
917 | /* | |
918 | * Board voltage sense converter | |
919 | * Two 10 bit read-outs from SBOX register 0x1038. | |
920 | * The format is very poorly documented, so no | |
921 | * warranty on this conversion. Assumption is | |
922 | * the reading is a binary fixed point number. | |
923 | * bit 15 Valid reading if set | |
924 | * bit 9:8 2 bit integer part | |
925 | * bit 7:0 8 bit fraction part | |
926 | * Return value is 0 (invalid) or voltage i uV. | |
927 | */ | |
928 | ||
929 | uint32_t | |
930 | bvs2volt(uint16_t sense) | |
931 | { | |
932 | uint32_t res, f, msk; | |
933 | ||
934 | if (! GET_BIT(15, sense)) | |
935 | return 0; | |
936 | ||
937 | /* | |
938 | * First get integer contribution | |
939 | * Then accumulate fraction contributions. | |
940 | * Divide and add fraction if corresponding bit set. | |
941 | */ | |
942 | res = 1000000 * GET_BITS(9, 8, sense); | |
943 | for(msk = (1 << 7), f = 1000000/2; msk && f; msk >>= 1, f >>= 1) | |
944 | if (sense & msk) | |
945 | res += f; | |
946 | ||
947 | return res; | |
948 | } | |
949 | #endif | |
950 | ||
951 | ||
952 | ||
953 | /* | |
954 | ** | |
955 | ** Initializations | |
956 | ** | |
957 | ** This has two intended purposes: | |
958 | ** - Do a on-time effort to collect info on properties that | |
959 | ** are not going to change after the initial setup by | |
960 | ** either bootstrap or kernel initialization. | |
961 | ** - Collect initial values on things we can modify. | |
962 | ** Intent is that unloading the ras module should reset | |
963 | ** all state to that of the time the module was loaded. | |
964 | ** | |
965 | */ | |
966 | ||
967 | ||
968 | /* | |
969 | *TBD: substitute with official defines when availble. | |
970 | */ | |
971 | #define KNC_FLASH_TAB 0x0FFF76000 /* Yes, it's below 4GB */ | |
972 | #define KNC_FLASH_FILT 0x400 /* Correctable MC event filter */ | |
973 | #define KNC_FLASH_BASE 0x0FFFA8000 /* Yes, it's below 4GB */ | |
974 | #define KNC_FLASH_SIZE 0x2000 /* 8 KB according to Scott */ | |
975 | #define KNC_FLASH_BOOT1 0x1274 /* Fboot1 version string */ | |
976 | #define KNC_FLASH_BOOTB 0x02b8 /* Fboot1 backup version string */ | |
977 | #define KNC_MP_PHYS 0x9e000 /* Location of MP table */ | |
978 | #define KNC_MPF_SIG 0xa0afb2a0 /* String "_PM_" inverted */ | |
979 | #define KNC_MPC_SIG 0x504d4350 /* String "PCMP" */ | |
980 | ||
981 | static void | |
982 | get_cpu_table(void) | |
983 | { | |
984 | struct mpf_intel * mpf; | |
985 | struct mpc_table * mpc; | |
986 | struct mpc_cpu * mpp; | |
987 | uint8_t * ptr, * ep; | |
988 | ||
989 | mpf = phys_to_virt((phys_addr_t) KNC_MP_PHYS); | |
990 | if (mpf) { | |
991 | if (*((uint32_t *) mpf->signature) != KNC_MPF_SIG) { | |
992 | printk("MP FP signature not found, %02x %02x %02x %02x\n", | |
993 | mpf->signature[0], mpf->signature[1], | |
994 | mpf->signature[2], mpf->signature[3]); | |
995 | return; | |
996 | } | |
997 | mpc = phys_to_virt((phys_addr_t) mpf->physptr); | |
998 | if (mpc) { | |
999 | if (*((uint32_t *) mpc->signature) != KNC_MPC_SIG) { | |
1000 | printk("MP header signature not found, %02x %02x %02x %02x\n", | |
1001 | mpc->signature[0], mpc->signature[1], | |
1002 | mpc->signature[2], mpc->signature[3]); | |
1003 | return; | |
1004 | } | |
1005 | ptr = (uint8_t *)(mpc + 1); | |
1006 | ep = ptr + mpc->length; | |
1007 | while(ptr < ep) { | |
1008 | switch(*ptr) { | |
1009 | case 0x00: /* CPU */ | |
1010 | mpp = (struct mpc_cpu *) ptr; | |
1011 | if (GET_BIT(0, mpp->cpuflag) && mpp->apicid < nr_cpu_ids) | |
1012 | xlat_cpu[mpp->apicid] = GET_BITS(7, 0, mpp->reserved[1]); | |
1013 | ptr += 20; | |
1014 | break; | |
1015 | case 0x01: /* BUS */ | |
1016 | ptr += 8; | |
1017 | break; | |
1018 | case 0x02: /* I/O-APIC */ | |
1019 | ptr += 8; | |
1020 | break; | |
1021 | case 0x03: /* INT source */ | |
1022 | ptr += 8; | |
1023 | break; | |
1024 | case 0x04: /* LINT source */ | |
1025 | ptr += 8; | |
1026 | break; | |
1027 | default: /* Table out of spec */ | |
1028 | ptr = ep; | |
1029 | } | |
1030 | } | |
1031 | } | |
1032 | #if 0 | |
1033 | { | |
1034 | uint32_t eax, ebx, ecx, edx; | |
1035 | uint32_t hwt, i; | |
1036 | ||
1037 | cpuid(1, &eax, &ebx, &ecx, &edx); | |
1038 | hwt = GET_BITS(23, 16, ebx); | |
1039 | if (hwt > nr_cpu_ids) | |
1040 | hwt = nr_cpu_ids; | |
1041 | printk("RAS.card: CPU thread table:\n"); | |
1042 | for(i=0; i < hwt; i++) | |
1043 | printk(" cpu %d -> thr %d\n", i, xlat_cpu[i]); | |
1044 | } | |
1045 | #endif | |
1046 | } | |
1047 | } | |
1048 | ||
1049 | ||
1050 | static void __init | |
1051 | mr_mk_cf_lst(void) | |
1052 | { | |
1053 | int i, n; | |
1054 | uint16_t f; | |
1055 | ||
1056 | /* | |
1057 | * If PM module interface is in place, then the | |
1058 | * core voltage list may already be populated. | |
1059 | */ | |
1060 | if (freq.supt[0] && freq.slen) | |
1061 | return; | |
1062 | ||
1063 | n = 0; | |
1064 | for(i = ARRAY_SIZE(cpu_tab) -1; i >= 0; i--) { | |
1065 | for(f = cpu_tab[i].min_clk; | |
1066 | f <= cpu_tab[i].max_clk; | |
1067 | f += cpu_tab[i].step_size) { | |
1068 | freq.supt[n] = 1000 * f; | |
1069 | freq.slen = ++n; | |
1070 | if (n >= MR_PTAB_LEN) | |
1071 | return; | |
1072 | } | |
1073 | } | |
1074 | } | |
1075 | ||
1076 | static void __init | |
1077 | mr_mk_gf_lst(void) | |
1078 | { | |
1079 | int i, n; | |
1080 | uint16_t f; | |
1081 | ||
1082 | n = 0; | |
1083 | for(i = ARRAY_SIZE(gddr_tab1) -1; i >= 0; i--) { | |
1084 | for(f = gddr_tab1[i].min_clk; | |
1085 | f <= gddr_tab1[i].max_clk; | |
1086 | f += gddr_tab1[i].step_size) { | |
1087 | gfreq.supt[n] = 1000 * f; | |
1088 | gfreq.slen = ++n; | |
1089 | if (n == MR_PTAB_LEN) | |
1090 | return; | |
1091 | } | |
1092 | } | |
1093 | for(i = ARRAY_SIZE(gddr_tab2) -1; i >= 0; i--) { | |
1094 | for(f = gddr_tab2[i].min_clk; | |
1095 | f <= gddr_tab2[i].max_clk; | |
1096 | f += gddr_tab2[i].step_size) { | |
1097 | gfreq.supt[n] = 1000 * f; | |
1098 | gfreq.slen = ++n; | |
1099 | if (n == MR_PTAB_LEN) | |
1100 | return; | |
1101 | } | |
1102 | } | |
1103 | } | |
1104 | ||
1105 | /* | |
1106 | * We can only list 64 values in this list, but on | |
1107 | * a VRM12 device there is 256 values to chose from. | |
1108 | * For now we'll list values from 0.7 to 1.3 volt | |
1109 | * in 10 mV increments (61 values). | |
1110 | */ | |
1111 | ||
1112 | #define VRM_MIN 600000 | |
1113 | #define VRM_MAX 1300000 | |
1114 | #define VRM_RES 10000 | |
1115 | ||
1116 | static void __init | |
1117 | mr_mk_cv_lst(void) | |
1118 | { | |
1119 | int n; | |
1120 | uint32_t cv; | |
1121 | ||
1122 | /* | |
1123 | * If PM module interface is in place, then the | |
1124 | * core voltage list may already be populated. | |
1125 | */ | |
1126 | if (volt.supt[0] && volt.slen) | |
1127 | return; | |
1128 | ||
1129 | n = 0; | |
1130 | for(cv = VRM_MIN; cv <= VRM_MAX; cv += VRM_RES) { | |
1131 | volt.supt[n] = cv; | |
1132 | volt.slen = ++n; | |
1133 | if (n >= MR_PTAB_LEN) | |
1134 | return; | |
1135 | } | |
1136 | } | |
1137 | ||
1138 | ||
1139 | void __init | |
1140 | mr_mt_card_init(void) | |
1141 | { | |
1142 | uint32_t scr7, scr9, cf; | |
1143 | uint32_t smc, ci; | |
1144 | int rtn; | |
1145 | #ifndef MIC_IS_EMULATION | |
1146 | uint8_t * parm; | |
1147 | #endif | |
1148 | #if ! USE_SMC | |
1149 | uint32_t gv; | |
1150 | #endif | |
1151 | #if USE_SVID | |
1152 | int svid; | |
1153 | uint8_t vr; | |
1154 | #else | |
1155 | #if ! USE_SMC | |
1156 | uint32_t cv; | |
1157 | #endif | |
1158 | #endif | |
1159 | #if USE_PM | |
1160 | int (* fnc)(void); | |
1161 | #endif | |
1162 | ||
1163 | /* | |
1164 | * Make CPU->phys ID translation table | |
1165 | */ | |
1166 | get_cpu_table(); | |
1167 | ||
1168 | /* | |
1169 | * Build numbers for fboot0 and fboot 1 repectively | |
1170 | */ | |
1171 | scr7 = mr_sbox_rl(0, SBOX_SCRATCH7); | |
1172 | ||
1173 | /* | |
1174 | * VERS: | |
1175 | * Map flash and look for version strings. | |
1176 | */ | |
1177 | #ifdef MIC_IS_EMULATION | |
1178 | vers.fboot1[0] = scnprintf(vers.fboot1 + 1, MR_VERS_LEN -2, | |
1179 | "No emulation flash version string (build %d)", | |
1180 | GET_BITS(31, 16, scr7)); | |
1181 | #else | |
1182 | parm = ioremap(KNC_FLASH_BASE, KNC_FLASH_SIZE); | |
1183 | if (!parm) { | |
1184 | printk("mr_mt_card_init: ioremap failure: parm %x\n", KNC_FLASH_BASE); | |
1185 | goto fail_iomap; | |
1186 | } | |
1187 | ||
1188 | /* | |
1189 | * The fboot0 version (hardwired in the chip) is placed in flash | |
1190 | * by bootstrap at a fixed location, and is less than 16 byte long. | |
1191 | */ | |
1192 | if (strnlen(parm + KNC_FLASH_BOOT1, 16) < 16) | |
1193 | vers.fboot1[0] = scnprintf(vers.fboot1 + 1, MR_VERS_LEN -2, | |
1194 | "fboot1 version: %s (build %d)", | |
1195 | parm + KNC_FLASH_BOOT1, GET_BITS(31, 16, scr7)); | |
1196 | else | |
1197 | vers.fboot1[0] =scnprintf(vers.fboot1 + 1, MR_VERS_LEN -2, | |
1198 | "No valid version string found"); | |
1199 | iounmap(parm); | |
1200 | ||
1201 | /* | |
1202 | * While at it, check if there is a MC filter list in flash | |
1203 | */ | |
1204 | parm = ioremap(KNC_FLASH_TAB, KNC_FLASH_SIZE); | |
1205 | if (!parm) { | |
1206 | printk("mr_mt_card_init: ioremap failure: parm %x\n", KNC_FLASH_TAB); | |
1207 | goto fail_iomap; | |
1208 | } | |
1209 | mcc_flt_parm(parm + KNC_FLASH_FILT); | |
1210 | iounmap(parm); | |
1211 | ||
1212 | fail_iomap: | |
1213 | #endif | |
1214 | ||
1215 | /* | |
1216 | * Retrieve ID details from the SMC | |
1217 | * UUID, 16 byte | |
1218 | * serial, 12 byte | |
1219 | * FW version, | |
1220 | * 15:0 Build number | |
1221 | * 23:16 Minor version | |
1222 | * 31:24 Major version | |
1223 | * Note: Ancient systems, like Berta, runs on cards with an older | |
1224 | * version on the SMC firmware that does not support serial. | |
1225 | */ | |
1226 | mr_smc_deglitch(); | |
1227 | rtn = gmbus_i2c_read(2, MR_SMC_ADDR, MR_SMC_UUID, hwinf.guid, 16); | |
1228 | #if SMC_TRACK | |
1229 | printk("%s: %2x -> %08x, rtn %d\n", __FUNCTION__, MR_SMC_UUID, *(uint32_t *) hwinf.guid, rtn); | |
1230 | #endif | |
1231 | if (rtn != 16) | |
1232 | memset(hwinf.guid, '\0', 16); | |
1233 | mr_smc_deglitch(); | |
1234 | rtn = gmbus_i2c_read(2, MR_SMC_ADDR, MR_SMC_SERIAL, hwinf.serial, 12); | |
1235 | #if SMC_TRACK | |
1236 | printk("%s: %2x -> %08x, rtn %d\n", __FUNCTION__, MR_SMC_SERIAL, *(uint32_t *) hwinf.serial, rtn); | |
1237 | #endif | |
1238 | if (rtn != 12) | |
1239 | memcpy(hwinf.serial, "Update_SMC!!", sizeof(hwinf.serial)); | |
1240 | if (! mr_smc_rd(MR_SMC_FW_VERSION, &smc)) | |
1241 | vers.fsc[0] = scnprintf(vers.fsc + 1, MR_VERS_LEN -2, | |
1242 | "SMC firmware rev. %d.%d (build %d)", | |
1243 | GET_BITS(31, 24, smc), | |
1244 | GET_BITS(23, 16, smc), | |
1245 | GET_BITS(15, 0, smc)); | |
1246 | ||
1247 | /* | |
1248 | * HWINF: | |
1249 | * Get processor details from SBOX componentID. | |
1250 | * 19:16 Model ID => aka revision | |
1251 | * 15:12 Stepping ID => stepping | |
1252 | * 11:8 Substepping ID => substep | |
1253 | * | |
1254 | * Get Card Revision details from the SMC. | |
1255 | * 17:16 board (0=MPI, CRB, SFF, Product) | |
1256 | * 10:8 fab version (0='A' .. 7='H') | |
1257 | * 2:0 PBA SKU # (need name table here?) | |
1258 | */ | |
1259 | ci = mr_sbox_rl(0, SBOX_COMPONENT_ID); | |
1260 | hwinf.rev = GET_BITS(19, 16, ci); | |
1261 | hwinf.step = GET_BITS(15, 12, ci); | |
1262 | hwinf.substep = GET_BITS(11, 8, ci); | |
1263 | if (! mr_smc_rd(MR_SMC_HW_REVISION, &smc)) { | |
1264 | hwinf.board = GET_BITS(17, 16, smc); | |
1265 | hwinf.fab = GET_BITS(10, 8, smc); | |
1266 | hwinf.sku = GET_BITS( 2, 0, smc); | |
1267 | } | |
1268 | ||
1269 | /* | |
1270 | * VOLT: | |
1271 | * By definition, reference voltage is 1st value seen. | |
1272 | * Order of preference is SVID, then SMC and lastly SBOX. | |
1273 | * SMC register bits 15:0 is voltage in mV. | |
1274 | * SBOX_COREVOLT should be in SVID voltage format. | |
1275 | */ | |
1276 | #if USE_SVID | |
1277 | svid = SvidCmd(SVID_VCCP, VR12Cmd_GetReg, VR12Reg_VID_Set); | |
1278 | if (svid >= 0) | |
1279 | volt.set = svid2volt(svid); | |
1280 | #else | |
1281 | #if USE_SMC | |
1282 | if (!mr_smc_rd(MR_SMC_VOLT_VCCP, &smc) && GET_BITS(31, 30, smc) != 0x3) | |
1283 | volt.set = GET_BITS(15, 0, smc) * 1000; | |
1284 | #else | |
1285 | cv = mr_sbox_rl(0, SBOX_COREVOLT); | |
1286 | volt.set = svid2volt(GET_BITS(7, 0, cv)); | |
1287 | #endif | |
1288 | #endif | |
1289 | mr_mk_cv_lst(); | |
1290 | ||
1291 | /* | |
1292 | * FREQ | |
1293 | * By definition, reference frequency is 1st value seen. | |
1294 | */ | |
1295 | cf = mr_sbox_rl(0, SBOX_COREFREQ); | |
1296 | freq.def = mr_mt_cf_r2f(GET_BITS(11, 0, cf)); | |
1297 | mr_mk_cf_lst(); | |
1298 | ||
1299 | /* | |
1300 | * GDDR: | |
1301 | * See layout of scratch #9 in 'common'. | |
1302 | * 26:16 Clock ratio encoding | |
1303 | * 27 ClamShell | |
1304 | */ | |
1305 | scr9 = mr_sbox_rl(0, SBOX_SCRATCH9); | |
1306 | gddr.speed = 2 * mr_mt_gf_r2f(GET_BITS(26, 16, scr9)); | |
1307 | ||
1308 | /* | |
1309 | * GVOLT: | |
1310 | * Report all values the hardware can set, kind | |
1311 | * of silly as these cannot be changed from uOS. | |
1312 | * Order of preference is SVID, then SMC and lastly SBOX. | |
1313 | * SMC register bits 15:0 is voltage in mV. | |
1314 | * | |
1315 | *TBD: Seriously suspect SBOX register to be wrong. | |
1316 | */ | |
1317 | #if USE_SVID | |
1318 | svid = SvidCmd(SVID_VDDQ, VR12Cmd_GetReg, VR12Reg_VID_Set); | |
1319 | if (svid >= 0) | |
1320 | gvolt.set = svid2volt(svid); | |
1321 | #else | |
1322 | #if USE_SMC | |
1323 | if (!mr_smc_rd(MR_SMC_VOLT_VDDQ, &smc) && GET_BITS(31, 30, smc) != 0x3) | |
1324 | gvolt.set = GET_BITS(15, 0, smc) * 1000; | |
1325 | #else | |
1326 | gv = mr_sbox_rl(0, SBOX_MEMVOLT); | |
1327 | gvolt.set = svid2volt(GET_BITS(7, 0, gv)); | |
1328 | #endif | |
1329 | #endif | |
1330 | ||
1331 | /* | |
1332 | * GFREQ: | |
1333 | * Report all values the hardware can set, kind | |
1334 | * of silly as these cannot be changed from uOS. | |
1335 | */ | |
1336 | gfreq.def = mr_mt_gf_r2f(GET_BITS(26, 16, scr9)); | |
1337 | mr_mk_gf_lst(); | |
1338 | ||
1339 | /* | |
1340 | * PWR: | |
1341 | * If we are going to use SVID registers we'd need | |
1342 | * to know the VRs capabilities and ICC_MAX setting. | |
1343 | */ | |
1344 | #if USE_SVID | |
1345 | vr = SvidCmd(SVID_VCCP, VR12Cmd_GetReg, VR12Reg_Capability); | |
1346 | if (vr >= 0) | |
1347 | vccp_cap = vr; | |
1348 | vr = SvidCmd(SVID_VDDQ, VR12Cmd_GetReg, VR12Reg_Capability); | |
1349 | if (vr >= 0) | |
1350 | vddq_cap = vr; | |
1351 | vr = SvidCmd(SVID_VDDG, VR12Cmd_GetReg, VR12Reg_Capability); | |
1352 | if (vr >= 0) | |
1353 | vddg_cap = vr; | |
1354 | vr = SvidCmd(SVID_VCCP, VR12Cmd_GetReg, VR12Reg_Icc_Max); | |
1355 | if (vr >= 0) | |
1356 | vccp_imax = vr; | |
1357 | vr = SvidCmd(SVID_VDDQ, VR12Cmd_GetReg, VR12Reg_Icc_Max); | |
1358 | if (vr >= 0) | |
1359 | vddq_imax = vr; | |
1360 | vr = SvidCmd(SVID_VDDG, VR12Cmd_GetReg, VR12Reg_Icc_Max); | |
1361 | if (vr >= 0) | |
1362 | vddg_imax = vr; | |
1363 | #endif | |
1364 | ||
1365 | /* | |
1366 | * ECC: | |
1367 | * | |
1368 | *TBD: Where to find ECC setting? | |
1369 | * There are several GBOX registers that has something | |
1370 | * named ECC in them. Scott to tell once PO is done. | |
1371 | */ | |
1372 | ecc.enable = GET_BIT(29, scr9); | |
1373 | ||
1374 | /* | |
1375 | * TRBO | |
1376 | * The PM module have the inital turbo mode setting. | |
1377 | * Get it now, so we don't need to call PM to report it. | |
1378 | */ | |
1379 | #if USE_PM | |
1380 | fnc = pm_cb.micpm_get_turbo; | |
1381 | if (fnc) | |
1382 | trbo.set = fnc(); | |
1383 | #endif | |
1384 | ||
1385 | /* | |
1386 | *TBD: Save registers this module may change | |
1387 | */ | |
1388 | } | |
1389 | ||
1390 | void __exit | |
1391 | mr_mt_card_exit(void) | |
1392 | { | |
1393 | /* | |
1394 | *TBD: Restore registers this module may change | |
1395 | */ | |
1396 | } | |
1397 | ||
1398 | ||
1399 | ||
1400 | /* | |
1401 | ** | |
1402 | ** Card specific 'Get' functions | |
1403 | ** | |
1404 | */ | |
1405 | ||
1406 | int | |
1407 | mr_get_volt(void * p) | |
1408 | { | |
1409 | struct mr_rsp_volt * r; | |
1410 | #if USE_PM | |
1411 | void (* fnc)(void); | |
1412 | #endif | |
1413 | ||
1414 | /* | |
1415 | * Preference is VR out. | |
1416 | * Not sure if board sensors work in KnC | |
1417 | */ | |
1418 | #if USE_SVID | |
1419 | { | |
1420 | int vout; | |
1421 | ||
1422 | vout = SvidCmd(SVID_VCCP, VR12Cmd_GetReg, VR12Reg_VID_Set); | |
1423 | if (vout < 0) | |
1424 | return vout; | |
1425 | volt.set = svid2volt(vout); | |
1426 | ||
1427 | vout = SvidCmd(SVID_VCCP, VR12Cmd_GetReg, VR12Reg_Vout); | |
1428 | if (vout < 0) | |
1429 | return vout; | |
1430 | volt.cur = vout2volt(vout); | |
1431 | } | |
1432 | #else | |
1433 | #if USE_SMC | |
1434 | { | |
1435 | uint32_t smc; | |
1436 | ||
1437 | volt.cur = 0; | |
1438 | volt.c_val = 3; | |
1439 | if (! mr_smc_rd(MR_SMC_VOLT_VCCP, &smc)) { | |
1440 | volt.c_val = GET_BITS(31, 30, smc); | |
1441 | if (volt.c_val != 0x3) | |
1442 | volt.cur = GET_BITS(15, 0, smc) * 1000; | |
1443 | } | |
1444 | ||
1445 | /* | |
1446 | *TBD: override 'set' value ? | |
1447 | */ | |
1448 | } | |
1449 | #else | |
1450 | { | |
1451 | uint32_t fsc, cv; | |
1452 | ||
1453 | cv = mr_sbox_rl(0, SBOX_COREVOLT); | |
1454 | volt.set = svid2volt(GET_BITS(7, 0, cv)); | |
1455 | ||
1456 | fsc = mr_sbox_rl(0, SBOX_BOARD_VOLTAGE_SENSE); | |
1457 | volt.cur = bvs2volt(GET_BITS(15, 0, fsc)); | |
1458 | } | |
1459 | #endif | |
1460 | #endif | |
1461 | ||
1462 | #if USE_PM | |
1463 | /* | |
1464 | * Ask PM for table refresh | |
1465 | */ | |
1466 | fnc = pm_cb.micpm_vf_refresh; | |
1467 | if (fnc) | |
1468 | fnc(); | |
1469 | #endif | |
1470 | ||
1471 | r = (struct mr_rsp_volt *) p; | |
1472 | *r = volt; | |
1473 | return sizeof(*r); | |
1474 | } | |
1475 | ||
1476 | ||
1477 | int | |
1478 | mr_get_freq(void * p) | |
1479 | { | |
1480 | struct mr_rsp_freq * r; | |
1481 | uint32_t cf, cr; | |
1482 | #if USE_PM | |
1483 | void (* fnc)(void); | |
1484 | #endif | |
1485 | ||
1486 | /* | |
1487 | * Current Ratio: | |
1488 | * 11:0 Current core ratio | |
1489 | * 15 Enable 600 MHz | |
1490 | * 27:16 Goal ratio | |
1491 | * 31 OC disable | |
1492 | * Goal ratio is a product of base ratio and fuse overrides | |
1493 | * Current ration is a product of goal, fuse limits and themal throttle | |
1494 | * | |
1495 | * Core Frequency: | |
1496 | * 11:0 Base ratio | |
1497 | * 15 Fuse override | |
1498 | * 31 Select ratio | |
1499 | * Base ratio accepted only if (bit 15 | bit 31 | OC disble) == 010 | |
1500 | * | |
1501 | *TBD: How to detect clock bypasses? | |
1502 | * ICC bypass cuts the core and reference base in half. | |
1503 | */ | |
1504 | cr = mr_sbox_rl(0, SBOX_CURRENTRATIO); | |
1505 | cf = mr_sbox_rl(0, SBOX_COREFREQ); | |
1506 | freq.cur = mr_mt_cf_r2f(GET_BITS(11, 0, cr)); | |
1507 | freq.def = mr_mt_cf_r2f(GET_BITS(11, 0, cf)); | |
1508 | if (GET_BITS(11, 0, cf) != GET_BITS(11, 0, cr)) | |
1509 | printk("RAS.get_freq: core not running at expected frequency\n"); | |
1510 | ||
1511 | #if USE_PM | |
1512 | /* | |
1513 | * Ask PM for table refresh | |
1514 | */ | |
1515 | fnc = pm_cb.micpm_vf_refresh; | |
1516 | if (fnc) | |
1517 | fnc(); | |
1518 | #endif | |
1519 | ||
1520 | r = (struct mr_rsp_freq *) p; | |
1521 | *r = freq; | |
1522 | return sizeof(*r); | |
1523 | } | |
1524 | ||
1525 | ||
1526 | #if USE_SVID | |
1527 | int | |
1528 | mr_get_svid(uint8_t vr, uint8_t cap, uint8_t imax, struct mr_rsp_vrr * vrr) | |
1529 | { | |
1530 | int v, a, p; | |
1531 | ||
1532 | p = SvidCmd(vr, VR12Cmd_GetReg, VR12Reg_Pout); | |
1533 | a = SvidCmd(vr, VR12Cmd_GetReg, VR12Reg_Iout); | |
1534 | v = SvidCmd(vr, VR12Cmd_GetReg, VR12Reg_Vout); | |
1535 | ||
1536 | if (p < 0 || a < 0 || v < 0) | |
1537 | return -MR_ERR_SMC; | |
1538 | ||
1539 | vrr->pwr = pout2watt(p); | |
1540 | vrr->cur = iout2amp(a, cap, imax); | |
1541 | vrr->volt = vout2volt(v); | |
1542 | ||
1543 | return 0; | |
1544 | } | |
1545 | #endif | |
1546 | ||
1547 | #define KNC_DFF_BOARD 2 /* DFF/SFF board */ | |
1548 | ||
1549 | int | |
1550 | mr_get_power(void * p) | |
1551 | { | |
1552 | struct mr_rsp_power * r; | |
1553 | #if USE_SMC | |
1554 | static struct mr_rsp_vrr vnil = { 0, 0, 0, 3, 3, 3 }; | |
1555 | static struct mr_rsp_pws pnil = { 0, 3 }; | |
1556 | uint32_t vccp, vddg, vddq; | |
1557 | uint32_t prd0, prd1, pcie, p2x3, p2x4; | |
1558 | #endif | |
1559 | ||
1560 | #if USE_SVID | |
1561 | /* | |
1562 | * Get VR status over SVID. | |
1563 | */ | |
1564 | if (mr_get_svid(SVID_VCCP, vccp_cap, vccp_imax, &power.vccp) < 0 || | |
1565 | mr_get_svid(SVID_VDDQ, vddq_cap, vddq_imax, &power.vddq) < 0 || | |
1566 | mr_get_svid(SVID_VDDG, vddg_cap, vddg_imax, &power.vddq) < 0) | |
1567 | return -MR_ERR_SMC; | |
1568 | #else | |
1569 | #if USE_SMC | |
1570 | /* | |
1571 | * Get VR status from SMC. | |
1572 | * Only voltages are available currently. | |
1573 | * Still need to screen for good data. | |
1574 | * Top 2 bits decode as | |
1575 | * 00 Data OK | |
1576 | * 01 Upper threshold reached | |
1577 | * 10 Lower threshold reached | |
1578 | * 11 Data unavailable | |
1579 | * Assume data is valid even if a threshold reached | |
1580 | */ | |
1581 | power.vccp = power.vddg = power.vddq = vnil; | |
1582 | if (! mr_smc_rd(MR_SMC_VOLT_VCCP, &vccp)) { | |
1583 | power.vccp.v_val = GET_BITS(31, 30, vccp); | |
1584 | if (power.vccp.v_val != 0x3) | |
1585 | power.vccp.volt = 1000 * GET_BITS(15, 0, vccp); | |
1586 | } | |
1587 | if (! mr_smc_rd(MR_SMC_VOLT_VDDG, &vddg)) { | |
1588 | power.vddg.v_val = GET_BITS(31, 30, vddg); | |
1589 | if (power.vddg.v_val != 0x3) | |
1590 | power.vddg.volt = 1000 * GET_BITS(15, 0, vddg); | |
1591 | } | |
1592 | if (! mr_smc_rd(MR_SMC_VOLT_VDDQ, &vddq)) { | |
1593 | power.vddq.v_val = GET_BITS(31, 30, vddq); | |
1594 | if (power.vddq.v_val != 0x3) | |
1595 | power.vddq.volt = 1000 * GET_BITS(15, 0, vddq); | |
1596 | } | |
1597 | if (! mr_smc_rd(MR_SMC_PWR_VCCP, &vccp)) { | |
1598 | power.vccp.p_val = GET_BITS(31, 30, vccp); | |
1599 | if (power.vccp.p_val != 0x3) | |
1600 | power.vccp.pwr = 1000000 * GET_BITS(15, 0, vccp); | |
1601 | } | |
1602 | if (! mr_smc_rd(MR_SMC_PWR_VDDG, &vddg)) { | |
1603 | power.vddg.p_val = GET_BITS(31, 30, vddg); | |
1604 | if (power.vddg.p_val != 0x3) | |
1605 | power.vddg.pwr = 1000000 * GET_BITS(15, 0, vddg); | |
1606 | } | |
1607 | if (! mr_smc_rd(MR_SMC_PWR_VDDQ, &vddq)) { | |
1608 | power.vddq.p_val = GET_BITS(31, 30, vddq); | |
1609 | if (power.vddq.p_val != 0x3) | |
1610 | power.vddq.pwr = 1000000 * GET_BITS(15, 0, vddq); | |
1611 | } | |
1612 | #endif | |
1613 | #endif | |
1614 | ||
1615 | #if USE_SMC | |
1616 | /* | |
1617 | * Get reads on VRs and power sensors from SMC. | |
1618 | * This is a mess: | |
1619 | * - total power may or may not include 3.3 V rail. | |
1620 | * If it is then it's not measured, just "guessed". | |
1621 | * - there are two averaging windows for total power, | |
1622 | * though it is not clear who controls these windows. | |
1623 | * For now we assume window 0 is shorter than window 1 | |
1624 | * and thus power 0 is 'current' reading and power 1 | |
1625 | * is the '20 sec' reading. | |
1626 | * TBD: Who controls the time windows and is is true | |
1627 | * that Window 0 is shorter than Window 1? | |
1628 | * - No specifics on how power sensors are averaged, | |
1629 | * i.e. is Window 0/1 used or is is a third window. | |
1630 | * Need to know, otherwise Ptot may not be sum(sources). | |
1631 | * - There still is no 'max' value from SMC | |
1632 | * | |
1633 | * Still need to screen for good data. | |
1634 | * Top 2 bits decode as | |
1635 | * 00 Data OK | |
1636 | * 01 Upper threshold reached | |
1637 | * 10 Lower threshold reached | |
1638 | * 11 Data unavailable | |
1639 | * Assume data is valid even if a threshold reached | |
1640 | */ | |
1641 | power.tot0 = power.tot1 = | |
1642 | power.inst = power.imax = | |
1643 | power.pcie = power.c2x3 = power.c2x4 = pnil; | |
1644 | ||
1645 | if (! mr_smc_rd(MR_SMC_AVG_PWR_0, &prd0)) { | |
1646 | power.tot0.p_val = GET_BITS(31, 30, prd0); | |
1647 | if (power.tot0.p_val != 0x3) | |
1648 | power.tot0.prr = 1000000 * GET_BITS(29, 0, prd0); | |
1649 | } | |
1650 | if (! mr_smc_rd(MR_SMC_AVG_PWR_1, &prd1)) { | |
1651 | power.tot1.p_val = GET_BITS(31, 30, prd1); | |
1652 | if (power.tot1.p_val != 0x3) | |
1653 | power.tot1.prr = 1000000 * GET_BITS(29, 0, prd1); | |
1654 | } | |
1655 | power.inst = power.imax = pnil; | |
1656 | if (! mr_smc_rd(MR_SMC_PWR_INST, &prd0)) { | |
1657 | power.inst.p_val = GET_BITS(31, 30, prd0); | |
1658 | if (power.inst.p_val != 0x3) | |
1659 | power.inst.prr = 1000000 * GET_BITS(29, 0, prd0); | |
1660 | } | |
1661 | if (! mr_smc_rd(MR_SMC_PWR_IMAX, &prd1)) { | |
1662 | power.imax.p_val = GET_BITS(31, 30, prd1); | |
1663 | if (power.imax.p_val != 0x3) | |
1664 | power.imax.prr = 1000000 * GET_BITS(29, 0, prd1); | |
1665 | } | |
1666 | if (! mr_smc_rd(MR_SMC_PWR_PCIE, &pcie)) { | |
1667 | power.pcie.p_val = GET_BITS(31, 30, pcie); | |
1668 | if (power.pcie.p_val != 0x3) | |
1669 | power.pcie.prr = 1000000 * GET_BITS(15, 0, pcie); | |
1670 | } | |
1671 | if (hwinf.board != KNC_DFF_BOARD) { | |
1672 | if (! mr_smc_rd(MR_SMC_PWR_2X3, &p2x3)) { | |
1673 | power.c2x3.p_val = GET_BITS(31, 30, p2x3); | |
1674 | if (power.c2x3.p_val != 0x3) | |
1675 | power.c2x3.prr = 1000000 * GET_BITS(15, 0, p2x3); | |
1676 | } | |
1677 | if (! mr_smc_rd(MR_SMC_PWR_2X4, &p2x4)) { | |
1678 | power.c2x4.p_val = GET_BITS(31, 30, p2x4); | |
1679 | if (power.c2x4.p_val != 0x3) | |
1680 | power.c2x4.prr = 1000000 * GET_BITS(15, 0, p2x4); | |
1681 | } | |
1682 | } | |
1683 | #endif | |
1684 | ||
1685 | r = (struct mr_rsp_power *) p; | |
1686 | *r = power; | |
1687 | return sizeof(*r); | |
1688 | } | |
1689 | ||
1690 | ||
1691 | int | |
1692 | mr_get_plim(void * p) | |
1693 | { | |
1694 | uint32_t pl0, pl1, grd; | |
1695 | struct mr_rsp_plim * r; | |
1696 | ||
1697 | /* | |
1698 | * Get values from PM | |
1699 | */ | |
1700 | if (! mr_smc_rd(MR_SMC_PWR_LIM_0, &pl0)) | |
1701 | plim.hmrk = GET_BITS(15, 0, pl0); | |
1702 | ||
1703 | if (! mr_smc_rd(MR_SMC_PWR_LIM_1, &pl1)) | |
1704 | plim.lmrk = GET_BITS(15, 0, pl1); | |
1705 | ||
1706 | if (! mr_smc_rd(MR_SMC_PWR_LIM0_GRD, &grd)) | |
1707 | plim.phys = plim.hmrk + GET_BITS(15, 0, grd); | |
1708 | ||
1709 | r = (struct mr_rsp_plim *) p; | |
1710 | *r = plim; | |
1711 | return sizeof(*r); | |
1712 | } | |
1713 | ||
1714 | ||
1715 | int | |
1716 | mr_get_gfreq(void * p) | |
1717 | { | |
1718 | struct mr_rsp_gfreq * r; | |
1719 | uint32_t gbr; | |
1720 | ||
1721 | /* | |
1722 | * SBOX register MEMFREQ bits 7:0 now holds 10 x rate in GTps. | |
1723 | */ | |
1724 | gbr = mr_sbox_rl(0, SBOX_MEMORYFREQ); | |
1725 | gfreq.cur = GET_BITS(7, 0, gbr) * 100000 / 2; | |
1726 | ||
1727 | r = (struct mr_rsp_gfreq *) p; | |
1728 | *r = gfreq; | |
1729 | return sizeof(*r); | |
1730 | } | |
1731 | ||
1732 | ||
1733 | int | |
1734 | mr_get_gvolt(void * p) | |
1735 | { | |
1736 | struct mr_rsp_gvolt * r; | |
1737 | ||
1738 | /* | |
1739 | * Preference is VR out. | |
1740 | * Not sure if board sensors work in KnC | |
1741 | */ | |
1742 | #if USE_SVID | |
1743 | { | |
1744 | int vout; | |
1745 | ||
1746 | vout = SvidCmd(SVID_VDDQ, VR12Cmd_GetReg, VR12Reg_VID_Set); | |
1747 | if (vout < 0) | |
1748 | return vout; | |
1749 | gvolt.set = svid2volt(vout); | |
1750 | ||
1751 | vout = SvidCmd(SVID_VDDQ, VR12Cmd_GetReg, VR12Reg_Vout); | |
1752 | if (vout < 0) | |
1753 | return vout; | |
1754 | gvolt.cur = vout2volt(vout); | |
1755 | } | |
1756 | #else | |
1757 | #if USE_SMC | |
1758 | { | |
1759 | uint32_t smc; | |
1760 | ||
1761 | gvolt.cur = 0; | |
1762 | gvolt.c_val = 3; | |
1763 | if (! mr_smc_rd(MR_SMC_VOLT_VDDQ, &smc)) { | |
1764 | gvolt.c_val = GET_BITS(31, 30, smc); | |
1765 | if (gvolt.c_val != 0x3) | |
1766 | gvolt.cur = GET_BITS(15, 0, smc) * 1000; | |
1767 | } | |
1768 | if (!gvolt.set) | |
1769 | gvolt.set = gvolt.cur; | |
1770 | } | |
1771 | #else | |
1772 | { | |
1773 | uint32_t bvs; | |
1774 | ||
1775 | bvs = mr_sbox_rl(0, SBOX_BOARD_VOLTAGE_SENSE); | |
1776 | gvolt.cur = bvs2volt(GET_BITS(31, 16, bvs)); | |
1777 | } | |
1778 | #endif | |
1779 | #endif | |
1780 | ||
1781 | r = (struct mr_rsp_gvolt *) p; | |
1782 | *r = gvolt; | |
1783 | return sizeof(*r); | |
1784 | } | |
1785 | ||
1786 | ||
1787 | /* | |
1788 | * Card has 3 dedicated temp sensors (read from SMC): | |
1789 | * 0 Air Inlet (aka West) | |
1790 | * 1 Air exhaust (aka East) | |
1791 | * 2 GDDR memory (not sure which chip) | |
1792 | * | |
1793 | * VRs can measure temperature too, which may be read | |
1794 | * from SMC (via I2C bus) or the VRs directly (via SVID). | |
1795 | * 3 Vccp VR (IR3538) temp | |
1796 | * 4 Vddq VR (IR3541, loop 1) temp | |
1797 | * 5 Vddg VR (IR3541, loop 2) temp | |
1798 | * Note: Vddg and Vddq are measured on the same VR, | |
1799 | * likely will be the same reading (or very close). | |
1800 | * | |
1801 | * SBOX board temperature sensors are not connected | |
1802 | * in KnC (SBOX HAS vol 1, section 1.40.1). Instead it | |
1803 | * relies on SMC to 'broadcast' sensor telemetry into | |
1804 | * the KnC's TMU unit via it's I2C bus. | |
1805 | * Currently it doesn't, though a DCR has been filed. | |
1806 | */ | |
1807 | ||
1808 | int | |
1809 | mr_get_temp(void * p) | |
1810 | { | |
1811 | struct mr_rsp_temp * r; | |
1812 | uint32_t die1, die2, die3; /* Die temps */ | |
1813 | uint32_t dmx1, dmx2, dmx3; /* Max die temps */ | |
1814 | #if USE_SVID | |
1815 | int tvccp, tvddq, tvddg; /* VR temps */ | |
1816 | #endif | |
1817 | #if USE_SMC | |
1818 | static struct mr_rsp_tsns tnil = { 0, 3 }; | |
1819 | #endif | |
1820 | ||
1821 | #if USE_SVID | |
1822 | /* | |
1823 | * Get VR temperatures over SVID. | |
1824 | * These are _all_ positive numbers. | |
1825 | */ | |
1826 | tvccp = SvidCmd(SVID_VCCP, VR12Cmd_GetReg, VR12Reg_Temp); | |
1827 | tvddq = SvidCmd(SVID_VDDQ, VR12Cmd_GetReg, VR12Reg_Temp); | |
1828 | tvddg = SvidCmd(SVID_VDDG, VR12Cmd_GetReg, VR12Reg_Temp); | |
1829 | if (tvccp < 0 || tvddq < 0 || tvddg < 0) | |
1830 | return -MR_ERR_SMC; | |
1831 | temp.vccp.cur = GET_BITS(7, 0, tvccp); | |
1832 | temp.vddq.cur = GET_BITS(7, 0, tvddq); | |
1833 | temp.vddg.cur = GET_BITS(7, 0, tvddg); | |
1834 | #endif | |
1835 | ||
1836 | #if USE_SMC | |
1837 | /* | |
1838 | * Get temp sensor readings from SMC. | |
1839 | * According to MAS 0.30 it presents | |
1840 | * - CPU die temp (just one value) | |
1841 | * - Fan exhaust temp | |
1842 | * - Fan inlet temp | |
1843 | * - Vccp VR temp | |
1844 | * - Vddg VR temp | |
1845 | * - Vddq VR temp | |
1846 | * - GDDR temp | |
1847 | * | |
1848 | * Still need to screen for good data. | |
1849 | * Top 2 bits decode as | |
1850 | * 00 Data OK | |
1851 | * 01 Upper threshold reached | |
1852 | * 10 Lower threshold reached | |
1853 | * 11 Data unavailable | |
1854 | * Assume data is valid even if a threshold reached | |
1855 | */ | |
1856 | { | |
1857 | uint32_t fin, fout, gddr; /* Sensor temps */ | |
1858 | uint32_t vccp, vddg, vddq; /* VR temps */ | |
1859 | uint32_t die; /* Die summary */ | |
1860 | ||
1861 | temp.die = temp.fin = temp.fout = | |
1862 | temp.vccp = temp.vddg = temp.vddq = tnil; | |
1863 | if (! mr_smc_rd(MR_SMC_TEMP_CPU, &die)) { | |
1864 | temp.die.c_val = GET_BITS(31, 30, die); | |
1865 | if (temp.die.c_val != 0x3) | |
1866 | temp.die.cur = GET_BITS(15, 0, die); | |
1867 | } | |
1868 | if (! mr_smc_rd(MR_SMC_TEMP_EXHAUST, &fout)) { | |
1869 | temp.fout.c_val = GET_BITS(31, 30, fout); | |
1870 | if (temp.fout.c_val != 0x3) | |
1871 | temp.fout.cur = GET_BITS(15, 0, fout); | |
1872 | } | |
1873 | if (! mr_smc_rd(MR_SMC_TEMP_INLET, &fin)) { | |
1874 | temp.fin.c_val = GET_BITS(31, 30, fin); | |
1875 | if (temp.fin.c_val != 0x3) | |
1876 | temp.fin.cur = GET_BITS(15, 0, fin); | |
1877 | } | |
1878 | if (! mr_smc_rd(MR_SMC_TEMP_VCCP, &vccp)) { | |
1879 | temp.vccp.c_val = GET_BITS(31, 30, vccp); | |
1880 | if (temp.vccp.c_val != 0x3) | |
1881 | temp.vccp.cur = GET_BITS(15, 0, vccp); | |
1882 | } | |
1883 | if (! mr_smc_rd(MR_SMC_TEMP_VDDG, &vddg)) { | |
1884 | temp.vddg.c_val = GET_BITS(31, 30, vddg); | |
1885 | if (temp.vddg.c_val != 0x3) | |
1886 | temp.vddg.cur = GET_BITS(15, 0, vddg); | |
1887 | } | |
1888 | if (! mr_smc_rd(MR_SMC_TEMP_VDDQ, &vddq)) { | |
1889 | temp.vddq.c_val = GET_BITS(31, 30, vddq); | |
1890 | if (temp.vddq.c_val != 0x3) | |
1891 | temp.vddq.cur = GET_BITS(15, 0, vddq); | |
1892 | } | |
1893 | if (! mr_smc_rd(MR_SMC_TEMP_GDDR, &gddr)) { | |
1894 | temp.gddr.c_val = GET_BITS(31, 30, gddr); | |
1895 | if (temp.gddr.c_val != 0x3) | |
1896 | temp.gddr.cur = GET_BITS(15, 0, gddr); | |
1897 | } | |
1898 | } | |
1899 | #else | |
1900 | /* | |
1901 | * The TMU registers relies on telemetry broadcasts from | |
1902 | * the SMC in order to report current data, early SMC | |
1903 | * firmware does not provide telemetry at all. | |
1904 | * Mapping of 'board temps' to physical sensors isn't | |
1905 | * really defined anywhere. Based on FreeBSD comments | |
1906 | * they map is: | |
1907 | * 0 Air Inlet | |
1908 | * 1 VCCP VR | |
1909 | * 2 GDDR (not sure which chip) | |
1910 | * 3 GDDR VR | |
1911 | * | |
1912 | *TBD: verify map on actual CRB | |
1913 | */ | |
1914 | { | |
1915 | uint32_t btr1, btr2; /* Board temps */ | |
1916 | uint32_t tsta; /* Thermal status */ | |
1917 | uint32_t fsc; /* Fan controller status */ | |
1918 | ||
1919 | fsc = mr_sbox_rl(0, SBOX_STATUS_FAN2); | |
1920 | btr1 = mr_sbox_rl(0, SBOX_BOARD_TEMP1); | |
1921 | btr2 = mr_sbox_rl(0, SBOX_BOARD_TEMP2); | |
1922 | tsta = mr_sbox_rl(0, SBOX_THERMAL_STATUS); | |
1923 | temp.fin.cur = (btr1 & (1 << 15)) ? GET_BITS( 8, 0, btr1) : 0; | |
1924 | temp.vccp.cur = (btr1 & (1 << 31)) ? GET_BITS(24, 16, btr1) : 0; | |
1925 | temp.gddr.cur = (btr2 & (1 << 15)) ? GET_BITS( 8, 0, btr2) : 0; | |
1926 | temp.vddq.cur = (btr2 & (1 << 31)) ? GET_BITS(24, 16, btr2) : 0; | |
1927 | temp.vddg.cur = GET_BITS(19, 12, fsc); | |
1928 | temp.brd.cur = 0; | |
1929 | if (temp.fin.cur > temp.brd.cur) | |
1930 | temp.brd.cur = temp.fin.cur; | |
1931 | if (temp.vccp.cur > temp.brd.cur) | |
1932 | temp.brd.cur = temp.vccp.cur; | |
1933 | if (temp.gddr.cur > temp.brd.cur) | |
1934 | temp.brd.cur = temp.gddr.cur; | |
1935 | if (temp.vddq.cur > temp.brd.cur) | |
1936 | temp.brd.cur = temp.vddq.cur; | |
1937 | if (tsta & (1 << 31)) | |
1938 | temp.die.cur = GET_BITS(30, 22, tsta); | |
1939 | } | |
1940 | #endif | |
1941 | ||
1942 | /* | |
1943 | * Raw SBOX data for die temperatures. | |
1944 | * | |
1945 | *TBD: do these depend on SMC telemetry? | |
1946 | * If so they probably won't work until DCR in place. | |
1947 | */ | |
1948 | die1 = mr_sbox_rl(0, SBOX_CURRENT_DIE_TEMP0); | |
1949 | die2 = mr_sbox_rl(0, SBOX_CURRENT_DIE_TEMP1); | |
1950 | die3 = mr_sbox_rl(0, SBOX_CURRENT_DIE_TEMP2); | |
1951 | dmx1 = mr_sbox_rl(0, SBOX_MAX_DIE_TEMP0); | |
1952 | dmx2 = mr_sbox_rl(0, SBOX_MAX_DIE_TEMP1); | |
1953 | dmx3 = mr_sbox_rl(0, SBOX_MAX_DIE_TEMP2); | |
1954 | ||
1955 | /* | |
1956 | * Die temperatures. | |
1957 | * Always positive numbers (or zero for unfused parts) | |
1958 | */ | |
1959 | temp.dies[0].cur = GET_BITS( 9, 0, die1); | |
1960 | temp.dies[1].cur = GET_BITS(19, 10, die1); | |
1961 | temp.dies[2].cur = GET_BITS(29, 20, die1); | |
1962 | temp.dies[3].cur = GET_BITS( 9, 0, die2); | |
1963 | temp.dies[4].cur = GET_BITS(19, 10, die2); | |
1964 | temp.dies[5].cur = GET_BITS(29, 20, die2); | |
1965 | temp.dies[6].cur = GET_BITS( 9, 0, die3); | |
1966 | temp.dies[7].cur = GET_BITS(19, 10, die3); | |
1967 | temp.dies[8].cur = GET_BITS(29, 20, die3); | |
1968 | ||
1969 | /* | |
1970 | * Die max temp (probably 0 for unfused parts) | |
1971 | */ | |
1972 | temp.dies[0].max = GET_BITS( 9, 0, dmx1); | |
1973 | temp.dies[1].max = GET_BITS(19, 10, dmx1); | |
1974 | temp.dies[2].max = GET_BITS(29, 20, dmx1); | |
1975 | temp.dies[3].max = GET_BITS( 9, 0, dmx2); | |
1976 | temp.dies[4].max = GET_BITS(19, 10, dmx2); | |
1977 | temp.dies[5].max = GET_BITS(29, 20, dmx2); | |
1978 | temp.dies[6].max = GET_BITS( 9, 0, dmx3); | |
1979 | temp.dies[7].max = GET_BITS(19, 10, dmx3); | |
1980 | temp.dies[8].max = GET_BITS(29, 20, dmx3); | |
1981 | ||
1982 | r = (struct mr_rsp_temp *) p; | |
1983 | *r = temp; | |
1984 | return sizeof(*r); | |
1985 | } | |
1986 | ||
1987 | ||
1988 | int | |
1989 | mr_get_fan(void * p) | |
1990 | { | |
1991 | struct mr_rsp_fan * r; | |
1992 | uint32_t fs, fp; | |
1993 | #if USE_SMC | |
1994 | uint32_t fa; | |
1995 | #endif | |
1996 | ||
1997 | r = (struct mr_rsp_fan *) p; | |
1998 | ||
1999 | /* | |
2000 | * Preference is SMC data. | |
2001 | * Not sure if SBOX registers work sensors work in KnC | |
2002 | */ | |
2003 | #if USE_SMC | |
2004 | /* | |
2005 | * Read fan state from SMC. | |
2006 | * No info on override available. | |
2007 | */ | |
2008 | r->override = 0; | |
2009 | r->r_val = r->p_val = 3; | |
2010 | if (mr_smc_rd(MR_SMC_FAN_TACH, &fs)) | |
2011 | fs = PUT_BITS(31, 30, 3); | |
2012 | if (mr_smc_rd(MR_SMC_FAN_PWM, &fp)) | |
2013 | fp = PUT_BITS(31, 30, 3); | |
2014 | if (mr_smc_rd(MR_SMC_FAN_PWM_ADD, &fa)) | |
2015 | fa = PUT_BITS(31, 30, 3); | |
2016 | ||
2017 | /* | |
2018 | * Still need to screen for good data. | |
2019 | * Top 2 bits decode as | |
2020 | * 00 Data OK | |
2021 | * 01 Reserved | |
2022 | * 10 Lower threshold reached (or reserved) | |
2023 | * 11 Data unavailable | |
2024 | * Assume data is still valid if a threshold reached | |
2025 | */ | |
2026 | if (GET_BITS(31, 30, fs) != 0x3) { | |
2027 | /* | |
2028 | * The override concept from KnF (and SBOX registers) | |
2029 | * seems to have been replaced with a PWM adder. | |
2030 | * Propose to set override flag if adder is non-zero. | |
2031 | */ | |
2032 | r->r_val = 0; | |
2033 | r->rpm = GET_BITS(15, 0, fs); | |
2034 | if (GET_BITS(31, 30, fp) != 0x3) { | |
2035 | r->p_val = 0; | |
2036 | r->pwm = GET_BITS(7, 0, fp); | |
2037 | if (GET_BITS(31, 30, fa) != 0x3) { | |
2038 | fa = GET_BITS(7, 0, fa); | |
2039 | if (fa) { | |
2040 | r->override = 1; | |
2041 | r->pwm += fa; | |
2042 | if (r->pwm > 100) | |
2043 | r->pwm = 100; | |
2044 | } | |
2045 | } | |
2046 | } | |
2047 | } | |
2048 | #else | |
2049 | /* | |
2050 | * Read fan state from SBOX registers | |
2051 | * Require SMC telemetry to work. | |
2052 | */ | |
2053 | fs = mr_sbox_rl(0, SBOX_STATUS_FAN1); | |
2054 | fp = mr_sbox_rl(0, SBOX_SPEED_OVERRIDE_FAN); | |
2055 | ||
2056 | r->override = GET_BIT(15, fp); | |
2057 | r->rpm = GET_BITS(15, 0, fs); | |
2058 | if (r->override) | |
2059 | r->pwm = GET_BITS( 7, 0, fp); | |
2060 | else | |
2061 | r->pwm = GET_BITS(23, 16, fs); | |
2062 | #endif | |
2063 | ||
2064 | return sizeof(*r); | |
2065 | } | |
2066 | ||
2067 | ||
2068 | int | |
2069 | mr_get_ecc(void * p) | |
2070 | { | |
2071 | struct mr_rsp_ecc * r; | |
2072 | ||
2073 | r = (struct mr_rsp_ecc *) p; | |
2074 | *r = ecc; | |
2075 | return sizeof(*r); | |
2076 | } | |
2077 | ||
2078 | ||
2079 | int | |
2080 | mr_get_trbo(void * p) | |
2081 | { | |
2082 | struct mr_rsp_trbo * r; | |
2083 | ||
2084 | /* | |
2085 | * Get current value from PM | |
2086 | */ | |
2087 | #if USE_PM | |
2088 | int (* fnc)(void); | |
2089 | ||
2090 | fnc = pm_cb.micpm_get_turbo; | |
2091 | if (fnc) { | |
2092 | uint32_t pm; | |
2093 | ||
2094 | pm = fnc(); | |
2095 | trbo.state = GET_BIT(1, pm); | |
2096 | trbo.avail = GET_BIT(2, pm); | |
2097 | if (! trbo.avail) | |
2098 | trbo.set = 0; | |
2099 | } | |
2100 | #endif | |
2101 | ||
2102 | r = (struct mr_rsp_trbo *) p; | |
2103 | *r = trbo; | |
2104 | return sizeof(*r); | |
2105 | } | |
2106 | ||
2107 | ||
2108 | int | |
2109 | mr_get_pmcfg(void * p) | |
2110 | { | |
2111 | struct mr_rsp_pmcfg * r; | |
2112 | ||
2113 | #if USE_PM | |
2114 | int (* fnc)(void); | |
2115 | ||
2116 | fnc = pm_cb.micpm_get_pmcfg; | |
2117 | if (fnc) | |
2118 | pmcfg.mode = fnc(); | |
2119 | #endif | |
2120 | ||
2121 | r = (struct mr_rsp_pmcfg *) p; | |
2122 | *r = pmcfg; | |
2123 | return sizeof(*r); | |
2124 | } | |
2125 | ||
2126 | ||
2127 | int | |
2128 | mr_get_led(void * p) | |
2129 | { | |
2130 | struct mr_rsp_led * r; | |
2131 | uint32_t led; | |
2132 | ||
2133 | if (mr_smc_rd(MR_SMC_LED_CODE, &led)) | |
2134 | return -MR_ERR_SMC; | |
2135 | ||
2136 | r = (struct mr_rsp_led *) p; | |
2137 | r->led = GET_BIT(0, led); | |
2138 | return sizeof(*r); | |
2139 | } | |
2140 | ||
2141 | ||
2142 | int | |
2143 | mr_get_prochot(void * p) | |
2144 | { | |
2145 | struct mr_rsp_ptrig * r; | |
2146 | uint32_t pwr0; | |
2147 | uint32_t time0; | |
2148 | ||
2149 | if (mr_smc_rd(MR_SMC_PWR_LIM_0, &pwr0) || | |
2150 | mr_smc_rd(MR_SMC_TIME_WIN_0, &time0)) | |
2151 | return -MR_ERR_SMC; | |
2152 | ||
2153 | r = (struct mr_rsp_ptrig *) p; | |
2154 | r->power = GET_BITS(15, 0, pwr0); | |
2155 | r->time = GET_BITS(15, 0, time0); | |
2156 | return sizeof(*r); | |
2157 | } | |
2158 | ||
2159 | ||
2160 | int | |
2161 | mr_get_pwralt(void * p) | |
2162 | { | |
2163 | struct mr_rsp_ptrig * r; | |
2164 | uint32_t pwr1; | |
2165 | uint32_t time1; | |
2166 | ||
2167 | if (mr_smc_rd(MR_SMC_PWR_LIM_1, &pwr1) || | |
2168 | mr_smc_rd(MR_SMC_TIME_WIN_1, &time1)) | |
2169 | return -MR_ERR_SMC; | |
2170 | ||
2171 | r = (struct mr_rsp_ptrig *) p; | |
2172 | r->power = GET_BITS(15, 0, pwr1); | |
2173 | r->time = GET_BITS(15, 0, time1); | |
2174 | return sizeof(*r); | |
2175 | } | |
2176 | ||
2177 | ||
2178 | int | |
2179 | mr_get_perst(void * p) | |
2180 | { | |
2181 | struct mr_rsp_perst * r; | |
2182 | uint32_t perst; | |
2183 | ||
2184 | if (mr_smc_rd(MR_SMC_PWR_LIM_PERS, &perst)) | |
2185 | return -MR_ERR_SMC; | |
2186 | ||
2187 | r = (struct mr_rsp_perst *) p; | |
2188 | r->perst = GET_BIT(0, perst); | |
2189 | return sizeof(*r); | |
2190 | } | |
2191 | ||
2192 | ||
2193 | int | |
2194 | mr_get_ttl(void * p) | |
2195 | { | |
2196 | struct mr_rsp_ttl * r; | |
2197 | ||
2198 | r = (struct mr_rsp_ttl *) p; | |
2199 | ||
2200 | #if USE_PM | |
2201 | mr_pm_ttl(r); | |
2202 | #endif | |
2203 | ||
2204 | return sizeof(*r); | |
2205 | } | |
2206 | ||
2207 | ||
2208 | /* | |
2209 | ** | |
2210 | ** Card specific 'Set' functions | |
2211 | ** Input screening takes place here (to the extent possible). | |
2212 | ** | |
2213 | */ | |
2214 | ||
2215 | ||
2216 | int | |
2217 | mr_set_volt(void * p) | |
2218 | { | |
2219 | #if USE_SVID | |
2220 | uint32_t err, val; | |
2221 | uint8_t svid; | |
2222 | ||
2223 | /* | |
2224 | * Ensure it's a supported value | |
2225 | * Which limits to use, physical or PM list? | |
2226 | */ | |
2227 | val = *(uint32_t *) p; | |
2228 | svid = volt2svid(val); | |
2229 | #if 1 | |
2230 | { | |
2231 | if (!svid) | |
2232 | return -MR_ERR_RANGE; | |
2233 | } | |
2234 | #else | |
2235 | { | |
2236 | int i; | |
2237 | ||
2238 | for(i = 0; i < MR_PTAB_LEN; i++) | |
2239 | if (volt.supt[i] == val) | |
2240 | break; | |
2241 | if (i == MR_PTAB_LEN) | |
2242 | return -MR_ERR_RANGE; | |
2243 | } | |
2244 | #endif | |
2245 | ||
2246 | /* | |
2247 | * Read-modify-write the core voltage VID register | |
2248 | */ | |
2249 | err = SvidCmd(SVID_VCCP, VR12Cmd_SetVID_Slow, svid); | |
2250 | printk("SetVolt: %d -> %08x (err %08x)\n", val, svid, err); | |
2251 | ||
2252 | return err ? -MR_ERR_SMC : 0; | |
2253 | #else | |
2254 | return -MR_ERR_INVOP; | |
2255 | #endif | |
2256 | } | |
2257 | ||
2258 | ||
2259 | int | |
2260 | mr_set_freq(void * p) | |
2261 | { | |
2262 | uint32_t cf, msk, new, val; | |
2263 | uint16_t rat; | |
2264 | int i; | |
2265 | ||
2266 | /* | |
2267 | * Ensure it's a supported value | |
2268 | */ | |
2269 | val = *(uint32_t *) p; | |
2270 | for(i = 0; i < MR_PTAB_LEN; i++) | |
2271 | if (freq.supt[i] == val) | |
2272 | break; | |
2273 | if (i == MR_PTAB_LEN) | |
2274 | return -MR_ERR_RANGE; | |
2275 | ||
2276 | /* | |
2277 | * Core Frequency: | |
2278 | * 11:0 Base ratio | |
2279 | * 15 Fuse override | |
2280 | * 31 Select ratio | |
2281 | * Base ratio accepted only if (bit 15 | bit 31 | OC disble) == 010 | |
2282 | * Pre-scale frequency to counter for any ICC trickery. | |
2283 | * Not nice, makes exact table matches difficult!! | |
2284 | */ | |
2285 | val = (val * icc_fwd()) / ICC_NOM; | |
2286 | rat = freq2ratio(val/1000, cpu_tab, ARRAY_SIZE(cpu_tab), 200); | |
2287 | cf = mr_sbox_rl(0, SBOX_COREFREQ); | |
2288 | msk = ~(PUT_BITS(11, 0, ~0) | PUT_BIT(15, 1) | PUT_BIT(31, 1)); | |
2289 | new = (cf & msk) | PUT_BITS(11, 0, rat) | PUT_BIT(31, 1); | |
2290 | mr_sbox_wl(0, SBOX_COREFREQ, new); | |
2291 | printk("SetFreq: %d -> %08x (%08x)\n", val, new, cf); | |
2292 | ||
2293 | /* | |
2294 | *TBD: | |
2295 | * We just changed the system's base clock without | |
2296 | * re-calibrating the APIC timer tick counters. | |
2297 | * There is probably a function call for the cpu-freq | |
2298 | * driver to deal with this, so should we call it? | |
2299 | */ | |
2300 | ||
2301 | return 0; | |
2302 | } | |
2303 | ||
2304 | ||
2305 | int | |
2306 | mr_set_plim(void * p) | |
2307 | { | |
2308 | plim.phys = *(uint32_t *) p; | |
2309 | ||
2310 | /* | |
2311 | * Notify PM of change | |
2312 | *TBD: not supported, remove? | |
2313 | */ | |
2314 | return 0; | |
2315 | } | |
2316 | ||
2317 | ||
2318 | int | |
2319 | mr_set_fan(void * p) | |
2320 | { | |
2321 | struct mr_set_fan * fc; | |
2322 | ||
2323 | /* | |
2324 | * Ensure operation is valid, i.e. no garbage | |
2325 | * in override flag (only 1 and 0 allowed) and | |
2326 | * that pwm in in range 0 through 99. | |
2327 | */ | |
2328 | fc = (struct mr_set_fan *) p; | |
2329 | if (GET_BITS(7, 1, fc->override) || fc->pwm >= 100) | |
2330 | return -MR_ERR_RANGE; | |
2331 | ||
2332 | #if USE_SMC | |
2333 | { | |
2334 | uint32_t dat; | |
2335 | ||
2336 | /* | |
2337 | * Determine the PWM-adder value, and send it to the SMC. | |
2338 | * Subsequent 'GET' fan will add the calculated PWM and | |
2339 | * this adder to report current PWM percentage. | |
2340 | * Only way to retrieve the adder is via GET_SMC(0x4b). | |
2341 | */ | |
2342 | if (fc->override) | |
2343 | dat = fc->pwm; | |
2344 | else | |
2345 | dat = 0; | |
2346 | ||
2347 | if (mr_smc_wr(MR_SMC_FAN_PWM_ADD, &dat)) | |
2348 | return -MR_ERR_SMC; | |
2349 | } | |
2350 | #else | |
2351 | /* | |
2352 | * Read-modify-write the fan override register | |
2353 | * Control of fan #1 only, don't touch #2 | |
2354 | * Note: require SMC to support SBOX registers | |
2355 | * which is not on the radar right now. | |
2356 | */ | |
2357 | { | |
2358 | uint32_t fcor, fco1, fco2; | |
2359 | ||
2360 | fcor = mr_sbox_rl(0, SBOX_SPEED_OVERRIDE_FAN); | |
2361 | fco2 = GET_BITS(31, 16, fcor); | |
2362 | if (fc->override) | |
2363 | fco1 = PUT_BIT(15, 1) | fc->pwm; | |
2364 | else | |
2365 | fco1 = 0; | |
2366 | mr_sbox_wl(0, SBOX_SPEED_OVERRIDE_FAN, | |
2367 | PUT_BITS(31, 16, fco2) | PUT_BITS(15, 0, fco1)); | |
2368 | } | |
2369 | #endif | |
2370 | ||
2371 | return 0; | |
2372 | } | |
2373 | ||
2374 | ||
2375 | int | |
2376 | mr_set_trbo(void * p) | |
2377 | { | |
2378 | uint32_t tmp; | |
2379 | #if USE_PM | |
2380 | void (* fnc)(int); | |
2381 | #endif | |
2382 | ||
2383 | /* | |
2384 | * Only values 0 and 1 allowed | |
2385 | */ | |
2386 | tmp = *(uint32_t *) p; | |
2387 | if (GET_BITS(31, 1, tmp)) | |
2388 | return -MR_ERR_RANGE; | |
2389 | trbo.set = tmp; | |
2390 | ||
2391 | #if USE_PM | |
2392 | /* | |
2393 | * Notify PM of new value | |
2394 | */ | |
2395 | fnc = pm_cb.micpm_set_turbo; | |
2396 | if (fnc) | |
2397 | fnc(trbo.set); | |
2398 | #endif | |
2399 | ||
2400 | return 0; | |
2401 | } | |
2402 | ||
2403 | ||
2404 | int | |
2405 | mr_set_led(void * p) | |
2406 | { | |
2407 | uint32_t led; | |
2408 | ||
2409 | /* | |
2410 | * Only values 0 and 1 allowed | |
2411 | */ | |
2412 | led = *(uint32_t *) p; | |
2413 | if (GET_BITS(31, 1, led)) | |
2414 | return -MR_ERR_RANGE; | |
2415 | ||
2416 | if (mr_smc_wr(MR_SMC_LED_CODE, &led)) | |
2417 | return -MR_ERR_SMC; | |
2418 | ||
2419 | return 0; | |
2420 | } | |
2421 | ||
2422 | ||
2423 | int | |
2424 | mr_set_prochot(void * p) | |
2425 | { | |
2426 | struct mr_rsp_ptrig * trig; | |
2427 | uint32_t pwr0; | |
2428 | uint32_t time0; | |
2429 | ||
2430 | trig = (struct mr_rsp_ptrig *) p; | |
2431 | pwr0 = trig->power; | |
2432 | time0 = trig->time; | |
2433 | ||
2434 | /* | |
2435 | * Check for sane values | |
2436 | *TBD: check pwr0 higher than current pwr1? | |
2437 | */ | |
2438 | if (pwr0 < 50 || pwr0 > 400) | |
2439 | return -MR_ERR_RANGE; | |
2440 | if (time0 < 50 || time0 > 1000) | |
2441 | return -MR_ERR_RANGE; | |
2442 | ||
2443 | if (mr_smc_wr(MR_SMC_PWR_LIM_0, &pwr0) || | |
2444 | mr_smc_wr(MR_SMC_TIME_WIN_0, &time0)) | |
2445 | return -MR_ERR_SMC; | |
2446 | ||
2447 | return 0; | |
2448 | } | |
2449 | ||
2450 | ||
2451 | int | |
2452 | mr_set_pwralt(void * p) | |
2453 | { | |
2454 | struct mr_rsp_ptrig * trig; | |
2455 | uint32_t pwr1; | |
2456 | uint32_t time1; | |
2457 | ||
2458 | trig = (struct mr_rsp_ptrig *) p; | |
2459 | pwr1 = trig->power; | |
2460 | time1 = trig->time; | |
2461 | ||
2462 | /* | |
2463 | * Check for sane values | |
2464 | *TBD: check pwr1 lower than current pwr0? | |
2465 | */ | |
2466 | if (pwr1 < 50 || pwr1 > 400) | |
2467 | return -MR_ERR_RANGE; | |
2468 | if (time1 < 50 || time1 > 1000) | |
2469 | return -MR_ERR_RANGE; | |
2470 | ||
2471 | if (mr_smc_wr(MR_SMC_PWR_LIM_1, &pwr1) || | |
2472 | mr_smc_wr(MR_SMC_TIME_WIN_1, &time1)) | |
2473 | return -MR_ERR_SMC; | |
2474 | ||
2475 | return 0; | |
2476 | } | |
2477 | ||
2478 | ||
2479 | int | |
2480 | mr_set_perst(void * p) | |
2481 | { | |
2482 | uint32_t perst; | |
2483 | ||
2484 | /* | |
2485 | * Only values 0 and 1 allowed | |
2486 | */ | |
2487 | perst = *(uint32_t *) p; | |
2488 | if (GET_BITS(31, 1, perst)) | |
2489 | return -MR_ERR_RANGE; | |
2490 | ||
2491 | if (mr_smc_wr(MR_SMC_PWR_LIM_PERS, &perst)) | |
2492 | return -MR_ERR_SMC; | |
2493 | ||
2494 | return 0; | |
2495 | } | |
2496 | ||
2497 | ||
2498 | #if USE_PM | |
2499 | /* | |
2500 | ** | |
2501 | ** API functions dedicated for PM support | |
2502 | ** | |
2503 | ** These functions are embedded within the MT callout table | |
2504 | ** and thus needs to follow the calling convention, which | |
2505 | ** for 'get' functions is to pass an opague pointer to a buffer | |
2506 | ** to hold retrieved data and on return get a staus code (positive | |
2507 | ** on success, negative on failures) and for 'put' functions is | |
2508 | ** to pass an opague pointer to a buffer holding input data. | |
2509 | ** | |
2510 | ** Function list as per PM needs: | |
2511 | ** | |
2512 | ** pm_get_pl0 reads 0x2c, 0x2d and 0x2e | |
2513 | ** pm_set_pl0 writes 0x2c and 0x2d | |
2514 | ** | |
2515 | ** pm_get_pl1 reads 0x2f and 0x30 | |
2516 | ** pm_set_pl1 writes 0x2f and 0x30 | |
2517 | ** | |
2518 | ** pm_get_pavg reads 0x35 and 0x36 | |
2519 | ** | |
2520 | ** pm_get_pttl reads 0x38 and 0x39 | |
2521 | ** | |
2522 | ** pm_get_volt reads 0x3c, 0x3d and 0x3e | |
2523 | ** | |
2524 | ** pm_get_temp reads 0x40, 0x43, 0x44 and 0x45 | |
2525 | ** | |
2526 | ** pm_get_tach reads 0x49 and 0x4a | |
2527 | ** | |
2528 | ** pm_get_tttl reads 0x4e and 0x4f | |
2529 | ** | |
2530 | ** pm_get_fttl reads 0x2b | |
2531 | ** pm_set_fttl writes 0x2b | |
2532 | ** | |
2533 | */ | |
2534 | ||
2535 | #include "micpm_api.h" | |
2536 | ||
2537 | int | |
2538 | pm_get_pl0(void * p) | |
2539 | { | |
2540 | struct pm_rsp_plim * r; | |
2541 | uint32_t lim, win, grd; | |
2542 | ||
2543 | lim = 0; | |
2544 | win = 0; | |
2545 | grd = 0; | |
2546 | mr_smc_rd(MR_SMC_PWR_LIM_0, &lim); | |
2547 | mr_smc_rd(MR_SMC_TIME_WIN_0, &win); | |
2548 | mr_smc_rd(MR_SMC_PWR_LIM0_GRD, &grd); | |
2549 | ||
2550 | r = (struct pm_rsp_plim *) p; | |
2551 | r->pwr_lim = GET_BITS(15, 0, lim); | |
2552 | r->time_win = GET_BITS(15, 0, win); | |
2553 | r->guard_band = GET_BITS(15, 0, grd); | |
2554 | ||
2555 | return sizeof(*r); | |
2556 | } | |
2557 | ||
2558 | int | |
2559 | pm_set_pl0(void * p) | |
2560 | { | |
2561 | struct pm_cmd_plim * r; | |
2562 | ||
2563 | /* | |
2564 | * Only lower 16 bit used | |
2565 | */ | |
2566 | r = (struct pm_cmd_plim *) p; | |
2567 | if (GET_BITS(31, 16, r->pwr_lim)) | |
2568 | return -MR_ERR_RANGE; | |
2569 | if (GET_BITS(31, 16, r->time_win)) | |
2570 | return -MR_ERR_RANGE; | |
2571 | ||
2572 | /* | |
2573 | * This does not allow caller to tell which failed. | |
2574 | *TBD: do we care? | |
2575 | */ | |
2576 | if (mr_smc_wr(MR_SMC_PWR_LIM_0, &r->pwr_lim)) | |
2577 | return -MR_ERR_SMC; | |
2578 | if (mr_smc_wr(MR_SMC_TIME_WIN_0, &r->time_win)) | |
2579 | return -MR_ERR_SMC; | |
2580 | ||
2581 | return 0; | |
2582 | } | |
2583 | ||
2584 | int | |
2585 | pm_get_pl1(void * p) | |
2586 | { | |
2587 | struct pm_rsp_plim * r; | |
2588 | uint32_t lim, win; | |
2589 | ||
2590 | lim = 0; | |
2591 | win = 0; | |
2592 | mr_smc_rd(MR_SMC_PWR_LIM_1, &lim); | |
2593 | mr_smc_rd(MR_SMC_TIME_WIN_1, &win); | |
2594 | ||
2595 | r = (struct pm_rsp_plim *) p; | |
2596 | r->pwr_lim = GET_BITS(15, 0, lim); | |
2597 | r->time_win = GET_BITS(15, 0, win); | |
2598 | r->guard_band = 0; | |
2599 | ||
2600 | return sizeof(*r); | |
2601 | } | |
2602 | ||
2603 | int | |
2604 | pm_set_pl1(void * p) | |
2605 | { | |
2606 | struct pm_cmd_plim * r; | |
2607 | ||
2608 | /* | |
2609 | * Only lower 16 bit used | |
2610 | */ | |
2611 | r = (struct pm_cmd_plim *) p; | |
2612 | if (GET_BITS(31, 16, r->pwr_lim)) | |
2613 | return -MR_ERR_RANGE; | |
2614 | if (GET_BITS(31, 16, r->time_win)) | |
2615 | return -MR_ERR_RANGE; | |
2616 | ||
2617 | /* | |
2618 | * This does not allow caller to tell which failed. | |
2619 | *TBD: do we care? | |
2620 | */ | |
2621 | if (mr_smc_wr(MR_SMC_PWR_LIM_1, &r->pwr_lim)) | |
2622 | return -MR_ERR_SMC; | |
2623 | if (mr_smc_wr(MR_SMC_TIME_WIN_1, &r->time_win)) | |
2624 | return -MR_ERR_SMC; | |
2625 | ||
2626 | return 0; | |
2627 | } | |
2628 | ||
2629 | int | |
2630 | pm_get_pavg(void * p) | |
2631 | { | |
2632 | struct pm_rsp_pavg * r; | |
2633 | uint32_t pwr0, pwr1; | |
2634 | ||
2635 | pwr0 = PUT_BITS(31, 30, 3); | |
2636 | pwr1 = PUT_BITS(31, 30, 3); | |
2637 | mr_smc_rd(MR_SMC_AVG_PWR_0, &pwr0); | |
2638 | mr_smc_rd(MR_SMC_AVG_PWR_1, &pwr1); | |
2639 | ||
2640 | r = (struct pm_rsp_pavg *) p; | |
2641 | r->stat_0 = GET_BITS(31, 30, pwr0); | |
2642 | r->stat_1 = GET_BITS(31, 30, pwr1); | |
2643 | r->pwr_0 = GET_BITS(29, 0, pwr0); | |
2644 | r->pwr_1 = GET_BITS(29, 0, pwr1); | |
2645 | ||
2646 | return sizeof(*r); | |
2647 | } | |
2648 | ||
2649 | int | |
2650 | pm_get_pttl(void * p) | |
2651 | { | |
2652 | struct pm_rsp_pttl * r; | |
2653 | uint32_t dur, ttl; | |
2654 | ||
2655 | if (mr_smc_rd(MR_SMC_PWR_TTL, &ttl)) | |
2656 | return -MR_ERR_SMC; | |
2657 | ||
2658 | r = (struct pm_rsp_pttl *) p; | |
2659 | r->pwr_ttl = GET_BIT(0, ttl); | |
2660 | dur = PUT_BITS(31, 30, 3); | |
2661 | if (r->pwr_ttl) | |
2662 | mr_smc_rd(MR_SMC_PWR_TTL_DUR, &dur); | |
2663 | r->stat_dur = GET_BITS(31, 30, dur); | |
2664 | r->duration = GET_BITS(15, 0, dur); | |
2665 | ||
2666 | return sizeof(*r); | |
2667 | } | |
2668 | ||
2669 | int | |
2670 | pm_get_volt(void * p) | |
2671 | { | |
2672 | struct pm_rsp_volt * r; | |
2673 | uint32_t vccp, vddg, vddq; | |
2674 | ||
2675 | vccp = PUT_BITS(31, 30, 3); | |
2676 | vddg = PUT_BITS(31, 30, 3); | |
2677 | vddq = PUT_BITS(31, 30, 3); | |
2678 | mr_smc_rd(MR_SMC_VOLT_VCCP, &vccp); | |
2679 | mr_smc_rd(MR_SMC_VOLT_VDDG, &vddg); | |
2680 | mr_smc_rd(MR_SMC_VOLT_VDDQ, &vddq); | |
2681 | ||
2682 | r = (struct pm_rsp_volt *) p; | |
2683 | r->stat_vccp = GET_BITS(31, 30, vccp); | |
2684 | r->stat_vddg = GET_BITS(31, 30, vddg); | |
2685 | r->stat_vddq = GET_BITS(31, 30, vddq); | |
2686 | r->vccp = GET_BITS(15, 0, vccp); | |
2687 | r->vddg = GET_BITS(15, 0, vddg); | |
2688 | r->vddq = GET_BITS(15, 0, vddq); | |
2689 | ||
2690 | return sizeof(*r); | |
2691 | } | |
2692 | ||
2693 | int | |
2694 | pm_get_temp(void * p) | |
2695 | { | |
2696 | struct pm_rsp_temp * r; | |
2697 | uint32_t cpu, vccp, vddg, vddq; | |
2698 | ||
2699 | cpu = PUT_BITS(31, 30, 3); | |
2700 | vccp = PUT_BITS(31, 30, 3); | |
2701 | vddg = PUT_BITS(31, 30, 3); | |
2702 | vddq = PUT_BITS(31, 30, 3); | |
2703 | mr_smc_rd(MR_SMC_TEMP_CPU, &cpu); | |
2704 | mr_smc_rd(MR_SMC_TEMP_VCCP, &vccp); | |
2705 | mr_smc_rd(MR_SMC_TEMP_VDDG, &vddg); | |
2706 | mr_smc_rd(MR_SMC_TEMP_VDDQ, &vddq); | |
2707 | ||
2708 | r = (struct pm_rsp_temp *) p; | |
2709 | r->stat_cpu = GET_BITS(31, 30, cpu); | |
2710 | r->stat_vccp = GET_BITS(31, 30, vccp); | |
2711 | r->stat_vddg = GET_BITS(31, 30, vddg); | |
2712 | r->stat_vddq = GET_BITS(31, 30, vddq); | |
2713 | r->cpu = GET_BITS(15, 0, cpu); | |
2714 | r->vccp = GET_BITS(15, 0, vccp); | |
2715 | r->vddg = GET_BITS(15, 0, vddg); | |
2716 | r->vddq = GET_BITS(15, 0, vddq); | |
2717 | ||
2718 | return sizeof(*r); | |
2719 | } | |
2720 | ||
2721 | int | |
2722 | pm_get_tach(void * p) | |
2723 | { | |
2724 | struct pm_rsp_tach * r; | |
2725 | uint32_t pwm, tach; | |
2726 | ||
2727 | pwm = PUT_BITS(31, 30, 3); | |
2728 | tach = PUT_BITS(31, 30, 3); | |
2729 | mr_smc_rd(MR_SMC_FAN_PWM, &pwm); | |
2730 | mr_smc_rd(MR_SMC_FAN_TACH, &tach); | |
2731 | ||
2732 | r = (struct pm_rsp_tach *) p; | |
2733 | r->stat_pwm = GET_BITS(31, 30, pwm); | |
2734 | r->stat_tach = GET_BITS(31, 30, tach); | |
2735 | r->fan_pwm = GET_BITS( 7, 0, pwm); | |
2736 | r->fan_tach = GET_BITS(15, 0, tach); | |
2737 | ||
2738 | return sizeof(*r); | |
2739 | } | |
2740 | ||
2741 | int | |
2742 | pm_get_tttl(void * p) | |
2743 | { | |
2744 | struct pm_rsp_tttl * r; | |
2745 | uint32_t dur, ttl; | |
2746 | ||
2747 | if (mr_smc_rd(MR_SMC_TRM_TTL, &ttl)) | |
2748 | return -MR_ERR_SMC; | |
2749 | ||
2750 | r = (struct pm_rsp_tttl *) p; | |
2751 | r->thrm_ttl = GET_BIT(0, ttl); | |
2752 | dur = PUT_BITS(31, 30, 3); | |
2753 | if (r->thrm_ttl) | |
2754 | mr_smc_rd(MR_SMC_TRM_TTL_DUR, &dur); | |
2755 | r->stat_dur = GET_BITS(31, 30, dur); | |
2756 | r->duration = GET_BITS(15, 0, dur); | |
2757 | ||
2758 | return sizeof(*r); | |
2759 | } | |
2760 | ||
2761 | int | |
2762 | pm_get_fttl(void * p) | |
2763 | { | |
2764 | struct pm_rsp_fttl * r; | |
2765 | uint32_t ttl; | |
2766 | ||
2767 | if (mr_smc_rd(MR_SMC_FORCE_TTL, &ttl)) | |
2768 | return MR_ERR_SMC; | |
2769 | ||
2770 | r = (struct pm_rsp_fttl *) p; | |
2771 | r->forced = GET_BIT(0, ttl); | |
2772 | ||
2773 | return sizeof(*r); | |
2774 | } | |
2775 | ||
2776 | int | |
2777 | pm_set_fttl(void * p) | |
2778 | { | |
2779 | uint32_t ttl; | |
2780 | ||
2781 | /* | |
2782 | * Only values 0 and 1 allowed | |
2783 | */ | |
2784 | ttl = ((struct pm_rsp_fttl *) p)->forced; | |
2785 | if (GET_BITS(31, 1, ttl)) | |
2786 | return -MR_ERR_RANGE; | |
2787 | ||
2788 | if (mr_smc_wr(MR_SMC_FORCE_TTL, &ttl)) | |
2789 | return -MR_ERR_SMC; | |
2790 | ||
2791 | return 0; | |
2792 | } | |
2793 | ||
2794 | #endif |