/* SPDX-License-Identifier: GPL-2.0-or-later */

/**
 * This code was adapted from src/soc/amd/common/block/pi/amd_late_init.c
 */

#include <fsp/util.h>
#include <memory_info.h>
#include <console/console.h>
#include <cbmem.h>
#include <string.h>
#include <ec/google/chromeec/ec.h>
#include <bootstate.h>
#include <lib.h>
#include <dimm_info_util.h>
#include <dmi_info.h>
#include <device/dram/ddr4.h>
#include <device/dram/lpddr4.h>

/**
 * Convert DDR clock speed (based on memory type) in MHz to the standard reported speed in MT/s
 */
static uint16_t ddr_speed_mhz_to_reported_mts(uint16_t ddr_type, uint16_t speed)
{
	switch (ddr_type) {
	case MEMORY_TYPE_DDR4:
		return ddr4_speed_mhz_to_reported_mts(speed);
	case MEMORY_TYPE_LPDDR4:
		return lpddr4_speed_mhz_to_reported_mts(speed);
	default:
		printk(BIOS_ERR, "Unknown memory type %x", ddr_type);
		return 0;
	}
}

/**
 * Populate dimm_info using AGESA TYPE17_DMI_INFO.
 */
static void transfer_memory_info(const TYPE17_DMI_INFO *dmi17,
				 struct dimm_info *dimm)
{
	hexstrtobin(dmi17->SerialNumber, dimm->serial, sizeof(dimm->serial));

	dimm->dimm_size = smbios_memory_size_to_mib(dmi17->MemorySize, dmi17->ExtSize);

	dimm->ddr_type = dmi17->MemoryType;

	dimm->configured_speed_mts = ddr_speed_mhz_to_reported_mts(
		dmi17->MemoryType, dmi17->ConfigSpeed);

	dimm->max_speed_mts = ddr_speed_mhz_to_reported_mts(dmi17->MemoryType, dmi17->Speed);

	dimm->rank_per_dimm = dmi17->Attributes;

	dimm->mod_type = smbios_form_factor_to_spd_mod_type(dmi17->MemoryType,
						dmi17->FormFactor);

	dimm->bus_width = smbios_bus_width_to_spd_width(dmi17->MemoryType, dmi17->TotalWidth,
						dmi17->DataWidth);

	dimm->mod_id = dmi17->ManufacturerIdCode;

	dimm->bank_locator = 0;

	strncpy((char *)dimm->module_part_number, dmi17->PartNumber,
		sizeof(dimm->module_part_number) - 1);
}

static void print_dimm_info(const struct dimm_info *dimm)
{
	printk(BIOS_DEBUG,
	       "CBMEM_ID_MEMINFO:\n"
	       "  dimm_size: %u\n"
	       "  ddr_type: 0x%hx\n"
	       "  ddr_frequency: %hu\n"
	       "  rank_per_dimm: %hhu\n"
	       "  channel_num: %hhu\n"
	       "  dimm_num: %hhu\n"
	       "  bank_locator: %hhu\n"
	       "  mod_id: %hx\n"
	       "  mod_type: 0x%hhx\n"
	       "  bus_width: %hhu\n"
	       "  serial: %02hhx%02hhx%02hhx%02hhx\n"
	       "  module_part_number(%zu): %s\n",
	       dimm->dimm_size,
	       dimm->ddr_type,
	       dimm->ddr_frequency,
	       dimm->rank_per_dimm,
	       dimm->channel_num,
	       dimm->dimm_num,
	       dimm->bank_locator,
	       dimm->mod_id,
	       dimm->mod_type,
	       dimm->bus_width,
	       dimm->serial[0],
	       dimm->serial[1],
	       dimm->serial[2],
	       dimm->serial[3],
	       strlen((const char *)dimm->module_part_number),
	       (char *)dimm->module_part_number);
}

static void print_dmi_info(const TYPE17_DMI_INFO *dmi17)
{
	printk(BIOS_DEBUG,
	       "AGESA TYPE 17 DMI INFO:\n"
	       "  Handle: %hu\n"
	       "  TotalWidth: %hu\n"
	       "  DataWidth: %hu\n"
	       "  MemorySize: %hu\n"
	       "  DeviceSet: %hhu\n"
	       "  Speed: %hu\n"
	       "  ManufacturerIdCode: %llx\n"
	       "  Attributes: %hhu\n"
	       "  ExtSize: %u\n"
	       "  ConfigSpeed: %hu\n"
	       "  MemoryType: 0x%x\n"
	       "  FormFactor: 0x%x\n"
	       "  DeviceLocator: %8s\n"
	       "  BankLocator: %10s\n"
	       "  SerialNumber(%zu): %9s\n"
	       "  PartNumber(%zu): %19s\n",
	       dmi17->Handle,
	       dmi17->TotalWidth,
	       dmi17->DataWidth,
	       dmi17->MemorySize,
	       dmi17->DeviceSet,
	       dmi17->Speed,
	       dmi17->ManufacturerIdCode,
	       dmi17->Attributes,
	       dmi17->ExtSize,
	       dmi17->ConfigSpeed,
	       dmi17->MemoryType,
	       dmi17->FormFactor,
	       dmi17->DeviceLocator,
	       dmi17->BankLocator,
	       strlen((const char *)dmi17->SerialNumber),
	       dmi17->SerialNumber,
	       strlen((const char *)dmi17->PartNumber),
	       dmi17->PartNumber);
}

/**
 * Marshalls dimm info from AMD_FSP_DMI_HOB into CBMEM_ID_MEMINFO
 */
static void prepare_dmi_17(void *unused)
{
	const DMI_INFO *dmi_table;
	const TYPE17_DMI_INFO *type17_dmi_info;
	struct memory_info *mem_info;
	struct dimm_info *dimm_info;
	char cbi_part_number[DIMM_INFO_PART_NUMBER_SIZE];
	bool use_cbi_part_number = false;
	size_t dimm_cnt = 0;
	size_t amd_fsp_dmi_hob_size;
	const EFI_GUID amd_fsp_dmi_hob_guid = AMD_FSP_DMI_HOB_GUID;

	printk(BIOS_DEBUG, "Saving dimm info for smbios type 17\n");

	/* Allocate meminfo in cbmem. */
	mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(struct memory_info));
	if (!mem_info) {
		printk(BIOS_ERR,
		       "Failed to add memory info to CBMEM, DMI tables will be incomplete\n");
		return;
	}
	memset(mem_info, 0, sizeof(struct memory_info));

	/* Locate the memory info HOB. */
	dmi_table = fsp_find_extension_hob_by_guid(
		(const uint8_t *)&amd_fsp_dmi_hob_guid, &amd_fsp_dmi_hob_size);

	if (dmi_table == NULL || amd_fsp_dmi_hob_size == 0) {
		printk(BIOS_ERR,
		       "AMD_FSP_DMI_HOB not found, DMI table 17 will be incomplete\n");
		return;
	}
	printk(BIOS_DEBUG, "AMD_FSP_DMI_HOB found\n");

	if (CONFIG(EC_GOOGLE_CHROMEEC)) {
		/* Prefer DRAM part number from CBI. */
		if (google_chromeec_cbi_get_dram_part_num(
			cbi_part_number, sizeof(cbi_part_number)) == 0) {
			use_cbi_part_number = true;
		} else {
			printk(BIOS_ERR, "Could not obtain DRAM part number from CBI\n");
		}
	}

	for (unsigned int channel = 0; channel < MAX_CHANNELS_PER_SOCKET; channel++) {
		for (unsigned int dimm = 0; dimm < MAX_DIMMS_PER_CHANNEL; dimm++) {
			type17_dmi_info = &dmi_table->T17[0][channel][dimm];
			/* DIMMs that are present will have a non-zero
			   handle. */
			if (type17_dmi_info->Handle == 0)
				continue;
			print_dmi_info(type17_dmi_info);
			dimm_info = &mem_info->dimm[dimm_cnt];
			dimm_info->channel_num = channel;
			dimm_info->dimm_num = channel;
			transfer_memory_info(type17_dmi_info, dimm_info);
			if (use_cbi_part_number) {
				/* mem_info is memset to 0 above, so it's
				   safe to assume module_part_number will be
				   null terminated */
				strncpy((char *)dimm_info->module_part_number, cbi_part_number,
					sizeof(dimm_info->module_part_number) - 1);
			}
			print_dimm_info(dimm_info);
			dimm_cnt++;
		}
	}
	mem_info->dimm_cnt = dimm_cnt;
}

/* AMD_FSP_DMI_HOB is initialized very late, so check it just in time for writing tables. */
BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY, prepare_dmi_17, NULL);
