Patchwork [U-Boot,1/2,v3] Exynos5: spl: Reorganize mem_timing struct to gain space in spl

login
register
mail settings
Submitter Akshay Saraswat
Date March 6, 2013, 2:22 p.m.
Message ID <1362579729-3546-2-git-send-email-akshay.s@samsung.com>
Download mbox | patch
Permalink /patch/225505/
State Changes Requested
Delegated to: Minkyu Kang
Headers show

Comments

Akshay Saraswat - March 6, 2013, 2:22 p.m.
Distributes struct mem_timings into new different structures
to gain space in spl by removing necessity of maintaining
two big and almost similar mem_timings instances.

Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
---
Changes since v1:
	- None.

Changes since v2:
	- Replaced non_spl_clock_div with clock_div.
	- Replaced ns_clk_div with clk_div.
	- Added few new comments.
	- Modified few comments.

 board/samsung/smdk5250/clock_init.c    | 177 ++++++++++++---------------------
 board/samsung/smdk5250/clock_init.h    |  74 ++++++++++----
 board/samsung/smdk5250/dmc_common.c    |  40 ++++----
 board/samsung/smdk5250/dmc_init_ddr3.c | 116 +++++++++++----------
 board/samsung/smdk5250/setup.h         |  15 ++-
 5 files changed, 211 insertions(+), 211 deletions(-)
Simon Glass - March 8, 2013, 3:33 a.m.
Hi Akshay,

On Wed, Mar 6, 2013 at 6:22 AM, Akshay Saraswat <akshay.s@samsung.com> wrote:
> Distributes struct mem_timings into new different structures
> to gain space in spl by removing necessity of maintaining
> two big and almost similar mem_timings instances.
>
> Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
> ---
> Changes since v1:
>         - None.
>
> Changes since v2:
>         - Replaced non_spl_clock_div with clock_div.
>         - Replaced ns_clk_div with clk_div.
>         - Added few new comments.
>         - Modified few comments.
>
>  board/samsung/smdk5250/clock_init.c    | 177 ++++++++++++---------------------
>  board/samsung/smdk5250/clock_init.h    |  74 ++++++++++----
>  board/samsung/smdk5250/dmc_common.c    |  40 ++++----
>  board/samsung/smdk5250/dmc_init_ddr3.c | 116 +++++++++++----------
>  board/samsung/smdk5250/setup.h         |  15 ++-
>  5 files changed, 211 insertions(+), 211 deletions(-)

Is it possible to move the non-spl code into a separate file? I think
it would be better if SPL includes one clock_init (memory, boot
peripheral) and U-Boot includes the other, and that there is nothing
in common. Would that work?

Regards,
Simon

Patch

diff --git a/board/samsung/smdk5250/clock_init.c b/board/samsung/smdk5250/clock_init.c
index c009ae5..2a07f44 100644
--- a/board/samsung/smdk5250/clock_init.c
+++ b/board/samsung/smdk5250/clock_init.c
@@ -127,14 +127,17 @@  struct arm_clk_ratios arm_clk_ratios[] = {
 		.arm_ratio = 0x0,
 	}
 };
-struct mem_timings mem_timings[] = {
-	{
-		.mem_manuf = MEM_MANUF_ELPIDA,
-		.mem_type = DDR_MODE_DDR3,
-		.frequency_mhz = 800,
+
+struct spl_clock_div spl_clock_div = {
 		.mpll_mdiv = 0xc8,
 		.mpll_pdiv = 0x3,
 		.mpll_sdiv = 0x0,
+		.bpll_mdiv = 0x64,
+		.bpll_pdiv = 0x3,
+		.bpll_sdiv = 0x0,
+};
+
+struct clock_div clock_div = {
 		.cpll_mdiv = 0xde,
 		.cpll_pdiv = 0x4,
 		.cpll_sdiv = 0x2,
@@ -147,14 +150,10 @@  struct mem_timings mem_timings[] = {
 		.vpll_mdiv = 0x96,
 		.vpll_pdiv = 0x3,
 		.vpll_sdiv = 0x2,
+};
 
-		.bpll_mdiv = 0x64,
-		.bpll_pdiv = 0x3,
-		.bpll_sdiv = 0x0,
+struct mem_timings mem_timings = {
 		.pclk_cdrex_ratio = 0x5,
-		.direct_cmd_msr = {
-			0x00020018, 0x00030000, 0x00010042, 0x00000d70
-		},
 		.timing_ref = 0x000000bb,
 		.timing_row = 0x8c36650e,
 		.timing_data = 0x3630580b,
@@ -163,8 +162,6 @@  struct mem_timings mem_timings[] = {
 		.phy1_dqs = 0x08080808,
 		.phy0_dq = 0x08080808,
 		.phy1_dq = 0x08080808,
-		.phy0_tFS = 0x4,
-		.phy1_tFS = 0x4,
 		.phy0_pulld_dqs = 0xf,
 		.phy1_pulld_dqs = 0xf,
 
@@ -186,10 +183,6 @@  struct mem_timings mem_timings[] = {
 
 		.rd_fetch = 0x3,
 
-		.zq_mode_dds = 0x7,
-		.zq_mode_term = 0x1,
-		.zq_mode_noterm = 0,
-
 		/*
 		* Dynamic Clock: Always Running
 		* Memory Burst length: 8
@@ -229,114 +222,49 @@  struct mem_timings mem_timings[] = {
 		.chips_per_channel = 2,
 		.chips_to_configure = 1,
 		.send_zq_init = 1,
+};
+
+struct mem_params mem_params[] = {
+	{
+		.mem_manuf = MEM_MANUF_ELPIDA,
+		.mem_type = DDR_MODE_DDR3,
+		.frequency_mhz = 800,
+
+		.direct_cmd_msr = {
+			0x00020018, 0x00030000, 0x00010042, 0x00000d70
+		},
+
+		.phy0_tFS = 0x4,
+		.phy1_tFS = 0x4,
+
+		.zq_mode_dds = 0x7,
+		.zq_mode_term = 0x1,
+		.zq_mode_noterm = 0,
+
 		.impedance = IMP_OUTPUT_DRV_30_OHM,
 		.gate_leveling_enable = 0,
 	}, {
 		.mem_manuf = MEM_MANUF_SAMSUNG,
 		.mem_type = DDR_MODE_DDR3,
 		.frequency_mhz = 800,
-		.mpll_mdiv = 0xc8,
-		.mpll_pdiv = 0x3,
-		.mpll_sdiv = 0x0,
-		.cpll_mdiv = 0xde,
-		.cpll_pdiv = 0x4,
-		.cpll_sdiv = 0x2,
-		.gpll_mdiv = 0x215,
-		.gpll_pdiv = 0xc,
-		.gpll_sdiv = 0x1,
-		.epll_mdiv = 0x60,
-		.epll_pdiv = 0x3,
-		.epll_sdiv = 0x3,
-		.vpll_mdiv = 0x96,
-		.vpll_pdiv = 0x3,
-		.vpll_sdiv = 0x2,
 
-		.bpll_mdiv = 0x64,
-		.bpll_pdiv = 0x3,
-		.bpll_sdiv = 0x0,
-		.pclk_cdrex_ratio = 0x5,
 		.direct_cmd_msr = {
 			0x00020018, 0x00030000, 0x00010000, 0x00000d70
 		},
-		.timing_ref = 0x000000bb,
-		.timing_row = 0x8c36650e,
-		.timing_data = 0x3630580b,
-		.timing_power = 0x41000a44,
-		.phy0_dqs = 0x08080808,
-		.phy1_dqs = 0x08080808,
-		.phy0_dq = 0x08080808,
-		.phy1_dq = 0x08080808,
+
 		.phy0_tFS = 0x8,
 		.phy1_tFS = 0x8,
-		.phy0_pulld_dqs = 0xf,
-		.phy1_pulld_dqs = 0xf,
-
-		.lpddr3_ctrl_phy_reset = 0x1,
-		.ctrl_start_point = 0x10,
-		.ctrl_inc = 0x10,
-		.ctrl_start = 0x1,
-		.ctrl_dll_on = 0x1,
-		.ctrl_ref = 0x8,
-
-		.ctrl_force = 0x1a,
-		.ctrl_rdlat = 0x0b,
-		.ctrl_bstlen = 0x08,
-
-		.fp_resync = 0x8,
-		.iv_size = 0x7,
-		.dfi_init_start = 1,
-		.aref_en = 1,
-
-		.rd_fetch = 0x3,
 
 		.zq_mode_dds = 0x5,
 		.zq_mode_term = 0x1,
 		.zq_mode_noterm = 1,
 
-		/*
-		* Dynamic Clock: Always Running
-		* Memory Burst length: 8
-		* Number of chips: 1
-		* Memory Bus width: 32 bit
-		* Memory Type: DDR3
-		* Additional Latancy for PLL: 0 Cycle
-		*/
-		.memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE |
-			DMC_MEMCONTROL_DPWRDN_DISABLE |
-			DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE |
-			DMC_MEMCONTROL_TP_DISABLE |
-			DMC_MEMCONTROL_DSREF_ENABLE |
-			DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) |
-			DMC_MEMCONTROL_MEM_TYPE_DDR3 |
-			DMC_MEMCONTROL_MEM_WIDTH_32BIT |
-			DMC_MEMCONTROL_NUM_CHIP_1 |
-			DMC_MEMCONTROL_BL_8 |
-			DMC_MEMCONTROL_PZQ_DISABLE |
-			DMC_MEMCONTROL_MRR_BYTE_7_0,
-		.memconfig = DMC_MEMCONFIGx_CHIP_MAP_INTERLEAVED |
-			DMC_MEMCONFIGx_CHIP_COL_10 |
-			DMC_MEMCONFIGx_CHIP_ROW_15 |
-			DMC_MEMCONFIGx_CHIP_BANK_8,
-		.membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40),
-		.membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80),
-		.prechconfig_tp_cnt = 0xff,
-		.dpwrdn_cyc = 0xff,
-		.dsref_cyc = 0xffff,
-		.concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE |
-			DMC_CONCONTROL_TIMEOUT_LEVEL0 |
-			DMC_CONCONTROL_RD_FETCH_DISABLE |
-			DMC_CONCONTROL_EMPTY_DISABLE |
-			DMC_CONCONTROL_AREF_EN_DISABLE |
-			DMC_CONCONTROL_IO_PD_CON_DISABLE,
-		.dmc_channels = 2,
-		.chips_per_channel = 2,
-		.chips_to_configure = 1,
-		.send_zq_init = 1,
 		.impedance = IMP_OUTPUT_DRV_40_OHM,
 		.gate_leveling_enable = 1,
 	}
 };
 
+
 /**
  * Get the required memory type and speed (SPL version).
  *
@@ -388,9 +316,24 @@  struct arm_clk_ratios *get_arm_ratios(void)
 	return NULL;
 }
 
+struct spl_clock_div *clock_get_spl_div(void)
+{
+	return &spl_clock_div;
+}
+
+struct clock_div *clock_get_div(void)
+{
+	return &clock_div;
+}
+
 struct mem_timings *clock_get_mem_timings(void)
 {
-	struct mem_timings *mem;
+	return &mem_timings;
+}
+
+struct mem_params *clock_get_mem_params(void)
+{
+	struct mem_params *mem;
 	enum ddr_mode mem_type;
 	enum mem_manuf mem_manuf;
 	unsigned frequency_mhz, arm_freq;
@@ -398,7 +341,7 @@  struct mem_timings *clock_get_mem_timings(void)
 
 	if (!clock_get_mem_selection(&mem_type, &frequency_mhz,
 						&arm_freq, &mem_manuf)) {
-		for (i = 0, mem = mem_timings; i < ARRAY_SIZE(mem_timings);
+		for (i = 0, mem = mem_params; i < ARRAY_SIZE(mem_params);
 				i++, mem++) {
 			if (mem->mem_type == mem_type &&
 					mem->frequency_mhz == frequency_mhz &&
@@ -417,12 +360,14 @@  struct mem_timings *clock_get_mem_timings(void)
 void system_clock_init()
 {
 	struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE;
-	struct mem_timings *mem;
 	struct arm_clk_ratios *arm_clk_ratio;
+	struct spl_clock_div *s_clk_div;
+	struct clock_div *clk_div;
 	u32 val, tmp;
 
-	mem = clock_get_mem_timings();
 	arm_clk_ratio = get_arm_ratios();
+	s_clk_div = clock_get_spl_div();
+	clk_div = clock_get_div();
 
 	clrbits_le32(&clk->src_cpu, MUX_APLL_SEL_MASK);
 	do {
@@ -499,28 +444,32 @@  void system_clock_init()
 
 	/* Set MPLL */
 	writel(MPLL_CON1_VAL, &clk->mpll_con1);
-	val = set_pll(mem->mpll_mdiv, mem->mpll_pdiv, mem->mpll_sdiv);
+	val = set_pll(s_clk_div->mpll_mdiv,
+				s_clk_div->mpll_pdiv, s_clk_div->mpll_sdiv);
 	writel(val, &clk->mpll_con0);
 	while (readl(&clk->mpll_con0) & MPLL_CON0_LOCKED)
 		;
 
 	/* Set BPLL */
 	writel(BPLL_CON1_VAL, &clk->bpll_con1);
-	val = set_pll(mem->bpll_mdiv, mem->bpll_pdiv, mem->bpll_sdiv);
+	val = set_pll(s_clk_div->bpll_mdiv,
+				s_clk_div->bpll_pdiv, s_clk_div->bpll_sdiv);
 	writel(val, &clk->bpll_con0);
 	while (readl(&clk->bpll_con0) & BPLL_CON0_LOCKED)
 		;
 
 	/* Set CPLL */
 	writel(CPLL_CON1_VAL, &clk->cpll_con1);
-	val = set_pll(mem->cpll_mdiv, mem->cpll_pdiv, mem->cpll_sdiv);
+	val = set_pll(clk_div->cpll_mdiv,
+				clk_div->cpll_pdiv, clk_div->cpll_sdiv);
 	writel(val, &clk->cpll_con0);
 	while (readl(&clk->cpll_con0) & CPLL_CON0_LOCKED)
 		;
 
 	/* Set GPLL */
 	writel(GPLL_CON1_VAL, &clk->gpll_con1);
-	val = set_pll(mem->gpll_mdiv, mem->gpll_pdiv, mem->gpll_sdiv);
+	val = set_pll(clk_div->gpll_mdiv,
+				clk_div->gpll_pdiv, clk_div->gpll_sdiv);
 	writel(val, &clk->gpll_con0);
 	while (readl(&clk->gpll_con0) & GPLL_CON0_LOCKED)
 		;
@@ -528,7 +477,8 @@  void system_clock_init()
 	/* Set EPLL */
 	writel(EPLL_CON2_VAL, &clk->epll_con2);
 	writel(EPLL_CON1_VAL, &clk->epll_con1);
-	val = set_pll(mem->epll_mdiv, mem->epll_pdiv, mem->epll_sdiv);
+	val = set_pll(clk_div->epll_mdiv,
+				clk_div->epll_pdiv, clk_div->epll_sdiv);
 	writel(val, &clk->epll_con0);
 	while (readl(&clk->epll_con0) & EPLL_CON0_LOCKED)
 		;
@@ -536,7 +486,8 @@  void system_clock_init()
 	/* Set VPLL */
 	writel(VPLL_CON2_VAL, &clk->vpll_con2);
 	writel(VPLL_CON1_VAL, &clk->vpll_con1);
-	val = set_pll(mem->vpll_mdiv, mem->vpll_pdiv, mem->vpll_sdiv);
+	val = set_pll(clk_div->vpll_mdiv,
+				clk_div->vpll_pdiv, clk_div->vpll_sdiv);
 	writel(val, &clk->vpll_con0);
 	while (readl(&clk->vpll_con0) & VPLL_CON0_LOCKED)
 		;
diff --git a/board/samsung/smdk5250/clock_init.h b/board/samsung/smdk5250/clock_init.h
index f751bcb..ae68333 100644
--- a/board/samsung/smdk5250/clock_init.h
+++ b/board/samsung/smdk5250/clock_init.h
@@ -47,19 +47,18 @@  struct arm_clk_ratios {
 	unsigned arm_ratio;
 };
 
-/* These are the memory timings for a particular memory type and speed */
-struct mem_timings {
-	enum mem_manuf mem_manuf;	/* Memory manufacturer */
-	enum ddr_mode mem_type;		/* Memory type */
-	unsigned frequency_mhz;		/* Frequency of memory in MHz */
-
-	/* Here follow the timing parameters for the selected memory */
-	unsigned apll_mdiv;
-	unsigned apll_pdiv;
-	unsigned apll_sdiv;
+/* pll's to be initialized in spl */
+struct spl_clock_div {
 	unsigned mpll_mdiv;
 	unsigned mpll_pdiv;
 	unsigned mpll_sdiv;
+	unsigned bpll_mdiv;
+	unsigned bpll_pdiv;
+	unsigned bpll_sdiv;
+};
+
+/* pll's to be initialized in main U-Boot */
+struct clock_div {
 	unsigned cpll_mdiv;
 	unsigned cpll_pdiv;
 	unsigned cpll_sdiv;
@@ -72,9 +71,14 @@  struct mem_timings {
 	unsigned vpll_mdiv;
 	unsigned vpll_pdiv;
 	unsigned vpll_sdiv;
-	unsigned bpll_mdiv;
-	unsigned bpll_pdiv;
-	unsigned bpll_sdiv;
+};
+
+/*
+ * These are the memory timings for a particular memory type and speed
+ * These doesn't usually change with vendor.
+ */
+struct mem_timings {
+	/* Here follow the timing parameters for the selected memory */
 	unsigned pclk_cdrex_ratio;
 	unsigned direct_cmd_msr[MEM_TIMINGS_MSR_COUNT];
 
@@ -88,8 +92,6 @@  struct mem_timings {
 	unsigned phy1_dqs;
 	unsigned phy0_dq;
 	unsigned phy1_dq;
-	unsigned phy0_tFS;
-	unsigned phy1_tFS;
 	unsigned phy0_pulld_dqs;
 	unsigned phy1_pulld_dqs;
 
@@ -111,10 +113,6 @@  struct mem_timings {
 
 	unsigned rd_fetch;
 
-	unsigned zq_mode_dds;
-	unsigned zq_mode_term;
-	unsigned zq_mode_noterm;	/* 1 to allow termination disable */
-
 	unsigned memcontrol;
 	unsigned memconfig;
 
@@ -129,19 +127,55 @@  struct mem_timings {
 	uint8_t chips_per_channel;	/* number of chips per channel */
 	uint8_t chips_to_configure;	/* number of chips to configure */
 	uint8_t send_zq_init;		/* 1 to send this command */
+};
+
+/*
+ * These are the memory timings for a particular memory type and speed
+ * These does change with vendor.
+ */
+struct mem_params {
+	/* Here follow the memory parameters which differ with vendors */
+	enum mem_manuf mem_manuf;	/* Memory manufacturer */
+	enum ddr_mode mem_type;		/* Memory type */
+	unsigned frequency_mhz;		/* Frequency of memory in MHz */
+
+	unsigned direct_cmd_msr[MEM_TIMINGS_MSR_COUNT];
+
+	unsigned phy0_tFS;
+	unsigned phy1_tFS;
+
+	unsigned zq_mode_dds;
+	unsigned zq_mode_term;
+	unsigned zq_mode_noterm;	/* 1 to allow termination disable */
+
 	unsigned impedance;		/* drive strength impedeance */
 	uint8_t gate_leveling_enable;	/* check gate leveling is enabled */
 };
 
+/* Get the pll's which need to be initialized in spl */
+struct spl_clock_div *clock_get_spl_div(void);
+
+/* Get the pll's which need to be initialized main U-Boot */
+struct clock_div *clock_get_div(void);
+
 /**
  * Get the correct memory timings for our selected memory type and speed.
  *
  * This function can be called from SPL or the main U-Boot.
  *
- * @return pointer to the memory timings that we should use
+ * @return pointer to the mem_timings struct that we should use
  */
 struct mem_timings *clock_get_mem_timings(void);
 
+/**
+ * Get the vendor specific memory timings for our selected memory type and speed.
+ *
+ * This function can be called from SPL or the main U-Boot.
+ *
+ * @return pointer to the mem_params struct that we should use
+ */
+struct mem_params *clock_get_mem_params(void);
+
 /*
  * Initialize clock for the device
  */
diff --git a/board/samsung/smdk5250/dmc_common.c b/board/samsung/smdk5250/dmc_common.c
index 109602a..1166cb7 100644
--- a/board/samsung/smdk5250/dmc_common.c
+++ b/board/samsung/smdk5250/dmc_common.c
@@ -30,7 +30,7 @@ 
 
 #define ZQ_INIT_TIMEOUT	10000
 
-int dmc_config_zq(struct mem_timings *mem,
+int dmc_config_zq(struct mem_params *mparams,
 		  struct exynos5_phy_control *phy0_ctrl,
 		  struct exynos5_phy_control *phy1_ctrl)
 {
@@ -43,14 +43,14 @@  int dmc_config_zq(struct mem_timings *mem,
 	 * long calibration for manual calibration
 	 */
 	val = PHY_CON16_RESET_VAL;
-	val |= mem->zq_mode_dds << PHY_CON16_ZQ_MODE_DDS_SHIFT;
-	val |= mem->zq_mode_term << PHY_CON16_ZQ_MODE_TERM_SHIFT;
+	val |= mparams->zq_mode_dds << PHY_CON16_ZQ_MODE_DDS_SHIFT;
+	val |= mparams->zq_mode_term << PHY_CON16_ZQ_MODE_TERM_SHIFT;
 	val |= ZQ_CLK_DIV_EN;
 	writel(val, &phy0_ctrl->phy_con16);
 	writel(val, &phy1_ctrl->phy_con16);
 
 	/* Disable termination */
-	if (mem->zq_mode_noterm)
+	if (mparams->zq_mode_noterm)
 		val |= PHY_CON16_ZQ_MODE_NOTERM_MASK;
 	writel(val, &phy0_ctrl->phy_con16);
 	writel(val, &phy1_ctrl->phy_con16);
@@ -108,15 +108,17 @@  void update_reset_dll(struct exynos5_dmc *dmc, enum ddr_mode mode)
 	writel(val, &dmc->phycontrol0);
 }
 
-void dmc_config_mrs(struct mem_timings *mem, struct exynos5_dmc *dmc)
+void dmc_config_mrs(struct mem_timings *mtimings,
+			struct mem_params *mparams,
+			struct exynos5_dmc *dmc)
 {
 	int channel, chip;
 
-	for (channel = 0; channel < mem->dmc_channels; channel++) {
+	for (channel = 0; channel < mtimings->dmc_channels; channel++) {
 		unsigned long mask;
 
 		mask = channel << DIRECT_CMD_CHANNEL_SHIFT;
-		for (chip = 0; chip < mem->chips_to_configure; chip++) {
+		for (chip = 0; chip < mtimings->chips_to_configure; chip++) {
 			int i;
 
 			mask |= chip << DIRECT_CMD_CHIP_SHIFT;
@@ -133,12 +135,12 @@  void dmc_config_mrs(struct mem_timings *mem, struct exynos5_dmc *dmc)
 
 			/* Sending EMRS/MRS commands */
 			for (i = 0; i < MEM_TIMINGS_MSR_COUNT; i++) {
-				writel(mem->direct_cmd_msr[i] | mask,
+				writel(mparams->direct_cmd_msr[i] | mask,
 				       &dmc->directcmd);
 				sdelay(0x10000);
 			}
 
-			if (mem->send_zq_init) {
+			if (mtimings->send_zq_init) {
 				/* Sending ZQINIT command */
 				writel(DIRECT_CMD_ZQINIT | mask,
 				       &dmc->directcmd);
@@ -149,15 +151,15 @@  void dmc_config_mrs(struct mem_timings *mem, struct exynos5_dmc *dmc)
 	}
 }
 
-void dmc_config_prech(struct mem_timings *mem, struct exynos5_dmc *dmc)
+void dmc_config_prech(struct mem_timings *mtimings, struct exynos5_dmc *dmc)
 {
 	int channel, chip;
 
-	for (channel = 0; channel < mem->dmc_channels; channel++) {
+	for (channel = 0; channel < mtimings->dmc_channels; channel++) {
 		unsigned long mask;
 
 		mask = channel << DIRECT_CMD_CHANNEL_SHIFT;
-		for (chip = 0; chip < mem->chips_per_channel; chip++) {
+		for (chip = 0; chip < mtimings->chips_per_channel; chip++) {
 			mask |= chip << DIRECT_CMD_CHIP_SHIFT;
 
 			/* PALL (all banks precharge) CMD */
@@ -167,10 +169,10 @@  void dmc_config_prech(struct mem_timings *mem, struct exynos5_dmc *dmc)
 	}
 }
 
-void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc)
+void dmc_config_memory(struct mem_timings *mtimings, struct exynos5_dmc *dmc)
 {
-	writel(mem->memconfig, &dmc->memconfig0);
-	writel(mem->memconfig, &dmc->memconfig1);
+	writel(mtimings->memconfig, &dmc->memconfig0);
+	writel(mtimings->memconfig, &dmc->memconfig1);
 	writel(DMC_MEMBASECONFIG0_VAL, &dmc->membaseconfig0);
 	writel(DMC_MEMBASECONFIG1_VAL, &dmc->membaseconfig1);
 }
@@ -178,14 +180,16 @@  void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc)
 void mem_ctrl_init()
 {
 	struct spl_machine_param *param = spl_get_machine_params();
-	struct mem_timings *mem;
+	struct mem_timings *mtimings;
+	struct mem_params *mparams;
 	int ret;
 
-	mem = clock_get_mem_timings();
+	mtimings = clock_get_mem_timings();
+	mparams = clock_get_mem_params();
 
 	/* If there are any other memory variant, add their init call below */
 	if (param->mem_type == DDR_MODE_DDR3) {
-		ret = ddr3_mem_ctrl_init(mem, param->mem_iv_size);
+		ret = ddr3_mem_ctrl_init(mtimings, mparams, param->mem_iv_size);
 		if (ret) {
 			/* will hang if failed to init memory control */
 			while (1)
diff --git a/board/samsung/smdk5250/dmc_init_ddr3.c b/board/samsung/smdk5250/dmc_init_ddr3.c
index e050790..7f4cb3c 100644
--- a/board/samsung/smdk5250/dmc_init_ddr3.c
+++ b/board/samsung/smdk5250/dmc_init_ddr3.c
@@ -40,7 +40,9 @@  static void reset_phy_ctrl(void)
 	writel(DDR3PHY_CTRL_PHY_RESET, &clk->lpddr3phy_ctrl);
 }
 
-int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size)
+int ddr3_mem_ctrl_init(struct mem_timings *mtimings,
+			struct mem_params *mparams,
+			unsigned long mem_iv_size)
 {
 	unsigned int val;
 	struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl;
@@ -54,93 +56,95 @@  int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size)
 	reset_phy_ctrl();
 
 	/* Set Impedance Output Driver */
-	val = (mem->impedance << CA_CK_DRVR_DS_OFFSET) |
-		(mem->impedance << CA_CKE_DRVR_DS_OFFSET) |
-		(mem->impedance << CA_CS_DRVR_DS_OFFSET) |
-		(mem->impedance << CA_ADR_DRVR_DS_OFFSET);
+	val = (mparams->impedance << CA_CK_DRVR_DS_OFFSET) |
+		(mparams->impedance << CA_CKE_DRVR_DS_OFFSET) |
+		(mparams->impedance << CA_CS_DRVR_DS_OFFSET) |
+		(mparams->impedance << CA_ADR_DRVR_DS_OFFSET);
 	writel(val, &phy0_ctrl->phy_con39);
 	writel(val, &phy1_ctrl->phy_con39);
 
 	/* Set Read Latency and Burst Length for PHY0 and PHY1 */
-	val = (mem->ctrl_bstlen << PHY_CON42_CTRL_BSTLEN_SHIFT) |
-		(mem->ctrl_rdlat << PHY_CON42_CTRL_RDLAT_SHIFT);
+	val = (mtimings->ctrl_bstlen << PHY_CON42_CTRL_BSTLEN_SHIFT) |
+		(mtimings->ctrl_rdlat << PHY_CON42_CTRL_RDLAT_SHIFT);
 	writel(val, &phy0_ctrl->phy_con42);
 	writel(val, &phy1_ctrl->phy_con42);
 
 	/* ZQ Calibration */
-	if (dmc_config_zq(mem, phy0_ctrl, phy1_ctrl))
+	if (dmc_config_zq(mparams, phy0_ctrl, phy1_ctrl))
 		return SETUP_ERR_ZQ_CALIBRATION_FAILURE;
 
 	/* DQ Signal */
-	writel(mem->phy0_pulld_dqs, &phy0_ctrl->phy_con14);
-	writel(mem->phy1_pulld_dqs, &phy1_ctrl->phy_con14);
+	writel(mtimings->phy0_pulld_dqs, &phy0_ctrl->phy_con14);
+	writel(mtimings->phy1_pulld_dqs, &phy1_ctrl->phy_con14);
 
-	writel(mem->concontrol | (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)
-		| (mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT),
+	writel(mtimings->concontrol
+		| (mtimings->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)
+		| (mtimings->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT),
 		&dmc->concontrol);
 
 	update_reset_dll(dmc, DDR_MODE_DDR3);
 
 	/* DQS Signal */
-	writel(mem->phy0_dqs, &phy0_ctrl->phy_con4);
-	writel(mem->phy1_dqs, &phy1_ctrl->phy_con4);
+	writel(mtimings->phy0_dqs, &phy0_ctrl->phy_con4);
+	writel(mtimings->phy1_dqs, &phy1_ctrl->phy_con4);
 
-	writel(mem->phy0_dq, &phy0_ctrl->phy_con6);
-	writel(mem->phy1_dq, &phy1_ctrl->phy_con6);
+	writel(mtimings->phy0_dq, &phy0_ctrl->phy_con6);
+	writel(mtimings->phy1_dq, &phy1_ctrl->phy_con6);
 
-	writel(mem->phy0_tFS, &phy0_ctrl->phy_con10);
-	writel(mem->phy1_tFS, &phy1_ctrl->phy_con10);
+	writel(mparams->phy0_tFS, &phy0_ctrl->phy_con10);
+	writel(mparams->phy1_tFS, &phy1_ctrl->phy_con10);
 
-	val = (mem->ctrl_start_point << PHY_CON12_CTRL_START_POINT_SHIFT) |
-		(mem->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) |
-		(mem->ctrl_dll_on << PHY_CON12_CTRL_DLL_ON_SHIFT) |
-		(mem->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT);
+	val = (mtimings->ctrl_start_point << PHY_CON12_CTRL_START_POINT_SHIFT) |
+		(mtimings->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) |
+		(mtimings->ctrl_dll_on << PHY_CON12_CTRL_DLL_ON_SHIFT) |
+		(mtimings->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT);
 	writel(val, &phy0_ctrl->phy_con12);
 	writel(val, &phy1_ctrl->phy_con12);
 
 	/* Start DLL locking */
-	writel(val | (mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT),
+	writel(val | (mtimings->ctrl_start << PHY_CON12_CTRL_START_SHIFT),
 		&phy0_ctrl->phy_con12);
-	writel(val | (mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT),
+	writel(val | (mtimings->ctrl_start << PHY_CON12_CTRL_START_SHIFT),
 		&phy1_ctrl->phy_con12);
 
 	update_reset_dll(dmc, DDR_MODE_DDR3);
 
-	writel(mem->concontrol | (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT),
+	writel(mtimings->concontrol
+		| (mtimings->rd_fetch << CONCONTROL_RD_FETCH_SHIFT),
 		&dmc->concontrol);
 
 	/* Memory Channel Inteleaving Size */
-	writel(mem->iv_size, &dmc->ivcontrol);
+	writel(mtimings->iv_size, &dmc->ivcontrol);
 
-	writel(mem->memconfig, &dmc->memconfig0);
-	writel(mem->memconfig, &dmc->memconfig1);
-	writel(mem->membaseconfig0, &dmc->membaseconfig0);
-	writel(mem->membaseconfig1, &dmc->membaseconfig1);
+	writel(mtimings->memconfig, &dmc->memconfig0);
+	writel(mtimings->memconfig, &dmc->memconfig1);
+	writel(mtimings->membaseconfig0, &dmc->membaseconfig0);
+	writel(mtimings->membaseconfig1, &dmc->membaseconfig1);
 
 	/* Precharge Configuration */
-	writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
+	writel(mtimings->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
 		&dmc->prechconfig);
 
 	/* Power Down mode Configuration */
-	writel(mem->dpwrdn_cyc << PWRDNCONFIG_DPWRDN_CYC_SHIFT |
-		mem->dsref_cyc << PWRDNCONFIG_DSREF_CYC_SHIFT,
+	writel(mtimings->dpwrdn_cyc << PWRDNCONFIG_DPWRDN_CYC_SHIFT |
+		mtimings->dsref_cyc << PWRDNCONFIG_DSREF_CYC_SHIFT,
 		&dmc->pwrdnconfig);
 
 	/* TimingRow, TimingData, TimingPower and Timingaref
 	 * values as per Memory AC parameters
 	 */
-	writel(mem->timing_ref, &dmc->timingref);
-	writel(mem->timing_row, &dmc->timingrow);
-	writel(mem->timing_data, &dmc->timingdata);
-	writel(mem->timing_power, &dmc->timingpower);
+	writel(mtimings->timing_ref, &dmc->timingref);
+	writel(mtimings->timing_row, &dmc->timingrow);
+	writel(mtimings->timing_data, &dmc->timingdata);
+	writel(mtimings->timing_power, &dmc->timingpower);
 
 	/* Send PALL command */
-	dmc_config_prech(mem, dmc);
+	dmc_config_prech(mtimings, dmc);
 
 	/* Send NOP, MRS and ZQINIT commands */
-	dmc_config_mrs(mem, dmc);
+	dmc_config_mrs(mtimings, mparams, dmc);
 
-	if (mem->gate_leveling_enable) {
+	if (mparams->gate_leveling_enable) {
 		val = PHY_CON0_RESET_VAL;
 		val |= P0_CMD_EN;
 		writel(val, &phy0_ctrl->phy_con0);
@@ -157,12 +161,12 @@  int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size)
 		writel(val, &phy0_ctrl->phy_con0);
 		writel(val, &phy1_ctrl->phy_con0);
 
-		val = (mem->ctrl_start_point <<
+		val = (mtimings->ctrl_start_point <<
 				PHY_CON12_CTRL_START_POINT_SHIFT) |
-			(mem->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) |
-			(mem->ctrl_force << PHY_CON12_CTRL_FORCE_SHIFT) |
-			(mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT) |
-			(mem->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT);
+			(mtimings->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) |
+			(mtimings->ctrl_force << PHY_CON12_CTRL_FORCE_SHIFT) |
+			(mtimings->ctrl_start << PHY_CON12_CTRL_START_SHIFT) |
+			(mtimings->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT);
 		writel(val, &phy0_ctrl->phy_con12);
 		writel(val, &phy1_ctrl->phy_con12);
 
@@ -203,13 +207,13 @@  int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size)
 		writel(0, &phy0_ctrl->phy_con14);
 		writel(0, &phy1_ctrl->phy_con14);
 
-		val = (mem->ctrl_start_point <<
+		val = (mtimings->ctrl_start_point <<
 				PHY_CON12_CTRL_START_POINT_SHIFT) |
-			(mem->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) |
-			(mem->ctrl_force << PHY_CON12_CTRL_FORCE_SHIFT) |
-			(mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT) |
-			(mem->ctrl_dll_on << PHY_CON12_CTRL_DLL_ON_SHIFT) |
-			(mem->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT);
+			(mtimings->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) |
+			(mtimings->ctrl_force << PHY_CON12_CTRL_FORCE_SHIFT) |
+			(mtimings->ctrl_start << PHY_CON12_CTRL_START_SHIFT) |
+			(mtimings->ctrl_dll_on << PHY_CON12_CTRL_DLL_ON_SHIFT) |
+			(mtimings->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT);
 		writel(val, &phy0_ctrl->phy_con12);
 		writel(val, &phy1_ctrl->phy_con12);
 
@@ -217,12 +221,14 @@  int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size)
 	}
 
 	/* Send PALL command */
-	dmc_config_prech(mem, dmc);
+	dmc_config_prech(mtimings, dmc);
 
-	writel(mem->memcontrol, &dmc->memcontrol);
+	writel(mtimings->memcontrol, &dmc->memcontrol);
 
 	/* Set DMC Concontrol and enable auto-refresh counter */
-	writel(mem->concontrol | (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)
-		| (mem->aref_en << CONCONTROL_AREF_EN_SHIFT), &dmc->concontrol);
+	writel(mtimings->concontrol
+		| (mtimings->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)
+		| (mtimings->aref_en << CONCONTROL_AREF_EN_SHIFT),
+		&dmc->concontrol);
 	return 0;
 }
diff --git a/board/samsung/smdk5250/setup.h b/board/samsung/smdk5250/setup.h
index a159601..b30d7d0 100644
--- a/board/samsung/smdk5250/setup.h
+++ b/board/samsung/smdk5250/setup.h
@@ -521,6 +521,7 @@ 
 #define PHY_CON42_CTRL_RDLAT_SHIFT	0
 
 struct mem_timings;
+struct mem_params;
 
 /* Errors that we can encourter in low-level setup */
 enum {
@@ -539,7 +540,9 @@  enum {
  *			accesses; may vary across boards.
  * @return 0 if ok, SETUP_ERR_... if there is a problem
  */
-int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size);
+int ddr3_mem_ctrl_init(struct mem_timings *mtimings,
+			struct mem_params *mparams,
+			unsigned long mem_iv_size);
 
 /*
  * Configure ZQ I/O interface
@@ -549,7 +552,7 @@  int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size);
  * @param phy1_ctrl	Pointer to struct containing PHY1 control reg
  * @return 0 if ok, -1 on error
  */
-int dmc_config_zq(struct mem_timings *mem,
+int dmc_config_zq(struct mem_params *mparams,
 		  struct exynos5_phy_control *phy0_ctrl,
 		  struct exynos5_phy_control *phy1_ctrl);
 
@@ -559,7 +562,9 @@  int dmc_config_zq(struct mem_timings *mem,
  * @param mem		Memory timings for this memory type.
  * @param dmc		Pointer to struct of DMC registers
  */
-void dmc_config_mrs(struct mem_timings *mem, struct exynos5_dmc *dmc);
+void dmc_config_mrs(struct mem_timings *mtimings,
+			struct mem_params *mparams,
+			struct exynos5_dmc *dmc);
 
 /*
  * Send PALL Direct commands
@@ -567,7 +572,7 @@  void dmc_config_mrs(struct mem_timings *mem, struct exynos5_dmc *dmc);
  * @param mem		Memory timings for this memory type.
  * @param dmc		Pointer to struct of DMC registers
  */
-void dmc_config_prech(struct mem_timings *mem, struct exynos5_dmc *dmc);
+void dmc_config_prech(struct mem_timings *mtimings, struct exynos5_dmc *dmc);
 
 /*
  * Configure the memconfig and membaseconfig registers
@@ -575,7 +580,7 @@  void dmc_config_prech(struct mem_timings *mem, struct exynos5_dmc *dmc);
  * @param mem		Memory timings for this memory type.
  * @param exynos5_dmc	Pointer to struct of DMC registers
  */
-void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc);
+void dmc_config_memory(struct mem_timings *mtimings, struct exynos5_dmc *dmc);
 
 /*
  * Reset the DLL. This function is common between DDR3 and LPDDR2.