// SPDX-License-Identifier: GPL-2.0
/*
 * Freescale eSDHC ColdFire family controller driver, platform bus.
 *
 * Copyright (c) 2020 Timesys Corporation
 *   Author: Angelo Dureghello <angelo.dureghello@timesys.it>
 */

#include <linux/module.h>
#include <linux/delay.h>
#include <linux/platform_data/mmc-esdhc-mcf.h>
#include <linux/mmc/mmc.h>
#include "sdhci-pltfm.h"
#include "sdhci-esdhc.h"

#define	ESDHC_PROCTL_D3CD		0x08
#define ESDHC_SYS_CTRL_DTOCV_MASK	0x0f
#define ESDHC_DEFAULT_HOST_CONTROL	0x28

/*
 * Freescale eSDHC has DMA ERR flag at bit 28, not as std spec says, bit 25.
 */
#define ESDHC_INT_VENDOR_SPEC_DMA_ERR	BIT(28)

struct pltfm_mcf_data {
	struct clk *clk_ipg;
	struct clk *clk_ahb;
	struct clk *clk_per;
	int aside;
	int current_bus_width;
};

static inline void esdhc_mcf_buffer_swap32(u32 *buf, int len)
{
	int i;
	u32 temp;

	len = (len + 3) >> 2;

	for (i = 0; i < len;  i++) {
		temp = swab32(*buf);
		*buf++ = temp;
	}
}

static inline void esdhc_clrset_be(struct sdhci_host *host,
				   u32 mask, u32 val, int reg)
{
	void __iomem *base = host->ioaddr + (reg & ~3);
	u8 shift = (reg & 3) << 3;

	mask <<= shift;
	val <<= shift;

	if (reg == SDHCI_HOST_CONTROL)
		val |= ESDHC_PROCTL_D3CD;

	writel((readl(base) & ~mask) | val, base);
}

/*
 * Note: mcf is big-endian, single bytes need to be accessed at big endian
 * offsets.
 */
static void esdhc_mcf_writeb_be(struct sdhci_host *host, u8 val, int reg)
{
	void __iomem *base = host->ioaddr + (reg & ~3);
	u8 shift = (reg & 3) << 3;
	u32 mask = ~(0xff << shift);

	if (reg == SDHCI_HOST_CONTROL) {
		u32 host_ctrl = ESDHC_DEFAULT_HOST_CONTROL;
		u8 dma_bits = (val & SDHCI_CTRL_DMA_MASK) >> 3;
		u8 tmp = readb(host->ioaddr + SDHCI_HOST_CONTROL + 1);

		tmp &= ~0x03;
		tmp |= dma_bits;

		/*
		 * Recomposition needed, restore always endianness and
		 * keep D3CD and AI, just setting bus width.
		 */
		host_ctrl |= val;
		host_ctrl |= (dma_bits << 8);
		writel(host_ctrl, host->ioaddr + SDHCI_HOST_CONTROL);

		return;
	}

	writel((readl(base) & mask) | (val << shift), base);
}

static void esdhc_mcf_writew_be(struct sdhci_host *host, u16 val, int reg)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct pltfm_mcf_data *mcf_data = sdhci_pltfm_priv(pltfm_host);
	void __iomem *base = host->ioaddr + (reg & ~3);
	u8 shift = (reg & 3) << 3;
	u32 mask = ~(0xffff << shift);

	switch (reg) {
	case SDHCI_TRANSFER_MODE:
		mcf_data->aside = val;
		return;
	case SDHCI_COMMAND:
		if (host->cmd->opcode == MMC_STOP_TRANSMISSION)
			val |= SDHCI_CMD_ABORTCMD;

		/*
		 * As for the fsl driver,
		 * we have to set the mode in a single write here.
		 */
		writel(val << 16 | mcf_data->aside,
		       host->ioaddr + SDHCI_TRANSFER_MODE);
		return;
	}

	writel((readl(base) & mask) | (val << shift), base);
}

static void esdhc_mcf_writel_be(struct sdhci_host *host, u32 val, int reg)
{
	writel(val, host->ioaddr + reg);
}

static u8 esdhc_mcf_readb_be(struct sdhci_host *host, int reg)
{
	if (reg == SDHCI_HOST_CONTROL) {
		u8 __iomem *base = host->ioaddr + (reg & ~3);
		u16 val = readw(base + 2);
		u8 dma_bits = (val >> 5) & SDHCI_CTRL_DMA_MASK;
		u8 host_ctrl = val & 0xff;

		host_ctrl &= ~SDHCI_CTRL_DMA_MASK;
		host_ctrl |= dma_bits;

		return host_ctrl;
	}

	return readb(host->ioaddr + (reg ^ 0x3));
}

static u16 esdhc_mcf_readw_be(struct sdhci_host *host, int reg)
{
	/*
	 * For SDHCI_HOST_VERSION, sdhci specs defines 0xFE,
	 * a wrong offset for us, we are at 0xFC.
	 */
	if (reg == SDHCI_HOST_VERSION)
		reg -= 2;

	return readw(host->ioaddr + (reg ^ 0x2));
}

static u32 esdhc_mcf_readl_be(struct sdhci_host *host, int reg)
{
	u32 val;

	val = readl(host->ioaddr + reg);

	/*
	 * RM (25.3.9) sd pin clock must never exceed 25Mhz.
	 * So forcing legacy mode at 25Mhz.
	 */
	if (unlikely(reg == SDHCI_CAPABILITIES))
		val &= ~SDHCI_CAN_DO_HISPD;

	if (unlikely(reg == SDHCI_INT_STATUS)) {
		if (val & ESDHC_INT_VENDOR_SPEC_DMA_ERR) {
			val &= ~ESDHC_INT_VENDOR_SPEC_DMA_ERR;
			val |= SDHCI_INT_ADMA_ERROR;
		}
	}

	return val;
}

static unsigned int esdhc_mcf_get_max_timeout_count(struct sdhci_host *host)
{
	return 1 << 27;
}

static void esdhc_mcf_set_timeout(struct sdhci_host *host,
				  struct mmc_command *cmd)
{
	/* Use maximum timeout counter */
	esdhc_clrset_be(host, ESDHC_SYS_CTRL_DTOCV_MASK, 0xE,
			SDHCI_TIMEOUT_CONTROL);
}

static void esdhc_mcf_reset(struct sdhci_host *host, u8 mask)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct pltfm_mcf_data *mcf_data = sdhci_pltfm_priv(pltfm_host);

	sdhci_reset(host, mask);

	esdhc_clrset_be(host, ESDHC_CTRL_BUSWIDTH_MASK,
			mcf_data->current_bus_width, SDHCI_HOST_CONTROL);

	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
}

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

	return pltfm_host->clock;
}

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

	return pltfm_host->clock / 256 / 16;
}

static void esdhc_mcf_pltfm_set_clock(struct sdhci_host *host,
				      unsigned int clock)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	unsigned long *pll_dr = (unsigned long *)MCF_PLL_DR;
	u32 fvco, fsys, fesdhc, temp;
	const int sdclkfs[] = {2, 4, 8, 16, 32, 64, 128, 256};
	int delta, old_delta = clock;
	int i, q, ri, rq;

	if (clock == 0) {
		host->mmc->actual_clock = 0;
		return;
	}

	/*
	 * ColdFire eSDHC clock.s
	 *
	 * pll -+-> / outdiv1 --> fsys
	 *      +-> / outdiv3 --> eSDHC clock ---> / SDCCLKFS / DVS
	 *
	 * mcf5441x datasheet says:
	 * (8.1.2) eSDHC should be 40 MHz max
	 * (25.3.9) eSDHC input is, as example, 96 Mhz ...
	 * (25.3.9) sd pin clock must never exceed 25Mhz
	 *
	 * fvco = fsys * outdvi1 + 1
	 * fshdc = fvco / outdiv3 + 1
	 */
	temp = readl(pll_dr);
	fsys = pltfm_host->clock;
	fvco = fsys * ((temp & 0x1f) + 1);
	fesdhc = fvco / (((temp >> 10) & 0x1f) + 1);

	for (i = 0; i < 8; ++i) {
		int result = fesdhc / sdclkfs[i];

		for (q = 1; q < 17; ++q) {
			int finale = result / q;

			delta = abs(clock - finale);

			if (delta < old_delta) {
				old_delta = delta;
				ri = i;
				rq = q;
			}
		}
	}

	/*
	 * Apply divisors and re-enable all the clocks
	 */
	temp = ((sdclkfs[ri] >> 1) << 8) | ((rq - 1) << 4) |
		(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN);
	esdhc_clrset_be(host, 0x0000fff7, temp, SDHCI_CLOCK_CONTROL);

	host->mmc->actual_clock = clock;

	mdelay(1);
}

static void esdhc_mcf_pltfm_set_bus_width(struct sdhci_host *host, int width)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct pltfm_mcf_data *mcf_data = sdhci_pltfm_priv(pltfm_host);

	switch (width) {
	case MMC_BUS_WIDTH_4:
		mcf_data->current_bus_width = ESDHC_CTRL_4BITBUS;
		break;
	default:
		mcf_data->current_bus_width = 0;
		break;
	}

	esdhc_clrset_be(host, ESDHC_CTRL_BUSWIDTH_MASK,
			mcf_data->current_bus_width, SDHCI_HOST_CONTROL);
}

static void esdhc_mcf_request_done(struct sdhci_host *host,
				   struct mmc_request *mrq)
{
	struct scatterlist *sg;
	u32 *buffer;
	int i;

	if (!mrq->data || !mrq->data->bytes_xfered)
		goto exit_done;

	if (mmc_get_dma_dir(mrq->data) != DMA_FROM_DEVICE)
		goto exit_done;

	/*
	 * On mcf5441x there is no hw sdma option/flag to select the dma
	 * transfer endiannes. A swap after the transfer is needed.
	 */
	for_each_sg(mrq->data->sg, sg, mrq->data->sg_len, i) {
		buffer = (u32 *)sg_virt(sg);
		esdhc_mcf_buffer_swap32(buffer, sg->length);
	}

exit_done:
	mmc_request_done(host->mmc, mrq);
}

static void esdhc_mcf_copy_to_bounce_buffer(struct sdhci_host *host,
					    struct mmc_data *data,
					    unsigned int length)
{
	sg_copy_to_buffer(data->sg, data->sg_len,
			  host->bounce_buffer, length);

	esdhc_mcf_buffer_swap32((u32 *)host->bounce_buffer,
				data->blksz * data->blocks);
}

static struct sdhci_ops sdhci_esdhc_ops = {
	.reset = esdhc_mcf_reset,
	.set_clock = esdhc_mcf_pltfm_set_clock,
	.get_max_clock = esdhc_mcf_pltfm_get_max_clock,
	.get_min_clock = esdhc_mcf_pltfm_get_min_clock,
	.set_bus_width = esdhc_mcf_pltfm_set_bus_width,
	.get_max_timeout_count = esdhc_mcf_get_max_timeout_count,
	.set_timeout = esdhc_mcf_set_timeout,
	.write_b = esdhc_mcf_writeb_be,
	.write_w = esdhc_mcf_writew_be,
	.write_l = esdhc_mcf_writel_be,
	.read_b = esdhc_mcf_readb_be,
	.read_w = esdhc_mcf_readw_be,
	.read_l = esdhc_mcf_readl_be,
	.copy_to_bounce_buffer = esdhc_mcf_copy_to_bounce_buffer,
	.request_done = esdhc_mcf_request_done,
};

static const struct sdhci_pltfm_data sdhci_esdhc_mcf_pdata = {
	.ops = &sdhci_esdhc_ops,
	.quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_FORCE_DMA,
		 /*
		  * Mandatory quirk,
		  * controller does not support cmd23,
		  * without, on > 8G cards cmd23 is used, and
		  * driver times out.
		  */
		  SDHCI_QUIRK2_HOST_NO_CMD23,
};

static int esdhc_mcf_plat_init(struct sdhci_host *host,
			       struct pltfm_mcf_data *mcf_data)
{
	struct mcf_esdhc_platform_data *plat_data;

	if (!host->mmc->parent->platform_data) {
		dev_err(mmc_dev(host->mmc), "no platform data!\n");
		return -EINVAL;
	}

	plat_data = (struct mcf_esdhc_platform_data *)
			host->mmc->parent->platform_data;

	/* Card_detect */
	switch (plat_data->cd_type) {
	default:
	case ESDHC_CD_CONTROLLER:
		/* We have a working card_detect back */
		host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
		break;
	case ESDHC_CD_PERMANENT:
		host->mmc->caps |= MMC_CAP_NONREMOVABLE;
		break;
	case ESDHC_CD_NONE:
		break;
	}

	switch (plat_data->max_bus_width) {
	case 4:
		host->mmc->caps |= MMC_CAP_4_BIT_DATA;
		break;
	case 1:
	default:
		host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA;
		break;
	}

	return 0;
}

static int sdhci_esdhc_mcf_probe(struct platform_device *pdev)
{
	struct sdhci_host *host;
	struct sdhci_pltfm_host *pltfm_host;
	struct pltfm_mcf_data *mcf_data;
	int err;

	host = sdhci_pltfm_init(pdev, &sdhci_esdhc_mcf_pdata,
				sizeof(*mcf_data));

	if (IS_ERR(host))
		return PTR_ERR(host);

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

	host->sdma_boundary = 0;

	host->flags |= SDHCI_AUTO_CMD12;

	mcf_data->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
	if (IS_ERR(mcf_data->clk_ipg)) {
		err = PTR_ERR(mcf_data->clk_ipg);
		goto err_exit;
	}

	mcf_data->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
	if (IS_ERR(mcf_data->clk_ahb)) {
		err = PTR_ERR(mcf_data->clk_ahb);
		goto err_exit;
	}

	mcf_data->clk_per = devm_clk_get(&pdev->dev, "per");
	if (IS_ERR(mcf_data->clk_per)) {
		err = PTR_ERR(mcf_data->clk_per);
		goto err_exit;
	}

	pltfm_host->clk = mcf_data->clk_per;
	pltfm_host->clock = clk_get_rate(pltfm_host->clk);
	err = clk_prepare_enable(mcf_data->clk_per);
	if (err)
		goto err_exit;

	err = clk_prepare_enable(mcf_data->clk_ipg);
	if (err)
		goto unprep_per;

	err = clk_prepare_enable(mcf_data->clk_ahb);
	if (err)
		goto unprep_ipg;

	err = esdhc_mcf_plat_init(host, mcf_data);
	if (err)
		goto unprep_ahb;

	err = sdhci_setup_host(host);
	if (err)
		goto unprep_ahb;

	if (!host->bounce_buffer) {
		dev_err(&pdev->dev, "bounce buffer not allocated");
		err = -ENOMEM;
		goto cleanup;
	}

	err = __sdhci_add_host(host);
	if (err)
		goto cleanup;

	return 0;

cleanup:
	sdhci_cleanup_host(host);
unprep_ahb:
	clk_disable_unprepare(mcf_data->clk_ahb);
unprep_ipg:
	clk_disable_unprepare(mcf_data->clk_ipg);
unprep_per:
	clk_disable_unprepare(mcf_data->clk_per);
err_exit:
	sdhci_pltfm_free(pdev);

	return err;
}

static int sdhci_esdhc_mcf_remove(struct platform_device *pdev)
{
	struct sdhci_host *host = platform_get_drvdata(pdev);
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct pltfm_mcf_data *mcf_data = sdhci_pltfm_priv(pltfm_host);

	sdhci_remove_host(host, 0);

	clk_disable_unprepare(mcf_data->clk_ipg);
	clk_disable_unprepare(mcf_data->clk_ahb);
	clk_disable_unprepare(mcf_data->clk_per);

	sdhci_pltfm_free(pdev);

	return 0;
}

static struct platform_driver sdhci_esdhc_mcf_driver = {
	.driver	= {
		.name = "sdhci-esdhc-mcf",
	},
	.probe = sdhci_esdhc_mcf_probe,
	.remove = sdhci_esdhc_mcf_remove,
};

module_platform_driver(sdhci_esdhc_mcf_driver);

MODULE_DESCRIPTION("SDHCI driver for Freescale ColdFire eSDHC");
MODULE_AUTHOR("Angelo Dureghello <angelo.dureghello@timesys.com>");
MODULE_LICENSE("GPL v2");
