xref: /illumos-gate/usr/src/common/mc/mc-amd/mcamd_rowcol_tbl.c (revision 5422785d352a2bb398daceab3d1898a8aa64d006)
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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  *
24  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 #pragma ident	"%Z%%M%	%I%	%E% SMI"
29 
30 #include <mcamd_api.h>
31 #include <mcamd_err.h>
32 #include <mcamd_rowcol_impl.h>
33 
34 /*
35  * =========== Chip-Select Bank Address Mode Encodings =======================
36  */
37 
38 /* Individual table declarations */
39 static const struct rct_bnkaddrmode bnkaddr_tbls_pre_d[];
40 static const struct rct_bnkaddrmode bnkaddr_tbls_d_e[];
41 static const struct rct_bnkaddrmode bnkaddr_tbls_f[];
42 
43 /* Managing bank address mode tables */
44 static const struct _bnkaddrmode_tbldesc {
45 	uint_t	revmask;
46 	int	nmodes;
47 	const struct rct_bnkaddrmode *modetbl;
48 } bnkaddr_tbls[] = {
49 	{ MC_F_REVS_BC, 7, bnkaddr_tbls_pre_d },
50 	{ MC_F_REVS_DE, 11, bnkaddr_tbls_d_e },
51 	{ MC_F_REVS_FG, 12, bnkaddr_tbls_f },
52 };
53 
54 /*
55  * =========== DRAM Address Mappings for bank/row/column =====================
56  */
57 
58 
59 /* Individual table declarations */
60 struct _rcbmap_tbl {
61 	uint_t mt_revmask;		/* revision to which this applies */
62 	int mt_width;			/* MC mode (64 or 128) */
63 	const struct rct_rcbmap mt_csmap[MC_RC_CSMODES];
64 };
65 
66 static const struct _rcbmap_tbl dram_addrmap_pre_d_64;
67 static const struct _rcbmap_tbl dram_addrmap_pre_d_128;
68 static const struct _rcbmap_tbl dram_addrmap_d_e_64;
69 static const struct _rcbmap_tbl dram_addrmap_d_e_128;
70 static const struct _rcbmap_tbl dram_addrmap_f_64;
71 static const struct _rcbmap_tbl dram_addrmap_f_128;
72 
73 /* Managing row/column/bank tables */
74 static const struct _rcbmap_tbldesc {
75 	int nmodes;
76 	const struct _rcbmap_tbl *rcbmap;
77 } rcbmap_tbls[] = {
78 	{ 7, &dram_addrmap_pre_d_64 },
79 	{ 7, &dram_addrmap_pre_d_128 },
80 	{ 11, &dram_addrmap_d_e_64 },
81 	{ 11, &dram_addrmap_d_e_128 },
82 	{ 12, &dram_addrmap_f_64 },
83 	{ 12, &dram_addrmap_f_128 },
84 };
85 
86 /*
87  * =========== Bank swizzling information ====================================
88  */
89 
90 /* Individual table declarations */
91 struct _bnkswzl_tbl {
92 	uint_t swzt_revmask;		/* revision to which this applies */
93 	int swzt_width;			/* MC mode (64 or 128) */
94 	const struct rct_bnkswzlinfo swzt_bits;
95 };
96 
97 static const struct _bnkswzl_tbl bnswzl_info_e_64;
98 static const struct _bnkswzl_tbl bnswzl_info_e_128;
99 static const struct _bnkswzl_tbl bnswzl_info_f_64;
100 static const struct _bnkswzl_tbl bnswzl_info_f_128;
101 
102 /* Managing bank swizzle tables */
103 static const struct _bnkswzl_tbl *bnkswzl_tbls[] = {
104 	&bnswzl_info_e_64,
105 	&bnswzl_info_e_128,
106 	&bnswzl_info_f_64,
107 	&bnswzl_info_f_128,
108 };
109 
110 /*
111  * ======================================================================
112  * | Tables reflecting those in the BKDG				|
113  * ======================================================================
114  */
115 
116 /*
117  * DRAM Address Mapping in Interleaving Mode
118  *
119  * Chip-select interleave is performed by addressing across the columns
120  * of the first row of internal bank-select 0 on a chip-select, then the
121  * next row on internal bank-select 1, then 2 then 3;  instead of then
122  * moving on to the next row of this chip-select we then rotate across
123  * other chip-selects in the interleave.  The row/column/bank mappings
124  * described elsewhere in this file show that a DRAM InputAddr breaks down
125  * as follows, using an example for CS Mode 0000 revision CG and earlier 64-bit
126  * mode; the cs size is 32MB, requiring 25 bits to address all of it.
127  *
128  * chip-selection bits |    offset within chip-select bits      |
129  *		       | row bits | bank bits | column bits | - |
130  *                      24      13 12       11 10          3 2 0
131  *
132  * The high-order chip-selection bits select the chip-select and the
133  * offset bits offset within the chosen chip-select.
134  *
135  * To establish say a 2-way interleave in which we consume all of one
136  * row number and all internal bank numbers on one cs before moving on
137  * to the next to do the same we will target the first row bit - bit 13;
138  * a 4-way interleave would use bits 14 and 13, and an 8-way interleave
139  * bits 15, 14 and 13.  We swap the chosen bits with the least significant
140  * high order chip-selection bits.
141  *
142  * The BKDG interleave tables really just describe the above.  Working
143  * out the high-order bits to swap is easy since that is derived directly
144  * from the chip-select size.  The low-order bits depend on the device
145  * parameters since we need to target the least significant row address bits -
146  * but we have that information from the rcbmap_tbls since the first row bit
147  * simply follows the last bank address bit.
148  */
149 
150 /*
151  * General notes for CS Bank Address Mode Encoding tables.
152  *
153  * These are indexed by chip-select mode.  Where the numbers of rows and
154  * columns is ambiguous (as it is for a number of rev CG and earlier cases)
155  * the bam_config should be initialized to 1 and the numbers of rows
156  * and columns should be the maximums.
157  */
158 
159 /*
160  * Chip Select Bank Address Mode Encoding for rev CG and earlier.
161  */
162 static const struct rct_bnkaddrmode bnkaddr_tbls_pre_d[] = {
163 	{	/* 000 */
164 		32, 12, 8
165 	},
166 	{	/* 001 */
167 		64, 12, 9
168 	},
169 	{	/* 010 */
170 		128, 13, 10, 1	/* AMBIG */
171 	},
172 	{	/* 011 */
173 		256, 13, 11, 1	/* AMBIG */
174 	},
175 	{	/* 100 */
176 		512, 14, 11, 1	/* AMBIG */
177 	},
178 	{	/* 101 */
179 		1024, 14, 12, 1	/* AMBIG */
180 	},
181 	{	/* 110 */
182 		2048, 14, 12
183 	}
184 };
185 
186 /*
187  * Chip Select Bank Address Mode Encoding for revs D and E.
188  */
189 static const struct rct_bnkaddrmode bnkaddr_tbls_d_e[] = {
190 	{	/* 0000 */
191 		32, 12, 8
192 	},
193 	{	/* 0001 */
194 		64, 12, 9
195 	},
196 	{	/* 0010 */
197 		128, 13, 9
198 	},
199 	{	/* 0011 */
200 		128, 12, 10
201 	},
202 	{	/* 0100 */
203 		256, 13, 10
204 	},
205 	{	/* 0101 */
206 		512, 14, 10
207 	},
208 	{	/* 0110 */
209 		256, 12, 11
210 	},
211 	{	/* 0111 */
212 		512, 13, 11
213 	},
214 	{	/* 1000 */
215 		1024, 14, 11
216 	},
217 	{	/* 1001 */
218 		1024, 13, 12
219 	},
220 	{	/* 1010 */
221 		2048, 14, 12
222 	}
223 };
224 
225 /*
226  * Chip Select Bank Address Mode Encoding for rev F
227  */
228 static const struct rct_bnkaddrmode bnkaddr_tbls_f[] = {
229 	{	/* 0000 */
230 		128, 13, 9
231 	},
232 	{	/* 0001 */
233 		256, 13, 10
234 	},
235 	{	/* 0010 */
236 		512, 14, 10
237 	},
238 	{	/* 0011 */
239 		512, 13, 11
240 	},
241 	{	/* 0100 */
242 		512, 13, 10
243 	},
244 	{	/* 0101 */
245 		1024, 14, 10
246 	},
247 	{	/* 0110 */
248 		1024, 14, 11
249 	},
250 	{	/* 0111 */
251 		2048, 15, 10
252 	},
253 	{	/* 1000 */
254 		2048, 14, 11
255 	},
256 	{	/* 1001 */
257 		4096, 15, 11
258 	},
259 	{	/* 1010 */
260 		4096, 16, 10
261 	},
262 	{	/* 1011 */
263 		8192, 16, 11
264 	}
265 
266 };
267 
268 /*
269  * General notes on Row/Column/Bank table initialisation.
270  *
271  * These are the tables 7, 8, 9, 10, 11 and 12 of BKDG 3.29 section 3.5.6.1.
272  * They apply in non-interleave (node or cs) mode and describe how for
273  * a given revision, access width, bank-swizzle mode, and current chip-select
274  * mode the row, column and internal sdram bank are derived from the
275  * normalizied InputAddr presented to the DRAM controller.
276  *
277  * The mt_csmap array is indexed by chip-select mode.  Within it the
278  * bankargs, rowbits and colbits arrays are indexed by bit number, so
279  * match the BKDG tables if the latter are read right-to-left.
280  *
281  * The bankargs list up to three bit numbers per bank bit.  For revisions
282  * CG and earlier there is no bank swizzling, so just a single number
283  * should be listed.  Revisions D and E have the same row/column/bank mapping,
284  * but rev E has the additional feature of being able to xor two row bits
285  * into each bank bit.  The consumer will know whether they are using bank
286  * swizzling - if so then they should xor the bankargs bits together.
287  * The first argument must be the bit number not already used in forming
288  * part of the row address - eg in table 12 for csmode 0000b bank address
289  * bit 0 is bit 12 xor bit 18 xor bit 21, and 18 and 21 are also mentioned in
290  * the row address (bits 10 and 1) so we must list bit 12 first.  We will
291  * use this information in chip-select interleave decoding in which we need
292  * to know which is the first bit after column and bank address bits.
293  *
294  * Column address A10 is always used for the Precharge All signal.  Where
295  * "PC" appears in the BKDG tables we will include MC_PC_ALL in the
296  * corresponding bit position.
297  *
298  * For some rev CG and earlier chipselect modes the number of rows and columns
299  * is ambiguous.  This is reflected in these tables by some bit being
300  * duplicated between row and column address.  In practice we will follow
301  * the convention of always assigning the floating bit to the row address.
302  */
303 
304 /*
305  * Row/Column/Bank address mappings for rev CG in 64-bit mode, no interleave.
306  * See BKDG 3.29 3.5.6 Table 7.
307  */
308 static const struct _rcbmap_tbl dram_addrmap_pre_d_64 = {
309 	MC_F_REVS_BC,
310 	64,
311 	{
312 	{   /* 000 */
313 	    2, { 11, 12 },
314 	    { 19, 20, 21, 22, 23, 24, 13, 14, 15, 16, 17, 18 },
315 	    { 3, 4, 5, 6, 7, 8, 9, 10 }
316 	},
317 	{   /* 001 */
318 	    2, { 13, 12 },
319 	    { 19, 20, 21, 22, 23, 24, 25, 14, 15, 16, 17, 18 },
320 	    { 3, 4, 5, 6, 7, 8, 9, 10, 11 }
321 	},
322 	{   /* 010 */
323 	    2, { 13, 12 },
324 	    { 19, 20, 21, 22, 23, 24, 25, 14, 15, 16, 17, 18, 26 },
325 	    { 3, 4, 5, 6, 7, 8, 9, 10, 11, 26 }
326 	},
327 	{   /* 011 */
328 	    2, { 13, 14 },
329 	    { 19, 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 27 },
330 	    { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 27 }
331 	},
332 	{   /* 100 */
333 	    2, { 13, 14 },
334 	    { 19, 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 27, 28 },
335 	    { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 28 }
336 	},
337 	{   /* 101 */
338 	    2, { 15, 14 },
339 	    { 19, 20, 21, 22, 23, 24, 25, 26, 29, 16, 17, 18, 27, 28 },
340 	    { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13, 28 }
341 	},
342 	{   /* 110 */
343 	    2, { 15, 14 },
344 	    { 19, 20, 21, 22, 23, 24, 25, 26, 29, 16, 17, 18, 27, 28 },
345 	    { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13, 30 }
346 	},
347 	/*
348 	 * remainder unused
349 	 */
350 	}
351 
352 };
353 
354 /*
355  * Row/Column/Bank address mappings for rev CG in 128-bit mode, no interleave.
356  * See BKDG 3.29 3.5.6 Table 8.
357  */
358 static const struct _rcbmap_tbl dram_addrmap_pre_d_128 = {
359 	MC_F_REVS_BC,
360 	128,
361 	{
362 	{   /* 000 */
363 	    2, { 12, 13 },
364 	    { 20, 21, 22, 23, 24, 25, 14, 15, 16, 17, 18, 19 },
365 	    { 4, 5, 6, 7, 8, 9, 10, 11 }
366 	},
367 	{   /* 001 */
368 	    2, { 14, 13 },
369 	    { 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 19 },
370 	    { 4, 5, 6, 7, 8, 9, 10, 11, 12 }
371 	},
372 	{   /* 010 */
373 	    2, { 14, 13 },
374 	    { 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 19, 27 },
375 	    { 4, 5, 6, 7, 8, 9, 10, 11, 12, 27 }
376 	},
377 	{   /* 011 */
378 	    2, { 14, 15 },
379 	    { 20, 21, 22, 23, 24, 25, 26, 27, 16, 17, 18, 19, 28 },
380 	    { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 28 }
381 	},
382 	{   /* 100 */
383 	    2, { 14, 15 },
384 	    { 20, 21, 22, 23, 24, 25, 26, 27, 16, 17, 18, 19, 28, 29 },
385 	    { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 29 }
386 	},
387 	{   /* 101 */
388 	    2, { 16, 15 },
389 	    { 20, 21, 22, 23, 24, 25, 26, 27, 30, 17, 18, 19, 28, 29 },
390 	    { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14, 29 }
391 	},
392 	{   /* 110 */
393 	    2, { 16, 15 },
394 	    { 20, 21, 22, 23, 24, 25, 26, 27, 30, 17, 18, 19, 28, 29 },
395 	    { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14, 31 }
396 	},
397 	/*
398 	 * remainder unused
399 	 */
400 	}
401 };
402 
403 /*
404  * Row/Column/Bank address mappings for rev D/E in 64-bit mode, no interleave.
405  * See BKDG 3.29 3.5.6 Table 9.
406  */
407 static const struct _rcbmap_tbl dram_addrmap_d_e_64 = {
408 	MC_F_REVS_DE,
409 	64,
410 	{
411 	{   /* 0000 */
412 	    2, { 11, 12 },
413 	    { 19, 20, 21, 22, 23, 24, 13, 14, 15, 16, 17, 18 },
414 	    { 3, 4, 5, 6, 7, 8, 9, 10 }
415 	},
416 	{   /* 0001 */
417 	    2, { 12, 13 },
418 	    { 19, 20, 21, 22, 23, 24, 25, 14, 15, 16, 17, 18, 26 },
419 	    { 3, 4, 5, 6, 7, 8, 9, 10, 11 }
420 	},
421 	{   /* 0010 */
422 	    2, { 12, 13 },
423 	    { 19, 20, 21, 22, 23, 24, 25, 14, 15, 16, 17, 18, 26 },
424 	    { 3, 4, 5, 6, 7, 8, 9, 10, 11 }
425 	},
426 	{   /* 0011 */
427 	    2, { 13, 14 },
428 	    { 19, 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 27, 28 },
429 	    { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
430 	},
431 	{   /* 0100 */
432 	    2, { 13, 14 },
433 	    { 19, 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 27, 28 },
434 	    { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
435 	},
436 	{   /* 0101 */
437 	    2, { 13, 14 },
438 	    { 19, 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 27, 28 },
439 	    { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
440 	},
441 	{   /* 0110 */
442 	    2, { 14, 15 },
443 	    { 19, 20, 21, 22, 23, 24, 25, 26, 27, 16, 17, 18, 28, 29 },
444 	    { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 }
445 	},
446 	{   /* 0111 */
447 	    2, { 14, 15 },
448 	    { 19, 20, 21, 22, 23, 24, 25, 26, 27, 16, 17, 18, 28, 29 },
449 	    { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 }
450 	},
451 	{   /* 1000 */
452 	    2, { 14, 15 },
453 	    { 19, 20, 21, 22, 23, 24, 25, 26, 27, 16, 17, 18, 28, 29 },
454 	    { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 }
455 	},
456 	{   /* 1001 */
457 	    2, { 15, 16 },
458 	    { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 17, 18, 29, 30 },
459 	    { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13, 14 }
460 	},
461 	{   /* 1010 */
462 	    2, { 15, 16 },
463 	    { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 17, 18, 29, 30 },
464 	    { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13, 14 }
465 	},
466 	/*
467 	 * remainder unused
468 	 */
469 	}
470 };
471 
472 /*
473  * Row/Column/Bank address mappings for rev D/E in 128-bit mode, no interleave.
474  * See BKDG 3.29 3.5.6 Table 9.
475  */
476 static const struct _rcbmap_tbl dram_addrmap_d_e_128 = {
477 	MC_F_REVS_DE,
478 	128,
479 	{
480 	{   /* 0000 */
481 	    2, { 12, 13 },
482 	    { 20, 21, 22, 23, 24, 25, 14, 15, 16, 17, 18, 19 },
483 	    { 4, 5, 6, 7, 8, 9, 10, 11 }
484 	},
485 	{   /* 0001 */
486 	    2, { 13, 14 },
487 	    { 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 19, 27 },
488 	    { 4, 5, 6, 7, 8, 9, 10, 11, 12 }
489 	},
490 	{   /* 0010 */
491 	    2, { 13, 14 },
492 	    { 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 19, 27 },
493 	    { 4, 5, 6, 7, 8, 9, 10, 11, 12 }
494 	},
495 	{   /* 0011 */
496 	    2, { 14, 15 },
497 	    { 20, 21, 22, 23, 24, 25, 26, 27, 16, 17, 18, 19, 28, 29 },
498 	    { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }
499 	},
500 	{   /* 0100 */
501 	    2, { 14, 15 },
502 	    { 20, 21, 22, 23, 24, 25, 26, 27, 16, 17, 18, 19, 28, 29 },
503 	    { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }
504 	},
505 	{   /* 0101 */
506 	    2, { 14, 15 },
507 	    { 20, 21, 22, 23, 24, 25, 26, 27, 16, 17, 18, 19, 28, 29 },
508 	    { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }
509 	},
510 	{   /* 0110 */
511 	    2, { 15, 16 },
512 	    { 20, 21, 22, 23, 24, 25, 26, 27, 28, 17, 18, 19, 29, 30 },
513 	    { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 }
514 	},
515 	{   /* 0111 */
516 	    2, { 15, 16 },
517 	    { 20, 21, 22, 23, 24, 25, 26, 27, 28, 17, 18, 19, 29, 30 },
518 	    { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 }
519 	},
520 	{   /* 1000 */
521 	    2, { 15, 16 },
522 	    { 20, 21, 22, 23, 24, 25, 26, 27, 28, 17, 18, 19, 29, 30 },
523 	    { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 }
524 	},
525 	{   /* 1001 */
526 	    2, { 16, 17 },
527 	    { 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 18, 19, 30, 31 },
528 	    { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14, 15 }
529 	},
530 	{   /* 1010 */
531 	    2, { 16, 17 },
532 	    { 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 18, 19, 30, 31 },
533 	    { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14, 15 }
534 	},
535 	/*
536 	 * remainder unused
537 	 */
538 	}
539 };
540 
541 /*
542  * Row/Column/Bank address mappings for revs F/G in 64-bit mode, no interleave.
543  */
544 static const struct _rcbmap_tbl dram_addrmap_f_64 = {
545 	MC_F_REVS_FG,
546 	64,
547 	{
548 	{	/* 0000 */
549 		2, { 12, 13 },
550 		{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 14, 15, 16, 17 },
551 		{ 3, 4, 5, 6, 7, 8, 9, 10, 11 },
552 	},
553 	{	/* 0001 */
554 		2, { 13, 14 },
555 		{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 15, 16, 17 },
556 		{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 },
557 	},
558 	{	/* 0010 */
559 		2, { 13, 14 },
560 		{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 15, 16, 17 },
561 		{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 },
562 	},
563 	{	/* 0011 */
564 		2, { 14, 15 },
565 		{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 16, 17 },
566 		{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 },
567 	},
568 	{	/* 0100 */
569 		3, { 13, 14, 15 },
570 		{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 16, 17 },
571 		{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 },
572 	},
573 	{	/* 0101 */
574 		3, { 13, 14, 15 },
575 		{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 16, 17 },
576 		{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
577 	},
578 	{	/* 0110 */
579 		2, { 14, 15 },
580 		{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 16, 17 },
581 		{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 },
582 	},
583 	{	/* 0111 */
584 		3, { 13, 14, 15 },
585 		{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 16, 17 },
586 		{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
587 	},
588 	{	/* 1000 */
589 		3, { 14, 15, 16 },
590 		{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 17 },
591 		{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 },
592 	},
593 	{	/* 1001 */
594 		3, { 14, 15, 16 },
595 		{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 17 },
596 		{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 },
597 	},
598 	{	/* 1010 */
599 		3, { 13, 14, 15 },
600 		{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
601 		    16, 17 },
602 		{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
603 	},
604 	{	/* 1011 */
605 		3, { 14, 15, 16 },
606 		{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
607 		    17 },
608 		{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 },
609 	},
610 	/*
611 	 * remainder unused
612 	 */
613 	}
614 };
615 
616 /*
617  * Row/Column/Bank address mappings for revs F/G in 128-bit mode, no interleave.
618  */
619 static const struct _rcbmap_tbl dram_addrmap_f_128 = {
620 	MC_F_REVS_FG,
621 	128,
622 	{
623 	{	/* 0000 */
624 		2, { 13, 14 },
625 		{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 15, 16, 17, 18 },
626 		{ 4, 5, 6, 7, 8, 9, 10, 11, 12 },
627 	},
628 	{	/* 0001 */
629 		2, { 14, 15 },
630 		{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 16, 17, 18 },
631 		{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
632 	},
633 	{	/* 0010 */
634 		2, { 14, 15 },
635 		{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 16, 17, 18 },
636 		{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
637 	},
638 	{	/* 0011 */
639 		2, { 15, 16 },
640 		{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 17, 18 },
641 		{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 },
642 	},
643 	{	/* 0100 */
644 		3, { 14, 15, 16 },
645 		{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 17, 18 },
646 		{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
647 	},
648 	{	/* 0101 */
649 		3, { 14, 15, 16 },
650 		{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 17, 18 },
651 		{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
652 	},
653 	{	/* 0110 */
654 		2, { 15, 16 },
655 		{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 17, 18 },
656 		{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 },
657 	},
658 	{	/* 0111 */
659 		3, { 14, 15, 16 },
660 		{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
661 		    17, 18 },
662 		{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
663 	},
664 	{	/* 1000 */
665 		3, { 15, 16, 17 },
666 		{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
667 		    18 },
668 		{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 },
669 	},
670 	{	/* 1001 */
671 		3, { 15, 16, 17 },
672 		{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
673 		    18 },
674 		{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 },
675 	},
676 	{	/* 1010 */
677 		3, { 14, 15, 16 },
678 		{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
679 		    17, 18 },
680 		{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
681 	},
682 	{	/* 1011 */
683 		3, { 15, 16, 17 },
684 		{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
685 		    18 },
686 		{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 },
687 	},
688 	/*
689 	 * remainder unused
690 	 */
691 	}
692 };
693 
694 /*
695  * Bank swizzling is an option in revisions E and later.  Each internal-bank-
696  * select address bit is xor'd with two row address bits.  Which row
697  * address bits to use is not dependent on bank address mode but on
698  * revision and dram controller width alone.
699  *
700  * While rev E only supports 2 bank address bits, rev F supports 3 but not
701  * all chip-select bank address modes use all 3.  These tables will list
702  * the row bits to use in swizzling for the maximum number of supported
703  * bank address bits - the consumer musr determine how many should be
704  * applied (listed in the above row/col/bank tables).
705  */
706 
707 static const struct _bnkswzl_tbl bnswzl_info_e_64 = {
708 	MC_F_REV_E,
709 	64,
710 	{
711 	    {
712 		{ 17, 20 },		/* rows bits to swizzle with BA0 */
713 		{ 18, 21 },		/* rows bits to swizzle with BA1 */
714 		/* only 2 bankaddr bits on rev E */
715 	    }
716 	}
717 };
718 
719 static const struct _bnkswzl_tbl bnswzl_info_e_128 = {
720 	MC_F_REV_E,
721 	128,
722 	{
723 	    {
724 		{ 18, 21 },		/* rows bits to swizzle with BA0 */
725 		{ 19, 22 },		/* rows bits to swizzle with BA1 */
726 		/* only 2 bankaddr bits on rev E */
727 	    }
728 	}
729 };
730 
731 static const struct _bnkswzl_tbl bnswzl_info_f_64 = {
732 	MC_F_REVS_FG,
733 	64,
734 	{
735 	    {
736 		{ 17, 22 },		/* rows bits to swizzle with BA0 */
737 		{ 18, 23 },		/* rows bits to swizzle with BA1 */
738 		{ 19, 24 },		/* rows bits to swizzle with BA2 */
739 	    }
740 	}
741 };
742 
743 static const struct _bnkswzl_tbl bnswzl_info_f_128 = {
744 	MC_F_REVS_FG,
745 	128,
746 	{
747 	    {
748 		{ 18, 23 },		/* rows bits to swizzle with BA0 */
749 		{ 19, 24 },		/* rows bits to swizzle with BA1 */
750 		{ 20, 25 },		/* rows bits to swizzle with BA2 */
751 	    }
752 	}
753 };
754 
755 /*
756  * Yet another highbit function.  This really needs to go to common source.
757  * Returns range 0 to 64 inclusive;
758  */
759 static int
760 topbit(uint64_t i)
761 {
762 	int h = 1;
763 
764 	if (i == 0)
765 		return (0);
766 
767 	if (i & 0xffffffff00000000ULL) {
768 		h += 32;
769 		i >>= 32;
770 	}
771 
772 	if (i & 0xffff0000) {
773 		h += 16;
774 		i >>= 16;
775 	}
776 
777 	if (i & 0xff00) {
778 		h += 8;
779 		i >>= 8;
780 	}
781 
782 	if (i & 0xf0) {
783 		h += 4;
784 		i >>= 4;
785 	}
786 
787 	if (i & 0xc) {
788 		h += 2;
789 		i >>= 2;
790 	}
791 
792 	if (i & 0x2)
793 		h += 1;
794 
795 	return (h);
796 }
797 
798 /*
799  * Lookup the Chip-Select Bank Address Mode Encoding table for a given
800  * chip revision and chip-select mode.
801  */
802 const struct rct_bnkaddrmode *
803 rct_bnkaddrmode(uint_t mcrev, uint_t csmode)
804 {
805 	int i;
806 	const struct _bnkaddrmode_tbldesc *bdp = bnkaddr_tbls;
807 
808 	for (i = 0; i < sizeof (bnkaddr_tbls) /
809 	    sizeof (struct _bnkaddrmode_tbldesc);
810 	    i++, bdp++) {
811 		if (MC_REV_MATCH(mcrev, bdp->revmask) && csmode < bdp->nmodes)
812 			return (&bdp->modetbl[csmode]);
813 
814 	}
815 
816 	return (NULL);
817 }
818 
819 /*
820  * Lookup the DRAM Address Mapping table for a given chip revision, access
821  * width, bank-swizzle and chip-select mode.
822  */
823 const struct rct_rcbmap *
824 rct_rcbmap(uint_t mcrev, int width, uint_t csmode)
825 {
826 	const struct _rcbmap_tbl *rcbm;
827 	int i;
828 
829 	for (i = 0; i < sizeof (rcbmap_tbls) /
830 	    sizeof (struct _rcbmap_tbldesc); i++) {
831 		rcbm = rcbmap_tbls[i].rcbmap;
832 		if (MC_REV_MATCH(mcrev, rcbm->mt_revmask) &&
833 		    rcbm->mt_width == width && csmode < rcbmap_tbls[i].nmodes)
834 			return (&rcbm->mt_csmap[csmode]);
835 	}
836 
837 	return (NULL);
838 }
839 
840 /*
841  * Lookup the bank swizzling information for a given chip revision and
842  * access width.
843  */
844 const struct rct_bnkswzlinfo *
845 rct_bnkswzlinfo(uint_t mcrev, int width)
846 {
847 	int i;
848 	const struct _bnkswzl_tbl *swztp;
849 
850 	for (i = 0; i < sizeof (bnkswzl_tbls) /
851 	    sizeof (struct rcb_bnkswzl_tbl *); i++) {
852 		swztp = bnkswzl_tbls[i];
853 		if (MC_REV_MATCH(mcrev, swztp->swzt_revmask) &&
854 		    swztp->swzt_width == width)
855 			return (&swztp->swzt_bits);
856 	}
857 
858 	return (NULL);
859 }
860 
861 void
862 rct_csintlv_bits(uint_t mcrev, int width, uint_t csmode, int factor,
863     struct rct_csintlv *csid)
864 {
865 	int i, lstbnkbit;
866 	size_t csz;
867 	const struct rct_bnkaddrmode *bam;
868 	const struct rct_rcbmap *rcm;
869 
870 	/*
871 	 * 8-way cs interleave for some large cs sizes in 128-bit mode is
872 	 * not implemented prior to rev F.
873 	 */
874 	if (factor == 8 && width == 128 &&
875 	    ((MC_REV_MATCH(mcrev, MC_F_REVS_BC) && csmode == 0x6) ||
876 	    (MC_REV_MATCH(mcrev, MC_F_REVS_DE) &&
877 	    (csmode == 0x9 || csmode == 0xa)))) {
878 		csid->csi_factor = 0;
879 		return;
880 	}
881 
882 	if ((bam = rct_bnkaddrmode(mcrev, csmode)) == NULL ||
883 	    (rcm = rct_rcbmap(mcrev, width, csmode)) == NULL) {
884 		csid->csi_factor = 0;
885 		return;
886 	}
887 
888 	csz = MC_CS_SIZE(bam, width);
889 
890 	switch (factor) {
891 		case 2:
892 			csid->csi_nbits = 1;
893 			break;
894 		case 4:
895 			csid->csi_nbits = 2;
896 			break;
897 		case 8:
898 			csid->csi_nbits = 3;
899 			break;
900 		default:
901 			csid->csi_factor = 0;
902 			return;
903 	}
904 
905 	csid->csi_hibit = topbit(csz) - 1;
906 
907 	/*
908 	 * The first row bit is immediately after the last bank bit.
909 	 */
910 	lstbnkbit = 0;
911 	for (i = 0; i < rcm->rcb_nbankbits; i++)
912 		if (rcm->rcb_bankbit[i] > lstbnkbit)
913 			lstbnkbit = rcm->rcb_bankbit[i];
914 
915 	csid->csi_lobit = lstbnkbit + 1;
916 
917 	csid->csi_factor = factor;
918 }
919