From 3cce7a0311b85f22e3b653bee1bf1c0e4c7e4e45 Mon Sep 17 00:00:00 2001 From: Shelley Chen Date: Wed, 6 Feb 2019 15:21:55 -0800 Subject: [PATCH] soc/intel/cannonlake: Add field to identify single channel memory Variants of Hatch need to accommodate single channel DDR. Also, removing const modifier as we'll need to set these fields incrementally now. For the single channel configuration, we set MemorySpdPtr10 to 0. For the dual channel configuration, we set MemorySpdPtr10 to MemorySpdPtr00. BUG=b:123062346, b:122959294 BRANCH=None TEST=Boot into current boards and ensure that we have 2 channels as expected Change-Id: Ice22b103664187834e255d1359bfd9b51993b5b6 Signed-off-by: Shelley Chen Reviewed-on: https://review.coreboot.org/c/31262 Reviewed-by: Patrick Rudolph Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/soc/intel/cannonlake/cnl_memcfg_init.c | 10 ++++--- .../cannonlake/include/soc/cnl_memcfg_init.h | 29 ++++++++++++++----- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/soc/intel/cannonlake/cnl_memcfg_init.c b/src/soc/intel/cannonlake/cnl_memcfg_init.c index 4425862c32..e97b5711e8 100644 --- a/src/soc/intel/cannonlake/cnl_memcfg_init.c +++ b/src/soc/intel/cannonlake/cnl_memcfg_init.c @@ -49,14 +49,16 @@ static void meminit_memcfg(FSP_M_CONFIG *mem_cfg, } static void meminit_memcfg_spd(FSP_M_CONFIG *mem_cfg, - const struct cnl_mb_cfg *board_cfg, + const struct cnl_mb_cfg *cnl_cfg, size_t spd_data_len, uintptr_t spd_data_ptr) { mem_cfg->MemorySpdDataLen = spd_data_len; - mem_cfg->MemorySpdPtr00 = spd_data_ptr; - /* Use the same spd data for channel 1, Dimm 0 */ - mem_cfg->MemorySpdPtr10 = mem_cfg->MemorySpdPtr00; + if (cnl_cfg->channel_empty[0] == 0) + mem_cfg->MemorySpdPtr00 = spd_data_ptr; + + if (cnl_cfg->channel_empty[1] == 0) + mem_cfg->MemorySpdPtr10 = spd_data_ptr; } /* diff --git a/src/soc/intel/cannonlake/include/soc/cnl_memcfg_init.h b/src/soc/intel/cannonlake/include/soc/cnl_memcfg_init.h index 245d2cfd61..c602180592 100644 --- a/src/soc/intel/cannonlake/include/soc/cnl_memcfg_init.h +++ b/src/soc/intel/cannonlake/include/soc/cnl_memcfg_init.h @@ -62,7 +62,7 @@ struct cnl_mb_cfg { * and let the meminit_lpddr4() routine take care of clearing the * unused fields for the caller. */ - const uint8_t dq_map[DDR_NUM_CHANNELS][3][DDR_NUM_PACKAGES]; + uint8_t dq_map[DDR_NUM_CHANNELS][3][DDR_NUM_PACKAGES]; /* * DQS CPU<>DRAM map Ch0 and Ch1. Each array entry represents a @@ -71,38 +71,51 @@ struct cnl_mb_cfg { * on the memory part, and the values in the array represent which * pin on the CPU that DRAM pin connects to. */ - const uint8_t dqs_map[DDR_NUM_CHANNELS][DQ_BITS_PER_DQS]; + uint8_t dqs_map[DDR_NUM_CHANNELS][DQ_BITS_PER_DQS]; /* * Rcomp resistor values. These values represent the resistance in * ohms of the three rcomp resistors attached to the DDR_COMP_0, * DDR_COMP_1, and DDR_COMP_2 pins on the DRAM. */ - const uint16_t rcomp_resistor[3]; + uint16_t rcomp_resistor[3]; /* * Rcomp target values. These will typically be the following * values for Cannon Lake : { 80, 40, 40, 40, 30 } */ - const uint16_t rcomp_targets[5]; + uint16_t rcomp_targets[5]; /* * Indicates whether memory is interleaved. * Set to 1 for an interleaved design, * set to 0 for non-interleaved design. */ - const uint8_t dq_pins_interleaved; + uint8_t dq_pins_interleaved; /* - * VREF_CA configuraation. + * VREF_CA configuration. * Set to 0 VREF_CA goes to both CH_A and CH_B, * set to 1 VREF_CA goes to CH_A and VREF_DQ_A goes to CH_B, * set to 2 VREF_CA goes to CH_A and VREF_DQ_B goes to CH_B. */ - const uint8_t vref_ca_config; + uint8_t vref_ca_config; /* Early Command Training Enabled */ - const uint8_t ect; + uint8_t ect; + + /* + * Flags to indicate which channels are populated. We + * currently support single or dual channel configurations. + * Set 1 to indicate that the channel is not populated Set 0 + * to indicate that the channel is populated. For example, + * dual channel memory configuration would have both + * channel_empty[0] = 0 and channel_empty[1] = 0. Note that + * this flag is only used for soldered down DRAM where we get + * SPD data from CBFS. We need the value 0 to default to + * populated in order to support existing boards. + */ + uint8_t channel_empty[2]; }; /*