/*
 * (C) Copyright 2012 SAMSUNG Electronics
 * Jaehoon Chung <jh80.chung@samsung.com>
 * Rajeshawari Shinde <rajeshwari.s@samsung.com>
 * Copyright 2013 Google Inc.  All rights reserved.
 *
 * 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; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,  MA 02111-1307 USA
 *
 */

#include <assert.h>
#include <libpayload.h>
#include <stddef.h>
#include <stdint.h>

#include "drivers/storage/dw_mmc.h"

enum {
	DwmmcMaxFreq = 52000000,
	DwmmcMinFreq = 400000
};

enum {
	PageSize = 4096
};

static int dwmci_wait_reset(DwmciHost *host, uint32_t value)
{
	unsigned long timeout_ms = 10;

	dwmci_writel(host, DWMCI_CTRL, value);
	return !mmc_busy_wait_io(dwmci_get_ioaddr(host, DWMCI_CTRL), NULL,
				 DWMCI_RESET_ALL, timeout_ms);
}

static void dwmci_set_idma_desc(DwmciIdmac *idmac, uint32_t desc0,
				uint32_t desc1, uint32_t desc2)
{
	DwmciIdmac *desc = idmac;

	desc->flags = desc0;
	desc->cnt = desc1;
	desc->addr = desc2;
	desc->next_addr = (unsigned int)desc + sizeof(DwmciIdmac);
}

static void dwmci_prepare_data(DwmciHost *host, MmcData *data)
{
	unsigned long ctrl;
	unsigned int i = 0, flags, cnt, blk_cnt;
	void *data_start;
	void const *start_addr;
	size_t data_len;
	ALLOC_CACHE_ALIGN_BUFFER(DwmciIdmac, cur_idmac, data->blocks);


	blk_cnt = data->blocks;

	dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET);

	data_start = cur_idmac;
	dwmci_writel(host, DWMCI_DBADDR, (uintptr_t)cur_idmac);

	if (data->flags == MMC_DATA_READ)
		start_addr = data->dest;
	else
		start_addr = data->src;

	do {
		flags = DWMCI_IDMAC_OWN | DWMCI_IDMAC_CH ;
		flags |= (i == 0) ? DWMCI_IDMAC_FS : 0;
		if (blk_cnt <= 8) {
			flags |= DWMCI_IDMAC_LD;
			cnt = data->blocksize * blk_cnt;
		} else
			cnt = data->blocksize * 8;

		dwmci_set_idma_desc(cur_idmac, flags, cnt,
				    (uint32_t)start_addr + (i * PageSize));

		if(blk_cnt < 8)
			break;
		blk_cnt -= 8;
		cur_idmac++;
		i++;
	} while(1);

	data_len = (void *)cur_idmac - data_start;
	dcache_clean_invalidate_by_mva(data_start, data_len + DMA_MINALIGN);

	dcache_clean_invalidate_by_mva(start_addr,
				       (data->blocks * data->blocksize));

	ctrl = dwmci_readl(host, DWMCI_CTRL);
	ctrl |= DWMCI_IDMAC_EN | DWMCI_DMA_EN;
	dwmci_writel(host, DWMCI_CTRL, ctrl);

	ctrl = dwmci_readl(host, DWMCI_BMOD);
	ctrl |= DWMCI_BMOD_IDMAC_FB | DWMCI_BMOD_IDMAC_EN;
	dwmci_writel(host, DWMCI_BMOD, ctrl);

	dwmci_writel(host, DWMCI_BLKSIZ, data->blocksize);
	dwmci_writel(host, DWMCI_BYTCNT, data->blocksize * data->blocks);
}

static int dwmci_set_transfer_mode(DwmciHost *host, MmcData *data)
{
	unsigned long mode;

	mode = DWMCI_CMD_DATA_EXP;
	if (data->flags & MMC_DATA_WRITE)
		mode |= DWMCI_CMD_RW;

	return mode;
}

static int dwmci_send_cmd(MmcCtrlr *ctrlr, MmcCommand *cmd, MmcData *data)
{
	DwmciHost *host = container_of(ctrlr, DwmciHost, mmc);
	int flags = 0;
	unsigned int busy_timeout_ms = 100, send_timeout_ms = 10;
	uint32_t mask, ctrl;

	if (mmc_busy_wait_io(dwmci_get_ioaddr(host, DWMCI_STATUS), NULL,
			     DWMCI_BUSY, busy_timeout_ms) != 0) {
		printf("Timeout on data busy\n");
		return MMC_TIMEOUT;
	}

	dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL);

	if (data)
		dwmci_prepare_data(host, data);

	dwmci_writel(host, DWMCI_CMDARG, cmd->cmdarg);

	if (data)
		flags = dwmci_set_transfer_mode(host, data);

	if ((cmd->resp_type & MMC_RSP_136) && (cmd->resp_type & MMC_RSP_BUSY))
		return -1;

	if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
		flags |= DWMCI_CMD_ABORT_STOP;
	else
		flags |= DWMCI_CMD_PRV_DAT_WAIT;

	if (cmd->resp_type & MMC_RSP_PRESENT) {
		flags |= DWMCI_CMD_RESP_EXP;
		if (cmd->resp_type & MMC_RSP_136)
			flags |= DWMCI_CMD_RESP_LENGTH;
	}

	if (cmd->resp_type & MMC_RSP_CRC)
		flags |= DWMCI_CMD_CHECK_CRC;

	flags |= (cmd->cmdidx | DWMCI_CMD_START | DWMCI_CMD_USE_HOLD_REG);

	mmc_debug("Sending CMD%d\n", cmd->cmdidx);

	dwmci_writel(host, DWMCI_CMD, flags);

	mask = 0;
	if (mmc_busy_wait_io_until(
			dwmci_get_ioaddr(host, DWMCI_RINTSTS), &mask,
			DWMCI_INTMSK_CDONE, send_timeout_ms) != 0) {
		mmc_error("CMD%d timeout.\n", cmd->cmdidx);
		return MMC_TIMEOUT;
	}
	if (!data)
		dwmci_writel(host, DWMCI_RINTSTS, mask);
	if (mask & DWMCI_INTMSK_RTO) {
		mmc_debug("Response Timeout..\n");
		return MMC_TIMEOUT;
	} else if (mask & DWMCI_INTMSK_RE) {
		mmc_debug("Response Error..\n");
		return -1;
	}

	if (cmd->resp_type & MMC_RSP_PRESENT) {
		if (cmd->resp_type & MMC_RSP_136) {
			cmd->response[0] = dwmci_readl(host, DWMCI_RESP3);
			cmd->response[1] = dwmci_readl(host, DWMCI_RESP2);
			cmd->response[2] = dwmci_readl(host, DWMCI_RESP1);
			cmd->response[3] = dwmci_readl(host, DWMCI_RESP0);
		} else {
			cmd->response[0] = dwmci_readl(host, DWMCI_RESP0);
		}
	}

	if (data) {
		uint32_t error_mask = (DWMCI_DATA_ERR | DWMCI_DATA_TOUT),
			 timeout_ms = 1000;
		mask = 0;
		if (mmc_busy_wait_io_until(
				dwmci_get_ioaddr(host, DWMCI_RINTSTS),
				&mask, error_mask | DWMCI_INTMSK_DTO,
				timeout_ms) != 0) {
			mmc_error("DATA timeout!\n");
			return MMC_TIMEOUT;
		}
		if (mask & error_mask) {
			mmc_error("DATA ERROR!\n");
			return -1;
		}

		dwmci_writel(host, DWMCI_RINTSTS, mask);

		ctrl = dwmci_readl(host, DWMCI_CTRL);
		ctrl &= ~(DWMCI_DMA_EN);
		dwmci_writel(host, DWMCI_CTRL, ctrl);
		if (data->flags & MMC_DATA_READ) {
			unsigned long data_len = data->blocks * data->blocksize;
			/*
			 * TODO(hungte) The buffer is supposed to have padding
			 * to the closest cache line boundary, ex:
			 * data_len = ALIGN(data_end, dcache_get_line_size());
			 */
			dcache_invalidate_by_mva(data->dest, data_len);
		}
	}

	return 0;
}

static void dwmci_set_clock(DwmciHost *host, uint32_t freq)
{
	uint32_t div;
	unsigned long sclk;

	sclk = host->src_hz / (DWMCI_GET_DIV_RATIO(host->clksel_val) + 1);
	div = (sclk + (2 * freq) - 1) / (2 * freq);
	dwmci_writel(host, DWMCI_CLKDIV, div);
}

static int dwmci_setup_bus(DwmciHost *host, uint32_t freq)
{
	int timeout_ms = 10;

	if ((freq == host->clock) || (freq == 0))
		return 0;

	dwmci_writel(host, DWMCI_CLKENA, 0);
	dwmci_writel(host, DWMCI_CLKSRC, 0);
	host->set_clk(host, freq);
	dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_PRV_DAT_WAIT |
			DWMCI_CMD_UPD_CLK | DWMCI_CMD_START);

	if (mmc_busy_wait_io(dwmci_get_ioaddr(host, DWMCI_CMD),
			     NULL, DWMCI_CMD_START, timeout_ms) != 0) {
		mmc_error("%s: TIMEOUT error!!\n", __func__);
		return -1;
	}

	dwmci_writel(host, DWMCI_CLKENA, DWMCI_CLKEN_ENABLE |
			DWMCI_CLKEN_LOW_PWR);

	dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_PRV_DAT_WAIT |
			DWMCI_CMD_UPD_CLK | DWMCI_CMD_START);

	if (mmc_busy_wait_io(dwmci_get_ioaddr(host, DWMCI_CMD),
			     NULL, DWMCI_CMD_START, timeout_ms) != 0) {
		mmc_error("%s: TIMEOUT error!!\n", __func__);
		return -1;
	}

	host->clock = freq;
	return 0;
}

static void dwmci_set_ios(MmcCtrlr *ctrlr)
{
	DwmciHost *host = container_of(ctrlr, DwmciHost, mmc);
	uint32_t ctype;

	mmc_debug("Buswidth = %d, clock: %d\n",
		  ctrlr->bus_width, ctrlr->bus_hz);

	dwmci_setup_bus(host, ctrlr->bus_hz);
	switch (ctrlr->bus_width) {
	case 8:
		ctype = DWMCI_CTYPE_8BIT;
		break;
	case 4:
		ctype = DWMCI_CTYPE_4BIT;
		break;
	default:
		ctype = DWMCI_CTYPE_1BIT;
		break;
	}

	dwmci_writel(host, DWMCI_CTYPE, ctype);
	dwmci_writel(host, DWMCI_CLKSEL, host->clksel_val);
}

static int dwmci_init(BlockDevCtrlrOps *me)
{
	DwmciHost *host = container_of(me, DwmciHost, mmc.ctrlr.ops);
	uint32_t fifo_size, fifoth_val;

	dwmci_writel(host, EMMCP_MPSBEGIN0, 0);
	dwmci_writel(host, EMMCP_SEND0, 0);
	dwmci_writel(host, EMMCP_CTRL0,
		MPSCTRL_SECURE_READ_BIT | MPSCTRL_SECURE_WRITE_BIT |
		MPSCTRL_NON_SECURE_READ_BIT | MPSCTRL_NON_SECURE_WRITE_BIT |
		MPSCTRL_VALID);

	dwmci_writel(host, DWMCI_PWREN, 1);

	if (!dwmci_wait_reset(host, DWMCI_RESET_ALL)) {
		printf("%s[%d] Reset failed!!\n", __func__, __LINE__);
		return -1;
	}

	/* Enumerate at 400KHz */
	dwmci_setup_bus(host, host->mmc.f_min);

	dwmci_writel(host, DWMCI_RINTSTS, 0xFFFFFFFF);
	dwmci_writel(host, DWMCI_INTMASK, 0);

	dwmci_writel(host, DWMCI_TMOUT, 0xFFFFFFFF);

	dwmci_writel(host, DWMCI_IDINTEN, 0);
	dwmci_writel(host, DWMCI_BMOD, 1);

	fifo_size = dwmci_readl(host, DWMCI_FIFOTH);
	fifo_size = ((fifo_size & RX_WMARK_MASK) >> RX_WMARK_SHIFT) + 1;
	if (host->fifoth_val) {
		fifoth_val = host->fifoth_val;
	} else {
		fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size / 2 - 1) |
			TX_WMARK(fifo_size / 2);
		host->fifoth_val = fifoth_val;
	}
	dwmci_writel(host, DWMCI_FIFOTH, fifoth_val);

	dwmci_writel(host, DWMCI_CLKENA, 0);
	dwmci_writel(host, DWMCI_CLKSRC, 0);

	return 0;
}

static int dwmci_update(BlockDevCtrlrOps *me)
{
	DwmciHost *host = container_of(me, DwmciHost, mmc.ctrlr.ops);

	if (!host->initialized && dwmci_init(me))
		return -1;

	host->initialized = 1;

	if (host->removable) {
		int present = 0;

		if (host->cd_gpio)	//use gpio detect
			present = host->cd_gpio->get(host->cd_gpio);
		else
			present = !dwmci_readl(host, DWMCI_CDETECT);
		if (present && !host->mmc.media) {
			// A card is present and not set up yet. Get it ready.
			if (mmc_setup_media(&host->mmc))
				return -1;
			host->mmc.media->dev.name = "removable dwmmc";
			host->mmc.media->dev.removable = 1;
			host->mmc.media->dev.ops.read = &block_mmc_read;
			host->mmc.media->dev.ops.write = &block_mmc_write;
			host->mmc.media->dev.ops.new_stream =
						&new_simple_stream;
			list_insert_after(&host->mmc.media->dev.list_node,
					  &removable_block_devices);
		} else if (!present && host->mmc.media) {
			// A card was present but isn't any more. Get rid of it.
			list_remove(&host->mmc.media->dev.list_node);
			free(host->mmc.media);
			host->mmc.media = NULL;
		}
	} else {
		if (mmc_setup_media(&host->mmc))
			return -1;
		host->mmc.media->dev.name = "dwmmc";
		host->mmc.media->dev.removable = 0;
		host->mmc.media->dev.ops.read = &block_mmc_read;
		host->mmc.media->dev.ops.write = &block_mmc_write;
		host->mmc.media->dev.ops.new_stream = &new_simple_stream;
		list_insert_after(&host->mmc.media->dev.list_node,
				  &fixed_block_devices);
		host->mmc.ctrlr.need_update = 0;
	}

	return 0;
}

DwmciHost *new_dwmci_host(uintptr_t ioaddr, uint32_t src_hz,
				int bus_width, int removable,
				GpioOps *card_detect, uint32_t clksel_val)
{
	DwmciHost *ctrlr = xzalloc(sizeof(*ctrlr));

	ctrlr->mmc.ctrlr.ops.update = &dwmci_update;
	ctrlr->mmc.ctrlr.need_update = 1;

	ctrlr->mmc.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
	ctrlr->mmc.f_min = DwmmcMinFreq;
	ctrlr->mmc.f_max = DwmmcMaxFreq;
	ctrlr->mmc.bus_width = bus_width;
	ctrlr->mmc.bus_hz = ctrlr->mmc.f_min;
	ctrlr->mmc.b_max = 65535; // Some controllers use 16-bit regs.
	if (bus_width == 8) {
		ctrlr->mmc.caps |= MMC_MODE_8BIT;
		ctrlr->mmc.caps &= ~MMC_MODE_4BIT;
	} else {
		ctrlr->mmc.caps |= MMC_MODE_4BIT;
		ctrlr->mmc.caps &= ~MMC_MODE_8BIT;
	}
	ctrlr->mmc.caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_HC;
	ctrlr->mmc.send_cmd = &dwmci_send_cmd;
	ctrlr->mmc.set_ios = &dwmci_set_ios;

	ctrlr->ioaddr = (void *)ioaddr;
	ctrlr->src_hz = src_hz;
	ctrlr->clksel_val = clksel_val;
	ctrlr->removable = removable;

	ctrlr->cd_gpio = card_detect;
	ctrlr->set_clk = dwmci_set_clock;
	return ctrlr;
}
