1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
5 #include <device/smbus_def.h>
6 #include <device/smbus_host.h>
9 static void update_spd_len(struct spd_block
*blk
)
12 for (i
= 0 ; i
< CONFIG_DIMM_MAX
; i
++)
13 if (blk
->spd_array
[i
] != NULL
)
14 j
|= blk
->spd_array
[i
][SPD_DRAM_TYPE
];
16 /* If spd used is DDR4, then its length is 512 byte. */
17 if (j
== SPD_DRAM_DDR4
)
18 blk
->len
= SPD_PAGE_LEN_DDR4
;
20 blk
->len
= SPD_PAGE_LEN
;
23 static void smbus_read_spd(u8
*spd
, u8 addr
)
28 if (CONFIG(SPD_READ_BY_WORD
))
29 step
= sizeof(uint16_t);
31 for (i
= 0; i
< SPD_PAGE_LEN
; i
+= step
) {
32 if (CONFIG(SPD_READ_BY_WORD
))
33 ((u16
*)spd
)[i
/ sizeof(uint16_t)] =
34 smbus_read_word(addr
, i
);
36 spd
[i
] = smbus_read_byte(addr
, i
);
40 /* return -1 if SMBus errors otherwise return 0 */
41 static int get_spd(u8
*spd
, u8 addr
)
43 if (CONFIG_DIMM_SPD_SIZE
> SPD_PAGE_LEN
) {
44 /* Restore to page 0 before reading */
45 smbus_write_byte(SPD_PAGE_0
, 0, 0);
48 /* If address is not 0, it will return CB_ERR(-1) if no dimm */
49 if (smbus_read_byte(addr
, 0) < 0) {
50 printk(BIOS_INFO
, "No memory dimm at address %02X\n",
55 if (i2c_eeprom_read(addr
, 0, SPD_PAGE_LEN
, spd
) < 0) {
56 printk(BIOS_INFO
, "do_i2c_eeprom_read failed, using fallback\n");
57 smbus_read_spd(spd
, addr
);
60 /* Check if module is DDR4, DDR4 spd is 512 byte. */
61 if (spd
[SPD_DRAM_TYPE
] == SPD_DRAM_DDR4
&& CONFIG_DIMM_SPD_SIZE
> SPD_PAGE_LEN
) {
62 /* Switch to page 1 */
63 smbus_write_byte(SPD_PAGE_1
, 0, 0);
65 if (i2c_eeprom_read(addr
, 0, SPD_PAGE_LEN
, spd
+ SPD_PAGE_LEN
) < 0) {
66 printk(BIOS_INFO
, "do_i2c_eeprom_read failed, using fallback\n");
67 smbus_read_spd(spd
+ SPD_PAGE_LEN
, addr
);
69 /* Restore to page 0 */
70 smbus_write_byte(SPD_PAGE_0
, 0, 0);
75 static u8 spd_data
[CONFIG_DIMM_MAX
* CONFIG_DIMM_SPD_SIZE
];
77 void get_spd_smbus(struct spd_block
*blk
)
80 for (i
= 0 ; i
< CONFIG_DIMM_MAX
; i
++) {
81 if (blk
->addr_map
[i
] == 0) {
82 blk
->spd_array
[i
] = NULL
;
86 if (get_spd(&spd_data
[i
* CONFIG_DIMM_SPD_SIZE
], blk
->addr_map
[i
]) == 0)
87 blk
->spd_array
[i
] = &spd_data
[i
* CONFIG_DIMM_SPD_SIZE
];
89 blk
->spd_array
[i
] = NULL
;
96 * get_spd_sn returns the SODIMM serial number. It only supports DDR3 and DDR4.
97 * return CB_SUCCESS, sn is the serial number and sn=0xffffffff if the dimm is not present.
98 * return CB_ERR, if dram_type is not supported or addr is a zero.
100 enum cb_err
get_spd_sn(u8 addr
, u32
*sn
)
106 /* addr is not a zero. */
110 if (CONFIG_DIMM_SPD_SIZE
> SPD_PAGE_LEN
) {
111 /* Restore to page 0 before reading */
112 smbus_write_byte(SPD_PAGE_0
, 0, 0);
115 /* If dimm is not present, set sn to 0xff. */
116 smbus_ret
= smbus_read_byte(addr
, SPD_DRAM_TYPE
);
118 printk(BIOS_INFO
, "No memory dimm at address %02X\n", addr
<< 1);
123 dram_type
= smbus_ret
& 0xff;
125 /* Check if module is DDR4, DDR4 spd is 512 byte. */
126 if (dram_type
== SPD_DRAM_DDR4
&& CONFIG_DIMM_SPD_SIZE
> SPD_PAGE_LEN
) {
127 /* Switch to page 1 */
128 smbus_write_byte(SPD_PAGE_1
, 0, 0);
130 for (i
= 0; i
< SPD_SN_LEN
; i
++)
131 *((u8
*)sn
+ i
) = smbus_read_byte(addr
,
132 i
+ DDR4_SPD_SN_OFF
);
134 /* Restore to page 0 */
135 smbus_write_byte(SPD_PAGE_0
, 0, 0);
136 } else if (dram_type
== SPD_DRAM_DDR3
) {
137 for (i
= 0; i
< SPD_SN_LEN
; i
++)
138 *((u8
*)sn
+ i
) = smbus_read_byte(addr
,
139 i
+ DDR3_SPD_SN_OFF
);
141 printk(BIOS_ERR
, "Unsupported dram_type\n");