/*
 * MOXA ART MMC host driver.
 *
 * Copyright (C) 2014 Jonas Jensen
 *
 * Jonas Jensen <jonas.jensen@gmail.com>
 *
 * Based on code from
 * Moxa Technologies Co., Ltd. <www.moxa.com>
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/blkdev.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sd.h>
#include <linux/sched.h>
#include <linux/io.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/clk.h>
#include <linux/bitops.h>
#include <linux/of_dma.h>
#include <linux/spinlock.h>

#define REG_COMMAND		0
#define REG_ARGUMENT		4
#define REG_RESPONSE0		8
#define REG_RESPONSE1		12
#define REG_RESPONSE2		16
#define REG_RESPONSE3		20
#define REG_RESPONSE_COMMAND	24
#define REG_DATA_CONTROL	28
#define REG_DATA_TIMER		32
#define REG_DATA_LENGTH		36
#define REG_STATUS		40
#define REG_CLEAR		44
#define REG_INTERRUPT_MASK	48
#define REG_POWER_CONTROL	52
#define REG_CLOCK_CONTROL	56
#define REG_BUS_WIDTH		60
#define REG_DATA_WINDOW		64
#define REG_FEATURE		68
#define REG_REVISION		72

/* REG_COMMAND */
#define CMD_SDC_RESET		BIT(10)
#define CMD_EN			BIT(9)
#define CMD_APP_CMD		BIT(8)
#define CMD_LONG_RSP		BIT(7)
#define CMD_NEED_RSP		BIT(6)
#define CMD_IDX_MASK		0x3f

/* REG_RESPONSE_COMMAND */
#define RSP_CMD_APP		BIT(6)
#define RSP_CMD_IDX_MASK	0x3f

/* REG_DATA_CONTROL */
#define DCR_DATA_FIFO_RESET     BIT(8)
#define DCR_DATA_THRES          BIT(7)
#define DCR_DATA_EN		BIT(6)
#define DCR_DMA_EN		BIT(5)
#define DCR_DATA_WRITE		BIT(4)
#define DCR_BLK_SIZE		0x0f

/* REG_DATA_LENGTH */
#define DATA_LEN_MASK		0xffffff

/* REG_STATUS */
#define WRITE_PROT		BIT(12)
#define CARD_DETECT		BIT(11)
/* 1-10 below can be sent to either registers, interrupt or clear. */
#define CARD_CHANGE		BIT(10)
#define FIFO_ORUN		BIT(9)
#define FIFO_URUN		BIT(8)
#define DATA_END		BIT(7)
#define CMD_SENT		BIT(6)
#define DATA_CRC_OK		BIT(5)
#define RSP_CRC_OK		BIT(4)
#define DATA_TIMEOUT		BIT(3)
#define RSP_TIMEOUT		BIT(2)
#define DATA_CRC_FAIL		BIT(1)
#define RSP_CRC_FAIL		BIT(0)

#define MASK_RSP		(RSP_TIMEOUT | RSP_CRC_FAIL | \
				 RSP_CRC_OK  | CARD_DETECT  | CMD_SENT)

#define MASK_DATA		(DATA_CRC_OK   | DATA_END | \
				 DATA_CRC_FAIL | DATA_TIMEOUT)

#define MASK_INTR_PIO		(FIFO_URUN | FIFO_ORUN | CARD_CHANGE)

/* REG_POWER_CONTROL */
#define SD_POWER_ON		BIT(4)
#define SD_POWER_MASK		0x0f

/* REG_CLOCK_CONTROL */
#define CLK_HISPD		BIT(9)
#define CLK_OFF			BIT(8)
#define CLK_SD			BIT(7)
#define CLK_DIV_MASK		0x7f

/* REG_BUS_WIDTH */
#define BUS_WIDTH_4_SUPPORT	BIT(3)
#define BUS_WIDTH_4		BIT(2)
#define BUS_WIDTH_1		BIT(0)

#define MMC_VDD_360		23
#define MIN_POWER		(MMC_VDD_360 - SD_POWER_MASK)
#define MAX_RETRIES		500000

struct moxart_host {
	spinlock_t			lock;

	void __iomem			*base;

	phys_addr_t			reg_phys;

	struct dma_chan			*dma_chan_tx;
	struct dma_chan                 *dma_chan_rx;
	struct dma_async_tx_descriptor	*tx_desc;
	struct mmc_host			*mmc;
	struct mmc_request		*mrq;
	struct scatterlist		*cur_sg;
	struct completion		dma_complete;
	struct completion		pio_complete;

	u32				num_sg;
	u32				data_remain;
	u32				data_len;
	u32				fifo_width;
	u32				timeout;
	u32				rate;

	long				sysclk;

	bool				have_dma;
	bool				is_removed;
};

static inline void moxart_init_sg(struct moxart_host *host,
				  struct mmc_data *data)
{
	host->cur_sg = data->sg;
	host->num_sg = data->sg_len;
	host->data_remain = host->cur_sg->length;

	if (host->data_remain > host->data_len)
		host->data_remain = host->data_len;
}

static inline int moxart_next_sg(struct moxart_host *host)
{
	int remain;
	struct mmc_data *data = host->mrq->cmd->data;

	host->cur_sg++;
	host->num_sg--;

	if (host->num_sg > 0) {
		host->data_remain = host->cur_sg->length;
		remain = host->data_len - data->bytes_xfered;
		if (remain > 0 && remain < host->data_remain)
			host->data_remain = remain;
	}

	return host->num_sg;
}

static int moxart_wait_for_status(struct moxart_host *host,
				  u32 mask, u32 *status)
{
	int ret = -ETIMEDOUT;
	u32 i;

	for (i = 0; i < MAX_RETRIES; i++) {
		*status = readl(host->base + REG_STATUS);
		if (!(*status & mask)) {
			udelay(5);
			continue;
		}
		writel(*status & mask, host->base + REG_CLEAR);
		ret = 0;
		break;
	}

	if (ret)
		dev_err(mmc_dev(host->mmc), "timed out waiting for status\n");

	return ret;
}


static void moxart_send_command(struct moxart_host *host,
	struct mmc_command *cmd)
{
	u32 status, cmdctrl;

	writel(RSP_TIMEOUT  | RSP_CRC_OK |
	       RSP_CRC_FAIL | CMD_SENT, host->base + REG_CLEAR);
	writel(cmd->arg, host->base + REG_ARGUMENT);

	cmdctrl = cmd->opcode & CMD_IDX_MASK;
	if (cmdctrl == SD_APP_SET_BUS_WIDTH    || cmdctrl == SD_APP_OP_COND   ||
	    cmdctrl == SD_APP_SEND_SCR         || cmdctrl == SD_APP_SD_STATUS ||
	    cmdctrl == SD_APP_SEND_NUM_WR_BLKS)
		cmdctrl |= CMD_APP_CMD;

	if (cmd->flags & MMC_RSP_PRESENT)
		cmdctrl |= CMD_NEED_RSP;

	if (cmd->flags & MMC_RSP_136)
		cmdctrl |= CMD_LONG_RSP;

	writel(cmdctrl | CMD_EN, host->base + REG_COMMAND);

	if (moxart_wait_for_status(host, MASK_RSP, &status) == -ETIMEDOUT)
		cmd->error = -ETIMEDOUT;

	if (status & RSP_TIMEOUT) {
		cmd->error = -ETIMEDOUT;
		return;
	}
	if (status & RSP_CRC_FAIL) {
		cmd->error = -EIO;
		return;
	}
	if (status & RSP_CRC_OK) {
		if (cmd->flags & MMC_RSP_136) {
			cmd->resp[3] = readl(host->base + REG_RESPONSE0);
			cmd->resp[2] = readl(host->base + REG_RESPONSE1);
			cmd->resp[1] = readl(host->base + REG_RESPONSE2);
			cmd->resp[0] = readl(host->base + REG_RESPONSE3);
		} else {
			cmd->resp[0] = readl(host->base + REG_RESPONSE0);
		}
	}
}

static void moxart_dma_complete(void *param)
{
	struct moxart_host *host = param;

	complete(&host->dma_complete);
}

static void moxart_transfer_dma(struct mmc_data *data, struct moxart_host *host)
{
	u32 len, dir_slave;
	long dma_time;
	struct dma_async_tx_descriptor *desc = NULL;
	struct dma_chan *dma_chan;

	if (host->data_len == data->bytes_xfered)
		return;

	if (data->flags & MMC_DATA_WRITE) {
		dma_chan = host->dma_chan_tx;
		dir_slave = DMA_MEM_TO_DEV;
	} else {
		dma_chan = host->dma_chan_rx;
		dir_slave = DMA_DEV_TO_MEM;
	}

	len = dma_map_sg(dma_chan->device->dev, data->sg,
			 data->sg_len, mmc_get_dma_dir(data));

	if (len > 0) {
		desc = dmaengine_prep_slave_sg(dma_chan, data->sg,
					       len, dir_slave,
					       DMA_PREP_INTERRUPT |
					       DMA_CTRL_ACK);
	} else {
		dev_err(mmc_dev(host->mmc), "dma_map_sg returned zero length\n");
	}

	if (desc) {
		host->tx_desc = desc;
		desc->callback = moxart_dma_complete;
		desc->callback_param = host;
		dmaengine_submit(desc);
		dma_async_issue_pending(dma_chan);
	}

	data->bytes_xfered += host->data_remain;

	dma_time = wait_for_completion_interruptible_timeout(
		   &host->dma_complete, host->timeout);

	dma_unmap_sg(dma_chan->device->dev,
		     data->sg, data->sg_len,
		     mmc_get_dma_dir(data));
}


static void moxart_transfer_pio(struct moxart_host *host)
{
	struct mmc_data *data = host->mrq->cmd->data;
	u32 *sgp, len = 0, remain, status;

	if (host->data_len == data->bytes_xfered)
		return;

	sgp = sg_virt(host->cur_sg);
	remain = host->data_remain;

	if (data->flags & MMC_DATA_WRITE) {
		while (remain > 0) {
			if (moxart_wait_for_status(host, FIFO_URUN, &status)
			     == -ETIMEDOUT) {
				data->error = -ETIMEDOUT;
				complete(&host->pio_complete);
				return;
			}
			for (len = 0; len < remain && len < host->fifo_width;) {
				iowrite32(*sgp, host->base + REG_DATA_WINDOW);
				sgp++;
				len += 4;
			}
			remain -= len;
		}

	} else {
		while (remain > 0) {
			if (moxart_wait_for_status(host, FIFO_ORUN, &status)
			    == -ETIMEDOUT) {
				data->error = -ETIMEDOUT;
				complete(&host->pio_complete);
				return;
			}
			for (len = 0; len < remain && len < host->fifo_width;) {
				/* SCR data must be read in big endian. */
				if (data->mrq->cmd->opcode == SD_APP_SEND_SCR)
					*sgp = ioread32be(host->base +
							  REG_DATA_WINDOW);
				else
					*sgp = ioread32(host->base +
							REG_DATA_WINDOW);
				sgp++;
				len += 4;
			}
			remain -= len;
		}
	}

	data->bytes_xfered += host->data_remain - remain;
	host->data_remain = remain;

	if (host->data_len != data->bytes_xfered)
		moxart_next_sg(host);
	else
		complete(&host->pio_complete);
}

static void moxart_prepare_data(struct moxart_host *host)
{
	struct mmc_data *data = host->mrq->cmd->data;
	u32 datactrl;
	int blksz_bits;

	if (!data)
		return;

	host->data_len = data->blocks * data->blksz;
	blksz_bits = ffs(data->blksz) - 1;
	BUG_ON(1 << blksz_bits != data->blksz);

	moxart_init_sg(host, data);

	datactrl = DCR_DATA_EN | (blksz_bits & DCR_BLK_SIZE);

	if (data->flags & MMC_DATA_WRITE)
		datactrl |= DCR_DATA_WRITE;

	if ((host->data_len > host->fifo_width) && host->have_dma)
		datactrl |= DCR_DMA_EN;

	writel(DCR_DATA_FIFO_RESET, host->base + REG_DATA_CONTROL);
	writel(MASK_DATA | FIFO_URUN | FIFO_ORUN, host->base + REG_CLEAR);
	writel(host->rate, host->base + REG_DATA_TIMER);
	writel(host->data_len, host->base + REG_DATA_LENGTH);
	writel(datactrl, host->base + REG_DATA_CONTROL);
}

static void moxart_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
	struct moxart_host *host = mmc_priv(mmc);
	long pio_time;
	unsigned long flags;
	u32 status;

	spin_lock_irqsave(&host->lock, flags);

	init_completion(&host->dma_complete);
	init_completion(&host->pio_complete);

	host->mrq = mrq;

	if (readl(host->base + REG_STATUS) & CARD_DETECT) {
		mrq->cmd->error = -ETIMEDOUT;
		goto request_done;
	}

	moxart_prepare_data(host);
	moxart_send_command(host, host->mrq->cmd);

	if (mrq->cmd->data) {
		if ((host->data_len > host->fifo_width) && host->have_dma) {

			writel(CARD_CHANGE, host->base + REG_INTERRUPT_MASK);

			spin_unlock_irqrestore(&host->lock, flags);

			moxart_transfer_dma(mrq->cmd->data, host);

			spin_lock_irqsave(&host->lock, flags);
		} else {

			writel(MASK_INTR_PIO, host->base + REG_INTERRUPT_MASK);

			spin_unlock_irqrestore(&host->lock, flags);

			/* PIO transfers start from interrupt. */
			pio_time = wait_for_completion_interruptible_timeout(
				   &host->pio_complete, host->timeout);

			spin_lock_irqsave(&host->lock, flags);
		}

		if (host->is_removed) {
			dev_err(mmc_dev(host->mmc), "card removed\n");
			mrq->cmd->error = -ETIMEDOUT;
			goto request_done;
		}

		if (moxart_wait_for_status(host, MASK_DATA, &status)
		    == -ETIMEDOUT) {
			mrq->cmd->data->error = -ETIMEDOUT;
			goto request_done;
		}

		if (status & DATA_CRC_FAIL)
			mrq->cmd->data->error = -ETIMEDOUT;

		if (mrq->cmd->data->stop)
			moxart_send_command(host, mrq->cmd->data->stop);
	}

request_done:
	spin_unlock_irqrestore(&host->lock, flags);
	mmc_request_done(host->mmc, mrq);
}

static irqreturn_t moxart_irq(int irq, void *devid)
{
	struct moxart_host *host = (struct moxart_host *)devid;
	u32 status;
	unsigned long flags;

	spin_lock_irqsave(&host->lock, flags);

	status = readl(host->base + REG_STATUS);
	if (status & CARD_CHANGE) {
		host->is_removed = status & CARD_DETECT;
		if (host->is_removed && host->have_dma) {
			dmaengine_terminate_all(host->dma_chan_tx);
			dmaengine_terminate_all(host->dma_chan_rx);
		}
		host->mrq = NULL;
		writel(MASK_INTR_PIO, host->base + REG_CLEAR);
		writel(CARD_CHANGE, host->base + REG_INTERRUPT_MASK);
		mmc_detect_change(host->mmc, 0);
	}
	if (status & (FIFO_ORUN | FIFO_URUN) && host->mrq)
		moxart_transfer_pio(host);

	spin_unlock_irqrestore(&host->lock, flags);

	return IRQ_HANDLED;
}

static void moxart_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
	struct moxart_host *host = mmc_priv(mmc);
	unsigned long flags;
	u8 power, div;
	u32 ctrl;

	spin_lock_irqsave(&host->lock, flags);

	if (ios->clock) {
		for (div = 0; div < CLK_DIV_MASK; ++div) {
			if (ios->clock >= host->sysclk / (2 * (div + 1)))
				break;
		}
		ctrl = CLK_SD | div;
		host->rate = host->sysclk / (2 * (div + 1));
		if (host->rate > host->sysclk)
			ctrl |= CLK_HISPD;
		writel(ctrl, host->base + REG_CLOCK_CONTROL);
	}

	if (ios->power_mode == MMC_POWER_OFF) {
		writel(readl(host->base + REG_POWER_CONTROL) & ~SD_POWER_ON,
		       host->base + REG_POWER_CONTROL);
	} else {
		if (ios->vdd < MIN_POWER)
			power = 0;
		else
			power = ios->vdd - MIN_POWER;

		writel(SD_POWER_ON | (u32) power,
		       host->base + REG_POWER_CONTROL);
	}

	switch (ios->bus_width) {
	case MMC_BUS_WIDTH_4:
		writel(BUS_WIDTH_4, host->base + REG_BUS_WIDTH);
		break;
	default:
		writel(BUS_WIDTH_1, host->base + REG_BUS_WIDTH);
		break;
	}

	spin_unlock_irqrestore(&host->lock, flags);
}


static int moxart_get_ro(struct mmc_host *mmc)
{
	struct moxart_host *host = mmc_priv(mmc);

	return !!(readl(host->base + REG_STATUS) & WRITE_PROT);
}

static const struct mmc_host_ops moxart_ops = {
	.request = moxart_request,
	.set_ios = moxart_set_ios,
	.get_ro = moxart_get_ro,
};

static int moxart_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *node = dev->of_node;
	struct resource res_mmc;
	struct mmc_host *mmc;
	struct moxart_host *host = NULL;
	struct dma_slave_config cfg;
	struct clk *clk;
	void __iomem *reg_mmc;
	int irq, ret;
	u32 i;

	mmc = mmc_alloc_host(sizeof(struct moxart_host), dev);
	if (!mmc) {
		dev_err(dev, "mmc_alloc_host failed\n");
		ret = -ENOMEM;
		goto out;
	}

	ret = of_address_to_resource(node, 0, &res_mmc);
	if (ret) {
		dev_err(dev, "of_address_to_resource failed\n");
		goto out;
	}

	irq = irq_of_parse_and_map(node, 0);
	if (irq <= 0) {
		dev_err(dev, "irq_of_parse_and_map failed\n");
		ret = -EINVAL;
		goto out;
	}

	clk = devm_clk_get(dev, NULL);
	if (IS_ERR(clk)) {
		ret = PTR_ERR(clk);
		goto out;
	}

	reg_mmc = devm_ioremap_resource(dev, &res_mmc);
	if (IS_ERR(reg_mmc)) {
		ret = PTR_ERR(reg_mmc);
		goto out;
	}

	ret = mmc_of_parse(mmc);
	if (ret)
		goto out;

	host = mmc_priv(mmc);
	host->mmc = mmc;
	host->base = reg_mmc;
	host->reg_phys = res_mmc.start;
	host->timeout = msecs_to_jiffies(1000);
	host->sysclk = clk_get_rate(clk);
	host->fifo_width = readl(host->base + REG_FEATURE) << 2;
	host->dma_chan_tx = dma_request_slave_channel_reason(dev, "tx");
	host->dma_chan_rx = dma_request_slave_channel_reason(dev, "rx");

	spin_lock_init(&host->lock);

	mmc->ops = &moxart_ops;
	mmc->f_max = DIV_ROUND_CLOSEST(host->sysclk, 2);
	mmc->f_min = DIV_ROUND_CLOSEST(host->sysclk, CLK_DIV_MASK * 2);
	mmc->ocr_avail = 0xffff00;	/* Support 2.0v - 3.6v power. */

	if (IS_ERR(host->dma_chan_tx) || IS_ERR(host->dma_chan_rx)) {
		if (PTR_ERR(host->dma_chan_tx) == -EPROBE_DEFER ||
		    PTR_ERR(host->dma_chan_rx) == -EPROBE_DEFER) {
			ret = -EPROBE_DEFER;
			goto out;
		}
		dev_dbg(dev, "PIO mode transfer enabled\n");
		host->have_dma = false;
	} else {
		dev_dbg(dev, "DMA channels found (%p,%p)\n",
			 host->dma_chan_tx, host->dma_chan_rx);
		host->have_dma = true;

		memset(&cfg, 0, sizeof(cfg));
		cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
		cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;

		cfg.direction = DMA_MEM_TO_DEV;
		cfg.src_addr = 0;
		cfg.dst_addr = host->reg_phys + REG_DATA_WINDOW;
		dmaengine_slave_config(host->dma_chan_tx, &cfg);

		cfg.direction = DMA_DEV_TO_MEM;
		cfg.src_addr = host->reg_phys + REG_DATA_WINDOW;
		cfg.dst_addr = 0;
		dmaengine_slave_config(host->dma_chan_rx, &cfg);
	}

	if (readl(host->base + REG_BUS_WIDTH) & BUS_WIDTH_4_SUPPORT)
		mmc->caps |= MMC_CAP_4_BIT_DATA;

	writel(0, host->base + REG_INTERRUPT_MASK);

	writel(CMD_SDC_RESET, host->base + REG_COMMAND);
	for (i = 0; i < MAX_RETRIES; i++) {
		if (!(readl(host->base + REG_COMMAND) & CMD_SDC_RESET))
			break;
		udelay(5);
	}

	ret = devm_request_irq(dev, irq, moxart_irq, 0, "moxart-mmc", host);
	if (ret)
		goto out;

	dev_set_drvdata(dev, mmc);
	ret = mmc_add_host(mmc);
	if (ret)
		goto out;

	dev_dbg(dev, "IRQ=%d, FIFO is %d bytes\n", irq, host->fifo_width);

	return 0;

out:
	if (mmc)
		mmc_free_host(mmc);
	return ret;
}

static int moxart_remove(struct platform_device *pdev)
{
	struct mmc_host *mmc = dev_get_drvdata(&pdev->dev);
	struct moxart_host *host = mmc_priv(mmc);

	dev_set_drvdata(&pdev->dev, NULL);

	if (mmc) {
		if (!IS_ERR(host->dma_chan_tx))
			dma_release_channel(host->dma_chan_tx);
		if (!IS_ERR(host->dma_chan_rx))
			dma_release_channel(host->dma_chan_rx);
		mmc_remove_host(mmc);

		writel(0, host->base + REG_INTERRUPT_MASK);
		writel(0, host->base + REG_POWER_CONTROL);
		writel(readl(host->base + REG_CLOCK_CONTROL) | CLK_OFF,
		       host->base + REG_CLOCK_CONTROL);
		mmc_free_host(mmc);
	}
	return 0;
}

static const struct of_device_id moxart_mmc_match[] = {
	{ .compatible = "moxa,moxart-mmc" },
	{ .compatible = "faraday,ftsdc010" },
	{ }
};
MODULE_DEVICE_TABLE(of, moxart_mmc_match);

static struct platform_driver moxart_mmc_driver = {
	.probe      = moxart_probe,
	.remove     = moxart_remove,
	.driver     = {
		.name		= "mmc-moxart",
		.of_match_table	= moxart_mmc_match,
	},
};
module_platform_driver(moxart_mmc_driver);

MODULE_ALIAS("platform:mmc-moxart");
MODULE_DESCRIPTION("MOXA ART MMC driver");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Jonas Jensen <jonas.jensen@gmail.com>");
