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

#include <console/console.h>
#include <cpu/cpu.h>
#include <fsp/util.h>
#include <FspGuids.h>
#include <misc_data.h>
#include <soc/cpu.h>
#include <soc/soc_util.h>
#include <types.h>

/*
 * The Zen/Zen+ based APUs can be RV (sometimes called RV1), PCO or RV2 silicon. RV2 has less
 * PCIe, USB3 and DisplayPort connectivity than RV(1) or PCO. A Picasso SoC is always PCO
 * silicon, a Dali SoC can either be RV2 or fused-down PCO silicon that has the same
 * connectivity as the RV2 one and Pollock is always RV2 silicon. Picasso and Dali are in a FP5
 * package while Pollock is in the smaller FT5 package.
 */

#define SOCKET_TYPE_SHIFT	28
#define SOCKET_TYPE_MASK	(0xf << SOCKET_TYPE_SHIFT)

/* some Pollock engineering samples return the wrong socket type */
enum socket_type get_socket_type(void)
{
	uint32_t ebx = cpuid_ebx(0x80000001);
	ebx = (ebx & SOCKET_TYPE_MASK) >> SOCKET_TYPE_SHIFT;
	return (enum socket_type)ebx;
}

void print_socket_type(void)
{
	enum socket_type socket = get_socket_type();

	printk(BIOS_INFO, "Socket type: ");

	switch (socket) {
	case SOCKET_FP5:
		printk(BIOS_INFO, "FP5\n");
		break;
	case SOCKET_AM4:
		printk(BIOS_INFO, "AM4\n");
		break;
	case SOCKET_FT5:
		printk(BIOS_INFO, "FT5\n");
		break;
	default:
		printk(BIOS_INFO, "unknown\n");
	}
}

/* returns 0 in case or errors */
static uint32_t get_internal_silicon_type(void)
{
	static uint32_t silicon_type;
	size_t hob_size = 0;
	const struct picasso_misc_data *hob;

	if (silicon_type)
		return silicon_type;

	hob = fsp_find_extension_hob_by_guid(PICASSO_MISC_DATA_HOB_GUID.b, &hob_size);

	if (hob == NULL || hob_size == 0) {
		printk(BIOS_ERR, "Couldn't find Picasso misc data HOB.\n");
		return 0;
	}

	if (hob->version != PICASSO_MISC_DATA_VERSION) {
		printk(BIOS_ERR, "Unexpected Picasso misc data HOB version.\n");
		return 0;
	}

	silicon_type = hob->silicon_id;

	printk(BIOS_DEBUG, "Silicon ID = 0x%x\n", silicon_type);

	return silicon_type;
}

#define SILICON_IS_MYSTERY_MEAT	(1 << 31)
#define SILICON_IS_RV2		(1 << 30)

static bool is_rv2_silicon(void)
{
	return get_internal_silicon_type() & SILICON_IS_RV2;
}

static bool is_mystery_silicon(void)
{
	return get_internal_silicon_type() & SILICON_IS_MYSTERY_MEAT;
}

static bool is_fam17_1x(void)
{
	return cpuid_match(cpuid_eax(1), PICASSO_B0_CPUID,
			   CPUID_ALL_STEPPINGS_AND_BASE_MODELS_MASK);
}

static bool is_fam17_11(void)
{
	return cpuid_match(cpuid_eax(1), RAVEN1_B0_CPUID, CPUID_ALL_STEPPINGS_MASK);
}

static bool is_fam17_18(void)
{
	return cpuid_match(cpuid_eax(1), PICASSO_B0_CPUID, CPUID_ALL_STEPPINGS_MASK);
}

static bool is_fam17_2x(void)
{
	return cpuid_match(cpuid_eax(1), RAVEN2_A0_CPUID,
			   CPUID_ALL_STEPPINGS_AND_BASE_MODELS_MASK);
}

static bool is_fam17_20(void)
{
	return cpuid_match(cpuid_eax(1), RAVEN2_A0_CPUID, CPUID_ALL_STEPPINGS_MASK);
}

enum silicon_type get_silicon_type(void)
{
	/*
	 * RV2 is fam17_20, but might return a fam17_1x CPUID in the is_mystery_silicon() case.
	 * is_rv2_silicon() has the correct information, but requires the HOB to be present.
	 */
	if (is_fam17_20() || is_rv2_silicon())
		return SILICON_RV2;

	if (is_fam17_18() && !is_rv2_silicon())
		return SILICON_PCO;

	if (is_fam17_11() && !is_rv2_silicon())
		return SILICON_RV1;

	/* some cases might still be missing */

	return SILICON_UNKNOWN;
}

/* some Pollock engineering samples return the wrong socket type and get detected as Dali */
enum soc_type get_soc_type(void)
{
	switch (get_socket_type()) {
	case SOCKET_FP5:
		if (is_fam17_1x() && !is_mystery_silicon())
			return SOC_PICASSO;

		if (is_fam17_2x() || (is_fam17_1x() && is_mystery_silicon()))
			return SOC_DALI;

		break;
	case SOCKET_FT5:
		/* add is_fam17_20() CPUID sanity check here? */
		return SOC_POLLOCK;
	case SOCKET_AM4:
		/* AM4 SoC type detection logic not implemented */
		break;
	}

	return SOC_UNKNOWN;
}

void print_silicon_type(void)
{
	const enum silicon_type silicon = get_silicon_type();

	printk(BIOS_INFO, "Silicon type: ");

	switch (silicon) {
	case SILICON_RV1:
		printk(BIOS_INFO, "RV1\n");
		break;
	case SILICON_PCO:
		printk(BIOS_INFO, "PCO\n");
		break;
	case SILICON_RV2:
		printk(BIOS_INFO, "RV2\n");
		break;
	default:
		printk(BIOS_INFO, "unknown\n");
	}
}

void print_soc_type(void)
{
	const enum soc_type soc = get_soc_type();

	printk(BIOS_INFO, "SoC type: ");

	switch (soc) {
	case SOC_PICASSO:
		printk(BIOS_INFO, "Picasso\n");
		break;
	case SOC_DALI:
		printk(BIOS_INFO, "Dali\n");
		break;
	case SOC_POLLOCK:
		printk(BIOS_INFO, "Pollock\n");
		break;
	default:
		printk(BIOS_INFO, "unknown\n");
	}
}

bool soc_is_reduced_io_sku(void)
{
	return get_silicon_type() == SILICON_RV2 || get_soc_type() == SOC_DALI;
}

bool soc_is_raven2(void)
{
	return get_silicon_type() == SILICON_RV2;
}
