// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
 * Microsemi SoCs serial gpio driver
 *
 * Author: <lars.povlsen@microchip.com>
 *
 * Copyright (c) 2018 Microsemi Corporation
 */

#include <dm.h>
#include <log.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <errno.h>
#include <clk.h>
#include <dm/device_compat.h>
#include <linux/bitops.h>
#include <linux/err.h>

#define MSCC_SGPIOS_PER_BANK	32
#define MSCC_SGPIO_BANK_DEPTH	4

enum {
	REG_INPUT_DATA,
	REG_PORT_CONFIG,
	REG_PORT_ENABLE,
	REG_SIO_CONFIG,
	REG_SIO_CLOCK,
	MAXREG
};

struct mscc_sgpio_bf {
	u8 beg;
	u8 end;
};

struct mscc_sgpio_props {
	u8 regoff[MAXREG];
	struct mscc_sgpio_bf auto_repeat;
	struct mscc_sgpio_bf port_width;
	struct mscc_sgpio_bf clk_freq;
	struct mscc_sgpio_bf bit_source;
};

#define __M(bf)		GENMASK((bf).end, (bf).beg)
#define __F(bf, x)	(__M(bf) & ((x) << (bf).beg))
#define __X(bf, x)	(((x) >> (bf).beg) & GENMASK(((bf).end - (bf).beg), 0))

#define MSCC_M_CFG_SIO_AUTO_REPEAT(p)		BIT(p->props->auto_repeat.beg)
#define MSCC_F_CFG_SIO_PORT_WIDTH(p, x)		__F(p->props->port_width, x)
#define MSCC_M_CFG_SIO_PORT_WIDTH(p)		__M(p->props->port_width)
#define MSCC_F_CLOCK_SIO_CLK_FREQ(p, x)		__F(p->props->clk_freq, x)
#define MSCC_M_CLOCK_SIO_CLK_FREQ(p)		__M(p->props->clk_freq)
#define MSCC_F_PORT_CFG_BIT_SOURCE(p, x)	__F(p->props->bit_source, x)
#define MSCC_X_PORT_CFG_BIT_SOURCE(p, x)	__X(p->props->bit_source, x)

const struct mscc_sgpio_props props_luton = {
	.regoff = { 0x00, 0x09, 0x29, 0x2a, 0x2b },
	.auto_repeat = { 5, 5 },
	.port_width  = { 2, 3 },
	.clk_freq    = { 0, 11 },
	.bit_source  = { 0, 11 },
};

const struct mscc_sgpio_props props_ocelot = {
	.regoff = { 0x00, 0x06, 0x26, 0x04, 0x05 },
	.auto_repeat = { 10, 10 },
	.port_width  = {  7, 8  },
	.clk_freq    = {  8, 19 },
	.bit_source  = { 12, 23 },
};

struct mscc_sgpio_priv {
	u32 bitcount;
	u32 ports;
	u32 clock;
	u32 mode[MSCC_SGPIOS_PER_BANK];
	u32 __iomem *regs;
	const struct mscc_sgpio_props *props;
};

static inline u32 sgpio_readl(struct mscc_sgpio_priv *priv, u32 rno, u32 off)
{
	u32 __iomem *reg = &priv->regs[priv->props->regoff[rno] + off];

	return readl(reg);
}

static inline void sgpio_writel(struct mscc_sgpio_priv *priv,
				u32 val, u32 rno, u32 off)
{
	u32 __iomem *reg = &priv->regs[priv->props->regoff[rno] + off];

	writel(val, reg);
}

static void sgpio_clrsetbits(struct mscc_sgpio_priv *priv,
			     u32 rno, u32 off, u32 clear, u32 set)
{
	u32 __iomem *reg = &priv->regs[priv->props->regoff[rno] + off];

	clrsetbits_le32(reg, clear, set);
}

static int mscc_sgpio_direction_input(struct udevice *dev, unsigned int gpio)
{
	struct mscc_sgpio_priv *priv = dev_get_priv(dev);

	u32 port = gpio % MSCC_SGPIOS_PER_BANK;
	u32 bit = gpio / MSCC_SGPIOS_PER_BANK;

	priv->mode[port] |= BIT(bit);

	return 0;
}

static int mscc_sgpio_direction_output(struct udevice *dev,
				       unsigned int gpio, int value)
{
	struct mscc_sgpio_priv *priv = dev_get_priv(dev);
	u32 port = gpio % MSCC_SGPIOS_PER_BANK;
	u32 bit = gpio / MSCC_SGPIOS_PER_BANK;
	u32 mask = 3 << (3 * bit);

	debug("set: port %d, bit %d, mask 0x%08x, value %d\n",
	      port, bit, mask, value);

	value = (value & 3) << (3 * bit);
	sgpio_clrsetbits(priv, REG_PORT_CONFIG, port,
			 MSCC_F_PORT_CFG_BIT_SOURCE(priv, mask),
			 MSCC_F_PORT_CFG_BIT_SOURCE(priv, value));
	clrbits_le32(&priv->mode[port], BIT(bit));

	return 0;
}

static int mscc_sgpio_get_function(struct udevice *dev, unsigned int gpio)
{
	struct mscc_sgpio_priv *priv = dev_get_priv(dev);
	u32 port = gpio % MSCC_SGPIOS_PER_BANK;
	u32 bit = gpio / MSCC_SGPIOS_PER_BANK;
	u32 val = priv->mode[port] & BIT(bit);

	if (val)
		return GPIOF_INPUT;
	else
		return GPIOF_OUTPUT;
}

static int mscc_sgpio_set_value(struct udevice *dev,
				unsigned int gpio, int value)
{
	return mscc_sgpio_direction_output(dev, gpio, value);
}

static int mscc_sgpio_get_value(struct udevice *dev, unsigned int gpio)
{
	struct mscc_sgpio_priv *priv = dev_get_priv(dev);
	u32 port = gpio % MSCC_SGPIOS_PER_BANK;
	u32 bit = gpio / MSCC_SGPIOS_PER_BANK;
	int ret;

	if (mscc_sgpio_get_function(dev, gpio) == GPIOF_INPUT) {
		ret = !!(sgpio_readl(priv, REG_INPUT_DATA, bit) & BIT(port));
	} else {
		u32 portval = sgpio_readl(priv, REG_PORT_CONFIG, port);

		ret = MSCC_X_PORT_CFG_BIT_SOURCE(priv, portval);
		ret = !!(ret & (3 << (3 * bit)));
	}

	debug("get: gpio %d, port %d, bit %d, value %d\n",
	      gpio, port, bit, ret);
	return ret;
}

static int mscc_sgpio_get_count(struct udevice *dev)
{
	struct ofnode_phandle_args args;
	int count = 0, i = 0, ret;

	ret = dev_read_phandle_with_args(dev, "gpio-ranges", NULL, 3, i, &args);
	while (ret != -ENOENT) {
		count += args.args[2];
		ret = dev_read_phandle_with_args(dev, "gpio-ranges", NULL, 3,
						 ++i, &args);
	}
	return count;
}

static int mscc_sgpio_probe(struct udevice *dev)
{
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	struct mscc_sgpio_priv *priv = dev_get_priv(dev);
	int err, div_clock = 0, port;
	u32 val;
	struct clk clk;

	err = clk_get_by_index(dev, 0, &clk);
	if (!err) {
		err = clk_get_rate(&clk);
		if (IS_ERR_VALUE(err)) {
			dev_err(dev, "Invalid clk rate\n");
			return -EINVAL;
		}
		div_clock = err;
	} else {
		dev_err(dev, "Failed to get clock\n");
		return err;
	}

	priv->props = (const struct mscc_sgpio_props *)dev_get_driver_data(dev);
	priv->ports = dev_read_u32_default(dev, "mscc,sgpio-ports", 0xFFFFFFFF);
	priv->clock = dev_read_u32_default(dev, "mscc,sgpio-frequency",
					   12500000);
	if (priv->clock <= 0 || priv->clock > div_clock) {
		dev_err(dev, "Invalid frequency %d\n", priv->clock);
		return -EINVAL;
	}

	uc_priv->gpio_count = mscc_sgpio_get_count(dev);
	uc_priv->gpio_count = dev_read_u32_default(dev, "ngpios",
						   uc_priv->gpio_count);
	if (uc_priv->gpio_count < 1 || uc_priv->gpio_count >
	    (4 * MSCC_SGPIOS_PER_BANK)) {
		dev_err(dev, "Invalid gpio count %d\n", uc_priv->gpio_count);
		return -EINVAL;
	}
	priv->bitcount = DIV_ROUND_UP(uc_priv->gpio_count,
				      MSCC_SGPIOS_PER_BANK);
	debug("probe: gpios = %d, bit-count = %d\n",
	      uc_priv->gpio_count, priv->bitcount);

	priv->regs = dev_read_addr_ptr(dev);
	uc_priv->bank_name = "sgpio";

	sgpio_clrsetbits(priv, REG_SIO_CONFIG, 0,
			 MSCC_M_CFG_SIO_PORT_WIDTH(priv),
			 MSCC_F_CFG_SIO_PORT_WIDTH(priv, priv->bitcount - 1) |
			 MSCC_M_CFG_SIO_AUTO_REPEAT(priv));
	val = div_clock / priv->clock;
	debug("probe: div-clock = %d KHz, freq = %d KHz, div = %d\n",
	      div_clock / 1000, priv->clock / 1000, val);
	sgpio_clrsetbits(priv, REG_SIO_CLOCK, 0,
			 MSCC_M_CLOCK_SIO_CLK_FREQ(priv),
			 MSCC_F_CLOCK_SIO_CLK_FREQ(priv, val));

	for (port = 0; port < 32; port++)
		sgpio_writel(priv, 0, REG_PORT_CONFIG, port);
	sgpio_writel(priv, priv->ports, REG_PORT_ENABLE, 0);

	debug("probe: sgpio regs = %p\n", priv->regs);

	return 0;
}

static const struct dm_gpio_ops mscc_sgpio_ops = {
	.direction_input	= mscc_sgpio_direction_input,
	.direction_output	= mscc_sgpio_direction_output,
	.get_function		= mscc_sgpio_get_function,
	.get_value		= mscc_sgpio_get_value,
	.set_value		= mscc_sgpio_set_value,
};

static const struct udevice_id mscc_sgpio_ids[] = {
	{ .compatible = "mscc,luton-sgpio", .data = (ulong)&props_luton },
	{ .compatible = "mscc,ocelot-sgpio", .data = (ulong)&props_ocelot },
	{ }
};

U_BOOT_DRIVER(gpio_mscc_sgpio) = {
	.name			= "mscc-sgpio",
	.id			= UCLASS_GPIO,
	.of_match		= mscc_sgpio_ids,
	.ops			= &mscc_sgpio_ops,
	.probe			= mscc_sgpio_probe,
	.priv_auto	= sizeof(struct mscc_sgpio_priv),
};
