blob: a683d17b2ce43ad5380186eaaa214f862f6748b7 [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 Walleijec8f1252010-08-13 11:31:59 +020022#include <linux/amba/serial.h>
Linus Walleijbb3cee22009-04-23 10:22:13 +010023#include <linux/platform_device.h>
24#include <linux/gpio.h>
Linus Walleijb7276b22010-08-05 07:58:58 +010025#include <linux/clk.h>
26#include <linux/err.h>
Linus Walleij93ac5a52010-09-13 00:35:37 +020027#include <linux/mtd/nand.h>
28#include <linux/mtd/fsmc.h>
Linus Walleij98da3522011-05-02 20:54:38 +020029#include <linux/pinctrl/machine.h>
Linus Walleij51dddfe2012-01-20 17:53:15 +010030#include <linux/pinctrl/pinconf-generic.h>
Jon Medhurstd70a5962011-08-04 15:41:42 +010031#include <linux/dma-mapping.h>
Linus Walleij50667d62012-06-19 23:44:25 +020032#include <linux/platform_data/clk-u300.h>
Linus Walleij65172852012-08-13 10:56:43 +020033#include <linux/platform_data/pinctrl-coh901.h>
Linus Walleij9f575d92013-01-04 10:35:06 +010034#include <linux/platform_data/dma-coh901318.h>
Rob Herring9e47b8b2013-01-07 09:45:59 -060035#include <linux/irqchip/arm-vic.h>
Linus Walleijbb3cee22009-04-23 10:22:13 +010036
37#include <asm/types.h>
38#include <asm/setup.h>
39#include <asm/memory.h>
Linus Walleijbb3cee22009-04-23 10:22:13 +010040#include <asm/mach/map.h>
Linus Walleij234323b2012-08-13 11:35:55 +020041#include <asm/mach-types.h>
42#include <asm/mach/arch.h>
Linus Walleijbb3cee22009-04-23 10:22:13 +010043
44#include <mach/hardware.h>
45#include <mach/syscon.h>
Linus Walleija4fe2922012-08-13 13:49:45 +020046#include <mach/irqs.h>
Linus Walleijbb3cee22009-04-23 10:22:13 +010047
Linus Walleij234323b2012-08-13 11:35:55 +020048#include "timer.h"
Linus Walleijc7c8c782009-08-14 10:59:05 +010049#include "spi.h"
Linus Walleij6be2a0c2009-08-13 21:42:01 +010050#include "i2c.h"
Linus Walleija64ae392012-02-20 21:26:30 +010051#include "u300-gpio.h"
Linus Walleijbb3cee22009-04-23 10:22:13 +010052
53/*
54 * Static I/O mappings that are needed for booting the U300 platforms. The
55 * only things we need are the areas where we find the timer, syscon and
56 * intcon, since the remaining device drivers will map their own memory
57 * physical to virtual as the need arise.
58 */
59static struct map_desc u300_io_desc[] __initdata = {
60 {
61 .virtual = U300_SLOW_PER_VIRT_BASE,
62 .pfn = __phys_to_pfn(U300_SLOW_PER_PHYS_BASE),
63 .length = SZ_64K,
64 .type = MT_DEVICE,
65 },
66 {
67 .virtual = U300_AHB_PER_VIRT_BASE,
68 .pfn = __phys_to_pfn(U300_AHB_PER_PHYS_BASE),
69 .length = SZ_32K,
70 .type = MT_DEVICE,
71 },
72 {
73 .virtual = U300_FAST_PER_VIRT_BASE,
74 .pfn = __phys_to_pfn(U300_FAST_PER_PHYS_BASE),
75 .length = SZ_32K,
76 .type = MT_DEVICE,
77 },
Linus Walleijbb3cee22009-04-23 10:22:13 +010078};
79
Linus Walleij234323b2012-08-13 11:35:55 +020080static void __init u300_map_io(void)
Linus Walleijbb3cee22009-04-23 10:22:13 +010081{
82 iotable_init(u300_io_desc, ARRAY_SIZE(u300_io_desc));
83}
84
85/*
86 * Declaration of devices found on the U300 board and
87 * their respective memory locations.
88 */
Linus Walleijec8f1252010-08-13 11:31:59 +020089
90static struct amba_pl011_data uart0_plat_data = {
91#ifdef CONFIG_COH901318
92 .dma_filter = coh901318_filter_id,
93 .dma_rx_param = (void *) U300_DMA_UART0_RX,
94 .dma_tx_param = (void *) U300_DMA_UART0_TX,
95#endif
96};
97
Russell King6db2a452011-12-18 15:26:38 +000098/* Slow device at 0x3000 offset */
99static AMBA_APB_DEVICE(uart0, "uart0", 0, U300_UART0_BASE,
100 { IRQ_U300_UART0 }, &uart0_plat_data);
Linus Walleijbb3cee22009-04-23 10:22:13 +0100101
102/* The U335 have an additional UART1 on the APP CPU */
Linus Walleijec8f1252010-08-13 11:31:59 +0200103static struct amba_pl011_data uart1_plat_data = {
104#ifdef CONFIG_COH901318
105 .dma_filter = coh901318_filter_id,
106 .dma_rx_param = (void *) U300_DMA_UART1_RX,
107 .dma_tx_param = (void *) U300_DMA_UART1_TX,
108#endif
109};
110
Russell King6db2a452011-12-18 15:26:38 +0000111/* Fast device at 0x7000 offset */
112static AMBA_APB_DEVICE(uart1, "uart1", 0, U300_UART1_BASE,
113 { IRQ_U300_UART1 }, &uart1_plat_data);
Linus Walleijbb3cee22009-04-23 10:22:13 +0100114
Russell King6db2a452011-12-18 15:26:38 +0000115/* AHB device at 0x4000 offset */
116static AMBA_APB_DEVICE(pl172, "pl172", 0, U300_EMIF_CFG_BASE, { }, NULL);
Linus Walleijbb3cee22009-04-23 10:22:13 +0100117
Russell King6db2a452011-12-18 15:26:38 +0000118/* Fast device at 0x6000 offset */
119static AMBA_APB_DEVICE(pl022, "pl022", 0, U300_SPI_BASE,
120 { IRQ_U300_SPI }, NULL);
Linus Walleijbb3cee22009-04-23 10:22:13 +0100121
Russell King6db2a452011-12-18 15:26:38 +0000122/* Fast device at 0x1000 offset */
123#define U300_MMCSD_IRQS { IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 }
124
Linus Walleija64ae392012-02-20 21:26:30 +0100125static struct mmci_platform_data mmcsd_platform_data = {
126 /*
127 * Do not set ocr_mask or voltage translation function,
128 * we have a regulator we can control instead.
129 */
130 .f_max = 24000000,
131 .gpio_wp = -1,
132 .gpio_cd = U300_GPIO_PIN_MMC_CD,
133 .cd_invert = true,
134 .capabilities = MMC_CAP_MMC_HIGHSPEED |
135 MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
136#ifdef CONFIG_COH901318
137 .dma_filter = coh901318_filter_id,
138 .dma_rx_param = (void *) U300_DMA_MMCSD_RX_TX,
139 /* Don't specify a TX channel, this RX channel is bidirectional */
140#endif
141};
142
Russell King6db2a452011-12-18 15:26:38 +0000143static AMBA_APB_DEVICE(mmcsd, "mmci", 0, U300_MMCSD_BASE,
Linus Walleija64ae392012-02-20 21:26:30 +0100144 U300_MMCSD_IRQS, &mmcsd_platform_data);
Linus Walleijbb3cee22009-04-23 10:22:13 +0100145
146/*
147 * The order of device declaration may be important, since some devices
148 * have dependencies on other devices being initialized first.
149 */
150static struct amba_device *amba_devs[] __initdata = {
151 &uart0_device,
Linus Walleijbb3cee22009-04-23 10:22:13 +0100152 &uart1_device,
Linus Walleijbb3cee22009-04-23 10:22:13 +0100153 &pl022_device,
154 &pl172_device,
155 &mmcsd_device,
156};
157
158/* Here follows a list of all hw resources that the platform devices
159 * allocate. Note, clock dependencies are not included
160 */
161
162static struct resource gpio_resources[] = {
163 {
164 .start = U300_GPIO_BASE,
165 .end = (U300_GPIO_BASE + SZ_4K - 1),
166 .flags = IORESOURCE_MEM,
167 },
168 {
169 .name = "gpio0",
170 .start = IRQ_U300_GPIO_PORT0,
171 .end = IRQ_U300_GPIO_PORT0,
172 .flags = IORESOURCE_IRQ,
173 },
174 {
175 .name = "gpio1",
176 .start = IRQ_U300_GPIO_PORT1,
177 .end = IRQ_U300_GPIO_PORT1,
178 .flags = IORESOURCE_IRQ,
179 },
180 {
181 .name = "gpio2",
182 .start = IRQ_U300_GPIO_PORT2,
183 .end = IRQ_U300_GPIO_PORT2,
184 .flags = IORESOURCE_IRQ,
185 },
Linus Walleijbb3cee22009-04-23 10:22:13 +0100186 {
187 .name = "gpio3",
188 .start = IRQ_U300_GPIO_PORT3,
189 .end = IRQ_U300_GPIO_PORT3,
190 .flags = IORESOURCE_IRQ,
191 },
192 {
193 .name = "gpio4",
194 .start = IRQ_U300_GPIO_PORT4,
195 .end = IRQ_U300_GPIO_PORT4,
196 .flags = IORESOURCE_IRQ,
197 },
Linus Walleijbb3cee22009-04-23 10:22:13 +0100198 {
199 .name = "gpio5",
200 .start = IRQ_U300_GPIO_PORT5,
201 .end = IRQ_U300_GPIO_PORT5,
202 .flags = IORESOURCE_IRQ,
203 },
204 {
205 .name = "gpio6",
206 .start = IRQ_U300_GPIO_PORT6,
207 .end = IRQ_U300_GPIO_PORT6,
208 .flags = IORESOURCE_IRQ,
209 },
Linus Walleijbb3cee22009-04-23 10:22:13 +0100210};
211
212static struct resource keypad_resources[] = {
213 {
214 .start = U300_KEYPAD_BASE,
215 .end = U300_KEYPAD_BASE + SZ_4K - 1,
216 .flags = IORESOURCE_MEM,
217 },
218 {
219 .name = "coh901461-press",
220 .start = IRQ_U300_KEYPAD_KEYBF,
221 .end = IRQ_U300_KEYPAD_KEYBF,
222 .flags = IORESOURCE_IRQ,
223 },
224 {
225 .name = "coh901461-release",
226 .start = IRQ_U300_KEYPAD_KEYBR,
227 .end = IRQ_U300_KEYPAD_KEYBR,
228 .flags = IORESOURCE_IRQ,
229 },
230};
231
232static struct resource rtc_resources[] = {
233 {
234 .start = U300_RTC_BASE,
235 .end = U300_RTC_BASE + SZ_4K - 1,
236 .flags = IORESOURCE_MEM,
237 },
238 {
239 .start = IRQ_U300_RTC,
240 .end = IRQ_U300_RTC,
241 .flags = IORESOURCE_IRQ,
242 },
243};
244
245/*
246 * Fsmc does have IRQs: #43 and #44 (NFIF and NFIF2)
247 * but these are not yet used by the driver.
248 */
249static struct resource fsmc_resources[] = {
250 {
Jean-Christophe PLAGNIOL-VILLARD6d7b42a2012-10-04 15:14:16 +0200251 .name = "nand_addr",
252 .start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE,
253 .end = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE + SZ_16K - 1,
254 .flags = IORESOURCE_MEM,
255 },
256 {
257 .name = "nand_cmd",
258 .start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE,
259 .end = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE + SZ_16K - 1,
260 .flags = IORESOURCE_MEM,
261 },
262 {
Linus Walleij93ac5a52010-09-13 00:35:37 +0200263 .name = "nand_data",
264 .start = U300_NAND_CS0_PHYS_BASE,
265 .end = U300_NAND_CS0_PHYS_BASE + SZ_16K - 1,
266 .flags = IORESOURCE_MEM,
267 },
268 {
269 .name = "fsmc_regs",
Linus Walleijbb3cee22009-04-23 10:22:13 +0100270 .start = U300_NAND_IF_PHYS_BASE,
271 .end = U300_NAND_IF_PHYS_BASE + SZ_4K - 1,
272 .flags = IORESOURCE_MEM,
273 },
274};
275
276static struct resource i2c0_resources[] = {
277 {
278 .start = U300_I2C0_BASE,
279 .end = U300_I2C0_BASE + SZ_4K - 1,
280 .flags = IORESOURCE_MEM,
281 },
282 {
283 .start = IRQ_U300_I2C0,
284 .end = IRQ_U300_I2C0,
285 .flags = IORESOURCE_IRQ,
286 },
287};
288
289static struct resource i2c1_resources[] = {
290 {
291 .start = U300_I2C1_BASE,
292 .end = U300_I2C1_BASE + SZ_4K - 1,
293 .flags = IORESOURCE_MEM,
294 },
295 {
296 .start = IRQ_U300_I2C1,
297 .end = IRQ_U300_I2C1,
298 .flags = IORESOURCE_IRQ,
299 },
300
301};
302
303static struct resource wdog_resources[] = {
304 {
305 .start = U300_WDOG_BASE,
306 .end = U300_WDOG_BASE + SZ_4K - 1,
307 .flags = IORESOURCE_MEM,
308 },
309 {
310 .start = IRQ_U300_WDOG,
311 .end = IRQ_U300_WDOG,
312 .flags = IORESOURCE_IRQ,
313 }
314};
315
Linus Walleij08d1e2e2009-12-17 09:46:24 +0100316static struct resource dma_resource[] = {
317 {
318 .start = U300_DMAC_BASE,
319 .end = U300_DMAC_BASE + PAGE_SIZE - 1,
320 .flags = IORESOURCE_MEM,
321 },
322 {
323 .start = IRQ_U300_DMA,
324 .end = IRQ_U300_DMA,
325 .flags = IORESOURCE_IRQ,
326 }
327};
328
Linus Walleij08d1e2e2009-12-17 09:46:24 +0100329
Linus Walleij128a06d2012-02-21 14:31:45 +0100330static struct resource pinctrl_resources[] = {
Linus Walleij98da3522011-05-02 20:54:38 +0200331 {
332 .start = U300_SYSCON_BASE,
333 .end = U300_SYSCON_BASE + SZ_4K - 1,
334 .flags = IORESOURCE_MEM,
335 },
336};
337
Linus Walleijbb3cee22009-04-23 10:22:13 +0100338static struct platform_device wdog_device = {
Linus Walleij633e81a2010-01-25 07:18:16 +0100339 .name = "coh901327_wdog",
Linus Walleijbb3cee22009-04-23 10:22:13 +0100340 .id = -1,
341 .num_resources = ARRAY_SIZE(wdog_resources),
342 .resource = wdog_resources,
343};
344
345static struct platform_device i2c0_device = {
Linus Walleij6be2a0c2009-08-13 21:42:01 +0100346 .name = "stu300",
Linus Walleijbb3cee22009-04-23 10:22:13 +0100347 .id = 0,
348 .num_resources = ARRAY_SIZE(i2c0_resources),
349 .resource = i2c0_resources,
350};
351
352static struct platform_device i2c1_device = {
Linus Walleij6be2a0c2009-08-13 21:42:01 +0100353 .name = "stu300",
Linus Walleijbb3cee22009-04-23 10:22:13 +0100354 .id = 1,
355 .num_resources = ARRAY_SIZE(i2c1_resources),
356 .resource = i2c1_resources,
357};
358
Linus Walleij128a06d2012-02-21 14:31:45 +0100359static struct platform_device pinctrl_device = {
360 .name = "pinctrl-u300",
361 .id = -1,
362 .num_resources = ARRAY_SIZE(pinctrl_resources),
363 .resource = pinctrl_resources,
364};
365
Linus Walleijcc890cd2011-09-08 09:04:51 +0100366/*
367 * The different variants have a few different versions of the
368 * GPIO block, with different number of ports.
369 */
370static struct u300_gpio_platform u300_gpio_plat = {
Linus Walleijcc890cd2011-09-08 09:04:51 +0100371 .ports = 7,
Linus Walleijcc890cd2011-09-08 09:04:51 +0100372 .gpio_base = 0,
Linus Walleijcc890cd2011-09-08 09:04:51 +0100373};
374
Linus Walleijbb3cee22009-04-23 10:22:13 +0100375static struct platform_device gpio_device = {
376 .name = "u300-gpio",
377 .id = -1,
378 .num_resources = ARRAY_SIZE(gpio_resources),
379 .resource = gpio_resources,
Linus Walleijcc890cd2011-09-08 09:04:51 +0100380 .dev = {
381 .platform_data = &u300_gpio_plat,
382 },
Linus Walleijbb3cee22009-04-23 10:22:13 +0100383};
384
385static struct platform_device keypad_device = {
386 .name = "keypad",
387 .id = -1,
388 .num_resources = ARRAY_SIZE(keypad_resources),
389 .resource = keypad_resources,
390};
391
392static struct platform_device rtc_device = {
Linus Walleij378ce742009-11-14 01:03:24 +0100393 .name = "rtc-coh901331",
Linus Walleijbb3cee22009-04-23 10:22:13 +0100394 .id = -1,
395 .num_resources = ARRAY_SIZE(rtc_resources),
396 .resource = rtc_resources,
397};
398
Linus Walleij93ac5a52010-09-13 00:35:37 +0200399static struct mtd_partition u300_partitions[] = {
400 {
401 .name = "bootrecords",
402 .offset = 0,
403 .size = SZ_128K,
404 },
405 {
406 .name = "free",
407 .offset = SZ_128K,
408 .size = 8064 * SZ_1K,
409 },
410 {
411 .name = "platform",
412 .offset = 8192 * SZ_1K,
413 .size = 253952 * SZ_1K,
414 },
415};
416
417static struct fsmc_nand_platform_data nand_platform_data = {
418 .partitions = u300_partitions,
419 .nr_partitions = ARRAY_SIZE(u300_partitions),
420 .options = NAND_SKIP_BBTSCAN,
421 .width = FSMC_NAND_BW8,
422};
423
424static struct platform_device nand_device = {
425 .name = "fsmc-nand",
Linus Walleijbb3cee22009-04-23 10:22:13 +0100426 .id = -1,
Linus Walleijbb3cee22009-04-23 10:22:13 +0100427 .resource = fsmc_resources,
Linus Walleij93ac5a52010-09-13 00:35:37 +0200428 .num_resources = ARRAY_SIZE(fsmc_resources),
429 .dev = {
430 .platform_data = &nand_platform_data,
431 },
Linus Walleijbb3cee22009-04-23 10:22:13 +0100432};
433
Linus Walleij08d1e2e2009-12-17 09:46:24 +0100434static struct platform_device dma_device = {
435 .name = "coh901318",
436 .id = -1,
437 .resource = dma_resource,
438 .num_resources = ARRAY_SIZE(dma_resource),
439 .dev = {
Linus Walleij08d1e2e2009-12-17 09:46:24 +0100440 .coherent_dma_mask = ~0,
441 },
442};
443
Linus Walleij51dddfe2012-01-20 17:53:15 +0100444static unsigned long pin_pullup_conf[] = {
445 PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 1),
446};
447
448static unsigned long pin_highz_conf[] = {
449 PIN_CONF_PACKED(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0),
450};
451
452/* Pin control settings */
Linus Walleije93bcee2012-02-09 07:23:28 +0100453static struct pinctrl_map __initdata u300_pinmux_map[] = {
Linus Walleij98da3522011-05-02 20:54:38 +0200454 /* anonymous maps for chip power and EMIFs */
Stephen Warren1e2082b2012-03-02 13:05:48 -0700455 PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "power"),
456 PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif0"),
457 PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif1"),
Linus Walleij98da3522011-05-02 20:54:38 +0200458 /* per-device maps for MMC/SD, SPI and UART */
Stephen Warren1e2082b2012-03-02 13:05:48 -0700459 PIN_MAP_MUX_GROUP_DEFAULT("mmci", "pinctrl-u300", NULL, "mmc0"),
460 PIN_MAP_MUX_GROUP_DEFAULT("pl022", "pinctrl-u300", NULL, "spi0"),
461 PIN_MAP_MUX_GROUP_DEFAULT("uart0", "pinctrl-u300", NULL, "uart0"),
Linus Walleij51dddfe2012-01-20 17:53:15 +0100462 /* This pin is used for clock return rather than GPIO */
463 PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO APP GPIO 11",
464 pin_pullup_conf),
465 /* This pin is used for card detect */
466 PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO MS INS",
467 pin_highz_conf),
Linus Walleij98da3522011-05-02 20:54:38 +0200468};
469
Linus Walleijbb3cee22009-04-23 10:22:13 +0100470/*
471 * Notice that AMBA devices are initialized before platform devices.
472 *
473 */
474static struct platform_device *platform_devs[] __initdata = {
Linus Walleij08d1e2e2009-12-17 09:46:24 +0100475 &dma_device,
Linus Walleijbb3cee22009-04-23 10:22:13 +0100476 &i2c0_device,
477 &i2c1_device,
478 &keypad_device,
479 &rtc_device,
Linus Walleij8604ac32012-11-20 14:42:47 +0100480 &pinctrl_device,
Linus Walleijbb3cee22009-04-23 10:22:13 +0100481 &gpio_device,
Linus Walleij93ac5a52010-09-13 00:35:37 +0200482 &nand_device,
Linus Walleijbb3cee22009-04-23 10:22:13 +0100483 &wdog_device,
Linus Walleijbb3cee22009-04-23 10:22:13 +0100484};
485
Linus Walleijbb3cee22009-04-23 10:22:13 +0100486/*
487 * Interrupts: the U300 platforms have two pl190 ARM PrimeCells connected
488 * together so some interrupts are connected to the first one and some
489 * to the second one.
490 */
Linus Walleij234323b2012-08-13 11:35:55 +0200491static void __init u300_init_irq(void)
Linus Walleijbb3cee22009-04-23 10:22:13 +0100492{
493 u32 mask[2] = {0, 0};
Linus Walleijb7276b22010-08-05 07:58:58 +0100494 struct clk *clk;
Linus Walleijbb3cee22009-04-23 10:22:13 +0100495 int i;
496
Linus Walleij379aae52010-08-05 07:58:13 +0100497 /* initialize clocking early, we want to clock the INTCON */
Linus Walleij50667d62012-06-19 23:44:25 +0200498 u300_clk_init(U300_SYSCON_VBASE);
499
500 /* Bootstrap EMIF and SEMI clocks */
501 clk = clk_get_sys("pl172", NULL);
502 BUG_ON(IS_ERR(clk));
503 clk_prepare_enable(clk);
504 clk = clk_get_sys("semi", NULL);
505 BUG_ON(IS_ERR(clk));
506 clk_prepare_enable(clk);
Linus Walleij379aae52010-08-05 07:58:13 +0100507
Linus Walleijb7276b22010-08-05 07:58:58 +0100508 /* Clock the interrupt controller */
509 clk = clk_get_sys("intcon", NULL);
510 BUG_ON(IS_ERR(clk));
Linus Walleij50667d62012-06-19 23:44:25 +0200511 clk_prepare_enable(clk);
Linus Walleijb7276b22010-08-05 07:58:58 +0100512
Linus Walleijcc890cd2011-09-08 09:04:51 +0100513 for (i = 0; i < U300_VIC_IRQS_END; i++)
Linus Walleijbb3cee22009-04-23 10:22:13 +0100514 set_bit(i, (unsigned long *) &mask[0]);
Linus Walleij13445002012-04-18 15:29:58 +0200515 vic_init((void __iomem *) U300_INTCON0_VBASE, IRQ_U300_INTCON0_START,
516 mask[0], mask[0]);
517 vic_init((void __iomem *) U300_INTCON1_VBASE, IRQ_U300_INTCON1_START,
518 mask[1], mask[1]);
Linus Walleijbb3cee22009-04-23 10:22:13 +0100519}
520
521
522/*
523 * U300 platforms peripheral handling
524 */
525struct db_chip {
526 u16 chipid;
527 const char *name;
528};
529
530/*
531 * This is a list of the Digital Baseband chips used in the U300 platform.
532 */
533static struct db_chip db_chips[] __initdata = {
534 {
535 .chipid = 0xb800,
536 .name = "DB3000",
537 },
538 {
539 .chipid = 0xc000,
540 .name = "DB3100",
541 },
542 {
543 .chipid = 0xc800,
544 .name = "DB3150",
545 },
546 {
547 .chipid = 0xd800,
548 .name = "DB3200",
549 },
550 {
551 .chipid = 0xe000,
552 .name = "DB3250",
553 },
554 {
555 .chipid = 0xe800,
556 .name = "DB3210",
557 },
558 {
559 .chipid = 0xf000,
560 .name = "DB3350 P1x",
561 },
562 {
563 .chipid = 0xf100,
564 .name = "DB3350 P2x",
565 },
566 {
567 .chipid = 0x0000, /* List terminator */
568 .name = NULL,
569 }
570};
571
Linus Walleija2bb9f42009-08-13 21:57:22 +0100572static void __init u300_init_check_chip(void)
Linus Walleijbb3cee22009-04-23 10:22:13 +0100573{
574
575 u16 val;
576 struct db_chip *chip;
577 const char *chipname;
578 const char unknown[] = "UNKNOWN";
579
580 /* Read out and print chip ID */
581 val = readw(U300_SYSCON_VBASE + U300_SYSCON_CIDR);
582 /* This is in funky bigendian order... */
583 val = (val & 0xFFU) << 8 | (val >> 8);
584 chip = db_chips;
585 chipname = unknown;
586
587 for ( ; chip->chipid; chip++) {
588 if (chip->chipid == (val & 0xFF00U)) {
589 chipname = chip->name;
590 break;
591 }
592 }
593 printk(KERN_INFO "Initializing U300 system on %s baseband chip " \
594 "(chip ID 0x%04x)\n", chipname, val);
595
Linus Walleijbb3cee22009-04-23 10:22:13 +0100596 if ((val & 0xFF00U) != 0xf000 && (val & 0xFF00U) != 0xf100) {
Linus Walleijec8f1252010-08-13 11:31:59 +0200597 printk(KERN_ERR "Platform configured for BS335 " \
Linus Walleijbb3cee22009-04-23 10:22:13 +0100598 " with DB3350 but %s detected, expect problems!",
599 chipname);
600 }
Linus Walleijbb3cee22009-04-23 10:22:13 +0100601}
602
603/*
604 * Some devices and their resources require reserved physical memory from
605 * the end of the available RAM. This function traverses the list of devices
Daniel Mack3ad2f3f2010-02-03 08:01:28 +0800606 * and assigns actual addresses to these.
Linus Walleijbb3cee22009-04-23 10:22:13 +0100607 */
608static void __init u300_assign_physmem(void)
609{
610 unsigned long curr_start = __pa(high_memory);
611 int i, j;
612
613 for (i = 0; i < ARRAY_SIZE(platform_devs); i++) {
614 for (j = 0; j < platform_devs[i]->num_resources; j++) {
615 struct resource *const res =
616 &platform_devs[i]->resource[j];
617
618 if (IORESOURCE_MEM == res->flags &&
619 0 == res->start) {
620 res->start = curr_start;
621 res->end += curr_start;
Joe Perches28f65c112011-06-09 09:13:32 -0700622 curr_start += resource_size(res);
Linus Walleijbb3cee22009-04-23 10:22:13 +0100623
624 printk(KERN_INFO "core.c: Mapping RAM " \
625 "%#x-%#x to device %s:%s\n",
626 res->start, res->end,
627 platform_devs[i]->name, res->name);
628 }
629 }
630 }
631}
632
Linus Walleij234323b2012-08-13 11:35:55 +0200633static void __init u300_init_machine(void)
Linus Walleijbb3cee22009-04-23 10:22:13 +0100634{
635 int i;
636 u16 val;
637
638 /* Check what platform we run and print some status information */
639 u300_init_check_chip();
640
Linus Walleijc7c8c782009-08-14 10:59:05 +0100641 /* Initialize SPI device with some board specifics */
642 u300_spi_init(&pl022_device);
Linus Walleijbb3cee22009-04-23 10:22:13 +0100643
644 /* Register the AMBA devices in the AMBA bus abstraction layer */
Linus Walleijbb3cee22009-04-23 10:22:13 +0100645 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
646 struct amba_device *d = amba_devs[i];
647 amba_device_register(d, &iomem_resource);
648 }
Linus Walleijbb3cee22009-04-23 10:22:13 +0100649
650 u300_assign_physmem();
651
Linus Walleij98da3522011-05-02 20:54:38 +0200652 /* Initialize pinmuxing */
Linus Walleije93bcee2012-02-09 07:23:28 +0100653 pinctrl_register_mappings(u300_pinmux_map,
654 ARRAY_SIZE(u300_pinmux_map));
Linus Walleij98da3522011-05-02 20:54:38 +0200655
Linus Walleij6be2a0c2009-08-13 21:42:01 +0100656 /* Register subdevices on the I2C buses */
657 u300_i2c_register_board_devices();
658
Linus Walleijbb3cee22009-04-23 10:22:13 +0100659 /* Register the platform devices */
660 platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
661
Linus Walleijec8f1252010-08-13 11:31:59 +0200662 /* Register subdevices on the SPI bus */
663 u300_spi_register_board_devices();
664
Linus Walleijc43ed562011-08-09 21:30:01 +0200665 /* Enable SEMI self refresh */
Linus Walleijbb3cee22009-04-23 10:22:13 +0100666 val = readw(U300_SYSCON_VBASE + U300_SYSCON_SMCR) |
667 U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE;
668 writew(val, U300_SYSCON_VBASE + U300_SYSCON_SMCR);
Linus Walleijbb3cee22009-04-23 10:22:13 +0100669}
670
Russell King7e3974b2011-11-05 15:51:25 +0000671/* Forward declare this function from the watchdog */
672void coh901327_watchdog_reset(void);
673
Linus Walleij234323b2012-08-13 11:35:55 +0200674static void u300_restart(char mode, const char *cmd)
Russell King7e3974b2011-11-05 15:51:25 +0000675{
676 switch (mode) {
677 case 's':
678 case 'h':
Russell King7e3974b2011-11-05 15:51:25 +0000679#ifdef CONFIG_COH901327_WATCHDOG
680 coh901327_watchdog_reset();
681#endif
682 break;
683 default:
684 /* Do nothing */
685 break;
686 }
687 /* Wait for system do die/reset. */
688 while (1);
689}
Linus Walleij234323b2012-08-13 11:35:55 +0200690
691MACHINE_START(U300, "Ericsson AB U335 S335/B335 Prototype Board")
692 /* Maintainer: Linus Walleij <linus.walleij@stericsson.com> */
693 .atag_offset = 0x100,
694 .map_io = u300_map_io,
Linus Walleijd4a31ee2012-10-17 13:16:46 +0200695 .nr_irqs = 0,
Linus Walleij234323b2012-08-13 11:35:55 +0200696 .init_irq = u300_init_irq,
Stephen Warren6bb27d72012-11-08 12:40:59 -0700697 .init_time = u300_timer_init,
Linus Walleij234323b2012-08-13 11:35:55 +0200698 .init_machine = u300_init_machine,
699 .restart = u300_restart,
700MACHINE_END