aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge
diff options
context:
space:
mode:
authorAngel Pons <th3fanbus@gmail.com>2020-11-12 01:44:05 +0100
committerAngel Pons <th3fanbus@gmail.com>2020-11-19 22:52:16 +0000
commit6a8ddc7efb10bed1df8b19b0b0d9322516def5ed (patch)
treee6b66f490175c513dece8be0724727f3e1792a80 /src/northbridge
parent8f0757ea945d51d3ad64207673f7ead451fae736 (diff)
nb/intel/sandybridge: Extract some IOSAV sequences into macros
This allows deduplicating them while preserving reproducibility. Tested with BUILD_TIMELESS=1, Asus P8H61-M PRO remains identical. Change-Id: Ic7d1a5732296bb678b9954f80508e9f7de7ff319 Signed-off-by: Angel Pons <th3fanbus@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/47493 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Diffstat (limited to 'src/northbridge')
-rw-r--r--src/northbridge/intel/sandybridge/raminit_common.c1285
-rw-r--r--src/northbridge/intel/sandybridge/raminit_common.h612
2 files changed, 639 insertions, 1258 deletions
diff --git a/src/northbridge/intel/sandybridge/raminit_common.c b/src/northbridge/intel/sandybridge/raminit_common.c
index 204bc97b5d..4f0a8da3f7 100644
--- a/src/northbridge/intel/sandybridge/raminit_common.c
+++ b/src/northbridge/intel/sandybridge/raminit_common.c
@@ -533,26 +533,7 @@ static void write_reset(ramctr_timing *ctrl)
/* Choose a populated rank */
slotrank = (ctrl->rankmap[channel] & 1) ? 0 : 2;
- const struct iosav_ssq sequence[] = {
- /* DRAM command ZQCS */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_ZQCS,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = 8,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- },
- };
+ const struct iosav_ssq sequence[] = ZQCS_SEQUENCE(slotrank, 3, 8, 0);
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
/*
@@ -889,29 +870,7 @@ void dram_mrscommands(ramctr_timing *ctrl)
/* Drain */
wait_for_iosav(channel);
- const struct iosav_ssq zqcs_sequence[] = {
- /* DRAM command ZQCS */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_ZQCS,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 4,
- .post_ssq_wait = 101,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .addr_wrap = 31,
- },
- },
- };
+ const struct iosav_ssq zqcs_sequence[] = ZQCS_SEQUENCE(slotrank, 4, 101, 31);
iosav_write_sequence(channel, zqcs_sequence, ARRAY_SIZE(zqcs_sequence));
/* Execute command queue */
@@ -1072,93 +1031,8 @@ static void test_timA(ramctr_timing *ctrl, int channel, int slotrank)
{
wait_for_iosav(channel);
- const struct iosav_ssq sequence[] = {
- /*
- * DRAM command MRS
- *
- * Write MR3 MPR enable. In this mode only RD and RDA
- * are allowed, and all reads return a predefined pattern.
- */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_MRS,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = ctrl->tMOD,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 4,
- .rowbits = 6,
- .bank = 3,
- .rank = slotrank,
- },
- },
- /* DRAM command RD */
- [1] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_RD,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = 4,
- .data_direction = SSQ_RD,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- },
- /* DRAM command RD */
- [2] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_RD,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 15,
- .cmd_delay_gap = 4,
- .post_ssq_wait = ctrl->CAS + 36,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- },
- /*
- * DRAM command MRS
- *
- * Write MR3 MPR disable.
- */
- [3] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_MRS,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = ctrl->tMOD,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 3,
- .rank = slotrank,
- },
- },
- };
+ const struct iosav_ssq sequence[] =
+ READ_MPR_SEQUENCE(ctrl->tMOD, 1, 3, 15, ctrl->CAS + 36);
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
/* Execute command queue */
@@ -1420,27 +1294,7 @@ int read_training(ramctr_timing *ctrl)
wait_for_iosav(channel);
- const struct iosav_ssq sequence[] = {
- /* DRAM command PREA */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_PRE,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = ctrl->tRP,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 1024,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- },
- };
+ const struct iosav_ssq sequence[] = PREA_SEQUENCE(ctrl->tRP, 0);
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
/* Execute command queue */
@@ -1537,98 +1391,8 @@ static void test_timC(ramctr_timing *ctrl, int channel, int slotrank)
wait_for_iosav(channel);
- const struct iosav_ssq wr_sequence[] = {
- /* DRAM command ACT */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_ACT,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 4,
- .cmd_delay_gap = MAX(ctrl->tRRD, (ctrl->tFAW >> 2) + 1),
- .post_ssq_wait = ctrl->tRCD,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .inc_bank = 1,
- .addr_wrap = 18,
- },
- },
- /* DRAM command NOP */
- [1] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_NOP,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 4,
- .post_ssq_wait = 4,
- .data_direction = SSQ_WR,
- },
- .sp_cmd_addr = {
- .address = 8,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .addr_wrap = 31,
- },
- },
- /* DRAM command WR */
- [2] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_WR,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 500,
- .cmd_delay_gap = 4,
- .post_ssq_wait = 4,
- .data_direction = SSQ_WR,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .inc_addr_8 = 1,
- .addr_wrap = 18,
- },
- },
- /* DRAM command NOP */
- [3] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_NOP,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = ctrl->CWL + ctrl->tWTR + 5,
- .data_direction = SSQ_WR,
- },
- .sp_cmd_addr = {
- .address = 8,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .addr_wrap = 31,
- },
- },
- };
+ const struct iosav_ssq wr_sequence[] =
+ MISC_WRITE_SEQUENCE(MAX(ctrl->tRRD, (ctrl->tFAW >> 2) + 1), 4, 4, 500, 18);
iosav_write_sequence(channel, wr_sequence, ARRAY_SIZE(wr_sequence));
/* Execute command queue */
@@ -1763,30 +1527,7 @@ static int discover_timC(ramctr_timing *ctrl, int channel, int slotrank)
wait_for_iosav(channel);
- const struct iosav_ssq sequence[] = {
- /* DRAM command PREA */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_PRE,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = ctrl->tRP,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 1024,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .addr_wrap = 18,
- },
- },
- };
+ const struct iosav_ssq sequence[] = PREA_SEQUENCE(ctrl->tRP, 18);
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
/* Execute command queue */
@@ -1896,94 +1637,8 @@ static void precharge(ramctr_timing *ctrl)
FOR_ALL_POPULATED_RANKS {
wait_for_iosav(channel);
- const struct iosav_ssq sequence[] = {
- /*
- * DRAM command MRS
- *
- * Write MR3 MPR enable.
- * In this mode only RD and RDA are allowed,
- * and all reads return a predefined pattern.
- */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_MRS,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = ctrl->tMOD,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 4,
- .rowbits = 6,
- .bank = 3,
- .rank = slotrank,
- },
- },
- /* DRAM command RD */
- [1] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_RD,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 3,
- .cmd_delay_gap = 4,
- .post_ssq_wait = 4,
- .data_direction = SSQ_RD,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- },
- /* DRAM command RD */
- [2] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_RD,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 4,
- .post_ssq_wait = ctrl->CAS + 8,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- },
- /*
- * DRAM command MRS
- *
- * Write MR3 MPR disable.
- */
- [3] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_MRS,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = ctrl->tMOD,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 3,
- .rank = slotrank,
- },
- },
- };
+ const struct iosav_ssq sequence[] =
+ READ_MPR_SEQUENCE(ctrl->tMOD, 3, 4, 1, ctrl->CAS + 8);
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
/* Execute command queue */
@@ -2002,94 +1657,8 @@ static void precharge(ramctr_timing *ctrl)
FOR_ALL_POPULATED_RANKS {
wait_for_iosav(channel);
- const struct iosav_ssq sequence[] = {
- /*
- * DRAM command MRS
- *
- * Write MR3 MPR enable.
- * In this mode only RD and RDA are allowed,
- * and all reads return a predefined pattern.
- */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_MRS,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = ctrl->tMOD,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 4,
- .rowbits = 6,
- .bank = 3,
- .rank = slotrank,
- },
- },
- /* DRAM command RD */
- [1] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_RD,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 3,
- .cmd_delay_gap = 4,
- .post_ssq_wait = 4,
- .data_direction = SSQ_RD,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- },
- /* DRAM command RD */
- [2] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_RD,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 4,
- .post_ssq_wait = ctrl->CAS + 8,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- },
- /*
- * DRAM command MRS
- *
- * Write MR3 MPR disable.
- */
- [3] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_MRS,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = ctrl->tMOD,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 3,
- .rank = slotrank,
- },
- },
- };
+ const struct iosav_ssq sequence[] =
+ READ_MPR_SEQUENCE(ctrl->tMOD, 3, 4, 1, ctrl->CAS + 8);
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
/* Execute command queue */
@@ -2245,94 +1814,7 @@ static void train_write_flyby(ramctr_timing *ctrl)
wait_for_iosav(channel);
- const struct iosav_ssq wr_sequence[] = {
- /* DRAM command ACT */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_ACT,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = ctrl->tRCD,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- },
- /* DRAM command NOP */
- [1] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_NOP,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = 4,
- .data_direction = SSQ_WR,
- },
- .sp_cmd_addr = {
- .address = 8,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .addr_wrap = 31,
- },
- },
- /* DRAM command WR */
- [2] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_WR,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 3,
- .cmd_delay_gap = 4,
- .post_ssq_wait = 4,
- .data_direction = SSQ_WR,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .inc_addr_8 = 1,
- .addr_wrap = 31,
- },
- },
- /* DRAM command NOP */
- [3] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_NOP,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = ctrl->CWL + ctrl->tWTR + 5,
- .data_direction = SSQ_WR,
- },
- .sp_cmd_addr = {
- .address = 8,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .addr_wrap = 31,
- },
- },
- };
+ const struct iosav_ssq wr_sequence[] = MISC_WRITE_SEQUENCE(3, 1, 3, 3, 31);
iosav_write_sequence(channel, wr_sequence, ARRAY_SIZE(wr_sequence));
/* Execute command queue */
@@ -2435,29 +1917,7 @@ static void write_op(ramctr_timing *ctrl, int channel)
/* choose an existing rank. */
slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
- const struct iosav_ssq sequence[] = {
- /* DRAM command ZQCS */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_ZQCS,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 4,
- .post_ssq_wait = 4,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .addr_wrap = 31,
- },
- },
- };
+ const struct iosav_ssq sequence[] = ZQCS_SEQUENCE(slotrank, 4, 4, 31);
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
/* Execute command queue */
@@ -2532,29 +1992,7 @@ int write_training(ramctr_timing *ctrl)
MCHBAR32(IOSAV_STATUS_ch(channel));
wait_for_iosav(channel);
- const struct iosav_ssq sequence[] = {
- /* DRAM command ZQCS */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_ZQCS,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 4,
- .post_ssq_wait = 101,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 0,
- .rank = 0,
- },
- .addr_update = {
- .addr_wrap = 31,
- },
- },
- };
+ const struct iosav_ssq sequence[] = ZQCS_SEQUENCE(0, 4, 101, 31);
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
/* Execute command queue */
@@ -2621,103 +2059,7 @@ static int test_command_training(ramctr_timing *ctrl, int channel, int slotrank)
wait_for_iosav(channel);
- const struct iosav_ssq sequence[] = {
- /* DRAM command ACT */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_ACT,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 8,
- .cmd_delay_gap = MAX(ctrl->tRRD, (ctrl->tFAW >> 2) + 1),
- .post_ssq_wait = ctrl->tRCD,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = ctr,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .inc_bank = 1,
- .addr_wrap = 18,
- },
- },
- /* DRAM command WR */
- [1] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_WR,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 32,
- .cmd_delay_gap = 4,
- .post_ssq_wait = ctrl->CWL + ctrl->tWTR + 8,
- .data_direction = SSQ_WR,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .inc_addr_8 = 1,
- .addr_wrap = 18,
- .lfsr_upd = 3,
- .lfsr_xors = 2,
- },
- },
- /* DRAM command RD */
- [2] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_RD,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 32,
- .cmd_delay_gap = 4,
- .post_ssq_wait = MAX(ctrl->tRTP, 8),
- .data_direction = SSQ_RD,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .inc_addr_8 = 1,
- .addr_wrap = 18,
- .lfsr_upd = 3,
- .lfsr_xors = 2,
- },
- },
- /* DRAM command PRE */
- [3] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_PRE,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 4,
- .post_ssq_wait = 15,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 1024,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .addr_wrap = 18,
- },
- },
- };
+ const struct iosav_ssq sequence[] = COMMAND_TRAINING_SEQUENCE(ctr);
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
/* Program LFSR for the RD/WR subsequences */
@@ -2786,29 +2128,7 @@ static void reprogram_320c(ramctr_timing *ctrl)
/* Choose an existing rank */
slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
- const struct iosav_ssq sequence[] = {
- /* DRAM command ZQCS */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_ZQCS,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 4,
- .post_ssq_wait = 4,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .addr_wrap = 31,
- },
- },
- };
+ const struct iosav_ssq sequence[] = ZQCS_SEQUENCE(slotrank, 4, 4, 31);
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
/* Execute command queue */
@@ -2826,29 +2146,7 @@ static void reprogram_320c(ramctr_timing *ctrl)
/* choose an existing rank. */
slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
- const struct iosav_ssq sequence[] = {
- /* DRAM command ZQCS */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_ZQCS,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 4,
- .post_ssq_wait = 4,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .addr_wrap = 31,
- },
- },
- };
+ const struct iosav_ssq sequence[] = ZQCS_SEQUENCE(slotrank, 4, 4, 31);
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
/* Execute command queue */
@@ -3010,94 +2308,8 @@ static int discover_edges_real(ramctr_timing *ctrl, int channel, int slotrank, i
wait_for_iosav(channel);
- const struct iosav_ssq sequence[] = {
- /*
- * DRAM command MRS
- *
- * Write MR3 MPR enable.
- * In this mode only RD and RDA are allowed,
- * and all reads return a predefined pattern.
- */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_MRS,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = ctrl->tMOD,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 4,
- .rowbits = 6,
- .bank = 3,
- .rank = slotrank,
- },
- },
- /* DRAM command RD */
- [1] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_RD,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 500,
- .cmd_delay_gap = 4,
- .post_ssq_wait = 4,
- .data_direction = SSQ_RD,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- },
- /* DRAM command RD */
- [2] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_RD,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 4,
- .post_ssq_wait = ctrl->CAS + 8,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- },
- /*
- * DRAM command MRS
- *
- * Write MR3 MPR disable.
- */
- [3] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_MRS,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = ctrl->tMOD,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 3,
- .rank = slotrank,
- },
- },
- };
+ const struct iosav_ssq sequence[] =
+ READ_MPR_SEQUENCE(ctrl->tMOD, 500, 4, 1, ctrl->CAS + 8);
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
/* Execute command queue */
@@ -3155,94 +2367,8 @@ int discover_edges(ramctr_timing *ctrl)
FOR_ALL_POPULATED_RANKS {
wait_for_iosav(channel);
- const struct iosav_ssq sequence[] = {
- /*
- * DRAM command MRS
- *
- * Write MR3 MPR enable.
- * In this mode only RD and RDA are allowed,
- * and all reads return a predefined pattern.
- */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_MRS,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = ctrl->tMOD,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 4,
- .rowbits = 6,
- .bank = 3,
- .rank = slotrank,
- },
- },
- /* DRAM command RD */
- [1] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_RD,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 3,
- .cmd_delay_gap = 4,
- .post_ssq_wait = 4,
- .data_direction = SSQ_RD,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- },
- /* DRAM command RD */
- [2] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_RD,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 4,
- .post_ssq_wait = ctrl->CAS + 8,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- },
- /*
- * DRAM command MRS
- *
- * Write MR3 MPR disable.
- */
- [3] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_MRS,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = ctrl->tMOD,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 3,
- .rank = slotrank,
- },
- },
- };
+ const struct iosav_ssq sequence[] =
+ READ_MPR_SEQUENCE(ctrl->tMOD, 3, 4, 1, ctrl->CAS + 8);
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
/* Execute command queue */
@@ -3263,94 +2389,8 @@ int discover_edges(ramctr_timing *ctrl)
FOR_ALL_POPULATED_RANKS {
wait_for_iosav(channel);
- const struct iosav_ssq sequence[] = {
- /*
- * DRAM command MRS
- *
- * Write MR3 MPR enable.
- * In this mode only RD and RDA are allowed,
- * and all reads return a predefined pattern.
- */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_MRS,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = ctrl->tMOD,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 4,
- .rowbits = 6,
- .bank = 3,
- .rank = slotrank,
- },
- },
- /* DRAM command RD */
- [1] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_RD,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 3,
- .cmd_delay_gap = 4,
- .post_ssq_wait = 4,
- .data_direction = SSQ_RD,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- },
- /* DRAM command RD */
- [2] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_RD,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 4,
- .post_ssq_wait = ctrl->CAS + 8,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- },
- /*
- * DRAM command MRS
- *
- * Write MR3 MPR disable.
- */
- [3] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_MRS,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = ctrl->tMOD,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 3,
- .rank = slotrank,
- },
- },
- };
+ const struct iosav_ssq sequence[] =
+ READ_MPR_SEQUENCE(ctrl->tMOD, 3, 4, 1, ctrl->CAS + 8);
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
/* Execute command queue */
@@ -3451,97 +2491,7 @@ static int discover_edges_write_real(ramctr_timing *ctrl, int channel, int slotr
}
wait_for_iosav(channel);
- const struct iosav_ssq sequence[] = {
- /* DRAM command ACT */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_ACT,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 4,
- .cmd_delay_gap = MAX(ctrl->tRRD,
- (ctrl->tFAW >> 2) + 1),
- .post_ssq_wait = ctrl->tRCD,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .addr_wrap = 18,
- },
- },
- /* DRAM command WR */
- [1] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_WR,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 32,
- .cmd_delay_gap = 20,
- .post_ssq_wait = ctrl->tWTR +
- ctrl->CWL + 8,
- .data_direction = SSQ_WR,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .inc_addr_8 = 1,
- .addr_wrap = 18,
- },
- },
- /* DRAM command RD */
- [2] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_RD,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 32,
- .cmd_delay_gap = 20,
- .post_ssq_wait = MAX(ctrl->tRTP, 8),
- .data_direction = SSQ_RD,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .inc_addr_8 = 1,
- .addr_wrap = 18,
- },
- },
- /* DRAM command PRE */
- [3] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_PRE,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = ctrl->tRP,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 1024,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- },
- };
+ const struct iosav_ssq sequence[] = WRITE_DATA_SEQUENCE;
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
/* Execute command queue */
@@ -3640,96 +2590,7 @@ static void test_timC_write(ramctr_timing *ctrl, int channel, int slotrank)
{
wait_for_iosav(channel);
- const struct iosav_ssq sequence[] = {
- /* DRAM command ACT */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_ACT,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 4,
- .cmd_delay_gap = MAX((ctrl->tFAW >> 2) + 1, ctrl->tRRD),
- .post_ssq_wait = ctrl->tRCD,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .inc_bank = 1,
- .addr_wrap = 18,
- },
- },
- /* DRAM command WR */
- [1] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_WR,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 480,
- .cmd_delay_gap = 4,
- .post_ssq_wait = ctrl->tWTR + ctrl->CWL + 8,
- .data_direction = SSQ_WR,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .inc_addr_8 = 1,
- .addr_wrap = 18,
- },
- },
- /* DRAM command RD */
- [2] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_RD,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 480,
- .cmd_delay_gap = 4,
- .post_ssq_wait = MAX(ctrl->tRTP, 8),
- .data_direction = SSQ_RD,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .inc_addr_8 = 1,
- .addr_wrap = 18,
- },
- },
- /* DRAM command PRE */
- [3] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_PRE,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 4,
- .post_ssq_wait = ctrl->tRP,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 1024,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- },
- };
+ const struct iosav_ssq sequence[] = AGGRESSIVE_WRITE_READ_SEQUENCE;
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
/* Execute command queue */
@@ -3906,99 +2767,7 @@ int channel_test(ramctr_timing *ctrl)
}
wait_for_iosav(channel);
- const struct iosav_ssq sequence[] = {
- /* DRAM command ACT */
- [0] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_ACT,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 4,
- .cmd_delay_gap = 8,
- .post_ssq_wait = 40,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .inc_bank = 1,
- .addr_wrap = 18,
- },
- },
- /* DRAM command WR */
- [1] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_WR,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 100,
- .cmd_delay_gap = 4,
- .post_ssq_wait = 40,
- .data_direction = SSQ_WR,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .inc_addr_8 = 1,
- .addr_wrap = 18,
- },
- },
- /* DRAM command RD */
- [2] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_RD,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 100,
- .cmd_delay_gap = 4,
- .post_ssq_wait = 40,
- .data_direction = SSQ_RD,
- },
- .sp_cmd_addr = {
- .address = 0,
- .rowbits = 0,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .inc_addr_8 = 1,
- .addr_wrap = 18,
- },
- },
- /* DRAM command PRE */
- [3] = {
- .sp_cmd_ctrl = {
- .command = IOSAV_PRE,
- .ranksel_ap = 1,
- },
- .subseq_ctrl = {
- .cmd_executions = 1,
- .cmd_delay_gap = 3,
- .post_ssq_wait = 40,
- .data_direction = SSQ_NA,
- },
- .sp_cmd_addr = {
- .address = 1024,
- .rowbits = 6,
- .bank = 0,
- .rank = slotrank,
- },
- .addr_update = {
- .addr_wrap = 18,
- },
- },
- };
+ const struct iosav_ssq sequence[] = MEMORY_TEST_SEQUENCE;
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
/* Execute command queue */
diff --git a/src/northbridge/intel/sandybridge/raminit_common.h b/src/northbridge/intel/sandybridge/raminit_common.h
index a8644ae6bc..3937f414d2 100644
--- a/src/northbridge/intel/sandybridge/raminit_common.h
+++ b/src/northbridge/intel/sandybridge/raminit_common.h
@@ -98,6 +98,618 @@ struct iosav_ssq {
} addr_update;
};
+#define ZQCS_SEQUENCE(slotrank, gap, post, wrap) \
+ { \
+ /* DRAM command ZQCS */ \
+ [0] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_ZQCS, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 1, \
+ .cmd_delay_gap = gap, \
+ .post_ssq_wait = post, \
+ .data_direction = SSQ_NA, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 0, \
+ .rowbits = 6, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .addr_wrap = wrap, \
+ }, \
+ }, \
+ }
+
+#define PREA_SEQUENCE(t_rp, wrap) \
+ { \
+ /* DRAM command PREA */ \
+ [0] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_PRE, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 1, \
+ .cmd_delay_gap = 3, \
+ .post_ssq_wait = t_rp, \
+ .data_direction = SSQ_NA, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 1024, \
+ .rowbits = 6, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .addr_wrap = wrap, \
+ }, \
+ }, \
+ }
+
+#define READ_MPR_SEQUENCE(t_mod, loops, gap, loops2, post2) \
+ { \
+ /* \
+ * DRAM command MRS \
+ * \
+ * Write MR3 MPR enable. In this mode only RD and RDA \
+ * are allowed, and all reads return a predefined pattern. \
+ */ \
+ [0] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_MRS, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 1, \
+ .cmd_delay_gap = 3, \
+ .post_ssq_wait = t_mod, \
+ .data_direction = SSQ_NA, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 4, \
+ .rowbits = 6, \
+ .bank = 3, \
+ .rank = slotrank, \
+ }, \
+ }, \
+ /* DRAM command RD */ \
+ [1] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_RD, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = loops, \
+ .cmd_delay_gap = gap, \
+ .post_ssq_wait = 4, \
+ .data_direction = SSQ_RD, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 0, \
+ .rowbits = 0, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ }, \
+ /* DRAM command RD */ \
+ [2] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_RD, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = loops2, \
+ .cmd_delay_gap = 4, \
+ .post_ssq_wait = post2, \
+ .data_direction = SSQ_NA, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 0, \
+ .rowbits = 6, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ }, \
+ /* \
+ * DRAM command MRS \
+ * \
+ * Write MR3 MPR disable. \
+ */ \
+ [3] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_MRS, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 1, \
+ .cmd_delay_gap = 3, \
+ .post_ssq_wait = t_mod, \
+ .data_direction = SSQ_NA, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 0, \
+ .rowbits = 6, \
+ .bank = 3, \
+ .rank = slotrank, \
+ }, \
+ }, \
+ }
+
+#define MISC_WRITE_SEQUENCE(gap0, loops0, gap1, loops2, wrap2) \
+ { \
+ /* DRAM command ACT */ \
+ [0] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_ACT, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = loops0, \
+ .cmd_delay_gap = gap0, \
+ .post_ssq_wait = ctrl->tRCD, \
+ .data_direction = SSQ_NA, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 0, \
+ .rowbits = 6, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .inc_bank = loops0 == 1 ? 0 : 1, \
+ .addr_wrap = loops0 == 1 ? 0 : 18, \
+ }, \
+ }, \
+ /* DRAM command NOP */ \
+ [1] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_NOP, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 1, \
+ .cmd_delay_gap = gap1, \
+ .post_ssq_wait = 4, \
+ .data_direction = SSQ_WR, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 8, \
+ .rowbits = 0, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .addr_wrap = 31, \
+ }, \
+ }, \
+ /* DRAM command WR */ \
+ [2] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_WR, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = loops2, \
+ .cmd_delay_gap = 4, \
+ .post_ssq_wait = 4, \
+ .data_direction = SSQ_WR, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 0, \
+ .rowbits = 0, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .inc_addr_8 = 1, \
+ .addr_wrap = wrap2, \
+ }, \
+ }, \
+ /* DRAM command NOP */ \
+ [3] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_NOP, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 1, \
+ .cmd_delay_gap = 3, \
+ .post_ssq_wait = ctrl->CWL + ctrl->tWTR + 5, \
+ .data_direction = SSQ_WR, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 8, \
+ .rowbits = 0, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .addr_wrap = 31, \
+ }, \
+ }, \
+ }
+
+#define COMMAND_TRAINING_SEQUENCE(ctr) \
+ { \
+ /* DRAM command ACT */ \
+ [0] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_ACT, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 8, \
+ .cmd_delay_gap = MAX(ctrl->tRRD, (ctrl->tFAW >> 2) + 1), \
+ .post_ssq_wait = ctrl->tRCD, \
+ .data_direction = SSQ_NA, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = ctr, \
+ .rowbits = 6, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .inc_bank = 1, \
+ .addr_wrap = 18, \
+ }, \
+ }, \
+ /* DRAM command WR */ \
+ [1] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_WR, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 32, \
+ .cmd_delay_gap = 4, \
+ .post_ssq_wait = ctrl->CWL + ctrl->tWTR + 8, \
+ .data_direction = SSQ_WR, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 0, \
+ .rowbits = 0, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .inc_addr_8 = 1, \
+ .addr_wrap = 18, \
+ .lfsr_upd = 3, \
+ .lfsr_xors = 2, \
+ }, \
+ }, \
+ /* DRAM command RD */ \
+ [2] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_RD, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 32, \
+ .cmd_delay_gap = 4, \
+ .post_ssq_wait = MAX(ctrl->tRTP, 8), \
+ .data_direction = SSQ_RD, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 0, \
+ .rowbits = 0, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .inc_addr_8 = 1, \
+ .addr_wrap = 18, \
+ .lfsr_upd = 3, \
+ .lfsr_xors = 2, \
+ }, \
+ }, \
+ /* DRAM command PRE */ \
+ [3] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_PRE, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 1, \
+ .cmd_delay_gap = 4, \
+ .post_ssq_wait = 15, \
+ .data_direction = SSQ_NA, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 1024, \
+ .rowbits = 6, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .addr_wrap = 18, \
+ }, \
+ }, \
+ }
+
+#define WRITE_DATA_SEQUENCE \
+ { \
+ /* DRAM command ACT */ \
+ [0] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_ACT, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 4, \
+ .cmd_delay_gap = MAX(ctrl->tRRD, (ctrl->tFAW >> 2) + 1), \
+ .post_ssq_wait = ctrl->tRCD, \
+ .data_direction = SSQ_NA, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 0, \
+ .rowbits = 6, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .inc_bank = 0, \
+ .addr_wrap = 18, \
+ }, \
+ }, \
+ /* DRAM command WR */ \
+ [1] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_WR, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 32, \
+ .cmd_delay_gap = 20, \
+ .post_ssq_wait = ctrl->CWL + ctrl->tWTR + 8, \
+ .data_direction = SSQ_WR, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 0, \
+ .rowbits = 0, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .inc_addr_8 = 1, \
+ .addr_wrap = 18, \
+ }, \
+ }, \
+ /* DRAM command RD */ \
+ [2] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_RD, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 32, \
+ .cmd_delay_gap = 20, \
+ .post_ssq_wait = MAX(ctrl->tRTP, 8), \
+ .data_direction = SSQ_RD, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 0, \
+ .rowbits = 0, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .inc_addr_8 = 1, \
+ .addr_wrap = 18, \
+ }, \
+ }, \
+ /* DRAM command PRE */ \
+ [3] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_PRE, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 1, \
+ .cmd_delay_gap = 3, \
+ .post_ssq_wait = ctrl->tRP, \
+ .data_direction = SSQ_NA, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 1024, \
+ .rowbits = 6, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ }, \
+ }
+
+#define AGGRESSIVE_WRITE_READ_SEQUENCE \
+ { \
+ /* DRAM command ACT */ \
+ [0] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_ACT, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 4, \
+ .cmd_delay_gap = MAX((ctrl->tFAW >> 2) + 1, ctrl->tRRD), \
+ .post_ssq_wait = ctrl->tRCD, \
+ .data_direction = SSQ_NA, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 0, \
+ .rowbits = 6, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .inc_bank = 1, \
+ .addr_wrap = 18, \
+ }, \
+ }, \
+ /* DRAM command WR */ \
+ [1] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_WR, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 480, \
+ .cmd_delay_gap = 4, \
+ .post_ssq_wait = ctrl->tWTR + ctrl->CWL + 8, \
+ .data_direction = SSQ_WR, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 0, \
+ .rowbits = 0, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .inc_addr_8 = 1, \
+ .addr_wrap = 18, \
+ }, \
+ }, \
+ /* DRAM command RD */ \
+ [2] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_RD, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 480, \
+ .cmd_delay_gap = 4, \
+ .post_ssq_wait = MAX(ctrl->tRTP, 8), \
+ .data_direction = SSQ_RD, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 0, \
+ .rowbits = 0, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .inc_addr_8 = 1, \
+ .addr_wrap = 18, \
+ }, \
+ }, \
+ /* DRAM command PRE */ \
+ [3] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_PRE, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 1, \
+ .cmd_delay_gap = 4, \
+ .post_ssq_wait = ctrl->tRP, \
+ .data_direction = SSQ_NA, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 1024, \
+ .rowbits = 6, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ }, \
+ }
+
+#define MEMORY_TEST_SEQUENCE \
+ { \
+ /* DRAM command ACT */ \
+ [0] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_ACT, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 4, \
+ .cmd_delay_gap = 8, \
+ .post_ssq_wait = 40, \
+ .data_direction = SSQ_NA, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 0, \
+ .rowbits = 6, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .inc_bank = 1, \
+ .addr_wrap = 18, \
+ }, \
+ }, \
+ /* DRAM command WR */ \
+ [1] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_WR, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 100, \
+ .cmd_delay_gap = 4, \
+ .post_ssq_wait = 40, \
+ .data_direction = SSQ_WR, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 0, \
+ .rowbits = 0, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .inc_addr_8 = 1, \
+ .addr_wrap = 18, \
+ }, \
+ }, \
+ /* DRAM command RD */ \
+ [2] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_RD, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 100, \
+ .cmd_delay_gap = 4, \
+ .post_ssq_wait = 40, \
+ .data_direction = SSQ_RD, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 0, \
+ .rowbits = 0, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .inc_addr_8 = 1, \
+ .addr_wrap = 18, \
+ }, \
+ }, \
+ /* DRAM command PRE */ \
+ [3] = { \
+ .sp_cmd_ctrl = { \
+ .command = IOSAV_PRE, \
+ .ranksel_ap = 1, \
+ }, \
+ .subseq_ctrl = { \
+ .cmd_executions = 1, \
+ .cmd_delay_gap = 3, \
+ .post_ssq_wait = 40, \
+ .data_direction = SSQ_NA, \
+ }, \
+ .sp_cmd_addr = { \
+ .address = 1024, \
+ .rowbits = 6, \
+ .bank = 0, \
+ .rank = slotrank, \
+ }, \
+ .addr_update = { \
+ .addr_wrap = 18, \
+ }, \
+ }, \
+ }
+
void iosav_write_sequence(const int ch, const struct iosav_ssq *seq, const unsigned int length);
void iosav_run_queue(const int ch, const u8 loops, const u8 as_timer);
void iosav_run_once(const int ch);