// 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_err(UCLASS_PCH, &pch);
	if (ret)
		return ret;

	/*
	 * 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,
};
