Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6
[safe/jmp/linux-2.6] / arch / powerpc / platforms / 85xx / mpc8544_ds.c
1 /*
2  * MPC8544 DS Board Setup
3  *
4  * Author Xianghua Xiao (x.xiao@freescale.com)
5  * Roy Zang <tie-fei.zang@freescale.com>
6  *      - Add PCI/PCI Exprees support
7  * Copyright 2007 Freescale Semiconductor Inc.
8  *
9  * This program is free software; you can redistribute  it and/or modify it
10  * under  the terms of  the GNU General  Public License as published by the
11  * Free Software Foundation;  either version 2 of the  License, or (at your
12  * option) any later version.
13  */
14
15 #include <linux/stddef.h>
16 #include <linux/kernel.h>
17 #include <linux/pci.h>
18 #include <linux/kdev_t.h>
19 #include <linux/delay.h>
20 #include <linux/seq_file.h>
21 #include <linux/interrupt.h>
22
23 #include <asm/system.h>
24 #include <asm/time.h>
25 #include <asm/machdep.h>
26 #include <asm/pci-bridge.h>
27 #include <asm/mpc85xx.h>
28 #include <mm/mmu_decl.h>
29 #include <asm/prom.h>
30 #include <asm/udbg.h>
31 #include <asm/mpic.h>
32 #include <asm/i8259.h>
33
34 #include <sysdev/fsl_soc.h>
35 #include <sysdev/fsl_pci.h>
36 #include "mpc85xx.h"
37
38 #undef DEBUG
39
40 #ifdef DEBUG
41 #define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
42 #else
43 #define DBG(fmt, args...)
44 #endif
45
46 #ifdef CONFIG_PPC_I8259
47 static void mpc8544_8259_cascade(unsigned int irq, struct irq_desc *desc)
48 {
49         unsigned int cascade_irq = i8259_irq();
50
51         if (cascade_irq != NO_IRQ) {
52                 generic_handle_irq(cascade_irq);
53         }
54         desc->chip->eoi(irq);
55 }
56 #endif  /* CONFIG_PPC_I8259 */
57
58 void __init mpc8544_ds_pic_init(void)
59 {
60         struct mpic *mpic;
61         struct resource r;
62         struct device_node *np = NULL;
63 #ifdef CONFIG_PPC_I8259
64         struct device_node *cascade_node = NULL;
65         int cascade_irq;
66 #endif
67
68         np = of_find_node_by_type(np, "open-pic");
69
70         if (np == NULL) {
71                 printk(KERN_ERR "Could not find open-pic node\n");
72                 return;
73         }
74
75         if (of_address_to_resource(np, 0, &r)) {
76                 printk(KERN_ERR "Failed to map mpic register space\n");
77                 of_node_put(np);
78                 return;
79         }
80
81         mpic = mpic_alloc(np, r.start,
82                           MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
83                         0, 256, " OpenPIC  ");
84         BUG_ON(mpic == NULL);
85
86         mpic_init(mpic);
87
88 #ifdef CONFIG_PPC_I8259
89         /* Initialize the i8259 controller */
90         for_each_node_by_type(np, "interrupt-controller")
91             if (of_device_is_compatible(np, "chrp,iic")) {
92                 cascade_node = np;
93                 break;
94         }
95
96         if (cascade_node == NULL) {
97                 printk(KERN_DEBUG "Could not find i8259 PIC\n");
98                 return;
99         }
100
101         cascade_irq = irq_of_parse_and_map(cascade_node, 0);
102         if (cascade_irq == NO_IRQ) {
103                 printk(KERN_ERR "Failed to map cascade interrupt\n");
104                 return;
105         }
106
107         DBG("mpc8544ds: cascade mapped to irq %d\n", cascade_irq);
108
109         i8259_init(cascade_node, 0);
110         of_node_put(cascade_node);
111
112         set_irq_chained_handler(cascade_irq, mpc8544_8259_cascade);
113 #endif  /* CONFIG_PPC_I8259 */
114 }
115
116 #ifdef CONFIG_PCI
117 enum pirq { PIRQA = 8, PIRQB, PIRQC, PIRQD, PIRQE, PIRQF, PIRQG, PIRQH };
118
119 /*
120  * Value in  table -- IRQ number
121  */
122 const unsigned char uli1575_irq_route_table[16] = {
123         0,              /* 0: Reserved */
124         0x8,
125         0,              /* 2: Reserved */
126         0x2,
127         0x4,
128         0x5,
129         0x7,
130         0x6,
131         0,              /* 8: Reserved */
132         0x1,
133         0x3,
134         0x9,
135         0xb,
136         0,              /* 13: Reserved */
137         0xd,
138         0xf,
139 };
140
141 static int __devinit
142 get_pci_irq_from_of(struct pci_controller *hose, int slot, int pin)
143 {
144         struct of_irq oirq;
145         u32 laddr[3];
146         struct device_node *hosenode = hose ? hose->arch_data : NULL;
147
148         if (!hosenode)
149                 return -EINVAL;
150
151         laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(slot, 0) << 8);
152         laddr[1] = laddr[2] = 0;
153         of_irq_map_raw(hosenode, &pin, 1, laddr, &oirq);
154         DBG("mpc8544_ds: pci irq addr %x, slot %d, pin %d, irq %d\n",
155             laddr[0], slot, pin, oirq.specifier[0]);
156         return oirq.specifier[0];
157 }
158
159 /*8259*/
160 static void __devinit quirk_uli1575(struct pci_dev *dev)
161 {
162         unsigned short temp;
163         struct pci_controller *hose = pci_bus_to_host(dev->bus);
164         unsigned char irq2pin[16];
165         unsigned long pirq_map_word = 0;
166         u32 irq;
167         int i;
168
169         /*
170          * ULI1575 interrupts route setup
171          */
172         memset(irq2pin, 0, 16); /* Initialize default value 0 */
173
174         irq2pin[6]=PIRQA+3;     /* enabled mapping for IRQ6 to PIRQD, used by SATA */
175
176         /*
177          * PIRQE -> PIRQF mapping set manually
178          *
179          * IRQ pin   IRQ#
180          * PIRQE ---- 9
181          * PIRQF ---- 10
182          * PIRQG ---- 11
183          * PIRQH ---- 12
184          */
185         for (i = 0; i < 4; i++)
186                 irq2pin[i + 9] = PIRQE + i;
187
188         /* Set IRQ-PIRQ Mapping to ULI1575 */
189         for (i = 0; i < 16; i++)
190                 if (irq2pin[i])
191                         pirq_map_word |= (uli1575_irq_route_table[i] & 0xf)
192                             << ((irq2pin[i] - PIRQA) * 4);
193
194         pirq_map_word |= 1<<26; /* disable INTx in EP mode*/
195
196         /* ULI1575 IRQ mapping conf register default value is 0xb9317542 */
197         DBG("Setup ULI1575 IRQ mapping configuration register value = 0x%x\n",
198                 (int)pirq_map_word);
199         pci_write_config_dword(dev, 0x48, pirq_map_word);
200
201 #define ULI1575_SET_DEV_IRQ(slot, pin, reg)                             \
202         do {                                                            \
203                 int irq;                                                \
204                 irq = get_pci_irq_from_of(hose, slot, pin);             \
205                 if (irq > 0 && irq < 16)                                \
206                         pci_write_config_byte(dev, reg, irq2pin[irq]);  \
207                 else                                                    \
208                         printk(KERN_WARNING "ULI1575 device"            \
209                                 "(slot %d, pin %d) irq %d is invalid.\n", \
210                                 slot, pin, irq);                        \
211         } while(0)
212
213         /* USB 1.1 OHCI controller 1, slot 28, pin 1 */
214         ULI1575_SET_DEV_IRQ(28, 1, 0x86);
215
216         /* USB 1.1 OHCI controller 2, slot 28, pin 2 */
217         ULI1575_SET_DEV_IRQ(28, 2, 0x87);
218
219         /* USB 1.1 OHCI controller 3, slot 28, pin 3 */
220         ULI1575_SET_DEV_IRQ(28, 3, 0x88);
221
222         /* USB 2.0 controller, slot 28, pin 4 */
223         irq = get_pci_irq_from_of(hose, 28, 4);
224         if (irq >= 0 && irq <= 15)
225                 pci_write_config_dword(dev, 0x74, uli1575_irq_route_table[irq]);
226
227         /* Audio controller, slot 29, pin 1 */
228         ULI1575_SET_DEV_IRQ(29, 1, 0x8a);
229
230         /* Modem controller, slot 29, pin 2 */
231         ULI1575_SET_DEV_IRQ(29, 2, 0x8b);
232
233         /* HD audio controller, slot 29, pin 3 */
234         ULI1575_SET_DEV_IRQ(29, 3, 0x8c);
235
236         /* SMB interrupt: slot 30, pin 1 */
237         ULI1575_SET_DEV_IRQ(30, 1, 0x8e);
238
239         /* PMU ACPI SCI interrupt: slot 30, pin 2 */
240         ULI1575_SET_DEV_IRQ(30, 2, 0x8f);
241
242         /* Serial ATA interrupt: slot 31, pin 1 */
243         ULI1575_SET_DEV_IRQ(31, 1, 0x8d);
244
245         /* Primary PATA IDE IRQ: 14
246          * Secondary PATA IDE IRQ: 15
247          */
248         pci_write_config_byte(dev, 0x44, 0x30 | uli1575_irq_route_table[14]);
249         pci_write_config_byte(dev, 0x75, uli1575_irq_route_table[15]);
250
251         /* Set IRQ14 and IRQ15 to legacy IRQs */
252         pci_read_config_word(dev, 0x46, &temp);
253         temp |= 0xc000;
254         pci_write_config_word(dev, 0x46, temp);
255
256         /* Set i8259 interrupt trigger
257          * IRQ 3:  Level
258          * IRQ 4:  Level
259          * IRQ 5:  Level
260          * IRQ 6:  Level
261          * IRQ 7:  Level
262          * IRQ 9:  Level
263          * IRQ 10: Level
264          * IRQ 11: Level
265          * IRQ 12: Level
266          * IRQ 14: Edge
267          * IRQ 15: Edge
268          */
269         outb(0xfa, 0x4d0);
270         outb(0x1e, 0x4d1);
271
272 #undef ULI1575_SET_DEV_IRQ
273 }
274
275 /* SATA */
276 static void __devinit quirk_uli5288(struct pci_dev *dev)
277 {
278         unsigned char c;
279
280         pci_read_config_byte(dev, 0x83, &c);
281         c |= 0x80;              /* read/write lock */
282         pci_write_config_byte(dev, 0x83, c);
283
284         pci_write_config_byte(dev, 0x09, 0x01); /* Base class code: storage */
285         pci_write_config_byte(dev, 0x0a, 0x06); /* IDE disk */
286
287         pci_read_config_byte(dev, 0x83, &c);
288         c &= 0x7f;
289         pci_write_config_byte(dev, 0x83, c);
290
291         pci_read_config_byte(dev, 0x84, &c);
292         c |= 0x01;                              /* emulated PATA mode enabled */
293         pci_write_config_byte(dev, 0x84, c);
294 }
295
296 /* PATA */
297 static void __devinit quirk_uli5229(struct pci_dev *dev)
298 {
299         unsigned short temp;
300         pci_write_config_word(dev, 0x04, 0x0405);       /* MEM IO MSI */
301         pci_read_config_word(dev, 0x4a, &temp);
302         temp |= 0x1000;                         /* Enable Native IRQ 14/15 */
303         pci_write_config_word(dev, 0x4a, temp);
304 }
305
306 /*Bridge*/
307 static void __devinit early_uli5249(struct pci_dev *dev)
308 {
309         unsigned char temp;
310         pci_write_config_word(dev, 0x04, 0x0007);       /* mem access */
311         pci_read_config_byte(dev, 0x7c, &temp);
312         pci_write_config_byte(dev, 0x7c, 0x80); /* R/W lock control */
313         pci_write_config_byte(dev, 0x09, 0x01); /* set as pci-pci bridge */
314         pci_write_config_byte(dev, 0x7c, temp); /* restore pci bus debug control */
315         dev->class |= 0x1;
316 }
317
318 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_uli1575);
319 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288);
320 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229);
321 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249);
322 #endif  /* CONFIG_PCI */
323
324 /*
325  * Setup the architecture
326  */
327 static void __init mpc8544_ds_setup_arch(void)
328 {
329 #ifdef CONFIG_PCI
330         struct device_node *np;
331 #endif
332
333         if (ppc_md.progress)
334                 ppc_md.progress("mpc8544_ds_setup_arch()", 0);
335
336 #ifdef CONFIG_PCI
337         for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) {
338                 struct resource rsrc;
339                 of_address_to_resource(np, 0, &rsrc);
340                 if ((rsrc.start & 0xfffff) == 0xb000)
341                         fsl_add_bridge(np, 1);
342                 else
343                         fsl_add_bridge(np, 0);
344         }
345 #endif
346
347         printk("MPC8544 DS board from Freescale Semiconductor\n");
348 }
349
350 /*
351  * Called very early, device-tree isn't unflattened
352  */
353 static int __init mpc8544_ds_probe(void)
354 {
355         unsigned long root = of_get_flat_dt_root();
356
357         return of_flat_dt_is_compatible(root, "MPC8544DS");
358 }
359
360 define_machine(mpc8544_ds) {
361         .name                   = "MPC8544 DS",
362         .probe                  = mpc8544_ds_probe,
363         .setup_arch             = mpc8544_ds_setup_arch,
364         .init_IRQ               = mpc8544_ds_pic_init,
365         .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
366         .get_irq                = mpic_get_irq,
367         .restart                = mpc85xx_restart,
368         .calibrate_decr         = generic_calibrate_decr,
369         .progress               = udbg_progress,
370 };