// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright 2019 Broadcom.
 */
#include <assert.h>
#include <drivers/bcm_gpio.h>
#include <initcall.h>
#include <io.h>
#include <mm/core_memprot.h>
#include <platform_config.h>
#include <trace.h>

#define IPROC_GPIO_DATA_IN_OFFSET	0x00
#define IPROC_GPIO_DATA_OUT_OFFSET	0x04
#define IPROC_GPIO_OUT_EN_OFFSET	0x08
#define IPROC_GPIO_INT_MSK_OFFSET	0x18

#define GPIO_BANK_SIZE			0x200
#define NGPIOS_PER_BANK			32
#define GPIO_BANK(pin)			((pin) / NGPIOS_PER_BANK)

#define IPROC_GPIO_REG(pin, reg)	((reg) + \
	GPIO_BANK(pin) * GPIO_BANK_SIZE)

#define IPROC_GPIO_SHIFT(pin)		((pin) % NGPIOS_PER_BANK)

#define GPIO_BANK_CNT			5
#define SEC_GPIO_SIZE			0x4
#define IPROC_GPIO_SEC_CFG_REG(pin) \
	(((GPIO_BANK_CNT - 1) - GPIO_BANK(pin)) * SEC_GPIO_SIZE)

static SLIST_HEAD(, bcm_gpio_chip) gclist = SLIST_HEAD_INITIALIZER(gclist);

struct bcm_gpio_chip *bcm_gpio_pin_to_chip(unsigned int pin)
{
	struct bcm_gpio_chip *gc = NULL;

	SLIST_FOREACH(gc, &gclist, link)
		if ((pin >= gc->gpio_base) &&
		    (pin < (gc->gpio_base + gc->ngpios)))
			return gc;
	return NULL;
}

static bool __maybe_unused gpio_is_range_overlap(unsigned int start,
						 unsigned int end)
{
	struct bcm_gpio_chip *gc = NULL;

	SLIST_FOREACH(gc, &gclist, link)
		if ((start < (gc->gpio_base + gc->ngpios)) &&
		    (end > gc->gpio_base))
			return true;
	return false;
}

static void iproc_set_bit(unsigned int reg, unsigned int gpio)
{
	unsigned int offset = IPROC_GPIO_REG(gpio, reg);
	unsigned int shift = IPROC_GPIO_SHIFT(gpio);
	struct bcm_gpio_chip *gc = bcm_gpio_pin_to_chip(gpio);

	assert(gc);
	io_setbits32(gc->base + offset, BIT(shift));
}

static void iproc_clr_bit(unsigned int reg, unsigned int gpio)
{
	unsigned int offset = IPROC_GPIO_REG(gpio, reg);
	unsigned int shift = IPROC_GPIO_SHIFT(gpio);
	struct bcm_gpio_chip *gc = bcm_gpio_pin_to_chip(gpio);

	assert(gc);
	io_clrbits32(gc->base + offset, BIT(shift));
}

static void iproc_gpio_set(unsigned int gpio, enum gpio_level val)
{
	if (val == GPIO_LEVEL_HIGH)
		iproc_set_bit(IPROC_GPIO_DATA_OUT_OFFSET, gpio);
	else
		iproc_clr_bit(IPROC_GPIO_DATA_OUT_OFFSET, gpio);
}

static enum gpio_level iproc_gpio_get(unsigned int gpio)
{
	unsigned int offset = IPROC_GPIO_REG(gpio, IPROC_GPIO_DATA_IN_OFFSET);
	unsigned int shift = IPROC_GPIO_SHIFT(gpio);
	struct bcm_gpio_chip *gc = bcm_gpio_pin_to_chip(gpio);

	assert(gc);

	if (io_read32(gc->base + offset) & BIT(shift))
		return GPIO_LEVEL_HIGH;
	else
		return GPIO_LEVEL_LOW;
}

static void iproc_gpio_set_dir(unsigned int gpio, enum gpio_dir dir)
{
	if (dir == GPIO_DIR_OUT)
		iproc_set_bit(IPROC_GPIO_OUT_EN_OFFSET, gpio);
	else
		iproc_clr_bit(IPROC_GPIO_OUT_EN_OFFSET, gpio);
}

static enum gpio_dir iproc_gpio_get_dir(unsigned int gpio)
{
	unsigned int offset = IPROC_GPIO_REG(gpio, IPROC_GPIO_OUT_EN_OFFSET);
	unsigned int shift = IPROC_GPIO_SHIFT(gpio);
	struct bcm_gpio_chip *gc = bcm_gpio_pin_to_chip(gpio);

	assert(gc);

	if (io_read32(gc->base + offset) & BIT(shift))
		return GPIO_DIR_OUT;
	else
		return GPIO_DIR_IN;
}

static enum gpio_interrupt iproc_gpio_get_itr(unsigned int gpio)
{
	unsigned int offset = IPROC_GPIO_REG(gpio, IPROC_GPIO_INT_MSK_OFFSET);
	unsigned int shift = IPROC_GPIO_SHIFT(gpio);
	struct bcm_gpio_chip *gc = bcm_gpio_pin_to_chip(gpio);

	assert(gc);

	if (io_read32(gc->base + offset) & BIT(shift))
		return GPIO_INTERRUPT_ENABLE;
	else
		return GPIO_INTERRUPT_DISABLE;
}

static void iproc_gpio_set_itr(unsigned int gpio,
			       enum gpio_interrupt ena_dis)
{
	if (ena_dis == GPIO_INTERRUPT_ENABLE)
		iproc_set_bit(IPROC_GPIO_OUT_EN_OFFSET, gpio);
	else
		iproc_clr_bit(IPROC_GPIO_OUT_EN_OFFSET, gpio);
}

static const struct gpio_ops bcm_gpio_ops = {
	.get_direction = iproc_gpio_get_dir,
	.set_direction = iproc_gpio_set_dir,
	.get_value = iproc_gpio_get,
	.set_value = iproc_gpio_set,
	.get_interrupt = iproc_gpio_get_itr,
	.set_interrupt = iproc_gpio_set_itr,
};
KEEP_PAGER(bcm_gpio_ops);

void iproc_gpio_set_secure(int gpiopin)
{
	vaddr_t regaddr = 0;
	unsigned int shift = IPROC_GPIO_SHIFT(gpiopin);
	vaddr_t baseaddr = (vaddr_t)phys_to_virt(CHIP_SECURE_GPIO_CONTROL0_BASE,
						 MEM_AREA_IO_SEC);

	regaddr = baseaddr + IPROC_GPIO_SEC_CFG_REG(gpiopin);

	io_clrbits32(regaddr, BIT(shift));
}

static void iproc_gpio_init(struct bcm_gpio_chip *gc, unsigned int paddr,
			    unsigned int gpio_base, unsigned int ngpios)
{
	assert(!gpio_is_range_overlap(gpio_base, gpio_base + gc->ngpios));

	gc->base = core_mmu_get_va(paddr, MEM_AREA_IO_SEC);
	gc->chip.ops = &bcm_gpio_ops;
	gc->gpio_base = gpio_base;
	gc->ngpios = ngpios;

	SLIST_INSERT_HEAD(&gclist, gc, link);

	DMSG("gpio chip for <%u - %u>", gpio_base, gpio_base + ngpios);
}

static TEE_Result bcm_gpio_init(void)
{
	struct bcm_gpio_chip *gc = NULL;

#ifdef SECURE_GPIO_BASE0
	gc = malloc(sizeof(*gc));
	if (gc == NULL)
		return TEE_ERROR_OUT_OF_MEMORY;

	iproc_gpio_init(gc, SECURE_GPIO_BASE0, GPIO_NUM_START0, NUM_GPIOS0);
#endif
#ifdef SECURE_GPIO_BASE1
	gc = malloc(sizeof(*gc));
	if (gc == NULL)
		return TEE_ERROR_OUT_OF_MEMORY;

	iproc_gpio_init(gc, SECURE_GPIO_BASE1, GPIO_NUM_START1, NUM_GPIOS1);
#endif
	return TEE_SUCCESS;
}
driver_init(bcm_gpio_init);
