1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _ASM_X86_AMD_NB_H |
3 | #define _ASM_X86_AMD_NB_H |
4 | |
5 | #include <linux/ioport.h> |
6 | #include <linux/pci.h> |
7 | #include <linux/refcount.h> |
8 | |
9 | struct amd_nb_bus_dev_range { |
10 | u8 bus; |
11 | u8 dev_base; |
12 | u8 dev_limit; |
13 | }; |
14 | |
15 | extern const struct amd_nb_bus_dev_range amd_nb_bus_dev_ranges[]; |
16 | |
17 | extern bool early_is_amd_nb(u32 value); |
18 | extern struct resource *amd_get_mmconfig_range(struct resource *res); |
19 | extern void amd_flush_garts(void); |
20 | extern int amd_numa_init(void); |
21 | extern int amd_get_subcaches(int); |
22 | extern int amd_set_subcaches(int, unsigned long); |
23 | |
24 | extern int amd_smn_read(u16 node, u32 address, u32 *value); |
25 | extern int amd_smn_write(u16 node, u32 address, u32 value); |
26 | |
27 | struct amd_l3_cache { |
28 | unsigned indices; |
29 | u8 subcaches[4]; |
30 | }; |
31 | |
32 | struct threshold_block { |
33 | unsigned int block; /* Number within bank */ |
34 | unsigned int bank; /* MCA bank the block belongs to */ |
35 | unsigned int cpu; /* CPU which controls MCA bank */ |
36 | u32 address; /* MSR address for the block */ |
37 | u16 interrupt_enable; /* Enable/Disable APIC interrupt */ |
38 | bool interrupt_capable; /* Bank can generate an interrupt. */ |
39 | |
40 | u16 threshold_limit; /* |
41 | * Value upon which threshold |
42 | * interrupt is generated. |
43 | */ |
44 | |
45 | struct kobject kobj; /* sysfs object */ |
46 | struct list_head miscj; /* |
47 | * List of threshold blocks |
48 | * within a bank. |
49 | */ |
50 | }; |
51 | |
52 | struct threshold_bank { |
53 | struct kobject *kobj; |
54 | struct threshold_block *blocks; |
55 | |
56 | /* initialized to the number of CPUs on the node sharing this bank */ |
57 | refcount_t cpus; |
58 | unsigned int shared; |
59 | }; |
60 | |
61 | struct amd_northbridge { |
62 | struct pci_dev *root; |
63 | struct pci_dev *misc; |
64 | struct pci_dev *link; |
65 | struct amd_l3_cache l3_cache; |
66 | struct threshold_bank *bank4; |
67 | }; |
68 | |
69 | struct amd_northbridge_info { |
70 | u16 num; |
71 | u64 flags; |
72 | struct amd_northbridge *nb; |
73 | }; |
74 | |
75 | #define AMD_NB_GART BIT(0) |
76 | #define AMD_NB_L3_INDEX_DISABLE BIT(1) |
77 | #define AMD_NB_L3_PARTITIONING BIT(2) |
78 | |
79 | #ifdef CONFIG_AMD_NB |
80 | |
81 | u16 amd_nb_num(void); |
82 | bool amd_nb_has_feature(unsigned int feature); |
83 | struct amd_northbridge *node_to_amd_nb(int node); |
84 | |
85 | static inline u16 amd_pci_dev_to_node_id(struct pci_dev *pdev) |
86 | { |
87 | struct pci_dev *misc; |
88 | int i; |
89 | |
90 | for (i = 0; i != amd_nb_num(); i++) { |
91 | misc = node_to_amd_nb(node: i)->misc; |
92 | |
93 | if (pci_domain_nr(bus: misc->bus) == pci_domain_nr(bus: pdev->bus) && |
94 | PCI_SLOT(misc->devfn) == PCI_SLOT(pdev->devfn)) |
95 | return i; |
96 | } |
97 | |
98 | WARN(1, "Unable to find AMD Northbridge id for %s\n" , pci_name(pdev)); |
99 | return 0; |
100 | } |
101 | |
102 | static inline bool amd_gart_present(void) |
103 | { |
104 | if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) |
105 | return false; |
106 | |
107 | /* GART present only on Fam15h, upto model 0fh */ |
108 | if (boot_cpu_data.x86 == 0xf || boot_cpu_data.x86 == 0x10 || |
109 | (boot_cpu_data.x86 == 0x15 && boot_cpu_data.x86_model < 0x10)) |
110 | return true; |
111 | |
112 | return false; |
113 | } |
114 | |
115 | #else |
116 | |
117 | #define amd_nb_num(x) 0 |
118 | #define amd_nb_has_feature(x) false |
119 | #define node_to_amd_nb(x) NULL |
120 | #define amd_gart_present(x) false |
121 | |
122 | #endif |
123 | |
124 | |
125 | #endif /* _ASM_X86_AMD_NB_H */ |
126 | |