blob: 8f9e77aea76aac7ff3f2b3e2d0b00910fed6d539 [file] [log] [blame]
Linus Walleijbb3cee22009-04-23 10:22:13 +01001/*
2 *
3 * arch/arm/mach-u300/core.c
4 *
5 *
Linus Walleijfcb28d22012-08-13 10:11:15 +02006 * Copyright (C) 2007-2012 ST-Ericsson SA
Linus Walleijbb3cee22009-04-23 10:22:13 +01007 * License terms: GNU General Public License (GPL) version 2
8 * Core platform support, IRQ handling and device definitions.
9 * Author: Linus Walleij <linus.walleij@stericsson.com>
10 */
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/spinlock.h>
14#include <linux/interrupt.h>
15#include <linux/bitops.h>
16#include <linux/device.h>
17#include <linux/mm.h>
18#include <linux/termios.h>
Linus Walleijec8f1252010-08-13 11:31:59 +020019#include <linux/dmaengine.h>
Linus Walleijbb3cee22009-04-23 10:22:13 +010020#include <linux/amba/bus.h>
Linus Walleija64ae392012-02-20 21:26:30 +010021#include <linux/amba/mmci.h>
Linus Walleijcf4af862013-04-19 14:56:46 +020022#include <linux/amba/pl022.h>
Linus Walleijec8f1252010-08-13 11:31:59 +020023#include <linux/amba/serial.h>
Linus Walleijbb3cee22009-04-23 10:22:13 +010024#include <linux/platform_device.h>
25#include <linux/gpio.h>
Linus Walleijb7276b22010-08-05 07:58:58 +010026#include <linux/clk.h>
27#include <linux/err.h>
Linus Walleij93ac5a52010-09-13 00:35:37 +020028#include <linux/mtd/nand.h>
29#include <linux/mtd/fsmc.h>
Linus Walleij98da3522011-05-02 20:54:38 +020030#include <linux/pinctrl/machine.h>
Linus Walleij51dddfe2012-01-20 17:53:15 +010031#include <linux/pinctrl/pinconf-generic.h>
Jon Medhurstd70a5962011-08-04 15:41:42 +010032#include <linux/dma-mapping.h>
Linus Walleij50667d62012-06-19 23:44:25 +020033#include <linux/platform_data/clk-u300.h>
Linus Walleij65172852012-08-13 10:56:43 +020034#include <linux/platform_data/pinctrl-coh901.h>
Linus Walleij9f575d92013-01-04 10:35:06 +010035#include <linux/platform_data/dma-coh901318.h>
Rob Herring9e47b8b2013-01-07 09:45:59 -060036#include <linux/irqchip/arm-vic.h>
Linus Walleij978577e2013-04-08 11:38:50 +020037#include <linux/irqchip.h>
38#include <linux/of_platform.h>
39#include <linux/clocksource.h>
Linus Walleijbb3cee22009-04-23 10:22:13 +010040
41#include <asm/types.h>
42#include <asm/setup.h>
43#include <asm/memory.h>
Linus Walleijbb3cee22009-04-23 10:22:13 +010044#include <asm/mach/map.h>
Linus Walleij234323b2012-08-13 11:35:55 +020045#include <asm/mach-types.h>
46#include <asm/mach/arch.h>
Linus Walleijbb3cee22009-04-23 10:22:13 +010047
48#include <mach/hardware.h>
49#include <mach/syscon.h>
Linus Walleija4fe2922012-08-13 13:49:45 +020050#include <mach/irqs.h>
Linus Walleijbb3cee22009-04-23 10:22:13 +010051
Linus Walleij234323b2012-08-13 11:35:55 +020052#include "timer.h"
Linus Walleijc7c8c782009-08-14 10:59:05 +010053#include "spi.h"
Linus Walleij6be2a0c2009-08-13 21:42:01 +010054#include "i2c.h"
Linus Walleija64ae392012-02-20 21:26:30 +010055#include "u300-gpio.h"
Linus Walleijbb3cee22009-04-23 10:22:13 +010056
57/*
58 * Static I/O mappings that are needed for booting the U300 platforms. The
59 * only things we need are the areas where we find the timer, syscon and
60 * intcon, since the remaining device drivers will map their own memory
61 * physical to virtual as the need arise.
62 */
63static struct map_desc u300_io_desc[] __initdata = {
64 {
65 .virtual = U300_SLOW_PER_VIRT_BASE,
66 .pfn = __phys_to_pfn(U300_SLOW_PER_PHYS_BASE),
67 .length = SZ_64K,
68 .type = MT_DEVICE,
69 },
70 {
71 .virtual = U300_AHB_PER_VIRT_BASE,
72 .pfn = __phys_to_pfn(U300_AHB_PER_PHYS_BASE),
73 .length = SZ_32K,
74 .type = MT_DEVICE,
75 },
76 {
77 .virtual = U300_FAST_PER_VIRT_BASE,
78 .pfn = __phys_to_pfn(U300_FAST_PER_PHYS_BASE),
79 .length = SZ_32K,
80 .type = MT_DEVICE,
81 },
Linus Walleijbb3cee22009-04-23 10:22:13 +010082};
83
Linus Walleij234323b2012-08-13 11:35:55 +020084static void __init u300_map_io(void)
Linus Walleijbb3cee22009-04-23 10:22:13 +010085{
86 iotable_init(u300_io_desc, ARRAY_SIZE(u300_io_desc));
87}
88
89/*
90 * Declaration of devices found on the U300 board and
91 * their respective memory locations.
92 */
Linus Walleijec8f1252010-08-13 11:31:59 +020093
94static struct amba_pl011_data uart0_plat_data = {
95#ifdef CONFIG_COH901318
96 .dma_filter = coh901318_filter_id,
97 .dma_rx_param = (void *) U300_DMA_UART0_RX,
98 .dma_tx_param = (void *) U300_DMA_UART0_TX,
99#endif
100};
101
Russell King6db2a452011-12-18 15:26:38 +0000102/* Slow device at 0x3000 offset */
103static AMBA_APB_DEVICE(uart0, "uart0", 0, U300_UART0_BASE,
104 { IRQ_U300_UART0 }, &uart0_plat_data);
Linus Walleijbb3cee22009-04-23 10:22:13 +0100105
106/* The U335 have an additional UART1 on the APP CPU */
Linus Walleijec8f1252010-08-13 11:31:59 +0200107static struct amba_pl011_data uart1_plat_data = {
108#ifdef CONFIG_COH901318
109 .dma_filter = coh901318_filter_id,
110 .dma_rx_param = (void *) U300_DMA_UART1_RX,
111 .dma_tx_param = (void *) U300_DMA_UART1_TX,
112#endif
113};
114
Russell King6db2a452011-12-18 15:26:38 +0000115/* Fast device at 0x7000 offset */
116static AMBA_APB_DEVICE(uart1, "uart1", 0, U300_UART1_BASE,
117 { IRQ_U300_UART1 }, &uart1_plat_data);
Linus Walleijbb3cee22009-04-23 10:22:13 +0100118
Russell King6db2a452011-12-18 15:26:38 +0000119/* AHB device at 0x4000 offset */
120static AMBA_APB_DEVICE(pl172, "pl172", 0, U300_EMIF_CFG_BASE, { }, NULL);
Linus Walleijbb3cee22009-04-23 10:22:13 +0100121
Russell King6db2a452011-12-18 15:26:38 +0000122/* Fast device at 0x6000 offset */
123static AMBA_APB_DEVICE(pl022, "pl022", 0, U300_SPI_BASE,
124 { IRQ_U300_SPI }, NULL);
Linus Walleijbb3cee22009-04-23 10:22:13 +0100125
Russell King6db2a452011-12-18 15:26:38 +0000126/* Fast device at 0x1000 offset */
127#define U300_MMCSD_IRQS { IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 }
128
Linus Walleija64ae392012-02-20 21:26:30 +0100129static struct mmci_platform_data mmcsd_platform_data = {
130 /*
131 * Do not set ocr_mask or voltage translation function,
132 * we have a regulator we can control instead.
133 */
134 .f_max = 24000000,
135 .gpio_wp = -1,
136 .gpio_cd = U300_GPIO_PIN_MMC_CD,
137 .cd_invert = true,
138 .capabilities = MMC_CAP_MMC_HIGHSPEED |
139 MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
140#ifdef CONFIG_COH901318
141 .dma_filter = coh901318_filter_id,
142 .dma_rx_param = (void *) U300_DMA_MMCSD_RX_TX,
143 /* Don't specify a TX channel, this RX channel is bidirectional */
144#endif
145};
146
Russell King6db2a452011-12-18 15:26:38 +0000147static AMBA_APB_DEVICE(mmcsd, "mmci", 0, U300_MMCSD_BASE,
Linus Walleija64ae392012-02-20 21:26:30 +0100148 U300_MMCSD_IRQS, &mmcsd_platform_data);
Linus Walleijbb3cee22009-04-23 10:22:13 +0100149
150/*
151 * The order of device declaration may be important, since some devices
152 * have dependencies on other devices being initialized first.
153 */
154static struct amba_device *amba_devs[] __initdata = {
155 &uart0_device,
Linus Walleijbb3cee22009-04-23 10:22:13 +0100156 &uart1_device,
Linus Walleijbb3cee22009-04-23 10:22:13 +0100157 &pl022_device,
158 &pl172_device,
159 &mmcsd_device,
160};
161
162/* Here follows a list of all hw resources that the platform devices
163 * allocate. Note, clock dependencies are not included
164 */
165
166static struct resource gpio_resources[] = {
167 {
168 .start = U300_GPIO_BASE,
169 .end = (U300_GPIO_BASE + SZ_4K - 1),
170 .flags = IORESOURCE_MEM,
171 },
172 {
173 .name = "gpio0",
174 .start = IRQ_U300_GPIO_PORT0,
175 .end = IRQ_U300_GPIO_PORT0,
176 .flags = IORESOURCE_IRQ,
177 },
178 {
179 .name = "gpio1",
180 .start = IRQ_U300_GPIO_PORT1,
181 .end = IRQ_U300_GPIO_PORT1,
182 .flags = IORESOURCE_IRQ,
183 },
184 {
185 .name = "gpio2",
186 .start = IRQ_U300_GPIO_PORT2,
187 .end = IRQ_U300_GPIO_PORT2,
188 .flags = IORESOURCE_IRQ,
189 },
Linus Walleijbb3cee22009-04-23 10:22:13 +0100190 {
191 .name = "gpio3",
192 .start = IRQ_U300_GPIO_PORT3,
193 .end = IRQ_U300_GPIO_PORT3,
194 .flags = IORESOURCE_IRQ,
195 },
196 {
197 .name = "gpio4",
198 .start = IRQ_U300_GPIO_PORT4,
199 .end = IRQ_U300_GPIO_PORT4,
200 .flags = IORESOURCE_IRQ,
201 },
Linus Walleijbb3cee22009-04-23 10:22:13 +0100202 {
203 .name = "gpio5",
204 .start = IRQ_U300_GPIO_PORT5,
205 .end = IRQ_U300_GPIO_PORT5,
206 .flags = IORESOURCE_IRQ,
207 },
208 {
209 .name = "gpio6",
210 .start = IRQ_U300_GPIO_PORT6,
211 .end = IRQ_U300_GPIO_PORT6,
212 .flags = IORESOURCE_IRQ,
213 },
Linus Walleijbb3cee22009-04-23 10:22:13 +0100214};
215
216static struct resource keypad_resources[] = {
217 {
218 .start = U300_KEYPAD_BASE,
219 .end = U300_KEYPAD_BASE + SZ_4K - 1,
220 .flags = IORESOURCE_MEM,
221 },
222 {
223 .name = "coh901461-press",
224 .start = IRQ_U300_KEYPAD_KEYBF,
225 .end = IRQ_U300_KEYPAD_KEYBF,
226 .flags = IORESOURCE_IRQ,
227 },
228 {
229 .name = "coh901461-release",
230 .start = IRQ_U300_KEYPAD_KEYBR,
231 .end = IRQ_U300_KEYPAD_KEYBR,
232 .flags = IORESOURCE_IRQ,
233 },
234};
235
236static struct resource rtc_resources[] = {
237 {
238 .start = U300_RTC_BASE,
239 .end = U300_RTC_BASE + SZ_4K - 1,
240 .flags = IORESOURCE_MEM,
241 },
242 {
243 .start = IRQ_U300_RTC,
244 .end = IRQ_U300_RTC,
245 .flags = IORESOURCE_IRQ,
246 },
247};
248
249/*
250 * Fsmc does have IRQs: #43 and #44 (NFIF and NFIF2)
251 * but these are not yet used by the driver.
252 */
253static struct resource fsmc_resources[] = {
254 {
Jean-Christophe PLAGNIOL-VILLARD6d7b42a2012-10-04 15:14:16 +0200255 .name = "nand_addr",
256 .start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE,
257 .end = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE + SZ_16K - 1,
258 .flags = IORESOURCE_MEM,
259 },
260 {
261 .name = "nand_cmd",
262 .start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE,
263 .end = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE + SZ_16K - 1,
264 .flags = IORESOURCE_MEM,
265 },
266 {
Linus Walleij93ac5a52010-09-13 00:35:37 +0200267 .name = "nand_data",
268 .start = U300_NAND_CS0_PHYS_BASE,
269 .end = U300_NAND_CS0_PHYS_BASE + SZ_16K - 1,
270 .flags = IORESOURCE_MEM,
271 },
272 {
273 .name = "fsmc_regs",
Linus Walleijbb3cee22009-04-23 10:22:13 +0100274 .start = U300_NAND_IF_PHYS_BASE,
275 .end = U300_NAND_IF_PHYS_BASE + SZ_4K - 1,
276 .flags = IORESOURCE_MEM,
277 },
278};
279
280static struct resource i2c0_resources[] = {
281 {
282 .start = U300_I2C0_BASE,
283 .end = U300_I2C0_BASE + SZ_4K - 1,
284 .flags = IORESOURCE_MEM,
285 },
286 {
287 .start = IRQ_U300_I2C0,
288 .end = IRQ_U300_I2C0,
289 .flags = IORESOURCE_IRQ,
290 },
291};
292
293static struct resource i2c1_resources[] = {
294 {
295 .start = U300_I2C1_BASE,
296 .end = U300_I2C1_BASE + SZ_4K - 1,
297 .flags = IORESOURCE_MEM,
298 },
299 {
300 .start = IRQ_U300_I2C1,
301 .end = IRQ_U300_I2C1,
302 .flags = IORESOURCE_IRQ,
303 },
304
305};
306
307static struct resource wdog_resources[] = {
308 {
309 .start = U300_WDOG_BASE,
310 .end = U300_WDOG_BASE + SZ_4K - 1,
311 .flags = IORESOURCE_MEM,
312 },
313 {
314 .start = IRQ_U300_WDOG,
315 .end = IRQ_U300_WDOG,
316 .flags = IORESOURCE_IRQ,
317 }
318};
319
Linus Walleij08d1e2e2009-12-17 09:46:24 +0100320static struct resource dma_resource[] = {
321 {
322 .start = U300_DMAC_BASE,
323 .end = U300_DMAC_BASE + PAGE_SIZE - 1,
324 .flags = IORESOURCE_MEM,
325 },
326 {
327 .start = IRQ_U300_DMA,
328 .end = IRQ_U300_DMA,
329 .flags = IORESOURCE_IRQ,
330 }
331};
332
Linus Walleij08d1e2e2009-12-17 09:46:24 +0100333
Linus Walleij128a06d2012-02-21 14:31:45 +0100334static struct resource pinctrl_resources[] = {
Linus Walleij98da3522011-05-02 20:54:38 +0200335 {
336 .start = U300_SYSCON_BASE,
337 .end = U300_SYSCON_BASE + SZ_4K - 1,
338 .flags = IORESOURCE_MEM,
339 },
340};
341
Linus Walleijbb3cee22009-04-23 10:22:13 +0100342static struct platform_device wdog_device = {
Linus Walleij633e81a2010-01-25 07:18:16 +0100343 .name = "coh901327_wdog",
Linus Walleijbb3cee22009-04-23 10:22:13 +0100344 .id = -1,
345 .num_resources = ARRAY_SIZE(wdog_resources),
346 .resource = wdog_resources,
347};
348
349static struct platform_device i2c0_device = {
Linus Walleij6be2a0c2009-08-13 21:42:01 +0100350 .name = "stu300",
Linus Walleijbb3cee22009-04-23 10:22:13 +0100351 .id = 0,
352 .num_resources = ARRAY_SIZE(i2c0_resources),
353 .resource = i2c0_resources,
354};
355
356static struct platform_device i2c1_device = {
Linus Walleij6be2a0c2009-08-13 21:42:01 +0100357 .name = "stu300",
Linus Walleijbb3cee22009-04-23 10:22:13 +0100358 .id = 1,
359 .num_resources = ARRAY_SIZE(i2c1_resources),
360 .resource = i2c1_resources,
361};
362
Linus Walleij128a06d2012-02-21 14:31:45 +0100363static struct platform_device pinctrl_device = {
364 .name = "pinctrl-u300",
365 .id = -1,
366 .num_resources = ARRAY_SIZE(pinctrl_resources),
367 .resource = pinctrl_resources,
368};
369
Linus Walleijcc890cd2011-09-08 09:04:51 +0100370/*
371 * The different variants have a few different versions of the
372 * GPIO block, with different number of ports.
373 */
374static struct u300_gpio_platform u300_gpio_plat = {
Linus Walleijcc890cd2011-09-08 09:04:51 +0100375 .ports = 7,
Linus Walleijcc890cd2011-09-08 09:04:51 +0100376 .gpio_base = 0,
Linus Walleijcc890cd2011-09-08 09:04:51 +0100377};
378
Linus Walleijbb3cee22009-04-23 10:22:13 +0100379static struct platform_device gpio_device = {
380 .name = "u300-gpio",
381 .id = -1,
382 .num_resources = ARRAY_SIZE(gpio_resources),
383 .resource = gpio_resources,
Linus Walleijcc890cd2011-09-08 09:04:51 +0100384 .dev = {
385 .platform_data = &u300_gpio_plat,
386 },
Linus Walleijbb3cee22009-04-23 10:22:13 +0100387};
388
389static struct platform_device keypad_device = {
390 .name = "keypad",
391 .id = -1,
392 .num_resources = ARRAY_SIZE(keypad_resources),
393 .resource = keypad_resources,
394};
395
396static struct platform_device rtc_device = {
Linus Walleij378ce742009-11-14 01:03:24 +0100397 .name = "rtc-coh901331",
Linus Walleijbb3cee22009-04-23 10:22:13 +0100398 .id = -1,
399 .num_resources = ARRAY_SIZE(rtc_resources),
400 .resource = rtc_resources,
401};
402
Linus Walleij93ac5a52010-09-13 00:35:37 +0200403static struct mtd_partition u300_partitions[] = {
404 {
405 .name = "bootrecords",
406 .offset = 0,
407 .size = SZ_128K,
408 },
409 {
410 .name = "free",
411 .offset = SZ_128K,
412 .size = 8064 * SZ_1K,
413 },
414 {
415 .name = "platform",
416 .offset = 8192 * SZ_1K,
417 .size = 253952 * SZ_1K,
418 },
419};
420
421static struct fsmc_nand_platform_data nand_platform_data = {
422 .partitions = u300_partitions,
423 .nr_partitions = ARRAY_SIZE(u300_partitions),
424 .options = NAND_SKIP_BBTSCAN,
425 .width = FSMC_NAND_BW8,
426};
427
428static struct platform_device nand_device = {
429 .name = "fsmc-nand",
Linus Walleijbb3cee22009-04-23 10:22:13 +0100430 .id = -1,
Linus Walleijbb3cee22009-04-23 10:22:13 +0100431 .resource = fsmc_resources,
Linus Walleij93ac5a52010-09-13 00:35:37 +0200432 .num_resources = ARRAY_SIZE(fsmc_resources),
433 .dev = {
434 .platform_data = &nand_platform_data,
435 },
Linus Walleijbb3cee22009-04-23 10:22:13 +0100436};
437
Linus Walleij08d1e2e2009-12-17 09:46:24 +0100438static struct platform_device dma_device = {
439 .name = "coh901318",
440 .id = -1,
441 .resource = dma_resource,
442 .num_resources = ARRAY_SIZE(dma_resource),
443 .dev = {
Linus Walleij08d1e2e2009-12-17 09:46:24 +0100444 .coherent_dma_mask = ~0,
445 },
446};
447
Linus Walleij51dddfe2012-01-20 17:53:15 +0100448static unsigned long pin_pullup_conf[] = {
449 PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 1),
450};
451
452static unsigned long pin_highz_conf[] = {
453 PIN_CONF_PACKED(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0),
454};
455
456/* Pin control settings */
Linus Walleije93bcee2012-02-09 07:23:28 +0100457static struct pinctrl_map __initdata u300_pinmux_map[] = {
Linus Walleij98da3522011-05-02 20:54:38 +0200458 /* anonymous maps for chip power and EMIFs */
Stephen Warren1e2082b2012-03-02 13:05:48 -0700459 PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "power"),
460 PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif0"),
461 PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif1"),
Linus Walleij98da3522011-05-02 20:54:38 +0200462 /* per-device maps for MMC/SD, SPI and UART */
Stephen Warren1e2082b2012-03-02 13:05:48 -0700463 PIN_MAP_MUX_GROUP_DEFAULT("mmci", "pinctrl-u300", NULL, "mmc0"),
464 PIN_MAP_MUX_GROUP_DEFAULT("pl022", "pinctrl-u300", NULL, "spi0"),
465 PIN_MAP_MUX_GROUP_DEFAULT("uart0", "pinctrl-u300", NULL, "uart0"),
Linus Walleij51dddfe2012-01-20 17:53:15 +0100466 /* This pin is used for clock return rather than GPIO */
467 PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO APP GPIO 11",
468 pin_pullup_conf),
469 /* This pin is used for card detect */
470 PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO MS INS",
471 pin_highz_conf),
Linus Walleij98da3522011-05-02 20:54:38 +0200472};
473
Linus Walleijbb3cee22009-04-23 10:22:13 +0100474/*
475 * Notice that AMBA devices are initialized before platform devices.
476 *
477 */
478static struct platform_device *platform_devs[] __initdata = {
Linus Walleij08d1e2e2009-12-17 09:46:24 +0100479 &dma_device,
Linus Walleijbb3cee22009-04-23 10:22:13 +0100480 &i2c0_device,
481 &i2c1_device,
482 &keypad_device,
483 &rtc_device,
Linus Walleij8604ac32012-11-20 14:42:47 +0100484 &pinctrl_device,
Linus Walleijbb3cee22009-04-23 10:22:13 +0100485 &gpio_device,
Linus Walleij93ac5a52010-09-13 00:35:37 +0200486 &nand_device,
Linus Walleijbb3cee22009-04-23 10:22:13 +0100487 &wdog_device,
Linus Walleijbb3cee22009-04-23 10:22:13 +0100488};
489
Linus Walleijbb3cee22009-04-23 10:22:13 +0100490/*
491 * Interrupts: the U300 platforms have two pl190 ARM PrimeCells connected
492 * together so some interrupts are connected to the first one and some
493 * to the second one.
494 */
Linus Walleij234323b2012-08-13 11:35:55 +0200495static void __init u300_init_irq(void)
Linus Walleijbb3cee22009-04-23 10:22:13 +0100496{
497 u32 mask[2] = {0, 0};
Linus Walleijb7276b22010-08-05 07:58:58 +0100498 struct clk *clk;
Linus Walleijbb3cee22009-04-23 10:22:13 +0100499 int i;
500
Linus Walleij379aae52010-08-05 07:58:13 +0100501 /* initialize clocking early, we want to clock the INTCON */
Linus Walleij50667d62012-06-19 23:44:25 +0200502 u300_clk_init(U300_SYSCON_VBASE);
503
504 /* Bootstrap EMIF and SEMI clocks */
505 clk = clk_get_sys("pl172", NULL);
506 BUG_ON(IS_ERR(clk));
507 clk_prepare_enable(clk);
508 clk = clk_get_sys("semi", NULL);
509 BUG_ON(IS_ERR(clk));
510 clk_prepare_enable(clk);
Linus Walleij379aae52010-08-05 07:58:13 +0100511
Linus Walleijb7276b22010-08-05 07:58:58 +0100512 /* Clock the interrupt controller */
513 clk = clk_get_sys("intcon", NULL);
514 BUG_ON(IS_ERR(clk));
Linus Walleij50667d62012-06-19 23:44:25 +0200515 clk_prepare_enable(clk);
Linus Walleijb7276b22010-08-05 07:58:58 +0100516
Linus Walleijcc890cd2011-09-08 09:04:51 +0100517 for (i = 0; i < U300_VIC_IRQS_END; i++)
Linus Walleijbb3cee22009-04-23 10:22:13 +0100518 set_bit(i, (unsigned long *) &mask[0]);
Linus Walleij13445002012-04-18 15:29:58 +0200519 vic_init((void __iomem *) U300_INTCON0_VBASE, IRQ_U300_INTCON0_START,
520 mask[0], mask[0]);
521 vic_init((void __iomem *) U300_INTCON1_VBASE, IRQ_U300_INTCON1_START,
522 mask[1], mask[1]);
Linus Walleijbb3cee22009-04-23 10:22:13 +0100523}
524
525
526/*
527 * U300 platforms peripheral handling
528 */
529struct db_chip {
530 u16 chipid;
531 const char *name;
532};
533
534/*
535 * This is a list of the Digital Baseband chips used in the U300 platform.
536 */
537static struct db_chip db_chips[] __initdata = {
538 {
539 .chipid = 0xb800,
540 .name = "DB3000",
541 },
542 {
543 .chipid = 0xc000,
544 .name = "DB3100",
545 },
546 {
547 .chipid = 0xc800,
548 .name = "DB3150",
549 },
550 {
551 .chipid = 0xd800,
552 .name = "DB3200",
553 },
554 {
555 .chipid = 0xe000,
556 .name = "DB3250",
557 },
558 {
559 .chipid = 0xe800,
560 .name = "DB3210",
561 },
562 {
563 .chipid = 0xf000,
564 .name = "DB3350 P1x",
565 },
566 {
567 .chipid = 0xf100,
568 .name = "DB3350 P2x",
569 },
570 {
571 .chipid = 0x0000, /* List terminator */
572 .name = NULL,
573 }
574};
575
Linus Walleija2bb9f42009-08-13 21:57:22 +0100576static void __init u300_init_check_chip(void)
Linus Walleijbb3cee22009-04-23 10:22:13 +0100577{
578
579 u16 val;
580 struct db_chip *chip;
581 const char *chipname;
582 const char unknown[] = "UNKNOWN";
583
584 /* Read out and print chip ID */
585 val = readw(U300_SYSCON_VBASE + U300_SYSCON_CIDR);
586 /* This is in funky bigendian order... */
587 val = (val & 0xFFU) << 8 | (val >> 8);
588 chip = db_chips;
589 chipname = unknown;
590
591 for ( ; chip->chipid; chip++) {
592 if (chip->chipid == (val & 0xFF00U)) {
593 chipname = chip->name;
594 break;
595 }
596 }
597 printk(KERN_INFO "Initializing U300 system on %s baseband chip " \
598 "(chip ID 0x%04x)\n", chipname, val);
599
Linus Walleijbb3cee22009-04-23 10:22:13 +0100600 if ((val & 0xFF00U) != 0xf000 && (val & 0xFF00U) != 0xf100) {
Linus Walleijec8f1252010-08-13 11:31:59 +0200601 printk(KERN_ERR "Platform configured for BS335 " \
Linus Walleijbb3cee22009-04-23 10:22:13 +0100602 " with DB3350 but %s detected, expect problems!",
603 chipname);
604 }
Linus Walleijbb3cee22009-04-23 10:22:13 +0100605}
606
607/*
608 * Some devices and their resources require reserved physical memory from
609 * the end of the available RAM. This function traverses the list of devices
Daniel Mack3ad2f3f2010-02-03 08:01:28 +0800610 * and assigns actual addresses to these.
Linus Walleijbb3cee22009-04-23 10:22:13 +0100611 */
612static void __init u300_assign_physmem(void)
613{
614 unsigned long curr_start = __pa(high_memory);
615 int i, j;
616
617 for (i = 0; i < ARRAY_SIZE(platform_devs); i++) {
618 for (j = 0; j < platform_devs[i]->num_resources; j++) {
619 struct resource *const res =
620 &platform_devs[i]->resource[j];
621
622 if (IORESOURCE_MEM == res->flags &&
623 0 == res->start) {
624 res->start = curr_start;
625 res->end += curr_start;
Joe Perches28f65c112011-06-09 09:13:32 -0700626 curr_start += resource_size(res);
Linus Walleijbb3cee22009-04-23 10:22:13 +0100627
628 printk(KERN_INFO "core.c: Mapping RAM " \
629 "%#x-%#x to device %s:%s\n",
630 res->start, res->end,
631 platform_devs[i]->name, res->name);
632 }
633 }
634 }
635}
636
Linus Walleij234323b2012-08-13 11:35:55 +0200637static void __init u300_init_machine(void)
Linus Walleijbb3cee22009-04-23 10:22:13 +0100638{
639 int i;
640 u16 val;
641
642 /* Check what platform we run and print some status information */
643 u300_init_check_chip();
644
Linus Walleijc7c8c782009-08-14 10:59:05 +0100645 /* Initialize SPI device with some board specifics */
646 u300_spi_init(&pl022_device);
Linus Walleijbb3cee22009-04-23 10:22:13 +0100647
648 /* Register the AMBA devices in the AMBA bus abstraction layer */
Linus Walleijbb3cee22009-04-23 10:22:13 +0100649 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
650 struct amba_device *d = amba_devs[i];
651 amba_device_register(d, &iomem_resource);
652 }
Linus Walleijbb3cee22009-04-23 10:22:13 +0100653
654 u300_assign_physmem();
655
Linus Walleij98da3522011-05-02 20:54:38 +0200656 /* Initialize pinmuxing */
Linus Walleije93bcee2012-02-09 07:23:28 +0100657 pinctrl_register_mappings(u300_pinmux_map,
658 ARRAY_SIZE(u300_pinmux_map));
Linus Walleij98da3522011-05-02 20:54:38 +0200659
Linus Walleij6be2a0c2009-08-13 21:42:01 +0100660 /* Register subdevices on the I2C buses */
661 u300_i2c_register_board_devices();
662
Linus Walleijbb3cee22009-04-23 10:22:13 +0100663 /* Register the platform devices */
664 platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
665
Linus Walleijec8f1252010-08-13 11:31:59 +0200666 /* Register subdevices on the SPI bus */
667 u300_spi_register_board_devices();
668
Linus Walleijc43ed562011-08-09 21:30:01 +0200669 /* Enable SEMI self refresh */
Linus Walleijbb3cee22009-04-23 10:22:13 +0100670 val = readw(U300_SYSCON_VBASE + U300_SYSCON_SMCR) |
671 U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE;
672 writew(val, U300_SYSCON_VBASE + U300_SYSCON_SMCR);
Linus Walleijbb3cee22009-04-23 10:22:13 +0100673}
674
Russell King7e3974b2011-11-05 15:51:25 +0000675/* Forward declare this function from the watchdog */
676void coh901327_watchdog_reset(void);
677
Linus Walleij234323b2012-08-13 11:35:55 +0200678static void u300_restart(char mode, const char *cmd)
Russell King7e3974b2011-11-05 15:51:25 +0000679{
680 switch (mode) {
681 case 's':
682 case 'h':
Russell King7e3974b2011-11-05 15:51:25 +0000683#ifdef CONFIG_COH901327_WATCHDOG
684 coh901327_watchdog_reset();
685#endif
686 break;
687 default:
688 /* Do nothing */
689 break;
690 }
691 /* Wait for system do die/reset. */
692 while (1);
693}
Linus Walleij234323b2012-08-13 11:35:55 +0200694
695MACHINE_START(U300, "Ericsson AB U335 S335/B335 Prototype Board")
696 /* Maintainer: Linus Walleij <linus.walleij@stericsson.com> */
697 .atag_offset = 0x100,
698 .map_io = u300_map_io,
Linus Walleijd4a31ee2012-10-17 13:16:46 +0200699 .nr_irqs = 0,
Linus Walleij234323b2012-08-13 11:35:55 +0200700 .init_irq = u300_init_irq,
Stephen Warren6bb27d72012-11-08 12:40:59 -0700701 .init_time = u300_timer_init,
Linus Walleij234323b2012-08-13 11:35:55 +0200702 .init_machine = u300_init_machine,
703 .restart = u300_restart,
704MACHINE_END
Linus Walleij978577e2013-04-08 11:38:50 +0200705
706#ifdef CONFIG_OF
707
Linus Walleijcf4af862013-04-19 14:56:46 +0200708static struct pl022_ssp_controller spi_plat_data = {
709 /* If you have several SPI buses this varies, we have only bus 0 */
710 .bus_id = 0,
711 /*
712 * On the APP CPU GPIO 4, 5 and 6 are connected as generic
713 * chip selects for SPI. (Same on U330, U335 and U365.)
714 * TODO: make sure the GPIO driver can select these properly
715 * and do padmuxing accordingly too.
716 */
717 .num_chipselect = 3,
718 .enable_dma = 1,
719 .dma_filter = coh901318_filter_id,
720 .dma_rx_param = (void *) U300_DMA_SPI_RX,
721 .dma_tx_param = (void *) U300_DMA_SPI_TX,
722};
723
Linus Walleij978577e2013-04-08 11:38:50 +0200724/* These are mostly to get the right device names for the clock lookups */
725static struct of_dev_auxdata u300_auxdata_lookup[] __initdata = {
726 OF_DEV_AUXDATA("stericsson,pinctrl-u300", U300_SYSCON_BASE,
727 "pinctrl-u300", NULL),
728 OF_DEV_AUXDATA("stericsson,gpio-coh901", U300_GPIO_BASE,
729 "u300-gpio", &u300_gpio_plat),
Linus Walleij63a62ec2013-04-19 12:59:59 +0200730 OF_DEV_AUXDATA("stericsson,coh901327", U300_WDOG_BASE,
731 "coh901327_wdog", NULL),
Linus Walleijae87bb82013-04-19 13:22:57 +0200732 OF_DEV_AUXDATA("stericsson,coh901331", U300_RTC_BASE,
733 "rtc-coh901331", NULL),
Linus Walleij39738cc2013-04-19 13:44:25 +0200734 OF_DEV_AUXDATA("stericsson,coh901318", U300_DMAC_BASE,
735 "coh901318", NULL),
Linus Walleijd1346362013-04-22 11:00:02 +0200736 OF_DEV_AUXDATA("stericsson,fsmc-nand", U300_NAND_IF_PHYS_BASE,
737 "fsmc-nand", NULL),
Linus Walleij978577e2013-04-08 11:38:50 +0200738 OF_DEV_AUXDATA("arm,primecell", U300_UART0_BASE,
739 "uart0", &uart0_plat_data),
740 OF_DEV_AUXDATA("arm,primecell", U300_UART1_BASE,
741 "uart1", &uart1_plat_data),
Linus Walleijcf4af862013-04-19 14:56:46 +0200742 OF_DEV_AUXDATA("arm,primecell", U300_SPI_BASE,
743 "pl022", &spi_plat_data),
Linus Walleijc023b8b2013-04-11 15:13:39 +0200744 OF_DEV_AUXDATA("st,ddci2c", U300_I2C0_BASE,
745 "stu300.0", NULL),
746 OF_DEV_AUXDATA("st,ddci2c", U300_I2C1_BASE,
747 "stu300.1", NULL),
Linus Walleij978577e2013-04-08 11:38:50 +0200748 OF_DEV_AUXDATA("arm,primecell", U300_MMCSD_BASE,
749 "mmci", &mmcsd_platform_data),
750 { /* sentinel */ },
751};
752
753static void __init u300_init_irq_dt(void)
754{
755 struct clk *clk;
756
757 /* initialize clocking early, we want to clock the INTCON */
758 u300_clk_init(U300_SYSCON_VBASE);
759
760 /* Bootstrap EMIF and SEMI clocks */
761 clk = clk_get_sys("pl172", NULL);
762 BUG_ON(IS_ERR(clk));
763 clk_prepare_enable(clk);
764 clk = clk_get_sys("semi", NULL);
765 BUG_ON(IS_ERR(clk));
766 clk_prepare_enable(clk);
767
768 /* Clock the interrupt controller */
769 clk = clk_get_sys("intcon", NULL);
770 BUG_ON(IS_ERR(clk));
771 clk_prepare_enable(clk);
772
773 irqchip_init();
774}
775
776static void __init u300_init_machine_dt(void)
777{
778 u16 val;
779
780 /* Check what platform we run and print some status information */
781 u300_init_check_chip();
782
783 u300_assign_physmem();
784
785 /* Initialize pinmuxing */
786 pinctrl_register_mappings(u300_pinmux_map,
787 ARRAY_SIZE(u300_pinmux_map));
788
789 of_platform_populate(NULL, of_default_bus_match_table,
790 u300_auxdata_lookup, NULL);
791
792 /* Enable SEMI self refresh */
793 val = readw(U300_SYSCON_VBASE + U300_SYSCON_SMCR) |
794 U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE;
795 writew(val, U300_SYSCON_VBASE + U300_SYSCON_SMCR);
796}
797
798static const char * u300_board_compat[] = {
799 "stericsson,u300",
800 NULL,
801};
802
803DT_MACHINE_START(U300_DT, "U300 S335/B335 (Device Tree)")
804 .map_io = u300_map_io,
805 .init_irq = u300_init_irq_dt,
806 .init_time = clocksource_of_init,
807 .init_machine = u300_init_machine_dt,
808 .restart = u300_restart,
809 .dt_compat = u300_board_compat,
810MACHINE_END
811
812#endif /* CONFIG_OF */