xref: /illumos-gate/usr/src/uts/intel/io/mc-amd/mcamd.h (revision 074bb90d80fdbeb2d04a8450a55ecbc96de28785)
1e4b86885SCheng Sean Ye /*
2e4b86885SCheng Sean Ye  * CDDL HEADER START
3e4b86885SCheng Sean Ye  *
4e4b86885SCheng Sean Ye  * The contents of this file are subject to the terms of the
5e4b86885SCheng Sean Ye  * Common Development and Distribution License (the "License").
6e4b86885SCheng Sean Ye  * You may not use this file except in compliance with the License.
7e4b86885SCheng Sean Ye  *
8e4b86885SCheng Sean Ye  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9e4b86885SCheng Sean Ye  * or http://www.opensolaris.org/os/licensing.
10e4b86885SCheng Sean Ye  * See the License for the specific language governing permissions
11e4b86885SCheng Sean Ye  * and limitations under the License.
12e4b86885SCheng Sean Ye  *
13e4b86885SCheng Sean Ye  * When distributing Covered Code, include this CDDL HEADER in each
14e4b86885SCheng Sean Ye  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15e4b86885SCheng Sean Ye  * If applicable, add the following below this CDDL HEADER, with the
16e4b86885SCheng Sean Ye  * fields enclosed by brackets "[]" replaced with your own identifying
17e4b86885SCheng Sean Ye  * information: Portions Copyright [yyyy] [name of copyright owner]
18e4b86885SCheng Sean Ye  *
19e4b86885SCheng Sean Ye  * CDDL HEADER END
20e4b86885SCheng Sean Ye  */
21e4b86885SCheng Sean Ye 
22e4b86885SCheng Sean Ye /*
23*074bb90dSTom Pothier  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24e4b86885SCheng Sean Ye  * Use is subject to license terms.
25e4b86885SCheng Sean Ye  */
26e4b86885SCheng Sean Ye 
27e4b86885SCheng Sean Ye #ifndef _MCAMD_H
28e4b86885SCheng Sean Ye #define	_MCAMD_H
29e4b86885SCheng Sean Ye 
30e4b86885SCheng Sean Ye /*
31e4b86885SCheng Sean Ye  * Header file for the mc-amd AMD memory-controller driver.  This should be
32e4b86885SCheng Sean Ye  * included from that driver source alone - any more-widely useful definitions
33e4b86885SCheng Sean Ye  * belong in mc_amd.h.
34e4b86885SCheng Sean Ye  */
35e4b86885SCheng Sean Ye 
36e4b86885SCheng Sean Ye #include <sys/types.h>
37e4b86885SCheng Sean Ye #include <sys/ddi.h>
38e4b86885SCheng Sean Ye #include <sys/sunddi.h>
39e4b86885SCheng Sean Ye #include <sys/ksynch.h>
40e4b86885SCheng Sean Ye #include <sys/mc_amd.h>
41e4b86885SCheng Sean Ye #include <sys/cpu_module.h>
42e4b86885SCheng Sean Ye #include <mcamd_api.h>
43e4b86885SCheng Sean Ye #include <mcamd_err.h>
44e4b86885SCheng Sean Ye #include <mcamd_dimmcfg.h>
45e4b86885SCheng Sean Ye 
46e4b86885SCheng Sean Ye #ifdef __cplusplus
47e4b86885SCheng Sean Ye extern "C" {
48e4b86885SCheng Sean Ye #endif
49e4b86885SCheng Sean Ye 
50e4b86885SCheng Sean Ye #if	MC_CHIP_DIMMPERCS > MC_UNUM_NDIMM
51e4b86885SCheng Sean Ye #error	"MC_CHIP_DIMMPERCS exceeds MC_UNUM_NDIMM"
52e4b86885SCheng Sean Ye #endif
53e4b86885SCheng Sean Ye 
54e4b86885SCheng Sean Ye /*
55e4b86885SCheng Sean Ye  * The memory controller configuration registers are accessed via PCI bus 0,
56e4b86885SCheng Sean Ye  * device 0x18 + nodeid, functions 0 to 3.  The function numbers are
57e4b86885SCheng Sean Ye  * MC_FUNC_*, defined in mc_amd.h.
58e4b86885SCheng Sean Ye  *
59e4b86885SCheng Sean Ye  * We do not attach to function 3 "Miscellaneous Control" pci1022,1103
60e4b86885SCheng Sean Ye  * since the agpgart driver already attaches to that function; instead we
61e4b86885SCheng Sean Ye  * retrieve what function 3 parameters we require via direct PCI Mechanism 1
62e4b86885SCheng Sean Ye  * accesses
63e4b86885SCheng Sean Ye  *
64e4b86885SCheng Sean Ye  * The memory controller driver attaches to these device nodes, but publishes
65e4b86885SCheng Sean Ye  * a single minor node.  We need to ensure that the minor node can be
66e4b86885SCheng Sean Ye  * consistently mapped back to a single (and the same) device node, so we
67e4b86885SCheng Sean Ye  * need to pick one to be used.  We'll use the dram address map device node,
68e4b86885SCheng Sean Ye  * as it'll be the last to be attached.
69e4b86885SCheng Sean Ye  */
70e4b86885SCheng Sean Ye #define	MC_FUNC_DEVIMAP		MC_FUNC_DRAMCTL
71e4b86885SCheng Sean Ye #define	MC_FUNC_NUM		(MC_FUNC_MISCCTL + 1)
72e4b86885SCheng Sean Ye 
73e4b86885SCheng Sean Ye #define	MC_FUNC_HTCONFIG_BINDNM	"pci1022,1100"
74e4b86885SCheng Sean Ye #define	MC_FUNC_ADDRMAP_BINDNM	"pci1022,1101"
75e4b86885SCheng Sean Ye #define	MC_FUNC_DRAMCTL_BINDNM	"pci1022,1102"
76e4b86885SCheng Sean Ye 
77e4b86885SCheng Sean Ye typedef struct mc_func {
78e4b86885SCheng Sean Ye 	uint_t mcf_instance;
79e4b86885SCheng Sean Ye 	dev_info_t *mcf_devi;
80e4b86885SCheng Sean Ye } mc_func_t;
81e4b86885SCheng Sean Ye 
82e4b86885SCheng Sean Ye typedef struct mc_dimm mc_dimm_t;
83e4b86885SCheng Sean Ye typedef struct mc_cs mc_cs_t;
84e4b86885SCheng Sean Ye typedef struct mc mc_t;
85e4b86885SCheng Sean Ye 
86e4b86885SCheng Sean Ye /*
87e4b86885SCheng Sean Ye  * Node types for mch_type below.  These are used in array indexing.
88e4b86885SCheng Sean Ye  */
89e4b86885SCheng Sean Ye #define	MC_NT_MC		0
90e4b86885SCheng Sean Ye #define	MC_NT_CS		1
91e4b86885SCheng Sean Ye #define	MC_NT_DIMM		2
92e4b86885SCheng Sean Ye #define	MC_NT_NTYPES		3
93e4b86885SCheng Sean Ye 
94e4b86885SCheng Sean Ye typedef struct mc_hdr {
95e4b86885SCheng Sean Ye 	uint_t mch_type;
96e4b86885SCheng Sean Ye 	union {
97e4b86885SCheng Sean Ye 		mc_t *_mch_mc;
98e4b86885SCheng Sean Ye 		mc_cs_t *_mch_cs;
99e4b86885SCheng Sean Ye 	} _mch_ptr;
100e4b86885SCheng Sean Ye } mc_hdr_t;
101e4b86885SCheng Sean Ye 
102e4b86885SCheng Sean Ye #define	mch_mc		_mch_ptr._mch_mc
103e4b86885SCheng Sean Ye 
104e4b86885SCheng Sean Ye struct mc_dimm {
105e4b86885SCheng Sean Ye 	mc_hdr_t mcd_hdr;			/* id, pointer to parent */
106e4b86885SCheng Sean Ye 	mc_dimm_t *mcd_next;			/* next dimm for this MC */
107e4b86885SCheng Sean Ye 	mc_cs_t *mcd_cs[MC_CHIP_DIMMRANKMAX];	/* associated chip-selects */
108e4b86885SCheng Sean Ye 	const mcdcfg_csl_t *mcd_csl[MC_CHIP_DIMMRANKMAX]; /* cs lines */
109e4b86885SCheng Sean Ye 	mcamd_prop_t mcd_num;			/* dimm number */
110e4b86885SCheng Sean Ye 	mcamd_prop_t mcd_size;			/* dimm size in bytes */
111e4b86885SCheng Sean Ye };
112e4b86885SCheng Sean Ye 
113e4b86885SCheng Sean Ye #define	mcd_mc mcd_hdr.mch_mc
114e4b86885SCheng Sean Ye 
115e4b86885SCheng Sean Ye /*
116e4b86885SCheng Sean Ye  * Chip-select properties.  If a chip-select is associated with just one
117e4b86885SCheng Sean Ye  * dimm (whether it be on the A or B dram channel) that number will be
118e4b86885SCheng Sean Ye  * in csp_dimmnums[0];  if the chip-select is associated with two dimms
119e4b86885SCheng Sean Ye  * then csp_dimmnums[0] has the dimm from channel A and csp_dimmnums[1] has
120e4b86885SCheng Sean Ye  * the partner dimm from channel B.
121e4b86885SCheng Sean Ye  */
122e4b86885SCheng Sean Ye typedef struct mccs_props {
123e4b86885SCheng Sean Ye 	mcamd_prop_t csp_num;			/* Chip-select number */
124e4b86885SCheng Sean Ye 	mcamd_prop_t csp_base;			/* DRAM CS Base */
125e4b86885SCheng Sean Ye 	mcamd_prop_t csp_mask;			/* DRAM CS Mask */
126e4b86885SCheng Sean Ye 	mcamd_prop_t csp_size;			/* Chip-select bank size */
127e4b86885SCheng Sean Ye 	mcamd_prop_t csp_csbe;			/* Chip-select bank enable */
128e4b86885SCheng Sean Ye 	mcamd_prop_t csp_spare;			/* Spare */
129e4b86885SCheng Sean Ye 	mcamd_prop_t csp_testfail;		/* TestFail */
130e4b86885SCheng Sean Ye 	mcamd_prop_t csp_dimmnums[MC_CHIP_DIMMPERCS]; /* dimm(s) in cs */
131e4b86885SCheng Sean Ye 	mcamd_prop_t csp_dimmrank;		/* rank # on dimms */
132e4b86885SCheng Sean Ye } mccs_props_t;
133e4b86885SCheng Sean Ye 
134e4b86885SCheng Sean Ye /*
135e4b86885SCheng Sean Ye  * Chip-select config register values
136e4b86885SCheng Sean Ye  */
137e4b86885SCheng Sean Ye typedef struct mccs_cfgrefs {
138e4b86885SCheng Sean Ye 	mcamd_cfgreg_t csr_csbase;		/* Raw CS base reg */
139e4b86885SCheng Sean Ye 	mcamd_cfgreg_t csr_csmask;		/* Raw CS mask reg */
140e4b86885SCheng Sean Ye } mccs_cfgregs_t;
141e4b86885SCheng Sean Ye 
142e4b86885SCheng Sean Ye struct mc_cs {
143e4b86885SCheng Sean Ye 	mc_hdr_t mccs_hdr;			/* id, pointer to parent */
144e4b86885SCheng Sean Ye 	mc_cs_t *mccs_next;			/* Next chip-select of MC */
145e4b86885SCheng Sean Ye 	mc_dimm_t *mccs_dimm[MC_CHIP_DIMMPERCS]; /* dimms for this cs */
146e4b86885SCheng Sean Ye 	const mcdcfg_csl_t *mccs_csl[MC_CHIP_DIMMPERCS]; /* cs lines */
147e4b86885SCheng Sean Ye 	mccs_props_t mccs_props;		/* Properties */
148e4b86885SCheng Sean Ye 	mccs_cfgregs_t mccs_cfgregs;		/* Raw config values */
149e4b86885SCheng Sean Ye };
150e4b86885SCheng Sean Ye 
151e4b86885SCheng Sean Ye #define	mccs_mc	mccs_hdr.mch_mc
152e4b86885SCheng Sean Ye 
153e4b86885SCheng Sean Ye /*
154e4b86885SCheng Sean Ye  * Memory controller properties.
155e4b86885SCheng Sean Ye  */
156e4b86885SCheng Sean Ye typedef struct mc_props {
157e4b86885SCheng Sean Ye 	mcamd_prop_t mcp_num;		/* Associated *chip* number */
158e4b86885SCheng Sean Ye 	mcamd_prop_t mcp_rev;		/* Chip revision (MC_REV_*) */
159e4b86885SCheng Sean Ye 	mcamd_prop_t mcp_base;		/* base address for mc's drams */
160e4b86885SCheng Sean Ye 	mcamd_prop_t mcp_lim;		/* limit address for mc's drams */
161e4b86885SCheng Sean Ye 	mcamd_prop_t mcp_ilen;		/* interleave enable */
162e4b86885SCheng Sean Ye 	mcamd_prop_t mcp_ilsel;		/* interleave select */
163e4b86885SCheng Sean Ye 	mcamd_prop_t mcp_csintlvfctr;	/* cs bank interleave factor */
164e4b86885SCheng Sean Ye 	mcamd_prop_t mcp_dramhole_size;	/* DRAM Hole Size */
165e4b86885SCheng Sean Ye 	mcamd_prop_t mcp_accwidth;	/* dram access width (64 or 128) */
166e4b86885SCheng Sean Ye 	mcamd_prop_t mcp_csbankmapreg;	/* chip-select bank mapping reg */
167e4b86885SCheng Sean Ye 	mcamd_prop_t mcp_bnkswzl;	/* BankSwizzle enabled */
168e4b86885SCheng Sean Ye 	mcamd_prop_t mcp_mod64mux;	/* Mismtached DIMMs support enabled */
169e4b86885SCheng Sean Ye 	mcamd_prop_t mcp_sparecs;	/* cs# replaced by online spare */
170e4b86885SCheng Sean Ye 	mcamd_prop_t mcp_badcs;		/* cs# replaced by online spare */
171e4b86885SCheng Sean Ye } mc_props_t;
172e4b86885SCheng Sean Ye 
173e4b86885SCheng Sean Ye /*
174e4b86885SCheng Sean Ye  * Memory controller config register values
175e4b86885SCheng Sean Ye  */
176e4b86885SCheng Sean Ye typedef struct mc_cfgregs {
177e4b86885SCheng Sean Ye 	mcamd_cfgreg_t mcr_htroute[MC_CHIP_MAXNODES];
178e4b86885SCheng Sean Ye 	mcamd_cfgreg_t mcr_htnodeid;
179e4b86885SCheng Sean Ye 	mcamd_cfgreg_t mcr_htunitid;
180e4b86885SCheng Sean Ye 	mcamd_cfgreg_t mcr_drambase;
181e4b86885SCheng Sean Ye 	mcamd_cfgreg_t mcr_dramlimit;
182e4b86885SCheng Sean Ye 	mcamd_cfgreg_t mcr_dramhole;
183e4b86885SCheng Sean Ye 	mcamd_cfgreg_t mcr_dramcfglo;
184e4b86885SCheng Sean Ye 	mcamd_cfgreg_t mcr_dramcfghi;
185e4b86885SCheng Sean Ye 	mcamd_cfgreg_t mcr_drammisc;
186e4b86885SCheng Sean Ye 	mcamd_cfgreg_t mcr_nbcfg;
187e4b86885SCheng Sean Ye 	mcamd_cfgreg_t mcr_sparectl;
188e4b86885SCheng Sean Ye 	mcamd_cfgreg_t mcr_scrubctl;
189e4b86885SCheng Sean Ye 	mcamd_cfgreg_t mcr_scrubaddrlo;
190e4b86885SCheng Sean Ye 	mcamd_cfgreg_t mcr_scrubaddrhi;
191e4b86885SCheng Sean Ye } mc_cfgregs_t;
192e4b86885SCheng Sean Ye 
193e4b86885SCheng Sean Ye struct mc {
194e4b86885SCheng Sean Ye 	mc_hdr_t mc_hdr;			/* id */
195e4b86885SCheng Sean Ye 	struct mc *mc_next;			/* next MC instance */
196e4b86885SCheng Sean Ye 	const char *mc_revname;			/* revision name string */
197e4b86885SCheng Sean Ye 	uint32_t mc_socket;			/* Package type */
198e4b86885SCheng Sean Ye 	uint_t mc_ref;				/* reference (attach) count */
199e4b86885SCheng Sean Ye 	mc_func_t mc_funcs[MC_FUNC_NUM];	/* Instance, devinfo, ... */
200e4b86885SCheng Sean Ye 	mc_cs_t *mc_cslist;			/* All active chip-selects */
201e4b86885SCheng Sean Ye 	mc_cs_t *mc_cslast;			/* End of chip-select list */
202e4b86885SCheng Sean Ye 	mc_dimm_t *mc_dimmlist;			/* List of all logical DIMMs, */
203e4b86885SCheng Sean Ye 	mc_dimm_t *mc_dimmlast;			/* linked via mcd_mcnext */
204e4b86885SCheng Sean Ye 	mc_props_t mc_props;			/* Properties */
205e4b86885SCheng Sean Ye 	mc_cfgregs_t mc_cfgregs;		/* Raw config values */
206e4b86885SCheng Sean Ye 	hrtime_t mc_spareswaptime;		/* If initiated by us */
207e4b86885SCheng Sean Ye 	nvlist_t *mc_nvl;			/* nvlist for export */
208e4b86885SCheng Sean Ye 	char *mc_snapshot;			/* packed nvlist for libmc */
209e4b86885SCheng Sean Ye 	size_t mc_snapshotsz;			/* packed nvlist buffer size */
210e4b86885SCheng Sean Ye 	uint_t mc_snapshotgen;			/* snapshot generation number */
211e4b86885SCheng Sean Ye 	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 */
214e4b86885SCheng Sean Ye };
215e4b86885SCheng Sean Ye 
216e4b86885SCheng Sean Ye typedef struct mcamd_hdl {
217e4b86885SCheng Sean Ye 	int mcamd_errno;
218e4b86885SCheng Sean Ye 	int mcamd_debug;
219e4b86885SCheng Sean Ye } mcamd_hdl_t;
220e4b86885SCheng Sean Ye 
221e4b86885SCheng Sean Ye extern mc_t *mc_list;
222e4b86885SCheng Sean Ye extern krwlock_t mc_lock;
223e4b86885SCheng Sean Ye 
224e4b86885SCheng Sean Ye extern void mcamd_mkhdl(mcamd_hdl_t *);
225e4b86885SCheng Sean Ye extern void mcamd_mc_register(cmi_hdl_t, mc_t *);
226e4b86885SCheng Sean Ye extern void mcamd_ereport_post(mc_t *, const char *, mc_unum_t *, uint64_t);
227e4b86885SCheng Sean Ye 
228e4b86885SCheng Sean Ye /*
229e4b86885SCheng Sean Ye  * mcamd_mc_ops prototypes
230e4b86885SCheng Sean Ye  */
231e4b86885SCheng Sean Ye extern cmi_errno_t mcamd_patounum_wrap(void *, uint64_t, uint8_t, uint8_t,
232e4b86885SCheng Sean Ye     uint32_t, int, mc_unum_t *);
233e4b86885SCheng Sean Ye extern cmi_errno_t mcamd_unumtopa_wrap(void *, mc_unum_t *, nvlist_t *,
234e4b86885SCheng Sean Ye     uint64_t *);
235e4b86885SCheng Sean Ye 
236e4b86885SCheng Sean Ye /*
237e4b86885SCheng Sean Ye  * Internal functions
238e4b86885SCheng Sean Ye  */
239e4b86885SCheng Sean Ye cmi_errno_t mcamd_cmierr(int, mcamd_hdl_t *);
240e4b86885SCheng Sean Ye 
241e4b86885SCheng Sean Ye #ifdef __cplusplus
242e4b86885SCheng Sean Ye }
243e4b86885SCheng Sean Ye #endif
244e4b86885SCheng Sean Ye 
245e4b86885SCheng Sean Ye #endif /* _MCAMD_H */
246