/*
 * Copyright (c) 2011, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdlib.h>
#include <reg.h>

#include "adm.h"
#include <platform/adm.h>

/* TODO: This ADM implementation is very specific for use by MMC.
 *       Replace with a generic ADM driver that can also be used
 *       by other peripherals such as usb/uart/nand/display etc.
 */

/* TODO:
 * adm module shouldn't have to include mmc.h.
 * clean this up when generic adm interface is implemented.
 */
#include "mmc.h"

extern void mdelay(unsigned msecs);
extern void dmb(void);

/* limit the max_row_len to fifo size so that
 * the same src and dst row attributes can be used.
 */
#define MAX_ROW_LEN     MMC_BOOT_MCI_FIFO_SIZE
#define MAX_ROW_NUM     0xFFFF

/* Structures for use with ADM:
 * Must be aligned on 8 byte boundary.
 */
static uint32_t adm_cmd_ptr_list[8] __attribute__ ((aligned(8)));
static uint32_t box_mode_entry[8] __attribute__ ((aligned(8)));

adm_result_t adm_transfer_start(uint32_t adm_chn, uint32_t * cmd_ptr_list);

/* CRCI - mmc slot mapping. */
extern uint8_t sdc_crci_map[5];

/* TODO:
 * This interface is very specific to MMC.
 * We need a generic ADM interface that can be easily
 * used by other modules such as usb/uart/nand.
 */
adm_result_t
adm_transfer_mmc_data(unsigned char slot,
		      unsigned char *data_ptr,
		      unsigned int data_len, unsigned char direction)
{
	uint32_t num_rows;
	uint16_t row_len;
	uint16_t row_offset;
	uint32_t row_num;
	uint32_t adm_crci_num;
	adm_result_t result = ADM_RESULT_SUCCESS;

	/* Make sure slot value is in the range 1..4 */
	ASSERT((slot >= 1) && (slot <= 4));

	adm_crci_num = sdc_crci_map[slot];
	row_len = MMC_BOOT_MCI_FIFO_SIZE;
	num_rows = data_len / MMC_BOOT_MCI_FIFO_SIZE;

	/* While there is data to be transferred */
	while (data_len) {
		if (data_len <= MAX_ROW_LEN) {
			row_len = data_len;
			row_offset = 0;
			row_num = 1;
		} else {
			row_len = MAX_ROW_LEN;
			row_offset = MAX_ROW_LEN;
			row_num = data_len / MAX_ROW_LEN;

			/* Limit the number of row to the max value allowed */
			if (row_num > MAX_ROW_NUM) {
				row_num = MAX_ROW_NUM;
			}
		}

		/* Program ADM registers and initiate data transfer */

		/*  Initialize the Box Mode command entry (single entry) */
		box_mode_entry[0] = (ADM_CMD_LIST_LC |
				     (adm_crci_num << 3) | ADM_ADDR_MODE_BOX);

		if (direction == ADM_MMC_READ) {
			box_mode_entry[1] = MMC_BOOT_MCI_FIFO;	/* SRC addr    */
			box_mode_entry[2] = (uint32_t) data_ptr;	/* DST addr    */
			box_mode_entry[3] = ((row_len << 16) |	/* SRC row len */
					     (row_len << 0));	/* DST row len */
			box_mode_entry[4] = ((row_num << 16) |	/* SRC row #   */
					     (row_num << 0));	/* DST row #   */
			box_mode_entry[5] = ((0 << 16) |	/* SRC offset  */
					     (row_offset << 0));	/* DST offset  */
		} else {
			box_mode_entry[1] = (uint32_t) data_ptr;	/* SRC addr    */
			box_mode_entry[2] = MMC_BOOT_MCI_FIFO;	/* DST addr    */
			box_mode_entry[3] = ((row_len << 16) |	/* SRC row len */
					     (row_len << 0));	/* DST row len */
			box_mode_entry[4] = ((row_num << 16) |	/* SRC row #   */
					     (row_num << 0));	/* DST row #   */
			box_mode_entry[5] = ((row_offset << 16) |	/* SRC offset  */
					     (0 << 0));	/* DST offset  */
		}

		/*  Initialize the ADM Command Pointer List (single entry) */
		adm_cmd_ptr_list[0] = (ADM_CMD_PTR_LP |
				       ADM_CMD_PTR_CMD_LIST |
				       (((uint32_t) (&box_mode_entry[0])) >>
					3));

		/* Start ADM transfer, this is a blocking call. */
		result = adm_transfer_start(ADM_CHN, adm_cmd_ptr_list);

		if (result != ADM_RESULT_SUCCESS) {
			break;
		}

		/* Update the data ptr and data len by the amount
		 * we just transferred.
		 */
		data_ptr += (row_len * row_num);
		data_len -= (row_len * row_num);
	}

	return result;
}

/*
 * Start the ADM data transfer and return the result of the transfer.
 * Blocks until transfer is completed.
 */
adm_result_t adm_transfer_start(uint32_t adm_chn, uint32_t * cmd_ptr_list)
{
	uint32_t reg_value;
	uint32_t timeout = 1;
	uint32_t delay_count = 100;

	/* Memory barrier to ensure that all ADM command list structure
	 * writes have completed before starting the ADM transfer.
	 */
	dmb();

	/* Start the ADM transfer by writing the command ptr */
	writel(((uint32_t) cmd_ptr_list) >> 3,
	       ADM_REG_CMD_PTR(adm_chn, ADM_SD));

	/* Poll the status register to check for transfer complete.
	 * Bail out if transfer is not finished within 1 sec.
	 * Note: This time depends on the amount of data being transferred.
	 * Increase the delay_count if this is not sufficient.
	 */
	do {
		reg_value = readl(ADM_REG_STATUS(adm_chn, ADM_SD));
		if ((reg_value & ADM_REG_STATUS__RSLT_VLD___M) != 0) {
			timeout = 0;
			break;
		}

		/* 10ms wait */
		mdelay(10);

	}
	while (delay_count--);

	/* Read out the IRQ register to clear the interrupt.
	 * Even though we are not using interrupts,
	 * kernel is not clearing the interupts during its
	 * ADM initialization, causing it to crash.
	 */
	reg_value = readl(ADM_REG_IRQ(ADM_SD));

	if (timeout) {
		return ADM_RESULT_TIMEOUT;
	} else {
		/* Get the result from the RSLT FIFO */
		reg_value = readl(ADM_REG_RSLT(adm_chn, ADM_SD));

		/* Check for any error */
		if (((reg_value & ADM_REG_RSLT__ERR___M) != 0) ||
		    ((reg_value & ADM_REG_RSLT__TPD___M) == 0) ||
		    ((reg_value & ADM_REG_RSLT__V___M) == 0)) {
			return ADM_RESULT_FAILURE;
		}
	}

	return ADM_RESULT_SUCCESS;
}
