diff options
Diffstat (limited to 'src/northbridge/intel/x4x/raminit_ddr23.c')
-rw-r--r-- | src/northbridge/intel/x4x/raminit_ddr23.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/src/northbridge/intel/x4x/raminit_ddr23.c b/src/northbridge/intel/x4x/raminit_ddr23.c index 6d6111c5c4..618e21215c 100644 --- a/src/northbridge/intel/x4x/raminit_ddr23.c +++ b/src/northbridge/intel/x4x/raminit_ddr23.c @@ -1361,8 +1361,7 @@ static u32 mirror_shift_bit(const u32 data, u8 bit) return (data & ~(3 << bit)) | temp0 | temp1; } -static void send_jedec_cmd(const struct sysinfo *s, u8 r, - u8 ch, u8 cmd, u32 val) +void send_jedec_cmd(const struct sysinfo *s, u8 r, u8 ch, u8 cmd, u32 val) { u32 addr = test_address(ch, r); volatile u32 rubbish; @@ -1933,6 +1932,24 @@ static void power_settings(struct sysinfo *s) MCHBAR8(0x561 + (lane << 2)) = MCHBAR8(0x561 + (lane << 2)) & ~(1 << 3); } +static void software_ddr3_reset(struct sysinfo *s) +{ + printk(BIOS_DEBUG, "Software initiated DDR3 reset.\n"); + MCHBAR8(0x1a8) = MCHBAR8(0x1a8) | 0x02; + MCHBAR8(0x5da) = MCHBAR8(0x5da) & ~0x80; + MCHBAR8(0x1a8) = MCHBAR8(0x1a8) & ~0x02; + MCHBAR8(0x5da) = (MCHBAR8(0x5da) & ~0x03) | 1; + udelay(200); + MCHBAR8(0x1a8) = MCHBAR8(0x1a8) & ~0x02; + MCHBAR8(0x5da) = MCHBAR8(0x5da) | 0x80; + MCHBAR8(0x5da) = MCHBAR8(0x5da) & ~0x80; + udelay(500); + MCHBAR8(0x5da) = MCHBAR8(0x5da) | 0x03; + MCHBAR8(0x5da) = MCHBAR8(0x5da) & ~0x03; + /* After write leveling the dram needs to be reset and reinitialised */ + jedec_ddr3(s); +} + void do_raminit(struct sysinfo *s, int fast_boot) { u8 ch; @@ -2019,6 +2036,17 @@ void do_raminit(struct sysinfo *s, int fast_boot) MCHBAR8(0x9d8) = MCHBAR8(0x9d8) | 0x7; } + /* DDR3 reset */ + if ((s->spd_type == DDR3) && (s->boot_path != BOOT_PATH_RESUME)) { + printk(BIOS_DEBUG, "DDR3 Reset.\n"); + MCHBAR8(0x1a8) = MCHBAR8(0x1a8) & ~0x2; + MCHBAR8(0x5da) = MCHBAR8(0x5da) | 0x80; + udelay(500); + MCHBAR8(0x1a8) = MCHBAR8(0x1a8) & ~0x2; + MCHBAR8(0x5da) = MCHBAR8(0x5da) & ~0x80; + udelay(500); + } + // Pre jedec MCHBAR8(0x40) = MCHBAR8(0x40) | 0x2; FOR_EACH_POPULATED_CHANNEL(s->dimms, ch) { @@ -2038,6 +2066,13 @@ void do_raminit(struct sysinfo *s, int fast_boot) printk(BIOS_DEBUG, "Done jedec steps\n"); + if (s->spd_type == DDR3) { + if (!fast_boot) + search_write_leveling(s); + if (s->boot_path == BOOT_PATH_NORMAL) + software_ddr3_reset(s); + } + // After JEDEC reset MCHBAR8(0x40) = MCHBAR8(0x40) & ~0x2; FOR_EACH_POPULATED_CHANNEL(s->dimms, ch) { |