From d5b780c5b1a7f6d7f12d3305dcfd36413a429c39 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Sat, 2 May 2020 21:48:46 +0200 Subject: 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 Reviewed-on: https://review.coreboot.org/c/coreboot/+/40980 Tested-by: build bot (Jenkins) Reviewed-by: Arthur Heymans --- src/northbridge/intel/sandybridge/mchbar_regs.h | 37 +++++++++++--- src/northbridge/intel/sandybridge/raminit_common.c | 17 ++++++- src/northbridge/intel/sandybridge/raminit_common.h | 57 ++++++++++++++++++++++ 3 files changed, 104 insertions(+), 7 deletions(-) (limited to 'src/northbridge/intel') diff --git a/src/northbridge/intel/sandybridge/mchbar_regs.h b/src/northbridge/intel/sandybridge/mchbar_regs.h index 446861b4b7..0edfd5354a 100644 --- a/src/northbridge/intel/sandybridge/mchbar_regs.h +++ b/src/northbridge/intel/sandybridge/mchbar_regs.h @@ -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 */ diff --git a/src/northbridge/intel/sandybridge/raminit_common.c b/src/northbridge/intel/sandybridge/raminit_common.c index d66a0f0ed3..c4bf5ff50e 100644 --- a/src/northbridge/intel/sandybridge/raminit_common.c +++ b/src/northbridge/intel/sandybridge/raminit_common.c @@ -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) diff --git a/src/northbridge/intel/sandybridge/raminit_common.h b/src/northbridge/intel/sandybridge/raminit_common.h index c544cdebaf..6e76cbc0bb 100644 --- a/src/northbridge/intel/sandybridge/raminit_common.h +++ b/src/northbridge/intel/sandybridge/raminit_common.h @@ -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 -- cgit v1.2.3