/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2013 Google Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <stdint.h>
#include <stdlib.h>
#include <arch/hlt.h>
#include <arch/io.h>
#include <console/console.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/smm.h>
#include <device/pci_def.h>
#include <elog.h>
#include <spi-generic.h>

#include <baytrail/iosf.h>
#include <baytrail/pci_devs.h>
#include <baytrail/pmc.h>
#include <baytrail/nvs.h>

/* GNVS needs to be set by coreboot initiating a software SMI. */
static global_nvs_t *gnvs;
static int smm_initialized;

int southbridge_io_trap_handler(int smif)
{
	switch (smif) {
	case 0x32:
		printk(BIOS_DEBUG, "OS Init\n");
		/* gnvs->smif:
		 *  On success, the IO Trap Handler returns 0
		 *  On failure, the IO Trap Handler returns a value != 0
		 */
		gnvs->smif = 0;
		return 1; /* IO trap handled */
	}

	/* Not handled */
	return 0;
}

void southbridge_smi_set_eos(void)
{
	enable_smi(EOS);
}

global_nvs_t *smm_get_gnvs(void)
{
	return gnvs;
}

static void busmaster_disable_on_bus(int bus)
{
	int slot, func;
	unsigned int val;
	unsigned char hdr;

	for (slot = 0; slot < 0x20; slot++) {
		for (func = 0; func < 8; func++) {
			u32 reg32;
			device_t dev = PCI_DEV(bus, slot, func);

			val = pci_read_config32(dev, PCI_VENDOR_ID);

			if (val == 0xffffffff || val == 0x00000000 ||
			    val == 0x0000ffff || val == 0xffff0000)
				continue;

			/* Disable Bus Mastering for this one device */
			reg32 = pci_read_config32(dev, PCI_COMMAND);
			reg32 &= ~PCI_COMMAND_MASTER;
			pci_write_config32(dev, PCI_COMMAND, reg32);

			/* If this is a bridge, then follow it. */
			hdr = pci_read_config8(dev, PCI_HEADER_TYPE);
			hdr &= 0x7f;
			if (hdr == PCI_HEADER_TYPE_BRIDGE ||
			    hdr == PCI_HEADER_TYPE_CARDBUS) {
				unsigned int buses;
				buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
				busmaster_disable_on_bus((buses >> 8) & 0xff);
			}
		}
	}
}

static void southbridge_smi_sleep(void)
{
	uint32_t reg32;
	uint8_t slp_typ;
	uint16_t pmbase = get_pmbase();

	/* First, disable further SMIs */
	disable_smi(SLP_SMI_EN);

	/* Figure out SLP_TYP */
	reg32 = inl(pmbase + PM1_CNT);
	printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", reg32);
	slp_typ = (reg32 >> 10) & 7;

	/* Do any mainboard sleep handling */
	mainboard_smi_sleep(slp_typ-2);

#if CONFIG_ELOG_GSMI
	/* Log S3, S4, and S5 entry */
	if (slp_typ >= 5)
		elog_add_event_byte(ELOG_TYPE_ACPI_ENTER, slp_typ-2);
#endif

	/* Next, do the deed.
	 */

	switch (slp_typ) {
	case SLP_TYP_S0:
		printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n");
		break;
	case SLP_TYP_S1:
		printk(BIOS_DEBUG, "SMI#: Entering S1 (Assert STPCLK#)\n");
		break;
	case SLP_TYP_S3:
		printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n");

		/* Invalidate the cache before going to S3 */
		wbinvd();
		break;
	case SLP_TYP_S4:
		printk(BIOS_DEBUG, "SMI#: Entering S4 (Suspend-To-Disk)\n");
		break;
	case SLP_TYP_S5:
		printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n");

		/* Disable all GPE */
		disable_all_gpe();

		/* also iterates over all bridges on bus 0 */
		busmaster_disable_on_bus(0);
		break;
	default:
		printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n");
		break;
	}

	/* Write back to the SLP register to cause the originally intended
	 * event again. We need to set BIT13 (SLP_EN) though to make the
	 * sleep happen.
	 */
	enable_pm1_control(SLP_EN);

	/* Make sure to stop executing code here for S3/S4/S5 */
	if (slp_typ > 1)
		hlt();

	/* In most sleep states, the code flow of this function ends at
	 * the line above. However, if we entered sleep state S1 and wake
	 * up again, we will continue to execute code in this function.
	 */
	reg32 = inl(pmbase + PM1_CNT);
	if (reg32 & SCI_EN) {
		/* The OS is not an ACPI OS, so we set the state to S0 */
		disable_pm1_control(SLP_EN | SLP_TYP);
	}
}

/*
 * Look for Synchronous IO SMI and use save state from that
 * core in case we are not running on the same core that
 * initiated the IO transaction.
 */
static em64t100_smm_state_save_area_t *smi_apmc_find_state_save(uint8_t cmd)
{
	em64t100_smm_state_save_area_t *state;
	int node;

	/* Check all nodes looking for the one that issued the IO */
	for (node = 0; node < CONFIG_MAX_CPUS; node++) {
		state = smm_get_save_state(node);

		/* Check for Synchronous IO (bit0==1) */
		if (!(state->io_misc_info & (1 << 0)))
			continue;

		/* Make sure it was a write (bit4==0) */
		if (state->io_misc_info & (1 << 4))
			continue;

		/* Check for APMC IO port */
		if (((state->io_misc_info >> 16) & 0xff) != APM_CNT)
			continue;

		/* Check AX against the requested command */
		if ((state->rax & 0xff) != cmd)
			continue;

		return state;
	}

	return NULL;
}

#if CONFIG_ELOG_GSMI
static void southbridge_smi_gsmi(void)
{
	u32 *ret, *param;
	uint8_t sub_command;
	em64t100_smm_state_save_area_t *io_smi =
		smi_apmc_find_state_save(ELOG_GSMI_APM_CNT);

	if (!io_smi)
		return;

	/* Command and return value in EAX */
	ret = (u32*)&io_smi->rax;
	sub_command = (uint8_t)(*ret >> 8);

	/* Parameter buffer in EBX */
	param = (u32*)&io_smi->rbx;

	/* drivers/elog/gsmi.c */
	*ret = gsmi_exec(sub_command, param);
}
#endif

static void finalize(void)
{
	static int finalize_done;

	if (finalize_done) {
		printk(BIOS_DEBUG, "SMM already finalized.\n");
		return;
	}
	finalize_done = 1;

#if CONFIG_SPI_FLASH_SMM
	/* Re-init SPI driver to handle locked BAR */
	spi_init();
#endif
}

/*
 * soc_legacy: A payload (Depthcharge) has indicated that the
 *   legacy payload (SeaBIOS) is being loaded. Switch devices that are
 *   in ACPI mode to PCI mode so that non-ACPI drivers may work.
 *
 */
static void soc_legacy(void)
{
	u32 reg32;

	/* LPE Device */
	 if (gnvs->dev.lpe_en) {
		reg32 = iosf_port58_read(LPE_PCICFGCTR1);
		reg32 &=
		~(LPE_PCICFGCTR1_PCI_CFG_DIS | LPE_PCICFGCTR1_ACPI_INT_EN);
		iosf_port58_write(LPE_PCICFGCTR1, reg32);
	}

	/* SCC Devices */
#define SCC_ACPI_MODE_DISABLE(name_) \
	do { if (gnvs->dev.scc_en[SCC_NVS_ ## name_]) { \
		reg32 = iosf_scc_read(SCC_ ## name_ ## _CTL); \
		reg32 &= ~(SCC_CTL_PCI_CFG_DIS | SCC_CTL_ACPI_INT_EN); \
		iosf_scc_write(SCC_ ## name_ ## _CTL, reg32); \
	} } while (0)

	SCC_ACPI_MODE_DISABLE(MMC);
	SCC_ACPI_MODE_DISABLE(SD);
	SCC_ACPI_MODE_DISABLE(SDIO);

	 /* LPSS Devices */
#define LPSS_ACPI_MODE_DISABLE(name_) \
	do { if (gnvs->dev.lpss_en[LPSS_NVS_ ## name_]) { \
		reg32 = iosf_lpss_read(LPSS_ ## name_ ## _CTL); \
		reg32 &= ~LPSS_CTL_PCI_CFG_DIS | ~LPSS_CTL_ACPI_INT_EN; \
		iosf_lpss_write(LPSS_ ## name_ ## _CTL, reg32); \
	} } while (0)

	LPSS_ACPI_MODE_DISABLE(SIO_DMA1);
	LPSS_ACPI_MODE_DISABLE(I2C1);
	LPSS_ACPI_MODE_DISABLE(I2C2);
	LPSS_ACPI_MODE_DISABLE(I2C3);
	LPSS_ACPI_MODE_DISABLE(I2C4);
	LPSS_ACPI_MODE_DISABLE(I2C5);
	LPSS_ACPI_MODE_DISABLE(I2C6);
	LPSS_ACPI_MODE_DISABLE(I2C7);
	LPSS_ACPI_MODE_DISABLE(SIO_DMA2);
	LPSS_ACPI_MODE_DISABLE(PWM1);
	LPSS_ACPI_MODE_DISABLE(PWM2);
	LPSS_ACPI_MODE_DISABLE(HSUART1);
	LPSS_ACPI_MODE_DISABLE(HSUART2);
	LPSS_ACPI_MODE_DISABLE(SPI);
}

static void southbridge_smi_apmc(void)
{
	uint8_t reg8;
	em64t100_smm_state_save_area_t *state;

	/* Emulate B2 register as the FADT / Linux expects it */

	reg8 = inb(APM_CNT);
	switch (reg8) {
	case APM_CNT_CST_CONTROL:
		/* Calling this function seems to cause
		 * some kind of race condition in Linux
		 * and causes a kernel oops
		 */
		printk(BIOS_DEBUG, "C-state control\n");
		break;
	case APM_CNT_PST_CONTROL:
		/* Calling this function seems to cause
		 * some kind of race condition in Linux
		 * and causes a kernel oops
		 */
		printk(BIOS_DEBUG, "P-state control\n");
		break;
	case APM_CNT_ACPI_DISABLE:
		disable_pm1_control(SCI_EN);
		printk(BIOS_DEBUG, "SMI#: ACPI disabled.\n");
		break;
	case APM_CNT_ACPI_ENABLE:
		enable_pm1_control(SCI_EN);
		printk(BIOS_DEBUG, "SMI#: ACPI enabled.\n");
		break;
	case APM_CNT_GNVS_UPDATE:
		if (smm_initialized) {
			printk(BIOS_DEBUG,
			       "SMI#: SMM structures already initialized!\n");
			return;
		}
		state = smi_apmc_find_state_save(reg8);
		if (state) {
			/* EBX in the state save contains the GNVS pointer */
			gnvs = (global_nvs_t *)((uint32_t)state->rbx);
			smm_initialized = 1;
			printk(BIOS_DEBUG, "SMI#: Setting GNVS to %p\n", gnvs);
		}
		break;
#if CONFIG_ELOG_GSMI
	case ELOG_GSMI_APM_CNT:
		southbridge_smi_gsmi();
		break;
#endif
	case APM_CNT_FINALIZE:
		finalize();
		break;

	case APM_CNT_LEGACY:
		soc_legacy();
		break;
	}

	mainboard_smi_apmc(reg8);
}

static void southbridge_smi_pm1(void)
{
	uint16_t pm1_sts = clear_pm1_status();

	/* While OSPM is not active, poweroff immediately
	 * on a power button event.
	 */
	if (pm1_sts & PWRBTN_STS) {
		// power button pressed
#if CONFIG_ELOG_GSMI
		elog_add_event(ELOG_TYPE_POWER_BUTTON);
#endif
		disable_pm1_control(-1UL);
		enable_pm1_control(SLP_EN | (SLP_TYP_S5 << SLP_TYP_SHIFT));
	}
}

static void southbridge_smi_gpe0(void)
{
	clear_gpe_status();
}

static void southbridge_smi_tco(void)
{
	uint32_t tco_sts = clear_tco_status();

	/* Any TCO event? */
	if (!tco_sts)
		return;

	if (tco_sts & TCO_TIMEOUT) { /* TIMEOUT */
		/* Handle TCO timeout */
		printk(BIOS_DEBUG, "TCO Timeout.\n");
	}
}

static void southbridge_smi_periodic(void)
{
	uint32_t reg32;

	reg32 = inl(get_pmbase() + SMI_EN);

	/* Are periodic SMIs enabled? */
	if ((reg32 & PERIODIC_EN) == 0)
		return;

	printk(BIOS_DEBUG, "Periodic SMI.\n");
}

typedef void (*smi_handler_t)(void);

static const smi_handler_t southbridge_smi[32] = {
	NULL,			  //  [0] reserved
	NULL,			  //  [1] reserved
	NULL,			  //  [2] BIOS_STS
	NULL,			  //  [3] LEGACY_USB_STS
	southbridge_smi_sleep,	  //  [4] SLP_SMI_STS
	southbridge_smi_apmc,	  //  [5] APM_STS
	NULL,			  //  [6] SWSMI_TMR_STS
	NULL,			  //  [7] reserved
	southbridge_smi_pm1,	  //  [8] PM1_STS
	southbridge_smi_gpe0,	  //  [9] GPE0_STS
	NULL,			  // [10] reserved
	NULL,			  // [11] reserved
	NULL,			  // [12] reserved
	southbridge_smi_tco,	  // [13] TCO_STS
	southbridge_smi_periodic, // [14] PERIODIC_STS
	NULL,			  // [15] SERIRQ_SMI_STS
	NULL,			  // [16] SMBUS_SMI_STS
	NULL,			  // [17] LEGACY_USB2_STS
	NULL,			  // [18] INTEL_USB2_STS
	NULL,			  // [19] reserved
	NULL,			  // [20] PCI_EXP_SMI_STS
	NULL,			  // [21] reserved
	NULL,			  // [22] reserved
	NULL,			  // [23] reserved
	NULL,			  // [24] reserved
	NULL,			  // [25] reserved
	NULL,			  // [26] SPI_STS
	NULL,			  // [27] reserved
	NULL,			  // [28] PUNIT
	NULL,			  // [29] GUNIT
	NULL,			  // [30] reserved
	NULL			  // [31] reserved
};

void southbridge_smi_handler(void)
{
	int i;
	uint32_t smi_sts;

	/* We need to clear the SMI status registers, or we won't see what's
	 * happening in the following calls.
	 */
	smi_sts = clear_smi_status();

	/* Call SMI sub handler for each of the status bits */
	for (i = 0; i < ARRAY_SIZE(southbridge_smi); i++) {
		if (!(smi_sts & (1 << i)))
			continue;

		if (southbridge_smi[i] != NULL) {
			southbridge_smi[i]();
		} else {
			printk(BIOS_DEBUG,
			       "SMI_STS[%d] occured, but no "
			       "handler available.\n", i);
		}
	}

	/* The GPIO SMI events do not have a status bit in SMI_STS. Therefore,
	 * these events need to be cleared and checked unconditionally. */
	mainboard_smi_gpi(clear_alt_status());
}
