2 * BRIEF MODULE DESCRIPTION
3 * Alchemy/AMD Au1x00 pci support.
5 * Copyright 2001,2002,2003 MontaVista Software Inc.
6 * Author: MontaVista Software, Inc.
7 * ppopov@mvista.com or source@mvista.com
9 * Support for all devices (greater than 16) added by David Gathright.
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
22 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 675 Mass Ave, Cambridge, MA 02139, USA.
31 #include <linux/config.h>
32 #include <linux/types.h>
33 #include <linux/pci.h>
34 #include <linux/kernel.h>
35 #include <linux/init.h>
37 #include <asm/mach-au1x00/au1000.h>
39 #define PCI_ACCESS_READ 0
40 #define PCI_ACCESS_WRITE 1
43 static int config_access(unsigned char access_type, struct pci_bus *bus,
44 unsigned int devfn, unsigned char where,
47 unsigned int device = PCI_SLOT(devfn);
48 unsigned int function = PCI_FUNC(devfn);
49 unsigned long config, status;
50 unsigned long cfg_addr;
57 au_writel(((0x2000 << 16) |
58 (au_readl(Au1500_PCI_STATCMD) & 0xffff)),
60 //au_writel(au_readl(Au1500_PCI_CFG) & ~PCI_ERROR, Au1500_PCI_CFG);
63 /* setup the config window */
64 if (bus->number == 0) {
65 cfg_addr = (unsigned long) ioremap(Au1500_EXT_CFG |
66 ((1 << device) << 11),
69 cfg_addr = (unsigned long) ioremap(Au1500_EXT_CFG_TYPE1 |
71 number << 16) | (device
78 panic(KERN_ERR "PCI unable to ioremap cfg space\n");
80 /* setup the lower bits of the 36 bit address */
81 config = cfg_addr | (function << 8) | (where & ~0x3);
84 if (access_type == PCI_ACCESS_WRITE) {
85 printk("cfg write: ");
89 printk("devfn %x, device %x func %x \n", devfn, device, function);
90 if (access_type == PCI_ACCESS_WRITE) {
91 printk("data %x\n", *data);
95 if (access_type == PCI_ACCESS_WRITE) {
96 au_writel(*data, config);
98 *data = au_readl(config);
103 iounmap((void *) cfg_addr);
105 /* check master abort */
106 status = au_readl(Au1500_PCI_STATCMD);
107 if (status & (1 << 29)) {
108 printk("master abort\n");
111 } else if ((status >> 28) & 0xf) {
112 printk("PCI ERR detected: status %x\n", status);
116 printk("bios_successful: %x\n", *data);
117 return PCIBIOS_SUCCESSFUL;
121 static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
127 ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
137 static int read_config_word(struct pci_bus *bus, unsigned int devfn,
138 int where, u16 * val)
143 ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
146 *val = data & 0xffff;
150 static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
151 int where, u32 * val)
155 ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val);
160 write_config_byte(struct pci_bus *bus, unsigned int devfn, int where,
165 if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
168 data = (data & ~(0xff << ((where & 3) << 3))) |
169 (val << ((where & 3) << 3));
171 if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
174 return PCIBIOS_SUCCESSFUL;
178 write_config_word(struct pci_bus *bus, unsigned int devfn, int where,
183 if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
186 data = (data & ~(0xffff << ((where & 3) << 3))) |
187 (val << ((where & 3) << 3));
189 if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
193 return PCIBIOS_SUCCESSFUL;
197 write_config_dword(struct pci_bus *bus, unsigned int devfn, int where,
200 if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val))
203 return PCIBIOS_SUCCESSFUL;
206 static int config_read(struct pci_bus *bus, unsigned int devfn,
207 int where, int size, u32 * val)
211 return read_config_byte(bus, devfn, where, (u8 *) val);
213 return read_config_word(bus, devfn, where, (u16 *) val);
215 return read_config_dword(bus, devfn, where, val);
219 static int config_write(struct pci_bus *bus, unsigned int devfn,
220 int where, int size, u32 val)
224 return write_config_byte(bus, devfn, where, (u8) val);
226 return write_config_word(bus, devfn, where, (u16) val);
228 return write_config_dword(bus, devfn, where, val);
233 struct pci_ops au1x_pci_ops = {