2 * Copyright 2002 Momentum Computer
3 * Author: Matthew Dharm <mdharm@momenco.com>
5 * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
12 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
13 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
15 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
16 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
17 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
18 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <linux/types.h>
28 #include <linux/pci.h>
29 #include <linux/kernel.h>
30 #include <asm/mv64340.h>
33 * galileo_pcibios_(read/write)_config_(dword/word/byte) -
35 * reads/write a dword/word/byte register from the configuration space
38 * Note that bus 0 and bus 1 are local, and we assume all other busses are
39 * bridged from bus 1. This is a safe assumption, since any other
40 * configuration will require major modifications to the CP7000G
45 * offset - register offset in the configuration space
46 * val - value to be written / read
49 * PCIBIOS_SUCCESSFUL when operation was succesfull
50 * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous
51 * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned
54 static int mv64340_read_config(struct pci_bus *bus, unsigned int devfn, int reg,
55 int size, u32 * val, u32 address_reg, u32 data_reg)
59 /* Accessing device 31 crashes the MV-64340. */
60 if (PCI_SLOT(devfn) > 5)
61 return PCIBIOS_DEVICE_NOT_FOUND;
63 address = (bus->number << 16) | (devfn << 8) |
64 (reg & 0xfc) | 0x80000000;
66 /* start the configuration cycle */
67 MV_WRITE(address_reg, address);
71 *val = MV_READ_8(data_reg + (reg & 0x3));
75 *val = MV_READ_16(data_reg + (reg & 0x3));
79 *val = MV_READ(data_reg);
83 return PCIBIOS_SUCCESSFUL;
86 static int mv64340_write_config(struct pci_bus *bus, unsigned int devfn,
87 int reg, int size, u32 val, u32 address_reg, u32 data_reg)
91 /* Accessing device 31 crashes the MV-64340. */
92 if (PCI_SLOT(devfn) > 5)
93 return PCIBIOS_DEVICE_NOT_FOUND;
95 address = (bus->number << 16) | (devfn << 8) |
96 (reg & 0xfc) | 0x80000000;
98 /* start the configuration cycle */
99 MV_WRITE(address_reg, address);
104 MV_WRITE_8(data_reg + (reg & 0x3), val);
109 MV_WRITE_16(data_reg + (reg & 0x3), val);
114 MV_WRITE(data_reg, val);
118 return PCIBIOS_SUCCESSFUL;
121 #define BUILD_PCI_OPS(host) \
123 static int mv64340_bus ## host ## _read_config(struct pci_bus *bus, \
124 unsigned int devfn, int reg, int size, u32 * val) \
126 return mv64340_read_config(bus, devfn, reg, size, val, \
127 MV64340_PCI_ ## host ## _CONFIG_ADDR, \
128 MV64340_PCI_ ## host ## _CONFIG_DATA_VIRTUAL_REG); \
131 static int mv64340_bus ## host ## _write_config(struct pci_bus *bus, \
132 unsigned int devfn, int reg, int size, u32 val) \
134 return mv64340_write_config(bus, devfn, reg, size, val, \
135 MV64340_PCI_ ## host ## _CONFIG_ADDR, \
136 MV64340_PCI_ ## host ## _CONFIG_DATA_VIRTUAL_REG); \
139 struct pci_ops mv64340_bus ## host ## _pci_ops = { \
140 .read = mv64340_bus ## host ## _read_config, \
141 .write = mv64340_bus ## host ## _write_config \