Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / arch / ppc / platforms / lite5200.c
1 /*
2  * Platform support file for the Freescale LITE5200 based on MPC52xx.
3  * A maximum of this file should be moved to syslib/mpc52xx_?????
4  * so that new platform based on MPC52xx need a minimal platform file
5  * ( avoid code duplication )
6  *
7  * 
8  * Maintainer : Sylvain Munaut <tnt@246tNt.com>
9  *
10  * Based on the 2.4 code written by Kent Borg,
11  * Dale Farnsworth <dale.farnsworth@mvista.com> and
12  * Wolfgang Denk <wd@denx.de>
13  * 
14  * Copyright 2004-2005 Sylvain Munaut <tnt@246tNt.com>
15  * Copyright 2003 Motorola Inc.
16  * Copyright 2003 MontaVista Software Inc.
17  * Copyright 2003 DENX Software Engineering (wd@denx.de)
18  *
19  * This file is licensed under the terms of the GNU General Public License
20  * version 2. This program is licensed "as is" without any warranty of any
21  * kind, whether express or implied.
22  */
23
24 #include <linux/config.h>
25 #include <linux/initrd.h>
26 #include <linux/seq_file.h>
27 #include <linux/kdev_t.h>
28 #include <linux/root_dev.h>
29 #include <linux/console.h>
30 #include <linux/module.h>
31
32 #include <asm/bootinfo.h>
33 #include <asm/io.h>
34 #include <asm/mpc52xx.h>
35 #include <asm/ppc_sys.h>
36 #include <asm/machdep.h>
37 #include <asm/pci-bridge.h>
38
39
40 extern int powersave_nap;
41
42 /* Board data given by U-Boot */
43 bd_t __res;
44 EXPORT_SYMBOL(__res);   /* For modules */
45
46
47 /* ======================================================================== */
48 /* Platform specific code                                                   */
49 /* ======================================================================== */
50
51 /* Supported PSC function in "preference" order */
52 struct mpc52xx_psc_func mpc52xx_psc_functions[] = {
53                 {       .id     = 0,
54                         .func   = "uart",
55                 },
56                 {       .id     = -1,   /* End entry */
57                         .func   = NULL,
58                 }
59         };
60
61
62 static int
63 lite5200_show_cpuinfo(struct seq_file *m)
64 {
65         seq_printf(m, "machine\t\t: Freescale LITE5200\n");
66         return 0;
67 }
68
69 #ifdef CONFIG_PCI
70 #ifdef CONFIG_LITE5200B
71 static int
72 lite5200_map_irq(struct pci_dev *dev, unsigned char idsel,
73                     unsigned char pin)
74 {
75         static char pci_irq_table[][4] =
76         /*
77          *      PCI IDSEL/INTPIN->INTLINE
78          *        A             B             C             D
79          */
80         {
81                 {MPC52xx_IRQ0, MPC52xx_IRQ1, MPC52xx_IRQ2, MPC52xx_IRQ3},
82                 {MPC52xx_IRQ1, MPC52xx_IRQ2, MPC52xx_IRQ3, MPC52xx_IRQ0},
83         };
84
85         const long min_idsel = 24, max_idsel = 25, irqs_per_slot = 4;
86         return PCI_IRQ_TABLE_LOOKUP;
87 }
88 #else /* Original Lite */
89 static int
90 lite5200_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
91 {
92         return (pin == 1) && (idsel==24) ? MPC52xx_IRQ0 : -1;
93 }
94 #endif
95 #endif
96
97 static void __init
98 lite5200_setup_cpu(void)
99 {
100         struct mpc52xx_gpio __iomem *gpio;
101         struct mpc52xx_intr __iomem *intr;
102
103         u32 port_config;
104         u32 intr_ctrl;
105
106         /* Map zones */
107         gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
108         intr = ioremap(MPC52xx_PA(MPC52xx_INTR_OFFSET), MPC52xx_INTR_SIZE);
109
110         if (!gpio || !intr) {
111                 printk(KERN_ERR __FILE__ ": "
112                         "Error while mapping GPIO/INTR during "
113                         "lite5200_setup_cpu\n");
114                 goto unmap_regs;
115         }
116
117         /* Get port mux config */
118         port_config = in_be32(&gpio->port_config);
119
120         /* 48Mhz internal, pin is GPIO */
121         port_config &= ~0x00800000;
122
123         /* USB port */
124         port_config &= ~0x00007000;     /* Differential mode - USB1 only */
125         port_config |=  0x00001000;
126
127         /* ATA CS is on csb_4/5 */
128         port_config &= ~0x03000000;
129         port_config |=  0x01000000;
130
131         /* Commit port config */
132         out_be32(&gpio->port_config, port_config);
133
134         /* IRQ[0-3] setup */
135         intr_ctrl = in_be32(&intr->ctrl);
136         intr_ctrl &= ~0x00ff0000;
137 #ifdef CONFIG_LITE5200B
138         /* IRQ[0-3] Level Active Low */
139         intr_ctrl |=  0x00ff0000;
140 #else
141         /* IRQ0 Level Active Low
142          * IRQ[1-3] Level Active High */
143         intr_ctrl |=  0x00c00000;
144 #endif
145         out_be32(&intr->ctrl, intr_ctrl);
146
147         /* Unmap reg zone */
148 unmap_regs:
149         if (gpio) iounmap(gpio);
150         if (intr) iounmap(intr);
151 }
152
153 static void __init
154 lite5200_setup_arch(void)
155 {
156         /* CPU & Port mux setup */
157         mpc52xx_setup_cpu();    /* Generic */
158         lite5200_setup_cpu();   /* Platform specific */
159
160 #ifdef CONFIG_PCI
161         /* PCI Bridge setup */
162         mpc52xx_find_bridges();
163 #endif
164 }
165
166 void __init
167 platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
168               unsigned long r6, unsigned long r7)
169 {
170         /* Generic MPC52xx platform initialization */
171         /* TODO Create one and move a max of stuff in it.
172            Put this init in the syslib */
173
174         struct bi_record *bootinfo = find_bootinfo();
175
176         if (bootinfo)
177                 parse_bootinfo(bootinfo);
178         else {
179                 /* Load the bd_t board info structure */
180                 if (r3)
181                         memcpy((void*)&__res,(void*)(r3+KERNELBASE),
182                                         sizeof(bd_t));
183
184 #ifdef CONFIG_BLK_DEV_INITRD
185                 /* Load the initrd */
186                 if (r4) {
187                         initrd_start = r4 + KERNELBASE;
188                         initrd_end = r5 + KERNELBASE;
189                 }
190 #endif
191
192                 /* Load the command line */
193                 if (r6) {
194                         *(char *)(r7+KERNELBASE) = 0;
195                         strcpy(cmd_line, (char *)(r6+KERNELBASE));
196                 }
197         }
198
199         /* PPC Sys identification */
200         identify_ppc_sys_by_id(mfspr(SPRN_SVR));
201
202         /* BAT setup */
203         mpc52xx_set_bat();
204
205         /* No ISA bus by default */
206 #ifdef CONFIG_PCI
207         isa_io_base             = 0;
208         isa_mem_base            = 0;
209 #endif
210
211         /* Powersave */
212         /* This is provided as an example on how to do it. But you
213            need to be aware that NAP disable bus snoop and that may
214            be required for some devices to work properly, like USB ... */
215         /* powersave_nap = 1; */
216
217
218         /* Setup the ppc_md struct */
219         ppc_md.setup_arch       = lite5200_setup_arch;
220         ppc_md.show_cpuinfo     = lite5200_show_cpuinfo;
221         ppc_md.show_percpuinfo  = NULL;
222         ppc_md.init_IRQ         = mpc52xx_init_irq;
223         ppc_md.get_irq          = mpc52xx_get_irq;
224
225 #ifdef CONFIG_PCI
226         ppc_md.pci_map_irq      = lite5200_map_irq;
227 #endif
228
229         ppc_md.find_end_of_memory = mpc52xx_find_end_of_memory;
230         ppc_md.setup_io_mappings  = mpc52xx_map_io;
231
232         ppc_md.restart          = mpc52xx_restart;
233         ppc_md.power_off        = mpc52xx_power_off;
234         ppc_md.halt             = mpc52xx_halt;
235
236                 /* No time keeper on the LITE5200 */
237         ppc_md.time_init        = NULL;
238         ppc_md.get_rtc_time     = NULL;
239         ppc_md.set_rtc_time     = NULL;
240
241         ppc_md.calibrate_decr   = mpc52xx_calibrate_decr;
242 #ifdef CONFIG_SERIAL_TEXT_DEBUG
243         ppc_md.progress         = mpc52xx_progress;
244 #endif
245 }
246