// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2018 Emlid Limited
 */

#include <common.h>
#include <dm.h>
#include <log.h>
#include <dm/pinctrl.h>
#include <dm/read.h>
#include <regmap.h>
#include <syscon.h>
#include <asm/cpu.h>
#include <asm/scu.h>
#include <linux/io.h>
#include <linux/printk.h>

#define BUFCFG_OFFSET				0x100

#define MRFLD_FAMILY_LEN			0x400

/* These are taken from Linux kernel */
#define MRFLD_PINMODE_MASK			0x07

#define pin_to_bufno(f, p)			((p) - (f)->pin_base)

struct mrfld_family {
	unsigned int family_number;
	unsigned int pin_base;
	size_t npins;
	void __iomem *regs;
};

#define MRFLD_FAMILY(b, s, e)				\
	{						\
		.family_number = (b),			\
		.pin_base = (s),			\
		.npins = (e) - (s) + 1,			\
	}

/* Now we only support SD/SDIO and I2C families of pins */
static struct mrfld_family mrfld_families[] = {
	MRFLD_FAMILY(3, 37, 56),
	MRFLD_FAMILY(7, 101, 114),
};

struct mrfld_pinctrl {
	const struct mrfld_family *families;
	size_t nfamilies;
};

static const struct mrfld_family *
mrfld_get_family(struct mrfld_pinctrl *mp, unsigned int pin)
{
	const struct mrfld_family *family;
	unsigned int i;

	for (i = 0; i < mp->nfamilies; i++) {
		family = &mp->families[i];
		if (pin >= family->pin_base &&
		    pin < family->pin_base + family->npins)
			return family;
	}

	pr_err("failed to find family for pin %u\n", pin);
	return NULL;
}

static void __iomem *
mrfld_get_bufcfg(struct mrfld_pinctrl *pinctrl, unsigned int pin)
{
	const struct mrfld_family *family;
	unsigned int bufno;

	family =  mrfld_get_family(pinctrl, pin);
	if (!family)
		return NULL;

	bufno = pin_to_bufno(family, pin);

	return family->regs + BUFCFG_OFFSET + bufno * 4;
}

static void
mrfld_setup_families(void *base_addr,
		     struct mrfld_family *families, unsigned int nfam)
{
	for (int i = 0; i < nfam; i++) {
		struct mrfld_family *family = &families[i];

		family->regs = base_addr +
			       family->family_number * MRFLD_FAMILY_LEN;
	}
}

static int mrfld_pinconfig_protected(unsigned int pin, u32 mask, u32 bits)
{
	struct mrfld_pinctrl *pinctrl;
	struct udevice *dev;
	void __iomem *bufcfg;
	u32 v, value;
	int ret;

	ret = syscon_get_by_driver_data(X86_SYSCON_PINCONF, &dev);
	if (ret)
		return ret;

	pinctrl = dev_get_priv(dev);

	bufcfg = mrfld_get_bufcfg(pinctrl, pin);
	if (!bufcfg)
		return -EINVAL;

	value = readl(bufcfg);

	v = (value & ~mask) | (bits & mask);

	debug("scu: v: 0x%x p: 0x%x bits: %d, mask: %d bufcfg: 0x%p\n",
	      v, (u32)bufcfg, bits, mask, bufcfg);

	return scu_ipc_raw_command(IPCMSG_INDIRECT_WRITE, 0, &v, 4, NULL, 0, (u32)bufcfg, 0);
}

static int mrfld_pinconfig(unsigned int pin, u32 mask, u32 bits)
{
	struct mrfld_pinctrl *pinctrl;
	struct udevice *dev;
	void __iomem *bufcfg;
	u32 v, value;
	int ret;

	ret = syscon_get_by_driver_data(X86_SYSCON_PINCONF, &dev);
	if (ret)
		return ret;

	pinctrl = dev_get_priv(dev);

	bufcfg = mrfld_get_bufcfg(pinctrl, pin);
	if (!bufcfg)
		return -EINVAL;

	value = readl(bufcfg);
	v = (value & ~mask) | (bits & mask);
	writel(v, bufcfg);

	debug("v: 0x%x p: 0x%x bits: %d, mask: %d bufcfg: 0x%p\n",
	      v, (u32)bufcfg, bits, mask, bufcfg);

	return 0;
}

static int mrfld_pinctrl_cfg_pin(ofnode pin_node)
{
	bool is_protected;
	int pad_offset;
	int mode;
	u32 mask;
	int ret;

	pad_offset = ofnode_read_s32_default(pin_node, "pad-offset", -1);
	if (pad_offset == -1)
		return -EINVAL;

	mode = ofnode_read_s32_default(pin_node, "mode-func", -1);
	if (mode == -1)
		return -EINVAL;

	mask = MRFLD_PINMODE_MASK;

	/* We don't support modes not in range 0..7 */
	if (mode & ~mask)
		return -ENOTSUPP;

	is_protected = ofnode_read_bool(pin_node, "protected");
	if (is_protected)
		ret = mrfld_pinconfig_protected(pad_offset, mask, mode);
	else
		ret = mrfld_pinconfig(pad_offset, mask, mode);
	if (ret)
		pr_err("Failed to set mode for pin %u (%d)\n", pad_offset, ret);

	return ret;
}

static int tangier_pinctrl_probe(struct udevice *dev)
{
	void *base_addr = syscon_get_first_range(X86_SYSCON_PINCONF);
	struct mrfld_pinctrl *pinctrl = dev_get_priv(dev);
	ofnode pin_node;
	int ret;

	mrfld_setup_families(base_addr, mrfld_families,
			     ARRAY_SIZE(mrfld_families));

	pinctrl->families = mrfld_families;
	pinctrl->nfamilies = ARRAY_SIZE(mrfld_families);

	ofnode_for_each_subnode(pin_node, dev_ofnode(dev)) {
		ret = mrfld_pinctrl_cfg_pin(pin_node);
		if (ret) {
			pr_err("%s: invalid configuration for the pin %ld\n",
			       __func__, pin_node.of_offset);
		}
	}

	return 0;
}

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

U_BOOT_DRIVER(tangier_pinctrl) = {
	.name = "tangier_pinctrl",
	.id = UCLASS_SYSCON,
	.of_match = tangier_pinctrl_match,
	.probe = tangier_pinctrl_probe,
	.priv_auto	= sizeof(struct mrfld_pinctrl),
};
