/* Copyright (c) 2013-2014, 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 <platform/iomap.h>
#include <platform/irqs.h>
#include <platform/interrupts.h>
#include <platform/timer.h>
#include <sys/types.h>
#include <target.h>
#include <string.h>
#include <stdlib.h>
#include <bits.h>
#include <debug.h>
#include <mmc.h>
#include <sdhci.h>
#include <sdhci_msm.h>

/* Known data stored in the card & read during tuning
 * process. 64 bytes for 4bit bus width & 128 bytes
 * of data for 8 bit bus width.
 * These values are derived from HPG
 */
static const uint32_t tuning_block_64[] = {
	0x00FF0FFF, 0xCCC3CCFF, 0xFFCC3CC3, 0xEFFEFFFE,
	0xDDFFDFFF, 0xFBFFFBFF, 0xFF7FFFBF, 0xEFBDF777,
	0xF0FFF0FF, 0x3CCCFC0F, 0xCFCC33CC, 0xEEFFEFFF,
	0xFDFFFDFF, 0xFFBFFFDF, 0xFFF7FFBB, 0xDE7B7FF7
};

static const uint32_t tuning_block_128[] = {
	0xFF00FFFF, 0x0000FFFF, 0xCCCCFFFF, 0xCCCC33CC,
	0xCC3333CC, 0xFFFFCCCC, 0xFFFFEEFF, 0xFFEEEEFF,
	0xFFDDFFFF, 0xDDDDFFFF, 0xBBFFFFFF, 0xBBFFFFFF,
	0xFFFFFFBB, 0xFFFFFF77, 0x77FF7777, 0xFFEEDDBB,
	0x00FFFFFF, 0x00FFFFFF, 0xCCFFFF00, 0xCC33CCCC,
	0x3333CCCC, 0xFFCCCCCC, 0xFFEEFFFF, 0xEEEEFFFF,
	0xDDFFFFFF, 0xDDFFFFFF, 0xFFFFFFDD, 0xFFFFFFBB,
	0xFFFFBBBB, 0xFFFF77FF, 0xFF7777FF, 0xEEDDBB77
};

/*
 * Function: sdhci int handler
 * Arg     : MSM specific data for sdhci
 * Return  : 0
 * Flow:   : 1. Read the power control mask register
 *           2. Check if bus is ON
 *           3. Write success to ack regiser
 * Details : This is power control interrupt handler.
 *           Once we receive the interrupt, we will ack the power control
 *           register that we have successfully completed pmic transactions
 */
static enum handler_return sdhci_int_handler(struct sdhci_msm_data *data)
{
	uint32_t ack;
	uint32_t status;

	/*
	 * Read the mask register to check if BUS & IO level
	 * interrupts are enabled
	 */
	status = readl(data->pwrctl_base + SDCC_HC_PWRCTL_MASK_REG);

	if (status & (SDCC_HC_BUS_ON | SDCC_HC_BUS_OFF))
		ack = SDCC_HC_BUS_ON_OFF_SUCC;
	if (status & (SDCC_HC_IO_SIG_LOW | SDCC_HC_IO_SIG_HIGH))
		ack |= SDCC_HC_IO_SIG_SUCC;

	/* Write success to power control register */
	writel(ack, (data->pwrctl_base + SDCC_HC_PWRCTL_CTL_REG));

	event_signal(data->sdhc_event, false);

	return 0;
}

/*
 * Function: sdhci clear pending interrupts
 * Arg     : MSM specific data for sdhci
 * Return  : None
 * Flow:   : Clear pending interrupts
 */
static void sdhci_clear_power_ctrl_irq(struct sdhci_msm_data *data)
{
	uint32_t irq_ctl;
	uint32_t irq_stat;

	/*
	 * Read the power control status register to know
	 * the status of BUS & IO_HIGH_V
	 */
	irq_stat = readl(data->pwrctl_base + SDCC_HC_PWRCTL_STATUS_REG);

	/* Clear the power control status */
	writel(irq_stat, (data->pwrctl_base + SDCC_HC_PWRCTL_CLEAR_REG));

	/*
	 * Handle the pending irq by ack'ing the bus & IO switch
	 */
	irq_ctl = readl(data->pwrctl_base + SDCC_HC_PWRCTL_CTL_REG);

	if (irq_stat & (SDCC_HC_BUS_ON | SDCC_HC_BUS_OFF))
		irq_ctl |= SDCC_HC_BUS_ON_OFF_SUCC;
	if (irq_stat & (SDCC_HC_IO_SIG_LOW | SDCC_HC_IO_SIG_HIGH))
		irq_ctl |= SDCC_HC_IO_SIG_SUCC;

	writel(irq_ctl, (data->pwrctl_base + SDCC_HC_PWRCTL_CTL_REG));
}

/*
 * Function: sdhci msm init
 * Arg     : MSM specific config data for sdhci
 * Return  : None
 * Flow:   : Enable sdhci mode & do msm specific init
 */
void sdhci_msm_init(struct sdhci_host *host, struct sdhci_msm_data *config)
{
	/* Disable HC mode */
	RMWREG32((config->pwrctl_base + SDCC_MCI_HC_MODE), SDHCI_HC_START_BIT, SDHCI_HC_WIDTH, 0);

	/* Core power reset */
	RMWREG32((config->pwrctl_base + SDCC_MCI_POWER), CORE_SW_RST_START, CORE_SW_RST_WIDTH, 1);

	/* Wait for the core power reset to complete*/
	 mdelay(1);

	/* Enable sdhc mode */
	writel(SDHCI_HC_MODE_EN, (config->pwrctl_base + SDCC_MCI_HC_MODE));

	/* Set the FF_CLK_SW_RST_DIS to 1 */
	RMWREG32((config->pwrctl_base + SDCC_MCI_HC_MODE), FF_CLK_SW_RST_DIS_START, FF_CLK_SW_RST_DIS_WIDTH, 1);

	/*
	 * Reset the controller
	 */
	sdhci_reset(host, SDHCI_SOFT_RESET);

	/*
	 * CORE_SW_RST may trigger power irq if previous status of PWRCTL
	 * was either BUS_ON or IO_HIGH. So before we enable the power irq
	 * interrupt in GIC (by registering the interrupt handler), we need to
	 * ensure that any pending power irq interrupt status is acknowledged
	 * otherwise power irq interrupt handler would be fired prematurely.
	 */
	sdhci_clear_power_ctrl_irq(config);

	/*
	 * Register the interrupt handler for pwr irq
	 */
	register_int_handler(config->pwr_irq, sdhci_int_handler, (void *)config);

	unmask_interrupt(config->pwr_irq);

	/* Enable pwr control interrupt */
	writel(SDCC_HC_PWR_CTRL_INT, (config->pwrctl_base + SDCC_HC_PWRCTL_MASK_REG));

	config->tuning_done = false;
	config->calibration_done = false;
	host->tuning_in_progress = false;
}

/*
 * Function: sdhci msm set mci clk
 * Arg     : Host structure
 * Return  : None
 * Flow:   : Set HC_SELECT & HC_SELECT_EN for hs400
 */
void sdhci_msm_set_mci_clk(struct sdhci_host *host)
{
	struct sdhci_msm_data *msm_host;

	msm_host = host->msm_host;

	if (host->timing == MMC_HS400_TIMING)
	{
		/*
		 * If the current tuning mode is HS400 then we should set the MCLK to run
		 * the clock @ MCLK/2. Also set HS400 mode in SELECT_IN of vendor specific
		 * register
		 */
		REG_RMW32(host, SDCC_VENDOR_SPECIFIC_FUNC, SDCC_HC_MCLK_HS400_START, SDCC_HC_MCLK_HS400_WIDTH, SDCC_HC_MCLK_SEL_HS400);

		/* Enable HS400 mode from HC_SELECT_IN bit of VENDOR_SPEC register
		 * As the SDCC spec does not have matching mode for HS400
		 */
		if (msm_host->tuning_done && !msm_host->calibration_done)
		{
			REG_RMW32(host, SDCC_VENDOR_SPECIFIC_FUNC, SDCC_HC_MCLK_SEL_IN_START, SDCC_HC_MCLK_SEL_IN_WIDTH, SDCC_HC_MCLK_SEL_IN_HS400);
			REG_RMW32(host, SDCC_VENDOR_SPECIFIC_FUNC, SDCC_HC_MCLK_SEL_IN_EN_START, SDCC_HC_MCLK_SEL_IN_EN_WIDTH, SDCC_HC_MCLK_SEL_IN_EN);
		}
	}
	else
	{
		/*
		 * Set 0x0 mode in SELECT_IN of vendor specific register so that the
		 * host control2 register settings from sdhc spec are used for
		 * speed mode
		 */
		REG_RMW32(host, SDCC_VENDOR_SPECIFIC_FUNC, SDCC_HC_MCLK_SEL_IN_START, SDCC_HC_MCLK_SEL_IN_WIDTH, 0x0);
		REG_RMW32(host, SDCC_VENDOR_SPECIFIC_FUNC, SDCC_HC_MCLK_SEL_IN_EN_START, SDCC_HC_MCLK_SEL_IN_EN_WIDTH, 0x0);
	}
}

/*
 * Set the value based on sdcc clock frequency
 */
static void msm_set_dll_freq(struct sdhci_host *host)
{
	uint32_t reg_val = 0;

	/* Set clock freq value based on clock range */
	if (host->cur_clk_rate <= 112000000)
		reg_val = 0x0;
	else if (host->cur_clk_rate <= 125000000)
		reg_val = 0x1;
	else if (host->cur_clk_rate <= 137000000)
		reg_val = 0x2;
	else if (host->cur_clk_rate <= 150000000)
		reg_val = 0x3;
	else if (host->cur_clk_rate <= 162000000)
		reg_val = 0x4;
	else if (host->cur_clk_rate <= 175000000)
		reg_val = 0x5;
	else if (host->cur_clk_rate <= 187000000)
		reg_val = 0x6;
	else if (host->cur_clk_rate <= 200000000)
		reg_val = 0x7;

	DBG("\n %s: DLL freq: 0x%08x\n", __func__, reg_val);

	REG_RMW32(host, SDCC_DLL_CONFIG_REG, SDCC_DLL_CONFIG_MCLK_START, SDCC_DLL_CONFIG_MCLK_WIDTH, reg_val);
}

/* Initialize DLL (Programmable Delay Line) */
static uint32_t sdhci_msm_init_dll(struct sdhci_host *host)
{
	uint32_t pwr_save = 0;
	uint32_t timeout = SDHCI_DLL_TIMEOUT;

	pwr_save = REG_READ32(host, SDCC_VENDOR_SPECIFIC_FUNC) & SDCC_DLL_PWR_SAVE_EN;

	/* PWR SAVE to 0 */
	if (pwr_save)
		REG_WRITE32(host, (REG_READ32(host, SDCC_VENDOR_SPECIFIC_FUNC) & ~SDCC_DLL_PWR_SAVE_EN), SDCC_VENDOR_SPECIFIC_FUNC);
	/* Set DLL_RST to 1 */
	REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | SDCC_DLL_RESET_EN), SDCC_DLL_CONFIG_REG);
	/* Set DLL_PDN to 1 */
	REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | SDCC_DLL_PDN_EN), SDCC_DLL_CONFIG_REG);

	/* Set frequency field in DLL_CONFIG */
	msm_set_dll_freq(host);

	/* Write 0 to DLL_RST */
	REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) & ~SDCC_DLL_RESET_EN), SDCC_DLL_CONFIG_REG);
	/* Write 0 to DLL_PDN */
	REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) & ~SDCC_DLL_PDN_EN), SDCC_DLL_CONFIG_REG);
	/* Write 1 to DLL_EN */
	REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | SDCC_DLL_EN), SDCC_DLL_CONFIG_REG);
	/* Write 1 to CLK_OUT_EN */
	REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | SDCC_DLL_CLK_OUT_EN), SDCC_DLL_CONFIG_REG);
	/* Wait for DLL_LOCK in DLL_STATUS register, wait time 50us */
	while(!((REG_READ32(host, SDCC_REG_DLL_STATUS)) & SDCC_DLL_LOCK_STAT));
	{
		udelay(1);
		timeout--;
		if (!timeout)
		{
			dprintf(CRITICAL, "%s: Failed to get DLL lock: 0x%08x\n", __func__, REG_READ32(host, SDCC_REG_DLL_STATUS));
			return 1;
		}
	}

	/* Set the powersave back on */
	if (pwr_save)
		REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | SDCC_DLL_PWR_SAVE_EN), SDCC_VENDOR_SPECIFIC_FUNC);

	return 0;
}

void sdhci_msm_toggle_cdr(struct sdhci_host *host, bool enable)
{
	uint32_t core_cfg;

	core_cfg = REG_READ32(host, SDCC_DLL_CONFIG_REG);

	if (enable)
	{
		core_cfg |= SDCC_DLL_CDR_EN;
	}
	else
	{
		core_cfg &= ~SDCC_DLL_CDR_EN;
	}

	REG_WRITE32(host, core_cfg, SDCC_DLL_CONFIG_REG);
}

/* Configure DLL with delay value based on 'phase' */
static uint32_t sdhci_msm_config_dll(struct sdhci_host *host, uint32_t phase)
{
	uint32_t core_cfg = 0;
	uint32_t timeout = SDHCI_DLL_TIMEOUT;

	/* Gray code values from SWI */
	uint32_t gray_code [] = { 0x0, 0x1, 0x3, 0x2, 0x6, 0x7, 0x5, 0x4, 0xC, 0xD, 0xF, 0xE, 0xA, 0xB, 0x9, 0x8 };

	/* set CDR_EN & CLK_OUT_EN to 0 and
	 * CDR_EXT_EN & DLL_EN to 1*/
	core_cfg = REG_READ32(host, SDCC_DLL_CONFIG_REG);
	core_cfg &= ~(SDCC_DLL_CDR_EN | SDCC_DLL_CLK_OUT_EN);
	core_cfg |= (SDCC_DLL_CDR_EXT_EN | SDCC_DLL_EN);
	REG_WRITE32(host, core_cfg, SDCC_DLL_CONFIG_REG);

	/* Wait until CLK_OUT_EN is 0 */
	while(REG_READ32(host, SDCC_DLL_CONFIG_REG) & SDCC_DLL_CLK_OUT_EN);

	REG_RMW32(host, SDCC_DLL_CONFIG_REG, SDCC_DLL_GRAY_CODE_START, SDCC_DLL_GRAY_CODE_WIDTH, gray_code[phase]);

	REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | SDCC_DLL_CLK_OUT_EN), SDCC_DLL_CONFIG_REG);

	/* Wait until CLK_OUT_EN is 1, wait time 50us */
	while(!(REG_READ32(host, SDCC_DLL_CONFIG_REG) & SDCC_DLL_CLK_OUT_EN))
	{
		timeout--;
		udelay(1);
		if (!timeout)
		{
			dprintf(CRITICAL, "%s: clk_out_en timed out: %08x\n", __func__, REG_READ32(host, SDCC_DLL_CONFIG_REG));
			return 1;
		}
	}

	core_cfg = REG_READ32(host, SDCC_DLL_CONFIG_REG);

	core_cfg |= SDCC_DLL_CDR_EN;
	core_cfg &= ~SDCC_DLL_CDR_EXT_EN;

	REG_WRITE32(host, core_cfg, SDCC_DLL_CONFIG_REG);

	return 0;
}

/*
 * Find the right tuning delay, this function finds the largest
 * consecutive sequence of phases & then selects the 3/4 th of
 * the range which has max entries
 * For eg: If we get the following sequence in phase_table[]
 * (A) phase_table[] = 0x1, 0x2, 0x3, 0x4 , 0x5
 * (B) phase_table[] = 0xA, 0xB, 0xC
 * In the above case the (A) has maximum consecutive entries with '5' entries
 * So delay would be phase_table[(0x5 * 3) / 4] = 0x3
 */
static int sdhci_msm_find_appropriate_phase(struct sdhci_host *host,
										   uint32_t *phase_table,
										   uint32_t total_phases)
{
	int sub_phases[MAX_PHASES][MAX_PHASES]={{0}};
	int phases_per_row[MAX_PHASES] = {0};
	uint32_t i,j;
	int selected_phase = 0;
	uint32_t row_index = 0;
	uint32_t col_index = 0;
	uint32_t phase_15_row_idx = 0;
	uint32_t phases_0_row_idx = 0;
	uint32_t max_phases_3_4_idx = 0;
	uint32_t max_phases = 0;
	uint32_t max_phases_row = 0;
	bool found_loop = false;

	if (!phase_table[0] && phase_table[total_phases - 1] == (MAX_PHASES - 1))
		found_loop = true;

	for (i = 0; i < total_phases; i++)
	{
		/* Break the phase table entries into different sub arrays based
		 * on the consecutive entries. Each row will have one sub array
		 * of consecutive entries.
		 * for eg: phase_table [] = { 0x0, 0x1, 0x2, 0xA, 0xB}
		 * sub_phases [0][] = { 0x0, 0x1, 0x2}
		 * sub_phases [1][] = { 0xA, 0xB}
		 */
		sub_phases[row_index][col_index] = phase_table[i];
		phases_per_row[row_index]++;
		col_index++;

		/* If we are at the last phase no need to check further */
		if ((i + 1) == total_phases)
			break;

		/* If phase_table does not have consecutive entries, move to next entry */
		if (phase_table[i]+1 != phase_table[i+1])
		{
			row_index++;
			col_index = 0;
		}
	}

	if (found_loop && total_phases < MAX_PHASES)
	{
		/* For consecutive entries we need to consider loops.
		 * If the phase_table contains 0x0 & 0xF then we have
		 * a loop, the number after 0xF in the sequence would be
		 * 0x0.
		 * for eg:
		 * phase_table = { 0x0, 0x1, 0x2, 0xD, 0xE, 0xF }
		 * then
		 * sub_phase [0][] = { 0x0, 0x1, 0x2 }
		 * sub_phase [1][] = { 0xD, 0xE, 0xF }
		 * Since we have a loop here, we need to merge the sub arrays as:
		 * sub_phase [1][] = { 0xD, 0xE, 0xF, 0x0, 0x1, 0x2 }
		 */

		/* The entry 0xF will always be in the last row
		 * and entry 0x0 will always be in the first row
		 */
		phase_15_row_idx = row_index;
		j = 0;
		for (i = phases_per_row[phase_15_row_idx] ; i < MAX_PHASES ; i++)
		{
			sub_phases[phase_15_row_idx][i] = sub_phases[phases_0_row_idx][j];
			if (++j >= phases_per_row[phases_0_row_idx])
				break;
		}

		/* Update the number of entries for the sub_phase after the merger */
		phases_per_row[phase_15_row_idx] = phases_per_row[phase_15_row_idx] + phases_per_row[phases_0_row_idx];
		phases_per_row[phases_0_row_idx] = 0;
	}

		for (i = 0 ; i <= row_index; i++)
		{
			if (phases_per_row[i] > max_phases)
			{
				max_phases = phases_per_row[i];
				max_phases_row = i;
			}
		}

	max_phases_3_4_idx = (max_phases * 3) / 4;
	if (max_phases_3_4_idx)
		max_phases_3_4_idx--;

	selected_phase = sub_phases[max_phases_row][max_phases_3_4_idx];

	return selected_phase;
}

static uint32_t sdhci_msm_cdclp533_calibration(struct sdhci_host *host)
{
	uint32_t timeout;
	uint32_t cdc_err;

	DBG("\n CDCLP533 Calibration Start\n");

	/* Reset & Initialize the DLL block */
	if (sdhci_msm_init_dll(host))
		return 1;

	/* Write the save phase */
	if (sdhci_msm_config_dll(host, host->msm_host->saved_phase))
		return 1;

	/* Write 1 to CMD_DAT_TRACK_SEL field in DLL_CONFIG */
	REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | CMD_DAT_TRACK_SEL), SDCC_DLL_CONFIG_REG);

	/* Write 0 to CDC_T4_DLY_SEL field in VENDOR_SPEC_DDR200_CFG */
	REG_WRITE32(host, (REG_READ32(host, SDCC_CDC_DDR200_CFG) & ~CDC_T4_DLY_SEL), SDCC_CDC_DDR200_CFG);

	/* Write 0 to START_CDC_TRAFFIC field in CORE_DDR200_CFG */
	REG_WRITE32(host, (REG_READ32(host, SDCC_CDC_DDR200_CFG) & ~START_CDC_TRAFFIC), SDCC_CDC_DDR200_CFG);

	/* Write 0 to CDC_SWITCH_BYPASS_OFF field in CSR_CDC_GEN_CFG */
	REG_WRITE32(host, (REG_READ32(host, SDCC_VENDOR_SPEC_CSR_CDC_CFG) & ~CDC_SWITCH_BYPASS_OFF), SDCC_VENDOR_SPEC_CSR_CDC_CFG);

	/* Write 1 to CDC_SWITCH_RC_EN field in CSR_CDC_GEN_CFG */
	REG_WRITE32(host, (REG_READ32(host, SDCC_VENDOR_SPEC_CSR_CDC_CFG) | CDC_SWITCH_RC_EN), SDCC_VENDOR_SPEC_CSR_CDC_CFG);

	/* Write 0 to START_CDC_TRAFFIC field in CORE_DDR200_CFG */
	REG_WRITE32(host, (REG_READ32(host, SDCC_CDC_DDR200_CFG) & ~START_CDC_TRAFFIC), SDCC_CDC_DDR200_CFG);

	/* Perform CDCLP533 initialization sequence
	 * SDCC_CSR_CDC_CTRL_CFG0 --> 0x11800EC
	 * SDCC_CSR_CDC_CTRL_CFG1 --> 0x3011111
	 * SDCC_CSR_CDC_CAL_TIMER_CFG0 -->  0x1201000
	 * SDCC_CSR_CDC_CAL_TIMER_CFG1 -->  0x4
	 * SDCC_CSR_CDC_REFCOUNT_CFG -->   0xCB732020
	 * SDCC_CSR_CDC_COARSE_CAL_CFG -->  0xB19
	 * SDCC_CSR_CDC_DELAY_CFG  -->   0x3AC
	 * SDCC_CDC_OFFSET_CFG     -->   0x0
	 * SDCC_CDC_SLAVE_DDA_CFG  -->   0x16334
	 */

	REG_WRITE32(host, 0x11800EC,  SDCC_CSR_CDC_CTRL_CFG0);
	REG_WRITE32(host, 0x3011111,  SDCC_CSR_CDC_CTRL_CFG1);
	REG_WRITE32(host, 0x1201000,  SDCC_CSR_CDC_CAL_TIMER_CFG0);
	REG_WRITE32(host, 0x4,        SDCC_CSR_CDC_CAL_TIMER_CFG1);
	REG_WRITE32(host, 0xCB732020, SDCC_CSR_CDC_REFCOUNT_CFG);
	REG_WRITE32(host, 0xB19,      SDCC_CSR_CDC_COARSE_CAL_CFG);
	REG_WRITE32(host, 0x3AC,      SDCC_CSR_CDC_DELAY_CFG);
	REG_WRITE32(host, 0x0,        SDCC_CDC_OFFSET_CFG);
	REG_WRITE32(host, 0x16334,    SDCC_CDC_SLAVE_DDA_CFG);

	/* Write 1 to SW_TRIGGER_FULL_CALIB */
	REG_WRITE32(host, (REG_READ32(host, SDCC_CSR_CDC_CTRL_CFG0) | CDC_SW_TRIGGER_FULL_CALIB), SDCC_CSR_CDC_CTRL_CFG0);

	/* Write 0 to SW_TRIGGER_FULL_CALIB */
	REG_WRITE32(host, (REG_READ32(host, SDCC_CSR_CDC_CTRL_CFG0) & ~CDC_SW_TRIGGER_FULL_CALIB), SDCC_CSR_CDC_CTRL_CFG0);

	/* Write 1 to HW_AUTO_CAL_EN */
	REG_WRITE32(host, (REG_READ32(host, SDCC_CSR_CDC_CTRL_CFG0) | CDC_HW_AUTO_CAL_EN), SDCC_CSR_CDC_CTRL_CFG0);

	/* Write 1 to TIMER_ENA */
	REG_WRITE32(host, (REG_READ32(host, SDCC_CSR_CDC_CAL_TIMER_CFG0) | CDC_TIMER_EN), SDCC_CSR_CDC_CAL_TIMER_CFG0);

	/* Wait for CALIBRATION_DONE in CDC_STATUS */
	timeout = CDC_STATUS_TIMEOUT;
	while (!(REG_READ32(host, SDCC_CSR_CDC_STATUS0) & BIT(0)))
	{
		timeout--;
		mdelay(1);
		if (!timeout)
		{
			dprintf(CRITICAL, "Error: Calibration done in CDC status not set\n");
			return 1;
		}
	}

	cdc_err = REG_READ32(host, SDCC_CSR_CDC_STATUS0) & CSR_CDC_ERROR_MASK;
	if (cdc_err)
	{
		dprintf(CRITICAL, "CDC error set during calibration: %x\n", cdc_err);
		return 1;
	}
	/* Write 1 to START_CDC_TRAFFIC field in CORE_DDR200_CFG */
	REG_WRITE32(host, (REG_READ32(host, SDCC_CDC_DDR200_CFG) | START_CDC_TRAFFIC), SDCC_CDC_DDR200_CFG);

	DBG("\n CDCLP533 Calibration Done\n");

	return 0;
}

/*
 * Function: sdhci msm execute tuning
 * Arg     : Host structure & bus width
 * Return  : 0 on Success, 1 on Failure
 * Flow:   : Execute Tuning sequence for HS200
 */
uint32_t sdhci_msm_execute_tuning(struct sdhci_host *host, uint32_t bus_width)
{
	uint32_t *tuning_block;
	uint32_t *tuning_data;
	uint32_t tuned_phases[MAX_PHASES] = {{0}};
	uint32_t size;
	uint32_t phase = 0;
	uint32_t tuned_phase_cnt = 0;
	int ret = 0;
	int i;
	struct sdhci_msm_data *msm_host;

	msm_host = host->msm_host;

	/* In Tuning mode */
	host->tuning_in_progress = true;

	/* Calibration for CDCLP533 needed for HS400 mode */
	if (msm_host->tuning_done && !msm_host->calibration_done && host->timing == MMC_HS400_TIMING)
	{
		ret = sdhci_msm_cdclp533_calibration(host);
		if (!ret)
			msm_host->calibration_done = true;
		goto out;
	}

	if (bus_width == DATA_BUS_WIDTH_8BIT)
	{
		tuning_block = tuning_block_128;
		size = sizeof(tuning_block_128);
	}
	else
	{
		tuning_block = tuning_block_64;
		size = sizeof(tuning_block_64);
	}

	tuning_data = (uint32_t *) memalign(CACHE_LINE, ROUNDUP(size, CACHE_LINE));

	ASSERT(tuning_data);

	/* Reset & Initialize the DLL block */
	if (sdhci_msm_init_dll(host))
	{
			ret = 1;
			goto free;
	}

	while (phase < MAX_PHASES)
	{
		struct mmc_command cmd = {0};

		/* configure dll to set phase delay */
		if (sdhci_msm_config_dll(host, phase))
		{
			ret = 1;
			goto free;
		}

		cmd.cmd_index = CMD21_SEND_TUNING_BLOCK;
		cmd.argument = 0x0;
		cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
		cmd.resp_type = SDHCI_CMD_RESP_R1;
		cmd.trans_mode = SDHCI_MMC_READ;
		cmd.data_present = 0x1;
		cmd.data.data_ptr = tuning_data;
		cmd.data.blk_sz = size;
		cmd.data.num_blocks = 0x1;

		/* send command */
		if (!sdhci_send_command(host, &cmd) && !memcmp(tuning_data, tuning_block, size))
				tuned_phases[tuned_phase_cnt++] = phase;

		phase++;
	}

	/* Find the appropriate tuned phase */
	if (tuned_phase_cnt)
	{
		DBG("\n Tuned phase\n");
		for (i = 0 ; i < tuned_phase_cnt ; i++)
		{
			DBG("%d\t", tuned_phases[i]);
		}

		ret = sdhci_msm_find_appropriate_phase(host, tuned_phases, tuned_phase_cnt);

		if (ret < 0)
		{
			dprintf(CRITICAL, "Failed in selecting the tuning phase\n");
			ret = 1;
			goto free;
		}

		phase = (uint32_t) ret;
		ret = 0;

		DBG("\n: %s: Tuned Phase: 0x%08x\n", __func__, phase);

		if (sdhci_msm_config_dll(host, phase))
			goto free;

		/* Save the tuned phase */
		host->msm_host->saved_phase = phase;
	}
	else
	{
		dprintf(CRITICAL, "Failed to get tuned phase\n");
		ret = 1;
	}

free:
	free(tuning_data);
out:
	/* Tuning done */
	host->tuning_in_progress = false;
	host->msm_host->tuning_done = true;
	return ret;
}

/*
 * API to disable HC mode
 */
void sdhci_mode_disable(struct sdhci_host *host)
{
	/* Disable HC mode */
	RMWREG32((host->msm_host->pwrctl_base + SDCC_MCI_HC_MODE), SDHCI_HC_START_BIT, SDHCI_HC_WIDTH, 0);
}

