nb/intel/sandybridge/romstage: Read fuse bits for max MEM Clk

Instead of hardcoding the maximum supported DDR frequency to
800Mhz (DDR3-1600), read the fuse bits that encode this information.

Test system:
 * Intel IvyBridge
 * Gigabyte GA-B75M-D3H

Change-Id: I515a2695a490f16aeb946bfaf3a1e860c607cba9
Signed-off-by: Patrick Rudolph <siro@das-labor.org>
Reviewed-on: https://review.coreboot.org/13487
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
Patrick Rudolph 2016-01-26 20:02:14 +01:00 committed by Martin Roth
parent 2bdeb7f843
commit 9f3f9154c9
3 changed files with 55 additions and 15 deletions

View File

@ -33,8 +33,10 @@
* These values are in 1/256 ns units. * These values are in 1/256 ns units.
* @{ * @{
*/ */
#define TCK_1333MHZ 192
#define TCK_1200MHZ 212
#define TCK_1066MHZ 240 #define TCK_1066MHZ 240
#define TCK_933MHZ 275 #define TCK_933MHZ 275
#define TCK_800MHZ 320 #define TCK_800MHZ 320
#define TCK_666MHZ 384 #define TCK_666MHZ 384
#define TCK_533MHZ 480 #define TCK_533MHZ 480

View File

@ -4089,26 +4089,61 @@ void init_dram_ddr3(spd_raw_data * spds, int mobile, int min_tck,
static unsigned int get_mem_min_tck(void) static unsigned int get_mem_min_tck(void)
{ {
u32 reg32;
u8 rev;
const struct device *dev; const struct device *dev;
const struct northbridge_intel_sandybridge_config *cfg; const struct northbridge_intel_sandybridge_config *cfg = NULL;
dev = dev_find_slot(0, HOST_BRIDGE); dev = dev_find_slot(0, HOST_BRIDGE);
if (!(dev && dev->chip_info)) if (dev)
return DEFAULT_TCK; cfg = dev->chip_info;
cfg = dev->chip_info;
/* If this is zero, it just means devicetree.cb didn't set it */ /* If this is zero, it just means devicetree.cb didn't set it */
if (cfg->max_mem_clock_mhz == 0) if (!cfg || cfg->max_mem_clock_mhz == 0) {
return DEFAULT_TCK; rev = pci_read_config8(PCI_DEV(0, 0, 0), PCI_DEVICE_ID);
if (cfg->max_mem_clock_mhz >= 800) if ((rev & BASE_REV_MASK) == BASE_REV_SNB) {
return TCK_800MHZ; /* read Capabilities A Register DMFC bits */
else if (cfg->max_mem_clock_mhz >= 666) reg32 = pci_read_config32(PCI_DEV(0, 0, 0), CAPID0_A);
return TCK_666MHZ; reg32 &= 0x7;
else if (cfg->max_mem_clock_mhz >= 533)
return TCK_533MHZ; switch (reg32) {
return TCK_400MHZ; case 7: return TCK_533MHZ;
case 6: return TCK_666MHZ;
case 5: return TCK_800MHZ;
/* reserved: */
default:
break;
}
} else {
/* read Capabilities B Register DMFC bits */
reg32 = pci_read_config32(PCI_DEV(0, 0, 0), CAPID0_B);
reg32 = (reg32 >> 4) & 0x7;
switch (reg32) {
case 7: return TCK_533MHZ;
case 6: return TCK_666MHZ;
case 5: return TCK_800MHZ;
case 4: return TCK_933MHZ;
case 3: return TCK_1066MHZ;
case 2: return TCK_1200MHZ;
case 1: return TCK_1333MHZ;
/* reserved: */
default:
break;
}
}
return DEFAULT_TCK;
} else {
if (cfg->max_mem_clock_mhz >= 800)
return TCK_800MHZ;
else if (cfg->max_mem_clock_mhz >= 666)
return TCK_666MHZ;
else if (cfg->max_mem_clock_mhz >= 533)
return TCK_533MHZ;
else
return TCK_400MHZ;
}
} }
void perform_raminit(int s3resume) void perform_raminit(int s3resume)

View File

@ -99,6 +99,9 @@
#define TSEG 0xb8 /* TSEG base */ #define TSEG 0xb8 /* TSEG base */
#define TOLUD 0xbc /* Top of Low Used Memory */ #define TOLUD 0xbc /* Top of Low Used Memory */
#define CAPID0_A 0xe4 /* Capabilities Register A */
#define CAPID0_B 0xe8 /* Capabilities Register B */
#define SKPAD 0xdc /* Scratchpad Data */ #define SKPAD 0xdc /* Scratchpad Data */
/* Device 0:1.0 PCI configuration space (PCI Express) */ /* Device 0:1.0 PCI configuration space (PCI Express) */