/* * 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. */ #include #include #include /* * =========== 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; }