]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/edb7xxx/v2_0/src/edb7xxx_misc.c
Initial revision
[karo-tx-redboot.git] / packages / hal / arm / edb7xxx / v2_0 / src / edb7xxx_misc.c
1 //==========================================================================
2 //
3 //      edb7xxx_misc.c
4 //
5 //      HAL misc board support code for ARM EDB7XXX-1
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 // Copyright (C) 2003 Gary Thomas <gary@mind.be>
13 //
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
17 //
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21 // for more details.
22 //
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 //
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
33 //
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
36 //
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38 // at http://sources.redhat.com/ecos/ecos-license/
39 // -------------------------------------------
40 //####ECOSGPLCOPYRIGHTEND####
41 //==========================================================================
42 //#####DESCRIPTIONBEGIN####
43 //
44 // Author(s):    gthomas
45 // Contributors: gthomas
46 // Date:         1999-02-20
47 // Purpose:      HAL board support
48 // Description:  Implementations of HAL board interfaces
49 //
50 //####DESCRIPTIONEND####
51 //
52 //========================================================================*/
53
54 #include <pkgconf/hal.h>
55 #include <pkgconf/system.h>
56 #include CYGBLD_HAL_PLATFORM_H
57
58 #include <cyg/infra/cyg_type.h>         // base types
59 #include <cyg/infra/cyg_trac.h>         // tracing macros
60 #include <cyg/infra/cyg_ass.h>          // assertion macros
61
62 #include <cyg/hal/hal_io.h>             // IO macros
63 #include <cyg/hal/hal_arch.h>           // Register state info
64 #include <cyg/hal/hal_diag.h>
65 #include <cyg/hal/hal_intr.h>           // Interrupt names
66 #include <cyg/hal/hal_cache.h>
67 #include <cyg/hal/hal_edb7xxx.h>         // Hardware definitions
68 #include <cyg/hal/hal_if.h>             // calling interface API
69
70 // #define CYGHWR_HAL_ARM_EDB7XXX_BATLOW
71 #ifdef CYGHWR_HAL_ARM_EDB7XXX_BATLOW
72 #include <cyg/hal/hal_intr.h>           // HAL interrupt macros
73 #include <cyg/hal/drv_api.h>            // HAL ISR support
74 static cyg_interrupt batlow_interrupt;
75 static cyg_handle_t  batlow_interrupt_handle;
76 #endif
77
78 #if (CYGHWR_HAL_ARM_EDB7XXX_PROCESSOR_CLOCK == 18432)
79 #define CPU_CLOCK 0
80 #elif (CYGHWR_HAL_ARM_EDB7XXX_PROCESSOR_CLOCK == 36864)
81 #define CPU_CLOCK 1
82 #elif (CYGHWR_HAL_ARM_EDB7XXX_PROCESSOR_CLOCK == 49152)
83 #define CPU_CLOCK 2
84 #elif (CYGHWR_HAL_ARM_EDB7XXX_PROCESSOR_CLOCK == 73728)
85 #define CPU_CLOCK 3
86 #elif (CYGHWR_HAL_ARM_EDB7XXX_PROCESSOR_CLOCK == 90317)
87 #define CPU_CLOCK 3 // Yes, the same
88 #define CPU_CLOCK_90MHZ
89 #else
90 #error Invalid CPU clock frequency
91 #endif
92
93 static cyg_uint32 _period;
94 void dram_delay_loop(void);
95
96 // Use Timer/Counter #2 for system clock
97
98 void hal_clock_initialize(cyg_uint32 period)
99 {
100     volatile cyg_uint32 *syscon1 = (volatile cyg_uint32 *)SYSCON1;
101     volatile cyg_uint32 *tc2d = (volatile cyg_uint32 *)TC2D;
102     // Set timer to 512KHz, prescale mode
103     *syscon1 = (*syscon1 & ~(SYSCON1_TC2M|SYSCON1_TC2S)) | SYSCON1_TC2S | SYSCON1_TC2M;
104     // Initialize counter
105     *tc2d = period;
106     _period = period;
107 }
108
109 // This routine is called during a clock interrupt.
110
111 static void __inline__
112 enable_FIQ(void)
113 {
114     asm volatile ("mrs r0,cpsr;"
115                   "bic r0,r0,#0x40;"
116                   "msr cpsr,r0");
117 }
118
119 #ifdef CYGHWR_HAL_ARM_EDB7XXX_SOFTWARE_DRAM_REFRESH
120 #define DRAM_START    0x00000000
121 #define DRAM_END      0x01000000
122 #define DRAM_ROW_SIZE 0x00000400
123 #define DRAM_REFRESH  (((DRAM_END-DRAM_START)/DRAM_ROW_SIZE)+99)/100
124
125 static void
126 do_DRAM_refresh(void)
127 {
128     static cyg_uint32 *row_ptr;
129     volatile cyg_uint32 val;
130     int i;
131     for (i = 0;  i < DRAM_REFRESH;  i++) {
132         val = *row_ptr;
133         row_ptr += DRAM_ROW_SIZE / sizeof(*row_ptr);
134         if (row_ptr >= (cyg_uint32 *)DRAM_END) row_ptr = (cyg_uint32 *)DRAM_START;
135     }
136 }
137 #endif // CYGHWR_HAL_ARM_EDB7XXX_SOFTWARE_DRAM_REFRESH
138
139 void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
140 {
141     volatile cyg_uint32 *tc2d = (volatile cyg_uint32 *)TC2D;
142     if (period != _period) {
143         *tc2d = period;
144         _period = period;
145     }
146 #if !defined(__EDB7312)
147 #ifndef CYGPKG_HAL_ARM_EDB7209
148 // EP7209 has no DRAM/controller, thus no problem
149     enable_FIQ();  // Should be safe here
150 #ifdef CYGHWR_HAL_ARM_EDB7XXX_SOFTWARE_DRAM_REFRESH
151     do_DRAM_refresh();
152 #else
153     dram_delay_loop();
154 #endif 
155 #endif
156 #endif // !defined(__EDB7312)
157 }
158
159 // Read the current value of the clock, returning the number of hardware "ticks"
160 // that have occurred (i.e. how far away the current value is from the start)
161
162 void hal_clock_read(cyg_uint32 *pvalue)
163 {
164     volatile cyg_int32 *tc2d = (volatile cyg_int32 *)TC2D;
165     static cyg_int32 clock_val;
166     clock_val = *tc2d & 0x0000FFFF;                 // Register has only 16 bits
167     if (clock_val & 0x00008000) clock_val |= 0xFFFF8000;  // Extend sign bit
168     *pvalue = (cyg_uint32)(_period - clock_val);    // 'clock_val' counts down and wraps
169 }
170
171 // Delay for some number of useconds.  Assume that the system clock
172 // has been set up to run at 512KHz (default).
173 void hal_delay_us(int us)
174 {
175     volatile cyg_int32 *tc2d = (volatile cyg_int32 *)TC2D;
176     cyg_int32 val, prev;
177     while (us >= 2) {
178         prev = *tc2d & 0x0000FFFF;                 // Register has only 16 bits
179         if (prev & 0x00008000) prev |= 0xFFFF8000;  // Extend sign bit
180         while (true) {
181             val = *tc2d & 0x0000FFFF;                 // Register has only 16 bits
182             if (val & 0x00008000) {
183                 val |= 0xFFFF8000;  // Extend sign bit
184                 *tc2d = _period;  // Need to reset counter
185             }
186             if (val != prev) {
187                 break;  // At least 2us have passed
188             }            
189         }
190         us -= 2;
191     }
192 }
193
194 void
195 dram_delay_loop(void)
196 {
197     // Temporary fix for DRAM starvation problem
198     if (CYGHWR_HAL_ARM_EDB7XXX_PROCESSOR_CLOCK > 37000) {
199         int i;
200         for (i = 0;  i < (CYGHWR_HAL_ARM_EDB7XXX_PROCESSOR_CLOCK*2)/24;  i++) ;  // approx 300 us
201     }
202 }
203
204 // These tables map the various [soft] interrupt numbers onto the hardware
205
206 static cyg_uint32 hal_interrupt_bitmap[] = {
207     0,              // CYGNUM_HAL_INTERRUPT_unused     0
208     INTSR1_EXTFIQ,  // CYGNUM_HAL_INTERRUPT_EXTFIQ     1
209     INTSR1_BLINT,   // CYGNUM_HAL_INTERRUPT_BLINT      2
210     INTSR1_WEINT,   // CYGNUM_HAL_INTERRUPT_WEINT      3
211     INTSR1_MCINT,   // CYGNUM_HAL_INTERRUPT_MCINT      4
212     INTSR1_CSINT,   // CYGNUM_HAL_INTERRUPT_CSINT      5
213     INTSR1_EINT1,   // CYGNUM_HAL_INTERRUPT_EINT1      6    
214     INTSR1_EINT2,   // CYGNUM_HAL_INTERRUPT_EINT2      7
215     INTSR1_EINT3,   // CYGNUM_HAL_INTERRUPT_EINT3      8
216     INTSR1_TC1OI,   // CYGNUM_HAL_INTERRUPT_TC1OI      9
217     INTSR1_TC2OI,   // CYGNUM_HAL_INTERRUPT_TC2OI      10
218     INTSR1_RTCMI,   // CYGNUM_HAL_INTERRUPT_RTCMI      11
219     INTSR1_TINT,    // CYGNUM_HAL_INTERRUPT_TINT       12
220     INTSR1_UTXINT1, // CYGNUM_HAL_INTERRUPT_UTXINT1    13
221     INTSR1_URXINT1, // CYGNUM_HAL_INTERRUPT_URXINT1    14
222     INTSR1_UMSINT,  // CYGNUM_HAL_INTERRUPT_UMSINT     15
223     INTSR1_SSEOTI,  // CYGNUM_HAL_INTERRUPT_SSEOTI     16
224     INTSR2_KBDINT,  // CYGNUM_HAL_INTERRUPT_KBDINT     17
225     INTSR2_SS2RX,   // CYGNUM_HAL_INTERRUPT_SS2RX      18
226     INTSR2_SS2TX,   // CYGNUM_HAL_INTERRUPT_SS2TX      19
227     INTSR2_UTXINT2, // CYGNUM_HAL_INTERRUPT_UTXINT2    20
228     INTSR2_URXINT2, // CYGNUM_HAL_INTERRUPT_URXINT2    21
229 #if defined(__EDB7211)
230     INTSR3_MCPINT   // CYGNUM_HAL_INTERRUPT_MCPINT     22
231 #endif
232 #if defined(__EDB7209)
233     INTSR3_I2SINT   // CYGNUM_HAL_INTERRUPT_I2SINT     22
234 #endif
235 #if defined(__EDB7312)
236     INTSR3_DAIINT   // CYGNUM_HAL_INTERRUPT_DAIINT     22
237 #endif
238 };
239
240 static cyg_uint32 hal_interrupt_mask_regmap[] = {
241     0,      // CYGNUM_HAL_INTERRUPT_unused     0
242     INTMR1, // CYGNUM_HAL_INTERRUPT_EXTFIQ     1
243     INTMR1, // CYGNUM_HAL_INTERRUPT_BLINT      2
244     INTMR1, // CYGNUM_HAL_INTERRUPT_WEINT      3
245     INTMR1, // CYGNUM_HAL_INTERRUPT_MCINT      4
246     INTMR1, // CYGNUM_HAL_INTERRUPT_CSINT      5
247     INTMR1, // CYGNUM_HAL_INTERRUPT_EINT1      6    
248     INTMR1, // CYGNUM_HAL_INTERRUPT_EINT2      7
249     INTMR1, // CYGNUM_HAL_INTERRUPT_EINT3      8
250     INTMR1, // CYGNUM_HAL_INTERRUPT_TC1OI      9
251     INTMR1, // CYGNUM_HAL_INTERRUPT_TC2OI      10
252     INTMR1, // CYGNUM_HAL_INTERRUPT_RTCMI      11
253     INTMR1, // CYGNUM_HAL_INTERRUPT_TINT       12
254     INTMR1, // CYGNUM_HAL_INTERRUPT_UTXINT1    13
255     INTMR1, // CYGNUM_HAL_INTERRUPT_URXINT1    14
256     INTMR1, // CYGNUM_HAL_INTERRUPT_UMSINT     15
257     INTMR1, // CYGNUM_HAL_INTERRUPT_SSEOTI     16
258     INTMR2, // CYGNUM_HAL_INTERRUPT_KBDINT     17
259     INTMR2, // CYGNUM_HAL_INTERRUPT_SS2RX      18
260     INTMR2, // CYGNUM_HAL_INTERRUPT_SS2TX      19
261     INTMR2, // CYGNUM_HAL_INTERRUPT_UTXINT2    20
262     INTMR2, // CYGNUM_HAL_INTERRUPT_URXINT2    21
263 #if defined(__EDB7211)
264     INTMR3, // CYGNUM_HAL_INTERRUPT_MCPINT     22
265 #endif
266 #if defined(__EDB7209)
267     INTMR3, // CYGNUM_HAL_INTERRUPT_I2SINT     22
268 #endif
269 #if defined(__EDB7312)
270     INTMR3, // CYGNUM_HAL_INTERRUPT_DAIINT     22
271 #endif
272 };
273
274 static cyg_uint32 hal_interrupt_clear_map[] = {
275     0,      // CYGNUM_HAL_INTERRUPT_unused     0
276     0,      // CYGNUM_HAL_INTERRUPT_EXTFIQ     1
277     BLEOI,  // CYGNUM_HAL_INTERRUPT_BLINT      2
278     TEOI,   // CYGNUM_HAL_INTERRUPT_WEINT      3
279     MCEOI,  // CYGNUM_HAL_INTERRUPT_MCINT      4
280     COEOI,  // CYGNUM_HAL_INTERRUPT_CSINT      5
281     0,      // CYGNUM_HAL_INTERRUPT_EINT1      6    
282     0,      // CYGNUM_HAL_INTERRUPT_EINT2      7
283     0,      // CYGNUM_HAL_INTERRUPT_EINT3      8
284     TC1EOI, // CYGNUM_HAL_INTERRUPT_TC1OI      9
285     TC2EOI, // CYGNUM_HAL_INTERRUPT_TC2OI      10
286     RTCEOI, // CYGNUM_HAL_INTERRUPT_RTCMI      11
287     TEOI,   // CYGNUM_HAL_INTERRUPT_TINT       12
288     0,      // CYGNUM_HAL_INTERRUPT_UTXINT1    13
289     0,      // CYGNUM_HAL_INTERRUPT_URXINT1    14
290     UMSEOI, // CYGNUM_HAL_INTERRUPT_UMSINT     15
291     0,      // CYGNUM_HAL_INTERRUPT_SSEOTI     16
292     KBDEOI, // CYGNUM_HAL_INTERRUPT_KBDINT     17
293     0,      // CYGNUM_HAL_INTERRUPT_SS2RX      18
294     0,      // CYGNUM_HAL_INTERRUPT_SS2TX      19
295     0,      // CYGNUM_HAL_INTERRUPT_UTXINT2    20
296     0,      // CYGNUM_HAL_INTERRUPT_URXINT2    21
297 #if defined(__EDB7211)
298     0,      // CYGNUM_HAL_INTERRUPT_MCPINT     22
299 #endif
300 #if defined(__EDB7209)
301     0,      // CYGNUM_HAL_INTERRUPT_I2SINT     22
302 #endif
303 #if defined(__EDB7312)
304     0,      // CYGNUM_HAL_INTERRUPT_DAIINT     22
305 #endif
306 };
307
308 static struct regmap {
309     int        first_int, last_int;
310     cyg_uint32 stat_reg, mask_reg;
311 } hal_interrupt_status_regmap[] = {
312     { CYGNUM_HAL_INTERRUPT_EXTFIQ, CYGNUM_HAL_INTERRUPT_MCINT,   INTSR1, INTMR1},
313 #if defined(__EDB7211)
314     { CYGNUM_HAL_INTERRUPT_MCPINT, CYGNUM_HAL_INTERRUPT_MCPINT,  INTSR3, INTMR3},
315 #endif
316 #if defined(__EDB7209)
317     { CYGNUM_HAL_INTERRUPT_I2SINT, CYGNUM_HAL_INTERRUPT_I2SINT,  INTSR3, INTMR3},
318 #endif
319 #if defined(__EDB7312)
320     { CYGNUM_HAL_INTERRUPT_DAIINT, CYGNUM_HAL_INTERRUPT_DAIINT,  INTSR3, INTMR3},
321 #endif
322     { CYGNUM_HAL_INTERRUPT_CSINT,  CYGNUM_HAL_INTERRUPT_SSEOTI,  INTSR1, INTMR1},
323     { CYGNUM_HAL_INTERRUPT_KBDINT, CYGNUM_HAL_INTERRUPT_URXINT2, INTSR2, INTMR2},
324     { 0, 0, 0, 0 }
325 };
326
327 #ifdef CYGHWR_HAL_ARM_EDB7XXX_BATLOW
328 // This ISR is called when the battery low interrupt occurs
329 int 
330 cyg_hal_batlow_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
331 {
332     diag_printf("Battery low\n");
333     cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_BLINT);
334     // Presumably, one would leave this masked until the battery changed
335     cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_BLINT);
336     return 0;  // No need to run DSR
337 }
338 #endif
339
340 //
341 // Early stage hardware initialization
342 //   Some initialization has already been done before we get here.  For now
343 // just set up the interrupt environment.
344
345 void hal_hardware_init(void)
346 {
347     volatile cyg_uint32 *icr;
348     int vector;
349     
350     // Clear and initialize instruction cache
351     HAL_ICACHE_INVALIDATE_ALL();
352     HAL_ICACHE_ENABLE();
353
354     // Any hardware/platform initialization that needs to be done.
355     *(volatile cyg_uint32 *)INTMR1 = 0;
356     *(volatile cyg_uint32 *)INTMR2 = 0;
357 #if !defined(__CL7111)
358     *(volatile cyg_uint32 *)INTMR3 = 0;
359 #endif
360 #if !defined(__CL7111) && !defined(__EDB7312)
361     *(volatile cyg_uint8 *)SYSCON3 = SYSCON3_CLKCTL(CPU_CLOCK);
362 #endif
363
364 #if 0
365     diag_printf("IMR1: %04x, IMR2: %04x\n",
366                 *(volatile cyg_uint32 *)INTMR1,
367                 *(volatile cyg_uint32 *)INTMR2);
368     diag_printf("Memcfg1: %08x, Memcfg2: %08x, DRAM refresh: %08x\n", 
369                 *(volatile cyg_uint32 *)MEMCFG1,
370                 *(volatile cyg_uint32 *)MEMCFG2,
371                 *(volatile cyg_uint8 *)DRFPR);
372 #endif
373 #define MEMCFG_BUS_WIDTH(n)   (n<<0)
374 #define MEMCFG_BUS_WIDTH_32   (0<<0)
375 #define MEMCFG_BUS_WIDTH_16   (1<<0)
376 #define MEMCFG_BUS_WIDTH_8    (2<<0)
377 #define MEMCFG_WAIT_STATES(n) (n<<2)     // 0 is max, 15 min
378 #define MEMCFG_SQAEN          (1<<6)
379 #define MEMCFG_CLKENB         (1<<7)
380
381 // These need to be checked/improved
382 #define CS0_CONFIG MEMCFG_BUS_WIDTH_32 | MEMCFG_WAIT_STATES(3) | MEMCFG_SQAEN
383 #define CS1_CONFIG MEMCFG_BUS_WIDTH_32 | MEMCFG_WAIT_STATES(4)
384 #define CS2_CONFIG MEMCFG_BUS_WIDTH_32 | MEMCFG_WAIT_STATES(0)
385 #define CS3_CONFIG MEMCFG_BUS_WIDTH_32 | MEMCFG_WAIT_STATES(0)
386 #define CS4_CONFIG MEMCFG_BUS_WIDTH_32 | MEMCFG_WAIT_STATES(0)
387 #define CS5_CONFIG MEMCFG_BUS_WIDTH_32 | MEMCFG_WAIT_STATES(0)
388 #define CS6_CONFIG MEMCFG_BUS_WIDTH_32 | MEMCFG_WAIT_STATES(0)
389 #define CS7_CONFIG MEMCFG_BUS_WIDTH_32 | MEMCFG_WAIT_STATES(0)
390
391 #if defined(__EDB7209)
392     *(volatile cyg_uint32 *)MEMCFG1 = 
393         (CS0_CONFIG << 0) |       // FLASH rom
394         (CS1_CONFIG << 8) |       // NAND flash
395         (CS2_CONFIG << 16) |      // Ethernet
396         (CS3_CONFIG << 24);       // Parallel printer, keyboard, touch panel
397     *(volatile cyg_uint32 *)MEMCFG2 = 
398         (CS4_CONFIG << 0) |       // USB
399         (CS5_CONFIG << 8) |       // Expansion
400         (CS6_CONFIG << 16) |      // Local SRAM
401         (CS7_CONFIG << 24);       // Boot ROM
402     // This value came from Cirrus, but doesn't match the recommendations above?
403     *(volatile cyg_uint32 *)MEMCFG1 = 0x3C001814;
404     // Set up GPIO lines
405     *(volatile cyg_uint8 *)PADDR   = 0x00;  // Keyboard data 0-7 input
406     *(volatile cyg_uint8 *)PBDDR   = 0xFA;  // 0 - I/O on J22
407                                             // 1 - RTS on UART1
408                                             // 2 - Ring on UART1
409                                             // 3 - SSI header, Pin 13
410                                             // 4 - NAND Command Latch Enable
411                                             // 5 - NAND Address Latch Enable
412                                             // 6 - On-board NAND Select (active low)
413                                             // 7 - SmartMedia Card Enable (active low)
414     *(volatile cyg_uint8 *)PBDR    = 0xC0;  // Everything off
415     *(volatile cyg_uint8 *)PDDDR   = 0x40;  // 0 - Diagnostic LED control
416                                             // 1 - Enable DC-DC converter for LCD
417                                             // 2 - Enable LCD
418                                             // 3 - ENable LCD Backlight
419                                             // 4 - CS4342 I2C Data
420                                             // 5 - CS4342 I2C Clock
421                                             // 6 - SmartMedia Presence indicator
422                                             // 7 - I/O on J22
423     *(volatile cyg_uint8 *)PDDR    = 0x00;  // Everything off
424     *(volatile cyg_uint8 *)PEDDR   = 0x05;  // 0 - Codec or ADC/DAC
425                                             // 1 - I/O on JP38 (0 when inserted)
426                                             // 2 - Enable touch panel
427     *(volatile cyg_uint8 *)PEDR    = 0x01;  // Enable audio (not CODEC)
428     // Initialize system control
429     *(volatile cyg_uint32 *)SYSCON2 = SYSCON2_KBWEN;
430 #endif
431
432 #if defined(__EDB7312)
433     *(volatile cyg_uint32 *)MEMCFG1 = 0x1F101710;
434     *(volatile cyg_uint32 *)MEMCFG2 = 0x00001F93;
435     // Set up GPIO lines
436     *(volatile cyg_uint8 *)PADDR   = 0x00;  // Keyboard data 0-7 input
437     *(volatile cyg_uint8 *)PBDDR   = 0xF2;
438     *(volatile cyg_uint8 *)PDDDR   = 0x2F;
439     *(volatile cyg_uint8 *)PDDDR   = 0x10;  // Directions are inverted!
440     *(volatile cyg_uint8 *)PDDR    = 0x00;  // Everything off
441     *(volatile cyg_uint8 *)PEDDR   = 0x01;
442     // Initialize system control
443     *(volatile cyg_uint32 *)SYSCON1 = 0x00040100;
444     *(volatile cyg_uint32 *)SYSCON2 = 0x00000102;
445
446 #ifdef CPU_CLOCK_90MHZ
447     // We must slow down the RAM timings compared to default by adding
448     // wait states or it does not work.
449     // Slow them all down to Random=5, Seq=3 waitstates by replacing
450     // that field throughout the default value copied from above:
451     *(volatile cyg_uint32 *)MEMCFG1 = (0x1F101710 & ~0x3c3c3c3c) | 0x0c0c0c0c;
452     *(volatile cyg_uint32 *)MEMCFG2 = (0x00001F93 & ~0x00003c3c) | 0x00000c0c;
453 #endif // CPU_CLOCK_90MHZ
454
455     *(volatile cyg_uint32 *)SYSCON3 = 0x00000208 | SYSCON3_CLKCTL(CPU_CLOCK);
456
457 #ifdef CPU_CLOCK_90MHZ
458     // Let the clock change settle before hitting the PLL multiplier
459     // register to change up by a further 22.5%
460     asm volatile( "nop;nop;nop;nop;nop;nop;nop;nop;");
461     *(volatile cyg_uint32 *)EP7312_PLL_MR = EP7312_PLL_MR_FOR_90MHz;
462     asm volatile( "nop;nop;nop;nop;nop;nop;nop;nop;");
463 #endif // CPU_CLOCK_90MHZ
464
465 #endif
466     // Reset all interrupt masks (disable all interrupt sources)
467     for (vector = CYGNUM_HAL_ISR_MIN;  vector < CYGNUM_HAL_ISR_COUNT;  vector++) {
468         icr = (volatile cyg_uint32 *)hal_interrupt_clear_map[vector];
469         if (icr) *icr = 0;  // Just a write clears the latch
470     }
471 #ifndef __EDB7312
472     // Turn on the DIAG LED to let the world know the board is alive
473     *(volatile unsigned char *)LEDFLSH = LEDFLSH_ENABLE|LEDFLSH_DUTY(16)|LEDFLSH_PERIOD(1);
474 #endif
475 #ifdef CYGHWR_HAL_ARM_EDB7XXX_BATLOW
476     cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_BLINT,
477                              99,                     // Priority - what goes here?
478                              0,                      //  Data item passed to interrupt handler
479                              cyg_hal_batlow_isr,
480                              0,
481                              &batlow_interrupt_handle,
482                              &batlow_interrupt);
483     cyg_drv_interrupt_attach(batlow_interrupt_handle);
484     cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_BLINT);
485 #endif
486
487     // Initialize real-time clock (for delays, etc, even if kernel doesn't use it)
488     hal_clock_initialize(CYGNUM_HAL_RTC_PERIOD);
489
490     // Set up eCos/ROM interfaces
491     hal_if_init();
492
493 #ifdef CYGSEM_EDB7XXX_LCD_COMM
494     // Initialize I/O channel
495     lcd_comm_init();
496 #endif
497 }
498
499 //
500 // This routine is called to respond to a hardware interrupt (IRQ).  It
501 // should interrogate the hardware and return the IRQ vector number.
502
503 // This code is a little convoluted to keep it general while still avoiding
504 // reading the hardware a lot, since the interrupt status is split across
505 // three separate registers.
506
507 int hal_spurious_ints;
508
509 int hal_IRQ_handler(void)
510 {
511     struct regmap *map = hal_interrupt_status_regmap;
512     cyg_uint32 stat;
513     int vector;
514     while (map->first_int) {
515         stat = *(volatile cyg_uint32 *)map->stat_reg & *(volatile cyg_uint32 *)map->mask_reg;
516         for (vector = map->first_int;  vector <= map->last_int;  vector++) {
517             if (stat & hal_interrupt_bitmap[vector]) return vector;
518         }
519         map++;  // Next interrupt status register
520     }
521     hal_spurious_ints++;
522     return CYGNUM_HAL_INTERRUPT_NONE; // This shouldn't happen!
523 }
524
525 //
526 // Interrupt control
527 //
528
529 void hal_interrupt_mask(int vector)
530 {
531     volatile cyg_uint32 *imr;
532     imr = (volatile cyg_uint32 *)hal_interrupt_mask_regmap[vector];
533     *imr &= ~hal_interrupt_bitmap[vector];
534 }
535
536 void hal_interrupt_unmask(int vector)
537 {
538     volatile cyg_uint32 *imr;
539     imr = (volatile cyg_uint32 *)hal_interrupt_mask_regmap[vector];
540     *imr |= hal_interrupt_bitmap[vector];
541 }
542
543 void hal_interrupt_acknowledge(int vector)
544 {
545     // Some interrupt sources have a register for this.
546     volatile cyg_uint8 *icr;
547     icr = (volatile cyg_uint8 *)hal_interrupt_clear_map[vector];
548     if (icr) {
549         *icr = 0;  // Any data clears interrupt
550     }
551 }
552
553 void hal_interrupt_configure(int vector, int level, int up)
554 {
555     // No interrupts are configurable on this hardware
556 }
557
558 void hal_interrupt_set_level(int vector, int level)
559 {
560     // No interrupts are configurable on this hardware
561 }
562
563 #define _CYGHWR_LAYOUT_ONLY
564 #include <cyg/hal/hal_platform_setup.h>
565
566 unsigned long
567 _edb7xxx_physical_address(unsigned long addr)
568 {
569     unsigned long res;
570
571     if (addr < DRAM_LA_END) {
572         res = addr + DRAM_PA;
573     } else {
574         res = addr | 0xC0000000;
575     }
576     return res;
577 }
578
579 /*------------------------------------------------------------------------*/
580 // EOF hal_misc.c