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

#define __SIMPLE_DEVICE__

#include <console/console.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <intelblocks/p2sb.h>
#include <intelblocks/p2sblib.h>
#include <intelblocks/pcr.h>
#include <soc/pci_devs.h>

void p2sb_dev_enable_bar(pci_devfn_t dev, uint64_t bar)
{
	/* Enable PCR Base addresses */
	pci_write_config32(dev, PCI_BASE_ADDRESS_0, (uint32_t)bar);
	pci_write_config32(dev, PCI_BASE_ADDRESS_1, (uint32_t)(bar >> 32));

	/* Enable P2SB MSE */
	pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
}

bool p2sb_dev_is_hidden(pci_devfn_t dev)
{
	const uint16_t pci_vid = pci_read_config16(dev, PCI_VENDOR_ID);

	if (pci_vid == 0xffff)
		return true;
	if (pci_vid == PCI_VID_INTEL)
		return false;
	printk(BIOS_ERR, "P2SB PCI_VENDOR_ID is invalid, unknown if hidden\n");
	return true;
}

static void p2sb_dev_set_hide_bit(pci_devfn_t dev, int hide)
{
	const uint16_t reg = P2SBC + 1;
	const uint8_t mask = P2SBC_HIDE_BIT;
	uint8_t val;

	val = pci_read_config8(dev, reg);
	val &= ~mask;
	if (hide)
		val |= mask;
	pci_write_config8(dev, reg, val);
}

void p2sb_dev_unhide(pci_devfn_t dev)
{
	p2sb_dev_set_hide_bit(dev, 0);

	if (p2sb_dev_is_hidden(dev))
		die_with_post_code(POSTCODE_HW_INIT_FAILURE,
				"Unable to unhide the P2SB device!\n");
}

void p2sb_dev_hide(pci_devfn_t dev)
{
	p2sb_dev_set_hide_bit(dev, 1);

	if (!p2sb_dev_is_hidden(dev))
		die_with_post_code(POSTCODE_HW_INIT_FAILURE,
				"Unable to hide the P2SB device!\n");
}

static void p2sb_send_sideband_msg(pci_devfn_t dev, uint8_t cmd, uint8_t pid,
						uint16_t reg, uint32_t *data)
{
	struct pcr_sbi_msg msg = {
		.pid = pid,
		.offset = reg,
		.opcode = cmd,
		.is_posted = false,
		.fast_byte_enable = 0xF,
		.bar = 0,
		.fid = 0
	};
	uint8_t response;
	int status;

	status = pcr_execute_sideband_msg(dev, &msg, data, &response);
	if (status || response)
		printk(BIOS_ERR, "Fail to execute p2sb sideband access\n");
}

static void p2sb_execute_sbi_in_smm(pci_devfn_t dev, uint8_t cmd, uint8_t pid,
						uint16_t reg, uint32_t *data)
{
	/* Unhide the P2SB device */
	p2sb_dev_unhide(dev);

	p2sb_send_sideband_msg(dev, cmd, pid, reg, data);

	/* Hide the P2SB device */
	p2sb_dev_hide(dev);
}

static void p2sb_execute_sideband_access(pci_devfn_t dev, uint8_t cmd, uint8_t pid,
						uint16_t reg, uint32_t *data)
{
	if (ENV_SMM)
		/*
		 * FSP-S will hide the P2SB device. With the device hidden, we will not be
		 * able to send the sideband interface message. Therefore, we need to unhide
		 * the P2SB device which can only be done in SMM requiring that this
		 * function is called from SMM.
		 */
		p2sb_execute_sbi_in_smm(dev, cmd, pid, reg, data);
	else if (!p2sb_dev_is_hidden(dev))
		p2sb_send_sideband_msg(dev, cmd, pid, reg, data);
	else
		printk(BIOS_WARNING, "Error: P2SB must be hidden, try calling from SMM!\n");
}

uint32_t p2sb_dev_sbi_read(pci_devfn_t dev, uint8_t pid, uint16_t reg)
{
	uint32_t val = 0;
	p2sb_execute_sideband_access(dev, PCR_READ, pid, reg, &val);
	return val;
}

void p2sb_dev_sbi_write(pci_devfn_t dev, uint8_t pid, uint16_t reg, uint32_t val)
{
	p2sb_execute_sideband_access(dev, PCR_WRITE, pid, reg, &val);
}
