blob: a9451c5c6ee5de5383c530a7f78038324f4ff86c [file] [log] [blame]
Ying Zhang8876a512014-10-31 18:06:18 +08001/*
2 * Copyright 2014 Freescale Semiconductor, Inc.
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7#include <common.h>
8#include <command.h>
9#include <i2c.h>
Shaohui Xiedd335672015-11-11 17:58:37 +080010#include <asm/io.h>
Shaohui Xie085ac1c2016-09-07 17:56:14 +080011#ifdef CONFIG_FSL_LSCH2
Shaohui Xiedd335672015-11-11 17:58:37 +080012#include <asm/arch/immap_lsch2.h>
Rai Harninder6aa1f3b2016-03-23 17:04:38 +053013#elif defined(CONFIG_FSL_LSCH3)
14#include <asm/arch/immap_lsch3.h>
Shaohui Xiedd335672015-11-11 17:58:37 +080015#else
Ying Zhang8876a512014-10-31 18:06:18 +080016#include <asm/immap_85xx.h>
Shaohui Xiedd335672015-11-11 17:58:37 +080017#endif
Ying Zhang8876a512014-10-31 18:06:18 +080018#include "vid.h"
19
20DECLARE_GLOBAL_DATA_PTR;
21
22int __weak i2c_multiplexer_select_vid_channel(u8 channel)
23{
24 return 0;
25}
26
27/*
28 * Compensate for a board specific voltage drop between regulator and SoC
29 * return a value in mV
30 */
31int __weak board_vdd_drop_compensation(void)
32{
33 return 0;
34}
35
36/*
Rajesh Bhagatc3a662f2018-01-17 16:13:02 +053037 * Board specific settings for specific voltage value
38 */
39int __weak board_adjust_vdd(int vdd)
40{
41 return 0;
42}
43
Rajesh Bhagate6cd8d52018-01-17 16:13:03 +053044#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
45 defined(CONFIG_VOL_MONITOR_IR36021_READ)
Rajesh Bhagatc3a662f2018-01-17 16:13:02 +053046/*
Ying Zhang8876a512014-10-31 18:06:18 +080047 * Get the i2c address configuration for the IR regulator chip
48 *
49 * There are some variance in the RDB HW regarding the I2C address configuration
50 * for the IR regulator chip, which is likely a problem of external resistor
51 * accuracy. So we just check each address in a hopefully non-intrusive mode
52 * and use the first one that seems to work
53 *
54 * The IR chip can show up under the following addresses:
55 * 0x08 (Verified on T1040RDB-PA,T4240RDB-PB,X-T4240RDB-16GPA)
56 * 0x09 (Verified on T1040RDB-PA)
Ying Zhangff779052016-01-22 12:15:13 +080057 * 0x38 (Verified on T2080QDS, T2081QDS, T4240RDB)
Ying Zhang8876a512014-10-31 18:06:18 +080058 */
59static int find_ir_chip_on_i2c(void)
60{
61 int i2caddress;
62 int ret;
63 u8 byte;
64 int i;
65 const int ir_i2c_addr[] = {0x38, 0x08, 0x09};
66
67 /* Check all the address */
68 for (i = 0; i < (sizeof(ir_i2c_addr)/sizeof(ir_i2c_addr[0])); i++) {
69 i2caddress = ir_i2c_addr[i];
70 ret = i2c_read(i2caddress,
71 IR36021_MFR_ID_OFFSET, 1, (void *)&byte,
72 sizeof(byte));
73 if ((ret >= 0) && (byte == IR36021_MFR_ID))
74 return i2caddress;
75 }
76 return -1;
77}
Rajesh Bhagate6cd8d52018-01-17 16:13:03 +053078#endif
Ying Zhang8876a512014-10-31 18:06:18 +080079
80/* Maximum loop count waiting for new voltage to take effect */
81#define MAX_LOOP_WAIT_NEW_VOL 100
82/* Maximum loop count waiting for the voltage to be stable */
83#define MAX_LOOP_WAIT_VOL_STABLE 100
84/*
85 * read_voltage from sensor on I2C bus
86 * We use average of 4 readings, waiting for WAIT_FOR_ADC before
87 * another reading
88 */
89#define NUM_READINGS 4 /* prefer to be power of 2 for efficiency */
90
91/* If an INA220 chip is available, we can use it to read back the voltage
92 * as it may have a higher accuracy than the IR chip for the same purpose
93 */
94#ifdef CONFIG_VOL_MONITOR_INA220
95#define WAIT_FOR_ADC 532 /* wait for 532 microseconds for ADC */
96#define ADC_MIN_ACCURACY 4
97#else
98#define WAIT_FOR_ADC 138 /* wait for 138 microseconds for ADC */
99#define ADC_MIN_ACCURACY 4
100#endif
101
102#ifdef CONFIG_VOL_MONITOR_INA220
103static int read_voltage_from_INA220(int i2caddress)
104{
105 int i, ret, voltage_read = 0;
106 u16 vol_mon;
107 u8 buf[2];
108
109 for (i = 0; i < NUM_READINGS; i++) {
110 ret = i2c_read(I2C_VOL_MONITOR_ADDR,
111 I2C_VOL_MONITOR_BUS_V_OFFSET, 1,
112 (void *)&buf, 2);
113 if (ret) {
114 printf("VID: failed to read core voltage\n");
115 return ret;
116 }
117 vol_mon = (buf[0] << 8) | buf[1];
118 if (vol_mon & I2C_VOL_MONITOR_BUS_V_OVF) {
119 printf("VID: Core voltage sensor error\n");
120 return -1;
121 }
122 debug("VID: bus voltage reads 0x%04x\n", vol_mon);
123 /* LSB = 4mv */
124 voltage_read += (vol_mon >> I2C_VOL_MONITOR_BUS_V_SHIFT) * 4;
125 udelay(WAIT_FOR_ADC);
126 }
127 /* calculate the average */
128 voltage_read /= NUM_READINGS;
129
130 return voltage_read;
131}
132#endif
133
134/* read voltage from IR */
135#ifdef CONFIG_VOL_MONITOR_IR36021_READ
136static int read_voltage_from_IR(int i2caddress)
137{
138 int i, ret, voltage_read = 0;
139 u16 vol_mon;
140 u8 buf;
141
142 for (i = 0; i < NUM_READINGS; i++) {
143 ret = i2c_read(i2caddress,
144 IR36021_LOOP1_VOUT_OFFSET,
145 1, (void *)&buf, 1);
146 if (ret) {
147 printf("VID: failed to read vcpu\n");
148 return ret;
149 }
150 vol_mon = buf;
151 if (!vol_mon) {
152 printf("VID: Core voltage sensor error\n");
153 return -1;
154 }
155 debug("VID: bus voltage reads 0x%02x\n", vol_mon);
156 /* Resolution is 1/128V. We scale up here to get 1/128mV
157 * and divide at the end
158 */
159 voltage_read += vol_mon * 1000;
160 udelay(WAIT_FOR_ADC);
161 }
162 /* Scale down to the real mV as IR resolution is 1/128V, rounding up */
163 voltage_read = DIV_ROUND_UP(voltage_read, 128);
164
165 /* calculate the average */
166 voltage_read /= NUM_READINGS;
167
168 /* Compensate for a board specific voltage drop between regulator and
169 * SoC before converting into an IR VID value
170 */
171 voltage_read -= board_vdd_drop_compensation();
172
173 return voltage_read;
174}
175#endif
176
Rajesh Bhagat170eecf2018-01-17 16:13:05 +0530177#ifdef CONFIG_VOL_MONITOR_LTC3882_READ
178/* read the current value of the LTC Regulator Voltage */
179static int read_voltage_from_LTC(int i2caddress)
180{
181 int ret, vcode = 0;
182 u8 chan = PWM_CHANNEL0;
183
184 /* select the PAGE 0 using PMBus commands PAGE for VDD*/
185 ret = i2c_write(I2C_VOL_MONITOR_ADDR,
186 PMBUS_CMD_PAGE, 1, &chan, 1);
187 if (ret) {
188 printf("VID: failed to select VDD Page 0\n");
189 return ret;
190 }
191
192 /*read the output voltage using PMBus command READ_VOUT*/
193 ret = i2c_read(I2C_VOL_MONITOR_ADDR,
194 PMBUS_CMD_READ_VOUT, 1, (void *)&vcode, 2);
195 if (ret) {
196 printf("VID: failed to read the volatge\n");
197 return ret;
198 }
199
200 /* Scale down to the real mV as LTC resolution is 1/4096V,rounding up */
201 vcode = DIV_ROUND_UP(vcode * 1000, 4096);
202
203 return vcode;
204}
205#endif
206
Ying Zhang8876a512014-10-31 18:06:18 +0800207static int read_voltage(int i2caddress)
208{
209 int voltage_read;
210#ifdef CONFIG_VOL_MONITOR_INA220
211 voltage_read = read_voltage_from_INA220(i2caddress);
212#elif defined CONFIG_VOL_MONITOR_IR36021_READ
213 voltage_read = read_voltage_from_IR(i2caddress);
Rajesh Bhagat170eecf2018-01-17 16:13:05 +0530214#elif defined CONFIG_VOL_MONITOR_LTC3882_READ
215 voltage_read = read_voltage_from_LTC(i2caddress);
Ying Zhang8876a512014-10-31 18:06:18 +0800216#else
217 return -1;
218#endif
219 return voltage_read;
220}
221
Rajesh Bhagate6cd8d52018-01-17 16:13:03 +0530222#ifdef CONFIG_VOL_MONITOR_IR36021_SET
Ying Zhang8876a512014-10-31 18:06:18 +0800223/*
224 * We need to calculate how long before the voltage stops to drop
225 * or increase. It returns with the loop count. Each loop takes
226 * several readings (WAIT_FOR_ADC)
227 */
228static int wait_for_new_voltage(int vdd, int i2caddress)
229{
230 int timeout, vdd_current;
231
232 vdd_current = read_voltage(i2caddress);
233 /* wait until voltage starts to reach the target. Voltage slew
234 * rates by typical regulators will always lead to stable readings
235 * within each fairly long ADC interval in comparison to the
236 * intended voltage delta change until the target voltage is
237 * reached. The fairly small voltage delta change to any target
238 * VID voltage also means that this function will always complete
239 * within few iterations. If the timeout was ever reached, it would
240 * point to a serious failure in the regulator system.
241 */
242 for (timeout = 0;
243 abs(vdd - vdd_current) > (IR_VDD_STEP_UP + IR_VDD_STEP_DOWN) &&
244 timeout < MAX_LOOP_WAIT_NEW_VOL; timeout++) {
245 vdd_current = read_voltage(i2caddress);
246 }
247 if (timeout >= MAX_LOOP_WAIT_NEW_VOL) {
248 printf("VID: Voltage adjustment timeout\n");
249 return -1;
250 }
251 return timeout;
252}
253
254/*
255 * this function keeps reading the voltage until it is stable or until the
256 * timeout expires
257 */
258static int wait_for_voltage_stable(int i2caddress)
259{
260 int timeout, vdd_current, vdd;
261
262 vdd = read_voltage(i2caddress);
263 udelay(NUM_READINGS * WAIT_FOR_ADC);
264
265 /* wait until voltage is stable */
266 vdd_current = read_voltage(i2caddress);
267 /* The maximum timeout is
268 * MAX_LOOP_WAIT_VOL_STABLE * NUM_READINGS * WAIT_FOR_ADC
269 */
270 for (timeout = MAX_LOOP_WAIT_VOL_STABLE;
271 abs(vdd - vdd_current) > ADC_MIN_ACCURACY &&
272 timeout > 0; timeout--) {
273 vdd = vdd_current;
274 udelay(NUM_READINGS * WAIT_FOR_ADC);
275 vdd_current = read_voltage(i2caddress);
276 }
277 if (timeout == 0)
278 return -1;
279 return vdd_current;
280}
281
Ying Zhang8876a512014-10-31 18:06:18 +0800282/* Set the voltage to the IR chip */
283static int set_voltage_to_IR(int i2caddress, int vdd)
284{
285 int wait, vdd_last;
286 int ret;
287 u8 vid;
288
289 /* Compensate for a board specific voltage drop between regulator and
290 * SoC before converting into an IR VID value
291 */
292 vdd += board_vdd_drop_compensation();
Shaohui Xie085ac1c2016-09-07 17:56:14 +0800293#ifdef CONFIG_FSL_LSCH2
Shaohui Xiedd335672015-11-11 17:58:37 +0800294 vid = DIV_ROUND_UP(vdd - 265, 5);
295#else
Ying Zhang8876a512014-10-31 18:06:18 +0800296 vid = DIV_ROUND_UP(vdd - 245, 5);
Shaohui Xiedd335672015-11-11 17:58:37 +0800297#endif
Ying Zhang8876a512014-10-31 18:06:18 +0800298
299 ret = i2c_write(i2caddress, IR36021_LOOP1_MANUAL_ID_OFFSET,
300 1, (void *)&vid, sizeof(vid));
301 if (ret) {
302 printf("VID: failed to write VID\n");
303 return -1;
304 }
305 wait = wait_for_new_voltage(vdd, i2caddress);
306 if (wait < 0)
307 return -1;
308 debug("VID: Waited %d us\n", wait * NUM_READINGS * WAIT_FOR_ADC);
309
310 vdd_last = wait_for_voltage_stable(i2caddress);
311 if (vdd_last < 0)
312 return -1;
313 debug("VID: Current voltage is %d mV\n", vdd_last);
314 return vdd_last;
315}
Rajesh Bhagat170eecf2018-01-17 16:13:05 +0530316
317#endif
318
319#ifdef CONFIG_VOL_MONITOR_LTC3882_SET
320/* this function sets the VDD and returns the value set */
321static int set_voltage_to_LTC(int i2caddress, int vdd)
322{
323 int ret, vdd_last, vdd_target = vdd;
324
325 /* Scale up to the LTC resolution is 1/4096V */
326 vdd = (vdd * 4096) / 1000;
327
328 /* 5-byte buffer which needs to be sent following the
329 * PMBus command PAGE_PLUS_WRITE.
330 */
331 u8 buff[5] = {0x04, PWM_CHANNEL0, PMBUS_CMD_VOUT_COMMAND,
332 vdd & 0xFF, (vdd & 0xFF00) >> 8};
333
334 /* Write the desired voltage code to the regulator */
335 ret = i2c_write(I2C_VOL_MONITOR_ADDR,
336 PMBUS_CMD_PAGE_PLUS_WRITE, 1, (void *)&buff, 5);
337 if (ret) {
338 printf("VID: I2C failed to write to the volatge regulator\n");
339 return -1;
340 }
341
342 /* Wait for the volatge to get to the desired value */
343 do {
344 vdd_last = read_voltage_from_LTC(i2caddress);
345 if (vdd_last < 0) {
346 printf("VID: Couldn't read sensor abort VID adjust\n");
347 return -1;
348 }
349 } while (vdd_last != vdd_target);
350
351 return vdd_last;
352}
Ying Zhang8876a512014-10-31 18:06:18 +0800353#endif
354
355static int set_voltage(int i2caddress, int vdd)
356{
357 int vdd_last = -1;
358
359#ifdef CONFIG_VOL_MONITOR_IR36021_SET
360 vdd_last = set_voltage_to_IR(i2caddress, vdd);
Rajesh Bhagat170eecf2018-01-17 16:13:05 +0530361#elif defined CONFIG_VOL_MONITOR_LTC3882_SET
362 vdd_last = set_voltage_to_LTC(i2caddress, vdd);
Ying Zhang8876a512014-10-31 18:06:18 +0800363#else
364 #error Specific voltage monitor must be defined
365#endif
366 return vdd_last;
367}
368
Priyanka Jainf9088dd2017-01-19 11:12:27 +0530369#ifdef CONFIG_FSL_LSCH3
370int adjust_vdd(ulong vdd_override)
371{
372 int re_enable = disable_interrupts();
373 struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
374 u32 fusesr;
Rajesh Bhagate6cd8d52018-01-17 16:13:03 +0530375#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
376 defined(CONFIG_VOL_MONITOR_IR36021_READ)
Priyanka Jainf9088dd2017-01-19 11:12:27 +0530377 u8 vid, buf;
Rajesh Bhagate6cd8d52018-01-17 16:13:03 +0530378#else
379 u8 vid;
380#endif
Priyanka Jainf9088dd2017-01-19 11:12:27 +0530381 int vdd_target, vdd_current, vdd_last;
382 int ret, i2caddress;
383 unsigned long vdd_string_override;
384 char *vdd_string;
Rajesh Bhagatd600b312018-01-17 16:13:01 +0530385#ifdef CONFIG_ARCH_LS1088A
386 static const uint16_t vdd[32] = {
387 10250,
388 9875,
389 9750,
390 0, /* reserved */
391 0, /* reserved */
392 0, /* reserved */
393 0, /* reserved */
394 0, /* reserved */
395 9000,
396 0, /* reserved */
397 0, /* reserved */
398 0, /* reserved */
399 0, /* reserved */
400 0, /* reserved */
401 0, /* reserved */
402 0, /* reserved */
403 10000, /* 1.0000V */
404 10125,
405 10250,
406 0, /* reserved */
407 0, /* reserved */
408 0, /* reserved */
409 0, /* reserved */
410 0, /* reserved */
411 0, /* reserved */
412 0, /* reserved */
413 0, /* reserved */
414 0, /* reserved */
415 0, /* reserved */
416 0, /* reserved */
417 0, /* reserved */
418 0, /* reserved */
419 };
420
421#else
Priyanka Jainf9088dd2017-01-19 11:12:27 +0530422 static const uint16_t vdd[32] = {
423 10500,
424 0, /* reserved */
425 9750,
426 0, /* reserved */
427 9500,
428 0, /* reserved */
429 0, /* reserved */
430 0, /* reserved */
431 0, /* reserved */
432 0, /* reserved */
433 0, /* reserved */
434 0, /* reserved */
435 0, /* reserved */
436 0, /* reserved */
437 0, /* reserved */
438 0, /* reserved */
439 10000, /* 1.0000V */
440 0, /* reserved */
441 10250,
442 0, /* reserved */
443 10500,
444 0, /* reserved */
445 0, /* reserved */
446 0, /* reserved */
447 0, /* reserved */
448 0, /* reserved */
449 0, /* reserved */
450 0, /* reserved */
451 0, /* reserved */
452 0, /* reserved */
453 0, /* reserved */
454 0, /* reserved */
455 };
Rajesh Bhagatd600b312018-01-17 16:13:01 +0530456#endif
Priyanka Jainf9088dd2017-01-19 11:12:27 +0530457 struct vdd_drive {
458 u8 vid;
459 unsigned voltage;
460 };
461
462 ret = i2c_multiplexer_select_vid_channel(I2C_MUX_CH_VOL_MONITOR);
463 if (ret) {
464 debug("VID: I2C failed to switch channel\n");
465 ret = -1;
466 goto exit;
467 }
Rajesh Bhagate6cd8d52018-01-17 16:13:03 +0530468#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
469 defined(CONFIG_VOL_MONITOR_IR36021_READ)
Priyanka Jainf9088dd2017-01-19 11:12:27 +0530470 ret = find_ir_chip_on_i2c();
471 if (ret < 0) {
472 printf("VID: Could not find voltage regulator on I2C.\n");
473 ret = -1;
474 goto exit;
475 } else {
476 i2caddress = ret;
477 debug("VID: IR Chip found on I2C address 0x%02x\n", i2caddress);
478 }
479
480 /* check IR chip work on Intel mode*/
481 ret = i2c_read(i2caddress,
482 IR36021_INTEL_MODE_OOFSET,
483 1, (void *)&buf, 1);
484 if (ret) {
485 printf("VID: failed to read IR chip mode.\n");
486 ret = -1;
487 goto exit;
488 }
489 if ((buf & IR36021_MODE_MASK) != IR36021_INTEL_MODE) {
490 printf("VID: IR Chip is not used in Intel mode.\n");
491 ret = -1;
492 goto exit;
493 }
Rajesh Bhagate6cd8d52018-01-17 16:13:03 +0530494#endif
Priyanka Jainf9088dd2017-01-19 11:12:27 +0530495
496 /* get the voltage ID from fuse status register */
497 fusesr = in_le32(&gur->dcfg_fusesr);
498 vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT) &
499 FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK;
500 if ((vid == 0) || (vid == FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK)) {
501 vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT) &
502 FSL_CHASSIS3_DCFG_FUSESR_VID_MASK;
503 }
504 vdd_target = vdd[vid];
505
506 /* check override variable for overriding VDD */
Simon Glass64b723f2017-08-03 12:22:12 -0600507 vdd_string = env_get(CONFIG_VID_FLS_ENV);
Priyanka Jainf9088dd2017-01-19 11:12:27 +0530508 if (vdd_override == 0 && vdd_string &&
509 !strict_strtoul(vdd_string, 10, &vdd_string_override))
510 vdd_override = vdd_string_override;
511
512 if (vdd_override >= VDD_MV_MIN && vdd_override <= VDD_MV_MAX) {
513 vdd_target = vdd_override * 10; /* convert to 1/10 mV */
514 debug("VDD override is %lu\n", vdd_override);
515 } else if (vdd_override != 0) {
516 printf("Invalid value.\n");
517 }
518
519 /* divide and round up by 10 to get a value in mV */
520 vdd_target = DIV_ROUND_UP(vdd_target, 10);
521 if (vdd_target == 0) {
522 debug("VID: VID not used\n");
523 ret = 0;
524 goto exit;
525 } else if (vdd_target < VDD_MV_MIN || vdd_target > VDD_MV_MAX) {
526 /* Check vdd_target is in valid range */
527 printf("VID: Target VID %d mV is not in range.\n",
528 vdd_target);
529 ret = -1;
530 goto exit;
531 } else {
532 debug("VID: vid = %d mV\n", vdd_target);
533 }
534
535 /*
536 * Read voltage monitor to check real voltage.
537 */
538 vdd_last = read_voltage(i2caddress);
539 if (vdd_last < 0) {
540 printf("VID: Couldn't read sensor abort VID adjustment\n");
541 ret = -1;
542 goto exit;
543 }
544 vdd_current = vdd_last;
545 debug("VID: Core voltage is currently at %d mV\n", vdd_last);
Rajesh Bhagat170eecf2018-01-17 16:13:05 +0530546
547#ifdef CONFIG_VOL_MONITOR_LTC3882_SET
548 /* Set the target voltage */
549 vdd_last = vdd_current = set_voltage(i2caddress, vdd_target);
550#else
Priyanka Jainf9088dd2017-01-19 11:12:27 +0530551 /*
552 * Adjust voltage to at or one step above target.
553 * As measurements are less precise than setting the values
554 * we may run through dummy steps that cancel each other
555 * when stepping up and then down.
556 */
557 while (vdd_last > 0 &&
558 vdd_last < vdd_target) {
559 vdd_current += IR_VDD_STEP_UP;
560 vdd_last = set_voltage(i2caddress, vdd_current);
561 }
562 while (vdd_last > 0 &&
563 vdd_last > vdd_target + (IR_VDD_STEP_DOWN - 1)) {
564 vdd_current -= IR_VDD_STEP_DOWN;
565 vdd_last = set_voltage(i2caddress, vdd_current);
566 }
567
Rajesh Bhagat170eecf2018-01-17 16:13:05 +0530568#endif
Rajesh Bhagatc3a662f2018-01-17 16:13:02 +0530569 if (board_adjust_vdd(vdd_target) < 0) {
570 ret = -1;
571 goto exit;
572 }
573
Priyanka Jainf9088dd2017-01-19 11:12:27 +0530574 if (vdd_last > 0)
575 printf("VID: Core voltage after adjustment is at %d mV\n",
576 vdd_last);
577 else
578 ret = -1;
579exit:
580 if (re_enable)
581 enable_interrupts();
582 i2c_multiplexer_select_vid_channel(I2C_MUX_CH_DEFAULT);
583 return ret;
584}
585#else /* !CONFIG_FSL_LSCH3 */
Ying Zhang8876a512014-10-31 18:06:18 +0800586int adjust_vdd(ulong vdd_override)
587{
588 int re_enable = disable_interrupts();
Priyanka Jainf9088dd2017-01-19 11:12:27 +0530589#if defined(CONFIG_FSL_LSCH2)
Shaohui Xiedd335672015-11-11 17:58:37 +0800590 struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
591#else
Ying Zhang8876a512014-10-31 18:06:18 +0800592 ccsr_gur_t __iomem *gur =
593 (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
Shaohui Xiedd335672015-11-11 17:58:37 +0800594#endif
Ying Zhang8876a512014-10-31 18:06:18 +0800595 u32 fusesr;
Ying Zhang7ad5eff2016-01-22 12:15:12 +0800596 u8 vid, buf;
Ying Zhang8876a512014-10-31 18:06:18 +0800597 int vdd_target, vdd_current, vdd_last;
598 int ret, i2caddress;
599 unsigned long vdd_string_override;
600 char *vdd_string;
601 static const uint16_t vdd[32] = {
602 0, /* unused */
603 9875, /* 0.9875V */
604 9750,
605 9625,
606 9500,
607 9375,
608 9250,
609 9125,
610 9000,
611 8875,
612 8750,
613 8625,
614 8500,
615 8375,
616 8250,
617 8125,
618 10000, /* 1.0000V */
619 10125,
620 10250,
621 10375,
622 10500,
623 10625,
624 10750,
625 10875,
626 11000,
627 0, /* reserved */
628 };
629 struct vdd_drive {
630 u8 vid;
631 unsigned voltage;
632 };
633
634 ret = i2c_multiplexer_select_vid_channel(I2C_MUX_CH_VOL_MONITOR);
635 if (ret) {
636 debug("VID: I2C failed to switch channel\n");
637 ret = -1;
638 goto exit;
639 }
Rajesh Bhagate6cd8d52018-01-17 16:13:03 +0530640#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
641 defined(CONFIG_VOL_MONITOR_IR36021_READ)
Ying Zhang8876a512014-10-31 18:06:18 +0800642 ret = find_ir_chip_on_i2c();
643 if (ret < 0) {
644 printf("VID: Could not find voltage regulator on I2C.\n");
645 ret = -1;
646 goto exit;
647 } else {
648 i2caddress = ret;
649 debug("VID: IR Chip found on I2C address 0x%02x\n", i2caddress);
650 }
651
Ying Zhang7ad5eff2016-01-22 12:15:12 +0800652 /* check IR chip work on Intel mode*/
653 ret = i2c_read(i2caddress,
654 IR36021_INTEL_MODE_OOFSET,
655 1, (void *)&buf, 1);
656 if (ret) {
657 printf("VID: failed to read IR chip mode.\n");
658 ret = -1;
659 goto exit;
660 }
661 if ((buf & IR36021_MODE_MASK) != IR36021_INTEL_MODE) {
662 printf("VID: IR Chip is not used in Intel mode.\n");
663 ret = -1;
664 goto exit;
665 }
Rajesh Bhagate6cd8d52018-01-17 16:13:03 +0530666#endif
Ying Zhang7ad5eff2016-01-22 12:15:12 +0800667
Ying Zhang8876a512014-10-31 18:06:18 +0800668 /* get the voltage ID from fuse status register */
669 fusesr = in_be32(&gur->dcfg_fusesr);
670 /*
671 * VID is used according to the table below
672 * ---------------------------------------
673 * | DA_V |
674 * |-------------------------------------|
675 * | 5b00000 | 5b00001-5b11110 | 5b11111 |
676 * ---------------+---------+-----------------+---------|
677 * | D | 5b00000 | NO VID | VID = DA_V | NO VID |
678 * | A |----------+---------+-----------------+---------|
679 * | _ | 5b00001 |VID = | VID = |VID = |
680 * | V | ~ | DA_V_ALT| DA_V_ALT | DA_A_VLT|
681 * | _ | 5b11110 | | | |
682 * | A |----------+---------+-----------------+---------|
683 * | L | 5b11111 | No VID | VID = DA_V | NO VID |
684 * | T | | | | |
685 * ------------------------------------------------------
686 */
Shaohui Xie085ac1c2016-09-07 17:56:14 +0800687#ifdef CONFIG_FSL_LSCH2
Shaohui Xiedd335672015-11-11 17:58:37 +0800688 vid = (fusesr >> FSL_CHASSIS2_DCFG_FUSESR_ALTVID_SHIFT) &
689 FSL_CHASSIS2_DCFG_FUSESR_ALTVID_MASK;
690 if ((vid == 0) || (vid == FSL_CHASSIS2_DCFG_FUSESR_ALTVID_MASK)) {
691 vid = (fusesr >> FSL_CHASSIS2_DCFG_FUSESR_VID_SHIFT) &
692 FSL_CHASSIS2_DCFG_FUSESR_VID_MASK;
693 }
694#else
Ying Zhang8876a512014-10-31 18:06:18 +0800695 vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_ALTVID_SHIFT) &
696 FSL_CORENET_DCFG_FUSESR_ALTVID_MASK;
697 if ((vid == 0) || (vid == FSL_CORENET_DCFG_FUSESR_ALTVID_MASK)) {
698 vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_VID_SHIFT) &
699 FSL_CORENET_DCFG_FUSESR_VID_MASK;
700 }
Shaohui Xiedd335672015-11-11 17:58:37 +0800701#endif
Ying Zhang8876a512014-10-31 18:06:18 +0800702 vdd_target = vdd[vid];
703
704 /* check override variable for overriding VDD */
Simon Glass64b723f2017-08-03 12:22:12 -0600705 vdd_string = env_get(CONFIG_VID_FLS_ENV);
Ying Zhang8876a512014-10-31 18:06:18 +0800706 if (vdd_override == 0 && vdd_string &&
707 !strict_strtoul(vdd_string, 10, &vdd_string_override))
708 vdd_override = vdd_string_override;
709 if (vdd_override >= VDD_MV_MIN && vdd_override <= VDD_MV_MAX) {
710 vdd_target = vdd_override * 10; /* convert to 1/10 mV */
711 debug("VDD override is %lu\n", vdd_override);
712 } else if (vdd_override != 0) {
713 printf("Invalid value.\n");
714 }
715 if (vdd_target == 0) {
716 debug("VID: VID not used\n");
717 ret = 0;
718 goto exit;
719 } else {
720 /* divide and round up by 10 to get a value in mV */
721 vdd_target = DIV_ROUND_UP(vdd_target, 10);
722 debug("VID: vid = %d mV\n", vdd_target);
723 }
724
725 /*
726 * Read voltage monitor to check real voltage.
727 */
728 vdd_last = read_voltage(i2caddress);
729 if (vdd_last < 0) {
730 printf("VID: Couldn't read sensor abort VID adjustment\n");
731 ret = -1;
732 goto exit;
733 }
734 vdd_current = vdd_last;
735 debug("VID: Core voltage is currently at %d mV\n", vdd_last);
736 /*
737 * Adjust voltage to at or one step above target.
738 * As measurements are less precise than setting the values
739 * we may run through dummy steps that cancel each other
740 * when stepping up and then down.
741 */
742 while (vdd_last > 0 &&
743 vdd_last < vdd_target) {
744 vdd_current += IR_VDD_STEP_UP;
745 vdd_last = set_voltage(i2caddress, vdd_current);
746 }
747 while (vdd_last > 0 &&
748 vdd_last > vdd_target + (IR_VDD_STEP_DOWN - 1)) {
749 vdd_current -= IR_VDD_STEP_DOWN;
750 vdd_last = set_voltage(i2caddress, vdd_current);
751 }
752
753 if (vdd_last > 0)
754 printf("VID: Core voltage after adjustment is at %d mV\n",
755 vdd_last);
756 else
757 ret = -1;
758exit:
759 if (re_enable)
760 enable_interrupts();
Wenbin Song44ad75c2016-03-09 13:38:23 +0800761
762 i2c_multiplexer_select_vid_channel(I2C_MUX_CH_DEFAULT);
763
Ying Zhang8876a512014-10-31 18:06:18 +0800764 return ret;
765}
Priyanka Jainf9088dd2017-01-19 11:12:27 +0530766#endif
Ying Zhang8876a512014-10-31 18:06:18 +0800767
768static int print_vdd(void)
769{
770 int vdd_last, ret, i2caddress;
771
772 ret = i2c_multiplexer_select_vid_channel(I2C_MUX_CH_VOL_MONITOR);
773 if (ret) {
774 debug("VID : I2c failed to switch channel\n");
775 return -1;
776 }
Rajesh Bhagate6cd8d52018-01-17 16:13:03 +0530777#if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
778 defined(CONFIG_VOL_MONITOR_IR36021_READ)
Ying Zhang8876a512014-10-31 18:06:18 +0800779 ret = find_ir_chip_on_i2c();
780 if (ret < 0) {
781 printf("VID: Could not find voltage regulator on I2C.\n");
Wenbin Song44ad75c2016-03-09 13:38:23 +0800782 goto exit;
Ying Zhang8876a512014-10-31 18:06:18 +0800783 } else {
784 i2caddress = ret;
785 debug("VID: IR Chip found on I2C address 0x%02x\n", i2caddress);
786 }
Rajesh Bhagate6cd8d52018-01-17 16:13:03 +0530787#endif
Ying Zhang8876a512014-10-31 18:06:18 +0800788
789 /*
790 * Read voltage monitor to check real voltage.
791 */
792 vdd_last = read_voltage(i2caddress);
793 if (vdd_last < 0) {
794 printf("VID: Couldn't read sensor abort VID adjustment\n");
Wenbin Song44ad75c2016-03-09 13:38:23 +0800795 goto exit;
Ying Zhang8876a512014-10-31 18:06:18 +0800796 }
797 printf("VID: Core voltage is at %d mV\n", vdd_last);
Wenbin Song44ad75c2016-03-09 13:38:23 +0800798exit:
799 i2c_multiplexer_select_vid_channel(I2C_MUX_CH_DEFAULT);
800
801 return ret < 0 ? -1 : 0;
Ying Zhang8876a512014-10-31 18:06:18 +0800802
Ying Zhang8876a512014-10-31 18:06:18 +0800803}
804
805static int do_vdd_override(cmd_tbl_t *cmdtp,
806 int flag, int argc,
807 char * const argv[])
808{
809 ulong override;
810
811 if (argc < 2)
812 return CMD_RET_USAGE;
813
814 if (!strict_strtoul(argv[1], 10, &override))
815 adjust_vdd(override); /* the value is checked by callee */
816 else
817 return CMD_RET_USAGE;
818 return 0;
819}
820
821static int do_vdd_read(cmd_tbl_t *cmdtp,
822 int flag, int argc,
823 char * const argv[])
824{
825 if (argc < 1)
826 return CMD_RET_USAGE;
827 print_vdd();
828
829 return 0;
830}
831
832U_BOOT_CMD(
833 vdd_override, 2, 0, do_vdd_override,
834 "override VDD",
835 " - override with the voltage specified in mV, eg. 1050"
836);
837
838U_BOOT_CMD(
839 vdd_read, 1, 0, do_vdd_read,
840 "read VDD",
841 " - Read the voltage specified in mV"
842)