// SPDX-License-Identifier: GPL-2.0
/*
 * sdhci_am654.c - SDHCI driver for TI's AM654 SOCs
 *
 * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com
 *
 */
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/regmap.h>

#include "sdhci-pltfm.h"

/* CTL_CFG Registers */
#define CTL_CFG_2		0x14

#define SLOTTYPE_MASK		GENMASK(31, 30)
#define SLOTTYPE_EMBEDDED	BIT(30)

/* PHY Registers */
#define PHY_CTRL1	0x100
#define PHY_CTRL2	0x104
#define PHY_CTRL3	0x108
#define PHY_CTRL4	0x10C
#define PHY_CTRL5	0x110
#define PHY_CTRL6	0x114
#define PHY_STAT1	0x130
#define PHY_STAT2	0x134

#define IOMUX_ENABLE_SHIFT	31
#define IOMUX_ENABLE_MASK	BIT(IOMUX_ENABLE_SHIFT)
#define OTAPDLYENA_SHIFT	20
#define OTAPDLYENA_MASK		BIT(OTAPDLYENA_SHIFT)
#define OTAPDLYSEL_SHIFT	12
#define OTAPDLYSEL_MASK		GENMASK(15, 12)
#define STRBSEL_SHIFT		24
#define STRBSEL_4BIT_MASK	GENMASK(27, 24)
#define STRBSEL_8BIT_MASK	GENMASK(31, 24)
#define SEL50_SHIFT		8
#define SEL50_MASK		BIT(SEL50_SHIFT)
#define SEL100_SHIFT		9
#define SEL100_MASK		BIT(SEL100_SHIFT)
#define FREQSEL_SHIFT		8
#define FREQSEL_MASK		GENMASK(10, 8)
#define DLL_TRIM_ICP_SHIFT	4
#define DLL_TRIM_ICP_MASK	GENMASK(7, 4)
#define DR_TY_SHIFT		20
#define DR_TY_MASK		GENMASK(22, 20)
#define ENDLL_SHIFT		1
#define ENDLL_MASK		BIT(ENDLL_SHIFT)
#define DLLRDY_SHIFT		0
#define DLLRDY_MASK		BIT(DLLRDY_SHIFT)
#define PDB_SHIFT		0
#define PDB_MASK		BIT(PDB_SHIFT)
#define CALDONE_SHIFT		1
#define CALDONE_MASK		BIT(CALDONE_SHIFT)
#define RETRIM_SHIFT		17
#define RETRIM_MASK		BIT(RETRIM_SHIFT)

#define DRIVER_STRENGTH_50_OHM	0x0
#define DRIVER_STRENGTH_33_OHM	0x1
#define DRIVER_STRENGTH_66_OHM	0x2
#define DRIVER_STRENGTH_100_OHM	0x3
#define DRIVER_STRENGTH_40_OHM	0x4

#define CLOCK_TOO_SLOW_HZ	400000

static struct regmap_config sdhci_am654_regmap_config = {
	.reg_bits = 32,
	.val_bits = 32,
	.reg_stride = 4,
	.fast_io = true,
};

struct sdhci_am654_data {
	struct regmap *base;
	int otap_del_sel;
	int trm_icp;
	int drv_strength;
	bool dll_on;
	int strb_sel;
	u32 flags;
};

struct sdhci_am654_driver_data {
	const struct sdhci_pltfm_data *pdata;
	u32 flags;
#define IOMUX_PRESENT	(1 << 0)
#define FREQSEL_2_BIT	(1 << 1)
#define STRBSEL_4_BIT	(1 << 2)
#define DLL_PRESENT	(1 << 3)
};

static void sdhci_am654_set_clock(struct sdhci_host *host, unsigned int clock)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
	int sel50, sel100, freqsel;
	u32 mask, val;
	int ret;

	if (sdhci_am654->dll_on) {
		regmap_update_bits(sdhci_am654->base, PHY_CTRL1, ENDLL_MASK, 0);

		sdhci_am654->dll_on = false;
	}

	sdhci_set_clock(host, clock);

	if (clock > CLOCK_TOO_SLOW_HZ) {
		/* Setup DLL Output TAP delay */
		mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
		val = (1 << OTAPDLYENA_SHIFT) |
		      (sdhci_am654->otap_del_sel << OTAPDLYSEL_SHIFT);
		regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask, val);
		/* Write to STRBSEL for HS400 speed mode */
		if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400) {
			if (sdhci_am654->flags & STRBSEL_4_BIT)
				mask = STRBSEL_4BIT_MASK;
			else
				mask = STRBSEL_8BIT_MASK;

			regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask,
					   sdhci_am654->strb_sel <<
					   STRBSEL_SHIFT);
		}

		if (sdhci_am654->flags & FREQSEL_2_BIT) {
			switch (clock) {
			case 200000000:
				sel50 = 0;
				sel100 = 0;
				break;
			case 100000000:
				sel50 = 0;
				sel100 = 1;
				break;
			default:
				sel50 = 1;
				sel100 = 0;
			}

			/* Configure PHY DLL frequency */
			mask = SEL50_MASK | SEL100_MASK;
			val = (sel50 << SEL50_SHIFT) | (sel100 << SEL100_SHIFT);
			regmap_update_bits(sdhci_am654->base, PHY_CTRL5, mask,
					   val);
		} else {
			switch (clock) {
			case 200000000:
				freqsel = 0x0;
				break;
			default:
				freqsel = 0x4;
			}

			regmap_update_bits(sdhci_am654->base, PHY_CTRL5,
					   FREQSEL_MASK,
					   freqsel << FREQSEL_SHIFT);
		}

		/* Configure DLL TRIM */
		mask = DLL_TRIM_ICP_MASK;
		val = sdhci_am654->trm_icp << DLL_TRIM_ICP_SHIFT;

		/* Configure DLL driver strength */
		mask |= DR_TY_MASK;
		val |= sdhci_am654->drv_strength << DR_TY_SHIFT;
		regmap_update_bits(sdhci_am654->base, PHY_CTRL1, mask, val);
		/* Enable DLL */
		regmap_update_bits(sdhci_am654->base, PHY_CTRL1, ENDLL_MASK,
				   0x1 << ENDLL_SHIFT);
		/*
		 * Poll for DLL ready. Use a one second timeout.
		 * Works in all experiments done so far
		 */
		ret = regmap_read_poll_timeout(sdhci_am654->base, PHY_STAT1,
					       val, val & DLLRDY_MASK, 1000,
					       1000000);
		if (ret) {
			dev_err(mmc_dev(host->mmc), "DLL failed to relock\n");
			return;
		}

		sdhci_am654->dll_on = true;
	}
}

static void sdhci_j721e_4bit_set_clock(struct sdhci_host *host,
				       unsigned int clock)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
	int val, mask;

	mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
	val = (1 << OTAPDLYENA_SHIFT) |
	      (sdhci_am654->otap_del_sel << OTAPDLYSEL_SHIFT);
	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask, val);

	sdhci_set_clock(host, clock);
}

static void sdhci_am654_set_power(struct sdhci_host *host, unsigned char mode,
				  unsigned short vdd)
{
	if (!IS_ERR(host->mmc->supply.vmmc)) {
		struct mmc_host *mmc = host->mmc;

		mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
	}
	sdhci_set_power_noreg(host, mode, vdd);
}

static void sdhci_am654_write_b(struct sdhci_host *host, u8 val, int reg)
{
	unsigned char timing = host->mmc->ios.timing;

	if (reg == SDHCI_HOST_CONTROL) {
		switch (timing) {
		/*
		 * According to the data manual, HISPD bit
		 * should not be set in these speed modes.
		 */
		case MMC_TIMING_SD_HS:
		case MMC_TIMING_MMC_HS:
			val &= ~SDHCI_CTRL_HISPD;
		}
	}

	writeb(val, host->ioaddr + reg);
}

static int sdhci_am654_execute_tuning(struct mmc_host *mmc, u32 opcode)
{
	struct sdhci_host *host = mmc_priv(mmc);
	int err = sdhci_execute_tuning(mmc, opcode);

	if (err)
		return err;
	/*
	 * Tuning data remains in the buffer after tuning.
	 * Do a command and data reset to get rid of it
	 */
	sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);

	return 0;
}

static struct sdhci_ops sdhci_am654_ops = {
	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
	.get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
	.set_uhs_signaling = sdhci_set_uhs_signaling,
	.set_bus_width = sdhci_set_bus_width,
	.set_power = sdhci_am654_set_power,
	.set_clock = sdhci_am654_set_clock,
	.write_b = sdhci_am654_write_b,
	.reset = sdhci_reset,
};

static const struct sdhci_pltfm_data sdhci_am654_pdata = {
	.ops = &sdhci_am654_ops,
	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
};

static const struct sdhci_am654_driver_data sdhci_am654_drvdata = {
	.pdata = &sdhci_am654_pdata,
	.flags = IOMUX_PRESENT | FREQSEL_2_BIT | STRBSEL_4_BIT | DLL_PRESENT,
};

static struct sdhci_ops sdhci_j721e_8bit_ops = {
	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
	.get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
	.set_uhs_signaling = sdhci_set_uhs_signaling,
	.set_bus_width = sdhci_set_bus_width,
	.set_power = sdhci_am654_set_power,
	.set_clock = sdhci_am654_set_clock,
	.write_b = sdhci_am654_write_b,
	.reset = sdhci_reset,
};

static const struct sdhci_pltfm_data sdhci_j721e_8bit_pdata = {
	.ops = &sdhci_j721e_8bit_ops,
	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
};

static const struct sdhci_am654_driver_data sdhci_j721e_8bit_drvdata = {
	.pdata = &sdhci_j721e_8bit_pdata,
	.flags = DLL_PRESENT,
};

static struct sdhci_ops sdhci_j721e_4bit_ops = {
	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
	.get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
	.set_uhs_signaling = sdhci_set_uhs_signaling,
	.set_bus_width = sdhci_set_bus_width,
	.set_power = sdhci_am654_set_power,
	.set_clock = sdhci_j721e_4bit_set_clock,
	.write_b = sdhci_am654_write_b,
	.reset = sdhci_reset,
};

static const struct sdhci_pltfm_data sdhci_j721e_4bit_pdata = {
	.ops = &sdhci_j721e_4bit_ops,
	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
};

static const struct sdhci_am654_driver_data sdhci_j721e_4bit_drvdata = {
	.pdata = &sdhci_j721e_4bit_pdata,
	.flags = IOMUX_PRESENT,
};
static int sdhci_am654_init(struct sdhci_host *host)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
	u32 ctl_cfg_2 = 0;
	u32 mask;
	u32 val;
	int ret;

	/* Reset OTAP to default value */
	mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask, 0x0);

	if (sdhci_am654->flags & DLL_PRESENT) {
		regmap_read(sdhci_am654->base, PHY_STAT1, &val);
		if (~val & CALDONE_MASK) {
			/* Calibrate IO lines */
			regmap_update_bits(sdhci_am654->base, PHY_CTRL1,
					   PDB_MASK, PDB_MASK);
			ret = regmap_read_poll_timeout(sdhci_am654->base,
						       PHY_STAT1, val,
						       val & CALDONE_MASK,
						       1, 20);
			if (ret)
				return ret;
		}
	}

	/* Enable pins by setting IO mux to 0 */
	if (sdhci_am654->flags & IOMUX_PRESENT)
		regmap_update_bits(sdhci_am654->base, PHY_CTRL1,
				   IOMUX_ENABLE_MASK, 0);

	/* Set slot type based on SD or eMMC */
	if (host->mmc->caps & MMC_CAP_NONREMOVABLE)
		ctl_cfg_2 = SLOTTYPE_EMBEDDED;

	regmap_update_bits(sdhci_am654->base, CTL_CFG_2, SLOTTYPE_MASK,
			   ctl_cfg_2);

	return sdhci_add_host(host);
}

static int sdhci_am654_get_of_property(struct platform_device *pdev,
					struct sdhci_am654_data *sdhci_am654)
{
	struct device *dev = &pdev->dev;
	int drv_strength;
	int ret;

	ret = device_property_read_u32(dev, "ti,otap-del-sel",
				       &sdhci_am654->otap_del_sel);
	if (ret)
		return ret;

	if (sdhci_am654->flags & DLL_PRESENT) {
		ret = device_property_read_u32(dev, "ti,trm-icp",
					       &sdhci_am654->trm_icp);
		if (ret)
			return ret;

		ret = device_property_read_u32(dev, "ti,driver-strength-ohm",
					       &drv_strength);
		if (ret)
			return ret;

		switch (drv_strength) {
		case 50:
			sdhci_am654->drv_strength = DRIVER_STRENGTH_50_OHM;
			break;
		case 33:
			sdhci_am654->drv_strength = DRIVER_STRENGTH_33_OHM;
			break;
		case 66:
			sdhci_am654->drv_strength = DRIVER_STRENGTH_66_OHM;
			break;
		case 100:
			sdhci_am654->drv_strength = DRIVER_STRENGTH_100_OHM;
			break;
		case 40:
			sdhci_am654->drv_strength = DRIVER_STRENGTH_40_OHM;
			break;
		default:
			dev_err(dev, "Invalid driver strength\n");
			return -EINVAL;
		}
	}

	device_property_read_u32(dev, "ti,strobe-sel", &sdhci_am654->strb_sel);

	sdhci_get_of_property(pdev);

	return 0;
}

static const struct of_device_id sdhci_am654_of_match[] = {
	{
		.compatible = "ti,am654-sdhci-5.1",
		.data = &sdhci_am654_drvdata,
	},
	{
		.compatible = "ti,j721e-sdhci-8bit",
		.data = &sdhci_j721e_8bit_drvdata,
	},
	{
		.compatible = "ti,j721e-sdhci-4bit",
		.data = &sdhci_j721e_4bit_drvdata,
	},
	{ /* sentinel */ }
};

static int sdhci_am654_probe(struct platform_device *pdev)
{
	const struct sdhci_am654_driver_data *drvdata;
	struct sdhci_pltfm_host *pltfm_host;
	struct sdhci_am654_data *sdhci_am654;
	const struct of_device_id *match;
	struct sdhci_host *host;
	struct resource *res;
	struct clk *clk_xin;
	struct device *dev = &pdev->dev;
	void __iomem *base;
	int ret;

	match = of_match_node(sdhci_am654_of_match, pdev->dev.of_node);
	drvdata = match->data;
	host = sdhci_pltfm_init(pdev, drvdata->pdata, sizeof(*sdhci_am654));
	if (IS_ERR(host))
		return PTR_ERR(host);

	pltfm_host = sdhci_priv(host);
	sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
	sdhci_am654->flags = drvdata->flags;

	clk_xin = devm_clk_get(dev, "clk_xin");
	if (IS_ERR(clk_xin)) {
		dev_err(dev, "clk_xin clock not found.\n");
		ret = PTR_ERR(clk_xin);
		goto err_pltfm_free;
	}

	pltfm_host->clk = clk_xin;

	/* Clocks are enabled using pm_runtime */
	pm_runtime_enable(dev);
	ret = pm_runtime_get_sync(dev);
	if (ret < 0) {
		pm_runtime_put_noidle(dev);
		goto pm_runtime_disable;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	base = devm_ioremap_resource(dev, res);
	if (IS_ERR(base)) {
		ret = PTR_ERR(base);
		goto pm_runtime_put;
	}

	sdhci_am654->base = devm_regmap_init_mmio(dev, base,
						  &sdhci_am654_regmap_config);
	if (IS_ERR(sdhci_am654->base)) {
		dev_err(dev, "Failed to initialize regmap\n");
		ret = PTR_ERR(sdhci_am654->base);
		goto pm_runtime_put;
	}

	ret = sdhci_am654_get_of_property(pdev, sdhci_am654);
	if (ret)
		goto pm_runtime_put;

	ret = mmc_of_parse(host->mmc);
	if (ret) {
		dev_err(dev, "parsing dt failed (%d)\n", ret);
		goto pm_runtime_put;
	}

	host->mmc_host_ops.execute_tuning = sdhci_am654_execute_tuning;

	ret = sdhci_am654_init(host);
	if (ret)
		goto pm_runtime_put;

	return 0;

pm_runtime_put:
	pm_runtime_put_sync(dev);
pm_runtime_disable:
	pm_runtime_disable(dev);
err_pltfm_free:
	sdhci_pltfm_free(pdev);
	return ret;
}

static int sdhci_am654_remove(struct platform_device *pdev)
{
	struct sdhci_host *host = platform_get_drvdata(pdev);
	int ret;

	sdhci_remove_host(host, true);
	ret = pm_runtime_put_sync(&pdev->dev);
	if (ret < 0)
		return ret;

	pm_runtime_disable(&pdev->dev);
	sdhci_pltfm_free(pdev);

	return 0;
}

static struct platform_driver sdhci_am654_driver = {
	.driver = {
		.name = "sdhci-am654",
		.of_match_table = sdhci_am654_of_match,
	},
	.probe = sdhci_am654_probe,
	.remove = sdhci_am654_remove,
};

module_platform_driver(sdhci_am654_driver);

MODULE_DESCRIPTION("Driver for SDHCI Controller on TI's AM654 devices");
MODULE_AUTHOR("Faiz Abbas <faiz_abbas@ti.com>");
MODULE_LICENSE("GPL");
