// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2019 Rockchip Electronics Co., Ltd
 */

#include <common.h>
#include <dm.h>
#include <dm/pinctrl.h>
#include <regmap.h>
#include <syscon.h>
#include <fdtdec.h>

#include "pinctrl-rockchip.h"

#define MAX_ROCKCHIP_PINS_ENTRIES	30
#define MAX_ROCKCHIP_GPIO_PER_BANK      32
#define RK_FUNC_GPIO                    0

static int rockchip_verify_config(struct udevice *dev, u32 bank, u32 pin)
{
	struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
	struct rockchip_pin_ctrl *ctrl = priv->ctrl;

	if (bank >= ctrl->nr_banks) {
		debug("pin conf bank %d >= nbanks %d\n", bank, ctrl->nr_banks);
		return -EINVAL;
	}

	if (pin >= MAX_ROCKCHIP_GPIO_PER_BANK) {
		debug("pin conf pin %d >= %d\n", pin,
		      MAX_ROCKCHIP_GPIO_PER_BANK);
		return -EINVAL;
	}

	return 0;
}

static void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin,
				      int *reg, u8 *bit, int *mask)
{
	struct rockchip_pinctrl_priv *priv = bank->priv;
	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
	struct rockchip_mux_recalced_data *data;
	int i;

	for (i = 0; i < ctrl->niomux_recalced; i++) {
		data = &ctrl->iomux_recalced[i];
		if (data->num == bank->bank_num &&
		    data->pin == pin)
			break;
	}

	if (i >= ctrl->niomux_recalced)
		return;

	*reg = data->reg;
	*mask = data->mask;
	*bit = data->bit;
}

static bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
				   int mux, u32 *reg, u32 *value)
{
	struct rockchip_pinctrl_priv *priv = bank->priv;
	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
	struct rockchip_mux_route_data *data;
	int i;

	for (i = 0; i < ctrl->niomux_routes; i++) {
		data = &ctrl->iomux_routes[i];
		if (data->bank_num == bank->bank_num &&
		    data->pin == pin && data->func == mux)
			break;
	}

	if (i >= ctrl->niomux_routes)
		return false;

	*reg = data->route_offset;
	*value = data->route_val;

	return true;
}

static int rockchip_get_mux_data(int mux_type, int pin, u8 *bit, int *mask)
{
	int offset = 0;

	if (mux_type & IOMUX_WIDTH_4BIT) {
		if ((pin % 8) >= 4)
			offset = 0x4;
		*bit = (pin % 4) * 4;
		*mask = 0xf;
	} else if (mux_type & IOMUX_WIDTH_3BIT) {
		/*
		 * pin0 ~ pin4 are at first register, and
		 * pin5 ~ pin7 are at second register.
		 */
		if ((pin % 8) >= 5)
			offset = 0x4;
		*bit = (pin % 8 % 5) * 3;
		*mask = 0x7;
	} else {
		*bit = (pin % 8) * 2;
		*mask = 0x3;
	}

	return offset;
}

static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
{
	struct rockchip_pinctrl_priv *priv = bank->priv;
	int iomux_num = (pin / 8);
	struct regmap *regmap;
	unsigned int val;
	int reg, ret, mask, mux_type;
	u8 bit;

	if (iomux_num > 3)
		return -EINVAL;

	if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
		debug("pin %d is unrouted\n", pin);
		return -EINVAL;
	}

	if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
		return RK_FUNC_GPIO;

	regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
				? priv->regmap_pmu : priv->regmap_base;

	/* get basic quadrupel of mux registers and the correct reg inside */
	mux_type = bank->iomux[iomux_num].type;
	reg = bank->iomux[iomux_num].offset;
	reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);

	if (bank->recalced_mask & BIT(pin))
		rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);

	ret = regmap_read(regmap, reg, &val);
	if (ret)
		return ret;

	return ((val >> bit) & mask);
}

static int rockchip_pinctrl_get_gpio_mux(struct udevice *dev, int banknum,
					 int index)
{	struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
	struct rockchip_pin_ctrl *ctrl = priv->ctrl;

	return rockchip_get_mux(&ctrl->pin_banks[banknum], index);
}

static int rockchip_verify_mux(struct rockchip_pin_bank *bank,
			       int pin, int mux)
{
	int iomux_num = (pin / 8);

	if (iomux_num > 3)
		return -EINVAL;

	if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
		debug("pin %d is unrouted\n", pin);
		return -EINVAL;
	}

	if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) {
		if (mux != IOMUX_GPIO_ONLY) {
			debug("pin %d only supports a gpio mux\n", pin);
			return -ENOTSUPP;
		}
	}

	return 0;
}

/*
 * Set a new mux function for a pin.
 *
 * The register is divided into the upper and lower 16 bit. When changing
 * a value, the previous register value is not read and changed. Instead
 * it seems the changed bits are marked in the upper 16 bit, while the
 * changed value gets set in the same offset in the lower 16 bit.
 * All pin settings seem to be 2 bit wide in both the upper and lower
 * parts.
 * @bank: pin bank to change
 * @pin: pin to change
 * @mux: new mux function to set
 */
static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
{
	struct rockchip_pinctrl_priv *priv = bank->priv;
	int iomux_num = (pin / 8);
	struct regmap *regmap;
	int reg, ret, mask, mux_type;
	u8 bit;
	u32 data, route_reg, route_val;

	ret = rockchip_verify_mux(bank, pin, mux);
	if (ret < 0)
		return ret;

	if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
		return 0;

	debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);

	regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
				? priv->regmap_pmu : priv->regmap_base;

	/* get basic quadrupel of mux registers and the correct reg inside */
	mux_type = bank->iomux[iomux_num].type;
	reg = bank->iomux[iomux_num].offset;
	reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);

	if (bank->recalced_mask & BIT(pin))
		rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);

	if (bank->route_mask & BIT(pin)) {
		if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
					   &route_val)) {
			ret = regmap_write(regmap, route_reg, route_val);
			if (ret)
				return ret;
		}
	}

	if (mux_type & IOMUX_WRITABLE_32BIT) {
		regmap_read(regmap, reg, &data);
		data &= ~(mask << bit);
	} else {
		data = (mask << (bit + 16));
	}

	data |= (mux & mask) << bit;
	ret = regmap_write(regmap, reg, data);

	return ret;
}

static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = {
	{ 2, 4, 8, 12, -1, -1, -1, -1 },
	{ 3, 6, 9, 12, -1, -1, -1, -1 },
	{ 5, 10, 15, 20, -1, -1, -1, -1 },
	{ 4, 6, 8, 10, 12, 14, 16, 18 },
	{ 4, 7, 10, 13, 16, 19, 22, 26 }
};

static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
				     int pin_num, int strength)
{
	struct rockchip_pinctrl_priv *priv = bank->priv;
	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
	struct regmap *regmap;
	int reg, ret, i;
	u32 data, rmask_bits, temp;
	u8 bit;
	/* Where need to clean the special mask for rockchip_perpin_drv_list */
	int drv_type = bank->drv[pin_num / 8].drv_type & (~DRV_TYPE_IO_MASK);

	debug("setting drive of GPIO%d-%d to %d\n", bank->bank_num,
	      pin_num, strength);

	ctrl->drv_calc_reg(bank, pin_num, &regmap, &reg, &bit);

	ret = -EINVAL;
	for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) {
		if (rockchip_perpin_drv_list[drv_type][i] == strength) {
			ret = i;
			break;
		} else if (rockchip_perpin_drv_list[drv_type][i] < 0) {
			ret = rockchip_perpin_drv_list[drv_type][i];
			break;
		}
	}

	if (ret < 0) {
		debug("unsupported driver strength %d\n", strength);
		return ret;
	}

	switch (drv_type) {
	case DRV_TYPE_IO_1V8_3V0_AUTO:
	case DRV_TYPE_IO_3V3_ONLY:
		rmask_bits = ROCKCHIP_DRV_3BITS_PER_PIN;
		switch (bit) {
		case 0 ... 12:
			/* regular case, nothing to do */
			break;
		case 15:
			/*
			 * drive-strength offset is special, as it is spread
			 * over 2 registers, the bit data[15] contains bit 0
			 * of the value while temp[1:0] contains bits 2 and 1
			 */
			data = (ret & 0x1) << 15;
			temp = (ret >> 0x1) & 0x3;

			data |= BIT(31);
			ret = regmap_write(regmap, reg, data);
			if (ret)
				return ret;

			temp |= (0x3 << 16);
			reg += 0x4;
			ret = regmap_write(regmap, reg, temp);

			return ret;
		case 18 ... 21:
			/* setting fully enclosed in the second register */
			reg += 4;
			bit -= 16;
			break;
		default:
			debug("unsupported bit: %d for pinctrl drive type: %d\n",
			      bit, drv_type);
			return -EINVAL;
		}
		break;
	case DRV_TYPE_IO_DEFAULT:
	case DRV_TYPE_IO_1V8_OR_3V0:
	case DRV_TYPE_IO_1V8_ONLY:
		rmask_bits = ROCKCHIP_DRV_BITS_PER_PIN;
		break;
	default:
		debug("unsupported pinctrl drive type: %d\n",
		      drv_type);
		return -EINVAL;
	}

	if (bank->drv[pin_num / 8].drv_type & DRV_TYPE_WRITABLE_32BIT) {
		regmap_read(regmap, reg, &data);
		data &= ~(((1 << rmask_bits) - 1) << bit);
	} else {
		/* enable the write to the equivalent lower bits */
		data = ((1 << rmask_bits) - 1) << (bit + 16);
	}

	data |= (ret << bit);
	ret = regmap_write(regmap, reg, data);
	return ret;
}

static int rockchip_pull_list[PULL_TYPE_MAX][4] = {
	{
		PIN_CONFIG_BIAS_DISABLE,
		PIN_CONFIG_BIAS_PULL_UP,
		PIN_CONFIG_BIAS_PULL_DOWN,
		PIN_CONFIG_BIAS_BUS_HOLD
	},
	{
		PIN_CONFIG_BIAS_DISABLE,
		PIN_CONFIG_BIAS_PULL_DOWN,
		PIN_CONFIG_BIAS_DISABLE,
		PIN_CONFIG_BIAS_PULL_UP
	},
};

static int rockchip_set_pull(struct rockchip_pin_bank *bank,
			     int pin_num, int pull)
{
	struct rockchip_pinctrl_priv *priv = bank->priv;
	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
	struct regmap *regmap;
	int reg, ret, i, pull_type;
	u8 bit;
	u32 data;

	debug("setting pull of GPIO%d-%d to %d\n", bank->bank_num,
	      pin_num, pull);

	ctrl->pull_calc_reg(bank, pin_num, &regmap, &reg, &bit);

	switch (ctrl->type) {
	case RK3036:
	case RK3128:
		data = BIT(bit + 16);
		if (pull == PIN_CONFIG_BIAS_DISABLE)
			data |= BIT(bit);
		ret = regmap_write(regmap, reg, data);
		break;
	case RV1108:
	case RK3188:
	case RK3288:
	case RK3368:
	case RK3399:
		/*
		 * Where need to clean the special mask for
		 * rockchip_pull_list.
		 */
		pull_type = bank->pull_type[pin_num / 8] & (~PULL_TYPE_IO_MASK);
		ret = -EINVAL;
		for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]);
			i++) {
			if (rockchip_pull_list[pull_type][i] == pull) {
				ret = i;
				break;
			}
		}

		if (ret < 0) {
			debug("unsupported pull setting %d\n", pull);
			return ret;
		}

		if (bank->pull_type[pin_num / 8] & PULL_TYPE_WRITABLE_32BIT) {
			regmap_read(regmap, reg, &data);
			data &= ~(((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << bit);
		} else {
			/* enable the write to the equivalent lower bits */
			data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
		}

		data |= (ret << bit);
		ret = regmap_write(regmap, reg, data);
		break;
	default:
		debug("unsupported pinctrl type\n");
		return -EINVAL;
	}

	return ret;
}

static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
				int pin_num, int enable)
{
	struct rockchip_pinctrl_priv *priv = bank->priv;
	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
	struct regmap *regmap;
	int reg, ret;
	u8 bit;
	u32 data;

	debug("setting input schmitt of GPIO%d-%d to %d\n", bank->bank_num,
	      pin_num, enable);

	ret = ctrl->schmitt_calc_reg(bank, pin_num, &regmap, &reg, &bit);
	if (ret)
		return ret;

	/* enable the write to the equivalent lower bits */
	data = BIT(bit + 16) | (enable << bit);

	return regmap_write(regmap, reg, data);
}

/*
 * Pinconf_ops handling
 */
static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
					unsigned int pull)
{
	switch (ctrl->type) {
	case RK3036:
	case RK3128:
		return (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT ||
			pull == PIN_CONFIG_BIAS_DISABLE);
	case RV1108:
	case RK3188:
	case RK3288:
	case RK3368:
	case RK3399:
		return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT);
	}

	return false;
}

/* set the pin config settings for a specified pin */
static int rockchip_pinconf_set(struct rockchip_pin_bank *bank,
				u32 pin, u32 param, u32 arg)
{
	struct rockchip_pinctrl_priv *priv = bank->priv;
	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
	int rc;

	switch (param) {
	case PIN_CONFIG_BIAS_DISABLE:
		rc =  rockchip_set_pull(bank, pin, param);
		if (rc)
			return rc;
		break;

	case PIN_CONFIG_BIAS_PULL_UP:
	case PIN_CONFIG_BIAS_PULL_DOWN:
	case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
	case PIN_CONFIG_BIAS_BUS_HOLD:
		if (!rockchip_pinconf_pull_valid(ctrl, param))
			return -ENOTSUPP;

		if (!arg)
			return -EINVAL;

		rc = rockchip_set_pull(bank, pin, param);
		if (rc)
			return rc;
		break;

	case PIN_CONFIG_DRIVE_STRENGTH:
		if (!ctrl->drv_calc_reg)
			return -ENOTSUPP;

		rc = rockchip_set_drive_perpin(bank, pin, arg);
		if (rc < 0)
			return rc;
		break;

	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
		if (!ctrl->schmitt_calc_reg)
			return -ENOTSUPP;

		rc = rockchip_set_schmitt(bank, pin, arg);
		if (rc < 0)
			return rc;
		break;

	default:
		break;
	}

	return 0;
}

static const struct pinconf_param rockchip_conf_params[] = {
	{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
	{ "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 },
	{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
	{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
	{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
	{ "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
	{ "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
	{ "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
	{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
};

static int rockchip_pinconf_prop_name_to_param(const char *property,
					       u32 *default_value)
{
	const struct pinconf_param *p, *end;

	p = rockchip_conf_params;
	end = p + sizeof(rockchip_conf_params) / sizeof(struct pinconf_param);

	/* See if this pctldev supports this parameter */
	for (; p < end; p++) {
		if (!strcmp(property, p->property)) {
			*default_value = p->default_value;
			return p->param;
		}
	}

	*default_value = 0;
	return -EPERM;
}

static int rockchip_pinctrl_set_state(struct udevice *dev,
				      struct udevice *config)
{
	struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
	u32 cells[MAX_ROCKCHIP_PINS_ENTRIES * 4];
	u32 bank, pin, mux, conf, arg, default_val;
	int ret, count, i;
	const char *prop_name;
	const void *value;
	int prop_len, param;
	const u32 *data;
	ofnode node;
#ifdef CONFIG_OF_LIVE
	const struct device_node *np;
	struct property *pp;
#else
	int property_offset, pcfg_node;
	const void *blob = gd->fdt_blob;
#endif
	data = dev_read_prop(config, "rockchip,pins", &count);
	if (count < 0) {
		debug("%s: bad array size %d\n", __func__, count);
		return -EINVAL;
	}

	count /= sizeof(u32);
	if (count > MAX_ROCKCHIP_PINS_ENTRIES * 4) {
		debug("%s: unsupported pins array count %d\n",
		      __func__, count);
		return -EINVAL;
	}

	for (i = 0; i < count; i++)
		cells[i] = fdt32_to_cpu(data[i]);

	for (i = 0; i < (count >> 2); i++) {
		bank = cells[4 * i + 0];
		pin = cells[4 * i + 1];
		mux = cells[4 * i + 2];
		conf = cells[4 * i + 3];

		ret = rockchip_verify_config(dev, bank, pin);
		if (ret)
			return ret;

		ret = rockchip_set_mux(&ctrl->pin_banks[bank], pin, mux);
		if (ret)
			return ret;

		node = ofnode_get_by_phandle(conf);
		if (!ofnode_valid(node))
			return -ENODEV;
#ifdef CONFIG_OF_LIVE
		np = ofnode_to_np(node);
		for (pp = np->properties; pp; pp = pp->next) {
			prop_name = pp->name;
			prop_len = pp->length;
			value = pp->value;
#else
		pcfg_node = ofnode_to_offset(node);
		fdt_for_each_property_offset(property_offset, blob, pcfg_node) {
			value = fdt_getprop_by_offset(blob, property_offset,
						      &prop_name, &prop_len);
			if (!value)
				return -ENOENT;
#endif
			param = rockchip_pinconf_prop_name_to_param(prop_name,
								    &default_val);
			if (param < 0)
				break;

			if (prop_len >= sizeof(fdt32_t))
				arg = fdt32_to_cpu(*(fdt32_t *)value);
			else
				arg = default_val;

			ret = rockchip_pinconf_set(&ctrl->pin_banks[bank], pin,
						   param, arg);
			if (ret) {
				debug("%s: rockchip_pinconf_set fail: %d\n",
				      __func__, ret);
				return ret;
			}
		}
	}

	return 0;
}

const struct pinctrl_ops rockchip_pinctrl_ops = {
	.set_state			= rockchip_pinctrl_set_state,
	.get_gpio_mux			= rockchip_pinctrl_get_gpio_mux,
};

/* retrieve the soc specific data */
static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *dev)
{
	struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
	struct rockchip_pin_ctrl *ctrl =
			(struct rockchip_pin_ctrl *)dev_get_driver_data(dev);
	struct rockchip_pin_bank *bank;
	int grf_offs, pmu_offs, drv_grf_offs, drv_pmu_offs, i, j;

	grf_offs = ctrl->grf_mux_offset;
	pmu_offs = ctrl->pmu_mux_offset;
	drv_pmu_offs = ctrl->pmu_drv_offset;
	drv_grf_offs = ctrl->grf_drv_offset;
	bank = ctrl->pin_banks;

	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
		int bank_pins = 0;

		bank->priv = priv;
		bank->pin_base = ctrl->nr_pins;
		ctrl->nr_pins += bank->nr_pins;

		/* calculate iomux and drv offsets */
		for (j = 0; j < 4; j++) {
			struct rockchip_iomux *iom = &bank->iomux[j];
			struct rockchip_drv *drv = &bank->drv[j];
			int inc;

			if (bank_pins >= bank->nr_pins)
				break;

			/* preset iomux offset value, set new start value */
			if (iom->offset >= 0) {
				if (iom->type & IOMUX_SOURCE_PMU)
					pmu_offs = iom->offset;
				else
					grf_offs = iom->offset;
			} else { /* set current iomux offset */
				iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
							pmu_offs : grf_offs;
			}

			/* preset drv offset value, set new start value */
			if (drv->offset >= 0) {
				if (iom->type & IOMUX_SOURCE_PMU)
					drv_pmu_offs = drv->offset;
				else
					drv_grf_offs = drv->offset;
			} else { /* set current drv offset */
				drv->offset = (iom->type & IOMUX_SOURCE_PMU) ?
						drv_pmu_offs : drv_grf_offs;
			}

			debug("bank %d, iomux %d has iom_offset 0x%x drv_offset 0x%x\n",
			      i, j, iom->offset, drv->offset);

			/*
			 * Increase offset according to iomux width.
			 * 4bit iomux'es are spread over two registers.
			 */
			inc = (iom->type & (IOMUX_WIDTH_4BIT |
					    IOMUX_WIDTH_3BIT)) ? 8 : 4;
			if (iom->type & IOMUX_SOURCE_PMU)
				pmu_offs += inc;
			else
				grf_offs += inc;

			/*
			 * Increase offset according to drv width.
			 * 3bit drive-strenth'es are spread over two registers.
			 */
			if ((drv->drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) ||
			    (drv->drv_type == DRV_TYPE_IO_3V3_ONLY))
				inc = 8;
			else
				inc = 4;

			if (iom->type & IOMUX_SOURCE_PMU)
				drv_pmu_offs += inc;
			else
				drv_grf_offs += inc;

			bank_pins += 8;
		}

		/* calculate the per-bank recalced_mask */
		for (j = 0; j < ctrl->niomux_recalced; j++) {
			int pin = 0;

			if (ctrl->iomux_recalced[j].num == bank->bank_num) {
				pin = ctrl->iomux_recalced[j].pin;
				bank->recalced_mask |= BIT(pin);
			}
		}

		/* calculate the per-bank route_mask */
		for (j = 0; j < ctrl->niomux_routes; j++) {
			int pin = 0;

			if (ctrl->iomux_routes[j].bank_num == bank->bank_num) {
				pin = ctrl->iomux_routes[j].pin;
				bank->route_mask |= BIT(pin);
			}
		}
	}

	return ctrl;
}

int rockchip_pinctrl_probe(struct udevice *dev)
{
	struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
	struct rockchip_pin_ctrl *ctrl;
	struct udevice *syscon;
	struct regmap *regmap;
	int ret = 0;

	/* get rockchip grf syscon phandle */
	ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,grf",
					   &syscon);
	if (ret) {
		debug("unable to find rockchip,grf syscon device (%d)\n", ret);
		return ret;
	}

	/* get grf-reg base address */
	regmap = syscon_get_regmap(syscon);
	if (!regmap) {
		debug("unable to find rockchip grf regmap\n");
		return -ENODEV;
	}
	priv->regmap_base = regmap;

	/* option: get pmu-reg base address */
	ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,pmu",
					   &syscon);
	if (!ret) {
		/* get pmugrf-reg base address */
		regmap = syscon_get_regmap(syscon);
		if (!regmap) {
			debug("unable to find rockchip pmu regmap\n");
			return -ENODEV;
		}
		priv->regmap_pmu = regmap;
	}

	ctrl = rockchip_pinctrl_get_soc_data(dev);
	if (!ctrl) {
		debug("driver data not available\n");
		return -EINVAL;
	}

	priv->ctrl = ctrl;
	return 0;
}
