1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Driver for Intel(R) 10nm server memory controller. 4 * Copyright (c) 2019, Intel Corporation. 5 * 6 */ 7 8 #include <linux/kernel.h> 9 #include <asm/cpu_device_id.h> 10 #include <asm/intel-family.h> 11 #include <asm/mce.h> 12 #include "edac_module.h" 13 #include "skx_common.h" 14 15 #define I10NM_REVISION "v0.0.3" 16 #define EDAC_MOD_STR "i10nm_edac" 17 18 /* Debug macros */ 19 #define i10nm_printk(level, fmt, arg...) \ 20 edac_printk(level, "i10nm", fmt, ##arg) 21 22 #define I10NM_GET_SCK_BAR(d, reg) \ 23 pci_read_config_dword((d)->uracu, 0xd0, &(reg)) 24 #define I10NM_GET_IMC_BAR(d, i, reg) \ 25 pci_read_config_dword((d)->uracu, 0xd8 + (i) * 4, &(reg)) 26 #define I10NM_GET_DIMMMTR(m, i, j) \ 27 (*(u32 *)((m)->mbase + 0x2080c + (i) * 0x4000 + (j) * 4)) 28 #define I10NM_GET_MCDDRTCFG(m, i, j) \ 29 (*(u32 *)((m)->mbase + 0x20970 + (i) * 0x4000 + (j) * 4)) 30 31 #define I10NM_GET_SCK_MMIO_BASE(reg) (GET_BITFIELD(reg, 0, 28) << 23) 32 #define I10NM_GET_IMC_MMIO_OFFSET(reg) (GET_BITFIELD(reg, 0, 10) << 12) 33 #define I10NM_GET_IMC_MMIO_SIZE(reg) ((GET_BITFIELD(reg, 13, 23) - \ 34 GET_BITFIELD(reg, 0, 10) + 1) << 12) 35 36 static struct list_head *i10nm_edac_list; 37 38 static struct pci_dev *pci_get_dev_wrapper(int dom, unsigned int bus, 39 unsigned int dev, unsigned int fun) 40 { 41 struct pci_dev *pdev; 42 43 pdev = pci_get_domain_bus_and_slot(dom, bus, PCI_DEVFN(dev, fun)); 44 if (!pdev) { 45 edac_dbg(2, "No device %02x:%02x.%x\n", 46 bus, dev, fun); 47 return NULL; 48 } 49 50 if (unlikely(pci_enable_device(pdev) < 0)) { 51 edac_dbg(2, "Failed to enable device %02x:%02x.%x\n", 52 bus, dev, fun); 53 return NULL; 54 } 55 56 pci_dev_get(pdev); 57 58 return pdev; 59 } 60 61 static int i10nm_get_all_munits(void) 62 { 63 struct pci_dev *mdev; 64 void __iomem *mbase; 65 unsigned long size; 66 struct skx_dev *d; 67 int i, j = 0; 68 u32 reg, off; 69 u64 base; 70 71 list_for_each_entry(d, i10nm_edac_list, list) { 72 d->util_all = pci_get_dev_wrapper(d->seg, d->bus[1], 29, 1); 73 if (!d->util_all) 74 return -ENODEV; 75 76 d->uracu = pci_get_dev_wrapper(d->seg, d->bus[0], 0, 1); 77 if (!d->uracu) 78 return -ENODEV; 79 80 if (I10NM_GET_SCK_BAR(d, reg)) { 81 i10nm_printk(KERN_ERR, "Failed to socket bar\n"); 82 return -ENODEV; 83 } 84 85 base = I10NM_GET_SCK_MMIO_BASE(reg); 86 edac_dbg(2, "socket%d mmio base 0x%llx (reg 0x%x)\n", 87 j++, base, reg); 88 89 for (i = 0; i < I10NM_NUM_IMC; i++) { 90 mdev = pci_get_dev_wrapper(d->seg, d->bus[0], 91 12 + i, 0); 92 if (i == 0 && !mdev) { 93 i10nm_printk(KERN_ERR, "No IMC found\n"); 94 return -ENODEV; 95 } 96 if (!mdev) 97 continue; 98 99 d->imc[i].mdev = mdev; 100 101 if (I10NM_GET_IMC_BAR(d, i, reg)) { 102 i10nm_printk(KERN_ERR, "Failed to get mc bar\n"); 103 return -ENODEV; 104 } 105 106 off = I10NM_GET_IMC_MMIO_OFFSET(reg); 107 size = I10NM_GET_IMC_MMIO_SIZE(reg); 108 edac_dbg(2, "mc%d mmio base 0x%llx size 0x%lx (reg 0x%x)\n", 109 i, base + off, size, reg); 110 111 mbase = ioremap(base + off, size); 112 if (!mbase) { 113 i10nm_printk(KERN_ERR, "Failed to ioremap 0x%llx\n", 114 base + off); 115 return -ENODEV; 116 } 117 118 d->imc[i].mbase = mbase; 119 } 120 } 121 122 return 0; 123 } 124 125 static struct res_config i10nm_cfg0 = { 126 .type = I10NM, 127 .decs_did = 0x3452, 128 .busno_cfg_offset = 0xcc, 129 }; 130 131 static struct res_config i10nm_cfg1 = { 132 .type = I10NM, 133 .decs_did = 0x3452, 134 .busno_cfg_offset = 0xd0, 135 }; 136 137 static const struct x86_cpu_id i10nm_cpuids[] = { 138 X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ATOM_TREMONT_D, X86_STEPPINGS(0x0, 0x3), &i10nm_cfg0), 139 X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ATOM_TREMONT_D, X86_STEPPINGS(0x4, 0xf), &i10nm_cfg1), 140 X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ICELAKE_X, X86_STEPPINGS(0x0, 0x3), &i10nm_cfg0), 141 X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ICELAKE_X, X86_STEPPINGS(0x4, 0xf), &i10nm_cfg1), 142 X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ICELAKE_D, X86_STEPPINGS(0x0, 0xf), &i10nm_cfg1), 143 {} 144 }; 145 MODULE_DEVICE_TABLE(x86cpu, i10nm_cpuids); 146 147 static bool i10nm_check_ecc(struct skx_imc *imc, int chan) 148 { 149 u32 mcmtr; 150 151 mcmtr = *(u32 *)(imc->mbase + 0x20ef8 + chan * 0x4000); 152 edac_dbg(1, "ch%d mcmtr reg %x\n", chan, mcmtr); 153 154 return !!GET_BITFIELD(mcmtr, 2, 2); 155 } 156 157 static int i10nm_get_dimm_config(struct mem_ctl_info *mci) 158 { 159 struct skx_pvt *pvt = mci->pvt_info; 160 struct skx_imc *imc = pvt->imc; 161 struct dimm_info *dimm; 162 u32 mtr, mcddrtcfg; 163 int i, j, ndimms; 164 165 for (i = 0; i < I10NM_NUM_CHANNELS; i++) { 166 if (!imc->mbase) 167 continue; 168 169 ndimms = 0; 170 for (j = 0; j < I10NM_NUM_DIMMS; j++) { 171 dimm = edac_get_dimm(mci, i, j, 0); 172 mtr = I10NM_GET_DIMMMTR(imc, i, j); 173 mcddrtcfg = I10NM_GET_MCDDRTCFG(imc, i, j); 174 edac_dbg(1, "dimmmtr 0x%x mcddrtcfg 0x%x (mc%d ch%d dimm%d)\n", 175 mtr, mcddrtcfg, imc->mc, i, j); 176 177 if (IS_DIMM_PRESENT(mtr)) 178 ndimms += skx_get_dimm_info(mtr, 0, 0, dimm, 179 imc, i, j); 180 else if (IS_NVDIMM_PRESENT(mcddrtcfg, j)) 181 ndimms += skx_get_nvdimm_info(dimm, imc, i, j, 182 EDAC_MOD_STR); 183 } 184 if (ndimms && !i10nm_check_ecc(imc, i)) { 185 i10nm_printk(KERN_ERR, "ECC is disabled on imc %d channel %d\n", 186 imc->mc, i); 187 return -ENODEV; 188 } 189 } 190 191 return 0; 192 } 193 194 static struct notifier_block i10nm_mce_dec = { 195 .notifier_call = skx_mce_check_error, 196 .priority = MCE_PRIO_EDAC, 197 }; 198 199 #ifdef CONFIG_EDAC_DEBUG 200 /* 201 * Debug feature. 202 * Exercise the address decode logic by writing an address to 203 * /sys/kernel/debug/edac/i10nm_test/addr. 204 */ 205 static struct dentry *i10nm_test; 206 207 static int debugfs_u64_set(void *data, u64 val) 208 { 209 struct mce m; 210 211 pr_warn_once("Fake error to 0x%llx injected via debugfs\n", val); 212 213 memset(&m, 0, sizeof(m)); 214 /* ADDRV + MemRd + Unknown channel */ 215 m.status = MCI_STATUS_ADDRV + 0x90; 216 /* One corrected error */ 217 m.status |= BIT_ULL(MCI_STATUS_CEC_SHIFT); 218 m.addr = val; 219 skx_mce_check_error(NULL, 0, &m); 220 221 return 0; 222 } 223 DEFINE_SIMPLE_ATTRIBUTE(fops_u64_wo, NULL, debugfs_u64_set, "%llu\n"); 224 225 static void setup_i10nm_debug(void) 226 { 227 i10nm_test = edac_debugfs_create_dir("i10nm_test"); 228 if (!i10nm_test) 229 return; 230 231 if (!edac_debugfs_create_file("addr", 0200, i10nm_test, 232 NULL, &fops_u64_wo)) { 233 debugfs_remove(i10nm_test); 234 i10nm_test = NULL; 235 } 236 } 237 238 static void teardown_i10nm_debug(void) 239 { 240 debugfs_remove_recursive(i10nm_test); 241 } 242 #else 243 static inline void setup_i10nm_debug(void) {} 244 static inline void teardown_i10nm_debug(void) {} 245 #endif /*CONFIG_EDAC_DEBUG*/ 246 247 static int __init i10nm_init(void) 248 { 249 u8 mc = 0, src_id = 0, node_id = 0; 250 const struct x86_cpu_id *id; 251 struct res_config *cfg; 252 const char *owner; 253 struct skx_dev *d; 254 int rc, i, off[3] = {0xd0, 0xc8, 0xcc}; 255 u64 tolm, tohm; 256 257 edac_dbg(2, "\n"); 258 259 owner = edac_get_owner(); 260 if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR))) 261 return -EBUSY; 262 263 id = x86_match_cpu(i10nm_cpuids); 264 if (!id) 265 return -ENODEV; 266 267 cfg = (struct res_config *)id->driver_data; 268 269 rc = skx_get_hi_lo(0x09a2, off, &tolm, &tohm); 270 if (rc) 271 return rc; 272 273 rc = skx_get_all_bus_mappings(cfg, &i10nm_edac_list); 274 if (rc < 0) 275 goto fail; 276 if (rc == 0) { 277 i10nm_printk(KERN_ERR, "No memory controllers found\n"); 278 return -ENODEV; 279 } 280 281 rc = i10nm_get_all_munits(); 282 if (rc < 0) 283 goto fail; 284 285 list_for_each_entry(d, i10nm_edac_list, list) { 286 rc = skx_get_src_id(d, 0xf8, &src_id); 287 if (rc < 0) 288 goto fail; 289 290 rc = skx_get_node_id(d, &node_id); 291 if (rc < 0) 292 goto fail; 293 294 edac_dbg(2, "src_id = %d node_id = %d\n", src_id, node_id); 295 for (i = 0; i < I10NM_NUM_IMC; i++) { 296 if (!d->imc[i].mdev) 297 continue; 298 299 d->imc[i].mc = mc++; 300 d->imc[i].lmc = i; 301 d->imc[i].src_id = src_id; 302 d->imc[i].node_id = node_id; 303 304 rc = skx_register_mci(&d->imc[i], d->imc[i].mdev, 305 "Intel_10nm Socket", EDAC_MOD_STR, 306 i10nm_get_dimm_config); 307 if (rc < 0) 308 goto fail; 309 } 310 } 311 312 rc = skx_adxl_get(); 313 if (rc) 314 goto fail; 315 316 opstate_init(); 317 mce_register_decode_chain(&i10nm_mce_dec); 318 setup_i10nm_debug(); 319 320 i10nm_printk(KERN_INFO, "%s\n", I10NM_REVISION); 321 322 return 0; 323 fail: 324 skx_remove(); 325 return rc; 326 } 327 328 static void __exit i10nm_exit(void) 329 { 330 edac_dbg(2, "\n"); 331 teardown_i10nm_debug(); 332 mce_unregister_decode_chain(&i10nm_mce_dec); 333 skx_adxl_put(); 334 skx_remove(); 335 } 336 337 module_init(i10nm_init); 338 module_exit(i10nm_exit); 339 340 MODULE_LICENSE("GPL v2"); 341 MODULE_DESCRIPTION("MC Driver for Intel 10nm server processors"); 342