summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2011-01-22 16:58:17 +0000
committerMichael Sevakis <jethead71@rockbox.org>2011-01-22 16:58:17 +0000
commit98246b82b912c26d17060b5aeb5443279b97cd24 (patch)
tree98afab9eec46e10a3f3d69a7a1b7ad15ae48f77a
parentaed62058317e06c5ae9d156f8a5b361a37efbdd5 (diff)
downloadrockbox-98246b82b912c26d17060b5aeb5443279b97cd24.tar.gz
rockbox-98246b82b912c26d17060b5aeb5443279b97cd24.zip
i.MX31: Add a debug menu to play around with DVFS/DPTC settings for fun, testing or benchmarking purposes. Can set the CPU frequency working point, whether DPTC voltage scaling is enabled and change the software-programmable load tracking weights.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29113 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/debug_menu.c3
-rw-r--r--firmware/target/arm/imx31/debug-imx31.c147
-rw-r--r--firmware/target/arm/imx31/debug-target.h1
-rw-r--r--firmware/target/arm/imx31/dvfs_dptc-imx31.c355
-rw-r--r--firmware/target/arm/imx31/dvfs_dptc-imx31.h12
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/dvfs_dptc_tables-target.h8
6 files changed, 410 insertions, 116 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index 968355f518..d0b919fea3 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -2345,6 +2345,9 @@ static const struct the_menu_item menuitems[] = {
2345#ifdef HAVE_ADJUSTABLE_CPU_FREQ 2345#ifdef HAVE_ADJUSTABLE_CPU_FREQ
2346 { "CPU frequency", dbg_cpufreq }, 2346 { "CPU frequency", dbg_cpufreq },
2347#endif 2347#endif
2348#if CONFIG_CPU == IMX31L
2349 { "DVFS/DPTC", __dbg_dvfs_dptc },
2350#endif
2348#if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR) 2351#if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
2349 { "S/PDIF analyzer", dbg_spdif }, 2352 { "S/PDIF analyzer", dbg_spdif },
2350#endif 2353#endif
diff --git a/firmware/target/arm/imx31/debug-imx31.c b/firmware/target/arm/imx31/debug-imx31.c
index 1239c7cae7..f8dacbedd5 100644
--- a/firmware/target/arm/imx31/debug-imx31.c
+++ b/firmware/target/arm/imx31/debug-imx31.c
@@ -29,6 +29,7 @@
29#include "adc.h" 29#include "adc.h"
30#include "ccm-imx31.h" 30#include "ccm-imx31.h"
31#include "dvfs_dptc-imx31.h" 31#include "dvfs_dptc-imx31.h"
32#include <stdio.h>
32 33
33bool __dbg_hw_info(void) 34bool __dbg_hw_info(void)
34{ 35{
@@ -242,4 +243,148 @@ bool dbg_ports(void)
242 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL)) 243 if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
243 return false; 244 return false;
244 } 245 }
245} 246}
247
248
249bool __dbg_dvfs_dptc(void)
250{
251 int ltwlevel;
252 unsigned long ltdetect;
253 int dvfs_wp, dvfs_mask;
254 bool dptc_on;
255 int i;
256 char buf[32];
257 unsigned long ltw[4];
258 bool ltwassert[4];
259
260 lcd_clear_display();
261 lcd_setfont(FONT_SYSFIXED);
262
263 dvfs_mask = dvfs_level_mask();
264
265 dvfs_wp = dvfs_enabled() ? -1 : (int)dvfs_get_level();
266 dptc_on = dptc_enabled();
267 dvfs_get_gp_sense(&ltwlevel, &ltdetect);
268
269 while (1)
270 {
271 int line = 0;
272
273 int button = button_get_w_tmo(HZ/10);
274
275 if (dvfs_wp < 0)
276 strcpy(buf, "Auto");
277 else
278 snprintf(buf, sizeof(buf), "%d", dvfs_wp);
279
280 lcd_puts(0, line, "[DVFS/DPTC]");
281 line += 2;
282 lcd_putsf(0, line, "CPU freq. point (Up/Dn) : %s", buf);
283 line += 2;
284 lcd_putsf(0, line, "DPTC volt. scale (Play) : %s",
285 dptc_on ? "Enabled" : "Disabled");
286 line += 2;
287 lcd_putsf(0, line, "GP load level (Vol +/-) : %d", ltwlevel);
288 line += 2;
289 lcd_puts(0, line, "----------------------------------------");
290 line += 2;
291 lcd_putsf(0, line++, "Frequency: %dHz", cpu_frequency);
292 i = dvfs_dptc_get_voltage();
293 lcd_putsf(0, line++, "Voltage : %d.%03d V", i / 1000, i % 1000);
294
295 for (i = 0; i <= 3; i++)
296 {
297 ltw[i] = dvfs_get_lt_weight(i + DVFS_LT_SIG_DVGP0);
298 ltwassert[i] = dvfs_get_gp_bit(i + DVFS_DVGP_0);
299 }
300
301 lcd_putsf(0, line++, "GPW (3-0): %lu%lu%lu%lu %c%c%c%c",
302 ltw[3], ltw[2], ltw[1], ltw[0],
303 ltwassert[3] ? 'y' : 'n',
304 ltwassert[2] ? 'y' : 'n',
305 ltwassert[1] ? 'y' : 'n',
306 ltwassert[0] ? 'y' : 'n');
307
308 line += 2;
309 lcd_puts(8, line, "(Press SELECT to revert)");
310
311 switch (button)
312 {
313 case DEBUG_CANCEL|BUTTON_REL:
314 return false;
315
316 /* CPU frequency */
317 case BUTTON_UP:
318 if (++dvfs_wp >= DVFS_NUM_LEVELS)
319 {
320 /* Going back to automatic */
321 dvfs_wp = -1;
322 dvfs_start();
323 }
324 else
325 {
326 if (dvfs_wp == 0)
327 {
328 /* Going to manual setting */
329 dvfs_stop();
330 }
331
332 /* Skip gaps in mask */
333 while (((1 << dvfs_wp) & dvfs_mask) == 0) dvfs_wp++;
334 dvfs_set_level(dvfs_wp);
335 }
336
337 break;
338
339 case BUTTON_DOWN:
340 if (--dvfs_wp == -1)
341 {
342 /* Going back to automatic */
343 dvfs_start();
344 }
345 else
346 {
347 if (dvfs_wp <= -2)
348 {
349 /* Going to manual setting */
350 dvfs_stop();
351 dvfs_wp = DVFS_NUM_LEVELS - 1;
352 }
353
354 /* Skip gaps in mask */
355 while (((1 << dvfs_wp) & dvfs_mask) == 0) dvfs_wp--;
356 dvfs_set_level(dvfs_wp);
357 }
358 break;
359
360 /* GP Load tracking */
361 case BUTTON_VOL_UP:
362 if (ltwlevel < 28)
363 dvfs_set_gp_sense(++ltwlevel, ltdetect);
364 break;
365
366 case BUTTON_VOL_DOWN:
367 if (ltwlevel > 0)
368 dvfs_set_gp_sense(--ltwlevel, ltdetect);
369 break;
370
371 case BUTTON_PLAY:
372 dptc_on = !dptc_enabled();
373 dptc_on ? dptc_start() : dptc_stop();
374 break;
375
376 case BUTTON_SELECT:
377 dvfs_start();
378 dptc_start();
379 dvfs_set_gp_sense(-1, 0);
380
381 dvfs_wp = dvfs_enabled() ? -1 : (int)dvfs_get_level();
382 dptc_on = dptc_enabled();
383 dvfs_get_gp_sense(&ltwlevel, &ltdetect);
384 break;
385 }
386
387 lcd_update();
388 yield();
389 }
390}
diff --git a/firmware/target/arm/imx31/debug-target.h b/firmware/target/arm/imx31/debug-target.h
index 06baee5ea0..ca02ab84de 100644
--- a/firmware/target/arm/imx31/debug-target.h
+++ b/firmware/target/arm/imx31/debug-target.h
@@ -24,5 +24,6 @@
24#define DEBUG_CANCEL BUTTON_BACK 24#define DEBUG_CANCEL BUTTON_BACK
25bool __dbg_hw_info(void); 25bool __dbg_hw_info(void);
26bool dbg_ports(void); 26bool dbg_ports(void);
27bool __dbg_dvfs_dptc(void);
27 28
28#endif /* DEBUG_TARGET_H */ 29#endif /* DEBUG_TARGET_H */
diff --git a/firmware/target/arm/imx31/dvfs_dptc-imx31.c b/firmware/target/arm/imx31/dvfs_dptc-imx31.c
index 555e030af5..b78a995f87 100644
--- a/firmware/target/arm/imx31/dvfs_dptc-imx31.c
+++ b/firmware/target/arm/imx31/dvfs_dptc-imx31.c
@@ -74,8 +74,6 @@ unsigned int dvfs_nr_up = 0;
74unsigned int dvfs_nr_pnc = 0; 74unsigned int dvfs_nr_pnc = 0;
75unsigned int dvfs_nr_no = 0; 75unsigned int dvfs_nr_no = 0;
76 76
77static void dvfs_stop(void);
78
79 77
80/* Wait for the UPDTEN flag to be set so that all bits may be written */ 78/* Wait for the UPDTEN flag to be set so that all bits may be written */
81static inline void wait_for_dvfs_update_en(void) 79static inline void wait_for_dvfs_update_en(void)
@@ -279,6 +277,9 @@ static void INIT_ATTR dvfs_init(void)
279 iomuxc_set_pin_mux(IOMUXC_GPIO1_5, 277 iomuxc_set_pin_mux(IOMUXC_GPIO1_5,
280 IOMUXC_MUX_OUT_FUNCTIONAL | IOMUXC_MUX_IN_FUNCTIONAL); 278 IOMUXC_MUX_OUT_FUNCTIONAL | IOMUXC_MUX_IN_FUNCTIONAL);
281#endif 279#endif
280
281 /* GP load bits disabled */
282 bitclr32(&CCM_PMCR1, 0xf);
282 283
283 /* Initialize DVFS signal weights and detection modes. */ 284 /* Initialize DVFS signal weights and detection modes. */
284 int i; 285 int i;
@@ -321,66 +322,6 @@ static void INIT_ATTR dvfs_init(void)
321 logf("DVFS: Initialized"); 322 logf("DVFS: Initialized");
322} 323}
323 324
324
325/* Start the DVFS hardware */
326static void dvfs_start(void)
327{
328 int oldlevel;
329
330 /* Have to wait at least 3 div3 clocks before enabling after being
331 * stopped. */
332 udelay(1500);
333
334 oldlevel = disable_irq_save();
335
336 if (!dvfs_running)
337 {
338 dvfs_running = true;
339
340 /* Unmask DVFS interrupt source and enable DVFS. */
341 avic_enable_int(INT_CCM_DVFS, INT_TYPE_IRQ, INT_PRIO_DVFS,
342 CCM_DVFS_HANDLER);
343
344 CCM_PMCR0 = (CCM_PMCR0 & ~CCM_PMCR0_FSVAIM) | CCM_PMCR0_DVFEN;
345 }
346
347 restore_irq(oldlevel);
348
349 logf("DVFS: started");
350}
351
352
353/* Stop the DVFS hardware and return to default frequency */
354static void dvfs_stop(void)
355{
356 int oldlevel = disable_irq_save();
357
358 if (dvfs_running)
359 {
360 /* Mask DVFS interrupts. */
361 CCM_PMCR0 |= CCM_PMCR0_FSVAIM | CCM_PMCR0_LBMI;
362 avic_disable_int(INT_CCM_DVFS);
363
364 if (((CCM_PMCR0 & CCM_PMCR0_DVSUP) >> CCM_PMCR0_DVSUP_POS) !=
365 DVFS_LEVEL_DEFAULT)
366 {
367 /* Set default frequency level */
368 wait_for_dvfs_update_en();
369 do_dvfs_update(DVFS_LEVEL_DEFAULT, false);
370 wait_for_dvfs_update_en();
371 }
372
373 /* Disable DVFS. */
374 CCM_PMCR0 &= ~CCM_PMCR0_DVFEN;
375 dvfs_running = false;
376 }
377
378 restore_irq(oldlevel);
379
380 logf("DVFS: stopped");
381}
382
383
384/** DPTC **/ 325/** DPTC **/
385 326
386/* Request tracking since boot */ 327/* Request tracking since boot */
@@ -540,75 +481,87 @@ static void INIT_ATTR dptc_init(void)
540} 481}
541 482
542 483
543/* Start DPTC module */ 484/** Main module interface **/
544static void dptc_start(void)
545{
546 int oldlevel = disable_irq_save();
547 485
548 if (!dptc_running) 486/* Initialize DVFS and DPTC */
549 { 487void INIT_ATTR dvfs_dptc_init(void)
550 dptc_running = true; 488{
489 dptc_init();
490 dvfs_init();
491}
551 492
552 /* Enable DPTC and unmask interrupt. */
553 avic_enable_int(INT_CCM_CLK, INT_TYPE_IRQ, INT_PRIO_DPTC,
554 CCM_CLK_HANDLER);
555 493
556 update_dptc_counts(dvfs_level, dptc_wp); 494/* Start DVFS and DPTC */
557 enable_dptc(); 495void dvfs_dptc_start(void)
558 } 496{
497 dvfs_start();
498 dptc_start();
499}
559 500
560 restore_irq(oldlevel);
561 501
562 logf("DPTC: started"); 502/* Stop DVFS and DPTC */
503void dvfs_dptc_stop(void)
504{
505 dptc_stop();
506 dvfs_stop();
563} 507}
564 508
565 509/* Start the DVFS hardware */
566/* Stop the DPTC hardware if running and go back to default working point */ 510void dvfs_start(void)
567static void dptc_stop(void)
568{ 511{
569 int oldlevel = disable_irq_save(); 512 int oldlevel;
570 513
571 if (dptc_running) 514 /* Have to wait at least 3 div3 clocks before enabling after being
515 * stopped. */
516 udelay(1500);
517
518 oldlevel = disable_irq_save();
519
520 if (!dvfs_running)
572 { 521 {
573 dptc_running = false; 522 dvfs_running = true;
574 523
575 /* Disable DPTC and mask interrupt. */ 524 /* Unmask DVFS interrupt source and enable DVFS. */
576 CCM_PMCR0 = (CCM_PMCR0 & ~CCM_PMCR0_DPTEN) | CCM_PMCR0_PTVAIM; 525 avic_enable_int(INT_CCM_DVFS, INT_TYPE_IRQ, INT_PRIO_DVFS,
577 avic_disable_int(INT_CCM_CLK); 526 CCM_DVFS_HANDLER);
578 527
579 /* Go back to default working point. */ 528 CCM_PMCR0 = (CCM_PMCR0 & ~CCM_PMCR0_FSVAIM) | CCM_PMCR0_DVFEN;
580 dptc_new_wp(DPTC_WP_DEFAULT);
581 } 529 }
582 530
583 restore_irq(oldlevel); 531 restore_irq(oldlevel);
584 532
585 logf("DPTC: stopped"); 533 logf("DVFS: started");
586} 534}
587 535
588 536
589/** Main module interface **/ 537/* Stop the DVFS hardware and return to default frequency */
590 538void dvfs_stop(void)
591/* Initialize DVFS and DPTC */
592void INIT_ATTR dvfs_dptc_init(void)
593{ 539{
594 dptc_init(); 540 int oldlevel = disable_irq_save();
595 dvfs_init();
596}
597 541
542 if (dvfs_running)
543 {
544 /* Mask DVFS interrupts. */
545 CCM_PMCR0 |= CCM_PMCR0_FSVAIM | CCM_PMCR0_LBMI;
546 avic_disable_int(INT_CCM_DVFS);
598 547
599/* Start DVFS and DPTC */ 548 if (((CCM_PMCR0 & CCM_PMCR0_DVSUP) >> CCM_PMCR0_DVSUP_POS) !=
600void dvfs_dptc_start(void) 549 DVFS_LEVEL_DEFAULT)
601{ 550 {
602 dvfs_start(); 551 /* Set default frequency level */
603 dptc_start(); 552 wait_for_dvfs_update_en();
604} 553 do_dvfs_update(DVFS_LEVEL_DEFAULT, false);
554 wait_for_dvfs_update_en();
555 }
605 556
557 /* Disable DVFS. */
558 CCM_PMCR0 &= ~CCM_PMCR0_DVFEN;
559 dvfs_running = false;
560 }
606 561
607/* Stop DVFS and DPTC */ 562 restore_irq(oldlevel);
608void dvfs_dptc_stop(void) 563
609{ 564 logf("DVFS: stopped");
610 dptc_stop();
611 dvfs_stop();
612} 565}
613 566
614 567
@@ -648,6 +601,26 @@ void dvfs_set_lt_weight(enum DVFS_LT_SIGS index, unsigned long value)
648} 601}
649 602
650 603
604/* Return a signal load tracking weight */
605unsigned long dvfs_get_lt_weight(enum DVFS_LT_SIGS index)
606{
607 volatile unsigned long *reg_p = &CCM_LTR2;
608 unsigned int shift = 3 * index;
609
610 if (index < 9)
611 {
612 reg_p = &CCM_LTR3;
613 shift += 5; /* Bits 7:5, 10:8 ... 31:29 */
614 }
615 else if (index < 16)
616 {
617 shift -= 16; /* Bits 13:11, 16:14 ... 31:29 */
618 }
619
620 return (*reg_p & (0x7 << shift)) >> shift;
621}
622
623
651/* Set a signal load detection mode */ 624/* Set a signal load detection mode */
652void dvfs_set_lt_detect(enum DVFS_LT_SIGS index, bool edge) 625void dvfs_set_lt_detect(enum DVFS_LT_SIGS index, bool edge)
653{ 626{
@@ -662,6 +635,21 @@ void dvfs_set_lt_detect(enum DVFS_LT_SIGS index, bool edge)
662} 635}
663 636
664 637
638/* Returns a signal load detection mode */
639bool dvfs_get_lt_detect(enum DVFS_LT_SIGS index)
640{
641 unsigned int shift = 32;
642
643 if ((unsigned)index < 13)
644 shift = index + 3;
645 else if ((unsigned)index < 16)
646 shift = index + 29;
647
648 return !!((CCM_LTR0 & (1ul << shift)) >> shift);
649}
650
651
652/* Set/clear the general-purpose load tracking bit */
665void dvfs_set_gp_bit(enum DVFS_DVGPS dvgp, bool assert) 653void dvfs_set_gp_bit(enum DVFS_DVGPS dvgp, bool assert)
666{ 654{
667 if ((unsigned)dvgp <= 3) 655 if ((unsigned)dvgp <= 3)
@@ -672,6 +660,82 @@ void dvfs_set_gp_bit(enum DVFS_DVGPS dvgp, bool assert)
672} 660}
673 661
674 662
663/* Return the general-purpose load tracking bit */
664bool dvfs_get_gp_bit(enum DVFS_DVGPS dvgp)
665{
666 if ((unsigned)dvgp <= 3)
667 return (CCM_PMCR1 & (1ul << dvgp)) != 0;
668 return false;
669}
670
671
672/* Set GP load tracking by code.
673 * level_code:
674 * lt 0 =defaults
675 * 0 =all off ->
676 * 28 =highest load
677 * gte 28=highest load
678 * detect_mask bits:
679 * b[3:0]: 1=LTn edge detect, 0=LTn level detect
680 */
681void dvfs_set_gp_sense(int level_code, unsigned long detect_mask)
682{
683 int i;
684
685 for (i = 0; i <= 3; i++)
686 {
687 int ltsig_num = DVFS_LT_SIG_DVGP0 + i;
688 int gpw_num = DVFS_DVGP_0 + i;
689 unsigned long weight;
690 bool edge;
691 bool assert;
692
693 if (level_code < 0)
694 {
695 /* defaults */
696 detect_mask = 0;
697 assert = 0;
698 weight = lt_signals[ltsig_num].weight;
699 edge = lt_signals[ltsig_num].detect != 0;
700 }
701 else
702 {
703 weight = MIN(level_code, 7);
704 edge = !!(detect_mask & 1);
705 assert = weight > 0;
706 detect_mask >>= 1;
707 level_code -= 7;
708 if (level_code < 0)
709 level_code = 0;
710 }
711
712 dvfs_set_lt_weight(ltsig_num, weight); /* set weight */
713 dvfs_set_lt_detect(ltsig_num, edge); /* set detect mode */
714 dvfs_set_gp_bit(gpw_num, assert); /* set activity */
715 }
716}
717
718/* Return GP weight settings */
719void dvfs_get_gp_sense(int *level_code, unsigned long *detect_mask)
720{
721 int i;
722 int code = 0;
723 unsigned long mask = 0;
724
725 for (i = DVFS_LT_SIG_DVGP0; i <= DVFS_LT_SIG_DVGP3; i++)
726 {
727 code += dvfs_get_lt_weight(i);
728 mask = (mask << 1) | (dvfs_get_lt_detect(i) ? 1 : 0);
729 }
730
731 if (level_code)
732 *level_code = code;
733
734 if (detect_mask)
735 *detect_mask = mask;
736}
737
738
675/* Turn the wait-for-interrupt monitoring on or off */ 739/* Turn the wait-for-interrupt monitoring on or off */
676void dvfs_wfi_monitor(bool on) 740void dvfs_wfi_monitor(bool on)
677{ 741{
@@ -700,18 +764,80 @@ unsigned int dvfs_get_level(void)
700} 764}
701 765
702 766
767/* Is DVFS enabled? */
768bool dvfs_enabled(void)
769{
770 return dvfs_running;
771}
772
773
774/* Get bitmask of levels supported */
775unsigned int dvfs_level_mask(void)
776{
777 return DVFS_LEVEL_MASK;
778}
779
780
703/* If DVFS is disabled, set the level explicitly */ 781/* If DVFS is disabled, set the level explicitly */
704void dvfs_set_level(unsigned int level) 782void dvfs_set_level(unsigned int level)
705{ 783{
706 int oldlevel = disable_irq_save(); 784 int oldlevel = disable_irq_save();
707 785
708 unsigned int currlevel = 786 if (!dvfs_running && level < DVFS_NUM_LEVELS)
709 (CCM_PMCR0 & CCM_PMCR0_DVSUP) >> CCM_PMCR0_DVSUP_POS; 787 {
788 unsigned int currlevel =
789 (CCM_PMCR0 & CCM_PMCR0_DVSUP) >> CCM_PMCR0_DVSUP_POS;
790 if (level != currlevel && ((1 << level) & DVFS_LEVEL_MASK))
791 set_current_dvfs_level(level);
792 }
710 793
711 if (!dvfs_running && level < DVFS_NUM_LEVELS && level != currlevel) 794 restore_irq(oldlevel);
712 set_current_dvfs_level(level); 795}
796
797
798/* Start DPTC module */
799void dptc_start(void)
800{
801 int oldlevel = disable_irq_save();
802
803 if (!dptc_running)
804 {
805 dptc_running = true;
806
807 /* Enable DPTC and unmask interrupt. */
808 avic_enable_int(INT_CCM_CLK, INT_TYPE_IRQ, INT_PRIO_DPTC,
809 CCM_CLK_HANDLER);
810
811 update_dptc_counts(dvfs_level, dptc_wp);
812 enable_dptc();
813 }
713 814
714 restore_irq(oldlevel); 815 restore_irq(oldlevel);
816
817 logf("DPTC: started");
818}
819
820
821/* Stop the DPTC hardware if running and go back to default working point */
822void dptc_stop(void)
823{
824 int oldlevel = disable_irq_save();
825
826 if (dptc_running)
827 {
828 dptc_running = false;
829
830 /* Disable DPTC and mask interrupt. */
831 CCM_PMCR0 = (CCM_PMCR0 & ~CCM_PMCR0_DPTEN) | CCM_PMCR0_PTVAIM;
832 avic_disable_int(INT_CCM_CLK);
833
834 /* Go back to default working point. */
835 dptc_new_wp(DPTC_WP_DEFAULT);
836 }
837
838 restore_irq(oldlevel);
839
840 logf("DPTC: stopped");
715} 841}
716 842
717 843
@@ -722,6 +848,13 @@ unsigned int dptc_get_wp(void)
722} 848}
723 849
724 850
851/* Is DPTC enabled? */
852bool dptc_enabled(void)
853{
854 return dptc_running;
855}
856
857
725/* If DPTC is not running, set the working point explicitly */ 858/* If DPTC is not running, set the working point explicitly */
726void dptc_set_wp(unsigned int wp) 859void dptc_set_wp(unsigned int wp)
727{ 860{
diff --git a/firmware/target/arm/imx31/dvfs_dptc-imx31.h b/firmware/target/arm/imx31/dvfs_dptc-imx31.h
index 6b59bffae6..1f3f1ab20d 100644
--- a/firmware/target/arm/imx31/dvfs_dptc-imx31.h
+++ b/firmware/target/arm/imx31/dvfs_dptc-imx31.h
@@ -124,16 +124,28 @@ void dvfs_dptc_init(void);
124void dvfs_dptc_start(void); 124void dvfs_dptc_start(void);
125void dvfs_dptc_stop(void); 125void dvfs_dptc_stop(void);
126 126
127void dvfs_start(void);
128void dvfs_stop(void);
129bool dvfs_enabled(void);
127void dvfs_wfi_monitor(bool on); 130void dvfs_wfi_monitor(bool on);
128void dvfs_set_lt_weight(enum DVFS_LT_SIGS index, unsigned long value); 131void dvfs_set_lt_weight(enum DVFS_LT_SIGS index, unsigned long value);
132unsigned long dvfs_get_lt_weight(enum DVFS_LT_SIGS index);
129void dvfs_set_lt_detect(enum DVFS_LT_SIGS index, bool edge); 133void dvfs_set_lt_detect(enum DVFS_LT_SIGS index, bool edge);
134bool dvfs_get_lt_detect(enum DVFS_LT_SIGS index);
130void dvfs_set_gp_bit(enum DVFS_DVGPS dvgp, bool assert); 135void dvfs_set_gp_bit(enum DVFS_DVGPS dvgp, bool assert);
136bool dvfs_get_gp_bit(enum DVFS_DVGPS dvgp);
131void dvfs_int_mask(bool mask); 137void dvfs_int_mask(bool mask);
138void dvfs_set_gp_sense(int level_code, unsigned long detect_mask);
139void dvfs_get_gp_sense(int *level_code, unsigned long *detect_mask);
140unsigned int dvfs_level_mask(void);
132 141
133unsigned int dvfs_dptc_get_voltage(void); 142unsigned int dvfs_dptc_get_voltage(void);
134unsigned int dvfs_get_level(void); 143unsigned int dvfs_get_level(void);
135void dvfs_set_level(unsigned int level); 144void dvfs_set_level(unsigned int level);
136 145
146void dptc_start(void);
147void dptc_stop(void);
148bool dptc_enabled(void);
137unsigned int dptc_get_wp(void); 149unsigned int dptc_get_wp(void);
138void dptc_set_wp(unsigned int wp); 150void dptc_set_wp(unsigned int wp);
139 151
diff --git a/firmware/target/arm/imx31/gigabeat-s/dvfs_dptc_tables-target.h b/firmware/target/arm/imx31/gigabeat-s/dvfs_dptc_tables-target.h
index 89edf09675..f81ef83ac7 100644
--- a/firmware/target/arm/imx31/gigabeat-s/dvfs_dptc_tables-target.h
+++ b/firmware/target/arm/imx31/gigabeat-s/dvfs_dptc_tables-target.h
@@ -241,10 +241,10 @@ static const struct dvfs_lt_signal_descriptor lt_signals[16] =
241 { 0, 0 }, /* DVFS_LT_SIG_ARM11_P_FIQ_B_RBT_GATE */ 241 { 0, 0 }, /* DVFS_LT_SIG_ARM11_P_FIQ_B_RBT_GATE */
242 { 0, 0 }, /* DVFS_LT_SIG_IPI_GPIO1_INT0 */ 242 { 0, 0 }, /* DVFS_LT_SIG_IPI_GPIO1_INT0 */
243 { 0, 0 }, /* DVFS_LT_SIG_IPI_INT_IPU_FUNC */ 243 { 0, 0 }, /* DVFS_LT_SIG_IPI_INT_IPU_FUNC */
244 { 7, 0 }, /* DVFS_LT_SIG_DVGP0 */ 244 { 0, 0 }, /* DVFS_LT_SIG_DVGP0 */
245 { 7, 0 }, /* DVFS_LT_SIG_DVGP1 */ 245 { 0, 0 }, /* DVFS_LT_SIG_DVGP1 */
246 { 7, 0 }, /* DVFS_LT_SIG_DVGP2 */ 246 { 0, 0 }, /* DVFS_LT_SIG_DVGP2 */
247 { 7, 0 }, /* DVFS_LT_SIG_DVGP3 */ 247 { 0, 0 }, /* DVFS_LT_SIG_DVGP3 */
248}; 248};
249 249
250#endif /* _DVFS_DPTC_TARGET_H_ */ 250#endif /* _DVFS_DPTC_TARGET_H_ */