shub_md.h 9.73 KB
Newer Older
1 2 3 4 5 6
/*
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
Jesse Barnes's avatar
Jesse Barnes committed
7
 * Copyright (c) 2001, 2002-2003 Silicon Graphics, Inc.  All rights reserved.
8 9
 */

David Mosberger's avatar
David Mosberger committed
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135

#ifndef _SHUB_MD_H
#define _SHUB_MD_H

/* SN2 supports a mostly-flat address space with 4 CPU-visible, evenly spaced, 
   contiguous regions, or "software banks".  On SN2, software bank n begins at 
   addresses n * 16GB, 0 <= n < 4.  Each bank has a 16GB address space.  If 
   the 4 dimms do not use up this space there will be holes between the 
   banks.  Even with these holes the whole memory space within a bank is
   not addressable address space.  The top 1/32 of each bank is directory
   memory space and is accessible through bist only.

   Physically a SN2 node board contains 2 daughter cards with 8 dimm sockets
   each.  A total of 16 dimm sockets arranged as 4 "DIMM banks" of 4 dimms 
   each.  The data is stripped across the 4 memory busses so all dimms within 
   a dimm bank must have identical capacity dimms.  Memory is increased or 
   decreased in sets of 4.  Each dimm bank has 2 dimms on each side.

             Physical Dimm Bank layout.
                  DTR Card0
                 ------------
   Dimm Bank 3   |  MemYL3  |   CS 3
                 |  MemXL3  |
                 |----------|
   Dimm Bank 2   |  MemYL2  |   CS 2
                 |  MemXL2  |
                 |----------|
   Dimm Bank 1   |  MemYL1  |   CS 1
                 |  MemXL1  |
                 |----------|
   Dimm Bank 0   |  MemYL0  |   CS 0 
                 |  MemXL0  |
                 ------------
                  |       |
                  BUS     BUS
                  XL      YL
                  |       |
                 ------------
                 |   SHUB   |
                 |    MD    |
                 ------------
                  |       |
                  BUS     BUS
                  XR      YR
                  |       |
                 ------------
   Dimm Bank 0   |  MemXR0  |   CS 0
                 |  MemYR0  |
                 |----------|
   Dimm Bank 1   |  MemXR1  |   CS 1
                 |  MemYR1  |
                 |----------|
   Dimm Bank 2   |  MemXR2  |   CS 2
                 |  MemYR2  |
                 |----------|
   Dimm Bank 3   |  MemXR3  |   CS 3
                 |  MemYR3  |
                 ------------
                  DTR Card1

   The dimms can be 1 or 2 sided dimms.  The size and bankness is defined  
   separately for each dimm bank in the sh_[x,y,jnr]_dimm_cfg MMR register.

   Normally software bank 0 would map directly to physical dimm bank 0.  The 
   software banks can map to the different physical dimm banks via the 
   DIMM[0-3]_CS field in SH_[x,y,jnr]_DIMM_CFG for each dimm slot.   

   All the PROM's data structures (promlog variables, klconfig, etc.)
   track memory by the physical dimm bank number.  The kernel usually
   tracks memory by the software bank number.

 */


/* Preprocessor macros */
#define MD_MEM_BANKS		4
#define MD_PHYS_BANKS_PER_DIMM  2                  /* dimms may be 2 sided. */
#define MD_NUM_PHYS_BANKS       (MD_MEM_BANKS * MD_PHYS_BANKS_PER_DIMM)
#define MD_DIMMS_IN_SLOT	4  /* 4 dimms in each dimm bank.  aka slot */

/* Address bits 35,34 control dimm bank access. */
#define MD_BANK_SHFT       	34     
#define MD_BANK_MASK       	(UINT64_CAST 0x3 << MD_BANK_SHFT )
#define MD_BANK_GET(addr)  	(((addr) & MD_BANK_MASK) >> MD_BANK_SHFT)
#define MD_BANK_SIZE       	(UINT64_CAST 0x1 << MD_BANK_SHFT ) /* 16 gb */
#define MD_BANK_OFFSET(_b) 	(UINT64_CAST (_b) << MD_BANK_SHFT)

/*Address bit 12 selects side of dimm if 2bnk dimms present. */
#define MD_PHYS_BANK_SEL_SHFT   12
#define MD_PHYS_BANK_SEL_MASK   (UINT64_CAST 0x1 << MD_PHYS_BANK_SEL_SHFT)

/* Address bit 7 determines if data resides on X or Y memory system. 
 * If addr Bit 7 is set the data resides on Y memory system and
 * the corresponing directory entry reside on the X. 
 */
#define MD_X_OR_Y_SEL_SHFT	7	
#define MD_X_OR_Y_SEL_MASK	(1 << MD_X_OR_Y_SEL_SHFT)	

/* Address bit 8 determines which directory entry of the pair the address
 * corresponds to.  If addr Bit 8 is set DirB corresponds to the memory address.
 */
#define MD_DIRA_OR_DIRB_SEL_SHFT	8
#define MD_DIRA_OR_DIRB_SEL_MASK  	(1 << MD_DIRA_OR_DIRB_SEL_SHFT)	

/* Address bit 11 determines if corresponding directory entry resides 
 * on Left or Right memory bus.  If addr Bit 11 is set the corresponding 
 * directory entry resides on Right memory bus.
 */
#define MD_L_OR_R_SEL_SHFT	11
#define MD_L_OR_R_SEL_MASK	(1 << MD_L_OR_R_SEL_SHFT)	

/* DRAM sizes. */
#define MD_SZ_64_Mb		0x0
#define MD_SZ_128_Mb		0x1
#define MD_SZ_256_Mb		0x2
#define MD_SZ_512_Mb		0x3
#define MD_SZ_1024_Mb		0x4
#define MD_SZ_2048_Mb	 	0x5
#define MD_SZ_UNUSED		0x7

#define MD_DIMM_SIZE_BYTES(_size, _2bk) (				 \
		( (_size) == 7 ? 0 : ( 0x4000000L << (_size)) << (_2bk)))\

#define MD_DIMM_SIZE_MBYTES(_size, _2bk) (				 \
	 	( (_size) == 7 ? 0 : ( 0x40L << (_size) ) << (_2bk)))  	 \

136
/* The top 1/32 of each bank is directory memory, and not accessible
David Mosberger's avatar
David Mosberger committed
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
 * via normal reads and writes */
#define MD_DIMM_USER_SIZE(_size)	((_size) * 31 / 32)

/* Minimum size of a populated bank is 64M (62M usable) */
#define MIN_BANK_SIZE		MD_DIMM_USER_SIZE((64 * 0x100000))
#define MIN_BANK_STRING		"62"


/*Possible values for FREQ field in sh_[x,y,jnr]_dimm_cfg regs */
#define MD_DIMM_100_CL2_0 	0x0
#define MD_DIMM_133_CL2_0 	0x1
#define MD_DIMM_133_CL2_5 	0x2
#define MD_DIMM_160_CL2_0 	0x3
#define MD_DIMM_160_CL2_5 	0x4
#define MD_DIMM_160_CL3_0 	0x5
#define MD_DIMM_200_CL2_0 	0x6
#define MD_DIMM_200_CL2_5 	0x7
#define MD_DIMM_200_CL3_0 	0x8

/* DIMM_CFG fields */
#define MD_DIMM_SHFT(_dimm)	((_dimm) << 3)
#define MD_DIMM_SIZE_MASK(_dimm)					\
		(SH_JNR_DIMM_CFG_DIMM0_SIZE_MASK << 			\
		(MD_DIMM_SHFT(_dimm)))

#define MD_DIMM_2BK_MASK(_dimm)						\
		(SH_JNR_DIMM_CFG_DIMM0_2BK_MASK << 			\
		MD_DIMM_SHFT(_dimm))

#define MD_DIMM_REV_MASK(_dimm)						\
		(SH_JNR_DIMM_CFG_DIMM0_REV_MASK << 			\
		MD_DIMM_SHFT(_dimm))

#define MD_DIMM_CS_MASK(_dimm)						\
		(SH_JNR_DIMM_CFG_DIMM0_CS_MASK << 			\
		MD_DIMM_SHFT(_dimm))

#define MD_DIMM_SIZE(_dimm, _cfg)					\
		(((_cfg) & MD_DIMM_SIZE_MASK(_dimm))			\
		>> (MD_DIMM_SHFT(_dimm)+SH_JNR_DIMM_CFG_DIMM0_SIZE_SHFT))

#define MD_DIMM_TWO_SIDED(_dimm,_cfg)					\
		( ((_cfg) & MD_DIMM_2BK_MASK(_dimm))			\
		>> (MD_DIMM_SHFT(_dimm)+SH_JNR_DIMM_CFG_DIMM0_2BK_SHFT))

#define MD_DIMM_REVERSED(_dimm,_cfg) 					\
		(((_cfg) & MD_DIMM_REV_MASK(_dimm))			\
		>> (MD_DIMM_SHFT(_dimm)+SH_JNR_DIMM_CFG_DIMM0_REV_SHFT))

#define MD_DIMM_CS(_dimm,_cfg)						\
		(((_cfg) & MD_DIMM_CS_MASK(_dimm))			\
		>> (MD_DIMM_SHFT(_dimm)+SH_JNR_DIMM_CFG_DIMM0_CS_SHFT))



/* Macros to set MMRs that must be set identically to others. */
#define MD_SET_DIMM_CFG(_n, _value) {					\
		REMOTE_HUB_S(_n, SH_X_DIMM_CFG,_value);			\
                REMOTE_HUB_S(_n, SH_Y_DIMM_CFG, _value);		\
                REMOTE_HUB_S(_n, SH_JNR_DIMM_CFG, _value);}

#define MD_SET_DQCT_CFG(_n, _value) {					\
		REMOTE_HUB_S(_n, SH_X_DQCT_CFG,_value);			\
		REMOTE_HUB_S(_n, SH_Y_DQCT_CFG,_value); }

#define MD_SET_CFG(_n, _value) {					\
		REMOTE_HUB_S(_n, SH_X_CFG,_value);			\
		REMOTE_HUB_S(_n, SH_Y_CFG,_value);} 

#define MD_SET_REFRESH_CONTROL(_n, _value) {				\
		REMOTE_HUB_S(_n, SH_X_REFRESH_CONTROL, _value);		\
		REMOTE_HUB_S(_n, SH_Y_REFRESH_CONTROL, _value);}

#define MD_SET_DQ_MMR_DIR_COFIG(_n, _value) {				\
		REMOTE_HUB_S(_n, SH_MD_DQLP_MMR_DIR_CONFIG, _value);	\
                REMOTE_HUB_S(_n, SH_MD_DQRP_MMR_DIR_CONFIG, _value);}

#define MD_SET_PIOWD_DIR_ENTRYS(_n, _value) {				\
		REMOTE_HUB_S(_n, SH_MD_DQLP_MMR_PIOWD_DIR_ENTRY, _value);\
		REMOTE_HUB_S(_n, SH_MD_DQRP_MMR_PIOWD_DIR_ENTRY, _value);}

/* 
 * There are 12 Node Presence MMRs, 4 in each primary DQ and 4 in the
 * LB.  The data in the left and right DQ MMRs and the LB must match.
 */
#define MD_SET_PRESENT_VEC(_n, _vec, _value) {				   \
		REMOTE_HUB_S(_n, SH_MD_DQLP_MMR_DIR_PRESVEC0+((_vec)*0x10),\
			 _value);					   \
		REMOTE_HUB_S(_n, SH_MD_DQRP_MMR_DIR_PRESVEC0+((_vec)*0x10),\
			 _value);					   \
		REMOTE_HUB_S(_n, SH_SHUBS_PRESENT0+((_vec)*0x80), _value);}
/*
 * There are 16 Privilege Vector MMRs, 8 in each primary DQ.  The data
 * in the corresponding left and right DQ MMRs must match.  Each MMR
 * pair is used for a single partition.
 */
#define MD_SET_PRI_VEC(_n, _vec, _value) {				  \
		REMOTE_HUB_S(_n, SH_MD_DQLP_MMR_DIR_PRIVEC0+((_vec)*0x10),\
			 _value);					  \
		REMOTE_HUB_S(_n, SH_MD_DQRP_MMR_DIR_PRIVEC0+((_vec)*0x10),\
			 _value);}
/*
 * There are 16 Local/Remote MMRs, 8 in each primary DQ.  The data in
 * the corresponding left and right DQ MMRs must match.  Each MMR pair
 * is used for a single partition.
 */
#define MD_SET_LOC_VEC(_n, _vec, _value) {				\
		REMOTE_HUB_S(_n, SH_MD_DQLP_MMR_DIR_LOCVEC0+((_vec)*0x10),\
			 _value);					\
		REMOTE_HUB_S(_n, SH_MD_DQRP_MMR_DIR_LOCVEC0+((_vec)*0x10),\
			 _value);}

/* Memory BIST CMDS */
#define MD_DIMM_INIT_MODE_SET	0x0
#define MD_DIMM_INIT_REFRESH	0x1
#define MD_DIMM_INIT_PRECHARGE	0x2
#define MD_DIMM_INIT_BURST_TERM	0x6
#define MD_DIMM_INIT_NOP	0x7
#define MD_DIMM_BIST_READ	0x10
#define MD_FILL_DIR		0x20
#define MD_FILL_DATA		0x30
#define MD_FILL_DIR_ACCESS	0X40
#define MD_READ_DIR_PAIR	0x50
#define MD_READ_DIR_TAG		0x60

/* SH_MMRBIST_CTL macros */
#define MD_BIST_FAIL(_n) (REMOTE_HUB_L(_n, SH_MMRBIST_CTL) &		\
                SH_MMRBIST_CTL_FAIL_MASK)

#define MD_BIST_IN_PROGRESS(_n) (REMOTE_HUB_L(_n, SH_MMRBIST_CTL) & 	\
                SH_MMRBIST_CTL_IN_PROGRESS_MASK)

#define MD_BIST_MEM_IDLE(_n); (REMOTE_HUB_L(_n, SH_MMRBIST_CTL) & 	\
                SH_MMRBIST_CTL_MEM_IDLE_MASK)

/* SH_MMRBIST_ERR macros */
#define MD_BIST_MISCOMPARE(_n) (REMOTE_HUB_L(_n, SH_MMRBIST_ERR) &	\
		SH_MMRBIST_ERR_DETECTED_MASK)

#endif	/* _SHUB_MD_H */