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

/*
 * This file is created based on Intel Alder Lake Processor SA Datasheet
 * Document number: 619503
 * Chapter number: 3
 */

#include <arch/ioapic.h>
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <delay.h>
#include <intelblocks/cpulib.h>
#include <intelblocks/msr.h>
#include <intelblocks/power_limit.h>
#include <intelblocks/systemagent.h>
#include <soc/iomap.h>
#include <soc/soc_chip.h>
#include <soc/systemagent.h>
#include <spi_flash.h>
#include "stddef.h"

/*
 * SoC implementation
 *
 * Add all known fixed memory ranges for Host Controller/Memory
 * controller.
 */
void soc_add_fixed_mmio_resources(struct device *dev, int *index)
{
	static const struct sa_mmio_descriptor soc_fixed_resources[] = {
		{ MCHBAR, MCH_BASE_ADDRESS, MCH_BASE_SIZE, "MCHBAR" },
		{ DMIBAR, DMI_BASE_ADDRESS, DMI_BASE_SIZE, "DMIBAR" },
		{ EPBAR, EP_BASE_ADDRESS, EP_BASE_SIZE, "EPBAR" },
		{ REGBAR, REG_BASE_ADDRESS, REG_BASE_SIZE, "REGBAR" },
		{ EDRAMBAR, EDRAM_BASE_ADDRESS, EDRAM_BASE_SIZE, "EDRAMBAR" },

		/* first field (sa_mmio_descriptor.index) is not used, setting to 0: */
		{ 0, CRAB_ABORT_BASE_ADDR, CRAB_ABORT_SIZE, "CRAB_ABORT" },
		{ 0, TPM_BASE_ADDRESS, TPM_SIZE, "TPM" },
		{ 0, LT_SECURITY_BASE_ADDR, LT_SECURITY_SIZE, "LT_SECURITY" },
		{ 0, IO_APIC_ADDR, APIC_SIZE, "APIC" },
		// PCH_PRESERVERD covers:
		// TraceHub SW BAR, SBREG, PMC MBAR, SPI BAR0, SerialIo BAR in ACPI mode
		// eSPI LGMR BAR, eSPI2 SEGMR BAR, TraceHub MTB BAR, TraceHub FW BAR
		// see fsp/ClientOneSiliconPkg/Fru/AdlPch/Include/PchReservedResourcesAdpP.h
		{ 0, PCH_PRESERVED_BASE_ADDRESS, PCH_PRESERVED_BASE_SIZE, "PCH_RESERVED" },
	};

	sa_add_fixed_mmio_resources(dev, index, soc_fixed_resources,
			ARRAY_SIZE(soc_fixed_resources));

	/* Add Vt-d resources if VT-d is enabled */
	if ((pci_read_config32(dev, CAPID0_A) & VTD_DISABLE))
		return;

	sa_add_fixed_mmio_resources(dev, index, soc_vtd_resources,
			ARRAY_SIZE(soc_vtd_resources));
}

/*
 * set MMIO resource's fields
 */
static void set_mmio_resource(
	struct sa_mmio_descriptor *resource,
	uint64_t base,
	uint64_t size,
	const char *description)
{
	if (resource == NULL) {
		printk(BIOS_ERR, "%s: argument resource is NULL for %s\n",
		__func__, description);
		return;
	}
	resource->base = base;
	resource->size = size;
	resource->description = description;
}

/*
 * SoC implementation
 *
 * Add all known configurable memory ranges for Host Controller/Memory
 * controller.
 */
void soc_add_configurable_mmio_resources(struct device *dev, int *resource_cnt)
{
	uint64_t size, base, tseg_base;
	int count = 0;
	struct sa_mmio_descriptor cfg_rsrc[6]; /* Increase size when adding more resources */

	/* MMCONF */
	size = get_mmcfg_size(dev);
	if (size > 0)
		set_mmio_resource(&(cfg_rsrc[count++]), CONFIG_ECAM_MMCONF_BASE_ADDRESS,
			size, "MMCONF");

	/* DSM */
	size = get_dsm_size(dev);
	if (size > 0) {
		base = pci_read_config32(dev, DSM_BASE_ADDR_REG) & 0xFFF00000;
		set_mmio_resource(&(cfg_rsrc[count++]), base, size, "DSM");
	}

	/* TSEG */
	size = sa_get_tseg_size();
	tseg_base = sa_get_tseg_base();
	if (size > 0)
		set_mmio_resource(&(cfg_rsrc[count++]), tseg_base, size, "TSEG");

	/* PMRR */
	size = get_valid_prmrr_size();
	if (size > 0) {
		uint64_t mask = pci_read_config32(dev, MSR_PRMRR_PHYS_MASK);
		base = pci_read_config32(dev, MSR_PRMRR_PHYS_BASE) & mask;
		set_mmio_resource(&(cfg_rsrc[count++]), base, size, "PMRR");
	}

	/* GSM */
	size = get_gsm_size(dev);
	if (size > 0) {
		base = sa_get_gsm_base();
		set_mmio_resource(&(cfg_rsrc[count++]), base, size, "GSM");
	}

	/* DPR */
	size = get_dpr_size(dev);
	if (size > 0) {
		/* DPR just below TSEG: */
		base = tseg_base - size;
		set_mmio_resource(&(cfg_rsrc[count++]), base, size, "DPR");
	}

	/* Add all the above */
	sa_add_fixed_mmio_resources(dev, resource_cnt, cfg_rsrc, count);
}

/*
 * SoC implementation
 *
 * Perform System Agent Initialization during Ramstage phase.
 */
void soc_systemagent_init(struct device *dev)
{
	struct soc_power_limits_config *soc_config;
	struct device *sa;
	uint16_t sa_pci_id;
	u8 tdp;
	size_t i;
	config_t *config;

	/* Enable Power Aware Interrupt Routing */
	enable_power_aware_intr();

	config = config_of_soc();

	/* Get System Agent PCI ID */
	sa = pcidev_path_on_root(SA_DEVFN_ROOT);
	sa_pci_id = sa ? pci_read_config16(sa, PCI_DEVICE_ID) : 0xFFFF;

	tdp = get_cpu_tdp();

	/* Choose power limits configuration based on the CPU SA PCI ID and
	 * CPU TDP value. */
	for (i = 0; i < ARRAY_SIZE(cpuid_to_adl); i++) {
		if (sa_pci_id == cpuid_to_adl[i].cpu_id &&
				tdp == cpuid_to_adl[i].cpu_tdp) {
			soc_config = &config->power_limits_config[cpuid_to_adl[i].limits];
			set_power_limits(MOBILE_SKU_PL1_TIME_SEC, soc_config);
			break;
		}
	}

	if (i == ARRAY_SIZE(cpuid_to_adl)) {
		printk(BIOS_ERR, "unknown SA ID: 0x%4x, skipped power limits configuration.\n",
			sa_pci_id);
		return;
	}
}

uint32_t soc_systemagent_max_chan_capacity_mib(u8 capid0_a_ddrsz)
{
	switch (capid0_a_ddrsz) {
	case 1:
		return 8192;
	case 2:
		return 4096;
	case 3:
		return 2048;
	default:
		return 65536;
	}
}

uint64_t get_mmcfg_size(struct device *dev)
{
	uint32_t pciexbar_reg;
	uint64_t mmcfg_length;

	if (!dev) {
		printk(BIOS_DEBUG, "%s : device is null\n", __func__);
		return 0;
	}

	pciexbar_reg = pci_read_config32(dev, PCIEXBAR);

	if (!(pciexbar_reg & (1 << 0))) {
		printk(BIOS_DEBUG, "%s : PCIEXBAR disabled\n", __func__);
		return 0;
	}

	switch ((pciexbar_reg & MASK_PCIEXBAR_LENGTH) >> PCIEXBAR_LENGTH_LSB) {
	case PCIEXBAR_LENGTH_4096MB:
		mmcfg_length = 4 * ((uint64_t)GiB);
		break;
	case PCIEXBAR_LENGTH_2048MB:
		mmcfg_length = 2 * ((uint64_t)GiB);
		break;
	case PCIEXBAR_LENGTH_1024MB:
		mmcfg_length = 1 * GiB;
		break;
	case PCIEXBAR_LENGTH_512MB:
		mmcfg_length = 512 * MiB;
		break;
	case PCIEXBAR_LENGTH_256MB:
		mmcfg_length = 256 * MiB;
		break;
	case PCIEXBAR_LENGTH_128MB:
		mmcfg_length = 128 * MiB;
		break;
	case PCIEXBAR_LENGTH_64MB:
		mmcfg_length = 64 * MiB;
		break;
	default:
		printk(BIOS_DEBUG, "%s : PCIEXBAR - invalid length (0x%x)\n", __func__,
			pciexbar_reg & MASK_PCIEXBAR_LENGTH);
		mmcfg_length = 0x0;
		break;
	}

	return mmcfg_length;
}

uint64_t get_dsm_size(struct device *dev)
{
	// - size : B0/D0/F0:R 50h [15:8]
	uint32_t reg32 = pci_read_config32(dev, GGC);
	uint64_t size;
	uint32_t size_field = (reg32 & MASK_DSM_LENGTH) >> MASK_DSM_LENGTH_LSB;
	if (size_field <= 0x10) { // 0x0 - 0x10
		size = size_field * 32 * MiB;
	} else if ((size_field >= 0xF0) && (size_field >= 0xFE)) {
		size = (size_field - 0xEF) * 4 * MiB;
	} else {
		switch (size_field) {
		case 0x20:
			size = 1 * GiB;
			break;
		case 0x30:
			size = 1536 * MiB;
			break;
		case 0x40:
			size = 2 * (uint64_t)GiB;
			break;
		default:
			printk(BIOS_DEBUG, "%s : DSM - invalid length (0x%x)\n",
				__func__, size_field);
			size = 0x0;
			break;
		}
	}
	return size;
}

uint64_t get_gsm_size(struct device *dev)
{
	const u32 gsm_size = pci_read_config32(dev, GGC);
	uint64_t size;
	uint32_t size_field = (gsm_size & MASK_GSM_LENGTH) >> MASK_GSM_LENGTH_LSB;
	switch (size_field) {
	case 0x0:
		size = 0;
		break;
	case 0x1:
		size = 2 * MiB;
		break;
	case 0x2:
		size = 4 * MiB;
		break;
	case 0x3:
		size = 8 * MiB;
		break;
	default:
		size = 0;
		break;
	}
	return size;
}
uint64_t get_dpr_size(struct device *dev)
{
	uint64_t size;
	uint32_t dpr_reg = pci_read_config32(dev, DPR_REG);
	uint32_t size_field = (dpr_reg & MASK_DPR_LENGTH) >> MASK_DPR_LENGTH_LSB;
	size = size_field * MiB;
	return size;
}
