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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [sh/] [hs7729pci/] [current/] [src/] [plf_misc.c] - Blame information for rev 838

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

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

powered by: WebSVN 2.1.0

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