// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2017 Intel Corporation.
 * Copyright 2019 Google LLC
 *
 * Modified from coreboot pmclib.c, pmc.c and pmutil.c
 */

#define LOG_CATEGORY UCLASS_ACPI_PMC

#include <common.h>
#include <dt-structs.h>
#include <dm.h>
#include <log.h>
#include <spl.h>
#include <acpi/acpi_s3.h>
#include <asm/io.h>
#include <asm/pci.h>
#include <power/acpi_pmc.h>

#define GPIO_GPE_CFG		0x1050

/* Memory mapped IO registers behind PMC_BASE_ADDRESS */
#define PRSTS			0x1000
#define GEN_PMCON1		0x1020
#define  COLD_BOOT_STS		BIT(27)
#define  COLD_RESET_STS		BIT(26)
#define  WARM_RESET_STS		BIT(25)
#define  GLOBAL_RESET_STS	BIT(24)
#define  SRS			BIT(20)
#define  MS4V			BIT(18)
#define  RPS			BIT(2)
#define GEN_PMCON1_CLR1_BITS	(COLD_BOOT_STS | COLD_RESET_STS | \
				 WARM_RESET_STS | GLOBAL_RESET_STS | \
				 SRS | MS4V)
#define GEN_PMCON2		0x1024
#define GEN_PMCON3		0x1028

/* Offset of TCO registers from ACPI base I/O address */
#define TCO_REG_OFFSET		0x60
#define TCO1_STS	0x64
#define   DMISCI_STS	BIT(9)
#define   BOOT_STS	BIT(18)
#define TCO2_STS	0x66
#define TCO1_CNT	0x68
#define   TCO_LOCK	BIT(12)
#define TCO2_CNT	0x6a

enum {
	ETR		= 0x1048,
	CF9_LOCK        = 1UL << 31,
	CF9_GLB_RST	= 1 << 20,
};

struct apl_pmc_platdata {
#if CONFIG_IS_ENABLED(OF_PLATDATA)
	struct dtd_intel_apl_pmc dtplat;
#endif
	pci_dev_t bdf;
};

static int apl_pmc_fill_power_state(struct udevice *dev)
{
	struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev);

	upriv->tco1_sts = inw(upriv->acpi_base + TCO1_STS);
	upriv->tco2_sts = inw(upriv->acpi_base + TCO2_STS);

	upriv->prsts = readl(upriv->pmc_bar0 + PRSTS);
	upriv->gen_pmcon1 = readl(upriv->pmc_bar0 + GEN_PMCON1);
	upriv->gen_pmcon2 = readl(upriv->pmc_bar0 + GEN_PMCON2);
	upriv->gen_pmcon3 = readl(upriv->pmc_bar0 + GEN_PMCON3);

	return 0;
}

static int apl_prev_sleep_state(struct udevice *dev, int prev_sleep_state)
{
	struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev);

	/* WAK_STS bit will not be set when waking from G3 state */
	if (!(upriv->pm1_sts & WAK_STS) &&
	    (upriv->gen_pmcon1 & COLD_BOOT_STS))
		prev_sleep_state = ACPI_S5;

	return prev_sleep_state;
}

static int apl_disable_tco(struct udevice *dev)
{
	struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev);

	pmc_disable_tco_base(upriv->acpi_base + TCO_REG_OFFSET);

	return 0;
}

static int apl_global_reset_set_enable(struct udevice *dev, bool enable)
{
	struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev);

	if (enable)
		setbits_le32(upriv->pmc_bar0 + ETR, CF9_GLB_RST);
	else
		clrbits_le32(upriv->pmc_bar0 + ETR, CF9_GLB_RST);

	return 0;
}

int apl_pmc_ofdata_to_uc_platdata(struct udevice *dev)
{
	struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev);
	struct apl_pmc_platdata *plat = dev_get_platdata(dev);

#if !CONFIG_IS_ENABLED(OF_PLATDATA)
	u32 base[6];
	int size;
	int ret;

	ret = dev_read_u32_array(dev, "early-regs", base, ARRAY_SIZE(base));
	if (ret)
		return log_msg_ret("Missing/short early-regs", ret);
	if (spl_phase() == PHASE_TPL) {
		upriv->pmc_bar0 = (void *)base[0];
		upriv->pmc_bar2 = (void *)base[2];

		/* Since PCI is not enabled, we must get the BDF manually */
		plat->bdf = pci_get_devfn(dev);
		if (plat->bdf < 0)
			return log_msg_ret("Cannot get PMC PCI address",
					   plat->bdf);
	}
	upriv->acpi_base = base[4];

	/* Since PCI is not enabled, we must get the BDF manually */
	plat->bdf = pci_get_devfn(dev);
	if (plat->bdf < 0)
		return log_msg_ret("Cannot get PMC PCI address", plat->bdf);

	/* Get the dwX values for pmc gpe settings */
	size = dev_read_size(dev, "gpe0-dw");
	if (size < 0)
		return log_msg_ret("Cannot read gpe0-dm", size);
	upriv->gpe0_count = size / sizeof(u32);
	ret = dev_read_u32_array(dev, "gpe0-dw", upriv->gpe0_dw,
				 upriv->gpe0_count);
	if (ret)
		return log_msg_ret("Bad gpe0-dw", ret);

	return pmc_ofdata_to_uc_platdata(dev);
#else
	struct dtd_intel_apl_pmc *dtplat = &plat->dtplat;

	plat->bdf = pci_ofplat_get_devfn(dtplat->reg[0]);
	upriv->pmc_bar0 = (void *)dtplat->early_regs[0];
	upriv->pmc_bar2 = (void *)dtplat->early_regs[2];
	upriv->acpi_base = dtplat->early_regs[4];
	upriv->gpe0_dwx_mask = dtplat->gpe0_dwx_mask;
	upriv->gpe0_dwx_shift_base = dtplat->gpe0_dwx_shift_base;
	upriv->gpe0_sts_reg = dtplat->gpe0_sts;
	upriv->gpe0_sts_reg += upriv->acpi_base;
	upriv->gpe0_en_reg = dtplat->gpe0_en;
	upriv->gpe0_en_reg += upriv->acpi_base;
	upriv->gpe0_count = min((int)ARRAY_SIZE(dtplat->gpe0_dw), GPE0_REG_MAX);
	memcpy(upriv->gpe0_dw, dtplat->gpe0_dw, sizeof(dtplat->gpe0_dw));
#endif
	upriv->gpe_cfg = (u32 *)(upriv->pmc_bar0 + GPIO_GPE_CFG);

	return 0;
}

static int enable_pmcbar(struct udevice *dev)
{
	struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev);
	struct apl_pmc_platdata *priv = dev_get_platdata(dev);
	pci_dev_t pmc = priv->bdf;

	/*
	 * Set PMC base addresses and enable decoding. BARs 1 and 3 are 64-bit
	 * BARs.
	 */
	pci_x86_write_config(pmc, PCI_BASE_ADDRESS_0, (ulong)upriv->pmc_bar0,
			     PCI_SIZE_32);
	pci_x86_write_config(pmc, PCI_BASE_ADDRESS_1, 0, PCI_SIZE_32);
	pci_x86_write_config(pmc, PCI_BASE_ADDRESS_2, (ulong)upriv->pmc_bar2,
			     PCI_SIZE_32);
	pci_x86_write_config(pmc, PCI_BASE_ADDRESS_3, 0, PCI_SIZE_32);
	pci_x86_write_config(pmc, PCI_BASE_ADDRESS_4, upriv->acpi_base,
			     PCI_SIZE_16);
	pci_x86_write_config(pmc, PCI_COMMAND, PCI_COMMAND_IO |
			     PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER,
			     PCI_SIZE_16);

	return 0;
}

static int apl_pmc_probe(struct udevice *dev)
{
	if (spl_phase() == PHASE_TPL) {
		return enable_pmcbar(dev);
	} else {
		struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev);

		upriv->pmc_bar0 = (void *)dm_pci_read_bar32(dev, 0);
		upriv->pmc_bar2 = (void *)dm_pci_read_bar32(dev, 2);
	}

	return 0;
}

static struct acpi_pmc_ops apl_pmc_ops = {
	.init			= apl_pmc_fill_power_state,
	.prev_sleep_state	= apl_prev_sleep_state,
	.disable_tco		= apl_disable_tco,
	.global_reset_set_enable = apl_global_reset_set_enable,
};

static const struct udevice_id apl_pmc_ids[] = {
	{ .compatible = "intel,apl-pmc" },
	{ }
};

U_BOOT_DRIVER(apl_pmc) = {
	.name		= "intel_apl_pmc",
	.id		= UCLASS_ACPI_PMC,
	.of_match	= apl_pmc_ids,
	.ofdata_to_platdata = apl_pmc_ofdata_to_uc_platdata,
	.probe		= apl_pmc_probe,
	.ops		= &apl_pmc_ops,
	.platdata_auto_alloc_size = sizeof(struct apl_pmc_platdata),
};
