aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/intel/x4x/raminit_ddr2.c
diff options
context:
space:
mode:
authorArthur Heymans <arthur@aheymans.xyz>2017-09-25 09:40:54 +0200
committerPatrick Georgi <pgeorgi@google.com>2018-04-17 10:39:45 +0000
commitadc571a54c484bc5a4bb7785db8eda1be153eed9 (patch)
tree383e4a655a22bdcfa7012cacf01daccc63f219fe /src/northbridge/intel/x4x/raminit_ddr2.c
parent0cdaad36eb033eec831ad1eecec785ce89950ca7 (diff)
nb/intel/x4x: Use SPI flash to cache raminit results
Stores information obtained from decoding dimms and receive enable results for future use. Depreciates using rtc nvram to store receive enable settings. A notable change is that receive enable results are always reused, not just on a resume from S3. This requires cbmem to be initialized a bit earlier, right after the raminit finished to be able to add the sysinfo struct to cbmem which gets cached to the SPI flash in ramstage. TESTED on Intel DG43GT with W25Q128.V. With 4 ddr2 dimms time in raminit goes from 133,857ms (using i2c block read to fetch SPD) to 21,071ms for cached results. Change-Id: I042dc5c52615d40781d9ef7ecd657ad0bf3ed08f Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-on: https://review.coreboot.org/21677 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
Diffstat (limited to 'src/northbridge/intel/x4x/raminit_ddr2.c')
-rw-r--r--src/northbridge/intel/x4x/raminit_ddr2.c95
1 files changed, 32 insertions, 63 deletions
diff --git a/src/northbridge/intel/x4x/raminit_ddr2.c b/src/northbridge/intel/x4x/raminit_ddr2.c
index 022cbaa0b4..336f77ec7d 100644
--- a/src/northbridge/intel/x4x/raminit_ddr2.c
+++ b/src/northbridge/intel/x4x/raminit_ddr2.c
@@ -1045,77 +1045,46 @@ static void jedec_ddr2(struct sysinfo *s)
printk(BIOS_DEBUG, "MRS done\n");
}
-static void sdram_save_receive_enable(void)
+static void sdram_recover_receive_enable(const struct sysinfo *s)
{
- int i = 0;
- u16 reg16;
- u8 values[18];
- u8 lane, ch;
-
- FOR_EACH_CHANNEL(ch) {
- lane = 0;
- while (lane < 8) {
- values[i] = (MCHBAR8(0x400*ch + 0x560 + lane++ * 4) & 0xf);
- values[i++] |= (MCHBAR8(0x400*ch + 0x560 + lane++ * 4) & 0xf) << 4;
- }
- values[i++] = (MCHBAR32(0x400*ch + 0x248) >> 16) & 0xf;
- reg16 = MCHBAR16(0x400*ch + 0x5fa);
- values[i++] = reg16 & 0xff;
- values[i++] = (reg16 >> 8) & 0xff;
- reg16 = MCHBAR16(0x400*ch + 0x58c);
- values[i++] = reg16 & 0xff;
- values[i++] = (reg16 >> 8) & 0xff;
- }
-
- for (i = 0; i < ARRAY_SIZE(values); i++)
- cmos_write(values[i], 128 + i);
-}
-
-static void sdram_recover_receive_enable(void)
-{
- u8 i;
u32 reg32;
- u16 reg16;
- u8 values[18];
- u8 ch, lane;
+ u16 medium, coarse_offset;
+ u8 pi_tap;
+ int lane, channel;
+
+ FOR_EACH_POPULATED_CHANNEL(s->dimms, channel) {
+ medium = 0;
+ coarse_offset = 0;
+ reg32 = MCHBAR32(0x400 * channel + 0x248);
+ reg32 &= ~0xf0000;
+ reg32 |= s->rcven_t[channel].min_common_coarse << 16;
+ MCHBAR32(0x400 * channel + 0x248) = reg32;
- for (i = 0; i < ARRAY_SIZE(values); i++)
- values[i] = cmos_read(128 + i);
-
- i = 0;
- FOR_EACH_CHANNEL(ch) {
- lane = 0;
- while (lane < 8) {
- MCHBAR8(0x400*ch + 0x560 + lane++ * 4) = 0x70 |
- (values[i] & 0xf);
- MCHBAR8(0x400*ch + 0x560 + lane++ * 4) = 0x70 |
- ((values[i++] >> 4) & 0xf);
+ for (lane = 0; lane < 8; lane++) {
+ medium |= s->rcven_t[channel].medium[lane]
+ << (lane * 2);
+ coarse_offset |=
+ (s->rcven_t[channel].coarse_offset[lane] & 0x3)
+ << (lane * 2);
+
+ pi_tap = MCHBAR8(0x400 * channel + 0x560 + lane * 4);
+ pi_tap &= ~0x7f;
+ pi_tap |= s->rcven_t[channel].tap[lane];
+ pi_tap |= s->rcven_t[channel].pi[lane] << 4;
+ MCHBAR8(0x400 * channel + 0x560 + lane * 4) = pi_tap;
}
- reg32 = (MCHBAR32(0x400*ch + 0x248) & ~0xf0000)
- | ((values[i++] & 0xf) << 16);
- MCHBAR32(0x400*ch + 0x248) = reg32;
- reg16 = values[i++];
- reg16 |= values[i++] << 8;
- MCHBAR16(0x400*ch + 0x5fa) = reg16;
- reg16 = values[i++];
- reg16 |= values[i++] << 8;
- MCHBAR16(0x400*ch + 0x58c) = reg16;
+ MCHBAR16(0x400 * channel + 0x58c) = medium;
+ MCHBAR16(0x400 * channel + 0x5fa) = coarse_offset;
}
}
-static void sdram_program_receive_enable(struct sysinfo *s)
+static void sdram_program_receive_enable(struct sysinfo *s, int fast_boot)
{
- /* enable upper CMOS */
- RCBA32(0x3400) = (1 << 2);
-
/* Program Receive Enable Timings */
- if ((s->boot_path == BOOT_PATH_WARM_RESET)
- || (s->boot_path == BOOT_PATH_RESUME)) {
- sdram_recover_receive_enable();
- } else {
+ if (fast_boot)
+ sdram_recover_receive_enable(s);
+ else
rcven(s);
- sdram_save_receive_enable();
- }
}
static void dradrb_ddr2(struct sysinfo *s)
@@ -1470,7 +1439,7 @@ static void power_ddr2(struct sysinfo *s)
MCHBAR8(0x561 + (lane << 2)) = MCHBAR8(0x561 + (lane << 2)) & ~(1 << 3);
}
-void raminit_ddr2(struct sysinfo *s)
+void raminit_ddr2(struct sysinfo *s, int fast_boot)
{
u8 ch;
u8 r, bank;
@@ -1613,7 +1582,7 @@ void raminit_ddr2(struct sysinfo *s)
}
// Receive enable
- sdram_program_receive_enable(s);
+ sdram_program_receive_enable(s, fast_boot);
printk(BIOS_DEBUG, "Done rcven\n");
// Finish rcven