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 KnF. | |
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 | ||
51 | #include <linux/types.h> | |
52 | #include <linux/errno.h> | |
53 | #include <linux/kernel.h> | |
54 | #include <linux/mm.h> | |
55 | #include <linux/mm_types.h> | |
56 | #include <linux/io.h> | |
57 | #include <linux/utsname.h> | |
58 | #include <linux/sched.h> | |
59 | #include <linux/time.h> | |
60 | #include <linux/jiffies.h> | |
61 | #include <linux/kernel_stat.h> | |
62 | #include <linux/bitmap.h> | |
63 | #include <generated/compile.h> | |
64 | #include <generated/utsrelease.h> | |
65 | #include <mic/micbaseaddressdefine.h> | |
66 | #include <mic/micsboxdefine.h> | |
67 | #include "micras_api.h" | |
68 | #include "micmca_api.h" | |
69 | #include "micras.h" | |
70 | ||
71 | ||
72 | /* | |
73 | * Persistent data accessible through the CP api. | |
74 | * Some functions just read/modify hardware CSRs | |
75 | * and thus need no storage between invocations. | |
76 | */ | |
77 | ||
78 | extern struct mr_rsp_vers vers; | |
79 | extern struct mr_rsp_volt volt; | |
80 | extern struct mr_rsp_freq freq; | |
81 | extern struct mr_rsp_power power; | |
82 | extern struct mr_rsp_plim plim; | |
83 | extern struct mr_rsp_gddr gddr; | |
84 | extern struct mr_rsp_gvolt gvolt; | |
85 | extern struct mr_rsp_gfreq gfreq; | |
86 | extern struct mr_rsp_temp temp; | |
87 | extern struct mr_rsp_ecc ecc; | |
88 | extern struct mr_rsp_trbo trbo; | |
89 | extern struct mr_rsp_pmcfg pmcfg; | |
90 | ||
91 | #if USE_FSC | |
92 | /* | |
93 | ** | |
94 | ** FSC API | |
95 | ** | |
96 | ** The FSC has a back-door communication channel, not documented | |
97 | ** anywhere in the register spec nor in any HAS or LLD that is | |
98 | ** available on recent KnF cards (later than rev ??). | |
99 | ** Found a .35 proposal for it, so it better do. In short, this | |
100 | ** backdoor relies on fan #2 is not used on KnF and the fact that | |
101 | ** controls for fan #2 is transmitted over I2C to the fan speed | |
102 | ** controller (FSC) unaltered, such that it can chose an alternate | |
103 | ** interpretation of received data. | |
104 | ** | |
105 | ** The Fan Speed Override register (SBOX 0x8007d102c) has this | |
106 | ** definition in the register spec: | |
107 | ** | |
108 | ** Bit(s) Usage | |
109 | ** ------ ---------- | |
110 | ** 7:0 Fan 1 override ratio | |
111 | ** 14 Fan 1 Set max speed | |
112 | ** 15 Fan 1 Enable override | |
113 | ** 23:16 Fan 2 override ratio | |
114 | ** 30 Fan 2 Set max speed | |
115 | ** 31 Fan 2 Enable override | |
116 | ** | |
117 | ** This register has been repurposed into a Message Gain Bit Bang Register | |
118 | ** (MGBR) with a 4 bit command and a 16 bit data field, layout is: | |
119 | ** | |
120 | ** Bit(s) Usage | |
121 | ** ------ ---------- | |
122 | ** 7:0 MGBR data 7:0 | |
123 | ** 21:14 MGBR data 15:8 | |
124 | ** 23:22 MGBR command 1:0 | |
125 | ** 31:30 MBGR command 3:2 | |
126 | ** | |
127 | ** Command Usage | |
128 | ** 0 Fan 1 Speed Override | |
129 | ** 1 Power Management and Control Config | |
130 | ** 7 PMC PCIe Alert Override | |
131 | ** 8 PMC 2x3 Alert Override | |
132 | ** 9 PMC 2x4 Alert Override | |
133 | ** 10 Temperature Override Command | |
134 | ** 11 General Status Command | |
135 | ** 12-15 PID Gain Command(s) | |
136 | ** | |
137 | ** Fan 1 control works as MGBR command 0, though the spec is unclear on | |
138 | ** whether the resulting FSO register format is same as the original spec. | |
139 | ** Specifically, old spec has Fan 1 override enable in FSO bit 15, whereas | |
140 | ** the MGBR spec has it in MGBR data bit 15 (corresponds to FSO bit 20). | |
141 | ** Test shows it has to be MGBR bit 9, i.e. compatible with register spec. | |
142 | ** | |
143 | ** Fan #2 Status Register (SBOX 0x8007d1028) has been redefined into a | |
144 | ** Message Gain Bit Bang Status (MGBSR) used to hold return data from | |
145 | ** the MGBR General Status command in this layout: | |
146 | ** | |
147 | ** Bit(s) Usage | |
148 | ** ------ ---------- | |
149 | ** 23:0 MGBSR data | |
150 | ** 31:28 MGBR Gen. Sts. selector (bits 23:0 source). | |
151 | ** | |
152 | ** To get access to KnF telemetry data, only MGBR command 11 is needed. | |
153 | ** Bits 7:0 of MGBR data for this command selects the sensor which FSC | |
154 | ** will report to MGBSR (not sure if one-time or repeatedly). The actual | |
155 | ** encoding is as follows: | |
156 | ** | |
157 | ** 0x00 Fan2Status | |
158 | ** 0x01 PMC Configuration Command Settings | |
159 | ** 0x07 Reads the 2x4 IR3275 Configuration Register | |
160 | ** 0x08 Reads the 2x3 IR3275 Configuration Register | |
161 | ** 0x09 Reads the PCIe IR3275 Configuration Register | |
162 | ** 0x0A Reads the Temperature Command Settings | |
163 | ** 0x20 Maximum Total Card Power - 1s Moving Average (20 Samples) | |
164 | ** 0x21 Maximum 2x4 Connector Power - 1s Moving Average (20 Samples) | |
165 | ** 0x22 Maximum 2x3 Connector Power - 1s Moving Average (20 Samples) | |
166 | ** 0x23 Maximum PCIe Connector Power - 1s Moving Average (20 Samples) | |
167 | ** 0x30 Maximum Total Card Power - Single Sample | |
168 | ** 0x31 Maximum 2x4 Connector Power - Single Sample | |
169 | ** 0x32 Maximum 2x3 Connector Power - Single Sample | |
170 | ** 0x33 Maximum PCIe Connector Power - Single Sample | |
171 | ** 0xA0 Returns the current Fan Tcontrol setting for the GPU temperature | |
172 | ** 0xA1 Maximum Temperature for Temperature Sensor 1 - VCCP | |
173 | ** 0xA2 Maximum Temperature for Temperature Sensor 2 - Air Inlet | |
174 | ** 0xA3 Maximum Temperature for Temperature Sensor 3 - NW GDDR | |
175 | ** 0xA4 Maximum Temperature for Temperature Sensor 4 - V1P5 VDD VR | |
176 | ** 0xA5 Maximum Temperature for Temperature Sensor 5 - Display Transmitter | |
177 | ** 0xA6 Maximum Temperature for GPU | |
178 | ** | |
179 | ** The 'return' values in MGBSR are 16 bit only, power in Watts, Temp in C. | |
180 | ** | |
181 | ** Implementation notes: | |
182 | ** > The MGBR API is timing sensitive. FSC reads the MGBR register | |
183 | ** at ~50 mSec intervals over an I2C bus and performs the command | |
184 | ** on every read, which in case of the General Status command will | |
185 | ** result in wrinting FSC internal data to the MGBSR register. | |
186 | ** A delay is required after every write to MGBR in order to | |
187 | ** ensure the FSC actually sees it. | |
188 | ** | |
189 | ** > I2C bus reads are 7 bytes, writes are 6 bytes, 1 clock at 100 kHz | |
190 | ** is 10 uSec, 1 byte roughly translates to 10 bits, so minimum delay | |
191 | ** on I2C from command written to return value is valid becomes | |
192 | ** 10 * (6 + 7) * 10 uSec = 1.3 mSec | |
193 | ** The I2C bus on KnF runs slower than 100 kHz, causing tranfers | |
194 | ** to take more time than that to finish. | |
195 | ** After the initial delay, we'll may need to wait on a result | |
196 | ** to arrive in the MGBSR register. | |
197 | ** | |
198 | ** > It seems that fan 1 override is a dynamic act, i.e. for it to | |
199 | ** be in effect the MBGR command needs to be set accordingly. | |
200 | ** Therefore, when reading telemetry, the MGBR command is set | |
201 | ** just for a period long enough for it to be seen by FSC and the | |
202 | ** result to be latched into the MGBSR register. After that period | |
203 | ** (when fan speed override is active) the MGBR is returned to | |
204 | ** restore the fan 1 override. | |
205 | ** | |
206 | */ | |
207 | ||
208 | #define MR_FSC_MGBR_OVR_CMD 0 /* Fan 1 Speed Override */ | |
209 | #define MR_FSC_MGBR_GEN_CMD 11 /* General Status command */ | |
210 | ||
211 | #define MR_FSC_STATUS 0x00 /* FSC Status & version */ | |
212 | #define MR_FSC_PMC_CFG 0x01 /* PMC Configuration */ | |
213 | ||
214 | #define MR_FSC_PWR_TOT 0x20 /* Total Power (1 sec avg) */ | |
215 | #define MR_FSC_PWR_2X4 0x21 /* 2x4 Power (1 sec avg) */ | |
216 | #define MR_FSC_PWR_2X3 0x22 /* 2x3 Power (1 sec avg) */ | |
217 | #define MR_FSC_PWR_PCIE 0x23 /* PCIe Power (1 sec avg) */ | |
218 | ||
219 | #define MR_FSC_PWR1_TOT 0x30 /* Total Power (single sample) */ | |
220 | #define MR_FSC_PWR1_2X4 0x31 /* 2x4 Power (single sample) */ | |
221 | #define MR_FSC_PWR1_2X3 0x32 /* 2x3 Power (single sample) */ | |
222 | #define MR_FSC_PWR1_PCIE 0x33 /* PCIe Power (single sample) */ | |
223 | ||
224 | #define MR_FSC_TEMP_VCCP 0xA1 /* VCCP VR Temperature */ | |
225 | #define MR_FSC_TEMP_INLET 0xA2 /* Card Inlet Temperature */ | |
226 | #define MR_FSC_TEMP_GDDR 0xA3 /* GDDR Temperature */ | |
227 | #define MR_FSC_TEMP_VDD 0xA4 /* VDD VR Temperature */ | |
228 | #define MR_FSC_TEMP_DISP 0xA5 /* Display Transmitter */ | |
229 | ||
230 | ||
231 | /* | |
232 | * Simple I/O access routines for FSC registers | |
233 | */ | |
234 | ||
235 | #ifdef MIC_IS_EMULATION | |
236 | /* | |
237 | * Emulation does not handle I2C busses in general. | |
238 | * Not sure if FSC is emulated, but won't rely on it. | |
239 | * The following stubs are for emulation only. | |
240 | */ | |
241 | ||
242 | int | |
243 | fsc_mgbr_read(uint32_t * v) | |
244 | { | |
245 | if (v) | |
246 | memset(v, 0, 4); | |
247 | ||
248 | return 0; | |
249 | } | |
250 | ||
251 | void | |
252 | fsc_mgbr_write(uint8_t c, uint32_t v) | |
253 | { | |
254 | } | |
255 | ||
256 | #else | |
257 | ||
258 | #if 0 | |
259 | #define RL printk("%s: %2x -> %08x\n", __FUNCTION__, mgbr_cmd, *val) | |
260 | #define WL printk("%s: %2x <- %08x\n", __FUNCTION__, mgbr_cmd, *val) | |
261 | #else | |
262 | #define RL /* As nothing */ | |
263 | #define WL /* As nothing */ | |
264 | #endif | |
265 | ||
266 | static uint8_t mgbr_cmd; /* Last MGBR command */ | |
267 | static uint32_t mgbr_dat; /* Last MGBR data */ | |
268 | static uint32_t fan1_ovr; /* Current fan 1 override command */ | |
269 | ||
270 | /* | |
271 | * Read MGBSR from SBOX | |
272 | * | |
273 | * This function only support MGBR commands MR_FSC_MGBR_{OVR|GEN}_CMD. | |
274 | * The operation mode is that the command is written to MGBR and after | |
275 | * a while the response shows up in MGBSR, which has fields that tell | |
276 | * which command caused the response (bits 31:28), and for GEN command | |
277 | * also which sensor was read. This function checks both fields. | |
278 | * | |
279 | * We'll poll at 1 mSec rate and allow up to 200 mSec for the | |
280 | * FSC to provide the measure in the SBOX register. | |
281 | */ | |
282 | ||
283 | int | |
284 | fsc_mgbsr_read(uint32_t * val) | |
285 | { | |
286 | uint32_t mgbsr; | |
287 | int n; | |
288 | ||
289 | for(n = 0; n < 200; n++) { | |
290 | mgbsr = mr_sbox_rl(0, SBOX_STATUS_FAN2); | |
291 | if ((GET_BITS(31, 28, mgbsr) == mgbr_cmd) || | |
292 | mgbr_cmd != MR_FSC_MGBR_GEN_CMD || mgbr_dat == 0) { | |
293 | if (mgbr_cmd != MR_FSC_MGBR_GEN_CMD || | |
294 | mgbr_dat <= 1) { | |
295 | *val = GET_BITS(23, 0, mgbsr); | |
296 | RL; | |
297 | return 0; | |
298 | } | |
299 | if (GET_BITS(23, 16, mgbsr) == mgbr_dat) { | |
300 | *val = GET_BITS(15, 0, mgbsr); | |
301 | RL; | |
302 | return 0; | |
303 | } | |
304 | } | |
305 | myDELAY(1000); | |
306 | } | |
307 | ||
308 | /* | |
309 | * Timeout | |
310 | */ | |
311 | return 1; | |
312 | } | |
313 | ||
314 | ||
315 | /* | |
316 | * Write MGBR on SBOX | |
317 | * | |
318 | * This function only support MGBR commands MR_FSC_MGBR_{OVR|GEN}_CMD. | |
319 | * The OVR command only when fan 1 speed override is active. | |
320 | * The GEN command is meant to cause a new selectable telemetry to be | |
321 | * pushed into the MBGSR register by the FSC. Any necessary delays | |
322 | * are handled here. Not by the read function. | |
323 | */ | |
324 | ||
325 | void | |
326 | fsc_mgbr_write(uint8_t c, uint32_t * val) | |
327 | { | |
328 | uint32_t prev_cmd, prev_dat; | |
329 | uint32_t mgbr_reg, mgbr_sel; | |
330 | uint32_t mgbsr, n; | |
331 | ||
332 | prev_cmd = mgbr_cmd; | |
333 | prev_dat = mgbr_dat; | |
334 | mgbr_cmd = GET_BITS(3, 0, c); | |
335 | mgbr_dat = GET_BITS(15, 0, *val); | |
336 | ||
337 | mgbr_reg = PUT_BITS(31, 30, (mgbr_cmd >> 2)) | | |
338 | PUT_BITS(23, 22, mgbr_cmd) | | |
339 | PUT_BITS(21, 14, (mgbr_dat >> 8)) | | |
340 | PUT_BITS( 7, 0, mgbr_dat); | |
341 | WL; | |
342 | mr_sbox_wl(0, SBOX_SPEED_OVERRIDE_FAN, mgbr_reg); | |
343 | ||
344 | /* | |
345 | * Special for Set Fan Speed, we keep track of that one | |
346 | */ | |
347 | if (mgbr_cmd == MR_FSC_MGBR_OVR_CMD) { | |
348 | if (GET_BIT(9, mgbr_dat)) | |
349 | fan1_ovr = GET_BITS(9, 0, mgbr_dat); | |
350 | else | |
351 | fan1_ovr = 0; | |
352 | } | |
353 | ||
354 | /* | |
355 | * If the command issued is the same as the previous command, | |
356 | * there is no way to determine if the MGBSR register is result | |
357 | * of this or the previous command. It is not possible to clear | |
358 | * MGBSR (read-only register), so if it is the same register, | |
359 | * we'll just have to wait long enough for FSC to respond. | |
360 | * Not all MGBR commands are mirrored into top 4 bits of MGBSR, | |
361 | * those gets the simple delay treatment. | |
362 | */ | |
363 | if ((mgbr_cmd == prev_cmd && mgbr_dat == prev_dat) || | |
364 | mgbr_cmd != MR_FSC_MGBR_GEN_CMD || mgbr_dat <= 1) { | |
365 | myDELAY(100 * 1000); | |
366 | return; | |
367 | } | |
368 | mgbr_sel = GET_BITS(7, 0, mgbr_dat); | |
369 | for(n = 0; n < 200; n++) { | |
370 | mgbsr = mr_sbox_rl(0, SBOX_STATUS_FAN2); | |
371 | if (GET_BITS(31, 28, mgbsr) == mgbr_cmd) { | |
372 | if (mgbr_cmd != MR_FSC_MGBR_GEN_CMD) | |
373 | return; | |
374 | if (GET_BITS(23, 16, mgbsr) == mgbr_sel) | |
375 | return; | |
376 | } | |
377 | myDELAY(1000); | |
378 | } | |
379 | } | |
380 | #undef RL | |
381 | #undef WL | |
382 | #endif /* EMULATION */ | |
383 | ||
384 | ||
385 | /* | |
386 | * Bypass for FSC access. | |
387 | * Somewhat bizarre backdoor to the FSC's MGBR and MGBSR registers. | |
388 | * The FSC interface is asymmetrical by nature since only the General | |
389 | * Status MGBR command can cause data to be returned through MGBSR. | |
390 | * To make it appear as telemetry registers can be read directly | |
391 | * and without need for privileges, the Read operation is rigged to | |
392 | * issue the appropriate MGBR registers itself when necessary. | |
393 | * | |
394 | * To protect the FSC integrity, the SET command are restricted | |
395 | * to privileged users and is only accepting commands that cannot | |
396 | * harm the FSC integrity. For now the whitelist consists of | |
397 | * 0 Fan 1 Speed Override | |
398 | * 1 Power Management and Control Config | |
399 | * 11 General Status command | |
400 | * | |
401 | * To read back the response from a SET command the exact same value | |
402 | * of 'parm' must be passed to a subsequent GET, in which case the | |
403 | * the GET routine will not insert it's own MGBR command to select | |
404 | * contents of the MGBSR to return. | |
405 | * | |
406 | * Notice that FSC read is equivalent of reading Fan #2 Status register | |
407 | * and FSC write is equivalent of writing Fan Speed Override register. | |
408 | * | |
409 | * This reuse the SMC interface structs, but the semantics are different. | |
410 | * | |
411 | * Return: | |
412 | * r->reg MGBSR sensor select (if applicable) or 0 | |
413 | * r->width always 3 (24 bit wide field) | |
414 | * r->rtn.val MGBSR sensor data | |
415 | * | |
416 | * Input: | |
417 | * parm 31:24 MGBR command (must be 0xb) | |
418 | * parm 15:0 MGBR data (sensor select) | |
419 | */ | |
420 | ||
421 | int | |
422 | mr_get_fsc(void * p) | |
423 | { | |
424 | int rtn; | |
425 | uint32_t raw; | |
426 | struct mr_rsp_smc * r; | |
427 | uint8_t cmd; | |
428 | uint32_t dat, parm; | |
429 | ||
430 | /* | |
431 | * Extract MGBR command and dat | |
432 | */ | |
433 | parm = * (uint32_t *) p; | |
434 | cmd = GET_BITS(31, 24, parm); | |
435 | dat = GET_BITS(15, 0, parm); | |
436 | ||
437 | /* | |
438 | * If the request is different from the last issued | |
439 | * 'SET' command in any way then 'GET' will issue the | |
440 | * corresponding MGBR command, if allowed. | |
441 | */ | |
442 | if (mgbr_cmd != cmd || mgbr_dat != dat) { | |
443 | /* | |
444 | * Only allow 'General Status' command | |
445 | */ | |
446 | if (cmd != MR_FSC_MGBR_GEN_CMD) | |
447 | return -MR_ERR_PERM; | |
448 | ||
449 | /* | |
450 | * Screen against known FSC register widths. | |
451 | * All commands seems to be 16 bit wide. | |
452 | * We insist that unused upper bits are zeros. | |
453 | */ | |
454 | if (dat != GET_BITS(23, 0, parm)) | |
455 | return -MR_ERR_INVAUX; | |
456 | ||
457 | /* | |
458 | * Better way to single out these numbers? | |
459 | * 0 1 20 21 22 23 30 31 32 33 a1 a2 a3 a4 a5 | |
460 | */ | |
461 | if (! ((dat <= 1) || | |
462 | (dat >= 0x20 && dat <= 0x23) || | |
463 | (dat >= 0x30 && dat <= 0x33) || | |
464 | (dat >= 0xa1 && dat <= 0xa5))) | |
465 | return -MR_ERR_PERM; | |
466 | ||
467 | /* | |
468 | * Write MGBR command | |
469 | */ | |
470 | fsc_mgbr_write(cmd, &dat); | |
471 | } | |
472 | ||
473 | /* | |
474 | * Read MGBSR result | |
475 | */ | |
476 | rtn = fsc_mgbsr_read(&raw); | |
477 | if (rtn) | |
478 | return -MR_ERR_SMC; | |
479 | ||
480 | /* | |
481 | * Revert to normal if fan 1 speed override mode if needed. | |
482 | */ | |
483 | if (fan1_ovr) | |
484 | fsc_mgbr_write(MR_FSC_MGBR_OVR_CMD, &fan1_ovr); | |
485 | ||
486 | r = (struct mr_rsp_smc *) p; | |
487 | if (cmd == MR_FSC_MGBR_GEN_CMD) | |
488 | r->reg = GET_BITS(7, 0, dat); | |
489 | r->width = 3; | |
490 | r->rtn.val = GET_BITS(23, 0, raw); | |
491 | ||
492 | return sizeof(*r); | |
493 | } | |
494 | ||
495 | ||
496 | int | |
497 | mr_set_fsc(void * p) | |
498 | { | |
499 | uint8_t cmd; | |
500 | uint32_t dat, parm; | |
501 | ||
502 | parm = * (uint32_t *) p; | |
503 | cmd = GET_BITS(31, 24, parm); | |
504 | dat = GET_BITS(15, 0, parm); | |
505 | ||
506 | /* | |
507 | * Screen against known FSC register widths. | |
508 | * All commands seems to be 16 bit wide. | |
509 | * We insist that unused upper bits are zeros. | |
510 | */ | |
511 | if (dat != GET_BITS(23, 0, parm)) | |
512 | return -MR_ERR_INVAUX; | |
513 | ||
514 | /* | |
515 | * 4-bit command code for FSC. | |
516 | * Mask of valid codes needs just 16 bits. | |
517 | * Max valid codes 0..1, 7..15, mask 0xff83. | |
518 | * Non-debug registers reduce mask to 0x0803. | |
519 | */ | |
520 | if (! ((1 << cmd) & 0x0803)) | |
521 | return -MR_ERR_PERM; | |
522 | ||
523 | /* | |
524 | * Write MGBR command and revert to fan 1 speed override mode | |
525 | * if needed (override in effect). Side effect of reverting | |
526 | * is that any reponse in MGBSR must to be read before next | |
527 | * FSC sample happens, i.e. within 50 mSec. | |
528 | */ | |
529 | fsc_mgbr_write(cmd, &dat); | |
530 | if (fan1_ovr) | |
531 | fsc_mgbr_write(MR_FSC_MGBR_OVR_CMD, &fan1_ovr); | |
532 | ||
533 | return 0; | |
534 | } | |
535 | #endif | |
536 | ||
537 | ||
538 | /* | |
539 | ** | |
540 | ** Conversion between CP formats (uV, MHz, etc.) | |
541 | ** and hardware register formats (SBOX mostly). | |
542 | ** | |
543 | */ | |
544 | ||
545 | ||
546 | /* | |
547 | * VRM11 voltage converters | |
548 | * Only bits 6:1 are being used as follows: | |
549 | * Volt = Max - Res * (Bits -1) | |
550 | * Bits = 1 + (Max - Volt) / Res | |
551 | * The delta divided by resolution is 62. | |
552 | * Bits value of 0 reserved for turning VR off. | |
553 | */ | |
554 | ||
555 | #define VRM11_MAX 1600000 /* 1.60 V */ | |
556 | #define VRM11_MIN 825000 /* 825 mV */ | |
557 | #define VRM11_RES 12500 /* 12.5 mV */ | |
558 | ||
559 | uint32_t | |
560 | vid2volt(uint8_t vid) | |
561 | { | |
562 | uint32_t bits; | |
563 | ||
564 | bits = GET_BITS(6, 1, vid); | |
565 | if (bits) | |
566 | return VRM11_MAX - VRM11_RES * (bits - 1); | |
567 | else | |
568 | return 0; | |
569 | } | |
570 | ||
571 | uint8_t | |
572 | volt2vid(uint32_t uv) | |
573 | { | |
574 | uint32_t delta, bits; | |
575 | ||
576 | bits = 0; | |
577 | if (uv >= VRM11_MIN && uv <= VRM11_MAX) { | |
578 | delta = VRM11_MAX - uv; | |
579 | /* | |
580 | * Why bother check for accurate input? | |
581 | * Ignoring it just rounds up to nearest! | |
582 | */ | |
583 | if (! (delta % VRM11_RES)) | |
584 | bits = 1 + delta / VRM11_RES; | |
585 | } | |
586 | return PUT_BITS(6, 1, bits); | |
587 | } | |
588 | ||
589 | ||
590 | /* | |
591 | * PLL tables used to map between hw scale register | |
592 | * value and actual frequencies given a fixed base. | |
593 | * The formula is (probably KnF specific) | |
594 | * freq = Base * Feedback / Feedforward | |
595 | * where | |
596 | * Base = 100 MHz | |
597 | * FeedBack = ratio bits 5:0 | |
598 | * FeedForward = ratio bits 7:6 (00 -> 8, 01 -> 4, 10 -> 2, 11 -> 1) | |
599 | * | |
600 | * Overlapping ranges over feedback and feedforward values are | |
601 | * handled by range table(s) below such that lower frequencies | |
602 | * can be selected at a finer granularity. | |
603 | */ | |
604 | ||
605 | struct pll_tab { | |
606 | uint8_t clk_div; /* Feed forward */ | |
607 | uint8_t min_mul; /* Lower feedback */ | |
608 | uint8_t max_mul; /* Upper feedback */ | |
609 | uint16_t min_clk; /* Lower frequency */ | |
610 | uint16_t max_clk; /* Upper frequency */ | |
611 | uint8_t step_size; /* Granularity */ | |
612 | } cpu_tab[] = { /* CPU PLL */ | |
613 | { 1, 20, 40, 2000, 4000, 100}, | |
614 | { 2, 20, 39, 1000, 1950, 50}, | |
615 | { 4, 20, 39, 500, 975, 25}, | |
616 | }, gddr_tab[] = { /* GDDR PLL */ | |
617 | {1, 14, 30, 1400, 3000, 100}, | |
618 | {2, 12, 27, 600, 1350, 50}, | |
619 | }; | |
620 | ||
621 | #define B_CLK 100 /* Base clock (MHz) */ | |
622 | ||
623 | static uint16_t | |
624 | ratio2freq(uint8_t ratio, struct pll_tab * tab, int tablen) | |
625 | { | |
626 | uint16_t fwd, bck; | |
627 | ||
628 | fwd = GET_BITS(7, 6, ~ratio); | |
629 | bck = GET_BITS(5, 0, ratio); | |
630 | ||
631 | if (fwd < tablen && bck >= tab[fwd].min_mul && bck <= tab[fwd].max_mul) | |
632 | return (B_CLK * bck) / tab[fwd].clk_div; | |
633 | ||
634 | return 0; | |
635 | } | |
636 | ||
637 | static uint8_t | |
638 | freq2ratio(uint16_t freq, struct pll_tab * tab, int tablen) | |
639 | { | |
640 | int fwd; | |
641 | ||
642 | for(fwd = tablen - 1; fwd >= 0; fwd--) { | |
643 | if (freq >= tab[fwd].min_clk && freq <= tab[fwd].max_clk) { | |
644 | /* | |
645 | * Why bother check for accurate input? | |
646 | * Ignoring just rounds down to nearest supported! | |
647 | */ | |
648 | if (freq % tab[fwd].step_size) | |
649 | break; | |
650 | ||
651 | return PUT_BITS(7, 6, ~fwd) | | |
652 | PUT_BITS(5, 0, (freq * tab[fwd].clk_div) / B_CLK); | |
653 | } | |
654 | } | |
655 | ||
656 | return 0; | |
657 | } | |
658 | ||
659 | static uint32_t | |
660 | mr_mt_gf_r2f(uint8_t pll) | |
661 | { | |
662 | return 1000 * ratio2freq(pll, gddr_tab, ARRAY_SIZE(gddr_tab)); | |
663 | } | |
664 | ||
665 | static uint32_t | |
666 | mr_mt_cf_r2f(uint8_t pll) | |
667 | { | |
668 | return 1000 * ratio2freq(pll, cpu_tab, ARRAY_SIZE(cpu_tab)); | |
669 | } | |
670 | ||
671 | ||
672 | /* | |
673 | * Board voltage sense converter | |
674 | * Two 10 bit read-outs from SBOX register 0x1038. | |
675 | * The format is very poorly documented, so no | |
676 | * warranty on this conversion. Assumption is | |
677 | * the reading is a binary fixed point number. | |
678 | * bit 15 Valid reading if set | |
679 | * bit 9:8 2 bit integer part | |
680 | * bit 7:0 8 bit fraction part | |
681 | * Return value is 0 (invalid) or voltage i uV. | |
682 | */ | |
683 | ||
684 | uint32_t | |
685 | bvs2volt(uint16_t sense) | |
686 | { | |
687 | uint32_t res, f, msk; | |
688 | ||
689 | if (! GET_BIT(15, sense)) | |
690 | return 0; | |
691 | ||
692 | /* | |
693 | * First get integer contribution | |
694 | * Then accumulate fraction contributions. | |
695 | * Divide and add fraction if corresponding bit set. | |
696 | */ | |
697 | res = 1000000 * GET_BITS(9, 8, sense); | |
698 | for(msk = (1 << 7), f = 1000000/2; msk && f; msk >>= 1, f >>= 1) | |
699 | if (sense & msk) | |
700 | res += f; | |
701 | ||
702 | return res; | |
703 | } | |
704 | ||
705 | ||
706 | ||
707 | /* | |
708 | ** | |
709 | ** Initializations | |
710 | ** | |
711 | ** This has two intended purposes: | |
712 | ** - Do a on-time effort to collect info on properties that | |
713 | ** are not going to change after the initial setup by | |
714 | ** either bootstrap or kernel initialization. | |
715 | ** - Collect initial values on things we can modify. | |
716 | ** Intent is that unloading the ras module should reset | |
717 | ** all state to that of the time the module was loaded. | |
718 | ** | |
719 | */ | |
720 | ||
721 | static void __init | |
722 | mr_mk_cf_lst(void) | |
723 | { | |
724 | int i, n; | |
725 | uint16_t f; | |
726 | ||
727 | n = 0; | |
728 | for(i = ARRAY_SIZE(cpu_tab) -1; i >= 0; i--) { | |
729 | for(f = cpu_tab[i].min_clk; | |
730 | f <= cpu_tab[i].max_clk; | |
731 | f += cpu_tab[i].step_size) { | |
732 | freq.supt[n] = 1000 * f; | |
733 | freq.slen = ++n; | |
734 | if (n >= MR_PTAB_LEN) | |
735 | return; | |
736 | } | |
737 | } | |
738 | } | |
739 | ||
740 | static void __init | |
741 | mr_mk_gf_lst(void) | |
742 | { | |
743 | int i, n; | |
744 | uint16_t f; | |
745 | ||
746 | n = 0; | |
747 | for(i = ARRAY_SIZE(gddr_tab) -1; i >= 0; i--) { | |
748 | for(f = gddr_tab[i].min_clk; | |
749 | f <= gddr_tab[i].max_clk; | |
750 | f += gddr_tab[i].step_size) { | |
751 | gfreq.supt[n] = 1000 * f; | |
752 | gfreq.slen = ++n; | |
753 | if (n == MR_PTAB_LEN) | |
754 | return; | |
755 | } | |
756 | } | |
757 | } | |
758 | ||
759 | static void __init | |
760 | mr_mk_cv_lst(void) | |
761 | { | |
762 | int n; | |
763 | uint32_t cv; | |
764 | ||
765 | n = 0; | |
766 | for(cv = VRM11_MIN; cv <= VRM11_MAX; cv += VRM11_RES) { | |
767 | volt.supt[n] = cv; | |
768 | volt.slen = ++n; | |
769 | if (n >= MR_PTAB_LEN) | |
770 | return; | |
771 | } | |
772 | } | |
773 | ||
774 | ||
775 | void __init | |
776 | mr_mt_card_init(void) | |
777 | { | |
778 | uint8_t * boot, * stage2, * parm; | |
779 | uint32_t scr7, scr9, fsc; | |
780 | uint32_t cv, cf, gv; | |
781 | int i, j; | |
782 | ||
783 | /* | |
784 | * VERS: | |
785 | * Map flash and scan for version strings. | |
786 | * Different methods for KnF and KnC. | |
787 | */ | |
788 | boot = ioremap(MIC_SPI_BOOTLOADER_BASE, MIC_SPI_BOOTLOADER_SIZE); | |
789 | stage2 = ioremap(MIC_SPI_2ND_STAGE_BASE, MIC_SPI_2ND_STAGE_SIZE); | |
790 | parm = ioremap(MIC_SPI_PARAMETER_BASE, MIC_SPI_PARAMETER_SIZE); | |
791 | if (!boot || !stage2 || !parm) { | |
792 | printk("mr_mt_init: ioremap failure: boot %p, stage2 %p, par %p\n", | |
793 | boot, stage2, parm); | |
794 | goto fail_iomap; | |
795 | } | |
796 | ||
797 | /* | |
798 | * Build numbers for fboot0 and fboot 1 repectively | |
799 | */ | |
800 | scr7 = mr_sbox_rl(0, SBOX_SCRATCH7); | |
801 | ||
802 | /* | |
803 | * Boot block scan: | |
804 | * Scan for string 'fboot0 version:' or use a 16 bit offset af offset 0xfff8. | |
805 | * The latter points directly to the numeral, not to the string mentioned. | |
806 | */ | |
807 | for(i = 0; i < MIC_SPI_BOOTLOADER_SIZE - 32; i++) { | |
808 | if (boot[i] != 'f') | |
809 | continue; | |
810 | ||
811 | if (! memcmp(boot + i, "fboot0 version:", 15)) { | |
812 | vers.fboot0[0] = scnprintf(vers.fboot0 + 1, MR_VERS_LEN -2, | |
813 | "%s (build %d)", boot + i, GET_BITS(15, 0, scr7)); | |
814 | break; | |
815 | } | |
816 | } | |
817 | ||
818 | /* | |
819 | * Stage 2 scan: | |
820 | * Scan for the magic string that locates the bootstrap version. This | |
821 | * area is formatted as '<txt> (<\0>, <vers>)', so the string we are | |
822 | * looking for is 23 bytes later. | |
823 | */ | |
824 | for(i = 0; i < MIC_SPI_2ND_STAGE_SIZE - 32; i++) { | |
825 | if (stage2[i] != 'L') | |
826 | continue; | |
827 | ||
828 | if (! memcmp(stage2 + i, "Larrabee bootstrap", 18)) { | |
829 | vers.fboot1[0] = scnprintf(vers.fboot1 + 1, MR_VERS_LEN -2, | |
830 | "fboot1 version: %s", stage2 + i + 23); | |
831 | vers.fboot1[0] = scnprintf(vers.fboot1 + vers.fboot1[0], MR_VERS_LEN -2, | |
832 | " (build %d)", GET_BITS(31, 16, scr7)); | |
833 | break; | |
834 | } | |
835 | } | |
836 | ||
837 | /* | |
838 | * Parameter block scan: | |
839 | * On 4 byte aligned locations, look for chars 'EOB_'. | |
840 | * Numerical values for that string is 0x5f424f45. | |
841 | */ | |
842 | for(i = j = 0; i < MIC_SPI_PARAMETER_SIZE; i += sizeof(uint32_t)) | |
843 | if (*(uint32_t *)(parm + i) == 0x5f424f45) { | |
844 | vers.flash[j][0] = scnprintf(vers.flash[j] + 1, MR_VERS_LEN -2, | |
845 | "flash %c%c%c%c version: %s", | |
846 | parm[i+4], parm[i+5], parm[i+6], parm[i+7], parm + i + 32); | |
847 | if (++j >= ARRAY_SIZE(vers.flash)) | |
848 | break; | |
849 | } | |
850 | ||
851 | fail_iomap: | |
852 | if (boot) | |
853 | iounmap(boot); | |
854 | if (stage2) | |
855 | iounmap(stage2); | |
856 | if (parm) | |
857 | iounmap(parm); | |
858 | ||
859 | #if USE_FSC | |
860 | /* | |
861 | * Reset SMC registers to default (MGBR cmd 0, data 0). | |
862 | */ | |
863 | mr_sbox_wl(0, SBOX_SPEED_OVERRIDE_FAN, 0); | |
864 | ||
865 | /* | |
866 | * The MGBR Status has this layout for (MGBR command 0). | |
867 | * 7:0 Firmware version | |
868 | * 10:8 Card straps | |
869 | * 11 Fan disable | |
870 | * 20:12 Temperatur sensor 5 | |
871 | * 27:21 Reserved | |
872 | * 31:28 Command (0) | |
873 | */ | |
874 | #else | |
875 | /* | |
876 | * Contrary to register spec, the fan speed controller | |
877 | * 2 status register has been redefined to hold version | |
878 | * information of the FSC firmware. | |
879 | * 7:0 Revision | |
880 | * 10:8 FSC straps | |
881 | * 11 Fan disable | |
882 | * 19:12 Temperatur sensor 5 | |
883 | * 27:20 Reserved | |
884 | * 28 BIOS clear | |
885 | * 31:29 Reserved | |
886 | * This is probably an early version of the MGBR hack. | |
887 | */ | |
888 | #endif | |
889 | ||
890 | /* | |
891 | * Retrieve FSC version and strap config | |
892 | */ | |
893 | fsc = mr_sbox_rl(0, SBOX_STATUS_FAN2); | |
894 | vers.fsc[0] = scnprintf(vers.fsc + 1, MR_VERS_LEN -2, | |
895 | "FSC firmware revision: %02x, straps %x", | |
896 | GET_BITS(7, 0, fsc), GET_BITS(10, 8, fsc)); | |
897 | ||
898 | /* | |
899 | * VOLT: | |
900 | * Report all voltages the hardware can set. | |
901 | */ | |
902 | cv = mr_sbox_rl(0, SBOX_COREVOLT); | |
903 | volt.set = vid2volt(GET_BITS(7, 0, cv)); | |
904 | mr_mk_cv_lst(); | |
905 | ||
906 | /* | |
907 | * FREQ: | |
908 | * In FreeBSD uOS the reference (nominal) frequency | |
909 | * is simply the value read from the SBOX at boot time. | |
910 | * We'll do the same and set 'def' to the same as 'current'. | |
911 | * Report all voltages the hardware can set. | |
912 | */ | |
913 | cf = mr_sbox_rl(0, SBOX_COREFREQ); | |
914 | freq.def = mr_mt_cf_r2f(GET_BITS(7, 0, cf)); | |
915 | mr_mk_cf_lst(); | |
916 | ||
917 | /* | |
918 | * GDDR: | |
919 | * See layout of scratch #9 in 'common'. | |
920 | * 23:16 Clock ratio encoding | |
921 | * 28:24 External clock frequency | |
922 | */ | |
923 | scr9 = mr_sbox_rl(0, SBOX_SCRATCH9); | |
924 | gddr.speed = 2 * mr_mt_gf_r2f(GET_BITS(23, 16, scr9)); | |
925 | ||
926 | /* | |
927 | * GVOLT: | |
928 | * Report all voltages the hardware can set. | |
929 | * Kind of silly as these cannot be changed from uOS. | |
930 | * Cheat and set 'def' to the same as 'current'. | |
931 | */ | |
932 | gv = mr_sbox_rl(0, SBOX_MEMVOLT); | |
933 | gvolt.set = vid2volt(GET_BITS(7, 0, gv)); | |
934 | ||
935 | /* | |
936 | * GFREQ: | |
937 | * Report all values the hardware can set. | |
938 | * Kind of silly as these cannot be changed from uOS. | |
939 | * Cheat and set 'ref' to the same as 'current'. | |
940 | */ | |
941 | gfreq.def = mr_mt_gf_r2f(GET_BITS(23, 16, scr9)); | |
942 | mr_mk_gf_lst(); | |
943 | ||
944 | /* | |
945 | * POWER: | |
946 | * If case FSC not working or if not compiled in, | |
947 | * preset all power readings as invalid. | |
948 | */ | |
949 | { | |
950 | struct mr_rsp_power tmp = {{0, 3}, {0, 3}, {0, 3}, | |
951 | {0, 3}, {0, 3}, {0, 3}, {0, 3}, | |
952 | {0, 0, 0, 3, 3, 3}, | |
953 | {0, 0, 0, 3, 3, 3}, | |
954 | {0, 0, 0, 3, 3, 3}}; | |
955 | power = tmp; | |
956 | } | |
957 | ||
958 | /* | |
959 | *TBD: Save card registers this module may change | |
960 | */ | |
961 | } | |
962 | ||
963 | void __exit | |
964 | mr_mt_card_exit(void) | |
965 | { | |
966 | /* | |
967 | *TBD: Restore card registers this module may change | |
968 | */ | |
969 | } | |
970 | ||
971 | ||
972 | ||
973 | /* | |
974 | ** | |
975 | ** Card specific 'Get' functions | |
976 | ** | |
977 | */ | |
978 | ||
979 | int | |
980 | mr_get_volt(void * p) | |
981 | { | |
982 | struct mr_rsp_volt * r; | |
983 | uint32_t cv, fsc; | |
984 | ||
985 | ||
986 | cv = mr_sbox_rl(0, SBOX_COREVOLT); | |
987 | volt.set = vid2volt(GET_BITS(7, 0, cv)); | |
988 | ||
989 | fsc = mr_sbox_rl(0, SBOX_BOARD_VOLTAGE_SENSE); | |
990 | volt.cur = bvs2volt(GET_BITS(15, 0, fsc)); | |
991 | ||
992 | r = (struct mr_rsp_volt *) p; | |
993 | *r = volt; | |
994 | return sizeof(*r); | |
995 | } | |
996 | ||
997 | int | |
998 | mr_get_freq(void * p) | |
999 | { | |
1000 | struct mr_rsp_freq * r; | |
1001 | uint32_t cf; | |
1002 | ||
1003 | cf = mr_sbox_rl(0, SBOX_COREFREQ); | |
1004 | freq.cur = mr_mt_cf_r2f(GET_BITS(7, 0, cf)); | |
1005 | ||
1006 | r = (struct mr_rsp_freq *) p; | |
1007 | *r = freq; | |
1008 | return sizeof(*r); | |
1009 | } | |
1010 | ||
1011 | #if USE_FSC | |
1012 | /* | |
1013 | * Get Power stats from the FSC | |
1014 | */ | |
1015 | static void | |
1016 | get_fsc_pwr(uint32_t req, struct mr_rsp_pws * pws) | |
1017 | { | |
1018 | uint32_t fsc; | |
1019 | ||
1020 | /* | |
1021 | * Read the FSC status | |
1022 | */ | |
1023 | fsc_mgbr_write(MR_FSC_MGBR_GEN_CMD, &req); | |
1024 | if (fsc_mgbsr_read(&fsc)) | |
1025 | pws->p_val = 3; | |
1026 | else { | |
1027 | pws->p_val = 0; | |
1028 | pws->prr = 1000000 * GET_BITS(15, 0, fsc); | |
1029 | } | |
1030 | } | |
1031 | #endif | |
1032 | ||
1033 | int | |
1034 | mr_get_power(void * p) | |
1035 | { | |
1036 | struct mr_rsp_power * r; | |
1037 | ||
1038 | #if USE_FSC | |
1039 | uint8_t prev_cmd; | |
1040 | uint32_t prev_dat; | |
1041 | ||
1042 | /* | |
1043 | * Backup current OVERRIDE register | |
1044 | */ | |
1045 | prev_cmd = mgbr_cmd; | |
1046 | prev_dat = mgbr_dat; | |
1047 | ||
1048 | /* | |
1049 | * Get Power stats from the FSC | |
1050 | */ | |
1051 | get_fsc_pwr(MR_FSC_PWR_TOT, &power.tot0); | |
1052 | get_fsc_pwr(MR_FSC_PWR1_TOT, &power.inst); | |
1053 | get_fsc_pwr(MR_FSC_PWR_PCIE, &power.pcie); | |
1054 | get_fsc_pwr(MR_FSC_PWR_2X3, &power.c2x3); | |
1055 | get_fsc_pwr(MR_FSC_PWR_2X4, &power.c2x4); | |
1056 | ||
1057 | /* | |
1058 | * Revert to normal or fan 1 speed override mode if needed. | |
1059 | */ | |
1060 | if (fan1_ovr) | |
1061 | fsc_mgbr_write(MR_FSC_MGBR_OVR_CMD, &fan1_ovr); | |
1062 | else | |
1063 | fsc_mgbr_write(prev_cmd, &prev_dat); | |
1064 | #endif | |
1065 | ||
1066 | r = (struct mr_rsp_power *) p; | |
1067 | *r = power; | |
1068 | return sizeof(*r); | |
1069 | } | |
1070 | ||
1071 | ||
1072 | int | |
1073 | mr_get_plim(void * p) | |
1074 | { | |
1075 | struct mr_rsp_plim * r; | |
1076 | ||
1077 | #if USE_FSC | |
1078 | uint32_t fsc, req, ofs; | |
1079 | ||
1080 | /* | |
1081 | * Read the FSC status | |
1082 | */ | |
1083 | req = MR_FSC_PMC_CFG; | |
1084 | fsc_mgbr_write(MR_FSC_MGBR_GEN_CMD, &req); | |
1085 | if (! fsc_mgbsr_read(&fsc)) { | |
1086 | ofs = 5 * GET_BITS(3, 0, fsc); | |
1087 | if (GET_BIT(4, fsc)) | |
1088 | plim.phys = 300 - ofs; | |
1089 | else | |
1090 | plim.phys = 300 + ofs; | |
1091 | plim.hmrk = plim.lmrk = plim.phys; | |
1092 | } | |
1093 | #endif | |
1094 | ||
1095 | r = (struct mr_rsp_plim *) p; | |
1096 | *r = plim; | |
1097 | return sizeof(*r); | |
1098 | } | |
1099 | ||
1100 | ||
1101 | int | |
1102 | mr_get_gfreq(void * p) | |
1103 | { | |
1104 | struct mr_rsp_gfreq * r; | |
1105 | uint32_t gbr; | |
1106 | ||
1107 | gbr = mr_sbox_rl(0, SBOX_MEMORYFREQ); | |
1108 | gfreq.cur = mr_mt_gf_r2f(GET_BITS(7, 0, gbr)); | |
1109 | ||
1110 | r = (struct mr_rsp_gfreq *) p; | |
1111 | *r = gfreq; | |
1112 | return sizeof(*r); | |
1113 | } | |
1114 | ||
1115 | ||
1116 | int | |
1117 | mr_get_gvolt(void * p) | |
1118 | { | |
1119 | struct mr_rsp_gvolt * r; | |
1120 | uint32_t gv, fsc; | |
1121 | ||
1122 | gv = mr_sbox_rl(0, SBOX_MEMVOLT); | |
1123 | gvolt.set = vid2volt(GET_BITS(7, 0, gv)); | |
1124 | ||
1125 | fsc = mr_sbox_rl(0, SBOX_BOARD_VOLTAGE_SENSE); | |
1126 | gvolt.cur = bvs2volt(GET_BITS(31, 16, fsc)); | |
1127 | ||
1128 | r = (struct mr_rsp_gvolt *) p; | |
1129 | *r = gvolt; | |
1130 | return sizeof(*r); | |
1131 | } | |
1132 | ||
1133 | int | |
1134 | mr_get_temp(void * p) | |
1135 | { | |
1136 | struct mr_rsp_temp * r; | |
1137 | uint32_t btr1, btr2; /* Board temps */ | |
1138 | uint32_t die1, die2, die3; /* Die temps */ | |
1139 | uint32_t dmx1, dmx2, dmx3; /* Max die temps */ | |
1140 | uint32_t tsta, fsc; /* Thermal status */ | |
1141 | ||
1142 | btr1 = mr_sbox_rl(0, SBOX_BOARD_TEMP1); | |
1143 | btr2 = mr_sbox_rl(0, SBOX_BOARD_TEMP2); | |
1144 | die1 = mr_sbox_rl(0, SBOX_CURRENT_DIE_TEMP0); | |
1145 | die2 = mr_sbox_rl(0, SBOX_CURRENT_DIE_TEMP1); | |
1146 | die3 = mr_sbox_rl(0, SBOX_CURRENT_DIE_TEMP2); | |
1147 | dmx1 = mr_sbox_rl(0, SBOX_MAX_DIE_TEMP0); | |
1148 | dmx2 = mr_sbox_rl(0, SBOX_MAX_DIE_TEMP1); | |
1149 | dmx3 = mr_sbox_rl(0, SBOX_MAX_DIE_TEMP2); | |
1150 | tsta = mr_sbox_rl(0, SBOX_THERMAL_STATUS); | |
1151 | fsc = mr_sbox_rl(0, SBOX_STATUS_FAN2); | |
1152 | ||
1153 | /* | |
1154 | * Board temperatures. | |
1155 | * No idea of where on the board they are located, but | |
1156 | * guessing from FreeBSD comments they are: | |
1157 | * 0 Air Inlet | |
1158 | * 1 VCCP VR | |
1159 | * 2 GDDR (not sure which chip) | |
1160 | * 3 GDDR VR | |
1161 | * The temperature read from FSC #2 seems valid, but | |
1162 | * there's no mention of where it's measured. | |
1163 | * The readings does not make much sense. | |
1164 | * Sample readings are like this: | |
1165 | * fin 32 | |
1166 | * vccp 28 (vccp VR) | |
1167 | * vddq 33 (gddr VR) | |
1168 | * vddg 28 (FSC 2) | |
1169 | * So, at least 'fin' is wrong (or fan in reverse). | |
1170 | */ | |
1171 | temp.fin.cur = (btr1 & (1 << 15)) ? GET_BITS( 8, 0, btr1) : 0; | |
1172 | temp.vccp.cur = (btr1 & (1 << 31)) ? GET_BITS(24, 16, btr1) : 0; | |
1173 | temp.gddr.cur = (btr2 & (1 << 15)) ? GET_BITS( 8, 0, btr2) : 0; | |
1174 | temp.vddq.cur = (btr2 & (1 << 31)) ? GET_BITS(24, 16, btr2) : 0; | |
1175 | temp.vddg.cur = GET_BITS(19, 12, fsc); | |
1176 | temp.brd.cur = 0; | |
1177 | if (temp.fin.cur > temp.brd.cur) | |
1178 | temp.brd.cur = temp.fin.cur; | |
1179 | if (temp.vccp.cur > temp.brd.cur) | |
1180 | temp.brd.cur = temp.vccp.cur; | |
1181 | if (temp.gddr.cur > temp.brd.cur) | |
1182 | temp.brd.cur = temp.gddr.cur; | |
1183 | if (temp.vddq.cur > temp.brd.cur) | |
1184 | temp.brd.cur = temp.vddq.cur; | |
1185 | temp.fout.c_val = 3; | |
1186 | temp.gddr.c_val = 3; | |
1187 | ||
1188 | /* | |
1189 | * Die temperatures. | |
1190 | */ | |
1191 | temp.die.cur = (tsta & (1 << 31)) ? GET_BITS(30, 22, tsta) : 0; | |
1192 | temp.dies[0].cur = GET_BITS( 8, 0, die1); | |
1193 | temp.dies[1].cur = GET_BITS(17, 9, die1); | |
1194 | temp.dies[2].cur = GET_BITS(26, 18, die1); | |
1195 | temp.dies[3].cur = GET_BITS( 8, 0, die2); | |
1196 | temp.dies[4].cur = GET_BITS(17, 9, die2); | |
1197 | temp.dies[5].cur = GET_BITS(26, 18, die2); | |
1198 | temp.dies[6].cur = GET_BITS( 8, 0, die3); | |
1199 | temp.dies[7].cur = GET_BITS(17, 9, die3); | |
1200 | temp.dies[8].cur = GET_BITS(26, 18, die3); | |
1201 | ||
1202 | /* | |
1203 | * Die max temp (min is not reported to CP). | |
1204 | */ | |
1205 | temp.dies[0].max = GET_BITS( 8, 0, dmx1); | |
1206 | temp.dies[1].max = GET_BITS(17, 9, dmx1); | |
1207 | temp.dies[2].max = GET_BITS(26, 18, dmx1); | |
1208 | temp.dies[3].max = GET_BITS( 8, 0, dmx2); | |
1209 | temp.dies[4].max = GET_BITS(17, 9, dmx2); | |
1210 | temp.dies[5].max = GET_BITS(26, 18, dmx2); | |
1211 | temp.dies[6].max = GET_BITS( 8, 0, dmx3); | |
1212 | temp.dies[7].max = GET_BITS(17, 9, dmx3); | |
1213 | temp.dies[8].max = GET_BITS(26, 18, dmx3); | |
1214 | ||
1215 | r = (struct mr_rsp_temp *) p; | |
1216 | *r = temp; | |
1217 | return sizeof(*r); | |
1218 | } | |
1219 | ||
1220 | ||
1221 | int | |
1222 | mr_get_fan(void * p) | |
1223 | { | |
1224 | struct mr_rsp_fan * r; | |
1225 | uint32_t fan1, fovr; | |
1226 | ||
1227 | r = (struct mr_rsp_fan *) p; | |
1228 | fan1 = mr_sbox_rl(0, SBOX_STATUS_FAN1); | |
1229 | ||
1230 | #if USE_FSC | |
1231 | fovr = fan1_ovr; | |
1232 | r->override = GET_BIT(9, fovr); | |
1233 | #else | |
1234 | fovr = mr_sbox_rl(0, SBOX_SPEED_OVERRIDE_FAN); | |
1235 | r->override = GET_BIT(15, fovr); | |
1236 | #endif | |
1237 | ||
1238 | r->rpm = GET_BITS(15, 0, fan1); | |
1239 | if (r->override) | |
1240 | r->pwm = GET_BITS( 7, 0, fovr); | |
1241 | else | |
1242 | r->pwm = GET_BITS(23, 16, fan1); | |
1243 | ||
1244 | return sizeof(*r); | |
1245 | } | |
1246 | ||
1247 | ||
1248 | int | |
1249 | mr_get_ecc(void * p) | |
1250 | { | |
1251 | struct mr_rsp_ecc * r; | |
1252 | ||
1253 | r = (struct mr_rsp_ecc *) p; | |
1254 | *r = ecc; | |
1255 | return sizeof(*r); | |
1256 | } | |
1257 | ||
1258 | ||
1259 | int | |
1260 | mr_get_trbo(void * p) | |
1261 | { | |
1262 | struct mr_rsp_trbo * r; | |
1263 | ||
1264 | r = (struct mr_rsp_trbo *) p; | |
1265 | *r = trbo; | |
1266 | return sizeof(*r); | |
1267 | } | |
1268 | ||
1269 | ||
1270 | int | |
1271 | mr_get_pmcfg(void * p) | |
1272 | { | |
1273 | struct mr_rsp_pmcfg * r; | |
1274 | ||
1275 | r = (struct mr_rsp_pmcfg *) p; | |
1276 | *r = pmcfg; | |
1277 | return sizeof(*r); | |
1278 | } | |
1279 | ||
1280 | ||
1281 | /* | |
1282 | ** | |
1283 | ** Card specific 'Set' functions | |
1284 | ** Input screening takes place here (to the extent possible). | |
1285 | ** | |
1286 | */ | |
1287 | ||
1288 | ||
1289 | int | |
1290 | mr_set_volt(void * p) | |
1291 | { | |
1292 | uint32_t cv, msk, new, val; | |
1293 | uint8_t vid; | |
1294 | int i; | |
1295 | ||
1296 | /* | |
1297 | * Ensure it's a supported value | |
1298 | */ | |
1299 | val = *(uint32_t *) p; | |
1300 | for(i = 0; i < MR_PTAB_LEN; i++) | |
1301 | if (volt.supt[i] == val) | |
1302 | break; | |
1303 | if (i == MR_PTAB_LEN) | |
1304 | return -MR_ERR_RANGE; | |
1305 | ||
1306 | /* | |
1307 | * Read-modify-write the core voltage VID register | |
1308 | */ | |
1309 | vid = volt2vid(val); | |
1310 | cv = mr_sbox_rl(0, SBOX_COREVOLT); | |
1311 | msk = ~PUT_BITS(7, 0, ~0); | |
1312 | new = (cv & msk) | PUT_BITS(7, 0, vid); | |
1313 | mr_sbox_wl(0, SBOX_COREVOLT, new); | |
1314 | printk("SetVolt: %d -> %08x (%08x)\n", val, new, cv); | |
1315 | ||
1316 | return 0; | |
1317 | } | |
1318 | ||
1319 | ||
1320 | int | |
1321 | mr_set_freq(void * p) | |
1322 | { | |
1323 | uint32_t cf, msk, new, val; | |
1324 | uint8_t rat; | |
1325 | int i; | |
1326 | ||
1327 | /* | |
1328 | * Ensure it's a supported value | |
1329 | */ | |
1330 | val = *(uint32_t *) p; | |
1331 | for(i = 0; i < MR_PTAB_LEN; i++) | |
1332 | if (freq.supt[i] == val) | |
1333 | break; | |
1334 | if (i == MR_PTAB_LEN) | |
1335 | return -MR_ERR_RANGE; | |
1336 | ||
1337 | /* | |
1338 | * Read-modify-write the core frequency PLL register | |
1339 | * | |
1340 | *TBD: or should we just overwrite it? | |
1341 | * Register fields (of relevance): | |
1342 | * 7:0 New PLL encoding | |
1343 | * 16 Async Operation | |
1344 | * 31 Override fuse setting | |
1345 | */ | |
1346 | rat = freq2ratio(val/1000, cpu_tab, ARRAY_SIZE(cpu_tab)); | |
1347 | cf = mr_sbox_rl(0, SBOX_COREFREQ); | |
1348 | msk = ~(PUT_BITS(7, 0, ~0) | PUT_BIT(16, 1) | PUT_BIT(31, 1)); | |
1349 | new = (cf & msk) | PUT_BITS(7, 0, rat) | PUT_BIT(31, 1); | |
1350 | mr_sbox_wl(0, SBOX_COREFREQ, new); | |
1351 | printk("SetFreq: %d -> %08x (%08x)\n", val, new, cf); | |
1352 | ||
1353 | /* | |
1354 | *TBD: | |
1355 | * We just changed the system's base clock without | |
1356 | * re-calibrating the APIC timer tick counters. | |
1357 | * There is probably a function call for the cpu-freq | |
1358 | * driver to deal with this, so should we call it? | |
1359 | */ | |
1360 | ||
1361 | return 0; | |
1362 | } | |
1363 | ||
1364 | ||
1365 | int | |
1366 | mr_set_plim(void * p) | |
1367 | { | |
1368 | plim.phys = *(uint32_t *) p; | |
1369 | return 0; | |
1370 | } | |
1371 | ||
1372 | ||
1373 | int | |
1374 | mr_set_fan(void * p) | |
1375 | { | |
1376 | struct mr_set_fan * fc; | |
1377 | ||
1378 | /* | |
1379 | * Ensure operation is valid, i.e. no garbage | |
1380 | * in override flag (only 1 and 0 allowed) and | |
1381 | * that pwm is not zero (or above lower limit?) | |
1382 | */ | |
1383 | fc = (struct mr_set_fan *) p; | |
1384 | if (GET_BITS(7, 1, fc->override) || !fc->pwm) | |
1385 | return -MR_ERR_RANGE; | |
1386 | ||
1387 | #if USE_FSC | |
1388 | { | |
1389 | uint32_t dat; | |
1390 | ||
1391 | /* | |
1392 | * Craft the default OVERRIDE command and write it to FSC | |
1393 | * through the MGBR register (command 0). | |
1394 | * This does not change the telemetry in MGBSR, so only way | |
1395 | * to ensure it gets registered by FSC is to wait it out | |
1396 | * (happens in fsc_mgbr_write function). | |
1397 | */ | |
1398 | if (fc->override) | |
1399 | dat = PUT_BIT(9, 1) | fc->pwm; | |
1400 | else | |
1401 | dat = 0; | |
1402 | fsc_mgbr_write(MR_FSC_MGBR_OVR_CMD, &dat); | |
1403 | } | |
1404 | #else | |
1405 | /* | |
1406 | * Read-modify-write the fan override register | |
1407 | * Control of fan #1 only, don't touch #2 | |
1408 | */ | |
1409 | { | |
1410 | uint32_t fcor, fco1, fco2; | |
1411 | ||
1412 | fcor = mr_sbox_rl(0, SBOX_SPEED_OVERRIDE_FAN); | |
1413 | fco2 = GET_BITS(31, 16, fcor); | |
1414 | if (fc->override) | |
1415 | fco1 = PUT_BIT(15, 1) | fc->pwm; | |
1416 | else | |
1417 | fco1 = 0; | |
1418 | mr_sbox_wl(0, SBOX_SPEED_OVERRIDE_FAN, | |
1419 | PUT_BITS(31, 16, fco2) | PUT_BITS(15, 0, fco1)); | |
1420 | } | |
1421 | #endif | |
1422 | ||
1423 | return 0; | |
1424 | } | |
1425 | ||
1426 | ||
1427 | int | |
1428 | mr_set_trbo(void * p) | |
1429 | { | |
1430 | return 0; | |
1431 | } | |
1432 |