/*
 * (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 <stddef.h>
#include <stdint.h>
#include <stdio.h>

#include "arch/cache.h"
#include "base/xalloc.h"
#include "drivers/blockdev/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_write32(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_write32(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_read32(host, DWMCI_CTRL);
	ctrl |= DWMCI_IDMAC_EN | DWMCI_DMA_EN;
	dwmci_write32(host, DWMCI_CTRL, ctrl);

	ctrl = dwmci_read32(host, DWMCI_BMOD);
	ctrl |= DWMCI_BMOD_IDMAC_FB | DWMCI_BMOD_IDMAC_EN;
	dwmci_write32(host, DWMCI_BMOD, ctrl);

	dwmci_write32(host, DWMCI_BLKSIZ, data->blocksize);
	dwmci_write32(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_write32(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL);

	if (data)
		dwmci_prepare_data(host, data);

	dwmci_write32(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_write32(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_write32(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_read32(host, DWMCI_RESP3);
			cmd->response[1] = dwmci_read32(host, DWMCI_RESP2);
			cmd->response[2] = dwmci_read32(host, DWMCI_RESP1);
			cmd->response[3] = dwmci_read32(host, DWMCI_RESP0);
		} else {
			cmd->response[0] = dwmci_read32(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_write32(host, DWMCI_RINTSTS, mask);

		ctrl = dwmci_read32(host, DWMCI_CTRL);
		ctrl &= ~(DWMCI_DMA_EN);
		dwmci_write32(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_write32(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_write32(host, DWMCI_CLKENA, 0);
	dwmci_write32(host, DWMCI_CLKSRC, 0);
	host->set_clk(host, freq);
	dwmci_write32(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_write32(host, DWMCI_CLKENA, DWMCI_CLKEN_ENABLE |
			DWMCI_CLKEN_LOW_PWR);

	dwmci_write32(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_write32(host, DWMCI_CTYPE, ctype);
	dwmci_write32(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_write32(host, EMMCP_MPSBEGIN0, 0);
	dwmci_write32(host, EMMCP_SEND0, 0);
	dwmci_write32(host, EMMCP_CTRL0,
		MPSCTRL_SECURE_READ_BIT | MPSCTRL_SECURE_WRITE_BIT |
		MPSCTRL_NON_SECURE_READ_BIT | MPSCTRL_NON_SECURE_WRITE_BIT |
		MPSCTRL_VALID);

	dwmci_write32(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_write32(host, DWMCI_RINTSTS, 0xFFFFFFFF);
	dwmci_write32(host, DWMCI_INTMASK, 0);

	dwmci_write32(host, DWMCI_TMOUT, 0xFFFFFFFF);

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

	fifo_size = dwmci_read32(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_write32(host, DWMCI_FIFOTH, fifoth_val);

	dwmci_write32(host, DWMCI_CLKENA, 0);
	dwmci_write32(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 = gpio_get(host->cd_gpio);
		else
			present = !dwmci_read32(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;
			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;
		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;
}
