Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
board-nhk8815.c
Go to the documentation of this file.
1 /*
2  * linux/arch/arm/mach-nomadik/board-8815nhk.c
3  *
4  * Copyright (C) STMicroelectronics
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2, as
8  * published by the Free Software Foundation.
9  *
10  * NHK15 board specifc driver definition
11  */
12 #include <linux/types.h>
13 #include <linux/kernel.h>
14 #include <linux/init.h>
15 #include <linux/platform_device.h>
16 #include <linux/amba/bus.h>
17 #include <linux/amba/mmci.h>
18 #include <linux/interrupt.h>
19 #include <linux/gpio.h>
20 #include <linux/mtd/mtd.h>
21 #include <linux/mtd/nand.h>
22 #include <linux/mtd/onenand.h>
23 #include <linux/mtd/partitions.h>
24 #include <linux/i2c.h>
25 #include <linux/io.h>
26 #include <linux/pinctrl/machine.h>
27 #include <asm/hardware/vic.h>
28 #include <asm/sizes.h>
29 #include <asm/mach-types.h>
30 #include <asm/mach/arch.h>
31 #include <asm/mach/irq.h>
32 #include <asm/mach/flash.h>
33 #include <asm/mach/time.h>
34 
35 #include <plat/gpio-nomadik.h>
36 #include <plat/mtu.h>
37 #include <plat/pincfg.h>
38 
40 #include <mach/fsmc.h>
41 
42 #include "cpu-8815.h"
43 
44 /* Initial value for SRC control register: all timers use MXTAL/8 source */
45 #define SRC_CR_INIT_MASK 0x00007fff
46 #define SRC_CR_INIT_VAL 0x2aaa8000
47 
48 /* These addresses span 16MB, so use three individual pages */
49 static struct resource nhk8815_nand_resources[] = {
50  {
51  .name = "nand_addr",
52  .start = NAND_IO_ADDR,
53  .end = NAND_IO_ADDR + 0xfff,
54  .flags = IORESOURCE_MEM,
55  }, {
56  .name = "nand_cmd",
57  .start = NAND_IO_CMD,
58  .end = NAND_IO_CMD + 0xfff,
59  .flags = IORESOURCE_MEM,
60  }, {
61  .name = "nand_data",
62  .start = NAND_IO_DATA,
63  .end = NAND_IO_DATA + 0xfff,
64  .flags = IORESOURCE_MEM,
65  }
66 };
67 
68 static int nhk8815_nand_init(void)
69 {
70  /* FSMC setup for nand chip select (8-bit nand in 8815NHK) */
71  writel(0x0000000E, FSMC_PCR(0));
72  writel(0x000D0A00, FSMC_PMEM(0));
73  writel(0x00100A00, FSMC_PATT(0));
74 
75  /* enable access to the chip select area */
76  writel(readl(FSMC_PCR(0)) | 0x04, FSMC_PCR(0));
77 
78  return 0;
79 }
80 
81 /*
82  * These partitions are the same as those used in the 2.6.20 release
83  * shipped by the vendor; the first two partitions are mandated
84  * by the boot ROM, and the bootloader area is somehow oversized...
85  */
86 static struct mtd_partition nhk8815_partitions[] = {
87  {
88  .name = "X-Loader(NAND)",
89  .offset = 0,
90  .size = SZ_256K,
91  }, {
92  .name = "MemInit(NAND)",
93  .offset = MTDPART_OFS_APPEND,
94  .size = SZ_256K,
95  }, {
96  .name = "BootLoader(NAND)",
97  .offset = MTDPART_OFS_APPEND,
98  .size = SZ_2M,
99  }, {
100  .name = "Kernel zImage(NAND)",
101  .offset = MTDPART_OFS_APPEND,
102  .size = 3 * SZ_1M,
103  }, {
104  .name = "Root Filesystem(NAND)",
105  .offset = MTDPART_OFS_APPEND,
106  .size = 22 * SZ_1M,
107  }, {
108  .name = "User Filesystem(NAND)",
109  .offset = MTDPART_OFS_APPEND,
110  .size = MTDPART_SIZ_FULL,
111  }
112 };
113 
114 static struct nomadik_nand_platform_data nhk8815_nand_data = {
115  .parts = nhk8815_partitions,
116  .nparts = ARRAY_SIZE(nhk8815_partitions),
118  .init = nhk8815_nand_init,
119 };
120 
121 static struct platform_device nhk8815_nand_device = {
122  .name = "nomadik_nand",
123  .dev = {
124  .platform_data = &nhk8815_nand_data,
125  },
126  .resource = nhk8815_nand_resources,
127  .num_resources = ARRAY_SIZE(nhk8815_nand_resources),
128 };
129 
130 /* These are the partitions for the OneNand device, different from above */
131 static struct mtd_partition nhk8815_onenand_partitions[] = {
132  {
133  .name = "X-Loader(OneNAND)",
134  .offset = 0,
135  .size = SZ_256K,
136  }, {
137  .name = "MemInit(OneNAND)",
138  .offset = MTDPART_OFS_APPEND,
139  .size = SZ_256K,
140  }, {
141  .name = "BootLoader(OneNAND)",
142  .offset = MTDPART_OFS_APPEND,
143  .size = SZ_2M-SZ_256K,
144  }, {
145  .name = "SysImage(OneNAND)",
146  .offset = MTDPART_OFS_APPEND,
147  .size = 4 * SZ_1M,
148  }, {
149  .name = "Root Filesystem(OneNAND)",
150  .offset = MTDPART_OFS_APPEND,
151  .size = 22 * SZ_1M,
152  }, {
153  .name = "User Filesystem(OneNAND)",
154  .offset = MTDPART_OFS_APPEND,
155  .size = MTDPART_SIZ_FULL,
156  }
157 };
158 
159 static struct onenand_platform_data nhk8815_onenand_data = {
160  .parts = nhk8815_onenand_partitions,
161  .nr_parts = ARRAY_SIZE(nhk8815_onenand_partitions),
162 };
163 
164 static struct resource nhk8815_onenand_resource[] = {
165  {
166  .start = 0x30000000,
167  .end = 0x30000000 + SZ_128K - 1,
168  .flags = IORESOURCE_MEM,
169  },
170 };
171 
172 static struct platform_device nhk8815_onenand_device = {
173  .name = "onenand-flash",
174  .id = -1,
175  .dev = {
176  .platform_data = &nhk8815_onenand_data,
177  },
178  .resource = nhk8815_onenand_resource,
179  .num_resources = ARRAY_SIZE(nhk8815_onenand_resource),
180 };
181 
182 static void __init nhk8815_onenand_init(void)
183 {
184 #ifdef CONFIG_MTD_ONENAND
185  /* Set up SMCS0 for OneNand */
186  writel(0x000030db, FSMC_BCR(0));
187  writel(0x02100551, FSMC_BTR(0));
188 #endif
189 }
190 
191 static struct mmci_platform_data mmcsd_plat_data = {
192  .ocr_mask = MMC_VDD_29_30,
193  .f_max = 48000000,
194  .gpio_wp = -1,
195  .gpio_cd = 111,
196  .cd_invert = true,
197  .capabilities = MMC_CAP_MMC_HIGHSPEED |
199 };
200 
201 static int __init nhk8815_mmcsd_init(void)
202 {
203  int ret;
204 
205  ret = gpio_request(112, "card detect bias");
206  if (ret)
207  return ret;
208  gpio_direction_output(112, 0);
209  amba_apb_device_add(NULL, "mmci", NOMADIK_SDI_BASE, SZ_4K, IRQ_SDMMC, 0, &mmcsd_plat_data, 0x10180180);
210  return 0;
211 }
212 module_init(nhk8815_mmcsd_init);
213 
214 static struct resource nhk8815_eth_resources[] = {
215  {
216  .name = "smc91x-regs",
217  .start = 0x34000000 + 0x300,
218  .end = 0x34000000 + SZ_64K - 1,
219  .flags = IORESOURCE_MEM,
220  }, {
221  .start = NOMADIK_GPIO_TO_IRQ(115),
222  .end = NOMADIK_GPIO_TO_IRQ(115),
224  }
225 };
226 
227 static struct platform_device nhk8815_eth_device = {
228  .name = "smc91x",
229  .resource = nhk8815_eth_resources,
230  .num_resources = ARRAY_SIZE(nhk8815_eth_resources),
231 };
232 
233 static int __init nhk8815_eth_init(void)
234 {
235  int gpio_nr = 115; /* hardwired in the board */
236  int err;
237 
238  err = gpio_request(gpio_nr, "eth_irq");
239  if (!err) err = nmk_gpio_set_mode(gpio_nr, NMK_GPIO_ALT_GPIO);
240  if (!err) err = gpio_direction_input(gpio_nr);
241  if (err)
242  pr_err("Error %i in %s\n", err, __func__);
243  return err;
244 }
245 device_initcall(nhk8815_eth_init);
246 
247 static struct platform_device *nhk8815_platform_devices[] __initdata = {
248  &nhk8815_nand_device,
249  &nhk8815_onenand_device,
250  &nhk8815_eth_device,
251  /* will add more devices */
252 };
253 
254 static void __init nomadik_timer_init(void)
255 {
256  u32 src_cr;
257 
258  /* Configure timer sources in "system reset controller" ctrl reg */
259  src_cr = readl(io_p2v(NOMADIK_SRC_BASE));
260  src_cr &= SRC_CR_INIT_MASK;
261  src_cr |= SRC_CR_INIT_VAL;
262  writel(src_cr, io_p2v(NOMADIK_SRC_BASE));
263 
265 }
266 
267 static struct sys_timer nomadik_timer = {
268  .init = nomadik_timer_init,
269 };
270 
271 static struct i2c_board_info __initdata nhk8815_i2c0_devices[] = {
272  {
273  I2C_BOARD_INFO("stw4811", 0x2d),
274  },
275 };
276 
277 static struct i2c_board_info __initdata nhk8815_i2c1_devices[] = {
278  {
279  I2C_BOARD_INFO("camera", 0x10),
280  },
281  {
282  I2C_BOARD_INFO("stw5095", 0x1a),
283  },
284  {
285  I2C_BOARD_INFO("lis3lv02dl", 0x1d),
286  },
287 };
288 
289 static struct i2c_board_info __initdata nhk8815_i2c2_devices[] = {
290  {
291  I2C_BOARD_INFO("stw4811-usb", 0x2d),
292  },
293 };
294 
295 static unsigned long out_low[] = { PIN_OUTPUT_LOW };
296 static unsigned long out_high[] = { PIN_OUTPUT_HIGH };
297 static unsigned long in_nopull[] = { PIN_INPUT_NOPULL };
298 static unsigned long in_pullup[] = { PIN_INPUT_PULLUP };
299 
300 static struct pinctrl_map __initdata nhk8815_pinmap[] = {
301  PIN_MAP_MUX_GROUP_DEFAULT("uart0", "pinctrl-stn8815", "u0_a_1", "u0"),
302  PIN_MAP_MUX_GROUP_DEFAULT("uart1", "pinctrl-stn8815", "u1_a_1", "u1"),
303  /* Hog in MMC/SD card mux */
304  PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-stn8815", "mmcsd_a_1", "mmcsd"),
305  /* MCCLK */
306  PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO8_B10", out_low),
307  /* MCCMD */
308  PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO9_A10", in_pullup),
309  /* MCCMDDIR */
310  PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO10_C11", out_high),
311  /* MCDAT3-0 */
312  PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO11_B11", in_pullup),
313  PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO12_A11", in_pullup),
314  PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO13_C12", in_pullup),
315  PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO14_B12", in_pullup),
316  /* MCDAT0DIR */
317  PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO15_A12", out_high),
318  /* MCDAT31DIR */
319  PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO16_C13", out_high),
320  /* MCMSFBCLK */
321  PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO24_C15", in_pullup),
322  /* CD input GPIO */
323  PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO111_H21", in_nopull),
324  /* CD bias drive */
325  PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO112_J21", out_low),
326 };
327 
328 static void __init nhk8815_platform_init(void)
329 {
330  pinctrl_register_mappings(nhk8815_pinmap, ARRAY_SIZE(nhk8815_pinmap));
332  nhk8815_onenand_init();
333  platform_add_devices(nhk8815_platform_devices,
334  ARRAY_SIZE(nhk8815_platform_devices));
335 
338 
339  i2c_register_board_info(0, nhk8815_i2c0_devices,
340  ARRAY_SIZE(nhk8815_i2c0_devices));
341  i2c_register_board_info(1, nhk8815_i2c1_devices,
342  ARRAY_SIZE(nhk8815_i2c1_devices));
343  i2c_register_board_info(2, nhk8815_i2c2_devices,
344  ARRAY_SIZE(nhk8815_i2c2_devices));
345 }
346 
347 MACHINE_START(NOMADIK, "NHK8815")
348  /* Maintainer: ST MicroElectronics */
349  .atag_offset = 0x100,
350  .map_io = cpu8815_map_io,
351  .init_irq = cpu8815_init_irq,
352  .handle_irq = vic_handle_irq,
353  .timer = &nomadik_timer,
354  .init_machine = nhk8815_platform_init,
355  .restart = cpu8815_restart,