/*
 * Pinctrl driver for STMicroelectronics STi SoCs
 *
 *  Copyright (c) 2017
 *  Patrice Chotard <patrice.chotard@st.com>
 *
 * SPDX-License-Identifier:	GPL-2.0
 */

#include <common.h>
#include <bitfield.h>
#include <dm.h>
#include <errno.h>
#include <regmap.h>
#include <syscon.h>
#include <asm/io.h>
#include <dm/pinctrl.h>

DECLARE_GLOBAL_DATA_PTR;

#define MAX_STI_PINCONF_ENTRIES		7
/* Output enable */
#define OE			(1 << 27)
/* Pull Up */
#define PU			(1 << 26)
/* Open Drain */
#define OD			(1 << 25)

/* User-frendly defines for Pin Direction */
		/* oe = 0, pu = 0, od = 0 */
#define IN			(0)
		/* oe = 0, pu = 1, od = 0 */
#define IN_PU			(PU)
		/* oe = 1, pu = 0, od = 0 */
#define OUT			(OE)
		/* oe = 1, pu = 1, od = 0 */
#define OUT_PU			(OE | PU)
		/* oe = 1, pu = 0, od = 1 */
#define BIDIR			(OE | OD)
		/* oe = 1, pu = 1, od = 1 */
#define BIDIR_PU		(OE | PU | OD)

struct sti_pinctrl_platdata {
	struct regmap *regmap;
};

struct sti_pin_desc {
	unsigned char bank;
	unsigned char pin;
	unsigned char alt;
	int dir;
};

/*
 * PIO alternative Function selector
 */
void sti_alternate_select(struct udevice *dev, struct sti_pin_desc *pin_desc)
{
	struct sti_pinctrl_platdata *plat = dev_get_platdata(dev);
	unsigned long sysconf, *sysconfreg;
	int alt = pin_desc->alt;
	int bank = pin_desc->bank;
	int pin = pin_desc->pin;

	sysconfreg = (unsigned long *)plat->regmap->base;

	switch (bank) {
	case 0 ... 5:		/* in "SBC Bank" */
		sysconfreg += bank;
		break;
	case 10 ... 20:		/* in "FRONT Bank" */
		sysconfreg += bank - 10;
		break;
	case 30 ... 35:		/* in "REAR Bank" */
		sysconfreg += bank - 30;
		break;
	case 40 ... 42:		/* in "FLASH Bank" */
		sysconfreg += bank - 40;
		break;
	default:
		BUG();
		return;
	}

	sysconf = readl(sysconfreg);
	sysconf = bitfield_replace(sysconf, pin * 4, 3, alt);
	writel(sysconf, sysconfreg);
}

/* pin configuration */
void sti_pin_configure(struct udevice *dev, struct sti_pin_desc *pin_desc)
{
	struct sti_pinctrl_platdata *plat = dev_get_platdata(dev);
	int bit;
	int oe = 0, pu = 0, od = 0;
	unsigned long *sysconfreg;
	int bank = pin_desc->bank;

	sysconfreg = (unsigned long *)plat->regmap->base + 40;

	/*
	 * NOTE: The PIO configuration for the PIO pins in the
	 * "FLASH Bank" are different from all the other banks!
	 * Specifically, the output-enable pin control register
	 * (SYS_CFG_3040) and the pull-up pin control register
	 * (SYS_CFG_3050), are both classed as being "reserved".
	 * Hence, we do not write to these registers to configure
	 * the OE and PU features for PIOs in this bank. However,
	 * the open-drain pin control register (SYS_CFG_3060)
	 * follows the style of the other banks, and so we can
	 * treat that register normally.
	 *
	 * Being pedantic, we should configure the PU and PD features
	 * in the "FLASH Bank" explicitly instead using the four
	 * SYS_CFG registers: 3080, 3081, 3085, and 3086. However, this
	 * would necessitate passing in the alternate function number
	 * to this function, and adding some horrible complexity here.
	 * Alternatively, we could just perform 4 32-bit "pokes" to
	 * these four SYS_CFG registers early in the initialization.
	 * In practice, these four SYS_CFG registers are correct
	 * after a reset, and U-Boot does not need to change them, so
	 * we (cheat and) rely on these registers being correct.
	 * WARNING: Please be aware of this (pragmatic) behaviour!
	 */
	int flashss = 0;	/* bool: PIO in the Flash Sub-System ? */

	switch (pin_desc->dir) {
	case IN:
		oe = 0; pu = 0; od = 0;
		break;
	case IN_PU:
		oe = 0; pu = 1; od = 0;
		break;
	case OUT:
		oe = 1; pu = 0; od = 0;
		break;
	case BIDIR:
		oe = 1; pu = 0; od = 1;
		break;
	case BIDIR_PU:
		oe = 1; pu = 1; od = 1;
		break;

	default:
		error("%s invalid direction value: 0x%x\n",
		      __func__, pin_desc->dir);
		BUG();
		break;
	}

	switch (bank) {
	case 0 ... 5:		/* in "SBC Bank" */
		sysconfreg += bank / 4;
		break;
	case 10 ... 20:		/* in "FRONT Bank" */
		bank -= 10;
		sysconfreg += bank / 4;
		break;
	case 30 ... 35:		/* in "REAR Bank" */
		bank -= 30;
		sysconfreg += bank / 4;
		break;
	case 40 ... 42:		/* in "FLASH Bank" */
		bank -= 40;
		sysconfreg += bank / 4;
		flashss = 1;	/* pin is in the Flash Sub-System */
		break;
	default:
		BUG();
		return;
	}

	bit = ((bank * 8) + pin_desc->pin) % 32;

	/*
	 * set the "Output Enable" pin control
	 * but, do nothing if in the flashSS
	 */
	if (!flashss) {
		if (oe)
			generic_set_bit(bit, sysconfreg);
		else
			generic_clear_bit(bit, sysconfreg);
	}

	sysconfreg += 10;	/* skip to next set of syscfg registers */

	/*
	 * set the "Pull Up" pin control
	 * but, do nothing if in the FlashSS
	 */

	if (!flashss) {
		if (pu)
			generic_set_bit(bit, sysconfreg);
		else
			generic_clear_bit(bit, sysconfreg);
	}

	sysconfreg += 10;	/* skip to next set of syscfg registers */

	/* set the "Open Drain Enable" pin control */
	if (od)
		generic_set_bit(bit, sysconfreg);
	else
		generic_clear_bit(bit, sysconfreg);
}


static int sti_pinctrl_set_state(struct udevice *dev, struct udevice *config)
{
	struct fdtdec_phandle_args args;
	const void *blob = gd->fdt_blob;
	const char *prop_name;
	int node = dev_of_offset(config);
	int property_offset, prop_len;
	int pinconf_node, ret, count;
	const char *bank_name;
	u32 cells[MAX_STI_PINCONF_ENTRIES];

	struct sti_pin_desc pin_desc;

	/* go to next node "st,pins" which contains the pins configuration */
	pinconf_node = fdt_subnode_offset(blob, node, "st,pins");

	/*
	 * parse each pins configuration which looks like :
	 *	pin_name = <bank_phandle pin_nb alt dir rt_type rt_delay rt_clk>
	 */

	fdt_for_each_property_offset(property_offset, blob, pinconf_node) {
		fdt_getprop_by_offset(blob, property_offset, &prop_name,
				      &prop_len);

		/* extract the bank of the pin description */
		ret = fdtdec_parse_phandle_with_args(blob, pinconf_node,
						     prop_name, "#gpio-cells",
						     0, 0, &args);
		if (ret < 0) {
			error("Can't get the gpio bank phandle: %d\n", ret);
			return ret;
		}

		bank_name = fdt_getprop(blob, args.node, "st,bank-name",
					&count);
		if (count < 0) {
			error("Can't find bank-name property %d\n", count);
			return -EINVAL;
		}

		pin_desc.bank = trailing_strtoln(bank_name, NULL);

		count = fdtdec_get_int_array_count(blob, pinconf_node,
						   prop_name, cells,
						   ARRAY_SIZE(cells));
		if (count < 0) {
			error("Bad pin configuration array %d\n", count);
			return -EINVAL;
		}

		if (count > MAX_STI_PINCONF_ENTRIES) {
			error("Unsupported pinconf array count %d\n", count);
			return -EINVAL;
		}

		pin_desc.pin = cells[1];
		pin_desc.alt = cells[2];
		pin_desc.dir = cells[3];

		sti_alternate_select(dev, &pin_desc);
		sti_pin_configure(dev, &pin_desc);
	};

	return 0;
}

static int sti_pinctrl_probe(struct udevice *dev)
{
	struct sti_pinctrl_platdata *plat = dev_get_platdata(dev);
	struct udevice *syscon;
	int err;

	/* get corresponding syscon phandle */
	err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
					   "st,syscfg", &syscon);
	if (err) {
		error("unable to find syscon device\n");
		return err;
	}

	plat->regmap = syscon_get_regmap(syscon);
	if (!plat->regmap) {
		error("unable to find regmap\n");
		return -ENODEV;
	}

	return 0;
}

static const struct udevice_id sti_pinctrl_ids[] = {
	{ .compatible = "st,stih407-sbc-pinctrl" },
	{ .compatible = "st,stih407-front-pinctrl" },
	{ .compatible = "st,stih407-rear-pinctrl" },
	{ .compatible = "st,stih407-flash-pinctrl" },
	{ }
};

const struct pinctrl_ops sti_pinctrl_ops = {
	.set_state = sti_pinctrl_set_state,
};

U_BOOT_DRIVER(pinctrl_sti) = {
	.name = "pinctrl_sti",
	.id = UCLASS_PINCTRL,
	.of_match = sti_pinctrl_ids,
	.ops = &sti_pinctrl_ops,
	.probe = sti_pinctrl_probe,
	.platdata_auto_alloc_size = sizeof(struct sti_pinctrl_platdata),
	.ops = &sti_pinctrl_ops,
};
