blob: 13d48125b89b2a7db86d3d92c2fa296543d82d4d [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>
Linus Walleij98da3522011-05-02 20:54:38 +020012#include <linux/pinctrl/machine.h>
Linus Walleij51dddfe2012-01-20 17:53:15 +010013#include <linux/pinctrl/pinconf-generic.h>
Linus Walleij50667d62012-06-19 23:44:25 +020014#include <linux/platform_data/clk-u300.h>
Linus Walleij65172852012-08-13 10:56:43 +020015#include <linux/platform_data/pinctrl-coh901.h>
Linus Walleij978577e2013-04-08 11:38:50 +020016#include <linux/irqchip.h>
17#include <linux/of_platform.h>
18#include <linux/clocksource.h>
Linus Walleij75a7f3f2013-04-22 11:29:30 +020019#include <linux/clk.h>
Linus Walleijbb3cee22009-04-23 10:22:13 +010020
Linus Walleijbb3cee22009-04-23 10:22:13 +010021#include <asm/mach/map.h>
Linus Walleij234323b2012-08-13 11:35:55 +020022#include <asm/mach/arch.h>
Linus Walleijbb3cee22009-04-23 10:22:13 +010023
Linus Walleij75a7f3f2013-04-22 11:29:30 +020024#include <mach/u300-regs.h>
Linus Walleijbb3cee22009-04-23 10:22:13 +010025#include <mach/syscon.h>
Linus Walleijbb3cee22009-04-23 10:22:13 +010026
27/*
28 * Static I/O mappings that are needed for booting the U300 platforms. The
29 * only things we need are the areas where we find the timer, syscon and
30 * intcon, since the remaining device drivers will map their own memory
31 * physical to virtual as the need arise.
32 */
33static struct map_desc u300_io_desc[] __initdata = {
34 {
35 .virtual = U300_SLOW_PER_VIRT_BASE,
36 .pfn = __phys_to_pfn(U300_SLOW_PER_PHYS_BASE),
37 .length = SZ_64K,
38 .type = MT_DEVICE,
39 },
40 {
41 .virtual = U300_AHB_PER_VIRT_BASE,
42 .pfn = __phys_to_pfn(U300_AHB_PER_PHYS_BASE),
43 .length = SZ_32K,
44 .type = MT_DEVICE,
45 },
46 {
47 .virtual = U300_FAST_PER_VIRT_BASE,
48 .pfn = __phys_to_pfn(U300_FAST_PER_PHYS_BASE),
49 .length = SZ_32K,
50 .type = MT_DEVICE,
51 },
Linus Walleijbb3cee22009-04-23 10:22:13 +010052};
53
Linus Walleij234323b2012-08-13 11:35:55 +020054static void __init u300_map_io(void)
Linus Walleijbb3cee22009-04-23 10:22:13 +010055{
56 iotable_init(u300_io_desc, ARRAY_SIZE(u300_io_desc));
57}
58
59/*
Linus Walleijcc890cd2011-09-08 09:04:51 +010060 * The different variants have a few different versions of the
61 * GPIO block, with different number of ports.
62 */
63static struct u300_gpio_platform u300_gpio_plat = {
Linus Walleijcc890cd2011-09-08 09:04:51 +010064 .ports = 7,
Linus Walleijcc890cd2011-09-08 09:04:51 +010065 .gpio_base = 0,
Linus Walleijcc890cd2011-09-08 09:04:51 +010066};
67
Linus Walleij51dddfe2012-01-20 17:53:15 +010068static unsigned long pin_pullup_conf[] = {
69 PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 1),
70};
71
72static unsigned long pin_highz_conf[] = {
73 PIN_CONF_PACKED(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0),
74};
75
76/* Pin control settings */
Linus Walleije93bcee2012-02-09 07:23:28 +010077static struct pinctrl_map __initdata u300_pinmux_map[] = {
Linus Walleij98da3522011-05-02 20:54:38 +020078 /* anonymous maps for chip power and EMIFs */
Stephen Warren1e2082b2012-03-02 13:05:48 -070079 PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "power"),
80 PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif0"),
81 PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif1"),
Linus Walleij98da3522011-05-02 20:54:38 +020082 /* per-device maps for MMC/SD, SPI and UART */
Stephen Warren1e2082b2012-03-02 13:05:48 -070083 PIN_MAP_MUX_GROUP_DEFAULT("mmci", "pinctrl-u300", NULL, "mmc0"),
84 PIN_MAP_MUX_GROUP_DEFAULT("pl022", "pinctrl-u300", NULL, "spi0"),
85 PIN_MAP_MUX_GROUP_DEFAULT("uart0", "pinctrl-u300", NULL, "uart0"),
Linus Walleij51dddfe2012-01-20 17:53:15 +010086 /* This pin is used for clock return rather than GPIO */
87 PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO APP GPIO 11",
88 pin_pullup_conf),
89 /* This pin is used for card detect */
90 PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO MS INS",
91 pin_highz_conf),
Linus Walleij98da3522011-05-02 20:54:38 +020092};
93
Linus Walleijbb3cee22009-04-23 10:22:13 +010094struct db_chip {
95 u16 chipid;
96 const char *name;
97};
98
99/*
100 * This is a list of the Digital Baseband chips used in the U300 platform.
101 */
102static struct db_chip db_chips[] __initdata = {
103 {
104 .chipid = 0xb800,
105 .name = "DB3000",
106 },
107 {
108 .chipid = 0xc000,
109 .name = "DB3100",
110 },
111 {
112 .chipid = 0xc800,
113 .name = "DB3150",
114 },
115 {
116 .chipid = 0xd800,
117 .name = "DB3200",
118 },
119 {
120 .chipid = 0xe000,
121 .name = "DB3250",
122 },
123 {
124 .chipid = 0xe800,
125 .name = "DB3210",
126 },
127 {
128 .chipid = 0xf000,
129 .name = "DB3350 P1x",
130 },
131 {
132 .chipid = 0xf100,
133 .name = "DB3350 P2x",
134 },
135 {
136 .chipid = 0x0000, /* List terminator */
137 .name = NULL,
138 }
139};
140
Linus Walleija2bb9f42009-08-13 21:57:22 +0100141static void __init u300_init_check_chip(void)
Linus Walleijbb3cee22009-04-23 10:22:13 +0100142{
143
144 u16 val;
145 struct db_chip *chip;
146 const char *chipname;
147 const char unknown[] = "UNKNOWN";
148
149 /* Read out and print chip ID */
150 val = readw(U300_SYSCON_VBASE + U300_SYSCON_CIDR);
151 /* This is in funky bigendian order... */
152 val = (val & 0xFFU) << 8 | (val >> 8);
153 chip = db_chips;
154 chipname = unknown;
155
156 for ( ; chip->chipid; chip++) {
157 if (chip->chipid == (val & 0xFF00U)) {
158 chipname = chip->name;
159 break;
160 }
161 }
162 printk(KERN_INFO "Initializing U300 system on %s baseband chip " \
163 "(chip ID 0x%04x)\n", chipname, val);
164
Linus Walleijbb3cee22009-04-23 10:22:13 +0100165 if ((val & 0xFF00U) != 0xf000 && (val & 0xFF00U) != 0xf100) {
Linus Walleijec8f1252010-08-13 11:31:59 +0200166 printk(KERN_ERR "Platform configured for BS335 " \
Linus Walleijbb3cee22009-04-23 10:22:13 +0100167 " with DB3350 but %s detected, expect problems!",
168 chipname);
169 }
Linus Walleijbb3cee22009-04-23 10:22:13 +0100170}
171
Russell King7e3974b2011-11-05 15:51:25 +0000172/* Forward declare this function from the watchdog */
173void coh901327_watchdog_reset(void);
174
Linus Walleij234323b2012-08-13 11:35:55 +0200175static void u300_restart(char mode, const char *cmd)
Russell King7e3974b2011-11-05 15:51:25 +0000176{
177 switch (mode) {
178 case 's':
179 case 'h':
Russell King7e3974b2011-11-05 15:51:25 +0000180#ifdef CONFIG_COH901327_WATCHDOG
181 coh901327_watchdog_reset();
182#endif
183 break;
184 default:
185 /* Do nothing */
186 break;
187 }
188 /* Wait for system do die/reset. */
189 while (1);
190}
Linus Walleij234323b2012-08-13 11:35:55 +0200191
Linus Walleij978577e2013-04-08 11:38:50 +0200192/* These are mostly to get the right device names for the clock lookups */
193static struct of_dev_auxdata u300_auxdata_lookup[] __initdata = {
194 OF_DEV_AUXDATA("stericsson,pinctrl-u300", U300_SYSCON_BASE,
195 "pinctrl-u300", NULL),
196 OF_DEV_AUXDATA("stericsson,gpio-coh901", U300_GPIO_BASE,
197 "u300-gpio", &u300_gpio_plat),
Linus Walleij63a62ec2013-04-19 12:59:59 +0200198 OF_DEV_AUXDATA("stericsson,coh901327", U300_WDOG_BASE,
199 "coh901327_wdog", NULL),
Linus Walleijae87bb82013-04-19 13:22:57 +0200200 OF_DEV_AUXDATA("stericsson,coh901331", U300_RTC_BASE,
201 "rtc-coh901331", NULL),
Linus Walleij39738cc2013-04-19 13:44:25 +0200202 OF_DEV_AUXDATA("stericsson,coh901318", U300_DMAC_BASE,
203 "coh901318", NULL),
Linus Walleijd1346362013-04-22 11:00:02 +0200204 OF_DEV_AUXDATA("stericsson,fsmc-nand", U300_NAND_IF_PHYS_BASE,
205 "fsmc-nand", NULL),
Linus Walleij978577e2013-04-08 11:38:50 +0200206 OF_DEV_AUXDATA("arm,primecell", U300_UART0_BASE,
Linus Walleij75a7f3f2013-04-22 11:29:30 +0200207 "uart0", NULL),
Linus Walleij978577e2013-04-08 11:38:50 +0200208 OF_DEV_AUXDATA("arm,primecell", U300_UART1_BASE,
Linus Walleij75a7f3f2013-04-22 11:29:30 +0200209 "uart1", NULL),
Linus Walleijcf4af862013-04-19 14:56:46 +0200210 OF_DEV_AUXDATA("arm,primecell", U300_SPI_BASE,
Linus Walleij75a7f3f2013-04-22 11:29:30 +0200211 "pl022", NULL),
Linus Walleijc023b8b2013-04-11 15:13:39 +0200212 OF_DEV_AUXDATA("st,ddci2c", U300_I2C0_BASE,
213 "stu300.0", NULL),
214 OF_DEV_AUXDATA("st,ddci2c", U300_I2C1_BASE,
215 "stu300.1", NULL),
Linus Walleij978577e2013-04-08 11:38:50 +0200216 OF_DEV_AUXDATA("arm,primecell", U300_MMCSD_BASE,
Linus Walleij75a7f3f2013-04-22 11:29:30 +0200217 "mmci", NULL),
Linus Walleij978577e2013-04-08 11:38:50 +0200218 { /* sentinel */ },
219};
220
221static void __init u300_init_irq_dt(void)
222{
223 struct clk *clk;
224
225 /* initialize clocking early, we want to clock the INTCON */
226 u300_clk_init(U300_SYSCON_VBASE);
227
228 /* Bootstrap EMIF and SEMI clocks */
229 clk = clk_get_sys("pl172", NULL);
230 BUG_ON(IS_ERR(clk));
231 clk_prepare_enable(clk);
232 clk = clk_get_sys("semi", NULL);
233 BUG_ON(IS_ERR(clk));
234 clk_prepare_enable(clk);
235
236 /* Clock the interrupt controller */
237 clk = clk_get_sys("intcon", NULL);
238 BUG_ON(IS_ERR(clk));
239 clk_prepare_enable(clk);
240
241 irqchip_init();
242}
243
244static void __init u300_init_machine_dt(void)
245{
246 u16 val;
247
248 /* Check what platform we run and print some status information */
249 u300_init_check_chip();
250
Linus Walleij978577e2013-04-08 11:38:50 +0200251 /* Initialize pinmuxing */
252 pinctrl_register_mappings(u300_pinmux_map,
253 ARRAY_SIZE(u300_pinmux_map));
254
255 of_platform_populate(NULL, of_default_bus_match_table,
256 u300_auxdata_lookup, NULL);
257
258 /* Enable SEMI self refresh */
259 val = readw(U300_SYSCON_VBASE + U300_SYSCON_SMCR) |
260 U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE;
261 writew(val, U300_SYSCON_VBASE + U300_SYSCON_SMCR);
262}
263
264static const char * u300_board_compat[] = {
265 "stericsson,u300",
266 NULL,
267};
268
269DT_MACHINE_START(U300_DT, "U300 S335/B335 (Device Tree)")
270 .map_io = u300_map_io,
271 .init_irq = u300_init_irq_dt,
272 .init_time = clocksource_of_init,
273 .init_machine = u300_init_machine_dt,
274 .restart = u300_restart,
275 .dt_compat = u300_board_compat,
276MACHINE_END