// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2016 Google, Inc
 */

#include <common.h>
#include <dm.h>
#include <errno.h>
#include <fdtdec.h>
#include <log.h>
#include <pch.h>
#include <pci.h>
#include <asm/cpu.h>
#include <asm/global_data.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/pci.h>
#include <dm/pinctrl.h>

DECLARE_GLOBAL_DATA_PTR;

#define GPIO_USESEL_OFFSET(x)	(x)
#define GPIO_IOSEL_OFFSET(x)	(x + 4)
#define GPIO_LVL_OFFSET(x)	((x) ? (x) + 8 : 0xc)
#define GPI_INV			0x2c

#define IOPAD_MODE_MASK			0x7
#define IOPAD_PULL_ASSIGN_SHIFT		7
#define IOPAD_PULL_ASSIGN_MASK		(0x3 << IOPAD_PULL_ASSIGN_SHIFT)
#define IOPAD_PULL_STRENGTH_SHIFT	9
#define IOPAD_PULL_STRENGTH_MASK	(0x3 << IOPAD_PULL_STRENGTH_SHIFT)

static int ich6_pinctrl_set_value(uint16_t base, unsigned offset, int value)
{
	if (value)
		setio_32(base, 1UL << offset);
	else
		clrio_32(base, 1UL << offset);

	return 0;
}

static int ich6_pinctrl_set_function(uint16_t base, unsigned offset, int func)
{
	if (func)
		setio_32(base, 1UL << offset);
	else
		clrio_32(base, 1UL << offset);

	return 0;
}

static int ich6_pinctrl_set_direction(uint16_t base, unsigned offset, int dir)
{
	if (!dir)
		setio_32(base, 1UL << offset);
	else
		clrio_32(base, 1UL << offset);

	return 0;
}

static int ich6_pinctrl_cfg_pin(s32 gpiobase, s32 iobase, int pin_node)
{
	bool is_gpio, invert;
	u32 gpio_offset[2];
	int pad_offset;
	int dir, val;
	int ret;

	/*
	 * GPIO node is not mandatory, so we only do the pinmuxing if the
	 * node exists.
	 */
	ret = fdtdec_get_int_array(gd->fdt_blob, pin_node, "gpio-offset",
				   gpio_offset, 2);
	if (!ret) {
		/* Do we want to force the GPIO mode? */
		is_gpio = fdtdec_get_bool(gd->fdt_blob, pin_node, "mode-gpio");
		if (is_gpio)
			ich6_pinctrl_set_function(GPIO_USESEL_OFFSET(gpiobase) +
						gpio_offset[0], gpio_offset[1],
						1);

		dir = fdtdec_get_int(gd->fdt_blob, pin_node, "direction", -1);
		if (dir != -1)
			ich6_pinctrl_set_direction(GPIO_IOSEL_OFFSET(gpiobase) +
						 gpio_offset[0], gpio_offset[1],
						 dir);

		val = fdtdec_get_int(gd->fdt_blob, pin_node, "output-value",
				     -1);
		if (val != -1)
			ich6_pinctrl_set_value(GPIO_LVL_OFFSET(gpiobase) +
					     gpio_offset[0], gpio_offset[1],
					     val);

		invert = fdtdec_get_bool(gd->fdt_blob, pin_node, "invert");
		if (invert)
			setio_32(gpiobase + GPI_INV, 1 << gpio_offset[1]);
		debug("gpio %#x bit %d, is_gpio %d, dir %d, val %d, invert %d\n",
		      gpio_offset[0], gpio_offset[1], is_gpio, dir, val,
		      invert);
	}

	/* if iobase is present, let's configure the pad */
	if (iobase != -1) {
		ulong iobase_addr;

		/*
		 * The offset for the same pin for the IOBASE and GPIOBASE are
		 * different, so instead of maintaining a lookup table,
		 * the device tree should provide directly the correct
		 * value for both mapping.
		 */
		pad_offset = fdtdec_get_int(gd->fdt_blob, pin_node,
					    "pad-offset", -1);
		if (pad_offset == -1)
			return 0;

		/* compute the absolute pad address */
		iobase_addr = iobase + pad_offset;

		/*
		 * Do we need to set a specific function mode?
		 * If someone put also 'mode-gpio', this option will
		 * be just ignored by the controller
		 */
		val = fdtdec_get_int(gd->fdt_blob, pin_node, "mode-func", -1);
		if (val != -1)
			clrsetbits_le32(iobase_addr, IOPAD_MODE_MASK, val);

		/* Configure the pull-up/down if needed */
		val = fdtdec_get_int(gd->fdt_blob, pin_node, "pull-assign", -1);
		if (val != -1)
			clrsetbits_le32(iobase_addr,
					IOPAD_PULL_ASSIGN_MASK,
					val << IOPAD_PULL_ASSIGN_SHIFT);

		val = fdtdec_get_int(gd->fdt_blob, pin_node, "pull-strength",
				     -1);
		if (val != -1)
			clrsetbits_le32(iobase_addr,
					IOPAD_PULL_STRENGTH_MASK,
					val << IOPAD_PULL_STRENGTH_SHIFT);

		debug("%s: pad cfg [0x%x]: %08x\n", __func__, pad_offset,
		      readl(iobase_addr));
	}

	return 0;
}

static int ich6_pinctrl_probe(struct udevice *dev)
{
	struct udevice *pch;
	int pin_node;
	int ret;
	u32 gpiobase;
	u32 iobase = -1;

	debug("%s: start\n", __func__);
	ret = uclass_first_device(UCLASS_PCH, &pch);
	if (ret)
		return ret;
	if (!pch)
		return -ENODEV;

	/*
	 * Get the memory/io base address to configure every pins.
	 * IOBASE is used to configure the mode/pads
	 * GPIOBASE is used to configure the direction and default value
	 */
	ret = pch_get_gpio_base(pch, &gpiobase);
	if (ret) {
		debug("%s: invalid GPIOBASE address (%08x)\n", __func__,
		      gpiobase);
		return -EINVAL;
	}

	/*
	 * Get the IOBASE, this is not mandatory as this is not
	 * supported by all the CPU
	 */
	ret = pch_get_io_base(pch, &iobase);
	if (ret && ret != -ENOSYS) {
		debug("%s: invalid IOBASE address (%08x)\n", __func__, iobase);
		return -EINVAL;
	}

	for (pin_node = fdt_first_subnode(gd->fdt_blob, dev_of_offset(dev));
	     pin_node > 0;
	     pin_node = fdt_next_subnode(gd->fdt_blob, pin_node)) {
		/* Configure the pin */
		ret = ich6_pinctrl_cfg_pin(gpiobase, iobase, pin_node);
		if (ret != 0) {
			debug("%s: invalid configuration for the pin %d\n",
			      __func__, pin_node);
			return ret;
		}
	}
	debug("%s: done\n", __func__);

	return 0;
}

static const struct udevice_id ich6_pinctrl_match[] = {
	{ .compatible = "intel,x86-pinctrl", .data = X86_SYSCON_PINCONF },
	{ /* sentinel */ }
};

U_BOOT_DRIVER(ich6_pinctrl) = {
	.name = "ich6_pinctrl",
	.id = UCLASS_SYSCON,
	.of_match = ich6_pinctrl_match,
	.probe = ich6_pinctrl_probe,
};
