more changes on original files
[linux-2.4.git] / arch / mips / au1000 / common / pci_ops.c
1 /*
2  * BRIEF MODULE DESCRIPTION
3  *      Alchemy/AMD Au1x00 pci support.
4  *
5  * Copyright 2001,2002,2003 MontaVista Software Inc.
6  * Author: MontaVista Software, Inc.
7  *              ppopov@mvista.com or source@mvista.com
8  *
9  *  - Support for all devices (greater than 16) added by David Gathright.
10  *  - Wired tlb fix for ioremap calls in interrupt routines by Embedded Edge.
11  *
12  *  This program is free software; you can redistribute  it and/or modify it
13  *  under  the terms of  the GNU General  Public License as published by the
14  *  Free Software Foundation;  either version 2 of the  License, or (at your
15  *  option) any later version.
16  *
17  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
18  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
19  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
20  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
21  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
23  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
25  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  *  You should have received a copy of the  GNU General Public License along
29  *  with this program; if not, write  to the Free Software Foundation, Inc.,
30  *  675 Mass Ave, Cambridge, MA 02139, USA.
31  */
32 #include <linux/config.h>
33
34 #ifdef CONFIG_PCI
35
36 #include <linux/types.h>
37 #include <linux/pci.h>
38 #include <linux/kernel.h>
39 #include <linux/init.h>
40 #include <linux/vmalloc.h>
41
42 #include <asm/au1000.h>
43 #ifdef CONFIG_MIPS_PB1000
44 #include <asm/pb1000.h>
45 #endif
46 #include <asm/pci_channel.h>
47
48 #define PCI_ACCESS_READ  0
49 #define PCI_ACCESS_WRITE 1
50
51 #undef DEBUG
52 #ifdef  DEBUG
53 #define DBG(x...)       printk(x)
54 #else
55 #define DBG(x...)       
56 #endif
57
58 int (*board_pci_idsel)(unsigned int devsel, int assert);
59
60 /* TBD */
61 static struct resource pci_io_resource = {
62         "pci IO space", 
63         (u32)PCI_IO_START,
64         (u32)PCI_IO_END,
65         IORESOURCE_IO
66 };
67
68 static struct resource pci_mem_resource = {
69         "pci memory space", 
70         (u32)PCI_MEM_START,
71         (u32)PCI_MEM_END,
72         IORESOURCE_MEM
73 };
74
75 extern struct pci_ops au1x_pci_ops;
76
77 struct pci_channel mips_pci_channels[] = {
78         {&au1x_pci_ops, &pci_io_resource, &pci_mem_resource, 
79                 PCI_FIRST_DEVFN,PCI_LAST_DEVFN},
80         {(struct pci_ops *) NULL, (struct resource *) NULL,
81          (struct resource *) NULL, (int) NULL, (int) NULL}
82 };
83
84
85 #ifdef CONFIG_MIPS_PB1000
86 /*
87  * "Bus 2" is really the first and only external slot on the pb1000.
88  * We'll call that bus 0, and limit the accesses to that single
89  * external slot only. The SDRAM is already initialized in setup.c.
90  */
91 static int config_access(unsigned char access_type, struct pci_dev *dev,
92                          unsigned char where, u32 * data)
93 {
94         unsigned char bus = dev->bus->number;
95         unsigned char dev_fn = dev->devfn;
96         unsigned long config;
97
98         if (((dev_fn >> 3) != 0) || (bus != 0)) {
99                 *data = 0xffffffff;
100                 return -1;
101         }
102
103         config = PCI_CONFIG_BASE | (where & ~0x3);
104
105         if (access_type == PCI_ACCESS_WRITE) {
106                 au_writel(*data, config);
107         } else {
108                 *data = au_readl(config);
109         }
110         au_sync_udelay(1);
111
112         DBG("config_access: %d bus %d dev_fn %x at %x *data %x, conf %x\n",
113                         access_type, bus, dev_fn, where, *data, config);
114
115         DBG("bridge config reg: %x (%x)\n", au_readl(PCI_BRIDGE_CONFIG), *data);
116
117         if (au_readl(PCI_BRIDGE_CONFIG) & (1 << 16)) {
118                 *data = 0xffffffff;
119                 return -1;
120         } else {
121                 return PCIBIOS_SUCCESSFUL;
122         }
123 }
124
125 #else
126
127
128 /* CP0 hazard avoidance. */
129 #define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
130                                      "nop; nop; nop; nop;\t" \
131                                      ".set reorder\n\t")
132
133 void mod_wired_entry(int entry, unsigned long entrylo0, 
134                 unsigned long entrylo1, unsigned long entryhi, 
135                 unsigned long pagemask)
136 {
137         unsigned long old_pagemask;
138         unsigned long old_ctx;
139
140         /* Save old context and create impossible VPN2 value */
141         old_ctx = read_c0_entryhi() & 0xff;
142         old_pagemask = read_c0_pagemask();
143         write_c0_index(entry);
144         BARRIER;
145         write_c0_pagemask(pagemask);
146         write_c0_entryhi(entryhi);
147         write_c0_entrylo0(entrylo0);
148         write_c0_entrylo1(entrylo1);
149         BARRIER;
150         tlb_write_indexed();
151         BARRIER;
152         write_c0_entryhi(old_ctx);
153         BARRIER;
154         write_c0_pagemask(old_pagemask);
155 }
156
157 struct vm_struct *pci_cfg_vm;
158 static int pci_cfg_wired_entry;
159 static int first_cfg = 1;
160 unsigned long last_entryLo0, last_entryLo1;
161
162 static int config_access(unsigned char access_type, struct pci_dev *dev, 
163                          unsigned char where, u32 * data)
164 {
165 #if defined( CONFIG_SOC_AU1500 ) || defined( CONFIG_SOC_AU1550 )
166         unsigned char bus = dev->bus->number;
167         unsigned int dev_fn = dev->devfn;
168         unsigned int device = PCI_SLOT(dev_fn);
169         unsigned int function = PCI_FUNC(dev_fn);
170         unsigned long offset, status;
171         unsigned long cfg_base;
172         unsigned long flags;
173         int error = PCIBIOS_SUCCESSFUL;
174         unsigned long entryLo0, entryLo1;
175
176         if (device > 19) {
177                 *data = 0xffffffff;
178                 return -1;
179         }
180
181         local_irq_save(flags);
182         au_writel(((0x2000 << 16) | (au_readl(Au1500_PCI_STATCMD) & 0xffff)), 
183                         Au1500_PCI_STATCMD);
184         au_sync_udelay(1);
185
186         /*
187          * We can't ioremap the entire pci config space because it's 
188          * too large. Nor can we call ioremap dynamically because some 
189          * device drivers use the pci config routines from within 
190          * interrupt handlers and that becomes a problem in get_vm_area().
191          * We use one wired tlb to handle all config accesses for all 
192          * busses. To improve performance, if the current device
193          * is the same as the last device accessed, we don't touch the
194          * tlb.
195          */
196         if (first_cfg) {
197                 /* reserve a wired entry for pci config accesses */
198                 first_cfg = 0;
199                 pci_cfg_vm = get_vm_area(0x2000, 0);
200                 if (!pci_cfg_vm) 
201                         panic (KERN_ERR "PCI unable to get vm area\n");
202                 pci_cfg_wired_entry = read_c0_wired();
203                 add_wired_entry(0, 0, (unsigned long)pci_cfg_vm->addr, 
204                                 PM_4K);
205                 last_entryLo0  = last_entryLo1 = 0xffffffff;
206         }
207
208         /* Since the Au1xxx doesn't do the idsel timing exactly to spec,
209          * many board vendors implement their own off-chip idsel, so call
210          * it now.  If it doesn't succeed, may as well bail out at this point.
211          */
212         if (board_pci_idsel) {
213                 if (board_pci_idsel(device, 1) == 0) {
214                         *data = 0xffffffff;
215                         local_irq_restore(flags);
216                         return -1;
217                 }
218         }
219
220         /* setup the config window */
221         if (bus == 0) {
222                 cfg_base = ((1<<device)<<11);
223         } else {
224                 cfg_base = 0x80000000 | (bus<<16) | (device<<11);
225         }
226
227         /* setup the lower bits of the 36 bit address */
228         offset = (function << 8) | (where & ~0x3);
229         /* pick up any address that falls below the page mask */
230         offset |= cfg_base & ~PAGE_MASK;
231
232         /* page boundary */
233         cfg_base = cfg_base & PAGE_MASK;
234
235         entryLo0 = (6 << 26)  | (cfg_base >> 6) | (2 << 3) | 7;
236         entryLo1 = (6 << 26)  | (cfg_base >> 6) | (0x1000 >> 6) | (2 << 3) | 7;
237
238         if ((entryLo0 != last_entryLo0) || (entryLo1 != last_entryLo1)) {
239                 mod_wired_entry(pci_cfg_wired_entry, entryLo0, entryLo1, 
240                                 (unsigned long)pci_cfg_vm->addr, PM_4K);
241                 last_entryLo0 = entryLo0;
242                 last_entryLo1 = entryLo1;
243         }
244
245         if (access_type == PCI_ACCESS_WRITE) {
246                 au_writel(*data, (int)(pci_cfg_vm->addr + offset));
247         } else {
248                 *data = au_readl((int)(pci_cfg_vm->addr + offset));
249         }
250         au_sync_udelay(2);
251
252         DBG("config_access: %d bus %d device %d at %x *data %x, conf %x\n", 
253                         access_type, bus, device, where, *data, offset);
254
255         /* check master abort */
256         status = au_readl(Au1500_PCI_STATCMD);
257
258         if (status & (1<<29)) { 
259                 *data = 0xffffffff;
260                 error = -1;
261         } else if ((status >> 28) & 0xf) {
262                 DBG("PCI ERR detected: status %x\n", status);
263                 *data = 0xffffffff;
264                 error = -1;
265         } 
266         
267         /* Take away the idsel.
268         */
269         if (board_pci_idsel) {
270                 (void)board_pci_idsel(device, 0);
271         }
272
273         local_irq_restore(flags);
274         return error;
275 #endif
276 }
277 #endif
278
279 static int read_config_byte(struct pci_dev *dev, int where, u8 * val)
280 {
281         u32 data;
282         int ret;
283
284         ret = config_access(PCI_ACCESS_READ, dev, where, &data);
285         if (where & 1) data >>= 8;
286         if (where & 2) data >>= 16;
287         *val = data & 0xff;
288         return ret;
289 }
290
291
292 static int read_config_word(struct pci_dev *dev, int where, u16 * val)
293 {
294         u32 data;
295         int ret;
296
297         ret = config_access(PCI_ACCESS_READ, dev, where, &data);
298         if (where & 2) data >>= 16;
299         *val = data & 0xffff;
300         return ret;
301 }
302
303 static int read_config_dword(struct pci_dev *dev, int where, u32 * val)
304 {
305         int ret;
306
307         ret = config_access(PCI_ACCESS_READ, dev, where, val);
308         return ret;
309 }
310
311
312 static int write_config_byte(struct pci_dev *dev, int where, u8 val)
313 {
314         u32 data = 0;
315
316         if (config_access(PCI_ACCESS_READ, dev, where, &data))
317                 return -1;
318
319         data = (data & ~(0xff << ((where & 3) << 3))) |
320                (val << ((where & 3) << 3));
321
322         if (config_access(PCI_ACCESS_WRITE, dev, where, &data))
323                 return -1;
324
325         return PCIBIOS_SUCCESSFUL;
326 }
327
328 static int write_config_word(struct pci_dev *dev, int where, u16 val)
329 {
330         u32 data = 0;
331
332         if (where & 1)
333                 return PCIBIOS_BAD_REGISTER_NUMBER;
334
335         if (config_access(PCI_ACCESS_READ, dev, where, &data))
336                return -1;
337
338         data = (data & ~(0xffff << ((where & 3) << 3))) |
339                (val << ((where & 3) << 3));
340
341         if (config_access(PCI_ACCESS_WRITE, dev, where, &data))
342                return -1;
343
344
345         return PCIBIOS_SUCCESSFUL;
346 }
347
348 static int write_config_dword(struct pci_dev *dev, int where, u32 val)
349 {
350         if (where & 3)
351                 return PCIBIOS_BAD_REGISTER_NUMBER;
352
353         if (config_access(PCI_ACCESS_WRITE, dev, where, &val))
354                return -1;
355
356         return PCIBIOS_SUCCESSFUL;
357 }
358
359 struct pci_ops au1x_pci_ops = {
360         read_config_byte,
361         read_config_word,
362         read_config_dword,
363         write_config_byte,
364         write_config_word,
365         write_config_dword
366 };
367 #endif /* CONFIG_PCI */