1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for Intel(R) 10nm server memory controller.
4 * Copyright (c) 2019, Intel Corporation.
8 #include <linux/kernel.h>
10 #include <asm/cpu_device_id.h>
11 #include <asm/intel-family.h>
13 #include "edac_module.h"
14 #include "skx_common.h"
16 #define I10NM_REVISION "v0.0.4"
17 #define EDAC_MOD_STR "i10nm_edac"
20 #define i10nm_printk(level, fmt, arg...) \
21 edac_printk(level, "i10nm", fmt, ##arg)
23 #define I10NM_GET_SCK_BAR(d, reg) \
24 pci_read_config_dword((d)->uracu, 0xd0, &(reg))
25 #define I10NM_GET_IMC_BAR(d, i, reg) \
26 pci_read_config_dword((d)->uracu, 0xd8 + (i) * 4, &(reg))
27 #define I10NM_GET_DIMMMTR(m, i, j) \
28 readl((m)->mbase + 0x2080c + (i) * (m)->chan_mmio_sz + (j) * 4)
29 #define I10NM_GET_MCDDRTCFG(m, i, j) \
30 readl((m)->mbase + 0x20970 + (i) * (m)->chan_mmio_sz + (j) * 4)
31 #define I10NM_GET_MCMTR(m, i) \
32 readl((m)->mbase + 0x20ef8 + (i) * (m)->chan_mmio_sz)
33 #define I10NM_GET_AMAP(m, i) \
34 readl((m)->mbase + 0x20814 + (i) * (m)->chan_mmio_sz)
36 #define I10NM_GET_SCK_MMIO_BASE(reg) (GET_BITFIELD(reg, 0, 28) << 23)
37 #define I10NM_GET_IMC_MMIO_OFFSET(reg) (GET_BITFIELD(reg, 0, 10) << 12)
38 #define I10NM_GET_IMC_MMIO_SIZE(reg) ((GET_BITFIELD(reg, 13, 23) - \
39 GET_BITFIELD(reg, 0, 10) + 1) << 12)
41 static struct list_head
*i10nm_edac_list
;
43 static struct pci_dev
*pci_get_dev_wrapper(int dom
, unsigned int bus
,
44 unsigned int dev
, unsigned int fun
)
48 pdev
= pci_get_domain_bus_and_slot(dom
, bus
, PCI_DEVFN(dev
, fun
));
50 edac_dbg(2, "No device %02x:%02x.%x\n",
55 if (unlikely(pci_enable_device(pdev
) < 0)) {
56 edac_dbg(2, "Failed to enable device %02x:%02x.%x\n",
66 static int i10nm_get_all_munits(void)
76 list_for_each_entry(d
, i10nm_edac_list
, list
) {
77 d
->util_all
= pci_get_dev_wrapper(d
->seg
, d
->bus
[1], 29, 1);
81 d
->uracu
= pci_get_dev_wrapper(d
->seg
, d
->bus
[0], 0, 1);
85 if (I10NM_GET_SCK_BAR(d
, reg
)) {
86 i10nm_printk(KERN_ERR
, "Failed to socket bar\n");
90 base
= I10NM_GET_SCK_MMIO_BASE(reg
);
91 edac_dbg(2, "socket%d mmio base 0x%llx (reg 0x%x)\n",
94 for (i
= 0; i
< I10NM_NUM_IMC
; i
++) {
95 mdev
= pci_get_dev_wrapper(d
->seg
, d
->bus
[0],
97 if (i
== 0 && !mdev
) {
98 i10nm_printk(KERN_ERR
, "No IMC found\n");
104 d
->imc
[i
].mdev
= mdev
;
106 if (I10NM_GET_IMC_BAR(d
, i
, reg
)) {
107 i10nm_printk(KERN_ERR
, "Failed to get mc bar\n");
111 off
= I10NM_GET_IMC_MMIO_OFFSET(reg
);
112 size
= I10NM_GET_IMC_MMIO_SIZE(reg
);
113 edac_dbg(2, "mc%d mmio base 0x%llx size 0x%lx (reg 0x%x)\n",
114 i
, base
+ off
, size
, reg
);
116 mbase
= ioremap(base
+ off
, size
);
118 i10nm_printk(KERN_ERR
, "Failed to ioremap 0x%llx\n",
123 d
->imc
[i
].mbase
= mbase
;
130 static struct res_config i10nm_cfg0
= {
133 .busno_cfg_offset
= 0xcc,
134 .ddr_chan_mmio_sz
= 0x4000,
137 static struct res_config i10nm_cfg1
= {
140 .busno_cfg_offset
= 0xd0,
141 .ddr_chan_mmio_sz
= 0x4000,
144 static struct res_config spr_cfg
= {
147 .busno_cfg_offset
= 0xd0,
148 .ddr_chan_mmio_sz
= 0x8000,
149 .support_ddr5
= true,
152 static const struct x86_cpu_id i10nm_cpuids
[] = {
153 X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ATOM_TREMONT_D
, X86_STEPPINGS(0x0, 0x3), &i10nm_cfg0
),
154 X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ATOM_TREMONT_D
, X86_STEPPINGS(0x4, 0xf), &i10nm_cfg1
),
155 X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ICELAKE_X
, X86_STEPPINGS(0x0, 0x3), &i10nm_cfg0
),
156 X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ICELAKE_X
, X86_STEPPINGS(0x4, 0xf), &i10nm_cfg1
),
157 X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ICELAKE_D
, X86_STEPPINGS(0x0, 0xf), &i10nm_cfg1
),
158 X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(SAPPHIRERAPIDS_X
, X86_STEPPINGS(0x0, 0xf), &spr_cfg
),
161 MODULE_DEVICE_TABLE(x86cpu
, i10nm_cpuids
);
163 static bool i10nm_check_ecc(struct skx_imc
*imc
, int chan
)
167 mcmtr
= I10NM_GET_MCMTR(imc
, chan
);
168 edac_dbg(1, "ch%d mcmtr reg %x\n", chan
, mcmtr
);
170 return !!GET_BITFIELD(mcmtr
, 2, 2);
173 static int i10nm_get_dimm_config(struct mem_ctl_info
*mci
,
174 struct res_config
*cfg
)
176 struct skx_pvt
*pvt
= mci
->pvt_info
;
177 struct skx_imc
*imc
= pvt
->imc
;
178 u32 mtr
, amap
, mcddrtcfg
;
179 struct dimm_info
*dimm
;
182 for (i
= 0; i
< I10NM_NUM_CHANNELS
; i
++) {
187 amap
= I10NM_GET_AMAP(imc
, i
);
188 for (j
= 0; j
< I10NM_NUM_DIMMS
; j
++) {
189 dimm
= edac_get_dimm(mci
, i
, j
, 0);
190 mtr
= I10NM_GET_DIMMMTR(imc
, i
, j
);
191 mcddrtcfg
= I10NM_GET_MCDDRTCFG(imc
, i
, j
);
192 edac_dbg(1, "dimmmtr 0x%x mcddrtcfg 0x%x (mc%d ch%d dimm%d)\n",
193 mtr
, mcddrtcfg
, imc
->mc
, i
, j
);
195 if (IS_DIMM_PRESENT(mtr
))
196 ndimms
+= skx_get_dimm_info(mtr
, 0, amap
, dimm
,
198 else if (IS_NVDIMM_PRESENT(mcddrtcfg
, j
))
199 ndimms
+= skx_get_nvdimm_info(dimm
, imc
, i
, j
,
202 if (ndimms
&& !i10nm_check_ecc(imc
, i
)) {
203 i10nm_printk(KERN_ERR
, "ECC is disabled on imc %d channel %d\n",
212 static struct notifier_block i10nm_mce_dec
= {
213 .notifier_call
= skx_mce_check_error
,
214 .priority
= MCE_PRIO_EDAC
,
217 #ifdef CONFIG_EDAC_DEBUG
220 * Exercise the address decode logic by writing an address to
221 * /sys/kernel/debug/edac/i10nm_test/addr.
223 static struct dentry
*i10nm_test
;
225 static int debugfs_u64_set(void *data
, u64 val
)
229 pr_warn_once("Fake error to 0x%llx injected via debugfs\n", val
);
231 memset(&m
, 0, sizeof(m
));
232 /* ADDRV + MemRd + Unknown channel */
233 m
.status
= MCI_STATUS_ADDRV
+ 0x90;
234 /* One corrected error */
235 m
.status
|= BIT_ULL(MCI_STATUS_CEC_SHIFT
);
237 skx_mce_check_error(NULL
, 0, &m
);
241 DEFINE_SIMPLE_ATTRIBUTE(fops_u64_wo
, NULL
, debugfs_u64_set
, "%llu\n");
243 static void setup_i10nm_debug(void)
245 i10nm_test
= edac_debugfs_create_dir("i10nm_test");
249 if (!edac_debugfs_create_file("addr", 0200, i10nm_test
,
250 NULL
, &fops_u64_wo
)) {
251 debugfs_remove(i10nm_test
);
256 static void teardown_i10nm_debug(void)
258 debugfs_remove_recursive(i10nm_test
);
261 static inline void setup_i10nm_debug(void) {}
262 static inline void teardown_i10nm_debug(void) {}
263 #endif /*CONFIG_EDAC_DEBUG*/
265 static int __init
i10nm_init(void)
267 u8 mc
= 0, src_id
= 0, node_id
= 0;
268 const struct x86_cpu_id
*id
;
269 struct res_config
*cfg
;
272 int rc
, i
, off
[3] = {0xd0, 0xc8, 0xcc};
277 owner
= edac_get_owner();
278 if (owner
&& strncmp(owner
, EDAC_MOD_STR
, sizeof(EDAC_MOD_STR
)))
281 id
= x86_match_cpu(i10nm_cpuids
);
285 cfg
= (struct res_config
*)id
->driver_data
;
287 rc
= skx_get_hi_lo(0x09a2, off
, &tolm
, &tohm
);
291 rc
= skx_get_all_bus_mappings(cfg
, &i10nm_edac_list
);
295 i10nm_printk(KERN_ERR
, "No memory controllers found\n");
299 rc
= i10nm_get_all_munits();
303 list_for_each_entry(d
, i10nm_edac_list
, list
) {
304 rc
= skx_get_src_id(d
, 0xf8, &src_id
);
308 rc
= skx_get_node_id(d
, &node_id
);
312 edac_dbg(2, "src_id = %d node_id = %d\n", src_id
, node_id
);
313 for (i
= 0; i
< I10NM_NUM_IMC
; i
++) {
319 d
->imc
[i
].src_id
= src_id
;
320 d
->imc
[i
].node_id
= node_id
;
321 d
->imc
[i
].chan_mmio_sz
= cfg
->ddr_chan_mmio_sz
;
323 rc
= skx_register_mci(&d
->imc
[i
], d
->imc
[i
].mdev
,
324 "Intel_10nm Socket", EDAC_MOD_STR
,
325 i10nm_get_dimm_config
, cfg
);
336 mce_register_decode_chain(&i10nm_mce_dec
);
339 i10nm_printk(KERN_INFO
, "%s\n", I10NM_REVISION
);
347 static void __exit
i10nm_exit(void)
350 teardown_i10nm_debug();
351 mce_unregister_decode_chain(&i10nm_mce_dec
);
356 module_init(i10nm_init
);
357 module_exit(i10nm_exit
);
359 MODULE_LICENSE("GPL v2");
360 MODULE_DESCRIPTION("MC Driver for Intel 10nm server processors");