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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [arm/] [xscale/] [pxa2x0/] [v2_0/] [src/] [pxa2x0_misc.c] - Blame information for rev 27

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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