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