diff options
author | Patrick Rudolph <siro@das-labor.org> | 2016-01-26 20:02:14 +0100 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2016-03-02 21:46:49 +0100 |
commit | 9f3f9154c9f3dd1e3cfbd2703b681c3e9ddf4dc7 (patch) | |
tree | c473e23fc7dc436629f0ca444ccf113173f632e4 /src/northbridge/intel/sandybridge/raminit.c | |
parent | 2bdeb7f843c707023ea2bd39e314f8eec51c7add (diff) | |
download | coreboot-9f3f9154c9f3dd1e3cfbd2703b681c3e9ddf4dc7.tar.xz |
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>
Diffstat (limited to 'src/northbridge/intel/sandybridge/raminit.c')
-rw-r--r-- | src/northbridge/intel/sandybridge/raminit.c | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c index 65282d2848..c154b23f91 100644 --- a/src/northbridge/intel/sandybridge/raminit.c +++ b/src/northbridge/intel/sandybridge/raminit.c @@ -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) { + u32 reg32; + u8 rev; 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); - if (!(dev && dev->chip_info)) - return DEFAULT_TCK; - - cfg = dev->chip_info; + 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); + + if ((rev & BASE_REV_MASK) == 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; - 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 perform_raminit(int s3resume) |