/* SPDX-License-Identifier: GPL-2.0-only */

#include <assert.h>
#include <baseboard/variants.h>
#include <cbfs.h>
#include <console/console.h>
#include <soc/gpio.h>
#include <soc/romstage.h>
#include <string.h>
#include <variant/gpio.h>

#include <fsp/soc_binding.h>

/* Offset to identify DRAM type. */
#define SPD_DRAM_TYPE_OFF	2
#define SPD_DRAM_LPDDR3	0xf1
#define SPD_DRAM_DDR4		0x0c

/* Length of SPD data. */
#define SPD_LEN_LPDDR3		256
#define SPD_LEN_DDR4		512

/* Fields that are common across different memory types. */
#define SPD_DENSITY_BANKS_OFF	4
#define SPD_ADDRESSING_OFF	5
#define SPD_PART_LEN		18

/* Fields that are different depending upon memory type. */
#define SPD_ORG_OFF_LPDDR3	7
#define SPD_BUSW_OFF_LPDDR3	8
#define SPD_PART_OFF_LPDDR3	128

#define SPD_ORG_OFF_DDR4	12
#define SPD_BUSW_OFF_DDR4	13
#define SPD_PART_OFF_DDR4	329

#define SPD_INFO(_type)				\
	[MEMORY_##_type] = {				\
		.str = #_type,				\
		.type_code = SPD_DRAM_##_type,		\
		.len = SPD_LEN_##_type,		\
		.org_off = SPD_ORG_OFF_##_type,	\
		.busw_off = SPD_BUSW_OFF_##_type,	\
		.part_off = SPD_PART_OFF_##_type,	\
	}

static const struct dram_info {
	const char *str;
	uint16_t type_code;
	uint16_t len;
	uint16_t org_off;
	uint16_t busw_off;
	uint16_t part_off;
} spd_info[MEMORY_COUNT] = {
	SPD_INFO(LPDDR3),
	SPD_INFO(DDR4),
};

static void mainboard_print_spd_info(const uint8_t *spd, enum memory_type type)
{
	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 };
	const struct dram_info *info = &spd_info[type];

	assert (info->type_code == spd[SPD_DRAM_TYPE_OFF]);

	/* Module type */
	printk(BIOS_INFO, "SPD: module type is %s\n", info->str);

	int banks = spd_banks[(spd[SPD_DENSITY_BANKS_OFF] >> 4) & 7];
	int capmb = spd_capmb[spd[SPD_DENSITY_BANKS_OFF] & 7] * 256;
	int rows  = spd_rows[(spd[SPD_ADDRESSING_OFF] >> 3) & 7];
	int cols  = spd_cols[spd[SPD_ADDRESSING_OFF] & 7];
	int ranks = spd_ranks[(spd[info->org_off] >> 3) & 7];
	int devw  = spd_devw[spd[info->org_off] & 7];
	int busw  = spd_busw[spd[info->busw_off] & 7];

	/* Module Part Number */
	memcpy(spd_name, &spd[info->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 uintptr_t mainboard_get_spd_data(enum memory_type type, bool use_sec_spd)
{
	char *spd_file;
	size_t spd_file_len;
	int spd_index;
	const size_t spd_len = spd_info[type].len;
	const char *spd_bin = use_sec_spd ? "sec-spd.bin" : "spd.bin";

	spd_index = variant_memory_sku();
	assert(spd_index >= 0);
	printk(BIOS_INFO, "SPD index %d\n", spd_index);

	/* Load SPD data from CBFS */
	spd_file = cbfs_map(spd_bin, &spd_file_len);
	if (!spd_file)
		die("SPD data not found.");

	/* make sure we have at least one SPD in the file. */
	if (spd_file_len < spd_len)
		die("Missing SPD data.");

	/* Make sure we did not overrun the buffer */
	if (spd_file_len < ((spd_index + 1) * spd_len))
		die("Invalid SPD index.");

	spd_index *= spd_len;
	mainboard_print_spd_info((uint8_t *)(spd_file + spd_index), type);

	return (uintptr_t)(spd_file + spd_index);
}

void mainboard_memory_init_params(FSPM_UPD *mupd)
{
	FSP_M_CONFIG *mem_cfg = &mupd->FspmConfig;
	struct memory_params p;

	const struct pad_config *pads;
	size_t num;

	pads = variant_romstage_gpio_table(&num);
	gpio_configure_pads(pads, num);

	memset(&p, 0, sizeof(p));
	variant_memory_params(&p);

	assert(p.type < MEMORY_COUNT);

	if (p.dq_map && p.dq_map_size)
		memcpy(&mem_cfg->DqByteMapCh0, p.dq_map, p.dq_map_size);

	if (p.dqs_map && p.dqs_map_size)
		memcpy(&mem_cfg->DqsMapCpu2DramCh0, p.dqs_map, p.dqs_map_size);

	memcpy(&mem_cfg->RcompResistor, p.rcomp_resistor,
		p.rcomp_resistor_size);
	memcpy(&mem_cfg->RcompTarget, p.rcomp_target, p.rcomp_target_size);

	mem_cfg->MemorySpdPtr00 = mainboard_get_spd_data(p.type, p.use_sec_spd);
	if (p.single_channel)
		mem_cfg->MemorySpdPtr10 = 0;
	else
		mem_cfg->MemorySpdPtr10 = mem_cfg->MemorySpdPtr00;
	mem_cfg->MemorySpdDataLen = spd_info[p.type].len;

	mem_cfg->SaOcSupport = p.enable_sa_oc_support;
	mem_cfg->SaVoltageOffset = p.sa_voltage_offset_val;
}
