18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Common codes for both the skx_edac driver and Intel 10nm server EDAC driver. 48c2ecf20Sopenharmony_ci * Originally split out from the skx_edac driver. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copyright (c) 2018, Intel Corporation. 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#ifndef _SKX_COMM_EDAC_H 108c2ecf20Sopenharmony_ci#define _SKX_COMM_EDAC_H 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#define MSG_SIZE 1024 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci/* 158c2ecf20Sopenharmony_ci * Debug macros 168c2ecf20Sopenharmony_ci */ 178c2ecf20Sopenharmony_ci#define skx_printk(level, fmt, arg...) \ 188c2ecf20Sopenharmony_ci edac_printk(level, "skx", fmt, ##arg) 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#define skx_mc_printk(mci, level, fmt, arg...) \ 218c2ecf20Sopenharmony_ci edac_mc_chipset_printk(mci, level, "skx", fmt, ##arg) 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci/* 248c2ecf20Sopenharmony_ci * Get a bit field at register value <v>, from bit <lo> to bit <hi> 258c2ecf20Sopenharmony_ci */ 268c2ecf20Sopenharmony_ci#define GET_BITFIELD(v, lo, hi) \ 278c2ecf20Sopenharmony_ci (((v) & GENMASK_ULL((hi), (lo))) >> (lo)) 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#define SKX_NUM_IMC 2 /* Memory controllers per socket */ 308c2ecf20Sopenharmony_ci#define SKX_NUM_CHANNELS 3 /* Channels per memory controller */ 318c2ecf20Sopenharmony_ci#define SKX_NUM_DIMMS 2 /* Max DIMMS per channel */ 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#define I10NM_NUM_IMC 4 348c2ecf20Sopenharmony_ci#define I10NM_NUM_CHANNELS 2 358c2ecf20Sopenharmony_ci#define I10NM_NUM_DIMMS 2 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#define MAX(a, b) ((a) > (b) ? (a) : (b)) 388c2ecf20Sopenharmony_ci#define NUM_IMC MAX(SKX_NUM_IMC, I10NM_NUM_IMC) 398c2ecf20Sopenharmony_ci#define NUM_CHANNELS MAX(SKX_NUM_CHANNELS, I10NM_NUM_CHANNELS) 408c2ecf20Sopenharmony_ci#define NUM_DIMMS MAX(SKX_NUM_DIMMS, I10NM_NUM_DIMMS) 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci#define IS_DIMM_PRESENT(r) GET_BITFIELD(r, 15, 15) 438c2ecf20Sopenharmony_ci#define IS_NVDIMM_PRESENT(r, i) GET_BITFIELD(r, i, i) 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci/* 468c2ecf20Sopenharmony_ci * Each cpu socket contains some pci devices that provide global 478c2ecf20Sopenharmony_ci * information, and also some that are local to each of the two 488c2ecf20Sopenharmony_ci * memory controllers on the die. 498c2ecf20Sopenharmony_ci */ 508c2ecf20Sopenharmony_cistruct skx_dev { 518c2ecf20Sopenharmony_ci struct list_head list; 528c2ecf20Sopenharmony_ci u8 bus[4]; 538c2ecf20Sopenharmony_ci int seg; 548c2ecf20Sopenharmony_ci struct pci_dev *sad_all; 558c2ecf20Sopenharmony_ci struct pci_dev *util_all; 568c2ecf20Sopenharmony_ci struct pci_dev *uracu; /* for i10nm CPU */ 578c2ecf20Sopenharmony_ci u32 mcroute; 588c2ecf20Sopenharmony_ci struct skx_imc { 598c2ecf20Sopenharmony_ci struct mem_ctl_info *mci; 608c2ecf20Sopenharmony_ci struct pci_dev *mdev; /* for i10nm CPU */ 618c2ecf20Sopenharmony_ci void __iomem *mbase; /* for i10nm CPU */ 628c2ecf20Sopenharmony_ci u8 mc; /* system wide mc# */ 638c2ecf20Sopenharmony_ci u8 lmc; /* socket relative mc# */ 648c2ecf20Sopenharmony_ci u8 src_id, node_id; 658c2ecf20Sopenharmony_ci struct skx_channel { 668c2ecf20Sopenharmony_ci struct pci_dev *cdev; 678c2ecf20Sopenharmony_ci struct pci_dev *edev; 688c2ecf20Sopenharmony_ci struct skx_dimm { 698c2ecf20Sopenharmony_ci u8 close_pg; 708c2ecf20Sopenharmony_ci u8 bank_xor_enable; 718c2ecf20Sopenharmony_ci u8 fine_grain_bank; 728c2ecf20Sopenharmony_ci u8 rowbits; 738c2ecf20Sopenharmony_ci u8 colbits; 748c2ecf20Sopenharmony_ci } dimms[NUM_DIMMS]; 758c2ecf20Sopenharmony_ci } chan[NUM_CHANNELS]; 768c2ecf20Sopenharmony_ci } imc[NUM_IMC]; 778c2ecf20Sopenharmony_ci}; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cistruct skx_pvt { 808c2ecf20Sopenharmony_ci struct skx_imc *imc; 818c2ecf20Sopenharmony_ci}; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cienum type { 848c2ecf20Sopenharmony_ci SKX, 858c2ecf20Sopenharmony_ci I10NM 868c2ecf20Sopenharmony_ci}; 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cienum { 898c2ecf20Sopenharmony_ci INDEX_SOCKET, 908c2ecf20Sopenharmony_ci INDEX_MEMCTRL, 918c2ecf20Sopenharmony_ci INDEX_CHANNEL, 928c2ecf20Sopenharmony_ci INDEX_DIMM, 938c2ecf20Sopenharmony_ci INDEX_MAX 948c2ecf20Sopenharmony_ci}; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_cistruct decoded_addr { 978c2ecf20Sopenharmony_ci struct skx_dev *dev; 988c2ecf20Sopenharmony_ci u64 addr; 998c2ecf20Sopenharmony_ci int socket; 1008c2ecf20Sopenharmony_ci int imc; 1018c2ecf20Sopenharmony_ci int channel; 1028c2ecf20Sopenharmony_ci u64 chan_addr; 1038c2ecf20Sopenharmony_ci int sktways; 1048c2ecf20Sopenharmony_ci int chanways; 1058c2ecf20Sopenharmony_ci int dimm; 1068c2ecf20Sopenharmony_ci int rank; 1078c2ecf20Sopenharmony_ci int channel_rank; 1088c2ecf20Sopenharmony_ci u64 rank_address; 1098c2ecf20Sopenharmony_ci int row; 1108c2ecf20Sopenharmony_ci int column; 1118c2ecf20Sopenharmony_ci int bank_address; 1128c2ecf20Sopenharmony_ci int bank_group; 1138c2ecf20Sopenharmony_ci}; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_cistruct res_config { 1168c2ecf20Sopenharmony_ci enum type type; 1178c2ecf20Sopenharmony_ci /* Configuration agent device ID */ 1188c2ecf20Sopenharmony_ci unsigned int decs_did; 1198c2ecf20Sopenharmony_ci /* Default bus number configuration register offset */ 1208c2ecf20Sopenharmony_ci int busno_cfg_offset; 1218c2ecf20Sopenharmony_ci}; 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_citypedef int (*get_dimm_config_f)(struct mem_ctl_info *mci); 1248c2ecf20Sopenharmony_citypedef bool (*skx_decode_f)(struct decoded_addr *res); 1258c2ecf20Sopenharmony_citypedef void (*skx_show_retry_log_f)(struct decoded_addr *res, char *msg, int len); 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ciint __init skx_adxl_get(void); 1288c2ecf20Sopenharmony_civoid __exit skx_adxl_put(void); 1298c2ecf20Sopenharmony_civoid skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log); 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ciint skx_get_src_id(struct skx_dev *d, int off, u8 *id); 1328c2ecf20Sopenharmony_ciint skx_get_node_id(struct skx_dev *d, u8 *id); 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ciint skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list); 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ciint skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm); 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ciint skx_get_dimm_info(u32 mtr, u32 mcmtr, u32 amap, struct dimm_info *dimm, 1398c2ecf20Sopenharmony_ci struct skx_imc *imc, int chan, int dimmno); 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ciint skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc, 1428c2ecf20Sopenharmony_ci int chan, int dimmno, const char *mod_str); 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ciint skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev, 1458c2ecf20Sopenharmony_ci const char *ctl_name, const char *mod_str, 1468c2ecf20Sopenharmony_ci get_dimm_config_f get_dimm_config); 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ciint skx_mce_check_error(struct notifier_block *nb, unsigned long val, 1498c2ecf20Sopenharmony_ci void *data); 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_civoid skx_remove(void); 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci#endif /* _SKX_COMM_EDAC_H */ 154