1 diff -Naurp linux-2.6.16.7-generic-patched/arch/mips/pci/Makefile linux-2.6.16.7-patched/arch/mips/pci/Makefile
2 --- linux-2.6.16.7-generic-patched/arch/mips/pci/Makefile 2006-04-17 23:53:25.000000000 +0200
3 +++ linux-2.6.16.7-patched/arch/mips/pci/Makefile 2006-07-05 15:21:58.000000000 +0200
4 @@ -18,6 +18,7 @@ obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o
5 obj-$(CONFIG_MIPS_TX3927) += ops-tx3927.o
6 obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o
7 obj-$(CONFIG_NEC_CMBVR4133) += fixup-vr4133.o
8 +obj-$(CONFIG_BCM_PCI) += fixup-bcm96348.o pci-bcm96348.o ops-bcm96348.o
11 # These are still pretty much in the old state, watch, go blind.
12 diff -Naurp linux-2.6.16.7-generic-patched/arch/mips/pci/fixup-bcm96348.c linux-2.6.16.7-patched/arch/mips/pci/fixup-bcm96348.c
13 --- linux-2.6.16.7-generic-patched/arch/mips/pci/fixup-bcm96348.c 1970-01-01 01:00:00.000000000 +0100
14 +++ linux-2.6.16.7-patched/arch/mips/pci/fixup-bcm96348.c 2006-07-05 15:21:58.000000000 +0200
18 + Copyright 2002 Broadcom Corp. All Rights Reserved.
20 + This program is free software; you can distribute it and/or modify it
21 + under the terms of the GNU General Public License (Version 2) as
22 + published by the Free Software Foundation.
24 + This program is distributed in the hope it will be useful, but WITHOUT
25 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26 + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29 + You should have received a copy of the GNU General Public License along
30 + with this program; if not, write to the Free Software Foundation, Inc.,
31 + 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
34 +#include <linux/init.h>
35 +#include <linux/types.h>
36 +#include <linux/pci.h>
39 +#include <bcm_intr.h>
40 +#include <bcm_map_part.h>
42 +static volatile MpiRegisters * mpi = (MpiRegisters *)(MPI_BASE);
44 +static char irq_tab_bcm96348[] __initdata = {
45 + [0] = INTERRUPT_ID_MPI,
46 + [1] = INTERRUPT_ID_MPI,
47 +#if defined(CONFIG_USB)
48 + [USB_HOST_SLOT] = INTERRUPT_ID_USBH
52 +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
54 + return irq_tab_bcm96348[slot];
57 +static void bcm96348_fixup(struct pci_dev *dev)
62 + memaddr = pci_resource_start(dev, 0);
63 + size = pci_resource_len(dev, 0);
65 + switch (PCI_SLOT(dev->devfn)) {
67 + // UBUS to PCI address range
68 + // Memory Window 1. Mask determines which bits are decoded.
69 + mpi->l2pmrange1 = ~(size-1);
70 + // UBUS to PCI Memory base address. This is akin to the ChipSelect base
72 + mpi->l2pmbase1 = memaddr & BCM_PCI_ADDR_MASK;
73 + // UBUS to PCI Remap Address. Replaces the masked address bits in the
74 + // range register with this setting.
75 + // Also, enable direct I/O and direct Memory accesses
76 + mpi->l2pmremap1 = (memaddr | MEM_WINDOW_EN);
81 + mpi->l2pmrange2 = ~(size-1);
82 + // UBUS to PCI Memory base address.
83 + mpi->l2pmbase2 = memaddr & BCM_PCI_ADDR_MASK;
84 + // UBUS to PCI Remap Address
85 + mpi->l2pmremap2 = (memaddr | MEM_WINDOW_EN);
88 +#if defined(CONFIG_USB)
90 + dev->resource[0].start = USB_HOST_BASE;
91 + dev->resource[0].end = USB_HOST_BASE+USB_BAR0_MEM_SIZE-1;
97 +struct pci_fixup pcibios_fixups[] = {
98 + { PCI_FIXUP_FINAL, PCI_ANY_ID, PCI_ANY_ID, bcm96348_fixup },
101 diff -Naurp linux-2.6.16.7-generic-patched/arch/mips/pci/ops-bcm96348.c linux-2.6.16.7-patched/arch/mips/pci/ops-bcm96348.c
102 --- linux-2.6.16.7-generic-patched/arch/mips/pci/ops-bcm96348.c 1970-01-01 01:00:00.000000000 +0100
103 +++ linux-2.6.16.7-patched/arch/mips/pci/ops-bcm96348.c 2006-07-05 15:21:58.000000000 +0200
107 + Copyright 2002 Broadcom Corp. All Rights Reserved.
109 + This program is free software; you can distribute it and/or modify it
110 + under the terms of the GNU General Public License (Version 2) as
111 + published by the Free Software Foundation.
113 + This program is distributed in the hope it will be useful, but WITHOUT
114 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
115 + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
118 + You should have received a copy of the GNU General Public License along
119 + with this program; if not, write to the Free Software Foundation, Inc.,
120 + 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
123 +#include <linux/types.h>
124 +#include <linux/pci.h>
125 +#include <linux/kernel.h>
126 +#include <linux/init.h>
127 +#include <asm/addrspace.h>
129 +#include <bcm_intr.h>
130 +#include <bcm_map_part.h>
133 +#include <linux/delay.h>
135 +#if defined(CONFIG_USB)
137 +#define DPRINT(x...) printk(x)
139 +#define DPRINT(x...)
143 +pci63xx_int_read(unsigned int devfn, int where, u32 * value, int size);
145 +pci63xx_int_write(unsigned int devfn, int where, u32 * value, int size);
147 +static bool usb_mem_size_rd = FALSE;
148 +static uint32 usb_mem_base = 0;
149 +static uint32 usb_cfg_space_cmd_reg = 0;
151 +static bool pci_mem_size_rd = FALSE;
153 +static volatile MpiRegisters * mpi = (MpiRegisters *)(MPI_BASE);
155 +static void mpi_SetupPciConfigAccess(uint32 addr)
157 + mpi->l2pcfgctl = (DIR_CFG_SEL | DIR_CFG_USEREG | addr) & ~CONFIG_TYPE;
160 +static void mpi_ClearPciConfigAccess(void)
162 + mpi->l2pcfgctl = 0x00000000;
165 +#if defined(CONFIG_USB)
166 +/* --------------------------------------------------------------------------
167 + Name: pci63xx_int_write
168 +Abstract: PCI Config write on internal device(s)
169 + -------------------------------------------------------------------------- */
171 +pci63xx_int_write(unsigned int devfn, int where, u32 * value, int size)
173 + if (PCI_SLOT(devfn) != USB_HOST_SLOT) {
174 + return PCIBIOS_SUCCESSFUL;
179 + DPRINT("W => Slot: %d Where: %2X Len: %d Data: %02X\n",
180 + PCI_SLOT(devfn), where, size, *value);
183 + DPRINT("W => Slot: %d Where: %2X Len: %d Data: %04X\n",
184 + PCI_SLOT(devfn), where, size, *value);
187 + usb_cfg_space_cmd_reg = *value;
194 + DPRINT("W => Slot: %d Where: %2X Len: %d Data: %08lX\n",
195 + PCI_SLOT(devfn), where, size, *value);
197 + case PCI_BASE_ADDRESS_0:
198 + if (*value == 0xffffffff) {
199 + usb_mem_size_rd = TRUE;
201 + usb_mem_base = *value;
212 + return PCIBIOS_SUCCESSFUL;
215 +/* --------------------------------------------------------------------------
216 + Name: pci63xx_int_read
217 +Abstract: PCI Config read on internal device(s)
218 + -------------------------------------------------------------------------- */
220 +pci63xx_int_read(unsigned int devfn, int where, u32 * value, int size)
222 + uint32 retValue = 0xFFFFFFFF;
224 + if (PCI_SLOT(devfn) != USB_HOST_SLOT) {
225 + return PCIBIOS_SUCCESSFUL;
228 + // For now, this is specific to the USB Host controller. We can
229 + // make it more general if we have to...
230 + // Emulate PCI Config accesses
232 + case PCI_VENDOR_ID:
233 + case PCI_DEVICE_ID:
234 + retValue = PCI_VENDOR_ID_BROADCOM | 0x63000000;
238 + retValue = (0x0006 << 16) | usb_cfg_space_cmd_reg;
240 + case PCI_CLASS_REVISION:
241 + case PCI_CLASS_DEVICE:
242 + retValue = (PCI_CLASS_SERIAL_USB << 16) | (0x10 << 8) | 0x01;
244 + case PCI_BASE_ADDRESS_0:
245 + if (usb_mem_size_rd) {
246 + retValue = USB_BAR0_MEM_SIZE;
248 + if (usb_mem_base != 0)
249 + retValue = usb_mem_base;
251 + retValue = USB_HOST_BASE;
253 + usb_mem_size_rd = FALSE;
255 + case PCI_CACHE_LINE_SIZE:
256 + case PCI_LATENCY_TIMER:
259 + case PCI_HEADER_TYPE:
260 + retValue = PCI_HEADER_TYPE_NORMAL;
262 + case PCI_SUBSYSTEM_VENDOR_ID:
263 + retValue = PCI_VENDOR_ID_BROADCOM;
265 + case PCI_SUBSYSTEM_ID:
268 + case PCI_INTERRUPT_LINE:
269 + retValue = INTERRUPT_ID_USBH;
277 + *value = (retValue >> ((where & 3) << 3)) & 0xff;
278 + DPRINT("R <= Slot: %d Where: %2X Len: %d Data: %02X\n",
279 + PCI_SLOT(devfn), where, size, *value);
282 + *value = (retValue >> ((where & 3) << 3)) & 0xffff;
283 + DPRINT("R <= Slot: %d Where: %2X Len: %d Data: %04X\n",
284 + PCI_SLOT(devfn), where, size, *value);
288 + DPRINT("R <= Slot: %d Where: %2X Len: %d Data: %08lX\n",
289 + PCI_SLOT(devfn), where, size, *value);
295 + return PCIBIOS_SUCCESSFUL;
299 +static int bcm96348_pcibios_read(struct pci_bus *bus, unsigned int devfn,
300 + int where, int size, u32 * val)
302 + volatile unsigned char *ioBase = (unsigned char *)(mpi->l2piobase | KSEG1);
305 +#if defined(CONFIG_USB)
306 + if (PCI_SLOT(devfn) == USB_HOST_SLOT)
307 + return pci63xx_int_read(devfn, where, val, size);
310 + mpi_SetupPciConfigAccess(BCM_PCI_CFG(PCI_SLOT(devfn), PCI_FUNC(devfn), where));
311 + data = *(uint32 *)ioBase;
314 + *val = (data >> ((where & 3) << 3)) & 0xff;
317 + *val = (data >> ((where & 3) << 3)) & 0xffff;
321 + /* Special case for reading PCI device range */
322 + if ((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_5)) {
323 + if (pci_mem_size_rd) {
324 + /* bcm6348 PCI memory window minimum size is 64K */
325 + *val &= PCI_SIZE_64K;
332 + pci_mem_size_rd = FALSE;
333 + mpi_ClearPciConfigAccess();
335 + return PCIBIOS_SUCCESSFUL;
338 +static int bcm96348_pcibios_write(struct pci_bus *bus, unsigned int devfn,
339 + int where, int size, u32 val)
341 + volatile unsigned char *ioBase = (unsigned char *)(mpi->l2piobase | KSEG1);
344 +#if defined(CONFIG_USB)
345 + if (PCI_SLOT(devfn) == USB_HOST_SLOT)
346 + return pci63xx_int_write(devfn, where, &val, size);
348 + mpi_SetupPciConfigAccess(BCM_PCI_CFG(PCI_SLOT(devfn), PCI_FUNC(devfn), where));
349 + data = *(uint32 *)ioBase;
352 + data = (data & ~(0xff << ((where & 3) << 3))) |
353 + (val << ((where & 3) << 3));
356 + data = (data & ~(0xffff << ((where & 3) << 3))) |
357 + (val << ((where & 3) << 3));
361 + /* Special case for reading PCI device range */
362 + if ((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_5)) {
363 + if (val == 0xffffffff)
364 + pci_mem_size_rd = TRUE;
370 + *(uint32 *)ioBase = data;
372 + mpi_ClearPciConfigAccess();
374 + return PCIBIOS_SUCCESSFUL;
377 +struct pci_ops bcm96348_pci_ops = {
378 + .read = bcm96348_pcibios_read,
379 + .write = bcm96348_pcibios_write
381 diff -Naurp linux-2.6.16.7-generic-patched/arch/mips/pci/pci-bcm96348.c linux-2.6.16.7-patched/arch/mips/pci/pci-bcm96348.c
382 --- linux-2.6.16.7-generic-patched/arch/mips/pci/pci-bcm96348.c 1970-01-01 01:00:00.000000000 +0100
383 +++ linux-2.6.16.7-patched/arch/mips/pci/pci-bcm96348.c 2006-07-05 15:21:58.000000000 +0200
387 + Copyright 2002 Broadcom Corp. All Rights Reserved.
389 + This program is free software; you can distribute it and/or modify it
390 + under the terms of the GNU General Public License (Version 2) as
391 + published by the Free Software Foundation.
393 + This program is distributed in the hope it will be useful, but WITHOUT
394 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
395 + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
398 + You should have received a copy of the GNU General Public License along
399 + with this program; if not, write to the Free Software Foundation, Inc.,
400 + 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
403 +#include <linux/types.h>
404 +#include <linux/pci.h>
405 +#include <linux/kernel.h>
406 +#include <linux/init.h>
408 +#include <asm/pci_channel.h>
411 +static struct resource bcm_pci_io_resource = {
412 + .name = "bcm96348 pci IO space",
413 + .start = BCM_PCI_IO_BASE,
414 + .end = BCM_PCI_IO_BASE + BCM_PCI_IO_SIZE_64KB - 1,
415 + .flags = IORESOURCE_IO
418 +static struct resource bcm_pci_mem_resource = {
419 + .name = "bcm96348 pci memory space",
420 + .start = BCM_PCI_MEM_BASE,
421 + .end = BCM_PCI_MEM_BASE + BCM_PCI_MEM_SIZE_16MB - 1,
422 + .flags = IORESOURCE_MEM
425 +extern struct pci_ops bcm96348_pci_ops;
427 +struct pci_controller bcm96348_controller = {
428 + .pci_ops = &bcm96348_pci_ops,
429 + .io_resource = &bcm_pci_io_resource,
430 + .mem_resource = &bcm_pci_mem_resource,
433 +static void bcm96348_pci_init(void)
435 + register_pci_controller(&bcm96348_controller);
438 +arch_initcall(bcm96348_pci_init);