From 577e41c06e74a30a422e30ff8b7b7d3db2d5a8b4 Mon Sep 17 00:00:00 2001 From: Ravi Sarawadi Date: Fri, 3 Aug 2018 15:41:31 -0700 Subject: [PATCH] soc/intel/apollolake: Add support for LPDDR4 nWR setting nWR (Write-Recovery for AutoPre-charge commands), the programmed value of nWR is the number of clock cycles the LPDDR4-SDRAM device uses to determine the starting point of an internal Pre-charge operation after a Write burst with AP (auto-pre-charge) enabled. For >2133MHz speed parts the nWR needs to be set to 24 clock cycles. The nWR field, though, is only in the GLK FSP, so just update that field conditionally based on the GLK Kconfig option. BUG=b:112062440 TEST= build test Change-Id: I1147538f72f4e2f14e32f3657c05f1f505a56fbf Signed-off-by: Ravi Sarawadi Signed-off-by: Aaron Durbin Reviewed-on: https://review.coreboot.org/27850 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- .../intel/apollolake/include/soc/meminit.h | 1 + src/soc/intel/apollolake/meminit.c | 20 +++++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/soc/intel/apollolake/include/soc/meminit.h b/src/soc/intel/apollolake/include/soc/meminit.h index 27b6556d12..31645a4dc4 100644 --- a/src/soc/intel/apollolake/include/soc/meminit.h +++ b/src/soc/intel/apollolake/include/soc/meminit.h @@ -81,6 +81,7 @@ enum { enum { ODT_A_B_HIGH_LOW = 0 << 1, ODT_A_B_HIGH_HIGH = 1 << 1, + nWR_24 = 1 << 5, }; /* Provide bit swizzling per DQS and byte swapping within a channel. */ diff --git a/src/soc/intel/apollolake/meminit.c b/src/soc/intel/apollolake/meminit.c index b0a5f4a534..9e6622cc1b 100644 --- a/src/soc/intel/apollolake/meminit.c +++ b/src/soc/intel/apollolake/meminit.c @@ -69,8 +69,10 @@ size_t iohole_in_mib(void) return 2 * (GiB / MiB); } -static void set_lpddr4_defaults(FSP_M_CONFIG *cfg) +static void set_lpddr4_defaults(FSP_M_CONFIG *cfg, int speed) { + uint8_t odt_config; + /* Enable memory down BGA since it's the only LPDDR4 packaging. */ cfg->Package = 1; cfg->MemoryDown = 1; @@ -122,10 +124,16 @@ static void set_lpddr4_defaults(FSP_M_CONFIG *cfg) /* Set CA ODT with default setting of ODT pins of LPDDR4 modules pulled up to 1.1V. */ - cfg->Ch0_OdtConfig = ODT_A_B_HIGH_HIGH; - cfg->Ch1_OdtConfig = ODT_A_B_HIGH_HIGH; - cfg->Ch2_OdtConfig = ODT_A_B_HIGH_HIGH; - cfg->Ch3_OdtConfig = ODT_A_B_HIGH_HIGH; + odt_config = ODT_A_B_HIGH_HIGH; + + /* Need to set correct Write-Recovery configuration based on speed. */ + if (IS_ENABLED(CONFIG_SOC_INTEL_GLK) && speed >= LP4_SPEED_2133) + odt_config |= nWR_24; + + cfg->Ch0_OdtConfig = odt_config; + cfg->Ch1_OdtConfig = odt_config; + cfg->Ch2_OdtConfig = odt_config; + cfg->Ch3_OdtConfig = odt_config; } struct speed_mapping { @@ -205,7 +213,7 @@ void meminit_lpddr4(FSP_M_CONFIG *cfg, int speed) printk(BIOS_INFO, "LP4DDR speed is %dMHz\n", speed); cfg->Profile = fsp_memory_profile(speed); - set_lpddr4_defaults(cfg); + set_lpddr4_defaults(cfg, speed); } static void enable_logical_chan0(FSP_M_CONFIG *cfg,