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

#include <arch/io.h>
#include <device/mmio.h>
#include <device/pci.h>
#include <console/console.h>
#include <soc/gpio.h>
#include <soc/pm.h>
#include <soc/smm.h>

/* GPIO-to-Pad LUTs */
static const u8 gpncore_gpio_to_pad[GPNCORE_COUNT] =
	{ 19, 18, 17, 20, 21, 22, 24, 25,	/* [ 0: 7] */
	  23, 16, 14, 15, 12, 26, 27,  1,	/* [ 8:15] */
	   4,  8, 11,  0,  3,  6, 10, 13,	/* [16:23] */
	   2,  5,  9 };				/* [24:26] */

static const u8 gpscore_gpio_to_pad[GPSCORE_COUNT] =
	{  85,  89, 93,  96, 99, 102,  98, 101,	/* [ 0:  7] */
	   34,  37, 36,  38, 39,  35,  40,  84,	/* [ 8: 15] */
	   62,  61, 64,  59, 54,  56,  60,  55,	/* [16: 23] */
	   63,  57, 51,  50, 53,  47,  52,  49,	/* [24: 31] */
	   48,  43, 46,  41, 45,  42,  58,  44,	/* [32: 39] */
	   95, 105, 70,  68, 67,  66,  69,  71,	/* [40: 47] */
	   65,  72, 86,  90, 88,  92, 103,  77,	/* [48: 55] */
	   79,  83, 78,  81, 80,  82,  13,  12,	/* [56: 63] */
	   15,  14, 17,  18, 19,  16,   2,   1,	/* [64: 71] */
	    0,   4,  6,   7,  9,   8,  33,  32,	/* [72: 79] */
	   31,  30, 29,  27, 25,  28,  26,  23,	/* [80: 87] */
	   21,  20, 24,  22,  5,   3,  10,  11,	/* [88: 95] */
	  106,  87, 91, 104, 97, 100 };		/* [96:101] */

static const u8 gpssus_gpio_to_pad[GPSSUS_COUNT] =
	{ 29, 33, 30, 31, 32, 34, 36, 35,	/* [ 0: 7] */
	  38, 37, 18,  7, 11, 20, 17,  1,	/* [ 8:15] */
	   8, 10, 19, 12,  0,  2, 23, 39,	/* [16:23] */
	  28, 27, 22, 21, 24, 25, 26, 51,	/* [24:31] */
	  56, 54, 49, 55, 48, 57, 50, 58,	/* [32:39] */
	  52, 53, 59, 40 };			/* [40:43] */

/* GPIO bank descriptions */
static const struct gpio_bank gpncore_bank = {
	.gpio_count = GPNCORE_COUNT,
	.gpio_to_pad = gpncore_gpio_to_pad,
	.legacy_base = GP_LEGACY_BASE_NONE,
	.pad_base = GPNCORE_PAD_BASE,
	.has_wake_en = 0,
	.gpio_f1_range_start = GPNCORE_GPIO_F1_RANGE_START,
	.gpio_f1_range_end = GPNCORE_GPIO_F1_RANGE_END,
};

static const struct gpio_bank gpscore_bank = {
	.gpio_count = GPSCORE_COUNT,
	.gpio_to_pad = gpscore_gpio_to_pad,
	.legacy_base = GPSCORE_LEGACY_BASE,
	.pad_base = GPSCORE_PAD_BASE,
	.has_wake_en = 0,
	.gpio_f1_range_start = GPSCORE_GPIO_F1_RANGE_START,
	.gpio_f1_range_end = GPSCORE_GPIO_F1_RANGE_END,
};

static const struct gpio_bank gpssus_bank = {
	.gpio_count = GPSSUS_COUNT,
	.gpio_to_pad = gpssus_gpio_to_pad,
	.legacy_base = GPSSUS_LEGACY_BASE,
	.pad_base = GPSSUS_PAD_BASE,
	.has_wake_en = 1,
	.gpio_f1_range_start = GPSSUS_GPIO_F1_RANGE_START,
	.gpio_f1_range_end = GPSSUS_GPIO_F1_RANGE_END,
};

static void setup_gpios(const struct soc_gpio_map *gpios,
			const struct gpio_bank *bank)
{
	const struct soc_gpio_map *config;
	int gpio = 0;
	u32 reg, pad_conf0;
	u8 set, bit;

	u32 use_sel[4] = {0};
	u32 io_sel[4] = {0};
	u32 gp_lvl[4] = {0};
	u32 tpe[4] = {0};
	u32 tne[4] = {0};
	u32 wake_en[4] = {0};

	if (!gpios)
		return;

	for (config = gpios; config->pad_conf0 != GPIO_LIST_END;
	     config++, gpio++) {
		if (gpio > bank->gpio_count)
			break;

		set = gpio >> 5;
		bit = gpio % 32;

		if (bank->legacy_base != GP_LEGACY_BASE_NONE) {
			/* Legacy IO configuration */
			use_sel[set] |= config->use_sel << bit;
			io_sel[set]  |= config->io_sel  << bit;
			gp_lvl[set]  |= config->gp_lvl  << bit;
			tpe[set]     |= config->tpe     << bit;
			tne[set]     |= config->tne     << bit;

			/* Some banks do not have wake_en ability */
			if (bank->has_wake_en)
				wake_en[set] |= config->wake_en << bit;
		}

		/* Pad configuration registers */
		reg = bank->pad_base + 16 * bank->gpio_to_pad[gpio];

		/* Add correct func to GPIO pad config */
		pad_conf0 = config->pad_conf0;
		if (config->is_gpio)
		{
			if (gpio >= bank->gpio_f1_range_start &&
			    gpio <= bank->gpio_f1_range_end)
				pad_conf0 |= PAD_FUNC1;
			else
				pad_conf0 |= PAD_FUNC0;
		}

#ifdef GPIO_DEBUG
		printk(BIOS_DEBUG, "Write Pad: Base(%x) - %x %x %x\n",
		       reg, pad_conf0, config->pad_conf1, config->pad_val);
#endif

		write32((u32 *)(reg + PAD_CONF0_REG), pad_conf0);
		write32((u32 *)(reg + PAD_CONF1_REG), config->pad_conf1);
		write32((u32 *)(reg + PAD_VAL_REG), config->pad_val);
	}

	if (bank->legacy_base != GP_LEGACY_BASE_NONE)
		for (set = 0; set <= (bank->gpio_count - 1) / 32; ++set) {
			reg = bank->legacy_base + 0x20 * set;

#ifdef GPIO_DEBUG
			printk(BIOS_DEBUG,
			       "Write GPIO: Reg(%x) - %x %x %x %x %x\n",
				reg, use_sel[set], io_sel[set], gp_lvl[set],
				tpe[set], tne[set]);
#endif

			outl(use_sel[set], reg + LEGACY_USE_SEL_REG);
			outl(io_sel[set], reg + LEGACY_IO_SEL_REG);
			outl(gp_lvl[set], reg + LEGACY_GP_LVL_REG);
			outl(tpe[set], reg + LEGACY_TPE_REG);
			outl(tne[set], reg + LEGACY_TNE_REG);

			/* TS registers are WOC  */
			outl(0, reg + LEGACY_TS_REG);

			if (bank->has_wake_en)
				outl(wake_en[set], reg + LEGACY_WAKE_EN_REG);
		}
}

static void setup_gpio_route(const struct soc_gpio_map *sus,
			     const struct soc_gpio_map *core)
{
	uint32_t route_reg = 0;
	int i;

	for (i = 0; i < 8; i++) {
		/* SMI takes precedence and wake_en implies SCI. */
		if (sus[i].smi) {
			route_reg |= ROUTE_SMI << (2 * i);
		} else if (sus[i].sci) {
			route_reg |= ROUTE_SCI << (2 * i);
		}

		if (core[i].smi) {
			route_reg |= ROUTE_SMI << (2 * (i + 8));
		} else if (core[i].sci) {
			route_reg |= ROUTE_SCI << (2 * (i + 8));
		}
	}
	smm_southcluster_save_param(SMM_SAVE_PARAM_GPIO_ROUTE, route_reg);
}

static void setup_dirqs(const u8 dirq[GPIO_MAX_DIRQS],
			const struct gpio_bank *bank)
{
	u32 *reg = (u32 *)(bank->pad_base + PAD_BASE_DIRQ_OFFSET);
	u32 val;
	int i;

	/* Write all four DIRQ registers */
	for (i=0; i<4; ++i) {
		val = dirq[i * 4 + 3] << 24 | dirq[i * 4 + 2] << 16 |
		      dirq[i * 4 + 1] << 8  | dirq[i * 4];
		write32(reg + i, val);
#ifdef GPIO_DEBUG
		printk(BIOS_DEBUG, "Write DIRQ reg(%x) - %x\n",
			reg + i, val);
#endif
	}
}

void setup_soc_gpios(struct soc_gpio_config *config, u8 enable_xdp_tap)
{
	if (config) {
		setup_gpios(config->ncore, &gpncore_bank);
		setup_gpios(config->score, &gpscore_bank);
		setup_gpios(config->ssus,  &gpssus_bank);
		setup_gpio_route(config->ssus, config->score);

		if (config->core_dirq)
			setup_dirqs(*config->core_dirq, &gpscore_bank);
		if (config->sus_dirq)
			setup_dirqs(*config->sus_dirq, &gpssus_bank);
	}

	/* Set on die termination feature with pull up value and
	 * drive the pad high for TAP_TDO and TAP_TMS
	 */
	if (!enable_xdp_tap) {
		printk(BIOS_DEBUG, "Tri-state TDO and TMS\n");
		write32((u32 *)(GPSSUS_PAD_BASE + 0x2fc), 0xc);
		write32((u32 *)(GPSSUS_PAD_BASE + 0x2cc), 0xc);
	}
}

struct soc_gpio_config* __weak mainboard_get_gpios(void)
{
	printk(BIOS_DEBUG, "Default/empty GPIO config\n");
	return NULL;
}
