coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
romstage.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <string.h>
4 #include <soc/romstage.h>
5 #include <soc/gpio_apl.h>
6 #include <soc/meminit.h>
7 #include <fsp/api.h>
8 #include <FspmUpd.h>
9 #include <console/console.h>
10 #include <gpio.h>
11 #include "gpio.h"
12 
13 /*
14  * Offsets:
15  * - GPIO_214: 0xd8
16  * - GPIO_215: 0xe0
17  */
19 
20 static const struct lpddr4_sku skus[] = {
21  /* Samsung 280 K4F8E304HB-MGCJ 8Gb dual-ch */
22  [0] = {
24  .ch0_rank_density = LP4_8Gb_DENSITY,
25  .ch1_rank_density = 0,
26  .ch0_dual_rank = 0,
27  .ch1_dual_rank = 0,
28  .part_num = "K4F8E304HB-MGCJ",
29  },
30  [1] = {
31  .speed = LP4_SPEED_2400,
32  .ch0_rank_density = LP4_8Gb_DENSITY,
33  .ch1_rank_density = LP4_8Gb_DENSITY,
34  .ch0_dual_rank = 0,
35  .ch1_dual_rank = 0,
36  .part_num = "K4F8E304HB-MGCJ",
37  },
38  [2] = {
39  .speed = LP4_SPEED_2400,
40  .ch0_rank_density = LP4_16Gb_DENSITY,
41  .ch1_rank_density = LP4_16Gb_DENSITY,
42  .ch0_dual_rank = 1,
43  .ch1_dual_rank = 1,
44  .part_num = "K4F6E304HB-MGCJ",
45  },
46 };
47 
48 static const struct lpddr4_cfg lp4cfg = {
49  .skus = skus,
50  .num_skus = ARRAY_SIZE(skus),
51 };
52 
53 static const uint8_t ch0_bit_swizzling[] = {
54  0x0D, 0x0A, 0x08, 0x0B, 0x0C, 0x0F, 0x0E, 0x09,
55  0x06, 0x00, 0x03, 0x04, 0x07, 0x01, 0x05, 0x02,
56  0x1C, 0x1A, 0x19, 0x1B, 0x1D, 0x1F, 0x1E, 0x18,
57  0x10, 0x17, 0x15, 0x16, 0x14, 0x12, 0x13, 0x11
58 };
59 
60 static const uint8_t ch1_bit_swizzling[] = {
61  0x00, 0x07, 0x04, 0x05, 0x06, 0x02, 0x03, 0x01,
62  0x08, 0x0F, 0x0D, 0x0B, 0x0A, 0x09, 0x0E, 0x0C,
63  0x17, 0x11, 0x13, 0x12, 0x14, 0x15, 0x16, 0x10,
64  0x1C, 0x1A, 0x1D, 0x1F, 0x18, 0x19, 0x1E, 0x1B
65 };
66 
67 static const uint8_t ch2_bit_swizzling[] = {
68  0x0D, 0x08, 0x0B, 0x0E, 0x0C, 0x0F, 0x09, 0x0A,
69  0x04, 0x07, 0x01, 0x06, 0x02, 0x03, 0x00, 0x05,
70  0x18, 0x19, 0x1C, 0x1A, 0x1D, 0x1E, 0x1F, 0x1B,
71  0x11, 0x13, 0x15, 0x10, 0x16, 0x12, 0x17, 0x14
72 };
73 
74 static const uint8_t ch3_bit_swizzling[] = {
75  0x00, 0x05, 0x04, 0x07, 0x03, 0x02, 0x06, 0x01,
76  0x0A, 0x0B, 0x08, 0x09, 0x0C, 0x0E, 0x0D, 0x0F,
77  0x12, 0x16, 0x14, 0x13, 0x17, 0x11, 0x15, 0x10,
78  0x19, 0x1F, 0x1D, 0x1B, 0x1E, 0x18, 0x1C, 0x1A
79 };
80 
81 /*
82  * GPIO215 GPIO214 Memory size
83  * 0 0 2 GiB
84  * 0 1 4 GiB
85  * 1 0 8 GiB
86  * 1 1 8 GiB
87  */
89 {
90  uint8_t memory_skuid = 0;
91 
92  for (uint8_t i = 0; i < ARRAY_SIZE(memory_skuid_pads); i++) {
93  uint8_t rx_state = gpio_get(memory_skuid_pads[i]);
94  memory_skuid |= rx_state << i;
95  }
96  return memory_skuid;
97 }
98 
99 void mainboard_memory_init_params(FSPM_UPD *memupd)
100 {
101  printk(BIOS_DEBUG, "MAINBOARD: %s/%s called\n", __FILE__, __func__);
102 
103  FSP_M_CONFIG *config = &memupd->FspmConfig;
104 
106 
107  uint8_t memory_skuid = get_memory_skuid();
108  printk(BIOS_DEBUG, "MAINBOARD: Found memory SKU ID: 0x%02x\n", memory_skuid);
109 
110  switch (memory_skuid) {
111  case 0: /* 2GB */
112  config->DualRankSupportEnable = 0;
113  config->Ch0_RankEnable = 1;
114  config->Ch0_DramDensity = 2;
115  config->Ch1_RankEnable = 1;
116  config->Ch1_DramDensity = 2;
117  config->Ch2_RankEnable = 0;
118  config->Ch3_RankEnable = 0;
119  printk(BIOS_INFO, "MAINBOARD: Found supported memory: 2GB\n");
120  break;
121  case 1: /* 4GB */
122  config->DualRankSupportEnable = 1;
123  config->Ch0_RankEnable = 1;
124  config->Ch0_DramDensity = 2;
125  config->Ch1_RankEnable = 1;
126  config->Ch1_DramDensity = 2;
127  config->Ch2_RankEnable = 1;
128  config->Ch2_DramDensity = 2;
129  config->Ch3_RankEnable = 1;
130  config->Ch3_DramDensity = 2;
131  printk(BIOS_INFO, "MAINBOARD: Found supported memory: 4GB\n");
132  break;
133  case 2: /* 8GB */
134  config->DualRankSupportEnable = 1;
135  config->Ch0_RankEnable = 3;
136  config->Ch0_DramDensity = 2;
137  config->Ch1_RankEnable = 3;
138  config->Ch1_DramDensity = 2;
139  config->Ch2_RankEnable = 3;
140  config->Ch2_DramDensity = 2;
141  config->Ch3_RankEnable = 3;
142  config->Ch3_DramDensity = 2;
143  printk(BIOS_INFO, "MAINBOARD: Found supported memory: 8GB\n");
144  break;
145  case 3: /* 8GB */
146  config->DualRankSupportEnable = 1;
147  config->Ch0_RankEnable = 1;
148  config->Ch0_DramDensity = 4;
149  config->Ch1_RankEnable = 1;
150  config->Ch1_DramDensity = 4;
151  config->Ch2_RankEnable = 1;
152  config->Ch2_DramDensity = 4;
153  config->Ch3_RankEnable = 1;
154  config->Ch3_DramDensity = 4;
155  printk(BIOS_INFO, "MAINBOARD: Found supported memory: 8GB\n");
156  break;
157  default:
158  printk(BIOS_INFO, "MAINBOARD: No supported memory found!\n");
159  break;
160  }
161 
162  config->Package = 0x1; // 0x0
163  config->Profile = 0xB; // 0x19
164  config->MemoryDown = 0x1; // 0x0
165  config->DDR3LPageSize = 0x0; // 0x1
166  config->DIMM0SPDAddress = 0x0; // 0xa0
167  config->DIMM1SPDAddress = 0x0; // 0xa4
168  config->RmtCheckRun = 0x3; // 0x0
169  config->RmtMarginCheckScaleHighThreshold = 0xC8; // 0x0
170  config->EnhancePort8xhDecoding = 0x0; // 0x1
171 
172  config->Ch0_DeviceWidth = 0x1; // 0x0
173  config->Ch0_Option = 0x3; // 0x0
174  config->Ch1_DeviceWidth = 0x1; // 0x0
175  config->Ch1_Option = 0x3; // 0x0
176  config->Ch2_DeviceWidth = 0x1; // 0x0
177  config->Ch2_Option = 0x3; // 0x0
178  config->Ch3_DeviceWidth = 0x1; // 0x0
179  config->Ch3_Option = 0x3; // 0x0
180  config->StartTimerTickerOfPfetAssert = 0x4E20; // 0x0
181 
182  memcpy(config->Ch0_Bit_swizzling, &ch0_bit_swizzling,
183  sizeof(ch0_bit_swizzling));
184  memcpy(config->Ch1_Bit_swizzling, &ch1_bit_swizzling,
185  sizeof(ch1_bit_swizzling));
186  memcpy(config->Ch2_Bit_swizzling, &ch2_bit_swizzling,
187  sizeof(ch2_bit_swizzling));
188  memcpy(config->Ch3_Bit_swizzling, &ch3_bit_swizzling,
189  sizeof(ch3_bit_swizzling));
190 }
191 
193 {
195 }
void save_lpddr4_dimm_info(const struct lpddr4_cfg *lpcfg, size_t mem_sku)
@ LP4_SPEED_2400
Definition: meminit.h:49
@ LP4_16Gb_DENSITY
Definition: meminit.h:58
@ LP4_8Gb_DENSITY
Definition: meminit.h:56
void * memcpy(void *dest, const void *src, size_t n)
Definition: memcpy.c:7
#define ARRAY_SIZE(a)
Definition: helpers.h:12
#define printk(level,...)
Definition: stdlib.h:16
__weak void mainboard_save_dimm_info(struct romstage_params *params)
Definition: romstage.c:138
#define FSP_M_CONFIG
Definition: fsp_upd.h:8
#define GPIO_214
Definition: gpio_apl.h:172
#define GPIO_215
Definition: gpio_apl.h:173
int gpio_get(gpio_t gpio)
Definition: gpio.c:166
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
static const struct pad_config gpio_table[]
Definition: gpio.h:24
void mainboard_memory_init_params(FSPM_UPD *mupd)
Definition: romstage.c:22
enum board_config config
Definition: memory.c:448
static const uint8_t memory_skuid_pads[]
Definition: romstage.c:18
static const struct lpddr4_cfg lp4cfg
Definition: romstage.c:48
static const struct lpddr4_sku skus[]
Definition: romstage.c:20
static const uint8_t ch1_bit_swizzling[]
Definition: romstage.c:60
static const uint8_t ch3_bit_swizzling[]
Definition: romstage.c:74
static const uint8_t ch0_bit_swizzling[]
Definition: romstage.c:53
static const uint8_t ch2_bit_swizzling[]
Definition: romstage.c:67
static uint8_t get_memory_skuid(void)
Definition: romstage.c:88
void gpio_configure_pads(const struct soc_amd_gpio *gpio_list_ptr, size_t size)
program a particular set of GPIO
Definition: gpio.c:307
unsigned char uint8_t
Definition: stdint.h:8
const struct lpddr4_sku * skus
Definition: meminit.h:112
int speed
Definition: meminit.h:102