// 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 <dm/pinctrl.h>
#include <dm/root.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/arch-armada8k/soc-info.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 = devfdt_get_addr_ptr(dev);
	if (priv->base_reg == (void *)FDT_ADDR_T_NONE) {
		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_alloc_size = sizeof(struct mvebu_pinctrl_priv),
	.ops		= &mvebu_pinctrl_ops,
	.probe		= mvebu_pinctl_probe
};
