import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / arch / mips / ddb5xxx / ddb5477 / pci.c
1 /*
2  * PCI code for DDB5477.
3  *
4  * Copyright (C) 2001 MontaVista Software Inc.
5  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
6  *
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.
11  *
12  */
13
14 #include <linux/config.h>
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/types.h>
18 #include <linux/pci.h>
19
20 #include <asm/bootinfo.h>
21 #include <asm/pci_channel.h>
22 #include <asm/debug.h>
23
24 #include <asm/ddb5xxx/ddb5xxx.h>
25
26 static struct resource extpci_io_resource = {
27         "ext pci IO space",
28         DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE + 0x4000,
29         DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI0_IO_SIZE -1,
30         IORESOURCE_IO};
31
32 static struct resource extpci_mem_resource = {
33         "ext pci memory space",
34         DDB_PCI0_MEM_BASE + 0x100000,
35         DDB_PCI0_MEM_BASE + DDB_PCI0_MEM_SIZE -1,
36         IORESOURCE_MEM};
37
38 static struct resource iopci_io_resource = {
39         "io pci IO space",
40         DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE,
41         DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI1_IO_SIZE -1,
42         IORESOURCE_IO};
43
44 static struct resource iopci_mem_resource = {
45         "ext pci memory space",
46         DDB_PCI1_MEM_BASE,
47         DDB_PCI1_MEM_BASE + DDB_PCI1_MEM_SIZE -1,
48         IORESOURCE_MEM};
49
50 extern struct pci_ops ddb5477_ext_pci_ops;
51 extern struct pci_ops ddb5477_io_pci_ops;
52
53 struct pci_channel mips_pci_channels[] = {
54         { &ddb5477_ext_pci_ops, &extpci_io_resource, &extpci_mem_resource },
55         { &ddb5477_io_pci_ops, &iopci_io_resource, &iopci_mem_resource },
56         { NULL, NULL, NULL}
57 };
58
59
60 /*
61  * we fix up irqs based on the slot number.
62  * The first entry is at AD:11.
63  * Fortunately this works because, although we have two pci buses,
64  * they all have different slot numbers (except for rockhopper slot 20
65  * which is handled below).
66  *
67  */
68
69 /*
70  * irq mapping : device -> pci int # -> vrc4377 irq# ,
71  * ddb5477 board manual page 4  and vrc5477 manual page 46
72  */
73
74 /*
75  * based on ddb5477 manual page 11
76  */
77 #define         MAX_SLOT_NUM            21
78 static unsigned char irq_map[MAX_SLOT_NUM] = {
79         /* SLOT:  0, AD:11 */ 0xff,
80         /* SLOT:  1, AD:12 */ 0xff,
81         /* SLOT:  2, AD:13 */ 0xff,
82         /* SLOT:  3, AD:14 */ 0xff,
83         /* SLOT:  4, AD:15 */ VRC5477_IRQ_INTA,       /* onboard tulip */
84         /* SLOT:  5, AD:16 */ VRC5477_IRQ_INTB,       /* slot 1 */
85         /* SLOT:  6, AD:17 */ VRC5477_IRQ_INTC,       /* slot 2 */
86         /* SLOT:  7, AD:18 */ VRC5477_IRQ_INTD,       /* slot 3 */
87         /* SLOT:  8, AD:19 */ VRC5477_IRQ_INTE,       /* slot 4 */
88         /* SLOT:  9, AD:20 */ 0xff,
89         /* SLOT: 10, AD:21 */ 0xff,
90         /* SLOT: 11, AD:22 */ 0xff,
91         /* SLOT: 12, AD:23 */ 0xff,
92         /* SLOT: 13, AD:24 */ 0xff,
93         /* SLOT: 14, AD:25 */ 0xff,
94         /* SLOT: 15, AD:26 */ 0xff,
95         /* SLOT: 16, AD:27 */ 0xff,
96         /* SLOT: 17, AD:28 */ 0xff,
97         /* SLOT: 18, AD:29 */ VRC5477_IRQ_IOPCI_INTC, /* vrc5477 ac97 */
98         /* SLOT: 19, AD:30 */ VRC5477_IRQ_IOPCI_INTB, /* vrc5477 usb peri */
99         /* SLOT: 20, AD:31 */ VRC5477_IRQ_IOPCI_INTA, /* vrc5477 usb host */
100 };
101 static unsigned char rockhopperII_irq_map[MAX_SLOT_NUM] = {
102         /* SLOT:  0, AD:11 */ 0xff,
103         /* SLOT:  1, AD:12 */ VRC5477_IRQ_INTB,       /* onboard AMD PCNET */
104         /* SLOT:  2, AD:13 */ 0xff,
105         /* SLOT:  3, AD:14 */ 0xff,
106         /* SLOT:  4, AD:15 */ 14,                     /* M5229 ide ISA irq */
107         /* SLOT:  5, AD:16 */ VRC5477_IRQ_INTD,       /* slot 3 */
108         /* SLOT:  6, AD:17 */ VRC5477_IRQ_INTA,       /* slot 4 */
109         /* SLOT:  7, AD:18 */ VRC5477_IRQ_INTD,       /* slot 5 */
110         /* SLOT:  8, AD:19 */ 0,                      /* M5457 modem nop */
111         /* SLOT:  9, AD:20 */ VRC5477_IRQ_INTA,       /* slot 2 */
112         /* SLOT: 10, AD:21 */ 0xff,
113         /* SLOT: 11, AD:22 */ 0xff,
114         /* SLOT: 12, AD:23 */ 0xff,
115         /* SLOT: 13, AD:24 */ 0xff,
116         /* SLOT: 14, AD:25 */ 0xff,
117         /* SLOT: 15, AD:26 */ 0xff,
118         /* SLOT: 16, AD:27 */ 0xff,
119         /* SLOT: 17, AD:28 */ 0,                      /* M7101 PMU nop */
120         /* SLOT: 18, AD:29 */ VRC5477_IRQ_IOPCI_INTC, /* vrc5477 ac97 */
121         /* SLOT: 19, AD:30 */ VRC5477_IRQ_IOPCI_INTB, /* vrc5477 usb peri */
122         /* SLOT: 20, AD:31 */ VRC5477_IRQ_IOPCI_INTA, /* vrc5477 usb host */
123 };
124
125 void __init pcibios_fixup_irqs(void)
126 {
127         struct pci_dev *dev;
128         int slot_num;
129         unsigned char *slot_irq_map;
130         unsigned char irq;
131
132         if (mips_machtype == MACH_NEC_ROCKHOPPERII)
133                 slot_irq_map = rockhopperII_irq_map;
134         else
135                 slot_irq_map = irq_map;
136
137
138         pci_for_each_dev(dev) {
139                 slot_num = PCI_SLOT(dev->devfn);
140                 irq = slot_irq_map[slot_num];
141
142                 db_assert(slot_num < MAX_SLOT_NUM);
143
144                 db_assert(irq != 0xff);
145
146                 pci_write_config_byte(dev,
147                                       PCI_INTERRUPT_LINE,
148                                       irq);
149
150                 dev->irq = irq;
151
152                 if (mips_machtype == MACH_NEC_ROCKHOPPERII) {
153                         /* hack to distinquish overlapping slot 20s, one
154                          * on bus 0 (ALI USB on the M1535 on the backplane),
155                          * and one on bus 2 (NEC USB controller on the CPU board)
156                          * Make the M1535 USB - ISA IRQ number 9.
157                          */
158                         if (slot_num == 20 && dev->bus->number == 0) {
159                                 pci_write_config_byte(dev,
160                                                       PCI_INTERRUPT_LINE,
161                                                       9);
162                                 dev->irq = 9;
163                         }
164                 }
165
166         }
167 }
168
169 void ddb_pci_reset_bus(void)
170 {
171         u32 temp;
172
173         /*
174          * I am not sure about the "official" procedure, the following
175          * steps work as far as I know:
176          * We first set PCI cold reset bit (bit 31) in PCICTRL-H.
177          * Then we clear the PCI warm reset bit (bit 30) to 0 in PCICTRL-H.
178          * The same is true for both PCI channels.
179          */
180         temp = ddb_in32(DDB_PCICTL0_H);
181         temp |= 0x80000000;
182         ddb_out32(DDB_PCICTL0_H, temp);
183         temp &= ~0xc0000000;
184         ddb_out32(DDB_PCICTL0_H, temp);
185
186         temp = ddb_in32(DDB_PCICTL1_H);
187         temp |= 0x80000000;
188         ddb_out32(DDB_PCICTL1_H, temp);
189         temp &= ~0xc0000000;
190         ddb_out32(DDB_PCICTL1_H, temp);
191 }
192
193 unsigned __init int pcibios_assign_all_busses(void)
194 {
195         /* we hope pci_auto has assigned the bus numbers to all buses */
196         return 1;
197 }
198
199 void __init pcibios_fixup_resources(struct pci_dev *dev)
200 {
201 }
202
203 /* 
204  * fixup baseboard AMD chip so that tx does not underflow.
205  *      bcr_18 |= 0x0800
206  * This sets NOUFLO bit which makes tx not start until whole pkt 
207  * is fetched to the chip.
208  */
209 #define PCNET32_WIO_RDP         0x10
210 #define PCNET32_WIO_RAP         0x12
211 #define PCNET32_WIO_RESET       0x14
212 #define PCNET32_WIO_BDP         0x16
213 void __init fix_amd_lance(struct pci_dev *dev)
214 {
215         unsigned long ioaddr;
216         u16 temp;
217
218         ioaddr=pci_resource_start(dev, 0);
219
220         inw(ioaddr + PCNET32_WIO_RESET);                /* reset chip */
221
222         /* bcr_18 |= 0x0800 */
223         outw (18, ioaddr + PCNET32_WIO_RAP);
224         temp = inw (ioaddr + PCNET32_WIO_BDP);
225         temp |= 0x0800;
226         outw (18, ioaddr + PCNET32_WIO_RAP);
227         outw (temp, ioaddr + PCNET32_WIO_BDP);
228 }
229
230 void __init pcibios_fixup(void)
231 {
232         if (mips_machtype == MACH_NEC_ROCKHOPPERII) {
233                 struct pci_dev *dev;
234
235 #define M1535_CONFIG_PORT 0x3f0
236 #define M1535_INDEX_PORT  0x3f0
237 #define M1535_DATA_PORT   0x3f1
238
239                 printk("Configuring ALI M1535 Super I/O mouse irq.\n");
240
241                 request_region(M1535_CONFIG_PORT, 2, "M1535 Super I/O config");
242
243                 /* Enter config mode. */
244                 outb(0x51, M1535_CONFIG_PORT);
245                 outb(0x23, M1535_CONFIG_PORT);
246
247                 /* Select device 0x07. */
248                 outb(0x07, M1535_INDEX_PORT);
249                 outb(0x07, M1535_DATA_PORT);
250
251                 /* Set mouse irq (register 0x72) to 12. */
252                 outb(0x72, M1535_INDEX_PORT);
253                 outb(0x0c, M1535_DATA_PORT);
254
255                 /* Exit config mode. */
256                 outb(0xbb, M1535_CONFIG_PORT);
257
258                 pci_for_each_dev(dev) {
259                         if(dev->vendor == PCI_VENDOR_ID_AL)
260                                 if(dev->device == PCI_DEVICE_ID_AL_M1535
261                                     || dev->device == PCI_DEVICE_ID_AL_M1533) {
262                                 u8 old;
263                                 printk("Enabling ALI M1533/35 PS2 keyboard/mouse.\n");
264                                 pci_read_config_byte(dev, 0x41, &old);
265                                 pci_write_config_byte(dev, 0x41, old | 0xd0);
266                         }
267
268                         if (dev->vendor == PCI_VENDOR_ID_AMD && 
269                                         dev->device == PCI_DEVICE_ID_AMD_LANCE) 
270                                 fix_amd_lance(dev);
271                 }
272
273         }
274 }
275