blob: d16cb46d0a0ccbcdeec4cf7a299966142671a5db [file] [log] [blame]
Angel Pons118a9c72020-04-02 23:48:34 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Raul E Rangel21db6cc2018-03-29 10:18:14 -06002
Subrata Banik6de8b422021-10-26 20:46:21 +05303#include <device/dram/spd.h>
Raul E Rangel21db6cc2018-03-29 10:18:14 -06004#include <dimm_info_util.h>
5#include <smbios.h>
6#include <spd.h>
7#include <console/console.h>
8
Subrata Banik3306f372021-10-26 13:19:20 +05309uint8_t smbios_bus_width_to_spd_width(uint8_t ddr_type, uint16_t total_width,
10 uint16_t data_width)
Raul E Rangel21db6cc2018-03-29 10:18:14 -060011{
12 uint8_t out;
13
14 /* Lookup table as defined in the JEDEC Standard. */
15 switch (data_width) {
16 case 64:
17 out = MEMORY_BUS_WIDTH_64;
18 break;
19 case 32:
20 out = MEMORY_BUS_WIDTH_32;
21 break;
22 case 16:
23 out = MEMORY_BUS_WIDTH_16;
24 break;
25 case 8:
26 out = MEMORY_BUS_WIDTH_8;
27 break;
28 default:
Fred Reitberger83a3b342023-06-02 11:50:48 -040029 printk(BIOS_NOTICE, "Unknown memory size %hu\n", data_width);
Raul E Rangel21db6cc2018-03-29 10:18:14 -060030 /*
31 * The SMBIOS spec says we should set 0xFFFF on an unknown
32 * value, but we don't have a way of passing that signal via SPD
33 * encoded values.
34 */
35 out = MEMORY_BUS_WIDTH_8;
36 break;
37 }
38
39 uint16_t extension_bits = total_width - data_width;
40
41 switch (extension_bits) {
42 case 8:
Subrata Banik3306f372021-10-26 13:19:20 +053043 if (ddr_type == MEMORY_TYPE_DDR5 || ddr_type == MEMORY_TYPE_LPDDR5)
44 out |= SPD_ECC_8BIT_LP5_DDR5;
45 else
46 out |= SPD_ECC_8BIT;
Raul E Rangel21db6cc2018-03-29 10:18:14 -060047 break;
48 case 0:
49 /* No extension bits */
50 break;
51 default:
Fred Reitberger83a3b342023-06-02 11:50:48 -040052 printk(BIOS_NOTICE, "Unknown number of extension bits %hu\n",
Raul E Rangel21db6cc2018-03-29 10:18:14 -060053 extension_bits);
54 break;
55 }
56
57 return out;
58}
59
60uint32_t smbios_memory_size_to_mib(uint16_t memory_size, uint32_t extended_size)
61{
62 /* Memory size is unknown */
63 if (memory_size == 0xFFFF)
64 return 0;
65 /* (32 GiB - 1 MiB) or greater is expressed in the extended size. */
66 else if (memory_size == 0x7FFF)
67 return extended_size;
68 /* When the MSB is flipped, the value is specified in kilobytes */
69 else if (memory_size & 0x8000)
70 return (memory_size ^ 0x8000) / KiB;
71 /* Value contains MiB */
72 else
73 return memory_size;
74}
75
Subrata Banik6de8b422021-10-26 20:46:21 +053076uint8_t smbios_form_factor_to_spd_mod_type(smbios_memory_type memory_type,
77 smbios_memory_form_factor form_factor)
Raul E Rangel21db6cc2018-03-29 10:18:14 -060078{
Subrata Banik6de8b422021-10-26 20:46:21 +053079 return convert_form_factor_to_module_type(memory_type, form_factor);
Raul E Rangel21db6cc2018-03-29 10:18:14 -060080}