// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for Marvell SOC Platform Group Xenon SDHC as a platform device
 *
 * Copyright (C) 2016 Marvell, All Rights Reserved.
 *
 * Author:	Victor Gu <xigu@marvell.com>
 * Date:	2016-8-24
 *
 * Included parts of the Linux driver version which was written by:
 * Hu Ziji <huziji@marvell.com>
 *
 * Ported to from Marvell 2015.01 to mainline U-Boot 2017.01:
 * Stefan Roese <sr@denx.de>
 */

#include <common.h>
#include <dm.h>
#include <fdtdec.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/libfdt.h>
#include <malloc.h>
#include <sdhci.h>
#include <power/regulator.h>

DECLARE_GLOBAL_DATA_PTR;

/* Register Offset of SD Host Controller SOCP self-defined register */
#define SDHC_SYS_CFG_INFO			0x0104
#define SLOT_TYPE_SDIO_SHIFT			24
#define SLOT_TYPE_EMMC_MASK			0xFF
#define SLOT_TYPE_EMMC_SHIFT			16
#define SLOT_TYPE_SD_SDIO_MMC_MASK		0xFF
#define SLOT_TYPE_SD_SDIO_MMC_SHIFT		8
#define NR_SUPPORTED_SLOT_MASK			0x7

#define SDHC_SYS_OP_CTRL			0x0108
#define AUTO_CLKGATE_DISABLE_MASK		BIT(20)
#define SDCLK_IDLEOFF_ENABLE_SHIFT		8
#define SLOT_ENABLE_SHIFT			0

#define SDHC_SYS_EXT_OP_CTRL			0x010C
#define MASK_CMD_CONFLICT_ERROR			BIT(8)

#define SDHC_SLOT_EMMC_CTRL			0x0130
#define ENABLE_DATA_STROBE_SHIFT		24
#define SET_EMMC_RSTN_SHIFT			16
#define EMMC_VCCQ_MASK				0x3
#define EMMC_VCCQ_1_8V				0x1
#define EMMC_VCCQ_1_2V				0x2
#define	EMMC_VCCQ_3_3V				0x3

#define SDHC_SLOT_RETUNING_REQ_CTRL		0x0144
/* retuning compatible */
#define RETUNING_COMPATIBLE			0x1

/* Xenon specific Mode Select value */
#define XENON_SDHCI_CTRL_HS200			0x5
#define XENON_SDHCI_CTRL_HS400			0x6

#define EMMC_PHY_REG_BASE			0x170
#define EMMC_PHY_TIMING_ADJUST			EMMC_PHY_REG_BASE
#define OUTPUT_QSN_PHASE_SELECT			BIT(17)
#define SAMPL_INV_QSP_PHASE_SELECT		BIT(18)
#define SAMPL_INV_QSP_PHASE_SELECT_SHIFT	18
#define EMMC_PHY_SLOW_MODE			BIT(29)
#define PHY_INITIALIZAION			BIT(31)
#define WAIT_CYCLE_BEFORE_USING_MASK		0xf
#define WAIT_CYCLE_BEFORE_USING_SHIFT		12
#define FC_SYNC_EN_DURATION_MASK		0xf
#define FC_SYNC_EN_DURATION_SHIFT		8
#define FC_SYNC_RST_EN_DURATION_MASK		0xf
#define FC_SYNC_RST_EN_DURATION_SHIFT		4
#define FC_SYNC_RST_DURATION_MASK		0xf
#define FC_SYNC_RST_DURATION_SHIFT		0

#define EMMC_PHY_FUNC_CONTROL			(EMMC_PHY_REG_BASE + 0x4)
#define DQ_ASYNC_MODE				BIT(4)
#define DQ_DDR_MODE_SHIFT			8
#define DQ_DDR_MODE_MASK			0xff
#define CMD_DDR_MODE				BIT(16)

#define EMMC_PHY_PAD_CONTROL			(EMMC_PHY_REG_BASE + 0x8)
#define REC_EN_SHIFT				24
#define REC_EN_MASK				0xf
#define FC_DQ_RECEN				BIT(24)
#define FC_CMD_RECEN				BIT(25)
#define FC_QSP_RECEN				BIT(26)
#define FC_QSN_RECEN				BIT(27)
#define OEN_QSN					BIT(28)
#define AUTO_RECEN_CTRL				BIT(30)

#define EMMC_PHY_PAD_CONTROL1			(EMMC_PHY_REG_BASE + 0xc)
#define EMMC5_1_FC_QSP_PD			BIT(9)
#define EMMC5_1_FC_QSP_PU			BIT(25)
#define EMMC5_1_FC_CMD_PD			BIT(8)
#define EMMC5_1_FC_CMD_PU			BIT(24)
#define EMMC5_1_FC_DQ_PD			0xff
#define EMMC5_1_FC_DQ_PU			(0xff << 16)

#define SDHCI_RETUNE_EVT_INTSIG			0x00001000

/* Hyperion only have one slot 0 */
#define XENON_MMC_SLOT_ID_HYPERION		0

#define MMC_TIMING_LEGACY	0
#define MMC_TIMING_MMC_HS	1
#define MMC_TIMING_SD_HS	2
#define MMC_TIMING_UHS_SDR12	3
#define MMC_TIMING_UHS_SDR25	4
#define MMC_TIMING_UHS_SDR50	5
#define MMC_TIMING_UHS_SDR104	6
#define MMC_TIMING_UHS_DDR50	7
#define MMC_TIMING_MMC_DDR52	8
#define MMC_TIMING_MMC_HS200	9
#define MMC_TIMING_MMC_HS400	10

#define XENON_MMC_MAX_CLK	400000000
#define XENON_MMC_3V3_UV	3300000
#define XENON_MMC_1V8_UV	1800000

enum soc_pad_ctrl_type {
	SOC_PAD_SD,
	SOC_PAD_FIXED_1_8V,
};

struct xenon_sdhci_plat {
	struct mmc_config cfg;
	struct mmc mmc;
};

struct xenon_sdhci_priv {
	struct sdhci_host host;

	u8 timing;

	unsigned int clock;

	void *pad_ctrl_reg;
	int pad_type;

	struct udevice *vqmmc;
};

static int xenon_mmc_phy_init(struct sdhci_host *host)
{
	struct xenon_sdhci_priv *priv = host->mmc->priv;
	u32 clock = priv->clock;
	u32 time;
	u32 var;

	/* Enable QSP PHASE SELECT */
	var = sdhci_readl(host, EMMC_PHY_TIMING_ADJUST);
	var |= SAMPL_INV_QSP_PHASE_SELECT;
	if ((priv->timing == MMC_TIMING_UHS_SDR50) ||
	    (priv->timing == MMC_TIMING_UHS_SDR25) ||
	    (priv->timing == MMC_TIMING_UHS_SDR12) ||
	    (priv->timing == MMC_TIMING_SD_HS) ||
	    (priv->timing == MMC_TIMING_LEGACY))
		var |= EMMC_PHY_SLOW_MODE;
	sdhci_writel(host, var, EMMC_PHY_TIMING_ADJUST);

	/* Poll for host MMC PHY clock init to be stable */
	/* Wait up to 10ms */
	time = 100;
	while (time--) {
		var = sdhci_readl(host, SDHCI_CLOCK_CONTROL);
		if (var & SDHCI_CLOCK_INT_STABLE)
			break;

		udelay(100);
	}

	if (time <= 0) {
		pr_err("Failed to enable MMC internal clock in time\n");
		return -ETIMEDOUT;
	}

	/* Init PHY */
	var = sdhci_readl(host, EMMC_PHY_TIMING_ADJUST);
	var |= PHY_INITIALIZAION;
	sdhci_writel(host, var, EMMC_PHY_TIMING_ADJUST);

	if (clock == 0) {
		/* Use the possibly slowest bus frequency value */
		clock = 100000;
	}

	/* Poll for host eMMC PHY init to complete */
	/* Wait up to 10ms */
	time = 100;
	while (time--) {
		var = sdhci_readl(host, EMMC_PHY_TIMING_ADJUST);
		var &= PHY_INITIALIZAION;
		if (!var)
			break;

		/* wait for host eMMC PHY init to complete */
		udelay(100);
	}

	if (time <= 0) {
		pr_err("Failed to init MMC PHY in time\n");
		return -ETIMEDOUT;
	}

	return 0;
}

#define ARMADA_3700_SOC_PAD_1_8V	0x1
#define ARMADA_3700_SOC_PAD_3_3V	0x0

static void armada_3700_soc_pad_voltage_set(struct sdhci_host *host)
{
	struct xenon_sdhci_priv *priv = host->mmc->priv;

	if (priv->pad_type == SOC_PAD_FIXED_1_8V)
		writel(ARMADA_3700_SOC_PAD_1_8V, priv->pad_ctrl_reg);
	else if (priv->pad_type == SOC_PAD_SD)
		writel(ARMADA_3700_SOC_PAD_3_3V, priv->pad_ctrl_reg);
}

static int xenon_mmc_start_signal_voltage_switch(struct sdhci_host *host)
{
	struct xenon_sdhci_priv *priv = host->mmc->priv;
	u8 voltage;
	u32 ctrl;
	int ret = 0;

	/* If there is no vqmmc regulator, return */
	if (!priv->vqmmc)
		return 0;

	if (priv->pad_type == SOC_PAD_FIXED_1_8V) {
		/* Switch to 1.8v */
		ret = regulator_set_value(priv->vqmmc,
					  XENON_MMC_1V8_UV);
	} else if (priv->pad_type == SOC_PAD_SD) {
		/* Get voltage info */
		voltage = sdhci_readb(host, SDHCI_POWER_CONTROL);
		voltage &= ~SDHCI_POWER_ON;

		if (voltage == SDHCI_POWER_330) {
			/* Switch to 3.3v */
			ret = regulator_set_value(priv->vqmmc,
						  XENON_MMC_3V3_UV);
		} else {
			/* Switch to 1.8v */
			ret = regulator_set_value(priv->vqmmc,
						  XENON_MMC_1V8_UV);
		}
	}

	/* Set VCCQ, eMMC mode: 1.8V; SD/SDIO mode: 3.3V */
	ctrl = sdhci_readl(host, SDHC_SLOT_EMMC_CTRL);
	if (IS_SD(host->mmc))
		ctrl |= EMMC_VCCQ_3_3V;
	else
		ctrl |= EMMC_VCCQ_1_8V;
	sdhci_writel(host, ctrl, SDHC_SLOT_EMMC_CTRL);

	if (ret)
		printf("Signal voltage switch fail\n");

	return ret;
}

static void xenon_mmc_phy_set(struct sdhci_host *host)
{
	struct xenon_sdhci_priv *priv = host->mmc->priv;
	u32 var;

	/* Setup pad, set bit[30], bit[28] and bits[26:24] */
	var = sdhci_readl(host, EMMC_PHY_PAD_CONTROL);
	var |= AUTO_RECEN_CTRL | OEN_QSN | FC_QSP_RECEN |
		FC_CMD_RECEN | FC_DQ_RECEN;
	sdhci_writel(host, var, EMMC_PHY_PAD_CONTROL);

	/* Set CMD and DQ Pull Up */
	var = sdhci_readl(host, EMMC_PHY_PAD_CONTROL1);
	var |= (EMMC5_1_FC_CMD_PU | EMMC5_1_FC_DQ_PU);
	var &= ~(EMMC5_1_FC_CMD_PD | EMMC5_1_FC_DQ_PD);
	sdhci_writel(host, var, EMMC_PHY_PAD_CONTROL1);

	/*
	 * If timing belongs to high speed, set bit[17] of
	 * EMMC_PHY_TIMING_ADJUST register
	 */
	if ((priv->timing == MMC_TIMING_MMC_HS400) ||
	    (priv->timing == MMC_TIMING_MMC_HS200) ||
	    (priv->timing == MMC_TIMING_UHS_SDR50) ||
	    (priv->timing == MMC_TIMING_UHS_SDR104) ||
	    (priv->timing == MMC_TIMING_UHS_DDR50) ||
	    (priv->timing == MMC_TIMING_UHS_SDR25) ||
	    (priv->timing == MMC_TIMING_MMC_DDR52)) {
		var = sdhci_readl(host, EMMC_PHY_TIMING_ADJUST);
		var |= OUTPUT_QSN_PHASE_SELECT;
		sdhci_writel(host, var, EMMC_PHY_TIMING_ADJUST);
	}

	/*
	 * When setting EMMC_PHY_FUNC_CONTROL register,
	 * SD clock should be disabled
	 */
	var = sdhci_readl(host, SDHCI_CLOCK_CONTROL);
	var &= ~SDHCI_CLOCK_CARD_EN;
	sdhci_writew(host, var, SDHCI_CLOCK_CONTROL);

	var = sdhci_readl(host, EMMC_PHY_FUNC_CONTROL);
	if (host->mmc->ddr_mode) {
		var |= (DQ_DDR_MODE_MASK << DQ_DDR_MODE_SHIFT) | CMD_DDR_MODE;
	} else {
		var &= ~((DQ_DDR_MODE_MASK << DQ_DDR_MODE_SHIFT) |
			 CMD_DDR_MODE);
	}
	sdhci_writel(host, var, EMMC_PHY_FUNC_CONTROL);

	/* Enable bus clock */
	var = sdhci_readl(host, SDHCI_CLOCK_CONTROL);
	var |= SDHCI_CLOCK_CARD_EN;
	sdhci_writew(host, var, SDHCI_CLOCK_CONTROL);

	xenon_mmc_phy_init(host);
}

/* Enable/Disable the Auto Clock Gating function of this slot */
static void xenon_mmc_set_acg(struct sdhci_host *host, bool enable)
{
	u32 var;

	var = sdhci_readl(host, SDHC_SYS_OP_CTRL);
	if (enable)
		var &= ~AUTO_CLKGATE_DISABLE_MASK;
	else
		var |= AUTO_CLKGATE_DISABLE_MASK;

	sdhci_writel(host, var, SDHC_SYS_OP_CTRL);
}

#define SLOT_MASK(slot)		BIT(slot)

/* Enable specific slot */
static void xenon_mmc_enable_slot(struct sdhci_host *host, u8 slot)
{
	u32 var;

	var = sdhci_readl(host, SDHC_SYS_OP_CTRL);
	var |= SLOT_MASK(slot) << SLOT_ENABLE_SHIFT;
	sdhci_writel(host, var, SDHC_SYS_OP_CTRL);
}

/* Enable Parallel Transfer Mode */
static void xenon_mmc_enable_parallel_tran(struct sdhci_host *host, u8 slot)
{
	u32 var;

	var = sdhci_readl(host, SDHC_SYS_EXT_OP_CTRL);
	var |= SLOT_MASK(slot);
	sdhci_writel(host, var, SDHC_SYS_EXT_OP_CTRL);
}

static void xenon_mmc_disable_tuning(struct sdhci_host *host, u8 slot)
{
	u32 var;

	/* Clear the Re-Tuning Request functionality */
	var = sdhci_readl(host, SDHC_SLOT_RETUNING_REQ_CTRL);
	var &= ~RETUNING_COMPATIBLE;
	sdhci_writel(host, var, SDHC_SLOT_RETUNING_REQ_CTRL);

	/* Clear the Re-tuning Event Signal Enable */
	var = sdhci_readl(host, SDHCI_SIGNAL_ENABLE);
	var &= ~SDHCI_RETUNE_EVT_INTSIG;
	sdhci_writel(host, var, SDHCI_SIGNAL_ENABLE);
}

/* Mask command conflict error */
static void xenon_mask_cmd_conflict_err(struct sdhci_host *host)
{
	u32  reg;

	reg = sdhci_readl(host, SDHC_SYS_EXT_OP_CTRL);
	reg |= MASK_CMD_CONFLICT_ERROR;
	sdhci_writel(host, reg, SDHC_SYS_EXT_OP_CTRL);
}

/* Platform specific function for post set_ios configuration */
static int xenon_sdhci_set_ios_post(struct sdhci_host *host)
{
	struct xenon_sdhci_priv *priv = host->mmc->priv;
	uint speed = host->mmc->tran_speed;
	int pwr_18v = 0;

	/*
	 * Signal Voltage Switching is only applicable for Host Controllers
	 * v3.00 and above.
	 */
	if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
		xenon_mmc_start_signal_voltage_switch(host);

	if ((sdhci_readb(host, SDHCI_POWER_CONTROL) & ~SDHCI_POWER_ON) ==
	    SDHCI_POWER_180)
		pwr_18v = 1;

	/* Set timing variable according to the configured speed */
	if (IS_SD(host->mmc)) {
		/* SD/SDIO */
		if (pwr_18v) {
			if (host->mmc->ddr_mode)
				priv->timing = MMC_TIMING_UHS_DDR50;
			else if (speed <= 25000000)
				priv->timing = MMC_TIMING_UHS_SDR25;
			else
				priv->timing = MMC_TIMING_UHS_SDR50;
		} else {
			if (speed <= 25000000)
				priv->timing = MMC_TIMING_LEGACY;
			else
				priv->timing = MMC_TIMING_SD_HS;
		}
	} else {
		/* eMMC */
		if (host->mmc->ddr_mode)
			priv->timing = MMC_TIMING_MMC_DDR52;
		else if (speed <= 26000000)
			priv->timing = MMC_TIMING_LEGACY;
		else
			priv->timing = MMC_TIMING_MMC_HS;
	}

	/* Re-init the PHY */
	xenon_mmc_phy_set(host);

	return 0;
}

/* Install a driver specific handler for post set_ios configuration */
static const struct sdhci_ops xenon_sdhci_ops = {
	.set_ios_post = xenon_sdhci_set_ios_post
};

static int xenon_sdhci_probe(struct udevice *dev)
{
	struct xenon_sdhci_plat *plat = dev_get_plat(dev);
	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
	struct xenon_sdhci_priv *priv = dev_get_priv(dev);
	struct sdhci_host *host = dev_get_priv(dev);
	int ret;

	host->mmc = &plat->mmc;
	host->mmc->priv = host;
	host->mmc->dev = dev;
	upriv->mmc = host->mmc;

	/* Set quirks */
	host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_32BIT_DMA_ADDR;

	/* Set default timing */
	priv->timing = MMC_TIMING_LEGACY;

	/* Get the vqmmc regulator if there is */
	device_get_supply_regulator(dev, "vqmmc-supply", &priv->vqmmc);
	/* Set the initial voltage value to 3.3V if there is regulator */
	if (priv->vqmmc) {
		ret = regulator_set_value(priv->vqmmc,
					  XENON_MMC_3V3_UV);
		if (ret) {
			printf("Failed to set VQMMC regulator to 3.3V\n");
			return ret;
		}
	}

	/* Disable auto clock gating during init */
	xenon_mmc_set_acg(host, false);

	/* Enable slot */
	xenon_mmc_enable_slot(host, XENON_MMC_SLOT_ID_HYPERION);

	/*
	 * Set default power on SoC PHY PAD register (currently only
	 * available on the Armada 3700)
	 */
	if (priv->pad_ctrl_reg)
		armada_3700_soc_pad_voltage_set(host);

	host->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_DDR_52MHz;

	ret = mmc_of_parse(dev, &plat->cfg);
	if (ret)
		return ret;

	host->ops = &xenon_sdhci_ops;

	host->max_clk = XENON_MMC_MAX_CLK;
	ret = sdhci_setup_cfg(&plat->cfg, host, XENON_MMC_MAX_CLK, 0);
	if (ret)
		return ret;

	ret = sdhci_probe(dev);
	if (ret)
		return ret;

	/* Enable parallel transfer */
	xenon_mmc_enable_parallel_tran(host, XENON_MMC_SLOT_ID_HYPERION);

	/* Disable tuning functionality of this slot */
	xenon_mmc_disable_tuning(host, XENON_MMC_SLOT_ID_HYPERION);

	/* Enable auto clock gating after init */
	xenon_mmc_set_acg(host, true);

	xenon_mask_cmd_conflict_err(host);

	return ret;
}

static int xenon_sdhci_of_to_plat(struct udevice *dev)
{
	struct sdhci_host *host = dev_get_priv(dev);
	struct xenon_sdhci_priv *priv = dev_get_priv(dev);
	const char *name;

	host->name = dev->name;
	host->ioaddr = dev_read_addr_ptr(dev);

	if (device_is_compatible(dev, "marvell,armada-3700-sdhci"))
		priv->pad_ctrl_reg = (void *)devfdt_get_addr_index(dev, 1);

	name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "marvell,pad-type",
			   NULL);
	if (name) {
		if (0 == strncmp(name, "sd", 2)) {
			priv->pad_type = SOC_PAD_SD;
		} else if (0 == strncmp(name, "fixed-1-8v", 10)) {
			priv->pad_type = SOC_PAD_FIXED_1_8V;
		} else {
			printf("Unsupported SOC PHY PAD ctrl type %s\n", name);
			return -EINVAL;
		}
	}

	return 0;
}

static int xenon_sdhci_bind(struct udevice *dev)
{
	struct xenon_sdhci_plat *plat = dev_get_plat(dev);

	return sdhci_bind(dev, &plat->mmc, &plat->cfg);
}

static const struct udevice_id xenon_sdhci_ids[] = {
	{ .compatible = "marvell,armada-8k-sdhci",},
	{ .compatible = "marvell,armada-3700-sdhci",},
	{ }
};

U_BOOT_DRIVER(xenon_sdhci_drv) = {
	.name		= "xenon_sdhci",
	.id		= UCLASS_MMC,
	.of_match	= xenon_sdhci_ids,
	.of_to_plat = xenon_sdhci_of_to_plat,
	.ops		= &sdhci_ops,
	.bind		= xenon_sdhci_bind,
	.probe		= xenon_sdhci_probe,
	.priv_auto	= sizeof(struct xenon_sdhci_priv),
	.plat_auto	= sizeof(struct xenon_sdhci_plat),
};
