nb/intel/sandybridge: Redefine IOSAV_SUBSEQUENCE
Instead of directly writing values to the IOSAV registers, use a struct and some helper functions to provide a cleaner interface for the IOSAV. Having IOSAV_SUBSEQUENCE refer to a static function is weird, but we will remove this macro in a follow-up that does not change the binary. Tested on Asus P8Z77-V LX2, still boots. Change-Id: I73f13c18a739c5586a7415966f9017c2335fdfd1 Signed-off-by: Angel Pons <th3fanbus@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/40980 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
This commit is contained in:
parent
2be5900087
commit
d5b780c5b1
|
@ -213,12 +213,37 @@
|
|||
((rate) << 12) | \
|
||||
((xors) << 16))
|
||||
|
||||
#define IOSAV_SUBSEQUENCE(ch, n, cmd, ranksel, reps, gap, post, dir, addr, rowbits, bank, rank, addr_1, addr_8, upd_bank, upd_rank, wrap, lfsr, rate, xors) \
|
||||
do { \
|
||||
MCHBAR32(IOSAV_n_SP_CMD_CTRL_ch(ch, n)) = (cmd) | ((ranksel) << 16); \
|
||||
MCHBAR32(IOSAV_n_SUBSEQ_CTRL_ch(ch, n)) = SUBSEQ_CTRL(reps, gap, post, dir); \
|
||||
MCHBAR32(IOSAV_n_SP_CMD_ADDR_ch(ch, n)) = SP_CMD_ADDR(addr, rowbits, bank, rank); \
|
||||
MCHBAR32(IOSAV_n_ADDR_UPDATE_ch(ch, n)) = ADDR_UPDATE(addr_1, addr_8, upd_bank, upd_rank, wrap, lfsr, rate, xors); \
|
||||
#define IOSAV_SUBSEQUENCE(ch, n, cmd, ranksel, reps, gap, post, dir, addr, row_bits, bank_addr, rank_addr, addr_1, addr_8, upd_bank, upd_rank, wrap, lfsr, rate, xors) \
|
||||
do { \
|
||||
const struct iosav_ssq ssq = { \
|
||||
.sp_cmd_ctrl = { \
|
||||
.command = cmd, \
|
||||
.ranksel_ap = ranksel, \
|
||||
}, \
|
||||
.subseq_ctrl = { \
|
||||
.cmd_executions = reps, \
|
||||
.cmd_delay_gap = gap, \
|
||||
.post_ssq_wait = post, \
|
||||
.data_direction = dir, \
|
||||
}, \
|
||||
.sp_cmd_addr = { \
|
||||
.address = addr, \
|
||||
.rowbits = row_bits, \
|
||||
.bank = bank_addr, \
|
||||
.rank = rank_addr, \
|
||||
}, \
|
||||
.addr_update = { \
|
||||
.inc_addr_1 = addr_1, \
|
||||
.inc_addr_8 = addr_8, \
|
||||
.inc_bank = upd_bank, \
|
||||
.inc_rank = upd_rank, \
|
||||
.addr_wrap = wrap, \
|
||||
.lfsr_upd = lfsr, \
|
||||
.upd_rate = rate, \
|
||||
.lfsr_xors = xors, \
|
||||
}, \
|
||||
}; \
|
||||
iosav_write_ssq(ch, n, &ssq); \
|
||||
} while (0)
|
||||
|
||||
/* Indexed register helper macros */
|
||||
|
|
|
@ -17,10 +17,25 @@
|
|||
|
||||
/* FIXME: no support for 3-channel chipsets */
|
||||
|
||||
/* Number of programmed IOSAV subsequences. */
|
||||
static unsigned int ssq_count = 0;
|
||||
|
||||
static void iosav_write_ssq(const int ch, const int n, const struct iosav_ssq *ssq)
|
||||
{
|
||||
MCHBAR32(IOSAV_n_SP_CMD_CTRL_ch(ch, ssq_count)) = ssq->sp_cmd_ctrl.raw;
|
||||
MCHBAR32(IOSAV_n_SUBSEQ_CTRL_ch(ch, ssq_count)) = ssq->subseq_ctrl.raw;
|
||||
MCHBAR32(IOSAV_n_SP_CMD_ADDR_ch(ch, ssq_count)) = ssq->sp_cmd_addr.raw;
|
||||
MCHBAR32(IOSAV_n_ADDR_UPDATE_ch(ch, ssq_count)) = ssq->addr_update.raw;
|
||||
|
||||
ssq_count++;
|
||||
}
|
||||
|
||||
/* length: [1..4] */
|
||||
static void iosav_run_queue(const int ch, const u8 loops, const u8 length, const u8 as_timer)
|
||||
{
|
||||
MCHBAR32(IOSAV_SEQ_CTL_ch(ch)) = loops | ((length - 1) << 18) | (as_timer << 22);
|
||||
MCHBAR32(IOSAV_SEQ_CTL_ch(ch)) = loops | ((ssq_count - 1) << 18) | (as_timer << 22);
|
||||
|
||||
ssq_count = 0;
|
||||
}
|
||||
|
||||
static void iosav_run_once(const int ch, const u8 length)
|
||||
|
|
|
@ -34,6 +34,63 @@
|
|||
#define IOSAV_WR (0xf201)
|
||||
#define IOSAV_NOP (0xf207)
|
||||
|
||||
struct iosav_ssq {
|
||||
/* IOSAV_n_SP_CMD_CTRL */
|
||||
union {
|
||||
struct {
|
||||
u32 command : 16;
|
||||
u32 ranksel_ap : 2;
|
||||
u32 : 14;
|
||||
};
|
||||
u32 raw;
|
||||
} sp_cmd_ctrl;
|
||||
|
||||
/* IOSAV_n_SUBSEQ_CTRL */
|
||||
union {
|
||||
struct {
|
||||
u32 cmd_executions : 9;
|
||||
u32 : 1;
|
||||
u32 cmd_delay_gap : 5;
|
||||
u32 : 1;
|
||||
u32 post_ssq_wait : 9;
|
||||
u32 : 1;
|
||||
u32 data_direction : 2;
|
||||
u32 : 4;
|
||||
};
|
||||
u32 raw;
|
||||
} subseq_ctrl;
|
||||
|
||||
/* IOSAV_n_SP_CMD_ADDR */
|
||||
union {
|
||||
struct {
|
||||
u32 address : 16;
|
||||
u32 rowbits : 3;
|
||||
u32 : 1;
|
||||
u32 bank : 3;
|
||||
u32 : 1;
|
||||
u32 rank : 2;
|
||||
u32 : 6;
|
||||
};
|
||||
u32 raw;
|
||||
} sp_cmd_addr;
|
||||
|
||||
/* IOSAV_n_ADDR_UPDATE */
|
||||
union {
|
||||
struct {
|
||||
u32 inc_addr_1 : 1;
|
||||
u32 inc_addr_8 : 1;
|
||||
u32 inc_bank : 1;
|
||||
u32 inc_rank : 2;
|
||||
u32 addr_wrap : 5;
|
||||
u32 lfsr_upd : 2;
|
||||
u32 upd_rate : 4;
|
||||
u32 lfsr_xors : 2;
|
||||
u32 : 14;
|
||||
};
|
||||
u32 raw;
|
||||
} addr_update;
|
||||
};
|
||||
|
||||
/* FIXME: Vendor BIOS uses 64 but our algorithms are less
|
||||
performant and even 1 seems to be enough in practice. */
|
||||
#define NUM_PATTERNS 4
|
||||
|
|
Loading…
Reference in New Issue