]> git.ipfire.org Git - people/ms/u-boot.git/blob - board/freescale/common/vid.c
board: common: vid: Move IR chip specific code in flag
[people/ms/u-boot.git] / board / freescale / common / vid.c
1 /*
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>
10 #include <asm/io.h>
11 #ifdef CONFIG_FSL_LSCH2
12 #include <asm/arch/immap_lsch2.h>
13 #elif defined(CONFIG_FSL_LSCH3)
14 #include <asm/arch/immap_lsch3.h>
15 #else
16 #include <asm/immap_85xx.h>
17 #endif
18 #include "vid.h"
19
20 DECLARE_GLOBAL_DATA_PTR;
21
22 int __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 */
31 int __weak board_vdd_drop_compensation(void)
32 {
33 return 0;
34 }
35
36 /*
37 * Board specific settings for specific voltage value
38 */
39 int __weak board_adjust_vdd(int vdd)
40 {
41 return 0;
42 }
43
44 #if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
45 defined(CONFIG_VOL_MONITOR_IR36021_READ)
46 /*
47 * 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)
57 * 0x38 (Verified on T2080QDS, T2081QDS, T4240RDB)
58 */
59 static 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 }
78 #endif
79
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
103 static 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
136 static 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
177 static int read_voltage(int i2caddress)
178 {
179 int voltage_read;
180 #ifdef CONFIG_VOL_MONITOR_INA220
181 voltage_read = read_voltage_from_INA220(i2caddress);
182 #elif defined CONFIG_VOL_MONITOR_IR36021_READ
183 voltage_read = read_voltage_from_IR(i2caddress);
184 #else
185 return -1;
186 #endif
187 return voltage_read;
188 }
189
190 #ifdef CONFIG_VOL_MONITOR_IR36021_SET
191 /*
192 * We need to calculate how long before the voltage stops to drop
193 * or increase. It returns with the loop count. Each loop takes
194 * several readings (WAIT_FOR_ADC)
195 */
196 static int wait_for_new_voltage(int vdd, int i2caddress)
197 {
198 int timeout, vdd_current;
199
200 vdd_current = read_voltage(i2caddress);
201 /* wait until voltage starts to reach the target. Voltage slew
202 * rates by typical regulators will always lead to stable readings
203 * within each fairly long ADC interval in comparison to the
204 * intended voltage delta change until the target voltage is
205 * reached. The fairly small voltage delta change to any target
206 * VID voltage also means that this function will always complete
207 * within few iterations. If the timeout was ever reached, it would
208 * point to a serious failure in the regulator system.
209 */
210 for (timeout = 0;
211 abs(vdd - vdd_current) > (IR_VDD_STEP_UP + IR_VDD_STEP_DOWN) &&
212 timeout < MAX_LOOP_WAIT_NEW_VOL; timeout++) {
213 vdd_current = read_voltage(i2caddress);
214 }
215 if (timeout >= MAX_LOOP_WAIT_NEW_VOL) {
216 printf("VID: Voltage adjustment timeout\n");
217 return -1;
218 }
219 return timeout;
220 }
221
222 /*
223 * this function keeps reading the voltage until it is stable or until the
224 * timeout expires
225 */
226 static int wait_for_voltage_stable(int i2caddress)
227 {
228 int timeout, vdd_current, vdd;
229
230 vdd = read_voltage(i2caddress);
231 udelay(NUM_READINGS * WAIT_FOR_ADC);
232
233 /* wait until voltage is stable */
234 vdd_current = read_voltage(i2caddress);
235 /* The maximum timeout is
236 * MAX_LOOP_WAIT_VOL_STABLE * NUM_READINGS * WAIT_FOR_ADC
237 */
238 for (timeout = MAX_LOOP_WAIT_VOL_STABLE;
239 abs(vdd - vdd_current) > ADC_MIN_ACCURACY &&
240 timeout > 0; timeout--) {
241 vdd = vdd_current;
242 udelay(NUM_READINGS * WAIT_FOR_ADC);
243 vdd_current = read_voltage(i2caddress);
244 }
245 if (timeout == 0)
246 return -1;
247 return vdd_current;
248 }
249
250 /* Set the voltage to the IR chip */
251 static int set_voltage_to_IR(int i2caddress, int vdd)
252 {
253 int wait, vdd_last;
254 int ret;
255 u8 vid;
256
257 /* Compensate for a board specific voltage drop between regulator and
258 * SoC before converting into an IR VID value
259 */
260 vdd += board_vdd_drop_compensation();
261 #ifdef CONFIG_FSL_LSCH2
262 vid = DIV_ROUND_UP(vdd - 265, 5);
263 #else
264 vid = DIV_ROUND_UP(vdd - 245, 5);
265 #endif
266
267 ret = i2c_write(i2caddress, IR36021_LOOP1_MANUAL_ID_OFFSET,
268 1, (void *)&vid, sizeof(vid));
269 if (ret) {
270 printf("VID: failed to write VID\n");
271 return -1;
272 }
273 wait = wait_for_new_voltage(vdd, i2caddress);
274 if (wait < 0)
275 return -1;
276 debug("VID: Waited %d us\n", wait * NUM_READINGS * WAIT_FOR_ADC);
277
278 vdd_last = wait_for_voltage_stable(i2caddress);
279 if (vdd_last < 0)
280 return -1;
281 debug("VID: Current voltage is %d mV\n", vdd_last);
282 return vdd_last;
283 }
284 #endif
285
286 static int set_voltage(int i2caddress, int vdd)
287 {
288 int vdd_last = -1;
289
290 #ifdef CONFIG_VOL_MONITOR_IR36021_SET
291 vdd_last = set_voltage_to_IR(i2caddress, vdd);
292 #else
293 #error Specific voltage monitor must be defined
294 #endif
295 return vdd_last;
296 }
297
298 #ifdef CONFIG_FSL_LSCH3
299 int adjust_vdd(ulong vdd_override)
300 {
301 int re_enable = disable_interrupts();
302 struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
303 u32 fusesr;
304 #if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
305 defined(CONFIG_VOL_MONITOR_IR36021_READ)
306 u8 vid, buf;
307 #else
308 u8 vid;
309 #endif
310 int vdd_target, vdd_current, vdd_last;
311 int ret, i2caddress;
312 unsigned long vdd_string_override;
313 char *vdd_string;
314 #ifdef CONFIG_ARCH_LS1088A
315 static const uint16_t vdd[32] = {
316 10250,
317 9875,
318 9750,
319 0, /* reserved */
320 0, /* reserved */
321 0, /* reserved */
322 0, /* reserved */
323 0, /* reserved */
324 9000,
325 0, /* reserved */
326 0, /* reserved */
327 0, /* reserved */
328 0, /* reserved */
329 0, /* reserved */
330 0, /* reserved */
331 0, /* reserved */
332 10000, /* 1.0000V */
333 10125,
334 10250,
335 0, /* reserved */
336 0, /* reserved */
337 0, /* reserved */
338 0, /* reserved */
339 0, /* reserved */
340 0, /* reserved */
341 0, /* reserved */
342 0, /* reserved */
343 0, /* reserved */
344 0, /* reserved */
345 0, /* reserved */
346 0, /* reserved */
347 0, /* reserved */
348 };
349
350 #else
351 static const uint16_t vdd[32] = {
352 10500,
353 0, /* reserved */
354 9750,
355 0, /* reserved */
356 9500,
357 0, /* reserved */
358 0, /* reserved */
359 0, /* reserved */
360 0, /* reserved */
361 0, /* reserved */
362 0, /* reserved */
363 0, /* reserved */
364 0, /* reserved */
365 0, /* reserved */
366 0, /* reserved */
367 0, /* reserved */
368 10000, /* 1.0000V */
369 0, /* reserved */
370 10250,
371 0, /* reserved */
372 10500,
373 0, /* reserved */
374 0, /* reserved */
375 0, /* reserved */
376 0, /* reserved */
377 0, /* reserved */
378 0, /* reserved */
379 0, /* reserved */
380 0, /* reserved */
381 0, /* reserved */
382 0, /* reserved */
383 0, /* reserved */
384 };
385 #endif
386 struct vdd_drive {
387 u8 vid;
388 unsigned voltage;
389 };
390
391 ret = i2c_multiplexer_select_vid_channel(I2C_MUX_CH_VOL_MONITOR);
392 if (ret) {
393 debug("VID: I2C failed to switch channel\n");
394 ret = -1;
395 goto exit;
396 }
397 #if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
398 defined(CONFIG_VOL_MONITOR_IR36021_READ)
399 ret = find_ir_chip_on_i2c();
400 if (ret < 0) {
401 printf("VID: Could not find voltage regulator on I2C.\n");
402 ret = -1;
403 goto exit;
404 } else {
405 i2caddress = ret;
406 debug("VID: IR Chip found on I2C address 0x%02x\n", i2caddress);
407 }
408
409 /* check IR chip work on Intel mode*/
410 ret = i2c_read(i2caddress,
411 IR36021_INTEL_MODE_OOFSET,
412 1, (void *)&buf, 1);
413 if (ret) {
414 printf("VID: failed to read IR chip mode.\n");
415 ret = -1;
416 goto exit;
417 }
418 if ((buf & IR36021_MODE_MASK) != IR36021_INTEL_MODE) {
419 printf("VID: IR Chip is not used in Intel mode.\n");
420 ret = -1;
421 goto exit;
422 }
423 #endif
424
425 /* get the voltage ID from fuse status register */
426 fusesr = in_le32(&gur->dcfg_fusesr);
427 vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT) &
428 FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK;
429 if ((vid == 0) || (vid == FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK)) {
430 vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT) &
431 FSL_CHASSIS3_DCFG_FUSESR_VID_MASK;
432 }
433 vdd_target = vdd[vid];
434
435 /* check override variable for overriding VDD */
436 vdd_string = env_get(CONFIG_VID_FLS_ENV);
437 if (vdd_override == 0 && vdd_string &&
438 !strict_strtoul(vdd_string, 10, &vdd_string_override))
439 vdd_override = vdd_string_override;
440
441 if (vdd_override >= VDD_MV_MIN && vdd_override <= VDD_MV_MAX) {
442 vdd_target = vdd_override * 10; /* convert to 1/10 mV */
443 debug("VDD override is %lu\n", vdd_override);
444 } else if (vdd_override != 0) {
445 printf("Invalid value.\n");
446 }
447
448 /* divide and round up by 10 to get a value in mV */
449 vdd_target = DIV_ROUND_UP(vdd_target, 10);
450 if (vdd_target == 0) {
451 debug("VID: VID not used\n");
452 ret = 0;
453 goto exit;
454 } else if (vdd_target < VDD_MV_MIN || vdd_target > VDD_MV_MAX) {
455 /* Check vdd_target is in valid range */
456 printf("VID: Target VID %d mV is not in range.\n",
457 vdd_target);
458 ret = -1;
459 goto exit;
460 } else {
461 debug("VID: vid = %d mV\n", vdd_target);
462 }
463
464 /*
465 * Read voltage monitor to check real voltage.
466 */
467 vdd_last = read_voltage(i2caddress);
468 if (vdd_last < 0) {
469 printf("VID: Couldn't read sensor abort VID adjustment\n");
470 ret = -1;
471 goto exit;
472 }
473 vdd_current = vdd_last;
474 debug("VID: Core voltage is currently at %d mV\n", vdd_last);
475 /*
476 * Adjust voltage to at or one step above target.
477 * As measurements are less precise than setting the values
478 * we may run through dummy steps that cancel each other
479 * when stepping up and then down.
480 */
481 while (vdd_last > 0 &&
482 vdd_last < vdd_target) {
483 vdd_current += IR_VDD_STEP_UP;
484 vdd_last = set_voltage(i2caddress, vdd_current);
485 }
486 while (vdd_last > 0 &&
487 vdd_last > vdd_target + (IR_VDD_STEP_DOWN - 1)) {
488 vdd_current -= IR_VDD_STEP_DOWN;
489 vdd_last = set_voltage(i2caddress, vdd_current);
490 }
491
492 if (board_adjust_vdd(vdd_target) < 0) {
493 ret = -1;
494 goto exit;
495 }
496
497 if (vdd_last > 0)
498 printf("VID: Core voltage after adjustment is at %d mV\n",
499 vdd_last);
500 else
501 ret = -1;
502 exit:
503 if (re_enable)
504 enable_interrupts();
505 i2c_multiplexer_select_vid_channel(I2C_MUX_CH_DEFAULT);
506 return ret;
507 }
508 #else /* !CONFIG_FSL_LSCH3 */
509 int adjust_vdd(ulong vdd_override)
510 {
511 int re_enable = disable_interrupts();
512 #if defined(CONFIG_FSL_LSCH2)
513 struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
514 #else
515 ccsr_gur_t __iomem *gur =
516 (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
517 #endif
518 u32 fusesr;
519 u8 vid, buf;
520 int vdd_target, vdd_current, vdd_last;
521 int ret, i2caddress;
522 unsigned long vdd_string_override;
523 char *vdd_string;
524 static const uint16_t vdd[32] = {
525 0, /* unused */
526 9875, /* 0.9875V */
527 9750,
528 9625,
529 9500,
530 9375,
531 9250,
532 9125,
533 9000,
534 8875,
535 8750,
536 8625,
537 8500,
538 8375,
539 8250,
540 8125,
541 10000, /* 1.0000V */
542 10125,
543 10250,
544 10375,
545 10500,
546 10625,
547 10750,
548 10875,
549 11000,
550 0, /* reserved */
551 };
552 struct vdd_drive {
553 u8 vid;
554 unsigned voltage;
555 };
556
557 ret = i2c_multiplexer_select_vid_channel(I2C_MUX_CH_VOL_MONITOR);
558 if (ret) {
559 debug("VID: I2C failed to switch channel\n");
560 ret = -1;
561 goto exit;
562 }
563 #if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
564 defined(CONFIG_VOL_MONITOR_IR36021_READ)
565 ret = find_ir_chip_on_i2c();
566 if (ret < 0) {
567 printf("VID: Could not find voltage regulator on I2C.\n");
568 ret = -1;
569 goto exit;
570 } else {
571 i2caddress = ret;
572 debug("VID: IR Chip found on I2C address 0x%02x\n", i2caddress);
573 }
574
575 /* check IR chip work on Intel mode*/
576 ret = i2c_read(i2caddress,
577 IR36021_INTEL_MODE_OOFSET,
578 1, (void *)&buf, 1);
579 if (ret) {
580 printf("VID: failed to read IR chip mode.\n");
581 ret = -1;
582 goto exit;
583 }
584 if ((buf & IR36021_MODE_MASK) != IR36021_INTEL_MODE) {
585 printf("VID: IR Chip is not used in Intel mode.\n");
586 ret = -1;
587 goto exit;
588 }
589 #endif
590
591 /* get the voltage ID from fuse status register */
592 fusesr = in_be32(&gur->dcfg_fusesr);
593 /*
594 * VID is used according to the table below
595 * ---------------------------------------
596 * | DA_V |
597 * |-------------------------------------|
598 * | 5b00000 | 5b00001-5b11110 | 5b11111 |
599 * ---------------+---------+-----------------+---------|
600 * | D | 5b00000 | NO VID | VID = DA_V | NO VID |
601 * | A |----------+---------+-----------------+---------|
602 * | _ | 5b00001 |VID = | VID = |VID = |
603 * | V | ~ | DA_V_ALT| DA_V_ALT | DA_A_VLT|
604 * | _ | 5b11110 | | | |
605 * | A |----------+---------+-----------------+---------|
606 * | L | 5b11111 | No VID | VID = DA_V | NO VID |
607 * | T | | | | |
608 * ------------------------------------------------------
609 */
610 #ifdef CONFIG_FSL_LSCH2
611 vid = (fusesr >> FSL_CHASSIS2_DCFG_FUSESR_ALTVID_SHIFT) &
612 FSL_CHASSIS2_DCFG_FUSESR_ALTVID_MASK;
613 if ((vid == 0) || (vid == FSL_CHASSIS2_DCFG_FUSESR_ALTVID_MASK)) {
614 vid = (fusesr >> FSL_CHASSIS2_DCFG_FUSESR_VID_SHIFT) &
615 FSL_CHASSIS2_DCFG_FUSESR_VID_MASK;
616 }
617 #else
618 vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_ALTVID_SHIFT) &
619 FSL_CORENET_DCFG_FUSESR_ALTVID_MASK;
620 if ((vid == 0) || (vid == FSL_CORENET_DCFG_FUSESR_ALTVID_MASK)) {
621 vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_VID_SHIFT) &
622 FSL_CORENET_DCFG_FUSESR_VID_MASK;
623 }
624 #endif
625 vdd_target = vdd[vid];
626
627 /* check override variable for overriding VDD */
628 vdd_string = env_get(CONFIG_VID_FLS_ENV);
629 if (vdd_override == 0 && vdd_string &&
630 !strict_strtoul(vdd_string, 10, &vdd_string_override))
631 vdd_override = vdd_string_override;
632 if (vdd_override >= VDD_MV_MIN && vdd_override <= VDD_MV_MAX) {
633 vdd_target = vdd_override * 10; /* convert to 1/10 mV */
634 debug("VDD override is %lu\n", vdd_override);
635 } else if (vdd_override != 0) {
636 printf("Invalid value.\n");
637 }
638 if (vdd_target == 0) {
639 debug("VID: VID not used\n");
640 ret = 0;
641 goto exit;
642 } else {
643 /* divide and round up by 10 to get a value in mV */
644 vdd_target = DIV_ROUND_UP(vdd_target, 10);
645 debug("VID: vid = %d mV\n", vdd_target);
646 }
647
648 /*
649 * Read voltage monitor to check real voltage.
650 */
651 vdd_last = read_voltage(i2caddress);
652 if (vdd_last < 0) {
653 printf("VID: Couldn't read sensor abort VID adjustment\n");
654 ret = -1;
655 goto exit;
656 }
657 vdd_current = vdd_last;
658 debug("VID: Core voltage is currently at %d mV\n", vdd_last);
659 /*
660 * Adjust voltage to at or one step above target.
661 * As measurements are less precise than setting the values
662 * we may run through dummy steps that cancel each other
663 * when stepping up and then down.
664 */
665 while (vdd_last > 0 &&
666 vdd_last < vdd_target) {
667 vdd_current += IR_VDD_STEP_UP;
668 vdd_last = set_voltage(i2caddress, vdd_current);
669 }
670 while (vdd_last > 0 &&
671 vdd_last > vdd_target + (IR_VDD_STEP_DOWN - 1)) {
672 vdd_current -= IR_VDD_STEP_DOWN;
673 vdd_last = set_voltage(i2caddress, vdd_current);
674 }
675
676 if (vdd_last > 0)
677 printf("VID: Core voltage after adjustment is at %d mV\n",
678 vdd_last);
679 else
680 ret = -1;
681 exit:
682 if (re_enable)
683 enable_interrupts();
684
685 i2c_multiplexer_select_vid_channel(I2C_MUX_CH_DEFAULT);
686
687 return ret;
688 }
689 #endif
690
691 static int print_vdd(void)
692 {
693 int vdd_last, ret, i2caddress;
694
695 ret = i2c_multiplexer_select_vid_channel(I2C_MUX_CH_VOL_MONITOR);
696 if (ret) {
697 debug("VID : I2c failed to switch channel\n");
698 return -1;
699 }
700 #if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \
701 defined(CONFIG_VOL_MONITOR_IR36021_READ)
702 ret = find_ir_chip_on_i2c();
703 if (ret < 0) {
704 printf("VID: Could not find voltage regulator on I2C.\n");
705 goto exit;
706 } else {
707 i2caddress = ret;
708 debug("VID: IR Chip found on I2C address 0x%02x\n", i2caddress);
709 }
710 #endif
711
712 /*
713 * Read voltage monitor to check real voltage.
714 */
715 vdd_last = read_voltage(i2caddress);
716 if (vdd_last < 0) {
717 printf("VID: Couldn't read sensor abort VID adjustment\n");
718 goto exit;
719 }
720 printf("VID: Core voltage is at %d mV\n", vdd_last);
721 exit:
722 i2c_multiplexer_select_vid_channel(I2C_MUX_CH_DEFAULT);
723
724 return ret < 0 ? -1 : 0;
725
726 }
727
728 static int do_vdd_override(cmd_tbl_t *cmdtp,
729 int flag, int argc,
730 char * const argv[])
731 {
732 ulong override;
733
734 if (argc < 2)
735 return CMD_RET_USAGE;
736
737 if (!strict_strtoul(argv[1], 10, &override))
738 adjust_vdd(override); /* the value is checked by callee */
739 else
740 return CMD_RET_USAGE;
741 return 0;
742 }
743
744 static int do_vdd_read(cmd_tbl_t *cmdtp,
745 int flag, int argc,
746 char * const argv[])
747 {
748 if (argc < 1)
749 return CMD_RET_USAGE;
750 print_vdd();
751
752 return 0;
753 }
754
755 U_BOOT_CMD(
756 vdd_override, 2, 0, do_vdd_override,
757 "override VDD",
758 " - override with the voltage specified in mV, eg. 1050"
759 );
760
761 U_BOOT_CMD(
762 vdd_read, 1, 0, do_vdd_read,
763 "read VDD",
764 " - Read the voltage specified in mV"
765 )