Angel Pons | f5627e8 | 2020-04-05 15:46:52 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Lijian Zhao | 0ade313 | 2017-07-07 12:25:20 -0700 | [diff] [blame] | 2 | |
Kyösti Mälkki | a963acd | 2019-08-16 20:34:25 +0300 | [diff] [blame] | 3 | #include <arch/romstage.h> |
Lijian Zhao | 0ade313 | 2017-07-07 12:25:20 -0700 | [diff] [blame] | 4 | #include <cbmem.h> |
| 5 | #include <console/console.h> |
| 6 | #include <fsp/util.h> |
Kyösti Mälkki | 32d47eb | 2019-09-28 00:00:30 +0300 | [diff] [blame] | 7 | #include <intelblocks/cfg.h> |
Lijian Zhao | e7a1e7d | 2017-10-09 18:39:30 -0700 | [diff] [blame] | 8 | #include <intelblocks/cse.h> |
Lijian Zhao | b3dfcb8 | 2017-08-16 22:18:52 -0700 | [diff] [blame] | 9 | #include <intelblocks/pmclib.h> |
Angel Pons | 53496e6 | 2021-02-19 20:38:37 +0100 | [diff] [blame] | 10 | #include <intelblocks/smbus.h> |
Lijian Zhao | 0ade313 | 2017-07-07 12:25:20 -0700 | [diff] [blame] | 11 | #include <memory_info.h> |
Subrata Banik | e8e4329 | 2018-02-06 13:28:53 +0530 | [diff] [blame] | 12 | #include <soc/intel/common/smbios.h> |
Lijian Zhao | e7a1e7d | 2017-10-09 18:39:30 -0700 | [diff] [blame] | 13 | #include <soc/iomap.h> |
Pratik Prajapati | 9027e1b | 2017-08-23 17:37:43 -0700 | [diff] [blame] | 14 | #include <soc/pci_devs.h> |
Lijian Zhao | 0ade313 | 2017-07-07 12:25:20 -0700 | [diff] [blame] | 15 | #include <soc/pm.h> |
| 16 | #include <soc/romstage.h> |
Subrata Banik | e8e4329 | 2018-02-06 13:28:53 +0530 | [diff] [blame] | 17 | #include <string.h> |
Lijian Zhao | 0ade313 | 2017-07-07 12:25:20 -0700 | [diff] [blame] | 18 | |
Elyes HAOUAS | c338507 | 2019-03-21 15:38:06 +0100 | [diff] [blame] | 19 | #include "../chip.h" |
| 20 | |
Subrata Banik | e8e4329 | 2018-02-06 13:28:53 +0530 | [diff] [blame] | 21 | #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 Banik | e8e4329 | 2018-02-06 13:28:53 +0530 | [diff] [blame] | 27 | /* Save the DIMM information for SMBIOS table 17 */ |
| 28 | static 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 Shaikh | 5c19009 | 2019-03-11 20:11:55 -0700 | [diff] [blame] | 40 | const char *dram_part_num; |
Nick Vaccaro | 0ed02d0 | 2020-09-30 09:49:05 -0700 | [diff] [blame] | 41 | size_t dram_part_num_len = 0; |
| 42 | bool part_num_overridden = false; |
Subrata Banik | e8e4329 | 2018-02-06 13:28:53 +0530 | [diff] [blame] | 43 | |
| 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 Vaccaro | 0ed02d0 | 2020-09-30 09:49:05 -0700 | [diff] [blame] | 64 | /* 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 Banik | e8e4329 | 2018-02-06 13:28:53 +0530 | [diff] [blame] | 71 | /* 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 Vaccaro | 0ed02d0 | 2020-09-30 09:49:05 -0700 | [diff] [blame] | 86 | if (!part_num_overridden) { |
| 87 | dram_part_num_len = |
| 88 | sizeof(src_dimm->ModulePartNum); |
| 89 | dram_part_num = (const char *) |
Furquan Shaikh | 5c19009 | 2019-03-11 20:11:55 -0700 | [diff] [blame] | 90 | &src_dimm->ModulePartNum[0]; |
Nick Vaccaro | 0ed02d0 | 2020-09-30 09:49:05 -0700 | [diff] [blame] | 91 | } |
Furquan Shaikh | 5c19009 | 2019-03-11 20:11:55 -0700 | [diff] [blame] | 92 | |
Christian Walter | f972322 | 2019-05-28 10:37:24 +0200 | [diff] [blame] | 93 | u8 memProfNum = memory_info_hob->MemoryProfile; |
| 94 | |
Subrata Banik | e8e4329 | 2018-02-06 13:28:53 +0530 | [diff] [blame] | 95 | /* 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 Toguo | 993f68a | 2019-02-04 17:05:51 -0800 | [diff] [blame] | 100 | src_dimm->RankInDimm, |
Subrata Banik | e8e4329 | 2018-02-06 13:28:53 +0530 | [diff] [blame] | 101 | channel_info->ChannelId, |
| 102 | src_dimm->DimmId, |
Furquan Shaikh | 5c19009 | 2019-03-11 20:11:55 -0700 | [diff] [blame] | 103 | dram_part_num, |
| 104 | dram_part_num_len, |
Duncan Laurie | 46340d0 | 2019-05-17 14:57:31 -0600 | [diff] [blame] | 105 | src_dimm->SpdSave + SPD_SAVE_OFFSET_SERIAL, |
Christian Walter | f972322 | 2019-05-28 10:37:24 +0200 | [diff] [blame] | 106 | memory_info_hob->DataWidth, |
| 107 | memory_info_hob->VddVoltage[memProfNum], |
Duncan Laurie | 1a86cda | 2019-06-10 14:00:56 -0700 | [diff] [blame] | 108 | memory_info_hob->EccSupport, |
| 109 | src_dimm->MfgId, |
David Milosevic | 6be82a4 | 2022-10-18 19:17:19 +0200 | [diff] [blame] | 110 | src_dimm->SpdModuleType, |
Eric Lai | b15946d | 2023-06-13 10:21:58 +0800 | [diff] [blame^] | 111 | 0, |
| 112 | memory_info_hob->MaximumMemoryClockSpeed); |
Subrata Banik | e8e4329 | 2018-02-06 13:28:53 +0530 | [diff] [blame] | 113 | 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älkki | cd7a70f | 2019-08-17 20:51:08 +0300 | [diff] [blame] | 120 | void mainboard_romstage_entry(void) |
Lijian Zhao | 0ade313 | 2017-07-07 12:25:20 -0700 | [diff] [blame] | 121 | { |
| 122 | bool s3wake; |
Duncan Laurie | 3da1b0d | 2019-01-07 11:57:03 -0800 | [diff] [blame] | 123 | struct chipset_power_state *ps = pmc_get_power_state(); |
Lijian Zhao | 0ade313 | 2017-07-07 12:25:20 -0700 | [diff] [blame] | 124 | |
Lijian Zhao | 0ade313 | 2017-07-07 12:25:20 -0700 | [diff] [blame] | 125 | /* Program MCHBAR, DMIBAR, GDXBAR and EDRAMBAR */ |
| 126 | systemagent_early_init(); |
Angel Pons | 53496e6 | 2021-02-19 20:38:37 +0100 | [diff] [blame] | 127 | /* Program SMBus base address and enable it */ |
| 128 | smbus_common_init(); |
Lijian Zhao | e7a1e7d | 2017-10-09 18:39:30 -0700 | [diff] [blame] | 129 | /* initialize Heci interface */ |
Subrata Banik | 0b92aa6 | 2022-06-01 06:54:44 +0000 | [diff] [blame] | 130 | cse_init(HECI1_BASE_ADDRESS); |
Lijian Zhao | 0ade313 | 2017-07-07 12:25:20 -0700 | [diff] [blame] | 131 | |
Lijian Zhao | b3dfcb8 | 2017-08-16 22:18:52 -0700 | [diff] [blame] | 132 | s3wake = pmc_fill_power_state(ps) == ACPI_S3; |
Lijian Zhao | 0ade313 | 2017-07-07 12:25:20 -0700 | [diff] [blame] | 133 | fsp_memory_init(s3wake); |
Lijian Zhao | 26be35a | 2018-04-17 16:13:39 -0700 | [diff] [blame] | 134 | pmc_set_disb(); |
Matt DeVillier | 7c2f57a | 2022-02-13 18:23:37 -0600 | [diff] [blame] | 135 | 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 Banik | e8e4329 | 2018-02-06 13:28:53 +0530 | [diff] [blame] | 145 | save_dimm_info(); |
Matt DeVillier | 7c2f57a | 2022-02-13 18:23:37 -0600 | [diff] [blame] | 146 | } |
Kyösti Mälkki | cd7a70f | 2019-08-17 20:51:08 +0300 | [diff] [blame] | 147 | } |