Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mach-real6410.c
Go to the documentation of this file.
1 /* linux/arch/arm/mach-s3c64xx/mach-real6410.c
2  *
3  * Copyright 2010 Darius Augulis <[email protected]>
4  * Copyright 2008 Openmoko, Inc.
5  * Copyright 2008 Simtec Electronics
6  * Ben Dooks <[email protected]>
7  * http://armlinux.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/init.h>
16 #include <linux/interrupt.h>
17 #include <linux/fb.h>
18 #include <linux/gpio.h>
19 #include <linux/kernel.h>
20 #include <linux/list.h>
21 #include <linux/dm9000.h>
22 #include <linux/mtd/mtd.h>
23 #include <linux/mtd/partitions.h>
24 #include <linux/platform_device.h>
25 #include <linux/serial_core.h>
26 #include <linux/types.h>
27 
28 #include <asm/hardware/vic.h>
29 #include <asm/mach-types.h>
30 #include <asm/mach/arch.h>
31 #include <asm/mach/map.h>
32 
33 #include <mach/map.h>
34 #include <mach/regs-gpio.h>
35 #include <mach/regs-modem.h>
36 #include <mach/regs-srom.h>
37 
38 #include <plat/adc.h>
39 #include <plat/cpu.h>
40 #include <plat/devs.h>
41 #include <plat/fb.h>
43 #include <plat/regs-serial.h>
45 
46 #include <video/platform_lcd.h>
47 #include <video/samsung_fimd.h>
48 
49 #include "common.h"
50 
51 #define UCON S3C2410_UCON_DEFAULT
52 #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
53 #define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
54 
55 static struct s3c2410_uartcfg real6410_uartcfgs[] __initdata = {
56  [0] = {
57  .hwport = 0,
58  .flags = 0,
59  .ucon = UCON,
60  .ulcon = ULCON,
61  .ufcon = UFCON,
62  },
63  [1] = {
64  .hwport = 1,
65  .flags = 0,
66  .ucon = UCON,
67  .ulcon = ULCON,
68  .ufcon = UFCON,
69  },
70  [2] = {
71  .hwport = 2,
72  .flags = 0,
73  .ucon = UCON,
74  .ulcon = ULCON,
75  .ufcon = UFCON,
76  },
77  [3] = {
78  .hwport = 3,
79  .flags = 0,
80  .ucon = UCON,
81  .ulcon = ULCON,
82  .ufcon = UFCON,
83  },
84 };
85 
86 /* DM9000AEP 10/100 ethernet controller */
87 
88 static struct resource real6410_dm9k_resource[] = {
90  [1] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN1 + 4, 2),
93 };
94 
95 static struct dm9000_plat_data real6410_dm9k_pdata = {
97 };
98 
99 static struct platform_device real6410_device_eth = {
100  .name = "dm9000",
101  .id = -1,
102  .num_resources = ARRAY_SIZE(real6410_dm9k_resource),
103  .resource = real6410_dm9k_resource,
104  .dev = {
105  .platform_data = &real6410_dm9k_pdata,
106  },
107 };
108 
109 static struct s3c_fb_pd_win real6410_lcd_type0_fb_win = {
110  .max_bpp = 32,
111  .default_bpp = 16,
112  .xres = 480,
113  .yres = 272,
114 };
115 
116 static struct fb_videomode real6410_lcd_type0_timing = {
117  /* 4.3" 480x272 */
118  .left_margin = 3,
119  .right_margin = 2,
120  .upper_margin = 1,
121  .lower_margin = 1,
122  .hsync_len = 40,
123  .vsync_len = 1,
124 };
125 
126 static struct s3c_fb_pd_win real6410_lcd_type1_fb_win = {
127  .max_bpp = 32,
128  .default_bpp = 16,
129  .xres = 800,
130  .yres = 480,
131 };
132 
133 static struct fb_videomode real6410_lcd_type1_timing = {
134  /* 7.0" 800x480 */
135  .left_margin = 8,
136  .right_margin = 13,
137  .upper_margin = 7,
138  .lower_margin = 5,
139  .hsync_len = 3,
140  .vsync_len = 1,
141  .xres = 800,
142  .yres = 480,
143 };
144 
145 static struct s3c_fb_platdata real6410_lcd_pdata[] __initdata = {
146  {
147  .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
148  .vtiming = &real6410_lcd_type0_timing,
149  .win[0] = &real6410_lcd_type0_fb_win,
152  }, {
153  .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
154  .vtiming = &real6410_lcd_type1_timing,
155  .win[0] = &real6410_lcd_type1_fb_win,
158  },
159  { },
160 };
161 
162 static struct mtd_partition real6410_nand_part[] = {
163  [0] = {
164  .name = "uboot",
165  .size = SZ_1M,
166  .offset = 0,
167  },
168  [1] = {
169  .name = "kernel",
170  .size = SZ_2M,
171  .offset = SZ_1M,
172  },
173  [2] = {
174  .name = "rootfs",
175  .size = MTDPART_SIZ_FULL,
176  .offset = SZ_1M + SZ_2M,
177  },
178 };
179 
180 static struct s3c2410_nand_set real6410_nand_sets[] = {
181  [0] = {
182  .name = "nand",
183  .nr_chips = 1,
184  .nr_partitions = ARRAY_SIZE(real6410_nand_part),
185  .partitions = real6410_nand_part,
186  },
187 };
188 
189 static struct s3c2410_platform_nand real6410_nand_info = {
190  .tacls = 25,
191  .twrph0 = 55,
192  .twrph1 = 40,
193  .nr_sets = ARRAY_SIZE(real6410_nand_sets),
194  .sets = real6410_nand_sets,
195 };
196 
197 static struct platform_device *real6410_devices[] __initdata = {
198  &real6410_device_eth,
201  &s3c_device_fb,
204  &s3c_device_ts,
206 };
207 
208 static void __init real6410_map_io(void)
209 {
210  u32 tmp;
211 
212  s3c64xx_init_io(NULL, 0);
213  s3c24xx_init_clocks(12000000);
214  s3c24xx_init_uarts(real6410_uartcfgs, ARRAY_SIZE(real6410_uartcfgs));
215 
216  /* set the LCD type */
217  tmp = __raw_readl(S3C64XX_SPCON);
221 
222  /* remove the LCD bypass */
224  tmp &= ~MIFPCON_LCD_BYPASS;
226 }
227 
228 /*
229  * real6410_features string
230  *
231  * 0-9 LCD configuration
232  *
233  */
234 static char real6410_features_str[12] __initdata = "0";
235 
236 static int __init real6410_features_setup(char *str)
237 {
238  if (str)
239  strlcpy(real6410_features_str, str,
240  sizeof(real6410_features_str));
241  return 1;
242 }
243 
244 __setup("real6410=", real6410_features_setup);
245 
246 #define FEATURE_SCREEN (1 << 0)
247 
249  int done;
251 };
252 
253 static void real6410_parse_features(
255  const char *features_str)
256 {
257  const char *fp = features_str;
258 
259  features->done = 0;
260  features->lcd_index = 0;
261 
262  while (*fp) {
263  char f = *fp++;
264 
265  switch (f) {
266  case '0'...'9': /* tft screen */
267  if (features->done & FEATURE_SCREEN) {
268  printk(KERN_INFO "REAL6410: '%c' ignored, "
269  "screen type already set\n", f);
270  } else {
271  int li = f - '0';
272  if (li >= ARRAY_SIZE(real6410_lcd_pdata))
273  printk(KERN_INFO "REAL6410: '%c' out "
274  "of range LCD mode\n", f);
275  else {
276  features->lcd_index = li;
277  }
278  }
279  features->done |= FEATURE_SCREEN;
280  break;
281  }
282  }
283 }
284 
285 static void __init real6410_machine_init(void)
286 {
287  u32 cs1;
288  struct real6410_features_t features = { 0 };
289 
290  printk(KERN_INFO "REAL6410: Option string real6410=%s\n",
291  real6410_features_str);
292 
293  /* Parse the feature string */
294  real6410_parse_features(&features, real6410_features_str);
295 
296  printk(KERN_INFO "REAL6410: selected LCD display is %dx%d\n",
297  real6410_lcd_pdata[features.lcd_index].win[0]->xres,
298  real6410_lcd_pdata[features.lcd_index].win[0]->yres);
299 
300  s3c_fb_set_platdata(&real6410_lcd_pdata[features.lcd_index]);
301  s3c_nand_set_platdata(&real6410_nand_info);
303 
304  /* configure nCS1 width to 16 bits */
305 
308  cs1 |= ((1 << S3C64XX_SROM_BW__DATAWIDTH__SHIFT) |
313 
314  /* set timing for nCS1 suitable for ethernet chip */
315 
323 
324  gpio_request(S3C64XX_GPF(15), "LCD power");
325 
326  platform_add_devices(real6410_devices, ARRAY_SIZE(real6410_devices));
327 }
328 
329 MACHINE_START(REAL6410, "REAL6410")
330  /* Maintainer: Darius Augulis <[email protected]> */
331  .atag_offset = 0x100,
332 
333  .init_irq = s3c6410_init_irq,
334  .handle_irq = vic_handle_irq,
335  .map_io = real6410_map_io,
336  .init_machine = real6410_machine_init,
337  .init_late = s3c64xx_init_late,
338  .timer = &s3c24xx_timer,
339  .restart = s3c64xx_restart,