summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2009-01-23 01:23:25 +0000
committerMichael Sevakis <jethead71@rockbox.org>2009-01-23 01:23:25 +0000
commit7bcfc38b4216b73afaeffec506a83debb7e58df2 (patch)
tree8904a1a2ccc27f3eabc1a8c64fee91ea3dcf1f10
parentda76a3469437261bd8857c6eddeaafcc601f373e (diff)
downloadrockbox-7bcfc38b4216b73afaeffec506a83debb7e58df2.tar.gz
rockbox-7bcfc38b4216b73afaeffec506a83debb7e58df2.zip
Gigabeat S: Implement a genuine udelay function. Timer is gated to not run in WFI mode to save power and as such time until rollover is variable.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19820 a1c6a512-1295-4272-9138-f99709370657
-rwxr-xr-xfirmware/export/imx31l.h86
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/button-imx31.c8
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/system-imx31.c31
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/system-target.h17
4 files changed, 123 insertions, 19 deletions
diff --git a/firmware/export/imx31l.h b/firmware/export/imx31l.h
index b55a56b105..c9ef446e90 100755
--- a/firmware/export/imx31l.h
+++ b/firmware/export/imx31l.h
@@ -514,6 +514,92 @@
514 514
515#define EPITSR_OCIF (1 << 0) 515#define EPITSR_OCIF (1 << 0)
516 516
517/* GPT */
518#define GPTCR (*(REG32_PTR_T)(GPT1_BASE_ADDR+0x00))
519#define GPTPR (*(REG32_PTR_T)(GPT1_BASE_ADDR+0x04))
520#define GPTSR (*(REG32_PTR_T)(GPT1_BASE_ADDR+0x08))
521#define GPTIR (*(REG32_PTR_T)(GPT1_BASE_ADDR+0x0C))
522#define GPTOCR1 (*(REG32_PTR_T)(GPT1_BASE_ADDR+0x10))
523#define GPTOCR2 (*(REG32_PTR_T)(GPT1_BASE_ADDR+0x14))
524#define GPTOCR3 (*(REG32_PTR_T)(GPT1_BASE_ADDR+0x18))
525#define GPTICR1 (*(REG32_PTR_T)(GPT1_BASE_ADDR+0x1C))
526#define GPTICR2 (*(REG32_PTR_T)(GPT1_BASE_ADDR+0x20))
527#define GPTCNT (*(REG32_PTR_T)(GPT1_BASE_ADDR+0x24))
528
529/* GPTCR */
530#define GPTCR_FO3 (0x1 << 31)
531#define GPTCR_FO2 (0x1 << 30)
532#define GPTCR_FO1 (0x1 << 29)
533
534#define GPTCR_OM3 (0x7 << 26)
535#define GPTCR_OM3_DISCONNECTED (0x0 << 26)
536#define GPTCR_OM3_TOGGLE (0x1 << 26)
537#define GPTCR_OM3_CLEAR (0x2 << 26)
538#define GPTCR_OM3_SET (0x3 << 26)
539#define GPTCR_OM3_SINGLE_COUNT (0x4 << 26)
540 /* 0x5-0x7 same as 0x4 */
541
542#define GPTCR_OM2 (0x7 << 23)
543#define GPTCR_OM2_DISCONNECTED (0x0 << 23)
544#define GPTCR_OM2_TOGGLE (0x1 << 23)
545#define GPTCR_OM2_CLEAR (0x2 << 23)
546#define GPTCR_OM2_SET (0x3 << 23)
547#define GPTCR_OM2_SINGLE_COUNT (0x4 << 23)
548
549 /* 0x5-0x7 same as 0x4 */
550#define GPTCR_OM1 (0x7 << 20)
551#define GPTCR_OM1_DISCONNECTED (0x0 << 20)
552#define GPTCR_OM1_TOGGLE (0x1 << 20)
553#define GPTCR_OM1_CLEAR (0x2 << 20)
554#define GPTCR_OM1_SET (0x3 << 20)
555#define GPTCR_OM1_SINGLE_COUNT (0x4 << 20)
556
557 /* 0x5-0x7 same as 0x4 */
558#define GPTCR_IM2 (0x3 << 18)
559#define GPTCR_IM2_DISABLED (0x0 << 18)
560#define GPTCR_IM2_RISING (0x1 << 18)
561#define GPTCR_IM2_FALLING (0x2 << 18)
562#define GPTCR_IM2_BOTH (0x3 << 18)
563
564#define GPTCR_IM1 (0x3 << 16)
565#define GPTCR_IM1_DISABLED (0x0 << 16)
566#define GPTCR_IM1_RISING (0x1 << 16)
567#define GPTCR_IM1_FALLING (0x2 << 16)
568#define GPTCR_IM1_BOTH (0x3 << 16)
569
570#define GPTCR_SWR (0x1 << 15)
571#define GPTCR_FRR (0x1 << 9)
572
573#define GPTCR_CLKSRC (0x7 << 6)
574#define GPTCR_CLKSRC_NONE (0x0 << 6)
575#define GPTCR_CLKSRC_IPG_CLK (0x1 << 6)
576#define GPTCR_CLKSRC_IPG_CLK_HIGHFREQ (0x2 << 6)
577#define GPTCR_CLKSRC_IPG_CLK_32K (0x4 << 6)
578/* Other values not defined */
579
580#define GPTCR_STOPEN (0x1 << 5)
581#define GPTCR_DOZEN (0x1 << 4)
582#define GPTCR_WAITEN (0x1 << 3)
583#define GPTCR_DBGEN (0x1 << 2)
584#define GPTCR_ENMODE (0x1 << 1)
585#define GPTCR_EN (0x1 << 0)
586
587/* GPTSR */
588#define GPTSR_ROV (0x1 << 5)
589#define GPTSR_IF2 (0x1 << 4)
590#define GPTSR_IF1 (0x1 << 3)
591#define GPTSR_OF3 (0x1 << 2)
592#define GPTSR_OF2 (0x1 << 1)
593#define GPTSR_OF1 (0x1 << 0)
594
595/* GPTIR */
596#define GPTIR_ROV (0x1 << 5)
597#define GPTIR_IF2IE (0x1 << 4)
598#define GPTIR_IF1IE (0x1 << 3)
599#define GPTIR_OF3IE (0x1 << 2)
600#define GPTIR_OF2IE (0x1 << 1)
601#define GPTIR_OF1IE (0x1 << 0)
602
517/* GPIO */ 603/* GPIO */
518#define GPIO1_DR (*(REG32_PTR_T)(GPIO1_BASE_ADDR+0x00)) 604#define GPIO1_DR (*(REG32_PTR_T)(GPIO1_BASE_ADDR+0x00))
519#define GPIO1_GDIR (*(REG32_PTR_T)(GPIO1_BASE_ADDR+0x04)) 605#define GPIO1_GDIR (*(REG32_PTR_T)(GPIO1_BASE_ADDR+0x04))
diff --git a/firmware/target/arm/imx31/gigabeat-s/button-imx31.c b/firmware/target/arm/imx31/gigabeat-s/button-imx31.c
index 7c432450c2..587e66e0bc 100644
--- a/firmware/target/arm/imx31/gigabeat-s/button-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/button-imx31.c
@@ -68,8 +68,6 @@ static __attribute__((interrupt("IRQ"))) void KPP_HANDLER(void)
68 68
69 for (col = 0; col < 3; col++) /* Col */ 69 for (col = 0; col < 3; col++) /* Col */
70 { 70 {
71 int i;
72
73 /* 2. Write 1s to KPDR[10:8] setting column data to 1s */ 71 /* 2. Write 1s to KPDR[10:8] setting column data to 1s */
74 KPP_KPDR |= (0x7 << 8); 72 KPP_KPDR |= (0x7 << 8);
75 73
@@ -78,8 +76,7 @@ static __attribute__((interrupt("IRQ"))) void KPP_HANDLER(void)
78 KPP_KPCR &= ~(0x7 << 8); 76 KPP_KPCR &= ~(0x7 << 8);
79 77
80 /* Give the columns time to discharge */ 78 /* Give the columns time to discharge */
81 for (i = 0; i < 128; i++) /* TODO: find minimum safe delay */ 79 udelay(2);
82 asm volatile ("");
83 80
84 /* 4. Configure columns as open-drain */ 81 /* 4. Configure columns as open-drain */
85 KPP_KPCR |= (0x7 << 8); 82 KPP_KPCR |= (0x7 << 8);
@@ -94,8 +91,7 @@ static __attribute__((interrupt("IRQ"))) void KPP_HANDLER(void)
94 91
95 /* Delay added to avoid propagating the 0 from column to row 92 /* Delay added to avoid propagating the 0 from column to row
96 * when scanning. */ 93 * when scanning. */
97 for (i = 0; i < 128; i++) /* TODO: find minimum safe delay */ 94 udelay(2);
98 asm volatile ("");
99 95
100 /* Read row input */ 96 /* Read row input */
101 button |= (~KPP_KPDR & kms[col].mask) << kms[col].shift; 97 button |= (~KPP_KPDR & kms[col].mask) << kms[col].shift;
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c
index c339f4fe7c..7454806d07 100644
--- a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c
@@ -32,6 +32,8 @@
32#include "clkctl-imx31.h" 32#include "clkctl-imx31.h"
33#include "mc13783.h" 33#include "mc13783.h"
34 34
35/** Watchdog timer routines **/
36
35/* Initialize the watchdog timer */ 37/* Initialize the watchdog timer */
36void watchdog_init(unsigned int half_seconds) 38void watchdog_init(unsigned int half_seconds)
37{ 39{
@@ -57,6 +59,33 @@ void watchdog_service(void)
57 WDOG_WSR = 0xaaaa; 59 WDOG_WSR = 0xaaaa;
58} 60}
59 61
62/** GPT timer routines - basis for udelay **/
63
64/* Start the general-purpose timer (1MHz) */
65void gpt_start(void)
66{
67 imx31_clkctl_module_clock_gating(CG_GPT, CGM_ON_RUN_WAIT);
68 unsigned int ipg_mhz = imx31_clkctl_get_ipg_clk() / 1000000;
69
70 GPTCR &= ~GPTCR_EN; /* Disable counter */
71 GPTCR |= GPTCR_SWR; /* Reset module */
72 while (GPTCR & GPTCR_SWR);
73 /* No output
74 * No capture
75 * Enable in run mode only (doesn't tick while in WFI)
76 * Freerun mode (count to 0xFFFFFFFF and roll-over to 0x00000000)
77 */
78 GPTCR = GPTCR_FRR | GPTCR_CLKSRC_IPG_CLK;
79 GPTPR = ipg_mhz - 1;
80 GPTCR |= GPTCR_EN;
81}
82
83/* Stop the general-purpose timer */
84void gpt_stop(void)
85{
86 GPTCR &= ~GPTCR_EN;
87}
88
60int system_memory_guard(int newmode) 89int system_memory_guard(int newmode)
61{ 90{
62 (void)newmode; 91 (void)newmode;
@@ -84,7 +113,6 @@ void system_init(void)
84 /* CGR0 */ 113 /* CGR0 */
85 CG_SD_MMC1, 114 CG_SD_MMC1,
86 CG_SD_MMC2, 115 CG_SD_MMC2,
87 CG_GPT,
88 CG_IIM, 116 CG_IIM,
89 CG_SDMA, 117 CG_SDMA,
90 CG_CSPI3, 118 CG_CSPI3,
@@ -140,6 +168,7 @@ void system_init(void)
140 imx31_clkctl_module_clock_gating(disable_clocks[i], CGM_OFF); 168 imx31_clkctl_module_clock_gating(disable_clocks[i], CGM_OFF);
141 169
142 avic_init(); 170 avic_init();
171 gpt_start();
143 gpio_init(); 172 gpio_init();
144} 173}
145 174
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-target.h b/firmware/target/arm/imx31/gigabeat-s/system-target.h
index b99b31d1b4..c7797e43c9 100644
--- a/firmware/target/arm/imx31/gigabeat-s/system-target.h
+++ b/firmware/target/arm/imx31/gigabeat-s/system-target.h
@@ -31,25 +31,18 @@
31#define CPUFREQ_MAX CPU_FREQ 31#define CPUFREQ_MAX CPU_FREQ
32#endif 32#endif
33 33
34/* For USB driver - no accuracy assurance */
35static inline void udelay(unsigned int usecs) 34static inline void udelay(unsigned int usecs)
36{ 35{
37 unsigned int x; 36 unsigned stop = GPTCNT + usecs;
38 for (x = 0; x < 300*usecs; x++) 37 while (TIME_BEFORE(GPTCNT, stop));
39 asm volatile ("");
40} 38}
41 39
42#if 0
43static inline void udelay(unsigned int usecs)
44{
45 volatile signed int stop = EPITCNT1 - usecs;
46 while ((signed int)EPITCNT1 > stop);
47}
48#endif
49
50void watchdog_init(unsigned int half_seconds); 40void watchdog_init(unsigned int half_seconds);
51void watchdog_service(void); 41void watchdog_service(void);
52 42
43void gpt_start(void);
44void gpt_stop(void);
45
53/* Prepare for transition to firmware */ 46/* Prepare for transition to firmware */
54void system_prepare_fw_start(void); 47void system_prepare_fw_start(void);
55void tick_stop(void); 48void tick_stop(void);