#include <mcamd_api.h>
#include <mcamd_err.h>
#include <mcamd_rowcol_impl.h>
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[];
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 },
};
struct _rcbmap_tbl {
uint_t mt_revmask;
int mt_width;
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;
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 },
};
struct _bnkswzl_tbl {
uint_t swzt_revmask;
int swzt_width;
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;
static const struct _bnkswzl_tbl *bnkswzl_tbls[] = {
&bnswzl_info_e_64,
&bnswzl_info_e_128,
&bnswzl_info_f_64,
&bnswzl_info_f_128,
};
static const struct rct_bnkaddrmode bnkaddr_tbls_pre_d[] = {
{
32, 12, 8
},
{
64, 12, 9
},
{
128, 13, 10, 1
},
{
256, 13, 11, 1
},
{
512, 14, 11, 1
},
{
1024, 14, 12, 1
},
{
2048, 14, 12
}
};
static const struct rct_bnkaddrmode bnkaddr_tbls_d_e[] = {
{
32, 12, 8
},
{
64, 12, 9
},
{
128, 13, 9
},
{
128, 12, 10
},
{
256, 13, 10
},
{
512, 14, 10
},
{
256, 12, 11
},
{
512, 13, 11
},
{
1024, 14, 11
},
{
1024, 13, 12
},
{
2048, 14, 12
}
};
static const struct rct_bnkaddrmode bnkaddr_tbls_f[] = {
{
128, 13, 9
},
{
256, 13, 10
},
{
512, 14, 10
},
{
512, 13, 11
},
{
512, 13, 10
},
{
1024, 14, 10
},
{
1024, 14, 11
},
{
2048, 15, 10
},
{
2048, 14, 11
},
{
4096, 15, 11
},
{
4096, 16, 10
},
{
8192, 16, 11
}
};
static const struct _rcbmap_tbl dram_addrmap_pre_d_64 = {
MC_F_REVS_BC,
64,
{
{
2, { 11, 12 },
{ 19, 20, 21, 22, 23, 24, 13, 14, 15, 16, 17, 18 },
{ 3, 4, 5, 6, 7, 8, 9, 10 }
},
{
2, { 13, 12 },
{ 19, 20, 21, 22, 23, 24, 25, 14, 15, 16, 17, 18 },
{ 3, 4, 5, 6, 7, 8, 9, 10, 11 }
},
{
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 }
},
{
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 }
},
{
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 }
},
{
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 }
},
{
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 }
},
}
};
static const struct _rcbmap_tbl dram_addrmap_pre_d_128 = {
MC_F_REVS_BC,
128,
{
{
2, { 12, 13 },
{ 20, 21, 22, 23, 24, 25, 14, 15, 16, 17, 18, 19 },
{ 4, 5, 6, 7, 8, 9, 10, 11 }
},
{
2, { 14, 13 },
{ 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 19 },
{ 4, 5, 6, 7, 8, 9, 10, 11, 12 }
},
{
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 }
},
{
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 }
},
{
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 }
},
{
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 }
},
{
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 }
},
}
};
static const struct _rcbmap_tbl dram_addrmap_d_e_64 = {
MC_F_REVS_DE,
64,
{
{
2, { 11, 12 },
{ 19, 20, 21, 22, 23, 24, 13, 14, 15, 16, 17, 18 },
{ 3, 4, 5, 6, 7, 8, 9, 10 }
},
{
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 }
},
{
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 }
},
{
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 }
},
{
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 }
},
{
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 }
},
{
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 }
},
{
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 }
},
{
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 }
},
{
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 }
},
{
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 }
},
}
};
static const struct _rcbmap_tbl dram_addrmap_d_e_128 = {
MC_F_REVS_DE,
128,
{
{
2, { 12, 13 },
{ 20, 21, 22, 23, 24, 25, 14, 15, 16, 17, 18, 19 },
{ 4, 5, 6, 7, 8, 9, 10, 11 }
},
{
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 }
},
{
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 }
},
{
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 }
},
{
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 }
},
{
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 }
},
{
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 }
},
{
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 }
},
{
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 }
},
{
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 }
},
{
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 }
},
}
};
static const struct _rcbmap_tbl dram_addrmap_f_64 = {
MC_F_REVS_FG,
64,
{
{
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 },
},
{
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 },
},
{
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 },
},
{
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 },
},
{
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 },
},
{
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 }
},
{
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 },
},
{
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 }
},
{
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 },
},
{
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 },
},
{
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 }
},
{
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 },
},
}
};
static const struct _rcbmap_tbl dram_addrmap_f_128 = {
MC_F_REVS_FG,
128,
{
{
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 },
},
{
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 },
},
{
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 },
},
{
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 },
},
{
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 },
},
{
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 },
},
{
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 },
},
{
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 },
},
{
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 },
},
{
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 },
},
{
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 },
},
{
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 },
},
}
};
static const struct _bnkswzl_tbl bnswzl_info_e_64 = {
MC_F_REV_E,
64,
{
{
{ 17, 20 },
{ 18, 21 },
}
}
};
static const struct _bnkswzl_tbl bnswzl_info_e_128 = {
MC_F_REV_E,
128,
{
{
{ 18, 21 },
{ 19, 22 },
}
}
};
static const struct _bnkswzl_tbl bnswzl_info_f_64 = {
MC_F_REVS_FG,
64,
{
{
{ 17, 22 },
{ 18, 23 },
{ 19, 24 },
}
}
};
static const struct _bnkswzl_tbl bnswzl_info_f_128 = {
MC_F_REVS_FG,
128,
{
{
{ 18, 23 },
{ 19, 24 },
{ 20, 25 },
}
}
};
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);
}
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);
}
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);
}
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;
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;
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;
}