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