OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [arm/] [xscale/] [pxa2x0/] [current/] [src/] [pxa2x0_misc.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      pxa2x0_misc.c
4
//
5
//      HAL misc board support code for Intel PXA2X0
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, 2003 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY 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        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):    <knud.woehler@microplex.de>
43
// Date:         2002-09-03
44
//
45
//####DESCRIPTIONEND####
46
//
47
//========================================================================*/
48
 
49
#include <pkgconf/hal.h>
50
#include <pkgconf/system.h>
51
#include CYGBLD_HAL_PLATFORM_H
52
#include <cyg/infra/cyg_type.h>
53
#include <cyg/infra/cyg_trac.h>
54
#include <cyg/infra/cyg_ass.h>
55
#include <cyg/hal/hal_misc.h>
56
#include <cyg/hal/hal_io.h>
57
#include <cyg/hal/hal_stub.h>
58
#include <cyg/hal/hal_arch.h>
59
#include <cyg/hal/hal_diag.h>
60
#include <cyg/hal/hal_intr.h>
61
#include <cyg/hal/hal_cache.h>
62
#include <cyg/hal/hal_pxa2x0.h>
63
#include <cyg/hal/hal_mm.h>
64
#include <cyg/infra/diag.h>
65
 
66
 
67
// Initialize the interrupt environment
68
externC void plf_hardware_init(void);
69
 
70
void hal_hardware_init(void)
71
{
72
    hal_xscale_core_init();
73
 
74
    *PXA2X0_ICMR = 0;           // IRQ Mask
75
    *PXA2X0_ICLR = 0;           // Route interrupts to IRQ
76
    *PXA2X0_ICCR = 1;
77
 
78
    *PXA2X0_GRER0 = 0;          // Disable rising edge detect
79
    *PXA2X0_GRER1 = 0;
80
    *PXA2X0_GRER2 = 0;
81
 
82
    *PXA2X0_GFER0 = 0;          // Disable falling edge detect
83
    *PXA2X0_GFER1 = 0;
84
    *PXA2X0_GFER2 = 0;
85
 
86
#if defined(CYGOPT_HAL_ARM_XSCALE_PXA2X0_VARIANT_PXA25X)
87
    *PXA2X0_GEDR0 = 0xffffffff; // Clear edge detect status
88
    *PXA2X0_GEDR1 = 0xffffffff;
89
    *PXA2X0_GEDR2 = 0x0001ffff;
90
#elif defined(CYGOPT_HAL_ARM_XSCALE_PXA2X0_VARIANT_PXA27X)
91
    *PXA2X0_ICMR2 = 0;
92
    *PXA2X0_ICLR2 = 0;
93
 
94
    *PXA2X0_GRER3 = 0;
95
    *PXA2X0_GFER3 = 0;
96
 
97
    *PXA2X0_GEDR0 = 0xfffff71b;
98
    *PXA2X0_GEDR1 = 0xffffffff;
99
    *PXA2X0_GEDR2 = 0xffffffff;
100
    *PXA2X0_GEDR3 = 0x1fffffff;
101
#endif
102
 
103
    plf_hardware_init();        // Perform any platform specific initializations
104
 
105
    *PXA2X0_OSCR = 0;           // Let the "OS" counter run
106
    *PXA2X0_OSMR0 = 0;
107
 
108
#ifdef CYGSEM_HAL_ENABLE_DCACHE_ON_STARTUP
109
    HAL_DCACHE_ENABLE();        // Enable caches
110
#endif
111
#ifdef CYGSEM_HAL_ENABLE_ICACHE_ON_STARTUP
112
    HAL_ICACHE_ENABLE();
113
#endif
114
}
115
 
116
//
117
// GPIO support functions
118
//
119
void
120
_pxa2x0_set_GPIO_mode(int bit, int mode, int dir)
121
{
122
    int bank = bit / 32;
123
    unsigned volatile long *gpdr, *gafr;
124
 
125
    gpdr = &PXA2X0_GPDR0[bank];
126
    gafr = &PXA2X0_GAFR0_L[(bit&0x30)>>4];
127
    bit %= 32;
128
    // Data direction registers have 1 bit per GPIO
129
    *gpdr = (*gpdr & ~(1<<bit)) | (dir<<bit);
130
    // Alternate function regusters have 2 bits per GPIO
131
    bit = (bit & 0x0F) * 2;
132
    *gafr = (*gafr & ~(3<<bit)) | (mode<<bit);
133
}
134
 
135
 
136
// Initialize the clock
137
static cyg_uint32  clock_period;
138
 
139
void hal_clock_initialize(cyg_uint32 period)
140
{
141
        *PXA2X0_OSMR0 = period;                                 // Load match value
142
        clock_period = period;
143
 
144
        *PXA2X0_OSCR = 0;                                                // Start the counter
145
    *PXA2X0_OSSR = PXA2X0_OSSR_TIMER0;          // Clear any pending interrupt
146
    *PXA2X0_OIER |= PXA2X0_OIER_TIMER0;         // Enable timer 0 interrupt
147
 
148
    HAL_INTERRUPT_UNMASK( CYGNUM_HAL_INTERRUPT_TIMER0 );        // Unmask timer 0 interrupt
149
}
150
 
151
// This routine is called during a clock interrupt.
152
void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
153
{
154
    *PXA2X0_OSMR0 = *PXA2X0_OSCR + period;      // Load new match value
155
    *PXA2X0_OSSR = PXA2X0_OSSR_TIMER0;          // Clear any pending interrupt
156
}
157
 
158
// Read the current value of the clock, returning the number of hardware
159
// "ticks" that have occurred (i.e. how far away the current value is from
160
// the start)
161
 
162
// Note: The "contract" for this function is that the value is the number
163
// of hardware clocks that have happened since the last interrupt (i.e.
164
// when it was reset).  This value is used to measure interrupt latencies.
165
// However, since the hardware counter runs freely, this routine computes
166
// the difference between the current clock period and the number of hardware
167
// ticks left before the next timer interrupt.
168
void hal_clock_read(cyg_uint32 *pvalue)
169
{
170
    int orig;
171
    HAL_DISABLE_INTERRUPTS(orig);
172
    *pvalue = clock_period + *PXA2X0_OSCR - *PXA2X0_OSMR0;
173
    HAL_RESTORE_INTERRUPTS(orig);
174
}
175
 
176
// Delay for some number of micro-seconds
177
void hal_delay_us(cyg_int32 usecs)
178
{
179
#if defined(CYGOPT_HAL_ARM_XSCALE_PXA2X0_VARIANT_PXA25X)
180
#  define NSECS_PER_TICK 271267 /* 3.6865 MHz clock */
181
#elif defined(CYGOPT_HAL_ARM_XSCALE_PXA2X0_VARIANT_PXA27X)
182
#  define NSECS_PER_TICK 307692 /* 3.25 MHz clock */
183
#endif
184
 
185
    cyg_uint32 val = 0;
186
    cyg_uint32 prev = *PXA2X0_OSCR;
187
    while (usecs-- > 0) {
188
        while (val < 1000000) {
189
            cyg_uint32 now = *PXA2X0_OSCR;
190
            cyg_uint32 diff = now - prev;
191
            val += NSECS_PER_TICK * diff;
192
            prev = now;
193
        }
194
        val -= 1000000;
195
    }
196
}
197
 
198
 
199
// Interrupt handling
200
 
201
// This routine is called to respond to a hardware interrupt (IRQ).  It
202
// should interrogate the hardware and return the IRQ vector number.
203
int hal_IRQ_handler(void)
204
{
205
    cyg_uint32 sources, index;
206
 
207
    sources = *PXA2X0_ICIP;
208
 
209
#ifdef HAL_EXTENDED_IRQ_HANDLER
210
    // Use platform specific IRQ handler, if defined
211
    // Note: this macro should do a 'return' with the appropriate
212
    // interrupt number if such an extended interrupt exists.  The
213
    // assumption is that the line after the macro starts 'normal' processing.
214
    HAL_EXTENDED_IRQ_HANDLER(sources);
215
#endif
216
 
217
    if ( sources & 0xff0000 )
218
        index = 16;
219
    else if ( sources & 0xff00 )
220
        index = 8;
221
    else if ( sources & 0xff )
222
        index = 0;
223
    else // if ( sources & 0xff000000 )
224
        index = 24;
225
 
226
    do {
227
        if ( (1 << index) & sources ) {
228
            if (index == CYGNUM_HAL_INTERRUPT_GPIOX) {
229
                // Special case of GPIO cascade.  Search for lowest set bit
230
                sources = *PXA2X0_GEDR0;
231
                index = 0;
232
                do {
233
                    if (sources & (1 << index)) {
234
                        return CYGNUM_HAL_INTERNAL_IRQS + index;
235
                    }
236
                    index++;
237
                } while (index < 32);
238
                sources = *PXA2X0_GEDR1;
239
                index = 0;
240
                do {
241
                    if (sources & (1 << index)) {
242
                        return CYGNUM_HAL_INTERNAL_IRQS + 32 + index;
243
                    }
244
                    index++;
245
                } while (index < 32);
246
                sources = *PXA2X0_GEDR2;
247
                index = 0;
248
                do {
249
                    if (sources & (1 << index)) {
250
                        return CYGNUM_HAL_INTERNAL_IRQS + 64 + index;
251
                    }
252
                    index++;
253
                } while (index < 32);
254
#ifdef CYGOPT_HAL_ARM_XSCALE_PXA2X0_VARIANT_PXA27X
255
                sources = *PXA2X0_GEDR3;
256
                index = 0;
257
                do {
258
                    if (sources & (1 << index)) {
259
                        return CYGNUM_HAL_INTERNAL_IRQS + 96 + index;
260
                    }
261
                    index++;
262
                } while (index < 32);
263
#endif
264
            }
265
            return index;
266
        }
267
      index++;
268
    } while ( index & 7 );
269
 
270
    return CYGNUM_HAL_INTERRUPT_NONE; // This shouldn't happen!
271
}
272
 
273
void hal_interrupt_mask(int vector)
274
{
275
 
276
#ifdef HAL_EXTENDED_INTERRUPT_MASK
277
    // Use platform specific handling, if defined
278
    // Note: this macro should do a 'return' for "extended" values of 'vector'
279
    // Normal vectors are handled by code subsequent to the macro call.
280
    HAL_EXTENDED_INTERRUPT_MASK(vector);
281
#endif
282
#ifdef CYGOPT_HAL_ARM_XSCALE_PXA2X0_VARIANT_PXA27X
283
    if (vector >= 32 && vector < CYGNUM_HAL_INTERNAL_IRQS) {
284
        *PXA2X0_ICMR2 &= ~(1 << (vector - 32));
285
        return;
286
    }
287
#endif
288
    if (vector >= CYGNUM_HAL_INTERRUPT_GPIO(2)) {
289
        vector = CYGNUM_HAL_INTERRUPT_GPIOX;
290
    }
291
    *PXA2X0_ICMR &= ~(1 << vector);
292
}
293
 
294
void hal_interrupt_unmask(int vector)
295
{
296
 
297
#ifdef HAL_EXTENDED_INTERRUPT_UNMASK
298
    // Use platform specific handling, if defined
299
    // Note: this macro should do a 'return' for "extended" values of 'vector'
300
    // Normal vectors are handled by code subsequent to the macro call.
301
    HAL_EXTENDED_INTERRUPT_UNMASK(vector);
302
#endif
303
#ifdef CYGOPT_HAL_ARM_XSCALE_PXA2X0_VARIANT_PXA27X
304
    if (vector >= 32 && vector < CYGNUM_HAL_INTERNAL_IRQS) {
305
        *PXA2X0_ICMR2 |= (1 << (vector - 32));
306
        return;
307
    }
308
#endif
309
    if (vector >= CYGNUM_HAL_INTERRUPT_GPIO(2)) {
310
        vector = CYGNUM_HAL_INTERRUPT_GPIOX;
311
    }
312
    *PXA2X0_ICMR |= (1 << vector);
313
}
314
 
315
void hal_interrupt_acknowledge(int vector)
316
{
317
 
318
#ifdef HAL_EXTENDED_INTERRUPT_ACKNOWLEDGE
319
    // Use platform specific handling, if defined
320
    // Note: this macro should do a 'return' for "extended" values of 'vector'
321
    // Normal vectors are handled by code subsequent to the macro call.
322
    HAL_EXTENDED_INTERRUPT_ACKNOWLEDGE(vector);
323
#endif
324
    if (vector == CYGNUM_HAL_INTERRUPT_GPIO0 || vector == CYGNUM_HAL_INTERRUPT_GPIO1) {
325
        *PXA2X0_GEDR0  = (1 << (vector - 8));
326
    } else {
327
#ifdef CYGOPT_HAL_ARM_XSCALE_PXA2X0_VARIANT_PXA27X
328
        if (vector >= CYGNUM_HAL_INTERRUPT_GPIO(96)) {
329
            *PXA2X0_GEDR3 = (1 << (vector - CYGNUM_HAL_INTERNAL_IRQS - 96));
330
        } else
331
#endif
332
        if (vector >= CYGNUM_HAL_INTERRUPT_GPIO(64)) {
333
            *PXA2X0_GEDR2  = (1 << (vector - CYGNUM_HAL_INTERNAL_IRQS - 64));
334
        } else if (vector >= CYGNUM_HAL_INTERRUPT_GPIO(32)) {
335
            *PXA2X0_GEDR1  = (1 << (vector - CYGNUM_HAL_INTERNAL_IRQS - 32));
336
        } else if (vector >= CYGNUM_HAL_INTERRUPT_GPIO(2)) {
337
            *PXA2X0_GEDR0  = (1 << (vector - CYGNUM_HAL_INTERNAL_IRQS));
338
        } else {
339
            // Not a GPIO interrupt
340
            return;
341
        }
342
    }
343
}
344
 
345
void hal_interrupt_configure(int vector, int level, int up)
346
{
347
    cyg_bool falling = level || !up;
348
    cyg_bool rising  = level || up;
349
 
350
#ifdef HAL_EXTENDED_INTERRUPT_CONFIGURE
351
    // Use platform specific handling, if defined
352
    // Note: this macro should do a 'return' for "extended" values of 'vector'
353
    // Normal vectors are handled by code subsequent to the macro call.
354
    HAL_EXTENDED_INTERRUPT_CONFIGURE(vector, level, up);
355
#endif
356
#ifdef CYGOPT_HAL_ARM_XSCALE_PXA2X0_VARIANT_PXA27X
357
    if (vector >= CYGNUM_HAL_INTERRUPT_GPIO(96)) {
358
        if (falling)
359
            *PXA2X0_GFER3 |=  (1 << (vector - CYGNUM_HAL_INTERNAL_IRQS - 96));
360
        else
361
            *PXA2X0_GFER3 &= ~(1 << (vector - CYGNUM_HAL_INTERNAL_IRQS - 96));
362
        if (rising)
363
            *PXA2X0_GRER3 |=  (1 << (vector - CYGNUM_HAL_INTERNAL_IRQS - 96));
364
        else
365
            *PXA2X0_GRER3 &= ~(1 << (vector - CYGNUM_HAL_INTERNAL_IRQS - 96));
366
    } else
367
#endif
368
    if (vector >= CYGNUM_HAL_INTERRUPT_GPIO(64)) {
369
        if (falling)
370
            *PXA2X0_GFER2 |=  (1 << (vector - CYGNUM_HAL_INTERNAL_IRQS - 64));
371
        else
372
            *PXA2X0_GFER2 &= ~(1 << (vector - CYGNUM_HAL_INTERNAL_IRQS - 64));
373
        if (rising)
374
            *PXA2X0_GRER2 |=  (1 << (vector - CYGNUM_HAL_INTERNAL_IRQS - 64));
375
        else
376
            *PXA2X0_GRER2 &= ~(1 << (vector - CYGNUM_HAL_INTERNAL_IRQS - 64));
377
    } else if (vector >= CYGNUM_HAL_INTERRUPT_GPIO(32)) {
378
        if (falling)
379
            *PXA2X0_GFER1 |=  (1 << (vector - CYGNUM_HAL_INTERNAL_IRQS - 32));
380
        else
381
            *PXA2X0_GFER1 &= ~(1 << (vector - CYGNUM_HAL_INTERNAL_IRQS - 32));
382
        if (rising)
383
            *PXA2X0_GRER1 |=  (1 << (vector - CYGNUM_HAL_INTERNAL_IRQS - 32));
384
        else
385
            *PXA2X0_GRER1 &= ~(1 << (vector - CYGNUM_HAL_INTERNAL_IRQS - 32));
386
    } else if (vector >= CYGNUM_HAL_INTERRUPT_GPIO(2)) {
387
        if (falling)
388
            *PXA2X0_GFER0 |=  (1 << (vector - CYGNUM_HAL_INTERNAL_IRQS));
389
        else
390
            *PXA2X0_GFER0 &= ~(1 << (vector - CYGNUM_HAL_INTERNAL_IRQS));
391
        if (rising)
392
            *PXA2X0_GRER0 |=  (1 << (vector - CYGNUM_HAL_INTERNAL_IRQS));
393
        else
394
            *PXA2X0_GRER0 &= ~(1 << (vector - CYGNUM_HAL_INTERNAL_IRQS));
395
    } else if (vector == CYGNUM_HAL_INTERRUPT_GPIO0 || vector == CYGNUM_HAL_INTERRUPT_GPIO1) {
396
        if (falling)
397
            *PXA2X0_GFER0 |=  (1 << (vector - 8));
398
        else
399
            *PXA2X0_GFER0 &= ~(1 << (vector - 8));
400
        if (rising)
401
            *PXA2X0_GRER0 |=  (1 << (vector - 8));
402
        else
403
            *PXA2X0_GRER0 &= ~(1 << (vector - 8));
404
    }
405
}
406
 
407
void hal_interrupt_set_level(int vector, int level)
408
{
409
 
410
#ifdef HAL_EXTENDED_INTERRUPT_SET_LEVEL
411
    // Use platform specific handling, if defined
412
    // Note: this macro should do a 'return' for "extended" values of 'vector'
413
    // Normal vectors are handled by code subsequent to the macro call.
414
    HAL_EXTENDED_INTERRUPT_SET_LEVEL(vector, level);
415
#endif
416
}
417
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.