1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #ifndef _SOC_APOLLOLAKE_MEMINIT_H_ 4 #define _SOC_APOLLOLAKE_MEMINIT_H_ 5 6 #include <fsp/soc_binding.h> 7 #include <types.h> 8 9 /* 10 * LPDDR4 helper routines for configuring the memory UPD for LPDDR4 operation. 11 * There are 4 physical LPDDR4 channels each 32-bits wide. There are 2 logical 12 * channels using 2 physical channels together to form a 64-bit interface to 13 * memory for each logical channel. 14 */ 15 16 enum { 17 LP4_PHYS_CH0A, 18 LP4_PHYS_CH0B, 19 LP4_PHYS_CH1A, 20 LP4_PHYS_CH1B, 21 LP4_NUM_PHYS_CHANNELS, 22 }; 23 24 /* Logical channel identification. */ 25 enum { 26 LP4_LCH0, 27 LP4_LCH1, 28 }; 29 30 /* 31 * The DQs within a physical channel can be bit-swizzled within each byte. 32 * Within a channel the bytes can be swapped, but the DQs need to be routed 33 * with the corresponding DQS (strobe). 34 */ 35 enum { 36 LP4_DQS0, 37 LP4_DQS1, 38 LP4_DQS2, 39 LP4_DQS3, 40 LP4_NUM_BYTE_LANES, 41 DQ_BITS_PER_DQS = 8, 42 }; 43 44 enum { 45 /* RL-tRCD-tRP */ 46 LP4_SPEED_1600 = 1600, /* 14-15-15 */ 47 LP4_SPEED_2133 = 2133, /* 20-20-20 */ 48 LP4_SPEED_2400 = 2400, /* 24-22-22 */ 49 }; 50 51 /* LPDDR4 module density in bits. */ 52 enum { 53 LP4_4Gb_DENSITY = 4, 54 LP4_6Gb_DENSITY = 6, 55 LP4_8Gb_DENSITY = 8, 56 LP4_12Gb_DENSITY = 12, 57 LP4_16Gb_DENSITY = 16, 58 }; 59 60 /* 61 * ODT settings : 62 * If ODT PIN to LP4 DRAM is pulled HIGH for ODT_A, and HIGH for ODT_B, 63 * choose ODT_AB_HIGH_HIGH. If ODT PIN to LP4 DRAM is pulled HIGH for ODT_A, 64 * and LOW for ODT_B, choose ODT_AB_HIGH_LOW. 65 * 66 * Note that the enum values correspond to the interpreted UPD fields 67 * within Ch[3:0]_OdtConfig parameters. 68 */ 69 enum { 70 ODT_A_B_HIGH_LOW = 0 << 1, 71 ODT_A_B_HIGH_HIGH = 1 << 1, 72 nWR_24 = 1 << 5, 73 }; 74 75 /* Provide bit swizzling per DQS and byte swapping within a channel. */ 76 struct lpddr4_chan_swizzle_cfg { 77 uint8_t dqs[LP4_NUM_BYTE_LANES][DQ_BITS_PER_DQS]; 78 }; 79 80 struct lpddr4_swizzle_cfg { 81 struct lpddr4_chan_swizzle_cfg phys[LP4_NUM_PHYS_CHANNELS]; 82 }; 83 84 /* 85 * Initialize default LPDDR4 settings with provided speed. No logical channels 86 * are enabled. Subsequent calls to logical channel enabling are required. 87 */ 88 void meminit_lpddr4(FSP_M_CONFIG *cfg, int speed); 89 90 /* 91 * Enable logical channel providing the full lpddr4_swizzle_config to 92 * fill in per channel swizzle definitions. This assumes a 64-bit wide 93 * memory width per logical channel -- i.e. 2 physical channels are configured 94 * to the memory reference code. 95 */ 96 void meminit_lpddr4_enable_channel(FSP_M_CONFIG *cfg, int logical_chan, 97 int rank_density_gb, int dual_rank, 98 const struct lpddr4_swizzle_cfg *scfg); 99 100 struct lpddr4_sku { 101 int speed; 102 int ch0_rank_density; 103 int ch1_rank_density; 104 int ch0_dual_rank; 105 int ch1_dual_rank; 106 const char *part_num; 107 bool disable_periodic_retraining; 108 }; 109 110 struct lpddr4_cfg { 111 const struct lpddr4_sku *skus; 112 size_t num_skus; 113 const struct lpddr4_swizzle_cfg *swizzle_config; 114 }; 115 116 /* 117 * Initialize LPDDR4 settings by the provided lpddr4_cfg information and sku id. 118 * The sku id is an index into the sku array within the lpddr4_cfg struct. 119 */ 120 void meminit_lpddr4_by_sku(FSP_M_CONFIG *cfg, 121 const struct lpddr4_cfg *lpcfg, size_t sku_id); 122 /* One of the two below needs to be called. If one is obtaining the part 123 * number out of band from the lpddr_cfg then the part_num variant will 124 * suffice. */ 125 void save_lpddr4_dimm_info(const struct lpddr4_cfg *lpcfg, size_t mem_sku); 126 void save_lpddr4_dimm_info_part_num(const char *dram_part_num); 127 128 /* Retrieve the amount of memory configured in the system in MiB. It's only 129 * valid during romstage. */ 130 size_t memory_in_system_in_mib(void); 131 /* Retrieve the requested i/o hole in MiB. Only valid in romstage. */ 132 size_t iohole_in_mib(void); 133 134 #endif /* _SOC_APOLLOLAKE_MEMINIT_H_ */ 135