Linux Audio

Check our new training course

Yocto / OpenEmbedded training

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