Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 964 lines (833 sloc) 34.737 kb
4bc042b initial public release v1.50
Patrick Titiano authored
1 /*
2 *
3 * @Component OMAPCONF
4 * @Filename vp.c
5 * @Description VOLTAGE PROCESSOR (VP) Common Definitions
6 * & Functions
7 * @Author Patrick Titiano (p-titiano@ti.com)
8 * @Date 2012
9 * @Copyright Texas Instruments Incorporated
10 *
11 *
12 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
13 *
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 *
19 * Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 *
22 * Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the
25 * distribution.
26 *
27 * Neither the name of Texas Instruments Incorporated nor the names of
28 * its contributors may be used to endorse or promote products derived
29 * from this software without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
37 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
41 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 *
43 */
44
45
46 #include <vp.h>
47 #include <lib.h>
48 #include <cpuinfo.h>
49 #include <clock44xx.h>
50 #include <clock54xx.h>
51 #include <autoadjust_table.h>
52 #include <pmic.h>
53
54
55 /* #define VP_DEBUG */
56 #ifdef VP_DEBUG
57 #define dprintf(format, ...) printf(format, ## __VA_ARGS__)
58 #else
59 #define dprintf(format, ...)
60 #endif
61
62
63 /* VP bitfields */
64 #define VP_ERROROFFSET_POS 24
65 #define VP_ERROROFFSET_LEN 8
66 #define VP_ERRORGAIN_POS 16
67 #define VP_ERRORGAIN_LEN 8
68 #define VP_INITVOLTAGE_POS 8
69 #define VP_INITVOLTAGE_LEN 8
70 #define VP_TIMEOUTEN_POS 3
71 #define VP_VPENABLE_POS 0
72
73 #define VP_VPINIDLE_POS 0
74
75 #define VP_VDDMAX_POS 24
76 #define VP_VDDMAX_LEN 8
77 #define VP_VDDMIN_POS 16
78 #define VP_VDDMIN_LEN 8
79 #define VP_TIMEOUT_POS 0
80 #define VP_TIMEOUT_LEN 16
81
82 #define VP_FORCEUPDATEWAIT_POS 8
83 #define VP_FORCEUPDATEWAIT_LEN 24
84 #define VP_VPVOLTAGE_POS 0
85 #define VP_VPVOLTAGE_LEN 8
86
87 #define VP_SMPSOFTWAREAITTIMEMAX_POS 8
88 #define VP_SMPSOFTWAREAITTIMEMAX_LEN 16
89 #define VP_VSTEPMAX_POS 0
90 #define VP_VSTEPMAX_LEN 8
91
92 #define VP_SMPSOFTWAREAITTIMEMIN_POS 8
93 #define VP_SMPSOFTWAREAITTIMEMIN_LEN 16
94 #define VP_VSTEPMIN_POS 0
95 #define VP_VSTEPMIN_LEN 8
96
97
98 #define VP_AUDIT_SHOW_STATUS(curr, golden) \
99 if (curr == golden) { \
100 snprintf(table[row++][3], TABLE_MAX_ELT_LEN, "Pass"); \
101 } else { \
102 snprintf(table[row++][3], TABLE_MAX_ELT_LEN, "FAIL"); \
103 (*err_nbr)++; \
104 }
105
106
107 /* ------------------------------------------------------------------------*//**
108 * @FUNCTION vp_error_offset_get
109 * @BRIEF return VP error offset
110 * @RETURNS 0 in case of success
111 * OMAPCONF_ERR_ARG
112 * @param[in] vp_config: VP_xyz_CONFIG register content
113 * @param[in,out] offset_raw: VP error offset RAW HEX value (RETURNED)
114 * @param[in,out] offset: VP error offset in % (signed) (RETURNED)
115 * @DESCRIPTION return VP error offset
116 *//*------------------------------------------------------------------------ */
117 int vp_error_offset_get(unsigned int vp_config,
118 signed char *offset_raw, double *offset)
119 {
120 CHECK_NULL_ARG(offset_raw, OMAPCONF_ERR_ARG);
121 CHECK_NULL_ARG(offset, OMAPCONF_ERR_ARG);
122
123 *offset_raw = (signed char) extract_bitfield(vp_config,
124 VP_ERROROFFSET_POS, VP_ERROROFFSET_LEN);
125 *offset = vp_error_offset_hex2percent(*offset_raw);
126
127 return 0;
128 }
129
130
131 /* ------------------------------------------------------------------------*//**
132 * @FUNCTION vp_error_offset_hex2percent
133 * @BRIEF convert VP error offset HEX signed value into %
134 * @RETURNS VP error offset in %
135 * @param[in] offset: VP error offset RAW HEX value
136 * @DESCRIPTION convert VP error offset HEX signed value into %
137 *//*------------------------------------------------------------------------ */
138 double vp_error_offset_hex2percent(signed char offset)
139 {
140 return (double) offset * 0.8;
141 }
142
143
144 /* ------------------------------------------------------------------------*//**
145 * @FUNCTION vp_error_gain_get
146 * @BRIEF return VP error gain
147 * @RETURNS 0 in case of success
148 * OMAPCONF_ERR_ARG
149 * @param[in] vp_config: VP_xyz_CONFIG register content
150 * @param[in] vdd_id: voltage domain ID
151 * @param[in,out] gain_raw: VP error gain RAW HEX value (RETURNED)
152 * @param[in,out] gain: VP error gain in mV/% (signed) (RETURNED)
153 * @DESCRIPTION return VP error gain
154 *//*------------------------------------------------------------------------ */
155 int vp_error_gain_get(unsigned int vp_config, unsigned short vdd_id,
156 signed char *gain_raw, double *gain)
157 {
158 CHECK_NULL_ARG(gain_raw, OMAPCONF_ERR_ARG);
159 CHECK_NULL_ARG(gain, OMAPCONF_ERR_ARG);
160
161 *gain_raw = (signed char) extract_bitfield(vp_config,
162 VP_ERRORGAIN_POS, VP_ERRORGAIN_LEN);
163 *gain = vp_error_gain_hex2percent(*gain_raw, vdd_id);
164
165 return 0;
166 }
167
168
169 /* ------------------------------------------------------------------------*//**
170 * @FUNCTION vp_error_gain_hex2percent
171 * @BRIEF convert VP error gain HEX signed value into mV/%
172 * @RETURNS VP error gain in mV/%
173 * @param[in] gain: VP error gain RAW HEX value
174 * @param[in] vdd_id: voltage domain ID
175 * @DESCRIPTION convert VP error gain HEX signed value into mV/%
176 *//*------------------------------------------------------------------------ */
177 double vp_error_gain_hex2percent(signed char gain, unsigned short vdd_id)
178 {
179 double step_mv;
180
181 step_mv = (double) smps_step_get(vdd_id2smps_id(vdd_id)) / 1000.0;
182
183 return (double) gain * step_mv / 100.0;
184 }
185
186
187 /* ------------------------------------------------------------------------*//**
188 * @FUNCTION vp_init_voltage_get
189 * @BRIEF return VP initial voltage
190 * @RETURNS 0 in case of success
191 * OMAPCONF_ERR_ARG
192 * OMAPCONF_ERR_CPU
193 * @param[in] vp_config: VP_xyz_CONFIG register content
194 * @param[in] vdd_id: voltage domain ID
195 * @param[in,out] init_vsel: initial voltage (vsel command) (RETURNED)
196 * @param[in,out] init_uv: initial voltage (in micro-volt) (RETURNED)
197 * @DESCRIPTION return VP initial voltage
198 *//*------------------------------------------------------------------------ */
199 int vp_init_voltage_get(unsigned int vp_config, unsigned short vdd_id,
200 unsigned char *init_vsel, unsigned int *init_uv)
201 {
202 CHECK_NULL_ARG(init_vsel, OMAPCONF_ERR_ARG);
203 CHECK_NULL_ARG(init_uv, OMAPCONF_ERR_ARG);
204
205 *init_vsel = (unsigned char) extract_bitfield(vp_config,
206 VP_INITVOLTAGE_POS, VP_INITVOLTAGE_LEN);
207 *init_uv = smps_vsel2uvolt(vdd_id2smps_id(vdd_id), *init_vsel);
208
209 return 0;
210 }
211
212
213 /* ------------------------------------------------------------------------*//**
214 * @FUNCTION vp_vc_timeout_is_enabled
215 * @BRIEF check if VC Timeout is enabled
216 * @RETURNS 1 if VC Timeout is enabled
217 * 0 if VC Timeout is disabled
218 * @param[in] vp_config: VP_xyz_CONFIG register content
219 * @DESCRIPTION check if VC Timeout is enabled
220 *//*------------------------------------------------------------------------ */
221 unsigned char vp_vc_timeout_is_enabled(unsigned int vp_config)
222 {
223 return extract_bit(vp_config, VP_TIMEOUTEN_POS);
224 }
225
226
227 /* ------------------------------------------------------------------------*//**
228 * @FUNCTION vp_is_enabled
229 * @BRIEF check if VP is enabled
230 * @RETURNS 1 if VP is enabled
231 * 0 if VP is disabled
232 * @param[in] vp_config: VP_xyz_CONFIG register content
233 * @DESCRIPTION check if VP is enabled
234 *//*------------------------------------------------------------------------ */
235 unsigned char vp_is_enabled(unsigned int vp_config)
236 {
237 return extract_bit(vp_config, VP_VPENABLE_POS);
238 }
239
240
241 /* ------------------------------------------------------------------------*//**
242 * @FUNCTION vp_is_idle
243 * @BRIEF check if VP is idle
244 * @RETURNS 1 if VP is idle
245 * 0 if VP is not idle (running)
246 * @param[in] vp_status: VP_xyz_STATUS register content
247 * @DESCRIPTION check if VP is idle
248 *//*------------------------------------------------------------------------ */
249 unsigned char vp_is_idle(unsigned int vp_status)
250 {
251 return extract_bit(vp_status, VP_VPINIDLE_POS);
252 }
253
254
255 /* ------------------------------------------------------------------------*//**
256 * @FUNCTION vp_min_voltage_get
257 * @BRIEF return VP minimum supply voltage
258 * @RETURNS 0 in case of success
259 * OMAPCONF_ERR_ARG
260 * OMAPCONF_ERR_CPU
261 * @param[in] vp_vlimitto: VP_xyz_VLIMITTO register content
262 * @param[in] vdd_id: voltage domain ID
263 * @param[in,out] min_vsel: minimum supply voltage (vsel command)
264 * (RETURNED)
265 * @param[in,out] min_uv: minimum supply voltage (in micro-volt)
266 * (RETURNED)
267 * @DESCRIPTION return VP minimum supply voltage
268 *//*------------------------------------------------------------------------ */
269 int vp_min_voltage_get(unsigned int vp_vlimitto, unsigned short vdd_id,
270 unsigned char *min_vsel, unsigned int *min_uv)
271 {
272 CHECK_NULL_ARG(min_vsel, OMAPCONF_ERR_ARG);
273 CHECK_NULL_ARG(min_uv, OMAPCONF_ERR_ARG);
274
275 *min_vsel = (unsigned char) extract_bitfield(vp_vlimitto,
276 VP_VDDMIN_POS, VP_VDDMIN_LEN);
277 *min_uv = smps_vsel2uvolt(vdd_id2smps_id(vdd_id), *min_vsel);
278
279 return 0;
280 }
281
282
283 /* ------------------------------------------------------------------------*//**
284 * @FUNCTION vp_max_voltage_get
285 * @BRIEF return VP maximum supply voltage
286 * @RETURNS 0 in case of success
287 * OMAPCONF_ERR_ARG
288 * OMAPCONF_ERR_CPU
289 * @param[in] vp_vlimitto: VP_xyz_VLIMITTO register content
290 * @param[in] vdd_id: voltage domain ID
291 * @param[in,out] max_vsel: maximum supply voltage (vsel command)
292 * (RETURNED)
293 * @param[in,out] max_uv: maximum supply voltage (in micro-volt)
294 * (RETURNED)
295 * @DESCRIPTION return VP maximum supply voltage
296 *//*------------------------------------------------------------------------ */
297 int vp_max_voltage_get(unsigned int vp_vlimitto, unsigned short vdd_id,
298 unsigned char *max_vsel, unsigned int *max_uv)
299 {
300 CHECK_NULL_ARG(max_vsel, OMAPCONF_ERR_ARG);
301 CHECK_NULL_ARG(max_uv, OMAPCONF_ERR_ARG);
302
303 *max_vsel = (unsigned char) extract_bitfield(vp_vlimitto,
304 VP_VDDMAX_POS, VP_VDDMAX_LEN);
305 *max_uv = smps_vsel2uvolt(vdd_id2smps_id(vdd_id), *max_vsel);
306
307 return 0;
308 }
309
310
311 /* ------------------------------------------------------------------------*//**
312 * @FUNCTION vp_last_voltage_get
313 * @BRIEF return the last voltage set by the voltage processor
314 * for a domain.
315 * @RETURNS 0 in case of success
316 * OMAPCONF_ERR_ARG
317 * OMAPCONF_ERR_CPU
318 * @param[in] vp_voltage: VP_xyz_VOLTAGE register content
319 * @param[in] vdd_id: voltage domain ID
320 * @param[in,out] vsel: last supply voltage programmed by VP
321 * (vsel command) (RETURNED)
322 * @param[in,out] uv: last supply voltage programmed by VP
323 * (in micro-volt) (RETURNED)
324 * @DESCRIPTION return the last voltage set by the voltage processor
325 * for a domain.
326 * NB: SR/VP/VC HAVE TO BE AT LEAST INITIALIZED
327 * (SR COULD BE DISABLED) OTHERWISE THIS VALUE HAS NO SENSE
328 *//*------------------------------------------------------------------------ */
329 int vp_last_voltage_get(unsigned int vp_voltage, unsigned short vdd_id,
330 unsigned char *vsel, unsigned int *uv)
331 {
332 CHECK_NULL_ARG(vsel, OMAPCONF_ERR_ARG);
333 CHECK_NULL_ARG(uv, OMAPCONF_ERR_ARG);
334
335 *vsel = (unsigned char) extract_bitfield(vp_voltage, 0,
336 smps_vsel_len_get(vdd_id2smps_id(vdd_id)));
337
338 *uv = smps_vsel2uvolt(vdd_id2smps_id(vdd_id), *vsel);
339 dprintf("%s(%u): VP_VOLTAGE=0x%08X, vsel=%02X voltage=%uV\n", __func__,
340 vdd_id, vp_voltage, *vsel, *uv);
341
342 return 0;
343 }
344
345
346 /* ------------------------------------------------------------------------*//**
347 * @FUNCTION vp_vc_timeout_get
348 * @BRIEF return VC maximum response wait time
349 * @RETURNS 0 in case of success
350 * OMAPCONF_ERR_ARG
351 * OMAPCONF_ERR_CPU
352 * @param[in] vp_vlimitto: VP_xyz_VLIMITTO register content
353 * @param[in,out] timeout_cycles: maximum response wait time
354 * (SYSCLK cycles) (RETURNED)
355 * @param[in,out] timeout_us: maximum response wait time (in micro-second)
356 * (RETURNED)
357 * @DESCRIPTION return VC maximum response wait time
358 *//*------------------------------------------------------------------------ */
359 int vp_vc_timeout_get(unsigned int vp_vlimitto,
360 unsigned int *timeout_cycles, unsigned int *timeout_us)
361 {
362 double sysclk;
363
364 CHECK_NULL_ARG(timeout_cycles, OMAPCONF_ERR_ARG);
365 CHECK_NULL_ARG(timeout_us, OMAPCONF_ERR_ARG);
366
367 if (cpu_is_omap44xx()) {
368 sysclk = clk44xx_get_system_clock_speed();
369 } else if (cpu_is_omap54xx()) {
370 sysclk = clk54xx_sysclk_rate_get();
371 } else {
372 fprintf(stderr, "%s(): cpu not supported!!!\n", __func__);
373 return OMAPCONF_ERR_CPU;
374 }
375
376 *timeout_cycles = extract_bitfield(vp_vlimitto,
377 VP_TIMEOUT_POS, VP_TIMEOUT_LEN);
378 *timeout_us = *timeout_cycles / sysclk;
379
380 return 0;
381 }
382
383
384 /* ------------------------------------------------------------------------*//**
385 * @FUNCTION vp_force_update_wait_time_get
386 * @BRIEF return the time voltage processor needs to wait for
387 * SMPS to be settled after receiving SMPS acknowledge.
388 * @RETURNS 0 in case of success
389 * OMAPCONF_ERR_ARG
390 * OMAPCONF_ERR_CPU
391 * @param[in] vp_voltage: VP_xyz_VOLTAGE register content
392 * @param[in,out] time_cycles: time VP needs to wait for SMPS to be
393 * settled (in SYSCLK cycles) (returned)
394 * @param[in,out] time VP needs to wait for SMPS to be settled
395 * (in micro-second) (returned)
396 * @DESCRIPTION return the time voltage processor needs to wait for
397 * SMPS to be settled after receiving SMPS acknowledge.
398 *//*------------------------------------------------------------------------ */
399 int vp_force_update_wait_time_get(unsigned int vp_voltage,
400 unsigned int *time_cycles, unsigned int *time_us)
401 {
402 double sysclk;
403
404 CHECK_NULL_ARG(time_cycles, OMAPCONF_ERR_ARG);
405 CHECK_NULL_ARG(time_us, OMAPCONF_ERR_ARG);
406
407 if (cpu_is_omap44xx()) {
408 sysclk = clk44xx_get_system_clock_speed();
409 } else if (cpu_is_omap54xx()) {
410 sysclk = clk54xx_sysclk_rate_get();
411 } else {
412 fprintf(stderr, "%s(): cpu not supported!!!\n", __func__);
413 return OMAPCONF_ERR_CPU;
414 }
415
416 *time_cycles = extract_bitfield(vp_voltage,
417 VP_FORCEUPDATEWAIT_POS, VP_FORCEUPDATEWAIT_LEN);
418 *time_us = *time_cycles / sysclk;
419
420 return 0;
421
422 }
423
424
425
426 /* ------------------------------------------------------------------------*//**
427 * @FUNCTION vp_max_step_get
428 * @BRIEF return VP maximum voltage step
429 * @RETURNS 0 in case of success
430 * OMAPCONF_ERR_ARG
431 * @param[in] vp_vstepmax: VP_xyz_VSTEPMAX register content
432 * @param[in] vdd_id: voltage domain ID
433 * @param[in,out] max_step: maximum voltage step (vsel command) (RETURNED)
434 * @param[in,out] max_uv: maximum voltage step (in micro-volt) (RETURNED)
435 * @DESCRIPTION return VP maximum voltage step
436 *//*------------------------------------------------------------------------ */
437 int vp_max_step_get(unsigned int vp_vstepmax, unsigned short vdd_id,
438 unsigned int *max_step, unsigned int *max_uv)
439 {
440 CHECK_NULL_ARG(max_step, OMAPCONF_ERR_ARG);
441 CHECK_NULL_ARG(max_uv, OMAPCONF_ERR_ARG);
442
443 *max_step = extract_bitfield(vp_vstepmax,
444 VP_VSTEPMAX_POS, VP_VSTEPMAX_LEN);
445 *max_uv = *max_step * smps_step_get(vdd_id2smps_id(vdd_id));
446
447 return 0;
448 }
449
450
451 /* ------------------------------------------------------------------------*//**
452 * @FUNCTION vp_min_step_get
453 * @BRIEF return VP minimum voltage step
454 * @RETURNS 0 in case of success
455 * OMAPCONF_ERR_ARG
456 * @param[in] vp_vstepmin: VP_xyz_VSTEPMIN register content
457 * @param[in] vdd_id: voltage domain ID
458 * @param[in,out] min_step: minimum voltage step (vsel command) (RETURNED)
459 * @param[in,out] min_uv: minimum voltage step (in micro-volt) (RETURNED)
460 * @DESCRIPTION return VP minimum voltage step
461 *//*------------------------------------------------------------------------ */
462 int vp_min_step_get(unsigned int vp_vstepmin, unsigned short vdd_id,
463 unsigned int *min_step, unsigned int *min_uv)
464 {
465 CHECK_NULL_ARG(min_step, OMAPCONF_ERR_ARG);
466 CHECK_NULL_ARG(min_uv, OMAPCONF_ERR_ARG);
467
468 *min_step = extract_bitfield(vp_vstepmin,
469 VP_VSTEPMIN_POS, VP_VSTEPMIN_LEN);
470 *min_uv = *min_step * smps_step_get(vdd_id2smps_id(vdd_id));
471
472 return 0;
473 }
474
475
476 /* ------------------------------------------------------------------------*//**
477 * @FUNCTION vp_positive_slew_rate_get
478 * @BRIEF return VP slew rate for positive voltage step
479 * @RETURNS 0 in case of success
480 * OMAPCONF_ERR_ARG
481 * OMAPCONF_ERR_CPU
482 * @param[in] vp_vstepmax: VP_xyz_VSTEPMAX register content
483 * @param[in,out] cycles: VP slew rate for positive voltage step
484 * in number of cycles per step (RETURNED)
485 * @param[in,out] us: VP slew rate for positive voltage step
486 * in micro-seconds per step (RETURNED)
487 * @DESCRIPTION return VP slew rate for positive voltage step
488 *//*------------------------------------------------------------------------ */
489 int vp_positive_slew_rate_get(unsigned int vp_vstepmax,
490 unsigned int *cycles, unsigned int *us)
491 {
492 int ret;
493
494 CHECK_NULL_ARG(cycles, OMAPCONF_ERR_ARG);
495 CHECK_NULL_ARG(us, OMAPCONF_ERR_ARG);
496
497 *cycles = extract_bitfield(vp_vstepmax,
498 VP_SMPSOFTWAREAITTIMEMAX_POS, VP_SMPSOFTWAREAITTIMEMAX_LEN);
499 ret = vp_slew_rate_cycles2us(*cycles);
500 if (ret >= 0) {
501 *us = ret;
502 return 0;
503 } else {
504 *us = 0;
505 return ret;
506 }
507 }
508
509
510 /* ------------------------------------------------------------------------*//**
511 * @FUNCTION vp_negative_slew_rate_get
512 * @BRIEF return VP slew rate for negative voltage step
513 * @RETURNS 0 in case of success
514 * OMAPCONF_ERR_ARG
515 * OMAPCONF_ERR_CPU
516 * @param[in] vp_vstepmin: VP_xyz_VSTEPMIN register content
517 * @param[in,out] cycles: VP slew rate for negative voltage step
518 * in number of cycles per step (RETURNED)
519 * @param[in,out] us: VP slew rate for negative voltage step
520 * in micro-seconds per step (RETURNED)
521 * @DESCRIPTION return VP slew rate for negative voltage step
522 *//*------------------------------------------------------------------------ */
523 int vp_negative_slew_rate_get(unsigned int vp_vstepmin,
524 unsigned int *cycles, unsigned int *us)
525 {
526 int ret;
527
528 CHECK_NULL_ARG(cycles, OMAPCONF_ERR_ARG);
529 CHECK_NULL_ARG(us, OMAPCONF_ERR_ARG);
530
531 *cycles = extract_bitfield(vp_vstepmin,
532 VP_SMPSOFTWAREAITTIMEMIN_POS, VP_SMPSOFTWAREAITTIMEMIN_LEN);
533 ret = vp_slew_rate_cycles2us(*cycles);
534 if (ret >= 0) {
535 *us = ret;
536 return 0;
537 } else {
538 *us = 0;
539 return ret;
540 }
541 }
542
543
544 /* ------------------------------------------------------------------------*//**
545 * @FUNCTION vp_slew_rate_cycles2us
546 * @BRIEF convert VP slew rate HEX value into micro-seconds
547 * @RETURNS VP slew rate in micro-seconds
548 * OMAPCONF_ERR_CPU
549 * @param[in] cycles: VP slew rate for negative voltage step in
550 * number of cycles per step
551 * @DESCRIPTION convert VP slew rate HEX value into micro-seconds
552 *//*------------------------------------------------------------------------ */
553 int vp_slew_rate_cycles2us(unsigned int cycles)
554 {
555 double sysclk;
556
557 if (cpu_is_omap44xx()) {
558 sysclk = clk44xx_get_system_clock_speed();
559 } else if (cpu_is_omap54xx()) {
560 sysclk = clk54xx_sysclk_rate_get();
561 } else {
562 fprintf(stderr, "%s(): cpu not supported!!!\n", __func__);
563 return OMAPCONF_ERR_CPU;
564 }
565
566 return (unsigned int) ((cycles / sysclk) + 1);
567 }
568
569
570 /* ------------------------------------------------------------------------*//**
571 * @FUNCTION vp_config_show
572 * @BRIEF decode and show VP current configuration
573 * @RETURNS 0 in case of success
574 * OMAPCONF_ERR_CPU
575 * OMAPCONF_ERR_REG_ACCESS
576 * @param[in,out] stream: output file (NULL: no output (silent))
577 * @param[in,out] vp_regs: VP registers content for the 3 VP instances
578 * (MPU, IVA/MM, CORE)
579 * @DESCRIPTION decode and show VP current configuration
580 *//*------------------------------------------------------------------------ */
581 int vp_config_show(FILE *stream, vp_registers vp_regs[3])
582 {
583 unsigned int cycles, us, step, uv;
584 unsigned char vsel;
585
586 char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN];
587 unsigned int i, row = 0;
588 signed char vp_offset_raw, vp_gain_raw;
589 double vp_offset, vp_gain;
590
591 CHECK_NULL_ARG(vp_regs, OMAPCONF_ERR_ARG);
592 if (!cpu_is_omap44xx() && !cpu_is_omap54xx()) {
593 fprintf(stderr, "%s(): cpu not supported!!!\n", __func__);
594 return OMAPCONF_ERR_CPU;
595 }
596
597
598 #ifdef VP_DEBUG
599 autoadjust_table_init(table);
600 autoadjust_table_strncpy(table, row, 0, "VP Registers");
601 autoadjust_table_strncpy(table, row, 1, "VP MPU");
602 if (cpu_is_omap44xx())
603 autoadjust_table_strncpy(table, row, 2, "VP MM");
604 else
605 autoadjust_table_strncpy(table, row, 2, "VP MM");
606 autoadjust_table_strncpy(table, row, 3, "VP CORE");
607 row++;
608 for (i = 0; i < 3; i++) {
609 row = 1;
610 autoadjust_table_strncpy(table, row, 0, "VP_CONFIG");
611 snprintf(table[row++][i + 1], TABLE_MAX_ELT_LEN, "0x%08X",
612 vp_regs[i].vp_config);
613 autoadjust_table_strncpy(table, row, 0, "VP_STATUS");
614 snprintf(table[row++][i + 1], TABLE_MAX_ELT_LEN, "0x%08X",
615 vp_regs[i].vp_status);
616 autoadjust_table_strncpy(table, row, 0, "VP_VLIMITTO");
617 snprintf(table[row++][i + 1], TABLE_MAX_ELT_LEN, "0x%08X",
618 vp_regs[i].vp_vlimitto);
619 autoadjust_table_strncpy(table, row, 0, "VP_VOLTAGE");
620 snprintf(table[row++][i + 1], TABLE_MAX_ELT_LEN, "0x%08X",
621 vp_regs[i].vp_voltage);
622 autoadjust_table_strncpy(table, row, 0, "VP_VSTEPMAX");
623 snprintf(table[row++][i + 1], TABLE_MAX_ELT_LEN, "0x%08X",
624 vp_regs[i].vp_vstepmax);
625 autoadjust_table_strncpy(table, row, 0, "VP_VSTEPMIN");
626 snprintf(table[row++][i + 1], TABLE_MAX_ELT_LEN, "0x%08X",
627 vp_regs[i].vp_vstepmin);
628 }
629 autoadjust_table_print(table, row, 4);
630 #endif
631
632
633 row = 0;
634 autoadjust_table_init(table);
635 autoadjust_table_strncpy(table, row, 0, "PRM VP Configuration");
636 autoadjust_table_strncpy(table, row, 1, "VP_MPU");
637 if (cpu_is_omap44xx())
638 autoadjust_table_strncpy(table, row, 2, "VP_IVA");
639 else
640 autoadjust_table_strncpy(table, row, 2, "VP_MM");
641 autoadjust_table_strncpy(table, row++, 3, "VP_CORE");
642
643 for (i = 0; i < 3; i++) {
644 row = 1;
645 autoadjust_table_strncpy(table, row, 0, "Mode");
646 if (vp_is_enabled(vp_regs[i].vp_config) == 1)
647 autoadjust_table_strncpy(table, row, i + 1, "Enabled");
648 else
649 autoadjust_table_strncpy(table, row, i + 1, "Disabled");
650 row++;
651
652 autoadjust_table_strncpy(table, row, 0, "Status");
653 if (vp_is_idle(vp_regs[i].vp_status) == 1)
654 autoadjust_table_strncpy(table, row, i + 1, "Idle");
655 else
656 autoadjust_table_strncpy(table, row, i + 1,
657 "Processing");
658 row++;
659
660 autoadjust_table_strncpy(table, row, 0, "VC Response Timeout");
661 if (vp_vc_timeout_is_enabled(vp_regs[i].vp_config) == 1) {
662 autoadjust_table_strncpy(table, row, i + 1, "Enabled");
663 row++;
664 autoadjust_table_strncpy(table, row, 0,
665 " Timeout (SysClk cycles, us)");
666 vp_vc_timeout_get(vp_regs[i].vp_vlimitto, &cycles, &us);
667 snprintf(table[row][i + 1], TABLE_MAX_ELT_LEN,
668 "%u (%uus)", cycles, us);
669 } else {
670 autoadjust_table_strncpy(table, row, i + 1, "Disabled");
671 }
672 row++;
673
674 autoadjust_table_strncpy(table, row, 0,
675 "Error Gain (hex, mV/%%)");
676 vp_error_gain_get(vp_regs[i].vp_config, vp_regs[i].vdd_id,
677 &vp_gain_raw, &vp_gain);
678 snprintf(table[row][i + 1], TABLE_MAX_ELT_LEN,
679 "0x%02X (%.3lfmV/%%)", vp_gain_raw, vp_gain);
680 row++;
681
682 autoadjust_table_strncpy(table, row, 0,
683 "Error Offset (hex, %%)");
684 vp_error_offset_get(vp_regs[i].vp_config,
685 &vp_offset_raw, &vp_offset);
686 snprintf(table[row][i + 1], TABLE_MAX_ELT_LEN,
687 "0x%02X (%.3lf%%)", vp_offset_raw, vp_offset);
688 row++;
689
690 autoadjust_table_strncpy(table, row, 0,
691 "Initial Voltage (step, V)");
692 vp_init_voltage_get(vp_regs[i].vp_config, vp_regs[i].vdd_id,
693 &vsel, &uv);
694 snprintf(table[row][i + 1], TABLE_MAX_ELT_LEN,
695 "0x%02X (%.6lfV)", vsel, (double) uv / 1000000.0);
696 row++;
697
698 autoadjust_table_strncpy(table, row, 0,
699 "MAX Voltage (step, V)");
700 vp_max_voltage_get(vp_regs[i].vp_vlimitto, vp_regs[i].vdd_id,
701 &vsel, &uv);
702 snprintf(table[row][i + 1], TABLE_MAX_ELT_LEN,
703 "0x%02X (%.6lfV)", vsel, (double) uv / 1000000.0);
704 row++;
705
706 autoadjust_table_strncpy(table, row, 0,
707 "MIN Voltage (step, V)");
708 vp_min_voltage_get(vp_regs[i].vp_vlimitto, vp_regs[i].vdd_id,
709 &vsel, &uv);
710 snprintf(table[row][i + 1], TABLE_MAX_ELT_LEN,
711 "0x%02X (%.6lfV)", vsel, (double) uv / 1000000.0);
712 row++;
713
714 autoadjust_table_strncpy(table, row, 0,
715 "Current Voltage (step, V)");
716 vp_last_voltage_get(vp_regs[i].vp_voltage, vp_regs[i].vdd_id,
717 &vsel, &uv);
718 snprintf(table[row][i + 1], TABLE_MAX_ELT_LEN,
719 "0x%02X (%.6lfV)", vsel, (double) uv / 1000000.0);
720 row++;
721
722 autoadjust_table_strncpy(table, row, 0,
723 "Force Update Wait (cycles, us)");
724 vp_force_update_wait_time_get(vp_regs[i].vp_voltage,
725 &cycles, &us);
726 snprintf(table[row][i + 1], TABLE_MAX_ELT_LEN, "%u (%uus)",
727 cycles, us);
728 row++;
729
730 autoadjust_table_strncpy(table, row, 0, "MAX Voltage Step");
731 vp_max_step_get(vp_regs[i].vp_vstepmax, vp_regs[i].vdd_id,
732 &step, &uv);
733 snprintf(table[row][i + 1], TABLE_MAX_ELT_LEN,
734 "0x%02X (%.3lfmV)", step, (double) uv / 1000.0);
735 row++;
736
737 autoadjust_table_strncpy(table, row, 0,
738 "SMPSWAITTIMEMAX (cycles/step, us)");
739 vp_positive_slew_rate_get(vp_regs[i].vp_vstepmax, &cycles, &us);
740 snprintf(table[row][i + 1], TABLE_MAX_ELT_LEN, "%u (%uus)",
741 cycles, us);
742 row++;
743
744 autoadjust_table_strncpy(table, row, 0, "MIN Voltage Step");
745 vp_min_step_get(vp_regs[i].vp_vstepmin, vp_regs[i].vdd_id,
746 &step, &uv);
747 snprintf(table[row][i + 1], TABLE_MAX_ELT_LEN,
748 "0x%02X (%.3lfmV)", step, (double) uv / 1000.0);
749 row++;
750
751 autoadjust_table_strncpy(table, row, 0,
752 "SMPSWAITTIMEMIN (cycles/step, us)");
753 vp_negative_slew_rate_get(vp_regs[i].vp_vstepmin, &cycles, &us);
754 snprintf(table[row][i + 1], TABLE_MAX_ELT_LEN, "%u (%uus)",
755 cycles, us);
756 row++;
757 }
758
759
760 if (stream != NULL)
761 autoadjust_table_fprint(stream, table, row, 4);
762
763 return 0;
764 }
765
766
767 /* ------------------------------------------------------------------------*//**
768 * @FUNCTION vp_config_audit
769 * @BRIEF audit Voltage Processor (VP) configuration
770 * @RETURNS 0 in case of success
771 * OMAPCONF_ERR_CPU
772 * OMAPCONF_ERR_ARG
773 * @param[in] stream: output file (NULL: no output (silent))
774 * @param[in] vp_name: voltage processor name
775 * @param[in] opp_name: OPP name
776 * @param[in] vp_regs: VP registers content
777 * @param[in] vp_golden_settings: expected ("golden") VP settings
778 * @param[in,out] err_nbr: audit error number
779 * @param[in,out] wng_nbr: audit warning number
780 * @DESCRIPTION audit Voltage Processor (VP) configuration by comparison
781 * with expected ("golden") settings
782 *//*------------------------------------------------------------------------ */
783 int vp_config_audit(FILE *stream, const char *vp_name, const char *opp_name,
784 vp_registers *vp_regs, const vp_audit_settings *vp_golden_settings,
785 unsigned int *err_nbr, unsigned int *wng_nbr)
786 {
787 signed char errgain_curr, errgain_expected;
788 double errgain_curr2, errgain_expected2;
789 signed char erroffset_curr, erroffset_expected;
790 double erroffset_curr2, erroffset_expected2;
791 unsigned int current, expected;
792 unsigned int current2, expected2;
793 char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN];
794 unsigned int row;
795 static const char mode_table[2][16] = {
796 "Disabled ",
797 "Enabled "};
798
799 CHECK_NULL_ARG(vp_name, OMAPCONF_ERR_ARG);
800 CHECK_NULL_ARG(vp_regs, OMAPCONF_ERR_ARG);
801 CHECK_NULL_ARG(vp_golden_settings, OMAPCONF_ERR_ARG);
802 CHECK_NULL_ARG(err_nbr, OMAPCONF_ERR_ARG);
803 CHECK_NULL_ARG(wng_nbr, OMAPCONF_ERR_ARG);
804 if (!cpu_is_omap44xx() && !cpu_is_omap54xx()) {
805 fprintf(stderr, "%s(): cpu not supported!!!\n", __func__);
806 return OMAPCONF_ERR_CPU;
807 }
808
809 *err_nbr = 0;
810 *wng_nbr = 0;
811 row = 0;
812 autoadjust_table_init(table);
813 snprintf(table[row][0], TABLE_MAX_ELT_LEN,
814 "PRM %s Configuration AUDIT (@%s)", vp_name, opp_name);
815 autoadjust_table_strncpy(table, row, 1, "Current");
816 autoadjust_table_strncpy(table, row, 2, "Expected");
817 autoadjust_table_strncpy(table, row, 3, "STATUS");
818 row++;
819
820 autoadjust_table_strncpy(table, row, 0, "Mode");
821 current = vp_is_enabled(vp_regs->vp_config);
822 expected = vp_golden_settings->mode;
823 autoadjust_table_strncpy(table, row, 1, (char *) mode_table[current]);
824 autoadjust_table_strncpy(table, row, 2, (char *) mode_table[expected]);
825 VP_AUDIT_SHOW_STATUS(current, expected);
826
827 autoadjust_table_strncpy(table, row, 0, "VC Response Timeout");
828 current = vp_vc_timeout_is_enabled(vp_regs->vp_config);
829 expected = vp_golden_settings->vc_timeout_mode;
830 autoadjust_table_strncpy(table, row, 1, (char *) mode_table[current]);
831 autoadjust_table_strncpy(table, row, 2, (char *) mode_table[expected]);
832 VP_AUDIT_SHOW_STATUS(current, expected);
833
834 autoadjust_table_strncpy(table, row, 0, " Timeout (SysClk cycles)");
835 vp_vc_timeout_get(vp_regs->vp_vlimitto,
836 &current, &current2);
837 expected = vp_golden_settings->vc_timeout_cycles;
838 snprintf(table[row][1], TABLE_MAX_ELT_LEN, "%u", current);
839 snprintf(table[row][2], TABLE_MAX_ELT_LEN, "%u", expected);
840 VP_AUDIT_SHOW_STATUS(current, expected);
841
842 autoadjust_table_strncpy(table, row, 0,
843 "Force Update Wait (SysClk cycles)");
844 vp_force_update_wait_time_get(vp_regs->vp_voltage,
845 &current, &current2);
846 expected = vp_golden_settings->force_update_wait_time;
847 snprintf(table[row][1], TABLE_MAX_ELT_LEN, "%u", current);
848 snprintf(table[row][2], TABLE_MAX_ELT_LEN, "%u", expected);
849 VP_AUDIT_SHOW_STATUS(current, expected);
850
851
852 autoadjust_table_strncpy(table, row, 0, "MAX Voltage Step");
853 vp_max_step_get(vp_regs->vp_vstepmax, vp_regs->vdd_id,
854 &current, &current2);
855 expected = vp_golden_settings->vstepmax;
856 expected2 = expected * smps_step_get(vdd_id2smps_id(vp_regs->vdd_id));
857 snprintf(table[row][1], TABLE_MAX_ELT_LEN,
858 "0x%02X (%.3lfmV)", current, (double) current2 / 1000.0);
859 snprintf(table[row][2], TABLE_MAX_ELT_LEN,
860 "0x%02X (%.3lfmV)", expected, (double) expected2 / 1000.0);
861 VP_AUDIT_SHOW_STATUS(current, expected);
862
863 autoadjust_table_strncpy(table, row, 0,
864 "SMPSWAITTIMEMAX (cycles/step, us)");
865 vp_positive_slew_rate_get(vp_regs->vp_vstepmax, &current, &current2);
866 expected = vp_golden_settings->positive_slew_rate;
867 expected2 = vp_slew_rate_cycles2us(expected);
868 snprintf(table[row][1], TABLE_MAX_ELT_LEN, "%u (%uus)",
869 current, current2);
870 snprintf(table[row][2], TABLE_MAX_ELT_LEN, "%u (%uus)",
871 expected, expected2);
872 VP_AUDIT_SHOW_STATUS(current, expected);
873
874 autoadjust_table_strncpy(table, row, 0, "MIN Voltage Step");
875 vp_min_step_get(vp_regs->vp_vstepmin, vp_regs->vdd_id,
876 &current, &current2);
877 expected = vp_golden_settings->vstepmin;
878 expected2 = expected * smps_step_get(vdd_id2smps_id(vp_regs->vdd_id));
879 snprintf(table[row][1], TABLE_MAX_ELT_LEN,
880 "0x%02X (%.3lfmV)", current, (double) current2 / 1000.0);
881 snprintf(table[row][2], TABLE_MAX_ELT_LEN,
882 "0x%02X (%.3lfmV)", expected, (double) expected2 / 1000.0);
883 VP_AUDIT_SHOW_STATUS(current, expected);
884
885 autoadjust_table_strncpy(table, row, 0,
886 "SMPSWAITTIMEMIN (cycles/step, us)");
887 vp_negative_slew_rate_get(vp_regs->vp_vstepmin, &current, &current2);
888 expected = vp_golden_settings->negative_slew_rate;
889 expected2 = vp_slew_rate_cycles2us(expected);
890 snprintf(table[row][1], TABLE_MAX_ELT_LEN, "%u (%uus)",
891 current, current2);
892 snprintf(table[row][2], TABLE_MAX_ELT_LEN, "%u (%uus)",
893 expected, expected2);
894 VP_AUDIT_SHOW_STATUS(current, expected);
895
896 autoadjust_table_strncpy(table, row, 0, "Initial Voltage (step, V)");
897 vp_init_voltage_get(vp_regs->vp_config, vp_regs->vdd_id,
898 (unsigned char *) &current, &current2);
899 expected = vp_golden_settings->init_voltage;
900 expected2 = smps_vsel2uvolt(vdd_id2smps_id(vp_regs->vdd_id), expected);
901 snprintf(table[row][1], TABLE_MAX_ELT_LEN,
902 "0x%02X (%.6lfV)", current, (double) current2 / 1000000.0);
903 snprintf(table[row][2], TABLE_MAX_ELT_LEN,
904 "0x%02X (%.6lfV)", expected, (double) expected2 / 1000000.0);
905 VP_AUDIT_SHOW_STATUS(current, expected);
906
907 autoadjust_table_strncpy(table, row, 0, "MAX Voltage (step, V)");
908 vp_max_voltage_get(vp_regs->vp_vlimitto, vp_regs->vdd_id,
909 (unsigned char *) &current, &current2);
910 expected = vp_golden_settings->max_voltage;
911 expected2 = smps_vsel2uvolt(vdd_id2smps_id(vp_regs->vdd_id), expected);
912 snprintf(table[row][1], TABLE_MAX_ELT_LEN,
913 "0x%02X (%.6lfV)", current, (double) current2 / 1000000.0);
914 snprintf(table[row][2], TABLE_MAX_ELT_LEN,
915 "0x%02X (%.6lfV)", expected, (double) expected2 / 1000000.0);
916 VP_AUDIT_SHOW_STATUS(current, expected);
917
918 autoadjust_table_strncpy(table, row, 0, "MIN Voltage (step, V)");
919 vp_min_voltage_get(vp_regs->vp_vlimitto, vp_regs->vdd_id,
920 (unsigned char *) &current, &current2);
921 expected = vp_golden_settings->min_voltage;
922 expected2 = smps_vsel2uvolt(vdd_id2smps_id(vp_regs->vdd_id), expected);
923 snprintf(table[row][1], TABLE_MAX_ELT_LEN,
924 "0x%02X (%.6lfV)", current, (double) current2 / 1000000.0);
925 snprintf(table[row][2], TABLE_MAX_ELT_LEN,
926 "0x%02X (%.6lfV)", expected, (double) expected2 / 1000000.0);
927 VP_AUDIT_SHOW_STATUS(current, expected);
928
929 autoadjust_table_strncpy(table, row, 0, "Error Gain (hex, mV/%)");
930 vp_error_gain_get(vp_regs->vp_config, vp_regs->vdd_id,
931 &errgain_curr, &errgain_curr2);
932 errgain_expected = vp_golden_settings->error_gain;
933 errgain_expected2 = vp_error_gain_hex2percent(errgain_expected,
934 vp_regs->vdd_id);
935 snprintf(table[row][1], TABLE_MAX_ELT_LEN,
936 "0x%02X (%.3lfmV/%%)", errgain_curr, errgain_curr2);
937 snprintf(table[row][2], TABLE_MAX_ELT_LEN,
938 "0x%02X (%.3lfmV/%%)", errgain_expected, errgain_expected2);
939 VP_AUDIT_SHOW_STATUS(errgain_curr, errgain_expected);
940
941 autoadjust_table_strncpy(table, row, 0, "Error Offset (hex, %)");
942 vp_error_offset_get(vp_regs->vp_config,
943 &erroffset_curr, &erroffset_curr2);
944 erroffset_expected = vp_golden_settings->error_offset;
945 erroffset_expected2 = vp_error_offset_hex2percent(erroffset_expected);
946 snprintf(table[row][1], TABLE_MAX_ELT_LEN,
947 "0x%02X (%.3lf%%)", erroffset_curr, erroffset_curr2);
948 snprintf(table[row][2], TABLE_MAX_ELT_LEN,
949 "0x%02X (%.3lf%%)", erroffset_expected, erroffset_expected2);
950 VP_AUDIT_SHOW_STATUS(erroffset_curr, erroffset_expected);
951
952 if (stream != NULL) {
953 autoadjust_table_fprint(stream, table, row, 4);
954 fprintf(stream, "NB:\n");
955 fprintf(stream, " - Report 'FAIL' when current setting is "
956 "different than golden setting.\n");
957 fprintf(stream, " - Report 'Pass' when current setting "
958 "matches golden setting.\n\n");
959 }
960
961 return 0;
962 }
963
Something went wrong with that request. Please try again.