// SPDX-License-Identifier: GPL-2.0+
/*
 * Pinctrl driver for Nexell SoCs
 * (C) Copyright 2016 Nexell
 * Bongyu, KOO <freestyle@nexell.co.kr>
 *
 * (C) Copyright 2019 Stefan Bosch <stefan_b@posteo.net>
 */

#include <common.h>
#include <dm.h>
#include <errno.h>
#include <asm/io.h>
#include <dm/pinctrl.h>
#include <dm/root.h>
#include "pinctrl-nexell.h"
#include "pinctrl-s5pxx18.h"

DECLARE_GLOBAL_DATA_PTR;

static void nx_gpio_set_bit(u32 *value, u32 bit, int enable)
{
	register u32 newvalue;

	newvalue = *value;
	newvalue &= ~(1ul << bit);
	newvalue |= (u32)enable << bit;
	writel(newvalue, value);
}

static void nx_gpio_set_bit2(u32 *value, u32 bit, u32 bit_value)
{
	register u32 newvalue = *value;

	newvalue = (u32)(newvalue & ~(3ul << (bit * 2)));
	newvalue = (u32)(newvalue | (bit_value << (bit * 2)));

	writel(newvalue, value);
}

static int nx_gpio_open_module(void *base)
{
	writel(0xFFFFFFFF, base + GPIOX_SLEW_DISABLE_DEFAULT);
	writel(0xFFFFFFFF, base + GPIOX_DRV1_DISABLE_DEFAULT);
	writel(0xFFFFFFFF, base + GPIOX_DRV0_DISABLE_DEFAULT);
	writel(0xFFFFFFFF, base + GPIOX_PULLSEL_DISABLE_DEFAULT);
	writel(0xFFFFFFFF, base + GPIOX_PULLENB_DISABLE_DEFAULT);
	return true;
}

static void nx_gpio_set_pad_function(void *base, u32 pin, u32 padfunc)
{
	u32 reg = (pin / 16) ? GPIOX_ALTFN1 : GPIOX_ALTFN0;

	nx_gpio_set_bit2(base + reg, pin % 16, padfunc);
}

static void nx_gpio_set_drive_strength(void *base, u32 pin, u32 drv)
{
	nx_gpio_set_bit(base + GPIOX_DRV1, pin, (int)(((u32)drv >> 0) & 0x1));
	nx_gpio_set_bit(base + GPIOX_DRV0, pin, (int)(((u32)drv >> 1) & 0x1));
}

static void nx_gpio_set_pull_mode(void *base, u32 pin, u32 mode)
{
	if (mode == nx_gpio_pull_off) {
		nx_gpio_set_bit(base + GPIOX_PULLENB, pin, false);
		nx_gpio_set_bit(base + GPIOX_PULLSEL, pin, false);
	} else {
		nx_gpio_set_bit(base + GPIOX_PULLSEL,
				pin, (mode & 1 ? true : false));
		nx_gpio_set_bit(base + GPIOX_PULLENB, pin, true);
	}
}

static void nx_alive_set_pullup(void *base, u32 pin, bool enable)
{
	u32 PULLUP_MASK;

	PULLUP_MASK = (1UL << pin);
	if (enable)
		writel(PULLUP_MASK, base + ALIVE_PADPULLUPSET);
	else
		writel(PULLUP_MASK, base + ALIVE_PADPULLUPRST);
}

static int s5pxx18_pinctrl_gpio_init(struct udevice *dev)
{
	struct nexell_pinctrl_priv *priv = dev_get_priv(dev);
	const struct nexell_pin_ctrl *ctrl = priv->pin_ctrl;
	unsigned long reg = priv->base;
	int i;

	for (i = 0; i < ctrl->nr_banks - 1; i++) /* except alive bank */
		nx_gpio_open_module((void *)(reg + ctrl->pin_banks[i].offset));

	return 0;
}

static int s5pxx18_pinctrl_alive_init(struct udevice *dev)
{
	struct nexell_pinctrl_priv *priv = dev_get_priv(dev);
	const struct nexell_pin_ctrl *ctrl = priv->pin_ctrl;
	unsigned long reg = priv->base;

	reg += ctrl->pin_banks[ctrl->nr_banks - 1].offset;

	writel(1, reg + ALIVE_PWRGATE);
	return 0;
}

int s5pxx18_pinctrl_init(struct udevice *dev)
{
	s5pxx18_pinctrl_gpio_init(dev);
	s5pxx18_pinctrl_alive_init(dev);

	return 0;
}

static int is_pin_alive(const char *name)
{
	return !strncmp(name, "alive", 5);
}

/**
 * s5pxx18_pinctrl_set_state: configure a pin state.
 * dev: the pinctrl device to be configured.
 * config: the state to be configured.
 */
static int s5pxx18_pinctrl_set_state(struct udevice *dev,
				     struct udevice *config)
{
	unsigned int count, idx, pin;
	unsigned int pinfunc, pinpud, pindrv;
	unsigned long reg;
	const char *name;
	int ret;

	/*
	 * refer to the following document for the pinctrl bindings
	 * doc/device-tree-bindings/pinctrl/nexell,s5pxx18-pinctrl.txt
	 */
	count = dev_read_string_count(config, "pins");

	if (count <= 0)
		return -EINVAL;

	pinfunc = dev_read_s32_default(config, "pin-function", -1);
	pinpud = dev_read_s32_default(config, "pin-pull", -1);
	pindrv = dev_read_s32_default(config, "pin-strength", -1);

	for (idx = 0; idx < count; idx++) {
		ret = dev_read_string_index(config, "pins", idx, &name);
		if (ret)
			return ret;
		if (!name)
			continue;
		reg = pin_to_bank_base(dev, name, &pin);

		if (is_pin_alive(name)) {
			/* pin pull up/down */
			if (pinpud != -1)
				nx_alive_set_pullup((void *)reg, pin,
						    pinpud & 1);
			continue;
		}

		/* pin function */
		if (pinfunc != -1)
			nx_gpio_set_pad_function((void *)reg, pin, pinfunc);

		/* pin pull up/down/off */
		if (pinpud != -1)
			nx_gpio_set_pull_mode((void *)reg, pin, pinpud);

		/* pin drive strength */
		if (pindrv != -1)
			nx_gpio_set_drive_strength((void *)reg, pin, pindrv);
	}

	return 0;
}

static struct pinctrl_ops s5pxx18_pinctrl_ops = {
	.set_state	= s5pxx18_pinctrl_set_state,
};

/* pin banks of s5pxx18 pin-controller */
static const struct nexell_pin_bank_data s5pxx18_pin_banks[] = {
	NEXELL_PIN_BANK(32, 0xA000, "gpioa"),
	NEXELL_PIN_BANK(32, 0xB000, "gpiob"),
	NEXELL_PIN_BANK(32, 0xC000, "gpioc"),
	NEXELL_PIN_BANK(32, 0xD000, "gpiod"),
	NEXELL_PIN_BANK(32, 0xE000, "gpioe"),
	NEXELL_PIN_BANK(6, 0x0800, "alive"),
};

const struct nexell_pin_ctrl s5pxx18_pin_ctrl[] = {
	{
		/* pin-controller data */
		.pin_banks	= s5pxx18_pin_banks,
		.nr_banks	= ARRAY_SIZE(s5pxx18_pin_banks),
	},
};

static const struct udevice_id s5pxx18_pinctrl_ids[] = {
	{ .compatible = "nexell,s5pxx18-pinctrl",
		.data = (ulong)s5pxx18_pin_ctrl },
	{ }
};

U_BOOT_DRIVER(pinctrl_s5pxx18) = {
	.name		= "pinctrl_s5pxx18",
	.id		= UCLASS_PINCTRL,
	.of_match	= s5pxx18_pinctrl_ids,
	.priv_auto_alloc_size = sizeof(struct nexell_pinctrl_priv),
	.ops		= &s5pxx18_pinctrl_ops,
	.probe		= nexell_pinctrl_probe,
	.flags		= DM_FLAG_PRE_RELOC
};
