/*
 * DDR3 mem setup file for board based on EXYNOS5
 *
 * Copyright (C) 2012 Samsung Electronics
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <config.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/cpu.h>
#include <asm/arch/dmc.h>
#include <asm/arch/power.h>
#include "common_setup.h"
#include "exynos5_setup.h"
#include "clock_init.h"

#define TIMEOUT_US		10000
#define NUM_BYTE_LANES		4
#define DEFAULT_DQS		8
#define DEFAULT_DQS_X4		(DEFAULT_DQS << 24) || (DEFAULT_DQS << 16) \
				|| (DEFAULT_DQS << 8) || (DEFAULT_DQS << 0)

#ifdef CONFIG_EXYNOS5250
static void reset_phy_ctrl(void)
{
	struct exynos5_clock *clk =
		(struct exynos5_clock *)samsung_get_base_clock();

	writel(DDR3PHY_CTRL_PHY_RESET_OFF, &clk->lpddr3phy_ctrl);
	writel(DDR3PHY_CTRL_PHY_RESET, &clk->lpddr3phy_ctrl);
}

int ddr3_mem_ctrl_init(struct mem_timings *mem, int reset)
{
	unsigned int val;
	struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl;
	struct exynos5_dmc *dmc;
	int i;

	phy0_ctrl = (struct exynos5_phy_control *)samsung_get_base_dmc_phy();
	phy1_ctrl = (struct exynos5_phy_control *)(samsung_get_base_dmc_phy()
							+ DMC_OFFSET);
	dmc = (struct exynos5_dmc *)samsung_get_base_dmc_ctrl();

	if (reset)
		reset_phy_ctrl();

	/* Set Impedance Output Driver */
	val = (mem->impedance << CA_CK_DRVR_DS_OFFSET) |
		(mem->impedance << CA_CKE_DRVR_DS_OFFSET) |
		(mem->impedance << CA_CS_DRVR_DS_OFFSET) |
		(mem->impedance << CA_ADR_DRVR_DS_OFFSET);
	writel(val, &phy0_ctrl->phy_con39);
	writel(val, &phy1_ctrl->phy_con39);

	/* Set Read Latency and Burst Length for PHY0 and PHY1 */
	val = (mem->ctrl_bstlen << PHY_CON42_CTRL_BSTLEN_SHIFT) |
		(mem->ctrl_rdlat << PHY_CON42_CTRL_RDLAT_SHIFT);
	writel(val, &phy0_ctrl->phy_con42);
	writel(val, &phy1_ctrl->phy_con42);

	/* ZQ Calibration */
	if (dmc_config_zq(mem, &phy0_ctrl->phy_con16, &phy1_ctrl->phy_con16,
			  &phy0_ctrl->phy_con17, &phy1_ctrl->phy_con17))
		return SETUP_ERR_ZQ_CALIBRATION_FAILURE;

	/* DQ Signal */
	writel(mem->phy0_pulld_dqs, &phy0_ctrl->phy_con14);
	writel(mem->phy1_pulld_dqs, &phy1_ctrl->phy_con14);

	writel(mem->concontrol | (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)
		| (mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT),
		&dmc->concontrol);

	update_reset_dll(&dmc->phycontrol0, DDR_MODE_DDR3);

	/* DQS Signal */
	writel(mem->phy0_dqs, &phy0_ctrl->phy_con4);
	writel(mem->phy1_dqs, &phy1_ctrl->phy_con4);

	writel(mem->phy0_dq, &phy0_ctrl->phy_con6);
	writel(mem->phy1_dq, &phy1_ctrl->phy_con6);

	writel(mem->phy0_tFS, &phy0_ctrl->phy_con10);
	writel(mem->phy1_tFS, &phy1_ctrl->phy_con10);

	val = (mem->ctrl_start_point << PHY_CON12_CTRL_START_POINT_SHIFT) |
		(mem->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) |
		(mem->ctrl_dll_on << PHY_CON12_CTRL_DLL_ON_SHIFT) |
		(mem->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT);
	writel(val, &phy0_ctrl->phy_con12);
	writel(val, &phy1_ctrl->phy_con12);

	/* Start DLL locking */
	writel(val | (mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT),
	       &phy0_ctrl->phy_con12);
	writel(val | (mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT),
	       &phy1_ctrl->phy_con12);

	update_reset_dll(&dmc->phycontrol0, DDR_MODE_DDR3);

	writel(mem->concontrol | (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT),
	       &dmc->concontrol);

	/* Memory Channel Inteleaving Size */
	writel(mem->iv_size, &dmc->ivcontrol);

	writel(mem->memconfig, &dmc->memconfig0);
	writel(mem->memconfig, &dmc->memconfig1);
	writel(mem->membaseconfig0, &dmc->membaseconfig0);
	writel(mem->membaseconfig1, &dmc->membaseconfig1);

	/* Precharge Configuration */
	writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
	       &dmc->prechconfig);

	/* Power Down mode Configuration */
	writel(mem->dpwrdn_cyc << PWRDNCONFIG_DPWRDN_CYC_SHIFT |
		mem->dsref_cyc << PWRDNCONFIG_DSREF_CYC_SHIFT,
		&dmc->pwrdnconfig);

	/* TimingRow, TimingData, TimingPower and Timingaref
	 * values as per Memory AC parameters
	 */
	writel(mem->timing_ref, &dmc->timingref);
	writel(mem->timing_row, &dmc->timingrow);
	writel(mem->timing_data, &dmc->timingdata);
	writel(mem->timing_power, &dmc->timingpower);

	/* Send PALL command */
	dmc_config_prech(mem, &dmc->directcmd);

	/* Send NOP, MRS and ZQINIT commands */
	dmc_config_mrs(mem, &dmc->directcmd);

	if (mem->gate_leveling_enable) {
		val = PHY_CON0_RESET_VAL;
		val |= P0_CMD_EN;
		writel(val, &phy0_ctrl->phy_con0);
		writel(val, &phy1_ctrl->phy_con0);

		val = PHY_CON2_RESET_VAL;
		val |= INIT_DESKEW_EN;
		writel(val, &phy0_ctrl->phy_con2);
		writel(val, &phy1_ctrl->phy_con2);

		val = PHY_CON0_RESET_VAL;
		val |= P0_CMD_EN;
		val |= BYTE_RDLVL_EN;
		writel(val, &phy0_ctrl->phy_con0);
		writel(val, &phy1_ctrl->phy_con0);

		val = (mem->ctrl_start_point <<
				PHY_CON12_CTRL_START_POINT_SHIFT) |
			(mem->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) |
			(mem->ctrl_force << PHY_CON12_CTRL_FORCE_SHIFT) |
			(mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT) |
			(mem->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT);
		writel(val, &phy0_ctrl->phy_con12);
		writel(val, &phy1_ctrl->phy_con12);

		val = PHY_CON2_RESET_VAL;
		val |= INIT_DESKEW_EN;
		val |= RDLVL_GATE_EN;
		writel(val, &phy0_ctrl->phy_con2);
		writel(val, &phy1_ctrl->phy_con2);

		val = PHY_CON0_RESET_VAL;
		val |= P0_CMD_EN;
		val |= BYTE_RDLVL_EN;
		val |= CTRL_SHGATE;
		writel(val, &phy0_ctrl->phy_con0);
		writel(val, &phy1_ctrl->phy_con0);

		val = PHY_CON1_RESET_VAL;
		val &= ~(CTRL_GATEDURADJ_MASK);
		writel(val, &phy0_ctrl->phy_con1);
		writel(val, &phy1_ctrl->phy_con1);

		writel(CTRL_RDLVL_GATE_ENABLE, &dmc->rdlvl_config);
		i = TIMEOUT_US;
		while ((readl(&dmc->phystatus) &
			(RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1)) !=
			(RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1) && i > 0) {
			/*
			 * TODO(waihong): Comment on how long this take to
			 * timeout
			 */
			sdelay(100);
			i--;
		}
		if (!i)
			return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
		writel(CTRL_RDLVL_GATE_DISABLE, &dmc->rdlvl_config);

		writel(0, &phy0_ctrl->phy_con14);
		writel(0, &phy1_ctrl->phy_con14);

		val = (mem->ctrl_start_point <<
				PHY_CON12_CTRL_START_POINT_SHIFT) |
			(mem->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) |
			(mem->ctrl_force << PHY_CON12_CTRL_FORCE_SHIFT) |
			(mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT) |
			(mem->ctrl_dll_on << PHY_CON12_CTRL_DLL_ON_SHIFT) |
			(mem->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT);
		writel(val, &phy0_ctrl->phy_con12);
		writel(val, &phy1_ctrl->phy_con12);

		update_reset_dll(&dmc->phycontrol0, DDR_MODE_DDR3);
	}

	/* Send PALL command */
	dmc_config_prech(mem, &dmc->directcmd);

	writel(mem->memcontrol, &dmc->memcontrol);

	/* Set DMC Concontrol and enable auto-refresh counter */
	writel(mem->concontrol | (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)
		| (mem->aref_en << CONCONTROL_AREF_EN_SHIFT), &dmc->concontrol);
	return 0;
}
#endif

#ifdef CONFIG_EXYNOS5420
/**
 * RAM address to use in the test.
 *
 * We'll use 4 words at this address and 4 at this address + 0x80 (Ares
 * interleaves channels every 128 bytes).  This will allow us to evaluate all of
 * the chips in a 1 chip per channel (2GB) system and half the chips in a 2
 * chip per channel (4GB) system.  We can't test the 2nd chip since we need to
 * do tests before the 2nd chip is enabled.  Looking at the 2nd chip isn't
 * critical because the 1st and 2nd chip have very similar timings (they'd
 * better have similar timings, since there's only a single adjustment that is
 * shared by both chips).
 */
const unsigned int test_addr = CONFIG_SYS_SDRAM_BASE;

/* Test pattern with which RAM will be tested */
static const unsigned int test_pattern[] = {
	0x5a5a5a5a,
	0xa5a5a5a5,
	0xf0f0f0f0,
	0x0f0f0f0f,
};

/**
 * This function is a test vector for sw read leveling,
 * it compares the read data with the written data.
 *
 * @param ch			DMC channel number
 * @param byte_lane		which DQS byte offset,
 *				possible values are 0,1,2,3
 * @return			TRUE if memory was good, FALSE if not.
 */
static bool dmc_valid_window_test_vector(int ch, int byte_lane)
{
	unsigned int read_data;
	unsigned int mask;
	int i;

	mask = 0xFF << (8 * byte_lane);

	for (i = 0; i < ARRAY_SIZE(test_pattern); i++) {
		read_data = readl(test_addr + i * 4 + ch * 0x80);
		if ((read_data & mask) != (test_pattern[i] & mask))
			return false;
	}

	return true;
}

/**
 * This function returns current read offset value.
 *
 * @param phy_ctrl	pointer to the current phy controller
 */
static unsigned int dmc_get_read_offset_value(struct exynos5420_phy_control
					       *phy_ctrl)
{
	return readl(&phy_ctrl->phy_con4);
}

/**
 * This function performs resync, so that slave DLL is updated.
 *
 * @param phy_ctrl	pointer to the current phy controller
 */
static void ddr_phy_set_do_resync(struct exynos5420_phy_control *phy_ctrl)
{
	setbits_le32(&phy_ctrl->phy_con10, PHY_CON10_CTRL_OFFSETR3);
	clrbits_le32(&phy_ctrl->phy_con10, PHY_CON10_CTRL_OFFSETR3);
}

/**
 * This function sets read offset value register with 'offset'.
 *
 * ...we also call call ddr_phy_set_do_resync().
 *
 * @param phy_ctrl	pointer to the current phy controller
 * @param offset	offset to read DQS
 */
static void dmc_set_read_offset_value(struct exynos5420_phy_control *phy_ctrl,
				      unsigned int offset)
{
	writel(offset, &phy_ctrl->phy_con4);
	ddr_phy_set_do_resync(phy_ctrl);
}

/**
 * Convert a 2s complement byte to a byte with a sign bit.
 *
 * NOTE: you shouldn't use normal math on the number returned by this function.
 *   As an example, -10 = 0xf6.  After this function -10 = 0x8a.  If you wanted
 *   to do math and get the average of 10 and -10 (should be 0):
 *     0x8a + 0xa = 0x94 (-108)
 *     0x94 / 2   = 0xca (-54)
 *   ...and 0xca = sign bit plus 0x4a, or -74
 *
 * Also note that you lose the ability to represent -128 since there are two
 * representations of 0.
 *
 * @param b	The byte to convert in two's complement.
 * @return	The 7-bit value + sign bit.
 */

unsigned char make_signed_byte(signed char b)
{
	if (b < 0)
		return 0x80 | -b;
	else
		return b;
}

/**
 * Test various shifts starting at 'start' and going to 'end'.
 *
 * For each byte lane, we'll walk through shift starting at 'start' and going
 * to 'end' (inclusive).  When we are finally able to read the test pattern
 * we'll store the value in the results array.
 *
 * @param phy_ctrl		pointer to the current phy controller
 * @param ch			channel number
 * @param start			the start shift.  -127 to 127
 * @param end			the end shift.  -127 to 127
 * @param results		we'll store results for each byte lane.
 */

void test_shifts(struct exynos5420_phy_control *phy_ctrl, int ch,
		 int start, int end, int results[NUM_BYTE_LANES])
{
	int incr = (start < end) ? 1 : -1;
	int byte_lane;

	for (byte_lane = 0; byte_lane < NUM_BYTE_LANES; byte_lane++) {
		int shift;

		dmc_set_read_offset_value(phy_ctrl, DEFAULT_DQS_X4);
		results[byte_lane] = DEFAULT_DQS;

		for (shift = start; shift != (end + incr); shift += incr) {
			unsigned int byte_offsetr;
			unsigned int offsetr;

			byte_offsetr = make_signed_byte(shift);

			offsetr = dmc_get_read_offset_value(phy_ctrl);
			offsetr &= ~(0xFF << (8 * byte_lane));
			offsetr |= (byte_offsetr << (8 * byte_lane));
			dmc_set_read_offset_value(phy_ctrl, offsetr);

			if (dmc_valid_window_test_vector(ch, byte_lane)) {
				results[byte_lane] = shift;
				break;
			}
		}
	}
}

/**
 * This function performs SW read leveling to compensate DQ-DQS skew at
 * receiver it first finds the optimal read offset value on each DQS
 * then applies the value to PHY.
 *
 * Read offset value has its min margin and max margin. If read offset
 * value exceeds its min or max margin, read data will have corruption.
 * To avoid this we are doing sw read leveling.
 *
 * SW read leveling is:
 * 1> Finding offset value's left_limit and right_limit
 * 2> and calculate its center value
 * 3> finally programs that center value to PHY
 * 4> then PHY gets its optimal offset value.
 *
 * @param phy_ctrl		pointer to the current phy controller
 * @param ch			channel number
 * @param coarse_lock_val	The coarse lock value read from PHY_CON13.
 *				(0 - 0x7f)
 */
static void software_find_read_offset(struct exynos5420_phy_control *phy_ctrl,
				      int ch, unsigned int coarse_lock_val)
{
	unsigned int offsetr_cent;
	int byte_lane;
	int left_limit;
	int right_limit;
	int left[NUM_BYTE_LANES];
	int right[NUM_BYTE_LANES];
	int i;

	/* Fill the memory with test patterns */
	for (i = 0; i < ARRAY_SIZE(test_pattern); i++)
		writel(test_pattern[i], test_addr + i * 4 + ch * 0x80);

	/* Figure out the limits we'll test with; keep -127 < limit < 127 */
	left_limit = DEFAULT_DQS - coarse_lock_val;
	right_limit = DEFAULT_DQS + coarse_lock_val;
	if (right_limit > 127)
		right_limit = 127;

	/* Fill in the location where reads were OK from left and right */
	test_shifts(phy_ctrl, ch, left_limit, right_limit, left);
	test_shifts(phy_ctrl, ch, right_limit, left_limit, right);

	/* Make a final value by taking the center between the left and right */
	offsetr_cent = 0;
	for (byte_lane = 0; byte_lane < NUM_BYTE_LANES; byte_lane++) {
		int temp_center;
		unsigned int vmwc;

		temp_center = (left[byte_lane] + right[byte_lane]) / 2;
		vmwc = make_signed_byte(temp_center);
		offsetr_cent |= vmwc << (8 * byte_lane);
	}
	dmc_set_read_offset_value(phy_ctrl, offsetr_cent);
}

int ddr3_mem_ctrl_init(struct mem_timings *mem, int reset)
{
	struct exynos5420_clock *clk =
		(struct exynos5420_clock *)samsung_get_base_clock();
	struct exynos5420_power *power =
		(struct exynos5420_power *)samsung_get_base_power();
	struct exynos5420_phy_control *phy0_ctrl, *phy1_ctrl;
	struct exynos5420_dmc *drex0, *drex1;
	struct exynos5420_tzasc *tzasc0, *tzasc1;
	struct exynos5_power *pmu;
	uint32_t val, n_lock_r, n_lock_w_phy0, n_lock_w_phy1;
	uint32_t lock0_info, lock1_info;
	int chip;
	int i;

	phy0_ctrl = (struct exynos5420_phy_control *)samsung_get_base_dmc_phy();
	phy1_ctrl = (struct exynos5420_phy_control *)(samsung_get_base_dmc_phy()
							+ DMC_OFFSET);
	drex0 = (struct exynos5420_dmc *)samsung_get_base_dmc_ctrl();
	drex1 = (struct exynos5420_dmc *)(samsung_get_base_dmc_ctrl()
							+ DMC_OFFSET);
	tzasc0 = (struct exynos5420_tzasc *)samsung_get_base_dmc_tzasc();
	tzasc1 = (struct exynos5420_tzasc *)(samsung_get_base_dmc_tzasc()
							+ DMC_OFFSET);
	pmu = (struct exynos5_power *)EXYNOS5420_POWER_BASE;

	if (CONFIG_NR_DRAM_BANKS > 4) {
		/* Need both controllers. */
		mem->memcontrol |= DMC_MEMCONTROL_NUM_CHIP_2;
		mem->chips_per_channel = 2;
		mem->chips_to_configure = 2;
	} else {
		/* 2GB requires a single controller */
		mem->memcontrol |= DMC_MEMCONTROL_NUM_CHIP_1;
	}

	/* Enable PAUSE for DREX */
	setbits_le32(&clk->pause, ENABLE_BIT);

	/* Enable BYPASS mode */
	setbits_le32(&clk->bpll_con1, BYPASS_EN);

	writel(MUX_BPLL_SEL_FOUTBPLL, &clk->src_cdrex);
	do {
		val = readl(&clk->mux_stat_cdrex);
		val &= BPLL_SEL_MASK;
	} while (val != FOUTBPLL);

	clrbits_le32(&clk->bpll_con1, BYPASS_EN);

	/* Specify the DDR memory type as DDR3 */
	val = readl(&phy0_ctrl->phy_con0);
	val &= ~(PHY_CON0_CTRL_DDR_MODE_MASK << PHY_CON0_CTRL_DDR_MODE_SHIFT);
	val |= (DDR_MODE_DDR3 << PHY_CON0_CTRL_DDR_MODE_SHIFT);
	writel(val, &phy0_ctrl->phy_con0);

	val = readl(&phy1_ctrl->phy_con0);
	val &= ~(PHY_CON0_CTRL_DDR_MODE_MASK << PHY_CON0_CTRL_DDR_MODE_SHIFT);
	val |= (DDR_MODE_DDR3 << PHY_CON0_CTRL_DDR_MODE_SHIFT);
	writel(val, &phy1_ctrl->phy_con0);

	/* Set Read Latency and Burst Length for PHY0 and PHY1 */
	val = (mem->ctrl_bstlen << PHY_CON42_CTRL_BSTLEN_SHIFT) |
		(mem->ctrl_rdlat << PHY_CON42_CTRL_RDLAT_SHIFT);
	writel(val, &phy0_ctrl->phy_con42);
	writel(val, &phy1_ctrl->phy_con42);

	val = readl(&phy0_ctrl->phy_con26);
	val &= ~(T_WRDATA_EN_MASK << T_WRDATA_EN_OFFSET);
	val |= (T_WRDATA_EN_DDR3 << T_WRDATA_EN_OFFSET);
	writel(val, &phy0_ctrl->phy_con26);

	val = readl(&phy1_ctrl->phy_con26);
	val &= ~(T_WRDATA_EN_MASK << T_WRDATA_EN_OFFSET);
	val |= (T_WRDATA_EN_DDR3 << T_WRDATA_EN_OFFSET);
	writel(val, &phy1_ctrl->phy_con26);

	/*
	 * Set Driver strength for CK, CKE, CS & CA to 0x7
	 * Set Driver strength for Data Slice 0~3 to 0x7
	 */
	val = (0x7 << CA_CK_DRVR_DS_OFFSET) | (0x7 << CA_CKE_DRVR_DS_OFFSET) |
		(0x7 << CA_CS_DRVR_DS_OFFSET) | (0x7 << CA_ADR_DRVR_DS_OFFSET);
	val |= (0x7 << DA_3_DS_OFFSET) | (0x7 << DA_2_DS_OFFSET) |
		(0x7 << DA_1_DS_OFFSET) | (0x7 << DA_0_DS_OFFSET);
	writel(val, &phy0_ctrl->phy_con39);
	writel(val, &phy1_ctrl->phy_con39);

	/* ZQ Calibration */
	if (dmc_config_zq(mem, &phy0_ctrl->phy_con16, &phy1_ctrl->phy_con16,
			  &phy0_ctrl->phy_con17, &phy1_ctrl->phy_con17))
		return SETUP_ERR_ZQ_CALIBRATION_FAILURE;

	clrbits_le32(&phy0_ctrl->phy_con16, ZQ_CLK_DIV_EN);
	clrbits_le32(&phy1_ctrl->phy_con16, ZQ_CLK_DIV_EN);

	/* DQ Signal */
	val = readl(&phy0_ctrl->phy_con14);
	val |= mem->phy0_pulld_dqs;
	writel(val, &phy0_ctrl->phy_con14);
	val = readl(&phy1_ctrl->phy_con14);
	val |= mem->phy1_pulld_dqs;
	writel(val, &phy1_ctrl->phy_con14);

	val = MEM_TERM_EN | PHY_TERM_EN;
	writel(val, &drex0->phycontrol0);
	writel(val, &drex1->phycontrol0);

	writel(mem->concontrol |
		(mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT) |
		(mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT),
		&drex0->concontrol);
	writel(mem->concontrol |
		(mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT) |
		(mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT),
		&drex1->concontrol);

	do {
		val = readl(&drex0->phystatus);
	} while ((val & DFI_INIT_COMPLETE) != DFI_INIT_COMPLETE);
	do {
		val = readl(&drex1->phystatus);
	} while ((val & DFI_INIT_COMPLETE) != DFI_INIT_COMPLETE);

	clrbits_le32(&drex0->concontrol, DFI_INIT_START);
	clrbits_le32(&drex1->concontrol, DFI_INIT_START);

	update_reset_dll(&drex0->phycontrol0, DDR_MODE_DDR3);
	update_reset_dll(&drex1->phycontrol0, DDR_MODE_DDR3);

	/*
	 * Set Base Address:
	 * 0x2000_0000 ~ 0x5FFF_FFFF
	 * 0x6000_0000 ~ 0x9FFF_FFFF
	 */
	/* MEMBASECONFIG0 */
	val = DMC_MEMBASECONFIGX_CHIP_BASE(DMC_CHIP_BASE_0) |
		DMC_MEMBASECONFIGX_CHIP_MASK(DMC_CHIP_MASK);
	writel(val, &tzasc0->membaseconfig0);
	writel(val, &tzasc1->membaseconfig0);

	/* MEMBASECONFIG1 */
	val = DMC_MEMBASECONFIGX_CHIP_BASE(DMC_CHIP_BASE_1) |
		DMC_MEMBASECONFIGX_CHIP_MASK(DMC_CHIP_MASK);
	writel(val, &tzasc0->membaseconfig1);
	writel(val, &tzasc1->membaseconfig1);

	/*
	 * Memory Channel Inteleaving Size
	 * Ares Channel interleaving = 128 bytes
	 */
	/* MEMCONFIG0/1 */
	writel(mem->memconfig, &tzasc0->memconfig0);
	writel(mem->memconfig, &tzasc1->memconfig0);
	writel(mem->memconfig, &tzasc0->memconfig1);
	writel(mem->memconfig, &tzasc1->memconfig1);

	/* Precharge Configuration */
	writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
	       &drex0->prechconfig0);
	writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
	       &drex1->prechconfig0);

	/*
	 * TimingRow, TimingData, TimingPower and Timingaref
	 * values as per Memory AC parameters
	 */
	writel(mem->timing_ref, &drex0->timingref);
	writel(mem->timing_ref, &drex1->timingref);
	writel(mem->timing_row, &drex0->timingrow0);
	writel(mem->timing_row, &drex1->timingrow0);
	writel(mem->timing_data, &drex0->timingdata0);
	writel(mem->timing_data, &drex1->timingdata0);
	writel(mem->timing_power, &drex0->timingpower0);
	writel(mem->timing_power, &drex1->timingpower0);

	if (reset) {
		/*
		 * Send NOP, MRS and ZQINIT commands
		 * Sending MRS command will reset the DRAM. We should not be
		 * reseting the DRAM after resume, this will lead to memory
		 * corruption as DRAM content is lost after DRAM reset
		 */
		dmc_config_mrs(mem, &drex0->directcmd);
		dmc_config_mrs(mem, &drex1->directcmd);
	}

	/*
	 * Get PHY_CON13 from both phys.  Gate CLKM around reading since
	 * PHY_CON13 is glitchy when CLKM is running.  We're paranoid and
	 * wait until we get a "fine lock", though a coarse lock is probably
	 * OK (we only use the coarse numbers below).  We try to gate the
	 * clock for as short a time as possible in case SDRAM is somehow
	 * sensitive.  sdelay(10) in the loop is arbitrary to make sure
	 * there is some time for PHY_CON13 to get updated.  In practice
	 * no delay appears to be needed.
	 */
	val = readl(&clk->gate_bus_cdrex);
	while (true) {
		writel(val & ~0x1, &clk->gate_bus_cdrex);
		lock0_info = readl(&phy0_ctrl->phy_con13);
		writel(val, &clk->gate_bus_cdrex);

		if ((lock0_info & CTRL_FINE_LOCKED) == CTRL_FINE_LOCKED)
			break;

		sdelay(10);
	}
	while (true) {
		writel(val & ~0x2, &clk->gate_bus_cdrex);
		lock1_info = readl(&phy1_ctrl->phy_con13);
		writel(val, &clk->gate_bus_cdrex);

		if ((lock1_info & CTRL_FINE_LOCKED) == CTRL_FINE_LOCKED)
			break;

		sdelay(10);
	}

	if (!reset) {
		/*
		 * During Suspend-Resume & S/W-Reset, as soon as PMU releases
		 * pad retention, CKE goes high. This causes memory contents
		 * not to be retained during DRAM initialization. Therfore,
		 * there is a new control register(0x100431e8[28]) which lets us
		 * release pad retention and retain the memory content until the
		 * initialization is complete.
		 */
		writel(PAD_RETENTION_DRAM_COREBLK_VAL,
		       &power->pad_retention_dram_coreblk_option);
		do {
			val = readl(&power->pad_retention_dram_status);
		} while (val != 0x1);

		/*
		 * CKE PAD retention disables DRAM self-refresh mode.
		 * Send auto refresh command for DRAM refresh.
		 */
		for (i = 0; i < 128; i++) {
			for (chip = 0; chip < mem->chips_to_configure; chip++) {
				writel(DIRECT_CMD_REFA |
				       (chip << DIRECT_CMD_CHIP_SHIFT),
				       &drex0->directcmd);
				writel(DIRECT_CMD_REFA |
				       (chip << DIRECT_CMD_CHIP_SHIFT),
				       &drex1->directcmd);
			}
		}
	}

	if (mem->gate_leveling_enable) {
		writel(PHY_CON0_RESET_VAL, &phy0_ctrl->phy_con0);
		writel(PHY_CON0_RESET_VAL, &phy1_ctrl->phy_con0);

		setbits_le32(&phy0_ctrl->phy_con0, P0_CMD_EN);
		setbits_le32(&phy1_ctrl->phy_con0, P0_CMD_EN);

		val = PHY_CON2_RESET_VAL;
		val |= INIT_DESKEW_EN;
		writel(val, &phy0_ctrl->phy_con2);
		writel(val, &phy1_ctrl->phy_con2);

		val =  readl(&phy0_ctrl->phy_con1);
		val |= (RDLVL_PASS_ADJ_VAL << RDLVL_PASS_ADJ_OFFSET);
		writel(val, &phy0_ctrl->phy_con1);

		val =  readl(&phy1_ctrl->phy_con1);
		val |= (RDLVL_PASS_ADJ_VAL << RDLVL_PASS_ADJ_OFFSET);
		writel(val, &phy1_ctrl->phy_con1);

		n_lock_w_phy0 = (lock0_info & CTRL_LOCK_COARSE_MASK) >> 2;
		n_lock_r = readl(&phy0_ctrl->phy_con12);
		n_lock_r &= ~CTRL_DLL_ON;
		n_lock_r |= n_lock_w_phy0;
		writel(n_lock_r, &phy0_ctrl->phy_con12);

		n_lock_w_phy1 = (lock1_info & CTRL_LOCK_COARSE_MASK) >> 2;
		n_lock_r = readl(&phy1_ctrl->phy_con12);
		n_lock_r &= ~CTRL_DLL_ON;
		n_lock_r |= n_lock_w_phy1;
		writel(n_lock_r, &phy1_ctrl->phy_con12);

		val = (0x3 << DIRECT_CMD_BANK_SHIFT) | 0x4;
		for (chip = 0; chip < mem->chips_to_configure; chip++) {
			writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
			       &drex0->directcmd);
			writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
			       &drex1->directcmd);
		}

		setbits_le32(&phy0_ctrl->phy_con2, RDLVL_GATE_EN);
		setbits_le32(&phy1_ctrl->phy_con2, RDLVL_GATE_EN);

		setbits_le32(&phy0_ctrl->phy_con0, CTRL_SHGATE);
		setbits_le32(&phy1_ctrl->phy_con0, CTRL_SHGATE);

		val = readl(&phy0_ctrl->phy_con1);
		val &= ~(CTRL_GATEDURADJ_MASK);
		writel(val, &phy0_ctrl->phy_con1);

		val = readl(&phy1_ctrl->phy_con1);
		val &= ~(CTRL_GATEDURADJ_MASK);
		writel(val, &phy1_ctrl->phy_con1);

		writel(CTRL_RDLVL_GATE_ENABLE, &drex0->rdlvl_config);
		i = TIMEOUT_US;
		while (((readl(&drex0->phystatus) & RDLVL_COMPLETE_CHO) !=
			RDLVL_COMPLETE_CHO) && (i > 0)) {
			/*
			 * TODO(waihong): Comment on how long this take to
			 * timeout
			 */
			sdelay(100);
			i--;
		}
		if (!i)
			return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
		writel(CTRL_RDLVL_GATE_DISABLE, &drex0->rdlvl_config);

		writel(CTRL_RDLVL_GATE_ENABLE, &drex1->rdlvl_config);
		i = TIMEOUT_US;
		while (((readl(&drex1->phystatus) & RDLVL_COMPLETE_CHO) !=
			RDLVL_COMPLETE_CHO) && (i > 0)) {
			/*
			 * TODO(waihong): Comment on how long this take to
			 * timeout
			 */
			sdelay(100);
			i--;
		}
		if (!i)
			return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
		writel(CTRL_RDLVL_GATE_DISABLE, &drex1->rdlvl_config);

		writel(0, &phy0_ctrl->phy_con14);
		writel(0, &phy1_ctrl->phy_con14);

		val = (0x3 << DIRECT_CMD_BANK_SHIFT);
		for (chip = 0; chip < mem->chips_to_configure; chip++) {
			writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
			       &drex0->directcmd);
			writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
			       &drex1->directcmd);
		}

		/* Common Settings for Leveling */
		val = PHY_CON12_RESET_VAL;
		writel((val + n_lock_w_phy0), &phy0_ctrl->phy_con12);
		writel((val + n_lock_w_phy1), &phy1_ctrl->phy_con12);

		setbits_le32(&phy0_ctrl->phy_con2, DLL_DESKEW_EN);
		setbits_le32(&phy1_ctrl->phy_con2, DLL_DESKEW_EN);
	}

	/*
	 * Do software read leveling
	 *
	 * Do this before we turn on auto refresh since the auto refresh can
	 * be in conflict with the resync operation that's part of setting
	 * read leveling.
	 */
	if (!reset) {
		/* restore calibrated value after resume */
		dmc_set_read_offset_value(phy0_ctrl, readl(&pmu->pmu_spare1));
		dmc_set_read_offset_value(phy1_ctrl, readl(&pmu->pmu_spare2));
	} else {
		software_find_read_offset(phy0_ctrl, 0,
					  CTRL_LOCK_COARSE(lock0_info));
		software_find_read_offset(phy1_ctrl, 1,
					  CTRL_LOCK_COARSE(lock1_info));
		/* save calibrated value to restore after resume */
		writel(dmc_get_read_offset_value(phy0_ctrl), &pmu->pmu_spare1);
		writel(dmc_get_read_offset_value(phy1_ctrl), &pmu->pmu_spare2);
	}

	/* Send PALL command */
	dmc_config_prech(mem, &drex0->directcmd);
	dmc_config_prech(mem, &drex1->directcmd);

	writel(mem->memcontrol, &drex0->memcontrol);
	writel(mem->memcontrol, &drex1->memcontrol);

	/*
	 * Set DMC Concontrol: Enable auto-refresh counter, provide
	 * read data fetch cycles and enable DREX auto set powerdown
	 * for input buffer of I/O in none read memory state.
	 */
	writel(mem->concontrol | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT) |
		(mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)|
		DMC_CONCONTROL_IO_PD_CON(0x2),
		&drex0->concontrol);
	writel(mem->concontrol | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT) |
		(mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)|
		DMC_CONCONTROL_IO_PD_CON(0x2),
		&drex1->concontrol);

	/*
	 * Enable Clock Gating Control for DMC
	 * this saves around 25 mw dmc power as compared to the power
	 * consumption without these bits enabled
	 */
	setbits_le32(&drex0->cgcontrol, DMC_INTERNAL_CG);
	setbits_le32(&drex1->cgcontrol, DMC_INTERNAL_CG);

	/*
	 * As per Exynos5800 UM ver 0.00 section 17.13.2.1
	 * CONCONTROL register bit 3 [update_mode], Exynos5800 does not
	 * support the PHY initiated update. And it is recommended to set
	 * this field to 1'b1 during initialization
	 *
	 * When we apply PHY-initiated mode, DLL lock value is determined
	 * once at DMC init time and not updated later when we change the MIF
	 * voltage based on ASV group in kernel. Applying MC-initiated mode
	 * makes sure that DLL tracing is ON so that silicon is able to
	 * compensate the voltage variation.
	 */
	val = readl(&drex0->concontrol);
	val |= CONCONTROL_UPDATE_MODE;
	writel(val , &drex0->concontrol);
	val = readl(&drex1->concontrol);
	val |= CONCONTROL_UPDATE_MODE;
	writel(val , &drex1->concontrol);

	return 0;
}
#endif
