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