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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [arm/] [xscale/] [uE250/] [current/] [src/] [uE250_pci.c] - Blame information for rev 868

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

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      uE250_pci.c
4
//
5
//      HAL support code for NMI uEngine uE250 PCI
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):    msalter
43
// Contributors: msalter, gthomas, David Mazur <david@mind.be>
44
// Date:         2002-01-04
45
// Purpose:      PCI support
46
// Description:  Implementations of HAL PCI interfaces
47
//
48
//####DESCRIPTIONEND####
49
//
50
//========================================================================*/
51
 
52
#include <pkgconf/hal.h>
53
#include <pkgconf/system.h>
54
#include CYGBLD_HAL_PLATFORM_H
55
#include CYGHWR_MEMORY_LAYOUT_H
56
 
57
#include <cyg/infra/cyg_type.h>         // base types
58
#include <cyg/infra/cyg_trac.h>         // tracing macros
59
#include <cyg/infra/cyg_ass.h>          // assertion macros
60
#include <cyg/infra/diag.h>             // diag_printf()
61
 
62
#include <cyg/hal/hal_io.h>             // IO macros
63
#include <cyg/hal/hal_if.h>             // calling interface API
64
#include <cyg/hal/hal_arch.h>           // Register state info
65
#include <cyg/hal/hal_diag.h>
66
#include <cyg/hal/hal_intr.h>           // Interrupt names
67
#include <cyg/hal/hal_cache.h>
68
#include <cyg/hal/plf_io.h>
69
#include <cyg/io/pci_hw.h>
70
#include <cyg/io/pci.h>
71
 
72
#ifdef CYGPKG_IO_PCI
73
 
74
#ifdef CYGSEM_HAL_LOAD_PCI_FPGA
75
static unsigned char uE250_pci_bitstream[] = {
76
#include "uE250_pci_bitstream.h"   
77
};
78
externC void load_fpga(void *bitstream, int len);
79
#endif
80
 
81
void
82
cyg_hal_plf_pci_init(void)
83
{
84
    cyg_uint8 next_bus;
85
    static bool _done = false;
86
 
87
    if (_done) return;
88
    _done = true;
89
 
90
//    diag_printf("Initializing PCI.\n");
91
 
92
#ifdef CYGSEM_HAL_LOAD_PCI_FPGA
93
    // Set MSC0 for FPGA configuration
94
    *PXA2X0_MSC1 = (*PXA2X0_MSC1 & 0x0000FFFF);
95
 
96
    // Program FPGA
97
    load_fpga(uE250_pci_bitstream, sizeof(uE250_pci_bitstream));
98
#endif
99
 
100
    *PXA2X0_MSC0 = (*PXA2X0_MSC0 & 0x0000FFFF) | 0x7ff10000;
101
    *PXA2X0_MSC1 = (*PXA2X0_MSC1 & 0x0000FFFF) | 0x70e40000;
102
    *PXA2X0_MSC2 = 0x70e470e4;
103
 
104
    *PXA2X0_MDREFR = 0x0009c018;
105
    *PXA2X0_MDCNFG = 0x03001bc9;
106
 
107
    // FIXME: Change MSC values ??
108
    // Set FPGA to 110.6 MHz
109
    *PXA2X0_GPDR0 |= (0x01 << 7);
110
    *PXA2X0_GPSR0 |= (0x01 << 7);
111
    *PXA2X0_GPDR1 |= (0x01 << (45-32));
112
    *PXA2X0_GPCR1 |= (0x01 << (45-32));
113
 
114
    // Set busmastering
115
    _pxa2x0_set_GPIO_mode(13, PXA2X0_GPIO_AF2, PXA2X0_GPIO_OUT);
116
    _pxa2x0_set_GPIO_mode(14, PXA2X0_GPIO_AF1, PXA2X0_GPIO_IN);
117
 
118
//    diag_printf("Activating PCI bridge.\n");
119
    PCICTL_MISC |= (1 | PCI_SDRAM_256) | PCI_TIMER;
120
 
121
    // Set command master
122
    cyg_hal_plf_pci_cfg_write_word(0, 0, CYG_PCI_CFG_COMMAND,
123
                                   CYG_PCI_CFG_COMMAND_MEMORY|CYG_PCI_CFG_COMMAND_MASTER);
124
 
125
//    diag_printf("Scanning PCI bridge...\n");
126
 
127
    // Initialize PCI support
128
    cyg_pci_init();
129
 
130
    // Configure PCI bus.
131
    next_bus = 1;
132
    cyg_pci_configure_bus(0, &next_bus);
133
 
134
    // Set up to handle PCI interrupts
135
    HAL_INTERRUPT_CONFIGURE(CYGNUM_HAL_INTERRUPT_GPIO1, 0, 0);  // Falling edge
136
    HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_GPIO1);
137
    PCICTL_INT_RESET = 0xFF;  // Clear all pending interrupts
138
    PCICTL_INT_EDGE = 0xFF;   // Generate interrupts
139
    PCICTL_IRQ_MASK = 0x00;   // All masked
140
 
141
    if (0){
142
        cyg_uint8 devfn;
143
        cyg_pci_device_id devid;
144
        cyg_pci_device dev_info;
145
        int i;
146
 
147
        devid = CYG_PCI_DEV_MAKE_ID(next_bus-1, 0) | CYG_PCI_NULL_DEVFN;
148
        while (cyg_pci_find_next(devid, &devid)) {
149
            devfn = CYG_PCI_DEV_GET_DEVFN(devid);
150
            cyg_pci_get_device_info(devid, &dev_info);
151
 
152
            diag_printf("\n");
153
            diag_printf("Bus:        %d\n", CYG_PCI_DEV_GET_BUS(devid));
154
            diag_printf("PCI Device: %d\n", CYG_PCI_DEV_GET_DEV(devfn));
155
            diag_printf("PCI Func  : %d\n", CYG_PCI_DEV_GET_FN(devfn));
156
            diag_printf("Vendor Id : 0x%08X\n", dev_info.vendor);
157
            diag_printf("Device Id : 0x%08X\n", dev_info.device);
158
            diag_printf("Command:    0x%04X\n", dev_info.command);
159
            for (i = 0; i < dev_info.num_bars; i++) {
160
                diag_printf("  BAR[%d]    0x%08x /", i, dev_info.base_address[i]);
161
                diag_printf(" probed size 0x%08x / CPU addr 0x%08x\n",
162
                            dev_info.base_size[i], dev_info.base_map[i]);
163
            }
164
        }
165
    }
166
}
167
 
168
void
169
_uE250_pci_translate_interrupt(int bus, int devfn, int *vector, int *valid)
170
{
171
    int dev = CYG_PCI_DEV_GET_DEV(devfn);
172
 
173
    if (dev <= 5) {
174
        *vector = _uPCI_BASE_INTERRUPT+(dev-1);
175
        valid = true;;
176
    } else {
177
        valid = false;
178
    }
179
}
180
 
181
static void
182
cyg_hal_plf_pci_clear_idsel(void)
183
{
184
    // Clear any active idsels
185
    PCICTL_MISC &= ~PCI_IDSEL_OFF;
186
    PCICTL_STATUS_REG = 0;
187
}
188
 
189
void
190
cyg_hal_plf_pci_select_idsel(cyg_uint32 dev)
191
{
192
    cyg_hal_plf_pci_clear_idsel();
193
    // PCICTL_STATUS_REG = 0x0;
194
    PCICTL_MISC |= 1 + (((dev + 1) << PCI_IDSEL_SHIFT));
195
}
196
 
197
#define _PCI_ADDR(bus, devfn) (PCI_CONFIG_BASE |                        \
198
                               (bus << 16) |                            \
199
                               (CYG_PCI_DEV_GET_DEV(devfn) << 11) |     \
200
                               (CYG_PCI_DEV_GET_FN(devfn) << 8))
201
 
202
cyg_uint32
203
cyg_hal_plf_pci_cfg_read_dword(cyg_uint32 bus, cyg_uint32 devfn,
204
                               cyg_uint32 offset)
205
{
206
    cyg_uint32 config_data;
207
    volatile cyg_uint32 *address = (cyg_uint32 *)_PCI_ADDR(bus, devfn);
208
 
209
    cyg_hal_plf_pci_select_idsel(CYG_PCI_DEV_GET_DEV(devfn));
210
    config_data = address[offset >> 2];
211
    if ((PCICTL_STATUS_REG & 0x0020) == 0x0020) {
212
        // Configuration cycle failed
213
        config_data = 0xFFFFFFFF;
214
    }
215
    cyg_hal_plf_pci_clear_idsel();
216
 
217
    return config_data;
218
}
219
 
220
void
221
cyg_hal_plf_pci_cfg_write_dword(cyg_uint32 bus, cyg_uint32 devfn,
222
                                cyg_uint32 offset, cyg_uint32 data)
223
{
224
    volatile cyg_uint32 *address = (cyg_uint32 *)_PCI_ADDR(bus, devfn);
225
 
226
    cyg_hal_plf_pci_select_idsel(CYG_PCI_DEV_GET_DEV(devfn));
227
    address[offset >> 2] = data;
228
    cyg_hal_plf_pci_clear_idsel();
229
}
230
 
231
 
232
 
233
cyg_uint16
234
cyg_hal_plf_pci_cfg_read_word(cyg_uint32 bus, cyg_uint32 devfn,
235
                              cyg_uint32 offset)
236
{
237
    cyg_uint16 config_data;
238
    volatile cyg_uint16 *address = (cyg_uint16 *)_PCI_ADDR(bus, devfn);
239
 
240
    cyg_hal_plf_pci_select_idsel(CYG_PCI_DEV_GET_DEV(devfn));
241
    config_data = address[offset >> 1];
242
    if ((PCICTL_STATUS_REG & 0x0020) == 0x0020) {
243
        // Configuration cycle failed
244
        config_data = 0xFFFF;
245
    }
246
    cyg_hal_plf_pci_clear_idsel();
247
 
248
    return config_data;
249
}
250
 
251
void
252
cyg_hal_plf_pci_cfg_write_word(cyg_uint32 bus, cyg_uint32 devfn,
253
                               cyg_uint32 offset, cyg_uint16 data)
254
{
255
    volatile cyg_uint16 *address = (cyg_uint16 *)_PCI_ADDR(bus, devfn);
256
 
257
    cyg_hal_plf_pci_select_idsel(CYG_PCI_DEV_GET_DEV(devfn));
258
    address[offset >> 1] = data;
259
    cyg_hal_plf_pci_clear_idsel();
260
}
261
 
262
cyg_uint8
263
cyg_hal_plf_pci_cfg_read_byte(cyg_uint32 bus, cyg_uint32 devfn,
264
                              cyg_uint32 offset)
265
{
266
    cyg_uint8 config_data;
267
    volatile cyg_uint8 *address = (cyg_uint8 *)_PCI_ADDR(bus, devfn);
268
 
269
    cyg_hal_plf_pci_select_idsel(CYG_PCI_DEV_GET_DEV(devfn));
270
    config_data = address[offset];
271
    if ((PCICTL_STATUS_REG & 0x0020) == 0x0020) {
272
        // Configuration cycle failed
273
        config_data = 0xFF;
274
    }
275
    cyg_hal_plf_pci_clear_idsel();
276
 
277
    return config_data;
278
}
279
 
280
 
281
void
282
cyg_hal_plf_pci_cfg_write_byte(cyg_uint32 bus, cyg_uint32 devfn,
283
                               cyg_uint32 offset, cyg_uint8 data)
284
{
285
    volatile cyg_uint8 *address = (cyg_uint8 *)_PCI_ADDR(bus, devfn);
286
 
287
    cyg_hal_plf_pci_select_idsel(CYG_PCI_DEV_GET_DEV(devfn));
288
    address[offset] = data;
289
    cyg_hal_plf_pci_clear_idsel();
290
}
291
 
292
//
293
// Note: PCI I/O space reads on this platform require additional 
294
// addressing gymnastics
295
 
296
/**
297
 * Reads an 8 bit value (byte) from the given address of the PCI
298
 * IO space.
299
 **/
300
cyg_uint8 pci_io_read_8(cyg_uint32 address)
301
{
302
    volatile cyg_uint8 *addr = (volatile cyg_uint8 *)(((address & 0x00000003) << 22) |
303
                                                      address | _PCI_READ_8);
304
    cyg_uint8 val = *addr;
305
#ifdef _PCI_DEBUG
306
    diag_printf("READ  PCI.8 [%p/%p] => %02x\n", address, addr, val);
307
#endif
308
    return val;
309
}
310
 
311
/**
312
 *  * Reads a 16 bit value (word) from the given address of the PCI
313
 *   * IO space.
314
 *    */
315
cyg_uint16 pci_io_read_16(cyg_uint32 address)
316
{
317
    volatile cyg_uint16 *addr = (volatile cyg_uint16 *)(((address & 0x00000002) << 21) |
318
                                                        address | _PCI_READ_16);
319
    cyg_uint16 val = *addr;
320
#ifdef _PCI_DEBUG
321
    diag_printf("READ  PCI.16 [%p/%p] => %04x\n", address, addr, val);
322
#endif
323
    return val;
324
}
325
 
326
/**
327
 *  * Reads a 32 bit value (double word) from the given address of the PCI
328
 *   * IO space.
329
 *    */
330
cyg_uint32 pci_io_read_32(cyg_uint32 address)
331
{
332
    volatile cyg_uint32 *addr = (volatile cyg_uint32 *)(address | _PCI_READ_32);
333
    cyg_uint32 val = *addr;
334
#ifdef _PCI_DEBUG
335
    diag_printf("READ PCI.32 [%p/%p] => %02x\n", address, addr, val);
336
#endif
337
    return val;
338
}
339
 
340
/**
341
 *  * Writes an 8 bit value (byte) into the given address of the PCI
342
 *   * IO space.
343
 *    */
344
void pci_io_write_8(cyg_uint32 address, cyg_uint8 value)
345
{
346
    *((volatile cyg_uint8 *)(address | _PCI_WRITE_X)) = value;
347
#ifdef _PCI_DEBUG
348
    diag_printf("WRITE PCI.8[%p] <= %02x\n", address | _PCI_WRITE_X, value);
349
#endif
350
}
351
 
352
/**
353
 *  * Writes a 16 bit value (single word) into the given address of the PCI
354
 *   * IO space.
355
 *    */
356
void pci_io_write_16(cyg_uint32 address, cyg_uint16 value)
357
{
358
    *((volatile cyg_uint16 *)(address | _PCI_WRITE_X)) = value;
359
#ifdef _PCI_DEBUG
360
    diag_printf("WRITE PCI.16[%p] <= %04x\n", address | _PCI_WRITE_X, value);
361
#endif
362
}
363
 
364
/**
365
 *  * Writes a 32 bit value (double word) into the given address of the PCI
366
 *   * IO space.
367
 *    */
368
void pci_io_write_32(cyg_uint32 address, cyg_uint32 value)
369
{
370
    *((volatile cyg_uint32 *)(address | _PCI_WRITE_X)) = value;
371
#ifdef _PCI_DEBUG
372
    diag_printf("WRITE PCI.32[%p] <= %08x\n", address | _PCI_WRITE_X, value);
373
#endif
374
}
375
 
376
#endif // CYGPKG_IO_PCI

powered by: WebSVN 2.1.0

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