// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2016 Marvell International Ltd.
 * https://spdx.org/licenses
 */

#include <common.h>
#include <config.h>
#include <fdtdec.h>
#include <errno.h>
#include <dm.h>
#include <log.h>
#include <dm/pinctrl.h>
#include <dm/root.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/arch-armada8k/soc-info.h>
#include <linux/bitops.h>
#include "pinctrl-mvebu.h"

#define AP_EMMC_PHY_CTRL_REG		0x100
#define CP_EMMC_PHY_CTRL_REG		0x424
#define EMMC_PHY_CTRL_SDPHY_EN		BIT(0)

#define AP806_EMMC_CLK_PIN_ID		0
#define AP806_EMMC_CLK_FUNC		0x1
#define CP110_EMMC_CLK_PIN_ID		56
#define CP110_EMMC_CLK_FUNC		0xe

DECLARE_GLOBAL_DATA_PTR;

/* mvebu_pinctl_emmc_set_mux: configure sd/mmc PHY mux
 * To enable SDIO/eMMC in Armada-APN806/CP110, need to configure PHY mux.
 * eMMC/SD PHY register responsible for muxing between MPPs and SD/eMMC
 * controller:
 * - Bit0 enabled SDIO/eMMC PHY is used as a MPP muxltiplexer,
 * - Bit0 disabled SDIO/eMMC PHY is connected to SDIO/eMMC controller
 * If pin function is set to eMMC/SD, then configure the eMMC/SD PHY
 * muxltiplexer register to be on SDIO/eMMC controller
 */
void mvebu_pinctl_emmc_set_mux(struct udevice *dev, u32 pin, u32 func)
{
	const void *blob = gd->fdt_blob;
	int node = dev_of_offset(dev);
	struct mvebu_pinctrl_priv *priv = dev_get_priv(dev);

	if (!fdt_node_check_compatible(blob, node, "marvell,ap806-pinctrl")) {
		if ((pin == AP806_EMMC_CLK_PIN_ID) &&
		    (func == AP806_EMMC_CLK_FUNC)) {
			clrbits_le32(priv->base_reg + AP_EMMC_PHY_CTRL_REG,
				     EMMC_PHY_CTRL_SDPHY_EN);
		}
	} else if (!fdt_node_check_compatible(blob, node,
					"marvell,armada-8k-cpm-pinctrl")) {
		if ((pin == CP110_EMMC_CLK_PIN_ID) &&
		    (func == CP110_EMMC_CLK_FUNC)) {
			clrbits_le32(priv->base_reg + CP_EMMC_PHY_CTRL_REG,
				     EMMC_PHY_CTRL_SDPHY_EN);
		}
	}
}

/*
 * mvebu_pinctrl_set_state: configure pin functions.
 * @dev: the pinctrl device to be configured.
 * @config: the state to be configured.
 * @return: 0 in success
 */
int mvebu_pinctrl_set_state(struct udevice *dev, struct udevice *config)
{
	const void *blob = gd->fdt_blob;
	int node = dev_of_offset(config);
	struct mvebu_pinctrl_priv *priv;
	u32 pin_arr[MVEBU_MAX_PINS_PER_BANK];
	u32 function;
	int i, pin_count;

	priv = dev_get_priv(dev);

	pin_count = fdtdec_get_int_array_count(blob, node,
					       "marvell,pins",
					       pin_arr,
					       MVEBU_MAX_PINS_PER_BANK);
	if (pin_count <= 0) {
		debug("Failed reading pins array for pinconfig %s (%d)\n",
		      config->name, pin_count);
		return -EINVAL;
	}

	function = fdtdec_get_int(blob, node, "marvell,function", 0xff);

	/*
	 * Check if setup of PHY mux is needed for this pins group.
	 * Only the first pin id in array is tested, all the rest use the same
	 * pin function.
	 */
	mvebu_pinctl_emmc_set_mux(dev, pin_arr[0], function);

	for (i = 0; i < pin_count; i++) {
		int reg_offset;
		int field_offset;
		int pin = pin_arr[i];

		if (function > priv->max_func) {
			debug("Illegal function %d for pinconfig %s\n",
			      function, config->name);
			return -EINVAL;
		}

		/* Calculate register address and bit in register */
		reg_offset   = priv->reg_direction * 4 *
					(pin >> (PIN_REG_SHIFT));
		field_offset = (BITS_PER_PIN) * (pin & PIN_FIELD_MASK);

		clrsetbits_le32(priv->base_reg + reg_offset,
				PIN_FUNC_MASK << field_offset,
				(function & PIN_FUNC_MASK) << field_offset);
	}

	return 0;
}

/*
 * mvebu_pinctrl_set_state_all: configure the entire bank pin functions.
 * @dev: the pinctrl device to be configured.
 * @config: the state to be configured.
 * @return: 0 in success
 */
static int mvebu_pinctrl_set_state_all(struct udevice *dev,
				       struct udevice *config)
{
	const void *blob = gd->fdt_blob;
	int node = dev_of_offset(config);
	struct mvebu_pinctrl_priv *priv;
	u32 func_arr[MVEBU_MAX_PINS_PER_BANK];
	int pin, err;

	priv = dev_get_priv(dev);

	err = fdtdec_get_int_array(blob, node, "pin-func",
				   func_arr, priv->pin_cnt);
	if (err) {
		debug("Failed reading pin functions for bank %s\n",
		      priv->bank_name);
		return -EINVAL;
	}

	/* Check if setup of PHY mux is needed for this pins group. */
	if (priv->pin_cnt < CP110_EMMC_CLK_PIN_ID)
		mvebu_pinctl_emmc_set_mux(dev, AP806_EMMC_CLK_PIN_ID,
					  func_arr[AP806_EMMC_CLK_PIN_ID]);
	else
		mvebu_pinctl_emmc_set_mux(dev, CP110_EMMC_CLK_PIN_ID,
					  func_arr[CP110_EMMC_CLK_PIN_ID]);

	for (pin = 0; pin < priv->pin_cnt; pin++) {
		int reg_offset;
		int field_offset;
		u32 func = func_arr[pin];

		/* Bypass pins with function 0xFF */
		if (func == 0xff) {
			debug("Warning: pin %d value is not modified ", pin);
			debug("(kept as default)\n");
			continue;
		} else if (func > priv->max_func) {
			debug("Illegal function %d for pin %d\n", func, pin);
			return -EINVAL;
		}

		/* Calculate register address and bit in register */
		reg_offset   = priv->reg_direction * 4 *
					(pin >> (PIN_REG_SHIFT));
		field_offset = (BITS_PER_PIN) * (pin & PIN_FIELD_MASK);

		clrsetbits_le32(priv->base_reg + reg_offset,
				PIN_FUNC_MASK << field_offset,
				(func & PIN_FUNC_MASK) << field_offset);
	}

	return 0;
}

int mvebu_pinctl_probe(struct udevice *dev)
{
	const void *blob = gd->fdt_blob;
	int node = dev_of_offset(dev);
	struct mvebu_pinctrl_priv *priv;

	priv = dev_get_priv(dev);
	if (!priv) {
		debug("%s: Failed to get private\n", __func__);
		return -EINVAL;
	}

	priv->base_reg = dev_read_addr_ptr(dev);
	if (!priv->base_reg) {
		debug("%s: Failed to get base address\n", __func__);
		return -EINVAL;
	}

	priv->pin_cnt   = fdtdec_get_int(blob, node, "pin-count",
					MVEBU_MAX_PINS_PER_BANK);
	priv->max_func  = fdtdec_get_int(blob, node, "max-func",
					 MVEBU_MAX_FUNC);
	priv->bank_name = fdt_getprop(blob, node, "bank-name", NULL);

	priv->reg_direction = 1;
	if (fdtdec_get_bool(blob, node, "reverse-reg"))
		priv->reg_direction = -1;

	return mvebu_pinctrl_set_state_all(dev, dev);
}

static struct pinctrl_ops mvebu_pinctrl_ops = {
	.set_state	= mvebu_pinctrl_set_state
};

static const struct udevice_id mvebu_pinctrl_ids[] = {
	{ .compatible = "marvell,mvebu-pinctrl" },
	{ .compatible = "marvell,ap806-pinctrl" },
	{ .compatible = "marvell,armada-7k-pinctrl" },
	{ .compatible = "marvell,armada-8k-cpm-pinctrl" },
	{ .compatible = "marvell,armada-8k-cps-pinctrl" },
	{ }
};

U_BOOT_DRIVER(pinctrl_mvebu) = {
	.name		= "mvebu_pinctrl",
	.id		= UCLASS_PINCTRL,
	.of_match	= mvebu_pinctrl_ids,
	.priv_auto	= sizeof(struct mvebu_pinctrl_priv),
	.ops		= &mvebu_pinctrl_ops,
	.probe		= mvebu_pinctl_probe
};
