1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <console/console.h>
6 #include <memory_info.h>
7 #include <soc/intel/common/smbios.h>
8 #include <soc/meminit.h>
11 #define FSP_SMBIOS_MEMORY_INFO_GUID \
13 0x8c, 0x10, 0xa1, 0x01, 0xee, 0x9d, 0x84, 0x49, \
14 0x88, 0xc3, 0xee, 0xe8, 0xc4, 0x9e, 0xfb, 0x89 \
17 void save_lpddr4_dimm_info_part_num(const char *dram_part_num
)
19 int channel
, dimm
, dimm_max
, index
, node
;
21 const DIMM_INFO
*src_dimm
;
22 struct dimm_info
*dest_dimm
;
23 struct memory_info
*mem_info
;
24 const CHANNEL_INFO
*channel_info
;
25 const FSP_SMBIOS_MEMORY_INFO
*memory_info_hob
;
26 const CONTROLLER_INFO
*ctrl_info
;
27 const uint8_t smbios_memory_info_guid
[16] =
28 FSP_SMBIOS_MEMORY_INFO_GUID
;
31 dram_part_num
= "Unknown";
33 /* Locate the memory info HOB */
34 memory_info_hob
= fsp_find_extension_hob_by_guid(
35 smbios_memory_info_guid
,
38 if (memory_info_hob
== NULL
|| hob_size
== 0) {
39 printk(BIOS_ERR
, "SMBIOS memory info HOB is missing\n");
44 * Allocate CBMEM area for DIMM information used to populate SMBIOS
47 mem_info
= cbmem_add(CBMEM_ID_MEMINFO
, sizeof(*mem_info
));
48 if (mem_info
== NULL
) {
49 printk(BIOS_ERR
, "CBMEM entry for DIMM info missing\n");
52 memset(mem_info
, 0, sizeof(*mem_info
));
54 /* Describe the first N DIMMs in the system */
56 dimm_max
= ARRAY_SIZE(mem_info
->dimm
);
58 for (node
= 0; node
< MAX_NODE_NUM
; node
++) {
59 ctrl_info
= &memory_info_hob
->Controller
[node
];
60 for (channel
= 0; channel
< ctrl_info
->ChannelCount
;
62 if (index
>= dimm_max
)
65 channel_info
= &ctrl_info
->ChannelInfo
[channel
];
67 for (dimm
= 0; dimm
< channel_info
->DimmCount
; dimm
++) {
68 if (index
>= dimm_max
)
70 src_dimm
= &channel_info
->DimmInfo
[dimm
];
71 dest_dimm
= &mem_info
->dimm
[index
];
73 if (!src_dimm
->DimmCapacity
)
76 /* Populate the DIMM information */
77 dimm_info_fill(dest_dimm
,
78 src_dimm
->DimmCapacity
,
79 memory_info_hob
->MemoryType
,
80 memory_info_hob
->ConfiguredMemoryClockSpeed
,
82 channel_info
->ChannelId
,
85 strlen(dram_part_num
),
86 src_dimm
->SpdSave
+ SPD_SAVE_OFFSET_SERIAL
,
87 memory_info_hob
->DataWidth
,
91 src_dimm
->SpdModuleType
,
93 memory_info_hob
->MaximumMemoryClockSpeed
);
98 mem_info
->dimm_cnt
= index
;
99 printk(BIOS_DEBUG
, "%d DIMMs found\n", mem_info
->dimm_cnt
);
102 void save_lpddr4_dimm_info(const struct lpddr4_cfg
*lp4cfg
, size_t mem_sku
)
104 const char *part_num
= NULL
;
106 if (mem_sku
>= lp4cfg
->num_skus
) {
107 printk(BIOS_ERR
, "Too few LPDDR4 SKUs: 0x%zx/0x%zx\n",
108 mem_sku
, lp4cfg
->num_skus
);
110 part_num
= lp4cfg
->skus
[mem_sku
].part_num
;
113 save_lpddr4_dimm_info_part_num(part_num
);