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

#include <stdint.h>
#include <string.h>
#include <device/mmio.h>
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>

#include <soc/iomap.h>
#include <soc/pcr.h>
#include <soc/soc_util.h>
#include <soc/gpio_dnv.h>

//         Community               PadOwnOffset                HostOwnOffset
//         GpiIsOffset
//         GpiIeOffset             GpiGpeStsOffset             GpiGpeEnOffset
//         SmiStsOffset
//         SmiEnOffset             NmiStsOffset                NmiEnOffset
//         PadCfgLockOffset
//         PadCfgLockTxOffset      PadCfgOffset                PadPerGroup
static const struct GPIO_GROUP_INFO mGpioGroupInfo[] = {
	{PID_GPIOCOM0, R_PCH_PCR_GPIO_NC_PAD_OWN, R_PCH_PCR_GPIO_NC_HOSTSW_OWN,
	 R_PCH_PCR_GPIO_NC_GPI_IS, R_PCH_PCR_GPIO_NC_GPI_IE,
	 R_PCH_PCR_GPIO_NC_GPI_GPE_STS, R_PCH_PCR_GPIO_NC_GPI_GPE_EN,
	 R_PCH_PCR_GPIO_NC_SMI_STS, R_PCH_PCR_GPIO_NC_SMI_EN,
	 R_PCH_PCR_GPIO_NC_NMI_STS, R_PCH_PCR_GPIO_NC_NMI_EN,
	 R_PCH_PCR_GPIO_NC_PADCFGLOCK, R_PCH_PCR_GPIO_NC_PADCFGLOCKTX,
	 R_PCH_PCR_GPIO_NC_PADCFG_OFFSET,
	 V_PCH_GPIO_NC_PAD_MAX}, // DNV NORTH_ALL
	{PID_GPIOCOM1, R_PCH_PCR_GPIO_SC_DFX_PAD_OWN,
	 R_PCH_PCR_GPIO_SC_DFX_HOSTSW_OWN, R_PCH_PCR_GPIO_SC_DFX_GPI_IS,
	 R_PCH_PCR_GPIO_SC_DFX_GPI_IE, R_PCH_PCR_GPIO_SC_DFX_GPI_GPE_STS,
	 R_PCH_PCR_GPIO_SC_DFX_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,
	 NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY,
	 NO_REGISTER_FOR_PROPERTY, R_PCH_PCR_GPIO_SC_DFX_PADCFGLOCK,
	 R_PCH_PCR_GPIO_SC_DFX_PADCFGLOCKTX,
	 R_PCH_PCR_GPIO_SC_DFX_PADCFG_OFFSET,
	 V_PCH_GPIO_SC_DFX_PAD_MAX}, // DNV SOUTH_DFX
	{PID_GPIOCOM1, R_PCH_PCR_GPIO_SC0_PAD_OWN,
	 R_PCH_PCR_GPIO_SC0_HOSTSW_OWN, R_PCH_PCR_GPIO_SC0_GPI_IS,
	 R_PCH_PCR_GPIO_SC0_GPI_IE, R_PCH_PCR_GPIO_SC0_GPI_GPE_STS,
	 R_PCH_PCR_GPIO_SC0_GPI_GPE_EN, R_PCH_PCR_GPIO_SC0_SMI_STS,
	 R_PCH_PCR_GPIO_SC0_SMI_EN, R_PCH_PCR_GPIO_SC0_NMI_STS,
	 R_PCH_PCR_GPIO_SC0_NMI_EN, R_PCH_PCR_GPIO_SC0_PADCFGLOCK,
	 R_PCH_PCR_GPIO_SC0_PADCFGLOCKTX, R_PCH_PCR_GPIO_SC0_PADCFG_OFFSET,
	 V_PCH_GPIO_SC0_PAD_MAX}, // DNV South Community 0
	{PID_GPIOCOM1, R_PCH_PCR_GPIO_SC1_PAD_OWN,
	 R_PCH_PCR_GPIO_SC1_HOSTSW_OWN, R_PCH_PCR_GPIO_SC1_GPI_IS,
	 R_PCH_PCR_GPIO_SC1_GPI_IE, R_PCH_PCR_GPIO_SC1_GPI_GPE_STS,
	 R_PCH_PCR_GPIO_SC1_GPI_GPE_EN, R_PCH_PCR_GPIO_SC1_SMI_STS,
	 R_PCH_PCR_GPIO_SC1_SMI_EN, R_PCH_PCR_GPIO_SC1_NMI_STS,
	 R_PCH_PCR_GPIO_SC1_NMI_EN, R_PCH_PCR_GPIO_SC1_PADCFGLOCK,
	 R_PCH_PCR_GPIO_SC1_PADCFGLOCKTX, R_PCH_PCR_GPIO_SC1_PADCFG_OFFSET,
	 V_PCH_GPIO_SC1_PAD_MAX}, // DNV South Community 1
};

/* Retrieve address and length of GPIO info table */
static struct GPIO_GROUP_INFO *
GpioGetGroupInfoTable(uint32_t *GpioGroupInfoTableLength)
{
	*GpioGroupInfoTableLength = ARRAY_SIZE(mGpioGroupInfo);
	return (struct GPIO_GROUP_INFO *)mGpioGroupInfo;
}

/* Get Gpio Pad Ownership */
static void GpioGetPadOwnership(GPIO_PAD GpioPad, GPIO_PAD_OWN *PadOwnVal)
{
	uint32_t Mask;
	uint32_t RegOffset;
	uint32_t GroupIndex;
	uint32_t PadNumber;
	struct GPIO_GROUP_INFO *GpioGroupInfo;
	uint32_t GpioGroupInfoLength;
	uint32_t PadOwnRegValue;

	GroupIndex = GPIO_GET_GROUP_INDEX_FROM_PAD(GpioPad);
	PadNumber = GPIO_GET_PAD_NUMBER(GpioPad);

	GpioGroupInfo = GpioGetGroupInfoTable(&GpioGroupInfoLength);

	//
	// Check if group argument exceeds GPIO GROUP INFO array
	//
	if ((uint32_t)GroupIndex >= GpioGroupInfoLength) {
		printk(BIOS_ERR, "GPIO ERROR: Group argument (%d) exceeds GPIO "
				 "group range\n",
		       GroupIndex);
		return;
	}

	//
	// Check if legal pin number
	//
	if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) {
		printk(BIOS_ERR, "GPIO ERROR: Pin number (%d) exceeds possible "
				 "range for this group\n",
		       PadNumber);
		return;
	}
	//
	// Calculate RegOffset using Pad Ownership offset and GPIO Pad number.
	// One DWord register contains information for 8 pads.
	//
	RegOffset =
		GpioGroupInfo[GroupIndex].PadOwnOffset + (PadNumber >> 3) * 0x4;

	//
	// Calculate pad bit position within DWord register
	//
	PadNumber %= 8;
	Mask = ((1 << 1) | (1 << 0)) << (PadNumber * 4);

	PadOwnRegValue = read32((void *)PCH_PCR_ADDRESS(
		GpioGroupInfo[GroupIndex].Community, RegOffset));

	*PadOwnVal = (GPIO_PAD_OWN)((PadOwnRegValue & Mask) >> (PadNumber * 4));
}

void gpio_configure_dnv_pads(const struct dnv_pad_config *gpio, size_t num)
{
	/* Return if gpio not valid */
	if ((gpio == NULL) || (num == 0))
		return;

	uint32_t Index;
	uint32_t Dw0Reg;
	uint32_t Dw0RegMask;
	uint32_t Dw1Reg;
	uint32_t Dw1RegMask;
	uint32_t PadCfgReg;
	uint64_t HostSoftOwnReg[V_PCH_GPIO_GROUP_MAX];
	uint64_t HostSoftOwnRegMask[V_PCH_GPIO_GROUP_MAX];
	uint64_t GpiGpeEnReg[V_PCH_GPIO_GROUP_MAX];
	uint64_t GpiGpeEnRegMask[V_PCH_GPIO_GROUP_MAX];
	struct GPIO_GROUP_INFO *GpioGroupInfo;
	uint32_t GpioGroupInfoLength;
	GPIO_PAD GpioGroupOffset;
	uint32_t NumberOfGroups;
	GPIO_PAD_OWN PadOwnVal;
	struct dnv_pad_config *GpioData;
	GPIO_PAD Group;
	uint32_t GroupIndex;
	uint32_t PadNumber;
	uint32_t FinalValue;
	uint32_t Data32;
	uint32_t PadMode1, PadMode2;

	PadOwnVal = GpioPadOwnHost;

	memset(HostSoftOwnReg, 0, sizeof(HostSoftOwnReg));
	memset(HostSoftOwnRegMask, 0, sizeof(HostSoftOwnRegMask));
	memset(GpiGpeEnReg, 0, sizeof(GpiGpeEnReg));
	memset(GpiGpeEnRegMask, 0, sizeof(GpiGpeEnRegMask));

	GpioGroupInfo = GpioGetGroupInfoTable(&GpioGroupInfoLength);

	GpioGroupOffset = GPIO_DNV_GROUP_MIN;
	NumberOfGroups = V_PCH_GPIO_GROUP_MAX;

	for (Index = 0; Index < (uint32_t)num; Index++) {
		Dw0RegMask = 0;
		Dw0Reg = 0;
		Dw1RegMask = 0;
		Dw1Reg = 0;

		GpioData = (struct dnv_pad_config *)&(gpio[Index]);

		Group = GPIO_GET_GROUP_FROM_PAD(GpioData->GpioPad);
		GroupIndex = GPIO_GET_GROUP_INDEX_FROM_PAD(GpioData->GpioPad);
		PadNumber = GPIO_GET_PAD_NUMBER(GpioData->GpioPad);

		//
		// Check if group index argument exceeds GPIO group index range
		//
		if (GroupIndex >= V_PCH_GPIO_GROUP_MAX) {
			printk(BIOS_ERR, "GPIO ERROR: Invalid Group Index "
					 "(GroupIndex=%d, Pad=%d)!\n",
			       GroupIndex, PadNumber);
			continue;
		}

		//
		// Check if group argument exceeds GPIO group range
		//
		if ((Group < GpioGroupOffset) ||
		    (Group >= NumberOfGroups + GpioGroupOffset)) {
			printk(BIOS_ERR,
			       "GPIO ERROR: Invalid Group (Group=%d)!\n",
			       Group);
			return;
		}

		//
		// Check if legal pin number
		//
		if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) {
			printk(BIOS_ERR, "GPIO ERROR: Invalid PadNumber "
					 "(PadNumber=%d)!\n",
			       PadNumber);
			return;
		}

		//
		// Check if selected GPIO Pad is not owned by CSME/ISH
		//
		GpioGetPadOwnership(GpioData->GpioPad, &PadOwnVal);

		if (PadOwnVal != GpioPadOwnHost) {
			printk(BIOS_ERR, "GPIO WARNING: Accessing pad not "
					 "owned by host (Group=%d, Pad=%d)!",
			       GroupIndex, PadNumber);
			if (PadOwnVal == GpioPadOwnCsme)
				printk(BIOS_ERR, "The owner is CSME\n");
			else if (PadOwnVal == GpioPadOwnIsh)
				printk(BIOS_ERR, "The owner is ISH\n");
			printk(BIOS_ERR, "** Please make sure the GPIO usage "
					 "in sync between CSME/ISH and Host IA "
					 "FW configuration.\n");
			printk(BIOS_ERR, "** All the GPIO occupied by CSME/ISH "
					 "should not do any configuration by "
					 "Host IA FW.\n");
			continue;
		}

		//
		// Configure Reset Type (PadRstCfg)
		//
		Dw0RegMask |=
			((((GpioData->GpioConfig.PowerConfig &
			    GPIO_CONF_RESET_MASK) >>
			   GPIO_CONF_RESET_BIT_POS) == GpioHardwareDefault)
				 ? 0x0
				 : B_PCH_GPIO_RST_CONF);
		Dw0Reg |= (((GpioData->GpioConfig.PowerConfig &
			     GPIO_CONF_RESET_MASK) >>
			    (GPIO_CONF_RESET_BIT_POS + 1))
			   << N_PCH_GPIO_RST_CONF);

		//
		// Configure how interrupt is triggered (RxEvCfg)
		//
		Dw0RegMask |=
			((((GpioData->GpioConfig.InterruptConfig &
			    GPIO_CONF_INT_TRIG_MASK) >>
			   GPIO_CONF_INT_TRIG_BIT_POS) == GpioHardwareDefault)
				 ? 0x0
				 : B_PCH_GPIO_RX_LVL_EDG);
		Dw0Reg |= (((GpioData->GpioConfig.InterruptConfig &
			     GPIO_CONF_INT_TRIG_MASK) >>
			    (GPIO_CONF_INT_TRIG_BIT_POS + 1))
			   << N_PCH_GPIO_RX_LVL_EDG);

		//
		// Configure interrupt generation (GPIRoutIOxAPIC/SCI/SMI/NMI)
		//
		Dw0RegMask |=
			((((GpioData->GpioConfig.InterruptConfig &
			    GPIO_CONF_INT_ROUTE_MASK) >>
			   GPIO_CONF_INT_ROUTE_BIT_POS) == GpioHardwareDefault)
				 ? 0x0
				 : (B_PCH_GPIO_RX_NMI_ROUTE |
				    B_PCH_GPIO_RX_SCI_ROUTE |
				    B_PCH_GPIO_RX_SMI_ROUTE |
				    B_PCH_GPIO_RX_APIC_ROUTE));
		Dw0Reg |= (((GpioData->GpioConfig.InterruptConfig &
			     GPIO_CONF_INT_ROUTE_MASK) >>
			    (GPIO_CONF_INT_ROUTE_BIT_POS + 1))
			   << N_PCH_GPIO_RX_NMI_ROUTE);

		// If CFIO is not Working as GPIO mode, Don't move TxDisable and
		// RxDisable
		if (GpioData->GpioConfig.PadMode == GpioPadModeGpio) {
			//
			// Configure GPIO direction (GPIORxDis and GPIOTxDis)
			//
			Dw0RegMask |= ((((GpioData->GpioConfig.Direction &
					  GPIO_CONF_DIR_MASK) >>
					 GPIO_CONF_DIR_BIT_POS) ==
					GpioHardwareDefault)
					       ? 0x0
					       : (B_PCH_GPIO_RXDIS |
						  B_PCH_GPIO_TXDIS));
			Dw0Reg |= (((GpioData->GpioConfig.Direction &
				     GPIO_CONF_DIR_MASK) >>
				    (GPIO_CONF_DIR_BIT_POS + 1))
				   << N_PCH_GPIO_TXDIS);
		}

		//
		// Configure GPIO input inversion (RXINV)
		//
		Dw0RegMask |= ((((GpioData->GpioConfig.Direction &
				  GPIO_CONF_INV_MASK) >>
				 GPIO_CONF_INV_BIT_POS) == GpioHardwareDefault)
				       ? 0x0
				       : B_PCH_GPIO_RXINV);
		Dw0Reg |= (((GpioData->GpioConfig.Direction &
			     GPIO_CONF_INV_MASK) >>
			    (GPIO_CONF_INV_BIT_POS + 1))
			   << N_PCH_GPIO_RXINV);

		//
		// Configure GPIO output state (GPIOTxState)
		//
		Dw0RegMask |=
			((((GpioData->GpioConfig.OutputState &
			    GPIO_CONF_OUTPUT_MASK) >>
			   GPIO_CONF_OUTPUT_BIT_POS) == GpioHardwareDefault)
				 ? 0x0
				 : B_PCH_GPIO_TX_STATE);
		Dw0Reg |= (((GpioData->GpioConfig.OutputState &
			     GPIO_CONF_OUTPUT_MASK) >>
			    (GPIO_CONF_OUTPUT_BIT_POS + 1))
			   << N_PCH_GPIO_TX_STATE);

		//
		// Configure GPIO RX raw override to '1' (RXRAW1)
		//
		Dw0RegMask |=
			((((GpioData->GpioConfig.OtherSettings &
			    GPIO_CONF_RXRAW_MASK) >>
			   GPIO_CONF_RXRAW_BIT_POS) == GpioHardwareDefault)
				 ? 0x0
				 : B_PCH_GPIO_RX_RAW1);
		Dw0Reg |= (((GpioData->GpioConfig.OtherSettings &
			     GPIO_CONF_RXRAW_MASK) >>
			    (GPIO_CONF_RXRAW_BIT_POS + 1))
			   << N_PCH_GPIO_RX_RAW1);

		//
		// Configure GPIO Pad Mode (PMode)
		//
		Dw0RegMask |=
			((((GpioData->GpioConfig.PadMode &
			    GPIO_CONF_PAD_MODE_MASK) >>
			   GPIO_CONF_PAD_MODE_BIT_POS) == GpioHardwareDefault)
				 ? 0x0
				 : B_PCH_GPIO_PAD_MODE);
		Dw0Reg |= (((GpioData->GpioConfig.PadMode &
			     GPIO_CONF_PAD_MODE_MASK) >>
			    (GPIO_CONF_PAD_MODE_BIT_POS + 1))
			   << N_PCH_GPIO_PAD_MODE);

		//
		// Configure GPIO termination (Term)
		//
		Dw1RegMask |= ((((GpioData->GpioConfig.ElectricalConfig &
				  GPIO_CONF_TERM_MASK) >>
				 GPIO_CONF_TERM_BIT_POS) == GpioHardwareDefault)
				       ? 0x0
				       : B_PCH_GPIO_TERM);
		Dw1Reg |= (((GpioData->GpioConfig.ElectricalConfig &
			     GPIO_CONF_TERM_MASK) >>
			    (GPIO_CONF_TERM_BIT_POS + 1))
			   << N_PCH_GPIO_TERM);

		//
		// Configure GPIO pad tolerance (padtol)
		//
		Dw1RegMask |=
			((((GpioData->GpioConfig.ElectricalConfig &
			    GPIO_CONF_PADTOL_MASK) >>
			   GPIO_CONF_PADTOL_BIT_POS) == GpioHardwareDefault)
				 ? 0x0
				 : B_PCH_GPIO_PADTOL);
		Dw1Reg |= (((GpioData->GpioConfig.ElectricalConfig &
			     GPIO_CONF_PADTOL_MASK) >>
			    (GPIO_CONF_PADTOL_BIT_POS + 1))
			   << N_PCH_GPIO_PADTOL);

		//
		// Check for additional requirements on setting PADCFG register
		//

		//
		// Create PADCFG register offset using group and pad number
		//
		PadCfgReg = 0x8 * PadNumber +
			    GpioGroupInfo[GroupIndex].PadCfgOffset;
		Data32 = read32((void *)PCH_PCR_ADDRESS(
			GpioGroupInfo[GroupIndex].Community, PadCfgReg));

		FinalValue = ((Data32 & (~Dw0RegMask)) | Dw0Reg);

		PadMode1 =
			(Data32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE;
		PadMode2 =
			(Dw0Reg & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE;

		if (((Data32 & B_PCH_GPIO_PAD_MODE) !=
		     (FinalValue & B_PCH_GPIO_PAD_MODE)) ||
		    (PadMode2 == 0)) {
			printk(BIOS_DEBUG, "Changing GpioPad PID: %x Offset: "
					   "0x%x PadModeP1: %d P2: %d ",
			       GpioGroupInfo[GroupIndex].Community, PadCfgReg,
			       PadMode1, PadMode2);
			printk(BIOS_DEBUG, "R: 0x%08x Fx%08x !\n", Data32,
			       FinalValue);
			//
			// Write PADCFG DW0 register``
			//
			mmio_andthenor32(
				(void *)(uint32_t)PCH_PCR_ADDRESS(
					GpioGroupInfo[GroupIndex].Community,
					PadCfgReg),
				~(uint32_t)Dw0RegMask, (uint32_t)Dw0Reg);
		}

		Data32 = read32((void *)PCH_PCR_ADDRESS(
			GpioGroupInfo[GroupIndex].Community, PadCfgReg + 0x4));
		FinalValue = ((Data32 & (~Dw1RegMask)) | Dw1Reg);
		if (Data32 != FinalValue) {
			//
			// Write PADCFG DW1 register
			//
			mmio_andthenor32(
				(void *)(uint32_t)PCH_PCR_ADDRESS(
					GpioGroupInfo[GroupIndex].Community,
					PadCfgReg + 0x4),
				~(uint32_t)Dw1RegMask, (uint32_t)Dw1Reg);
		}

		//
		// Update value to be programmed in HOSTSW_OWN register
		//
		HostSoftOwnRegMask[GroupIndex] |=
			((uint64_t)GpioData->GpioConfig.HostSoftPadOwn & 0x1) << PadNumber;
		HostSoftOwnReg[GroupIndex] |=
			((uint64_t)GpioData->GpioConfig.HostSoftPadOwn >> 0x1) << PadNumber;

		//
		// Update value to be programmed in GPI_GPE_EN register
		//
		GpiGpeEnRegMask[GroupIndex] |=
			((uint64_t)GpioData->GpioConfig.InterruptConfig & 0x1) << PadNumber;
		GpiGpeEnReg[GroupIndex] |=
			(((uint64_t)GpioData->GpioConfig.InterruptConfig & GpioIntSci) >> 3)
			<< PadNumber;
	}

	for (Index = 0; Index < NumberOfGroups; Index++) {
		//
		// Write HOSTSW_OWN registers
		//
		if (GpioGroupInfo[Index].HostOwnOffset !=
		    NO_REGISTER_FOR_PROPERTY) {
			mmio_andthenor32(
				(void *)PCH_PCR_ADDRESS(
					GpioGroupInfo[Index].Community,
					GpioGroupInfo[Index].HostOwnOffset),
				~(uint32_t)(HostSoftOwnRegMask[Index] &
					    0xFFFFFFFF),
				(uint32_t)(HostSoftOwnReg[Index] & 0xFFFFFFFF));
			mmio_andthenor32(
				(void *)PCH_PCR_ADDRESS(
					GpioGroupInfo[Index].Community,
					GpioGroupInfo[Index].HostOwnOffset +
						0x4),
				~(uint32_t)(HostSoftOwnRegMask[Index] >> 32),
				(uint32_t)(HostSoftOwnReg[Index] >> 32));
		}

		//
		// Write GPI_GPE_EN registers
		//
		if (GpioGroupInfo[Index].GpiGpeEnOffset !=
		    NO_REGISTER_FOR_PROPERTY) {
			mmio_andthenor32(
				(void *)PCH_PCR_ADDRESS(
					GpioGroupInfo[Index].Community,
					GpioGroupInfo[Index].GpiGpeEnOffset),
				~(uint32_t)(GpiGpeEnRegMask[Index] &
					    0xFFFFFFFF),
				(uint32_t)(GpiGpeEnReg[Index] & 0xFFFFFFFF));
			mmio_andthenor32(
				(void *)PCH_PCR_ADDRESS(
					GpioGroupInfo[Index].Community,
					GpioGroupInfo[Index].GpiGpeEnOffset +
						0x4),
				~(uint32_t)(GpiGpeEnRegMask[Index] >> 32),
				(uint32_t)(GpiGpeEnReg[Index] >> 32));
		}
	}
}
