summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur Heymans <arthur@aheymans.xyz>2017-05-15 10:33:01 +0200
committerPatrick Georgi <pgeorgi@google.com>2018-05-14 07:41:58 +0000
commit66a0f55c2e2c6e042c58ae423901d7e41c5a2c84 (patch)
tree19bf9be143782db00e7103448f4b3d50d08cbc63
parent7a3a319e3ac56853468f7787cf25f9bba6b261d3 (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>
-rw-r--r--src/northbridge/intel/x4x/raminit_ddr23.c113
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) /