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