mb/google/auron: Move SPD file handling to chipset
The SPD file handling code is generic and can be used on any other mainboard. Move it to chipset scope to enable code reuse. Change-Id: I85b1460ccb82f0c1bf409db4a6b4c9355c25e76d Signed-off-by: Angel Pons <th3fanbus@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/55808 Reviewed-by: Michael Niewöhner <foss@mniewoehner.de> Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
This commit is contained in:
parent
333751b22e
commit
2a90e396fc
|
@ -1,103 +1,11 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
#include <cbfs.h>
|
|
||||||
#include <console/console.h>
|
|
||||||
#include <mainboard/google/auron/variant.h>
|
#include <mainboard/google/auron/variant.h>
|
||||||
#include <southbridge/intel/lynxpoint/lp_gpio.h>
|
|
||||||
#include <soc/pei_data.h>
|
#include <soc/pei_data.h>
|
||||||
#include <soc/pei_wrapper.h>
|
#include <soc/pei_wrapper.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
#define SPD_DRAM_TYPE 2
|
|
||||||
#define SPD_DRAM_DDR3 0x0b
|
|
||||||
#define SPD_DRAM_LPDDR3 0xf1
|
|
||||||
#define SPD_DENSITY_BANKS 4
|
|
||||||
#define SPD_ADDRESSING 5
|
|
||||||
#define SPD_ORGANIZATION 7
|
|
||||||
#define SPD_BUS_DEV_WIDTH 8
|
|
||||||
#define SPD_PART_OFF 128
|
|
||||||
#define SPD_PART_LEN 18
|
|
||||||
|
|
||||||
#define SPD_LEN 256
|
|
||||||
|
|
||||||
static void mainboard_print_spd_info(uint8_t spd[])
|
|
||||||
{
|
|
||||||
const int spd_banks[8] = { 8, 16, 32, 64, -1, -1, -1, -1 };
|
|
||||||
const int spd_capmb[8] = { 1, 2, 4, 8, 16, 32, 64, 0 };
|
|
||||||
const int spd_rows[8] = { 12, 13, 14, 15, 16, -1, -1, -1 };
|
|
||||||
const int spd_cols[8] = { 9, 10, 11, 12, -1, -1, -1, -1 };
|
|
||||||
const int spd_ranks[8] = { 1, 2, 3, 4, -1, -1, -1, -1 };
|
|
||||||
const int spd_devw[8] = { 4, 8, 16, 32, -1, -1, -1, -1 };
|
|
||||||
const int spd_busw[8] = { 8, 16, 32, 64, -1, -1, -1, -1 };
|
|
||||||
char spd_name[SPD_PART_LEN+1] = { 0 };
|
|
||||||
|
|
||||||
int banks = spd_banks[(spd[SPD_DENSITY_BANKS] >> 4) & 7];
|
|
||||||
int capmb = spd_capmb[spd[SPD_DENSITY_BANKS] & 7] * 256;
|
|
||||||
int rows = spd_rows[(spd[SPD_ADDRESSING] >> 3) & 7];
|
|
||||||
int cols = spd_cols[spd[SPD_ADDRESSING] & 7];
|
|
||||||
int ranks = spd_ranks[(spd[SPD_ORGANIZATION] >> 3) & 7];
|
|
||||||
int devw = spd_devw[spd[SPD_ORGANIZATION] & 7];
|
|
||||||
int busw = spd_busw[spd[SPD_BUS_DEV_WIDTH] & 7];
|
|
||||||
|
|
||||||
/* Module type */
|
|
||||||
printk(BIOS_INFO, "SPD: module type is ");
|
|
||||||
switch (spd[SPD_DRAM_TYPE]) {
|
|
||||||
case SPD_DRAM_DDR3:
|
|
||||||
printk(BIOS_INFO, "DDR3\n");
|
|
||||||
break;
|
|
||||||
case SPD_DRAM_LPDDR3:
|
|
||||||
printk(BIOS_INFO, "LPDDR3\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printk(BIOS_INFO, "Unknown (%02x)\n", spd[SPD_DRAM_TYPE]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Module Part Number */
|
|
||||||
memcpy(spd_name, &spd[SPD_PART_OFF], SPD_PART_LEN);
|
|
||||||
spd_name[SPD_PART_LEN] = 0;
|
|
||||||
printk(BIOS_INFO, "SPD: module part is %s\n", spd_name);
|
|
||||||
|
|
||||||
printk(BIOS_INFO, "SPD: banks %d, ranks %d, rows %d, columns %d, "
|
|
||||||
"density %d Mb\n", banks, ranks, rows, cols, capmb);
|
|
||||||
printk(BIOS_INFO, "SPD: device width %d bits, bus width %d bits\n",
|
|
||||||
devw, busw);
|
|
||||||
|
|
||||||
if (capmb > 0 && busw > 0 && devw > 0 && ranks > 0) {
|
|
||||||
/* SIZE = DENSITY / 8 * BUS_WIDTH / SDRAM_WIDTH * RANKS */
|
|
||||||
printk(BIOS_INFO, "SPD: module size is %u MB (per channel)\n",
|
|
||||||
capmb / 8 * busw / devw * ranks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fill_spd_for_index(uint8_t spd[], unsigned int spd_index)
|
|
||||||
{
|
|
||||||
size_t spd_file_len;
|
|
||||||
uint8_t *spd_file = cbfs_map("spd.bin", &spd_file_len);
|
|
||||||
|
|
||||||
printk(BIOS_DEBUG, "SPD index %d\n", spd_index);
|
|
||||||
|
|
||||||
if (!spd_file)
|
|
||||||
die("SPD data not found.");
|
|
||||||
|
|
||||||
if (spd_file_len < SPD_LEN)
|
|
||||||
die("Missing SPD data.");
|
|
||||||
|
|
||||||
if (spd_file_len < ((spd_index + 1) * SPD_LEN)) {
|
|
||||||
printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n");
|
|
||||||
spd_index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(spd, spd_file + (spd_index * SPD_LEN), SPD_LEN);
|
|
||||||
|
|
||||||
/* Make sure a valid SPD was found */
|
|
||||||
if (spd[0] == 0)
|
|
||||||
die("Invalid SPD data.");
|
|
||||||
|
|
||||||
mainboard_print_spd_info(spd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy SPD data for on-board memory */
|
/* Copy SPD data for on-board memory */
|
||||||
void mainboard_fill_spd_data(struct pei_data *pei_data)
|
void mainboard_fill_spd_data(struct pei_data *pei_data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,6 +8,7 @@ romstage-y += early_init.c
|
||||||
romstage-y += raminit.c
|
romstage-y += raminit.c
|
||||||
romstage-y += report_platform.c
|
romstage-y += report_platform.c
|
||||||
romstage-y += romstage.c
|
romstage-y += romstage.c
|
||||||
|
romstage-$(CONFIG_HAVE_SPD_IN_CBFS) += spd.c
|
||||||
|
|
||||||
ramstage-y += acpi.c
|
ramstage-y += acpi.c
|
||||||
ramstage-y += finalize.c
|
ramstage-y += finalize.c
|
||||||
|
|
|
@ -28,8 +28,12 @@ static inline void pei_data_usb3_port(struct pei_data *pei_data, int port,
|
||||||
|
|
||||||
#define SPD_MEMORY_DOWN 0xff
|
#define SPD_MEMORY_DOWN 0xff
|
||||||
|
|
||||||
|
#define SPD_LEN 256
|
||||||
|
|
||||||
void broadwell_fill_pei_data(struct pei_data *pei_data);
|
void broadwell_fill_pei_data(struct pei_data *pei_data);
|
||||||
void mainboard_fill_pei_data(struct pei_data *pei_data);
|
void mainboard_fill_pei_data(struct pei_data *pei_data);
|
||||||
void mainboard_fill_spd_data(struct pei_data *pei_data);
|
void mainboard_fill_spd_data(struct pei_data *pei_data);
|
||||||
|
|
||||||
|
void fill_spd_for_index(uint8_t spd[], unsigned int spd_index);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
|
#include <cbfs.h>
|
||||||
|
#include <console/console.h>
|
||||||
|
#include <soc/pei_data.h>
|
||||||
|
#include <soc/pei_wrapper.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
#define SPD_DRAM_TYPE 2
|
||||||
|
#define SPD_DRAM_DDR3 0x0b
|
||||||
|
#define SPD_DRAM_LPDDR3 0xf1
|
||||||
|
#define SPD_DENSITY_BANKS 4
|
||||||
|
#define SPD_ADDRESSING 5
|
||||||
|
#define SPD_ORGANIZATION 7
|
||||||
|
#define SPD_BUS_DEV_WIDTH 8
|
||||||
|
#define SPD_PART_OFF 128
|
||||||
|
#define SPD_PART_LEN 18
|
||||||
|
|
||||||
|
static void print_spd_info(uint8_t spd[])
|
||||||
|
{
|
||||||
|
const int spd_banks[8] = { 8, 16, 32, 64, -1, -1, -1, -1 };
|
||||||
|
const int spd_capmb[8] = { 1, 2, 4, 8, 16, 32, 64, 0 };
|
||||||
|
const int spd_rows[8] = { 12, 13, 14, 15, 16, -1, -1, -1 };
|
||||||
|
const int spd_cols[8] = { 9, 10, 11, 12, -1, -1, -1, -1 };
|
||||||
|
const int spd_ranks[8] = { 1, 2, 3, 4, -1, -1, -1, -1 };
|
||||||
|
const int spd_devw[8] = { 4, 8, 16, 32, -1, -1, -1, -1 };
|
||||||
|
const int spd_busw[8] = { 8, 16, 32, 64, -1, -1, -1, -1 };
|
||||||
|
char spd_name[SPD_PART_LEN+1] = { 0 };
|
||||||
|
|
||||||
|
int banks = spd_banks[(spd[SPD_DENSITY_BANKS] >> 4) & 7];
|
||||||
|
int capmb = spd_capmb[spd[SPD_DENSITY_BANKS] & 7] * 256;
|
||||||
|
int rows = spd_rows[(spd[SPD_ADDRESSING] >> 3) & 7];
|
||||||
|
int cols = spd_cols[spd[SPD_ADDRESSING] & 7];
|
||||||
|
int ranks = spd_ranks[(spd[SPD_ORGANIZATION] >> 3) & 7];
|
||||||
|
int devw = spd_devw[spd[SPD_ORGANIZATION] & 7];
|
||||||
|
int busw = spd_busw[spd[SPD_BUS_DEV_WIDTH] & 7];
|
||||||
|
|
||||||
|
/* Module type */
|
||||||
|
printk(BIOS_INFO, "SPD: module type is ");
|
||||||
|
switch (spd[SPD_DRAM_TYPE]) {
|
||||||
|
case SPD_DRAM_DDR3:
|
||||||
|
printk(BIOS_INFO, "DDR3\n");
|
||||||
|
break;
|
||||||
|
case SPD_DRAM_LPDDR3:
|
||||||
|
printk(BIOS_INFO, "LPDDR3\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printk(BIOS_INFO, "Unknown (%02x)\n", spd[SPD_DRAM_TYPE]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Module Part Number */
|
||||||
|
memcpy(spd_name, &spd[SPD_PART_OFF], SPD_PART_LEN);
|
||||||
|
spd_name[SPD_PART_LEN] = 0;
|
||||||
|
printk(BIOS_INFO, "SPD: module part is %s\n", spd_name);
|
||||||
|
|
||||||
|
printk(BIOS_INFO, "SPD: banks %d, ranks %d, rows %d, columns %d, "
|
||||||
|
"density %d Mb\n", banks, ranks, rows, cols, capmb);
|
||||||
|
printk(BIOS_INFO, "SPD: device width %d bits, bus width %d bits\n",
|
||||||
|
devw, busw);
|
||||||
|
|
||||||
|
if (capmb > 0 && busw > 0 && devw > 0 && ranks > 0) {
|
||||||
|
/* SIZE = DENSITY / 8 * BUS_WIDTH / SDRAM_WIDTH * RANKS */
|
||||||
|
printk(BIOS_INFO, "SPD: module size is %u MB (per channel)\n",
|
||||||
|
capmb / 8 * busw / devw * ranks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill_spd_for_index(uint8_t spd[], unsigned int spd_index)
|
||||||
|
{
|
||||||
|
size_t spd_file_len;
|
||||||
|
uint8_t *spd_file = cbfs_map("spd.bin", &spd_file_len);
|
||||||
|
|
||||||
|
printk(BIOS_DEBUG, "SPD index %d\n", spd_index);
|
||||||
|
|
||||||
|
if (!spd_file)
|
||||||
|
die("SPD data not found.");
|
||||||
|
|
||||||
|
if (spd_file_len < SPD_LEN)
|
||||||
|
die("Missing SPD data.");
|
||||||
|
|
||||||
|
if (spd_file_len < ((spd_index + 1) * SPD_LEN)) {
|
||||||
|
printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n");
|
||||||
|
spd_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(spd, spd_file + (spd_index * SPD_LEN), SPD_LEN);
|
||||||
|
|
||||||
|
/* Make sure a valid SPD was found */
|
||||||
|
if (spd[0] == 0)
|
||||||
|
die("Invalid SPD data.");
|
||||||
|
|
||||||
|
print_spd_info(spd);
|
||||||
|
}
|
Loading…
Reference in New Issue