1
2
3
4
5
6
7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8
9#include <linux/types.h>
10#include <linux/slab.h>
11#include <linux/init.h>
12#include <linux/errno.h>
13#include <linux/export.h>
14#include <linux/spinlock.h>
15#include <linux/pci_ids.h>
16#include <asm/amd_nb.h>
17
18#define PCI_DEVICE_ID_AMD_17H_ROOT 0x1450
19#define PCI_DEVICE_ID_AMD_17H_M10H_ROOT 0x15d0
20#define PCI_DEVICE_ID_AMD_17H_M30H_ROOT 0x1480
21#define PCI_DEVICE_ID_AMD_17H_M60H_ROOT 0x1630
22#define PCI_DEVICE_ID_AMD_19H_M10H_ROOT 0x14a4
23#define PCI_DEVICE_ID_AMD_17H_DF_F4 0x1464
24#define PCI_DEVICE_ID_AMD_17H_M10H_DF_F4 0x15ec
25#define PCI_DEVICE_ID_AMD_17H_M30H_DF_F4 0x1494
26#define PCI_DEVICE_ID_AMD_17H_M60H_DF_F4 0x144c
27#define PCI_DEVICE_ID_AMD_17H_M70H_DF_F4 0x1444
28#define PCI_DEVICE_ID_AMD_19H_DF_F4 0x1654
29#define PCI_DEVICE_ID_AMD_19H_M10H_DF_F4 0x14b1
30#define PCI_DEVICE_ID_AMD_19H_M40H_ROOT 0x14b5
31#define PCI_DEVICE_ID_AMD_19H_M40H_DF_F4 0x167d
32#define PCI_DEVICE_ID_AMD_19H_M50H_DF_F4 0x166e
33
34
35static DEFINE_MUTEX(smn_mutex);
36
37static u32 *flush_words;
38
39static const struct pci_device_id amd_root_ids[] = {
40 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_ROOT) },
41 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_ROOT) },
42 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M30H_ROOT) },
43 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M60H_ROOT) },
44 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M10H_ROOT) },
45 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M40H_ROOT) },
46 {}
47};
48
49#define PCI_DEVICE_ID_AMD_CNB17H_F4 0x1704
50
51static const struct pci_device_id amd_nb_misc_ids[] = {
52 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
53 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) },
54 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) },
55 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M10H_F3) },
56 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F3) },
57 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M60H_NB_F3) },
58 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
59 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
60 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
61 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) },
62 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F3) },
63 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M60H_DF_F3) },
64 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) },
65 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F3) },
66 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_DF_F3) },
67 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M10H_DF_F3) },
68 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M40H_DF_F3) },
69 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M50H_DF_F3) },
70 {}
71};
72
73static const struct pci_device_id amd_nb_link_ids[] = {
74 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) },
75 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F4) },
76 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M60H_NB_F4) },
77 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) },
78 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F4) },
79 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F4) },
80 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F4) },
81 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F4) },
82 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M60H_DF_F4) },
83 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F4) },
84 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_DF_F4) },
85 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M10H_DF_F4) },
86 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M40H_DF_F4) },
87 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M50H_DF_F4) },
88 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) },
89 {}
90};
91
92static const struct pci_device_id hygon_root_ids[] = {
93 { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_ROOT) },
94 {}
95};
96
97static const struct pci_device_id hygon_nb_misc_ids[] = {
98 { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) },
99 {}
100};
101
102static const struct pci_device_id hygon_nb_link_ids[] = {
103 { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_DF_F4) },
104 {}
105};
106
107const struct amd_nb_bus_dev_range amd_nb_bus_dev_ranges[] __initconst = {
108 { 0x00, 0x18, 0x20 },
109 { 0xff, 0x00, 0x20 },
110 { 0xfe, 0x00, 0x20 },
111 { }
112};
113
114static struct amd_northbridge_info amd_northbridges;
115
116u16 amd_nb_num(void)
117{
118 return amd_northbridges.num;
119}
120EXPORT_SYMBOL_GPL(amd_nb_num);
121
122bool amd_nb_has_feature(unsigned int feature)
123{
124 return ((amd_northbridges.flags & feature) == feature);
125}
126EXPORT_SYMBOL_GPL(amd_nb_has_feature);
127
128struct amd_northbridge *node_to_amd_nb(int node)
129{
130 return (node < amd_northbridges.num) ? &amd_northbridges.nb[node] : NULL;
131}
132EXPORT_SYMBOL_GPL(node_to_amd_nb);
133
134static struct pci_dev *next_northbridge(struct pci_dev *dev,
135 const struct pci_device_id *ids)
136{
137 do {
138 dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
139 if (!dev)
140 break;
141 } while (!pci_match_id(ids, dev));
142 return dev;
143}
144
145static int __amd_smn_rw(u16 node, u32 address, u32 *value, bool write)
146{
147 struct pci_dev *root;
148 int err = -ENODEV;
149
150 if (node >= amd_northbridges.num)
151 goto out;
152
153 root = node_to_amd_nb(node)->root;
154 if (!root)
155 goto out;
156
157 mutex_lock(&smn_mutex);
158
159 err = pci_write_config_dword(root, 0x60, address);
160 if (err) {
161 pr_warn("Error programming SMN address 0x%x.\n", address);
162 goto out_unlock;
163 }
164
165 err = (write ? pci_write_config_dword(root, 0x64, *value)
166 : pci_read_config_dword(root, 0x64, value));
167 if (err)
168 pr_warn("Error %s SMN address 0x%x.\n",
169 (write ? "writing to" : "reading from"), address);
170
171out_unlock:
172 mutex_unlock(&smn_mutex);
173
174out:
175 return err;
176}
177
178int amd_smn_read(u16 node, u32 address, u32 *value)
179{
180 return __amd_smn_rw(node, address, value, false);
181}
182EXPORT_SYMBOL_GPL(amd_smn_read);
183
184int amd_smn_write(u16 node, u32 address, u32 value)
185{
186 return __amd_smn_rw(node, address, &value, true);
187}
188EXPORT_SYMBOL_GPL(amd_smn_write);
189
190
191int amd_cache_northbridges(void)
192{
193 const struct pci_device_id *misc_ids = amd_nb_misc_ids;
194 const struct pci_device_id *link_ids = amd_nb_link_ids;
195 const struct pci_device_id *root_ids = amd_root_ids;
196 struct pci_dev *root, *misc, *link;
197 struct amd_northbridge *nb;
198 u16 roots_per_misc = 0;
199 u16 misc_count = 0;
200 u16 root_count = 0;
201 u16 i, j;
202
203 if (amd_northbridges.num)
204 return 0;
205
206 if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
207 root_ids = hygon_root_ids;
208 misc_ids = hygon_nb_misc_ids;
209 link_ids = hygon_nb_link_ids;
210 }
211
212 misc = NULL;
213 while ((misc = next_northbridge(misc, misc_ids)) != NULL)
214 misc_count++;
215
216 if (!misc_count)
217 return -ENODEV;
218
219 root = NULL;
220 while ((root = next_northbridge(root, root_ids)) != NULL)
221 root_count++;
222
223 if (root_count) {
224 roots_per_misc = root_count / misc_count;
225
226
227
228
229
230 if (!roots_per_misc || (root_count % roots_per_misc)) {
231 pr_info("Unsupported AMD DF/PCI configuration found\n");
232 return -ENODEV;
233 }
234 }
235
236 nb = kcalloc(misc_count, sizeof(struct amd_northbridge), GFP_KERNEL);
237 if (!nb)
238 return -ENOMEM;
239
240 amd_northbridges.nb = nb;
241 amd_northbridges.num = misc_count;
242
243 link = misc = root = NULL;
244 for (i = 0; i < amd_northbridges.num; i++) {
245 node_to_amd_nb(i)->root = root =
246 next_northbridge(root, root_ids);
247 node_to_amd_nb(i)->misc = misc =
248 next_northbridge(misc, misc_ids);
249 node_to_amd_nb(i)->link = link =
250 next_northbridge(link, link_ids);
251
252
253
254
255
256
257
258
259
260
261 for (j = 1; j < roots_per_misc; j++)
262 root = next_northbridge(root, root_ids);
263 }
264
265 if (amd_gart_present())
266 amd_northbridges.flags |= AMD_NB_GART;
267
268
269
270
271 if (!cpuid_edx(0x80000006))
272 return 0;
273
274
275
276
277
278 if (boot_cpu_data.x86 == 0x10 &&
279 boot_cpu_data.x86_model >= 0x8 &&
280 (boot_cpu_data.x86_model > 0x9 ||
281 boot_cpu_data.x86_stepping >= 0x1))
282 amd_northbridges.flags |= AMD_NB_L3_INDEX_DISABLE;
283
284 if (boot_cpu_data.x86 == 0x15)
285 amd_northbridges.flags |= AMD_NB_L3_INDEX_DISABLE;
286
287
288 if (boot_cpu_data.x86 == 0x15)
289 amd_northbridges.flags |= AMD_NB_L3_PARTITIONING;
290
291 return 0;
292}
293EXPORT_SYMBOL_GPL(amd_cache_northbridges);
294
295
296
297
298
299bool __init early_is_amd_nb(u32 device)
300{
301 const struct pci_device_id *misc_ids = amd_nb_misc_ids;
302 const struct pci_device_id *id;
303 u32 vendor = device & 0xffff;
304
305 if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
306 boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
307 return false;
308
309 if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
310 misc_ids = hygon_nb_misc_ids;
311
312 device >>= 16;
313 for (id = misc_ids; id->vendor; id++)
314 if (vendor == id->vendor && device == id->device)
315 return true;
316 return false;
317}
318
319struct resource *amd_get_mmconfig_range(struct resource *res)
320{
321 u32 address;
322 u64 base, msr;
323 unsigned int segn_busn_bits;
324
325 if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
326 boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
327 return NULL;
328
329
330 if (boot_cpu_data.x86 < 0x10)
331 return NULL;
332
333 address = MSR_FAM10H_MMIO_CONF_BASE;
334 rdmsrl(address, msr);
335
336
337 if (!(msr & FAM10H_MMIO_CONF_ENABLE))
338 return NULL;
339
340 base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
341
342 segn_busn_bits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
343 FAM10H_MMIO_CONF_BUSRANGE_MASK;
344
345 res->flags = IORESOURCE_MEM;
346 res->start = base;
347 res->end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
348 return res;
349}
350
351int amd_get_subcaches(int cpu)
352{
353 struct pci_dev *link = node_to_amd_nb(topology_die_id(cpu))->link;
354 unsigned int mask;
355
356 if (!amd_nb_has_feature(AMD_NB_L3_PARTITIONING))
357 return 0;
358
359 pci_read_config_dword(link, 0x1d4, &mask);
360
361 return (mask >> (4 * cpu_data(cpu).cpu_core_id)) & 0xf;
362}
363
364int amd_set_subcaches(int cpu, unsigned long mask)
365{
366 static unsigned int reset, ban;
367 struct amd_northbridge *nb = node_to_amd_nb(topology_die_id(cpu));
368 unsigned int reg;
369 int cuid;
370
371 if (!amd_nb_has_feature(AMD_NB_L3_PARTITIONING) || mask > 0xf)
372 return -EINVAL;
373
374
375 if (reset == 0) {
376 pci_read_config_dword(nb->link, 0x1d4, &reset);
377 pci_read_config_dword(nb->misc, 0x1b8, &ban);
378 ban &= 0x180000;
379 }
380
381
382 if (mask != 0xf) {
383 pci_read_config_dword(nb->misc, 0x1b8, ®);
384 pci_write_config_dword(nb->misc, 0x1b8, reg & ~0x180000);
385 }
386
387 cuid = cpu_data(cpu).cpu_core_id;
388 mask <<= 4 * cuid;
389 mask |= (0xf ^ (1 << cuid)) << 26;
390
391 pci_write_config_dword(nb->link, 0x1d4, mask);
392
393
394 pci_read_config_dword(nb->link, 0x1d4, ®);
395 if (reg == reset) {
396 pci_read_config_dword(nb->misc, 0x1b8, ®);
397 reg &= ~0x180000;
398 pci_write_config_dword(nb->misc, 0x1b8, reg | ban);
399 }
400
401 return 0;
402}
403
404static void amd_cache_gart(void)
405{
406 u16 i;
407
408 if (!amd_nb_has_feature(AMD_NB_GART))
409 return;
410
411 flush_words = kmalloc_array(amd_northbridges.num, sizeof(u32), GFP_KERNEL);
412 if (!flush_words) {
413 amd_northbridges.flags &= ~AMD_NB_GART;
414 pr_notice("Cannot initialize GART flush words, GART support disabled\n");
415 return;
416 }
417
418 for (i = 0; i != amd_northbridges.num; i++)
419 pci_read_config_dword(node_to_amd_nb(i)->misc, 0x9c, &flush_words[i]);
420}
421
422void amd_flush_garts(void)
423{
424 int flushed, i;
425 unsigned long flags;
426 static DEFINE_SPINLOCK(gart_lock);
427
428 if (!amd_nb_has_feature(AMD_NB_GART))
429 return;
430
431
432
433
434
435
436
437 spin_lock_irqsave(&gart_lock, flags);
438 flushed = 0;
439 for (i = 0; i < amd_northbridges.num; i++) {
440 pci_write_config_dword(node_to_amd_nb(i)->misc, 0x9c,
441 flush_words[i] | 1);
442 flushed++;
443 }
444 for (i = 0; i < amd_northbridges.num; i++) {
445 u32 w;
446
447 for (;;) {
448 pci_read_config_dword(node_to_amd_nb(i)->misc,
449 0x9c, &w);
450 if (!(w & 1))
451 break;
452 cpu_relax();
453 }
454 }
455 spin_unlock_irqrestore(&gart_lock, flags);
456 if (!flushed)
457 pr_notice("nothing to flush?\n");
458}
459EXPORT_SYMBOL_GPL(amd_flush_garts);
460
461static void __fix_erratum_688(void *info)
462{
463#define MSR_AMD64_IC_CFG 0xC0011021
464
465 msr_set_bit(MSR_AMD64_IC_CFG, 3);
466 msr_set_bit(MSR_AMD64_IC_CFG, 14);
467}
468
469
470static __init void fix_erratum_688(void)
471{
472 struct pci_dev *F4;
473 u32 val;
474
475 if (boot_cpu_data.x86 != 0x14)
476 return;
477
478 if (!amd_northbridges.num)
479 return;
480
481 F4 = node_to_amd_nb(0)->link;
482 if (!F4)
483 return;
484
485 if (pci_read_config_dword(F4, 0x164, &val))
486 return;
487
488 if (val & BIT(2))
489 return;
490
491 on_each_cpu(__fix_erratum_688, NULL, 0);
492
493 pr_info("x86/cpu/AMD: CPU erratum 688 worked around\n");
494}
495
496static __init int init_amd_nbs(void)
497{
498 amd_cache_northbridges();
499 amd_cache_gart();
500
501 fix_erratum_688();
502
503 return 0;
504}
505
506
507fs_initcall(init_amd_nbs);
508