diff --git a/src/northbridge/intel/sandybridge/mchbar_regs.h b/src/northbridge/intel/sandybridge/mchbar_regs.h index 742c499433..849a8927a6 100644 --- a/src/northbridge/intel/sandybridge/mchbar_regs.h +++ b/src/northbridge/intel/sandybridge/mchbar_regs.h @@ -188,64 +188,6 @@ * [6] Cleared with a new sequence, and set when done and refresh counter is drained. */ -/* Temporary IOSAV register macros to verifiably split bitfields */ -#define SUBSEQ_CTRL(reps, gap, post, dir) (((reps) << 0) | \ - ((gap) << 10) | \ - ((post) << 16) | \ - ((dir) << 26)) - -#define SSQ_NA 0 /* Non-data */ -#define SSQ_RD 1 /* Read */ -#define SSQ_WR 2 /* Write */ -#define SSQ_RW 3 /* Read and write */ - -#define SP_CMD_ADDR(addr, rowbits, bank, rank) (((addr) << 0) | \ - ((rowbits) << 16) | \ - ((bank) << 20) | \ - ((rank) << 24)) - -#define ADDR_UPDATE(addr_1, addr_8, bank, rank, wrap, lfsr, rate, xors) (((addr_1) << 0) | \ - ((addr_8) << 1) | \ - ((bank) << 2) | \ - ((rank) << 3) | \ - ((wrap) << 5) | \ - ((lfsr) << 10) | \ - ((rate) << 12) | \ - ((xors) << 16)) - -#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, &ssq); \ - } while (0) - /* Indexed register helper macros */ #define Gz(r, z) ((r) + ((z) << 8)) #define Ly(r, y) ((r) + ((y) << 2)) diff --git a/src/northbridge/intel/sandybridge/raminit_common.c b/src/northbridge/intel/sandybridge/raminit_common.c index b5d337dc74..371527e9ef 100644 --- a/src/northbridge/intel/sandybridge/raminit_common.c +++ b/src/northbridge/intel/sandybridge/raminit_common.c @@ -594,11 +594,26 @@ static void write_reset(ramctr_timing *ctrl) slotrank = (ctrl->rankmap[channel] & 1) ? 0 : 2; /* DRAM command ZQCS */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_ZQCS, 0, - 1, 3, 8, SSQ_NA, - 0, 6, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* * Execute command queue - why is bit 22 set here?! @@ -687,25 +702,71 @@ static void write_mrreg(ramctr_timing *ctrl, int channel, int slotrank, int reg, } /* DRAM command MRS */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_MRS, 0, - 1, 4, 4, SSQ_NA, - val, 6, reg, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .sp_cmd_ctrl = { + .command = IOSAV_MRS, + }, + .subseq_ctrl = { + .cmd_executions = 1, + .cmd_delay_gap = 4, + .post_ssq_wait = 4, + .data_direction = SSQ_NA, + }, + .sp_cmd_addr = { + .address = val, + .rowbits = 6, + .bank = reg, + .rank = slotrank, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command MRS */ - IOSAV_SUBSEQUENCE(channel, 1, - IOSAV_MRS, 1, - 1, 4, 4, SSQ_NA, - val, 6, reg, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .sp_cmd_ctrl = { + .command = IOSAV_MRS, + .ranksel_ap = 1, + }, + .subseq_ctrl = { + .cmd_executions = 1, + .cmd_delay_gap = 4, + .post_ssq_wait = 4, + .data_direction = SSQ_NA, + }, + .sp_cmd_addr = { + .address = val, + .rowbits = 6, + .bank = reg, + .rank = slotrank, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command MRS */ - IOSAV_SUBSEQUENCE(channel, 2, - IOSAV_MRS, 0, - 1, 4, ctrl->tMOD, SSQ_NA, - val, 6, reg, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .sp_cmd_ctrl = { + .command = IOSAV_MRS, + }, + .subseq_ctrl = { + .cmd_executions = 1, + .cmd_delay_gap = 4, + .post_ssq_wait = ctrl->tMOD, + .data_direction = SSQ_NA, + }, + .sp_cmd_addr = { + .address = val, + .rowbits = 6, + .bank = reg, + .rank = slotrank, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -831,18 +892,53 @@ void dram_mrscommands(ramctr_timing *ctrl) } /* DRAM command NOP (without ODT nor chip selects) */ - IOSAV_SUBSEQUENCE(BROADCAST_CH, 0, - IOSAV_NOP & ~(0xff << 8), 0, - 1, 4, 15, SSQ_NA, - 2, 6, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .sp_cmd_ctrl = { + .command = IOSAV_NOP & ~(0xff << 8), + }, + .subseq_ctrl = { + .cmd_executions = 1, + .cmd_delay_gap = 4, + .post_ssq_wait = 15, + .data_direction = SSQ_NA, + }, + .sp_cmd_addr = { + .address = 2, + .rowbits = 6, + .bank = 0, + .rank = 0, + }, + }; + iosav_write_ssq(BROADCAST_CH, &ssq); + } /* DRAM command ZQCL */ - IOSAV_SUBSEQUENCE(BROADCAST_CH, 1, - IOSAV_ZQCS, 1, - 1, 4, 400, SSQ_NA, - 1024, 6, 0, 0, - 0, 0, 0, 1, 20, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .sp_cmd_ctrl = { + .command = IOSAV_ZQCS, + .ranksel_ap = 1, + }, + .subseq_ctrl = { + .cmd_executions = 1, + .cmd_delay_gap = 4, + .post_ssq_wait = 400, + .data_direction = SSQ_NA, + }, + .sp_cmd_addr = { + .address = 1024, + .rowbits = 6, + .bank = 0, + .rank = 0, + }, + .addr_update = { + .inc_rank = 1, + .addr_wrap = 20, + }, + }; + iosav_write_ssq(BROADCAST_CH, &ssq); + } /* Execute command queue on all channels. Do it four times. */ iosav_run_queue(BROADCAST_CH, 4, 0); @@ -866,11 +962,29 @@ void dram_mrscommands(ramctr_timing *ctrl) wait_for_iosav(channel); /* DRAM command ZQCS */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_ZQCS, 0, - 1, 4, 101, SSQ_NA, - 0, 6, 0, slotrank, - 0, 0, 0, 0, 31, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -1030,37 +1144,106 @@ static void test_timA(ramctr_timing *ctrl, int channel, int slotrank) { wait_for_iosav(channel); - /* DRAM command MRS - write MR3 MPR enable - in this mode only RD and RDA are allowed - all reads return a predefined pattern */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_MRS, 1, - 1, 3, ctrl->tMOD, SSQ_NA, - 4, 6, 3, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + /* + * DRAM command MRS + * + * Write MR3 MPR enable. + * In this mode only RD and RDA are allowed, and all reads return a predefined pattern. + */ + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command RD */ - IOSAV_SUBSEQUENCE(channel, 1, - IOSAV_RD, 1, - 1, 3, 4, SSQ_RD, - 0, 0, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command RD */ - IOSAV_SUBSEQUENCE(channel, 2, - IOSAV_RD, 1, - 15, 4, ctrl->CAS + 36, SSQ_NA, - 0, 6, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } - /* DRAM command MRS - write MR3 MPR disable */ - IOSAV_SUBSEQUENCE(channel, 3, - IOSAV_MRS, 1, - 1, 3, ctrl->tMOD, SSQ_NA, - 0, 6, 3, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + /* + * DRAM command MRS + * + * Write MR3 MPR disable. + */ + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -1322,11 +1505,27 @@ int read_training(ramctr_timing *ctrl) wait_for_iosav(channel); /* DRAM command PREA */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_PRE, 1, - 1, 3, ctrl->tRP, SSQ_NA, - 1024, 6, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -1423,32 +1622,110 @@ static void test_timC(ramctr_timing *ctrl, int channel, int slotrank) wait_for_iosav(channel); /* DRAM command ACT */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_ACT, 1, - 4, MAX(ctrl->tRRD, (ctrl->tFAW >> 2) + 1), ctrl->tRCD, SSQ_NA, - 0, 6, 0, slotrank, - 0, 0, 1, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command NOP */ - IOSAV_SUBSEQUENCE(channel, 1, - IOSAV_NOP, 1, - 1, 4, 4, SSQ_WR, - 8, 0, 0, slotrank, - 0, 0, 0, 0, 31, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command WR */ - IOSAV_SUBSEQUENCE(channel, 2, - IOSAV_WR, 1, - 500, 4, 4, SSQ_WR, - 0, 0, 0, slotrank, - 0, 1, 0, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command NOP */ - IOSAV_SUBSEQUENCE(channel, 3, - IOSAV_NOP, 1, - 1, 3, ctrl->CWL + ctrl->tWTR + 5, SSQ_WR, - 8, 0, 0, slotrank, - 0, 0, 0, 0, 31, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -1456,32 +1733,110 @@ static void test_timC(ramctr_timing *ctrl, int channel, int slotrank) wait_for_iosav(channel); /* DRAM command PREA */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_PRE, 1, - 1, 3, ctrl->tRP, SSQ_NA, - 1024, 6, 0, slotrank, - 0, 0, 0, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command ACT */ - IOSAV_SUBSEQUENCE(channel, 1, - IOSAV_ACT, 1, - 8, MAX(ctrl->tRRD, (ctrl->tFAW >> 2) + 1), ctrl->CAS, SSQ_NA, - 0, 6, 0, slotrank, - 0, 0, 1, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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->CAS, + .data_direction = SSQ_NA, + }, + .sp_cmd_addr = { + .address = 0, + .rowbits = 6, + .bank = 0, + .rank = slotrank, + }, + .addr_update = { + .inc_bank = 1, + .addr_wrap = 18, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command RD */ - IOSAV_SUBSEQUENCE(channel, 2, - IOSAV_RD, 1, - 500, 4, MAX(ctrl->tRTP, 8), SSQ_RD, - 0, 0, 0, slotrank, - 0, 1, 0, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .sp_cmd_ctrl = { + .command = IOSAV_RD, + .ranksel_ap = 1, + }, + .subseq_ctrl = { + .cmd_executions = 500, + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command PREA */ - IOSAV_SUBSEQUENCE(channel, 3, - IOSAV_PRE, 1, - 1, 3, ctrl->tRP, SSQ_NA, - 1024, 6, 0, slotrank, - 0, 0, 0, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -1517,11 +1872,30 @@ static int discover_timC(ramctr_timing *ctrl, int channel, int slotrank) wait_for_iosav(channel); /* DRAM command PREA */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_PRE, 1, - 1, 3, ctrl->tRP, SSQ_NA, - 1024, 6, 0, slotrank, - 0, 0, 0, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -1620,37 +1994,107 @@ static void precharge(ramctr_timing *ctrl) FOR_ALL_POPULATED_RANKS { wait_for_iosav(channel); - /* DRAM command MRS - write MR3 MPR enable - in this mode only RD and RDA are allowed - all reads return a predefined pattern */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_MRS, 1, - 1, 3, ctrl->tMOD, SSQ_NA, - 4, 6, 3, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + /* + * DRAM command MRS + * + * Write MR3 MPR enable. + * In this mode only RD and RDA are allowed, + * and all reads return a predefined pattern. + */ + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command RD */ - IOSAV_SUBSEQUENCE(channel, 1, - IOSAV_RD, 1, - 3, 4, 4, SSQ_RD, - 0, 0, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command RD */ - IOSAV_SUBSEQUENCE(channel, 2, - IOSAV_RD, 1, - 1, 4, ctrl->CAS + 8, SSQ_NA, - 0, 6, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } - /* DRAM command MRS - * write MR3 MPR disable */ - IOSAV_SUBSEQUENCE(channel, 3, - IOSAV_MRS, 1, - 1, 3, ctrl->tMOD, SSQ_NA, - 0, 6, 3, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + /* + * DRAM command MRS + * + * Write MR3 MPR disable. + */ + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -1667,37 +2111,108 @@ static void precharge(ramctr_timing *ctrl) FOR_ALL_POPULATED_RANKS { wait_for_iosav(channel); - /* DRAM command MRS - * write MR3 MPR enable - * in this mode only RD and RDA are allowed - * all reads return a predefined pattern */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_MRS, 1, - 1, 3, ctrl->tMOD, SSQ_NA, - 4, 6, 3, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + + /* + * DRAM command MRS + * + * Write MR3 MPR enable. + * In this mode only RD and RDA are allowed, + * and all reads return a predefined pattern. + */ + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command RD */ - IOSAV_SUBSEQUENCE(channel, 1, - IOSAV_RD, 1, - 3, 4, 4, SSQ_RD, - 0, 0, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command RD */ - IOSAV_SUBSEQUENCE(channel, 2, - IOSAV_RD, 1, - 1, 4, ctrl->CAS + 8, SSQ_NA, - 0, 6, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } - /* DRAM command MRS - * write MR3 MPR disable */ - IOSAV_SUBSEQUENCE(channel, 3, - IOSAV_MRS, 1, - 1, 3, ctrl->tMOD, SSQ_NA, - 0, 6, 3, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + /* + * DRAM command MRS + * + * Write MR3 MPR disable. + */ + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -1714,18 +2229,50 @@ static void test_timB(ramctr_timing *ctrl, int channel, int slotrank) wait_for_iosav(channel); /* DRAM command NOP */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_NOP, 1, - 1, 3, ctrl->CWL + ctrl->tWLO, SSQ_WR, - 8, 0, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .sp_cmd_ctrl = { + .command = IOSAV_NOP, + .ranksel_ap = 1, + }, + .subseq_ctrl = { + .cmd_executions = 1, + .cmd_delay_gap = 3, + .post_ssq_wait = ctrl->CWL + ctrl->tWLO, + .data_direction = SSQ_WR, + }, + .sp_cmd_addr = { + .address = 8, + .rowbits = 0, + .bank = 0, + .rank = slotrank, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command NOP */ - IOSAV_SUBSEQUENCE(channel, 1, - IOSAV_NOP_ALT, 1, - 1, 3, ctrl->CAS + 38, SSQ_RD, - 4, 0, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .sp_cmd_ctrl = { + .command = IOSAV_NOP_ALT, + .ranksel_ap = 1, + }, + .subseq_ctrl = { + .cmd_executions = 1, + .cmd_delay_gap = 3, + .post_ssq_wait = ctrl->CAS + 38, + .data_direction = SSQ_RD, + }, + .sp_cmd_addr = { + .address = 4, + .rowbits = 0, + .bank = 0, + .rank = slotrank, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -1824,32 +2371,106 @@ static void adjust_high_timB(ramctr_timing *ctrl) wait_for_iosav(channel); /* DRAM command ACT */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_ACT, 1, - 1, 3, ctrl->tRCD, SSQ_NA, - 0, 6, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command NOP */ - IOSAV_SUBSEQUENCE(channel, 1, - IOSAV_NOP, 1, - 1, 3, 4, SSQ_WR, - 8, 0, 0, slotrank, - 0, 0, 0, 0, 31, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command WR */ - IOSAV_SUBSEQUENCE(channel, 2, - IOSAV_WR, 1, - 3, 4, 4, SSQ_WR, - 0, 0, 0, slotrank, - 0, 1, 0, 0, 31, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command NOP */ - IOSAV_SUBSEQUENCE(channel, 3, - IOSAV_NOP, 1, - 1, 3, ctrl->CWL + ctrl->tWTR + 5, SSQ_WR, - 8, 0, 0, slotrank, - 0, 0, 0, 0, 31, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -1857,27 +2478,78 @@ static void adjust_high_timB(ramctr_timing *ctrl) wait_for_iosav(channel); /* DRAM command PREA */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_PRE, 1, - 1, 3, ctrl->tRP, SSQ_NA, - 1024, 6, 0, slotrank, - 0, 0, 0, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command ACT */ - IOSAV_SUBSEQUENCE(channel, 1, - IOSAV_ACT, 1, - 1, 3, ctrl->tRCD, SSQ_NA, - 0, 6, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command RD */ - IOSAV_SUBSEQUENCE(channel, 2, - IOSAV_RD, 3, - 1, 3, ctrl->tRP + + { + const struct iosav_ssq ssq = { + .sp_cmd_ctrl = { + .command = IOSAV_RD, + .ranksel_ap = 3, + }, + .subseq_ctrl = { + .cmd_executions = 1, + .cmd_delay_gap = 3, + .post_ssq_wait = ctrl->tRP + ctrl->timings[channel][slotrank].roundtrip_latency + - ctrl->timings[channel][slotrank].io_latency, SSQ_RD, - 8, 6, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + ctrl->timings[channel][slotrank].io_latency, + .data_direction = SSQ_RD, + }, + .sp_cmd_addr = { + .address = 8, + .rowbits = 6, + .bank = 0, + .rank = slotrank, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -1909,11 +2581,29 @@ static void write_op(ramctr_timing *ctrl, int channel) slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0; /* DRAM command ZQCS */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_ZQCS, 0, - 1, 4, 4, SSQ_NA, - 0, 6, 0, slotrank, - 0, 0, 0, 0, 31, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -1988,11 +2678,29 @@ int write_training(ramctr_timing *ctrl) wait_for_iosav(channel); /* DRAM command ZQCS */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_ZQCS, 0, - 1, 4, 101, SSQ_NA, - 0, 6, 0, 0, - 0, 0, 0, 0, 31, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -2058,36 +2766,120 @@ static int test_320c(ramctr_timing *ctrl, int channel, int slotrank) wait_for_iosav(channel); /* DRAM command ACT */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_ACT, 1, - 8, MAX(ctrl->tRRD, (ctrl->tFAW >> 2) + 1), ctrl->tRCD, SSQ_NA, - ctr, 6, 0, slotrank, - 0, 0, 1, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command WR */ - IOSAV_SUBSEQUENCE(channel, 1, - IOSAV_WR, 1, - 32, 4, ctrl->CWL + ctrl->tWTR + 8, SSQ_WR, - 0, 0, 0, slotrank, - 0, 1, 0, 0, 18, 3, 0, 2); - + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } + /* FIXME: Hardcoded subsequence index */ MCHBAR32(IOSAV_n_ADDRESS_LFSR_ch(channel, 1)) = 0x389abcd; /* DRAM command RD */ - IOSAV_SUBSEQUENCE(channel, 2, - IOSAV_RD, 1, - 32, 4, MAX(ctrl->tRTP, 8), SSQ_RD, - 0, 0, 0, slotrank, - 0, 1, 0, 0, 18, 3, 0, 2); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } + /* FIXME: Hardcoded subsequence index */ MCHBAR32(IOSAV_n_ADDRESS_LFSR_ch(channel, 2)) = 0x389abcd; /* DRAM command PRE */ - IOSAV_SUBSEQUENCE(channel, 3, - IOSAV_PRE, 1, - 1, 4, 15, SSQ_NA, - 1024, 6, 0, slotrank, - 0, 0, 0, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -2150,11 +2942,29 @@ static void reprogram_320c(ramctr_timing *ctrl) slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0; /* DRAM command ZQCS */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_ZQCS, 0, - 1, 4, 4, SSQ_NA, - 0, 6, 0, slotrank, - 0, 0, 0, 0, 31, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -2172,11 +2982,29 @@ static void reprogram_320c(ramctr_timing *ctrl) slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0; /* DRAM command ZQCS */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_ZQCS, 0, - 1, 4, 4, SSQ_NA, - 0, 6, 0, slotrank, - 0, 0, 0, 0, 31, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -2333,37 +3161,107 @@ static int discover_edges_real(ramctr_timing *ctrl, int channel, int slotrank, i wait_for_iosav(channel); - /* DRAM command MRS - write MR3 MPR enable - in this mode only RD and RDA are allowed - all reads return a predefined pattern */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_MRS, 1, - 1, 3, ctrl->tMOD, SSQ_NA, - 4, 6, 3, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + /* + * DRAM command MRS + * + * Write MR3 MPR enable. + * In this mode only RD and RDA are allowed, + * and all reads return a predefined pattern. + */ + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command RD */ - IOSAV_SUBSEQUENCE(channel, 1, - IOSAV_RD, 1, - 500, 4, 4, SSQ_RD, - 0, 0, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command RD */ - IOSAV_SUBSEQUENCE(channel, 2, - IOSAV_RD, 1, - 1, 4, ctrl->CAS + 8, SSQ_NA, - 0, 6, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } - /* DRAM command MRS - MR3 disable MPR */ - IOSAV_SUBSEQUENCE(channel, 3, - IOSAV_MRS, 1, - 1, 3, ctrl->tMOD, SSQ_NA, - 0, 6, 3, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + /* + * DRAM command MRS + * + * Write MR3 MPR disable. + */ + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -2421,38 +3319,107 @@ int discover_edges(ramctr_timing *ctrl) FOR_ALL_POPULATED_RANKS { wait_for_iosav(channel); - /* DRAM command MRS - MR3 enable MPR - write MR3 MPR enable - in this mode only RD and RDA are allowed - all reads return a predefined pattern */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_MRS, 1, - 1, 3, ctrl->tMOD, SSQ_NA, - 4, 6, 3, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + /* + * DRAM command MRS + * + * Write MR3 MPR enable. + * In this mode only RD and RDA are allowed, + * and all reads return a predefined pattern. + */ + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command RD */ - IOSAV_SUBSEQUENCE(channel, 1, - IOSAV_RD, 1, - 3, 4, 4, SSQ_RD, - 0, 0, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command RD */ - IOSAV_SUBSEQUENCE(channel, 2, - IOSAV_RD, 1, - 1, 4, ctrl->CAS + 8, SSQ_NA, - 0, 6, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } - /* DRAM command MRS - * MR3 disable MPR */ - IOSAV_SUBSEQUENCE(channel, 3, - IOSAV_MRS, 1, - 1, 3, ctrl->tMOD, SSQ_NA, - 0, 6, 3, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + /* + * DRAM command MRS + * + * Write MR3 MPR disable. + */ + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -2472,38 +3439,107 @@ int discover_edges(ramctr_timing *ctrl) FOR_ALL_POPULATED_RANKS { wait_for_iosav(channel); - /* DRAM command MRS - MR3 enable MPR - write MR3 MPR enable - in this mode only RD and RDA are allowed - all reads return a predefined pattern */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_MRS, 1, - 1, 3, ctrl->tMOD, SSQ_NA, - 4, 6, 3, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + /* + * DRAM command MRS + * + * Write MR3 MPR enable. + * In this mode only RD and RDA are allowed, + * and all reads return a predefined pattern. + */ + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command RD */ - IOSAV_SUBSEQUENCE(channel, 1, - IOSAV_RD, 1, - 3, 4, 4, SSQ_RD, - 0, 0, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command RD */ - IOSAV_SUBSEQUENCE(channel, 2, - IOSAV_RD, 1, - 1, 4, ctrl->CAS + 8, SSQ_NA, - 0, 6, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } - /* DRAM command MRS - * MR3 disable MPR */ - IOSAV_SUBSEQUENCE(channel, 3, - IOSAV_MRS, 1, - 1, 3, ctrl->tMOD, SSQ_NA, - 0, 6, 3, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + /* + * DRAM command MRS + * + * Write MR3 MPR disable. + */ + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -2606,32 +3642,109 @@ static int discover_edges_write_real(ramctr_timing *ctrl, int channel, int slotr wait_for_iosav(channel); /* DRAM command ACT */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_ACT, 1, - 4, MAX(ctrl->tRRD, (ctrl->tFAW >> 2) + 1), ctrl->tRCD, SSQ_NA, - 0, 6, 0, slotrank, - 0, 0, 0, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command WR */ - IOSAV_SUBSEQUENCE(channel, 1, - IOSAV_WR, 1, - 32, 20, ctrl->tWTR + ctrl->CWL + 8, SSQ_WR, - 0, 0, 0, slotrank, - 0, 1, 0, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command RD */ - IOSAV_SUBSEQUENCE(channel, 2, - IOSAV_RD, 1, - 32, 20, MAX(ctrl->tRTP, 8), SSQ_RD, - 0, 0, 0, slotrank, - 0, 1, 0, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command PRE */ - IOSAV_SUBSEQUENCE(channel, 3, - IOSAV_PRE, 1, - 1, 3, ctrl->tRP, SSQ_NA, - 1024, 6, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -2730,32 +3843,108 @@ static void test_timC_write(ramctr_timing *ctrl, int channel, int slotrank) wait_for_iosav(channel); /* DRAM command ACT */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_ACT, 1, - 4, MAX((ctrl->tFAW >> 2) + 1, ctrl->tRRD), ctrl->tRCD, SSQ_NA, - 0, 6, 0, slotrank, - 0, 0, 1, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command WR */ - IOSAV_SUBSEQUENCE(channel, 1, - IOSAV_WR, 1, - 480, 4, ctrl->tWTR + ctrl->CWL + 8, SSQ_WR, - 0, 0, 0, slotrank, - 0, 1, 0, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command RD */ - IOSAV_SUBSEQUENCE(channel, 2, - IOSAV_RD, 1, - 480, 4, MAX(ctrl->tRTP, 8), SSQ_RD, - 0, 0, 0, slotrank, - 0, 1, 0, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command PRE */ - IOSAV_SUBSEQUENCE(channel, 3, - IOSAV_PRE, 1, - 1, 4, ctrl->tRP, SSQ_NA, - 1024, 6, 0, slotrank, - 0, 0, 0, 0, 0, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -2947,32 +4136,111 @@ int channel_test(ramctr_timing *ctrl) wait_for_iosav(channel); /* DRAM command ACT */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_ACT, 1, - 4, 8, 40, SSQ_NA, - 0, 6, 0, slotrank, - 0, 0, 1, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command WR */ - IOSAV_SUBSEQUENCE(channel, 1, - IOSAV_WR, 1, - 100, 4, 40, SSQ_WR, - 0, 0, 0, slotrank, - 0, 1, 0, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command RD */ - IOSAV_SUBSEQUENCE(channel, 2, - IOSAV_RD, 1, - 100, 4, 40, SSQ_RD, - 0, 0, 0, slotrank, - 0, 1, 0, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command PRE */ - IOSAV_SUBSEQUENCE(channel, 3, - IOSAV_PRE, 1, - 1, 3, 40, SSQ_NA, - 1024, 6, 0, slotrank, - 0, 0, 0, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* Execute command queue */ iosav_run_once(channel); @@ -2999,25 +4267,85 @@ void channel_scrub(ramctr_timing *ctrl) wait_for_iosav(channel); /* DRAM command ACT */ - IOSAV_SUBSEQUENCE(channel, 0, - IOSAV_ACT, 1, - 1, MAX((ctrl->tFAW >> 2) + 1, ctrl->tRRD), ctrl->tRCD, SSQ_NA, - row, 6, 0, slotrank, - 1, 0, 0, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .sp_cmd_ctrl = { + .command = IOSAV_ACT, + .ranksel_ap = 1, + }, + .subseq_ctrl = { + .cmd_executions = 1, + .cmd_delay_gap = MAX((ctrl->tFAW >> 2) + 1, + ctrl->tRRD), + .post_ssq_wait = ctrl->tRCD, + .data_direction = SSQ_NA, + }, + .sp_cmd_addr = { + .address = row, + .rowbits = 6, + .bank = 0, + .rank = slotrank, + }, + .addr_update = { + .inc_addr_1 = 1, + .addr_wrap = 18, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command WR */ - IOSAV_SUBSEQUENCE(channel, 1, - IOSAV_WR, 1, - 129, 4, 40, SSQ_WR, - row, 0, 0, slotrank, - 0, 1, 0, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .sp_cmd_ctrl = { + .command = IOSAV_WR, + .ranksel_ap = 1, + }, + .subseq_ctrl = { + .cmd_executions = 129, + .cmd_delay_gap = 4, + .post_ssq_wait = 40, + .data_direction = SSQ_WR, + }, + .sp_cmd_addr = { + .address = row, + .rowbits = 0, + .bank = 0, + .rank = slotrank, + }, + .addr_update = { + .inc_addr_8 = 1, + .addr_wrap = 18, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* DRAM command PRE */ - IOSAV_SUBSEQUENCE(channel, 2, - IOSAV_PRE, 1, - 1, 3, 40, SSQ_NA, - 1024, 6, 0, slotrank, - 0, 0, 0, 0, 18, 0, 0, 0); + { + const struct iosav_ssq ssq = { + .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, + }, + }; + iosav_write_ssq(channel, &ssq); + } /* execute command queue */ iosav_run_once(channel); diff --git a/src/northbridge/intel/sandybridge/raminit_common.h b/src/northbridge/intel/sandybridge/raminit_common.h index 6e76cbc0bb..3f31950408 100644 --- a/src/northbridge/intel/sandybridge/raminit_common.h +++ b/src/northbridge/intel/sandybridge/raminit_common.h @@ -25,6 +25,7 @@ #define NUM_SLOTS 2 #define NUM_LANES 9 +/* IOSAV_n_SP_CMD_CTRL DRAM commands */ #define IOSAV_MRS (0xf000) #define IOSAV_PRE (0xf002) #define IOSAV_ZQCS (0xf003) @@ -34,6 +35,12 @@ #define IOSAV_WR (0xf201) #define IOSAV_NOP (0xf207) +/* IOSAV_n_SUBSEQ_CTRL data direction */ +#define SSQ_NA 0 /* Non-data */ +#define SSQ_RD 1 /* Read */ +#define SSQ_WR 2 /* Write */ +#define SSQ_RW 3 /* Read and write */ + struct iosav_ssq { /* IOSAV_n_SP_CMD_CTRL */ union {