1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  *
22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef _MCAMD_ROWCOL_IMPL_H
27 #define	_MCAMD_ROWCOL_IMPL_H
28 
29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30 
31 #include <mcamd_api.h>
32 #include <sys/mc_amd.h>
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 #define	MC_PC_COLADDRBIT	10	/* col address bit used for precharge */
39 #define	MC_PC_ALL		-1	/* marker used in tables */
40 
41 #define	MC_CS_SCALE		(1024 * 1024)
42 #define	MC_CS_SIZE(bam, width) \
43 	((size_t)bam->bam_sizemb * MC_CS_SCALE * ((width) == 128 ? 2 : 1))
44 
45 #define	MC_CS_MODE(csbmap, csnum) \
46 	(csbmap >> MC_CHIP_DIMMPAIR(csnum) * MC_DC_BAM_CSBANK_SHIFT & \
47 	MC_DC_BAM_CSBANK_MASK)
48 
49 #define	BIT(val, num) ((val) & 1ULL << num)
50 
51 #define	BITS(val, high, low) \
52 	((val) & (((2ULL << (high)) - 1) & ~((1ULL << (low)) - 1)))
53 
54 #define	SETBIT(var, num) (var |= (1ULL << (num)))
55 
56 #define	BITVAL(var, num) ((BIT(var, num) >> (num)) & 1ULL)
57 
58 #define	MC_RC_ROW_MAX	14	/* maximum number of row address bits */
59 #define	MC_RC_COL_MAX	12	/* maximum number of col address bits */
60 #define	MC_RC_BANKBITS	2	/* number of internal banksel bits */
61 #define	MC_RC_BANKARGS	3	/* bits used for 1 banksel bit */
62 #define	MC_RC_CSMODES	16	/* max number of cs bankaddr modes */
63 
64 /*
65  * Row, column and bank mapping is derived after allowing for interleave
66  * from the normalized dram address through the tables of BKDG 3.29
67  * section 3.5.6.1.  We have tables for:
68  *
69  *	. rev CG and earlier, 64-bit MC mode
70  *	. rev CG and earlier, 128-bit MC mode
71  *	. rev D and later, 64-bit MC mode (no bank swizzling if rev E)
72  *	. rev D and later, 128-bit MC mode (no bank swizzling if rev E)
73  *	. rev E and later, 64-bit MC mode with bank swizzling
74  *	. rev E and later, 128-bit MC mode with bank swizzling
75  *
76  * Each table is indexed by CS Mode (equivalently, CS size) and tells us
77  * which bits of the normalized dram address (i.e., the address modified for
78  * the local MC base address and with node interleave selection bits removed)
79  * to use in forming the column address, row address and internal bank
80  * selection.
81  *
82  * Note that for rev CG and earlier there is some overloading of CS mode
83  * encoding such that we do not know the number of row and column address
84  * bits from the CS mode alone, e.g., for 128MB DIMM modules we may have
85  * 13 row bits and 9 column, or 12 row and 10 column.  In these case the
86  * tables held in the structures defined below will have a duplicated bit
87  * number in the row and column bits.  In these ambiguous cases cm_rc_ambig
88  * should be set in the table.
89  */
90 
91 struct bankaddr_mode {
92 	int bam_sizemb;			/* DIMM size in MB */
93 	int bam_nrows;			/* number of row address bits */
94 	int bam_ncols;			/* number of column address bits */
95 	int bam_ambig;			/* numbers are maximums; keep last */
96 };
97 
98 struct csrcb_map {
99 	int csrcb_bankargs[MC_RC_BANKBITS][MC_RC_BANKARGS];
100 	int csrcb_rowbits[MC_RC_ROW_MAX];
101 	int csrcb_colbits[MC_RC_COL_MAX + 1];	/* one for MC_PC_ALL */
102 };
103 
104 struct csrcb_map_tbl {
105 	int mt_rev;			/* revision to which this applies */
106 	int mt_width;			/* MC mode (64 or 128) */
107 	struct csrcb_map mt_csmap[MC_RC_CSMODES];
108 };
109 
110 struct csintlv_desc {
111 	int csi_factor;			/* cs interleave factor */
112 	int csi_hibit;			/* first non-offset bit in addr */
113 	int csi_lobit;			/* first row bit in addr */
114 	int csi_nbits;			/* number of bits to swap in mask */
115 };
116 
117 #define	MC_RC_CSI_SWAPPED_BIT(csidp, n)				\
118 	(csidp->csi_factor && n >= csidp->csi_lobit &&		\
119 	n <= csidp->csi_lobit + csidp->csi_nbits - 1)
120 
121 #define	MC_RC_CSI_BITSWAP(csidp, n)				\
122 	(csidp->csi_hibit + n - csidp->csi_lobit)
123 
124 extern const struct bankaddr_mode *rct_bankaddr_mode(uint_t, uint_t);
125 extern const struct csrcb_map *rct_rcbmap(uint_t, int, uint_t);
126 extern void rct_csintlv_bits(uint_t, int, uint_t, int, struct csintlv_desc *);
127 
128 #ifdef __cplusplus
129 }
130 #endif
131 
132 #endif /* _MCAMD_ROWCOL_IMPL_H */
133