/*
 * Copyright (c) 2018-2019 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT intel_gpio

/**
 * @file
 * @brief Intel GPIO Controller Driver
 *
 * The GPIO controller on Intel SoC serves
 * both GPIOs and Pinmuxing function. This driver provides
 * the GPIO function.
 *
 * Due to GPIO callback only allowing 32 pins (as a 32-bit mask) at once,
 * each set is further sub-divided into multiple devices, so
 * we export GPIO_INTEL_NR_SUBDEVS devices to the kernel.
 */

#include <errno.h>
#include <drivers/gpio.h>
#include <soc.h>
#include <sys/sys_io.h>
#include <sys/__assert.h>
#include <sys/slist.h>
#include <sys/speculation.h>

#include "gpio_utils.h"

BUILD_ASSERT(DT_INST_IRQN(0) == 14);

#define REG_MISCCFG			0x0010
#define MISCCFG_IRQ_ROUTE_POS		3

#define REG_PAD_OWNER_BASE		0x0020
#define PAD_OWN_MASK			0x03
#define PAD_OWN_HOST			0
#define PAD_OWN_CSME			1
#define PAD_OWN_ISH			2
#define PAD_OWN_IE			3

#define PAD_HOST_SW_OWN_GPIO		1
#define PAD_HOST_SW_OWN_ACPI		0

#define REG_GPI_INT_STS_BASE		0x0100

#define PAD_CFG0_RXPADSTSEL		BIT(29)
#define PAD_CFG0_RXRAW1			BIT(28)

#define PAD_CFG0_PMODE_MASK		(0x0F << 10)

#define PAD_CFG0_RXEVCFG_POS		25
#define PAD_CFG0_RXEVCFG_MASK		(0x03 << PAD_CFG0_RXEVCFG_POS)
#define PAD_CFG0_RXEVCFG_LEVEL		(0 << PAD_CFG0_RXEVCFG_POS)
#define PAD_CFG0_RXEVCFG_EDGE		(1 << PAD_CFG0_RXEVCFG_POS)
#define PAD_CFG0_RXEVCFG_DRIVE0		(2 << PAD_CFG0_RXEVCFG_POS)

#define PAD_CFG0_PREGFRXSEL		BIT(24)
#define PAD_CFG0_RXINV			BIT(23)

#define PAD_CFG0_RXDIS			BIT(9)
#define PAD_CFG0_TXDIS			BIT(8)
#define PAD_CFG0_RXSTATE		BIT(1)
#define PAD_CFG0_RXSTATE_POS		1
#define PAD_CFG0_TXSTATE		BIT(0)
#define PAD_CFG0_TXSTATE_POS		0

#define PAD_CFG1_IOSTERM_POS		8
#define PAD_CFG1_IOSTERM_MASK		(0x03 << PAD_CFG1_IOSTERM_POS)
#define PAD_CFG1_IOSTERM_FUNC		(0 << PAD_CFG1_IOSTERM_POS)
#define PAD_CFG1_IOSTERM_DISPUD		(1 << PAD_CFG1_IOSTERM_POS)
#define PAD_CFG1_IOSTERM_PU		(2 << PAD_CFG1_IOSTERM_POS)
#define PAD_CFG1_IOSTERM_PD		(3 << PAD_CFG1_IOSTERM_POS)

#define PAD_CFG1_TERM_POS		10
#define PAD_CFG1_TERM_MASK		(0x0F << PAD_CFG1_TERM_POS)
#define PAD_CFG1_TERM_NONE		(0x00 << PAD_CFG1_TERM_POS)
#define PAD_CFG1_TERM_PD_5K		(0x02 << PAD_CFG1_TERM_POS)
#define PAD_CFG1_TERM_PD_20K		(0x04 << PAD_CFG1_TERM_POS)
#define PAD_CFG1_TERM_NONE2		(0x08 << PAD_CFG1_TERM_POS)
#define PAD_CFG1_TERM_PU_1K		(0x09 << PAD_CFG1_TERM_POS)
#define PAD_CFG1_TERM_PU_5K		(0x0A << PAD_CFG1_TERM_POS)
#define PAD_CFG1_TERM_PU_2K		(0x0B << PAD_CFG1_TERM_POS)
#define PAD_CFG1_TERM_PU_20K		(0x0C << PAD_CFG1_TERM_POS)
#define PAD_CFG1_TERM_PU_1K_2K		(0x0D << PAD_CFG1_TERM_POS)

#define PAD_CFG1_IOSSTATE_POS		14
#define PAD_CFG1_IOSSTATE_MASK		(0x0F << PAD_CFG1_IOSSTATE_POS)
#define PAD_CFG1_IOSSTATE_IGNORE	(0x0F << PAD_CFG1_IOSSTATE_POS)

/* Required by DEVICE_MMIO_NAMED_* macros */
#define DEV_CFG(_dev) \
	((const struct gpio_intel_config *)(_dev)->config)
#define DEV_DATA(_dev) ((struct gpio_intel_data *)(_dev)->data)

struct gpio_intel_config {
	/* gpio_driver_config needs to be first */
	struct gpio_driver_config common;

	DEVICE_MMIO_NAMED_ROM(reg_base);

	uint8_t	pin_offset;
	uint8_t group_index;
	uint8_t	num_pins;
};

struct gpio_intel_data {
	/* gpio_driver_data needs to be first */
	struct gpio_driver_data common;

	DEVICE_MMIO_NAMED_RAM(reg_base);

	/* Pad base address */
	uint32_t pad_base;

	sys_slist_t cb;
};

static inline mm_reg_t regs(const struct device *dev)
{
	return GPIO_REG_BASE(DEVICE_MMIO_NAMED_GET(dev, reg_base));
}

static inline mm_reg_t pad_base(const struct device *dev)
{
	return GPIO_PAD_BASE(DEVICE_MMIO_NAMED_GET(dev, reg_base));
}

#ifdef CONFIG_GPIO_INTEL_CHECK_PERMS
/**
 * @brief Check if host has permission to alter this GPIO pin.
 *
 * @param "struct device *dev" Device struct
 * @param "uint32_t raw_pin" Raw GPIO pin
 *
 * @return true if host owns the GPIO pin, false otherwise
 */
static bool check_perm(const struct device *dev, uint32_t raw_pin)
{
	struct gpio_intel_data *data = dev->data;
	const struct gpio_intel_config *cfg = dev->config;
	uint32_t offset, val, pin_offset;

	pin_offset = cfg->pin_offset;
	/* First is to establish that host software owns the pin */

	/* read the Pad Ownership register related to the pin */
	offset = GPIO_PAD_OWNERSHIP(raw_pin, pin_offset);
	val = sys_read32(regs(dev) + offset);

	/* get the bits about ownership */
	offset = GPIO_OWNERSHIP_BIT(raw_pin);
	val = (val >> offset) & PAD_OWN_MASK;
	if (val) {
		/* PAD_OWN_HOST == 0, so !0 => false*/
		return false;
	}

	/* Also need to make sure the function of pad is GPIO */
	offset = data->pad_base + (raw_pin << 3);
	val = sys_read32(regs(dev) + offset);
	if (val & PAD_CFG0_PMODE_MASK) {
		/* mode is not zero => not functioning as GPIO */
		return false;
	}

	return true;
}
#else
#define check_perm(...) (1)
#endif

/*
 * as the kernel initializes the subdevices, we add them
 * to the list of devices to check at ISR time.
 */

static int nr_isr_devs;

static const struct device *isr_devs[GPIO_INTEL_NR_SUBDEVS];

static void gpio_intel_isr(const struct device *dev)
{
	const struct gpio_intel_config *cfg;
	struct gpio_intel_data *data;
	struct gpio_callback *cb, *tmp;
	uint32_t reg, int_sts, cur_mask, acc_mask;
	int isr_dev;

	for (isr_dev = 0; isr_dev < nr_isr_devs; ++isr_dev) {
		dev = isr_devs[isr_dev];
		cfg = dev->config;
		data = dev->data;

		reg = regs(dev) + REG_GPI_INT_STS_BASE
		      + GPIO_INTERRUPT_BASE(cfg);
		int_sts = sys_read32(reg);
		acc_mask = 0U;

		SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&data->cb, cb, tmp, node) {
			cur_mask = int_sts & cb->pin_mask;
			acc_mask |= cur_mask;
			if (cur_mask) {
				__ASSERT(cb->handler, "No callback handler!");
				cb->handler(dev, cb, cur_mask);
			}
		}

		/* clear handled interrupt bits */
		sys_write32(acc_mask, reg);
	}
}

static int gpio_intel_config(const struct device *dev,
			     gpio_pin_t pin, gpio_flags_t flags)
{
	const struct gpio_intel_config *cfg = dev->config;
	struct gpio_intel_data *data = dev->data;
	uint32_t raw_pin, reg, cfg0, cfg1;

	/* Only support push-pull mode */
	if ((flags & GPIO_SINGLE_ENDED) != 0U) {
		return -ENOTSUP;
	}

	pin = k_array_index_sanitize(pin, cfg->num_pins + 1);

	raw_pin = GPIO_RAW_PIN(pin, cfg->pin_offset);

	if (!check_perm(dev, raw_pin)) {
		return -EINVAL;
	}

	/* read in pad configuration register */
	reg = regs(dev) + data->pad_base + (raw_pin * PIN_OFFSET);
	cfg0 = sys_read32(reg);
	cfg1 = sys_read32(reg + 4);

	/* don't override RX to 1 */
	cfg0 &= ~(PAD_CFG0_RXRAW1);

	/* set input/output */
	if ((flags & GPIO_INPUT) != 0U) {
		/* clear RX disable bit */
		cfg0 &= ~PAD_CFG0_RXDIS;
	} else {
		/* set RX disable bit */
		cfg0 |= PAD_CFG0_RXDIS;
	}

	if ((flags & GPIO_OUTPUT) != 0U) {
		/* pin to output */

		/* set pin output if desired */
		if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0U) {
			cfg0 |= PAD_CFG0_TXSTATE;
		} else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0U) {
			cfg0 &= ~PAD_CFG0_TXSTATE;
		}

		/* clear TX disable bit */
		cfg0 &= ~PAD_CFG0_TXDIS;
	} else {
		/* set TX disable bit */
		cfg0 |= PAD_CFG0_TXDIS;
	}

	/* pull-up or pull-down */
	cfg1 &= ~(PAD_CFG1_TERM_MASK | PAD_CFG1_IOSTERM_MASK);
	if ((flags & GPIO_PULL_UP) != 0U) {
		cfg1 |= (PAD_CFG1_TERM_PU_20K | PAD_CFG1_IOSTERM_PU);
	} else if ((flags & GPIO_PULL_DOWN) != 0U) {
		cfg1 |= (PAD_CFG1_TERM_PD_20K | PAD_CFG1_IOSTERM_PD);
	} else {
		cfg1 |= (PAD_CFG1_TERM_NONE | PAD_CFG1_IOSTERM_FUNC);
	}

	/* IO Standby state to TX,RX enabled */
	cfg1 &= ~PAD_CFG1_IOSSTATE_MASK;

	/* write back pad configuration register after all changes */
	sys_write32(cfg0, reg);
	sys_write32(cfg1, reg + 4);

	return 0;
}

static int gpio_intel_pin_interrupt_configure(const struct device *dev,
					      gpio_pin_t pin,
					      enum gpio_int_mode mode,
					      enum gpio_int_trig trig)
{
	const struct gpio_intel_config *cfg = dev->config;
	struct gpio_intel_data *data = dev->data;
	uint32_t raw_pin, cfg0, cfg1;
	uint32_t reg, reg_en, reg_sts;

	/* no double-edge triggering according to data sheet */
	if (trig == GPIO_INT_TRIG_BOTH) {
		return -ENOTSUP;
	}

	pin = k_array_index_sanitize(pin, cfg->num_pins + 1);

	raw_pin = GPIO_RAW_PIN(pin, cfg->pin_offset);

	if (!check_perm(dev, raw_pin)) {
		return -EINVAL;
	}

	/* set owner to GPIO driver mode for legacy interrupt mode */
	reg = regs(dev) + REG_PAD_HOST_SW_OWNER + GPIO_BASE(cfg);
	sys_bitfield_set_bit(reg, raw_pin);

	/* read in pad configuration register */
	reg = regs(dev) + data->pad_base + (raw_pin * PIN_OFFSET);
	cfg0 = sys_read32(reg);
	cfg1 = sys_read32(reg + 4);

	reg_en = regs(dev) + REG_GPI_INT_EN_BASE + GPIO_BASE(cfg);

	/* disable interrupt bit first before setup */
	sys_bitfield_clear_bit(reg_en, raw_pin);

	/* clear (by setting) interrupt status bit */
	reg_sts = regs(dev) + REG_GPI_INT_STS_BASE + GPIO_BASE(cfg);
	sys_bitfield_set_bit(reg_sts, raw_pin);

	/* clear level/edge configuration bits */
	cfg0 &= ~PAD_CFG0_RXEVCFG_MASK;

	if (mode == GPIO_INT_MODE_DISABLED) {
		/* set RX conf to drive 0 */
		cfg0 |= PAD_CFG0_RXEVCFG_DRIVE0;
	} else {
		/* cannot enable interrupt without pin as input */
		if ((cfg0 & PAD_CFG0_RXDIS) != 0U) {
			return -ENOTSUP;
		}

		/*
		 * Do not enable interrupt with pin as output.
		 * Hardware does not seem to support triggering
		 * interrupt by setting line as both input/output
		 * and then setting output to desired level.
		 * So just say not supported.
		 */
		if ((cfg0 & PAD_CFG0_TXDIS) == 0U) {
			return -ENOTSUP;
		}

		if (mode == GPIO_INT_MODE_LEVEL) {
			/* level trigger */
			cfg0 |= PAD_CFG0_RXEVCFG_LEVEL;
		} else {
			/* edge trigger */
			cfg0 |= PAD_CFG0_RXEVCFG_EDGE;
		}

		/* invert pin for active low triggering */
		if (trig == GPIO_INT_TRIG_LOW) {
			cfg0 |= PAD_CFG0_RXINV;
		} else {
			cfg0 &= ~PAD_CFG0_RXINV;
		}
	}

	/* write back pad configuration register after all changes */
	sys_write32(cfg0, reg);
	sys_write32(cfg1, reg + 4);

	if (mode != GPIO_INT_MODE_DISABLED) {
		/* enable interrupt bit */
		sys_bitfield_set_bit(reg_en, raw_pin);
	}

	return 0;
}

static int gpio_intel_manage_callback(const struct device *dev,
				      struct gpio_callback *callback,
				      bool set)
{
	struct gpio_intel_data *data = dev->data;

	return gpio_manage_callback(&data->cb, callback, set);
}

static int port_get_raw(const struct device *dev, uint32_t mask,
			uint32_t *value,
			bool read_tx)
{
	const struct gpio_intel_config *cfg = dev->config;
	struct gpio_intel_data *data = dev->data;
	uint32_t pin, raw_pin, reg_addr, reg_val, cmp;

	if (read_tx) {
		cmp = PAD_CFG0_TXSTATE;
	} else {
		cmp = PAD_CFG0_RXSTATE;
	}

	*value = 0;
	while (mask != 0U) {
		pin = find_lsb_set(mask) - 1;

		if (pin >= cfg->num_pins) {
			break;
		}

		mask &= ~BIT(pin);

		raw_pin = GPIO_RAW_PIN(pin, cfg->pin_offset);

		if (!check_perm(dev, raw_pin)) {
			continue;
		}

		reg_addr = regs(dev) + data->pad_base + (raw_pin * PIN_OFFSET);
		reg_val = sys_read32(reg_addr);

		if ((reg_val & cmp) != 0U) {
			*value |= BIT(pin);
		}
	}

	return 0;
}

static int port_set_raw(const struct device *dev, uint32_t mask,
			uint32_t value)
{
	const struct gpio_intel_config *cfg = dev->config;
	struct gpio_intel_data *data = dev->data;
	uint32_t pin, raw_pin, reg_addr, reg_val;

	while (mask != 0) {
		pin = find_lsb_set(mask) - 1;

		if (pin >= cfg->num_pins) {
			break;
		}

		mask &= ~BIT(pin);

		raw_pin = GPIO_RAW_PIN(pin, cfg->pin_offset);

		if (!check_perm(dev, raw_pin)) {
			continue;
		}

		reg_addr = regs(dev) + data->pad_base + (raw_pin * PIN_OFFSET);
		reg_val = sys_read32(reg_addr);

		if ((value & BIT(pin)) != 0) {
			reg_val |= PAD_CFG0_TXSTATE;
		} else {
			reg_val &= ~PAD_CFG0_TXSTATE;
		}

		sys_write32(reg_val, reg_addr);
	}

	return 0;
}

static int gpio_intel_port_set_masked_raw(const struct device *dev,
					  uint32_t mask,
					  uint32_t value)
{
	uint32_t port_val;

	port_get_raw(dev, mask, &port_val, true);

	port_val = (port_val & ~mask) | (mask & value);

	port_set_raw(dev, mask, port_val);

	return 0;
}

static int gpio_intel_port_set_bits_raw(const struct device *dev,
					uint32_t mask)
{
	return gpio_intel_port_set_masked_raw(dev, mask, mask);
}

static int gpio_intel_port_clear_bits_raw(const struct device *dev,
					  uint32_t mask)
{
	return gpio_intel_port_set_masked_raw(dev, mask, 0);
}

static int gpio_intel_port_toggle_bits(const struct device *dev,
				       uint32_t mask)
{
	uint32_t port_val;

	port_get_raw(dev, mask, &port_val, true);

	port_val ^= mask;

	port_set_raw(dev, mask, port_val);

	return 0;
}

static int gpio_intel_port_get_raw(const struct device *dev,
				   uint32_t *value)
{
	return port_get_raw(dev, 0xFFFFFFFF, value, false);
}

static const struct gpio_driver_api gpio_intel_api = {
	.pin_configure = gpio_intel_config,
	.manage_callback = gpio_intel_manage_callback,
	.port_get_raw = gpio_intel_port_get_raw,
	.port_set_masked_raw = gpio_intel_port_set_masked_raw,
	.port_set_bits_raw = gpio_intel_port_set_bits_raw,
	.port_clear_bits_raw = gpio_intel_port_clear_bits_raw,
	.port_toggle_bits = gpio_intel_port_toggle_bits,
	.pin_interrupt_configure = gpio_intel_pin_interrupt_configure,
};

int gpio_intel_init(const struct device *dev)
{
	struct gpio_intel_data *data = dev->data;

#ifdef CONFIG_SOC_APOLLO_LAKE
	/*
	 * On Apollo Lake, each GPIO controller has more than 32 pins.
	 * But Zephyr API can only manipulate 32 pins per controller.
	 * So the workaround is to divide each hardware GPIO controller
	 * into 32-pin blocks so each block has a GPIO driver instance.
	 * Compounding to the issue is that there cannot be two device
	 * tree nodes with same register address. So another workaround
	 * is to increment the register addresses by 1 for each block.
	 * So when mapping the address, the lowest 8-bit needs to be
	 * masked to get the actual hardware address. Hence the weird
	 * code below.
	 */

	const struct gpio_intel_config *cfg = dev->config;

	device_map(&data->reg_base,
		   cfg->reg_base.phys_addr & ~0xFFU,
		   cfg->reg_base.size,
		   K_MEM_CACHE_NONE);
#else
	DEVICE_MMIO_NAMED_MAP(dev, reg_base, K_MEM_CACHE_NONE);
#endif
	data->pad_base = pad_base(dev);

	__ASSERT(nr_isr_devs < GPIO_INTEL_NR_SUBDEVS, "too many subdevs");

	if (nr_isr_devs == 0) {
		/* Note that all controllers are using the same IRQ line.
		 * So we can just use the values from the first instance.
		 */
		IRQ_CONNECT(DT_INST_IRQN(0),
			    DT_INST_IRQ(0, priority),
			    gpio_intel_isr, NULL,
			    DT_INST_IRQ(0, sense));

		irq_enable(DT_INST_IRQN(0));
	}

	isr_devs[nr_isr_devs++] = dev;

	/* route to IRQ 14 */

	sys_bitfield_clear_bit(regs(dev) + REG_MISCCFG,
			       MISCCFG_IRQ_ROUTE_POS);

	return 0;
}

#define GPIO_INTEL_DEV_CFG_DATA(n)					       \
	static const struct gpio_intel_config				       \
		gpio_intel_cfg_##n = {					       \
		.common = {						       \
			.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n),   \
		},							       \
		DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(n)),	       \
		.pin_offset = DT_INST_PROP(n, pin_offset),		       \
		.group_index = DT_INST_PROP_OR(n, group_index, 0),	       \
		.num_pins = DT_INST_PROP(n, ngpios),			       \
	};								       \
									       \
	static struct gpio_intel_data gpio_intel_data_##n;		       \
									       \
	DEVICE_DT_INST_DEFINE(n,					       \
			      gpio_intel_init,				       \
			      NULL,					       \
			      &gpio_intel_data_##n,			       \
			      &gpio_intel_cfg_##n,			       \
			      POST_KERNEL, CONFIG_GPIO_INIT_PRIORITY,	       \
			      &gpio_intel_api);

/* "sub" devices.  no more than GPIO_INTEL_NR_SUBDEVS of these! */
DT_INST_FOREACH_STATUS_OKAY(GPIO_INTEL_DEV_CFG_DATA)
