Merge tag 'drm-vc4-fixes-2016-09-14' of https://github.com/anholt/linux into drm...
[linux-2.6-block.git] / arch / x86 / kernel / apic / apic_numachip.c
CommitLineData
44b111b5
SP
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Numascale NumaConnect-Specific APIC Code
7 *
8 * Copyright (C) 2011 Numascale AS. All rights reserved.
9 *
10 * Send feedback to <support@numascale.com>
11 *
12 */
13
44b111b5 14#include <linux/init.h>
44b111b5 15
f9726bfd 16#include <asm/numachip/numachip.h>
44b111b5 17#include <asm/numachip/numachip_csr.h>
44b111b5
SP
18#include <asm/ipi.h>
19#include <asm/apic_flat_64.h>
fb50b020 20#include <asm/pgtable.h>
db1003a7 21#include <asm/pci_x86.h>
44b111b5 22
db1003a7
DB
23u8 numachip_system __read_mostly;
24static const struct apic apic_numachip1;
d9d4dee6 25static const struct apic apic_numachip2;
db1003a7 26static void (*numachip_apic_icr_write)(int apicid, unsigned int val) __read_mostly;
44b111b5 27
db1003a7 28static unsigned int numachip1_get_apic_id(unsigned long x)
44b111b5
SP
29{
30 unsigned long value;
c8a470ca 31 unsigned int id = (x >> 24) & 0xff;
44b111b5 32
bc696ca0 33 if (static_cpu_has(X86_FEATURE_NODEID_MSR)) {
c8a470ca
DB
34 rdmsrl(MSR_FAM10H_NODE_ID, value);
35 id |= (value << 2) & 0xff00;
36 }
44b111b5
SP
37
38 return id;
39}
40
db1003a7 41static unsigned long numachip1_set_apic_id(unsigned int id)
44b111b5
SP
42{
43 unsigned long x;
44
45 x = ((id & 0xffU) << 24);
46 return x;
47}
48
d9d4dee6
DB
49static unsigned int numachip2_get_apic_id(unsigned long x)
50{
51 u64 mcfg;
52
53 rdmsrl(MSR_FAM10H_MMIO_CONF_BASE, mcfg);
54 return ((mcfg >> (28 - 8)) & 0xfff00) | (x >> 24);
55}
56
57static unsigned long numachip2_set_apic_id(unsigned int id)
58{
59 return id << 24;
60}
61
fa63030e
DB
62static int numachip_apic_id_valid(int apicid)
63{
64 /* Trust what bootloader passes in MADT */
65 return 1;
66}
67
44b111b5
SP
68static int numachip_apic_id_registered(void)
69{
db1003a7 70 return 1;
44b111b5
SP
71}
72
73static int numachip_phys_pkg_id(int initial_apic_id, int index_msb)
74{
75 return initial_apic_id >> index_msb;
76}
77
db1003a7 78static void numachip1_apic_icr_write(int apicid, unsigned int val)
44b111b5 79{
db1003a7
DB
80 write_lcsr(CSR_G3_EXT_IRQ_GEN, (apicid << 16) | val);
81}
44b111b5 82
d9d4dee6
DB
83static void numachip2_apic_icr_write(int apicid, unsigned int val)
84{
85 numachip2_write32_lcsr(NUMACHIP2_APIC_ICR, (apicid << 12) | val);
86}
87
db1003a7
DB
88static int numachip_wakeup_secondary(int phys_apicid, unsigned long start_rip)
89{
90 numachip_apic_icr_write(phys_apicid, APIC_DM_INIT);
91 numachip_apic_icr_write(phys_apicid, APIC_DM_STARTUP |
92 (start_rip >> 12));
44b111b5 93
44b111b5
SP
94 return 0;
95}
96
97static void numachip_send_IPI_one(int cpu, int vector)
98{
ad03a9c2 99 int local_apicid, apicid = per_cpu(x86_cpu_to_apicid, cpu);
db1003a7 100 unsigned int dmode;
44b111b5 101
ad03a9c2
DB
102 preempt_disable();
103 local_apicid = __this_cpu_read(x86_cpu_to_apicid);
104
105 /* Send via local APIC where non-local part matches */
106 if (!((apicid ^ local_apicid) >> NUMACHIP_LAPIC_BITS)) {
107 unsigned long flags;
108
109 local_irq_save(flags);
110 __default_send_IPI_dest_field(apicid, vector,
111 APIC_DEST_PHYSICAL);
112 local_irq_restore(flags);
113 preempt_enable();
114 return;
115 }
116 preempt_enable();
117
db1003a7
DB
118 dmode = (vector == NMI_VECTOR) ? APIC_DM_NMI : APIC_DM_FIXED;
119 numachip_apic_icr_write(apicid, dmode | vector);
44b111b5
SP
120}
121
122static void numachip_send_IPI_mask(const struct cpumask *mask, int vector)
123{
124 unsigned int cpu;
125
126 for_each_cpu(cpu, mask)
127 numachip_send_IPI_one(cpu, vector);
128}
129
130static void numachip_send_IPI_mask_allbutself(const struct cpumask *mask,
131 int vector)
132{
133 unsigned int this_cpu = smp_processor_id();
134 unsigned int cpu;
135
136 for_each_cpu(cpu, mask) {
137 if (cpu != this_cpu)
138 numachip_send_IPI_one(cpu, vector);
139 }
140}
141
142static void numachip_send_IPI_allbutself(int vector)
143{
144 unsigned int this_cpu = smp_processor_id();
145 unsigned int cpu;
146
147 for_each_online_cpu(cpu) {
148 if (cpu != this_cpu)
149 numachip_send_IPI_one(cpu, vector);
150 }
151}
152
153static void numachip_send_IPI_all(int vector)
154{
155 numachip_send_IPI_mask(cpu_online_mask, vector);
156}
157
158static void numachip_send_IPI_self(int vector)
159{
25e5a76b 160 apic_write(APIC_SELF_IPI, vector);
44b111b5
SP
161}
162
db1003a7 163static int __init numachip1_probe(void)
44b111b5 164{
db1003a7 165 return apic == &apic_numachip1;
44b111b5
SP
166}
167
d9d4dee6
DB
168static int __init numachip2_probe(void)
169{
170 return apic == &apic_numachip2;
171}
172
44b111b5
SP
173static void fixup_cpu_id(struct cpuinfo_x86 *c, int node)
174{
c8a470ca
DB
175 u64 val;
176 u32 nodes = 1;
177
178 this_cpu_write(cpu_llc_id, node);
179
180 /* Account for nodes per socket in multi-core-module processors */
bc696ca0 181 if (static_cpu_has(X86_FEATURE_NODEID_MSR)) {
c8a470ca
DB
182 rdmsrl(MSR_FAM10H_NODE_ID, val);
183 nodes = ((val >> 3) & 7) + 1;
68894632 184 }
c8a470ca
DB
185
186 c->phys_proc_id = node / nodes;
44b111b5
SP
187}
188
189static int __init numachip_system_init(void)
190{
db1003a7
DB
191 /* Map the LCSR area and set up the apic_icr_write function */
192 switch (numachip_system) {
193 case 1:
194 init_extra_mapping_uc(NUMACHIP_LCSR_BASE, NUMACHIP_LCSR_SIZE);
195 numachip_apic_icr_write = numachip1_apic_icr_write;
db1003a7 196 break;
d9d4dee6
DB
197 case 2:
198 init_extra_mapping_uc(NUMACHIP2_LCSR_BASE, NUMACHIP2_LCSR_SIZE);
199 numachip_apic_icr_write = numachip2_apic_icr_write;
d9d4dee6 200 break;
db1003a7 201 default:
44b111b5 202 return 0;
db1003a7 203 }
b980dcf2 204
44b111b5 205 x86_cpuinit.fixup_cpu_id = fixup_cpu_id;
dd7a5ab4 206 x86_init.pci.arch_init = pci_numachip_init;
44b111b5 207
44b111b5
SP
208 return 0;
209}
210early_initcall(numachip_system_init);
211
db1003a7 212static int numachip1_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
44b111b5 213{
db1003a7
DB
214 if ((strncmp(oem_id, "NUMASC", 6) != 0) ||
215 (strncmp(oem_table_id, "NCONNECT", 8) != 0))
216 return 0;
44b111b5 217
db1003a7 218 numachip_system = 1;
44b111b5 219
db1003a7
DB
220 return 1;
221}
44b111b5 222
d9d4dee6
DB
223static int numachip2_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
224{
225 if ((strncmp(oem_id, "NUMASC", 6) != 0) ||
226 (strncmp(oem_table_id, "NCONECT2", 8) != 0))
227 return 0;
228
229 numachip_system = 2;
230
231 return 1;
232}
233
ad03a9c2
DB
234/* APIC IPIs are queued */
235static void numachip_apic_wait_icr_idle(void)
236{
237}
238
239/* APIC NMI IPIs are queued */
240static u32 numachip_safe_apic_wait_icr_idle(void)
241{
242 return 0;
243}
244
db1003a7 245static const struct apic apic_numachip1 __refconst = {
44b111b5 246 .name = "NumaConnect system",
db1003a7
DB
247 .probe = numachip1_probe,
248 .acpi_madt_oem_check = numachip1_acpi_madt_oem_check,
fa63030e 249 .apic_id_valid = numachip_apic_id_valid,
44b111b5
SP
250 .apic_id_registered = numachip_apic_id_registered,
251
252 .irq_delivery_mode = dest_Fixed,
253 .irq_dest_mode = 0, /* physical */
254
bf721d3a 255 .target_cpus = online_target_cpus,
44b111b5
SP
256 .disable_esr = 0,
257 .dest_logical = 0,
258 .check_apicid_used = NULL,
44b111b5 259
9d8e1066 260 .vector_allocation_domain = default_vector_allocation_domain,
44b111b5
SP
261 .init_apic_ldr = flat_init_apic_ldr,
262
263 .ioapic_phys_id_map = NULL,
264 .setup_apic_routing = NULL,
44b111b5
SP
265 .cpu_present_to_apicid = default_cpu_present_to_apicid,
266 .apicid_to_cpu_present = NULL,
44b111b5 267 .check_phys_apicid_present = default_check_phys_apicid_present,
44b111b5 268 .phys_pkg_id = numachip_phys_pkg_id,
44b111b5 269
db1003a7
DB
270 .get_apic_id = numachip1_get_apic_id,
271 .set_apic_id = numachip1_set_apic_id,
44b111b5 272
6398268d 273 .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and,
44b111b5 274
c61a0d31 275 .send_IPI = numachip_send_IPI_one,
44b111b5
SP
276 .send_IPI_mask = numachip_send_IPI_mask,
277 .send_IPI_mask_allbutself = numachip_send_IPI_mask_allbutself,
278 .send_IPI_allbutself = numachip_send_IPI_allbutself,
279 .send_IPI_all = numachip_send_IPI_all,
280 .send_IPI_self = numachip_send_IPI_self,
281
282 .wakeup_secondary_cpu = numachip_wakeup_secondary,
44b111b5
SP
283 .inquire_remote_apic = NULL, /* REMRD not supported */
284
285 .read = native_apic_mem_read,
286 .write = native_apic_mem_write,
2a43195d 287 .eoi_write = native_apic_mem_write,
44b111b5
SP
288 .icr_read = native_apic_icr_read,
289 .icr_write = native_apic_icr_write,
ad03a9c2
DB
290 .wait_icr_idle = numachip_apic_wait_icr_idle,
291 .safe_wait_icr_idle = numachip_safe_apic_wait_icr_idle,
44b111b5 292};
44b111b5 293
db1003a7 294apic_driver(apic_numachip1);
d9d4dee6
DB
295
296static const struct apic apic_numachip2 __refconst = {
297 .name = "NumaConnect2 system",
298 .probe = numachip2_probe,
299 .acpi_madt_oem_check = numachip2_acpi_madt_oem_check,
300 .apic_id_valid = numachip_apic_id_valid,
301 .apic_id_registered = numachip_apic_id_registered,
302
303 .irq_delivery_mode = dest_Fixed,
304 .irq_dest_mode = 0, /* physical */
305
306 .target_cpus = online_target_cpus,
307 .disable_esr = 0,
308 .dest_logical = 0,
309 .check_apicid_used = NULL,
310
311 .vector_allocation_domain = default_vector_allocation_domain,
312 .init_apic_ldr = flat_init_apic_ldr,
313
314 .ioapic_phys_id_map = NULL,
315 .setup_apic_routing = NULL,
316 .cpu_present_to_apicid = default_cpu_present_to_apicid,
317 .apicid_to_cpu_present = NULL,
318 .check_phys_apicid_present = default_check_phys_apicid_present,
319 .phys_pkg_id = numachip_phys_pkg_id,
320
321 .get_apic_id = numachip2_get_apic_id,
322 .set_apic_id = numachip2_set_apic_id,
d9d4dee6
DB
323
324 .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and,
325
c61a0d31 326 .send_IPI = numachip_send_IPI_one,
d9d4dee6
DB
327 .send_IPI_mask = numachip_send_IPI_mask,
328 .send_IPI_mask_allbutself = numachip_send_IPI_mask_allbutself,
329 .send_IPI_allbutself = numachip_send_IPI_allbutself,
330 .send_IPI_all = numachip_send_IPI_all,
331 .send_IPI_self = numachip_send_IPI_self,
332
333 .wakeup_secondary_cpu = numachip_wakeup_secondary,
334 .inquire_remote_apic = NULL, /* REMRD not supported */
335
336 .read = native_apic_mem_read,
337 .write = native_apic_mem_write,
338 .eoi_write = native_apic_mem_write,
339 .icr_read = native_apic_icr_read,
340 .icr_write = native_apic_icr_write,
ad03a9c2
DB
341 .wait_icr_idle = numachip_apic_wait_icr_idle,
342 .safe_wait_icr_idle = numachip_safe_apic_wait_icr_idle,
d9d4dee6
DB
343};
344
345apic_driver(apic_numachip2);