• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/arch/arm/mach-s3c2410/
1/* linux/arch/arm/mach-s3c2410/mach-vr1000.c
2 *
3 * Copyright (c) 2003-2008 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/gpio.h>
22#include <linux/dm9000.h>
23#include <linux/i2c.h>
24
25#include <linux/serial.h>
26#include <linux/tty.h>
27#include <linux/serial_8250.h>
28#include <linux/serial_reg.h>
29#include <linux/io.h>
30
31#include <asm/mach/arch.h>
32#include <asm/mach/map.h>
33#include <asm/mach/irq.h>
34
35#include <mach/bast-map.h>
36#include <mach/vr1000-map.h>
37#include <mach/vr1000-irq.h>
38#include <mach/vr1000-cpld.h>
39
40#include <mach/hardware.h>
41#include <asm/irq.h>
42#include <asm/mach-types.h>
43
44#include <plat/regs-serial.h>
45#include <mach/regs-gpio.h>
46#include <mach/leds-gpio.h>
47
48#include <plat/clock.h>
49#include <plat/devs.h>
50#include <plat/cpu.h>
51#include <plat/iic.h>
52#include <plat/audio-simtec.h>
53
54#include "usb-simtec.h"
55#include "nor-simtec.h"
56
57/* macros for virtual address mods for the io space entries */
58#define VA_C5(item) ((unsigned long)(item) + BAST_VAM_CS5)
59#define VA_C4(item) ((unsigned long)(item) + BAST_VAM_CS4)
60#define VA_C3(item) ((unsigned long)(item) + BAST_VAM_CS3)
61#define VA_C2(item) ((unsigned long)(item) + BAST_VAM_CS2)
62
63/* macros to modify the physical addresses for io space */
64
65#define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2))
66#define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3))
67#define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4))
68#define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5))
69
70static struct map_desc vr1000_iodesc[] __initdata = {
71  /* ISA IO areas */
72  {
73	  .virtual	= (u32)S3C24XX_VA_ISA_BYTE,
74	  .pfn		= PA_CS2(BAST_PA_ISAIO),
75	  .length	= SZ_16M,
76	  .type		= MT_DEVICE,
77  }, {
78	  .virtual	= (u32)S3C24XX_VA_ISA_WORD,
79	  .pfn		= PA_CS3(BAST_PA_ISAIO),
80	  .length	= SZ_16M,
81	  .type		= MT_DEVICE,
82  },
83
84  /*  CPLD control registers, and external interrupt controls */
85  {
86	  .virtual	= (u32)VR1000_VA_CTRL1,
87	  .pfn		= __phys_to_pfn(VR1000_PA_CTRL1),
88	  .length	= SZ_1M,
89	  .type		= MT_DEVICE,
90  }, {
91	  .virtual	= (u32)VR1000_VA_CTRL2,
92	  .pfn		= __phys_to_pfn(VR1000_PA_CTRL2),
93	  .length	= SZ_1M,
94	  .type		= MT_DEVICE,
95  }, {
96	  .virtual	= (u32)VR1000_VA_CTRL3,
97	  .pfn		= __phys_to_pfn(VR1000_PA_CTRL3),
98	  .length	= SZ_1M,
99	  .type		= MT_DEVICE,
100  }, {
101	  .virtual	= (u32)VR1000_VA_CTRL4,
102	  .pfn		= __phys_to_pfn(VR1000_PA_CTRL4),
103	  .length	= SZ_1M,
104	  .type		= MT_DEVICE,
105  },
106};
107
108#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
109#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
110#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
111
112/* uart clock source(s) */
113
114static struct s3c24xx_uart_clksrc vr1000_serial_clocks[] = {
115	[0] = {
116		.name		= "uclk",
117		.divisor	= 1,
118		.min_baud	= 0,
119		.max_baud	= 0,
120	},
121	[1] = {
122		.name		= "pclk",
123		.divisor	= 1,
124		.min_baud	= 0,
125		.max_baud	= 0.
126	}
127};
128
129static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
130	[0] = {
131		.hwport	     = 0,
132		.flags	     = 0,
133		.ucon	     = UCON,
134		.ulcon	     = ULCON,
135		.ufcon	     = UFCON,
136		.clocks	     = vr1000_serial_clocks,
137		.clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
138	},
139	[1] = {
140		.hwport	     = 1,
141		.flags	     = 0,
142		.ucon	     = UCON,
143		.ulcon	     = ULCON,
144		.ufcon	     = UFCON,
145		.clocks	     = vr1000_serial_clocks,
146		.clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
147	},
148	/* port 2 is not actually used */
149	[2] = {
150		.hwport	     = 2,
151		.flags	     = 0,
152		.ucon	     = UCON,
153		.ulcon	     = ULCON,
154		.ufcon	     = UFCON,
155		.clocks	     = vr1000_serial_clocks,
156		.clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
157
158	}
159};
160
161/* definitions for the vr1000 extra 16550 serial ports */
162
163#define VR1000_BAUDBASE (3692307)
164
165#define VR1000_SERIAL_MAPBASE(x) (VR1000_PA_SERIAL + 0x80 + ((x) << 5))
166
167static struct plat_serial8250_port serial_platform_data[] = {
168	[0] = {
169		.mapbase	= VR1000_SERIAL_MAPBASE(0),
170		.irq		= IRQ_VR1000_SERIAL + 0,
171		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
172		.iotype		= UPIO_MEM,
173		.regshift	= 0,
174		.uartclk	= VR1000_BAUDBASE,
175	},
176	[1] = {
177		.mapbase	= VR1000_SERIAL_MAPBASE(1),
178		.irq		= IRQ_VR1000_SERIAL + 1,
179		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
180		.iotype		= UPIO_MEM,
181		.regshift	= 0,
182		.uartclk	= VR1000_BAUDBASE,
183	},
184	[2] = {
185		.mapbase	= VR1000_SERIAL_MAPBASE(2),
186		.irq		= IRQ_VR1000_SERIAL + 2,
187		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
188		.iotype		= UPIO_MEM,
189		.regshift	= 0,
190		.uartclk	= VR1000_BAUDBASE,
191	},
192	[3] = {
193		.mapbase	= VR1000_SERIAL_MAPBASE(3),
194		.irq		= IRQ_VR1000_SERIAL + 3,
195		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
196		.iotype		= UPIO_MEM,
197		.regshift	= 0,
198		.uartclk	= VR1000_BAUDBASE,
199	},
200	{ },
201};
202
203static struct platform_device serial_device = {
204	.name			= "serial8250",
205	.id			= PLAT8250_DEV_PLATFORM,
206	.dev			= {
207		.platform_data	= serial_platform_data,
208	},
209};
210
211/* DM9000 ethernet devices */
212
213static struct resource vr1000_dm9k0_resource[] = {
214	[0] = {
215		.start = S3C2410_CS5 + VR1000_PA_DM9000,
216		.end   = S3C2410_CS5 + VR1000_PA_DM9000 + 3,
217		.flags = IORESOURCE_MEM
218	},
219	[1] = {
220		.start = S3C2410_CS5 + VR1000_PA_DM9000 + 0x40,
221		.end   = S3C2410_CS5 + VR1000_PA_DM9000 + 0x7f,
222		.flags = IORESOURCE_MEM
223	},
224	[2] = {
225		.start = IRQ_VR1000_DM9000A,
226		.end   = IRQ_VR1000_DM9000A,
227		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
228	}
229
230};
231
232static struct resource vr1000_dm9k1_resource[] = {
233	[0] = {
234		.start = S3C2410_CS5 + VR1000_PA_DM9000 + 0x80,
235		.end   = S3C2410_CS5 + VR1000_PA_DM9000 + 0x83,
236		.flags = IORESOURCE_MEM
237	},
238	[1] = {
239		.start = S3C2410_CS5 + VR1000_PA_DM9000 + 0xC0,
240		.end   = S3C2410_CS5 + VR1000_PA_DM9000 + 0xFF,
241		.flags = IORESOURCE_MEM
242	},
243	[2] = {
244		.start = IRQ_VR1000_DM9000N,
245		.end   = IRQ_VR1000_DM9000N,
246		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
247	}
248};
249
250/* for the moment we limit ourselves to 16bit IO until some
251 * better IO routines can be written and tested
252*/
253
254static struct dm9000_plat_data vr1000_dm9k_platdata = {
255	.flags		= DM9000_PLATF_16BITONLY,
256};
257
258static struct platform_device vr1000_dm9k0 = {
259	.name		= "dm9000",
260	.id		= 0,
261	.num_resources	= ARRAY_SIZE(vr1000_dm9k0_resource),
262	.resource	= vr1000_dm9k0_resource,
263	.dev		= {
264		.platform_data = &vr1000_dm9k_platdata,
265	}
266};
267
268static struct platform_device vr1000_dm9k1 = {
269	.name		= "dm9000",
270	.id		= 1,
271	.num_resources	= ARRAY_SIZE(vr1000_dm9k1_resource),
272	.resource	= vr1000_dm9k1_resource,
273	.dev		= {
274		.platform_data = &vr1000_dm9k_platdata,
275	}
276};
277
278/* LEDS */
279
280static struct s3c24xx_led_platdata vr1000_led1_pdata = {
281	.name		= "led1",
282	.gpio		= S3C2410_GPB(0),
283	.def_trigger	= "",
284};
285
286static struct s3c24xx_led_platdata vr1000_led2_pdata = {
287	.name		= "led2",
288	.gpio		= S3C2410_GPB(1),
289	.def_trigger	= "",
290};
291
292static struct s3c24xx_led_platdata vr1000_led3_pdata = {
293	.name		= "led3",
294	.gpio		= S3C2410_GPB(2),
295	.def_trigger	= "",
296};
297
298static struct platform_device vr1000_led1 = {
299	.name		= "s3c24xx_led",
300	.id		= 1,
301	.dev		= {
302		.platform_data	= &vr1000_led1_pdata,
303	},
304};
305
306static struct platform_device vr1000_led2 = {
307	.name		= "s3c24xx_led",
308	.id		= 2,
309	.dev		= {
310		.platform_data	= &vr1000_led2_pdata,
311	},
312};
313
314static struct platform_device vr1000_led3 = {
315	.name		= "s3c24xx_led",
316	.id		= 3,
317	.dev		= {
318		.platform_data	= &vr1000_led3_pdata,
319	},
320};
321
322/* I2C devices. */
323
324static struct i2c_board_info vr1000_i2c_devs[] __initdata = {
325	{
326		I2C_BOARD_INFO("tlv320aic23", 0x1a),
327	}, {
328		I2C_BOARD_INFO("tmp101", 0x48),
329	}, {
330		I2C_BOARD_INFO("m41st87", 0x68),
331	},
332};
333
334/* devices for this board */
335
336static struct platform_device *vr1000_devices[] __initdata = {
337	&s3c_device_ohci,
338	&s3c_device_lcd,
339	&s3c_device_wdt,
340	&s3c_device_i2c0,
341	&s3c_device_adc,
342	&serial_device,
343	&vr1000_dm9k0,
344	&vr1000_dm9k1,
345	&vr1000_led1,
346	&vr1000_led2,
347	&vr1000_led3,
348};
349
350static struct clk *vr1000_clocks[] __initdata = {
351	&s3c24xx_dclk0,
352	&s3c24xx_dclk1,
353	&s3c24xx_clkout0,
354	&s3c24xx_clkout1,
355	&s3c24xx_uclk,
356};
357
358static void vr1000_power_off(void)
359{
360	gpio_direction_output(S3C2410_GPB(9), 1);
361}
362
363static void __init vr1000_map_io(void)
364{
365	/* initialise clock sources */
366
367	s3c24xx_dclk0.parent = &clk_upll;
368	s3c24xx_dclk0.rate   = 12*1000*1000;
369
370	s3c24xx_dclk1.parent = NULL;
371	s3c24xx_dclk1.rate   = 3692307;
372
373	s3c24xx_clkout0.parent  = &s3c24xx_dclk0;
374	s3c24xx_clkout1.parent  = &s3c24xx_dclk1;
375
376	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
377
378	s3c24xx_register_clocks(vr1000_clocks, ARRAY_SIZE(vr1000_clocks));
379
380	pm_power_off = vr1000_power_off;
381
382	s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
383	s3c24xx_init_clocks(0);
384	s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
385}
386
387static void __init vr1000_init(void)
388{
389	s3c_i2c0_set_platdata(NULL);
390	platform_add_devices(vr1000_devices, ARRAY_SIZE(vr1000_devices));
391
392	i2c_register_board_info(0, vr1000_i2c_devs,
393				ARRAY_SIZE(vr1000_i2c_devs));
394
395	nor_simtec_init();
396	simtec_audio_add(NULL, true, NULL);
397
398	WARN_ON(gpio_request(S3C2410_GPB(9), "power off"));
399}
400
401MACHINE_START(VR1000, "Thorcom-VR1000")
402	/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
403	.phys_io	= S3C2410_PA_UART,
404	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
405	.boot_params	= S3C2410_SDRAM_PA + 0x100,
406	.map_io		= vr1000_map_io,
407	.init_machine	= vr1000_init,
408	.init_irq	= s3c24xx_init_irq,
409	.timer		= &s3c24xx_timer,
410MACHINE_END
411