Attention is currently required from: Patrick Rudolph. Angel Pons has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/60223 )
Change subject: [TESTME] nb/intel/ironlake: Make raminit more magic ......................................................................
[TESTME] nb/intel/ironlake: Make raminit more magic
Change-Id: I7e09cc67ab64699121ba75fb5473b93194d8f36f Signed-off-by: Angel Pons th3fanbus@gmail.com --- M src/northbridge/intel/ironlake/raminit.c M src/northbridge/intel/ironlake/raminit.h 2 files changed, 134 insertions(+), 28 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/23/60223/1
diff --git a/src/northbridge/intel/ironlake/raminit.c b/src/northbridge/intel/ironlake/raminit.c index da506ac..6162085 100644 --- a/src/northbridge/intel/ironlake/raminit.c +++ b/src/northbridge/intel/ironlake/raminit.c @@ -241,11 +241,12 @@ } }
-static void write_26c(int channel, u16 si) +static void write_26c(int channel, u16 clock_speed) { + const u16 reftimeout = clock_speed * 7800 / 900; mchbar_write32(0x26c + (channel << 10), 0x03243f35); - mchbar_write32(0x268 + (channel << 10), 0xcfc00000 | si << 9); - mchbar_write16(0x2b9 + (channel << 10), si); + mchbar_write32(0x268 + (channel << 10), 0xcfc00000 | reftimeout << 9); + mchbar_write16(0x2b9 + (channel << 10), reftimeout); }
static void toggle_1d0_142_5ff(void) @@ -765,10 +766,12 @@ 375; some_delay_3_ps = halfcycle_ps(info) - some_delay_2_ps % halfcycle_ps(info); + info->some_delay_3_halfcycles = 0; if (info->revision_flag_1) { if (some_delay_3_ps >= 150) { const int some_delay_3_halfcycles = (some_delay_3_ps << 6) / halfcycle_ps(info); + info->some_delay_3_halfcycles = some_delay_3_halfcycles; some_delay_3_ps_rounded = halfcycle_ps(info) * some_delay_3_halfcycles >> 6; } @@ -784,6 +787,7 @@ some_delay_2_halfcycles_ceil - 1; if (!info->revision_flag_1) some_delay_2_halfcycles_floor++; + info->some_delay_2_halfcycles_floor = some_delay_2_halfcycles_floor; info->some_delay_2_halfcycles_ceil = some_delay_2_halfcycles_ceil; info->some_delay_3_ps_rounded = some_delay_3_ps_rounded; if ((info->populated_ranks[0][0][0] && info->populated_ranks[0][1][0]) @@ -910,6 +914,11 @@ info->avg4044[channel] = sum / count; info->max4048[channel] = max_of_unk; } + if (info->silicon_revision == 2 || info->silicon_revision == 3) + info->revision_flag_2 = 0; + else + info->revision_flag_2 = 1; + }
static void jedec_read(struct raminfo *info, @@ -1229,7 +1238,7 @@ cas_latency_derived << 16 | 0x4700000); mchbar_write32(0x258 + (channel << 10), (info->board_lane_delay[5] + info->clock_speed_index + 9) << 12 | - (info->clock_speed_index - info->cas_latency + 12) << 8 | + (info->clock_speed_index + 12 - info->cas_latency) << 8 | info->board_lane_delay[2] << 17 | info->board_lane_delay[4] << 24 | 0x47); mchbar_write32(0x25c + (channel << 10), @@ -3156,7 +3165,7 @@
info.last_500_command[0] = 0; info.last_500_command[1] = 0; - +/* info.board_lane_delay[0] = 0x14; info.board_lane_delay[1] = 0x07; info.board_lane_delay[2] = 0x07; @@ -3166,6 +3175,16 @@ info.board_lane_delay[6] = 0x04; info.board_lane_delay[7] = 0x05; 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[4] = 0x4a; + info.board_lane_delay[5] = 0x04; + info.board_lane_delay[6] = 0x04; + info.board_lane_delay[7] = 0x05; + info.board_lane_delay[8] = 0x10;
info.training.reg_178 = 0; info.training.reg_10b = 0; @@ -3362,25 +3381,88 @@ write_1d0(0, 0x33d, 0, 0); write_500(&info, 0, 0, 0xb61, 0, 0); write_500(&info, 1, 0, 0xb61, 0, 0); - mchbar_write32(0x1a30, 0); + mchbar_write32(0x1a30, (info.revision < 0x8) << 18); mchbar_write32(0x1a34, 0); + mchbar_write16(0x614, 0xb5b | (info.populated_ranks[1][0][0] * 0x404) | (info.populated_ranks[0][0][0] * 0xa0)); mchbar_write16(0x616, 0x26a); mchbar_write32(0x134, 0x856000); mchbar_write32(0x160, 0x5ffffff); - mchbar_clrsetbits32(0x114, ~0, 0xc2024440); // !!!! - mchbar_clrsetbits32(0x118, ~0, 0x4); // !!!! - for (channel = 0; channel < NUM_CHANNELS; channel++) - mchbar_write32(0x260 + (channel << 10), 0x30809ff | - (info.populated_ranks_mask[channel] & 3) << 20); + { + u8 val8 = 0; + u32 val32 = 0x2024400; + if (info.revision_flag_2 == 1) { + if (info.clock_speed_index > 2) + val8 = 1; + } else { + const u8 lut_118[4] = { 0xa, 0xd, 0x10, 0x14 }; + val8 = lut_118[info.clock_speed_index] - 4; + val32 |= 0xc << 28; + } + mchbar_clrsetbits32(0x114, 0xdffffcff, val32 | 0x40); + mchbar_clrsetbits32(0x118, 0x3f, val8 * 2); + + const u32 another_delay = 5625 + (info.clock_speed_index == 0 ? 1875 : 0); + const unsigned int cycle_time_ps = cycle_ps(&info); + u8 idx = 3; + while (idx * cycle_time_ps < another_delay) + idx++; + + for (channel = 0; channel < NUM_CHANNELS; channel++) { + val32 = 0x1fe; + val32 |= (idx + 1) * (1 << 17); + val32 |= val8 << 10; + val32 |= idx << 24; + val32 |= info.populated_ranks_mask[channel] << 20; + val32 |= !((info.populated_ranks_mask[channel] & 0x5) == 0x5); + mchbar_write32(0x260 + (channel << 10), val32); + } + } + for (channel = 0; channel < NUM_CHANNELS; channel++) { - mchbar_write16(0x31c + (channel << 10), 0x101); - mchbar_write16(0x360 + (channel << 10), 0x909); - mchbar_write16(0x3a4 + (channel << 10), 0x101); - mchbar_write16(0x3e8 + (channel << 10), 0x101); + const u8 clock_idx = info.clock_speed_index; + u8 val8 = clock_idx; + u32 val32 = 0x2c002c00; + if (channel == 0) { + if (info.silicon_revision == 0 || info.silicon_revision == 1) { + switch (clock_idx) { + case 0: + val8 = 8; + break; + case 1: + val8 = 2; + break; + case 2: + val8 = 9; + break; + case 3: + val8 = 10; + break; + } + } else { + val32 = 0; + } + } else { + u8 rankmask = 0x5; + rankmask &= info.populated_ranks_mask[0]; + rankmask &= info.populated_ranks_mask[1]; + if (info.silicon_revision != 1 || clock_idx < 2 || rankmask != 0x5) + val32 = 0; + else + val8 = 11; + } + const bool is_2dpc = (info.populated_ranks_mask[channel] & 0x5) == 0x5; + const u16 lut_x60[2][4] = { + { 0x101, 0x909, 0xa0a, 0x505 }, + { 0x202, 0xa0a, 0x505, 0x606 }, + }; + mchbar_write16(0x31c + (channel << 10), val8 << 8 | val8); + mchbar_write16(0x360 + (channel << 10), lut_x60[is_2dpc][clock_idx]); + mchbar_write16(0x3a4 + (channel << 10), clock_idx << 8 | clock_idx); + mchbar_write16(0x3e8 + (channel << 10), clock_idx << 8 | clock_idx); mchbar_write32(0x320 + (channel << 10), 0x29002900); - mchbar_write32(0x324 + (channel << 10), 0); + mchbar_write32(0x324 + (channel << 10), val32); mchbar_write32(0x368 + (channel << 10), 0x32003200); mchbar_write16(0x352 + (channel << 10), 0x505); mchbar_write16(0x354 + (channel << 10), 0x3c3c); @@ -3398,10 +3480,13 @@
rmw_1d0(0x21c, 0x38, 0, 6);
- write_1d0(((!info.populated_ranks[1][0][0]) << 1) | ((!info. - populated_ranks[0] - [0][0]) << 0), - 0x1d1, 3, 1); + if (info.revision >= 0x10) { + u8 channel_disable_mask = 0; + channel_disable_mask |= !info.populated_ranks[0][0][0] << 0; + channel_disable_mask |= !info.populated_ranks[1][0][0] << 1; + write_1d0(channel_disable_mask, 0x1d1, 3, 1); + } + for (channel = 0; channel < NUM_CHANNELS; channel++) { mchbar_write16(0x38e + (channel << 10), 0x5f5f); mchbar_write16(0x3d2 + (channel << 10), 0x5f5f); @@ -3462,8 +3547,23 @@ write_1d0(info.cached_training->reg_10b, 0x10b, 6, 1); }
- mchbar_clrsetbits32(0x1f4, ~0, 1 << 17); // !!!! - mchbar_write32(0x1f0, 0x1d000200); + { + const u32 val0 = (info.some_delay_3_halfcycles | 1 << 8) << 9; + mchbar_clrsetbits32(0x1f4, 0x7fe81, val0); + + u8 val1 = 2; + if (info.silicon_revision == 2 || info.silicon_revision == 3) + val1 = 0; + if (info.revision < 0x10) + val1 = 0; + if (info.revision < 0x8) + val1 = info.revision_flag_1; + + const u8 val2 = info.revision_flag_1 == 0 ? 0 : 6; + const u8 val3 = info.some_delay_2_halfcycles_floor; + + mchbar_write32(0x1f0, (((0xe800 | val1) << 3 | val2) << 3 | val3) << 7); + } mchbar_setbits8(0x1f0, 1 << 0); while (mchbar_read8(0x1f0) & 1) ; @@ -3558,11 +3658,13 @@ mchbar_clrsetbits32(0x2d0, ~0xff0c01ff, 0x200000); mchbar_write16(0x6c0, 0x14a0); mchbar_clrsetbits32(0x6d0, ~0xff0000ff, 0x8000); - mchbar_write16(0x232, 1 << 3); - /* 0x40004 or 0 depending on ? */ - mchbar_clrsetbits32(0x234, 0x40004, 0x40004); + mchbar_write16(0x232, 2 + info.board_lane_delay[1] - info.max_slots_used_in_channel); + { + const u32 val32 = info.max_slots_used_in_channel == 1 ? 0x40004 : 0; + mchbar_clrsetbits32(0x234, 0x40004, val32); + } mchbar_clrsetbits32(0x34, 0x7, 5); - mchbar_write32(0x128, 0x2150d05); + mchbar_write32(0x128, ((frequency_11(&info) * 20 / 18) & 0x3ff) << 16 | 0xd05); mchbar_write8(0x12c, 0x1f); mchbar_write8(0x12d, 0x56); mchbar_write8(0x12e, 0x31); @@ -3640,8 +3742,9 @@
/* was == 1 but is common */ pci_write_config16(NORTHBRIDGE, 0xc8, 3); - write_26c(0, 0x820); - write_26c(1, 0x820); + for (channel = 0; channel < NUM_CHANNELS; channel++) + write_26c(channel, (info.clock_speed_index + 3) * 60); + mchbar_setbits32(0x130, 1 << 1); /* end */
diff --git a/src/northbridge/intel/ironlake/raminit.h b/src/northbridge/intel/ironlake/raminit.h index edfce51..ea080fa 100644 --- a/src/northbridge/intel/ironlake/raminit.h +++ b/src/northbridge/intel/ironlake/raminit.h @@ -68,8 +68,11 @@ u32 delay46_ps[2]; u32 delay54_ps[2]; u8 revision_flag_1; + u8 revision_flag_2; u8 some_delay_1_cycle_floor; + u8 some_delay_2_halfcycles_floor; u8 some_delay_2_halfcycles_ceil; + u8 some_delay_3_halfcycles; u8 some_delay_3_ps_rounded;
const struct ram_training *cached_training;