/*
 * Copyright (c) 2021-2023 IoT.bzh
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 */

#define DT_DRV_COMPAT renesas_rcar_pfc

#include "pfc_rcar.h"
#include <zephyr/arch/cpu.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/init.h>
#include <zephyr/sys/util.h>
#include <zephyr/sys/device_mmio.h>

#define PFC_RCAR_PMMR 0x0

/* Gen3 only has one base address, Gen4 has one per GPIO controller */
#if defined(CONFIG_SOC_SERIES_RCAR_GEN3)
#define PFC_RCAR_GPSR 0x100
#define PFC_RCAR_IPSR 0x200
#elif defined(CONFIG_SOC_SERIES_RCAR_GEN4)
#define PFC_RCAR_GPSR 0x040
#define PFC_RCAR_IPSR 0x060
#else
#error Unsupported SoC Series
#endif

/* swap both arguments */
#define PFC_REG_ADDRESS(idx, inst) DT_INST_REG_ADDR_BY_IDX(inst, idx)
static uintptr_t reg_base[] = {
	LISTIFY(DT_NUM_REGS(DT_DRV_INST(0)), PFC_REG_ADDRESS, (,), 0)
};

#define PFC_REG_SIZE(idx, inst) DT_INST_REG_SIZE_BY_IDX(inst, idx)
static const uintptr_t __maybe_unused reg_sizes[] = {
	LISTIFY(DT_NUM_REGS(DT_DRV_INST(0)), PFC_REG_SIZE, (,), 0)
};

#ifdef CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL
/* POC Control Register can control IO voltage level that is supplied to the pin */
struct pfc_pocctrl_reg {
	uint32_t offset;
	const uint16_t pins[32];
};
#endif /* CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL */

/*
 * Each drive step is either encoded in 2 or 3 bits.
 * So based on a 24 mA maximum value each step is either
 * 24/4 mA or 24/8 mA.
 */
#define PFC_RCAR_DRIVE_MAX 24U
#define PFC_RCAR_DRIVE_STEP(size) \
	(size == 2 ? PFC_RCAR_DRIVE_MAX / 4 : PFC_RCAR_DRIVE_MAX / 8)

/* Some registers such as IPSR GPSR or DRVCTRL are protected and
 * must be preceded to a write to PMMR with the inverse value.
 */
static void pfc_rcar_write(uintptr_t pfc_base, uint32_t offs, uint32_t val)
{
	sys_write32(~val, pfc_base + PFC_RCAR_PMMR);
	sys_write32(val, pfc_base + offs);
}

/* Set the pin either in gpio or peripheral */
static void pfc_rcar_set_gpsr(uintptr_t pfc_base,
			      uint16_t pin, bool peripheral)
{
#if defined(CONFIG_SOC_SERIES_RCAR_GEN3)
	/* On Gen3 we have multiple GPSR at one base address */
	uint8_t bank = pin / 32;
#elif defined(CONFIG_SOC_SERIES_RCAR_GEN4)
	/* On Gen4 we have one GPSR at multiple base address */
	uint8_t bank = 0;
#endif
	uint8_t bit = pin % 32;
	uint32_t val = sys_read32(pfc_base + PFC_RCAR_GPSR +
				  bank * sizeof(uint32_t));

	if (peripheral) {
		val |= BIT(bit);
	} else {
		val &= ~BIT(bit);
	}
	pfc_rcar_write(pfc_base, PFC_RCAR_GPSR + bank * sizeof(uint32_t), val);
}

/* Set peripheral function */
static void pfc_rcar_set_ipsr(uintptr_t pfc_base,
			      const struct rcar_pin_func *rcar_func)
{
	uint16_t reg_offs = PFC_RCAR_IPSR + rcar_func->bank * sizeof(uint32_t);
	uint32_t val = sys_read32(pfc_base + reg_offs);

	val &= ~(0xFU << rcar_func->shift);
	val |= (rcar_func->func << rcar_func->shift);
	pfc_rcar_write(pfc_base, reg_offs, val);
}

static uint32_t pfc_rcar_get_drive_reg(uint16_t pin, uint8_t *offset,
				       uint8_t *size)
{
	const struct pfc_drive_reg *drive_regs = pfc_rcar_get_drive_regs();

	while (drive_regs->reg != 0U) {
		for (size_t i = 0U; i < ARRAY_SIZE(drive_regs->fields); i++) {
			if (drive_regs->fields[i].pin == pin) {
				*offset = drive_regs->fields[i].offset;
				*size = drive_regs->fields[i].size;
				return drive_regs->reg;
			}
		}
		drive_regs++;
	}

	return 0;
}

/*
 * Maximum drive strength is 24mA. This value can be lowered
 * using DRVCTRLx registers, some pins have 8 steps (3 bits size encoded)
 * some have 4 steps (2 bits size encoded).
 */
static int pfc_rcar_set_drive_strength(uintptr_t pfc_base, uint16_t pin,
				       uint8_t strength)
{
	uint8_t offset, size, step;
	uint32_t reg, val;

	reg = pfc_rcar_get_drive_reg(pin, &offset, &size);
	if (reg == 0U) {
		return -EINVAL;
	}

	step = PFC_RCAR_DRIVE_STEP(size);
	if ((strength < step) || (strength > PFC_RCAR_DRIVE_MAX)) {
		return -EINVAL;
	}

	/* Convert the value from mA based on a full drive strength
	 * value of 24mA.
	 */
	strength = (strength / step) - 1U;
	/* clear previous drive strength value */
	val = sys_read32(pfc_base + reg);
	val &= ~GENMASK(offset + size - 1U, offset);
	val |= strength << offset;

	pfc_rcar_write(pfc_base, reg, val);

	return 0;
}

static const struct pfc_bias_reg *pfc_rcar_get_bias_reg(uint16_t pin,
							uint8_t *bit)
{
	const struct pfc_bias_reg *bias_regs = pfc_rcar_get_bias_regs();

	/* Loop around all the registers to find the bit for a given pin */
	while (bias_regs->puen && bias_regs->pud) {
		for (size_t i = 0U; i < ARRAY_SIZE(bias_regs->pins); i++) {
			if (bias_regs->pins[i] == pin) {
				*bit = i;
				return bias_regs;
			}
		}
		bias_regs++;
	}

	return NULL;
}

int pfc_rcar_set_bias(uintptr_t pfc_base, uint16_t pin, uint16_t flags)
{
	uint32_t val;
	uint8_t bit;
	const struct pfc_bias_reg *bias_reg = pfc_rcar_get_bias_reg(pin, &bit);

	if (bias_reg == NULL) {
		return -EINVAL;
	}

	/* pull enable/disable*/
	val = sys_read32(pfc_base + bias_reg->puen);
	if ((flags & RCAR_PIN_FLAGS_PUEN) == 0U) {
		sys_write32(val & ~BIT(bit), pfc_base + bias_reg->puen);
		return 0;
	}
	sys_write32(val | BIT(bit), pfc_base + bias_reg->puen);

	/* pull - up/down */
	val = sys_read32(pfc_base + bias_reg->pud);
	if (flags & RCAR_PIN_FLAGS_PUD) {
		sys_write32(val | BIT(bit), pfc_base + bias_reg->pud);
	} else {
		sys_write32(val & ~BIT(bit), pfc_base + bias_reg->pud);
	}
	return 0;
}

#ifdef CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL

const struct pfc_pocctrl_reg pfc_r8a77951_r8a77961_volt_regs[] = {
	{
		.offset = 0x0380,
		.pins = {
			[0]  = RCAR_GP_PIN(3,  0),    /* SD0_CLK  */
			[1]  = RCAR_GP_PIN(3,  1),    /* SD0_CMD  */
			[2]  = RCAR_GP_PIN(3,  2),    /* SD0_DAT0 */
			[3]  = RCAR_GP_PIN(3,  3),    /* SD0_DAT1 */
			[4]  = RCAR_GP_PIN(3,  4),    /* SD0_DAT2 */
			[5]  = RCAR_GP_PIN(3,  5),    /* SD0_DAT3 */
			[6]  = RCAR_GP_PIN(3,  6),    /* SD1_CLK  */
			[7]  = RCAR_GP_PIN(3,  7),    /* SD1_CMD  */
			[8]  = RCAR_GP_PIN(3,  8),    /* SD1_DAT0 */
			[9]  = RCAR_GP_PIN(3,  9),    /* SD1_DAT1 */
			[10] = RCAR_GP_PIN(3,  10),   /* SD1_DAT2 */
			[11] = RCAR_GP_PIN(3,  11),   /* SD1_DAT3 */
			[12] = RCAR_GP_PIN(4,  0),    /* SD2_CLK  */
			[13] = RCAR_GP_PIN(4,  1),    /* SD2_CMD  */
			[14] = RCAR_GP_PIN(4,  2),    /* SD2_DAT0 */
			[15] = RCAR_GP_PIN(4,  3),    /* SD2_DAT1 */
			[16] = RCAR_GP_PIN(4,  4),    /* SD2_DAT2 */
			[17] = RCAR_GP_PIN(4,  5),    /* SD2_DAT3 */
			[18] = RCAR_GP_PIN(4,  6),    /* SD2_DS   */
			[19] = RCAR_GP_PIN(4,  7),    /* SD3_CLK  */
			[20] = RCAR_GP_PIN(4,  8),    /* SD3_CMD  */
			[21] = RCAR_GP_PIN(4,  9),    /* SD3_DAT0 */
			[22] = RCAR_GP_PIN(4,  10),   /* SD3_DAT1 */
			[23] = RCAR_GP_PIN(4,  11),   /* SD3_DAT2 */
			[24] = RCAR_GP_PIN(4,  12),   /* SD3_DAT3 */
			[25] = RCAR_GP_PIN(4,  13),   /* SD3_DAT4 */
			[26] = RCAR_GP_PIN(4,  14),   /* SD3_DAT5 */
			[27] = RCAR_GP_PIN(4,  15),   /* SD3_DAT6 */
			[28] = RCAR_GP_PIN(4,  16),   /* SD3_DAT7 */
			[29] = RCAR_GP_PIN(4,  17),   /* SD3_DS   */
			[30] = -1,
			[31] = -1,
		}
	},
	{ /* sentinel */ },
};

static const struct pfc_pocctrl_reg *pfc_rcar_get_io_voltage_regs(void)
{
	return pfc_r8a77951_r8a77961_volt_regs;
}

static const struct pfc_pocctrl_reg *pfc_rcar_get_pocctrl_reg(uint16_t pin, uint8_t *bit)
{
	const struct pfc_pocctrl_reg *voltage_regs = pfc_rcar_get_io_voltage_regs();

	BUILD_ASSERT(ARRAY_SIZE(voltage_regs->pins) < UINT8_MAX);

	/* Loop around all the registers to find the bit for a given pin */
	while (voltage_regs && voltage_regs->offset) {
		uint8_t i;

		for (i = 0U; i < ARRAY_SIZE(voltage_regs->pins); i++) {
			if (voltage_regs->pins[i] == pin) {
				*bit = i;
				return voltage_regs;
			}
		}
		voltage_regs++;
	}

	return NULL;
}

static void pfc_rcar_set_voltage(uintptr_t pfc_base, uint16_t pin, uint16_t voltage)
{
	uint32_t val;
	uint8_t bit;
	const struct pfc_pocctrl_reg *voltage_reg;

	voltage_reg = pfc_rcar_get_pocctrl_reg(pin, &bit);
	if (!voltage_reg) {
		return;
	}

	val = sys_read32(pfc_base + voltage_reg->offset);

	switch (voltage) {
	case PIN_VOLTAGE_1P8V:
		if (!(val & BIT(bit))) {
			return;
		}
		val &= ~BIT(bit);
		break;
	case PIN_VOLTAGE_3P3V:
		if (val & BIT(bit)) {
			return;
		}
		val |= BIT(bit);
		break;
	default:
		break;
	}

	pfc_rcar_write(pfc_base, voltage_reg->offset, val);
}
#endif /* CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL */

int pinctrl_configure_pin(const pinctrl_soc_pin_t *pin)
{
	int ret = 0;
	uint8_t reg_index;
	uintptr_t pfc_base;

	ret = pfc_rcar_get_reg_index(pin->pin, &reg_index);
	if (ret) {
		return ret;
	}

	if (reg_index >= ARRAY_SIZE(reg_base)) {
		return -EINVAL;
	}

	pfc_base = reg_base[reg_index];

	/* Set pin as GPIO if capable */
	if (RCAR_IS_GP_PIN(pin->pin)) {
		pfc_rcar_set_gpsr(pfc_base, pin->pin, false);
	} else if ((pin->flags & RCAR_PIN_FLAGS_FUNC_SET) == 0U) {
		/* A function must be set for non GPIO capable pin */
		return -EINVAL;
	}

#ifdef CONFIG_PINCTRL_RCAR_VOLTAGE_CONTROL
	if (pin->voltage != PIN_VOLTAGE_NONE) {
		pfc_rcar_set_voltage(pfc_base, pin->pin, pin->voltage);
	}
#endif

	/* Select function for pin */
	if ((pin->flags & RCAR_PIN_FLAGS_FUNC_SET) != 0U) {
		pfc_rcar_set_ipsr(pfc_base, &pin->func);

		if (RCAR_IS_GP_PIN(pin->pin)) {
			pfc_rcar_set_gpsr(pfc_base, pin->pin, true);
		}

		if ((pin->flags & RCAR_PIN_FLAGS_PULL_SET) != 0U) {
			ret = pfc_rcar_set_bias(pfc_base, pin->pin, pin->flags);
			if (ret < 0) {
				return ret;
			}
		}
	}

	if (pin->drive_strength != 0U) {
		ret = pfc_rcar_set_drive_strength(pfc_base, pin->pin,
						  pin->drive_strength);
	}

	return ret;
}

int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
			   uintptr_t reg)
{
	int ret = 0;

	ARG_UNUSED(reg);
	while (pin_cnt-- > 0U) {
		ret = pinctrl_configure_pin(pins++);
		if (ret < 0) {
			break;
		}
	}

	return ret;
}

#if defined(DEVICE_MMIO_IS_IN_RAM)
__boot_func static int pfc_rcar_driver_init(void)
{
	for (unsigned int i = 0; i < ARRAY_SIZE(reg_base); i++) {
		device_map(reg_base + i, reg_base[i], reg_sizes[i], K_MEM_CACHE_NONE);
	}
	return 0;
}

SYS_INIT(pfc_rcar_driver_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
#endif
