Merge branch 'master' into upstream
[linux-2.6] / arch / powerpc / platforms / 85xx / mpc85xx_ads.c
1 /*
2  * MPC85xx setup and early boot code plus other random bits.
3  *
4  * Maintained by Kumar Gala (see MAINTAINERS for contact information)
5  *
6  * Copyright 2005 Freescale Semiconductor Inc.
7  *
8  * This program is free software; you can redistribute  it and/or modify it
9  * under  the terms of  the GNU General  Public License as published by the
10  * Free Software Foundation;  either version 2 of the  License, or (at your
11  * option) any later version.
12  */
13
14 #include <linux/stddef.h>
15 #include <linux/kernel.h>
16 #include <linux/pci.h>
17 #include <linux/kdev_t.h>
18 #include <linux/delay.h>
19 #include <linux/seq_file.h>
20 #include <linux/root_dev.h>
21
22 #include <asm/system.h>
23 #include <asm/time.h>
24 #include <asm/machdep.h>
25 #include <asm/pci-bridge.h>
26 #include <asm/mpc85xx.h>
27 #include <asm/prom.h>
28 #include <asm/mpic.h>
29 #include <mm/mmu_decl.h>
30 #include <asm/udbg.h>
31
32 #include <sysdev/fsl_soc.h>
33 #include "mpc85xx.h"
34
35 #ifdef CONFIG_CPM2
36 #include <linux/fs_enet_pd.h>
37 #include <asm/cpm2.h>
38 #include <sysdev/cpm2_pic.h>
39 #include <asm/fs_pd.h>
40 #endif
41
42 #ifndef CONFIG_PCI
43 unsigned long isa_io_base = 0;
44 unsigned long isa_mem_base = 0;
45 #endif
46
47 #ifdef CONFIG_PCI
48 int
49 mpc85xx_exclude_device(u_char bus, u_char devfn)
50 {
51         if (bus == 0 && PCI_SLOT(devfn) == 0)
52                 return PCIBIOS_DEVICE_NOT_FOUND;
53         else
54                 return PCIBIOS_SUCCESSFUL;
55 }
56 #endif /* CONFIG_PCI */
57
58 #ifdef CONFIG_CPM2
59
60 static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
61 {
62         int cascade_irq;
63
64         while ((cascade_irq = cpm2_get_irq()) >= 0) {
65                 generic_handle_irq(cascade_irq);
66         }
67         desc->chip->eoi(irq);
68 }
69
70 #endif /* CONFIG_CPM2 */
71
72 void __init mpc85xx_ads_pic_init(void)
73 {
74         struct mpic *mpic;
75         struct resource r;
76         struct device_node *np = NULL;
77 #ifdef CONFIG_CPM2
78         int irq;
79 #endif
80
81         np = of_find_node_by_type(np, "open-pic");
82
83         if (np == NULL) {
84                 printk(KERN_ERR "Could not find open-pic node\n");
85                 return;
86         }
87
88         if(of_address_to_resource(np, 0, &r)) {
89                 printk(KERN_ERR "Could not map mpic register space\n");
90                 of_node_put(np);
91                 return;
92         }
93
94         mpic = mpic_alloc(np, r.start,
95                         MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
96                         4, 0, " OpenPIC  ");
97         BUG_ON(mpic == NULL);
98         of_node_put(np);
99
100         mpic_assign_isu(mpic, 0, r.start + 0x10200);
101         mpic_assign_isu(mpic, 1, r.start + 0x10280);
102         mpic_assign_isu(mpic, 2, r.start + 0x10300);
103         mpic_assign_isu(mpic, 3, r.start + 0x10380);
104         mpic_assign_isu(mpic, 4, r.start + 0x10400);
105         mpic_assign_isu(mpic, 5, r.start + 0x10480);
106         mpic_assign_isu(mpic, 6, r.start + 0x10500);
107         mpic_assign_isu(mpic, 7, r.start + 0x10580);
108
109         /* Unused on this platform (leave room for 8548) */
110         mpic_assign_isu(mpic, 8, r.start + 0x10600);
111         mpic_assign_isu(mpic, 9, r.start + 0x10680);
112         mpic_assign_isu(mpic, 10, r.start + 0x10700);
113         mpic_assign_isu(mpic, 11, r.start + 0x10780);
114
115         /* External Interrupts */
116         mpic_assign_isu(mpic, 12, r.start + 0x10000);
117         mpic_assign_isu(mpic, 13, r.start + 0x10080);
118         mpic_assign_isu(mpic, 14, r.start + 0x10100);
119
120         mpic_init(mpic);
121
122 #ifdef CONFIG_CPM2
123         /* Setup CPM2 PIC */
124         np = of_find_node_by_type(NULL, "cpm-pic");
125         if (np == NULL) {
126                 printk(KERN_ERR "PIC init: can not find cpm-pic node\n");
127                 return;
128         }
129         irq = irq_of_parse_and_map(np, 0);
130
131         cpm2_pic_init(np);
132         set_irq_chained_handler(irq, cpm2_cascade);
133 #endif
134 }
135
136 /*
137  * Setup the architecture
138  */
139 #ifdef CONFIG_CPM2
140 void init_fcc_ioports(struct fs_platform_info *fpi)
141 {
142         struct io_port *io = cpm2_map(im_ioport);
143         int fcc_no = fs_get_fcc_index(fpi->fs_no);
144         int target;
145         u32 tempval;
146
147         switch(fcc_no) {
148         case 1:
149                 tempval = in_be32(&io->iop_pdirb);
150                 tempval &= ~PB2_DIRB0;
151                 tempval |= PB2_DIRB1;
152                 out_be32(&io->iop_pdirb, tempval);
153
154                 tempval = in_be32(&io->iop_psorb);
155                 tempval &= ~PB2_PSORB0;
156                 tempval |= PB2_PSORB1;
157                 out_be32(&io->iop_psorb, tempval);
158
159                 tempval = in_be32(&io->iop_pparb);
160                 tempval |= (PB2_DIRB0 | PB2_DIRB1);
161                 out_be32(&io->iop_pparb, tempval);
162
163                 target = CPM_CLK_FCC2;
164                 break;
165         case 2:
166                 tempval = in_be32(&io->iop_pdirb);
167                 tempval &= ~PB3_DIRB0;
168                 tempval |= PB3_DIRB1;
169                 out_be32(&io->iop_pdirb, tempval);
170
171                 tempval = in_be32(&io->iop_psorb);
172                 tempval &= ~PB3_PSORB0;
173                 tempval |= PB3_PSORB1;
174                 out_be32(&io->iop_psorb, tempval);
175
176                 tempval = in_be32(&io->iop_pparb);
177                 tempval |= (PB3_DIRB0 | PB3_DIRB1);
178                 out_be32(&io->iop_pparb, tempval);
179
180                 tempval = in_be32(&io->iop_pdirc);
181                 tempval |= PC3_DIRC1;
182                 out_be32(&io->iop_pdirc, tempval);
183
184                 tempval = in_be32(&io->iop_pparc);
185                 tempval |= PC3_DIRC1;
186                 out_be32(&io->iop_pparc, tempval);
187
188                 target = CPM_CLK_FCC3;
189                 break;
190         default:
191                 printk(KERN_ERR "init_fcc_ioports: invalid FCC number\n");
192                 return;
193         }
194
195         /* Port C has clocks......  */
196         tempval = in_be32(&io->iop_psorc);
197         tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8));
198         out_be32(&io->iop_psorc, tempval);
199
200         tempval = in_be32(&io->iop_pdirc);
201         tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8));
202         out_be32(&io->iop_pdirc, tempval);
203         tempval = in_be32(&io->iop_pparc);
204         tempval |= (PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8));
205         out_be32(&io->iop_pparc, tempval);
206
207         cpm2_unmap(io);
208
209         /* Configure Serial Interface clock routing.
210          * First,  clear FCC bits to zero,
211          * then set the ones we want.
212          */
213         cpm2_clk_setup(target, fpi->clk_rx, CPM_CLK_RX);
214         cpm2_clk_setup(target, fpi->clk_tx, CPM_CLK_TX);
215 }
216 #endif
217
218 static void __init mpc85xx_ads_setup_arch(void)
219 {
220         struct device_node *cpu;
221 #ifdef CONFIG_PCI
222         struct device_node *np;
223 #endif
224
225         if (ppc_md.progress)
226                 ppc_md.progress("mpc85xx_ads_setup_arch()", 0);
227
228         cpu = of_find_node_by_type(NULL, "cpu");
229         if (cpu != 0) {
230                 const unsigned int *fp;
231
232                 fp = get_property(cpu, "clock-frequency", NULL);
233                 if (fp != 0)
234                         loops_per_jiffy = *fp / HZ;
235                 else
236                         loops_per_jiffy = 50000000 / HZ;
237                 of_node_put(cpu);
238         }
239
240 #ifdef CONFIG_CPM2
241         cpm2_reset();
242 #endif
243
244 #ifdef CONFIG_PCI
245         for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
246                 add_bridge(np);
247         ppc_md.pci_exclude_device = mpc85xx_exclude_device;
248 #endif
249
250 #ifdef  CONFIG_ROOT_NFS
251         ROOT_DEV = Root_NFS;
252 #else
253         ROOT_DEV = Root_HDA1;
254 #endif
255 }
256
257 void mpc85xx_ads_show_cpuinfo(struct seq_file *m)
258 {
259         uint pvid, svid, phid1;
260         uint memsize = total_memory;
261
262         pvid = mfspr(SPRN_PVR);
263         svid = mfspr(SPRN_SVR);
264
265         seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
266         seq_printf(m, "Machine\t\t: mpc85xx\n");
267         seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
268         seq_printf(m, "SVR\t\t: 0x%x\n", svid);
269
270         /* Display cpu Pll setting */
271         phid1 = mfspr(SPRN_HID1);
272         seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
273
274         /* Display the amount of memory */
275         seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
276 }
277
278 /*
279  * Called very early, device-tree isn't unflattened
280  */
281 static int __init mpc85xx_ads_probe(void)
282 {
283         /* We always match for now, eventually we should look at the flat
284            dev tree to ensure this is the board we are suppose to run on
285         */
286         return 1;
287 }
288
289 define_machine(mpc85xx_ads) {
290         .name                   = "MPC85xx ADS",
291         .probe                  = mpc85xx_ads_probe,
292         .setup_arch             = mpc85xx_ads_setup_arch,
293         .init_IRQ               = mpc85xx_ads_pic_init,
294         .show_cpuinfo           = mpc85xx_ads_show_cpuinfo,
295         .get_irq                = mpic_get_irq,
296         .restart                = mpc85xx_restart,
297         .calibrate_decr         = generic_calibrate_decr,
298         .progress               = udbg_progress,
299 };