Attention is currently required from: Patrick Rudolph. Angel Pons has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/60226 )
Change subject: [TESTME] nb/intel/ironlake: Even more magic ......................................................................
[TESTME] nb/intel/ironlake: Even more magic
Change-Id: Ia2c3b47d908cfed49757c0449aeebf05dccbc799 Signed-off-by: Angel Pons th3fanbus@gmail.com --- M src/northbridge/intel/ironlake/raminit.c 1 file changed, 93 insertions(+), 35 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/26/60226/1
diff --git a/src/northbridge/intel/ironlake/raminit.c b/src/northbridge/intel/ironlake/raminit.c index 668d610..bac8832 100644 --- a/src/northbridge/intel/ironlake/raminit.c +++ b/src/northbridge/intel/ironlake/raminit.c @@ -19,6 +19,7 @@ #include <spd.h> #include <timestamp.h> #include <cpu/x86/mtrr.h> +#include <cpu/intel/model_2065x/model_2065x.h> #include <cpu/intel/speedstep.h> #include <cpu/intel/turbo.h> #include <mrc_cache.h> @@ -424,6 +425,11 @@ write_1d0((v & and) | or, addr, split, 1); }
+static void or_1d0(u16 addr, u32 or, int bits) +{ + rmw_1d0(addr, ~0, or, bits); +} + static int find_highest_bit_set(u16 val) { int i; @@ -1112,19 +1118,17 @@ cas_latency_shift = 0; } { - int speed_bit; - speed_bit = - ((info->clock_speed_index > 1 - || (info->silicon_revision != 2 - && info->silicon_revision != 3))) ^ (info->revision >= - 0x10); - write_500(info, 0, speed_bit | ((!info->use_ecc) << 1), 0x60e, - 3, 1); - write_500(info, 1, speed_bit | ((!info->use_ecc) << 1), 0x60e, - 3, 1); - if (info->revision >= 0x10 && info->clock_speed_index <= 1 - && (info->silicon_revision == 2 - || info->silicon_revision == 3)) + u8 speed_bit = 0; + if (info->clock_speed_index <= 1) { + if (info->silicon_revision == 2 || info->silicon_revision == 3) + speed_bit = 1; + } + if (info->revision < 0x10) + speed_bit = !speed_bit; + + write_500(info, 0, speed_bit | !info->use_ecc << 1, 0x60e, 3, 1); + write_500(info, 1, speed_bit | !info->use_ecc << 1, 0x60e, 3, 1); + if (info->revision >= 0x10 && speed_bit) rmw_1d0(0x116, 5, 2, 4); } mchbar_write32(0x120, 1 << (info->max_slots_used_in_channel + 28) | 0x188e7f9f); @@ -1215,27 +1219,30 @@ cas_latency_derived++; for (channel = 0; channel < NUM_CHANNELS; channel++) { mchbar_write32(0x240 + (channel << 10), - ((info->clock_speed_index == 0) * 0x11000) | - 0x1002100 | (2 + info->clock_speed_index) << 4 | - (info->cas_latency - 3)); - write_500(info, channel, (info->clock_speed_index << 1) | 1, + (info->cas_latency - 3) | + (2 + info->clock_speed_index) << 4 | + ((info->clock_speed_index == 0) + 2) << 12 | + (info->clock_speed_index == 0) << 16 | + 0x1000100); + write_500(info, channel, info->clock_speed_index * 2 + 1, 0x609, 6, 1); write_500(info, channel, info->clock_speed_index + 2 * info->cas_latency - 7, 0x601, 6, 1);
mchbar_write32(0x250 + (channel << 10), - (lane_3_delay + info->clock_speed_index + 9) << 6 | - info->board_lane_delay[7] << 2 | - info->board_lane_delay[4] << 16 | - info->board_lane_delay[1] << 25 | + (lane_3_delay + info->clock_speed_index + 9) << 6 | /* write to pchg */ + info->board_lane_delay[7] << 2 | /* read to precharge */ + info->board_lane_delay[4] << 16 | /* refresh to activate */ + info->board_lane_delay[1] << 25 | /* precharge to activate */ info->board_lane_delay[1] << 29 | 1); mchbar_write32(0x254 + (channel << 10), info->board_lane_delay[1] >> 3 | - (info->board_lane_delay[8] + 4 * info->use_ecc) << 6 | - 0x80 | info->board_lane_delay[6] << 1 | - info->board_lane_delay[2] << 28 | - cas_latency_derived << 16 | 0x4700000); + (info->board_lane_delay[8] + 2 + 4 * info->use_ecc) << 6 | /* tFAW */ + info->board_lane_delay[6] << 1 | /* activate to activate */ + info->board_lane_delay[2] << 28 | /* activate to write */ + cas_latency_derived << 16 | /* read to write */ + 0x4700000); mchbar_write32(0x258 + (channel << 10), (info->board_lane_delay[5] + info->clock_speed_index + 9) << 12 | (info->clock_speed_index + 12 - info->cas_latency) << 8 | @@ -3177,12 +3184,12 @@ info.board_lane_delay[8] = 0x10; */ info.board_lane_delay[0] = 0x18; - info.board_lane_delay[1] = 0x07; - info.board_lane_delay[2] = 0x07; - info.board_lane_delay[3] = 0x08; + info.board_lane_delay[1] = 0x09; + info.board_lane_delay[2] = 0x09; + info.board_lane_delay[3] = 0x0a; info.board_lane_delay[4] = 0x4a; - info.board_lane_delay[5] = 0x04; - info.board_lane_delay[6] = 0x04; + info.board_lane_delay[5] = 0x05; + info.board_lane_delay[6] = 0x04 | 1 << 7; /* HACK FOR maxact_dischk */ info.board_lane_delay[7] = 0x05; info.board_lane_delay[8] = 0x10;
@@ -3463,7 +3470,7 @@ mchbar_write16(0x3e8 + (channel << 10), clock_idx << 8 | clock_idx); mchbar_write32(0x320 + (channel << 10), 0x29002900); mchbar_write32(0x324 + (channel << 10), val32); - mchbar_write32(0x368 + (channel << 10), 0x32003200); + mchbar_write32(0x368 + (channel << 10), is_2dpc ? 0x07000700 : 0x32003200); mchbar_write16(0x352 + (channel << 10), 0x505); mchbar_write16(0x354 + (channel << 10), 0x3c3c); mchbar_write16(0x356 + (channel << 10), 0x1040); @@ -3472,9 +3479,50 @@ mchbar_write16(0x422 + (channel << 10), 0x1040); }
- write_1d0(0x4, 0x151, 4, 1); - write_1d0(0, 0x142, 3, 1); - rdmsr(0x1ac); // !!!! + { + u32 local_20; + if (info.revision >= 0x10) + local_20 = 4; + else if (info.revision >= 0x8) + local_20 = 0; + else if (1 /* some unknown checks */) + local_20 = 6; + else + local_20 = 2; + + write_1d0(local_20, 0x151, 4, 1); + write_1d0(0, 0x142, 3, 1); + + if (info.revision >= 0x18) { + /* Get TDP limit in 1/8W units */ + const msr_t msr = rdmsr(MSR_TURBO_POWER_CURRENT_LIMIT); + if ((msr.lo & 0x7fff) < 145) { + or_1d0(0x132, 1 << 2, 5); + or_1d0(0x132, 1 << 1, 5); + or_1d0(0xce, 1 << 3, 6); + or_1d0(0x320, 1 << 3, 6); + or_1d0(0x132, 1 << 0, 5); + or_1d0(0xd6, 1 << 4, 6); + or_1d0(0x328, 1 << 4, 6); + or_1d0(0x11c, 1 << 2, 4); + or_1d0(0x11c, 1 << 1, 4); + or_1d0(0x11c, 1 << 0, 4); + or_1d0(0xd6, 1 << 3, 6); + or_1d0(0x328, 1 << 3, 6); + or_1d0(0x132, 1 << 3, 5); + or_1d0(0x132, 1 << 3, 5); + or_1d0(0xce, 1 << 4, 6); + or_1d0(0x132, 1 << 3, 5); + or_1d0(0xce, 1 << 4, 6); + or_1d0(0x11c, 1 << 3, 4); + or_1d0(0x11c, 1 << 3, 4); + or_1d0(0x11c, 1 << 3, 4); + or_1d0(0xce, 1 << 4, 6); + or_1d0(0x320, 1 << 4, 6); + } + } + } + write_500(&info, 1, 1, 0x6b3, 4, 1); write_500(&info, 1, 1, 0x6cf, 4, 1);
@@ -3667,7 +3715,13 @@ mchbar_write32(0x128, ((frequency_11(&info) * 20 / 18) & 0x3ff) << 16 | 0xd05); mchbar_write8(0x12c, 0x1f); mchbar_write8(0x12d, 0x56); - mchbar_write8(0x12e, 0x31); + { + u8 val8 = 3; + if (info.clock_speed_index > 0 /* || unknown check */) + val8 = 0; + + mchbar_write8(0x12e, (val8 | 0xc) << 2 | info.max_slots_used_in_channel); + } mchbar_write8(0x12f, 0); mchbar_write8(0x271, 1 << 1); mchbar_write8(0x671, 1 << 1); @@ -3675,7 +3729,11 @@ for (channel = 0; channel < NUM_CHANNELS; channel++) mchbar_write32(0x294 + (channel << 10), (info.populated_ranks_mask[channel] & 3) << 16); + mchbar_clrsetbits32(0x134, ~0xfc01ffff, 0x10000); + + mdelay(1); + mchbar_clrsetbits32(0x134, ~0xfc85ffff, 0x850000); for (channel = 0; channel < NUM_CHANNELS; channel++) mchbar_clrsetbits32(0x260 + (channel << 10), 0xf << 20, 1 << 27 |