xref: /titanic_52/usr/src/common/mc/mc-amd/mcamd_api.h (revision 4156fc34b973159b0334e05ae5ec19344487bdc0)
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 /*
237aec1d6eScindi  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
247aec1d6eScindi  * Use is subject to license terms.
257aec1d6eScindi  */
267aec1d6eScindi 
277aec1d6eScindi #ifndef _MCAMD_API_H
287aec1d6eScindi #define	_MCAMD_API_H
297aec1d6eScindi 
307aec1d6eScindi #pragma ident	"%Z%%M%	%I%	%E% SMI"
317aec1d6eScindi 
327aec1d6eScindi /*
337aec1d6eScindi  * Primary header file for mcamd_* routines in $SRC/common/mc.  The
347aec1d6eScindi  * routines not implemented there are required to be implemented in the
357aec1d6eScindi  * kernel or userland consumer of this interface (such as the mc-amd driver).
367aec1d6eScindi  * The common code must use the wrapper functions provided by the consumer
377aec1d6eScindi  * to navigate the MC tree, get properties etc.
387aec1d6eScindi  */
397aec1d6eScindi 
407aec1d6eScindi #if defined(_KERNEL)
417aec1d6eScindi #include <sys/systm.h>
427aec1d6eScindi #include <sys/sunddi.h>
437aec1d6eScindi #else
447aec1d6eScindi #include <string.h>
457aec1d6eScindi #include <assert.h>
467aec1d6eScindi #endif
477aec1d6eScindi 
487aec1d6eScindi #include <sys/types.h>
497aec1d6eScindi #include <sys/mc.h>
507aec1d6eScindi #include <sys/mca_amd.h>
517aec1d6eScindi #include <sys/mc_amd.h>
527aec1d6eScindi 
537aec1d6eScindi #ifdef __cplusplus
547aec1d6eScindi extern "C" {
557aec1d6eScindi #endif
567aec1d6eScindi 
577aec1d6eScindi /*
587aec1d6eScindi  * Consumers of this common code must implement the following types.
597aec1d6eScindi  */
607aec1d6eScindi typedef struct mcamd_node mcamd_node_t;
617aec1d6eScindi struct mcamd_hdl;
627aec1d6eScindi 
637aec1d6eScindi /*
648a40a695Sgavinm  * Properties and raw register values for an mcamd_node_t are retrieved via
658a40a695Sgavinm  * mcamd_get_numprop(s) and mcamd_get_cfgreg(s) specifying a property or
668a40a695Sgavinm  * register code below.
677aec1d6eScindi  */
687aec1d6eScindi 
698a40a695Sgavinm typedef uint64_t mcamd_prop_t;
708a40a695Sgavinm typedef uint32_t mcamd_cfgreg_t;
717aec1d6eScindi 
728a40a695Sgavinm typedef enum mcamd_propcode {
738a40a695Sgavinm 	/*
748a40a695Sgavinm 	 * Common properties
758a40a695Sgavinm 	 */
768a40a695Sgavinm 	MCAMD_PROP_NUM = 0x4000,
777aec1d6eScindi #define	MCAMD_PROPSTR_NUM		"num"
788a40a695Sgavinm 	MCAMD_PROP_SIZE,
797aec1d6eScindi #define	MCAMD_PROPSTR_SIZE		"size"
808a40a695Sgavinm 	MCAMD_PROP_BASE_ADDR,
818a40a695Sgavinm #define	MCAMD_PROPSTR_BASE_ADDR		"base-addr"
828a40a695Sgavinm 	/*
838a40a695Sgavinm 	 * Memory controller properties
848a40a695Sgavinm 	 */
858a40a695Sgavinm 	MCAMD_PROP_REV = 0x5000,
867aec1d6eScindi #define	MCAMD_PROPSTR_REV		"revision"
878a40a695Sgavinm 	MCAMD_PROP_LIM_ADDR,
888a40a695Sgavinm #define	MCAMD_PROPSTR_LIM_ADDR		"lim-addr"
898a40a695Sgavinm 	MCAMD_PROP_ILEN,
908a40a695Sgavinm #define	MCAMD_PROPSTR_ILEN		"node-ilen"
918a40a695Sgavinm 	MCAMD_PROP_ILSEL,
928a40a695Sgavinm #define	MCAMD_PROPSTR_ILSEL		"node-ilsel"
938a40a695Sgavinm 	MCAMD_PROP_CSINTLVFCTR,
948a40a695Sgavinm #define	MCAMD_PROPSTR_CSINTLVFCTR	"cs-intlv-factor"
958a40a695Sgavinm 	MCAMD_PROP_DRAMHOLE_SIZE,
968a40a695Sgavinm #define	MCAMD_PROPSTR_DRAMHOLE_SIZE	"dram-hole-size"
978a40a695Sgavinm 	MCAMD_PROP_ACCESS_WIDTH,
988a40a695Sgavinm #define	MCAMD_PROPSTR_ACCESS_WIDTH	"access-width"
998a40a695Sgavinm 	MCAMD_PROP_CSBANKMAPREG,
1008a40a695Sgavinm #define	MCAMD_PROPSTR_CSBANKMAPREG	"bank-mapping"
1018a40a695Sgavinm 	MCAMD_PROP_BANKSWZL,
1028a40a695Sgavinm #define	MCAMD_PROPSTR_BANKSWZL		"bankswizzle"
1038a40a695Sgavinm 	MCAMD_PROP_MOD64MUX,
1048a40a695Sgavinm #define	MCAMD_PROPSTR_MOD64MUX		"mismatched-dimm-support"
1058a40a695Sgavinm 	MCAMD_PROP_SPARECS,
1068a40a695Sgavinm #define	MCAMD_PROPSTR_SPARECS		"spare-csnum"
1078a40a695Sgavinm 	MCAMD_PROP_BADCS,
1088a40a695Sgavinm #define	MCAMD_PROPSTR_BADCS		"bad-csnum"
1098a40a695Sgavinm 	/*
1108a40a695Sgavinm 	 * Chip-select properties
1118a40a695Sgavinm 	 */
1128a40a695Sgavinm 	MCAMD_PROP_MASK = 0x6000,
1138a40a695Sgavinm #define	MCAMD_PROPSTR_MASK		"mask"
1148a40a695Sgavinm 	MCAMD_PROP_CSBE,
1158a40a695Sgavinm #define	MCAMD_PROPSTR_CSBE		"cs-bank-enable"
1168a40a695Sgavinm 	MCAMD_PROP_SPARE,
1178a40a695Sgavinm #define	MCAMD_PROPSTR_SPARE		"online-spare"
1188a40a695Sgavinm 	MCAMD_PROP_TESTFAIL,
1198a40a695Sgavinm #define	MCAMD_PROPSTR_TESTFAIL		"failed-test"
1208a40a695Sgavinm 	MCAMD_PROP_CSDIMM1,
1218a40a695Sgavinm #define	MCAMD_PROPSTR_CSDIMM1		"dimm1-num"
1228a40a695Sgavinm 	MCAMD_PROP_CSDIMM2,
1238a40a695Sgavinm #define	MCAMD_PROPSTR_CSDIMM2		"dimm2-num"
1248a40a695Sgavinm 	MCAMD_PROP_DIMMRANK
1258a40a695Sgavinm #define	MCAMD_PROPSTR_DIMMRANK		"dimm-rank"
1268a40a695Sgavinm } mcamd_propcode_t;
1277aec1d6eScindi 
1288a40a695Sgavinm typedef enum mcamd_regcode {
1298a40a695Sgavinm 	MCAMD_REG_DRAMBASE = 0x7000,
1308a40a695Sgavinm 	MCAMD_REG_DRAMLIMIT,
1318a40a695Sgavinm 	MCAMD_REG_DRAMHOLE,
1328a40a695Sgavinm 	MCAMD_REG_DRAMCFGLO,
1338a40a695Sgavinm 	MCAMD_REG_DRAMCFGHI,
1348a40a695Sgavinm 	MCAMD_REG_CSBASE,
1358a40a695Sgavinm 	MCAMD_REG_CSMASK
1368a40a695Sgavinm } mcamd_regcode_t;
1377aec1d6eScindi /*
1387aec1d6eScindi  * Flags for mcamd_dprintf
1397aec1d6eScindi  */
1407aec1d6eScindi #define	MCAMD_DBG_ERR		0x1
1417aec1d6eScindi #define	MCAMD_DBG_FLOW		0x2
1427aec1d6eScindi 
1437aec1d6eScindi typedef union mcamd_dimm_offset_un mcamd_dimm_offset_un_t;
1447aec1d6eScindi 
1457aec1d6eScindi /*
1467aec1d6eScindi  * Offset definition.  Encode everything in a single uint64_t, allowing some
1477aec1d6eScindi  * room for growth in numbers of rows/columns/banks in future MC revisions.
1487aec1d6eScindi  * Some consumers will handle this as an opaque uint64 to be passed around,
1498a40a695Sgavinm  * while others will want to look inside via the union defined below.  Since
1508a40a695Sgavinm  * we must support a 32-bit kernel we structure this as two uint32_t.
1517aec1d6eScindi  */
1527aec1d6eScindi 
1537aec1d6eScindi #define	MCAMD_OFFSET_VERSION_0			0x0
1547aec1d6eScindi #define	MCAMD_OFFSET_VERSION			MCAMD_OFFSET_VERSION_0
1557aec1d6eScindi 
1567aec1d6eScindi union mcamd_dimm_offset_un {
1577aec1d6eScindi 	uint64_t _dou_offset;
1587aec1d6eScindi 	struct {
1597aec1d6eScindi 		struct {
1607aec1d6eScindi 			uint32_t dou_col:20;	/* column address */
1617aec1d6eScindi 			uint32_t dou_bank:4;	/* internal sdram bank number */
1627aec1d6eScindi 			uint32_t unused:8;
1637aec1d6eScindi 		} lo;
1647aec1d6eScindi 		struct {
1657aec1d6eScindi 			uint32_t dou_row:20;	/* row address */
1667aec1d6eScindi 			uint32_t dou_rank:3;	/* cs rank on dimm */
1677aec1d6eScindi 			uint32_t unused:4;
1687aec1d6eScindi 			uint32_t dou_version:4;	/* offset encoding version */
1697aec1d6eScindi 			uint32_t dou_valid:1;	/* set if valid */
1707aec1d6eScindi 		} hi;
1717aec1d6eScindi 	} _dou_hilo;
1727aec1d6eScindi };
1737aec1d6eScindi 
1747aec1d6eScindi #define	do_offset  _dou_offset
1757aec1d6eScindi 
1767aec1d6eScindi #define	do_valid _dou_hilo.hi.dou_valid
1777aec1d6eScindi #define	do_version _dou_hilo.hi.dou_version
1787aec1d6eScindi #define	do_rank _dou_hilo.hi.dou_rank
1797aec1d6eScindi #define	do_row _dou_hilo.hi.dou_row
1807aec1d6eScindi #define	do_bank _dou_hilo.lo.dou_bank
1817aec1d6eScindi #define	do_col _dou_hilo.lo.dou_col
1827aec1d6eScindi 
1837aec1d6eScindi /*
1847aec1d6eScindi  * The following work on an offset treated as a uint64_t.
1857aec1d6eScindi  */
1867aec1d6eScindi #define	MCAMD_RC_OFFSET_VALID(offset) (((uint64_t)(offset) & (1ULL << 63)) != 0)
1877aec1d6eScindi #define	MCAMD_RC_OFFSET_VERSION(offset) (((uint64_t)offset >> 59) & 0xf)
1887aec1d6eScindi 
1897aec1d6eScindi /*
1907aec1d6eScindi  * Value to be used to indicate an invalid offset.
1917aec1d6eScindi  */
1927aec1d6eScindi #define	MCAMD_RC_INVALID_OFFSET 0x0
1937aec1d6eScindi 
1947aec1d6eScindi /*
1957aec1d6eScindi  * Routines provided by the common mcamd code.
1967aec1d6eScindi  */
1978a40a695Sgavinm extern const char *mcamd_get_propname(mcamd_propcode_t);
1987aec1d6eScindi 
1997aec1d6eScindi extern int mcamd_patounum(struct mcamd_hdl *, mcamd_node_t *, uint64_t,
200*4156fc34Sgavinm     uint8_t, uint8_t, uint32_t, int, mc_unum_t *);
2018a40a695Sgavinm extern int mcamd_unumtopa(struct mcamd_hdl *, mcamd_node_t *, mc_unum_t *,
2027aec1d6eScindi     uint64_t *);
2038a40a695Sgavinm extern int mc_pa_to_offset(struct mcamd_hdl *, mcamd_node_t *, mcamd_node_t *,
2048a40a695Sgavinm     uint64_t, uint64_t *);
2058a40a695Sgavinm extern int mc_offset_to_pa(struct mcamd_hdl *, mcamd_node_t *, mcamd_node_t *,
2068a40a695Sgavinm     uint64_t, uint64_t *);
2077aec1d6eScindi 
2087aec1d6eScindi extern int mcamd_cs_size(struct mcamd_hdl *, mcamd_node_t *, int, size_t *);
2097aec1d6eScindi 
2107aec1d6eScindi extern int mcamd_synd_validate(struct mcamd_hdl *, uint32_t, int);
2117aec1d6eScindi extern int mcamd_eccsynd_decode(struct mcamd_hdl *, uint32_t, uint_t *);
2127aec1d6eScindi extern int mcamd_cksynd_decode(struct mcamd_hdl *, uint32_t, uint_t *,
2137aec1d6eScindi     uint_t *);
2147aec1d6eScindi extern int mcamd_cksym_decode(struct mcamd_hdl *, uint_t, int *, int *,
2157aec1d6eScindi     int *, int *);
2167aec1d6eScindi 
2177aec1d6eScindi extern void *mcamd_set_errno_ptr(struct mcamd_hdl *, int);
2187aec1d6eScindi extern const char *mcamd_strerror(int);
2197aec1d6eScindi extern const char *mcamd_errmsg(struct mcamd_hdl *);
2207aec1d6eScindi 
2217aec1d6eScindi /*
2227aec1d6eScindi  * Routines to be provided by wrapper code.
2237aec1d6eScindi  */
2247aec1d6eScindi extern mcamd_node_t *mcamd_mc_next(struct mcamd_hdl *, mcamd_node_t *,
2257aec1d6eScindi     mcamd_node_t *);
2267aec1d6eScindi extern mcamd_node_t *mcamd_cs_next(struct mcamd_hdl *, mcamd_node_t *,
2277aec1d6eScindi     mcamd_node_t *);
2287aec1d6eScindi extern mcamd_node_t *mcamd_dimm_next(struct mcamd_hdl *, mcamd_node_t *,
2297aec1d6eScindi     mcamd_node_t *);
2307aec1d6eScindi 
2317aec1d6eScindi extern mcamd_node_t *mcamd_cs_mc(struct mcamd_hdl *, mcamd_node_t *);
2327aec1d6eScindi extern mcamd_node_t *mcamd_dimm_mc(struct mcamd_hdl *, mcamd_node_t *);
2337aec1d6eScindi 
2348a40a695Sgavinm extern int mcamd_get_numprop(struct mcamd_hdl *, mcamd_node_t *,
2358a40a695Sgavinm     mcamd_propcode_t, mcamd_prop_t *);
2368a40a695Sgavinm extern int mcamd_get_numprops(struct mcamd_hdl *, ...);
2378a40a695Sgavinm extern int mcamd_get_cfgreg(struct mcamd_hdl *, mcamd_node_t *,
2388a40a695Sgavinm     mcamd_regcode_t, mcamd_cfgreg_t *);
2398a40a695Sgavinm extern int mcamd_get_cfgregs(struct mcamd_hdl *, ...);
2407aec1d6eScindi 
2417aec1d6eScindi extern int mcamd_errno(struct mcamd_hdl *);
2427aec1d6eScindi extern int mcamd_set_errno(struct mcamd_hdl *, int);
2437aec1d6eScindi extern void mcamd_dprintf(struct mcamd_hdl *, int, const char *, ...);
2447aec1d6eScindi 
2457aec1d6eScindi #ifdef __cplusplus
2467aec1d6eScindi }
2477aec1d6eScindi #endif
2487aec1d6eScindi 
2497aec1d6eScindi #endif /* _MCAMD_API_H */
250