Commit | Line | Data |
---|---|---|
28ad94ec AR |
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> | |
171af7dc | 17 | #include <linux/amba/mmci.h> |
725b1f9d AR |
18 | #include <linux/interrupt.h> |
19 | #include <linux/gpio.h> | |
63234717 AR |
20 | #include <linux/mtd/mtd.h> |
21 | #include <linux/mtd/nand.h> | |
41863f73 | 22 | #include <linux/mtd/fsmc.h> |
c1558b55 | 23 | #include <linux/mtd/onenand.h> |
63234717 | 24 | #include <linux/mtd/partitions.h> |
d088f671 | 25 | #include <linux/i2c.h> |
63234717 | 26 | #include <linux/io.h> |
2601ccfe | 27 | #include <linux/pinctrl/machine.h> |
7cb15e10 | 28 | #include <linux/platform_data/pinctrl-nomadik.h> |
694e33a7 LW |
29 | #include <linux/platform_data/clocksource-nomadik-mtu.h> |
30 | #include <linux/platform_data/mtd-nomadik-nand.h> | |
42ab5304 | 31 | #include <asm/hardware/vic.h> |
63234717 | 32 | #include <asm/sizes.h> |
28ad94ec AR |
33 | #include <asm/mach-types.h> |
34 | #include <asm/mach/arch.h> | |
8b85e7cb | 35 | #include <asm/mach/flash.h> |
b9576623 | 36 | #include <asm/mach/time.h> |
0813069d | 37 | #include <mach/irqs.h> |
28ad94ec | 38 | |
61b38753 LW |
39 | #include "cpu-8815.h" |
40 | ||
59b559d7 SK |
41 | /* Initial value for SRC control register: all timers use MXTAL/8 source */ |
42 | #define SRC_CR_INIT_MASK 0x00007fff | |
43 | #define SRC_CR_INIT_VAL 0x2aaa8000 | |
44 | ||
db6364a6 LW |
45 | #define ALE_OFF 0x1000000 |
46 | #define CLE_OFF 0x800000 | |
47 | ||
3ad2f3fb | 48 | /* These addresses span 16MB, so use three individual pages */ |
63234717 AR |
49 | static struct resource nhk8815_nand_resources[] = { |
50 | { | |
41863f73 LW |
51 | .name = "nand_data", |
52 | .start = 0x40000000, | |
53 | .end = 0x40000000 + SZ_16K - 1, | |
63234717 | 54 | .flags = IORESOURCE_MEM, |
db6364a6 | 55 | }, { |
63234717 | 56 | .name = "nand_addr", |
db6364a6 LW |
57 | .start = 0x40000000 + ALE_OFF, |
58 | .end = 0x40000000 +ALE_OFF + SZ_16K - 1, | |
63234717 AR |
59 | .flags = IORESOURCE_MEM, |
60 | }, { | |
61 | .name = "nand_cmd", | |
db6364a6 LW |
62 | .start = 0x40000000 + CLE_OFF, |
63 | .end = 0x40000000 + CLE_OFF + SZ_16K - 1, | |
63234717 AR |
64 | .flags = IORESOURCE_MEM, |
65 | }, { | |
41863f73 LW |
66 | .name = "fsmc_regs", |
67 | .start = NOMADIK_FSMC_BASE, | |
68 | .end = NOMADIK_FSMC_BASE + SZ_4K - 1, | |
63234717 | 69 | .flags = IORESOURCE_MEM, |
41863f73 | 70 | }, |
63234717 AR |
71 | }; |
72 | ||
63234717 AR |
73 | /* |
74 | * These partitions are the same as those used in the 2.6.20 release | |
75 | * shipped by the vendor; the first two partitions are mandated | |
76 | * by the boot ROM, and the bootloader area is somehow oversized... | |
77 | */ | |
78 | static struct mtd_partition nhk8815_partitions[] = { | |
79 | { | |
80 | .name = "X-Loader(NAND)", | |
81 | .offset = 0, | |
82 | .size = SZ_256K, | |
83 | }, { | |
84 | .name = "MemInit(NAND)", | |
85 | .offset = MTDPART_OFS_APPEND, | |
86 | .size = SZ_256K, | |
87 | }, { | |
88 | .name = "BootLoader(NAND)", | |
89 | .offset = MTDPART_OFS_APPEND, | |
90 | .size = SZ_2M, | |
91 | }, { | |
92 | .name = "Kernel zImage(NAND)", | |
93 | .offset = MTDPART_OFS_APPEND, | |
94 | .size = 3 * SZ_1M, | |
95 | }, { | |
96 | .name = "Root Filesystem(NAND)", | |
97 | .offset = MTDPART_OFS_APPEND, | |
98 | .size = 22 * SZ_1M, | |
99 | }, { | |
100 | .name = "User Filesystem(NAND)", | |
101 | .offset = MTDPART_OFS_APPEND, | |
102 | .size = MTDPART_SIZ_FULL, | |
103 | } | |
104 | }; | |
105 | ||
41863f73 LW |
106 | static struct fsmc_nand_timings nhk8815_nand_timings = { |
107 | .thiz = 0, | |
108 | .thold = 0x10, | |
109 | .twait = 0x0A, | |
110 | .tset = 0, | |
111 | }; | |
112 | ||
113 | static struct fsmc_nand_platform_data nhk8815_nand_platform_data = { | |
114 | .nand_timings = &nhk8815_nand_timings, | |
115 | .partitions = nhk8815_partitions, | |
116 | .nr_partitions = ARRAY_SIZE(nhk8815_partitions), | |
117 | .width = FSMC_NAND_BW8, | |
63234717 AR |
118 | }; |
119 | ||
120 | static struct platform_device nhk8815_nand_device = { | |
41863f73 LW |
121 | .name = "fsmc-nand", |
122 | .id = -1, | |
123 | .resource = nhk8815_nand_resources, | |
124 | .num_resources = ARRAY_SIZE(nhk8815_nand_resources), | |
125 | .dev = { | |
126 | .platform_data = &nhk8815_nand_platform_data, | |
63234717 | 127 | }, |
63234717 AR |
128 | }; |
129 | ||
8b85e7cb AR |
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 | ||
c1558b55 | 159 | static struct onenand_platform_data nhk8815_onenand_data = { |
8b85e7cb AR |
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 = { | |
c1558b55 | 173 | .name = "onenand-flash", |
8b85e7cb AR |
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 | ||
db6364a6 LW |
182 | /* bus control reg. and bus timing reg. for CS0..CS3 */ |
183 | #define FSMC_BCR(x) (NOMADIK_FSMC_VA + (x << 3)) | |
184 | #define FSMC_BTR(x) (NOMADIK_FSMC_VA + (x << 3) + 0x04) | |
185 | ||
8b85e7cb AR |
186 | static void __init nhk8815_onenand_init(void) |
187 | { | |
c1558b55 | 188 | #ifdef CONFIG_MTD_ONENAND |
8b85e7cb | 189 | /* Set up SMCS0 for OneNand */ |
c1558b55 AR |
190 | writel(0x000030db, FSMC_BCR(0)); |
191 | writel(0x02100551, FSMC_BTR(0)); | |
8b85e7cb AR |
192 | #endif |
193 | } | |
63234717 | 194 | |
171af7dc LW |
195 | static struct mmci_platform_data mmcsd_plat_data = { |
196 | .ocr_mask = MMC_VDD_29_30, | |
197 | .f_max = 48000000, | |
198 | .gpio_wp = -1, | |
199 | .gpio_cd = 111, | |
200 | .cd_invert = true, | |
201 | .capabilities = MMC_CAP_MMC_HIGHSPEED | | |
202 | MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA, | |
203 | }; | |
204 | ||
205 | static int __init nhk8815_mmcsd_init(void) | |
206 | { | |
207 | int ret; | |
208 | ||
209 | ret = gpio_request(112, "card detect bias"); | |
210 | if (ret) | |
211 | return ret; | |
212 | gpio_direction_output(112, 0); | |
213 | amba_apb_device_add(NULL, "mmci", NOMADIK_SDI_BASE, SZ_4K, IRQ_SDMMC, 0, &mmcsd_plat_data, 0x10180180); | |
214 | return 0; | |
215 | } | |
216 | module_init(nhk8815_mmcsd_init); | |
217 | ||
725b1f9d AR |
218 | static struct resource nhk8815_eth_resources[] = { |
219 | { | |
220 | .name = "smc91x-regs", | |
221 | .start = 0x34000000 + 0x300, | |
222 | .end = 0x34000000 + SZ_64K - 1, | |
223 | .flags = IORESOURCE_MEM, | |
224 | }, { | |
225 | .start = NOMADIK_GPIO_TO_IRQ(115), | |
226 | .end = NOMADIK_GPIO_TO_IRQ(115), | |
227 | .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING, | |
228 | } | |
229 | }; | |
230 | ||
231 | static struct platform_device nhk8815_eth_device = { | |
232 | .name = "smc91x", | |
233 | .resource = nhk8815_eth_resources, | |
234 | .num_resources = ARRAY_SIZE(nhk8815_eth_resources), | |
235 | }; | |
236 | ||
237 | static int __init nhk8815_eth_init(void) | |
238 | { | |
239 | int gpio_nr = 115; /* hardwired in the board */ | |
240 | int err; | |
241 | ||
242 | err = gpio_request(gpio_nr, "eth_irq"); | |
243 | if (!err) err = nmk_gpio_set_mode(gpio_nr, NMK_GPIO_ALT_GPIO); | |
244 | if (!err) err = gpio_direction_input(gpio_nr); | |
245 | if (err) | |
246 | pr_err("Error %i in %s\n", err, __func__); | |
247 | return err; | |
248 | } | |
249 | device_initcall(nhk8815_eth_init); | |
250 | ||
28ad94ec | 251 | static struct platform_device *nhk8815_platform_devices[] __initdata = { |
63234717 | 252 | &nhk8815_nand_device, |
8b85e7cb | 253 | &nhk8815_onenand_device, |
725b1f9d AR |
254 | &nhk8815_eth_device, |
255 | /* will add more devices */ | |
28ad94ec AR |
256 | }; |
257 | ||
59b559d7 SK |
258 | static void __init nomadik_timer_init(void) |
259 | { | |
260 | u32 src_cr; | |
261 | ||
262 | /* Configure timer sources in "system reset controller" ctrl reg */ | |
263 | src_cr = readl(io_p2v(NOMADIK_SRC_BASE)); | |
264 | src_cr &= SRC_CR_INIT_MASK; | |
265 | src_cr |= SRC_CR_INIT_VAL; | |
266 | writel(src_cr, io_p2v(NOMADIK_SRC_BASE)); | |
267 | ||
0813069d | 268 | nmdk_timer_init(io_p2v(NOMADIK_MTU0_BASE), IRQ_MTU0); |
59b559d7 SK |
269 | } |
270 | ||
d088f671 LW |
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 | ||
2601ccfe LW |
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 | ||
28ad94ec AR |
328 | static void __init nhk8815_platform_init(void) |
329 | { | |
2601ccfe | 330 | pinctrl_register_mappings(nhk8815_pinmap, ARRAY_SIZE(nhk8815_pinmap)); |
28ad94ec | 331 | cpu8815_platform_init(); |
8b85e7cb | 332 | nhk8815_onenand_init(); |
28ad94ec AR |
333 | platform_add_devices(nhk8815_platform_devices, |
334 | ARRAY_SIZE(nhk8815_platform_devices)); | |
335 | ||
7c77852d LW |
336 | amba_apb_device_add(NULL, "uart0", NOMADIK_UART0_BASE, SZ_4K, IRQ_UART0, 0, NULL, 0); |
337 | amba_apb_device_add(NULL, "uart1", NOMADIK_UART1_BASE, SZ_4K, IRQ_UART1, 0, NULL, 0); | |
d088f671 LW |
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)); | |
28ad94ec AR |
345 | } |
346 | ||
347 | MACHINE_START(NOMADIK, "NHK8815") | |
348 | /* Maintainer: ST MicroElectronics */ | |
013b5fb2 | 349 | .atag_offset = 0x100, |
28ad94ec AR |
350 | .map_io = cpu8815_map_io, |
351 | .init_irq = cpu8815_init_irq, | |
42ab5304 | 352 | .handle_irq = vic_handle_irq, |
6bb27d73 | 353 | .init_time = nomadik_timer_init, |
28ad94ec | 354 | .init_machine = nhk8815_platform_init, |
35b47a40 | 355 | .restart = cpu8815_restart, |
28ad94ec | 356 | MACHINE_END |