Merge branch 'upstream-fixes'
[mw/micromonitor-lm32.git] / umon_ports / bf537 / cpuio.c
1 #include "config.h"
2 #include "stddefs.h"
3 #include "cpuio.h"
4 #include "genlib.h"
5 #include "cache.h"
6 #include "warmstart.h"
7 #include "cpu.h"
8 #include "cdefBF537.h"
9 #include "sd.h"
10
11 #define THR             0x00
12 #define RBR             0x00
13 #define DLL             0x00
14 #define DLH             0x04
15 #define IER             0x04
16 #define LCR             0x0c
17 #define MCR             0x10
18 #define LSR             0x14
19 #define SCR             0x1c
20 #define GCTL    0x24
21
22 #define UART0_BASE      0xffc00400
23 #define UART1_BASE      0xffc02000
24 #define CONSOLE(reg) (UART0_BASE+reg)
25
26 /* If for some reason, DMA-based character reception on the UARTs is
27  * not desireable, then comment out this definition...
28  */
29 #define DMA_UART_RCV
30
31 #if PLATFORM_VTCEZ
32 #undef DMA_UART_RCV
33 #endif
34
35 #ifdef DMA_UART_RCV
36 #define UBUFSIZ 32
37 uint32_t ubuf0[UBUFSIZ/4];
38 uint8_t *uptr0;
39 uint8_t *uend0;
40 #endif
41
42
43 struct abcd {
44         int a;
45         char b;
46         int c;
47         long d;
48 };
49
50 struct abcd S1, S2;
51
52 void
53 test_func(int mode)
54 {
55         S1.a = 44;
56         S1.b = 'c';
57         S1.c = 9999;
58         S1.d = 0x10002345;
59         printf("S1: %d 0x%02x %d 0x%lx\n",S1.a, S1.b, S1.c, S1.d);
60
61         if (mode == 1) {
62                 printf("This will fail...\n");
63                 S2 = S1;
64         }
65         else {
66                 printf("This will work...\n");
67                 memcpy((char *)&S2,(char *)&S1,sizeof(struct abcd));
68         }
69
70         printf("S2: %d 0x%02x %d 0x%lx\n",S2.a, S2.b, S2.c, S2.d);
71 }
72
73 /* devInit():
74  * Initialize console...
75  */
76 void
77 devInit(int baud)
78 {
79         ushort tmp;
80
81         *(vushort *)CONSOLE(GCTL) = 1;          /* Enable UART clocks */
82         *(vushort *)CONSOLE(MCR) = 0;
83         *(vushort *)CONSOLE(LCR) = 0x03;        /* no parity, 8-bit char, 1 stopbit */
84         tmp = *(vushort *)CONSOLE(LSR);         /* clear LSR */
85         *(vushort *)CONSOLE(IER) = 0;           /* no ints */
86         *(vushort *)CONSOLE(SCR) = 0;           /* no ints */
87         ConsoleBaudSet(baud);
88
89 #ifdef DMA_UART_RCV
90         /* Init DMA8 (UART0 RCV):
91          */
92         *pDMA8_START_ADDR = ubuf0;
93         *pDMA8_CURR_ADDR = ubuf0;
94         *pDMA8_X_COUNT = UBUFSIZ;
95         *pDMA8_X_MODIFY = 1;
96         *pDMA8_CURR_X_COUNT = 0;
97         *pDMA8_CONFIG = DMAEN | WNR | WDSIZE_8 | FLOW_AUTO;
98         *pUART0_IER = ERBFI;
99         uptr0 = (uint8_t *)ubuf0;
100         uend0 = uptr0+UBUFSIZ;
101 #endif
102
103 }
104
105 /* ConsoleBaudSet():
106  * Change baud rate to that of 'baud'.
107  */
108 int
109 ConsoleBaudSet(int baud)
110 {
111         unsigned short  lctl, hi, lo;
112
113         lo = SYSCLKFREQ/(baud*16);
114         hi = (lo & 0xff00) >> 8;
115         lo &= 0x00ff;
116
117         lctl = *(vushort *)CONSOLE(LCR);        /* Save linectl reg */
118         *(vushort *)CONSOLE(LCR) = DLAB;
119         *(vushort *)CONSOLE(DLL) = lo;          /* Set baud divisor */
120         *(vushort *)CONSOLE(DLH) = hi;
121         *(vushort *)CONSOLE(LCR) = lctl;        /* Restore linectl reg */
122         return(0);
123 }
124
125 /* target_console_empty():
126  * Returns 1 if there are no characters waiting to
127  * be put out on the UART; else return 0 indicating that the UART
128  * is still busy outputting characters from its FIFO.
129  */
130 int
131 target_console_empty(void)
132 {
133         if (*(ushort *)CONSOLE(LSR) & TEMT)
134                 return(1);
135         return(0);
136 }
137
138 /* target_putchar():
139  * When buffer has space available, load the incoming character
140  * into the UART.
141  */
142 int
143 target_putchar(char c)
144 {
145     /* Wait for transmit ready bit */
146         while(!(*(vushort *)CONSOLE(LSR) & THRE));
147
148         *(vushort *)CONSOLE(THR) = (ushort)c;
149
150     return((int)c);
151 }
152
153 /* target_gotachar():
154  * Return 0 if no char is avaialable at UART rcv fifo; else 1.
155  * Do NOT pull character out of fifo, just return status. 
156  */
157 int
158 target_gotachar(void)
159 {
160 #ifdef DMA_UART_RCV
161         if (*pDMA8_CURR_ADDR != uptr0)
162                 return(1);
163 #else
164         if (*(vushort *)CONSOLE(LSR) & DR)
165                 return(1);
166 #endif
167         return(0);
168 }
169
170 /* target_getchar():
171  * Assume there is a character in the UART's input buffer and just
172  * pull it out and return it.
173  */
174 int 
175 target_getchar(void)
176 {
177 #ifdef DMA_UART_RCV
178         if (uptr0 == uend0)
179                 uptr0 = (uint8_t *)ubuf0;
180         return(*uptr0++);
181 #else
182     return((int)*(vushort *)CONSOLE(RBR));
183 #endif
184 }
185
186 int
187 iInvalidateRange(char *start, int size)
188 {
189         long addr, end, imemctrl;
190
191
192         /* If start and size are zero, then we are to invalidate the entire
193          * i-Cache.  That's done by clearing the IMC bit then re-setting it.
194          */
195         if ((start == 0) && (size == 0)) {
196                 imemctrl = *pIMEM_CONTROL;
197
198                 asm("ssync;");
199                 *pIMEM_CONTROL &= ~IMC;
200                 asm("csync;");
201                 *pIMEM_CONTROL = imemctrl;
202                 asm("csync;");
203         }
204         else {
205                 addr = (long)start;
206                 addr &= ~0x1f;
207                 end = (long)(start + size);
208
209                 for(;addr < end; addr += 32)
210                         IFlush((char *)addr);
211         }
212         return(0);
213 }
214
215 int
216 dFlushRange(char *start, int size)
217 {
218         long addr, end;
219
220         /* TODO:
221          * This needs to support the "start=0,size=0" input to flush
222          * the entire d-cache.
223          */
224         addr = (long)start;
225         addr &= ~0x1f;
226         end = (long)(start + size);
227
228         for(;addr < end; addr += 32)
229                 Flush((char *)addr);
230
231         return(0);
232 }
233
234 /* cacheInitForTarget():
235  * Establish target specific function pointers and
236  * enable i-cache...
237  * Refer to $core/cache.c for a description of the function pointers.
238  * NOTE:
239  * If cache (either I or D or both) is enabled, then it is important
240  * that the appropriate cacheflush/invalidate function be established.
241  * This is very important because programs (i.e. cpu instructions) are
242  * transferred to memory using data memory accesses and could
243  * potentially result in cache coherency problems.
244  */
245 void
246 cacheInitForTarget(void)
247 {
248         extern int icache_off(void);
249         extern int dcache_off(void);
250
251         icacheDisable = icache_off;
252         dcacheDisable = dcache_off;
253         dcacheFlush = dFlushRange;
254         icacheInvalidate = iInvalidateRange;
255 }
256
257 /* target_reset():
258  * From BF537 programmer's manual...
259  * The reset vector is determined by the processor system. It points to the
260  * start of the on-chip boot ROM (0xef000000), or to the start of
261  * external asynchronous memory (0x20000000), depending on the state of
262  * the BMODE pins.  uMon is built to run in Mode 0, which means the CPU
263  * starts fetching from location 0x20000000 immediately out of reset.
264  */
265 void
266 target_reset(void)
267 {
268         flushDcache(0,0);
269         disableDcache();
270         invalidateIcache(0,0);
271         disableIcache();
272
273         /* Use Watchdog to generate reset...
274          */
275         *pWDOG_CTL = 0x0ad0;    /* Disable watchdog */
276         *pWDOG_CNT = 0x0004;    /* Set a low count value */
277         *pWDOG_CTL = 0x0000;    /* Enable watchdog */
278         while(1);                               /* Wait for the hit */
279 }
280
281 void
282 ledloop(void)
283 {
284         volatile int i;
285
286         *pPORTFIO_DIR |= 0x0100;
287         while(1) {
288                 *pPORTFIO_SET |= 0x0100;
289                 for(i=0;i<1000000;i++);
290                 *pPORTFIO_CLEAR |= 0x0100;
291                 for(i=0;i<1000000;i++);
292         }
293 }
294
295 /* If any CPU IO wasn't initialized in reset.S, do it here...
296  * This just provides a "C-level" IO init opportunity. 
297  */
298 void
299 initCPUio(void)
300 {
301 #if INCLUDE_SD
302         sdio_init();
303 #endif
304 }
305
306 void
307 showBlackfinInfo(int center)
308 {
309         int (*pfunc)(char *, ...);
310
311         if (center)
312                 pfunc = cprintf;
313         else
314                 pfunc = printf;
315         pfunc("CPU Version %d\n",*pDSPID & 0x0000ffff);
316 }
317
318 int
319 bfin_i2cshow(int interface)
320 {
321 #if PLATFORM_VTCEZ
322         printf("Addr      Description\n");
323         printf("0x42      ADV7173B Multiformat SDTV Video Decoder\n");
324         printf("0xb8      MT9V022  Digital Image Sensor\n");
325 #else
326         printf("SHOW function not available on BFIN eval board.\n");
327 #endif
328         return(0);
329 }