From dc542702108fc80997f074978ac404c83ee0e9bf Mon Sep 17 00:00:00 2001 From: Lee Leahy Date: Sat, 18 Jun 2016 18:52:43 -0700 Subject: soc/intel/quark: Pass in the memory initialization parameters Specify the memory initialization parameters in mainboard/intel/galileo/devicetree.cb. Pass these values into FSP to initialize memory. TEST=Build and run on Galileo Gen2 Change-Id: I83ee196f5fb825118a3a74b61f73f3728a1a1dc6 Signed-off-by: Lee Leahy Reviewed-on: https://review.coreboot.org/15260 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- src/mainboard/intel/galileo/devicetree.cb | 27 +++++- src/soc/intel/quark/chip.h | 79 ++++++++++++++++- src/soc/intel/quark/romstage/romstage.c | 101 ++++++++++++++++++++-- src/vendorcode/intel/fsp/fsp1_1/quark/FspUpdVpd.h | 101 +++++++++++++++++++--- 4 files changed, 288 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/mainboard/intel/galileo/devicetree.cb b/src/mainboard/intel/galileo/devicetree.cb index fcc0dae526..f7d666d6f5 100644 --- a/src/mainboard/intel/galileo/devicetree.cb +++ b/src/mainboard/intel/galileo/devicetree.cb @@ -20,7 +20,32 @@ chip soc/intel/quark # Set the parameters for MemoryInit ############################################################ - register "PcdSmmTsegSize" = "0" # SMM Region size in MiB + register "AddrMode" = "0" + register "ChanMask" = "1" # Channel 0 enabled + register "ChanWidth" = "1" # 16-bit channel + register "DramDensity" = "1" # 1 Gib; + register "DramRonVal" = "0" # 34 Ohm + register "DramRttNomVal" = "2" # 120 Ohm + register "DramRttWrVal" = "0" # off + register "DramSpeed" = "0" # 800 MHz + register "DramType" = "0" # DDR3 + register "DramWidth" = "0" # 8-bit + register "EccScrubBlkSize" = "2" # 64 byte blocks + register "EccScrubInterval" = "0" # ECC scrub disabled + register "Flags" = "MRC_FLAG_SCRAMBLE_EN" + register "FspReservedMemoryLength" = "0x00100000" # Size in bytes + register "RankMask" = "1" # RANK 0 enabled + register "SmmTsegSize" = "0" # SMM Region size in MiB + register "SocRdOdtVal" = "0" # off + register "SocWrRonVal" = "1" # 32 Ohm + register "SocWrSlewRate" = "1" # 4V/nSec + register "SrInt" = "3" # 7.8 uSec + register "SrTemp" = "0" # normal + register "tCL" = "6" # clocks + register "tFAW" = "40000" # picoseconds + register "tRAS" = "37500" # picoseconds + register "tRRD" = "10000" # picoseconds + register "tWTR" = "10000" # picoseconds ############################################################ # Enable the devices diff --git a/src/soc/intel/quark/chip.h b/src/soc/intel/quark/chip.h index fc9890fde5..66105eaa0b 100644 --- a/src/soc/intel/quark/chip.h +++ b/src/soc/intel/quark/chip.h @@ -23,6 +23,19 @@ #include #include +/// +/// MRC Flags bits +/// +#define MRC_FLAG_ECC_EN BIT0 +#define MRC_FLAG_SCRAMBLE_EN BIT1 +#define MRC_FLAG_MEMTEST_EN BIT2 + +/* 0b DDR "fly-by" topology else 1b DDR "tree" topology */ +#define MRC_FLAG_TOP_TREE_EN BIT3 + +/* If set ODR signal is asserted to DRAM devices on writes */ +#define MRC_FLAG_WR_ODT_EN BIT4 + struct soc_intel_quark_config { /* * MemoryInit: @@ -33,7 +46,71 @@ struct soc_intel_quark_config { * built into the coreboot image. The fields below contain retain * the FSP PCD field name. */ - UINT16 PcdSmmTsegSize; + + UINT32 FspReservedMemoryLength; /* FSP reserved memory in bytes */ + + UINT32 Flags; /* Bitmap of MRC_FLAG_XXX defs above */ + UINT32 tRAS; /* ACT to PRE command period in picoseconds */ + + /* Delay from start of internal write transaction to internal read + * command in picoseconds + */ + UINT32 tWTR; + + /* ACT to ACT command period (JESD79 specific to page size 1K/2K) in + * picoseconds + */ + UINT32 tRRD; + + /* Four activate window (JESD79 specific to page size 1K/2K) in + * picoseconds + */ + UINT32 tFAW; + UINT8 DramWidth; /* 0=x8, 1=x16, others=RESERVED */ + + /* 0=DDRFREQ_800, 1=DDRFREQ_1066, others=RESERVED. Only 533MHz SKU + * support 1066 memory + */ + UINT8 DramSpeed; + UINT8 DramType; /* 0=DDR3,1=DDR3L, others=RESERVED */ + + /* bit[0] RANK0_EN, bit[1] RANK1_EN, others=RESERVED */ + UINT8 RankMask; + UINT8 ChanMask; /* bit[0] CHAN0_EN, others=RESERVED */ + UINT8 ChanWidth; /* 1=x16, others=RESERVED */ + + /* 0, 1, 2 (mode 2 forced if ecc enabled), others=RESERVED */ + UINT8 AddrMode; + + /* 1=1.95us, 2=3.9us, 3=7.8us, others=RESERVED. REFRESH_RATE */ + UINT8 SrInt; + UINT8 SrTemp; /* 0=normal, 1=extended, others=RESERVED */ + + /* 0=34ohm, 1=40ohm, others=RESERVED. RON_VALUE Select MRS1.DIC driver + * impedance control. + */ + UINT8 DramRonVal; + UINT8 DramRttNomVal; /* 0=40ohm, 1=60ohm, 2=120ohm, others=RESERVED */ + UINT8 DramRttWrVal; /* 0=off others=RESERVED */ + + /* 0=off, 1=60ohm, 2=120ohm, 3=180ohm, others=RESERVED */ + UINT8 SocRdOdtVal; + UINT8 SocWrRonVal; /* 0=27ohm, 1=32ohm, 2=40ohm, others=RESERVED */ + UINT8 SocWrSlewRate; /* 0=2.5V/ns, 1=4V/ns, others=RESERVED */ + + /* 0=512Mb, 1=1Gb, 2=2Gb, 3=4Gb, others=RESERVED */ + UINT8 DramDensity; + UINT8 tCL; /* DRAM CAS Latency in clocks */ + + /* ECC scrub interval in miliseconds 1..255 (0 works as feature + * disable) + */ + UINT8 EccScrubInterval; + + /* Number of 32B blocks read for ECC scrub 2..16 */ + UINT8 EccScrubBlkSize; + + UINT8 SmmTsegSize; /* SMM size in MiB */ }; extern struct chip_operations soc_ops; diff --git a/src/soc/intel/quark/romstage/romstage.c b/src/soc/intel/quark/romstage/romstage.c index b99ad5425d..2a4c658745 100644 --- a/src/soc/intel/quark/romstage/romstage.c +++ b/src/soc/intel/quark/romstage/romstage.c @@ -129,6 +129,8 @@ void soc_memory_init_params(struct romstage_params *params, const struct device *dev; const struct soc_intel_quark_config *config; struct chipset_power_state *ps = car_get_var_ptr(&power_state); + char *rmu_file; + size_t rmu_file_len; /* Locate the configuration data from devicetree.cb */ dev = dev_find_slot(0, LPC_DEV_FUNC); @@ -150,11 +152,44 @@ void soc_memory_init_params(struct romstage_params *params, reg_script_run_on_dev(LPC_BDF, clear_smi_and_wake_events); } + /* Locate the RMU data file in flash */ + rmu_file = cbfs_boot_map_with_leak("rmu.bin", CBFS_TYPE_RAW, + &rmu_file_len); + if (!rmu_file) + die("Microcode file (rmu.bin) not found."); + /* Update the UPD data for MemoryInit */ printk(BIOS_DEBUG, "Updating UPD values for MemoryInit: 0x%p\n", upd); - upd->PcdSerialRegisterBase = UART_BASE_ADDRESS; - upd->PcdSmmTsegSize = IS_ENABLED(CONFIG_HAVE_SMI_HANDLER) ? - config->PcdSmmTsegSize : 0; + upd->AddrMode = config->AddrMode; + upd->ChanMask = config->ChanMask; + upd->ChanWidth = config->ChanWidth; + upd->DramDensity = config->DramDensity; + upd->DramRonVal = config->DramRonVal; + upd->DramRttNomVal = config->DramRttNomVal; + upd->DramRttWrVal = config->DramRttWrVal; + upd->DramSpeed = config->DramSpeed; + upd->DramType = config->DramType; + upd->DramWidth = config->DramWidth; + upd->EccScrubBlkSize = config->EccScrubBlkSize; + upd->EccScrubInterval = config->EccScrubInterval; + upd->Flags = config->Flags; + upd->FspReservedMemoryLength = config->FspReservedMemoryLength; + upd->RankMask = config->RankMask; + upd->RmuBaseAddress = (uintptr_t)rmu_file; + upd->RmuLength = rmu_file_len; + upd->SerialPortBaseAddress = UART_BASE_ADDRESS; + upd->SmmTsegSize = IS_ENABLED(CONFIG_HAVE_SMI_HANDLER) ? + config->SmmTsegSize : 0; + upd->SocRdOdtVal = config->SocRdOdtVal; + upd->SocWrRonVal = config->SocWrRonVal; + upd->SocWrSlewRate = config->SocWrSlewRate; + upd->SrInt = config->SrInt; + upd->SrTemp = config->SrTemp; + upd->tCL = config->tCL; + upd->tFAW = config->tFAW; + upd->tRAS = config->tRAS; + upd->tRRD = config->tRRD; + upd->tWTR = config->tWTR; } void soc_display_memory_init_params(const MEMORY_INIT_UPD *old, @@ -162,11 +197,61 @@ void soc_display_memory_init_params(const MEMORY_INIT_UPD *old, { /* Display the parameters for MemoryInit */ printk(BIOS_SPEW, "UPD values for MemoryInit at: 0x%p\n", new); - fsp_display_upd_value("PcdSerialRegisterBase", - sizeof(old->PcdSerialRegisterBase), - old->PcdSerialRegisterBase, new->PcdSerialRegisterBase); - fsp_display_upd_value("PcdSmmTsegSize", sizeof(old->PcdSmmTsegSize), - old->PcdSmmTsegSize, new->PcdSmmTsegSize); + fsp_display_upd_value("AddrMode", sizeof(old->AddrMode), + old->AddrMode, new->AddrMode); + fsp_display_upd_value("ChanMask", sizeof(old->ChanMask), + old->ChanMask, new->ChanMask); + fsp_display_upd_value("ChanWidth", sizeof(old->ChanWidth), + old->ChanWidth, new->ChanWidth); + fsp_display_upd_value("DramDensity", sizeof(old->DramDensity), + old->DramDensity, new->DramDensity); + fsp_display_upd_value("DramRonVal", sizeof(old->DramRonVal), + old->DramRonVal, new->DramRonVal); + fsp_display_upd_value("DramRttNomVal", sizeof(old->DramRttNomVal), + old->DramRttNomVal, new->DramRttNomVal); + fsp_display_upd_value("DramRttWrVal", sizeof(old->DramRttWrVal), + old->DramRttWrVal, new->DramRttWrVal); + fsp_display_upd_value("DramSpeed", sizeof(old->DramSpeed), + old->DramSpeed, new->DramSpeed); + fsp_display_upd_value("DramType", sizeof(old->DramType), + old->DramType, new->DramType); + fsp_display_upd_value("DramWidth", sizeof(old->DramWidth), + old->DramWidth, new->DramWidth); + fsp_display_upd_value("EccScrubBlkSize", sizeof(old->EccScrubBlkSize), + old->EccScrubBlkSize, new->EccScrubBlkSize); + fsp_display_upd_value("EccScrubInterval", sizeof(old->EccScrubInterval), + old->EccScrubInterval, new->EccScrubInterval); + fsp_display_upd_value("Flags", sizeof(old->Flags), old->Flags, + new->Flags); + fsp_display_upd_value("FspReservedMemoryLength", + sizeof(old->FspReservedMemoryLength), + old->FspReservedMemoryLength, new->FspReservedMemoryLength); + fsp_display_upd_value("RankMask", sizeof(old->RankMask), old->RankMask, + new->RankMask); + fsp_display_upd_value("RmuBaseAddress", sizeof(old->RmuBaseAddress), + old->RmuBaseAddress, new->RmuBaseAddress); + fsp_display_upd_value("RmuLength", sizeof(old->RmuLength), + old->RmuLength, new->RmuLength); + fsp_display_upd_value("SerialPortBaseAddress", + sizeof(old->SerialPortBaseAddress), + old->SerialPortBaseAddress, new->SerialPortBaseAddress); + fsp_display_upd_value("SmmTsegSize", sizeof(old->SmmTsegSize), + old->SmmTsegSize, new->SmmTsegSize); + fsp_display_upd_value("SocRdOdtVal", sizeof(old->SocRdOdtVal), + old->SocRdOdtVal, new->SocRdOdtVal); + fsp_display_upd_value("SocWrRonVal", sizeof(old->SocWrRonVal), + old->SocWrRonVal, new->SocWrRonVal); + fsp_display_upd_value("SocWrSlewRate", sizeof(old->SocWrSlewRate), + old->SocWrSlewRate, new->SocWrSlewRate); + fsp_display_upd_value("SrInt", sizeof(old->SrInt), old->SrInt, + new->SrInt); + fsp_display_upd_value("SrTemp", sizeof(old->SrTemp), old->SrTemp, + new->SrTemp); + fsp_display_upd_value("tCL", sizeof(old->tCL), old->tCL, new->tCL); + fsp_display_upd_value("tFAW", sizeof(old->tFAW), old->tFAW, new->tFAW); + fsp_display_upd_value("tRAS", sizeof(old->tRAS), old->tRAS, new->tRAS); + fsp_display_upd_value("tRRD", sizeof(old->tRRD), old->tRRD, new->tRRD); + fsp_display_upd_value("tWTR", sizeof(old->tWTR), old->tWTR, new->tWTR); } void soc_after_ram_init(struct romstage_params *params) diff --git a/src/vendorcode/intel/fsp/fsp1_1/quark/FspUpdVpd.h b/src/vendorcode/intel/fsp/fsp1_1/quark/FspUpdVpd.h index 86f548777c..2c7e81265c 100644 --- a/src/vendorcode/intel/fsp/fsp1_1/quark/FspUpdVpd.h +++ b/src/vendorcode/intel/fsp/fsp1_1/quark/FspUpdVpd.h @@ -85,29 +85,110 @@ typedef struct { UINT64 Revision; /** Offset 0x0028 **/ - UINT32 PcdRmuBinaryBaseAddress; + UINT32 RmuBaseAddress; /** Offset 0x002C **/ - UINT32 UnusedUpdSpace0; + UINT32 RmuLength; /** Offset 0x0030 **/ - UINT32 PcdSerialRegisterBase; + UINT32 SerialPortBaseAddress; /** Offset 0x0034 **/ - UINT8 PcdSmmTsegSize; -/** Offset 0x0035 + UINT32 tRAS; +/** Offset 0x0038 +**/ + UINT32 tWTR; +/** Offset 0x003C +**/ + UINT32 tRRD; +/** Offset 0x0040 +**/ + UINT32 tFAW; +/** Offset 0x0044 +**/ + UINT32 Flags; +/** Offset 0x0048 +**/ + UINT8 DramWidth; +/** Offset 0x0049 +**/ + UINT8 DramSpeed; +/** Offset 0x004A +**/ + UINT8 DramType; +/** Offset 0x004B +**/ + UINT8 RankMask; +/** Offset 0x004C +**/ + UINT8 ChanMask; +/** Offset 0x004D +**/ + UINT8 ChanWidth; +/** Offset 0x004E +**/ + UINT8 AddrMode; +/** Offset 0x004F +**/ + UINT8 SrInt; +/** Offset 0x0050 +**/ + UINT8 SrTemp; +/** Offset 0x0051 +**/ + UINT8 DramRonVal; +/** Offset 0x0052 **/ - UINT8 ReservedMemoryInitUpd[3]; + UINT8 DramRttNomVal; +/** Offset 0x0053 +**/ + UINT8 DramRttWrVal; +/** Offset 0x0054 +**/ + UINT8 SocRdOdtVal; +/** Offset 0x0055 +**/ + UINT8 SocWrRonVal; +/** Offset 0x0056 +**/ + UINT8 SocWrSlewRate; +/** Offset 0x0057 +**/ + UINT8 DramDensity; +/** Offset 0x0058 +**/ + UINT8 tCL; +/** Offset 0x0059 +**/ + UINT8 EccScrubInterval; +/** Offset 0x005A +**/ + UINT8 EccScrubBlkSize; +/** Offset 0x005B +**/ + UINT8 SmmTsegSize; +/** Offset 0x005C +**/ + UINT32 FspReservedMemoryLength; +/** Offset 0x0060 +**/ + UINT32 MrcDataPtr; +/** Offset 0x0064 +**/ + UINT32 MrcDataLength; +/** Offset 0x0068 +**/ + UINT8 ReservedMemoryInitUpd[8]; } MEMORY_INIT_UPD; typedef struct { -/** Offset 0x0038 +/** Offset 0x0070 **/ UINT64 Signature; -/** Offset 0x0040 +/** Offset 0x0078 **/ UINT64 Revision; -/** Offset 0x0048 +/** Offset 0x0080 **/ UINT16 PcdRegionTerminator; } SILICON_INIT_UPD; @@ -132,7 +213,7 @@ typedef struct _UPD_DATA_REGION { /** Offset 0x0018 **/ MEMORY_INIT_UPD MemoryInitUpd; -/** Offset 0x0038 +/** Offset 0x0070 **/ SILICON_INIT_UPD SiliconInitUpd; } UPD_DATA_REGION; -- cgit v1.2.3