Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/mach-realview/realview_pbx.c
10817 views
1
/*
2
* arch/arm/mach-realview/realview_pbx.c
3
*
4
* Copyright (C) 2009 ARM Limited
5
* Copyright (C) 2000 Deep Blue Solutions Ltd
6
*
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License version 2 as
9
* published by the Free Software Foundation.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
*/
20
21
#include <linux/init.h>
22
#include <linux/platform_device.h>
23
#include <linux/sysdev.h>
24
#include <linux/amba/bus.h>
25
#include <linux/amba/pl061.h>
26
#include <linux/amba/mmci.h>
27
#include <linux/amba/pl022.h>
28
#include <linux/io.h>
29
30
#include <asm/irq.h>
31
#include <asm/leds.h>
32
#include <asm/mach-types.h>
33
#include <asm/pmu.h>
34
#include <asm/smp_twd.h>
35
#include <asm/pgtable.h>
36
#include <asm/hardware/gic.h>
37
#include <asm/hardware/cache-l2x0.h>
38
39
#include <asm/mach/arch.h>
40
#include <asm/mach/map.h>
41
#include <asm/mach/time.h>
42
43
#include <mach/hardware.h>
44
#include <mach/board-pbx.h>
45
#include <mach/irqs.h>
46
47
#include "core.h"
48
49
static struct map_desc realview_pbx_io_desc[] __initdata = {
50
{
51
.virtual = IO_ADDRESS(REALVIEW_SYS_BASE),
52
.pfn = __phys_to_pfn(REALVIEW_SYS_BASE),
53
.length = SZ_4K,
54
.type = MT_DEVICE,
55
}, {
56
.virtual = IO_ADDRESS(REALVIEW_PBX_GIC_CPU_BASE),
57
.pfn = __phys_to_pfn(REALVIEW_PBX_GIC_CPU_BASE),
58
.length = SZ_4K,
59
.type = MT_DEVICE,
60
}, {
61
.virtual = IO_ADDRESS(REALVIEW_PBX_GIC_DIST_BASE),
62
.pfn = __phys_to_pfn(REALVIEW_PBX_GIC_DIST_BASE),
63
.length = SZ_4K,
64
.type = MT_DEVICE,
65
}, {
66
.virtual = IO_ADDRESS(REALVIEW_SCTL_BASE),
67
.pfn = __phys_to_pfn(REALVIEW_SCTL_BASE),
68
.length = SZ_4K,
69
.type = MT_DEVICE,
70
}, {
71
.virtual = IO_ADDRESS(REALVIEW_PBX_TIMER0_1_BASE),
72
.pfn = __phys_to_pfn(REALVIEW_PBX_TIMER0_1_BASE),
73
.length = SZ_4K,
74
.type = MT_DEVICE,
75
}, {
76
.virtual = IO_ADDRESS(REALVIEW_PBX_TIMER2_3_BASE),
77
.pfn = __phys_to_pfn(REALVIEW_PBX_TIMER2_3_BASE),
78
.length = SZ_4K,
79
.type = MT_DEVICE,
80
},
81
#ifdef CONFIG_PCI
82
{
83
.virtual = PCIX_UNIT_BASE,
84
.pfn = __phys_to_pfn(REALVIEW_PBX_PCI_BASE),
85
.length = REALVIEW_PBX_PCI_BASE_SIZE,
86
.type = MT_DEVICE,
87
},
88
#endif
89
#ifdef CONFIG_DEBUG_LL
90
{
91
.virtual = IO_ADDRESS(REALVIEW_PBX_UART0_BASE),
92
.pfn = __phys_to_pfn(REALVIEW_PBX_UART0_BASE),
93
.length = SZ_4K,
94
.type = MT_DEVICE,
95
},
96
#endif
97
};
98
99
static struct map_desc realview_local_io_desc[] __initdata = {
100
{
101
.virtual = IO_ADDRESS(REALVIEW_PBX_TILE_GIC_CPU_BASE),
102
.pfn = __phys_to_pfn(REALVIEW_PBX_TILE_GIC_CPU_BASE),
103
.length = SZ_4K,
104
.type = MT_DEVICE,
105
}, {
106
.virtual = IO_ADDRESS(REALVIEW_PBX_TILE_GIC_DIST_BASE),
107
.pfn = __phys_to_pfn(REALVIEW_PBX_TILE_GIC_DIST_BASE),
108
.length = SZ_4K,
109
.type = MT_DEVICE,
110
}, {
111
.virtual = IO_ADDRESS(REALVIEW_PBX_TILE_L220_BASE),
112
.pfn = __phys_to_pfn(REALVIEW_PBX_TILE_L220_BASE),
113
.length = SZ_8K,
114
.type = MT_DEVICE,
115
}
116
};
117
118
static void __init realview_pbx_map_io(void)
119
{
120
iotable_init(realview_pbx_io_desc, ARRAY_SIZE(realview_pbx_io_desc));
121
if (core_tile_pbx11mp() || core_tile_pbxa9mp())
122
iotable_init(realview_local_io_desc, ARRAY_SIZE(realview_local_io_desc));
123
}
124
125
static struct pl061_platform_data gpio0_plat_data = {
126
.gpio_base = 0,
127
.irq_base = -1,
128
};
129
130
static struct pl061_platform_data gpio1_plat_data = {
131
.gpio_base = 8,
132
.irq_base = -1,
133
};
134
135
static struct pl061_platform_data gpio2_plat_data = {
136
.gpio_base = 16,
137
.irq_base = -1,
138
};
139
140
static struct pl022_ssp_controller ssp0_plat_data = {
141
.bus_id = 0,
142
.enable_dma = 0,
143
.num_chipselect = 1,
144
};
145
146
/*
147
* RealView PBXCore AMBA devices
148
*/
149
150
#define GPIO2_IRQ { IRQ_PBX_GPIO2, NO_IRQ }
151
#define GPIO3_IRQ { IRQ_PBX_GPIO3, NO_IRQ }
152
#define AACI_IRQ { IRQ_PBX_AACI, NO_IRQ }
153
#define MMCI0_IRQ { IRQ_PBX_MMCI0A, IRQ_PBX_MMCI0B }
154
#define KMI0_IRQ { IRQ_PBX_KMI0, NO_IRQ }
155
#define KMI1_IRQ { IRQ_PBX_KMI1, NO_IRQ }
156
#define PBX_SMC_IRQ { NO_IRQ, NO_IRQ }
157
#define MPMC_IRQ { NO_IRQ, NO_IRQ }
158
#define PBX_CLCD_IRQ { IRQ_PBX_CLCD, NO_IRQ }
159
#define DMAC_IRQ { IRQ_PBX_DMAC, NO_IRQ }
160
#define SCTL_IRQ { NO_IRQ, NO_IRQ }
161
#define PBX_WATCHDOG_IRQ { IRQ_PBX_WATCHDOG, NO_IRQ }
162
#define PBX_GPIO0_IRQ { IRQ_PBX_GPIO0, NO_IRQ }
163
#define GPIO1_IRQ { IRQ_PBX_GPIO1, NO_IRQ }
164
#define PBX_RTC_IRQ { IRQ_PBX_RTC, NO_IRQ }
165
#define SCI_IRQ { IRQ_PBX_SCI, NO_IRQ }
166
#define PBX_UART0_IRQ { IRQ_PBX_UART0, NO_IRQ }
167
#define PBX_UART1_IRQ { IRQ_PBX_UART1, NO_IRQ }
168
#define PBX_UART2_IRQ { IRQ_PBX_UART2, NO_IRQ }
169
#define PBX_UART3_IRQ { IRQ_PBX_UART3, NO_IRQ }
170
#define PBX_SSP_IRQ { IRQ_PBX_SSP, NO_IRQ }
171
172
/* FPGA Primecells */
173
AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
174
AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
175
AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
176
AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
177
AMBA_DEVICE(uart3, "fpga:uart3", PBX_UART3, NULL);
178
179
/* DevChip Primecells */
180
AMBA_DEVICE(smc, "dev:smc", PBX_SMC, NULL);
181
AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL);
182
AMBA_DEVICE(wdog, "dev:wdog", PBX_WATCHDOG, NULL);
183
AMBA_DEVICE(gpio0, "dev:gpio0", PBX_GPIO0, &gpio0_plat_data);
184
AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
185
AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
186
AMBA_DEVICE(rtc, "dev:rtc", PBX_RTC, NULL);
187
AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL);
188
AMBA_DEVICE(uart0, "dev:uart0", PBX_UART0, NULL);
189
AMBA_DEVICE(uart1, "dev:uart1", PBX_UART1, NULL);
190
AMBA_DEVICE(uart2, "dev:uart2", PBX_UART2, NULL);
191
AMBA_DEVICE(ssp0, "dev:ssp0", PBX_SSP, &ssp0_plat_data);
192
193
/* Primecells on the NEC ISSP chip */
194
AMBA_DEVICE(clcd, "issp:clcd", PBX_CLCD, &clcd_plat_data);
195
AMBA_DEVICE(dmac, "issp:dmac", DMAC, NULL);
196
197
static struct amba_device *amba_devs[] __initdata = {
198
&dmac_device,
199
&uart0_device,
200
&uart1_device,
201
&uart2_device,
202
&uart3_device,
203
&smc_device,
204
&clcd_device,
205
&sctl_device,
206
&wdog_device,
207
&gpio0_device,
208
&gpio1_device,
209
&gpio2_device,
210
&rtc_device,
211
&sci0_device,
212
&ssp0_device,
213
&aaci_device,
214
&mmc0_device,
215
&kmi0_device,
216
&kmi1_device,
217
};
218
219
/*
220
* RealView PB-X platform devices
221
*/
222
static struct resource realview_pbx_flash_resources[] = {
223
[0] = {
224
.start = REALVIEW_PBX_FLASH0_BASE,
225
.end = REALVIEW_PBX_FLASH0_BASE + REALVIEW_PBX_FLASH0_SIZE - 1,
226
.flags = IORESOURCE_MEM,
227
},
228
[1] = {
229
.start = REALVIEW_PBX_FLASH1_BASE,
230
.end = REALVIEW_PBX_FLASH1_BASE + REALVIEW_PBX_FLASH1_SIZE - 1,
231
.flags = IORESOURCE_MEM,
232
},
233
};
234
235
static struct resource realview_pbx_smsc911x_resources[] = {
236
[0] = {
237
.start = REALVIEW_PBX_ETH_BASE,
238
.end = REALVIEW_PBX_ETH_BASE + SZ_64K - 1,
239
.flags = IORESOURCE_MEM,
240
},
241
[1] = {
242
.start = IRQ_PBX_ETH,
243
.end = IRQ_PBX_ETH,
244
.flags = IORESOURCE_IRQ,
245
},
246
};
247
248
static struct resource realview_pbx_isp1761_resources[] = {
249
[0] = {
250
.start = REALVIEW_PBX_USB_BASE,
251
.end = REALVIEW_PBX_USB_BASE + SZ_128K - 1,
252
.flags = IORESOURCE_MEM,
253
},
254
[1] = {
255
.start = IRQ_PBX_USB,
256
.end = IRQ_PBX_USB,
257
.flags = IORESOURCE_IRQ,
258
},
259
};
260
261
static struct resource pmu_resources[] = {
262
[0] = {
263
.start = IRQ_PBX_PMU_CPU0,
264
.end = IRQ_PBX_PMU_CPU0,
265
.flags = IORESOURCE_IRQ,
266
},
267
[1] = {
268
.start = IRQ_PBX_PMU_CPU1,
269
.end = IRQ_PBX_PMU_CPU1,
270
.flags = IORESOURCE_IRQ,
271
},
272
[2] = {
273
.start = IRQ_PBX_PMU_CPU2,
274
.end = IRQ_PBX_PMU_CPU2,
275
.flags = IORESOURCE_IRQ,
276
},
277
[3] = {
278
.start = IRQ_PBX_PMU_CPU3,
279
.end = IRQ_PBX_PMU_CPU3,
280
.flags = IORESOURCE_IRQ,
281
},
282
};
283
284
static struct platform_device pmu_device = {
285
.name = "arm-pmu",
286
.id = ARM_PMU_DEVICE_CPU,
287
.num_resources = ARRAY_SIZE(pmu_resources),
288
.resource = pmu_resources,
289
};
290
291
static void __init gic_init_irq(void)
292
{
293
/* ARM PBX on-board GIC */
294
if (core_tile_pbx11mp() || core_tile_pbxa9mp()) {
295
gic_init(0, 29, __io_address(REALVIEW_PBX_TILE_GIC_DIST_BASE),
296
__io_address(REALVIEW_PBX_TILE_GIC_CPU_BASE));
297
} else {
298
gic_init(0, IRQ_PBX_GIC_START,
299
__io_address(REALVIEW_PBX_GIC_DIST_BASE),
300
__io_address(REALVIEW_PBX_GIC_CPU_BASE));
301
}
302
}
303
304
static void __init realview_pbx_timer_init(void)
305
{
306
timer0_va_base = __io_address(REALVIEW_PBX_TIMER0_1_BASE);
307
timer1_va_base = __io_address(REALVIEW_PBX_TIMER0_1_BASE) + 0x20;
308
timer2_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE);
309
timer3_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE) + 0x20;
310
311
#ifdef CONFIG_LOCAL_TIMERS
312
if (core_tile_pbx11mp() || core_tile_pbxa9mp())
313
twd_base = __io_address(REALVIEW_PBX_TILE_TWD_BASE);
314
#endif
315
realview_timer_init(IRQ_PBX_TIMER0_1);
316
}
317
318
static struct sys_timer realview_pbx_timer = {
319
.init = realview_pbx_timer_init,
320
};
321
322
static void realview_pbx_fixup(struct machine_desc *mdesc, struct tag *tags,
323
char **from, struct meminfo *meminfo)
324
{
325
#ifdef CONFIG_SPARSEMEM
326
/*
327
* Memory configuration with SPARSEMEM enabled on RealView PBX (see
328
* asm/mach/memory.h for more information).
329
*/
330
meminfo->bank[0].start = 0;
331
meminfo->bank[0].size = SZ_256M;
332
meminfo->bank[1].start = 0x20000000;
333
meminfo->bank[1].size = SZ_512M;
334
meminfo->bank[2].start = 0x80000000;
335
meminfo->bank[2].size = SZ_256M;
336
meminfo->nr_banks = 3;
337
#else
338
realview_fixup(mdesc, tags, from, meminfo);
339
#endif
340
}
341
342
static void realview_pbx_reset(char mode)
343
{
344
void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL);
345
void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK);
346
347
/*
348
* To reset, we hit the on-board reset register
349
* in the system FPGA
350
*/
351
__raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl);
352
__raw_writel(0x00F0, reset_ctrl);
353
__raw_writel(0x00F4, reset_ctrl);
354
}
355
356
static void __init realview_pbx_init(void)
357
{
358
int i;
359
360
#ifdef CONFIG_CACHE_L2X0
361
if (core_tile_pbxa9mp()) {
362
void __iomem *l2x0_base =
363
__io_address(REALVIEW_PBX_TILE_L220_BASE);
364
365
/* set RAM latencies to 1 cycle for eASIC */
366
writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL);
367
writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL);
368
369
/* 16KB way size, 8-way associativity, parity disabled
370
* Bits: .. 0 0 0 0 1 00 1 0 1 001 0 000 0 .... .... .... */
371
l2x0_init(l2x0_base, 0x02520000, 0xc0000fff);
372
platform_device_register(&pmu_device);
373
}
374
#endif
375
376
realview_flash_register(realview_pbx_flash_resources,
377
ARRAY_SIZE(realview_pbx_flash_resources));
378
realview_eth_register(NULL, realview_pbx_smsc911x_resources);
379
platform_device_register(&realview_i2c_device);
380
platform_device_register(&realview_cf_device);
381
realview_usb_register(realview_pbx_isp1761_resources);
382
383
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
384
struct amba_device *d = amba_devs[i];
385
amba_device_register(d, &iomem_resource);
386
}
387
388
#ifdef CONFIG_LEDS
389
leds_event = realview_leds_event;
390
#endif
391
realview_reset = realview_pbx_reset;
392
}
393
394
MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")
395
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
396
.boot_params = PLAT_PHYS_OFFSET + 0x00000100,
397
.fixup = realview_pbx_fixup,
398
.map_io = realview_pbx_map_io,
399
.init_early = realview_init_early,
400
.init_irq = gic_init_irq,
401
.timer = &realview_pbx_timer,
402
.init_machine = realview_pbx_init,
403
MACHINE_END
404
405