diff options
Diffstat (limited to 'arch/arm/mach-vexpress')
-rw-r--r-- | arch/arm/mach-vexpress/Kconfig | 47 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/Makefile.boot | 6 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/core.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/include/mach/debug-macro.S | 30 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/include/mach/irqs.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/include/mach/motherboard.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/include/mach/uncompress.h | 22 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/platsmp.c | 155 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/v2m.c | 213 |
9 files changed, 470 insertions, 13 deletions
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig index 88c3ba151e8..cf8730d35e7 100644 --- a/arch/arm/mach-vexpress/Kconfig +++ b/arch/arm/mach-vexpress/Kconfig | |||
@@ -1,14 +1,55 @@ | |||
1 | menu "Versatile Express platform type" | 1 | menu "Versatile Express platform type" |
2 | depends on ARCH_VEXPRESS | 2 | depends on ARCH_VEXPRESS |
3 | 3 | ||
4 | config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA | ||
5 | bool | ||
6 | select ARM_ERRATA_720789 | ||
7 | select ARM_ERRATA_751472 | ||
8 | select PL310_ERRATA_753970 if CACHE_PL310 | ||
9 | help | ||
10 | Provides common dependencies for Versatile Express platforms | ||
11 | based on Cortex-A5 and Cortex-A9 processors. In order to | ||
12 | build a working kernel, you must also enable relevant core | ||
13 | tile support or Flattened Device Tree based support options. | ||
14 | |||
4 | config ARCH_VEXPRESS_CA9X4 | 15 | config ARCH_VEXPRESS_CA9X4 |
5 | bool "Versatile Express Cortex-A9x4 tile" | 16 | bool "Versatile Express Cortex-A9x4 tile" |
17 | select ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA | ||
18 | select ARM_GIC | ||
6 | select CPU_V7 | 19 | select CPU_V7 |
20 | select HAVE_SMP | ||
21 | select MIGHT_HAVE_CACHE_L2X0 | ||
22 | |||
23 | config ARCH_VEXPRESS_DT | ||
24 | bool "Device Tree support for Versatile Express platforms" | ||
25 | select ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA | ||
7 | select ARM_GIC | 26 | select ARM_GIC |
8 | select ARM_ERRATA_720789 | 27 | select ARM_PATCH_PHYS_VIRT |
9 | select ARM_ERRATA_751472 | 28 | select AUTO_ZRELADDR |
10 | select PL310_ERRATA_753970 | 29 | select CPU_V7 |
11 | select HAVE_SMP | 30 | select HAVE_SMP |
12 | select MIGHT_HAVE_CACHE_L2X0 | 31 | select MIGHT_HAVE_CACHE_L2X0 |
32 | select USE_OF | ||
33 | help | ||
34 | New Versatile Express platforms require Flattened Device Tree to | ||
35 | be passed to the kernel. | ||
36 | |||
37 | This option enables support for systems using Cortex processor based | ||
38 | ARM core and logic (FPGA) tiles on the Versatile Express motherboard, | ||
39 | for example: | ||
40 | |||
41 | - CoreTile Express A5x2 (V2P-CA5s) | ||
42 | - CoreTile Express A9x4 (V2P-CA9) | ||
43 | - CoreTile Express A15x2 (V2P-CA15) | ||
44 | - LogicTile Express 13MG (V2F-2XV6) with A5, A7, A9 or A15 SMMs | ||
45 | (Soft Macrocell Models) | ||
46 | - Versatile Express RTSMs (Models) | ||
47 | |||
48 | You must boot using a Flattened Device Tree in order to use these | ||
49 | platforms. The traditional (ATAGs) boot method is not usable on | ||
50 | these boards with this option. | ||
51 | |||
52 | If your bootloader supports Flattened Device Tree based booting, | ||
53 | say Y here. | ||
13 | 54 | ||
14 | endmenu | 55 | endmenu |
diff --git a/arch/arm/mach-vexpress/Makefile.boot b/arch/arm/mach-vexpress/Makefile.boot index 8630b3d10a4..909f85ebf5f 100644 --- a/arch/arm/mach-vexpress/Makefile.boot +++ b/arch/arm/mach-vexpress/Makefile.boot | |||
@@ -1,3 +1,9 @@ | |||
1 | # Those numbers are used only by the non-DT V2P-CA9 platform | ||
2 | # The DT-enabled ones require CONFIG_AUTO_ZRELADDR=y | ||
1 | zreladdr-y += 0x60008000 | 3 | zreladdr-y += 0x60008000 |
2 | params_phys-y := 0x60000100 | 4 | params_phys-y := 0x60000100 |
3 | initrd_phys-y := 0x60800000 | 5 | initrd_phys-y := 0x60800000 |
6 | |||
7 | dtb-$(CONFIG_ARCH_VEXPRESS_DT) += vexpress-v2p-ca5s.dtb \ | ||
8 | vexpress-v2p-ca9.dtb \ | ||
9 | vexpress-v2p-ca15-tc1.dtb | ||
diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h index 33c5a825aba..a3a4980770b 100644 --- a/arch/arm/mach-vexpress/core.h +++ b/arch/arm/mach-vexpress/core.h | |||
@@ -3,3 +3,5 @@ | |||
3 | 3 | ||
4 | /* Tile's peripherals static mappings should start here */ | 4 | /* Tile's peripherals static mappings should start here */ |
5 | #define V2T_PERIPH 0xf8200000 | 5 | #define V2T_PERIPH 0xf8200000 |
6 | |||
7 | void vexpress_dt_smp_map_io(void); | ||
diff --git a/arch/arm/mach-vexpress/include/mach/debug-macro.S b/arch/arm/mach-vexpress/include/mach/debug-macro.S index fd9e6c7ea49..fa8224794e0 100644 --- a/arch/arm/mach-vexpress/include/mach/debug-macro.S +++ b/arch/arm/mach-vexpress/include/mach/debug-macro.S | |||
@@ -10,12 +10,34 @@ | |||
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #define DEBUG_LL_UART_OFFSET 0x00009000 | 13 | #define DEBUG_LL_PHYS_BASE 0x10000000 |
14 | #define DEBUG_LL_UART_OFFSET 0x00009000 | ||
15 | |||
16 | #define DEBUG_LL_PHYS_BASE_RS1 0x1c000000 | ||
17 | #define DEBUG_LL_UART_OFFSET_RS1 0x00090000 | ||
18 | |||
19 | #define DEBUG_LL_VIRT_BASE 0xf8000000 | ||
14 | 20 | ||
15 | .macro addruart,rp,rv,tmp | 21 | .macro addruart,rp,rv,tmp |
16 | mov \rp, #DEBUG_LL_UART_OFFSET | 22 | |
17 | orr \rv, \rp, #0xf8000000 @ virtual base | 23 | @ Make an educated guess regarding the memory map: |
18 | orr \rp, \rp, #0x10000000 @ physical base | 24 | @ - the original A9 core tile, which has MPCore peripherals |
25 | @ located at 0x1e000000, should use UART at 0x10009000 | ||
26 | @ - all other (RS1 complaint) tiles use UART mapped | ||
27 | @ at 0x1c090000 | ||
28 | mrc p15, 4, \tmp, c15, c0, 0 | ||
29 | cmp \tmp, #0x1e000000 | ||
30 | |||
31 | @ Original memory map | ||
32 | moveq \rp, #DEBUG_LL_UART_OFFSET | ||
33 | orreq \rv, \rp, #DEBUG_LL_VIRT_BASE | ||
34 | orreq \rp, \rp, #DEBUG_LL_PHYS_BASE | ||
35 | |||
36 | @ RS1 memory map | ||
37 | movne \rp, #DEBUG_LL_UART_OFFSET_RS1 | ||
38 | orrne \rv, \rp, #DEBUG_LL_VIRT_BASE | ||
39 | orrne \rp, \rp, #DEBUG_LL_PHYS_BASE_RS1 | ||
40 | |||
19 | .endm | 41 | .endm |
20 | 42 | ||
21 | #include <asm/hardware/debug-pl01x.S> | 43 | #include <asm/hardware/debug-pl01x.S> |
diff --git a/arch/arm/mach-vexpress/include/mach/irqs.h b/arch/arm/mach-vexpress/include/mach/irqs.h index 7054cbfc9de..4b10ee7657a 100644 --- a/arch/arm/mach-vexpress/include/mach/irqs.h +++ b/arch/arm/mach-vexpress/include/mach/irqs.h | |||
@@ -1,4 +1,4 @@ | |||
1 | #define IRQ_LOCALTIMER 29 | 1 | #define IRQ_LOCALTIMER 29 |
2 | #define IRQ_LOCALWDOG 30 | 2 | #define IRQ_LOCALWDOG 30 |
3 | 3 | ||
4 | #define NR_IRQS 128 | 4 | #define NR_IRQS 256 |
diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h index b4c498c1dbe..31a92890893 100644 --- a/arch/arm/mach-vexpress/include/mach/motherboard.h +++ b/arch/arm/mach-vexpress/include/mach/motherboard.h | |||
@@ -117,6 +117,12 @@ int v2m_cfg_read(u32 devfn, u32 *data); | |||
117 | void v2m_flags_set(u32 data); | 117 | void v2m_flags_set(u32 data); |
118 | 118 | ||
119 | /* | 119 | /* |
120 | * Miscellaneous | ||
121 | */ | ||
122 | #define SYS_MISC_MASTERSITE (1 << 14) | ||
123 | #define SYS_PROCIDx_HBI_MASK 0xfff | ||
124 | |||
125 | /* | ||
120 | * Core tile IDs | 126 | * Core tile IDs |
121 | */ | 127 | */ |
122 | #define V2M_CT_ID_CA9 0x0c000191 | 128 | #define V2M_CT_ID_CA9 0x0c000191 |
diff --git a/arch/arm/mach-vexpress/include/mach/uncompress.h b/arch/arm/mach-vexpress/include/mach/uncompress.h index 7972c5748d0..7dab5596b86 100644 --- a/arch/arm/mach-vexpress/include/mach/uncompress.h +++ b/arch/arm/mach-vexpress/include/mach/uncompress.h | |||
@@ -22,7 +22,27 @@ | |||
22 | #define AMBA_UART_CR(base) (*(volatile unsigned char *)((base) + 0x30)) | 22 | #define AMBA_UART_CR(base) (*(volatile unsigned char *)((base) + 0x30)) |
23 | #define AMBA_UART_FR(base) (*(volatile unsigned char *)((base) + 0x18)) | 23 | #define AMBA_UART_FR(base) (*(volatile unsigned char *)((base) + 0x18)) |
24 | 24 | ||
25 | #define get_uart_base() (0x10000000 + 0x00009000) | 25 | #define UART_BASE 0x10009000 |
26 | #define UART_BASE_RS1 0x1c090000 | ||
27 | |||
28 | static unsigned long get_uart_base(void) | ||
29 | { | ||
30 | unsigned long mpcore_periph; | ||
31 | |||
32 | /* | ||
33 | * Make an educated guess regarding the memory map: | ||
34 | * - the original A9 core tile, which has MPCore peripherals | ||
35 | * located at 0x1e000000, should use UART at 0x10009000 | ||
36 | * - all other (RS1 complaint) tiles use UART mapped | ||
37 | * at 0x1c090000 | ||
38 | */ | ||
39 | asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (mpcore_periph)); | ||
40 | |||
41 | if (mpcore_periph == 0x1e000000) | ||
42 | return UART_BASE; | ||
43 | else | ||
44 | return UART_BASE_RS1; | ||
45 | } | ||
26 | 46 | ||
27 | /* | 47 | /* |
28 | * This does not append a newline | 48 | * This does not append a newline |
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c index a1ed6d68597..14ba1128ae8 100644 --- a/arch/arm/mach-vexpress/platsmp.c +++ b/arch/arm/mach-vexpress/platsmp.c | |||
@@ -12,6 +12,11 @@ | |||
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/smp.h> | 13 | #include <linux/smp.h> |
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <linux/of_fdt.h> | ||
16 | |||
17 | #include <asm/smp_scu.h> | ||
18 | #include <asm/hardware/gic.h> | ||
19 | #include <asm/mach/map.h> | ||
15 | 20 | ||
16 | #include <mach/motherboard.h> | 21 | #include <mach/motherboard.h> |
17 | 22 | ||
@@ -19,13 +24,156 @@ | |||
19 | 24 | ||
20 | extern void versatile_secondary_startup(void); | 25 | extern void versatile_secondary_startup(void); |
21 | 26 | ||
27 | #if defined(CONFIG_OF) | ||
28 | |||
29 | static enum { | ||
30 | GENERIC_SCU, | ||
31 | CORTEX_A9_SCU, | ||
32 | } vexpress_dt_scu __initdata = GENERIC_SCU; | ||
33 | |||
34 | static struct map_desc vexpress_dt_cortex_a9_scu_map __initdata = { | ||
35 | .virtual = V2T_PERIPH, | ||
36 | /* .pfn set in vexpress_dt_init_cortex_a9_scu() */ | ||
37 | .length = SZ_128, | ||
38 | .type = MT_DEVICE, | ||
39 | }; | ||
40 | |||
41 | static void *vexpress_dt_cortex_a9_scu_base __initdata; | ||
42 | |||
43 | const static char *vexpress_dt_cortex_a9_match[] __initconst = { | ||
44 | "arm,cortex-a5-scu", | ||
45 | "arm,cortex-a9-scu", | ||
46 | NULL | ||
47 | }; | ||
48 | |||
49 | static int __init vexpress_dt_find_scu(unsigned long node, | ||
50 | const char *uname, int depth, void *data) | ||
51 | { | ||
52 | if (of_flat_dt_match(node, vexpress_dt_cortex_a9_match)) { | ||
53 | phys_addr_t phys_addr; | ||
54 | __be32 *reg = of_get_flat_dt_prop(node, "reg", NULL); | ||
55 | |||
56 | if (WARN_ON(!reg)) | ||
57 | return -EINVAL; | ||
58 | |||
59 | phys_addr = be32_to_cpup(reg); | ||
60 | vexpress_dt_scu = CORTEX_A9_SCU; | ||
61 | |||
62 | vexpress_dt_cortex_a9_scu_map.pfn = __phys_to_pfn(phys_addr); | ||
63 | iotable_init(&vexpress_dt_cortex_a9_scu_map, 1); | ||
64 | vexpress_dt_cortex_a9_scu_base = ioremap(phys_addr, SZ_256); | ||
65 | if (WARN_ON(!vexpress_dt_cortex_a9_scu_base)) | ||
66 | return -EFAULT; | ||
67 | } | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | void __init vexpress_dt_smp_map_io(void) | ||
73 | { | ||
74 | if (initial_boot_params) | ||
75 | WARN_ON(of_scan_flat_dt(vexpress_dt_find_scu, NULL)); | ||
76 | } | ||
77 | |||
78 | static int __init vexpress_dt_cpus_num(unsigned long node, const char *uname, | ||
79 | int depth, void *data) | ||
80 | { | ||
81 | static int prev_depth = -1; | ||
82 | static int nr_cpus = -1; | ||
83 | |||
84 | if (prev_depth > depth && nr_cpus > 0) | ||
85 | return nr_cpus; | ||
86 | |||
87 | if (nr_cpus < 0 && strcmp(uname, "cpus") == 0) | ||
88 | nr_cpus = 0; | ||
89 | |||
90 | if (nr_cpus >= 0) { | ||
91 | const char *device_type = of_get_flat_dt_prop(node, | ||
92 | "device_type", NULL); | ||
93 | |||
94 | if (device_type && strcmp(device_type, "cpu") == 0) | ||
95 | nr_cpus++; | ||
96 | } | ||
97 | |||
98 | prev_depth = depth; | ||
99 | |||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static void __init vexpress_dt_smp_init_cpus(void) | ||
104 | { | ||
105 | int ncores = 0, i; | ||
106 | |||
107 | switch (vexpress_dt_scu) { | ||
108 | case GENERIC_SCU: | ||
109 | ncores = of_scan_flat_dt(vexpress_dt_cpus_num, NULL); | ||
110 | break; | ||
111 | case CORTEX_A9_SCU: | ||
112 | ncores = scu_get_core_count(vexpress_dt_cortex_a9_scu_base); | ||
113 | break; | ||
114 | default: | ||
115 | WARN_ON(1); | ||
116 | break; | ||
117 | } | ||
118 | |||
119 | if (ncores < 2) | ||
120 | return; | ||
121 | |||
122 | if (ncores > nr_cpu_ids) { | ||
123 | pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", | ||
124 | ncores, nr_cpu_ids); | ||
125 | ncores = nr_cpu_ids; | ||
126 | } | ||
127 | |||
128 | for (i = 0; i < ncores; ++i) | ||
129 | set_cpu_possible(i, true); | ||
130 | |||
131 | set_smp_cross_call(gic_raise_softirq); | ||
132 | } | ||
133 | |||
134 | static void __init vexpress_dt_smp_prepare_cpus(unsigned int max_cpus) | ||
135 | { | ||
136 | int i; | ||
137 | |||
138 | switch (vexpress_dt_scu) { | ||
139 | case GENERIC_SCU: | ||
140 | for (i = 0; i < max_cpus; i++) | ||
141 | set_cpu_present(i, true); | ||
142 | break; | ||
143 | case CORTEX_A9_SCU: | ||
144 | scu_enable(vexpress_dt_cortex_a9_scu_base); | ||
145 | break; | ||
146 | default: | ||
147 | WARN_ON(1); | ||
148 | break; | ||
149 | } | ||
150 | } | ||
151 | |||
152 | #else | ||
153 | |||
154 | static void __init vexpress_dt_smp_init_cpus(void) | ||
155 | { | ||
156 | WARN_ON(1); | ||
157 | } | ||
158 | |||
159 | void __init vexpress_dt_smp_prepare_cpus(unsigned int max_cpus) | ||
160 | { | ||
161 | WARN_ON(1); | ||
162 | } | ||
163 | |||
164 | #endif | ||
165 | |||
22 | /* | 166 | /* |
23 | * Initialise the CPU possible map early - this describes the CPUs | 167 | * Initialise the CPU possible map early - this describes the CPUs |
24 | * which may be present or become present in the system. | 168 | * which may be present or become present in the system. |
25 | */ | 169 | */ |
26 | void __init smp_init_cpus(void) | 170 | void __init smp_init_cpus(void) |
27 | { | 171 | { |
28 | ct_desc->init_cpu_map(); | 172 | if (ct_desc) |
173 | ct_desc->init_cpu_map(); | ||
174 | else | ||
175 | vexpress_dt_smp_init_cpus(); | ||
176 | |||
29 | } | 177 | } |
30 | 178 | ||
31 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) | 179 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) |
@@ -34,7 +182,10 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus) | |||
34 | * Initialise the present map, which describes the set of CPUs | 182 | * Initialise the present map, which describes the set of CPUs |
35 | * actually populated at the present time. | 183 | * actually populated at the present time. |
36 | */ | 184 | */ |
37 | ct_desc->smp_enable(max_cpus); | 185 | if (ct_desc) |
186 | ct_desc->smp_enable(max_cpus); | ||
187 | else | ||
188 | vexpress_dt_smp_prepare_cpus(max_cpus); | ||
38 | 189 | ||
39 | /* | 190 | /* |
40 | * Write the address of secondary startup into the | 191 | * Write the address of secondary startup into the |
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 663a9883192..47cdcca5a7e 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c | |||
@@ -6,6 +6,10 @@ | |||
6 | #include <linux/amba/mmci.h> | 6 | #include <linux/amba/mmci.h> |
7 | #include <linux/io.h> | 7 | #include <linux/io.h> |
8 | #include <linux/init.h> | 8 | #include <linux/init.h> |
9 | #include <linux/of_address.h> | ||
10 | #include <linux/of_fdt.h> | ||
11 | #include <linux/of_irq.h> | ||
12 | #include <linux/of_platform.h> | ||
9 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
10 | #include <linux/ata_platform.h> | 14 | #include <linux/ata_platform.h> |
11 | #include <linux/smsc911x.h> | 15 | #include <linux/smsc911x.h> |
@@ -21,6 +25,8 @@ | |||
21 | #include <asm/mach/map.h> | 25 | #include <asm/mach/map.h> |
22 | #include <asm/mach/time.h> | 26 | #include <asm/mach/time.h> |
23 | #include <asm/hardware/arm_timer.h> | 27 | #include <asm/hardware/arm_timer.h> |
28 | #include <asm/hardware/cache-l2x0.h> | ||
29 | #include <asm/hardware/gic.h> | ||
24 | #include <asm/hardware/timer-sp.h> | 30 | #include <asm/hardware/timer-sp.h> |
25 | #include <asm/hardware/sp810.h> | 31 | #include <asm/hardware/sp810.h> |
26 | #include <asm/hardware/gic.h> | 32 | #include <asm/hardware/gic.h> |
@@ -430,8 +436,9 @@ static void __init v2m_populate_ct_desc(void) | |||
430 | ct_desc = ct_descs[i]; | 436 | ct_desc = ct_descs[i]; |
431 | 437 | ||
432 | if (!ct_desc) | 438 | if (!ct_desc) |
433 | panic("vexpress: failed to populate core tile description " | 439 | panic("vexpress: this kernel does not support core tile ID 0x%08x when booting via ATAGs.\n" |
434 | "for tile ID 0x%8x\n", current_tile_id); | 440 | "You may need a device tree blob or a different kernel to boot on this board.\n", |
441 | current_tile_id); | ||
435 | } | 442 | } |
436 | 443 | ||
437 | static void __init v2m_map_io(void) | 444 | static void __init v2m_map_io(void) |
@@ -476,3 +483,205 @@ MACHINE_START(VEXPRESS, "ARM-Versatile Express") | |||
476 | .init_machine = v2m_init, | 483 | .init_machine = v2m_init, |
477 | .restart = v2m_restart, | 484 | .restart = v2m_restart, |
478 | MACHINE_END | 485 | MACHINE_END |
486 | |||
487 | #if defined(CONFIG_ARCH_VEXPRESS_DT) | ||
488 | |||
489 | static struct map_desc v2m_rs1_io_desc __initdata = { | ||
490 | .virtual = V2M_PERIPH, | ||
491 | .pfn = __phys_to_pfn(0x1c000000), | ||
492 | .length = SZ_2M, | ||
493 | .type = MT_DEVICE, | ||
494 | }; | ||
495 | |||
496 | static int __init v2m_dt_scan_memory_map(unsigned long node, const char *uname, | ||
497 | int depth, void *data) | ||
498 | { | ||
499 | const char **map = data; | ||
500 | |||
501 | if (strcmp(uname, "motherboard") != 0) | ||
502 | return 0; | ||
503 | |||
504 | *map = of_get_flat_dt_prop(node, "arm,v2m-memory-map", NULL); | ||
505 | |||
506 | return 1; | ||
507 | } | ||
508 | |||
509 | void __init v2m_dt_map_io(void) | ||
510 | { | ||
511 | const char *map = NULL; | ||
512 | |||
513 | of_scan_flat_dt(v2m_dt_scan_memory_map, &map); | ||
514 | |||
515 | if (map && strcmp(map, "rs1") == 0) | ||
516 | iotable_init(&v2m_rs1_io_desc, 1); | ||
517 | else | ||
518 | iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc)); | ||
519 | |||
520 | #if defined(CONFIG_SMP) | ||
521 | vexpress_dt_smp_map_io(); | ||
522 | #endif | ||
523 | } | ||
524 | |||
525 | static struct clk_lookup v2m_dt_lookups[] = { | ||
526 | { /* AMBA bus clock */ | ||
527 | .con_id = "apb_pclk", | ||
528 | .clk = &dummy_apb_pclk, | ||
529 | }, { /* SP804 timers */ | ||
530 | .dev_id = "sp804", | ||
531 | .con_id = "v2m-timer0", | ||
532 | .clk = &v2m_sp804_clk, | ||
533 | }, { /* SP804 timers */ | ||
534 | .dev_id = "sp804", | ||
535 | .con_id = "v2m-timer1", | ||
536 | .clk = &v2m_sp804_clk, | ||
537 | }, { /* PL180 MMCI */ | ||
538 | .dev_id = "mb:mmci", /* 10005000.mmci */ | ||
539 | .clk = &osc2_clk, | ||
540 | }, { /* PL050 KMI0 */ | ||
541 | .dev_id = "10006000.kmi", | ||
542 | .clk = &osc2_clk, | ||
543 | }, { /* PL050 KMI1 */ | ||
544 | .dev_id = "10007000.kmi", | ||
545 | .clk = &osc2_clk, | ||
546 | }, { /* PL011 UART0 */ | ||
547 | .dev_id = "10009000.uart", | ||
548 | .clk = &osc2_clk, | ||
549 | }, { /* PL011 UART1 */ | ||
550 | .dev_id = "1000a000.uart", | ||
551 | .clk = &osc2_clk, | ||
552 | }, { /* PL011 UART2 */ | ||
553 | .dev_id = "1000b000.uart", | ||
554 | .clk = &osc2_clk, | ||
555 | }, { /* PL011 UART3 */ | ||
556 | .dev_id = "1000c000.uart", | ||
557 | .clk = &osc2_clk, | ||
558 | }, { /* SP805 WDT */ | ||
559 | .dev_id = "1000f000.wdt", | ||
560 | .clk = &v2m_ref_clk, | ||
561 | }, { /* PL111 CLCD */ | ||
562 | .dev_id = "1001f000.clcd", | ||
563 | .clk = &osc1_clk, | ||
564 | }, | ||
565 | /* RS1 memory map */ | ||
566 | { /* PL180 MMCI */ | ||
567 | .dev_id = "mb:mmci", /* 1c050000.mmci */ | ||
568 | .clk = &osc2_clk, | ||
569 | }, { /* PL050 KMI0 */ | ||
570 | .dev_id = "1c060000.kmi", | ||
571 | .clk = &osc2_clk, | ||
572 | }, { /* PL050 KMI1 */ | ||
573 | .dev_id = "1c070000.kmi", | ||
574 | .clk = &osc2_clk, | ||
575 | }, { /* PL011 UART0 */ | ||
576 | .dev_id = "1c090000.uart", | ||
577 | .clk = &osc2_clk, | ||
578 | }, { /* PL011 UART1 */ | ||
579 | .dev_id = "1c0a0000.uart", | ||
580 | .clk = &osc2_clk, | ||
581 | }, { /* PL011 UART2 */ | ||
582 | .dev_id = "1c0b0000.uart", | ||
583 | .clk = &osc2_clk, | ||
584 | }, { /* PL011 UART3 */ | ||
585 | .dev_id = "1c0c0000.uart", | ||
586 | .clk = &osc2_clk, | ||
587 | }, { /* SP805 WDT */ | ||
588 | .dev_id = "1c0f0000.wdt", | ||
589 | .clk = &v2m_ref_clk, | ||
590 | }, { /* PL111 CLCD */ | ||
591 | .dev_id = "1c1f0000.clcd", | ||
592 | .clk = &osc1_clk, | ||
593 | }, | ||
594 | }; | ||
595 | |||
596 | void __init v2m_dt_init_early(void) | ||
597 | { | ||
598 | struct device_node *node; | ||
599 | u32 dt_hbi; | ||
600 | |||
601 | node = of_find_compatible_node(NULL, NULL, "arm,vexpress-sysreg"); | ||
602 | v2m_sysreg_base = of_iomap(node, 0); | ||
603 | if (WARN_ON(!v2m_sysreg_base)) | ||
604 | return; | ||
605 | |||
606 | /* Confirm board type against DT property, if available */ | ||
607 | if (of_property_read_u32(allnodes, "arm,hbi", &dt_hbi) == 0) { | ||
608 | u32 misc = readl(v2m_sysreg_base + V2M_SYS_MISC); | ||
609 | u32 id = readl(v2m_sysreg_base + (misc & SYS_MISC_MASTERSITE ? | ||
610 | V2M_SYS_PROCID1 : V2M_SYS_PROCID0)); | ||
611 | u32 hbi = id & SYS_PROCIDx_HBI_MASK; | ||
612 | |||
613 | if (WARN_ON(dt_hbi != hbi)) | ||
614 | pr_warning("vexpress: DT HBI (%x) is not matching " | ||
615 | "hardware (%x)!\n", dt_hbi, hbi); | ||
616 | } | ||
617 | |||
618 | clkdev_add_table(v2m_dt_lookups, ARRAY_SIZE(v2m_dt_lookups)); | ||
619 | versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000); | ||
620 | } | ||
621 | |||
622 | static struct of_device_id vexpress_irq_match[] __initdata = { | ||
623 | { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, | ||
624 | {} | ||
625 | }; | ||
626 | |||
627 | static void __init v2m_dt_init_irq(void) | ||
628 | { | ||
629 | of_irq_init(vexpress_irq_match); | ||
630 | } | ||
631 | |||
632 | static void __init v2m_dt_timer_init(void) | ||
633 | { | ||
634 | struct device_node *node; | ||
635 | const char *path; | ||
636 | int err; | ||
637 | |||
638 | node = of_find_compatible_node(NULL, NULL, "arm,sp810"); | ||
639 | v2m_sysctl_init(of_iomap(node, 0)); | ||
640 | |||
641 | err = of_property_read_string(of_aliases, "arm,v2m_timer", &path); | ||
642 | if (WARN_ON(err)) | ||
643 | return; | ||
644 | node = of_find_node_by_path(path); | ||
645 | v2m_sp804_init(of_iomap(node, 0), irq_of_parse_and_map(node, 0)); | ||
646 | } | ||
647 | |||
648 | static struct sys_timer v2m_dt_timer = { | ||
649 | .init = v2m_dt_timer_init, | ||
650 | }; | ||
651 | |||
652 | static struct of_dev_auxdata v2m_dt_auxdata_lookup[] __initdata = { | ||
653 | OF_DEV_AUXDATA("arm,vexpress-flash", V2M_NOR0, "physmap-flash", | ||
654 | &v2m_flash_data), | ||
655 | OF_DEV_AUXDATA("arm,primecell", V2M_MMCI, "mb:mmci", &v2m_mmci_data), | ||
656 | /* RS1 memory map */ | ||
657 | OF_DEV_AUXDATA("arm,vexpress-flash", 0x08000000, "physmap-flash", | ||
658 | &v2m_flash_data), | ||
659 | OF_DEV_AUXDATA("arm,primecell", 0x1c050000, "mb:mmci", &v2m_mmci_data), | ||
660 | {} | ||
661 | }; | ||
662 | |||
663 | static void __init v2m_dt_init(void) | ||
664 | { | ||
665 | l2x0_of_init(0x00400000, 0xfe0fffff); | ||
666 | of_platform_populate(NULL, of_default_bus_match_table, | ||
667 | v2m_dt_auxdata_lookup, NULL); | ||
668 | pm_power_off = v2m_power_off; | ||
669 | } | ||
670 | |||
671 | const static char *v2m_dt_match[] __initconst = { | ||
672 | "arm,vexpress", | ||
673 | NULL, | ||
674 | }; | ||
675 | |||
676 | DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express") | ||
677 | .dt_compat = v2m_dt_match, | ||
678 | .map_io = v2m_dt_map_io, | ||
679 | .init_early = v2m_dt_init_early, | ||
680 | .init_irq = v2m_dt_init_irq, | ||
681 | .timer = &v2m_dt_timer, | ||
682 | .init_machine = v2m_dt_init, | ||
683 | .handle_irq = gic_handle_irq, | ||
684 | .restart = v2m_restart, | ||
685 | MACHINE_END | ||
686 | |||
687 | #endif | ||