// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2016
 * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
 *
 * based on arch/powerpc/include/asm/mpc85xx_gpio.h, which is
 *
 * Copyright 2010 eXMeritus, A Boeing Company
 * Copyright 2020 NXP
 */

#include <common.h>
#include <dm.h>
#include <mapmem.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <dm/of_access.h>

struct ccsr_gpio {
	u32	gpdir;
	u32	gpodr;
	u32	gpdat;
	u32	gpier;
	u32	gpimr;
	u32	gpicr;
	u32	gpibe;
};

struct mpc8xxx_gpio_data {
	/* The bank's register base in memory */
	struct ccsr_gpio __iomem *base;
	/* The address of the registers; used to identify the bank */
	ulong addr;
	/* The GPIO count of the bank */
	uint gpio_count;
	/* The GPDAT register cannot be used to determine the value of output
	 * pins on MPC8572/MPC8536, so we shadow it and use the shadowed value
	 * for output pins
	 */
	u32 dat_shadow;
	ulong type;
	bool  little_endian;
};

enum {
	MPC8XXX_GPIO_TYPE,
	MPC5121_GPIO_TYPE,
};

inline u32 gpio_mask(uint gpio)
{
	return (1U << (31 - (gpio)));
}

static inline u32 mpc8xxx_gpio_get_val(struct udevice *dev, u32 mask)
{
	struct mpc8xxx_gpio_data *data = dev_get_priv(dev);

	if (data->little_endian)
		return in_le32(&data->base->gpdat) & mask;
	else
		return in_be32(&data->base->gpdat) & mask;
}

static inline u32 mpc8xxx_gpio_get_dir(struct udevice *dev, u32 mask)
{
	struct mpc8xxx_gpio_data *data = dev_get_priv(dev);

	if (data->little_endian)
		return in_le32(&data->base->gpdir) & mask;
	else
		return in_be32(&data->base->gpdir) & mask;
}

static inline int mpc8xxx_gpio_open_drain_val(struct udevice *dev, u32 mask)
{
	struct mpc8xxx_gpio_data *data = dev_get_priv(dev);

	if (data->little_endian)
		return in_le32(&data->base->gpodr) & mask;
	else
		return in_be32(&data->base->gpodr) & mask;
}

static inline void mpc8xxx_gpio_open_drain_on(struct udevice *dev, u32
					      gpios)
{
	struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
	/* GPODR register 1 -> open drain on */
	if (data->little_endian)
		setbits_le32(&data->base->gpodr, gpios);
	else
		setbits_be32(&data->base->gpodr, gpios);
}

static inline void mpc8xxx_gpio_open_drain_off(struct udevice *dev,
					       u32 gpios)
{
	struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
	/* GPODR register 0 -> open drain off (actively driven) */
	if (data->little_endian)
		clrbits_le32(&data->base->gpodr, gpios);
	else
		clrbits_be32(&data->base->gpodr, gpios);
}

static int mpc8xxx_gpio_direction_input(struct udevice *dev, uint gpio)
{
	struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
	u32 mask = gpio_mask(gpio);

	/* GPDIR register 0 -> input */
	if (data->little_endian)
		clrbits_le32(&data->base->gpdir, mask);
	else
		clrbits_be32(&data->base->gpdir, mask);

	return 0;
}

static int mpc8xxx_gpio_set_value(struct udevice *dev, uint gpio, int value)
{
	struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
	struct ccsr_gpio *base = data->base;
	u32 mask = gpio_mask(gpio);
	u32 gpdir;

	if (value) {
		data->dat_shadow |= mask;
	} else {
		data->dat_shadow &= ~mask;
	}

	if (data->little_endian)
		gpdir = in_le32(&base->gpdir);
	else
		gpdir = in_be32(&base->gpdir);

	gpdir |= gpio_mask(gpio);

	if (data->little_endian) {
		out_le32(&base->gpdat, gpdir & data->dat_shadow);
		out_le32(&base->gpdir, gpdir);
	} else {
		out_be32(&base->gpdat, gpdir & data->dat_shadow);
		out_be32(&base->gpdir, gpdir);
	}

	return 0;
}

static int mpc8xxx_gpio_direction_output(struct udevice *dev, uint gpio,
					 int value)
{
	struct mpc8xxx_gpio_data *data = dev_get_priv(dev);

	/* GPIO 28..31 are input only on MPC5121 */
	if (data->type == MPC5121_GPIO_TYPE && gpio >= 28)
		return -EINVAL;

	return mpc8xxx_gpio_set_value(dev, gpio, value);
}

static int mpc8xxx_gpio_get_value(struct udevice *dev, uint gpio)
{
	struct mpc8xxx_gpio_data *data = dev_get_priv(dev);

	if (!!mpc8xxx_gpio_get_dir(dev, gpio_mask(gpio))) {
		/* Output -> use shadowed value */
		return !!(data->dat_shadow & gpio_mask(gpio));
	}

	/* Input -> read value from GPDAT register */
	return !!mpc8xxx_gpio_get_val(dev, gpio_mask(gpio));
}

static int mpc8xxx_gpio_get_function(struct udevice *dev, uint gpio)
{
	int dir;

	dir = !!mpc8xxx_gpio_get_dir(dev, gpio_mask(gpio));
	return dir ? GPIOF_OUTPUT : GPIOF_INPUT;
}

#if CONFIG_IS_ENABLED(OF_CONTROL)
static int mpc8xxx_gpio_of_to_plat(struct udevice *dev)
{
	struct mpc8xxx_gpio_plat *plat = dev_get_plat(dev);
	struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
	fdt_addr_t addr;
	u32 i;
	u32 reg[4];

	if (ofnode_read_bool(dev->node, "little-endian"))
		data->little_endian = true;

	if (data->little_endian)
		dev_read_u32_array(dev, "reg", reg, 4);
	else
		dev_read_u32_array(dev, "reg", reg, 2);

	if (data->little_endian) {
		for (i = 0; i < 2; i++)
			reg[i] = be32_to_cpu(reg[i]);
	}

	addr = dev_translate_address(dev, reg);

	plat->addr = addr;

	if (data->little_endian)
		plat->size = reg[3];
	else
		plat->size = reg[1];

	plat->ngpios = dev_read_u32_default(dev, "ngpios", 32);

	return 0;
}
#endif

static int mpc8xxx_gpio_platdata_to_priv(struct udevice *dev)
{
	struct mpc8xxx_gpio_data *priv = dev_get_priv(dev);
	struct mpc8xxx_gpio_plat *plat = dev_get_plat(dev);
	unsigned long size = plat->size;
	ulong driver_data = dev_get_driver_data(dev);

	if (size == 0)
		size = 0x100;

	priv->addr = plat->addr;
	priv->base = map_sysmem(plat->addr, size);

	if (!priv->base)
		return -ENOMEM;

	priv->gpio_count = plat->ngpios;
	priv->dat_shadow = 0;

	priv->type = driver_data;

	return 0;
}

static int mpc8xxx_gpio_probe(struct udevice *dev)
{
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
	char name[32], *str;

	mpc8xxx_gpio_platdata_to_priv(dev);

	snprintf(name, sizeof(name), "MPC@%lx_", data->addr);
	str = strdup(name);

	if (!str)
		return -ENOMEM;

	if (ofnode_device_is_compatible(dev->node, "fsl,qoriq-gpio")) {
		unsigned long gpibe = data->addr + sizeof(struct ccsr_gpio)
			- sizeof(u32);

		out_be32((unsigned int *)gpibe, 0xffffffff);
	}

	uc_priv->bank_name = str;
	uc_priv->gpio_count = data->gpio_count;

	return 0;
}

static const struct dm_gpio_ops gpio_mpc8xxx_ops = {
	.direction_input	= mpc8xxx_gpio_direction_input,
	.direction_output	= mpc8xxx_gpio_direction_output,
	.get_value		= mpc8xxx_gpio_get_value,
	.set_value		= mpc8xxx_gpio_set_value,
	.get_function		= mpc8xxx_gpio_get_function,
};

static const struct udevice_id mpc8xxx_gpio_ids[] = {
	{ .compatible = "fsl,pq3-gpio", .data = MPC8XXX_GPIO_TYPE },
	{ .compatible = "fsl,mpc8308-gpio", .data = MPC8XXX_GPIO_TYPE },
	{ .compatible = "fsl,mpc8349-gpio", .data = MPC8XXX_GPIO_TYPE },
	{ .compatible = "fsl,mpc8572-gpio", .data = MPC8XXX_GPIO_TYPE},
	{ .compatible = "fsl,mpc8610-gpio", .data = MPC8XXX_GPIO_TYPE},
	{ .compatible = "fsl,mpc5121-gpio", .data = MPC5121_GPIO_TYPE, },
	{ .compatible = "fsl,qoriq-gpio", .data = MPC8XXX_GPIO_TYPE },
	{ /* sentinel */ }
};

U_BOOT_DRIVER(gpio_mpc8xxx) = {
	.name	= "gpio_mpc8xxx",
	.id	= UCLASS_GPIO,
	.ops	= &gpio_mpc8xxx_ops,
#if CONFIG_IS_ENABLED(OF_CONTROL)
	.of_to_plat = mpc8xxx_gpio_of_to_plat,
	.plat_auto	= sizeof(struct mpc8xxx_gpio_plat),
	.of_match = mpc8xxx_gpio_ids,
#endif
	.probe	= mpc8xxx_gpio_probe,
	.priv_auto	= sizeof(struct mpc8xxx_gpio_data),
};
