Ravi Sarawadi | 8069b5d | 2022-04-10 23:36:52 -0700 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | |
| 3 | #include <arch/romstage.h> |
| 4 | #include <cbmem.h> |
| 5 | #include <console/console.h> |
| 6 | #include <fsp/util.h> |
| 7 | #include <intelblocks/cfg.h> |
| 8 | #include <intelblocks/cse.h> |
| 9 | #include <intelblocks/pmclib.h> |
| 10 | #include <intelblocks/smbus.h> |
Subrata Banik | 2bce51e | 2022-09-08 13:29:22 -0700 | [diff] [blame] | 11 | #include <intelblocks/thermal.h> |
Ravi Sarawadi | 8069b5d | 2022-04-10 23:36:52 -0700 | [diff] [blame] | 12 | #include <memory_info.h> |
| 13 | #include <soc/intel/common/smbios.h> |
| 14 | #include <soc/iomap.h> |
| 15 | #include <soc/pm.h> |
| 16 | #include <soc/romstage.h> |
| 17 | #include <soc/soc_chip.h> |
| 18 | #include <string.h> |
| 19 | |
| 20 | #define FSP_SMBIOS_MEMORY_INFO_GUID \ |
| 21 | { \ |
| 22 | 0xd4, 0x71, 0x20, 0x9b, 0x54, 0xb0, 0x0c, 0x4e, \ |
| 23 | 0x8d, 0x09, 0x11, 0xcf, 0x8b, 0x9f, 0x03, 0x23 \ |
| 24 | } |
| 25 | |
| 26 | /* Save the DIMM information for SMBIOS table 17 */ |
| 27 | static void save_dimm_info(void) |
| 28 | { |
| 29 | int node, channel, dimm, dimm_max, index; |
| 30 | size_t hob_size; |
| 31 | const CONTROLLER_INFO *ctrlr_info; |
| 32 | const CHANNEL_INFO *channel_info; |
| 33 | const DIMM_INFO *src_dimm; |
| 34 | struct dimm_info *dest_dimm; |
| 35 | struct memory_info *mem_info; |
| 36 | const MEMORY_INFO_DATA_HOB *meminfo_hob; |
| 37 | const uint8_t smbios_memory_info_guid[sizeof(EFI_GUID)] = FSP_SMBIOS_MEMORY_INFO_GUID; |
| 38 | const uint8_t *serial_num; |
| 39 | const char *dram_part_num = NULL; |
| 40 | size_t dram_part_num_len = 0; |
| 41 | |
| 42 | /* Locate the memory info HOB, presence validated by raminit */ |
| 43 | meminfo_hob = fsp_find_extension_hob_by_guid( |
| 44 | smbios_memory_info_guid, |
| 45 | &hob_size); |
Elyes Haouas | 6a8029c | 2022-09-13 10:16:01 +0200 | [diff] [blame] | 46 | if (!meminfo_hob || hob_size == 0) { |
Ravi Sarawadi | 8069b5d | 2022-04-10 23:36:52 -0700 | [diff] [blame] | 47 | printk(BIOS_ERR, "SMBIOS MEMORY_INFO_DATA_HOB not found\n"); |
| 48 | return; |
| 49 | } |
| 50 | |
| 51 | /* |
| 52 | * Allocate CBMEM area for DIMM information used to populate SMBIOS |
| 53 | * table 17 |
| 54 | */ |
| 55 | mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info)); |
Elyes Haouas | 6a8029c | 2022-09-13 10:16:01 +0200 | [diff] [blame] | 56 | if (!mem_info) { |
Ravi Sarawadi | 8069b5d | 2022-04-10 23:36:52 -0700 | [diff] [blame] | 57 | printk(BIOS_ERR, "CBMEM entry for DIMM info missing\n"); |
| 58 | return; |
| 59 | } |
| 60 | memset(mem_info, 0, sizeof(*mem_info)); |
| 61 | |
| 62 | /* Allow mainboard to override DRAM part number. */ |
| 63 | dram_part_num = mainboard_get_dram_part_num(); |
| 64 | if (dram_part_num) |
| 65 | dram_part_num_len = strlen(dram_part_num); |
| 66 | |
| 67 | /* Save available DIMM information */ |
| 68 | index = 0; |
| 69 | dimm_max = ARRAY_SIZE(mem_info->dimm); |
| 70 | for (node = 0; node < MAX_NODE; node++) { |
| 71 | ctrlr_info = &meminfo_hob->Controller[node]; |
| 72 | for (channel = 0; channel < MAX_CH && index < dimm_max; channel++) { |
| 73 | channel_info = &ctrlr_info->ChannelInfo[channel]; |
| 74 | if (channel_info->Status != CHANNEL_PRESENT) |
| 75 | continue; |
| 76 | |
| 77 | for (dimm = 0; dimm < MAX_DIMM && index < dimm_max; dimm++) { |
| 78 | src_dimm = &channel_info->DimmInfo[dimm]; |
| 79 | dest_dimm = &mem_info->dimm[index]; |
| 80 | if (src_dimm->Status != DIMM_PRESENT) |
| 81 | continue; |
| 82 | |
| 83 | /* If there is no DRAM part number overridden by |
| 84 | * mainboard then use original one. */ |
| 85 | if (!dram_part_num) { |
| 86 | dram_part_num_len = sizeof(src_dimm->ModulePartNum); |
| 87 | dram_part_num = (const char *) |
| 88 | &src_dimm->ModulePartNum[0]; |
| 89 | } |
| 90 | |
| 91 | uint8_t memProfNum = meminfo_hob->MemoryProfile; |
| 92 | serial_num = src_dimm->SpdSave + SPD_SAVE_OFFSET_SERIAL; |
| 93 | |
| 94 | /* Populate the DIMM information */ |
| 95 | dimm_info_fill(dest_dimm, |
| 96 | src_dimm->DimmCapacity, |
| 97 | meminfo_hob->MemoryType, |
| 98 | meminfo_hob->ConfiguredMemoryClockSpeed, |
| 99 | src_dimm->RankInDimm, |
| 100 | channel_info->ChannelId, |
| 101 | src_dimm->DimmId, |
| 102 | dram_part_num, |
| 103 | dram_part_num_len, |
| 104 | serial_num, |
| 105 | meminfo_hob->DataWidth, |
| 106 | meminfo_hob->VddVoltage[memProfNum], |
| 107 | meminfo_hob->EccSupport, |
| 108 | src_dimm->MfgId, |
David Milosevic | 6be82a4 | 2022-10-18 19:17:19 +0200 | [diff] [blame] | 109 | src_dimm->SpdModuleType, |
Eric Lai | b15946d | 2023-06-13 10:21:58 +0800 | [diff] [blame] | 110 | node, |
| 111 | meminfo_hob->MaximumMemoryClockSpeed); |
Ravi Sarawadi | 8069b5d | 2022-04-10 23:36:52 -0700 | [diff] [blame] | 112 | index++; |
| 113 | } |
| 114 | } |
| 115 | } |
| 116 | mem_info->dimm_cnt = index; |
Subrata Banik | ecb4a24 | 2023-03-16 18:25:45 +0530 | [diff] [blame] | 117 | if (mem_info->dimm_cnt == 0) |
| 118 | printk(BIOS_ERR, "No DIMMs found\n"); |
| 119 | else |
| 120 | printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt); |
Ravi Sarawadi | 8069b5d | 2022-04-10 23:36:52 -0700 | [diff] [blame] | 121 | } |
| 122 | |
| 123 | void mainboard_romstage_entry(void) |
| 124 | { |
Ravi Sarawadi | 8069b5d | 2022-04-10 23:36:52 -0700 | [diff] [blame] | 125 | struct chipset_power_state *ps = pmc_get_power_state(); |
Subrata Banik | d4cc902 | 2023-01-16 13:52:40 +0530 | [diff] [blame] | 126 | bool s3wake = pmc_fill_power_state(ps) == ACPI_S3; |
Ravi Sarawadi | 8069b5d | 2022-04-10 23:36:52 -0700 | [diff] [blame] | 127 | |
Ravi Sarawadi | 8069b5d | 2022-04-10 23:36:52 -0700 | [diff] [blame] | 128 | /* Initialize HECI interface */ |
| 129 | cse_init(HECI1_BASE_ADDRESS); |
| 130 | |
Krishna Prasad Bhat | 7542fa1 | 2023-09-22 00:38:53 +0530 | [diff] [blame] | 131 | if (!s3wake && CONFIG(SOC_INTEL_CSE_LITE_SKU)) { |
| 132 | cse_fill_bp_info(); |
| 133 | if (CONFIG(SOC_INTEL_CSE_LITE_SYNC_IN_ROMSTAGE)) |
| 134 | cse_fw_sync(); |
| 135 | } |
Ravi Sarawadi | 8069b5d | 2022-04-10 23:36:52 -0700 | [diff] [blame] | 136 | |
Bora Guvendik | 34c37bb | 2023-03-13 14:27:30 -0700 | [diff] [blame] | 137 | /* Update coreboot timestamp table with CSE timestamps */ |
| 138 | if (CONFIG(SOC_INTEL_CSE_PRE_CPU_RESET_TELEMETRY)) |
| 139 | cse_get_telemetry_data(); |
| 140 | |
Subrata Banik | d4cc902 | 2023-01-16 13:52:40 +0530 | [diff] [blame] | 141 | /* Program MCHBAR, DMIBAR, GDXBAR and EDRAMBAR */ |
| 142 | systemagent_early_init(); |
| 143 | /* Program SMBus base address and enable it */ |
| 144 | smbus_common_init(); |
| 145 | |
Subrata Banik | 2bce51e | 2022-09-08 13:29:22 -0700 | [diff] [blame] | 146 | /* |
| 147 | * Set low maximum temp threshold value used for dynamic thermal sensor |
| 148 | * shutdown consideration. |
| 149 | * |
| 150 | * If Dynamic Thermal Shutdown is enabled then PMC logic shuts down the |
| 151 | * thermal sensor when CPU is in a C-state and LTT >= DTS Temp. |
| 152 | */ |
| 153 | pch_thermal_configuration(); |
Ravi Sarawadi | 8069b5d | 2022-04-10 23:36:52 -0700 | [diff] [blame] | 154 | fsp_memory_init(s3wake); |
| 155 | pmc_set_disb(); |
| 156 | if (!s3wake) |
| 157 | save_dimm_info(); |
| 158 | } |