2 * This file is part of the coreboot project.
4 * Copyright (C) 2016 Intel Corporation.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <arch/byteorder.h>
18 #include <console/console.h>
21 #include <device/early_smbus.h>
22 #include <device/dram/ddr3.h>
24 static u8 spd_data
[CONFIG_DIMM_MAX
* CONFIG_DIMM_SPD_SIZE
] CAR_GLOBAL
;
26 void dump_spd_info(struct spd_block
*blk
)
30 for (i
= 0; i
< CONFIG_DIMM_MAX
; i
++)
31 if (blk
->spd_array
[i
] != NULL
&& blk
->spd_array
[i
][0] != 0) {
32 printk(BIOS_DEBUG
, "SPD @ 0x%02X\n", blk
->addr_map
[i
]);
33 print_spd_info(blk
->spd_array
[i
]);
37 void print_spd_info(uint8_t spd
[])
39 const int spd_banks
[8] = { 8, 16, 32, 64, -1, -1, -1, -1 };
40 const int spd_capmb
[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
41 const int spd_rows
[8] = {12, 13, 14, 15, 16, 17, -1, -1 };
42 const int spd_cols
[8] = { 9, 10, 11, 12, -1, -1, -1, -1 };
43 const int spd_ranks
[8] = { 1, 2, 3, 4, -1, -1, -1, -1 };
44 const int spd_devw
[8] = { 4, 8, 16, 32, -1, -1, -1, -1 };
45 const int spd_busw
[8] = { 8, 16, 32, 64, -1, -1, -1, -1 };
46 char spd_name
[DDR4_SPD_PART_LEN
+1] = { 0 };
48 int banks
= spd_banks
[(spd
[SPD_DENSITY_BANKS
] >> 4) & 7];
49 int capmb
= spd_capmb
[spd
[SPD_DENSITY_BANKS
] & 7] * 256;
50 int rows
= spd_rows
[(spd
[SPD_ADDRESSING
] >> 3) & 7];
51 int cols
= spd_cols
[spd
[SPD_ADDRESSING
] & 7];
52 int ranks
= spd_ranks
[(spd
[SPD_ORGANIZATION
] >> 3) & 7];
53 int devw
= spd_devw
[spd
[SPD_ORGANIZATION
] & 7];
54 int busw
= spd_busw
[spd
[SPD_BUS_DEV_WIDTH
] & 7];
57 printk(BIOS_INFO
, "SPD: module type is ");
58 switch (spd
[SPD_DRAM_TYPE
]) {
60 printk(BIOS_INFO
, "DDR3\n");
61 /* Module Part Number */
62 memcpy(spd_name
, &spd
[DDR3_SPD_PART_OFF
], DDR3_SPD_PART_LEN
);
63 spd_name
[DDR3_SPD_PART_LEN
] = 0;
65 case SPD_DRAM_LPDDR3_INTEL
:
66 case SPD_DRAM_LPDDR3_JEDEC
:
67 printk(BIOS_INFO
, "LPDDR3\n");
68 /* Module Part Number */
69 memcpy(spd_name
, &spd
[LPDDR3_SPD_PART_OFF
],
71 spd_name
[LPDDR3_SPD_PART_LEN
] = 0;
74 printk(BIOS_INFO
, "DDR4\n");
75 memcpy(spd_name
, &spd
[DDR4_SPD_PART_OFF
], DDR4_SPD_PART_LEN
);
76 spd_name
[DDR4_SPD_PART_LEN
] = 0;
77 ranks
= (spd
[SPD_ORGANIZATION
] >> 3) & 7;
78 devw
= spd_devw
[spd
[12] & 7];
79 busw
= spd_busw
[spd
[13] & 7];
82 printk(BIOS_INFO
, "Unknown (%02x)\n", spd
[SPD_DRAM_TYPE
]);
86 printk(BIOS_INFO
, "SPD: module part is %s\n", spd_name
);
89 "SPD: banks %d, ranks %d, rows %d, columns %d, density %d Mb\n",
90 banks
, ranks
, rows
, cols
, capmb
);
91 printk(BIOS_INFO
, "SPD: device width %d bits, bus width %d bits\n",
94 if (capmb
> 0 && busw
> 0 && devw
> 0 && ranks
> 0) {
95 /* SIZE = DENSITY / 8 * BUS_WIDTH / SDRAM_WIDTH * RANKS */
96 printk(BIOS_INFO
, "SPD: module size is %u MB (per channel)\n",
97 capmb
/ 8 * busw
/ devw
* ranks
);
101 static void update_spd_len(struct spd_block
*blk
)
104 for (i
= 0 ; i
< CONFIG_DIMM_MAX
; i
++)
105 if (blk
->spd_array
[i
] != NULL
)
106 j
|= blk
->spd_array
[i
][SPD_DRAM_TYPE
];
108 /* If spd used is DDR4, then its length is 512 byte. */
109 if (j
== SPD_DRAM_DDR4
)
110 blk
->len
= SPD_PAGE_LEN_DDR4
;
112 blk
->len
= SPD_PAGE_LEN
;
115 int get_spd_cbfs_rdev(struct region_device
*spd_rdev
, u8 spd_index
)
119 uint32_t cbfs_type
= CBFS_TYPE_SPD
;
121 if (cbfs_boot_locate(&fh
, "spd.bin", &cbfs_type
) < 0)
123 cbfs_file_data(spd_rdev
, &fh
);
124 return rdev_chain(spd_rdev
, spd_rdev
, spd_index
* CONFIG_DIMM_SPD_SIZE
,
125 CONFIG_DIMM_SPD_SIZE
);
128 static void get_spd(u8
*spd
, u8 addr
)
131 if (smbus_read_byte(0, addr
, 0) == 0xff) {
132 printk(BIOS_INFO
, "No memory dimm at address %02X\n",
134 /* Make sure spd is zeroed if dimm doesn't exist. */
135 memset(spd
, 0, CONFIG_DIMM_SPD_SIZE
);
139 for (i
= 0; i
< SPD_PAGE_LEN
; i
++)
140 spd
[i
] = smbus_read_byte(0, addr
, i
);
141 /* Check if module is DDR4, DDR4 spd is 512 byte. */
142 if (spd
[SPD_DRAM_TYPE
] == SPD_DRAM_DDR4
&&
143 CONFIG_DIMM_SPD_SIZE
>= SPD_DRAM_DDR4
) {
144 /* Switch to page 1 */
145 smbus_write_byte(0, SPD_PAGE_1
, 0, 0);
146 for (i
= 0; i
< SPD_PAGE_LEN
; i
++)
147 spd
[i
+SPD_PAGE_LEN
] = smbus_read_byte(0, addr
, i
);
148 /* Restore to page 0 */
149 smbus_write_byte(0, SPD_PAGE_0
, 0, 0);
153 void get_spd_smbus(struct spd_block
*blk
)
156 unsigned char *spd_data_ptr
= car_get_var_ptr(&spd_data
);
158 for (i
= 0 ; i
< CONFIG_DIMM_MAX
; i
++) {
159 get_spd(spd_data_ptr
+ i
* CONFIG_DIMM_SPD_SIZE
,
161 blk
->spd_array
[i
] = spd_data_ptr
+ i
* CONFIG_DIMM_SPD_SIZE
;
167 #if CONFIG_DIMM_SPD_SIZE == 128
168 int read_ddr3_spd_from_cbfs(u8
*buf
, int idx
)
170 const int SPD_CRC_HI
= 127;
171 const int SPD_CRC_LO
= 126;
173 const char *spd_file
;
174 size_t spd_file_len
= 0;
175 size_t min_len
= (idx
+ 1) * CONFIG_DIMM_SPD_SIZE
;
177 spd_file
= cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD
,
180 printk(BIOS_EMERG
, "file [spd.bin] not found in CBFS");
181 if (spd_file_len
< min_len
)
182 printk(BIOS_EMERG
, "Missing SPD data.");
183 if (!spd_file
|| spd_file_len
< min_len
)
186 memcpy(buf
, spd_file
+ (idx
* CONFIG_DIMM_SPD_SIZE
),
187 CONFIG_DIMM_SPD_SIZE
);
189 u16 crc
= spd_ddr3_calc_crc(buf
, CONFIG_DIMM_SPD_SIZE
);
191 if (((buf
[SPD_CRC_LO
] == 0) && (buf
[SPD_CRC_HI
] == 0))
192 || (buf
[SPD_CRC_LO
] != (crc
& 0xff))
193 || (buf
[SPD_CRC_HI
] != (crc
>> 8))) {
195 "SPD CRC %02x%02x is invalid, should be %04x\n",
196 buf
[SPD_CRC_HI
], buf
[SPD_CRC_LO
], crc
);
197 buf
[SPD_CRC_LO
] = crc
& 0xff;
198 buf
[SPD_CRC_HI
] = crc
>> 8;
200 printk(BIOS_WARNING
, "\nDisplay the SPD");
201 for (i
= 0; i
< CONFIG_DIMM_SPD_SIZE
; i
++) {
202 if ((i
% 16) == 0x00)
203 printk(BIOS_WARNING
, "\n%02x: ", i
);
204 printk(BIOS_WARNING
, "%02x ", buf
[i
]);
206 printk(BIOS_WARNING
, "\n");