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