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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [ppc/] [syslib/] [mpc52xx_pci.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * PCI code for the Freescale MPC52xx embedded CPU.
3
 *
4
 *
5
 * Maintainer : Sylvain Munaut <tnt@246tNt.com>
6
 *
7
 * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
8
 *
9
 * This file is licensed under the terms of the GNU General Public License
10
 * version 2. This program is licensed "as is" without any warranty of any
11
 * kind, whether express or implied.
12
 */
13
 
14
 
15
#include <asm/pci.h>
16
 
17
#include <asm/mpc52xx.h>
18
#include "mpc52xx_pci.h"
19
 
20
#include <asm/delay.h>
21
#include <asm/machdep.h>
22
 
23
 
24
/* This macro is defined to activate the workaround for the bug
25
   435 of the MPC5200 (L25R). With it activated, we don't do any
26
   32 bits configuration access during type-1 cycles */
27
#define MPC5200_BUG_435_WORKAROUND
28
 
29
 
30
static int
31
mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
32
                                int offset, int len, u32 *val)
33
{
34
        struct pci_controller *hose = bus->sysdata;
35
        u32 value;
36
 
37
        if (ppc_md.pci_exclude_device)
38
                if (ppc_md.pci_exclude_device(bus->number, devfn))
39
                        return PCIBIOS_DEVICE_NOT_FOUND;
40
 
41
        out_be32(hose->cfg_addr,
42
                (1 << 31) |
43
                ((bus->number - hose->bus_offset) << 16) |
44
                (devfn << 8) |
45
                (offset & 0xfc));
46
        mb();
47
 
48
#ifdef MPC5200_BUG_435_WORKAROUND
49
        if (bus->number != hose->bus_offset) {
50
                switch (len) {
51
                        case 1:
52
                                value = in_8(((u8 __iomem *)hose->cfg_data) + (offset & 3));
53
                                break;
54
                        case 2:
55
                                value = in_le16(((u16 __iomem *)hose->cfg_data) + ((offset>>1) & 1));
56
                                break;
57
 
58
                        default:
59
                                value = in_le16((u16 __iomem *)hose->cfg_data) |
60
                                        (in_le16(((u16 __iomem *)hose->cfg_data) + 1) << 16);
61
                                break;
62
                }
63
        }
64
        else
65
#endif
66
        {
67
                value = in_le32(hose->cfg_data);
68
 
69
                if (len != 4) {
70
                        value >>= ((offset & 0x3) << 3);
71
                        value &= 0xffffffff >> (32 - (len << 3));
72
                }
73
        }
74
 
75
        *val = value;
76
 
77
        out_be32(hose->cfg_addr, 0);
78
        mb();
79
 
80
        return PCIBIOS_SUCCESSFUL;
81
}
82
 
83
static int
84
mpc52xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
85
                                int offset, int len, u32 val)
86
{
87
        struct pci_controller *hose = bus->sysdata;
88
        u32 value, mask;
89
 
90
        if (ppc_md.pci_exclude_device)
91
                if (ppc_md.pci_exclude_device(bus->number, devfn))
92
                        return PCIBIOS_DEVICE_NOT_FOUND;
93
 
94
        out_be32(hose->cfg_addr,
95
                (1 << 31) |
96
                ((bus->number - hose->bus_offset) << 16) |
97
                (devfn << 8) |
98
                (offset & 0xfc));
99
        mb();
100
 
101
#ifdef MPC5200_BUG_435_WORKAROUND
102
        if (bus->number != hose->bus_offset) {
103
                switch (len) {
104
                        case 1:
105
                                out_8(((u8 __iomem *)hose->cfg_data) +
106
                                        (offset & 3), val);
107
                                break;
108
                        case 2:
109
                                out_le16(((u16 __iomem *)hose->cfg_data) +
110
                                        ((offset>>1) & 1), val);
111
                                break;
112
 
113
                        default:
114
                                out_le16((u16 __iomem *)hose->cfg_data,
115
                                        (u16)val);
116
                                out_le16(((u16 __iomem *)hose->cfg_data) + 1,
117
                                        (u16)(val>>16));
118
                                break;
119
                }
120
        }
121
        else
122
#endif
123
        {
124
                if (len != 4) {
125
                        value = in_le32(hose->cfg_data);
126
 
127
                        offset = (offset & 0x3) << 3;
128
                        mask = (0xffffffff >> (32 - (len << 3)));
129
                        mask <<= offset;
130
 
131
                        value &= ~mask;
132
                        val = value | ((val << offset) & mask);
133
                }
134
 
135
                out_le32(hose->cfg_data, val);
136
        }
137
        mb();
138
 
139
        out_be32(hose->cfg_addr, 0);
140
        mb();
141
 
142
        return PCIBIOS_SUCCESSFUL;
143
}
144
 
145
static struct pci_ops mpc52xx_pci_ops = {
146
        .read  = mpc52xx_pci_read_config,
147
        .write = mpc52xx_pci_write_config
148
};
149
 
150
 
151
static void __init
152
mpc52xx_pci_setup(struct mpc52xx_pci __iomem *pci_regs)
153
{
154
        u32 tmp;
155
 
156
        /* Setup control regs */
157
        tmp = in_be32(&pci_regs->scr);
158
        tmp |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
159
        out_be32(&pci_regs->scr, tmp);
160
 
161
        /* Setup windows */
162
        out_be32(&pci_regs->iw0btar, MPC52xx_PCI_IWBTAR_TRANSLATION(
163
                MPC52xx_PCI_MEM_START + MPC52xx_PCI_MEM_OFFSET,
164
                MPC52xx_PCI_MEM_START,
165
                MPC52xx_PCI_MEM_SIZE ));
166
 
167
        out_be32(&pci_regs->iw1btar, MPC52xx_PCI_IWBTAR_TRANSLATION(
168
                MPC52xx_PCI_MMIO_START + MPC52xx_PCI_MEM_OFFSET,
169
                MPC52xx_PCI_MMIO_START,
170
                MPC52xx_PCI_MMIO_SIZE ));
171
 
172
        out_be32(&pci_regs->iw2btar, MPC52xx_PCI_IWBTAR_TRANSLATION(
173
                MPC52xx_PCI_IO_BASE,
174
                MPC52xx_PCI_IO_START,
175
                MPC52xx_PCI_IO_SIZE ));
176
 
177
        out_be32(&pci_regs->iwcr, MPC52xx_PCI_IWCR_PACK(
178
                ( MPC52xx_PCI_IWCR_ENABLE |             /* iw0btar */
179
                  MPC52xx_PCI_IWCR_READ_MULTI |
180
                  MPC52xx_PCI_IWCR_MEM ),
181
                ( MPC52xx_PCI_IWCR_ENABLE |             /* iw1btar */
182
                  MPC52xx_PCI_IWCR_READ |
183
                  MPC52xx_PCI_IWCR_MEM ),
184
                ( MPC52xx_PCI_IWCR_ENABLE |             /* iw2btar */
185
                  MPC52xx_PCI_IWCR_IO )
186
        ));
187
 
188
 
189
        out_be32(&pci_regs->tbatr0,
190
                MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_IO );
191
        out_be32(&pci_regs->tbatr1,
192
                MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_MEM );
193
 
194
        out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD);
195
 
196
        /* Reset the exteral bus ( internal PCI controller is NOT resetted ) */
197
        /* Not necessary and can be a bad thing if for example the bootloader
198
           is displaying a splash screen or ... Just left here for
199
           documentation purpose if anyone need it */
200
        tmp = in_be32(&pci_regs->gscr);
201
#if 0
202
        out_be32(&pci_regs->gscr, tmp | MPC52xx_PCI_GSCR_PR);
203
        udelay(50);
204
#endif
205
        out_be32(&pci_regs->gscr, tmp & ~MPC52xx_PCI_GSCR_PR);
206
}
207
 
208
static void
209
mpc52xx_pci_fixup_resources(struct pci_dev *dev)
210
{
211
        int i;
212
 
213
        /* We don't rely on boot loader for PCI and resets all
214
           devices */
215
        for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
216
                struct resource *res = &dev->resource[i];
217
                if (res->end > res->start) {    /* Only valid resources */
218
                        res->end -= res->start;
219
                        res->start = 0;
220
                        res->flags |= IORESOURCE_UNSET;
221
                }
222
        }
223
 
224
        /* The PCI Host bridge of MPC52xx has a prefetch memory resource
225
           fixed to 1Gb. Doesn't fit in the resource system so we remove it */
226
        if ( (dev->vendor == PCI_VENDOR_ID_MOTOROLA) &&
227
             (   dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200
228
              || dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200B) ) {
229
                struct resource *res = &dev->resource[1];
230
                res->start = res->end = res->flags = 0;
231
        }
232
}
233
 
234
void __init
235
mpc52xx_find_bridges(void)
236
{
237
        struct mpc52xx_pci __iomem *pci_regs;
238
        struct pci_controller *hose;
239
 
240
        pci_assign_all_buses = 1;
241
 
242
        pci_regs = ioremap(MPC52xx_PA(MPC52xx_PCI_OFFSET), MPC52xx_PCI_SIZE);
243
        if (!pci_regs)
244
                return;
245
 
246
        hose = pcibios_alloc_controller();
247
        if (!hose) {
248
                iounmap(pci_regs);
249
                return;
250
        }
251
 
252
        ppc_md.pci_swizzle = common_swizzle;
253
        ppc_md.pcibios_fixup_resources = mpc52xx_pci_fixup_resources;
254
 
255
        hose->first_busno = 0;
256
        hose->last_busno = 0xff;
257
        hose->bus_offset = 0;
258
        hose->ops = &mpc52xx_pci_ops;
259
 
260
        mpc52xx_pci_setup(pci_regs);
261
 
262
        hose->pci_mem_offset = MPC52xx_PCI_MEM_OFFSET;
263
 
264
        hose->io_base_virt = ioremap(MPC52xx_PCI_IO_BASE, MPC52xx_PCI_IO_SIZE);
265
        isa_io_base = (unsigned long) hose->io_base_virt;
266
 
267
        hose->cfg_addr = &pci_regs->car;
268
        hose->cfg_data = hose->io_base_virt;
269
 
270
        /* Setup resources */
271
        pci_init_resource(&hose->mem_resources[0],
272
                        MPC52xx_PCI_MEM_START,
273
                        MPC52xx_PCI_MEM_STOP,
274
                        IORESOURCE_MEM|IORESOURCE_PREFETCH,
275
                        "PCI prefetchable memory");
276
 
277
        pci_init_resource(&hose->mem_resources[1],
278
                        MPC52xx_PCI_MMIO_START,
279
                        MPC52xx_PCI_MMIO_STOP,
280
                        IORESOURCE_MEM,
281
                        "PCI memory");
282
 
283
        pci_init_resource(&hose->io_resource,
284
                        MPC52xx_PCI_IO_START,
285
                        MPC52xx_PCI_IO_STOP,
286
                        IORESOURCE_IO,
287
                        "PCI I/O");
288
 
289
}

powered by: WebSVN 2.1.0

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