nb/intel/sandybridge: Make helper for write leveling sequence

Encapsulate the IOSAV sequence into a helper to help reduce clutter.

Tested on Asus P8H61-M PRO, still boots.

Change-Id: I58595a5c53fcdc3f29fa55b015a82cbfe85cd6cb
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47615
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
This commit is contained in:
Angel Pons 2020-11-14 16:49:29 +01:00 committed by Felix Held
parent 068c2595f2
commit 9426721807
3 changed files with 90 additions and 82 deletions

View File

@ -1698,9 +1698,6 @@ static void precharge(ramctr_timing *ctrl)
static void test_timB(ramctr_timing *ctrl, int channel, int slotrank)
{
/* First DQS/DQS# rising edge after write leveling mode is programmed */
const u32 tWLMRD = 40;
u32 mr1reg = make_mr1(ctrl, slotrank, channel) | 1 << 7;
int bank = 1;
@ -1709,85 +1706,7 @@ static void test_timB(ramctr_timing *ctrl, int channel, int slotrank)
wait_for_iosav(channel);
const struct iosav_ssq sequence[] = {
/* DRAM command MRS: enable DQs on this slotrank */
[0] = {
.sp_cmd_ctrl = {
.command = IOSAV_MRS,
.ranksel_ap = 1,
},
.subseq_ctrl = {
.cmd_executions = 1,
.cmd_delay_gap = 3,
.post_ssq_wait = tWLMRD,
.data_direction = SSQ_NA,
},
.sp_cmd_addr = {
.address = mr1reg,
.rowbits = 6,
.bank = bank,
.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 = ctrl->CWL + ctrl->tWLO,
.data_direction = SSQ_WR,
},
.sp_cmd_addr = {
.address = 8,
.rowbits = 0,
.bank = 0,
.rank = slotrank,
},
},
/* DRAM command NOP */
[2] = {
.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,
},
},
/* DRAM command MRS: disable DQs on this slotrank */
[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 = mr1reg | 1 << 12,
.rowbits = 6,
.bank = bank,
.rank = slotrank,
},
},
};
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
iosav_write_jedec_write_leveling_sequence(ctrl, channel, slotrank, bank, mr1reg);
/* Execute command queue */
iosav_run_once(channel);

View File

@ -253,6 +253,8 @@ void iosav_write_zqcs_sequence(int channel, int slotrank, u32 gap, u32 post, u32
void iosav_write_prea_sequence(int channel, int slotrank, u32 post, u32 wrap);
void iosav_write_read_mpr_sequence(
int channel, int slotrank, u32 tMOD, u32 loops, u32 gap, u32 loops2, u32 post2);
void iosav_write_jedec_write_leveling_sequence(
ramctr_timing *ctrl, int channel, int slotrank, int bank, u32 mr1reg);
void iosav_write_misc_write_sequence(ramctr_timing *ctrl, int channel, int slotrank,
u32 gap0, u32 loops0, u32 gap1, u32 loops2, u32 wrap2);
void iosav_write_command_training_sequence(

View File

@ -199,6 +199,93 @@ void iosav_write_read_mpr_sequence(
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
}
void iosav_write_jedec_write_leveling_sequence(
ramctr_timing *ctrl, int channel, int slotrank, int bank, u32 mr1reg)
{
/* First DQS/DQS# rising edge after write leveling mode is programmed */
const u32 tWLMRD = 40;
const struct iosav_ssq sequence[] = {
/* DRAM command MRS: enable DQs on this slotrank */
[0] = {
.sp_cmd_ctrl = {
.command = IOSAV_MRS,
.ranksel_ap = 1,
},
.subseq_ctrl = {
.cmd_executions = 1,
.cmd_delay_gap = 3,
.post_ssq_wait = tWLMRD,
.data_direction = SSQ_NA,
},
.sp_cmd_addr = {
.address = mr1reg,
.rowbits = 6,
.bank = bank,
.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 = ctrl->CWL + ctrl->tWLO,
.data_direction = SSQ_WR,
},
.sp_cmd_addr = {
.address = 8,
.rowbits = 0,
.bank = 0,
.rank = slotrank,
},
},
/* DRAM command NOP */
[2] = {
.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,
},
},
/* DRAM command MRS: disable DQs on this slotrank */
[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 = mr1reg | 1 << 12,
.rowbits = 6,
.bank = bank,
.rank = slotrank,
},
},
};
iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
}
void iosav_write_misc_write_sequence(ramctr_timing *ctrl, int channel, int slotrank,
u32 gap0, u32 loops0, u32 gap1, u32 loops2, u32 wrap2)
{