diff mbox

[4/9,V9] Exynos5420: Add DDR3 initialization for 5420

Message ID 1385984858-30816-5-git-send-email-rajeshwari.s@samsung.com
State New
Headers show

Commit Message

Rajeshwari Shinde Dec. 2, 2013, 11:47 a.m. UTC
This patch intends to add DDR3 initialization code for Exynos5420.

Signed-off-by: Rajeshwari S Shinde <rajeshwari.s@samsung.com>
Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
Acked-by: Simon Glass <sjg@chromium.org>
---
Changes in V2:
	- Corrected a compilation issue for SMDK5250.
Changes in V3:
	- None
Changes in V4:
	- None
Changes in V5:
	- None
Changes in V6:
	- None
Changes in V7:
	- Fixed multi line comment.
Changes in V8:
	- None
Changes in V9:
	- Used samsung_get base to get the dmc base address
 arch/arm/cpu/armv7/exynos/dmc_common.c    |  10 +-
 arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c | 425 +++++++++++++++++++++++++++++-
 arch/arm/cpu/armv7/exynos/exynos5_setup.h |   2 +
 arch/arm/include/asm/arch-exynos/cpu.h    |   4 +
 arch/arm/include/asm/arch-exynos/dmc.h    | 123 ++++++---
 arch/arm/include/asm/arch-exynos/power.h  |   6 +
 6 files changed, 525 insertions(+), 45 deletions(-)

Comments

Minkyu Kang Dec. 3, 2013, 6:15 a.m. UTC | #1
Dear Rajeshwari S Shinde,

On 02/12/13 20:47, Rajeshwari S Shinde wrote:
> This patch intends to add DDR3 initialization code for Exynos5420.
> 
> Signed-off-by: Rajeshwari S Shinde <rajeshwari.s@samsung.com>
> Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
> Acked-by: Simon Glass <sjg@chromium.org>
> ---
> Changes in V2:
> 	- Corrected a compilation issue for SMDK5250.
> Changes in V3:
> 	- None
> Changes in V4:
> 	- None
> Changes in V5:
> 	- None
> Changes in V6:
> 	- None
> Changes in V7:
> 	- Fixed multi line comment.
> Changes in V8:
> 	- None
> Changes in V9:
> 	- Used samsung_get base to get the dmc base address
>  arch/arm/cpu/armv7/exynos/dmc_common.c    |  10 +-
>  arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c | 425 +++++++++++++++++++++++++++++-
>  arch/arm/cpu/armv7/exynos/exynos5_setup.h |   2 +
>  arch/arm/include/asm/arch-exynos/cpu.h    |   4 +
>  arch/arm/include/asm/arch-exynos/dmc.h    | 123 ++++++---
>  arch/arm/include/asm/arch-exynos/power.h  |   6 +
>  6 files changed, 525 insertions(+), 45 deletions(-)
> 
> diff --git a/arch/arm/cpu/armv7/exynos/dmc_common.c b/arch/arm/cpu/armv7/exynos/dmc_common.c
> index 53cfe6e..9e432c2 100644
> --- a/arch/arm/cpu/armv7/exynos/dmc_common.c
> +++ b/arch/arm/cpu/armv7/exynos/dmc_common.c
> @@ -1,5 +1,5 @@
>  /*
> - * Mem setup common file for different types of DDR present on SMDK5250 boards.
> + * Mem setup common file for different types of DDR present on Exynos boards.
>   *
>   * Copyright (C) 2012 Samsung Electronics
>   *
> @@ -152,14 +152,6 @@ void dmc_config_prech(struct mem_timings *mem, struct exynos5_dmc *dmc)
>  	}
>  }
>  
> -void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc)
> -{
> -	writel(mem->memconfig, &dmc->memconfig0);
> -	writel(mem->memconfig, &dmc->memconfig1);
> -	writel(DMC_MEMBASECONFIG0_VAL, &dmc->membaseconfig0);
> -	writel(DMC_MEMBASECONFIG1_VAL, &dmc->membaseconfig1);
> -}
> -
>  void mem_ctrl_init(int reset)
>  {
>  	struct spl_machine_param *param = spl_get_machine_params();
> diff --git a/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c b/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c
> index 5f5914e..aa46a43 100644
> --- a/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c
> +++ b/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c
> @@ -1,5 +1,5 @@
>  /*
> - * DDR3 mem setup file for SMDK5250 board based on EXYNOS5
> + * DDR3 mem setup file for board based on EXYNOS5
>   *
>   * Copyright (C) 2012 Samsung Electronics
>   *
> @@ -11,12 +11,14 @@
>  #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 RDLVL_COMPLETE_TIMEOUT	10000
> +#define TIMEOUT	10000
>  
> +#ifdef CONFIG_EXYNOS5250
>  static void reset_phy_ctrl(void)
>  {
>  	struct exynos5_clock *clk =
> @@ -108,7 +110,7 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
>  
>  	/* Precharge Configuration */
>  	writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
> -	       &dmc->prechconfig);
> +	       &dmc->prechconfig0);
>  
>  	/* Power Down mode Configuration */
>  	writel(mem->dpwrdn_cyc << PWRDNCONFIG_DPWRDN_CYC_SHIFT |
> @@ -174,7 +176,7 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
>  		writel(val, &phy1_ctrl->phy_con1);
>  
>  		writel(CTRL_RDLVL_GATE_ENABLE, &dmc->rdlvl_config);
> -		i = RDLVL_COMPLETE_TIMEOUT;
> +		i = TIMEOUT;
>  		while ((readl(&dmc->phystatus) &
>  			(RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1)) !=
>  			(RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1) && i > 0) {
> @@ -215,3 +217,418 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
>  		| (mem->aref_en << CONCONTROL_AREF_EN_SHIFT), &dmc->concontrol);
>  	return 0;
>  }
> +#endif
> +
> +#ifdef CONFIG_EXYNOS5420

we can avoid ifdef here.

int ddr3_mem_ctrl_init(...)
{
	if (proid_is_exynos5250())
		exynos5250_ddr3_mem_ctrl_init();
	else
		exynos5420_ddr3_mem_ctrl_init();
}

> +int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
> +		       int reset)
> +{
> +	struct exynos5420_clock *clk =
> +		(struct exynos5420_clock *)samsung_get_base_clock();
> +	struct exynos5_power *power =
> +		(struct exynos5_power *)samsung_get_base_power();
> +	struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl;
> +	struct exynos5_dmc *drex0, *drex1;
> +	struct exynos5_tzasc *tzasc0, *tzasc1;
> +	uint32_t val, n_lock_r, n_lock_w_phy0, n_lock_w_phy1;
> +	int chip;
> +	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);
> +	drex0 = (struct exynos5_dmc *)samsung_get_base_dmc_ctrl();
> +	drex1 = (struct exynos5_dmc *)(samsung_get_base_dmc_ctrl()
> +							+ DMC_OFFSET);
> +	tzasc0 = (struct exynos5_tzasc *)samsung_get_base_dmc_tzasc0();
> +	tzasc1 = (struct exynos5_tzasc *)(samsung_get_base_dmc_tzasc0()
> +							+ DMC_OFFSET);
> +
> +	/* 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, phy1_ctrl))
> +		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, DDR_MODE_DDR3);
> +	update_reset_dll(drex1, 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->timingrow);
> +	writel(mem->timing_row, &drex1->timingrow);
> +	writel(mem->timing_data, &drex0->timingdata);
> +	writel(mem->timing_data, &drex1->timingdata);
> +	writel(mem->timing_power, &drex0->timingpower);
> +	writel(mem->timing_power, &drex1->timingpower);
> +
> +	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);
> +		dmc_config_mrs(mem, drex1);
> +	} else {
> +		/*
> +		 * 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_r = readl(&phy0_ctrl->phy_con13);
> +		n_lock_w_phy0 = (n_lock_r & 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_r = readl(&phy1_ctrl->phy_con13);
> +		n_lock_w_phy1 = (n_lock_r & 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;
> +		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;
> +		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);
> +		}
> +
> +		if (mem->read_leveling_enable) {
> +			/* Set Read DQ Calibration */
> +			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);
> +			}
> +
> +			val = readl(&phy0_ctrl->phy_con1);
> +			val |= READ_LEVELLING_DDR3;
> +			writel(val, &phy0_ctrl->phy_con1);
> +			val = readl(&phy1_ctrl->phy_con1);
> +			val |= READ_LEVELLING_DDR3;
> +			writel(val, &phy1_ctrl->phy_con1);
> +
> +			val = readl(&phy0_ctrl->phy_con2);
> +			val |= (RDLVL_EN | RDLVL_INCR_ADJ);
> +			writel(val, &phy0_ctrl->phy_con2);
> +			val = readl(&phy1_ctrl->phy_con2);
> +			val |= (RDLVL_EN | RDLVL_INCR_ADJ);
> +			writel(val, &phy1_ctrl->phy_con2);
> +
> +			setbits_le32(&drex0->rdlvl_config,
> +				     CTRL_RDLVL_DATA_ENABLE);
> +			i = TIMEOUT;
> +			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;
> +
> +			clrbits_le32(&drex0->rdlvl_config,
> +				     CTRL_RDLVL_DATA_ENABLE);
> +			setbits_le32(&drex1->rdlvl_config,
> +				     CTRL_RDLVL_DATA_ENABLE);
> +			i = TIMEOUT;
> +			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;
> +
> +			clrbits_le32(&drex1->rdlvl_config,
> +				     CTRL_RDLVL_DATA_ENABLE);
> +
> +			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);
> +			}
> +
> +			update_reset_dll(drex0, DDR_MODE_DDR3);
> +			update_reset_dll(drex1, DDR_MODE_DDR3);
> +		}
> +
> +		/* 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);
> +	}
> +
> +	/* Send PALL command */
> +	dmc_config_prech(mem, drex0);
> +	dmc_config_prech(mem, drex1);
> +
> +	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);
> +
> +	return 0;
> +}
> +#endif
> diff --git a/arch/arm/cpu/armv7/exynos/exynos5_setup.h b/arch/arm/cpu/armv7/exynos/exynos5_setup.h
> index c8d6515..42a7fb8 100644
> --- a/arch/arm/cpu/armv7/exynos/exynos5_setup.h
> +++ b/arch/arm/cpu/armv7/exynos/exynos5_setup.h
> @@ -436,6 +436,7 @@
>   */
>  #ifndef CONFIG_SMDK5420
>  
> +

unnecessary blank line.

>  /* APLL_CON1 */
>  #define APLL_CON1_VAL	(0x00203800)
>  
> @@ -696,6 +697,7 @@
>  #define CLK_DIV_CPERI1_VAL	NOT_AVAILABLE
>  
>  #else
> +#define PAD_RETENTION_DRAM_COREBLK_VAL	0x10000000
>  
>  /* APLL_CON1 */
>  #define APLL_CON1_VAL	(0x0020F300)
> diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h
> index 2b44210..2c642ba 100644
> --- a/arch/arm/include/asm/arch-exynos/cpu.h
> +++ b/arch/arm/include/asm/arch-exynos/cpu.h
> @@ -53,6 +53,7 @@
>  #define EXYNOS4_AUDIOSS_BASE		DEVICE_NOT_AVAILABLE
>  #define EXYNOS4_USB_HOST_XHCI_BASE	DEVICE_NOT_AVAILABLE
>  #define EXYNOS4_USB3PHY_BASE		DEVICE_NOT_AVAILABLE
> +#define EXYNOS4_DMC_TZASC0_BASE		DEVICE_NOT_AVAILABLE
>  
>  /* EXYNOS4X12 */
>  #define EXYNOS4X12_GPIO_PART3_BASE	0x03860000
> @@ -91,6 +92,7 @@
>  #define EXYNOS4X12_AUDIOSS_BASE		DEVICE_NOT_AVAILABLE
>  #define EXYNOS4X12_USB_HOST_XHCI_BASE	DEVICE_NOT_AVAILABLE
>  #define EXYNOS4X12_USB3PHY_BASE		DEVICE_NOT_AVAILABLE
> +#define EXYNOS4X12_DMC_TZASC0_BASE	DEVICE_NOT_AVAILABLE
>  
>  /* EXYNOS5 */
>  #define EXYNOS5_I2C_SPACING		0x10000
> @@ -129,6 +131,7 @@
>  
>  #define EXYNOS5_ADC_BASE		DEVICE_NOT_AVAILABLE
>  #define EXYNOS5_MODEM_BASE		DEVICE_NOT_AVAILABLE
> +#define EXYNOS5_DMC_TZASC0_BASE		DEVICE_NOT_AVAILABLE
>  
>  /* EXYNOS5420 */
>  #define EXYNOS5420_AUDIOSS_BASE		0x03810000
> @@ -284,6 +287,7 @@ SAMSUNG_BASE(spi_isp, SPI_ISP_BASE)
>  SAMSUNG_BASE(tzpc, TZPC_BASE)
>  SAMSUNG_BASE(dmc_ctrl, DMC_CTRL_BASE)
>  SAMSUNG_BASE(dmc_phy, DMC_PHY_BASE)
> +SAMSUNG_BASE(dmc_tzasc0, DMC_TZASC0_BASE)

then do we need to define two base addresses for TZASC?
you never use TZASC1.

>  SAMSUNG_BASE(audio_ass, AUDIOSS_BASE)
>  #endif
>  
> diff --git a/arch/arm/include/asm/arch-exynos/dmc.h b/arch/arm/include/asm/arch-exynos/dmc.h
> index f65c676..0913299 100644
> --- a/arch/arm/include/asm/arch-exynos/dmc.h
> +++ b/arch/arm/include/asm/arch-exynos/dmc.h
> @@ -114,13 +114,24 @@ struct exynos4_dmc {
>  struct exynos5_dmc {
>  	unsigned int concontrol;
>  	unsigned int memcontrol;
> +
> +/*
> + * Between 5250 and 5420, the DMC Register differs only at 0x8 offset.
> + * So to use the same structure and simplify the code put a define to
> + * distinguish between memconfig0 and cgcontrol register
> + */
> +#ifdef CONFIG_EXYNOS5250

No. we don't allow ifdef.

>  	unsigned int memconfig0;
> +#else
> +	unsigned int cgcontrol;
> +#endif
>  	unsigned int memconfig1;
>  	unsigned int directcmd;
> -	unsigned int prechconfig;
> +	unsigned int prechconfig0;
>  	unsigned int phycontrol0;
> -	unsigned char res1[0xc];
> -	unsigned int pwrdnconfig;
> +	unsigned int prechconfig1;
> +	unsigned char res1[0x8];
> +	unsigned int pwrdnconfig;	/* 0x0028*/
>  	unsigned int timingpzq;
>  	unsigned int timingref;
>  	unsigned int timingrow;
> @@ -128,12 +139,12 @@ struct exynos5_dmc {
>  	unsigned int timingpower;
>  	unsigned int phystatus;
>  	unsigned char res2[0x4];
> -	unsigned int chipstatus_ch0;
> +	unsigned int chipstatus_ch0;	/* 0x0048 */
>  	unsigned int chipstatus_ch1;
>  	unsigned char res3[0x4];
>  	unsigned int mrstatus;
>  	unsigned char res4[0x8];
> -	unsigned int qoscontrol0;
> +	unsigned int qoscontrol0;	/* 0x0060 */
>  	unsigned char resr5[0x4];
>  	unsigned int qoscontrol1;
>  	unsigned char res6[0x4];
> @@ -164,45 +175,83 @@ struct exynos5_dmc {
>  	unsigned int qoscontrol14;
>  	unsigned char res19[0x4];
>  	unsigned int qoscontrol15;
> -	unsigned char res20[0x14];
> +	unsigned char res20[0x4];
> +	unsigned int timing_set_sw;	/* 0x00e0 */
> +	unsigned int timingrow1;
> +	unsigned int timingdata1;
> +	unsigned int timingpower1;
>  	unsigned int ivcontrol;
>  	unsigned int wrtra_config;
>  	unsigned int rdlvl_config;
> -	unsigned char res21[0x8];
> +	unsigned char res21[0x4];
> +	unsigned int brbrsvcontrol;	/* 0x0100*/
>  	unsigned int brbrsvconfig;
>  	unsigned int brbqosconfig;
>  	unsigned int membaseconfig0;
> -	unsigned int membaseconfig1;
> +	unsigned int membaseconfig1;	/* 0x0110 */
>  	unsigned char res22[0xc];
> -	unsigned int wrlvl_config;
> -	unsigned char res23[0xc];
> -	unsigned int perevcontrol;
> +	unsigned int wrlvl_config0;	/* 0x0120 */
> +	unsigned int wrlvl_config1;
> +	unsigned int wrlvl_status;
> +	unsigned char res23[0x4];
> +	unsigned int perevcontrol;	/* 0x0130 */
>  	unsigned int perev0config;
>  	unsigned int perev1config;
>  	unsigned int perev2config;
>  	unsigned int perev3config;
> -	unsigned char res24[0xdebc];
> -	unsigned int pmnc_ppc_a;
> -	unsigned char res25[0xc];
> -	unsigned int cntens_ppc_a;
> -	unsigned char res26[0xc];
> -	unsigned int cntenc_ppc_a;
> -	unsigned char res27[0xc];
> -	unsigned int intens_ppc_a;
> -	unsigned char res28[0xc];
> -	unsigned int intenc_ppc_a;
> -	unsigned char res29[0xc];
> -	unsigned int flag_ppc_a;
> -	unsigned char res30[0xac];
> -	unsigned int ccnt_ppc_a;
> -	unsigned char res31[0xc];
> -	unsigned int pmcnt0_ppc_a;
> +	unsigned char res22a[0xc];
> +	unsigned int ctrl_io_rdata_ch0;
> +	unsigned int ctrl_io_rdata_ch1;
> +	unsigned char res23a[0x8];
> +	unsigned int cacal_config0;
> +	unsigned int cacal_config1;
> +	unsigned int cacal_status;
> +	unsigned char res24[0x94];
> +	unsigned int emergent_config0;	/* 0x0200 */
> +	unsigned int emergent_config1;
> +	unsigned char res25[0x8];
> +	unsigned int bp_control0;
> +	unsigned int bp_control0_r;
> +	unsigned int bp_control0_w;
> +	unsigned char res26[0x4];
> +	unsigned int bp_control1;
> +	unsigned int bp_control1_r;
> +	unsigned int bp_control1_w;
> +	unsigned char res27[0x4];
> +	unsigned int bp_control2;
> +	unsigned int bp_control2_r;
> +	unsigned int bp_control2_w;
> +	unsigned char res28[0x4];
> +	unsigned int bp_control3;
> +	unsigned int bp_control3_r;
> +	unsigned int bp_control3_w;
> +	unsigned char res29[0xb4];
> +	unsigned int winconfig_odt_w;	/* 0x0300 */
> +	unsigned char res30[0x4];
> +	unsigned int winconfig_ctrl_read;
> +	unsigned int winconfig_ctrl_gate;
> +	unsigned char res31[0xdcf0];
> +	unsigned int pmnc_ppc;
>  	unsigned char res32[0xc];
> -	unsigned int pmcnt1_ppc_a;
> +	unsigned int cntens_ppc;
>  	unsigned char res33[0xc];
> -	unsigned int pmcnt2_ppc_a;
> +	unsigned int cntenc_ppc;
>  	unsigned char res34[0xc];
> -	unsigned int pmcnt3_ppc_a;
> +	unsigned int intens_ppc;
> +	unsigned char res35[0xc];
> +	unsigned int intenc_ppc;
> +	unsigned char res36[0xc];
> +	unsigned int flag_ppc;		/* 0xe050 */
> +	unsigned char res37[0xac];
> +	unsigned int ccnt_ppc;
> +	unsigned char res38[0xc];
> +	unsigned int pmcnt0_ppc;
> +	unsigned char res39[0xc];
> +	unsigned int pmcnt1_ppc;
> +	unsigned char res40[0xc];
> +	unsigned int pmcnt2_ppc;
> +	unsigned char res41[0xc];
> +	unsigned int pmcnt3_ppc;	/* 0xe140 */
>  };
>  
>  struct exynos5_phy_control {
> @@ -211,13 +260,13 @@ struct exynos5_phy_control {
>  	unsigned int phy_con2;
>  	unsigned int phy_con3;
>  	unsigned int phy_con4;
> -	unsigned char res1[4];
> +	unsigned int phy_con5;
>  	unsigned int phy_con6;
>  	unsigned char res2[4];
>  	unsigned int phy_con8;
>  	unsigned int phy_con9;
>  	unsigned int phy_con10;
> -	unsigned char res3[4];
> +	unsigned int phy_con11;
>  	unsigned int phy_con12;
>  	unsigned int phy_con13;
>  	unsigned int phy_con14;
> @@ -252,6 +301,15 @@ struct exynos5_phy_control {
>  	unsigned int phy_con42;
>  };
>  
> +struct exynos5_tzasc {
> +	unsigned char res1[0xf00];
> +	unsigned int membaseconfig0;
> +	unsigned int membaseconfig1;
> +	unsigned char res2[0x8];
> +	unsigned int memconfig0;
> +	unsigned int memconfig1;
> +};
> +
>  enum ddr_mode {
>  	DDR_MODE_DDR2,
>  	DDR_MODE_DDR3,
> @@ -286,6 +344,7 @@ enum mem_manuf {
>  #define PHY_CON0_T_WRRDCMD_SHIFT	17
>  #define PHY_CON0_T_WRRDCMD_MASK		(0x7 << PHY_CON0_T_WRRDCMD_SHIFT)
>  #define PHY_CON0_CTRL_DDR_MODE_SHIFT	11
> +#define PHY_CON0_CTRL_DDR_MODE_MASK	0x3
>  
>  /* PHY_CON1 register fields */
>  #define PHY_CON1_RDLVL_RDDATA_ADJ_SHIFT	0
> diff --git a/arch/arm/include/asm/arch-exynos/power.h b/arch/arm/include/asm/arch-exynos/power.h
> index 8db18c5..6077fc3 100644
> --- a/arch/arm/include/asm/arch-exynos/power.h
> +++ b/arch/arm/include/asm/arch-exynos/power.h
> @@ -690,9 +690,15 @@ struct exynos5_power {
>  	unsigned int	pad_retention_spi_status;
>  	unsigned int	pad_retention_spi_option;
>  	unsigned char	res117[0x14];
> +	#ifdef CONFIG_EXYNOS5250

ditto.

>  	unsigned int	pad_retention_gpio_dmc_configuration;
>  	unsigned int	pad_retention_gpio_dmc_status;
>  	unsigned int	pad_retention_gpio_dmc_option;
> +	#else
> +	unsigned int	pad_retention_dram_coreblk_configuration;
> +	unsigned int	pad_retention_dram_coreblk_status;
> +	unsigned int	pad_retention_dram_coreblk_option;
> +	#endif
>  	unsigned char	res118[0x14];
>  	unsigned int	pad_isolation_configuration;
>  	unsigned int	pad_isolation_status;
> 

Thanks,
Minkyu Kang.
Rajeshwari Birje Dec. 5, 2013, 7:25 a.m. UTC | #2
Hi Minkyu Kang,

Thank you for comments.

On Tue, Dec 3, 2013 at 11:45 AM, Minkyu Kang <mk7.kang@samsung.com> wrote:
> Dear Rajeshwari S Shinde,
>
> On 02/12/13 20:47, Rajeshwari S Shinde wrote:
>> This patch intends to add DDR3 initialization code for Exynos5420.
>>
>> Signed-off-by: Rajeshwari S Shinde <rajeshwari.s@samsung.com>
>> Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
>> Acked-by: Simon Glass <sjg@chromium.org>
>> ---
>> Changes in V2:
>>       - Corrected a compilation issue for SMDK5250.
>> Changes in V3:
>>       - None
>> Changes in V4:
>>       - None
>> Changes in V5:
>>       - None
>> Changes in V6:
>>       - None
>> Changes in V7:
>>       - Fixed multi line comment.
>> Changes in V8:
>>       - None
>> Changes in V9:
>>       - Used samsung_get base to get the dmc base address
>>  arch/arm/cpu/armv7/exynos/dmc_common.c    |  10 +-
>>  arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c | 425 +++++++++++++++++++++++++++++-
>>  arch/arm/cpu/armv7/exynos/exynos5_setup.h |   2 +
>>  arch/arm/include/asm/arch-exynos/cpu.h    |   4 +
>>  arch/arm/include/asm/arch-exynos/dmc.h    | 123 ++++++---
>>  arch/arm/include/asm/arch-exynos/power.h  |   6 +
>>  6 files changed, 525 insertions(+), 45 deletions(-)
>>
>> diff --git a/arch/arm/cpu/armv7/exynos/dmc_common.c b/arch/arm/cpu/armv7/exynos/dmc_common.c
>> index 53cfe6e..9e432c2 100644
>> --- a/arch/arm/cpu/armv7/exynos/dmc_common.c
>> +++ b/arch/arm/cpu/armv7/exynos/dmc_common.c
>> @@ -1,5 +1,5 @@
>>  /*
>> - * Mem setup common file for different types of DDR present on SMDK5250 boards.
>> + * Mem setup common file for different types of DDR present on Exynos boards.
>>   *
>>   * Copyright (C) 2012 Samsung Electronics
>>   *
>> @@ -152,14 +152,6 @@ void dmc_config_prech(struct mem_timings *mem, struct exynos5_dmc *dmc)
>>       }
>>  }
>>
>> -void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc)
>> -{
>> -     writel(mem->memconfig, &dmc->memconfig0);
>> -     writel(mem->memconfig, &dmc->memconfig1);
>> -     writel(DMC_MEMBASECONFIG0_VAL, &dmc->membaseconfig0);
>> -     writel(DMC_MEMBASECONFIG1_VAL, &dmc->membaseconfig1);
>> -}
>> -
>>  void mem_ctrl_init(int reset)
>>  {
>>       struct spl_machine_param *param = spl_get_machine_params();
>> diff --git a/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c b/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c
>> index 5f5914e..aa46a43 100644
>> --- a/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c
>> +++ b/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c
>> @@ -1,5 +1,5 @@
>>  /*
>> - * DDR3 mem setup file for SMDK5250 board based on EXYNOS5
>> + * DDR3 mem setup file for board based on EXYNOS5
>>   *
>>   * Copyright (C) 2012 Samsung Electronics
>>   *
>> @@ -11,12 +11,14 @@
>>  #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 RDLVL_COMPLETE_TIMEOUT       10000
>> +#define TIMEOUT      10000
>>
>> +#ifdef CONFIG_EXYNOS5250
>>  static void reset_phy_ctrl(void)
>>  {
>>       struct exynos5_clock *clk =
>> @@ -108,7 +110,7 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
>>
>>       /* Precharge Configuration */
>>       writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
>> -            &dmc->prechconfig);
>> +            &dmc->prechconfig0);
>>
>>       /* Power Down mode Configuration */
>>       writel(mem->dpwrdn_cyc << PWRDNCONFIG_DPWRDN_CYC_SHIFT |
>> @@ -174,7 +176,7 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
>>               writel(val, &phy1_ctrl->phy_con1);
>>
>>               writel(CTRL_RDLVL_GATE_ENABLE, &dmc->rdlvl_config);
>> -             i = RDLVL_COMPLETE_TIMEOUT;
>> +             i = TIMEOUT;
>>               while ((readl(&dmc->phystatus) &
>>                       (RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1)) !=
>>                       (RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1) && i > 0) {
>> @@ -215,3 +217,418 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
>>               | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT), &dmc->concontrol);
>>       return 0;
>>  }
>> +#endif
>> +
>> +#ifdef CONFIG_EXYNOS5420
>
> we can avoid ifdef here.
>
> int ddr3_mem_ctrl_init(...)
> {
>         if (proid_is_exynos5250())
>                 exynos5250_ddr3_mem_ctrl_init();
>         else
>                 exynos5420_ddr3_mem_ctrl_init();
> }
>
Will do it this way
>> +int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
>> +                    int reset)
>> +{
>> +     struct exynos5420_clock *clk =
>> +             (struct exynos5420_clock *)samsung_get_base_clock();
>> +     struct exynos5_power *power =
>> +             (struct exynos5_power *)samsung_get_base_power();
>> +     struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl;
>> +     struct exynos5_dmc *drex0, *drex1;
>> +     struct exynos5_tzasc *tzasc0, *tzasc1;
>> +     uint32_t val, n_lock_r, n_lock_w_phy0, n_lock_w_phy1;
>> +     int chip;
>> +     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);
>> +     drex0 = (struct exynos5_dmc *)samsung_get_base_dmc_ctrl();
>> +     drex1 = (struct exynos5_dmc *)(samsung_get_base_dmc_ctrl()
>> +                                                     + DMC_OFFSET);
>> +     tzasc0 = (struct exynos5_tzasc *)samsung_get_base_dmc_tzasc0();
>> +     tzasc1 = (struct exynos5_tzasc *)(samsung_get_base_dmc_tzasc0()
>> +                                                     + DMC_OFFSET);
>> +
>> +     /* 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, phy1_ctrl))
>> +             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, DDR_MODE_DDR3);
>> +     update_reset_dll(drex1, 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->timingrow);
>> +     writel(mem->timing_row, &drex1->timingrow);
>> +     writel(mem->timing_data, &drex0->timingdata);
>> +     writel(mem->timing_data, &drex1->timingdata);
>> +     writel(mem->timing_power, &drex0->timingpower);
>> +     writel(mem->timing_power, &drex1->timingpower);
>> +
>> +     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);
>> +             dmc_config_mrs(mem, drex1);
>> +     } else {
>> +             /*
>> +              * 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_r = readl(&phy0_ctrl->phy_con13);
>> +             n_lock_w_phy0 = (n_lock_r & 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_r = readl(&phy1_ctrl->phy_con13);
>> +             n_lock_w_phy1 = (n_lock_r & 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;
>> +             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;
>> +             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);
>> +             }
>> +
>> +             if (mem->read_leveling_enable) {
>> +                     /* Set Read DQ Calibration */
>> +                     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);
>> +                     }
>> +
>> +                     val = readl(&phy0_ctrl->phy_con1);
>> +                     val |= READ_LEVELLING_DDR3;
>> +                     writel(val, &phy0_ctrl->phy_con1);
>> +                     val = readl(&phy1_ctrl->phy_con1);
>> +                     val |= READ_LEVELLING_DDR3;
>> +                     writel(val, &phy1_ctrl->phy_con1);
>> +
>> +                     val = readl(&phy0_ctrl->phy_con2);
>> +                     val |= (RDLVL_EN | RDLVL_INCR_ADJ);
>> +                     writel(val, &phy0_ctrl->phy_con2);
>> +                     val = readl(&phy1_ctrl->phy_con2);
>> +                     val |= (RDLVL_EN | RDLVL_INCR_ADJ);
>> +                     writel(val, &phy1_ctrl->phy_con2);
>> +
>> +                     setbits_le32(&drex0->rdlvl_config,
>> +                                  CTRL_RDLVL_DATA_ENABLE);
>> +                     i = TIMEOUT;
>> +                     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;
>> +
>> +                     clrbits_le32(&drex0->rdlvl_config,
>> +                                  CTRL_RDLVL_DATA_ENABLE);
>> +                     setbits_le32(&drex1->rdlvl_config,
>> +                                  CTRL_RDLVL_DATA_ENABLE);
>> +                     i = TIMEOUT;
>> +                     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;
>> +
>> +                     clrbits_le32(&drex1->rdlvl_config,
>> +                                  CTRL_RDLVL_DATA_ENABLE);
>> +
>> +                     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);
>> +                     }
>> +
>> +                     update_reset_dll(drex0, DDR_MODE_DDR3);
>> +                     update_reset_dll(drex1, DDR_MODE_DDR3);
>> +             }
>> +
>> +             /* 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);
>> +     }
>> +
>> +     /* Send PALL command */
>> +     dmc_config_prech(mem, drex0);
>> +     dmc_config_prech(mem, drex1);
>> +
>> +     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);
>> +
>> +     return 0;
>> +}
>> +#endif
>> diff --git a/arch/arm/cpu/armv7/exynos/exynos5_setup.h b/arch/arm/cpu/armv7/exynos/exynos5_setup.h
>> index c8d6515..42a7fb8 100644
>> --- a/arch/arm/cpu/armv7/exynos/exynos5_setup.h
>> +++ b/arch/arm/cpu/armv7/exynos/exynos5_setup.h
>> @@ -436,6 +436,7 @@
>>   */
>>  #ifndef CONFIG_SMDK5420
>>
>> +
>
> unnecessary blank line.
will remove this
>
>>  /* APLL_CON1 */
>>  #define APLL_CON1_VAL        (0x00203800)
>>
>> @@ -696,6 +697,7 @@
>>  #define CLK_DIV_CPERI1_VAL   NOT_AVAILABLE
>>
>>  #else
>> +#define PAD_RETENTION_DRAM_COREBLK_VAL       0x10000000
>>
>>  /* APLL_CON1 */
>>  #define APLL_CON1_VAL        (0x0020F300)
>> diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h
>> index 2b44210..2c642ba 100644
>> --- a/arch/arm/include/asm/arch-exynos/cpu.h
>> +++ b/arch/arm/include/asm/arch-exynos/cpu.h
>> @@ -53,6 +53,7 @@
>>  #define EXYNOS4_AUDIOSS_BASE         DEVICE_NOT_AVAILABLE
>>  #define EXYNOS4_USB_HOST_XHCI_BASE   DEVICE_NOT_AVAILABLE
>>  #define EXYNOS4_USB3PHY_BASE         DEVICE_NOT_AVAILABLE
>> +#define EXYNOS4_DMC_TZASC0_BASE              DEVICE_NOT_AVAILABLE
>>
>>  /* EXYNOS4X12 */
>>  #define EXYNOS4X12_GPIO_PART3_BASE   0x03860000
>> @@ -91,6 +92,7 @@
>>  #define EXYNOS4X12_AUDIOSS_BASE              DEVICE_NOT_AVAILABLE
>>  #define EXYNOS4X12_USB_HOST_XHCI_BASE        DEVICE_NOT_AVAILABLE
>>  #define EXYNOS4X12_USB3PHY_BASE              DEVICE_NOT_AVAILABLE
>> +#define EXYNOS4X12_DMC_TZASC0_BASE   DEVICE_NOT_AVAILABLE
>>
>>  /* EXYNOS5 */
>>  #define EXYNOS5_I2C_SPACING          0x10000
>> @@ -129,6 +131,7 @@
>>
>>  #define EXYNOS5_ADC_BASE             DEVICE_NOT_AVAILABLE
>>  #define EXYNOS5_MODEM_BASE           DEVICE_NOT_AVAILABLE
>> +#define EXYNOS5_DMC_TZASC0_BASE              DEVICE_NOT_AVAILABLE
>>
>>  /* EXYNOS5420 */
>>  #define EXYNOS5420_AUDIOSS_BASE              0x03810000
>> @@ -284,6 +287,7 @@ SAMSUNG_BASE(spi_isp, SPI_ISP_BASE)
>>  SAMSUNG_BASE(tzpc, TZPC_BASE)
>>  SAMSUNG_BASE(dmc_ctrl, DMC_CTRL_BASE)
>>  SAMSUNG_BASE(dmc_phy, DMC_PHY_BASE)
>> +SAMSUNG_BASE(dmc_tzasc0, DMC_TZASC0_BASE)
>
> then do we need to define two base addresses for TZASC?
> you never use TZASC1.
Acessing base address for TZASC1 in following manner. Hence added only
SAMSUNG_BASE(dmc_tzasc0, DMC_TZASC0_BASE)
"tzasc1 = (struct exynos5_tzasc *)(samsung_get_base_dmc_tzasc0()
                                                     + DMC_OFFSET);"
>
>>  SAMSUNG_BASE(audio_ass, AUDIOSS_BASE)
>>  #endif
>>
>> diff --git a/arch/arm/include/asm/arch-exynos/dmc.h b/arch/arm/include/asm/arch-exynos/dmc.h
>> index f65c676..0913299 100644
>> --- a/arch/arm/include/asm/arch-exynos/dmc.h
>> +++ b/arch/arm/include/asm/arch-exynos/dmc.h
>> @@ -114,13 +114,24 @@ struct exynos4_dmc {
>>  struct exynos5_dmc {
>>       unsigned int concontrol;
>>       unsigned int memcontrol;
>> +
>> +/*
>> + * Between 5250 and 5420, the DMC Register differs only at 0x8 offset.
>> + * So to use the same structure and simplify the code put a define to
>> + * distinguish between memconfig0 and cgcontrol register
>> + */
>> +#ifdef CONFIG_EXYNOS5250
>
> No. we don't allow ifdef.
Will add separate structure for 5420
>
>>       unsigned int memconfig0;
>> +#else
>> +     unsigned int cgcontrol;
>> +#endif
>>       unsigned int memconfig1;
>>       unsigned int directcmd;
>> -     unsigned int prechconfig;
>> +     unsigned int prechconfig0;
>>       unsigned int phycontrol0;
>> -     unsigned char res1[0xc];
>> -     unsigned int pwrdnconfig;
>> +     unsigned int prechconfig1;
>> +     unsigned char res1[0x8];
>> +     unsigned int pwrdnconfig;       /* 0x0028*/
>>       unsigned int timingpzq;
>>       unsigned int timingref;
>>       unsigned int timingrow;
>> @@ -128,12 +139,12 @@ struct exynos5_dmc {
>>       unsigned int timingpower;
>>       unsigned int phystatus;
>>       unsigned char res2[0x4];
>> -     unsigned int chipstatus_ch0;
>> +     unsigned int chipstatus_ch0;    /* 0x0048 */
>>       unsigned int chipstatus_ch1;
>>       unsigned char res3[0x4];
>>       unsigned int mrstatus;
>>       unsigned char res4[0x8];
>> -     unsigned int qoscontrol0;
>> +     unsigned int qoscontrol0;       /* 0x0060 */
>>       unsigned char resr5[0x4];
>>       unsigned int qoscontrol1;
>>       unsigned char res6[0x4];
>> @@ -164,45 +175,83 @@ struct exynos5_dmc {
>>       unsigned int qoscontrol14;
>>       unsigned char res19[0x4];
>>       unsigned int qoscontrol15;
>> -     unsigned char res20[0x14];
>> +     unsigned char res20[0x4];
>> +     unsigned int timing_set_sw;     /* 0x00e0 */
>> +     unsigned int timingrow1;
>> +     unsigned int timingdata1;
>> +     unsigned int timingpower1;
>>       unsigned int ivcontrol;
>>       unsigned int wrtra_config;
>>       unsigned int rdlvl_config;
>> -     unsigned char res21[0x8];
>> +     unsigned char res21[0x4];
>> +     unsigned int brbrsvcontrol;     /* 0x0100*/
>>       unsigned int brbrsvconfig;
>>       unsigned int brbqosconfig;
>>       unsigned int membaseconfig0;
>> -     unsigned int membaseconfig1;
>> +     unsigned int membaseconfig1;    /* 0x0110 */
>>       unsigned char res22[0xc];
>> -     unsigned int wrlvl_config;
>> -     unsigned char res23[0xc];
>> -     unsigned int perevcontrol;
>> +     unsigned int wrlvl_config0;     /* 0x0120 */
>> +     unsigned int wrlvl_config1;
>> +     unsigned int wrlvl_status;
>> +     unsigned char res23[0x4];
>> +     unsigned int perevcontrol;      /* 0x0130 */
>>       unsigned int perev0config;
>>       unsigned int perev1config;
>>       unsigned int perev2config;
>>       unsigned int perev3config;
>> -     unsigned char res24[0xdebc];
>> -     unsigned int pmnc_ppc_a;
>> -     unsigned char res25[0xc];
>> -     unsigned int cntens_ppc_a;
>> -     unsigned char res26[0xc];
>> -     unsigned int cntenc_ppc_a;
>> -     unsigned char res27[0xc];
>> -     unsigned int intens_ppc_a;
>> -     unsigned char res28[0xc];
>> -     unsigned int intenc_ppc_a;
>> -     unsigned char res29[0xc];
>> -     unsigned int flag_ppc_a;
>> -     unsigned char res30[0xac];
>> -     unsigned int ccnt_ppc_a;
>> -     unsigned char res31[0xc];
>> -     unsigned int pmcnt0_ppc_a;
>> +     unsigned char res22a[0xc];
>> +     unsigned int ctrl_io_rdata_ch0;
>> +     unsigned int ctrl_io_rdata_ch1;
>> +     unsigned char res23a[0x8];
>> +     unsigned int cacal_config0;
>> +     unsigned int cacal_config1;
>> +     unsigned int cacal_status;
>> +     unsigned char res24[0x94];
>> +     unsigned int emergent_config0;  /* 0x0200 */
>> +     unsigned int emergent_config1;
>> +     unsigned char res25[0x8];
>> +     unsigned int bp_control0;
>> +     unsigned int bp_control0_r;
>> +     unsigned int bp_control0_w;
>> +     unsigned char res26[0x4];
>> +     unsigned int bp_control1;
>> +     unsigned int bp_control1_r;
>> +     unsigned int bp_control1_w;
>> +     unsigned char res27[0x4];
>> +     unsigned int bp_control2;
>> +     unsigned int bp_control2_r;
>> +     unsigned int bp_control2_w;
>> +     unsigned char res28[0x4];
>> +     unsigned int bp_control3;
>> +     unsigned int bp_control3_r;
>> +     unsigned int bp_control3_w;
>> +     unsigned char res29[0xb4];
>> +     unsigned int winconfig_odt_w;   /* 0x0300 */
>> +     unsigned char res30[0x4];
>> +     unsigned int winconfig_ctrl_read;
>> +     unsigned int winconfig_ctrl_gate;
>> +     unsigned char res31[0xdcf0];
>> +     unsigned int pmnc_ppc;
>>       unsigned char res32[0xc];
>> -     unsigned int pmcnt1_ppc_a;
>> +     unsigned int cntens_ppc;
>>       unsigned char res33[0xc];
>> -     unsigned int pmcnt2_ppc_a;
>> +     unsigned int cntenc_ppc;
>>       unsigned char res34[0xc];
>> -     unsigned int pmcnt3_ppc_a;
>> +     unsigned int intens_ppc;
>> +     unsigned char res35[0xc];
>> +     unsigned int intenc_ppc;
>> +     unsigned char res36[0xc];
>> +     unsigned int flag_ppc;          /* 0xe050 */
>> +     unsigned char res37[0xac];
>> +     unsigned int ccnt_ppc;
>> +     unsigned char res38[0xc];
>> +     unsigned int pmcnt0_ppc;
>> +     unsigned char res39[0xc];
>> +     unsigned int pmcnt1_ppc;
>> +     unsigned char res40[0xc];
>> +     unsigned int pmcnt2_ppc;
>> +     unsigned char res41[0xc];
>> +     unsigned int pmcnt3_ppc;        /* 0xe140 */
>>  };
>>
>>  struct exynos5_phy_control {
>> @@ -211,13 +260,13 @@ struct exynos5_phy_control {
>>       unsigned int phy_con2;
>>       unsigned int phy_con3;
>>       unsigned int phy_con4;
>> -     unsigned char res1[4];
>> +     unsigned int phy_con5;
>>       unsigned int phy_con6;
>>       unsigned char res2[4];
>>       unsigned int phy_con8;
>>       unsigned int phy_con9;
>>       unsigned int phy_con10;
>> -     unsigned char res3[4];
>> +     unsigned int phy_con11;
>>       unsigned int phy_con12;
>>       unsigned int phy_con13;
>>       unsigned int phy_con14;
>> @@ -252,6 +301,15 @@ struct exynos5_phy_control {
>>       unsigned int phy_con42;
>>  };
>>
>> +struct exynos5_tzasc {
>> +     unsigned char res1[0xf00];
>> +     unsigned int membaseconfig0;
>> +     unsigned int membaseconfig1;
>> +     unsigned char res2[0x8];
>> +     unsigned int memconfig0;
>> +     unsigned int memconfig1;
>> +};
>> +
>>  enum ddr_mode {
>>       DDR_MODE_DDR2,
>>       DDR_MODE_DDR3,
>> @@ -286,6 +344,7 @@ enum mem_manuf {
>>  #define PHY_CON0_T_WRRDCMD_SHIFT     17
>>  #define PHY_CON0_T_WRRDCMD_MASK              (0x7 << PHY_CON0_T_WRRDCMD_SHIFT)
>>  #define PHY_CON0_CTRL_DDR_MODE_SHIFT 11
>> +#define PHY_CON0_CTRL_DDR_MODE_MASK  0x3
>>
>>  /* PHY_CON1 register fields */
>>  #define PHY_CON1_RDLVL_RDDATA_ADJ_SHIFT      0
>> diff --git a/arch/arm/include/asm/arch-exynos/power.h b/arch/arm/include/asm/arch-exynos/power.h
>> index 8db18c5..6077fc3 100644
>> --- a/arch/arm/include/asm/arch-exynos/power.h
>> +++ b/arch/arm/include/asm/arch-exynos/power.h
>> @@ -690,9 +690,15 @@ struct exynos5_power {
>>       unsigned int    pad_retention_spi_status;
>>       unsigned int    pad_retention_spi_option;
>>       unsigned char   res117[0x14];
>> +     #ifdef CONFIG_EXYNOS5250
>
> ditto.
Will add separate structure for 5420
>>       unsigned int    pad_retention_gpio_dmc_configuration;
>>       unsigned int    pad_retention_gpio_dmc_status;
>>       unsigned int    pad_retention_gpio_dmc_option;
>> +     #else
>> +     unsigned int    pad_retention_dram_coreblk_configuration;
>> +     unsigned int    pad_retention_dram_coreblk_status;
>> +     unsigned int    pad_retention_dram_coreblk_option;
>> +     #endif
>>       unsigned char   res118[0x14];
>>       unsigned int    pad_isolation_configuration;
>>       unsigned int    pad_isolation_status;
>>
>
> Thanks,
> Minkyu Kang.
> _______________________________________________
> U-Boot mailing list
> U-Boot@lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
Minkyu Kang Dec. 5, 2013, 7:43 a.m. UTC | #3
On 05/12/13 16:25, Rajeshwari Birje wrote:
> Hi Minkyu Kang,
> 
> Thank you for comments.
> 
> On Tue, Dec 3, 2013 at 11:45 AM, Minkyu Kang <mk7.kang@samsung.com> wrote:
>> Dear Rajeshwari S Shinde,
>>
>> On 02/12/13 20:47, Rajeshwari S Shinde wrote:
>>> This patch intends to add DDR3 initialization code for Exynos5420.
>>>
>>> Signed-off-by: Rajeshwari S Shinde <rajeshwari.s@samsung.com>
>>> Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
>>> Acked-by: Simon Glass <sjg@chromium.org>
>>> ---
>>> Changes in V2:
>>>       - Corrected a compilation issue for SMDK5250.
>>> Changes in V3:
>>>       - None
>>> Changes in V4:
>>>       - None
>>> Changes in V5:
>>>       - None
>>> Changes in V6:
>>>       - None
>>> Changes in V7:
>>>       - Fixed multi line comment.
>>> Changes in V8:
>>>       - None
>>> Changes in V9:
>>>       - Used samsung_get base to get the dmc base address
>>>  arch/arm/cpu/armv7/exynos/dmc_common.c    |  10 +-
>>>  arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c | 425 +++++++++++++++++++++++++++++-
>>>  arch/arm/cpu/armv7/exynos/exynos5_setup.h |   2 +
>>>  arch/arm/include/asm/arch-exynos/cpu.h    |   4 +
>>>  arch/arm/include/asm/arch-exynos/dmc.h    | 123 ++++++---
>>>  arch/arm/include/asm/arch-exynos/power.h  |   6 +
>>>  6 files changed, 525 insertions(+), 45 deletions(-)
>>>
>>> diff --git a/arch/arm/cpu/armv7/exynos/exynos5_setup.h b/arch/arm/cpu/armv7/exynos/exynos5_setup.h
>>> index c8d6515..42a7fb8 100644
>>> --- a/arch/arm/cpu/armv7/exynos/exynos5_setup.h
>>> +++ b/arch/arm/cpu/armv7/exynos/exynos5_setup.h
>>> @@ -436,6 +436,7 @@
>>>   */
>>>  #ifndef CONFIG_SMDK5420
>>>
>>> +
>>
>> unnecessary blank line.
> will remove this
>>
>>>  /* APLL_CON1 */
>>>  #define APLL_CON1_VAL        (0x00203800)
>>>
>>> @@ -696,6 +697,7 @@
>>>  #define CLK_DIV_CPERI1_VAL   NOT_AVAILABLE
>>>
>>>  #else
>>> +#define PAD_RETENTION_DRAM_COREBLK_VAL       0x10000000
>>>
>>>  /* APLL_CON1 */
>>>  #define APLL_CON1_VAL        (0x0020F300)
>>> diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h
>>> index 2b44210..2c642ba 100644
>>> --- a/arch/arm/include/asm/arch-exynos/cpu.h
>>> +++ b/arch/arm/include/asm/arch-exynos/cpu.h
>>> @@ -53,6 +53,7 @@
>>>  #define EXYNOS4_AUDIOSS_BASE         DEVICE_NOT_AVAILABLE
>>>  #define EXYNOS4_USB_HOST_XHCI_BASE   DEVICE_NOT_AVAILABLE
>>>  #define EXYNOS4_USB3PHY_BASE         DEVICE_NOT_AVAILABLE
>>> +#define EXYNOS4_DMC_TZASC0_BASE              DEVICE_NOT_AVAILABLE
>>>
>>>  /* EXYNOS4X12 */
>>>  #define EXYNOS4X12_GPIO_PART3_BASE   0x03860000
>>> @@ -91,6 +92,7 @@
>>>  #define EXYNOS4X12_AUDIOSS_BASE              DEVICE_NOT_AVAILABLE
>>>  #define EXYNOS4X12_USB_HOST_XHCI_BASE        DEVICE_NOT_AVAILABLE
>>>  #define EXYNOS4X12_USB3PHY_BASE              DEVICE_NOT_AVAILABLE
>>> +#define EXYNOS4X12_DMC_TZASC0_BASE   DEVICE_NOT_AVAILABLE
>>>
>>>  /* EXYNOS5 */
>>>  #define EXYNOS5_I2C_SPACING          0x10000
>>> @@ -129,6 +131,7 @@
>>>
>>>  #define EXYNOS5_ADC_BASE             DEVICE_NOT_AVAILABLE
>>>  #define EXYNOS5_MODEM_BASE           DEVICE_NOT_AVAILABLE
>>> +#define EXYNOS5_DMC_TZASC0_BASE              DEVICE_NOT_AVAILABLE
>>>
>>>  /* EXYNOS5420 */
>>>  #define EXYNOS5420_AUDIOSS_BASE              0x03810000
>>> @@ -284,6 +287,7 @@ SAMSUNG_BASE(spi_isp, SPI_ISP_BASE)
>>>  SAMSUNG_BASE(tzpc, TZPC_BASE)
>>>  SAMSUNG_BASE(dmc_ctrl, DMC_CTRL_BASE)
>>>  SAMSUNG_BASE(dmc_phy, DMC_PHY_BASE)
>>> +SAMSUNG_BASE(dmc_tzasc0, DMC_TZASC0_BASE)
>>
>> then do we need to define two base addresses for TZASC?
>> you never use TZASC1.
> Acessing base address for TZASC1 in following manner. Hence added only
> SAMSUNG_BASE(dmc_tzasc0, DMC_TZASC0_BASE)
> "tzasc1 = (struct exynos5_tzasc *)(samsung_get_base_dmc_tzasc0()
>                                                      + DMC_OFFSET);"

Yes, so my suggestion is defining TZASC only.

#define EXYNOS5420_DMC_TZASC_BASE     0x10D40000
SAMSUNG_BASE(dmc_tzasc, DMC_TZASC_BASE)

>>
>>>  SAMSUNG_BASE(audio_ass, AUDIOSS_BASE)
>>>  #endif
>>>

Thanks,
Minkyu Kang.
Rajeshwari Birje Dec. 9, 2013, 8:11 a.m. UTC | #4
Hi Minkyu Kang,

Please do find the comment bellow.

On Thu, Dec 5, 2013 at 12:55 PM, Rajeshwari Birje
<rajeshwari.birje@gmail.com> wrote:
> Hi Minkyu Kang,
>
> Thank you for comments.
>
> On Tue, Dec 3, 2013 at 11:45 AM, Minkyu Kang <mk7.kang@samsung.com> wrote:
>> Dear Rajeshwari S Shinde,
>>
>> On 02/12/13 20:47, Rajeshwari S Shinde wrote:
>>> This patch intends to add DDR3 initialization code for Exynos5420.
>>>
>>> Signed-off-by: Rajeshwari S Shinde <rajeshwari.s@samsung.com>
>>> Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
>>> Acked-by: Simon Glass <sjg@chromium.org>
>>> ---
>>> Changes in V2:
>>>       - Corrected a compilation issue for SMDK5250.
>>> Changes in V3:
>>>       - None
>>> Changes in V4:
>>>       - None
>>> Changes in V5:
>>>       - None
>>> Changes in V6:
>>>       - None
>>> Changes in V7:
>>>       - Fixed multi line comment.
>>> Changes in V8:
>>>       - None
>>> Changes in V9:
>>>       - Used samsung_get base to get the dmc base address
>>>  arch/arm/cpu/armv7/exynos/dmc_common.c    |  10 +-
>>>  arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c | 425 +++++++++++++++++++++++++++++-
>>>  arch/arm/cpu/armv7/exynos/exynos5_setup.h |   2 +
>>>  arch/arm/include/asm/arch-exynos/cpu.h    |   4 +
>>>  arch/arm/include/asm/arch-exynos/dmc.h    | 123 ++++++---
>>>  arch/arm/include/asm/arch-exynos/power.h  |   6 +
>>>  6 files changed, 525 insertions(+), 45 deletions(-)
>>>
>>> diff --git a/arch/arm/cpu/armv7/exynos/dmc_common.c b/arch/arm/cpu/armv7/exynos/dmc_common.c
>>> index 53cfe6e..9e432c2 100644
>>> --- a/arch/arm/cpu/armv7/exynos/dmc_common.c
>>> +++ b/arch/arm/cpu/armv7/exynos/dmc_common.c
>>> @@ -1,5 +1,5 @@
>>>  /*
>>> - * Mem setup common file for different types of DDR present on SMDK5250 boards.
>>> + * Mem setup common file for different types of DDR present on Exynos boards.
>>>   *
>>>   * Copyright (C) 2012 Samsung Electronics
>>>   *
>>> @@ -152,14 +152,6 @@ void dmc_config_prech(struct mem_timings *mem, struct exynos5_dmc *dmc)
>>>       }
>>>  }
>>>
>>> -void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc)
>>> -{
>>> -     writel(mem->memconfig, &dmc->memconfig0);
>>> -     writel(mem->memconfig, &dmc->memconfig1);
>>> -     writel(DMC_MEMBASECONFIG0_VAL, &dmc->membaseconfig0);
>>> -     writel(DMC_MEMBASECONFIG1_VAL, &dmc->membaseconfig1);
>>> -}
>>> -
>>>  void mem_ctrl_init(int reset)
>>>  {
>>>       struct spl_machine_param *param = spl_get_machine_params();
>>> diff --git a/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c b/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c
>>> index 5f5914e..aa46a43 100644
>>> --- a/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c
>>> +++ b/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c
>>> @@ -1,5 +1,5 @@
>>>  /*
>>> - * DDR3 mem setup file for SMDK5250 board based on EXYNOS5
>>> + * DDR3 mem setup file for board based on EXYNOS5
>>>   *
>>>   * Copyright (C) 2012 Samsung Electronics
>>>   *
>>> @@ -11,12 +11,14 @@
>>>  #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 RDLVL_COMPLETE_TIMEOUT       10000
>>> +#define TIMEOUT      10000
>>>
>>> +#ifdef CONFIG_EXYNOS5250
>>>  static void reset_phy_ctrl(void)
>>>  {
>>>       struct exynos5_clock *clk =
>>> @@ -108,7 +110,7 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
>>>
>>>       /* Precharge Configuration */
>>>       writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
>>> -            &dmc->prechconfig);
>>> +            &dmc->prechconfig0);
>>>
>>>       /* Power Down mode Configuration */
>>>       writel(mem->dpwrdn_cyc << PWRDNCONFIG_DPWRDN_CYC_SHIFT |
>>> @@ -174,7 +176,7 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
>>>               writel(val, &phy1_ctrl->phy_con1);
>>>
>>>               writel(CTRL_RDLVL_GATE_ENABLE, &dmc->rdlvl_config);
>>> -             i = RDLVL_COMPLETE_TIMEOUT;
>>> +             i = TIMEOUT;
>>>               while ((readl(&dmc->phystatus) &
>>>                       (RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1)) !=
>>>                       (RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1) && i > 0) {
>>> @@ -215,3 +217,418 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
>>>               | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT), &dmc->concontrol);
>>>       return 0;
>>>  }
>>> +#endif
>>> +
>>> +#ifdef CONFIG_EXYNOS5420
>>
>> we can avoid ifdef here.
>>
>> int ddr3_mem_ctrl_init(...)
>> {
>>         if (proid_is_exynos5250())
>>                 exynos5250_ddr3_mem_ctrl_init();
>>         else
>>                 exynos5420_ddr3_mem_ctrl_init();
>> }
>>
> Will do it this way
Doing it this way increases the spl size.
hence will keep the #ifdef defines.
diff mbox

Patch

diff --git a/arch/arm/cpu/armv7/exynos/dmc_common.c b/arch/arm/cpu/armv7/exynos/dmc_common.c
index 53cfe6e..9e432c2 100644
--- a/arch/arm/cpu/armv7/exynos/dmc_common.c
+++ b/arch/arm/cpu/armv7/exynos/dmc_common.c
@@ -1,5 +1,5 @@ 
 /*
- * Mem setup common file for different types of DDR present on SMDK5250 boards.
+ * Mem setup common file for different types of DDR present on Exynos boards.
  *
  * Copyright (C) 2012 Samsung Electronics
  *
@@ -152,14 +152,6 @@  void dmc_config_prech(struct mem_timings *mem, struct exynos5_dmc *dmc)
 	}
 }
 
-void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc)
-{
-	writel(mem->memconfig, &dmc->memconfig0);
-	writel(mem->memconfig, &dmc->memconfig1);
-	writel(DMC_MEMBASECONFIG0_VAL, &dmc->membaseconfig0);
-	writel(DMC_MEMBASECONFIG1_VAL, &dmc->membaseconfig1);
-}
-
 void mem_ctrl_init(int reset)
 {
 	struct spl_machine_param *param = spl_get_machine_params();
diff --git a/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c b/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c
index 5f5914e..aa46a43 100644
--- a/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c
+++ b/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c
@@ -1,5 +1,5 @@ 
 /*
- * DDR3 mem setup file for SMDK5250 board based on EXYNOS5
+ * DDR3 mem setup file for board based on EXYNOS5
  *
  * Copyright (C) 2012 Samsung Electronics
  *
@@ -11,12 +11,14 @@ 
 #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 RDLVL_COMPLETE_TIMEOUT	10000
+#define TIMEOUT	10000
 
+#ifdef CONFIG_EXYNOS5250
 static void reset_phy_ctrl(void)
 {
 	struct exynos5_clock *clk =
@@ -108,7 +110,7 @@  int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
 
 	/* Precharge Configuration */
 	writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
-	       &dmc->prechconfig);
+	       &dmc->prechconfig0);
 
 	/* Power Down mode Configuration */
 	writel(mem->dpwrdn_cyc << PWRDNCONFIG_DPWRDN_CYC_SHIFT |
@@ -174,7 +176,7 @@  int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
 		writel(val, &phy1_ctrl->phy_con1);
 
 		writel(CTRL_RDLVL_GATE_ENABLE, &dmc->rdlvl_config);
-		i = RDLVL_COMPLETE_TIMEOUT;
+		i = TIMEOUT;
 		while ((readl(&dmc->phystatus) &
 			(RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1)) !=
 			(RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1) && i > 0) {
@@ -215,3 +217,418 @@  int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
 		| (mem->aref_en << CONCONTROL_AREF_EN_SHIFT), &dmc->concontrol);
 	return 0;
 }
+#endif
+
+#ifdef CONFIG_EXYNOS5420
+int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
+		       int reset)
+{
+	struct exynos5420_clock *clk =
+		(struct exynos5420_clock *)samsung_get_base_clock();
+	struct exynos5_power *power =
+		(struct exynos5_power *)samsung_get_base_power();
+	struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl;
+	struct exynos5_dmc *drex0, *drex1;
+	struct exynos5_tzasc *tzasc0, *tzasc1;
+	uint32_t val, n_lock_r, n_lock_w_phy0, n_lock_w_phy1;
+	int chip;
+	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);
+	drex0 = (struct exynos5_dmc *)samsung_get_base_dmc_ctrl();
+	drex1 = (struct exynos5_dmc *)(samsung_get_base_dmc_ctrl()
+							+ DMC_OFFSET);
+	tzasc0 = (struct exynos5_tzasc *)samsung_get_base_dmc_tzasc0();
+	tzasc1 = (struct exynos5_tzasc *)(samsung_get_base_dmc_tzasc0()
+							+ DMC_OFFSET);
+
+	/* 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, phy1_ctrl))
+		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, DDR_MODE_DDR3);
+	update_reset_dll(drex1, 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->timingrow);
+	writel(mem->timing_row, &drex1->timingrow);
+	writel(mem->timing_data, &drex0->timingdata);
+	writel(mem->timing_data, &drex1->timingdata);
+	writel(mem->timing_power, &drex0->timingpower);
+	writel(mem->timing_power, &drex1->timingpower);
+
+	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);
+		dmc_config_mrs(mem, drex1);
+	} else {
+		/*
+		 * 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_r = readl(&phy0_ctrl->phy_con13);
+		n_lock_w_phy0 = (n_lock_r & 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_r = readl(&phy1_ctrl->phy_con13);
+		n_lock_w_phy1 = (n_lock_r & 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;
+		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;
+		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);
+		}
+
+		if (mem->read_leveling_enable) {
+			/* Set Read DQ Calibration */
+			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);
+			}
+
+			val = readl(&phy0_ctrl->phy_con1);
+			val |= READ_LEVELLING_DDR3;
+			writel(val, &phy0_ctrl->phy_con1);
+			val = readl(&phy1_ctrl->phy_con1);
+			val |= READ_LEVELLING_DDR3;
+			writel(val, &phy1_ctrl->phy_con1);
+
+			val = readl(&phy0_ctrl->phy_con2);
+			val |= (RDLVL_EN | RDLVL_INCR_ADJ);
+			writel(val, &phy0_ctrl->phy_con2);
+			val = readl(&phy1_ctrl->phy_con2);
+			val |= (RDLVL_EN | RDLVL_INCR_ADJ);
+			writel(val, &phy1_ctrl->phy_con2);
+
+			setbits_le32(&drex0->rdlvl_config,
+				     CTRL_RDLVL_DATA_ENABLE);
+			i = TIMEOUT;
+			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;
+
+			clrbits_le32(&drex0->rdlvl_config,
+				     CTRL_RDLVL_DATA_ENABLE);
+			setbits_le32(&drex1->rdlvl_config,
+				     CTRL_RDLVL_DATA_ENABLE);
+			i = TIMEOUT;
+			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;
+
+			clrbits_le32(&drex1->rdlvl_config,
+				     CTRL_RDLVL_DATA_ENABLE);
+
+			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);
+			}
+
+			update_reset_dll(drex0, DDR_MODE_DDR3);
+			update_reset_dll(drex1, DDR_MODE_DDR3);
+		}
+
+		/* 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);
+	}
+
+	/* Send PALL command */
+	dmc_config_prech(mem, drex0);
+	dmc_config_prech(mem, drex1);
+
+	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);
+
+	return 0;
+}
+#endif
diff --git a/arch/arm/cpu/armv7/exynos/exynos5_setup.h b/arch/arm/cpu/armv7/exynos/exynos5_setup.h
index c8d6515..42a7fb8 100644
--- a/arch/arm/cpu/armv7/exynos/exynos5_setup.h
+++ b/arch/arm/cpu/armv7/exynos/exynos5_setup.h
@@ -436,6 +436,7 @@ 
  */
 #ifndef CONFIG_SMDK5420
 
+
 /* APLL_CON1 */
 #define APLL_CON1_VAL	(0x00203800)
 
@@ -696,6 +697,7 @@ 
 #define CLK_DIV_CPERI1_VAL	NOT_AVAILABLE
 
 #else
+#define PAD_RETENTION_DRAM_COREBLK_VAL	0x10000000
 
 /* APLL_CON1 */
 #define APLL_CON1_VAL	(0x0020F300)
diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h
index 2b44210..2c642ba 100644
--- a/arch/arm/include/asm/arch-exynos/cpu.h
+++ b/arch/arm/include/asm/arch-exynos/cpu.h
@@ -53,6 +53,7 @@ 
 #define EXYNOS4_AUDIOSS_BASE		DEVICE_NOT_AVAILABLE
 #define EXYNOS4_USB_HOST_XHCI_BASE	DEVICE_NOT_AVAILABLE
 #define EXYNOS4_USB3PHY_BASE		DEVICE_NOT_AVAILABLE
+#define EXYNOS4_DMC_TZASC0_BASE		DEVICE_NOT_AVAILABLE
 
 /* EXYNOS4X12 */
 #define EXYNOS4X12_GPIO_PART3_BASE	0x03860000
@@ -91,6 +92,7 @@ 
 #define EXYNOS4X12_AUDIOSS_BASE		DEVICE_NOT_AVAILABLE
 #define EXYNOS4X12_USB_HOST_XHCI_BASE	DEVICE_NOT_AVAILABLE
 #define EXYNOS4X12_USB3PHY_BASE		DEVICE_NOT_AVAILABLE
+#define EXYNOS4X12_DMC_TZASC0_BASE	DEVICE_NOT_AVAILABLE
 
 /* EXYNOS5 */
 #define EXYNOS5_I2C_SPACING		0x10000
@@ -129,6 +131,7 @@ 
 
 #define EXYNOS5_ADC_BASE		DEVICE_NOT_AVAILABLE
 #define EXYNOS5_MODEM_BASE		DEVICE_NOT_AVAILABLE
+#define EXYNOS5_DMC_TZASC0_BASE		DEVICE_NOT_AVAILABLE
 
 /* EXYNOS5420 */
 #define EXYNOS5420_AUDIOSS_BASE		0x03810000
@@ -284,6 +287,7 @@  SAMSUNG_BASE(spi_isp, SPI_ISP_BASE)
 SAMSUNG_BASE(tzpc, TZPC_BASE)
 SAMSUNG_BASE(dmc_ctrl, DMC_CTRL_BASE)
 SAMSUNG_BASE(dmc_phy, DMC_PHY_BASE)
+SAMSUNG_BASE(dmc_tzasc0, DMC_TZASC0_BASE)
 SAMSUNG_BASE(audio_ass, AUDIOSS_BASE)
 #endif
 
diff --git a/arch/arm/include/asm/arch-exynos/dmc.h b/arch/arm/include/asm/arch-exynos/dmc.h
index f65c676..0913299 100644
--- a/arch/arm/include/asm/arch-exynos/dmc.h
+++ b/arch/arm/include/asm/arch-exynos/dmc.h
@@ -114,13 +114,24 @@  struct exynos4_dmc {
 struct exynos5_dmc {
 	unsigned int concontrol;
 	unsigned int memcontrol;
+
+/*
+ * Between 5250 and 5420, the DMC Register differs only at 0x8 offset.
+ * So to use the same structure and simplify the code put a define to
+ * distinguish between memconfig0 and cgcontrol register
+ */
+#ifdef CONFIG_EXYNOS5250
 	unsigned int memconfig0;
+#else
+	unsigned int cgcontrol;
+#endif
 	unsigned int memconfig1;
 	unsigned int directcmd;
-	unsigned int prechconfig;
+	unsigned int prechconfig0;
 	unsigned int phycontrol0;
-	unsigned char res1[0xc];
-	unsigned int pwrdnconfig;
+	unsigned int prechconfig1;
+	unsigned char res1[0x8];
+	unsigned int pwrdnconfig;	/* 0x0028*/
 	unsigned int timingpzq;
 	unsigned int timingref;
 	unsigned int timingrow;
@@ -128,12 +139,12 @@  struct exynos5_dmc {
 	unsigned int timingpower;
 	unsigned int phystatus;
 	unsigned char res2[0x4];
-	unsigned int chipstatus_ch0;
+	unsigned int chipstatus_ch0;	/* 0x0048 */
 	unsigned int chipstatus_ch1;
 	unsigned char res3[0x4];
 	unsigned int mrstatus;
 	unsigned char res4[0x8];
-	unsigned int qoscontrol0;
+	unsigned int qoscontrol0;	/* 0x0060 */
 	unsigned char resr5[0x4];
 	unsigned int qoscontrol1;
 	unsigned char res6[0x4];
@@ -164,45 +175,83 @@  struct exynos5_dmc {
 	unsigned int qoscontrol14;
 	unsigned char res19[0x4];
 	unsigned int qoscontrol15;
-	unsigned char res20[0x14];
+	unsigned char res20[0x4];
+	unsigned int timing_set_sw;	/* 0x00e0 */
+	unsigned int timingrow1;
+	unsigned int timingdata1;
+	unsigned int timingpower1;
 	unsigned int ivcontrol;
 	unsigned int wrtra_config;
 	unsigned int rdlvl_config;
-	unsigned char res21[0x8];
+	unsigned char res21[0x4];
+	unsigned int brbrsvcontrol;	/* 0x0100*/
 	unsigned int brbrsvconfig;
 	unsigned int brbqosconfig;
 	unsigned int membaseconfig0;
-	unsigned int membaseconfig1;
+	unsigned int membaseconfig1;	/* 0x0110 */
 	unsigned char res22[0xc];
-	unsigned int wrlvl_config;
-	unsigned char res23[0xc];
-	unsigned int perevcontrol;
+	unsigned int wrlvl_config0;	/* 0x0120 */
+	unsigned int wrlvl_config1;
+	unsigned int wrlvl_status;
+	unsigned char res23[0x4];
+	unsigned int perevcontrol;	/* 0x0130 */
 	unsigned int perev0config;
 	unsigned int perev1config;
 	unsigned int perev2config;
 	unsigned int perev3config;
-	unsigned char res24[0xdebc];
-	unsigned int pmnc_ppc_a;
-	unsigned char res25[0xc];
-	unsigned int cntens_ppc_a;
-	unsigned char res26[0xc];
-	unsigned int cntenc_ppc_a;
-	unsigned char res27[0xc];
-	unsigned int intens_ppc_a;
-	unsigned char res28[0xc];
-	unsigned int intenc_ppc_a;
-	unsigned char res29[0xc];
-	unsigned int flag_ppc_a;
-	unsigned char res30[0xac];
-	unsigned int ccnt_ppc_a;
-	unsigned char res31[0xc];
-	unsigned int pmcnt0_ppc_a;
+	unsigned char res22a[0xc];
+	unsigned int ctrl_io_rdata_ch0;
+	unsigned int ctrl_io_rdata_ch1;
+	unsigned char res23a[0x8];
+	unsigned int cacal_config0;
+	unsigned int cacal_config1;
+	unsigned int cacal_status;
+	unsigned char res24[0x94];
+	unsigned int emergent_config0;	/* 0x0200 */
+	unsigned int emergent_config1;
+	unsigned char res25[0x8];
+	unsigned int bp_control0;
+	unsigned int bp_control0_r;
+	unsigned int bp_control0_w;
+	unsigned char res26[0x4];
+	unsigned int bp_control1;
+	unsigned int bp_control1_r;
+	unsigned int bp_control1_w;
+	unsigned char res27[0x4];
+	unsigned int bp_control2;
+	unsigned int bp_control2_r;
+	unsigned int bp_control2_w;
+	unsigned char res28[0x4];
+	unsigned int bp_control3;
+	unsigned int bp_control3_r;
+	unsigned int bp_control3_w;
+	unsigned char res29[0xb4];
+	unsigned int winconfig_odt_w;	/* 0x0300 */
+	unsigned char res30[0x4];
+	unsigned int winconfig_ctrl_read;
+	unsigned int winconfig_ctrl_gate;
+	unsigned char res31[0xdcf0];
+	unsigned int pmnc_ppc;
 	unsigned char res32[0xc];
-	unsigned int pmcnt1_ppc_a;
+	unsigned int cntens_ppc;
 	unsigned char res33[0xc];
-	unsigned int pmcnt2_ppc_a;
+	unsigned int cntenc_ppc;
 	unsigned char res34[0xc];
-	unsigned int pmcnt3_ppc_a;
+	unsigned int intens_ppc;
+	unsigned char res35[0xc];
+	unsigned int intenc_ppc;
+	unsigned char res36[0xc];
+	unsigned int flag_ppc;		/* 0xe050 */
+	unsigned char res37[0xac];
+	unsigned int ccnt_ppc;
+	unsigned char res38[0xc];
+	unsigned int pmcnt0_ppc;
+	unsigned char res39[0xc];
+	unsigned int pmcnt1_ppc;
+	unsigned char res40[0xc];
+	unsigned int pmcnt2_ppc;
+	unsigned char res41[0xc];
+	unsigned int pmcnt3_ppc;	/* 0xe140 */
 };
 
 struct exynos5_phy_control {
@@ -211,13 +260,13 @@  struct exynos5_phy_control {
 	unsigned int phy_con2;
 	unsigned int phy_con3;
 	unsigned int phy_con4;
-	unsigned char res1[4];
+	unsigned int phy_con5;
 	unsigned int phy_con6;
 	unsigned char res2[4];
 	unsigned int phy_con8;
 	unsigned int phy_con9;
 	unsigned int phy_con10;
-	unsigned char res3[4];
+	unsigned int phy_con11;
 	unsigned int phy_con12;
 	unsigned int phy_con13;
 	unsigned int phy_con14;
@@ -252,6 +301,15 @@  struct exynos5_phy_control {
 	unsigned int phy_con42;
 };
 
+struct exynos5_tzasc {
+	unsigned char res1[0xf00];
+	unsigned int membaseconfig0;
+	unsigned int membaseconfig1;
+	unsigned char res2[0x8];
+	unsigned int memconfig0;
+	unsigned int memconfig1;
+};
+
 enum ddr_mode {
 	DDR_MODE_DDR2,
 	DDR_MODE_DDR3,
@@ -286,6 +344,7 @@  enum mem_manuf {
 #define PHY_CON0_T_WRRDCMD_SHIFT	17
 #define PHY_CON0_T_WRRDCMD_MASK		(0x7 << PHY_CON0_T_WRRDCMD_SHIFT)
 #define PHY_CON0_CTRL_DDR_MODE_SHIFT	11
+#define PHY_CON0_CTRL_DDR_MODE_MASK	0x3
 
 /* PHY_CON1 register fields */
 #define PHY_CON1_RDLVL_RDDATA_ADJ_SHIFT	0
diff --git a/arch/arm/include/asm/arch-exynos/power.h b/arch/arm/include/asm/arch-exynos/power.h
index 8db18c5..6077fc3 100644
--- a/arch/arm/include/asm/arch-exynos/power.h
+++ b/arch/arm/include/asm/arch-exynos/power.h
@@ -690,9 +690,15 @@  struct exynos5_power {
 	unsigned int	pad_retention_spi_status;
 	unsigned int	pad_retention_spi_option;
 	unsigned char	res117[0x14];
+	#ifdef CONFIG_EXYNOS5250
 	unsigned int	pad_retention_gpio_dmc_configuration;
 	unsigned int	pad_retention_gpio_dmc_status;
 	unsigned int	pad_retention_gpio_dmc_option;
+	#else
+	unsigned int	pad_retention_dram_coreblk_configuration;
+	unsigned int	pad_retention_dram_coreblk_status;
+	unsigned int	pad_retention_dram_coreblk_option;
+	#endif
 	unsigned char	res118[0x14];
 	unsigned int	pad_isolation_configuration;
 	unsigned int	pad_isolation_status;