blob: b3777b686f73df989487a65f4d40202c430c91e2 [file] [log] [blame]
Angel Ponsf5627e82020-04-05 15:46:52 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Lijian Zhao0ade3132017-07-07 12:25:20 -07002
Kyösti Mälkkia963acd2019-08-16 20:34:25 +03003#include <arch/romstage.h>
Lijian Zhao0ade3132017-07-07 12:25:20 -07004#include <cbmem.h>
5#include <console/console.h>
6#include <fsp/util.h>
Kyösti Mälkki32d47eb2019-09-28 00:00:30 +03007#include <intelblocks/cfg.h>
Lijian Zhaoe7a1e7d2017-10-09 18:39:30 -07008#include <intelblocks/cse.h>
Lijian Zhaob3dfcb82017-08-16 22:18:52 -07009#include <intelblocks/pmclib.h>
Angel Pons53496e62021-02-19 20:38:37 +010010#include <intelblocks/smbus.h>
Lijian Zhao0ade3132017-07-07 12:25:20 -070011#include <memory_info.h>
Subrata Banike8e43292018-02-06 13:28:53 +053012#include <soc/intel/common/smbios.h>
Lijian Zhaoe7a1e7d2017-10-09 18:39:30 -070013#include <soc/iomap.h>
Pratik Prajapati9027e1b2017-08-23 17:37:43 -070014#include <soc/pci_devs.h>
Lijian Zhao0ade3132017-07-07 12:25:20 -070015#include <soc/pm.h>
16#include <soc/romstage.h>
Subrata Banike8e43292018-02-06 13:28:53 +053017#include <string.h>
Lijian Zhao0ade3132017-07-07 12:25:20 -070018
Elyes HAOUASc3385072019-03-21 15:38:06 +010019#include "../chip.h"
20
Subrata Banike8e43292018-02-06 13:28:53 +053021#define FSP_SMBIOS_MEMORY_INFO_GUID \
22{ \
23 0xd4, 0x71, 0x20, 0x9b, 0x54, 0xb0, 0x0c, 0x4e, \
24 0x8d, 0x09, 0x11, 0xcf, 0x8b, 0x9f, 0x03, 0x23 \
25}
26
Subrata Banike8e43292018-02-06 13:28:53 +053027/* Save the DIMM information for SMBIOS table 17 */
28static void save_dimm_info(void)
29{
30 int channel, dimm, dimm_max, index;
31 size_t hob_size;
32 const CONTROLLER_INFO *ctrlr_info;
33 const CHANNEL_INFO *channel_info;
34 const DIMM_INFO *src_dimm;
35 struct dimm_info *dest_dimm;
36 struct memory_info *mem_info;
37 const MEMORY_INFO_DATA_HOB *memory_info_hob;
38 const uint8_t smbios_memory_info_guid[16] =
39 FSP_SMBIOS_MEMORY_INFO_GUID;
Furquan Shaikh5c190092019-03-11 20:11:55 -070040 const char *dram_part_num;
Nick Vaccaro0ed02d02020-09-30 09:49:05 -070041 size_t dram_part_num_len = 0;
42 bool part_num_overridden = false;
Subrata Banike8e43292018-02-06 13:28:53 +053043
44 /* Locate the memory info HOB, presence validated by raminit */
45 memory_info_hob = fsp_find_extension_hob_by_guid(
46 smbios_memory_info_guid,
47 &hob_size);
48 if (memory_info_hob == NULL || hob_size == 0) {
49 printk(BIOS_ERR, "SMBIOS MEMORY_INFO_DATA_HOB not found\n");
50 return;
51 }
52
53 /*
54 * Allocate CBMEM area for DIMM information used to populate SMBIOS
55 * table 17
56 */
57 mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
58 if (mem_info == NULL) {
59 printk(BIOS_ERR, "CBMEM entry for DIMM info missing\n");
60 return;
61 }
62 memset(mem_info, 0, sizeof(*mem_info));
63
Nick Vaccaro0ed02d02020-09-30 09:49:05 -070064 /* Allow mainboard to override DRAM part number. */
65 dram_part_num = mainboard_get_dram_part_num();
66 if (dram_part_num) {
67 dram_part_num_len = strlen(dram_part_num);
68 part_num_overridden = true;
69 }
70
Subrata Banike8e43292018-02-06 13:28:53 +053071 /* Describe the first N DIMMs in the system */
72 index = 0;
73 dimm_max = ARRAY_SIZE(mem_info->dimm);
74 ctrlr_info = &memory_info_hob->Controller[0];
75 for (channel = 0; channel < MAX_CH && index < dimm_max; channel++) {
76 channel_info = &ctrlr_info->ChannelInfo[channel];
77 if (channel_info->Status != CHANNEL_PRESENT)
78 continue;
79 for (dimm = 0; dimm < MAX_DIMM && index < dimm_max; dimm++) {
80 src_dimm = &channel_info->DimmInfo[dimm];
81 dest_dimm = &mem_info->dimm[index];
82
83 if (src_dimm->Status != DIMM_PRESENT)
84 continue;
85
Nick Vaccaro0ed02d02020-09-30 09:49:05 -070086 if (!part_num_overridden) {
87 dram_part_num_len =
88 sizeof(src_dimm->ModulePartNum);
89 dram_part_num = (const char *)
Furquan Shaikh5c190092019-03-11 20:11:55 -070090 &src_dimm->ModulePartNum[0];
Nick Vaccaro0ed02d02020-09-30 09:49:05 -070091 }
Furquan Shaikh5c190092019-03-11 20:11:55 -070092
Christian Walterf9723222019-05-28 10:37:24 +020093 u8 memProfNum = memory_info_hob->MemoryProfile;
94
Subrata Banike8e43292018-02-06 13:28:53 +053095 /* Populate the DIMM information */
96 dimm_info_fill(dest_dimm,
97 src_dimm->DimmCapacity,
98 memory_info_hob->MemoryType,
99 memory_info_hob->ConfiguredMemoryClockSpeed,
Francois Toguo993f68a2019-02-04 17:05:51 -0800100 src_dimm->RankInDimm,
Subrata Banike8e43292018-02-06 13:28:53 +0530101 channel_info->ChannelId,
102 src_dimm->DimmId,
Furquan Shaikh5c190092019-03-11 20:11:55 -0700103 dram_part_num,
104 dram_part_num_len,
Duncan Laurie46340d02019-05-17 14:57:31 -0600105 src_dimm->SpdSave + SPD_SAVE_OFFSET_SERIAL,
Christian Walterf9723222019-05-28 10:37:24 +0200106 memory_info_hob->DataWidth,
107 memory_info_hob->VddVoltage[memProfNum],
Duncan Laurie1a86cda2019-06-10 14:00:56 -0700108 memory_info_hob->EccSupport,
109 src_dimm->MfgId,
David Milosevic6be82a42022-10-18 19:17:19 +0200110 src_dimm->SpdModuleType,
Eric Laib15946d2023-06-13 10:21:58 +0800111 0,
112 memory_info_hob->MaximumMemoryClockSpeed);
Subrata Banike8e43292018-02-06 13:28:53 +0530113 index++;
114 }
115 }
116 mem_info->dimm_cnt = index;
117 printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt);
118}
119
Kyösti Mälkkicd7a70f2019-08-17 20:51:08 +0300120void mainboard_romstage_entry(void)
Lijian Zhao0ade3132017-07-07 12:25:20 -0700121{
122 bool s3wake;
Duncan Laurie3da1b0d2019-01-07 11:57:03 -0800123 struct chipset_power_state *ps = pmc_get_power_state();
Lijian Zhao0ade3132017-07-07 12:25:20 -0700124
Lijian Zhao0ade3132017-07-07 12:25:20 -0700125 /* Program MCHBAR, DMIBAR, GDXBAR and EDRAMBAR */
126 systemagent_early_init();
Angel Pons53496e62021-02-19 20:38:37 +0100127 /* Program SMBus base address and enable it */
128 smbus_common_init();
Lijian Zhaoe7a1e7d2017-10-09 18:39:30 -0700129 /* initialize Heci interface */
Subrata Banik0b92aa62022-06-01 06:54:44 +0000130 cse_init(HECI1_BASE_ADDRESS);
Lijian Zhao0ade3132017-07-07 12:25:20 -0700131
Lijian Zhaob3dfcb82017-08-16 22:18:52 -0700132 s3wake = pmc_fill_power_state(ps) == ACPI_S3;
Lijian Zhao0ade3132017-07-07 12:25:20 -0700133 fsp_memory_init(s3wake);
Lijian Zhao26be35a2018-04-17 16:13:39 -0700134 pmc_set_disb();
Matt DeVillier7c2f57a2022-02-13 18:23:37 -0600135 if (!s3wake) {
136 /*
137 * cse_fw_sync() must be called after DRAM initialization as
138 * HMRFPO_ENABLE HECI command (which is used by cse_fw_sync())
139 * is expected to be executed after DRAM initialization.
140 */
141
142 if (CONFIG(SOC_INTEL_CSE_LITE_SKU))
143 cse_fw_sync();
144
Subrata Banike8e43292018-02-06 13:28:53 +0530145 save_dimm_info();
Matt DeVillier7c2f57a2022-02-13 18:23:37 -0600146 }
Kyösti Mälkkicd7a70f2019-08-17 20:51:08 +0300147}