summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/target/arm/as3525/system-as3525.c20
-rw-r--r--firmware/target/arm/as3525/system-target.h63
-rw-r--r--firmware/target/arm/as3525/usb-drv-as3525.c3
3 files changed, 22 insertions, 64 deletions
diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c
index 940f183c63..aa98aff852 100644
--- a/firmware/target/arm/as3525/system-as3525.c
+++ b/firmware/target/arm/as3525/system-as3525.c
@@ -326,6 +326,26 @@ int system_memory_guard(int newmode)
326 return 0; 326 return 0;
327} 327}
328 328
329void udelay(unsigned short usecs)
330{
331 unsigned cycles_per_usec;
332 unsigned delay;
333
334 if (cpu_frequency == CPUFREQ_MAX) {
335 cycles_per_usec = (CPUFREQ_MAX + 999999) / 1000000;
336 } else {
337 cycles_per_usec = (CPUFREQ_NORMAL + 999999) / 1000000;
338 }
339
340 delay = (usecs * cycles_per_usec + 3) / 4;
341
342 asm volatile(
343 "1: subs %0, %0, #1 \n" /* 1 cycle */
344 " bne 1b \n" /* 3 cycles */
345 : : "r"(delay)
346 );
347}
348
329#ifndef BOOTLOADER 349#ifndef BOOTLOADER
330#ifdef HAVE_ADJUSTABLE_CPU_FREQ 350#ifdef HAVE_ADJUSTABLE_CPU_FREQ
331 351
diff --git a/firmware/target/arm/as3525/system-target.h b/firmware/target/arm/as3525/system-target.h
index 523237ffcd..90e5e3a882 100644
--- a/firmware/target/arm/as3525/system-target.h
+++ b/firmware/target/arm/as3525/system-target.h
@@ -49,66 +49,5 @@ extern int c200v2_variant;
49#define TIMER_PERIOD (KERNEL_TIMER_FREQ/HZ) 49#define TIMER_PERIOD (KERNEL_TIMER_FREQ/HZ)
50#endif 50#endif
51 51
52/* 52void udelay(unsigned short usecs);
53 * This function is not overly accurate, so rather call it with an usec more
54 * than less (see below comment)
55 *
56 * if inlined it expands to a really small and fast function if it's called
57 * with compile time constants */
58static inline void udelay(unsigned usecs) __attribute__((always_inline));
59static inline void udelay(unsigned usecs)
60{
61 unsigned now;
62 int end;
63
64 /**
65 * we're limited to 0.666us multiplies due to the odd timer frequency (1.5MHz),
66 * to avoid calculating which is safer (need to round up for small values)
67 * and saves spending time in the divider we have a lut for
68 * small us values, it should be roughly us*3/2
69 **/
70 static const unsigned char udelay_lut[] =
71 {
72 0, 2, 3, 5, 6, 8, 9, 11, 12, 14,
73 15, 17, 18, 20, 21, 23, 24, 26, 27, 29,
74 };
75
76
77 now = TIMER2_VALUE;
78 /* we don't want to handle multiple overflows, so limit the numbers
79 * (if you want to wait more than a tick just poll current_tick, or
80 * call sleep()) */
81 if (UNLIKELY(usecs >= (TIMER_PERIOD*2/3)))
82 panicf("%s(): %d too high!", __func__, usecs);
83 if (UNLIKELY(usecs <= 0))
84 return;
85 if (usecs < ARRAYLEN(udelay_lut))
86 { /* the timer decrements */
87 end = now - udelay_lut[usecs];
88 }
89 else
90 { /* to usecs */
91 int delay = usecs * 3 / 2; /* us * 0.666 = us*timer_period */
92 end = now - delay;
93 }
94
95 unsigned old;
96
97 /* underrun ? */
98 if (end < 0)
99 {
100 do {
101 old = now;
102 now = TIMER2_VALUE;
103 } while(now <= old); /* if the new value is higher then we wrapped */
104
105 end += TIMER_PERIOD;
106 }
107
108 do {
109 /* if timer wraps then we missed our end value */
110 old = now;
111 now = TIMER2_VALUE;
112 } while(now > (unsigned)end && now <= old);
113}
114#endif /* SYSTEM_TARGET_H */ 53#endif /* SYSTEM_TARGET_H */
diff --git a/firmware/target/arm/as3525/usb-drv-as3525.c b/firmware/target/arm/as3525/usb-drv-as3525.c
index 0b73713c51..0b69e8953b 100644
--- a/firmware/target/arm/as3525/usb-drv-as3525.c
+++ b/firmware/target/arm/as3525/usb-drv-as3525.c
@@ -80,8 +80,7 @@ void usb_attach(void)
80/* delay is in milliseconds */ 80/* delay is in milliseconds */
81static inline void usb_delay(int delay) 81static inline void usb_delay(int delay)
82{ 82{
83 while(delay--) 83 udelay(1000 * delay);
84 udelay(1000);
85} 84}
86 85
87static void usb_phy_on(void) 86static void usb_phy_on(void)