From 6d7a8c1125d17781fe2354eb316df247c82df741 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Tue, 7 Mar 2017 20:48:14 +0100 Subject: nb/intel/x4x/raminit: Rework receive enable calibration Moves receive enable calibration to a separate file to lighten raminit.c a bit. Receive enable calibration is quite similar to gm45 so it reuses some of its function names. The functional changes are: * the minimum coarse is now reset for each channel; * on the second fine search for DQS high, TAP overflow is handled by increasing medium; * start coarse at CAS + 1 instead of CAS - 1. Other Intel northbridges do the same and the results are more in line with register dumps from vendor bios. These might improve stability. TESTED on ga-g41m-es2l Change-Id: I0c970455e609d3ce96a262cbf110336a2079da4d Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/18692 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/northbridge/intel/x4x/raminit_ddr2.c | 283 +------------------------------ 1 file changed, 1 insertion(+), 282 deletions(-) (limited to 'src/northbridge/intel/x4x/raminit_ddr2.c') diff --git a/src/northbridge/intel/x4x/raminit_ddr2.c b/src/northbridge/intel/x4x/raminit_ddr2.c index bc012d259b..9c13fc1995 100644 --- a/src/northbridge/intel/x4x/raminit_ddr2.c +++ b/src/northbridge/intel/x4x/raminit_ddr2.c @@ -31,11 +31,6 @@ #define ME_UMA_SIZEMB 0 -static inline void barrier(void) -{ - asm volatile("mfence":::); -} - static u32 fsb2mhz(u32 speed) { return (speed * 267) + 800; @@ -1161,282 +1156,6 @@ static void jedec_ddr2(struct sysinfo *s) printk(BIOS_DEBUG, "MRS done\n"); } -static u8 sampledqs(u16 mchloc, u32 addr, u8 hilow, u8 repeat) -{ - u8 dqsmatch = 1; - volatile u32 strobe; - - while (repeat-- > 0) { - MCHBAR8(0x5d8) = MCHBAR8(0x5d8) & ~0x2; - udelay(2); - MCHBAR8(0x5d8) = MCHBAR8(0x5d8) | 0x2; - udelay(2); - MCHBAR8(0x9d8) = MCHBAR8(0x9d8) & ~0x2; - udelay(2); - MCHBAR8(0x9d8) = MCHBAR8(0x9d8) | 0x2; - udelay(2); - barrier(); - strobe = read32((u32 *)addr); - barrier(); - if (((MCHBAR32(mchloc) & 0x40) >> 6) != hilow) - dqsmatch = 0; - } - return dqsmatch; -} - -static void rcven_ddr2(struct sysinfo *s) -{ - u8 i, reg8, ch, lane; - u32 addr; - u8 tap = 0; - u8 savecc, savemedium, savetap, coarsecommon, medium; - u8 lanecoarse[8] = {0}; - u8 mincoarse = 0xff; - u8 pitap[2][8]; - u16 coarsectrl[2]; - u16 coarsedelay[2]; - u16 mediumphase[2]; - u16 readdelay[2]; - u16 mchbar; - MCHBAR8(0x5d8) = MCHBAR8(0x5d8) & ~0xc; - MCHBAR8(0x9d8) = MCHBAR8(0x9d8) & ~0xc; - MCHBAR8(0x5dc) = MCHBAR8(0x5dc) & ~0x80; - - FOR_EACH_POPULATED_CHANNEL(s->dimms, ch) { - addr = (ch << 29); - for (i = 0; !RANK_IS_POPULATED(s->dimms, ch, i); i++) - addr += 128*1024*1024; - - for (lane = 0; lane < 8; lane++) { - printk(BIOS_DEBUG, "Channel %d, Lane %d addr=0x%08x\n", ch, lane, addr); - coarsecommon = (s->selected_timings.CAS - 1); - switch (lane) { - case 0: case 1: - medium = 0; - break; - case 2: case 3: - medium = 1; - break; - case 4: case 5: - medium = 2; - break; - case 6: case 7: - medium = 3; - break; - default: - medium = 0; - break; - } - mchbar = 0x400*ch + 0x561 + (lane << 2); - tap = 0; - MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) & ~0xf0000) | - (coarsecommon << 16); - MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) & ~(3 << (lane*2))) | - (medium << (lane*2)); - MCHBAR8(0x400*ch + 0x560 + lane*4) = MCHBAR8(0x400*ch + 0x560 + lane*4) & ~0xf; - MCHBAR8(0x400*ch + 0x560 + lane*4) = MCHBAR8(0x400*ch + 0x560 + lane*4) & ~0x70; - savecc = coarsecommon; - savemedium = medium; - savetap = 0; - - MCHBAR16(0x400*ch + 0x588) = (MCHBAR16(0x400*ch + 0x588) & ~(3 << (lane*2))) | - (1 << (lane*2)); - - printk(BIOS_DEBUG, "rcven 0.1 coarse=%d\n", coarsecommon); - while (sampledqs(mchbar, addr, 1, 1) == 1) { - if (medium < 3) { - medium++; - MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) & - ~(3 << (lane*2))) | (medium << (lane*2)); - } else { - medium = 0; - coarsecommon++; - MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) & - ~0xf0000) | (coarsecommon << 16); - MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) & - ~(3 << (lane*2))) | (medium << (lane*2)); - } - if (coarsecommon > 16) { - die("Coarse > 16: DQS tuning failed, halt\n"); - break; - } - } - printk(BIOS_DEBUG, " GOT IT (high -> low transition) coarse=%d medium=%d\n", coarsecommon, medium); - - savemedium = medium; - savecc = coarsecommon; - if (medium < 3) { - medium++; - MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) & - ~(3 << (lane*2))) | (medium << (lane*2)); - } else { - medium = 0; - coarsecommon++; - - MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) & ~0xf0000) | - (coarsecommon << 16); - MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) & ~(3 << (lane*2))) | - (medium << (lane*2)); - } - - printk(BIOS_DEBUG, "rcven 0.2\n"); - while (sampledqs(mchbar, addr, 0, 1) == 1) { - savemedium = medium; - savecc = coarsecommon; - if (medium < 3) { - medium++; - MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) & - ~(3 << (lane*2))) | (medium << (lane*2)); - } else { - medium = 0; - coarsecommon++; - MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) & - ~0xf0000) | (coarsecommon << 16); - MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) & - ~(3 << (lane*2))) | (medium << (lane*2)); - } - if (coarsecommon > 16) { - die("Coarse DQS tuning 2 failed, halt\n"); - break; - } - } - printk(BIOS_DEBUG, " GOT IT (low -> high transition) coarse=%d medium=%d\n", coarsecommon, medium); - - - coarsecommon = savecc; - medium = savemedium; - MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) & - ~0xf0000) | (coarsecommon << 16); - MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) & - ~(3 << (lane*2))) | (medium << (lane*2)); - - printk(BIOS_DEBUG, "rcven 0.3\n"); - tap = 0; - while (sampledqs(mchbar, addr, 1, 1) == 0) { - savetap = tap; - tap++; - if (tap > 14) - break; - MCHBAR8(0x400*ch + 0x560 + (lane*4)) = - (MCHBAR8(0x400*ch + 0x560 + (lane*4)) & ~0xf) | tap; - } - - tap = savetap; - MCHBAR8(0x400*ch + 0x560 + (lane*4)) = - (MCHBAR8(0x400*ch + 0x560 + (lane*4)) & ~0xf) | tap; - MCHBAR8(0x400*ch + 0x560 + (lane*4)) = - (MCHBAR8(0x400*ch + 0x560 + (lane*4)) & ~0x70) | 0x30; - if (medium < 3) { - medium++; - MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) & - ~(3 << (lane*2))) | (medium << (lane*2)); - } else { - medium = 0; - coarsecommon++; - MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) & - ~0xf0000) | (coarsecommon << 16); - MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) & - ~(3 << (lane*2))) | (medium << (lane*2)); - } - if (sampledqs(mchbar, addr, 1, 1) == 0) - die("Not at DQS high, doh\n"); - - printk(BIOS_DEBUG, "rcven 0.4\n"); - while (sampledqs(mchbar, addr, 1, 1) == 1) { - coarsecommon--; - MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) & - ~0xf0000) | (coarsecommon << 16); - if (coarsecommon == 0) { - die("Couldn't find DQS-high 0 indicator, halt\n"); - break; - } - } - printk(BIOS_DEBUG, " GOT IT (high -> low transition) coarse=%d medium=%d\n", coarsecommon, medium); - - printk(BIOS_DEBUG, "rcven 0.5\n"); - while (sampledqs(mchbar, addr, 0, 1) == 1) { - savemedium = medium; - savecc = coarsecommon; - if (medium < 3) { - medium++; - MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) & - ~(3 << (lane*2))) | (medium << (lane*2)); - } else { - medium = 0; - coarsecommon++; - MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) & - ~0xf0000) | (coarsecommon << 16); - MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) & - ~(3 << (lane*2))) | (medium << (lane*2)); - } - if (coarsecommon > 16) { - die("Coarse DQS tuning 5 failed, halt\n"); - break; - } - } - printk(BIOS_DEBUG, " GOT IT (low -> high transition) coarse=%d medium=%d\n", coarsecommon, medium); - - printk(BIOS_DEBUG, "rcven 0.6\n"); - coarsecommon = savecc; - medium = savemedium; - MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) & - ~0xf0000) | (coarsecommon << 16); - MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) & - ~(3 << (lane*2))) | (medium << (lane*2)); - while (sampledqs(mchbar, addr, 1, 1) == 0) { - savetap = tap; - tap++; - if (tap > 14) - break; - MCHBAR8(0x400*ch + 0x560 + lane*4) = - (MCHBAR8(0x400*ch + 0x560 + lane*4) & ~0xf) | tap; - } - tap = savetap; - MCHBAR8(0x400*ch + 0x560 + lane*4) = - (MCHBAR8(0x400*ch + 0x560 + lane*4) & ~0xf) | tap; - MCHBAR8(0x400*ch + 0x560 + lane*4) = - (MCHBAR8(0x400*ch + 0x560 + lane*4) & ~0x70) | 0x70; - - pitap[ch][lane] = 0x70 | tap; - - MCHBAR16(0x400*ch + 0x588) = MCHBAR16(0x400*ch + 0x588) & ~(3 << (lane*2)); - lanecoarse[lane] = coarsecommon; - printk(BIOS_DEBUG, "rcven 0.7\n"); - } // END EACH LANE - - // Find minimum coarse value - for (lane = 0; lane < 8; lane++) { - if (mincoarse > lanecoarse[lane]) - mincoarse = lanecoarse[lane]; - } - - printk(BIOS_DEBUG, "Found min coarse value = %d\n", mincoarse); - - for (lane = 0; lane < 8; lane++) { - reg8 = (lanecoarse[lane] == 0) ? 0 : lanecoarse[lane] - mincoarse; - MCHBAR16(0x400*ch + 0x5fa) = (MCHBAR16(0x400*ch + 0x5fa) & ~(3 << (lane*2))) | - (reg8 << (lane*2)); - } - MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) & ~0xf0000) | (mincoarse << 16); - coarsectrl[ch] = mincoarse; - coarsedelay[ch] = MCHBAR16(0x400*ch + 0x5fa); - mediumphase[ch] = MCHBAR16(0x400*ch + 0x58c); - readdelay[ch] = MCHBAR16(0x400*ch + 0x588); - } // END EACH POPULATED CHANNEL - - FOR_EACH_CHANNEL(ch) { - for (lane = 0; lane < 8; lane++) { - MCHBAR8(0x400*ch + 0x560 + (lane*4)) = - (MCHBAR8(0x400*ch + 0x560 + (lane*4)) & ~0xf) | pitap[ch][lane]; - } - MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) & ~0xf0000) | - (coarsectrl[ch] << 16); - MCHBAR16(0x400*ch + 0x5fa) = coarsedelay[ch]; - MCHBAR16(0x400*ch + 0x58c) = mediumphase[ch]; - } - printk(BIOS_DEBUG, "End rcven\n"); -} - static void sdram_save_receive_enable(void) { int i = 0; @@ -1505,7 +1224,7 @@ static void sdram_program_receive_enable(struct sysinfo *s) || (s->boot_path == BOOT_PATH_RESUME)) { sdram_recover_receive_enable(); } else { - rcven_ddr2(s); + rcven(s); sdram_save_receive_enable(); } } -- cgit v1.2.3