/*
 * Copyright (C) 2014 Broadcom Corporation
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation version 2.
 *
 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
 * kind, whether express or implied; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

/*
 * iProc SDHCI platform driver
 */

#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/mmc/host.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include "sdhci-pltfm.h"

struct sdhci_iproc_data {
	const struct sdhci_pltfm_data *pdata;
	u32 caps;
	u32 caps1;
	u32 mmc_caps;
};

struct sdhci_iproc_host {
	const struct sdhci_iproc_data *data;
	u32 shadow_cmd;
	u32 shadow_blk;
	bool is_cmd_shadowed;
	bool is_blk_shadowed;
};

#define REG_OFFSET_IN_BITS(reg) ((reg) << 3 & 0x18)

static inline u32 sdhci_iproc_readl(struct sdhci_host *host, int reg)
{
	u32 val = readl(host->ioaddr + reg);

	pr_debug("%s: readl [0x%02x] 0x%08x\n",
		 mmc_hostname(host->mmc), reg, val);
	return val;
}

static u16 sdhci_iproc_readw(struct sdhci_host *host, int reg)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct sdhci_iproc_host *iproc_host = sdhci_pltfm_priv(pltfm_host);
	u32 val;
	u16 word;

	if ((reg == SDHCI_TRANSFER_MODE) && iproc_host->is_cmd_shadowed) {
		/* Get the saved transfer mode */
		val = iproc_host->shadow_cmd;
	} else if ((reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) &&
		   iproc_host->is_blk_shadowed) {
		/* Get the saved block info */
		val = iproc_host->shadow_blk;
	} else {
		val = sdhci_iproc_readl(host, (reg & ~3));
	}
	word = val >> REG_OFFSET_IN_BITS(reg) & 0xffff;
	return word;
}

static u8 sdhci_iproc_readb(struct sdhci_host *host, int reg)
{
	u32 val = sdhci_iproc_readl(host, (reg & ~3));
	u8 byte = val >> REG_OFFSET_IN_BITS(reg) & 0xff;
	return byte;
}

static inline void sdhci_iproc_writel(struct sdhci_host *host, u32 val, int reg)
{
	pr_debug("%s: writel [0x%02x] 0x%08x\n",
		 mmc_hostname(host->mmc), reg, val);

	writel(val, host->ioaddr + reg);

	if (host->clock <= 400000) {
		/* Round up to micro-second four SD clock delay */
		if (host->clock)
			udelay((4 * 1000000 + host->clock - 1) / host->clock);
		else
			udelay(10);
	}
}

/*
 * The Arasan has a bugette whereby it may lose the content of successive
 * writes to the same register that are within two SD-card clock cycles of
 * each other (a clock domain crossing problem). The data
 * register does not have this problem, which is just as well - otherwise we'd
 * have to nobble the DMA engine too.
 *
 * This wouldn't be a problem with the code except that we can only write the
 * controller with 32-bit writes.  So two different 16-bit registers are
 * written back to back creates the problem.
 *
 * In reality, this only happens when SDHCI_BLOCK_SIZE and SDHCI_BLOCK_COUNT
 * are written followed by SDHCI_TRANSFER_MODE and SDHCI_COMMAND.
 * The BLOCK_SIZE and BLOCK_COUNT are meaningless until a command issued so
 * the work around can be further optimized. We can keep shadow values of
 * BLOCK_SIZE, BLOCK_COUNT, and TRANSFER_MODE until a COMMAND is issued.
 * Then, write the BLOCK_SIZE+BLOCK_COUNT in a single 32-bit write followed
 * by the TRANSFER+COMMAND in another 32-bit write.
 */
static void sdhci_iproc_writew(struct sdhci_host *host, u16 val, int reg)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct sdhci_iproc_host *iproc_host = sdhci_pltfm_priv(pltfm_host);
	u32 word_shift = REG_OFFSET_IN_BITS(reg);
	u32 mask = 0xffff << word_shift;
	u32 oldval, newval;

	if (reg == SDHCI_COMMAND) {
		/* Write the block now as we are issuing a command */
		if (iproc_host->is_blk_shadowed) {
			sdhci_iproc_writel(host, iproc_host->shadow_blk,
				SDHCI_BLOCK_SIZE);
			iproc_host->is_blk_shadowed = false;
		}
		oldval = iproc_host->shadow_cmd;
		iproc_host->is_cmd_shadowed = false;
	} else if ((reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) &&
		   iproc_host->is_blk_shadowed) {
		/* Block size and count are stored in shadow reg */
		oldval = iproc_host->shadow_blk;
	} else {
		/* Read reg, all other registers are not shadowed */
		oldval = sdhci_iproc_readl(host, (reg & ~3));
	}
	newval = (oldval & ~mask) | (val << word_shift);

	if (reg == SDHCI_TRANSFER_MODE) {
		/* Save the transfer mode until the command is issued */
		iproc_host->shadow_cmd = newval;
		iproc_host->is_cmd_shadowed = true;
	} else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) {
		/* Save the block info until the command is issued */
		iproc_host->shadow_blk = newval;
		iproc_host->is_blk_shadowed = true;
	} else {
		/* Command or other regular 32-bit write */
		sdhci_iproc_writel(host, newval, reg & ~3);
	}
}

static void sdhci_iproc_writeb(struct sdhci_host *host, u8 val, int reg)
{
	u32 oldval = sdhci_iproc_readl(host, (reg & ~3));
	u32 byte_shift = REG_OFFSET_IN_BITS(reg);
	u32 mask = 0xff << byte_shift;
	u32 newval = (oldval & ~mask) | (val << byte_shift);

	sdhci_iproc_writel(host, newval, reg & ~3);
}

static unsigned int sdhci_iproc_get_max_clock(struct sdhci_host *host)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);

	if (pltfm_host->clk)
		return sdhci_pltfm_clk_get_max_clock(host);
	else
		return pltfm_host->clock;
}

static const struct sdhci_ops sdhci_iproc_ops = {
	.set_clock = sdhci_set_clock,
	.get_max_clock = sdhci_iproc_get_max_clock,
	.set_bus_width = sdhci_set_bus_width,
	.reset = sdhci_reset,
	.set_uhs_signaling = sdhci_set_uhs_signaling,
};

static const struct sdhci_ops sdhci_iproc_32only_ops = {
	.read_l = sdhci_iproc_readl,
	.read_w = sdhci_iproc_readw,
	.read_b = sdhci_iproc_readb,
	.write_l = sdhci_iproc_writel,
	.write_w = sdhci_iproc_writew,
	.write_b = sdhci_iproc_writeb,
	.set_clock = sdhci_set_clock,
	.get_max_clock = sdhci_iproc_get_max_clock,
	.set_bus_width = sdhci_set_bus_width,
	.reset = sdhci_reset,
	.set_uhs_signaling = sdhci_set_uhs_signaling,
};

static const struct sdhci_pltfm_data sdhci_iproc_cygnus_pltfm_data = {
	.quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
		  SDHCI_QUIRK_NO_HISPD_BIT,
	.quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN | SDHCI_QUIRK2_HOST_OFF_CARD_ON,
	.ops = &sdhci_iproc_32only_ops,
};

static const struct sdhci_iproc_data iproc_cygnus_data = {
	.pdata = &sdhci_iproc_cygnus_pltfm_data,
	.caps = ((0x1 << SDHCI_MAX_BLOCK_SHIFT)
			& SDHCI_MAX_BLOCK_MASK) |
		SDHCI_CAN_VDD_330 |
		SDHCI_CAN_VDD_180 |
		SDHCI_CAN_DO_SUSPEND |
		SDHCI_CAN_DO_HISPD |
		SDHCI_CAN_DO_ADMA2 |
		SDHCI_CAN_DO_SDMA,
	.caps1 = SDHCI_DRIVER_TYPE_C |
		 SDHCI_DRIVER_TYPE_D |
		 SDHCI_SUPPORT_DDR50,
	.mmc_caps = MMC_CAP_1_8V_DDR,
};

static const struct sdhci_pltfm_data sdhci_iproc_pltfm_data = {
	.quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
		  SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 |
		  SDHCI_QUIRK_NO_HISPD_BIT,
	.quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN,
	.ops = &sdhci_iproc_ops,
};

static const struct sdhci_iproc_data iproc_data = {
	.pdata = &sdhci_iproc_pltfm_data,
	.caps = ((0x1 << SDHCI_MAX_BLOCK_SHIFT)
			& SDHCI_MAX_BLOCK_MASK) |
		SDHCI_CAN_VDD_330 |
		SDHCI_CAN_VDD_180 |
		SDHCI_CAN_DO_SUSPEND |
		SDHCI_CAN_DO_HISPD |
		SDHCI_CAN_DO_ADMA2 |
		SDHCI_CAN_DO_SDMA,
	.caps1 = SDHCI_DRIVER_TYPE_C |
		 SDHCI_DRIVER_TYPE_D |
		 SDHCI_SUPPORT_DDR50,
};

static const struct sdhci_pltfm_data sdhci_bcm2835_pltfm_data = {
	.quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
		  SDHCI_QUIRK_MISSING_CAPS |
		  SDHCI_QUIRK_NO_HISPD_BIT,
	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
	.ops = &sdhci_iproc_32only_ops,
};

static const struct sdhci_iproc_data bcm2835_data = {
	.pdata = &sdhci_bcm2835_pltfm_data,
	.caps = ((0x1 << SDHCI_MAX_BLOCK_SHIFT)
			& SDHCI_MAX_BLOCK_MASK) |
		SDHCI_CAN_VDD_330 |
		SDHCI_CAN_DO_HISPD,
	.caps1 = SDHCI_DRIVER_TYPE_A |
		 SDHCI_DRIVER_TYPE_C,
	.mmc_caps = 0x00000000,
};

static const struct sdhci_ops sdhci_iproc_bcm2711_ops = {
	.read_l = sdhci_iproc_readl,
	.read_w = sdhci_iproc_readw,
	.read_b = sdhci_iproc_readb,
	.write_l = sdhci_iproc_writel,
	.write_w = sdhci_iproc_writew,
	.write_b = sdhci_iproc_writeb,
	.set_clock = sdhci_set_clock,
	.set_power = sdhci_set_power_and_bus_voltage,
	.get_max_clock = sdhci_iproc_get_max_clock,
	.set_bus_width = sdhci_set_bus_width,
	.reset = sdhci_reset,
	.set_uhs_signaling = sdhci_set_uhs_signaling,
};

static const struct sdhci_pltfm_data sdhci_bcm2711_pltfm_data = {
	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
	.ops = &sdhci_iproc_bcm2711_ops,
};

static const struct sdhci_iproc_data bcm2711_data = {
	.pdata = &sdhci_bcm2711_pltfm_data,
	.mmc_caps = MMC_CAP_3_3V_DDR,
};

static const struct sdhci_pltfm_data sdhci_bcm7211a0_pltfm_data = {
	.quirks = SDHCI_QUIRK_MISSING_CAPS |
		SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
		SDHCI_QUIRK_BROKEN_DMA |
		SDHCI_QUIRK_BROKEN_ADMA,
	.ops = &sdhci_iproc_ops,
};

#define BCM7211A0_BASE_CLK_MHZ 100
static const struct sdhci_iproc_data bcm7211a0_data = {
	.pdata = &sdhci_bcm7211a0_pltfm_data,
	.caps = ((BCM7211A0_BASE_CLK_MHZ / 2) << SDHCI_TIMEOUT_CLK_SHIFT) |
		(BCM7211A0_BASE_CLK_MHZ << SDHCI_CLOCK_BASE_SHIFT) |
		((0x2 << SDHCI_MAX_BLOCK_SHIFT)
			& SDHCI_MAX_BLOCK_MASK) |
		SDHCI_CAN_VDD_330 |
		SDHCI_CAN_VDD_180 |
		SDHCI_CAN_DO_SUSPEND |
		SDHCI_CAN_DO_HISPD,
	.caps1 = SDHCI_DRIVER_TYPE_C |
		 SDHCI_DRIVER_TYPE_D,
};

static const struct of_device_id sdhci_iproc_of_match[] = {
	{ .compatible = "brcm,bcm2835-sdhci", .data = &bcm2835_data },
	{ .compatible = "brcm,bcm2711-emmc2", .data = &bcm2711_data },
	{ .compatible = "brcm,sdhci-iproc-cygnus", .data = &iproc_cygnus_data},
	{ .compatible = "brcm,sdhci-iproc", .data = &iproc_data },
	{ .compatible = "brcm,bcm7211a0-sdhci", .data = &bcm7211a0_data },
	{ }
};
MODULE_DEVICE_TABLE(of, sdhci_iproc_of_match);

#ifdef CONFIG_ACPI
/*
 * This is a duplicate of bcm2835_(pltfrm_)data without caps quirks
 * which are provided by the ACPI table.
 */
static const struct sdhci_pltfm_data sdhci_bcm_arasan_data = {
	.quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
		  SDHCI_QUIRK_NO_HISPD_BIT,
	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
	.ops = &sdhci_iproc_32only_ops,
};

static const struct sdhci_iproc_data bcm_arasan_data = {
	.pdata = &sdhci_bcm_arasan_data,
};

static const struct acpi_device_id sdhci_iproc_acpi_ids[] = {
	{ .id = "BRCM5871", .driver_data = (kernel_ulong_t)&iproc_cygnus_data },
	{ .id = "BRCM5872", .driver_data = (kernel_ulong_t)&iproc_data },
	{ .id = "BCM2847",  .driver_data = (kernel_ulong_t)&bcm_arasan_data },
	{ .id = "BRCME88C", .driver_data = (kernel_ulong_t)&bcm2711_data },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(acpi, sdhci_iproc_acpi_ids);
#endif

static int sdhci_iproc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	const struct sdhci_iproc_data *iproc_data = NULL;
	struct sdhci_host *host;
	struct sdhci_iproc_host *iproc_host;
	struct sdhci_pltfm_host *pltfm_host;
	int ret;

	iproc_data = device_get_match_data(dev);
	if (!iproc_data)
		return -ENODEV;

	host = sdhci_pltfm_init(pdev, iproc_data->pdata, sizeof(*iproc_host));
	if (IS_ERR(host))
		return PTR_ERR(host);

	pltfm_host = sdhci_priv(host);
	iproc_host = sdhci_pltfm_priv(pltfm_host);

	iproc_host->data = iproc_data;

	ret = mmc_of_parse(host->mmc);
	if (ret)
		goto err;

	sdhci_get_property(pdev);

	host->mmc->caps |= iproc_host->data->mmc_caps;

	if (dev->of_node) {
		pltfm_host->clk = devm_clk_get(dev, NULL);
		if (IS_ERR(pltfm_host->clk)) {
			ret = PTR_ERR(pltfm_host->clk);
			goto err;
		}
		ret = clk_prepare_enable(pltfm_host->clk);
		if (ret) {
			dev_err(dev, "failed to enable host clk\n");
			goto err;
		}
	}

	if (iproc_host->data->pdata->quirks & SDHCI_QUIRK_MISSING_CAPS) {
		host->caps = iproc_host->data->caps;
		host->caps1 = iproc_host->data->caps1;
	}

	ret = sdhci_add_host(host);
	if (ret)
		goto err_clk;

	return 0;

err_clk:
	if (dev->of_node)
		clk_disable_unprepare(pltfm_host->clk);
err:
	sdhci_pltfm_free(pdev);
	return ret;
}

static void sdhci_iproc_shutdown(struct platform_device *pdev)
{
	sdhci_pltfm_suspend(&pdev->dev);
}

static struct platform_driver sdhci_iproc_driver = {
	.driver = {
		.name = "sdhci-iproc",
		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
		.of_match_table = sdhci_iproc_of_match,
		.acpi_match_table = ACPI_PTR(sdhci_iproc_acpi_ids),
		.pm = &sdhci_pltfm_pmops,
	},
	.probe = sdhci_iproc_probe,
	.remove = sdhci_pltfm_unregister,
	.shutdown = sdhci_iproc_shutdown,
};
module_platform_driver(sdhci_iproc_driver);

MODULE_AUTHOR("Broadcom");
MODULE_DESCRIPTION("IPROC SDHCI driver");
MODULE_LICENSE("GPL v2");
