// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright (c) 2016, Linaro Limited
 */

#include <assert.h>
#include <drivers/pl061_gpio.h>
#include <io.h>
#include <keep.h>
#include <trace.h>
#include <util.h>

#ifndef PLAT_PL061_MAX_GPIOS
# define PLAT_PL061_MAX_GPIOS	32
#endif	/* PLAT_PL061_MAX_GPIOS */

#define MAX_GPIO_DEVICES	((PLAT_PL061_MAX_GPIOS + \
	(GPIOS_PER_PL061 - 1)) / GPIOS_PER_PL061)

#define GPIOS_PER_PL061		8

/* gpio register offsets */
#define GPIODIR		0x400
#define GPIOIS		0x404
#define GPIOIBE		0x408
#define GPIOIEV		0x40C
#define GPIOIE		0x410
#define GPIORIS		0x414
#define GPIOMIS		0x418
#define GPIOIC		0x41C
#define GPIOAFSEL	0x420

/* gpio register masks */
#define GPIOIE_ENABLED		SHIFT_U32(1, 0)
#define GPIOIE_MASKED		SHIFT_U32(0, 0)
#define GPIOAFSEL_HW		SHIFT_U32(1, 0)
#define GPIOAFSEL_SW		SHIFT_U32(0, 0)
#define GPIODIR_OUT			SHIFT_U32(1, 0)
#define GPIODIR_IN			SHIFT_U32(0, 0)

static vaddr_t pl061_reg_base[MAX_GPIO_DEVICES];

static enum gpio_dir pl061_get_direction(unsigned int gpio_pin)
{
	vaddr_t base_addr;
	uint8_t data;
	unsigned int offset;

	assert(gpio_pin < PLAT_PL061_MAX_GPIOS);

	base_addr = pl061_reg_base[gpio_pin / GPIOS_PER_PL061];
	offset = gpio_pin % GPIOS_PER_PL061;
	data = io_read8(base_addr + GPIODIR);
	if (data & BIT(offset))
		return GPIO_DIR_OUT;
	return GPIO_DIR_IN;
}

static void pl061_set_direction(unsigned int gpio_pin, enum gpio_dir direction)
{
	vaddr_t base_addr;
	unsigned int offset;

	assert(gpio_pin < PLAT_PL061_MAX_GPIOS);

	base_addr = pl061_reg_base[gpio_pin / GPIOS_PER_PL061];
	offset = gpio_pin % GPIOS_PER_PL061;
	if (direction == GPIO_DIR_OUT)
		io_setbits8(base_addr + GPIODIR, BIT(offset));
	else
		io_clrbits8(base_addr + GPIODIR, BIT(offset));
}

/*
 * The offset of GPIODATA register is 0.
 * The values read from GPIODATA are determined for each bit, by the mask bit
 * derived from the address used to access the data register, PADDR[9:2].
 * Bits that are 1 in the address mask cause the corresponding bits in GPIODATA
 * to be read, and bits that are 0 in the address mask cause the corresponding
 * bits in GPIODATA to be read as 0, regardless of their value.
 */
static enum gpio_level pl061_get_value(unsigned int gpio_pin)
{
	vaddr_t base_addr;
	unsigned int offset;

	assert(gpio_pin < PLAT_PL061_MAX_GPIOS);

	base_addr = pl061_reg_base[gpio_pin / GPIOS_PER_PL061];
	offset = gpio_pin % GPIOS_PER_PL061;
	if (io_read8(base_addr + BIT(offset + 2)))
		return GPIO_LEVEL_HIGH;
	return GPIO_LEVEL_LOW;
}

/*
 * In order to write GPIODATA, the corresponding bits in the mask, resulting
 * from the address bus, PADDR[9:2], must be HIGH. Otherwise the bit values
 * remain unchanged by the write.
 */
static void pl061_set_value(unsigned int gpio_pin, enum gpio_level value)
{
	vaddr_t base_addr;
	unsigned int offset;

	assert(gpio_pin < PLAT_PL061_MAX_GPIOS);

	base_addr = pl061_reg_base[gpio_pin / GPIOS_PER_PL061];
	offset = gpio_pin % GPIOS_PER_PL061;
	if (value == GPIO_LEVEL_HIGH)
		io_write8(base_addr + BIT(offset + 2), BIT(offset));
	else
		io_write8(base_addr + BIT(offset + 2), 0);
}

static enum gpio_interrupt pl061_get_interrupt(unsigned int gpio_pin)
{
	vaddr_t base_addr;
	uint8_t data;
	unsigned int offset;

	assert(gpio_pin < PLAT_PL061_MAX_GPIOS);

	base_addr = pl061_reg_base[gpio_pin / GPIOS_PER_PL061];
	offset = gpio_pin % GPIOS_PER_PL061;
	data = io_read8(base_addr + GPIOIE);
	if (data & BIT(offset))
		return GPIO_INTERRUPT_ENABLE;
	return GPIO_INTERRUPT_DISABLE;
}

static void pl061_set_interrupt(unsigned int gpio_pin,
	enum gpio_interrupt ena_dis)
{
	vaddr_t base_addr;
	unsigned int offset;

	assert(gpio_pin < PLAT_PL061_MAX_GPIOS);

	base_addr = pl061_reg_base[gpio_pin / GPIOS_PER_PL061];
	offset = gpio_pin % GPIOS_PER_PL061;
	if (ena_dis == GPIO_INTERRUPT_ENABLE)
		io_setbits8(base_addr + GPIOIE, BIT(offset));
	else
		io_clrbits8(base_addr + GPIOIE, BIT(offset));
}

/*
 * Register the PL061 GPIO controller with a base address and the offset
 * of start pin in this GPIO controller.
 * This function is called after pl061_init().
 */
void pl061_register(vaddr_t base_addr, unsigned int gpio_dev)
{
	assert(gpio_dev < MAX_GPIO_DEVICES);

	pl061_reg_base[gpio_dev] = base_addr;
}

static const struct gpio_ops pl061_ops = {
	.get_direction = pl061_get_direction,
	.set_direction = pl061_set_direction,
	.get_value = pl061_get_value,
	.set_value = pl061_set_value,
	.get_interrupt = pl061_get_interrupt,
	.set_interrupt = pl061_set_interrupt,
};
KEEP_PAGER(pl061_ops);

/*
 * Initialize PL061 GPIO controller
 */
void pl061_init(struct pl061_data *pd)
{
	COMPILE_TIME_ASSERT(PLAT_PL061_MAX_GPIOS > 0);

	assert(pd);
	pd->chip.ops = &pl061_ops;
}

enum pl061_mode_control pl061_get_mode_control(unsigned int gpio_pin)
{
	vaddr_t base_addr;
	uint8_t data;
	unsigned int offset;

	assert(gpio_pin < PLAT_PL061_MAX_GPIOS);

	base_addr = pl061_reg_base[gpio_pin / GPIOS_PER_PL061];
	offset = gpio_pin % GPIOS_PER_PL061;
	data = io_read8(base_addr + GPIOAFSEL);
	if (data & BIT(offset))
		return PL061_MC_HW;
	return PL061_MC_SW;
}

void pl061_set_mode_control(unsigned int gpio_pin,
	enum pl061_mode_control hw_sw)
{
	vaddr_t base_addr;
	unsigned int offset;

	assert(gpio_pin < PLAT_PL061_MAX_GPIOS);

	base_addr = pl061_reg_base[gpio_pin / GPIOS_PER_PL061];
	offset = gpio_pin % GPIOS_PER_PL061;
	if (hw_sw == PL061_MC_HW)
		io_setbits8(base_addr + GPIOAFSEL, BIT(offset));
	else
		io_clrbits8(base_addr + GPIOAFSEL, BIT(offset));
}
