// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2010-2016, NVIDIA CORPORATION.
 * (based on tegra_gpio.c)
 */

#include <dm.h>
#include <malloc.h>
#include <errno.h>
#include <fdtdec.h>
#include <asm/io.h>
#include <asm/bitops.h>
#include <asm/gpio.h>
#include <dm/device-internal.h>
#include <dt-bindings/gpio/gpio.h>
#include "tegra186_gpio_priv.h"

struct tegra186_gpio_port_data {
	const char *name;
	uint32_t offset;
};

struct tegra186_gpio_ctlr_data {
	const struct tegra186_gpio_port_data *ports;
	uint32_t port_count;
};

struct tegra186_gpio_plat {
	const char *name;
	uint32_t *regs;
};

static uint32_t *tegra186_gpio_reg(struct udevice *dev, uint32_t reg,
				   uint32_t gpio)
{
	struct tegra186_gpio_plat *plat = dev_get_plat(dev);
	uint32_t index = (reg + (gpio * TEGRA186_GPIO_PER_GPIO_STRIDE)) / 4;

	return &(plat->regs[index]);
}

static int tegra186_gpio_set_out(struct udevice *dev, unsigned offset,
				 bool output)
{
	uint32_t *reg;
	uint32_t rval;

	reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_OUTPUT_CONTROL, offset);
	rval = readl(reg);
	if (output)
		rval &= ~TEGRA186_GPIO_OUTPUT_CONTROL_FLOATED;
	else
		rval |= TEGRA186_GPIO_OUTPUT_CONTROL_FLOATED;
	writel(rval, reg);

	reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_ENABLE_CONFIG, offset);
	rval = readl(reg);
	if (output)
		rval |= TEGRA186_GPIO_ENABLE_CONFIG_OUT;
	else
		rval &= ~TEGRA186_GPIO_ENABLE_CONFIG_OUT;
	rval |= TEGRA186_GPIO_ENABLE_CONFIG_ENABLE;
	writel(rval, reg);

	return 0;
}

static int tegra186_gpio_set_val(struct udevice *dev, unsigned offset, bool val)
{
	uint32_t *reg;
	uint32_t rval;

	reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_OUTPUT_VALUE, offset);
	rval = readl(reg);
	if (val)
		rval |= TEGRA186_GPIO_OUTPUT_VALUE_HIGH;
	else
		rval &= ~TEGRA186_GPIO_OUTPUT_VALUE_HIGH;
	writel(rval, reg);

	return 0;
}

static int tegra186_gpio_direction_input(struct udevice *dev, unsigned offset)
{
	return tegra186_gpio_set_out(dev, offset, false);
}

static int tegra186_gpio_direction_output(struct udevice *dev, unsigned offset,
				       int value)
{
	int ret;

	ret = tegra186_gpio_set_val(dev, offset, value != 0);
	if (ret)
		return ret;
	return tegra186_gpio_set_out(dev, offset, true);
}

static int tegra186_gpio_get_value(struct udevice *dev, unsigned offset)
{
	uint32_t *reg;
	uint32_t rval;

	reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_ENABLE_CONFIG, offset);
	rval = readl(reg);

	if (rval & TEGRA186_GPIO_ENABLE_CONFIG_OUT)
		reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_OUTPUT_VALUE,
					offset);
	else
		reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_INPUT, offset);

	rval = readl(reg);
	return !!rval;
}

static int tegra186_gpio_set_value(struct udevice *dev, unsigned offset,
				   int value)
{
	return tegra186_gpio_set_val(dev, offset, value != 0);
}

static int tegra186_gpio_get_function(struct udevice *dev, unsigned offset)
{
	uint32_t *reg;
	uint32_t rval;

	reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_ENABLE_CONFIG, offset);
	rval = readl(reg);
	if (rval & TEGRA186_GPIO_ENABLE_CONFIG_OUT)
		return GPIOF_OUTPUT;
	else
		return GPIOF_INPUT;
}

static int tegra186_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
			       struct ofnode_phandle_args *args)
{
	int gpio, port, ret;

	gpio = args->args[0];
	port = gpio / TEGRA186_GPIO_PER_GPIO_COUNT;
	ret = device_get_child(dev, port, &desc->dev);
	if (ret)
		return ret;
	desc->offset = gpio % TEGRA186_GPIO_PER_GPIO_COUNT;
	desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;

	return 0;
}

static const struct dm_gpio_ops tegra186_gpio_ops = {
	.direction_input	= tegra186_gpio_direction_input,
	.direction_output	= tegra186_gpio_direction_output,
	.get_value		= tegra186_gpio_get_value,
	.set_value		= tegra186_gpio_set_value,
	.get_function		= tegra186_gpio_get_function,
	.xlate			= tegra186_gpio_xlate,
};

/**
 * We have a top-level GPIO device with no actual GPIOs. It has a child device
 * for each port within the controller.
 */
static int tegra186_gpio_bind(struct udevice *parent)
{
	struct tegra186_gpio_plat *parent_plat = dev_get_plat(parent);
	struct tegra186_gpio_ctlr_data *ctlr_data =
		(struct tegra186_gpio_ctlr_data *)dev_get_driver_data(parent);
	uint32_t *regs;
	int port, ret;

	/* If this is a child device, there is nothing to do here */
	if (parent_plat)
		return 0;

	regs = dev_read_addr_name_ptr(parent, "gpio");
	if (!regs)
		return -EINVAL;

	for (port = 0; port < ctlr_data->port_count; port++) {
		struct tegra186_gpio_plat *plat;
		struct udevice *dev;

		plat = calloc(1, sizeof(*plat));
		if (!plat)
			return -ENOMEM;
		plat->name = ctlr_data->ports[port].name;
		plat->regs = &(regs[ctlr_data->ports[port].offset / 4]);

		ret = device_bind(parent, parent->driver, plat->name, plat,
				  dev_ofnode(parent), &dev);
		if (ret)
			return ret;
	}

	return 0;
}

static int tegra186_gpio_probe(struct udevice *dev)
{
	struct tegra186_gpio_plat *plat = dev_get_plat(dev);
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);

	/* Only child devices have ports */
	if (!plat)
		return 0;

	uc_priv->gpio_count = TEGRA186_GPIO_PER_GPIO_COUNT;
	uc_priv->bank_name = plat->name;

	return 0;
}

static const struct tegra186_gpio_port_data tegra186_gpio_main_ports[] = {
	{"A",  0x2000},
	{"B",  0x3000},
	{"C",  0x3200},
	{"D",  0x3400},
	{"E",  0x2200},
	{"F",  0x2400},
	{"G",  0x4200},
	{"H",  0x1000},
	{"I",  0x0800},
	{"J",  0x5000},
	{"K",  0x5200},
	{"L",  0x1200},
	{"M",  0x5600},
	{"N",  0x0000},
	{"O",  0x0200},
	{"P",  0x4000},
	{"Q",  0x0400},
	{"R",  0x0a00},
	{"T",  0x0600},
	{"X",  0x1400},
	{"Y",  0x1600},
	{"BB", 0x2600},
	{"CC", 0x5400},
};

static const struct tegra186_gpio_ctlr_data tegra186_gpio_main_data = {
	.ports = tegra186_gpio_main_ports,
	.port_count = ARRAY_SIZE(tegra186_gpio_main_ports),
};

static const struct tegra186_gpio_port_data tegra186_gpio_aon_ports[] = {
	{"S",  0x0200},
	{"U",  0x0400},
	{"V",  0x0800},
	{"W",  0x0a00},
	{"Z",  0x0e00},
	{"AA", 0x0c00},
	{"EE", 0x0600},
	{"FF", 0x0000},
};

static const struct tegra186_gpio_ctlr_data tegra186_gpio_aon_data = {
	.ports = tegra186_gpio_aon_ports,
	.port_count = ARRAY_SIZE(tegra186_gpio_aon_ports),
};

static const struct udevice_id tegra186_gpio_ids[] = {
	{
		.compatible = "nvidia,tegra186-gpio",
		.data = (ulong)&tegra186_gpio_main_data,
	},
	{
		.compatible = "nvidia,tegra186-gpio-aon",
		.data = (ulong)&tegra186_gpio_aon_data,
	},
	{ }
};

U_BOOT_DRIVER(tegra186_gpio) = {
	.name = "tegra186_gpio",
	.id = UCLASS_GPIO,
	.of_match = tegra186_gpio_ids,
	.bind = tegra186_gpio_bind,
	.probe = tegra186_gpio_probe,
	.ops = &tegra186_gpio_ops,
};
