diff options
author | Arthur Heymans <arthur@aheymans.xyz> | 2017-05-15 10:33:01 +0200 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2018-05-14 07:41:58 +0000 |
commit | 66a0f55c2e2c6e042c58ae423901d7e41c5a2c84 (patch) | |
tree | 19bf9be143782db00e7103448f4b3d50d08cbc63 /src/northbridge/intel | |
parent | 7a3a319e3ac56853468f7787cf25f9bba6b261d3 (diff) |
nb/intel/x4x/raminit: Support programming DDR3 timings
Also throws in some minor fixes like the wrong conditional for
bankmod and using real CAS when programming MCHBAR(0x248).
Change-Id: Ia2494684ec66d84d4dc27c6a6b425a33ace6e827
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/19873
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
Diffstat (limited to 'src/northbridge/intel')
-rw-r--r-- | src/northbridge/intel/x4x/raminit_ddr23.c | 113 |
1 files changed, 76 insertions, 37 deletions
diff --git a/src/northbridge/intel/x4x/raminit_ddr23.c b/src/northbridge/intel/x4x/raminit_ddr23.c index 0e64213d50..5c74c6de1e 100644 --- a/src/northbridge/intel/x4x/raminit_ddr23.c +++ b/src/northbridge/intel/x4x/raminit_ddr23.c @@ -464,12 +464,72 @@ static void program_timings(struct sysinfo *s) 5200 }; - ta1 = 6; - ta2 = 6; - ta3 = 5; - ta4 = 8; + const static u8 ddr3_turnaround_tab[3][6][4] = { + { /* DDR3 800 */ + {0x9, 0x7, 0x7, 0x9}, /* CL = 5 */ + {0x9, 0x7, 0x8, 0x8}, /* CL = 6 */ + }, + { /* DDR3 1066 */ + {0x0, 0x0, 0x0, 0x0}, /* CL = 5 - Not supported */ + {0x9, 0x7, 0x7, 0x9}, /* CL = 6 */ + {0x9, 0x7, 0x8, 0x8}, /* CL = 7 */ + {0x9, 0x7, 0x9, 0x7} /* CL = 8 */ + }, + { /* DDR3 1333 */ + {0x0, 0x0, 0x0, 0x0}, /* CL = 5 - Not supported */ + {0x0, 0x0, 0x0, 0x0}, /* CL = 6 - Not supported */ + {0x0, 0x0, 0x0, 0x0}, /* CL = 7 - Not supported */ + {0x9, 0x7, 0x9, 0x8}, /* CL = 8 */ + {0x9, 0x7, 0xA, 0x7}, /* CL = 9 */ + {0x9, 0x7, 0xB, 0x6}, /* CL = 10 */ + } + }; - twl = s->selected_timings.CAS - 1; + /* [DDR freq][0x26F & 1][pagemod] */ + const static u8 ddr2_x252_tab[2][2][2] = { + { /* DDR2 667 */ + {12, 16}, + {14, 18} + }, + { /* DDR2 800 */ + {14, 18}, + {16, 20} + } + }; + + const static u8 ddr3_x252_tab[3][2][2] = { + { /* DDR3 800 */ + {16, 20}, + {18, 22} + }, + { /* DDR3 1067 */ + {20, 26}, + {26, 26} + }, + { /* DDR3 1333 */ + {20, 30}, + {22, 32}, + } + }; + + if (s->spd_type == DDR2) { + ta1 = 6; + ta2 = 6; + ta3 = 5; + ta4 = 8; + } else { + int ddr3_idx = s->selected_timings.mem_clk - MEM_CLOCK_800MHz; + int cas_idx = s->selected_timings.CAS - 5; + ta1 = ddr3_turnaround_tab[ddr3_idx][cas_idx][0]; + ta2 = ddr3_turnaround_tab[ddr3_idx][cas_idx][1]; + ta3 = ddr3_turnaround_tab[ddr3_idx][cas_idx][2]; + ta4 = ddr3_turnaround_tab[ddr3_idx][cas_idx][3]; + } + + if (s->spd_type == DDR2) + twl = s->selected_timings.CAS - 1; + else /* DDR3 */ + twl = s->selected_timings.mem_clk - MEM_CLOCK_800MHz + 5; FOR_EACH_POPULATED_DIMM(s->dimms, i) { if (s->dimms[i].n_banks == N_BANKS_8) { @@ -500,37 +560,16 @@ static void program_timings(struct sysinfo *s) (s->selected_timings.tRP << 13) | ((s->selected_timings.tRP + trpmod) << 9) | s->selected_timings.tRFC; - reg8 = (MCHBAR8(0x400*i + 0x26f) >> 1) & 1; - if (bankmod) { - switch (s->selected_timings.mem_clk) { - default: - case MEM_CLOCK_667MHz: - if (reg8) { - if (pagemod) - reg32 |= 16 << 22; - else - reg32 |= 12 << 22; - } else { - if (pagemod) - reg32 |= 18 << 22; - else - reg32 |= 14 << 22; - } - break; - case MEM_CLOCK_800MHz: - if (reg8) { - if (pagemod) - reg32 |= 18 << 22; - else - reg32 |= 14 << 22; - } else { - if (pagemod) - reg32 |= 20 << 22; - else - reg32 |= 16 << 22; - } - break; - } + if (bankmod == 0) { + reg8 = (MCHBAR8(0x400*i + 0x26f) >> 1) & 1; + if (s->spd_type == DDR2) + reg32 |= ddr2_x252_tab[s->selected_timings.mem_clk + - MEM_CLOCK_667MHz][reg8][pagemod] + << 22; + else + reg32 |= ddr3_x252_tab[s->selected_timings.mem_clk + - MEM_CLOCK_800MHz][reg8][pagemod] + << 22; } MCHBAR32(0x400*i + 0x252) = reg32; @@ -564,7 +603,7 @@ static void program_timings(struct sysinfo *s) fsb = fsb2ps[s->selected_timings.fsb_clk]; ddr = ddr2ps[s->selected_timings.mem_clk]; - reg32 = (u32)((adjusted_cas + 7 + reg8) * ddr); + reg32 = (u32)((s->selected_timings.CAS + 7 + reg8) * ddr); reg32 = (u32)((reg32 / fsb) << 8); reg32 |= 0x0e000000; if ((fsb2mhz(s->selected_timings.fsb_clk) / |