Linux Audio

Check our new training course

Real-Time Linux with PREEMPT_RT training

Feb 18-20, 2025
Register
Loading...
v3.5.6
 
  1/*
  2 * Shared support code for AMD K8 northbridges and derivates.
  3 * Copyright 2006 Andi Kleen, SUSE Labs. Subject to GPLv2.
  4 */
 
 
 
  5#include <linux/types.h>
  6#include <linux/slab.h>
  7#include <linux/init.h>
  8#include <linux/errno.h>
  9#include <linux/module.h>
 10#include <linux/spinlock.h>
 
 11#include <asm/amd_nb.h>
 12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 13static u32 *flush_words;
 14
 15const struct pci_device_id amd_nb_misc_ids[] = {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 16	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
 17	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) },
 18	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 19	{}
 20};
 21EXPORT_SYMBOL(amd_nb_misc_ids);
 22
 23static struct pci_device_id amd_nb_link_ids[] = {
 24	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 25	{}
 26};
 27
 28const struct amd_nb_bus_dev_range amd_nb_bus_dev_ranges[] __initconst = {
 29	{ 0x00, 0x18, 0x20 },
 30	{ 0xff, 0x00, 0x20 },
 31	{ 0xfe, 0x00, 0x20 },
 32	{ }
 33};
 34
 35struct amd_northbridge_info amd_northbridges;
 36EXPORT_SYMBOL(amd_northbridges);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 37
 38static struct pci_dev *next_northbridge(struct pci_dev *dev,
 39					const struct pci_device_id *ids)
 40{
 41	do {
 42		dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
 43		if (!dev)
 44			break;
 45	} while (!pci_match_id(ids, dev));
 46	return dev;
 47}
 48
 49int amd_cache_northbridges(void)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 50{
 51	u16 i = 0;
 
 
 
 52	struct amd_northbridge *nb;
 53	struct pci_dev *misc, *link;
 
 
 
 54
 55	if (amd_nb_num())
 56		return 0;
 57
 
 
 
 
 
 
 58	misc = NULL;
 59	while ((misc = next_northbridge(misc, amd_nb_misc_ids)) != NULL)
 60		i++;
 61
 62	if (i == 0)
 63		return 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 64
 65	nb = kzalloc(i * sizeof(struct amd_northbridge), GFP_KERNEL);
 66	if (!nb)
 67		return -ENOMEM;
 68
 69	amd_northbridges.nb = nb;
 70	amd_northbridges.num = i;
 71
 72	link = misc = NULL;
 73	for (i = 0; i != amd_nb_num(); i++) {
 
 
 74		node_to_amd_nb(i)->misc = misc =
 75			next_northbridge(misc, amd_nb_misc_ids);
 76		node_to_amd_nb(i)->link = link =
 77			next_northbridge(link, amd_nb_link_ids);
 78        }
 79
 80	/* some CPU families (e.g. family 0x11) do not support GART */
 81	if (boot_cpu_data.x86 == 0xf || boot_cpu_data.x86 == 0x10 ||
 82	    boot_cpu_data.x86 == 0x15)
 
 
 
 
 
 
 
 
 
 
 
 83		amd_northbridges.flags |= AMD_NB_GART;
 84
 85	/*
 
 
 
 
 
 
 86	 * Some CPU families support L3 Cache Index Disable. There are some
 87	 * limitations because of E382 and E388 on family 0x10.
 88	 */
 89	if (boot_cpu_data.x86 == 0x10 &&
 90	    boot_cpu_data.x86_model >= 0x8 &&
 91	    (boot_cpu_data.x86_model > 0x9 ||
 92	     boot_cpu_data.x86_mask >= 0x1))
 93		amd_northbridges.flags |= AMD_NB_L3_INDEX_DISABLE;
 94
 95	if (boot_cpu_data.x86 == 0x15)
 96		amd_northbridges.flags |= AMD_NB_L3_INDEX_DISABLE;
 97
 98	/* L3 cache partitioning is supported on family 0x15 */
 99	if (boot_cpu_data.x86 == 0x15)
100		amd_northbridges.flags |= AMD_NB_L3_PARTITIONING;
101
102	return 0;
103}
104EXPORT_SYMBOL_GPL(amd_cache_northbridges);
105
106/*
107 * Ignores subdevice/subvendor but as far as I can figure out
108 * they're useless anyways
109 */
110bool __init early_is_amd_nb(u32 device)
111{
 
112	const struct pci_device_id *id;
113	u32 vendor = device & 0xffff;
114
 
 
 
 
 
 
 
115	device >>= 16;
116	for (id = amd_nb_misc_ids; id->vendor; id++)
117		if (vendor == id->vendor && device == id->device)
118			return true;
119	return false;
120}
121
122struct resource *amd_get_mmconfig_range(struct resource *res)
123{
124	u32 address;
125	u64 base, msr;
126	unsigned segn_busn_bits;
127
128	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
 
129		return NULL;
130
131	/* assume all cpus from fam10h have mmconfig */
132        if (boot_cpu_data.x86 < 0x10)
133		return NULL;
134
135	address = MSR_FAM10H_MMIO_CONF_BASE;
136	rdmsrl(address, msr);
137
138	/* mmconfig is not enabled */
139	if (!(msr & FAM10H_MMIO_CONF_ENABLE))
140		return NULL;
141
142	base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
143
144	segn_busn_bits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
145			 FAM10H_MMIO_CONF_BUSRANGE_MASK;
146
147	res->flags = IORESOURCE_MEM;
148	res->start = base;
149	res->end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
150	return res;
151}
152
153int amd_get_subcaches(int cpu)
154{
155	struct pci_dev *link = node_to_amd_nb(amd_get_nb_id(cpu))->link;
156	unsigned int mask;
157	int cuid;
158
159	if (!amd_nb_has_feature(AMD_NB_L3_PARTITIONING))
160		return 0;
161
162	pci_read_config_dword(link, 0x1d4, &mask);
163
164	cuid = cpu_data(cpu).compute_unit_id;
165	return (mask >> (4 * cuid)) & 0xf;
166}
167
168int amd_set_subcaches(int cpu, int mask)
169{
170	static unsigned int reset, ban;
171	struct amd_northbridge *nb = node_to_amd_nb(amd_get_nb_id(cpu));
172	unsigned int reg;
173	int cuid;
174
175	if (!amd_nb_has_feature(AMD_NB_L3_PARTITIONING) || mask > 0xf)
176		return -EINVAL;
177
178	/* if necessary, collect reset state of L3 partitioning and BAN mode */
179	if (reset == 0) {
180		pci_read_config_dword(nb->link, 0x1d4, &reset);
181		pci_read_config_dword(nb->misc, 0x1b8, &ban);
182		ban &= 0x180000;
183	}
184
185	/* deactivate BAN mode if any subcaches are to be disabled */
186	if (mask != 0xf) {
187		pci_read_config_dword(nb->misc, 0x1b8, &reg);
188		pci_write_config_dword(nb->misc, 0x1b8, reg & ~0x180000);
189	}
190
191	cuid = cpu_data(cpu).compute_unit_id;
192	mask <<= 4 * cuid;
193	mask |= (0xf ^ (1 << cuid)) << 26;
194
195	pci_write_config_dword(nb->link, 0x1d4, mask);
196
197	/* reset BAN mode if L3 partitioning returned to reset state */
198	pci_read_config_dword(nb->link, 0x1d4, &reg);
199	if (reg == reset) {
200		pci_read_config_dword(nb->misc, 0x1b8, &reg);
201		reg &= ~0x180000;
202		pci_write_config_dword(nb->misc, 0x1b8, reg | ban);
203	}
204
205	return 0;
206}
207
208static int amd_cache_gart(void)
209{
210	u16 i;
211
212       if (!amd_nb_has_feature(AMD_NB_GART))
213               return 0;
214
215       flush_words = kmalloc(amd_nb_num() * sizeof(u32), GFP_KERNEL);
216       if (!flush_words) {
217               amd_northbridges.flags &= ~AMD_NB_GART;
218               return -ENOMEM;
219       }
220
221       for (i = 0; i != amd_nb_num(); i++)
222               pci_read_config_dword(node_to_amd_nb(i)->misc, 0x9c,
223                                     &flush_words[i]);
224
225       return 0;
 
226}
227
228void amd_flush_garts(void)
229{
230	int flushed, i;
231	unsigned long flags;
232	static DEFINE_SPINLOCK(gart_lock);
233
234	if (!amd_nb_has_feature(AMD_NB_GART))
235		return;
236
237	/* Avoid races between AGP and IOMMU. In theory it's not needed
238	   but I'm not sure if the hardware won't lose flush requests
239	   when another is pending. This whole thing is so expensive anyways
240	   that it doesn't matter to serialize more. -AK */
 
 
241	spin_lock_irqsave(&gart_lock, flags);
242	flushed = 0;
243	for (i = 0; i < amd_nb_num(); i++) {
244		pci_write_config_dword(node_to_amd_nb(i)->misc, 0x9c,
245				       flush_words[i] | 1);
246		flushed++;
247	}
248	for (i = 0; i < amd_nb_num(); i++) {
249		u32 w;
250		/* Make sure the hardware actually executed the flush*/
251		for (;;) {
252			pci_read_config_dword(node_to_amd_nb(i)->misc,
253					      0x9c, &w);
254			if (!(w & 1))
255				break;
256			cpu_relax();
257		}
258	}
259	spin_unlock_irqrestore(&gart_lock, flags);
260	if (!flushed)
261		printk("nothing to flush?\n");
262}
263EXPORT_SYMBOL_GPL(amd_flush_garts);
264
265static __init int init_amd_nbs(void)
266{
267	int err = 0;
268
269	err = amd_cache_northbridges();
 
 
270
271	if (err < 0)
272		printk(KERN_NOTICE "AMD NB: Cannot enumerate AMD northbridges.\n");
 
 
 
273
274	if (amd_cache_gart() < 0)
275		printk(KERN_NOTICE "AMD NB: Cannot initialize GART flush words, "
276		       "GART support disabled.\n");
277
278	return err;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
279}
280
281/* This has to go after the PCI subsystem */
282fs_initcall(init_amd_nbs);
v6.8
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Shared support code for AMD K8 northbridges and derivatives.
  4 * Copyright 2006 Andi Kleen, SUSE Labs.
  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_17H_MA0H_ROOT		0x14b5
 23#define PCI_DEVICE_ID_AMD_19H_M10H_ROOT		0x14a4
 24#define PCI_DEVICE_ID_AMD_19H_M40H_ROOT		0x14b5
 25#define PCI_DEVICE_ID_AMD_19H_M60H_ROOT		0x14d8
 26#define PCI_DEVICE_ID_AMD_19H_M70H_ROOT		0x14e8
 27#define PCI_DEVICE_ID_AMD_1AH_M00H_ROOT		0x153a
 28#define PCI_DEVICE_ID_AMD_1AH_M20H_ROOT		0x1507
 29#define PCI_DEVICE_ID_AMD_MI200_ROOT		0x14bb
 30#define PCI_DEVICE_ID_AMD_MI300_ROOT		0x14f8
 31
 32#define PCI_DEVICE_ID_AMD_17H_DF_F4		0x1464
 33#define PCI_DEVICE_ID_AMD_17H_M10H_DF_F4	0x15ec
 34#define PCI_DEVICE_ID_AMD_17H_M30H_DF_F4	0x1494
 35#define PCI_DEVICE_ID_AMD_17H_M60H_DF_F4	0x144c
 36#define PCI_DEVICE_ID_AMD_17H_M70H_DF_F4	0x1444
 37#define PCI_DEVICE_ID_AMD_17H_MA0H_DF_F4	0x1728
 38#define PCI_DEVICE_ID_AMD_19H_DF_F4		0x1654
 39#define PCI_DEVICE_ID_AMD_19H_M10H_DF_F4	0x14b1
 40#define PCI_DEVICE_ID_AMD_19H_M40H_DF_F4	0x167d
 41#define PCI_DEVICE_ID_AMD_19H_M50H_DF_F4	0x166e
 42#define PCI_DEVICE_ID_AMD_19H_M60H_DF_F4	0x14e4
 43#define PCI_DEVICE_ID_AMD_19H_M70H_DF_F4	0x14f4
 44#define PCI_DEVICE_ID_AMD_19H_M78H_DF_F4	0x12fc
 45#define PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4	0x12c4
 46#define PCI_DEVICE_ID_AMD_MI200_DF_F4		0x14d4
 47#define PCI_DEVICE_ID_AMD_MI300_DF_F4		0x152c
 48
 49/* Protect the PCI config register pairs used for SMN. */
 50static DEFINE_MUTEX(smn_mutex);
 51
 52static u32 *flush_words;
 53
 54static const struct pci_device_id amd_root_ids[] = {
 55	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_ROOT) },
 56	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_ROOT) },
 57	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M30H_ROOT) },
 58	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M60H_ROOT) },
 59	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_MA0H_ROOT) },
 60	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M10H_ROOT) },
 61	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M40H_ROOT) },
 62	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M60H_ROOT) },
 63	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M70H_ROOT) },
 64	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_ROOT) },
 65	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_ROOT) },
 66	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_ROOT) },
 67	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI300_ROOT) },
 68	{}
 69};
 70
 71#define PCI_DEVICE_ID_AMD_CNB17H_F4     0x1704
 72
 73static const struct pci_device_id amd_nb_misc_ids[] = {
 74	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
 75	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) },
 76	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) },
 77	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M10H_F3) },
 78	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F3) },
 79	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M60H_NB_F3) },
 80	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
 81	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
 82	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
 83	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) },
 84	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F3) },
 85	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M60H_DF_F3) },
 86	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_MA0H_DF_F3) },
 87	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) },
 88	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F3) },
 89	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_DF_F3) },
 90	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M10H_DF_F3) },
 91	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M40H_DF_F3) },
 92	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M50H_DF_F3) },
 93	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M60H_DF_F3) },
 94	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M70H_DF_F3) },
 95	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F3) },
 96	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F3) },
 97	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_DF_F3) },
 98	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_DF_F3) },
 99	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI300_DF_F3) },
100	{}
101};
 
102
103static const struct pci_device_id amd_nb_link_ids[] = {
104	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) },
105	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F4) },
106	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M60H_NB_F4) },
107	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) },
108	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F4) },
109	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F4) },
110	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F4) },
111	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F4) },
112	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M60H_DF_F4) },
113	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F4) },
114	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_MA0H_DF_F4) },
115	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_DF_F4) },
116	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M10H_DF_F4) },
117	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M40H_DF_F4) },
118	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M50H_DF_F4) },
119	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M60H_DF_F4) },
120	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M70H_DF_F4) },
121	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F4) },
122	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) },
123	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4) },
124	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_DF_F4) },
125	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI300_DF_F4) },
126	{}
127};
128
129static const struct pci_device_id hygon_root_ids[] = {
130	{ PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_ROOT) },
131	{}
132};
133
134static const struct pci_device_id hygon_nb_misc_ids[] = {
135	{ PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) },
136	{}
137};
138
139static const struct pci_device_id hygon_nb_link_ids[] = {
140	{ PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_DF_F4) },
141	{}
142};
143
144const struct amd_nb_bus_dev_range amd_nb_bus_dev_ranges[] __initconst = {
145	{ 0x00, 0x18, 0x20 },
146	{ 0xff, 0x00, 0x20 },
147	{ 0xfe, 0x00, 0x20 },
148	{ }
149};
150
151static struct amd_northbridge_info amd_northbridges;
152
153u16 amd_nb_num(void)
154{
155	return amd_northbridges.num;
156}
157EXPORT_SYMBOL_GPL(amd_nb_num);
158
159bool amd_nb_has_feature(unsigned int feature)
160{
161	return ((amd_northbridges.flags & feature) == feature);
162}
163EXPORT_SYMBOL_GPL(amd_nb_has_feature);
164
165struct amd_northbridge *node_to_amd_nb(int node)
166{
167	return (node < amd_northbridges.num) ? &amd_northbridges.nb[node] : NULL;
168}
169EXPORT_SYMBOL_GPL(node_to_amd_nb);
170
171static struct pci_dev *next_northbridge(struct pci_dev *dev,
172					const struct pci_device_id *ids)
173{
174	do {
175		dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
176		if (!dev)
177			break;
178	} while (!pci_match_id(ids, dev));
179	return dev;
180}
181
182static int __amd_smn_rw(u16 node, u32 address, u32 *value, bool write)
183{
184	struct pci_dev *root;
185	int err = -ENODEV;
186
187	if (node >= amd_northbridges.num)
188		goto out;
189
190	root = node_to_amd_nb(node)->root;
191	if (!root)
192		goto out;
193
194	mutex_lock(&smn_mutex);
195
196	err = pci_write_config_dword(root, 0x60, address);
197	if (err) {
198		pr_warn("Error programming SMN address 0x%x.\n", address);
199		goto out_unlock;
200	}
201
202	err = (write ? pci_write_config_dword(root, 0x64, *value)
203		     : pci_read_config_dword(root, 0x64, value));
204	if (err)
205		pr_warn("Error %s SMN address 0x%x.\n",
206			(write ? "writing to" : "reading from"), address);
207
208out_unlock:
209	mutex_unlock(&smn_mutex);
210
211out:
212	return err;
213}
214
215int amd_smn_read(u16 node, u32 address, u32 *value)
216{
217	return __amd_smn_rw(node, address, value, false);
218}
219EXPORT_SYMBOL_GPL(amd_smn_read);
220
221int amd_smn_write(u16 node, u32 address, u32 value)
222{
223	return __amd_smn_rw(node, address, &value, true);
224}
225EXPORT_SYMBOL_GPL(amd_smn_write);
226
227
228static int amd_cache_northbridges(void)
229{
230	const struct pci_device_id *misc_ids = amd_nb_misc_ids;
231	const struct pci_device_id *link_ids = amd_nb_link_ids;
232	const struct pci_device_id *root_ids = amd_root_ids;
233	struct pci_dev *root, *misc, *link;
234	struct amd_northbridge *nb;
235	u16 roots_per_misc = 0;
236	u16 misc_count = 0;
237	u16 root_count = 0;
238	u16 i, j;
239
240	if (amd_northbridges.num)
241		return 0;
242
243	if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
244		root_ids = hygon_root_ids;
245		misc_ids = hygon_nb_misc_ids;
246		link_ids = hygon_nb_link_ids;
247	}
248
249	misc = NULL;
250	while ((misc = next_northbridge(misc, misc_ids)))
251		misc_count++;
252
253	if (!misc_count)
254		return -ENODEV;
255
256	root = NULL;
257	while ((root = next_northbridge(root, root_ids)))
258		root_count++;
259
260	if (root_count) {
261		roots_per_misc = root_count / misc_count;
262
263		/*
264		 * There should be _exactly_ N roots for each DF/SMN
265		 * interface.
266		 */
267		if (!roots_per_misc || (root_count % roots_per_misc)) {
268			pr_info("Unsupported AMD DF/PCI configuration found\n");
269			return -ENODEV;
270		}
271	}
272
273	nb = kcalloc(misc_count, sizeof(struct amd_northbridge), GFP_KERNEL);
274	if (!nb)
275		return -ENOMEM;
276
277	amd_northbridges.nb = nb;
278	amd_northbridges.num = misc_count;
279
280	link = misc = root = NULL;
281	for (i = 0; i < amd_northbridges.num; i++) {
282		node_to_amd_nb(i)->root = root =
283			next_northbridge(root, root_ids);
284		node_to_amd_nb(i)->misc = misc =
285			next_northbridge(misc, misc_ids);
286		node_to_amd_nb(i)->link = link =
287			next_northbridge(link, link_ids);
 
288
289		/*
290		 * If there are more PCI root devices than data fabric/
291		 * system management network interfaces, then the (N)
292		 * PCI roots per DF/SMN interface are functionally the
293		 * same (for DF/SMN access) and N-1 are redundant.  N-1
294		 * PCI roots should be skipped per DF/SMN interface so
295		 * the following DF/SMN interfaces get mapped to
296		 * correct PCI roots.
297		 */
298		for (j = 1; j < roots_per_misc; j++)
299			root = next_northbridge(root, root_ids);
300	}
301
302	if (amd_gart_present())
303		amd_northbridges.flags |= AMD_NB_GART;
304
305	/*
306	 * Check for L3 cache presence.
307	 */
308	if (!cpuid_edx(0x80000006))
309		return 0;
310
311	/*
312	 * Some CPU families support L3 Cache Index Disable. There are some
313	 * limitations because of E382 and E388 on family 0x10.
314	 */
315	if (boot_cpu_data.x86 == 0x10 &&
316	    boot_cpu_data.x86_model >= 0x8 &&
317	    (boot_cpu_data.x86_model > 0x9 ||
318	     boot_cpu_data.x86_stepping >= 0x1))
319		amd_northbridges.flags |= AMD_NB_L3_INDEX_DISABLE;
320
321	if (boot_cpu_data.x86 == 0x15)
322		amd_northbridges.flags |= AMD_NB_L3_INDEX_DISABLE;
323
324	/* L3 cache partitioning is supported on family 0x15 */
325	if (boot_cpu_data.x86 == 0x15)
326		amd_northbridges.flags |= AMD_NB_L3_PARTITIONING;
327
328	return 0;
329}
 
330
331/*
332 * Ignores subdevice/subvendor but as far as I can figure out
333 * they're useless anyways
334 */
335bool __init early_is_amd_nb(u32 device)
336{
337	const struct pci_device_id *misc_ids = amd_nb_misc_ids;
338	const struct pci_device_id *id;
339	u32 vendor = device & 0xffff;
340
341	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
342	    boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
343		return false;
344
345	if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
346		misc_ids = hygon_nb_misc_ids;
347
348	device >>= 16;
349	for (id = misc_ids; id->vendor; id++)
350		if (vendor == id->vendor && device == id->device)
351			return true;
352	return false;
353}
354
355struct resource *amd_get_mmconfig_range(struct resource *res)
356{
357	u32 address;
358	u64 base, msr;
359	unsigned int segn_busn_bits;
360
361	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
362	    boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
363		return NULL;
364
365	/* assume all cpus from fam10h have mmconfig */
366	if (boot_cpu_data.x86 < 0x10)
367		return NULL;
368
369	address = MSR_FAM10H_MMIO_CONF_BASE;
370	rdmsrl(address, msr);
371
372	/* mmconfig is not enabled */
373	if (!(msr & FAM10H_MMIO_CONF_ENABLE))
374		return NULL;
375
376	base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
377
378	segn_busn_bits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
379			 FAM10H_MMIO_CONF_BUSRANGE_MASK;
380
381	res->flags = IORESOURCE_MEM;
382	res->start = base;
383	res->end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
384	return res;
385}
386
387int amd_get_subcaches(int cpu)
388{
389	struct pci_dev *link = node_to_amd_nb(topology_die_id(cpu))->link;
390	unsigned int mask;
 
391
392	if (!amd_nb_has_feature(AMD_NB_L3_PARTITIONING))
393		return 0;
394
395	pci_read_config_dword(link, 0x1d4, &mask);
396
397	return (mask >> (4 * cpu_data(cpu).topo.core_id)) & 0xf;
 
398}
399
400int amd_set_subcaches(int cpu, unsigned long mask)
401{
402	static unsigned int reset, ban;
403	struct amd_northbridge *nb = node_to_amd_nb(topology_die_id(cpu));
404	unsigned int reg;
405	int cuid;
406
407	if (!amd_nb_has_feature(AMD_NB_L3_PARTITIONING) || mask > 0xf)
408		return -EINVAL;
409
410	/* if necessary, collect reset state of L3 partitioning and BAN mode */
411	if (reset == 0) {
412		pci_read_config_dword(nb->link, 0x1d4, &reset);
413		pci_read_config_dword(nb->misc, 0x1b8, &ban);
414		ban &= 0x180000;
415	}
416
417	/* deactivate BAN mode if any subcaches are to be disabled */
418	if (mask != 0xf) {
419		pci_read_config_dword(nb->misc, 0x1b8, &reg);
420		pci_write_config_dword(nb->misc, 0x1b8, reg & ~0x180000);
421	}
422
423	cuid = cpu_data(cpu).topo.core_id;
424	mask <<= 4 * cuid;
425	mask |= (0xf ^ (1 << cuid)) << 26;
426
427	pci_write_config_dword(nb->link, 0x1d4, mask);
428
429	/* reset BAN mode if L3 partitioning returned to reset state */
430	pci_read_config_dword(nb->link, 0x1d4, &reg);
431	if (reg == reset) {
432		pci_read_config_dword(nb->misc, 0x1b8, &reg);
433		reg &= ~0x180000;
434		pci_write_config_dword(nb->misc, 0x1b8, reg | ban);
435	}
436
437	return 0;
438}
439
440static void amd_cache_gart(void)
441{
442	u16 i;
443
444	if (!amd_nb_has_feature(AMD_NB_GART))
445		return;
446
447	flush_words = kmalloc_array(amd_northbridges.num, sizeof(u32), GFP_KERNEL);
448	if (!flush_words) {
449		amd_northbridges.flags &= ~AMD_NB_GART;
450		pr_notice("Cannot initialize GART flush words, GART support disabled\n");
451		return;
452	}
 
 
 
453
454	for (i = 0; i != amd_northbridges.num; i++)
455		pci_read_config_dword(node_to_amd_nb(i)->misc, 0x9c, &flush_words[i]);
456}
457
458void amd_flush_garts(void)
459{
460	int flushed, i;
461	unsigned long flags;
462	static DEFINE_SPINLOCK(gart_lock);
463
464	if (!amd_nb_has_feature(AMD_NB_GART))
465		return;
466
467	/*
468	 * Avoid races between AGP and IOMMU. In theory it's not needed
469	 * but I'm not sure if the hardware won't lose flush requests
470	 * when another is pending. This whole thing is so expensive anyways
471	 * that it doesn't matter to serialize more. -AK
472	 */
473	spin_lock_irqsave(&gart_lock, flags);
474	flushed = 0;
475	for (i = 0; i < amd_northbridges.num; i++) {
476		pci_write_config_dword(node_to_amd_nb(i)->misc, 0x9c,
477				       flush_words[i] | 1);
478		flushed++;
479	}
480	for (i = 0; i < amd_northbridges.num; i++) {
481		u32 w;
482		/* Make sure the hardware actually executed the flush*/
483		for (;;) {
484			pci_read_config_dword(node_to_amd_nb(i)->misc,
485					      0x9c, &w);
486			if (!(w & 1))
487				break;
488			cpu_relax();
489		}
490	}
491	spin_unlock_irqrestore(&gart_lock, flags);
492	if (!flushed)
493		pr_notice("nothing to flush?\n");
494}
495EXPORT_SYMBOL_GPL(amd_flush_garts);
496
497static void __fix_erratum_688(void *info)
498{
499#define MSR_AMD64_IC_CFG 0xC0011021
500
501	msr_set_bit(MSR_AMD64_IC_CFG, 3);
502	msr_set_bit(MSR_AMD64_IC_CFG, 14);
503}
504
505/* Apply erratum 688 fix so machines without a BIOS fix work. */
506static __init void fix_erratum_688(void)
507{
508	struct pci_dev *F4;
509	u32 val;
510
511	if (boot_cpu_data.x86 != 0x14)
512		return;
 
513
514	if (!amd_northbridges.num)
515		return;
516
517	F4 = node_to_amd_nb(0)->link;
518	if (!F4)
519		return;
520
521	if (pci_read_config_dword(F4, 0x164, &val))
522		return;
523
524	if (val & BIT(2))
525		return;
526
527	on_each_cpu(__fix_erratum_688, NULL, 0);
528
529	pr_info("x86/cpu/AMD: CPU erratum 688 worked around\n");
530}
531
532static __init int init_amd_nbs(void)
533{
534	amd_cache_northbridges();
535	amd_cache_gart();
536
537	fix_erratum_688();
538
539	return 0;
540}
541
542/* This has to go after the PCI subsystem */
543fs_initcall(init_amd_nbs);