Commit | Line | Data |
---|---|---|
bb3cee2b LW |
1 | /* |
2 | * | |
3 | * arch/arm/mach-u300/core.c | |
4 | * | |
5 | * | |
fcb28d2e | 6 | * Copyright (C) 2007-2012 ST-Ericsson SA |
bb3cee2b LW |
7 | * 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> | |
98da3529 | 12 | #include <linux/pinctrl/machine.h> |
51dddfe8 | 13 | #include <linux/pinctrl/pinconf-generic.h> |
50667d63 | 14 | #include <linux/platform_data/clk-u300.h> |
978577ea | 15 | #include <linux/irqchip.h> |
cf0ce095 | 16 | #include <linux/of_address.h> |
978577ea LW |
17 | #include <linux/of_platform.h> |
18 | #include <linux/clocksource.h> | |
75a7f3f1 | 19 | #include <linux/clk.h> |
bb3cee2b | 20 | |
bb3cee2b | 21 | #include <asm/mach/map.h> |
234323ba | 22 | #include <asm/mach/arch.h> |
bb3cee2b | 23 | |
4cc4f6d1 LW |
24 | /* |
25 | * These are the large blocks of memory allocated for I/O. | |
26 | * the defines are used for setting up the I/O memory mapping. | |
27 | */ | |
28 | ||
29 | /* NAND Flash CS0 */ | |
30 | #define U300_NAND_CS0_PHYS_BASE 0x80000000 | |
31 | /* NFIF */ | |
32 | #define U300_NAND_IF_PHYS_BASE 0x9f800000 | |
33 | /* ALE, CLE offset for FSMC NAND */ | |
34 | #define PLAT_NAND_CLE (1 << 16) | |
35 | #define PLAT_NAND_ALE (1 << 17) | |
36 | /* AHB Peripherals */ | |
37 | #define U300_AHB_PER_PHYS_BASE 0xa0000000 | |
38 | #define U300_AHB_PER_VIRT_BASE 0xff010000 | |
39 | /* FAST Peripherals */ | |
40 | #define U300_FAST_PER_PHYS_BASE 0xc0000000 | |
41 | #define U300_FAST_PER_VIRT_BASE 0xff020000 | |
42 | /* SLOW Peripherals */ | |
43 | #define U300_SLOW_PER_PHYS_BASE 0xc0010000 | |
44 | #define U300_SLOW_PER_VIRT_BASE 0xff000000 | |
45 | /* Boot ROM */ | |
46 | #define U300_BOOTROM_PHYS_BASE 0xffff0000 | |
47 | #define U300_BOOTROM_VIRT_BASE 0xffff0000 | |
48 | /* SEMI config base */ | |
49 | #define U300_SEMI_CONFIG_BASE 0x2FFE0000 | |
50 | ||
51 | /* | |
52 | * AHB peripherals | |
53 | */ | |
54 | ||
55 | /* AHB Peripherals Bridge Controller */ | |
56 | #define U300_AHB_BRIDGE_BASE (U300_AHB_PER_PHYS_BASE+0x0000) | |
57 | /* Vectored Interrupt Controller 0, servicing 32 interrupts */ | |
58 | #define U300_INTCON0_BASE (U300_AHB_PER_PHYS_BASE+0x1000) | |
59 | #define U300_INTCON0_VBASE IOMEM(U300_AHB_PER_VIRT_BASE+0x1000) | |
60 | /* Vectored Interrupt Controller 1, servicing 32 interrupts */ | |
61 | #define U300_INTCON1_BASE (U300_AHB_PER_PHYS_BASE+0x2000) | |
62 | #define U300_INTCON1_VBASE IOMEM(U300_AHB_PER_VIRT_BASE+0x2000) | |
63 | /* Memory Stick Pro (MSPRO) controller */ | |
64 | #define U300_MSPRO_BASE (U300_AHB_PER_PHYS_BASE+0x3000) | |
65 | /* EMIF Configuration Area */ | |
66 | #define U300_EMIF_CFG_BASE (U300_AHB_PER_PHYS_BASE+0x4000) | |
67 | ||
68 | /* | |
69 | * FAST peripherals | |
70 | */ | |
71 | ||
72 | /* FAST bridge control */ | |
73 | #define U300_FAST_BRIDGE_BASE (U300_FAST_PER_PHYS_BASE+0x0000) | |
74 | /* MMC/SD controller */ | |
75 | #define U300_MMCSD_BASE (U300_FAST_PER_PHYS_BASE+0x1000) | |
76 | /* PCM I2S0 controller */ | |
77 | #define U300_PCM_I2S0_BASE (U300_FAST_PER_PHYS_BASE+0x2000) | |
78 | /* PCM I2S1 controller */ | |
79 | #define U300_PCM_I2S1_BASE (U300_FAST_PER_PHYS_BASE+0x3000) | |
80 | /* I2C0 controller */ | |
81 | #define U300_I2C0_BASE (U300_FAST_PER_PHYS_BASE+0x4000) | |
82 | /* I2C1 controller */ | |
83 | #define U300_I2C1_BASE (U300_FAST_PER_PHYS_BASE+0x5000) | |
84 | /* SPI controller */ | |
85 | #define U300_SPI_BASE (U300_FAST_PER_PHYS_BASE+0x6000) | |
86 | /* Fast UART1 on U335 only */ | |
87 | #define U300_UART1_BASE (U300_FAST_PER_PHYS_BASE+0x7000) | |
88 | ||
89 | /* | |
90 | * SLOW peripherals | |
91 | */ | |
92 | ||
93 | /* SLOW bridge control */ | |
94 | #define U300_SLOW_BRIDGE_BASE (U300_SLOW_PER_PHYS_BASE) | |
95 | /* SYSCON */ | |
96 | #define U300_SYSCON_BASE (U300_SLOW_PER_PHYS_BASE+0x1000) | |
97 | #define U300_SYSCON_VBASE IOMEM(U300_SLOW_PER_VIRT_BASE+0x1000) | |
98 | /* Watchdog */ | |
99 | #define U300_WDOG_BASE (U300_SLOW_PER_PHYS_BASE+0x2000) | |
100 | /* UART0 */ | |
101 | #define U300_UART0_BASE (U300_SLOW_PER_PHYS_BASE+0x3000) | |
102 | /* APP side special timer */ | |
103 | #define U300_TIMER_APP_BASE (U300_SLOW_PER_PHYS_BASE+0x4000) | |
104 | #define U300_TIMER_APP_VBASE IOMEM(U300_SLOW_PER_VIRT_BASE+0x4000) | |
105 | /* Keypad */ | |
106 | #define U300_KEYPAD_BASE (U300_SLOW_PER_PHYS_BASE+0x5000) | |
107 | /* GPIO */ | |
108 | #define U300_GPIO_BASE (U300_SLOW_PER_PHYS_BASE+0x6000) | |
109 | /* RTC */ | |
110 | #define U300_RTC_BASE (U300_SLOW_PER_PHYS_BASE+0x7000) | |
111 | /* Bus tracer */ | |
112 | #define U300_BUSTR_BASE (U300_SLOW_PER_PHYS_BASE+0x8000) | |
113 | /* Event handler (hardware queue) */ | |
114 | #define U300_EVHIST_BASE (U300_SLOW_PER_PHYS_BASE+0x9000) | |
115 | /* Genric Timer */ | |
116 | #define U300_TIMER_BASE (U300_SLOW_PER_PHYS_BASE+0xa000) | |
117 | /* PPM */ | |
118 | #define U300_PPM_BASE (U300_SLOW_PER_PHYS_BASE+0xb000) | |
119 | ||
120 | /* | |
121 | * REST peripherals | |
122 | */ | |
123 | ||
124 | /* ISP (image signal processor) */ | |
125 | #define U300_ISP_BASE (0xA0008000) | |
126 | /* DMA Controller base */ | |
127 | #define U300_DMAC_BASE (0xC0020000) | |
128 | /* MSL Base */ | |
129 | #define U300_MSL_BASE (0xc0022000) | |
130 | /* APEX Base */ | |
131 | #define U300_APEX_BASE (0xc0030000) | |
132 | /* Video Encoder Base */ | |
133 | #define U300_VIDEOENC_BASE (0xc0080000) | |
134 | /* XGAM Base */ | |
135 | #define U300_XGAM_BASE (0xd0000000) | |
0004b017 LW |
136 | |
137 | /* | |
138 | * SYSCON addresses applicable to the core machine. | |
139 | */ | |
140 | ||
141 | /* Chip ID register 16bit (R/-) */ | |
142 | #define U300_SYSCON_CIDR (0x400) | |
143 | /* SMCR */ | |
144 | #define U300_SYSCON_SMCR (0x4d0) | |
145 | #define U300_SYSCON_SMCR_FIELD_MASK (0x000e) | |
146 | #define U300_SYSCON_SMCR_SEMI_SREFACK_IND (0x0008) | |
147 | #define U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE (0x0004) | |
148 | #define U300_SYSCON_SMCR_SEMI_EXT_BOOT_MODE_ENABLE (0x0002) | |
149 | /* CPU_SW_DBGEN Software Debug Enable 16bit (R/W) */ | |
150 | #define U300_SYSCON_CSDR (0x4f0) | |
151 | #define U300_SYSCON_CSDR_SW_DEBUG_ENABLE (0x0001) | |
152 | /* PRINT_CONTROL Print Control 16bit (R/-) */ | |
153 | #define U300_SYSCON_PCR (0x4f8) | |
154 | #define U300_SYSCON_PCR_SERV_IND (0x0001) | |
155 | /* BOOT_CONTROL 16bit (R/-) */ | |
156 | #define U300_SYSCON_BCR (0x4fc) | |
157 | #define U300_SYSCON_BCR_ACC_CPU_SUBSYS_VINITHI_IND (0x0400) | |
158 | #define U300_SYSCON_BCR_APP_CPU_SUBSYS_VINITHI_IND (0x0200) | |
159 | #define U300_SYSCON_BCR_EXTRA_BOOT_OPTION_MASK (0x01FC) | |
160 | #define U300_SYSCON_BCR_APP_BOOT_SERV_MASK (0x0003) | |
bb3cee2b | 161 | |
cf0ce095 LW |
162 | static void __iomem *syscon_base; |
163 | ||
bb3cee2b LW |
164 | /* |
165 | * Static I/O mappings that are needed for booting the U300 platforms. The | |
166 | * only things we need are the areas where we find the timer, syscon and | |
167 | * intcon, since the remaining device drivers will map their own memory | |
168 | * physical to virtual as the need arise. | |
169 | */ | |
170 | static struct map_desc u300_io_desc[] __initdata = { | |
171 | { | |
172 | .virtual = U300_SLOW_PER_VIRT_BASE, | |
173 | .pfn = __phys_to_pfn(U300_SLOW_PER_PHYS_BASE), | |
174 | .length = SZ_64K, | |
175 | .type = MT_DEVICE, | |
176 | }, | |
177 | { | |
178 | .virtual = U300_AHB_PER_VIRT_BASE, | |
179 | .pfn = __phys_to_pfn(U300_AHB_PER_PHYS_BASE), | |
180 | .length = SZ_32K, | |
181 | .type = MT_DEVICE, | |
182 | }, | |
183 | { | |
184 | .virtual = U300_FAST_PER_VIRT_BASE, | |
185 | .pfn = __phys_to_pfn(U300_FAST_PER_PHYS_BASE), | |
186 | .length = SZ_32K, | |
187 | .type = MT_DEVICE, | |
188 | }, | |
bb3cee2b LW |
189 | }; |
190 | ||
234323ba | 191 | static void __init u300_map_io(void) |
bb3cee2b LW |
192 | { |
193 | iotable_init(u300_io_desc, ARRAY_SIZE(u300_io_desc)); | |
194 | } | |
195 | ||
51dddfe8 LW |
196 | static unsigned long pin_pullup_conf[] = { |
197 | PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 1), | |
198 | }; | |
199 | ||
200 | static unsigned long pin_highz_conf[] = { | |
201 | PIN_CONF_PACKED(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0), | |
202 | }; | |
203 | ||
204 | /* Pin control settings */ | |
e93bcee0 | 205 | static struct pinctrl_map __initdata u300_pinmux_map[] = { |
98da3529 | 206 | /* anonymous maps for chip power and EMIFs */ |
1e2082b5 SW |
207 | PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "power"), |
208 | PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif0"), | |
209 | PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif1"), | |
98da3529 | 210 | /* per-device maps for MMC/SD, SPI and UART */ |
1e2082b5 SW |
211 | PIN_MAP_MUX_GROUP_DEFAULT("mmci", "pinctrl-u300", NULL, "mmc0"), |
212 | PIN_MAP_MUX_GROUP_DEFAULT("pl022", "pinctrl-u300", NULL, "spi0"), | |
213 | PIN_MAP_MUX_GROUP_DEFAULT("uart0", "pinctrl-u300", NULL, "uart0"), | |
51dddfe8 LW |
214 | /* This pin is used for clock return rather than GPIO */ |
215 | PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO APP GPIO 11", | |
216 | pin_pullup_conf), | |
217 | /* This pin is used for card detect */ | |
218 | PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO MS INS", | |
219 | pin_highz_conf), | |
98da3529 LW |
220 | }; |
221 | ||
bb3cee2b LW |
222 | struct db_chip { |
223 | u16 chipid; | |
224 | const char *name; | |
225 | }; | |
226 | ||
227 | /* | |
228 | * This is a list of the Digital Baseband chips used in the U300 platform. | |
229 | */ | |
230 | static struct db_chip db_chips[] __initdata = { | |
231 | { | |
232 | .chipid = 0xb800, | |
233 | .name = "DB3000", | |
234 | }, | |
235 | { | |
236 | .chipid = 0xc000, | |
237 | .name = "DB3100", | |
238 | }, | |
239 | { | |
240 | .chipid = 0xc800, | |
241 | .name = "DB3150", | |
242 | }, | |
243 | { | |
244 | .chipid = 0xd800, | |
245 | .name = "DB3200", | |
246 | }, | |
247 | { | |
248 | .chipid = 0xe000, | |
249 | .name = "DB3250", | |
250 | }, | |
251 | { | |
252 | .chipid = 0xe800, | |
253 | .name = "DB3210", | |
254 | }, | |
255 | { | |
256 | .chipid = 0xf000, | |
257 | .name = "DB3350 P1x", | |
258 | }, | |
259 | { | |
260 | .chipid = 0xf100, | |
261 | .name = "DB3350 P2x", | |
262 | }, | |
263 | { | |
264 | .chipid = 0x0000, /* List terminator */ | |
265 | .name = NULL, | |
266 | } | |
267 | }; | |
268 | ||
a2bb9f4d | 269 | static void __init u300_init_check_chip(void) |
bb3cee2b LW |
270 | { |
271 | ||
272 | u16 val; | |
273 | struct db_chip *chip; | |
274 | const char *chipname; | |
275 | const char unknown[] = "UNKNOWN"; | |
276 | ||
277 | /* Read out and print chip ID */ | |
cf0ce095 | 278 | val = readw(syscon_base + U300_SYSCON_CIDR); |
bb3cee2b LW |
279 | /* This is in funky bigendian order... */ |
280 | val = (val & 0xFFU) << 8 | (val >> 8); | |
281 | chip = db_chips; | |
282 | chipname = unknown; | |
283 | ||
284 | for ( ; chip->chipid; chip++) { | |
285 | if (chip->chipid == (val & 0xFF00U)) { | |
286 | chipname = chip->name; | |
287 | break; | |
288 | } | |
289 | } | |
290 | printk(KERN_INFO "Initializing U300 system on %s baseband chip " \ | |
291 | "(chip ID 0x%04x)\n", chipname, val); | |
292 | ||
bb3cee2b | 293 | if ((val & 0xFF00U) != 0xf000 && (val & 0xFF00U) != 0xf100) { |
ec8f1253 | 294 | printk(KERN_ERR "Platform configured for BS335 " \ |
bb3cee2b LW |
295 | " with DB3350 but %s detected, expect problems!", |
296 | chipname); | |
297 | } | |
bb3cee2b LW |
298 | } |
299 | ||
7e3974b2 RK |
300 | /* Forward declare this function from the watchdog */ |
301 | void coh901327_watchdog_reset(void); | |
302 | ||
7b6d864b | 303 | static void u300_restart(enum reboot_mode mode, const char *cmd) |
7e3974b2 RK |
304 | { |
305 | switch (mode) { | |
7b6d864b RH |
306 | case REBOOT_SOFT: |
307 | case REBOOT_HARD: | |
7e3974b2 RK |
308 | #ifdef CONFIG_COH901327_WATCHDOG |
309 | coh901327_watchdog_reset(); | |
310 | #endif | |
311 | break; | |
312 | default: | |
313 | /* Do nothing */ | |
314 | break; | |
315 | } | |
316 | /* Wait for system do die/reset. */ | |
317 | while (1); | |
318 | } | |
234323ba | 319 | |
978577ea LW |
320 | /* These are mostly to get the right device names for the clock lookups */ |
321 | static struct of_dev_auxdata u300_auxdata_lookup[] __initdata = { | |
322 | OF_DEV_AUXDATA("stericsson,pinctrl-u300", U300_SYSCON_BASE, | |
323 | "pinctrl-u300", NULL), | |
324 | OF_DEV_AUXDATA("stericsson,gpio-coh901", U300_GPIO_BASE, | |
b263e9b8 | 325 | "u300-gpio", NULL), |
63a62ec0 LW |
326 | OF_DEV_AUXDATA("stericsson,coh901327", U300_WDOG_BASE, |
327 | "coh901327_wdog", NULL), | |
ae87bb8e LW |
328 | OF_DEV_AUXDATA("stericsson,coh901331", U300_RTC_BASE, |
329 | "rtc-coh901331", NULL), | |
39738cc9 LW |
330 | OF_DEV_AUXDATA("stericsson,coh901318", U300_DMAC_BASE, |
331 | "coh901318", NULL), | |
d134636f LW |
332 | OF_DEV_AUXDATA("stericsson,fsmc-nand", U300_NAND_IF_PHYS_BASE, |
333 | "fsmc-nand", NULL), | |
978577ea | 334 | OF_DEV_AUXDATA("arm,primecell", U300_UART0_BASE, |
75a7f3f1 | 335 | "uart0", NULL), |
978577ea | 336 | OF_DEV_AUXDATA("arm,primecell", U300_UART1_BASE, |
75a7f3f1 | 337 | "uart1", NULL), |
cf4af867 | 338 | OF_DEV_AUXDATA("arm,primecell", U300_SPI_BASE, |
75a7f3f1 | 339 | "pl022", NULL), |
c023b8b2 LW |
340 | OF_DEV_AUXDATA("st,ddci2c", U300_I2C0_BASE, |
341 | "stu300.0", NULL), | |
342 | OF_DEV_AUXDATA("st,ddci2c", U300_I2C1_BASE, | |
343 | "stu300.1", NULL), | |
978577ea | 344 | OF_DEV_AUXDATA("arm,primecell", U300_MMCSD_BASE, |
75a7f3f1 | 345 | "mmci", NULL), |
978577ea LW |
346 | { /* sentinel */ }, |
347 | }; | |
348 | ||
349 | static void __init u300_init_irq_dt(void) | |
350 | { | |
cf0ce095 | 351 | struct device_node *syscon; |
978577ea LW |
352 | struct clk *clk; |
353 | ||
cf0ce095 LW |
354 | syscon = of_find_node_by_path("/syscon@c0011000"); |
355 | if (!syscon) { | |
356 | pr_crit("could not find syscon node\n"); | |
357 | return; | |
358 | } | |
359 | syscon_base = of_iomap(syscon, 0); | |
360 | if (!syscon_base) { | |
361 | pr_crit("could not remap syscon\n"); | |
362 | return; | |
363 | } | |
978577ea | 364 | /* initialize clocking early, we want to clock the INTCON */ |
cf0ce095 | 365 | u300_clk_init(syscon_base); |
978577ea LW |
366 | |
367 | /* Bootstrap EMIF and SEMI clocks */ | |
368 | clk = clk_get_sys("pl172", NULL); | |
369 | BUG_ON(IS_ERR(clk)); | |
370 | clk_prepare_enable(clk); | |
371 | clk = clk_get_sys("semi", NULL); | |
372 | BUG_ON(IS_ERR(clk)); | |
373 | clk_prepare_enable(clk); | |
374 | ||
375 | /* Clock the interrupt controller */ | |
376 | clk = clk_get_sys("intcon", NULL); | |
377 | BUG_ON(IS_ERR(clk)); | |
378 | clk_prepare_enable(clk); | |
379 | ||
380 | irqchip_init(); | |
381 | } | |
382 | ||
383 | static void __init u300_init_machine_dt(void) | |
384 | { | |
385 | u16 val; | |
386 | ||
387 | /* Check what platform we run and print some status information */ | |
388 | u300_init_check_chip(); | |
389 | ||
978577ea LW |
390 | /* Initialize pinmuxing */ |
391 | pinctrl_register_mappings(u300_pinmux_map, | |
392 | ARRAY_SIZE(u300_pinmux_map)); | |
393 | ||
435ebcbc | 394 | of_platform_default_populate(NULL, u300_auxdata_lookup, NULL); |
978577ea LW |
395 | |
396 | /* Enable SEMI self refresh */ | |
cf0ce095 | 397 | val = readw(syscon_base + U300_SYSCON_SMCR) | |
978577ea | 398 | U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE; |
cf0ce095 | 399 | writew(val, syscon_base + U300_SYSCON_SMCR); |
978577ea LW |
400 | } |
401 | ||
402 | static const char * u300_board_compat[] = { | |
403 | "stericsson,u300", | |
404 | NULL, | |
405 | }; | |
406 | ||
407 | DT_MACHINE_START(U300_DT, "U300 S335/B335 (Device Tree)") | |
408 | .map_io = u300_map_io, | |
409 | .init_irq = u300_init_irq_dt, | |
3722ed23 | 410 | .init_time = clocksource_probe, |
978577ea LW |
411 | .init_machine = u300_init_machine_dt, |
412 | .restart = u300_restart, | |
413 | .dt_compat = u300_board_compat, | |
414 | MACHINE_END |