1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #ifndef _SOC_CANNONLAKE_MEMCFG_INIT_H_ 4 #define _SOC_CANNONLAKE_MEMCFG_INIT_H_ 5 6 #include <stddef.h> 7 #include <stdint.h> 8 #include <fsp/soc_binding.h> 9 10 /* Number of dq bits controlled per dqs */ 11 #define DQ_BITS_PER_DQS 8 12 13 /* Number of memory DIMM slots available on Cannonlake board */ 14 #define NUM_DIMM_SLOT 4 15 16 /* 17 * Number of memory packages, where a "package" represents a 64-bit solution. 18 */ 19 #define DDR_NUM_PACKAGES 2 20 21 /* 64-bit Channel identification */ 22 enum { 23 DDR_CH0, 24 DDR_CH1, 25 DDR_NUM_CHANNELS 26 }; 27 28 struct spd_by_pointer { 29 size_t spd_data_len; 30 uintptr_t spd_data_ptr; 31 }; 32 33 enum mem_info_read_type { 34 NOT_EXISTING, /* No memory in this slot */ 35 READ_SMBUS, /* Read on-module spd by SMBUS. */ 36 READ_SPD_CBFS, /* Find spd file in CBFS. */ 37 READ_SPD_MEMPTR /* Find spd data from pointer. */ 38 }; 39 40 struct spd_info { 41 enum mem_info_read_type read_type; 42 union spd_data_by { 43 /* To read on-module spd when read_type is READ_SMBUS. */ 44 uint8_t spd_smbus_address; 45 46 /* To identify spd file when read_type is READ_SPD_CBFS. */ 47 int spd_index; 48 49 /* To find spd data when read_type is READ_SPD_MEMPTR. */ 50 struct spd_by_pointer spd_data_ptr_info; 51 } spd_spec; 52 }; 53 54 /* Board-specific memory dq mapping information */ 55 struct cnl_mb_cfg { 56 /* Parameters required to access SPD for CH0D0/CH0D1/CH1D0/CH1D1. */ 57 struct spd_info spd[NUM_DIMM_SLOT]; 58 59 /* 60 * For each channel, there are 6 sets of DQ byte mappings, 61 * where each set has a package 0 and a package 1 value (package 0 62 * represents the first 64-bit lpddr4 chip combination, and package 1 63 * represents the second 64-bit lpddr4 chip combination). 64 * The first three sets are for CLK, CMD, and CTL. 65 * The fsp package actually expects 6 sets, even though the last 3 sets 66 * are not used in CNL. 67 * We let the meminit_lpddr4() routine take care of clearing the 68 * unused fields for the caller. 69 * Note that dq_map is only used by LPDDR; it does not need to be 70 * initialized for designs using DDR4. 71 */ 72 uint8_t dq_map[DDR_NUM_CHANNELS][6][DDR_NUM_PACKAGES]; 73 74 /* 75 * DQS CPU<>DRAM map Ch0 and Ch1. Each array entry represents a 76 * mapping of a dq bit on the CPU to the bit it's connected to on 77 * the memory part. The array index represents the dqs bit number 78 * on the memory part, and the values in the array represent which 79 * pin on the CPU that DRAM pin connects to. 80 * dqs_map is only used by LPDDR; same comments apply as for dq_map 81 * above. 82 */ 83 uint8_t dqs_map[DDR_NUM_CHANNELS][DQ_BITS_PER_DQS]; 84 85 /* 86 * Rcomp resistor values. These values represent the resistance in 87 * ohms of the three rcomp resistors attached to the DDR_COMP_0, 88 * DDR_COMP_1, and DDR_COMP_2 pins on the DRAM. 89 */ 90 uint16_t rcomp_resistor[3]; 91 92 /* 93 * Rcomp target values. These will typically be the following 94 * values for Cannon Lake : { 80, 40, 40, 40, 30 } 95 */ 96 uint16_t rcomp_targets[5]; 97 98 /* 99 * Indicates whether memory is interleaved. 100 * Set to 1 for an interleaved design, 101 * set to 0 for non-interleaved design. 102 */ 103 uint8_t dq_pins_interleaved; 104 105 /* 106 * VREF_CA configuration. 107 * Set to 0 VREF_CA goes to both CH_A and CH_B, 108 * set to 1 VREF_CA goes to CH_A and VREF_DQ_A goes to CH_B, 109 * set to 2 VREF_CA goes to CH_A and VREF_DQ_B goes to CH_B. 110 */ 111 uint8_t vref_ca_config; 112 113 /* Early Command Training Enabled */ 114 uint8_t ect; 115 }; 116 117 /* 118 * Initialize default memory configurations for CannonLake. 119 */ 120 void cannonlake_memcfg_init(FSP_M_CONFIG *mem_cfg, 121 const struct cnl_mb_cfg *cnl_cfg); 122 123 #endif /* _SOC_CANNONLAKE_MEMCFG_INIT_H_ */ 124