source: rtems/c/src/lib/libbsp/powerpc/beatnik/pci/gt_pci_init.c @ 0c875c6a

4.115
Last change on this file since 0c875c6a was 0c875c6a, checked in by Joel Sherrill <joel.sherrill@…>, on 01/28/11 at 20:29:53

2011-01-28 Joel Sherrill <joel.sherrilL@…>

  • beatnik/include/bsp.h, beatnik/irq/irq.h, beatnik/pci/gt_pci_init.c, ep1a/console/polled_io.c, ep1a/irq/openpic_xxx_irq.c, gen5200/include/irq.h, gen5200/irq/irq.c, gen5200/startup/bspstart.c, haleakala/irq/irq.c, mbx8xx/irq/irq.c, mbx8xx/irq/irq.h, motorola_powerpc/include/bsp.h, mpc8260ads/irq/irq.c, mpc8260ads/irq/irq.h, mvme3100/include/bsp.h, mvme3100/irq/irq.h, mvme3100/start/start.S, mvme5500/include/bsp.h, mvme5500/irq/irq.h, psim/include/bsp.h, psim/include/coverhd.h, psim/irq/irq.h, psim/shmsupp/addrconv.c, psim/shmsupp/getcfg.c, psim/startup/linkcmds, psim/tools/psim-gdb-top.in, psim/tools/psim-top.in, psim/tools/runtest-top.in, qemuppc/irq/irq.h, score603e/irq/irq.c, shared/bootloader/bootldr.h, shared/bootloader/em86.c, shared/bootloader/em86real.S, shared/bootloader/exception.S, shared/bootloader/head.S, shared/bootloader/lib.c, shared/bootloader/misc.c, shared/bootloader/mm.c, shared/bootloader/pci.c, shared/console/console.c, shared/console/consoleIo.h, shared/console/inch.c, shared/console/keyboard.h, shared/console/polled_io.c, shared/irq/i8259.c, shared/irq/irq.h, shared/irq/openpic_i8259_irq.c, shared/motorola/motorola.c, shared/motorola/motorola.h, shared/openpic/openpic.c, shared/openpic/openpic.h, shared/pci/pci.c, shared/residual/residual.c, shared/start/start.S, ss555/irq/irq.h: Fix typo where license said found in found in.
  • Property mode set to 100644
File size: 8.2 KB
Line 
1/* $Id$ */
2
3/* PCI configuration space access */
4
5/*
6 * Acknowledgements:
7 * Valuable information was obtained from the following drivers
8 *   netbsd: (C) Allegro Networks Inc; Wasabi Systems Inc.
9 *   linux:  (C) MontaVista, Software, Inc; Chris Zankel, Mark A. Greer.
10 *   rtems:  (C) Brookhaven National Laboratory; K. Feng
11 */
12
13/*
14 * Original file header of libbsp/shared/pci.c where this file is based upon.
15 *
16 *  Copyright (C) 1999 valette@crf.canon.fr
17 *
18 *  This code is heavily inspired by the public specification of STREAM V2
19 *  that can be found at :
20 *
21 *      <http://www.chorus.com/Documentation/index.html> by following
22 *  the STREAM API Specification Document link.
23 *
24 *  The license and distribution terms for this file may be
25 *  found in the file LICENSE in this distribution or at
26 *  http://www.rtems.com/license/LICENSE.
27 *
28 *  $Id$
29 *
30 *  Till Straumann, <strauman@slac.stanford.edu>, 1/2002
31 *   - separated bridge detection code out of this file
32 */
33
34#include <rtems.h>
35#include <bsp.h>
36#include <libcpu/io.h>
37#include <bsp/pci.h>
38#include <rtems/bspIo.h>
39#include <stdint.h>
40
41/* set to max so we get early access to hose 0 */
42unsigned        BSP_pci_hose1_bus_base = (unsigned)-1;
43
44#define MV64x60_PCI0_CONFIG_ADDR        (BSP_MV64x60_BASE + 0xcf8)
45#define MV64x60_PCI0_CONFIG_DATA        (BSP_MV64x60_BASE + 0xcfc)
46#define MV64x60_PCI1_CONFIG_ADDR        (BSP_MV64x60_BASE + 0xc78)
47#define MV64x60_PCI1_CONFIG_DATA        (BSP_MV64x60_BASE + 0xc7c)
48
49#define PCI_BUS2HOSE(bus) (bus<BSP_pci_hose1_bus_base?0:1)
50
51void detect_host_bridge(void)
52{
53
54}
55
56typedef struct {
57        volatile unsigned char *pci_config_addr;
58        volatile unsigned char *pci_config_data;
59} PciHoseCfg;
60
61static PciHoseCfg hoses[2] = {
62        {
63                pci_config_addr:        (volatile unsigned char *)(MV64x60_PCI0_CONFIG_ADDR),
64                pci_config_data:        (volatile unsigned char *)(MV64x60_PCI0_CONFIG_DATA),
65        },
66        {
67                pci_config_addr:        (volatile unsigned char *)(MV64x60_PCI1_CONFIG_ADDR),
68                pci_config_data:        (volatile unsigned char *)(MV64x60_PCI1_CONFIG_DATA),
69        }
70};
71
72#define pci hoses[hose]
73
74#define HOSE_PREAMBLE \
75        uint8_t hose; \
76                if (bus < BSP_pci_hose1_bus_base) { \
77                        hose = 0; \
78                } else { \
79                        hose = 1; \
80                        bus -= BSP_pci_hose1_bus_base; \
81                }
82
83
84/* Sigh; we have to copy those out from the shared area... */
85static int
86indirect_pci_read_config_byte(unsigned char bus, unsigned char slot,
87                              unsigned char function,
88                              unsigned char offset, uint8_t *val) {
89HOSE_PREAMBLE;
90        out_be32((volatile unsigned *) pci.pci_config_addr,
91                 0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));
92        *val = in_8(pci.pci_config_data + (offset&3));
93        return PCIBIOS_SUCCESSFUL;
94}
95
96static int
97indirect_pci_read_config_word(unsigned char bus, unsigned char slot,
98                              unsigned char function,
99                              unsigned char offset, uint16_t *val) {
100HOSE_PREAMBLE;
101        *val = 0xffff;
102        if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
103        out_be32((unsigned int*) pci.pci_config_addr,
104                 0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));
105        *val = in_le16((volatile unsigned short *)(pci.pci_config_data + (offset&3)));
106        return PCIBIOS_SUCCESSFUL;
107}
108
109static int
110indirect_pci_read_config_dword(unsigned char bus, unsigned char slot,
111                              unsigned char function,
112                              unsigned char offset, uint32_t *val) {
113HOSE_PREAMBLE;
114        *val = 0xffffffff;
115        if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
116        out_be32((unsigned int*) pci.pci_config_addr,
117                 0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|(offset<<24));
118        *val = in_le32((volatile unsigned *)pci.pci_config_data);
119        return PCIBIOS_SUCCESSFUL;
120}
121
122static int
123indirect_pci_write_config_byte(unsigned char bus, unsigned char slot,
124                               unsigned char function,
125                               unsigned char offset, uint8_t val) {
126HOSE_PREAMBLE;
127        out_be32((unsigned int*) pci.pci_config_addr,
128                 0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));
129        out_8(pci.pci_config_data + (offset&3), val);
130        return PCIBIOS_SUCCESSFUL;
131}
132
133static int
134indirect_pci_write_config_word(unsigned char bus, unsigned char slot,
135                               unsigned char function,
136                               unsigned char offset, uint16_t val) {
137HOSE_PREAMBLE;
138        if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
139        out_be32((unsigned int*) pci.pci_config_addr,
140                 0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|((offset&~3)<<24));
141        out_le16((volatile unsigned short *)(pci.pci_config_data + (offset&3)), val);
142        return PCIBIOS_SUCCESSFUL;
143}
144
145static int
146indirect_pci_write_config_dword(unsigned char bus, unsigned char slot,
147                                unsigned char function,
148                                unsigned char offset, uint32_t val) {
149HOSE_PREAMBLE;
150        if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
151        out_be32((unsigned int*) pci.pci_config_addr,
152                 0x80|(bus<<8)|(PCI_DEVFN(slot,function)<<16)|(offset<<24));
153        out_le32((volatile unsigned *)pci.pci_config_data, val);
154        return PCIBIOS_SUCCESSFUL;
155}
156
157const pci_config_access_functions pci_hosed_indirect_functions = {
158        indirect_pci_read_config_byte,
159        indirect_pci_read_config_word,
160        indirect_pci_read_config_dword,
161        indirect_pci_write_config_byte,
162        indirect_pci_write_config_word,
163        indirect_pci_write_config_dword
164};
165
166
167extern unsigned char ucMaxPCIBus; /* importing this is ugly */
168
169/* This is a very ugly hack. I don't want to change the shared
170 * code to support multiple hoses so we hide everything under
171 * the hood with horrible kludges for now. Sorry.
172 */
173void
174BSP_pci_initialize(void)
175{
176
177#if 0   /* These values are already set up for the shared/pci.c code      */
178{
179extern pci_config_access_functions pci_indirect_functions;
180        /* by means of the PCI_CONFIG_ADDR/PCI_CONFIG_DATA macros (bsp.h) */
181        BSP_pci_configuration.pci_config_addr = hoses[0].pci_config_addr;
182        BSP_pci_configuration.pci_config_data = hoses[0].pci_config_data;
183        BSP_pci_configuration.pci_functions   = &pci_indirect_functions;
184}
185#endif
186        /* initialize the first hose */
187        /* scan hose 0 and sets the maximum bus number */
188        pci_initialize();
189        /* remember the boundary */
190        BSP_pci_hose1_bus_base = pci_bus_count();
191        /* so far, so good -- now comes the cludgy part: */
192        /* hack/reset the bus count */
193        ucMaxPCIBus = 0;
194        /* scan hose 1 */
195        BSP_pci_configuration.pci_config_addr = hoses[1].pci_config_addr;
196        BSP_pci_configuration.pci_config_data = hoses[1].pci_config_data;
197        pci_initialize();
198        /* check for overflow of an unsigned char */
199        if ( BSP_pci_hose1_bus_base + pci_bus_count() > 255 ) {
200                BSP_panic("Too many PCI busses in the system");
201        }
202        /* readjust total number */
203        ucMaxPCIBus+=BSP_pci_hose1_bus_base;
204
205        /* install new access functions that can hide the hoses */
206        BSP_pci_configuration.pci_config_addr = (volatile unsigned char *)0xdeadbeef;
207        BSP_pci_configuration.pci_config_data = (volatile unsigned char *)0xdeadbeef;
208        BSP_pci_configuration.pci_functions   = &pci_hosed_indirect_functions;
209}
210
211#define PCI_ERR_BITS            0xf900
212#define PCI_STATUS_OK(x)        (!((x)&PCI_ERR_BITS))
213
214/* For now, just clear errors in the PCI status reg.
215 *
216 * Returns: (for diagnostic purposes)
217 *          original settings (i.e. before applying the clearing
218 *          sequence)
219 *          (pci_status(hose_1)&0xff00) | ((pci_status(hose_2)>>8)&0xff)
220 */
221
222static unsigned long clear_hose_errors(int bus, int quiet)
223{
224unsigned long   rval;
225uint16_t        pcistat;
226int                             count;
227int                             hose = PCI_BUS2HOSE(bus);
228
229        /* read error status for info return */
230        pci_read_config_word(bus,0,0,PCI_STATUS,&pcistat);
231        rval = pcistat;
232
233        count=10;
234        do {
235                /* clear error reporting registers */
236
237                /* clear PCI status register */
238                pci_write_config_word(bus,0,0,PCI_STATUS, PCI_ERR_BITS);
239
240                /* read  new status */
241                pci_read_config_word(bus,0,0,PCI_STATUS, &pcistat);
242
243        } while ( ! PCI_STATUS_OK(pcistat) && count-- );
244
245        if ( !PCI_STATUS_OK(rval) && !quiet) {
246                printk("Cleared PCI errors at discovery (hose %i): pci_stat was 0x%04x\n", hose, rval);
247        }
248        if ( !PCI_STATUS_OK(pcistat) ) {
249                printk("Unable to clear PCI errors at discovery (hose %i) still 0x%04x after 10 attempts\n",hose, pcistat);
250        }
251        return rval;
252}
253
254unsigned short
255(*_BSP_clear_vmebridge_errors)(int) = 0;
256
257unsigned long
258_BSP_clear_hostbridge_errors(int enableMCP, int quiet)
259{
260unsigned long   rval;
261
262        /* MCP is not connected */
263        if ( enableMCP )
264                return -1;
265
266        rval  = (clear_hose_errors(0, quiet) & PCI_ERR_BITS)>>8;
267        rval |= clear_hose_errors(BSP_pci_hose1_bus_base, quiet) & PCI_ERR_BITS;
268
269        /* Tsi148 doesn't propagate VME bus errors to PCI status reg. */
270        if ( _BSP_clear_vmebridge_errors )
271                rval |= _BSP_clear_vmebridge_errors(quiet)<<16;
272
273        return rval;
274}
Note: See TracBrowser for help on using the repository browser.