Merge tag 'r8169-20060920-00' of git://electric-eye.fr.zoreil.com/home/romieu/linux...
[pandora-kernel.git] / arch / arm / mach-s3c2410 / mach-vr1000.c
1 /* linux/arch/arm/mach-s3c2410/mach-vr1000.c
2  *
3  * Copyright (c) 2003-2005 Simtec Electronics
4  *   Ben Dooks <ben@simtec.co.uk>
5  *
6  * Machine support for Thorcom VR1000 board. Designed for Thorcom by
7  * Simtec Electronics, http://www.simtec.co.uk/
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  *
13 */
14
15 #include <linux/kernel.h>
16 #include <linux/types.h>
17 #include <linux/interrupt.h>
18 #include <linux/list.h>
19 #include <linux/timer.h>
20 #include <linux/init.h>
21 #include <linux/dm9000.h>
22
23 #include <linux/serial.h>
24 #include <linux/tty.h>
25 #include <linux/serial_8250.h>
26 #include <linux/serial_reg.h>
27
28 #include <asm/mach/arch.h>
29 #include <asm/mach/map.h>
30 #include <asm/mach/irq.h>
31
32 #include <asm/arch/bast-map.h>
33 #include <asm/arch/vr1000-map.h>
34 #include <asm/arch/vr1000-irq.h>
35 #include <asm/arch/vr1000-cpld.h>
36
37 #include <asm/hardware.h>
38 #include <asm/io.h>
39 #include <asm/irq.h>
40 #include <asm/mach-types.h>
41
42 #include <asm/arch/regs-serial.h>
43 #include <asm/arch/regs-gpio.h>
44
45 #include "clock.h"
46 #include "devs.h"
47 #include "cpu.h"
48 #include "usb-simtec.h"
49
50 /* macros for virtual address mods for the io space entries */
51 #define VA_C5(item) ((unsigned long)(item) + BAST_VAM_CS5)
52 #define VA_C4(item) ((unsigned long)(item) + BAST_VAM_CS4)
53 #define VA_C3(item) ((unsigned long)(item) + BAST_VAM_CS3)
54 #define VA_C2(item) ((unsigned long)(item) + BAST_VAM_CS2)
55
56 /* macros to modify the physical addresses for io space */
57
58 #define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2))
59 #define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3))
60 #define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4))
61 #define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5))
62
63 static struct map_desc vr1000_iodesc[] __initdata = {
64   /* ISA IO areas */
65   {
66           .virtual      = (u32)S3C24XX_VA_ISA_BYTE,
67           .pfn          = PA_CS2(BAST_PA_ISAIO),
68           .length       = SZ_16M,
69           .type         = MT_DEVICE,
70   }, {
71           .virtual      = (u32)S3C24XX_VA_ISA_WORD,
72           .pfn          = PA_CS3(BAST_PA_ISAIO),
73           .length       = SZ_16M,
74           .type         = MT_DEVICE,
75   },
76
77   /*  CPLD control registers, and external interrupt controls */
78   {
79           .virtual      = (u32)VR1000_VA_CTRL1,
80           .pfn          = __phys_to_pfn(VR1000_PA_CTRL1),
81           .length       = SZ_1M,
82           .type         = MT_DEVICE,
83   }, {
84           .virtual      = (u32)VR1000_VA_CTRL2,
85           .pfn          = __phys_to_pfn(VR1000_PA_CTRL2),
86           .length       = SZ_1M,
87           .type         = MT_DEVICE,
88   }, {
89           .virtual      = (u32)VR1000_VA_CTRL3,
90           .pfn          = __phys_to_pfn(VR1000_PA_CTRL3),
91           .length       = SZ_1M,
92           .type         = MT_DEVICE,
93   }, {
94           .virtual      = (u32)VR1000_VA_CTRL4,
95           .pfn          = __phys_to_pfn(VR1000_PA_CTRL4),
96           .length       = SZ_1M,
97           .type         = MT_DEVICE,
98   },
99
100   /* peripheral space... one for each of fast/slow/byte/16bit */
101   /* note, ide is only decoded in word space, even though some registers
102    * are only 8bit */
103
104   /* slow, byte */
105   { VA_C2(VR1000_VA_IDEPRI),  PA_CS3(VR1000_PA_IDEPRI),   SZ_1M,  MT_DEVICE },
106   { VA_C2(VR1000_VA_IDESEC),  PA_CS3(VR1000_PA_IDESEC),   SZ_1M,  MT_DEVICE },
107   { VA_C2(VR1000_VA_IDEPRIAUX), PA_CS3(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
108   { VA_C2(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
109
110   /* slow, word */
111   { VA_C3(VR1000_VA_IDEPRI),  PA_CS3(VR1000_PA_IDEPRI),   SZ_1M,  MT_DEVICE },
112   { VA_C3(VR1000_VA_IDESEC),  PA_CS3(VR1000_PA_IDESEC),   SZ_1M,  MT_DEVICE },
113   { VA_C3(VR1000_VA_IDEPRIAUX), PA_CS3(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
114   { VA_C3(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
115
116   /* fast, byte */
117   { VA_C4(VR1000_VA_IDEPRI),  PA_CS5(VR1000_PA_IDEPRI),   SZ_1M,  MT_DEVICE },
118   { VA_C4(VR1000_VA_IDESEC),  PA_CS5(VR1000_PA_IDESEC),   SZ_1M,  MT_DEVICE },
119   { VA_C4(VR1000_VA_IDEPRIAUX), PA_CS5(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
120   { VA_C4(VR1000_VA_IDESECAUX), PA_CS5(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
121
122   /* fast, word */
123   { VA_C5(VR1000_VA_IDEPRI),  PA_CS5(VR1000_PA_IDEPRI),   SZ_1M,  MT_DEVICE },
124   { VA_C5(VR1000_VA_IDESEC),  PA_CS5(VR1000_PA_IDESEC),   SZ_1M,  MT_DEVICE },
125   { VA_C5(VR1000_VA_IDEPRIAUX), PA_CS5(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
126   { VA_C5(VR1000_VA_IDESECAUX), PA_CS5(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
127 };
128
129 #define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
130 #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
131 #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
132
133 /* uart clock source(s) */
134
135 static struct s3c24xx_uart_clksrc vr1000_serial_clocks[] = {
136         [0] = {
137                 .name           = "uclk",
138                 .divisor        = 1,
139                 .min_baud       = 0,
140                 .max_baud       = 0,
141         },
142         [1] = {
143                 .name           = "pclk",
144                 .divisor        = 1,
145                 .min_baud       = 0,
146                 .max_baud       = 0.
147         }
148 };
149
150 static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
151         [0] = {
152                 .hwport      = 0,
153                 .flags       = 0,
154                 .ucon        = UCON,
155                 .ulcon       = ULCON,
156                 .ufcon       = UFCON,
157                 .clocks      = vr1000_serial_clocks,
158                 .clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
159         },
160         [1] = {
161                 .hwport      = 1,
162                 .flags       = 0,
163                 .ucon        = UCON,
164                 .ulcon       = ULCON,
165                 .ufcon       = UFCON,
166                 .clocks      = vr1000_serial_clocks,
167                 .clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
168         },
169         /* port 2 is not actually used */
170         [2] = {
171                 .hwport      = 2,
172                 .flags       = 0,
173                 .ucon        = UCON,
174                 .ulcon       = ULCON,
175                 .ufcon       = UFCON,
176                 .clocks      = vr1000_serial_clocks,
177                 .clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
178
179         }
180 };
181
182 /* definitions for the vr1000 extra 16550 serial ports */
183
184 #define VR1000_BAUDBASE (3692307)
185
186 #define VR1000_SERIAL_MAPBASE(x) (VR1000_PA_SERIAL + 0x80 + ((x) << 5))
187
188 static struct plat_serial8250_port serial_platform_data[] = {
189         [0] = {
190                 .mapbase        = VR1000_SERIAL_MAPBASE(0),
191                 .irq            = IRQ_VR1000_SERIAL + 0,
192                 .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
193                 .iotype         = UPIO_MEM,
194                 .regshift       = 0,
195                 .uartclk        = VR1000_BAUDBASE,
196         },
197         [1] = {
198                 .mapbase        = VR1000_SERIAL_MAPBASE(1),
199                 .irq            = IRQ_VR1000_SERIAL + 1,
200                 .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
201                 .iotype         = UPIO_MEM,
202                 .regshift       = 0,
203                 .uartclk        = VR1000_BAUDBASE,
204         },
205         [2] = {
206                 .mapbase        = VR1000_SERIAL_MAPBASE(2),
207                 .irq            = IRQ_VR1000_SERIAL + 2,
208                 .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
209                 .iotype         = UPIO_MEM,
210                 .regshift       = 0,
211                 .uartclk        = VR1000_BAUDBASE,
212         },
213         [3] = {
214                 .mapbase        = VR1000_SERIAL_MAPBASE(3),
215                 .irq            = IRQ_VR1000_SERIAL + 3,
216                 .flags          = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
217                 .iotype         = UPIO_MEM,
218                 .regshift       = 0,
219                 .uartclk        = VR1000_BAUDBASE,
220         },
221         { },
222 };
223
224 static struct platform_device serial_device = {
225         .name                   = "serial8250",
226         .id                     = PLAT8250_DEV_PLATFORM,
227         .dev                    = {
228                 .platform_data  = serial_platform_data,
229         },
230 };
231
232 /* MTD NOR Flash */
233
234 static struct resource vr1000_nor_resource[] = {
235         [0] = {
236                 .start  = S3C2410_CS1 + 0x4000000,
237                 .end    = S3C2410_CS1 + 0x4000000 + SZ_16M - 1,
238                 .flags  = IORESOURCE_MEM,
239         }
240 };
241
242 static struct platform_device vr1000_nor = {
243         .name           = "bast-nor",
244         .id             = -1,
245         .num_resources  = ARRAY_SIZE(vr1000_nor_resource),
246         .resource       = vr1000_nor_resource,
247 };
248
249 /* DM9000 ethernet devices */
250
251 static struct resource vr1000_dm9k0_resource[] = {
252         [0] = {
253                 .start = S3C2410_CS5 + VR1000_PA_DM9000,
254                 .end   = S3C2410_CS5 + VR1000_PA_DM9000 + 3,
255                 .flags = IORESOURCE_MEM
256         },
257         [1] = {
258                 .start = S3C2410_CS5 + VR1000_PA_DM9000 + 0x40,
259                 .end   = S3C2410_CS5 + VR1000_PA_DM9000 + 0x7f,
260                 .flags = IORESOURCE_MEM
261         },
262         [2] = {
263                 .start = IRQ_VR1000_DM9000A,
264                 .end   = IRQ_VR1000_DM9000A,
265                 .flags = IORESOURCE_IRQ
266         }
267
268 };
269
270 static struct resource vr1000_dm9k1_resource[] = {
271         [0] = {
272                 .start = S3C2410_CS5 + VR1000_PA_DM9000 + 0x80,
273                 .end   = S3C2410_CS5 + VR1000_PA_DM9000 + 0x83,
274                 .flags = IORESOURCE_MEM
275         },
276         [1] = {
277                 .start = S3C2410_CS5 + VR1000_PA_DM9000 + 0xC0,
278                 .end   = S3C2410_CS5 + VR1000_PA_DM9000 + 0xFF,
279                 .flags = IORESOURCE_MEM
280         },
281         [2] = {
282                 .start = IRQ_VR1000_DM9000N,
283                 .end   = IRQ_VR1000_DM9000N,
284                 .flags = IORESOURCE_IRQ
285         }
286 };
287
288 /* for the moment we limit ourselves to 16bit IO until some
289  * better IO routines can be written and tested
290 */
291
292 static struct dm9000_plat_data vr1000_dm9k_platdata = {
293         .flags          = DM9000_PLATF_16BITONLY,
294 };
295
296 static struct platform_device vr1000_dm9k0 = {
297         .name           = "dm9000",
298         .id             = 0,
299         .num_resources  = ARRAY_SIZE(vr1000_dm9k0_resource),
300         .resource       = vr1000_dm9k0_resource,
301         .dev            = {
302                 .platform_data = &vr1000_dm9k_platdata,
303         }
304 };
305
306 static struct platform_device vr1000_dm9k1 = {
307         .name           = "dm9000",
308         .id             = 1,
309         .num_resources  = ARRAY_SIZE(vr1000_dm9k1_resource),
310         .resource       = vr1000_dm9k1_resource,
311         .dev            = {
312                 .platform_data = &vr1000_dm9k_platdata,
313         }
314 };
315
316 /* devices for this board */
317
318 static struct platform_device *vr1000_devices[] __initdata = {
319         &s3c_device_usb,
320         &s3c_device_lcd,
321         &s3c_device_wdt,
322         &s3c_device_i2c,
323         &s3c_device_iis,
324         &s3c_device_adc,
325         &serial_device,
326         &vr1000_nor,
327         &vr1000_dm9k0,
328         &vr1000_dm9k1
329 };
330
331 static struct clk *vr1000_clocks[] = {
332         &s3c24xx_dclk0,
333         &s3c24xx_dclk1,
334         &s3c24xx_clkout0,
335         &s3c24xx_clkout1,
336         &s3c24xx_uclk,
337 };
338
339 static struct s3c24xx_board vr1000_board __initdata = {
340         .devices       = vr1000_devices,
341         .devices_count = ARRAY_SIZE(vr1000_devices),
342         .clocks        = vr1000_clocks,
343         .clocks_count  = ARRAY_SIZE(vr1000_clocks),
344 };
345
346 static void vr1000_power_off(void)
347 {
348         s3c2410_gpio_cfgpin(S3C2410_GPB9, S3C2410_GPB9_OUTP);
349         s3c2410_gpio_setpin(S3C2410_GPB9, 1);
350 }
351
352 static void __init vr1000_map_io(void)
353 {
354         /* initialise clock sources */
355
356         s3c24xx_dclk0.parent = NULL;
357         s3c24xx_dclk0.rate   = 12*1000*1000;
358
359         s3c24xx_dclk1.parent = NULL;
360         s3c24xx_dclk1.rate   = 3692307;
361
362         s3c24xx_clkout0.parent  = &s3c24xx_dclk0;
363         s3c24xx_clkout1.parent  = &s3c24xx_dclk1;
364
365         s3c24xx_uclk.parent  = &s3c24xx_clkout1;
366
367         pm_power_off = vr1000_power_off;
368
369         s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
370         s3c24xx_init_clocks(0);
371         s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
372         s3c24xx_set_board(&vr1000_board);
373         usb_simtec_init();
374 }
375
376
377 MACHINE_START(VR1000, "Thorcom-VR1000")
378         /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
379         .phys_io        = S3C2410_PA_UART,
380         .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
381         .boot_params    = S3C2410_SDRAM_PA + 0x100,
382         .map_io         = vr1000_map_io,
383         .init_irq       = s3c24xx_init_irq,
384         .timer          = &s3c24xx_timer,
385 MACHINE_END