diff options
author | Nico Huber <nico.h@gmx.de> | 2019-08-11 17:48:44 +0200 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2023-01-26 13:37:33 +0000 |
commit | d13118320030c6df48ad33243d48c3ff34cb67d7 (patch) | |
tree | d731b3c53a8c474b723afada688c52881c349ef1 | |
parent | c9847884ffc9693cd8482ee77f1b03e66fa10026 (diff) |
nb/intel/gm45: Split DDR2 I/O init out
Move DDR3 memory I/O init to its own function and add DDR2 memory I/O
init. Read I/O init is common to both DDR2 and DDR3.
TEST: DDR2 systems boot (with the rest of the patch train)
- Tested on a Dell Latitude E6400
- Tested on a Compal JHL90
TEST: Ensure DDR3 systems still boot
- Tested on a Thinkpad X200
Change-Id: Ic4d5130f527249d3a5b98bae778cdf21a1753b04
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/34833
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
-rw-r--r-- | src/northbridge/intel/gm45/raminit.c | 136 |
1 files changed, 125 insertions, 11 deletions
diff --git a/src/northbridge/intel/gm45/raminit.c b/src/northbridge/intel/gm45/raminit.c index a57f201d4f..8a72d4afba 100644 --- a/src/northbridge/intel/gm45/raminit.c +++ b/src/northbridge/intel/gm45/raminit.c @@ -1498,6 +1498,7 @@ static void ddr3_select_clock_mux(const mem_clock_t ddr3clock, ((( clk1067 && !cardF[ch])?3:2) << 11) | mixed); } } + static void ddr3_write_io_init(const mem_clock_t ddr3clock, const dimminfo_t *const dimms, const stepping_t stepping, @@ -1564,9 +1565,10 @@ static void ddr3_write_io_init(const mem_clock_t ddr3clock, mchbar_write32(0x1590, 0x00e70067); mchbar_write32(0x1594, 0x000d8000); } -static void ddr3_read_io_init(const mem_clock_t ddr3clock, - const dimminfo_t *const dimms, - const int sff) + +static void ddr_read_io_init(const mem_clock_t ddr_clock, + const dimminfo_t *const dimms, + const int sff) { int ch; @@ -1577,7 +1579,7 @@ static void ddr3_read_io_init(const mem_clock_t ddr3clock, tmp = mchbar_read32(addr); tmp &= ~((3 << 25) | (1 << 8) | (7 << 16) | (0xf << 20) | (1 << 27)); tmp |= (1 << 27); - switch (ddr3clock) { + switch (ddr_clock) { case MEM_CLOCK_667MT: tmp |= (1 << 16) | (4 << 20); break; @@ -1598,10 +1600,10 @@ static void ddr3_read_io_init(const mem_clock_t ddr3clock, } } -static void memory_io_init(const mem_clock_t ddr3clock, - const dimminfo_t *const dimms, - const stepping_t stepping, - const int sff) +static void ddr3_memory_io_init(const mem_clock_t ddr3clock, + const dimminfo_t *const dimms, + const stepping_t stepping, + const int sff) { u32 tmp; @@ -1694,7 +1696,114 @@ static void memory_io_init(const mem_clock_t ddr3clock, ddr3_write_io_init(ddr3clock, dimms, stepping, sff); - ddr3_read_io_init(ddr3clock, dimms, sff); + ddr_read_io_init(ddr3clock, dimms, sff); +} + +static void ddr2_select_clock_mux(const dimminfo_t *const dimms) +{ + int ch; + unsigned int o; + FOR_EACH_POPULATED_CHANNEL(dimms, ch) { + const unsigned int b = 0x14b0 + (ch * 0x0100); + for (o = 0; o < 0x20; o += 4) + mchbar_clrbits32(b + o, 7 << 11); + } +} + +static void ddr2_write_io_init(const dimminfo_t *const dimms) +{ + int s; + + mchbar_clrsetbits32(CxWRTy_MCHBAR(0, 0), 0xf7bff71f, 0x008b0008); + + for (s = 1; s < 4; ++s) { + mchbar_clrsetbits32(CxWRTy_MCHBAR(0, s), 0xf7bff71f, 0x00800000); + } + + mchbar_clrsetbits32(0x1490, 0xf7fff77f, 0x00800000); + mchbar_clrsetbits32(0x1494, 0xf71f8000, 0x00040000); + + mchbar_clrsetbits32(CxWRTy_MCHBAR(1, 0), 0xf7bff71f, 0x00890008); + + for (s = 1; s < 4; ++s) { + mchbar_clrsetbits32(CxWRTy_MCHBAR(1, s), 0xf7bff71f, 0x00890000); + } + + mchbar_clrsetbits32(0x1590, 0xf7fff77f, 0x00800000); + mchbar_clrsetbits32(0x1594, 0xf71f8000, 0x00040000); +} + +static void ddr2_memory_io_init(const mem_clock_t ddr2clock, + const dimminfo_t *const dimms, + const stepping_t stepping, + const int sff) +{ + u32 tmp; + u32 tmp2; + + if (stepping < STEPPING_B1) + die("Stepping <B1 unsupported in DDR2 memory i/o initialization.\n"); + if (sff) + die("SFF platform unsupported in DDR2 memory i/o initialization.\n"); + + tmp = mchbar_read32(0x140c); + tmp &= ~(0xff | (1<<11) | (0xf<<28)); + tmp |= (1<<0) | (1<<12) | (1<<16) | (1<<18) | (1<<27); + mchbar_write32(0x140c, tmp); + + tmp = mchbar_read32(0x1440); + tmp &= ~(1<<5); + tmp |= (1<<0) | (1<<2) | (1<<3) | (1<<4) | (1<<6); + mchbar_write32(0x1440, tmp); + + tmp = mchbar_read32(0x1414); + tmp &= ~((1<<20) | (7<<11) | (0xf << 24) | (0xf << 16)); + tmp |= (3<<11); + tmp2 = mchbar_read32(0x142c); + tmp2 &= ~((0xf << 8) | (0x7 << 20) | 0xf); + tmp2 |= (0x3 << 20); + switch (ddr2clock) { + case MEM_CLOCK_667MT: + tmp |= (2 << 24) | (10 << 16); + tmp2 |= (2 << 8) | 0xc; + break; + case MEM_CLOCK_800MT: + tmp |= (3 << 24) | (7 << 16); + tmp2 |= (3 << 8) | 0xa; + break; + default: + die("Wrong clock"); + } + mchbar_write32(0x1414, tmp); + mchbar_write32(0x142c, tmp2); + + mchbar_clrbits32(0x1418, (1<<3) | (1<<11) | (1<<19) | (1<<27)); + mchbar_clrbits32(0x141c, (1<<3) | (1<<11) | (1<<19) | (1<<27)); + + tmp = mchbar_read32(0x400); + tmp &= ~((3 << 4) | (3 << 16) | (3 << 30)); + tmp |= (2 << 4) | (2 << 16); + mchbar_write32(0x400, tmp); + + mchbar_clrbits32(0x404, 0xf << 20); + + mchbar_clrbits32(0x40c, 1 << 6); + + tmp = mchbar_read32(0x410); + tmp &= ~(0xf << 28); + tmp |= 2 << 28; + mchbar_write32(0x410, tmp); + + tmp = mchbar_read32(0x41c); + tmp &= ~((7<<0) | (7<<4)); + tmp |= (1<<0) | (1<<3) | (1<<4) | (1<<7); + mchbar_write32(0x41c, tmp); + + ddr2_select_clock_mux(dimms); + + ddr2_write_io_init(dimms); + + ddr_read_io_init(ddr2clock, dimms, sff); } static void jedec_command(const uintptr_t rankaddr, const u32 cmd, const u32 val) @@ -1967,8 +2076,13 @@ void raminit(sysinfo_t *const sysinfo, const int s3resume) /* Program egress VC1 timings. */ vc1_program_timings(timings->fsb_clock); /* Perform system-memory i/o initialization. */ - memory_io_init(timings->mem_clock, dimms, - sysinfo->stepping, sysinfo->sff); + if (sysinfo->spd_type == DDR2) { + ddr2_memory_io_init(timings->mem_clock, dimms, + sysinfo->stepping, sysinfo->sff); + } else { + ddr3_memory_io_init(timings->mem_clock, dimms, + sysinfo->stepping, sysinfo->sff); + } /* Initialize memory map with dummy values of 128MB per rank with a page size of 4KB. This makes the JEDEC initialization code easier. */ |