/*
 * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <errno.h>
#include <stdbool.h>

#include <libfdt.h>

#include <platform_def.h>

#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/st/stm32_gpio.h>
#include <drivers/st/stm32mp1_clk.h>
#include <drivers/st/stm32mp1_clkfunc.h>
#include <lib/mmio.h>
#include <lib/utils_def.h>

#define DT_GPIO_BANK_SHIFT	12
#define DT_GPIO_BANK_MASK	GENMASK(16, 12)
#define DT_GPIO_PIN_SHIFT	8
#define DT_GPIO_PIN_MASK	GENMASK(11, 8)
#define DT_GPIO_MODE_MASK	GENMASK(7, 0)

/*******************************************************************************
 * This function gets GPIO bank node in DT.
 * Returns node offset if status is okay in DT, else return 0
 ******************************************************************************/
static int ckeck_gpio_bank(void *fdt, uint32_t bank, int pinctrl_node)
{
	int pinctrl_subnode;
	uint32_t bank_offset = stm32_get_gpio_bank_offset(bank);

	fdt_for_each_subnode(pinctrl_subnode, fdt, pinctrl_node) {
		const fdt32_t *cuint;

		if (fdt_getprop(fdt, pinctrl_subnode,
				"gpio-controller", NULL) == NULL) {
			continue;
		}

		cuint = fdt_getprop(fdt, pinctrl_subnode, "reg", NULL);
		if (cuint == NULL) {
			continue;
		}

		if ((fdt32_to_cpu(*cuint) == bank_offset) &&
		    (fdt_get_status(pinctrl_subnode) != DT_DISABLED)) {
			return pinctrl_subnode;
		}
	}

	return 0;
}

/*******************************************************************************
 * This function gets the pin settings from DT information.
 * When analyze and parsing is done, set the GPIO registers.
 * Returns 0 on success and a negative FDT error code on failure.
 ******************************************************************************/
static int dt_set_gpio_config(void *fdt, int node, uint8_t status)
{
	const fdt32_t *cuint, *slewrate;
	int len;
	int pinctrl_node;
	uint32_t i;
	uint32_t speed = GPIO_SPEED_LOW;
	uint32_t pull = GPIO_NO_PULL;

	cuint = fdt_getprop(fdt, node, "pinmux", &len);
	if (cuint == NULL) {
		return -FDT_ERR_NOTFOUND;
	}

	pinctrl_node = fdt_parent_offset(fdt, fdt_parent_offset(fdt, node));
	if (pinctrl_node < 0) {
		return -FDT_ERR_NOTFOUND;
	}

	slewrate = fdt_getprop(fdt, node, "slew-rate", NULL);
	if (slewrate != NULL) {
		speed = fdt32_to_cpu(*slewrate);
	}

	if (fdt_getprop(fdt, node, "bias-pull-up", NULL) != NULL) {
		pull = GPIO_PULL_UP;
	} else if (fdt_getprop(fdt, node, "bias-pull-down", NULL) != NULL) {
		pull = GPIO_PULL_DOWN;
	} else {
		VERBOSE("No bias configured in node %d\n", node);
	}

	for (i = 0U; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
		uint32_t pincfg;
		uint32_t bank;
		uint32_t pin;
		uint32_t mode;
		uint32_t alternate = GPIO_ALTERNATE_(0);
		int bank_node;
		int clk;

		pincfg = fdt32_to_cpu(*cuint);
		cuint++;

		bank = (pincfg & DT_GPIO_BANK_MASK) >> DT_GPIO_BANK_SHIFT;

		pin = (pincfg & DT_GPIO_PIN_MASK) >> DT_GPIO_PIN_SHIFT;

		mode = pincfg & DT_GPIO_MODE_MASK;

		switch (mode) {
		case 0:
			mode = GPIO_MODE_INPUT;
			break;
		case 1 ... 16:
			alternate = mode - 1U;
			mode = GPIO_MODE_ALTERNATE;
			break;
		case 17:
			mode = GPIO_MODE_ANALOG;
			break;
		default:
			mode = GPIO_MODE_OUTPUT;
			break;
		}

		if (fdt_getprop(fdt, node, "drive-open-drain", NULL) != NULL) {
			mode |= GPIO_OPEN_DRAIN;
		}

		bank_node = ckeck_gpio_bank(fdt, bank, pinctrl_node);
		if (bank_node == 0) {
			ERROR("PINCTRL inconsistent in DT\n");
			panic();
		}

		clk = fdt_get_clock_id(bank_node);
		if (clk < 0) {
			return -FDT_ERR_NOTFOUND;
		}

		/* Platform knows the clock: assert it is okay */
		assert((unsigned long)clk == stm32_get_gpio_bank_clock(bank));

		set_gpio(bank, pin, mode, speed, pull, alternate, status);
	}

	return 0;
}

/*******************************************************************************
 * This function gets the pin settings from DT information.
 * When analyze and parsing is done, set the GPIO registers.
 * Returns 0 on success and a negative FDT/ERRNO error code on failure.
 ******************************************************************************/
int dt_set_pinctrl_config(int node)
{
	const fdt32_t *cuint;
	int lenp = 0;
	uint32_t i;
	uint8_t status = fdt_get_status(node);
	void *fdt;

	if (fdt_get_address(&fdt) == 0) {
		return -ENOENT;
	}

	if (status == DT_DISABLED) {
		return -FDT_ERR_NOTFOUND;
	}

	cuint = fdt_getprop(fdt, node, "pinctrl-0", &lenp);
	if (cuint == NULL) {
		return -FDT_ERR_NOTFOUND;
	}

	for (i = 0; i < ((uint32_t)lenp / 4U); i++) {
		int p_node, p_subnode;

		p_node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
		if (p_node < 0) {
			return -FDT_ERR_NOTFOUND;
		}

		fdt_for_each_subnode(p_subnode, fdt, p_node) {
			int ret = dt_set_gpio_config(fdt, p_subnode, status);

			if (ret < 0) {
				return ret;
			}
		}

		cuint++;
	}

	return 0;
}

void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
	      uint32_t pull, uint32_t alternate, uint8_t status)
{
	uintptr_t base = stm32_get_gpio_bank_base(bank);
	unsigned long clock = stm32_get_gpio_bank_clock(bank);

	assert(pin <= GPIO_PIN_MAX);

	stm32mp1_clk_enable(clock);

	mmio_clrbits_32(base + GPIO_MODE_OFFSET,
			((uint32_t)GPIO_MODE_MASK << (pin << 1)));
	mmio_setbits_32(base + GPIO_MODE_OFFSET,
			(mode & ~GPIO_OPEN_DRAIN) << (pin << 1));

	if ((mode & GPIO_OPEN_DRAIN) != 0U) {
		mmio_setbits_32(base + GPIO_TYPE_OFFSET, BIT(pin));
	} else {
		mmio_clrbits_32(base + GPIO_TYPE_OFFSET, BIT(pin));
	}

	mmio_clrbits_32(base + GPIO_SPEED_OFFSET,
			((uint32_t)GPIO_SPEED_MASK << (pin << 1)));
	mmio_setbits_32(base + GPIO_SPEED_OFFSET, speed << (pin << 1));

	mmio_clrbits_32(base + GPIO_PUPD_OFFSET,
			((uint32_t)GPIO_PULL_MASK << (pin << 1)));
	mmio_setbits_32(base + GPIO_PUPD_OFFSET, pull << (pin << 1));

	if (pin < GPIO_ALT_LOWER_LIMIT) {
		mmio_clrbits_32(base + GPIO_AFRL_OFFSET,
				((uint32_t)GPIO_ALTERNATE_MASK << (pin << 2)));
		mmio_setbits_32(base + GPIO_AFRL_OFFSET,
				alternate << (pin << 2));
	} else {
		mmio_clrbits_32(base + GPIO_AFRH_OFFSET,
				((uint32_t)GPIO_ALTERNATE_MASK <<
				 ((pin - GPIO_ALT_LOWER_LIMIT) << 2)));
		mmio_setbits_32(base + GPIO_AFRH_OFFSET,
				alternate << ((pin - GPIO_ALT_LOWER_LIMIT) <<
					      2));
	}

	VERBOSE("GPIO %u mode set to 0x%x\n", bank,
		mmio_read_32(base + GPIO_MODE_OFFSET));
	VERBOSE("GPIO %u speed set to 0x%x\n", bank,
		mmio_read_32(base + GPIO_SPEED_OFFSET));
	VERBOSE("GPIO %u mode pull to 0x%x\n", bank,
		mmio_read_32(base + GPIO_PUPD_OFFSET));
	VERBOSE("GPIO %u mode alternate low to 0x%x\n", bank,
		mmio_read_32(base + GPIO_AFRL_OFFSET));
	VERBOSE("GPIO %u mode alternate high to 0x%x\n", bank,
		mmio_read_32(base + GPIO_AFRH_OFFSET));

	stm32mp1_clk_disable((unsigned long)clock);
}

void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure)
{
	uintptr_t base = stm32_get_gpio_bank_base(bank);
	int clock = stm32_get_gpio_bank_clock(bank);

	assert(pin <= GPIO_PIN_MAX);

	stm32mp1_clk_enable((unsigned long)clock);

	if (secure) {
		mmio_setbits_32(base + GPIO_SECR_OFFSET, BIT(pin));
	} else {
		mmio_clrbits_32(base + GPIO_SECR_OFFSET, BIT(pin));
	}

	stm32mp1_clk_disable((unsigned long)clock);
}
