/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <mcamd_api.h>
#include <mcamd_err.h>
#include <mcamd_rowcol_impl.h>
/*
* =========== Chip-Select Bank Address Mode Encodings =======================
*/
/* Individual table declarations */
static const struct rct_bnkaddrmode bnkaddr_tbls_pre_d[];
static const struct rct_bnkaddrmode bnkaddr_tbls_d_e[];
static const struct rct_bnkaddrmode bnkaddr_tbls_f[];
/* Managing bank address mode tables */
static const struct _bnkaddrmode_tbldesc {
uint_t revmask;
int nmodes;
const struct rct_bnkaddrmode *modetbl;
} bnkaddr_tbls[] = {
{ MC_F_REVS_BC, 7, bnkaddr_tbls_pre_d },
{ MC_F_REVS_DE, 11, bnkaddr_tbls_d_e },
{ MC_F_REVS_FG, 12, bnkaddr_tbls_f },
};
/*
* =========== DRAM Address Mappings for bank/row/column =====================
*/
/* Individual table declarations */
struct _rcbmap_tbl {
uint_t mt_revmask; /* revision to which this applies */
int mt_width; /* MC mode (64 or 128) */
const struct rct_rcbmap mt_csmap[MC_RC_CSMODES];
};
static const struct _rcbmap_tbl dram_addrmap_pre_d_64;
static const struct _rcbmap_tbl dram_addrmap_pre_d_128;
static const struct _rcbmap_tbl dram_addrmap_d_e_64;
static const struct _rcbmap_tbl dram_addrmap_d_e_128;
static const struct _rcbmap_tbl dram_addrmap_f_64;
static const struct _rcbmap_tbl dram_addrmap_f_128;
/* Managing row/column/bank tables */
static const struct _rcbmap_tbldesc {
int nmodes;
const struct _rcbmap_tbl *rcbmap;
} rcbmap_tbls[] = {
{ 7, &dram_addrmap_pre_d_64 },
{ 7, &dram_addrmap_pre_d_128 },
{ 11, &dram_addrmap_d_e_64 },
{ 11, &dram_addrmap_d_e_128 },
{ 12, &dram_addrmap_f_64 },
{ 12, &dram_addrmap_f_128 },
};
/*
* =========== Bank swizzling information ====================================
*/
/* Individual table declarations */
struct _bnkswzl_tbl {
uint_t swzt_revmask; /* revision to which this applies */
int swzt_width; /* MC mode (64 or 128) */
const struct rct_bnkswzlinfo swzt_bits;
};
static const struct _bnkswzl_tbl bnswzl_info_e_64;
static const struct _bnkswzl_tbl bnswzl_info_e_128;
static const struct _bnkswzl_tbl bnswzl_info_f_64;
static const struct _bnkswzl_tbl bnswzl_info_f_128;
/* Managing bank swizzle tables */
static const struct _bnkswzl_tbl *bnkswzl_tbls[] = {
&bnswzl_info_e_64,
&bnswzl_info_e_128,
&bnswzl_info_f_64,
&bnswzl_info_f_128,
};
/*
* ======================================================================
* | Tables reflecting those in the BKDG |
* ======================================================================
*/
/*
* DRAM Address Mapping in Interleaving Mode
*
* Chip-select interleave is performed by addressing across the columns
* of the first row of internal bank-select 0 on a chip-select, then the
* next row on internal bank-select 1, then 2 then 3; instead of then
* moving on to the next row of this chip-select we then rotate across
* other chip-selects in the interleave. The row/column/bank mappings
* described elsewhere in this file show that a DRAM InputAddr breaks down
* as follows, using an example for CS Mode 0000 revision CG and earlier 64-bit
* mode; the cs size is 32MB, requiring 25 bits to address all of it.
*
* chip-selection bits | offset within chip-select bits |
* | row bits | bank bits | column bits | - |
* 24 13 12 11 10 3 2 0
*
* The high-order chip-selection bits select the chip-select and the
* offset bits offset within the chosen chip-select.
*
* To establish say a 2-way interleave in which we consume all of one
* row number and all internal bank numbers on one cs before moving on
* to the next to do the same we will target the first row bit - bit 13;
* a 4-way interleave would use bits 14 and 13, and an 8-way interleave
* bits 15, 14 and 13. We swap the chosen bits with the least significant
* high order chip-selection bits.
*
* The BKDG interleave tables really just describe the above. Working
* out the high-order bits to swap is easy since that is derived directly
* from the chip-select size. The low-order bits depend on the device
* parameters since we need to target the least significant row address bits -
* but we have that information from the rcbmap_tbls since the first row bit
* simply follows the last bank address bit.
*/
/*
* General notes for CS Bank Address Mode Encoding tables.
*
* These are indexed by chip-select mode. Where the numbers of rows and
* columns is ambiguous (as it is for a number of rev CG and earlier cases)
* the bam_config should be initialized to 1 and the numbers of rows
* and columns should be the maximums.
*/
/*
* Chip Select Bank Address Mode Encoding for rev CG and earlier.
*/
static const struct rct_bnkaddrmode bnkaddr_tbls_pre_d[] = {
{ /* 000 */
32, 12, 8
},
{ /* 001 */
64, 12, 9
},
{ /* 010 */
128, 13, 10, 1 /* AMBIG */
},
{ /* 011 */
256, 13, 11, 1 /* AMBIG */
},
{ /* 100 */
512, 14, 11, 1 /* AMBIG */
},
{ /* 101 */
1024, 14, 12, 1 /* AMBIG */
},
{ /* 110 */
2048, 14, 12
}
};
/*
* Chip Select Bank Address Mode Encoding for revs D and E.
*/
static const struct rct_bnkaddrmode bnkaddr_tbls_d_e[] = {
{ /* 0000 */
32, 12, 8
},
{ /* 0001 */
64, 12, 9
},
{ /* 0010 */
128, 13, 9
},
{ /* 0011 */
128, 12, 10
},
{ /* 0100 */
256, 13, 10
},
{ /* 0101 */
512, 14, 10
},
{ /* 0110 */
256, 12, 11
},
{ /* 0111 */
512, 13, 11
},
{ /* 1000 */
1024, 14, 11
},
{ /* 1001 */
1024, 13, 12
},
{ /* 1010 */
2048, 14, 12
}
};
/*
* Chip Select Bank Address Mode Encoding for rev F
*/
static const struct rct_bnkaddrmode bnkaddr_tbls_f[] = {
{ /* 0000 */
128, 13, 9
},
{ /* 0001 */
256, 13, 10
},
{ /* 0010 */
512, 14, 10
},
{ /* 0011 */
512, 13, 11
},
{ /* 0100 */
512, 13, 10
},
{ /* 0101 */
1024, 14, 10
},
{ /* 0110 */
1024, 14, 11
},
{ /* 0111 */
2048, 15, 10
},
{ /* 1000 */
2048, 14, 11
},
{ /* 1001 */
4096, 15, 11
},
{ /* 1010 */
4096, 16, 10
},
{ /* 1011 */
8192, 16, 11
}
};
/*
* General notes on Row/Column/Bank table initialisation.
*
* These are the tables 7, 8, 9, 10, 11 and 12 of BKDG 3.29 section 3.5.6.1.
* They apply in non-interleave (node or cs) mode and describe how for
* a given revision, access width, bank-swizzle mode, and current chip-select
* mode the row, column and internal sdram bank are derived from the
* normalizied InputAddr presented to the DRAM controller.
*
* The mt_csmap array is indexed by chip-select mode. Within it the
* bankargs, rowbits and colbits arrays are indexed by bit number, so
* match the BKDG tables if the latter are read right-to-left.
*
* The bankargs list up to three bit numbers per bank bit. For revisions
* CG and earlier there is no bank swizzling, so just a single number
* should be listed. Revisions D and E have the same row/column/bank mapping,
* but rev E has the additional feature of being able to xor two row bits
* into each bank bit. The consumer will know whether they are using bank
* swizzling - if so then they should xor the bankargs bits together.
* The first argument must be the bit number not already used in forming
* part of the row address - eg in table 12 for csmode 0000b bank address
* bit 0 is bit 12 xor bit 18 xor bit 21, and 18 and 21 are also mentioned in
* the row address (bits 10 and 1) so we must list bit 12 first. We will
* use this information in chip-select interleave decoding in which we need
* to know which is the first bit after column and bank address bits.
*
* Column address A10 is always used for the Precharge All signal. Where
* "PC" appears in the BKDG tables we will include MC_PC_ALL in the
* corresponding bit position.
*
* For some rev CG and earlier chipselect modes the number of rows and columns
* is ambiguous. This is reflected in these tables by some bit being
* duplicated between row and column address. In practice we will follow
* the convention of always assigning the floating bit to the row address.
*/
/*
* Row/Column/Bank address mappings for rev CG in 64-bit mode, no interleave.
* See BKDG 3.29 3.5.6 Table 7.
*/
static const struct _rcbmap_tbl dram_addrmap_pre_d_64 = {
MC_F_REVS_BC,
64,
{
{ /* 000 */
2, { 11, 12 },
{ 19, 20, 21, 22, 23, 24, 13, 14, 15, 16, 17, 18 },
{ 3, 4, 5, 6, 7, 8, 9, 10 }
},
{ /* 001 */
2, { 13, 12 },
{ 19, 20, 21, 22, 23, 24, 25, 14, 15, 16, 17, 18 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11 }
},
{ /* 010 */
2, { 13, 12 },
{ 19, 20, 21, 22, 23, 24, 25, 14, 15, 16, 17, 18, 26 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 26 }
},
{ /* 011 */
2, { 13, 14 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 27 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 27 }
},
{ /* 100 */
2, { 13, 14 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 27, 28 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 28 }
},
{ /* 101 */
2, { 15, 14 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 29, 16, 17, 18, 27, 28 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13, 28 }
},
{ /* 110 */
2, { 15, 14 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 29, 16, 17, 18, 27, 28 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13, 30 }
},
/*
* remainder unused
*/
}
};
/*
* Row/Column/Bank address mappings for rev CG in 128-bit mode, no interleave.
* See BKDG 3.29 3.5.6 Table 8.
*/
static const struct _rcbmap_tbl dram_addrmap_pre_d_128 = {
MC_F_REVS_BC,
128,
{
{ /* 000 */
2, { 12, 13 },
{ 20, 21, 22, 23, 24, 25, 14, 15, 16, 17, 18, 19 },
{ 4, 5, 6, 7, 8, 9, 10, 11 }
},
{ /* 001 */
2, { 14, 13 },
{ 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 19 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12 }
},
{ /* 010 */
2, { 14, 13 },
{ 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 19, 27 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 27 }
},
{ /* 011 */
2, { 14, 15 },
{ 20, 21, 22, 23, 24, 25, 26, 27, 16, 17, 18, 19, 28 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 28 }
},
{ /* 100 */
2, { 14, 15 },
{ 20, 21, 22, 23, 24, 25, 26, 27, 16, 17, 18, 19, 28, 29 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 29 }
},
{ /* 101 */
2, { 16, 15 },
{ 20, 21, 22, 23, 24, 25, 26, 27, 30, 17, 18, 19, 28, 29 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14, 29 }
},
{ /* 110 */
2, { 16, 15 },
{ 20, 21, 22, 23, 24, 25, 26, 27, 30, 17, 18, 19, 28, 29 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14, 31 }
},
/*
* remainder unused
*/
}
};
/*
* Row/Column/Bank address mappings for rev D/E in 64-bit mode, no interleave.
* See BKDG 3.29 3.5.6 Table 9.
*/
static const struct _rcbmap_tbl dram_addrmap_d_e_64 = {
MC_F_REVS_DE,
64,
{
{ /* 0000 */
2, { 11, 12 },
{ 19, 20, 21, 22, 23, 24, 13, 14, 15, 16, 17, 18 },
{ 3, 4, 5, 6, 7, 8, 9, 10 }
},
{ /* 0001 */
2, { 12, 13 },
{ 19, 20, 21, 22, 23, 24, 25, 14, 15, 16, 17, 18, 26 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11 }
},
{ /* 0010 */
2, { 12, 13 },
{ 19, 20, 21, 22, 23, 24, 25, 14, 15, 16, 17, 18, 26 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11 }
},
{ /* 0011 */
2, { 13, 14 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 27, 28 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
},
{ /* 0100 */
2, { 13, 14 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 27, 28 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
},
{ /* 0101 */
2, { 13, 14 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 27, 28 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
},
{ /* 0110 */
2, { 14, 15 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 16, 17, 18, 28, 29 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 }
},
{ /* 0111 */
2, { 14, 15 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 16, 17, 18, 28, 29 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 }
},
{ /* 1000 */
2, { 14, 15 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 16, 17, 18, 28, 29 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 }
},
{ /* 1001 */
2, { 15, 16 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 17, 18, 29, 30 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13, 14 }
},
{ /* 1010 */
2, { 15, 16 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 17, 18, 29, 30 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13, 14 }
},
/*
* remainder unused
*/
}
};
/*
* Row/Column/Bank address mappings for rev D/E in 128-bit mode, no interleave.
* See BKDG 3.29 3.5.6 Table 9.
*/
static const struct _rcbmap_tbl dram_addrmap_d_e_128 = {
MC_F_REVS_DE,
128,
{
{ /* 0000 */
2, { 12, 13 },
{ 20, 21, 22, 23, 24, 25, 14, 15, 16, 17, 18, 19 },
{ 4, 5, 6, 7, 8, 9, 10, 11 }
},
{ /* 0001 */
2, { 13, 14 },
{ 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 19, 27 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12 }
},
{ /* 0010 */
2, { 13, 14 },
{ 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 19, 27 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12 }
},
{ /* 0011 */
2, { 14, 15 },
{ 20, 21, 22, 23, 24, 25, 26, 27, 16, 17, 18, 19, 28, 29 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }
},
{ /* 0100 */
2, { 14, 15 },
{ 20, 21, 22, 23, 24, 25, 26, 27, 16, 17, 18, 19, 28, 29 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }
},
{ /* 0101 */
2, { 14, 15 },
{ 20, 21, 22, 23, 24, 25, 26, 27, 16, 17, 18, 19, 28, 29 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }
},
{ /* 0110 */
2, { 15, 16 },
{ 20, 21, 22, 23, 24, 25, 26, 27, 28, 17, 18, 19, 29, 30 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 }
},
{ /* 0111 */
2, { 15, 16 },
{ 20, 21, 22, 23, 24, 25, 26, 27, 28, 17, 18, 19, 29, 30 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 }
},
{ /* 1000 */
2, { 15, 16 },
{ 20, 21, 22, 23, 24, 25, 26, 27, 28, 17, 18, 19, 29, 30 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 }
},
{ /* 1001 */
2, { 16, 17 },
{ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 18, 19, 30, 31 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14, 15 }
},
{ /* 1010 */
2, { 16, 17 },
{ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 18, 19, 30, 31 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14, 15 }
},
/*
* remainder unused
*/
}
};
/*
* Row/Column/Bank address mappings for revs F/G in 64-bit mode, no interleave.
*/
static const struct _rcbmap_tbl dram_addrmap_f_64 = {
MC_F_REVS_FG,
64,
{
{ /* 0000 */
2, { 12, 13 },
{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 14, 15, 16, 17 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11 },
},
{ /* 0001 */
2, { 13, 14 },
{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 15, 16, 17 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 },
},
{ /* 0010 */
2, { 13, 14 },
{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 15, 16, 17 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 },
},
{ /* 0011 */
2, { 14, 15 },
{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 16, 17 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 },
},
{ /* 0100 */
3, { 13, 14, 15 },
{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 16, 17 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 },
},
{ /* 0101 */
3, { 13, 14, 15 },
{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 16, 17 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
},
{ /* 0110 */
2, { 14, 15 },
{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 16, 17 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 },
},
{ /* 0111 */
3, { 13, 14, 15 },
{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 16, 17 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
},
{ /* 1000 */
3, { 14, 15, 16 },
{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 17 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 },
},
{ /* 1001 */
3, { 14, 15, 16 },
{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 17 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 },
},
{ /* 1010 */
3, { 13, 14, 15 },
{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
16, 17 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
},
{ /* 1011 */
3, { 14, 15, 16 },
{ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
17 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 },
},
/*
* remainder unused
*/
}
};
/*
* Row/Column/Bank address mappings for revs F/G in 128-bit mode, no interleave.
*/
static const struct _rcbmap_tbl dram_addrmap_f_128 = {
MC_F_REVS_FG,
128,
{
{ /* 0000 */
2, { 13, 14 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 15, 16, 17, 18 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12 },
},
{ /* 0001 */
2, { 14, 15 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 16, 17, 18 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
},
{ /* 0010 */
2, { 14, 15 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 16, 17, 18 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
},
{ /* 0011 */
2, { 15, 16 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 17, 18 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 },
},
{ /* 0100 */
3, { 14, 15, 16 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 17, 18 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
},
{ /* 0101 */
3, { 14, 15, 16 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 17, 18 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
},
{ /* 0110 */
2, { 15, 16 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 17, 18 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 },
},
{ /* 0111 */
3, { 14, 15, 16 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
17, 18 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
},
{ /* 1000 */
3, { 15, 16, 17 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
18 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 },
},
{ /* 1001 */
3, { 15, 16, 17 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
18 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 },
},
{ /* 1010 */
3, { 14, 15, 16 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
17, 18 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
},
{ /* 1011 */
3, { 15, 16, 17 },
{ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
18 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 },
},
/*
* remainder unused
*/
}
};
/*
* Bank swizzling is an option in revisions E and later. Each internal-bank-
* select address bit is xor'd with two row address bits. Which row
* address bits to use is not dependent on bank address mode but on
* revision and dram controller width alone.
*
* While rev E only supports 2 bank address bits, rev F supports 3 but not
* all chip-select bank address modes use all 3. These tables will list
* the row bits to use in swizzling for the maximum number of supported
* bank address bits - the consumer musr determine how many should be
* applied (listed in the above row/col/bank tables).
*/
static const struct _bnkswzl_tbl bnswzl_info_e_64 = {
MC_F_REV_E,
64,
{
{
{ 17, 20 }, /* rows bits to swizzle with BA0 */
{ 18, 21 }, /* rows bits to swizzle with BA1 */
/* only 2 bankaddr bits on rev E */
}
}
};
static const struct _bnkswzl_tbl bnswzl_info_e_128 = {
MC_F_REV_E,
128,
{
{
{ 18, 21 }, /* rows bits to swizzle with BA0 */
{ 19, 22 }, /* rows bits to swizzle with BA1 */
/* only 2 bankaddr bits on rev E */
}
}
};
static const struct _bnkswzl_tbl bnswzl_info_f_64 = {
MC_F_REVS_FG,
64,
{
{
{ 17, 22 }, /* rows bits to swizzle with BA0 */
{ 18, 23 }, /* rows bits to swizzle with BA1 */
{ 19, 24 }, /* rows bits to swizzle with BA2 */
}
}
};
static const struct _bnkswzl_tbl bnswzl_info_f_128 = {
MC_F_REVS_FG,
128,
{
{
{ 18, 23 }, /* rows bits to swizzle with BA0 */
{ 19, 24 }, /* rows bits to swizzle with BA1 */
{ 20, 25 }, /* rows bits to swizzle with BA2 */
}
}
};
/*
* Yet another highbit function. This really needs to go to common source.
* Returns range 0 to 64 inclusive;
*/
static int
topbit(uint64_t i)
{
int h = 1;
if (i == 0)
return (0);
if (i & 0xffffffff00000000ULL) {
h += 32;
i >>= 32;
}
if (i & 0xffff0000) {
h += 16;
i >>= 16;
}
if (i & 0xff00) {
h += 8;
i >>= 8;
}
if (i & 0xf0) {
h += 4;
i >>= 4;
}
if (i & 0xc) {
h += 2;
i >>= 2;
}
if (i & 0x2)
h += 1;
return (h);
}
/*
* Lookup the Chip-Select Bank Address Mode Encoding table for a given
* chip revision and chip-select mode.
*/
const struct rct_bnkaddrmode *
rct_bnkaddrmode(uint_t mcrev, uint_t csmode)
{
int i;
const struct _bnkaddrmode_tbldesc *bdp = bnkaddr_tbls;
for (i = 0; i < sizeof (bnkaddr_tbls) /
sizeof (struct _bnkaddrmode_tbldesc);
i++, bdp++) {
if (MC_REV_MATCH(mcrev, bdp->revmask) && csmode < bdp->nmodes)
return (&bdp->modetbl[csmode]);
}
return (NULL);
}
/*
* Lookup the DRAM Address Mapping table for a given chip revision, access
* width, bank-swizzle and chip-select mode.
*/
const struct rct_rcbmap *
rct_rcbmap(uint_t mcrev, int width, uint_t csmode)
{
const struct _rcbmap_tbl *rcbm;
int i;
for (i = 0; i < sizeof (rcbmap_tbls) /
sizeof (struct _rcbmap_tbldesc); i++) {
rcbm = rcbmap_tbls[i].rcbmap;
if (MC_REV_MATCH(mcrev, rcbm->mt_revmask) &&
rcbm->mt_width == width && csmode < rcbmap_tbls[i].nmodes)
return (&rcbm->mt_csmap[csmode]);
}
return (NULL);
}
/*
* Lookup the bank swizzling information for a given chip revision and
* access width.
*/
const struct rct_bnkswzlinfo *
rct_bnkswzlinfo(uint_t mcrev, int width)
{
int i;
const struct _bnkswzl_tbl *swztp;
for (i = 0; i < sizeof (bnkswzl_tbls) /
sizeof (struct rcb_bnkswzl_tbl *); i++) {
swztp = bnkswzl_tbls[i];
if (MC_REV_MATCH(mcrev, swztp->swzt_revmask) &&
swztp->swzt_width == width)
return (&swztp->swzt_bits);
}
return (NULL);
}
void
rct_csintlv_bits(uint_t mcrev, int width, uint_t csmode, int factor,
struct rct_csintlv *csid)
{
int i, lstbnkbit;
size_t csz;
const struct rct_bnkaddrmode *bam;
const struct rct_rcbmap *rcm;
/*
* 8-way cs interleave for some large cs sizes in 128-bit mode is
* not implemented prior to rev F.
*/
if (factor == 8 && width == 128 &&
((MC_REV_MATCH(mcrev, MC_F_REVS_BC) && csmode == 0x6) ||
(MC_REV_MATCH(mcrev, MC_F_REVS_DE) &&
(csmode == 0x9 || csmode == 0xa)))) {
csid->csi_factor = 0;
return;
}
if ((bam = rct_bnkaddrmode(mcrev, csmode)) == NULL ||
(rcm = rct_rcbmap(mcrev, width, csmode)) == NULL) {
csid->csi_factor = 0;
return;
}
csz = MC_CS_SIZE(bam, width);
switch (factor) {
case 2:
csid->csi_nbits = 1;
break;
case 4:
csid->csi_nbits = 2;
break;
case 8:
csid->csi_nbits = 3;
break;
default:
csid->csi_factor = 0;
return;
}
csid->csi_hibit = topbit(csz) - 1;
/*
* The first row bit is immediately after the last bank bit.
*/
lstbnkbit = 0;
for (i = 0; i < rcm->rcb_nbankbits; i++)
if (rcm->rcb_bankbit[i] > lstbnkbit)
lstbnkbit = rcm->rcb_bankbit[i];
csid->csi_lobit = lstbnkbit + 1;
csid->csi_factor = factor;
}