Pull bugzilla-5737 into release branch
[linux-2.6] / arch / ppc / platforms / 4xx / xilinx_ml403.c
1 /*
2  * arch/ppc/platforms/4xx/xilinx_ml403.c
3  *
4  * Xilinx ML403 evaluation board initialization
5  *
6  * Author: Grant Likely <grant.likely@secretlab.ca>
7  *
8  * 2005 (c) Secret Lab Technologies Ltd.
9  * 2002-2004 (c) MontaVista Software, Inc.
10  *
11  * This file is licensed under the terms of the GNU General Public License
12  * version 2.  This program is licensed "as is" without any warranty of any
13  * kind, whether express or implied.
14  */
15
16 #include <linux/config.h>
17 #include <linux/init.h>
18 #include <linux/irq.h>
19 #include <linux/tty.h>
20 #include <linux/serial.h>
21 #include <linux/serial_core.h>
22 #include <linux/serial_8250.h>
23 #include <linux/serialP.h>
24 #include <asm/io.h>
25 #include <asm/machdep.h>
26 #include <asm/ppc_sys.h>
27
28 #include <syslib/gen550.h>
29 #include <platforms/4xx/xparameters/xparameters.h>
30
31 /*
32  * As an overview of how the following functions (platform_init,
33  * ml403_map_io, ml403_setup_arch and ml403_init_IRQ) fit into the
34  * kernel startup procedure, here's a call tree:
35  *
36  * start_here                                   arch/ppc/kernel/head_4xx.S
37  *  early_init                                  arch/ppc/kernel/setup.c
38  *  machine_init                                arch/ppc/kernel/setup.c
39  *    platform_init                             this file
40  *      ppc4xx_init                             arch/ppc/syslib/ppc4xx_setup.c
41  *        parse_bootinfo
42  *          find_bootinfo
43  *        "setup some default ppc_md pointers"
44  *  MMU_init                                    arch/ppc/mm/init.c
45  *    *ppc_md.setup_io_mappings == ml403_map_io this file
46  *      ppc4xx_map_io                           arch/ppc/syslib/ppc4xx_setup.c
47  *  start_kernel                                init/main.c
48  *    setup_arch                                arch/ppc/kernel/setup.c
49  * #if defined(CONFIG_KGDB)
50  *      *ppc_md.kgdb_map_scc() == gen550_kgdb_map_scc
51  * #endif
52  *      *ppc_md.setup_arch == ml403_setup_arch  this file
53  *        ppc4xx_setup_arch                     arch/ppc/syslib/ppc4xx_setup.c
54  *          ppc4xx_find_bridges                 arch/ppc/syslib/ppc405_pci.c
55  *    init_IRQ                                  arch/ppc/kernel/irq.c
56  *      *ppc_md.init_IRQ == ml403_init_IRQ      this file
57  *        ppc4xx_init_IRQ                       arch/ppc/syslib/ppc4xx_setup.c
58  *          ppc4xx_pic_init                     arch/ppc/syslib/xilinx_pic.c
59  */
60
61 /* Board specifications structures */
62 struct ppc_sys_spec *cur_ppc_sys_spec;
63 struct ppc_sys_spec ppc_sys_specs[] = {
64         {
65                 /* Only one entry, always assume the same design */
66                 .ppc_sys_name   = "Xilinx ML403 Reference Design",
67                 .mask           = 0x00000000,
68                 .value          = 0x00000000,
69                 .num_devices    = 1,
70                 .device_list    = (enum ppc_sys_devices[])
71                 {
72                         VIRTEX_UART,
73                 },
74         },
75 };
76
77 #if defined(XPAR_POWER_0_POWERDOWN_BASEADDR)
78
79 static volatile unsigned *powerdown_base =
80     (volatile unsigned *) XPAR_POWER_0_POWERDOWN_BASEADDR;
81
82 static void
83 xilinx_power_off(void)
84 {
85         local_irq_disable();
86         out_be32(powerdown_base, XPAR_POWER_0_POWERDOWN_VALUE);
87         while (1) ;
88 }
89 #endif
90
91 void __init
92 ml403_map_io(void)
93 {
94         ppc4xx_map_io();
95
96 #if defined(XPAR_POWER_0_POWERDOWN_BASEADDR)
97         powerdown_base = ioremap((unsigned long) powerdown_base,
98                                  XPAR_POWER_0_POWERDOWN_HIGHADDR -
99                                  XPAR_POWER_0_POWERDOWN_BASEADDR + 1);
100 #endif
101 }
102
103 /* Early serial support functions */
104 static void __init
105 ml403_early_serial_init(int num, struct plat_serial8250_port *pdata)
106 {
107 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
108         struct uart_port serial_req;
109
110         memset(&serial_req, 0, sizeof(serial_req));
111         serial_req.mapbase      = pdata->mapbase;
112         serial_req.membase      = pdata->membase;
113         serial_req.irq          = pdata->irq;
114         serial_req.uartclk      = pdata->uartclk;
115         serial_req.regshift     = pdata->regshift;
116         serial_req.iotype       = pdata->iotype;
117         serial_req.flags        = pdata->flags;
118         gen550_init(num, &serial_req);
119 #endif
120 }
121
122 void __init
123 ml403_early_serial_map(void)
124 {
125 #ifdef CONFIG_SERIAL_8250
126         struct plat_serial8250_port *pdata;
127         int i = 0;
128
129         pdata = (struct plat_serial8250_port *) ppc_sys_get_pdata(VIRTEX_UART);
130         while(pdata && pdata->flags)
131         {
132                 pdata->membase = ioremap(pdata->mapbase, 0x100);
133                 ml403_early_serial_init(i, pdata);
134                 pdata++;
135                 i++;
136         }
137 #endif /* CONFIG_SERIAL_8250 */
138 }
139
140 void __init
141 ml403_setup_arch(void)
142 {
143         ml403_early_serial_map();
144         ppc4xx_setup_arch();    /* calls ppc4xx_find_bridges() */
145
146         /* Identify the system */
147         printk(KERN_INFO "Xilinx ML403 Reference System (Virtex-4 FX)\n");
148 }
149
150 /* Called after board_setup_irq from ppc4xx_init_IRQ(). */
151 void __init
152 ml403_init_irq(void)
153 {
154         ppc4xx_init_IRQ();
155 }
156
157 void __init
158 platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
159               unsigned long r6, unsigned long r7)
160 {
161         ppc4xx_init(r3, r4, r5, r6, r7);
162
163         identify_ppc_sys_by_id(mfspr(SPRN_PVR));
164
165         ppc_md.setup_arch = ml403_setup_arch;
166         ppc_md.setup_io_mappings = ml403_map_io;
167         ppc_md.init_IRQ = ml403_init_irq;
168
169 #if defined(XPAR_POWER_0_POWERDOWN_BASEADDR)
170         ppc_md.power_off = xilinx_power_off;
171 #endif
172
173 #ifdef CONFIG_KGDB
174         ppc_md.early_serial_map = ml403_early_serial_map;
175 #endif
176 }
177