Patrick Rudolph (siro@das-labor.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13487
-gerrit
commit bf6a8166121e96a926b78c8dfcb034a2da7b4509 Author: Patrick Rudolph siro@das-labor.org Date: Tue Jan 26 20:02:14 2016 +0100
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 --- src/include/device/dram/ddr3.h | 4 +- src/northbridge/intel/sandybridge/romstage.c | 65 ++++++++++++++++++++++------ 2 files changed, 54 insertions(+), 15 deletions(-)
diff --git a/src/include/device/dram/ddr3.h b/src/include/device/dram/ddr3.h index de75aee..525f497 100644 --- a/src/include/device/dram/ddr3.h +++ b/src/include/device/dram/ddr3.h @@ -33,8 +33,10 @@ * These values are in 1/256 ns units. * @{ */ +#define TCK_1333MHZ 192 +#define TCK_1200MHZ 212 #define TCK_1066MHZ 240 -#define TCK_933MHZ 275 +#define TCK_933MHZ 275 #define TCK_800MHZ 320 #define TCK_666MHZ 384 #define TCK_533MHZ 480 diff --git a/src/northbridge/intel/sandybridge/romstage.c b/src/northbridge/intel/sandybridge/romstage.c index 34d759f..ef5e0a0 100644 --- a/src/northbridge/intel/sandybridge/romstage.c +++ b/src/northbridge/intel/sandybridge/romstage.c @@ -36,30 +36,67 @@
#define HOST_BRIDGE PCI_DEVFN(0, 0) #define DEFAULT_TCK TCK_800MHZ +#define CAPID0_A 0xe4 +#define CAPID0_B 0xe8
static unsigned int get_mem_min_tck(void) { + u32 reg32; + u8 rev; const struct device *dev; const struct northbridge_intel_sandybridge_config *cfg;
dev = dev_find_slot(0, HOST_BRIDGE); - if (!(dev && dev->chip_info)) - return DEFAULT_TCK; - - cfg = dev->chip_info; + cfg = NULL; + if (dev) + cfg = dev->chip_info;
/* 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) { + rev = pci_read_config8(PCI_DEV(0, 0, 0), PCI_DEVICE_ID) & BASE_REV_MASK; + + if (rev == BASE_REV_SNB) { + /* read Capabilities A Register DMFC bits */ + reg32 = pci_read_config32(PCI_DEV(0, 0, 0), CAPID0_A); + reg32 &= 0x7; + + switch (reg32) { + 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; - - 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; + } 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 main(unsigned long bist)