1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Common codes for both the skx_edac driver and Intel 10nm server EDAC driver. 4*4882a593Smuzhiyun * Originally split out from the skx_edac driver. 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * Copyright (c) 2018, Intel Corporation. 7*4882a593Smuzhiyun */ 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun #ifndef _SKX_COMM_EDAC_H 10*4882a593Smuzhiyun #define _SKX_COMM_EDAC_H 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun #define MSG_SIZE 1024 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun /* 15*4882a593Smuzhiyun * Debug macros 16*4882a593Smuzhiyun */ 17*4882a593Smuzhiyun #define skx_printk(level, fmt, arg...) \ 18*4882a593Smuzhiyun edac_printk(level, "skx", fmt, ##arg) 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun #define skx_mc_printk(mci, level, fmt, arg...) \ 21*4882a593Smuzhiyun edac_mc_chipset_printk(mci, level, "skx", fmt, ##arg) 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun /* 24*4882a593Smuzhiyun * Get a bit field at register value <v>, from bit <lo> to bit <hi> 25*4882a593Smuzhiyun */ 26*4882a593Smuzhiyun #define GET_BITFIELD(v, lo, hi) \ 27*4882a593Smuzhiyun (((v) & GENMASK_ULL((hi), (lo))) >> (lo)) 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun #define SKX_NUM_IMC 2 /* Memory controllers per socket */ 30*4882a593Smuzhiyun #define SKX_NUM_CHANNELS 3 /* Channels per memory controller */ 31*4882a593Smuzhiyun #define SKX_NUM_DIMMS 2 /* Max DIMMS per channel */ 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun #define I10NM_NUM_IMC 4 34*4882a593Smuzhiyun #define I10NM_NUM_CHANNELS 2 35*4882a593Smuzhiyun #define I10NM_NUM_DIMMS 2 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun #define MAX(a, b) ((a) > (b) ? (a) : (b)) 38*4882a593Smuzhiyun #define NUM_IMC MAX(SKX_NUM_IMC, I10NM_NUM_IMC) 39*4882a593Smuzhiyun #define NUM_CHANNELS MAX(SKX_NUM_CHANNELS, I10NM_NUM_CHANNELS) 40*4882a593Smuzhiyun #define NUM_DIMMS MAX(SKX_NUM_DIMMS, I10NM_NUM_DIMMS) 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun #define IS_DIMM_PRESENT(r) GET_BITFIELD(r, 15, 15) 43*4882a593Smuzhiyun #define IS_NVDIMM_PRESENT(r, i) GET_BITFIELD(r, i, i) 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun /* 46*4882a593Smuzhiyun * Each cpu socket contains some pci devices that provide global 47*4882a593Smuzhiyun * information, and also some that are local to each of the two 48*4882a593Smuzhiyun * memory controllers on the die. 49*4882a593Smuzhiyun */ 50*4882a593Smuzhiyun struct skx_dev { 51*4882a593Smuzhiyun struct list_head list; 52*4882a593Smuzhiyun u8 bus[4]; 53*4882a593Smuzhiyun int seg; 54*4882a593Smuzhiyun struct pci_dev *sad_all; 55*4882a593Smuzhiyun struct pci_dev *util_all; 56*4882a593Smuzhiyun struct pci_dev *uracu; /* for i10nm CPU */ 57*4882a593Smuzhiyun u32 mcroute; 58*4882a593Smuzhiyun struct skx_imc { 59*4882a593Smuzhiyun struct mem_ctl_info *mci; 60*4882a593Smuzhiyun struct pci_dev *mdev; /* for i10nm CPU */ 61*4882a593Smuzhiyun void __iomem *mbase; /* for i10nm CPU */ 62*4882a593Smuzhiyun u8 mc; /* system wide mc# */ 63*4882a593Smuzhiyun u8 lmc; /* socket relative mc# */ 64*4882a593Smuzhiyun u8 src_id, node_id; 65*4882a593Smuzhiyun struct skx_channel { 66*4882a593Smuzhiyun struct pci_dev *cdev; 67*4882a593Smuzhiyun struct pci_dev *edev; 68*4882a593Smuzhiyun struct skx_dimm { 69*4882a593Smuzhiyun u8 close_pg; 70*4882a593Smuzhiyun u8 bank_xor_enable; 71*4882a593Smuzhiyun u8 fine_grain_bank; 72*4882a593Smuzhiyun u8 rowbits; 73*4882a593Smuzhiyun u8 colbits; 74*4882a593Smuzhiyun } dimms[NUM_DIMMS]; 75*4882a593Smuzhiyun } chan[NUM_CHANNELS]; 76*4882a593Smuzhiyun } imc[NUM_IMC]; 77*4882a593Smuzhiyun }; 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun struct skx_pvt { 80*4882a593Smuzhiyun struct skx_imc *imc; 81*4882a593Smuzhiyun }; 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun enum type { 84*4882a593Smuzhiyun SKX, 85*4882a593Smuzhiyun I10NM 86*4882a593Smuzhiyun }; 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun enum { 89*4882a593Smuzhiyun INDEX_SOCKET, 90*4882a593Smuzhiyun INDEX_MEMCTRL, 91*4882a593Smuzhiyun INDEX_CHANNEL, 92*4882a593Smuzhiyun INDEX_DIMM, 93*4882a593Smuzhiyun INDEX_MAX 94*4882a593Smuzhiyun }; 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun struct decoded_addr { 97*4882a593Smuzhiyun struct skx_dev *dev; 98*4882a593Smuzhiyun u64 addr; 99*4882a593Smuzhiyun int socket; 100*4882a593Smuzhiyun int imc; 101*4882a593Smuzhiyun int channel; 102*4882a593Smuzhiyun u64 chan_addr; 103*4882a593Smuzhiyun int sktways; 104*4882a593Smuzhiyun int chanways; 105*4882a593Smuzhiyun int dimm; 106*4882a593Smuzhiyun int rank; 107*4882a593Smuzhiyun int channel_rank; 108*4882a593Smuzhiyun u64 rank_address; 109*4882a593Smuzhiyun int row; 110*4882a593Smuzhiyun int column; 111*4882a593Smuzhiyun int bank_address; 112*4882a593Smuzhiyun int bank_group; 113*4882a593Smuzhiyun }; 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun struct res_config { 116*4882a593Smuzhiyun enum type type; 117*4882a593Smuzhiyun /* Configuration agent device ID */ 118*4882a593Smuzhiyun unsigned int decs_did; 119*4882a593Smuzhiyun /* Default bus number configuration register offset */ 120*4882a593Smuzhiyun int busno_cfg_offset; 121*4882a593Smuzhiyun }; 122*4882a593Smuzhiyun 123*4882a593Smuzhiyun typedef int (*get_dimm_config_f)(struct mem_ctl_info *mci); 124*4882a593Smuzhiyun typedef bool (*skx_decode_f)(struct decoded_addr *res); 125*4882a593Smuzhiyun typedef void (*skx_show_retry_log_f)(struct decoded_addr *res, char *msg, int len); 126*4882a593Smuzhiyun 127*4882a593Smuzhiyun int __init skx_adxl_get(void); 128*4882a593Smuzhiyun void __exit skx_adxl_put(void); 129*4882a593Smuzhiyun void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log); 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun int skx_get_src_id(struct skx_dev *d, int off, u8 *id); 132*4882a593Smuzhiyun int skx_get_node_id(struct skx_dev *d, u8 *id); 133*4882a593Smuzhiyun 134*4882a593Smuzhiyun int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list); 135*4882a593Smuzhiyun 136*4882a593Smuzhiyun int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm); 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun int skx_get_dimm_info(u32 mtr, u32 mcmtr, u32 amap, struct dimm_info *dimm, 139*4882a593Smuzhiyun struct skx_imc *imc, int chan, int dimmno); 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc, 142*4882a593Smuzhiyun int chan, int dimmno, const char *mod_str); 143*4882a593Smuzhiyun 144*4882a593Smuzhiyun int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev, 145*4882a593Smuzhiyun const char *ctl_name, const char *mod_str, 146*4882a593Smuzhiyun get_dimm_config_f get_dimm_config); 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun int skx_mce_check_error(struct notifier_block *nb, unsigned long val, 149*4882a593Smuzhiyun void *data); 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun void skx_remove(void); 152*4882a593Smuzhiyun 153*4882a593Smuzhiyun #endif /* _SKX_COMM_EDAC_H */ 154