blob: 8f337c1c1d55afb5c5f5eda0627c1510b30979f8 [file] [log] [blame]
Angel Pons0612b272020-04-05 15:46:56 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Aamir Bohra52f29742017-04-19 18:19:14 +05302
Kyösti Mälkki75664672020-01-01 17:42:45 +02003#include <console/console.h>
Kyösti Mälkki75664672020-01-01 17:42:45 +02004#include <spd_bin.h>
Wim Vervoorn30e91492020-05-01 13:50:08 +02005#include <device/smbus_def.h>
Kyösti Mälkki1cae4542020-01-06 12:31:34 +02006#include <device/smbus_host.h>
Aamir Bohra52f29742017-04-19 18:19:14 +05307#include "smbuslib.h"
8
Kyösti Mälkki75664672020-01-01 17:42:45 +02009static void update_spd_len(struct spd_block *blk)
10{
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];
15
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;
21}
22
23static void smbus_read_spd(u8 *spd, u8 addr)
24{
25 u16 i;
26 u8 step = 1;
27
28 if (CONFIG(SPD_READ_BY_WORD))
29 step = sizeof(uint16_t);
30
31 for (i = 0; i < SPD_PAGE_LEN; i += step) {
32 if (CONFIG(SPD_READ_BY_WORD))
33 ((u16*)spd)[i / sizeof(uint16_t)] =
Kyösti Mälkki265cd9a2020-01-01 17:42:45 +020034 do_smbus_read_word(SMBUS_IO_BASE, addr, i);
Kyösti Mälkki75664672020-01-01 17:42:45 +020035 else
Kyösti Mälkki265cd9a2020-01-01 17:42:45 +020036 spd[i] = do_smbus_read_byte(SMBUS_IO_BASE, addr, i);
Kyösti Mälkki75664672020-01-01 17:42:45 +020037 }
38}
39
Eric Lai0ee9b14c2020-04-21 15:32:20 +080040/* return -1 if SMBus errors otherwise return 0 */
41static int get_spd(u8 *spd, u8 addr)
Kyösti Mälkki75664672020-01-01 17:42:45 +020042{
Eric Lai0ee9b14c2020-04-21 15:32:20 +080043 /* If address is not 0, it will return CB_ERR(-1) if no dimm */
44 if (do_smbus_read_byte(SMBUS_IO_BASE, addr, 0) < 0) {
Kyösti Mälkki75664672020-01-01 17:42:45 +020045 printk(BIOS_INFO, "No memory dimm at address %02X\n",
46 addr << 1);
Eric Lai0ee9b14c2020-04-21 15:32:20 +080047 return -1;
Kyösti Mälkki75664672020-01-01 17:42:45 +020048 }
Wim Vervoorn30e91492020-05-01 13:50:08 +020049
50 if (do_i2c_eeprom_read(SMBUS_IO_BASE, addr, 0, SPD_PAGE_LEN, spd) == SMBUS_ERROR) {
51 printk(BIOS_INFO, "do_i2c_eeprom_read failed, using fallback\n");
52 smbus_read_spd(spd, addr);
53 }
Kyösti Mälkki75664672020-01-01 17:42:45 +020054
55 /* Check if module is DDR4, DDR4 spd is 512 byte. */
56 if (spd[SPD_DRAM_TYPE] == SPD_DRAM_DDR4 &&
57 CONFIG_DIMM_SPD_SIZE > SPD_PAGE_LEN) {
58 /* Switch to page 1 */
Kyösti Mälkki265cd9a2020-01-01 17:42:45 +020059 do_smbus_write_byte(SMBUS_IO_BASE, SPD_PAGE_1, 0, 0);
Wim Vervoorn30e91492020-05-01 13:50:08 +020060
61 if (do_i2c_eeprom_read(SMBUS_IO_BASE, addr, 0, SPD_PAGE_LEN,
62 spd + SPD_PAGE_LEN) == SMBUS_ERROR) {
63 printk(BIOS_INFO, "do_i2c_eeprom_read failed, using fallback\n");
64 smbus_read_spd(spd + SPD_PAGE_LEN, addr);
65 }
Kyösti Mälkki75664672020-01-01 17:42:45 +020066 /* Restore to page 0 */
Kyösti Mälkki265cd9a2020-01-01 17:42:45 +020067 do_smbus_write_byte(SMBUS_IO_BASE, SPD_PAGE_0, 0, 0);
Kyösti Mälkki75664672020-01-01 17:42:45 +020068 }
Eric Lai0ee9b14c2020-04-21 15:32:20 +080069 return 0;
Kyösti Mälkki75664672020-01-01 17:42:45 +020070}
71
72static u8 spd_data[CONFIG_DIMM_MAX * CONFIG_DIMM_SPD_SIZE];
73
74void get_spd_smbus(struct spd_block *blk)
75{
76 u8 i;
77 for (i = 0 ; i < CONFIG_DIMM_MAX; i++) {
Eric Lai0ee9b14c2020-04-21 15:32:20 +080078 if (blk->addr_map[i] == 0) {
79 blk->spd_array[i] = NULL;
80 continue;
81 }
82
83 if (get_spd(&spd_data[i * CONFIG_DIMM_SPD_SIZE], blk->addr_map[i]) == 0)
84 blk->spd_array[i] = &spd_data[i * CONFIG_DIMM_SPD_SIZE];
85 else
86 blk->spd_array[i] = NULL;
Kyösti Mälkki75664672020-01-01 17:42:45 +020087 }
88
89 update_spd_len(blk);
90}
Jamie Chen7adcfde2020-04-16 01:20:29 +080091
92/*
93 * get_spd_sn returns the SODIMM serial number. It only supports DDR3 and DDR4.
94 * return CB_SUCCESS, sn is the serial number and sn=0xffffffff if the dimm is not present.
95 * return CB_ERR, if dram_type is not supported or addr is a zero.
96 */
97enum cb_err get_spd_sn(u8 addr, u32 *sn)
98{
99 u8 i;
100 u8 dram_type;
101 int smbus_ret;
102
103 /* addr is not a zero. */
104 if (addr == 0x0)
105 return CB_ERR;
106
107 /* If dimm is not present, set sn to 0xff. */
108 smbus_ret = do_smbus_read_byte(SMBUS_IO_BASE, addr, SPD_DRAM_TYPE);
109 if (smbus_ret < 0) {
110 printk(BIOS_INFO, "No memory dimm at address %02X\n", addr);
111 *sn = 0xffffffff;
112 return CB_SUCCESS;
113 }
114
115 dram_type = smbus_ret & 0xff;
116
117 /* Check if module is DDR4, DDR4 spd is 512 byte. */
118 if (dram_type == SPD_DRAM_DDR4 && CONFIG_DIMM_SPD_SIZE > SPD_PAGE_LEN) {
119 /* Switch to page 1 */
120 do_smbus_write_byte(SMBUS_IO_BASE, SPD_PAGE_1, 0, 0);
121
122 for (i = 0; i < SPD_SN_LEN; i++)
123 *((u8 *)sn + i) = do_smbus_read_byte(SMBUS_IO_BASE, addr,
124 i + DDR4_SPD_SN_OFF);
125
126 /* Restore to page 0 */
127 do_smbus_write_byte(SMBUS_IO_BASE, SPD_PAGE_0, 0, 0);
128 } else if (dram_type == SPD_DRAM_DDR3) {
129 for (i = 0; i < SPD_SN_LEN; i++)
130 *((u8 *)sn + i) = do_smbus_read_byte(SMBUS_IO_BASE, addr,
131 i + DDR3_SPD_SN_OFF);
132 } else {
133 printk(BIOS_ERR, "Unsupported dram_type\n");
134 return CB_ERR;
135 }
136
137 return CB_SUCCESS;
138}