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 */
39static const struct rct_bnkaddrmode bnkaddr_tbls_pre_d[];
40static const struct rct_bnkaddrmode bnkaddr_tbls_d_e[];
41static const struct rct_bnkaddrmode bnkaddr_tbls_f[];
42
43/* Managing bank address mode tables */
44static 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 */
60struct _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
66static const struct _rcbmap_tbl dram_addrmap_pre_d_64;
67static const struct _rcbmap_tbl dram_addrmap_pre_d_128;
68static const struct _rcbmap_tbl dram_addrmap_d_e_64;
69static const struct _rcbmap_tbl dram_addrmap_d_e_128;
70static const struct _rcbmap_tbl dram_addrmap_f_64;
71static const struct _rcbmap_tbl dram_addrmap_f_128;
72
73/* Managing row/column/bank tables */
74static 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 */
91struct _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
97static const struct _bnkswzl_tbl bnswzl_info_e_64;
98static const struct _bnkswzl_tbl bnswzl_info_e_128;
99static const struct _bnkswzl_tbl bnswzl_info_f_64;
100static const struct _bnkswzl_tbl bnswzl_info_f_128;
101
102/* Managing bank swizzle tables */
103static 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 */
162static 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 */
189static 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 */
228static 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 */
308static 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 */
358static 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 */
407static 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 */
476static 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 */
544static 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 */
619static 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
707static 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
719static 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
731static 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
743static 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 */
759static int
760topbit(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 */
802const struct rct_bnkaddrmode *
803rct_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 */
823const struct rct_rcbmap *
824rct_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 */
844const struct rct_bnkswzlinfo *
845rct_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
861void
862rct_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