]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/mac7100/var/v2_0/src/mac7100_misc.c
Initial revision
[karo-tx-redboot.git] / packages / hal / arm / mac7100 / var / v2_0 / src / mac7100_misc.c
1 /*==========================================================================
2 //
3 //      mac7100_misc.c
4 //
5 //      HAL misc board support code for Freescale MAC7100
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 Nick Garnett <nickg@calivar.com>
13 // Copyright (c) 2006 eCosCentric Ltd
14 //
15 // Ecos is free software; you can redistribute it and/or modify it under
16 // the terms of the GNU General Public License as published by the Free
17 // Software Foundation; either version 2 or (at your option) any later version.
18 //
19 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
20 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
22 // for more details.
23 //
24 // You should have received a copy of the GNU General Public License along
25 // with eCos; if not, write to the Free Software Foundation, Inc.,
26 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 //
28 // As a special exception, if other files instantiate templates or use macros
29 // or inline functions from this file, or you compile this file and link it
30 // with other works to produce a work based on this file, this file does not
31 // by itself cause the resulting work to be covered by the GNU General Public
32 // License. However the source code for this file must still be made available
33 // in accordance with section (3) of the GNU General Public License.
34 //
35 // This exception does not invalidate any other reasons why a work based on
36 // this file might be covered by the GNU General Public License.
37 // -------------------------------------------
38 //####ECOSGPLCOPYRIGHTEND####
39 //==========================================================================
40 //#####DESCRIPTIONBEGIN####
41 //
42 // Author(s):    Ilija Koco <ilijak@siva.com.mk>
43 // Contributors: 
44 // Date:         2006-04-12
45 // Purpose:      HAL board support
46 // Description:  Implementations of HAL board interfaces
47 //
48 //####DESCRIPTIONEND####
49 //
50 //========================================================================
51 */
52
53 #include <pkgconf/hal.h>
54
55 #include <cyg/infra/cyg_type.h>         // base types
56 #include <cyg/infra/cyg_trac.h>         // tracing macros
57 #include <cyg/infra/cyg_ass.h>          // assertion macros
58
59 #include <cyg/hal/hal_io.h>             // IO macros
60 #include <cyg/hal/hal_arch.h>           // Register state info
61 #include <cyg/hal/hal_diag.h>
62 #include <cyg/hal/hal_intr.h>           // necessary?
63 #include <cyg/hal/hal_cache.h>
64 #include <cyg/hal/hal_if.h>             // calling interface
65 #include <cyg/hal/hal_misc.h>           // helper functions
66 #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
67 #include <cyg/hal/drv_api.h>            // HAL ISR support
68 #endif
69 #include <cyg/hal/var_io.h>             // platform registers
70 #include <cyg/devs/ser_esci.h>            // ESCI registers
71 #include <pkgconf/io_serial_freescale_esci.h>
72
73 // -------------------------------------------------------------------------
74 // Clock support
75
76 static cyg_uint32 _period;
77
78 void hal_clock_initialize(cyg_uint32 period)
79 {
80     CYG_ADDRESS pit_base = MAC7100_PIT_BASE;
81     cyg_uint32 pit_en;
82
83     CYG_ASSERT(period < 0x10000, "Invalid clock period");
84
85     // Disable counter
86     HAL_READ_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
87     pit_en &= ~MAC7100_PIT_EN_PEN(CYGNUM_PIT_CHAN_CLOCK);
88     HAL_WRITE_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
89
90     // Set registers
91     _period=period;
92     HAL_WRITE_UINT32(MAC7100_PIT_TLVAL(pit_base, CYGNUM_PIT_CHAN_CLOCK), 
93                      period);
94
95     // Start timer
96     pit_en |= MAC7100_PIT_EN_PEN(CYGNUM_PIT_CHAN_CLOCK);
97     HAL_WRITE_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
98
99     // Enable timer interrupt    
100     HAL_READ_UINT32(MAC7100_PIT_INTEN(pit_base), pit_en);
101     pit_en |= MAC7100_PIT_EN_PEN(CYGNUM_PIT_CHAN_CLOCK);
102     HAL_WRITE_UINT32(MAC7100_PIT_INTEN(pit_base), pit_en);
103
104     HAL_READ_UINT32(MAC7100_PIT_INTSEL(pit_base), pit_en);
105     pit_en |= MAC7100_PIT_EN_PEN(CYGNUM_PIT_CHAN_CLOCK);
106     HAL_WRITE_UINT32(MAC7100_PIT_INTSEL(pit_base), pit_en);
107 }
108
109 void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
110 {
111     HAL_WRITE_UINT32(MAC7100_PIT_FLG(MAC7100_PIT_BASE), 
112                      MAC7100_PIT_FLAG_TIF(CYGNUM_PIT_CHAN_CLOCK));
113 }
114
115
116 void hal_clock_read(cyg_uint32 *pvalue)
117 {
118     cyg_uint32 val;
119
120     HAL_READ_UINT32(MAC7100_PIT_TLVAL(MAC7100_PIT_BASE,CYGNUM_PIT_CHAN_CLOCK),
121                     val);
122     *pvalue = _period-val;
123 }
124
125 // -------------------------------------------------------------------------
126 //
127 // Delay for some number of micro-seconds
128 //
129
130 #if CYGNUM_PIT_CHAN_US!=0
131 #define CYGNUM_1_US (CYGNUM_HAL_ARM_MAC7100_CLOCK_SPEED/2000000)
132 #else
133 #define CYGNUM_1_US (CYGNUM_HAL_ARM_MAC7100_F_OSC/1000000)
134 #endif
135
136 void hal_delay_us(cyg_int32 usecs)
137 {
138     CYG_ADDRESS pit_base = MAC7100_PIT_BASE;
139     cyg_uint32 pit_en;
140     
141     
142     // Clear flag
143     HAL_WRITE_UINT32(MAC7100_PIT_FLG(pit_base), 
144                      MAC7100_PIT_FLAG_TIF(CYGNUM_PIT_CHAN_US));
145
146     // Set timer
147     HAL_WRITE_UINT32(MAC7100_PIT_TLVAL(pit_base, CYGNUM_PIT_CHAN_US), 
148                      usecs*CYGNUM_1_US-1);
149     HAL_READ_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
150     pit_en |= MAC7100_PIT_EN_PEN(CYGNUM_PIT_CHAN_US);
151     HAL_WRITE_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
152
153     do {
154       HAL_READ_UINT32(MAC7100_PIT_FLG(pit_base), pit_en); 
155     }while (!(pit_en & MAC7100_PIT_FLAG_TIF(CYGNUM_PIT_CHAN_US)));
156     
157     // Disable counter
158     HAL_READ_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
159     pit_en &= ~MAC7100_PIT_EN_PEN(CYGNUM_PIT_CHAN_US);
160     HAL_WRITE_UINT32(MAC7100_PIT_EN(pit_base), pit_en);
161 }
162
163
164 // -------------------------------------------------------------------------
165 // Hardware init
166
167 void hal_intc_init(void);
168 void hal_pit_init(void);
169 static void hal_mac7100_esci_pins(cyg_uint32);
170 void hal_hardware_init(void)
171 {
172     // Reset all interrupts
173     //
174
175     // Flush internal priority level stack
176     //
177     
178     // Set up eCos/ROM interfaces
179 #if (defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_A) || \
180     (CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 0)
181     hal_mac7100_esci_pins(FREESCALE_ESCI_A_I);
182 #endif
183 #if (defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_B) || \
184     (CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 1)
185     hal_mac7100_esci_pins(FREESCALE_ESCI_B_I);
186 #endif
187 #if defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_C
188     hal_mac7100_esci_pins(FREESCALE_ESCI_C_I);
189 #endif
190 #if defined CYGPKG_IO_SERIAL_FREESCALE_ESCI_D
191     hal_mac7100_esci_pins(FREESCALE_ESCI_D_I);
192 #endif
193     
194     hal_intc_init();    // Initialize interrupt controller
195     hal_pit_init();     // Initilaize CLOCK for channels 1..10
196     hal_if_init();
197 }
198
199 void hal_pit_init(void)
200 {
201     cyg_uint32 pit_ctrl;
202     
203     CYG_ADDRESS pit_base=MAC7100_PIT_BASE;
204     
205     HAL_READ_UINT32(MAC7100_PIT_CTRL(pit_base), pit_ctrl);
206     pit_ctrl &= ~MAC7100_PIT_MDIS;
207     HAL_WRITE_UINT32(MAC7100_PIT_CTRL(pit_base), pit_ctrl);
208 }
209
210
211 // -------------------------------------------------------------------------
212 // This routine is called to respond to a hardware interrupt (IRQ).  It
213 // should interrogate the hardware and return the IRQ vector number.
214
215 typedef struct ClSlMask_T {
216   cyg_uint8 ClMask;
217   cyg_uint8 SlMask;
218 } ClSlMask_T;
219
220 static ClSlMask_T ClSlMasks[CYGNUM_HAL_ISR_COUNT];
221
222 void hal_intc_init(void)
223 {
224     cyg_uint8 iconfig;
225     CYG_ADDRESS intc_base=MAC7100_INTC_BASE;
226
227     iconfig = (CYGHWR_HAL_ARM_MAC7100_INTC_FIQDEF | 
228                CYGHWR_HAL_ARM_MAC7100_INTC_EMASK);
229     HAL_WRITE_UINT8(MAC7100_INTC_ICONFIG(intc_base), iconfig);
230 }
231
232 int hal_IRQ_handler(void)
233 {
234     CYG_ADDRESS intc_base=MAC7100_INTC_BASE;
235     cyg_int8 irq_num;
236     ClSlMask_T clslmask;
237         
238     HAL_READ_UINT8(MAC7100_INTC_CLMASK(intc_base), clslmask.ClMask);
239     HAL_READ_UINT8(MAC7100_INTC_SLMASK(intc_base), clslmask.SlMask);
240 #ifdef CYGHWR_HAL_ARM_MAC7100_FIQ
241     HAL_READ_UINT8(MAC7100_FIQIACK(intc_base), irq_num);
242     if((irq_num-=CYGNUM_HAL_ISR_COUNT)<0){
243 #endif //CYGHWR_HAL_ARM_MAC7100_FIQ
244         HAL_READ_UINT8(MAC7100_INTC_IRQIACK(intc_base), irq_num);
245         if((irq_num-=CYGNUM_HAL_ISR_COUNT)<0){
246             irq_num=CYGNUM_HAL_INTERRUPT_NONE;
247         }else{
248             ClSlMasks[irq_num]=clslmask;
249         }
250     return irq_num;
251 #ifdef CYGHWR_HAL_ARM_MAC7100_FIQ
252     }
253 #endif // CYGHWR_HAL_ARM_MAC7100_FIQ
254 }
255
256 // -------------------------------------------------------------------------
257 // Interrupt control
258 //
259
260 void hal_interrupt_mask(int vector)
261 {
262     CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
263                vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
264     
265     HAL_WRITE_UINT8(MAC7100_INTC_SIMR(MAC7100_INTC_BASE), vector);
266 }
267
268 void hal_interrupt_unmask(int vector)
269 {
270     CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
271                vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
272     
273     HAL_WRITE_UINT8(MAC7100_INTC_CIMR(MAC7100_INTC_BASE), vector);
274 }
275
276 void hal_interrupt_acknowledge(int vector)
277 {
278     // ?? No check for valid vector here! Spurious interrupts
279     // ?? must be acknowledged, too.
280     
281     if(vector>=0)
282         HAL_WRITE_UINT8(MAC7100_INTC_CLMASK(MAC7100_INTC_BASE), 
283                         ClSlMasks[vector].ClMask);
284 }
285
286 void hal_interrupt_configure(int vector, int level, int up)
287 {
288     // TO DO
289 }
290
291 void hal_interrupt_set_level(int vector, int level)
292 {
293     CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
294                vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
295     CYG_ASSERT(level >=0 level <= 15, "Invalid level");
296     
297     HAL_WRITE_UINT8(MAC7100_INTC_ICR(MAC7100_INTC_BASE,vector), 
298                     MAC7100_INTC_INT_LEVEL(level));
299 }
300
301 void hal_show_IRQ(int vector, int data, int handler)
302 {
303 //    UNDEFINED(__FUNCTION__);  // FIXME
304 }
305
306
307 void hal_mac7100_reset_cpu(void)
308 {
309     // TO DO use watchdog to reset cpu 
310 }
311
312 // Set ESCI channel pins in perpheral mode
313
314 void
315 hal_mac7100_esci_pins(cyg_uint32 i_esci){
316     cyg_uint16 *p_pim_config=0;
317     
318     switch(i_esci){
319     case FREESCALE_ESCI_A_I:
320         p_pim_config=
321           (cyg_uint16 *)MAC7100_PIM_CONFIG(MAC7100_PORT_G_OFFSET,2);
322         break;
323     case FREESCALE_ESCI_B_I:
324         p_pim_config=(cyg_uint16 *)MAC7100_PIM_CONFIG(MAC7100_PORT_G_OFFSET,0);
325         break;
326     case FREESCALE_ESCI_C_I:
327         p_pim_config=
328           (cyg_uint16 *)MAC7100_PIM_CONFIG(MAC7100_PORT_G_OFFSET,14);
329         break;
330     case FREESCALE_ESCI_D_I:
331         p_pim_config=
332           (cyg_uint16 *)MAC7100_PIM_CONFIG(MAC7100_PORT_G_OFFSET,15);
333         break;
334     }
335     HAL_WRITE_UINT16(p_pim_config++, MAC7100_PIM_MODE_PERIPHERAL);
336     HAL_WRITE_UINT16(p_pim_config, MAC7100_PIM_MODE_PERIPHERAL);
337 }
338
339
340 //--------------------------------------------------------------------------
341 // EOF mac7100_misc.c