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

#include <acpi/acpi_pm.h>
#include <device/mmio.h>
#include <device/device.h>
#include <console/console.h>
#include <elog.h>
#include <gpio.h>
#include <amdblocks/acpi.h>
#include <amdblocks/acpimmio.h>
#include <amdblocks/gpio.h>
#include <amdblocks/smi.h>
#include <soc/gpio.h>
#include <soc/smi.h>
#include <assert.h>
#include <string.h>
#include <types.h>

/*
 * acpimmio_gpio0, acpimmio_remote_gpio and acpimmio_iomux are defined in
 * soc/amd/common/block/acpimmio/mmio_util.c and declared as extern variables/constants in
 * amdblocks/acpimmio.h which is included in this file.
 */

/* MMIO access of new-style GPIO bank configuration registers */
static inline void *gpio_ctrl_ptr(gpio_t gpio_num)
{
	if (SOC_GPIO_TOTAL_PINS < AMD_GPIO_FIRST_REMOTE_GPIO_NUMBER ||
			/* Verstage on PSP would need to map acpimmio_remote_gpio */
			(CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK) && ENV_SEPARATE_VERSTAGE) ||
			gpio_num < AMD_GPIO_FIRST_REMOTE_GPIO_NUMBER)
		return acpimmio_gpio0 + gpio_num * sizeof(uint32_t);
	else
		return acpimmio_remote_gpio +
			(gpio_num - AMD_GPIO_FIRST_REMOTE_GPIO_NUMBER) * sizeof(uint32_t);
}

static inline uint32_t gpio_read32(gpio_t gpio_num)
{
	return read32(gpio_ctrl_ptr(gpio_num));
}

static inline void gpio_write32(gpio_t gpio_num, uint32_t value)
{
	write32(gpio_ctrl_ptr(gpio_num), value);
}

static inline void *gpio_mux_ptr(gpio_t gpio_num)
{
	if (SOC_GPIO_TOTAL_PINS < AMD_GPIO_FIRST_REMOTE_GPIO_NUMBER ||
			/* Verstage on PSP would need to map acpimmio_remote_gpio */
			(CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK) && ENV_SEPARATE_VERSTAGE) ||
			gpio_num < AMD_GPIO_FIRST_REMOTE_GPIO_NUMBER)
		return acpimmio_iomux + gpio_num;
	else
		return acpimmio_remote_gpio + AMD_GPIO_REMOTE_GPIO_MUX_OFFSET +
			(gpio_num - AMD_GPIO_FIRST_REMOTE_GPIO_NUMBER);
}

static uint8_t get_gpio_mux(gpio_t gpio_num)
{
	return read8(gpio_mux_ptr(gpio_num));
}

static void set_gpio_mux(gpio_t gpio_num, uint8_t function)
{
	write8(gpio_mux_ptr(gpio_num), function & AMD_GPIO_MUX_MASK);
	get_gpio_mux(gpio_num); /* Flush posted write */
}

static int get_gpio_gevent(gpio_t gpio, const struct soc_amd_event *table,
				size_t items)
{
	size_t i;

	for (i = 0; i < items; i++) {
		if ((table + i)->gpio == gpio)
			return (int)(table + i)->event;
	}
	return -1;
}

static void program_smi(uint32_t flags, unsigned int gevent_num)
{
	uint8_t level;

	if (!is_gpio_event_level_triggered(flags)) {
		printk(BIOS_ERR, "ERROR: %s - Only level trigger allowed for SMI!\n", __func__);
		BUG();
		return;
	}

	if (is_gpio_event_active_high(flags))
		level = SMI_SCI_LVL_HIGH;
	else
		level = SMI_SCI_LVL_LOW;

	configure_gevent_smi(gevent_num, SMI_MODE_SMI, level);
}

/*
 * For each general purpose event, GPE, the choice of edge/level triggered
 * event is represented as a single bit in SMI_SCI_LEVEL register.
 *
 * In a similar fashion, polarity (rising/falling, hi/lo) of each GPE is
 * represented as a single bit in SMI_SCI_TRIG register.
 */
static void program_sci(uint32_t flags, unsigned int gevent_num)
{
	struct sci_source sci;

	sci.scimap = gevent_num;
	sci.gpe = gevent_num;

	if (is_gpio_event_level_triggered(flags))
		sci.level = SMI_SCI_LVL;
	else
		sci.level = SMI_SCI_EDG;

	if (is_gpio_event_active_high(flags))
		sci.direction = SMI_SCI_LVL_HIGH;
	else
		sci.direction = SMI_SCI_LVL_LOW;

	configure_scimap(&sci);
}

static void gpio_update32(gpio_t gpio_num, uint32_t mask, uint32_t or)
{
	uint32_t reg;

	reg = gpio_read32(gpio_num);
	reg &= mask;
	reg |= or;
	gpio_write32(gpio_num, reg);
}

/* Set specified bits of a register to match those of ctrl. */
static void gpio_setbits32(gpio_t gpio_num, uint32_t mask, uint32_t ctrl)
{
	gpio_update32(gpio_num, ~mask, ctrl & mask);
}

static void gpio_and32(gpio_t gpio_num, uint32_t mask)
{
	gpio_update32(gpio_num, mask, 0);
}

static void gpio_or32(gpio_t gpio_num, uint32_t or)
{
	gpio_update32(gpio_num, -1UL, or);
}

static void master_switch_clr(uint32_t mask)
{
	const gpio_t master_reg = GPIO_MASTER_SWITCH / sizeof(uint32_t);
	gpio_and32(master_reg, ~mask);
}

static void master_switch_set(uint32_t or)
{
	const gpio_t master_reg = GPIO_MASTER_SWITCH / sizeof(uint32_t);
	gpio_or32(master_reg, or);
}

int gpio_get(gpio_t gpio_num)
{
	uint32_t reg;

	reg = gpio_read32(gpio_num);
	return !!(reg & GPIO_PIN_STS);
}

void gpio_set(gpio_t gpio_num, int value)
{
	gpio_setbits32(gpio_num, GPIO_OUTPUT_VALUE, value ? GPIO_OUTPUT_VALUE : 0);
}

void gpio_input_pulldown(gpio_t gpio_num)
{
	gpio_setbits32(gpio_num, GPIO_PULL_MASK | GPIO_OUTPUT_ENABLE, GPIO_PULLDOWN_ENABLE);
}

void gpio_input_pullup(gpio_t gpio_num)
{
	gpio_setbits32(gpio_num, GPIO_PULL_MASK | GPIO_OUTPUT_ENABLE, GPIO_PULLUP_ENABLE);
}

void gpio_input(gpio_t gpio_num)
{
	gpio_and32(gpio_num, ~(GPIO_PULL_MASK | GPIO_OUTPUT_ENABLE));
}

void gpio_output(gpio_t gpio_num, int value)
{
	/* set GPIO output value before setting the direction to output to avoid glitches */
	gpio_set(gpio_num, value);
	gpio_or32(gpio_num, GPIO_OUTPUT_ENABLE);
}

const char *gpio_acpi_path(gpio_t gpio)
{
	return "\\_SB.GPIO";
}

uint16_t gpio_acpi_pin(gpio_t gpio)
{
	return gpio;
}

void gpio_save_pin_registers(gpio_t gpio, struct soc_amd_gpio_register_save *save)
{
	save->mux_value = get_gpio_mux(gpio);
	save->control_value = gpio_read32(gpio);
}

void gpio_restore_pin_registers(gpio_t gpio, struct soc_amd_gpio_register_save *save)
{
	set_gpio_mux(gpio, save->mux_value);
	gpio_write32(gpio, save->control_value);
	gpio_read32(gpio); /* Flush posted write */
}

static void set_single_gpio(const struct soc_amd_gpio *g)
{
	static const struct soc_amd_event *gev_tbl;
	static size_t gev_items;
	int gevent_num;
	const bool can_set_smi_flags = !((CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK) &&
			ENV_SEPARATE_VERSTAGE) ||
			CONFIG(SOC_AMD_COMMON_BLOCK_BANKED_GPIOS_NON_SOC_CODEBASE));

	set_gpio_mux(g->gpio, g->function);

	gpio_setbits32(g->gpio, PAD_CFG_MASK, g->control);
	/* Clear interrupt and wake status (write 1-to-clear bits) */
	gpio_or32(g->gpio, GPIO_INT_STATUS | GPIO_WAKE_STATUS);
	if (g->flags == 0)
		return;

	/* Can't set SMI flags from PSP */
	if (!can_set_smi_flags)
		return;

	if (gev_tbl == NULL)
		soc_get_gpio_event_table(&gev_tbl, &gev_items);

	gevent_num = get_gpio_gevent(g->gpio, gev_tbl, gev_items);
	if (gevent_num < 0) {
		printk(BIOS_WARNING, "Warning: GPIO pin %d has no associated gevent!\n",
				     g->gpio);
		return;
	}

	if (g->flags & GPIO_FLAG_SMI) {
		program_smi(g->flags, gevent_num);
	} else if (g->flags & GPIO_FLAG_SCI) {
		program_sci(g->flags, gevent_num);
	}
}

void gpio_configure_pads_with_override(const struct soc_amd_gpio *base_cfg,
					size_t base_num_pads,
					const struct soc_amd_gpio *override_cfg,
					size_t override_num_pads)
{
	const struct soc_amd_gpio *c;
	size_t i, j;

	if (!base_cfg || !base_num_pads)
		return;

	/*
	 * Disable blocking wake/interrupt status generation while updating
	 * debounce registers. Otherwise when a debounce register is updated
	 * the whole GPIO controller will zero out all interrupt enable status
	 * bits while the delay happens. This could cause us to drop the bits
	 * due to the read-modify-write that happens on each register.
	 *
	 * Additionally disable interrupt generation so we don't get any
	 * spurious interrupts while updating the registers.
	 */
	master_switch_clr(GPIO_MASK_STS_EN | GPIO_INTERRUPT_EN);

	for (i = 0; i < base_num_pads; i++) {
		c = &base_cfg[i];
		/* Check if override exist for GPIO from the base configuration */
		for (j = 0; override_cfg && j < override_num_pads; j++) {
			if (c->gpio == override_cfg[j].gpio) {
				c = &override_cfg[j];
				break;
			}
		}
		set_single_gpio(c);
	}

	/*
	 * Re-enable interrupt status generation.
	 *
	 * We leave MASK_STATUS disabled because the kernel may reconfigure the
	 * debounce registers while the drivers load. This will cause interrupts
	 * to be missed during boot.
	 */
	master_switch_set(GPIO_INTERRUPT_EN);
}

void gpio_configure_pads(const struct soc_amd_gpio *gpio_list_ptr, size_t size)
{
	gpio_configure_pads_with_override(gpio_list_ptr, size, NULL, 0);
}

int gpio_interrupt_status(gpio_t gpio)
{
	uint32_t reg = gpio_read32(gpio);

	if (reg & GPIO_INT_STATUS) {
		/* Clear interrupt status, preserve wake status */
		reg &= ~GPIO_WAKE_STATUS;
		gpio_write32(gpio, reg);
		return 1;
	}

	return 0;
}

static void check_and_add_wake_gpio(gpio_t begin, gpio_t end, struct gpio_wake_state *state)
{
	gpio_t i;
	uint32_t reg;

	for (i = begin; i < end; i++) {
		reg = gpio_read32(i);
		if (!(reg & GPIO_WAKE_STATUS))
			continue;
		printk(BIOS_INFO, "GPIO %d woke system.\n", i);
		if (state->num_valid_wake_gpios >= ARRAY_SIZE(state->wake_gpios))
			continue;
		state->wake_gpios[state->num_valid_wake_gpios++] = i;
	}
}

static void check_gpios(uint32_t wake_stat, unsigned int bit_limit, gpio_t gpio_base,
			struct gpio_wake_state *state)
{
	unsigned int i;
	gpio_t begin;
	gpio_t end;

	for (i = 0; i < bit_limit; i++) {
		if (!(wake_stat & BIT(i)))
			continue;
		/* Each wake status register bit is for 4 GPIOs that then will be checked */
		begin = gpio_base + i * 4;
		end = begin + 4;
		/* There is no gpio 63. */
		if (begin == 60)
			end = 63;
		check_and_add_wake_gpio(begin, end, state);
	}
}

void gpio_fill_wake_state(struct gpio_wake_state *state)
{
	/* Turn the wake registers into "gpio" index to conform to existing API. */
	const gpio_t stat0 = GPIO_WAKE_STAT_0 / sizeof(uint32_t);
	const gpio_t stat1 = GPIO_WAKE_STAT_1 / sizeof(uint32_t);
	const gpio_t control_switch = GPIO_MASTER_SWITCH / sizeof(uint32_t);

	memset(state, 0, sizeof(*state));

	state->control_switch = gpio_read32(control_switch);
	state->wake_stat[0] = gpio_read32(stat0);
	state->wake_stat[1] = gpio_read32(stat1);

	printk(BIOS_INFO, "GPIO Control Switch: 0x%08x, Wake Stat 0: 0x%08x, Wake Stat 1: 0x%08x\n",
		state->control_switch, state->wake_stat[0], state->wake_stat[1]);

	check_gpios(state->wake_stat[0], 32, 0, state);
	check_gpios(state->wake_stat[1], 14, 128, state);
}

void gpio_add_events(void)
{
	const struct chipset_power_state *ps;
	const struct gpio_wake_state *state;
	unsigned int i;
	unsigned int end;

	if (acpi_pm_state_for_elog(&ps) < 0)
		return;
	state = &ps->gpio_state;

	end = MIN(state->num_valid_wake_gpios, ARRAY_SIZE(state->wake_gpios));
	for (i = 0; i < end; i++)
		elog_add_event_wake(ELOG_WAKE_SOURCE_GPIO, state->wake_gpios[i]);
}
