Linux-2.6.12-rc2
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / arch / mips / gt64120 / common / pci.c
blobe9e5419a0d537be75e5a2e537a3c3692639262ac
1 /*
2 * BRIEF MODULE DESCRIPTION
3 * Galileo Evaluation Boards PCI support.
5 * The general-purpose functions to read/write and configure the GT64120A's
6 * PCI registers (function names start with pci0 or pci1) are either direct
7 * copies of functions written by Galileo Technology, or are modifications
8 * of their functions to work with Linux 2.4 vs Linux 2.2. These functions
9 * are Copyright - Galileo Technology.
11 * Other functions are derived from other MIPS PCI implementations, or were
12 * written by RidgeRun, Inc, Copyright (C) 2000 RidgeRun, Inc.
13 * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
20 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
21 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
23 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * You should have received a copy of the GNU General Public License along
32 * with this program; if not, write to the Free Software Foundation, Inc.,
33 * 675 Mass Ave, Cambridge, MA 02139, USA.
35 #include <linux/init.h>
36 #include <linux/types.h>
37 #include <linux/pci.h>
38 #include <linux/kernel.h>
39 #include <asm/gt64120.h>
41 #define SELF 0
44 * pciXReadConfigReg - Read from a PCI configuration register
45 * - Make sure the GT is configured as a master before
46 * reading from another device on the PCI.
47 * - The function takes care of Big/Little endian conversion.
48 * INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI
49 * spec)
50 * pciDevNum: The device number needs to be addressed.
51 * RETURNS: data , if the data == 0xffffffff check the master abort bit in the
52 * cause register to make sure the data is valid
54 * Configuration Address 0xCF8:
56 * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
57 * |congif|Reserved| Bus |Device|Function|Register|00|
58 * |Enable| |Number|Number| Number | Number | | <=field Name
61 static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device)
63 unsigned int DataForRegCf8;
64 unsigned int data;
66 DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
67 (PCI_FUNC(device->devfn) << 8) |
68 (offset & ~0x3)) | 0x80000000;
69 GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
72 * The casual observer might wonder why the READ is duplicated here,
73 * rather than immediately following the WRITE, and just have the swap
74 * in the "if". That's because there is a latency problem with trying
75 * to read immediately after setting up the address register. The "if"
76 * check gives enough time for the address to stabilize, so the READ
77 * can work.
79 if (PCI_SLOT(device->devfn) == SELF) /* This board */
80 return GT_READ(GT_PCI0_CFGDATA_OFS);
81 else /* PCI is little endian so swap the Data. */
82 return __GT_READ(GT_PCI0_CFGDATA_OFS);
86 * pciXWriteConfigReg - Write to a PCI configuration register
87 * - Make sure the GT is configured as a master before
88 * writingto another device on the PCI.
89 * - The function takes care of Big/Little endian conversion.
90 * Inputs: unsigned int regOffset: The register offset as it apears in the
91 * GT spec
92 * (or any other PCI device spec)
93 * pciDevNum: The device number needs to be addressed.
95 * Configuration Address 0xCF8:
97 * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
98 * |congif|Reserved| Bus |Device|Function|Register|00|
99 * |Enable| |Number|Number| Number | Number | | <=field Name
102 static void pci0WriteConfigReg(unsigned int offset,
103 struct pci_dev *device, unsigned int data)
105 unsigned int DataForRegCf8;
107 DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
108 (PCI_FUNC(device->devfn) << 8) |
109 (offset & ~0x3)) | 0x80000000;
110 GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
112 if (PCI_SLOT(device->devfn) == SELF) /* This board */
113 GT_WRITE(GT_PCI0_CFGDATA_OFS, data);
114 else /* configuration Transaction over the pci. */
115 __GT_WRITE(GT_PCI0_CFGDATA_OFS, data);
118 extern struct pci_ops gt64120_pci_ops;
120 void __init pcibios_init(void)
122 u32 tmp;
123 struct pci_dev controller;
125 controller.devfn = SELF;
127 tmp = GT_READ(GT_PCI0_CMD_OFS); /* Huh??? -- Ralf */
128 tmp = GT_READ(GT_PCI0_BARE_OFS);
131 * You have to enable bus mastering to configure any other
132 * card on the bus.
134 tmp = pci0ReadConfigReg(PCI_COMMAND, &controller);
135 tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
136 pci0WriteConfigReg(PCI_COMMAND, &controller, tmp);
139 * Reset PCI I/O and PCI MEM values to ones supported by EVM.
141 ioport_resource.start = GT_PCI_IO_BASE;
142 ioport_resource.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1;
143 iomem_resource.start = GT_PCI_MEM_BASE;
144 iomem_resource.end = GT_PCI_MEM_BASE + GT_PCI_MEM_SIZE - 1;
146 pci_scan_bus(0, &gt64120_pci_ops, NULL);