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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [sh/] [hs7729pci/] [v2_0/] [src/] [plf_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
//      plf_misc.c
4
//
5
//      HAL platform miscellaneous functions
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):    jskov
44
// Contributors: jskov
45
// Date:         2001-05-25
46
// Purpose:      HAL miscellaneous functions
47
// Description:  This file contains miscellaneous functions provided by the
48
//               HAL.
49
//
50
//####DESCRIPTIONEND####
51
//
52
//==========================================================================
53
 
54
#include <pkgconf/hal.h>
55
 
56
#include <cyg/hal/hal_if.h>             // interfacing API
57
#include <cyg/hal/plf_io.h>
58
#include <cyg/hal/drv_api.h>            // interrupt handling
59
 
60
//--------------------------------------------------------------------------
61
externC void cyg_hal_init_superIO(void);
62
static cyg_uint32 cyg_hal_plf_pci_arbiter(CYG_ADDRWORD vector, CYG_ADDRWORD data);
63
 
64
static cyg_interrupt intr;
65
static cyg_handle_t  intr_handle;
66
 
67
void
68
hal_platform_init(void)
69
{
70
    // Init superIO before calling if_init (which will use UARTs)
71
    cyg_hal_init_superIO();
72
 
73
    hal_if_init();
74
 
75
#if defined(CYGPKG_REDBOOT) && defined(CYGPKG_IO_PCI)
76
    cyg_hal_plf_pci_init();
77
#endif
78
 
79
    // Set up interrupt arbiter
80
    cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_PCI, 1,
81
                             0, cyg_hal_plf_pci_arbiter, NULL,
82
                             &intr_handle, &intr);
83
    cyg_drv_interrupt_attach(intr_handle);
84
    cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_PCI);
85
}
86
 
87
#if defined(CYGPKG_IO_PCI)
88
//--------------------------------------------------------------------------
89
// PCI stuff
90
 
91
// For some reason the PCI config cycles only succeed with some
92
// delays at suitable places.
93
#define _DELAY() do { int i; for (i = 0; i < 100; i++) ; } while(0)
94
 
95
#include <cyg/io/pci_hw.h>
96
#include <cyg/io/pci.h>
97
#include <cyg/hal/hal_if.h>
98
#include <cyg/hal/hal_arbiter.h>        // hal_call_isr
99
 
100
void
101
cyg_hal_plf_pci_init(void)
102
{
103
    cyg_uint8  next_bus;
104
 
105
    static int initialized = 0;
106
    if (initialized) return;
107
    initialized = 1;
108
 
109
    // Set PCI bases
110
    HAL_WRITE_UINT32(CYGARC_REG_PCI_IO_MEMOFFSET, CYGARC_BUS_ADDRESS(HAL_PCI_ALLOC_BASE_IO));
111
    HAL_WRITE_UINT32(CYGARC_REG_PCI_MEM_MEMOFFSET, CYGARC_BUS_ADDRESS(HAL_PCI_ALLOC_BASE_MEMORY));
112
 
113
    // Reset PCI - this does not have the desired effect; devices remain enabled.
114
    HAL_WRITE_UINT32(CYGARC_REG_SD0001_RESET, CYGARC_REG_SD0001_RESET_PCIRST);
115
    CYGACC_CALL_IF_DELAY_US(100);
116
 
117
    // Bring PCI out of reset
118
    HAL_WRITE_UINT32(CYGARC_REG_SD0001_RESET, 0);
119
    CYGACC_CALL_IF_DELAY_US(10000);
120
 
121
    // Set PCI access timeouts/retries to max
122
    HAL_WRITE_UINT32(CYGARC_REG_SD0001_PCI_CTL, (CYGARC_REG_SD0001_PCI_CTL_MAX_DEADLOCK_CNT
123
                                                 |CYGARC_REG_SD0001_PCI_CTL_MAX_RETRY_CNT));
124
    CYGACC_CALL_IF_DELAY_US(10000);
125
 
126
    // Enable controller
127
    // Setup for bus mastering
128
    cyg_hal_plf_pci_cfg_write_dword(0, CYG_PCI_DEV_MAKE_DEVFN(0,0),
129
                                    CYG_PCI_CFG_COMMAND,
130
                                    CYG_PCI_CFG_COMMAND_MEMORY |
131
                                    CYG_PCI_CFG_COMMAND_MASTER |
132
                                    CYG_PCI_CFG_COMMAND_PARITY |
133
                                    CYG_PCI_CFG_COMMAND_SERR);
134
 
135
    // Setup latency timer field
136
    cyg_hal_plf_pci_cfg_write_byte(0, CYG_PCI_DEV_MAKE_DEVFN(0,0),
137
                                   CYG_PCI_CFG_LATENCY_TIMER, 32);
138
 
139
    // Set memory base
140
    cyg_hal_plf_pci_cfg_write_dword(0, CYG_PCI_DEV_MAKE_DEVFN(0,0),
141
                                    CYG_PCI_CFG_BAR_1, 0x0c000008);
142
 
143
    // Configure PCI bus.
144
    next_bus = 1;
145
    cyg_pci_configure_bus(0, &next_bus);
146
}
147
 
148
//--------------------------------------------------------------------------
149
// Config space accessor functions
150
cyg_uint32
151
cyg_hal_plf_pci_cfg_read_dword (cyg_uint32 bus, cyg_uint32 devfn,
152
                                cyg_uint32 offset)
153
{
154
    cyg_uint32 config_data;
155
 
156
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_ADDR,
157
                     CYGARC_REG_PCI_CFG_ADDR_ENABLE |
158
                     (bus << CYGARC_REG_PCI_CFG_ADDR_BUSNO_shift) |
159
                     (devfn << CYGARC_REG_PCI_CFG_ADDR_FUNC_shift) |
160
                     (offset));
161
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_CMD, CYGARC_REG_PCI_CFG_CMD_RCFG);
162
    _DELAY();
163
    HAL_READ_UINT32(CYGARC_REG_PCI_CFG_DATA, config_data);
164
 
165
    return config_data;
166
}
167
 
168
cyg_uint16
169
cyg_hal_plf_pci_cfg_read_word (cyg_uint32 bus, cyg_uint32 devfn,
170
                               cyg_uint32 offset)
171
{
172
    cyg_uint32 config_dword;
173
 
174
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_ADDR,
175
                     CYGARC_REG_PCI_CFG_ADDR_ENABLE |
176
                     (bus << CYGARC_REG_PCI_CFG_ADDR_BUSNO_shift) |
177
                     (devfn << CYGARC_REG_PCI_CFG_ADDR_FUNC_shift) |
178
                     (offset & ~3));
179
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_CMD, CYGARC_REG_PCI_CFG_CMD_RCFG);
180
    _DELAY();
181
    HAL_READ_UINT32(CYGARC_REG_PCI_CFG_DATA, config_dword);
182
 
183
    return (cyg_uint16)((config_dword >> ((offset & 3) * 8)) & 0xffff);
184
}
185
 
186
cyg_uint8
187
cyg_hal_plf_pci_cfg_read_byte (cyg_uint32 bus, cyg_uint32 devfn,
188
                               cyg_uint32 offset)
189
{
190
    cyg_uint32 config_dword;
191
 
192
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_ADDR,
193
                     CYGARC_REG_PCI_CFG_ADDR_ENABLE |
194
                     (bus << CYGARC_REG_PCI_CFG_ADDR_BUSNO_shift) |
195
                     (devfn << CYGARC_REG_PCI_CFG_ADDR_FUNC_shift) |
196
                     (offset & ~3));
197
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_CMD, CYGARC_REG_PCI_CFG_CMD_RCFG);
198
    _DELAY();
199
    HAL_READ_UINT32(CYGARC_REG_PCI_CFG_DATA, config_dword);
200
 
201
    return (cyg_uint8)((config_dword >> ((offset & 3) * 8)) & 0xff);
202
}
203
 
204
void
205
cyg_hal_plf_pci_cfg_write_dword (cyg_uint32 bus, cyg_uint32 devfn,
206
                                 cyg_uint32 offset, cyg_uint32 data)
207
{
208
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_ADDR,
209
                     CYGARC_REG_PCI_CFG_ADDR_ENABLE |
210
                     (bus << CYGARC_REG_PCI_CFG_ADDR_BUSNO_shift) |
211
                     (devfn << CYGARC_REG_PCI_CFG_ADDR_FUNC_shift) |
212
                     (offset));
213
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_DATA, data);
214
    _DELAY();
215
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_CMD, CYGARC_REG_PCI_CFG_CMD_WCFG);
216
    _DELAY();
217
}
218
 
219
void
220
cyg_hal_plf_pci_cfg_write_word (cyg_uint32 bus, cyg_uint32 devfn,
221
                                cyg_uint32 offset, cyg_uint16 data)
222
{
223
    cyg_uint32 config_dword, shift;
224
 
225
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_ADDR,
226
                     CYGARC_REG_PCI_CFG_ADDR_ENABLE |
227
                     (bus << CYGARC_REG_PCI_CFG_ADDR_BUSNO_shift) |
228
                     (devfn << CYGARC_REG_PCI_CFG_ADDR_FUNC_shift) |
229
                     (offset & ~3));
230
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_CMD, CYGARC_REG_PCI_CFG_CMD_RCFG);
231
    _DELAY();
232
    HAL_READ_UINT32(CYGARC_REG_PCI_CFG_DATA, config_dword);
233
 
234
    shift = (offset & 3) * 8;
235
    config_dword &= ~(0xffff << shift);
236
    config_dword |= (data << shift);
237
 
238
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_ADDR,
239
                     CYGARC_REG_PCI_CFG_ADDR_ENABLE |
240
                     (bus << CYGARC_REG_PCI_CFG_ADDR_BUSNO_shift) |
241
                     (devfn << CYGARC_REG_PCI_CFG_ADDR_FUNC_shift) |
242
                     (offset & ~3));
243
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_DATA, config_dword);
244
    _DELAY();
245
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_CMD, CYGARC_REG_PCI_CFG_CMD_WCFG);
246
    _DELAY();
247
}
248
 
249
void
250
cyg_hal_plf_pci_cfg_write_byte (cyg_uint32 bus, cyg_uint32 devfn,
251
                                cyg_uint32 offset, cyg_uint8  data)
252
{
253
    cyg_uint32 config_dword, shift;
254
 
255
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_ADDR,
256
                     CYGARC_REG_PCI_CFG_ADDR_ENABLE |
257
                     (bus << CYGARC_REG_PCI_CFG_ADDR_BUSNO_shift) |
258
                     (devfn << CYGARC_REG_PCI_CFG_ADDR_FUNC_shift) |
259
                     (offset & ~3));
260
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_CMD, CYGARC_REG_PCI_CFG_CMD_RCFG);
261
    _DELAY();
262
    HAL_READ_UINT32(CYGARC_REG_PCI_CFG_DATA, config_dword);
263
 
264
    shift = (offset & 3) * 8;
265
    config_dword &= ~(0xff << shift);
266
    config_dword |= (data << shift);
267
 
268
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_ADDR,
269
                     CYGARC_REG_PCI_CFG_ADDR_ENABLE |
270
                     (bus << CYGARC_REG_PCI_CFG_ADDR_BUSNO_shift) |
271
                     (devfn << CYGARC_REG_PCI_CFG_ADDR_FUNC_shift) |
272
                     (offset & ~3));
273
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_DATA, config_dword);
274
    _DELAY();
275
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_CMD, CYGARC_REG_PCI_CFG_CMD_WCFG);
276
    _DELAY();
277
}
278
 
279
//--------------------------------------------------------------------------
280
// IO space accessor functions
281
 
282
#if 0 // Don't need these after all. But keep them around just in case...
283
 
284
static void
285
pci_io_delay(void)
286
{
287
    int i = 100;
288
    cyg_uint32 flg;
289
    do {
290
        HAL_READ_UINT32(CYGARC_REG_PCI_CFG_FLG, flg);
291
    } while (i-- && (flg & CYGARC_REG_PCI_CFG_FLG_ACTIVE));
292
 
293
    // FIXME: what happens on timeout? Do we need to fill in 0xfffffff
294
    // in read data, by any chance?
295
}
296
 
297
static void
298
pci_io_status(void)
299
{
300
    // FIXME: check status...
301
}
302
 
303
 
304
void
305
cyg_hal_plf_pci_io_write_byte (cyg_uint32 addr, cyg_uint8 data)
306
{
307
    cyg_uint32 io_addr = addr - HAL_PCI_PHYSICAL_IO_BASE;
308
    int shift = io_addr & 3;
309
 
310
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_DATA, ((cyg_uint32)data << (8*shift)));
311
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_ADDR, io_addr & ~3);
312
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_CMD, (CYGARC_REG_PCI_CFG_CMD_BE0 << shift)
313
                     | CYGARC_REG_PCI_CFG_CMD_CMDEN
314
                     | CYGARC_REG_PCI_CFG_CMD_IO_WRITE
315
                     | CYGARC_REG_PCI_CFG_CMD_WT);
316
    pci_io_delay();
317
}
318
 
319
void
320
cyg_hal_plf_pci_io_write_word (cyg_uint32 addr, cyg_uint16 data)
321
{
322
    cyg_uint32 io_addr = addr - HAL_PCI_PHYSICAL_IO_BASE;
323
    int shift = io_addr & 2;
324
 
325
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_DATA, ((cyg_uint32)data << (8*shift)));
326
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_ADDR, io_addr & ~3);
327
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_CMD, ((CYGARC_REG_PCI_CFG_CMD_BE1|CYGARC_REG_PCI_CFG_CMD_BE0) << shift)
328
                     | CYGARC_REG_PCI_CFG_CMD_CMDEN
329
                     | CYGARC_REG_PCI_CFG_CMD_IO_WRITE
330
                     | CYGARC_REG_PCI_CFG_CMD_WT);
331
    pci_io_delay();
332
}
333
 
334
void
335
cyg_hal_plf_pci_io_write_dword (cyg_uint32 addr, cyg_uint32 data)
336
{
337
    cyg_uint32 io_addr = addr - HAL_PCI_PHYSICAL_IO_BASE;
338
 
339
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_DATA, data);
340
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_ADDR, io_addr & ~3);
341
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_CMD,
342
                     (CYGARC_REG_PCI_CFG_CMD_BE3|CYGARC_REG_PCI_CFG_CMD_BE2
343
                      | CYGARC_REG_PCI_CFG_CMD_BE1|CYGARC_REG_PCI_CFG_CMD_BE0)
344
                     | CYGARC_REG_PCI_CFG_CMD_CMDEN
345
                     | CYGARC_REG_PCI_CFG_CMD_IO_WRITE
346
                     | CYGARC_REG_PCI_CFG_CMD_WT);
347
    pci_io_delay();
348
}
349
 
350
cyg_uint8
351
cyg_hal_plf_pci_io_read_byte (cyg_uint32 addr)
352
{
353
    cyg_uint32 io_addr = addr - HAL_PCI_PHYSICAL_IO_BASE;
354
    cyg_uint32 data;
355
    int shift = io_addr & 3;
356
 
357
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_ADDR, io_addr & ~3);
358
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_CMD, (CYGARC_REG_PCI_CFG_CMD_BE0 << shift)
359
                     | CYGARC_REG_PCI_CFG_CMD_CMDEN
360
                     | CYGARC_REG_PCI_CFG_CMD_IO_READ
361
                     | CYGARC_REG_PCI_CFG_CMD_RD);
362
    pci_io_delay();
363
    HAL_READ_UINT32(CYGARC_REG_PCI_CFG_DATA, data);
364
    return (cyg_uint8)(0xff & (data >> (8*shift)));
365
}
366
 
367
cyg_uint16
368
cyg_hal_plf_pci_io_read_word (cyg_uint32 addr)
369
{
370
    cyg_uint32 io_addr = addr - HAL_PCI_PHYSICAL_IO_BASE;
371
    cyg_uint32 data;
372
    int shift = io_addr & 2;
373
 
374
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_ADDR, io_addr & ~3);
375
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_CMD, ((CYGARC_REG_PCI_CFG_CMD_BE1|CYGARC_REG_PCI_CFG_CMD_BE0) << shift)
376
                     | CYGARC_REG_PCI_CFG_CMD_CMDEN
377
                     | CYGARC_REG_PCI_CFG_CMD_IO_READ
378
                     | CYGARC_REG_PCI_CFG_CMD_RD);
379
    pci_io_delay();
380
    HAL_READ_UINT32(CYGARC_REG_PCI_CFG_DATA, data);
381
    return (cyg_uint16)(0xffff & (data >> (shift*8)));
382
}
383
 
384
cyg_uint32
385
cyg_hal_plf_pci_io_read_dword (cyg_uint32 addr)
386
{
387
    cyg_uint32 io_addr = addr - HAL_PCI_PHYSICAL_IO_BASE;
388
    cyg_uint32 data;
389
 
390
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_ADDR, io_addr & ~3);
391
    HAL_WRITE_UINT32(CYGARC_REG_PCI_CFG_CMD,
392
                     (CYGARC_REG_PCI_CFG_CMD_BE3|CYGARC_REG_PCI_CFG_CMD_BE2
393
                      | CYGARC_REG_PCI_CFG_CMD_BE1|CYGARC_REG_PCI_CFG_CMD_BE0)
394
                     | CYGARC_REG_PCI_CFG_CMD_CMDEN
395
                     | CYGARC_REG_PCI_CFG_CMD_IO_READ
396
                     | CYGARC_REG_PCI_CFG_CMD_RD);
397
    pci_io_delay();
398
    HAL_READ_UINT32(CYGARC_REG_PCI_CFG_DATA, data);
399
    return data;
400
}
401
#endif
402
 
403
//--------------------------------------------------------------------------
404
// PCI interrupt decoding
405
static cyg_uint32
406
cyg_hal_plf_pci_arbiter(CYG_ADDRWORD vector, CYG_ADDRWORD data)
407
{
408
    cyg_uint32 isr_ret, int_sts;
409
 
410
    HAL_READ_UINT32(CYGARC_REG_SD0001_INT_STS1, int_sts);
411
    if (int_sts & CYGARC_REG_SD0001_INT_INTA) {
412
        isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_PCIA);
413
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
414
        if (isr_ret & CYG_ISR_HANDLED)
415
#endif
416
            return isr_ret;
417
    }
418
    if (int_sts & CYGARC_REG_SD0001_INT_INTB) {
419
        isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_PCIB);
420
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
421
        if (isr_ret & CYG_ISR_HANDLED)
422
#endif
423
            return isr_ret;
424
    }
425
    if (int_sts & CYGARC_REG_SD0001_INT_INTC) {
426
        isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_PCIC);
427
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
428
        if (isr_ret & CYG_ISR_HANDLED)
429
#endif
430
            return isr_ret;
431
    }
432
    if (int_sts & CYGARC_REG_SD0001_INT_INTD) {
433
        isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_PCID);
434
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
435
        if (isr_ret & CYG_ISR_HANDLED)
436
#endif
437
            return isr_ret;
438
    }
439
 
440
    return 0;
441
}
442
 
443
 
444
#endif // CYGPKG_IO_PCI
445
//--------------------------------------------------------------------------
446
// eof plf_misc.c

powered by: WebSVN 2.1.0

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