xref: /illumos-gate/usr/src/uts/intel/io/mc-amd/mcamd.h (revision 074bb90d)
17aec1d6eScindi /*
27aec1d6eScindi  * CDDL HEADER START
37aec1d6eScindi  *
47aec1d6eScindi  * The contents of this file are subject to the terms of the
58a40a695Sgavinm  * Common Development and Distribution License (the "License").
68a40a695Sgavinm  * You may not use this file except in compliance with the License.
77aec1d6eScindi  *
87aec1d6eScindi  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97aec1d6eScindi  * or http://www.opensolaris.org/os/licensing.
107aec1d6eScindi  * See the License for the specific language governing permissions
117aec1d6eScindi  * and limitations under the License.
127aec1d6eScindi  *
137aec1d6eScindi  * When distributing Covered Code, include this CDDL HEADER in each
147aec1d6eScindi  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157aec1d6eScindi  * If applicable, add the following below this CDDL HEADER, with the
167aec1d6eScindi  * fields enclosed by brackets "[]" replaced with your own identifying
177aec1d6eScindi  * information: Portions Copyright [yyyy] [name of copyright owner]
187aec1d6eScindi  *
197aec1d6eScindi  * CDDL HEADER END
207aec1d6eScindi  */
217aec1d6eScindi 
227aec1d6eScindi /*
23*074bb90dSTom Pothier  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
247aec1d6eScindi  * Use is subject to license terms.
257aec1d6eScindi  */
267aec1d6eScindi 
277aec1d6eScindi #ifndef _MCAMD_H
287aec1d6eScindi #define	_MCAMD_H
297aec1d6eScindi 
30bb86c342Sgavinm /*
31bb86c342Sgavinm  * Header file for the mc-amd AMD memory-controller driver.  This should be
32bb86c342Sgavinm  * included from that driver source alone - any more-widely useful definitions
33bb86c342Sgavinm  * belong in mc_amd.h.
34bb86c342Sgavinm  */
35bb86c342Sgavinm 
367aec1d6eScindi #include <sys/types.h>
377aec1d6eScindi #include <sys/ddi.h>
387aec1d6eScindi #include <sys/sunddi.h>
397aec1d6eScindi #include <sys/ksynch.h>
407aec1d6eScindi #include <sys/mc_amd.h>
4120c794b3Sgavinm #include <sys/cpu_module.h>
427aec1d6eScindi #include <mcamd_api.h>
4320c794b3Sgavinm #include <mcamd_err.h>
448a40a695Sgavinm #include <mcamd_dimmcfg.h>
457aec1d6eScindi 
467aec1d6eScindi #ifdef __cplusplus
477aec1d6eScindi extern "C" {
487aec1d6eScindi #endif
497aec1d6eScindi 
50bb86c342Sgavinm #if	MC_CHIP_DIMMPERCS > MC_UNUM_NDIMM
51bb86c342Sgavinm #error	"MC_CHIP_DIMMPERCS exceeds MC_UNUM_NDIMM"
52bb86c342Sgavinm #endif
53bb86c342Sgavinm 
547aec1d6eScindi /*
55bb86c342Sgavinm  * The memory controller configuration registers are accessed via PCI bus 0,
56bb86c342Sgavinm  * device 0x18 + nodeid, functions 0 to 3.  The function numbers are
57bb86c342Sgavinm  * MC_FUNC_*, defined in mc_amd.h.
58bb86c342Sgavinm  *
59bb86c342Sgavinm  * We do not attach to function 3 "Miscellaneous Control" pci1022,1103
608a40a695Sgavinm  * since the agpgart driver already attaches to that function; instead we
618a40a695Sgavinm  * retrieve what function 3 parameters we require via direct PCI Mechanism 1
62bb86c342Sgavinm  * accesses
63bb86c342Sgavinm  *
64bb86c342Sgavinm  * The memory controller driver attaches to these device nodes, but publishes
657aec1d6eScindi  * a single minor node.  We need to ensure that the minor node can be
66bb86c342Sgavinm  * consistently mapped back to a single (and the same) device node, so we
67bb86c342Sgavinm  * need to pick one to be used.  We'll use the dram address map device node,
68bb86c342Sgavinm  * as it'll be the last to be attached.
697aec1d6eScindi  */
707aec1d6eScindi #define	MC_FUNC_DEVIMAP		MC_FUNC_DRAMCTL
71bb86c342Sgavinm #define	MC_FUNC_NUM		(MC_FUNC_MISCCTL + 1)
727aec1d6eScindi 
73bb86c342Sgavinm #define	MC_FUNC_HTCONFIG_BINDNM	"pci1022,1100"
74bb86c342Sgavinm #define	MC_FUNC_ADDRMAP_BINDNM	"pci1022,1101"
75bb86c342Sgavinm #define	MC_FUNC_DRAMCTL_BINDNM	"pci1022,1102"
767aec1d6eScindi 
777aec1d6eScindi typedef struct mc_func {
787aec1d6eScindi 	uint_t mcf_instance;
797aec1d6eScindi 	dev_info_t *mcf_devi;
807aec1d6eScindi } mc_func_t;
817aec1d6eScindi 
827aec1d6eScindi typedef struct mc_dimm mc_dimm_t;
837aec1d6eScindi typedef struct mc_cs mc_cs_t;
847aec1d6eScindi typedef struct mc mc_t;
857aec1d6eScindi 
867aec1d6eScindi /*
877aec1d6eScindi  * Node types for mch_type below.  These are used in array indexing.
887aec1d6eScindi  */
897aec1d6eScindi #define	MC_NT_MC		0
907aec1d6eScindi #define	MC_NT_CS		1
917aec1d6eScindi #define	MC_NT_DIMM		2
927aec1d6eScindi #define	MC_NT_NTYPES		3
937aec1d6eScindi 
947aec1d6eScindi typedef struct mc_hdr {
957aec1d6eScindi 	uint_t mch_type;
967aec1d6eScindi 	union {
977aec1d6eScindi 		mc_t *_mch_mc;
987aec1d6eScindi 		mc_cs_t *_mch_cs;
997aec1d6eScindi 	} _mch_ptr;
1007aec1d6eScindi } mc_hdr_t;
1017aec1d6eScindi 
1027aec1d6eScindi #define	mch_mc		_mch_ptr._mch_mc
1037aec1d6eScindi 
1047aec1d6eScindi struct mc_dimm {
1057aec1d6eScindi 	mc_hdr_t mcd_hdr;			/* id, pointer to parent */
1067aec1d6eScindi 	mc_dimm_t *mcd_next;			/* next dimm for this MC */
1077aec1d6eScindi 	mc_cs_t *mcd_cs[MC_CHIP_DIMMRANKMAX];	/* associated chip-selects */
1088a40a695Sgavinm 	const mcdcfg_csl_t *mcd_csl[MC_CHIP_DIMMRANKMAX]; /* cs lines */
1098a40a695Sgavinm 	mcamd_prop_t mcd_num;			/* dimm number */
1108a40a695Sgavinm 	mcamd_prop_t mcd_size;			/* dimm size in bytes */
1117aec1d6eScindi };
1127aec1d6eScindi 
1137aec1d6eScindi #define	mcd_mc mcd_hdr.mch_mc
1147aec1d6eScindi 
1158a40a695Sgavinm /*
1168a40a695Sgavinm  * Chip-select properties.  If a chip-select is associated with just one
1178a40a695Sgavinm  * dimm (whether it be on the A or B dram channel) that number will be
1188a40a695Sgavinm  * in csp_dimmnums[0];  if the chip-select is associated with two dimms
1198a40a695Sgavinm  * then csp_dimmnums[0] has the dimm from channel A and csp_dimmnums[1] has
1208a40a695Sgavinm  * the partner dimm from channel B.
1218a40a695Sgavinm  */
1228a40a695Sgavinm typedef struct mccs_props {
1238a40a695Sgavinm 	mcamd_prop_t csp_num;			/* Chip-select number */
1248a40a695Sgavinm 	mcamd_prop_t csp_base;			/* DRAM CS Base */
1258a40a695Sgavinm 	mcamd_prop_t csp_mask;			/* DRAM CS Mask */
1268a40a695Sgavinm 	mcamd_prop_t csp_size;			/* Chip-select bank size */
1278a40a695Sgavinm 	mcamd_prop_t csp_csbe;			/* Chip-select bank enable */
1288a40a695Sgavinm 	mcamd_prop_t csp_spare;			/* Spare */
1298a40a695Sgavinm 	mcamd_prop_t csp_testfail;		/* TestFail */
1308a40a695Sgavinm 	mcamd_prop_t csp_dimmnums[MC_CHIP_DIMMPERCS]; /* dimm(s) in cs */
1318a40a695Sgavinm 	mcamd_prop_t csp_dimmrank;		/* rank # on dimms */
1328a40a695Sgavinm } mccs_props_t;
1338a40a695Sgavinm 
1348a40a695Sgavinm /*
1358a40a695Sgavinm  * Chip-select config register values
1368a40a695Sgavinm  */
1378a40a695Sgavinm typedef struct mccs_cfgrefs {
1388a40a695Sgavinm 	mcamd_cfgreg_t csr_csbase;		/* Raw CS base reg */
1398a40a695Sgavinm 	mcamd_cfgreg_t csr_csmask;		/* Raw CS mask reg */
1408a40a695Sgavinm } mccs_cfgregs_t;
1418a40a695Sgavinm 
1427aec1d6eScindi struct mc_cs {
1437aec1d6eScindi 	mc_hdr_t mccs_hdr;			/* id, pointer to parent */
1447aec1d6eScindi 	mc_cs_t *mccs_next;			/* Next chip-select of MC */
1457aec1d6eScindi 	mc_dimm_t *mccs_dimm[MC_CHIP_DIMMPERCS]; /* dimms for this cs */
1468a40a695Sgavinm 	const mcdcfg_csl_t *mccs_csl[MC_CHIP_DIMMPERCS]; /* cs lines */
1478a40a695Sgavinm 	mccs_props_t mccs_props;		/* Properties */
1488a40a695Sgavinm 	mccs_cfgregs_t mccs_cfgregs;		/* Raw config values */
1497aec1d6eScindi };
1507aec1d6eScindi 
1517aec1d6eScindi #define	mccs_mc	mccs_hdr.mch_mc
1527aec1d6eScindi 
1538a40a695Sgavinm /*
1548a40a695Sgavinm  * Memory controller properties.
1558a40a695Sgavinm  */
1567aec1d6eScindi typedef struct mc_props {
1578a40a695Sgavinm 	mcamd_prop_t mcp_num;		/* Associated *chip* number */
1588a40a695Sgavinm 	mcamd_prop_t mcp_rev;		/* Chip revision (MC_REV_*) */
1598a40a695Sgavinm 	mcamd_prop_t mcp_base;		/* base address for mc's drams */
1608a40a695Sgavinm 	mcamd_prop_t mcp_lim;		/* limit address for mc's drams */
1618a40a695Sgavinm 	mcamd_prop_t mcp_ilen;		/* interleave enable */
1628a40a695Sgavinm 	mcamd_prop_t mcp_ilsel;		/* interleave select */
1638a40a695Sgavinm 	mcamd_prop_t mcp_csintlvfctr;	/* cs bank interleave factor */
1648a40a695Sgavinm 	mcamd_prop_t mcp_dramhole_size;	/* DRAM Hole Size */
1658a40a695Sgavinm 	mcamd_prop_t mcp_accwidth;	/* dram access width (64 or 128) */
1668a40a695Sgavinm 	mcamd_prop_t mcp_csbankmapreg;	/* chip-select bank mapping reg */
1678a40a695Sgavinm 	mcamd_prop_t mcp_bnkswzl;	/* BankSwizzle enabled */
1688a40a695Sgavinm 	mcamd_prop_t mcp_mod64mux;	/* Mismtached DIMMs support enabled */
1698a40a695Sgavinm 	mcamd_prop_t mcp_sparecs;	/* cs# replaced by online spare */
1708a40a695Sgavinm 	mcamd_prop_t mcp_badcs;		/* cs# replaced by online spare */
1717aec1d6eScindi } mc_props_t;
1727aec1d6eScindi 
1738a40a695Sgavinm /*
1748a40a695Sgavinm  * Memory controller config register values
1758a40a695Sgavinm  */
1768a40a695Sgavinm typedef struct mc_cfgregs {
1779dd0f810Scindi 	mcamd_cfgreg_t mcr_htroute[MC_CHIP_MAXNODES];
1789dd0f810Scindi 	mcamd_cfgreg_t mcr_htnodeid;
1799dd0f810Scindi 	mcamd_cfgreg_t mcr_htunitid;
1808a40a695Sgavinm 	mcamd_cfgreg_t mcr_drambase;
1818a40a695Sgavinm 	mcamd_cfgreg_t mcr_dramlimit;
1828a40a695Sgavinm 	mcamd_cfgreg_t mcr_dramhole;
1838a40a695Sgavinm 	mcamd_cfgreg_t mcr_dramcfglo;
1848a40a695Sgavinm 	mcamd_cfgreg_t mcr_dramcfghi;
1858a40a695Sgavinm 	mcamd_cfgreg_t mcr_drammisc;
1868a40a695Sgavinm 	mcamd_cfgreg_t mcr_nbcfg;
1878a40a695Sgavinm 	mcamd_cfgreg_t mcr_sparectl;
18820c794b3Sgavinm 	mcamd_cfgreg_t mcr_scrubctl;
18920c794b3Sgavinm 	mcamd_cfgreg_t mcr_scrubaddrlo;
19020c794b3Sgavinm 	mcamd_cfgreg_t mcr_scrubaddrhi;
1918a40a695Sgavinm } mc_cfgregs_t;
1928a40a695Sgavinm 
1937aec1d6eScindi struct mc {
1947aec1d6eScindi 	mc_hdr_t mc_hdr;			/* id */
19520c794b3Sgavinm 	struct mc *mc_next;			/* next MC instance */
1967aec1d6eScindi 	const char *mc_revname;			/* revision name string */
1978a40a695Sgavinm 	uint32_t mc_socket;			/* Package type */
1987aec1d6eScindi 	uint_t mc_ref;				/* reference (attach) count */
1997aec1d6eScindi 	mc_func_t mc_funcs[MC_FUNC_NUM];	/* Instance, devinfo, ... */
2007aec1d6eScindi 	mc_cs_t *mc_cslist;			/* All active chip-selects */
2017aec1d6eScindi 	mc_cs_t *mc_cslast;			/* End of chip-select list */
2028a40a695Sgavinm 	mc_dimm_t *mc_dimmlist;			/* List of all logical DIMMs, */
2038a40a695Sgavinm 	mc_dimm_t *mc_dimmlast;			/* linked via mcd_mcnext */
2047aec1d6eScindi 	mc_props_t mc_props;			/* Properties */
2058a40a695Sgavinm 	mc_cfgregs_t mc_cfgregs;		/* Raw config values */
2068a40a695Sgavinm 	hrtime_t mc_spareswaptime;		/* If initiated by us */
2077aec1d6eScindi 	nvlist_t *mc_nvl;			/* nvlist for export */
2087aec1d6eScindi 	char *mc_snapshot;			/* packed nvlist for libmc */
2097aec1d6eScindi 	size_t mc_snapshotsz;			/* packed nvlist buffer size */
2107aec1d6eScindi 	uint_t mc_snapshotgen;			/* snapshot generation number */
2118a40a695Sgavinm 	int mc_csdiscontig;			/* chip-selects discontiguous */
212*074bb90dSTom Pothier 	uint_t smb_chipid;			/* smbios chip instance */
213*074bb90dSTom Pothier 	nvlist_t *smb_bboard;			/* smbios chip's parent */
2147aec1d6eScindi };
2157aec1d6eScindi 
2167aec1d6eScindi typedef struct mcamd_hdl {
2177aec1d6eScindi 	int mcamd_errno;
2187aec1d6eScindi 	int mcamd_debug;
2197aec1d6eScindi } mcamd_hdl_t;
2207aec1d6eScindi 
2217aec1d6eScindi extern mc_t *mc_list;
2227aec1d6eScindi extern krwlock_t mc_lock;
2237aec1d6eScindi 
2247aec1d6eScindi extern void mcamd_mkhdl(mcamd_hdl_t *);
22520c794b3Sgavinm extern void mcamd_mc_register(cmi_hdl_t, mc_t *);
2268a40a695Sgavinm extern void mcamd_ereport_post(mc_t *, const char *, mc_unum_t *, uint64_t);
2277aec1d6eScindi 
22820c794b3Sgavinm /*
22920c794b3Sgavinm  * mcamd_mc_ops prototypes
23020c794b3Sgavinm  */
23120c794b3Sgavinm extern cmi_errno_t mcamd_patounum_wrap(void *, uint64_t, uint8_t, uint8_t,
23220c794b3Sgavinm     uint32_t, int, mc_unum_t *);
23320c794b3Sgavinm extern cmi_errno_t mcamd_unumtopa_wrap(void *, mc_unum_t *, nvlist_t *,
23420c794b3Sgavinm     uint64_t *);
23520c794b3Sgavinm 
23620c794b3Sgavinm /*
23720c794b3Sgavinm  * Internal functions
23820c794b3Sgavinm  */
23920c794b3Sgavinm cmi_errno_t mcamd_cmierr(int, mcamd_hdl_t *);
24020c794b3Sgavinm 
2417aec1d6eScindi #ifdef __cplusplus
2427aec1d6eScindi }
2437aec1d6eScindi #endif
2447aec1d6eScindi 
2457aec1d6eScindi #endif /* _MCAMD_H */
246