mb/system76/cml-u/dt: Make use of chipset devicetree
[coreboot.git] / src / soc / intel / common / block / smbus / smbuslib.c
blobaff6fb0a1b2233904aeca62b06ea56a7964a4c1d
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <spd_bin.h>
5 #include <device/smbus_def.h>
6 #include <device/smbus_host.h>
7 #include "smbuslib.h"
9 static void update_spd_len(struct spd_block *blk)
11 u8 i, j = 0;
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;
19 else
20 blk->len = SPD_PAGE_LEN;
23 static void smbus_read_spd(u8 *spd, u8 addr)
25 u16 i;
26 u8 step = 1;
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);
35 else
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",
51 addr << 1);
52 return -1;
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);
72 return 0;
75 static u8 spd_data[CONFIG_DIMM_MAX * CONFIG_DIMM_SPD_SIZE];
77 void get_spd_smbus(struct spd_block *blk)
79 u8 i;
80 for (i = 0 ; i < CONFIG_DIMM_MAX; i++) {
81 if (blk->addr_map[i] == 0) {
82 blk->spd_array[i] = NULL;
83 continue;
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];
88 else
89 blk->spd_array[i] = NULL;
92 update_spd_len(blk);
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)
102 u8 i;
103 u8 dram_type;
104 int smbus_ret;
106 /* addr is not a zero. */
107 if (addr == 0x0)
108 return CB_ERR;
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);
117 if (smbus_ret < 0) {
118 printk(BIOS_INFO, "No memory dimm at address %02X\n", addr << 1);
119 *sn = 0xffffffff;
120 return CB_SUCCESS;
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);
140 } else {
141 printk(BIOS_ERR, "Unsupported dram_type\n");
142 return CB_ERR;
145 return CB_SUCCESS;