Blame view

arch/arm/mach-vexpress/v2m.c 10 KB
ceade897f   Russell King   ARM: Add Versatil...
1
2
3
4
5
6
7
8
9
  /*
   * Versatile Express V2M Motherboard Support
   */
  #include <linux/device.h>
  #include <linux/amba/bus.h>
  #include <linux/amba/mmci.h>
  #include <linux/io.h>
  #include <linux/init.h>
  #include <linux/platform_device.h>
95c34f831   Nick Bowler   ARM: 6633/1: vexp...
10
  #include <linux/ata_platform.h>
ceade897f   Russell King   ARM: Add Versatil...
11
12
  #include <linux/smsc911x.h>
  #include <linux/spinlock.h>
edbaa603e   Kay Sievers   driver-core: remo...
13
  #include <linux/device.h>
ceade897f   Russell King   ARM: Add Versatil...
14
  #include <linux/usb/isp1760.h>
6d803ba73   Jean-Christop PLAGNIOL-VILLARD   ARM: 6483/1: arm ...
15
  #include <linux/clkdev.h>
0f71fd492   Marc Zyngier   ARM: 6909/1: VExp...
16
  #include <linux/mtd/physmap.h>
ceade897f   Russell King   ARM: Add Versatil...
17

80b5efbd4   Will Deacon   ARM: 6771/1: vexp...
18
  #include <asm/mach-types.h>
ceade897f   Russell King   ARM: Add Versatil...
19
  #include <asm/sizes.h>
80b5efbd4   Will Deacon   ARM: 6771/1: vexp...
20
  #include <asm/mach/arch.h>
ceade897f   Russell King   ARM: Add Versatil...
21
22
23
  #include <asm/mach/map.h>
  #include <asm/mach/time.h>
  #include <asm/hardware/arm_timer.h>
58daf18cd   Russell King   Merge branch 'clk...
24
  #include <asm/hardware/timer-sp.h>
baaece224   Pawel Moll   ARM: 6635/2: Conf...
25
  #include <asm/hardware/sp810.h>
abd3ca51f   Marc Zyngier   ARM: VExpress: co...
26
  #include <asm/hardware/gic.h>
ceade897f   Russell King   ARM: Add Versatil...
27

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

80b5efbd4   Will Deacon   ARM: 6771/1: vexp...
429
  	ct_desc->init_tile();
ceade897f   Russell King   ARM: Add Versatil...
430
  }
80b5efbd4   Will Deacon   ARM: 6771/1: vexp...
431
432
  
  MACHINE_START(VEXPRESS, "ARM-Versatile Express")
e9ce8e5bd   Nicolas Pitre   ARM: vexpress: co...
433
  	.atag_offset	= 0x100,
80b5efbd4   Will Deacon   ARM: 6771/1: vexp...
434
435
436
437
  	.map_io		= v2m_map_io,
  	.init_early	= v2m_init_early,
  	.init_irq	= v2m_init_irq,
  	.timer		= &v2m_timer,
abd3ca51f   Marc Zyngier   ARM: VExpress: co...
438
  	.handle_irq	= gic_handle_irq,
80b5efbd4   Will Deacon   ARM: 6771/1: vexp...
439
  	.init_machine	= v2m_init,
f5733a1e8   Russell King   ARM: restart: Ver...
440
  	.restart	= v2m_restart,
80b5efbd4   Will Deacon   ARM: 6771/1: vexp...
441
  MACHINE_END