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