1 /*
2  * Versatile Express V2M Motherboard Support
3  */
4 #include <linux/device.h>
5 #include <linux/amba/bus.h>
6 #include <linux/amba/mmci.h>
7 #include <linux/io.h>
8 #include <linux/init.h>
9 #include <linux/platform_device.h>
10 #include <linux/ata_platform.h>
11 #include <linux/smsc911x.h>
12 #include <linux/spinlock.h>
13 #include <linux/device.h>
14 #include <linux/usb/isp1760.h>
15 #include <linux/clkdev.h>
16 #include <linux/mtd/physmap.h>
17 
18 #include <asm/mach-types.h>
19 #include <asm/sizes.h>
20 #include <asm/mach/arch.h>
21 #include <asm/mach/map.h>
22 #include <asm/mach/time.h>
23 #include <asm/hardware/arm_timer.h>
24 #include <asm/hardware/timer-sp.h>
25 #include <asm/hardware/sp810.h>
26 #include <asm/hardware/gic.h>
27 
28 #include <mach/ct-ca9x4.h>
29 #include <mach/motherboard.h>
30 
31 #include <plat/sched_clock.h>
32 
33 #include "core.h"
34 
35 #define V2M_PA_CS0	0x40000000
36 #define V2M_PA_CS1	0x44000000
37 #define V2M_PA_CS2	0x48000000
38 #define V2M_PA_CS3	0x4c000000
39 #define V2M_PA_CS7	0x10000000
40 
41 static struct map_desc v2m_io_desc[] __initdata = {
42 	{
43 		.virtual	= __MMIO_P2V(V2M_PA_CS7),
44 		.pfn		= __phys_to_pfn(V2M_PA_CS7),
45 		.length		= SZ_128K,
46 		.type		= MT_DEVICE,
47 	},
48 };
49 
v2m_timer_init(void)50 static void __init v2m_timer_init(void)
51 {
52 	u32 scctrl;
53 
54 	/* Select 1MHz TIMCLK as the reference clock for SP804 timers */
55 	scctrl = readl(MMIO_P2V(V2M_SYSCTL + SCCTRL));
56 	scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK;
57 	scctrl |= SCCTRL_TIMEREN1SEL_TIMCLK;
58 	writel(scctrl, MMIO_P2V(V2M_SYSCTL + SCCTRL));
59 
60 	writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL);
61 	writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL);
62 
63 	sp804_clocksource_init(MMIO_P2V(V2M_TIMER1), "v2m-timer1");
64 	sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0,
65 		"v2m-timer0");
66 }
67 
68 static struct sys_timer v2m_timer = {
69 	.init	= v2m_timer_init,
70 };
71 
72 
73 static DEFINE_SPINLOCK(v2m_cfg_lock);
74 
v2m_cfg_write(u32 devfn,u32 data)75 int v2m_cfg_write(u32 devfn, u32 data)
76 {
77 	/* Configuration interface broken? */
78 	u32 val;
79 
80 	printk("%s: writing %08x to %08x\n", __func__, data, devfn);
81 
82 	devfn |= SYS_CFG_START | SYS_CFG_WRITE;
83 
84 	spin_lock(&v2m_cfg_lock);
85 	val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
86 	writel(val & ~SYS_CFG_COMPLETE, MMIO_P2V(V2M_SYS_CFGSTAT));
87 
88 	writel(data, MMIO_P2V(V2M_SYS_CFGDATA));
89 	writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL));
90 
91 	do {
92 		val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
93 	} while (val == 0);
94 	spin_unlock(&v2m_cfg_lock);
95 
96 	return !!(val & SYS_CFG_ERR);
97 }
98 
v2m_cfg_read(u32 devfn,u32 * data)99 int v2m_cfg_read(u32 devfn, u32 *data)
100 {
101 	u32 val;
102 
103 	devfn |= SYS_CFG_START;
104 
105 	spin_lock(&v2m_cfg_lock);
106 	writel(0, MMIO_P2V(V2M_SYS_CFGSTAT));
107 	writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL));
108 
109 	mb();
110 
111 	do {
112 		cpu_relax();
113 		val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
114 	} while (val == 0);
115 
116 	*data = readl(MMIO_P2V(V2M_SYS_CFGDATA));
117 	spin_unlock(&v2m_cfg_lock);
118 
119 	return !!(val & SYS_CFG_ERR);
120 }
121 
122 
123 static struct resource v2m_pcie_i2c_resource = {
124 	.start	= V2M_SERIAL_BUS_PCI,
125 	.end	= V2M_SERIAL_BUS_PCI + SZ_4K - 1,
126 	.flags	= IORESOURCE_MEM,
127 };
128 
129 static struct platform_device v2m_pcie_i2c_device = {
130 	.name		= "versatile-i2c",
131 	.id		= 0,
132 	.num_resources	= 1,
133 	.resource	= &v2m_pcie_i2c_resource,
134 };
135 
136 static struct resource v2m_ddc_i2c_resource = {
137 	.start	= V2M_SERIAL_BUS_DVI,
138 	.end	= V2M_SERIAL_BUS_DVI + SZ_4K - 1,
139 	.flags	= IORESOURCE_MEM,
140 };
141 
142 static struct platform_device v2m_ddc_i2c_device = {
143 	.name		= "versatile-i2c",
144 	.id		= 1,
145 	.num_resources	= 1,
146 	.resource	= &v2m_ddc_i2c_resource,
147 };
148 
149 static struct resource v2m_eth_resources[] = {
150 	{
151 		.start	= V2M_LAN9118,
152 		.end	= V2M_LAN9118 + SZ_64K - 1,
153 		.flags	= IORESOURCE_MEM,
154 	}, {
155 		.start	= IRQ_V2M_LAN9118,
156 		.end	= IRQ_V2M_LAN9118,
157 		.flags	= IORESOURCE_IRQ,
158 	},
159 };
160 
161 static struct smsc911x_platform_config v2m_eth_config = {
162 	.flags		= SMSC911X_USE_32BIT,
163 	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
164 	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
165 	.phy_interface	= PHY_INTERFACE_MODE_MII,
166 };
167 
168 static struct platform_device v2m_eth_device = {
169 	.name		= "smsc911x",
170 	.id		= -1,
171 	.resource	= v2m_eth_resources,
172 	.num_resources	= ARRAY_SIZE(v2m_eth_resources),
173 	.dev.platform_data = &v2m_eth_config,
174 };
175 
176 static struct resource v2m_usb_resources[] = {
177 	{
178 		.start	= V2M_ISP1761,
179 		.end	= V2M_ISP1761 + SZ_128K - 1,
180 		.flags	= IORESOURCE_MEM,
181 	}, {
182 		.start	= IRQ_V2M_ISP1761,
183 		.end	= IRQ_V2M_ISP1761,
184 		.flags	= IORESOURCE_IRQ,
185 	},
186 };
187 
188 static struct isp1760_platform_data v2m_usb_config = {
189 	.is_isp1761		= true,
190 	.bus_width_16		= false,
191 	.port1_otg		= true,
192 	.analog_oc		= false,
193 	.dack_polarity_high	= false,
194 	.dreq_polarity_high	= false,
195 };
196 
197 static struct platform_device v2m_usb_device = {
198 	.name		= "isp1760",
199 	.id		= -1,
200 	.resource	= v2m_usb_resources,
201 	.num_resources	= ARRAY_SIZE(v2m_usb_resources),
202 	.dev.platform_data = &v2m_usb_config,
203 };
204 
v2m_flash_set_vpp(struct platform_device * pdev,int on)205 static void v2m_flash_set_vpp(struct platform_device *pdev, int on)
206 {
207 	writel(on != 0, MMIO_P2V(V2M_SYS_FLASH));
208 }
209 
210 static struct physmap_flash_data v2m_flash_data = {
211 	.width		= 4,
212 	.set_vpp	= v2m_flash_set_vpp,
213 };
214 
215 static struct resource v2m_flash_resources[] = {
216 	{
217 		.start	= V2M_NOR0,
218 		.end	= V2M_NOR0 + SZ_64M - 1,
219 		.flags	= IORESOURCE_MEM,
220 	}, {
221 		.start	= V2M_NOR1,
222 		.end	= V2M_NOR1 + SZ_64M - 1,
223 		.flags	= IORESOURCE_MEM,
224 	},
225 };
226 
227 static struct platform_device v2m_flash_device = {
228 	.name		= "physmap-flash",
229 	.id		= -1,
230 	.resource	= v2m_flash_resources,
231 	.num_resources	= ARRAY_SIZE(v2m_flash_resources),
232 	.dev.platform_data = &v2m_flash_data,
233 };
234 
235 static struct pata_platform_info v2m_pata_data = {
236 	.ioport_shift	= 2,
237 };
238 
239 static struct resource v2m_pata_resources[] = {
240 	{
241 		.start	= V2M_CF,
242 		.end	= V2M_CF + 0xff,
243 		.flags	= IORESOURCE_MEM,
244 	}, {
245 		.start	= V2M_CF + 0x100,
246 		.end	= V2M_CF + SZ_4K - 1,
247 		.flags	= IORESOURCE_MEM,
248 	},
249 };
250 
251 static struct platform_device v2m_cf_device = {
252 	.name		= "pata_platform",
253 	.id		= -1,
254 	.resource	= v2m_pata_resources,
255 	.num_resources	= ARRAY_SIZE(v2m_pata_resources),
256 	.dev.platform_data = &v2m_pata_data,
257 };
258 
v2m_mmci_status(struct device * dev)259 static unsigned int v2m_mmci_status(struct device *dev)
260 {
261 	return readl(MMIO_P2V(V2M_SYS_MCI)) & (1 << 0);
262 }
263 
264 static struct mmci_platform_data v2m_mmci_data = {
265 	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
266 	.status		= v2m_mmci_status,
267 };
268 
269 static AMBA_DEVICE(aaci,  "mb:aaci",  V2M_AACI, NULL);
270 static AMBA_DEVICE(mmci,  "mb:mmci",  V2M_MMCI, &v2m_mmci_data);
271 static AMBA_DEVICE(kmi0,  "mb:kmi0",  V2M_KMI0, NULL);
272 static AMBA_DEVICE(kmi1,  "mb:kmi1",  V2M_KMI1, NULL);
273 static AMBA_DEVICE(uart0, "mb:uart0", V2M_UART0, NULL);
274 static AMBA_DEVICE(uart1, "mb:uart1", V2M_UART1, NULL);
275 static AMBA_DEVICE(uart2, "mb:uart2", V2M_UART2, NULL);
276 static AMBA_DEVICE(uart3, "mb:uart3", V2M_UART3, NULL);
277 static AMBA_DEVICE(wdt,   "mb:wdt",   V2M_WDT, NULL);
278 static AMBA_DEVICE(rtc,   "mb:rtc",   V2M_RTC, NULL);
279 
280 static struct amba_device *v2m_amba_devs[] __initdata = {
281 	&aaci_device,
282 	&mmci_device,
283 	&kmi0_device,
284 	&kmi1_device,
285 	&uart0_device,
286 	&uart1_device,
287 	&uart2_device,
288 	&uart3_device,
289 	&wdt_device,
290 	&rtc_device,
291 };
292 
293 
v2m_osc_round(struct clk * clk,unsigned long rate)294 static long v2m_osc_round(struct clk *clk, unsigned long rate)
295 {
296 	return rate;
297 }
298 
v2m_osc1_set(struct clk * clk,unsigned long rate)299 static int v2m_osc1_set(struct clk *clk, unsigned long rate)
300 {
301 	return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_MB | 1, rate);
302 }
303 
304 static const struct clk_ops osc1_clk_ops = {
305 	.round	= v2m_osc_round,
306 	.set	= v2m_osc1_set,
307 };
308 
309 static struct clk osc1_clk = {
310 	.ops	= &osc1_clk_ops,
311 	.rate	= 24000000,
312 };
313 
314 static struct clk osc2_clk = {
315 	.rate	= 24000000,
316 };
317 
318 static struct clk v2m_sp804_clk = {
319 	.rate	= 1000000,
320 };
321 
322 static struct clk v2m_ref_clk = {
323 	.rate   = 32768,
324 };
325 
326 static struct clk dummy_apb_pclk;
327 
328 static struct clk_lookup v2m_lookups[] = {
329 	{	/* AMBA bus clock */
330 		.con_id		= "apb_pclk",
331 		.clk		= &dummy_apb_pclk,
332 	}, {	/* UART0 */
333 		.dev_id		= "mb:uart0",
334 		.clk		= &osc2_clk,
335 	}, {	/* UART1 */
336 		.dev_id		= "mb:uart1",
337 		.clk		= &osc2_clk,
338 	}, {	/* UART2 */
339 		.dev_id		= "mb:uart2",
340 		.clk		= &osc2_clk,
341 	}, {	/* UART3 */
342 		.dev_id		= "mb:uart3",
343 		.clk		= &osc2_clk,
344 	}, {	/* KMI0 */
345 		.dev_id		= "mb:kmi0",
346 		.clk		= &osc2_clk,
347 	}, {	/* KMI1 */
348 		.dev_id		= "mb:kmi1",
349 		.clk		= &osc2_clk,
350 	}, {	/* MMC0 */
351 		.dev_id		= "mb:mmci",
352 		.clk		= &osc2_clk,
353 	}, {	/* CLCD */
354 		.dev_id		= "mb:clcd",
355 		.clk		= &osc1_clk,
356 	}, {	/* SP805 WDT */
357 		.dev_id		= "mb:wdt",
358 		.clk		= &v2m_ref_clk,
359 	}, {	/* SP804 timers */
360 		.dev_id		= "sp804",
361 		.con_id		= "v2m-timer0",
362 		.clk		= &v2m_sp804_clk,
363 	}, {	/* SP804 timers */
364 		.dev_id		= "sp804",
365 		.con_id		= "v2m-timer1",
366 		.clk		= &v2m_sp804_clk,
367 	},
368 };
369 
v2m_init_early(void)370 static void __init v2m_init_early(void)
371 {
372 	ct_desc->init_early();
373 	clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups));
374 	versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
375 }
376 
v2m_power_off(void)377 static void v2m_power_off(void)
378 {
379 	if (v2m_cfg_write(SYS_CFG_SHUTDOWN | SYS_CFG_SITE_MB, 0))
380 		printk(KERN_EMERG "Unable to shutdown\n");
381 }
382 
v2m_restart(char str,const char * cmd)383 static void v2m_restart(char str, const char *cmd)
384 {
385 	if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE_MB, 0))
386 		printk(KERN_EMERG "Unable to reboot\n");
387 }
388 
389 struct ct_desc *ct_desc;
390 
391 static struct ct_desc *ct_descs[] __initdata = {
392 #ifdef CONFIG_ARCH_VEXPRESS_CA9X4
393 	&ct_ca9x4_desc,
394 #endif
395 };
396 
v2m_populate_ct_desc(void)397 static void __init v2m_populate_ct_desc(void)
398 {
399 	int i;
400 	u32 current_tile_id;
401 
402 	ct_desc = NULL;
403 	current_tile_id = readl(MMIO_P2V(V2M_SYS_PROCID0)) & V2M_CT_ID_MASK;
404 
405 	for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i)
406 		if (ct_descs[i]->id == current_tile_id)
407 			ct_desc = ct_descs[i];
408 
409 	if (!ct_desc)
410 		panic("vexpress: failed to populate core tile description "
411 		      "for tile ID 0x%8x\n", current_tile_id);
412 }
413 
v2m_map_io(void)414 static void __init v2m_map_io(void)
415 {
416 	iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
417 	v2m_populate_ct_desc();
418 	ct_desc->map_io();
419 }
420 
v2m_init_irq(void)421 static void __init v2m_init_irq(void)
422 {
423 	ct_desc->init_irq();
424 }
425 
v2m_init(void)426 static void __init v2m_init(void)
427 {
428 	int i;
429 
430 	platform_device_register(&v2m_pcie_i2c_device);
431 	platform_device_register(&v2m_ddc_i2c_device);
432 	platform_device_register(&v2m_flash_device);
433 	platform_device_register(&v2m_cf_device);
434 	platform_device_register(&v2m_eth_device);
435 	platform_device_register(&v2m_usb_device);
436 
437 	for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++)
438 		amba_device_register(v2m_amba_devs[i], &iomem_resource);
439 
440 	pm_power_off = v2m_power_off;
441 
442 	ct_desc->init_tile();
443 }
444 
445 MACHINE_START(VEXPRESS, "ARM-Versatile Express")
446 	.atag_offset	= 0x100,
447 	.map_io		= v2m_map_io,
448 	.init_early	= v2m_init_early,
449 	.init_irq	= v2m_init_irq,
450 	.timer		= &v2m_timer,
451 	.handle_irq	= gic_handle_irq,
452 	.init_machine	= v2m_init,
453 	.restart	= v2m_restart,
454 MACHINE_END
455