Feed the mess through indent.
[linux-2.6/linux-mips.git] / arch / mips / pci / ops-ddb5476.c
blob1953aa09f88a8f9b273177645200a230fb1b8ce3
1 /*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
5 * arch/mips/ddb5xxx/ddb5476/pci_ops.c
6 * Define the pci_ops for DB5477.
8 * Much of the code is derived from the original DDB5074 port by
9 * Geert Uytterhoeven <geert@sonycom.com>
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.
17 #include <linux/config.h>
18 #include <linux/pci.h>
19 #include <linux/kernel.h>
20 #include <linux/types.h>
22 #include <asm/addrspace.h>
23 #include <asm/debug.h>
25 #include <asm/ddb5xxx/ddb5xxx.h>
28 * config_swap structure records what set of pdar/pmr are used
29 * to access pci config space. It also provides a place hold the
30 * original values for future restoring.
32 struct pci_config_swap {
33 u32 pdar;
34 u32 pmr;
35 u32 config_base;
36 u32 config_size;
37 u32 pdar_backup;
38 u32 pmr_backup;
42 * On DDB5476, we have one set of swap registers
44 struct pci_config_swap ext_pci_swap = {
45 DDB_PCIW0,
46 DDB_PCIINIT0,
47 DDB_PCI_CONFIG_BASE,
48 DDB_PCI_CONFIG_SIZE
51 static int pci_config_workaround = 1;
54 * access config space
56 static inline u32 ddb_access_config_base(struct pci_config_swap *swap, u32 bus, /* 0 means top level bus */
57 u32 slot_num)
59 u32 pci_addr = 0;
60 u32 pciinit_offset = 0;
61 u32 virt_addr = swap->config_base;
62 u32 option;
64 if (pci_config_workaround) {
65 /* [jsun] work around Vrc5476 controller itself, returnning
66 * slot 0 essentially makes vrc5476 invisible
68 if (slot_num == 12)
69 slot_num = 0;
71 #if 0
72 /* BUG : skip P2P bridge for now */
73 if (slot_num == 5)
74 slot_num = 0;
75 #endif
77 } else {
78 /* now we have to be hornest, returning the true
79 * PCI config headers for vrc5476
81 if (slot_num == 12) {
82 swap->pdar_backup = ddb_in32(swap->pdar);
83 swap->pmr_backup = ddb_in32(swap->pmr);
84 return DDB_BASE + DDB_PCI_BASE;
88 /* minimum pdar (window) size is 2MB */
89 db_assert(swap->config_size >= (2 << 20));
91 db_assert(slot_num < (1 << 5));
92 db_assert(bus < (1 << 8));
94 /* backup registers */
95 swap->pdar_backup = ddb_in32(swap->pdar);
96 swap->pmr_backup = ddb_in32(swap->pmr);
98 /* set the pdar (pci window) register */
99 ddb_set_pdar(swap->pdar, swap->config_base, swap->config_size, 32, /* 32 bit wide */
100 0, /* not on local memory bus */
101 0); /* not visible from PCI bus (N/A) */
104 * calcuate the absolute pci config addr;
105 * according to the spec, we start scanning from adr:11 (0x800)
107 if (bus == 0) {
108 /* type 0 config */
109 pci_addr = 0x800 << slot_num;
110 } else {
111 /* type 1 config */
112 pci_addr = (bus << 16) | (slot_num << 11);
113 /* panic("ddb_access_config_base: we don't support type 1 config Yet"); */
117 * if pci_addr is less than pci config window size, we set
118 * pciinit_offset to 0 and adjust the virt_address.
119 * Otherwise we will try to adjust pciinit_offset.
121 if (pci_addr < swap->config_size) {
122 virt_addr = KSEG1ADDR(swap->config_base + pci_addr);
123 pciinit_offset = 0;
124 } else {
125 db_assert((pci_addr & (swap->config_size - 1)) == 0);
126 virt_addr = KSEG1ADDR(swap->config_base);
127 pciinit_offset = pci_addr;
130 /* set the pmr register */
131 option = DDB_PCI_ACCESS_32;
132 if (bus != 0)
133 option |= DDB_PCI_CFGTYPE1;
134 ddb_set_pmr(swap->pmr, DDB_PCICMD_CFG, pciinit_offset, option);
136 return virt_addr;
139 static inline void ddb_close_config_base(struct pci_config_swap *swap)
141 ddb_out32(swap->pdar, swap->pdar_backup);
142 ddb_out32(swap->pmr, swap->pmr_backup);
145 static int read_config_dword(struct pci_config_swap *swap,
146 struct pci_dev *dev, u32 where, u32 * val)
148 u32 bus, slot_num, func_num;
149 u32 base;
151 db_assert((where & 3) == 0);
152 db_assert(where < (1 << 8));
154 /* check if the bus is top-level */
155 if (dev->bus->parent != NULL) {
156 bus = dev->bus->number;
157 db_assert(bus != 0);
158 } else {
159 bus = 0;
162 slot_num = PCI_SLOT(dev->devfn);
163 func_num = PCI_FUNC(dev->devfn);
164 base = ddb_access_config_base(swap, bus, slot_num);
165 *val = *(volatile u32 *) (base + (func_num << 8) + where);
166 ddb_close_config_base(swap);
167 return PCIBIOS_SUCCESSFUL;
170 static int read_config_word(struct pci_config_swap *swap,
171 struct pci_dev *dev, u32 where, u16 * val)
173 int status;
174 u32 result;
176 db_assert((where & 1) == 0);
178 status = read_config_dword(swap, dev, where & ~3, &result);
179 if (where & 2)
180 result >>= 16;
181 *val = result & 0xffff;
182 return status;
185 static int read_config_byte(struct pci_config_swap *swap,
186 struct pci_dev *dev, u32 where, u8 * val)
188 int status;
189 u32 result;
191 status = read_config_dword(swap, dev, where & ~3, &result);
192 if (where & 1)
193 result >>= 8;
194 if (where & 2)
195 result >>= 16;
196 *val = result & 0xff;
197 return status;
200 static int write_config_dword(struct pci_config_swap *swap,
201 struct pci_dev *dev, u32 where, u32 val)
203 u32 bus, slot_num, func_num;
204 u32 base;
206 db_assert((where & 3) == 0);
207 db_assert(where < (1 << 8));
209 /* check if the bus is top-level */
210 if (dev->bus->parent != NULL) {
211 bus = dev->bus->number;
212 db_assert(bus != 0);
213 } else {
214 bus = 0;
217 slot_num = PCI_SLOT(dev->devfn);
218 func_num = PCI_FUNC(dev->devfn);
219 base = ddb_access_config_base(swap, bus, slot_num);
220 *(volatile u32 *) (base + (func_num << 8) + where) = val;
221 ddb_close_config_base(swap);
222 return PCIBIOS_SUCCESSFUL;
225 static int write_config_word(struct pci_config_swap *swap,
226 struct pci_dev *dev, u32 where, u16 val)
228 int status, shift = 0;
229 u32 result;
231 db_assert((where & 1) == 0);
233 status = read_config_dword(swap, dev, where & ~3, &result);
234 if (status != PCIBIOS_SUCCESSFUL)
235 return status;
237 if (where & 2)
238 shift += 16;
239 result &= ~(0xffff << shift);
240 result |= val << shift;
241 return write_config_dword(swap, dev, where & ~3, result);
244 static int write_config_byte(struct pci_config_swap *swap,
245 struct pci_dev *dev, u32 where, u8 val)
247 int status, shift = 0;
248 u32 result;
250 status = read_config_dword(swap, dev, where & ~3, &result);
251 if (status != PCIBIOS_SUCCESSFUL)
252 return status;
254 if (where & 2)
255 shift += 16;
256 if (where & 1)
257 shift += 8;
258 result &= ~(0xff << shift);
259 result |= val << shift;
260 return write_config_dword(swap, dev, where & ~3, result);
263 #define MAKE_PCI_OPS(prefix, rw, unitname, unittype, pciswap) \
264 static int prefix##_##rw##_config_##unitname(struct pci_dev *dev, int where, unittype val) \
266 return rw##_config_##unitname(pciswap, \
267 dev, \
268 where, \
269 val); \
272 MAKE_PCI_OPS(extpci, read, byte, u8 *, &ext_pci_swap)
273 MAKE_PCI_OPS(extpci, read, word, u16 *, &ext_pci_swap)
274 MAKE_PCI_OPS(extpci, read, dword, u32 *, &ext_pci_swap)
276 MAKE_PCI_OPS(extpci, write, byte, u8, &ext_pci_swap)
277 MAKE_PCI_OPS(extpci, write, word, u16, &ext_pci_swap)
278 MAKE_PCI_OPS(extpci, write, dword, u32, &ext_pci_swap)
280 struct pci_ops ddb5476_ext_pci_ops = {
281 extpci_read_config_byte,
282 extpci_read_config_word,
283 extpci_read_config_dword,
284 extpci_write_config_byte,
285 extpci_write_config_word,
286 extpci_write_config_dword
290 #if defined(CONFIG_RUNTIME_DEBUG)
291 void jsun_scan_pci_bus(void)
293 struct pci_bus bus;
294 struct pci_dev dev;
295 unsigned int devfn;
296 int j;
298 pci_config_workaround = 0;
300 bus.parent = NULL; /* we scan the top level only */
301 dev.bus = &bus;
302 dev.sysdata = NULL;
304 /* scan ext pci bus and io pci bus */
305 for (j = 0; j < 1; j++) {
306 printk(KERN_INFO "scan ddb5476 external PCI bus:\n");
307 bus.ops = &ddb5476_ext_pci_ops;
309 for (devfn = 0; devfn < 0x100; devfn += 8) {
310 u32 temp;
311 u16 temp16;
312 u8 temp8;
313 int i;
315 dev.devfn = devfn;
316 db_verify(pci_read_config_dword(&dev, 0, &temp),
317 == PCIBIOS_SUCCESSFUL);
318 if (temp == 0xffffffff)
319 continue;
321 printk(KERN_INFO "slot %d: (addr %d) \n",
322 devfn / 8, 11 + devfn / 8);
324 /* verify read word and byte */
325 db_verify(pci_read_config_word(&dev, 2, &temp16),
326 == PCIBIOS_SUCCESSFUL);
327 db_assert(temp16 == (temp >> 16));
328 db_verify(pci_read_config_byte(&dev, 3, &temp8),
329 == PCIBIOS_SUCCESSFUL);
330 db_assert(temp8 == (temp >> 24));
331 db_verify(pci_read_config_byte(&dev, 1, &temp8),
332 == PCIBIOS_SUCCESSFUL);
333 db_assert(temp8 == ((temp >> 8) & 0xff));
335 for (i = 0; i < 16; i++) {
336 if ((i % 4) == 0)
337 printk(KERN_INFO);
338 db_verify(pci_read_config_dword
339 (&dev, i * 4, &temp),
340 == PCIBIOS_SUCCESSFUL);
341 printk("\t%08X", temp);
342 if ((i % 4) == 3)
343 printk("\n");
348 pci_config_workaround = 1;
350 #endif