[U-Boot] [PATCH] EXYNOS: SMDK5250: Add support for DDR3 memory.
Chander Kashyap
chander.kashyap at linaro.org
Thu Feb 9 14:14:37 CET 2012
Dear Hatim,
On 8 February 2012 17:14, Hatim Ali <hatim.rv at samsung.com> wrote:
> SMDK5250 development boards have different memory variants like
> DDR3, LPDDR2 and LPDDR3. This patch adds supports for DDR3.
> The DDR3 is configured for 667Mhz and is being enabled by default.
>
> This patch is based on Chander Kashyap's v9 patchset.
> (http://comments.gmane.org/gmane.comp.boot-loaders.u-boot/124396)
>
> Signed-off-by: Hatim Ali <hatim.rv at samsung.com>
>
> diff --git a/board/samsung/smdk5250/Makefile b/board/samsung/smdk5250/Makefile
> index 226db1f..50a17cb 100644
> --- a/board/samsung/smdk5250/Makefile
> +++ b/board/samsung/smdk5250/Makefile
> @@ -27,7 +27,11 @@ LIB = $(obj)lib$(BOARD).o
> SOBJS := lowlevel_init.o
>
> COBJS := clock_init.o
> +ifdef CONFIG_DDR3
> +COBJS += dmc_init_ddr3.o
> +else
> COBJS += dmc_init.o
> +endif
> COBJS += tzpc_init.o
>
> ifndef CONFIG_SPL_BUILD
> diff --git a/board/samsung/smdk5250/dmc_init.c b/board/samsung/smdk5250/dmc_init.c
> index 7881074..160d86e 100644
> --- a/board/samsung/smdk5250/dmc_init.c
> +++ b/board/samsung/smdk5250/dmc_init.c
> @@ -248,7 +248,7 @@ static void config_rdlvl(struct exynos5_dmc *dmc,
> * ctrl_gateduradj, rdlvl_pass_adj
> * rdlvl_rddataPadj
> */
> - val = SET_RDLVL_RDDATAPADJ;
> + val = SET_RDLVL_RDDATA_ADJ;
> writel(val, &phy0_ctrl->phy_con1);
> writel(val, &phy1_ctrl->phy_con1);
>
> @@ -361,8 +361,8 @@ void mem_ctrl_init()
> config_zq(phy0_ctrl, phy1_ctrl);
>
> /* Operation Mode : LPDDR2 */
> - val = PHY_CON0_RESET_VAL;
> - SET_CTRL_DDR_MODE(val, DDR_MODE_LPDDR2);
> + val = CTRL_DDR_MODE(LPDDR2);
> + val |= BYTE_RDLVL_EN;
> writel(val, &phy0_ctrl->phy_con0);
> writel(val, &phy1_ctrl->phy_con0);
>
Spilt the patch in two. One related to dmc_init.c and second for ddr3 support.
> diff --git a/board/samsung/smdk5250/dmc_init_ddr3.c b/board/samsung/smdk5250/dmc_init_ddr3.c
> new file mode 100644
> index 0000000..da42dd2
> --- /dev/null
> +++ b/board/samsung/smdk5250/dmc_init_ddr3.c
> @@ -0,0 +1,464 @@
> +/*
> + * DDR3 Memory setup for SMDK5250 board based on EXYNOS5
> + *
> + * Copyright (C) 2012 Samsung Electronics
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <config.h>
> +#include <asm/io.h>
> +#include <asm/arch/dmc.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/cpu.h>
> +#include "setup.h"
> +
> +/* APLL : 1GHz */
> +/* MCLK_CDREX: MCLK_CDREX_677*/
> +/* LPDDR support: DDR3 */
> +
> +static void dmc_directcmd_PALL(struct exynos5_dmc *dmc)
> +{
> + unsigned long channel, chip, mask = 0, val;
> +
> + /* Sending PALL cmd on
> + * Channel0-Chip0
> + * Channel0-Chip1
> + * Channel1-Chip0
> + * Channel1-Chip1
> + */
> + for (channel = 0; channel < CONFIG_DMC_CHANNELS; channel++) {
> + SET_CMD_CHANNEL(mask, channel);
> + for (chip = 0; chip < CONFIG_CHIPS_PER_CHANNEL; chip++) {
> + SET_CMD_CHIP(mask, chip);
> + val = DIRECT_CMD_PALL | mask;
> + writel(val, &dmc->directcmd);
> + sdelay(0x10000);
> + }
> + }
> +
> +}
> +
> +
> +static void dmc_directcmd(struct exynos5_dmc *dmc)
> +{
> + unsigned long channel, mask = 0, val;
> +
> + /* Selecting Channel0-Chip0 */
> + SET_CMD_CHANNEL(mask, 0);
> + SET_CMD_CHIP(mask, 0);
> +
> + /* Sending NOP cmd on Channel0-Chip0 */
> + val = DIRECT_CMD_NOP | mask;
> + writel(val, &dmc->directcmd);
> + sdelay(0x10000);
> +
> + dmc_directcmd_PALL(dmc);
> +
> + /* Selecting Chip 0*/
> + mask = 0;
> + SET_CMD_CHIP(mask, 0);
> + for (channel = 0; channel < CONFIG_DMC_CHANNELS; channel++) {
> + /* Selecting Channel */
> + SET_CMD_CHANNEL(mask, channel);
> +
> + if (channel == 1) {
> + /* Sending NOP cmd on Channel1-Chip0 */
> + val = DIRECT_CMD_NOP | mask;
> + writel(val, &dmc->directcmd);
> + sdelay(0x10000);
> + }
> + /* Sending MRS/EMRS command and ZQINIT command
> + * on Channel0-Chip0
> + */
> + val = DIRECT_CMD_MRS1 | mask;
> + writel(val, &dmc->directcmd);
> + sdelay(0x10000);
> +
> + val = DIRECT_CMD_MRS2 | mask;
> + writel(val, &dmc->directcmd);
> + sdelay(0x10000);
> +
> + val = DIRECT_CMD_MRS3 | mask;
> + writel(val, &dmc->directcmd);
> + sdelay(0x10000);
> +
> + val = DIRECT_CMD_MRS4 | mask;
> + writel(val, &dmc->directcmd);
> + sdelay(0x10000);
> +
> + val = DIRECT_CMD_ZQINIT | mask;
> + writel(val, &dmc->directcmd);
> + sdelay(0x10000);
> + }
> +}
> +
> +static void update_reset_dll(struct exynos5_dmc *dmc)
> +{
> + unsigned long val;
> + val = (PHY_CONTROL0_RESET_VAL | MEM_TERM_EN |
> + PHY_TERM_EN | CTRL_SHGATE);
> + /*
> + * Update DLL Information:
> + * Force DLL Resyncronization
> + */
> + val |= FP_RSYNC;
> + writel(val, &dmc->phycontrol0);
> +
> + /* Reset Force DLL Resyncronization */
> + val &= ~FP_RSYNC;
> + writel(val, &dmc->phycontrol0);
> +}
> +
> +static void config_memory(struct exynos5_dmc *dmc)
> +{
> + /*
> + * 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
> + */
> + writel(DMC_MEMCONTROL_VAL, &dmc->memcontrol);
> +
> + /*
> + * Memory Configuration Chip 0
> + * Address Mapping: Interleaved
> + * Number of Column address Bits: 10 bits
> + * Number of Rows Address Bits: 15
> + * Number of Banks: 8
> + */
> + writel(DMC_MEMCONFIG0_VAL, &dmc->memconfig0);
> +
> + /*
> + * Memory Configuration Chip 1
> + * Address Mapping: Interleaved
> + * Number of Column address Bits: 10 bits
> + * Number of Rows Address Bits: 15
> + * Number of Banks: 8
> + */
> + writel(DMC_MEMCONFIG1_VAL, &dmc->memconfig1);
> +
> + /*
> + * Chip0: AXI
> + * AXI Base Address: 0x40000000
> + * AXI Base Address Mask: 0x7C0
> + */
> + writel(DMC_MEMBASECONFIG0_VAL, &dmc->membaseconfig0);
> +
> + /*
> + * Chip1: AXI
> + * AXI Base Address: 0x80000000
> + * AXI Base Address Mask: 0x7C0
> + */
> + writel(DMC_MEMBASECONFIG1_VAL, &dmc->membaseconfig1);
> +}
> +
> +static void reset_phy_ctrl(void)
> +{
> + struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE;
> + writel(PHY_RESET_VAL, &clk->lpddr3phy_ctrl);
> + writel(PHY_SET_VAL, &clk->lpddr3phy_ctrl);
> + writel(PHY_RESET_VAL, &clk->lpddr3phy_ctrl);
> + writel(PHY_SET_VAL, &clk->lpddr3phy_ctrl);
> +}
> +
> +static void config_zq(struct exynos5_phy_control *phy0_ctrl,
> + struct exynos5_phy_control *phy1_ctrl)
> +{
> + unsigned long val = 0;
> + /*
> + * ZQ Calibration:
> + * Select Driver Strength,
> + * long calibration for manual calibration
> + */
> + val = PHY_CON16_RESET_VAL;
> + SET_ZQ_MODE_DDS_VAL(val);
> + SET_ZQ_MODE_TERM_VAL(val);
> + val = val | ZQ_CLK_DIV_EN | ZQ_CLK_EN;
> + writel(val, &phy0_ctrl->phy_con16);
> + writel(val, &phy1_ctrl->phy_con16);
> +
> + writel(val, &phy0_ctrl->phy_con16);
> + writel(val, &phy1_ctrl->phy_con16);
> +
> + /* ZQ_MANUAL_START: Enable */
> + val |= ZQ_MANUAL_STR;
> + writel(val, &phy0_ctrl->phy_con16);
> + writel(val, &phy1_ctrl->phy_con16);
> +
> + sdelay(0x10000);
> + sdelay(0x10000);
> +
> + /* ZQ_MANUAL_START: Disable */
> + val &= ~ZQ_MANUAL_STR;
> + writel(val, &phy0_ctrl->phy_con16);
> + writel(val, &phy1_ctrl->phy_con16);
> +}
> +
> +void mem_ctrl_init()
> +{
> + struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE;
> + struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl;
> + struct exynos5_dmc *dmc;
> + unsigned int val, tmp;
> +
> + phy0_ctrl = (struct exynos5_phy_control *)EXYNOS5_DMC_PHY0_BASE;
> + phy1_ctrl = (struct exynos5_phy_control *)EXYNOS5_DMC_PHY1_BASE;
> + dmc = (struct exynos5_dmc *)EXYNOS5_DMC_CTRL_BASE;
> +
> + writel(0x0, &clk->src_cdrex);
> + writel(CLK_DIV_CDREX_VAL, &clk->div_cdrex);
> +
> + writel(MPLL_CON1_VAL, &clk->mpll_con1);
> + writel(MPLL_CON0_VAL, &clk->mpll_con0);
> + writel(BPLL_CON1_VAL, &clk->bpll_con1);
> + writel(BPLL_CON0_VAL, &clk->bpll_con0);
> +
> + sdelay(0x10000);
> + sdelay(0x10000);
> + sdelay(0x10000);
> +
> + writel(CLK_SRC_CDREX_VAL, &clk->src_cdrex);
> +
> + sdelay(0x10000);
> +
> + reset_phy_ctrl();
> +
> + sdelay(0x10000);
> +
> + /* Setting CTRL_FORCE value in MDLL control register*/
> + val = PHY_CON12_RESET_VAL;
> + SET_CTRL_FORCE_VAL(val, 0x33);
> + writel(val, &phy0_ctrl->phy_con12);
> + writel(val, &phy1_ctrl->phy_con12);
> +
> + sdelay(0x10000);
> +
> + update_reset_dll(dmc);
> +
> + /*set Read Latance and Burst Length for PHY0 and PHY1 */
> + writel(PHY_CON42_VAL, &phy0_ctrl->phy_con42);
> + writel(PHY_CON42_VAL, &phy1_ctrl->phy_con42);
> +
> + /* Setting Operation Mode: DDR3
> + * Enabling byte_rdlvl
> + */
> + val = CTRL_DDR_MODE(DDR3);
> + val |= BYTE_RDLVL_EN;
> + writel(val, &phy0_ctrl->phy_con0);
> + writel(val, &phy1_ctrl->phy_con0);
> +
> + /* ZQ Calibration */
> + config_zq(phy0_ctrl, phy1_ctrl);
> +
> + /* DQS, DQ: Signal, for LPDDR3: Always Set */
> + val = CTRL_PULLD_DQ | CTRL_PULLD_DQS;
> + writel(val, &phy0_ctrl->phy_con14);
> + writel(val, &phy1_ctrl->phy_con14);
> +
> + /* Set DMC Concontrol
> + * dfi_init_start = 1
> + * rd_fetch = 0x3
> + * empty = 0
> + */
> + val = DMC_CONCONTROL_RESET_VAL;
> + SET_RD_FETCH(val);
> + val |= DFI_INIT_START;
> + val &= ~EMPTY;
> + writel(val, &dmc->concontrol);
> +
> + update_reset_dll(dmc);
> +
> + /* Set DQS offsets */
> + writel(DDR3_PHY0_DQS, &phy0_ctrl->phy_con4);
> + writel(DDR3_PHY1_DQS, &phy1_ctrl->phy_con4);
> +
> + /* Set DQS offsets */
> + writel(DDR3_PHY0_DQ, &phy0_ctrl->phy_con6);
> + writel(DDR3_PHY1_DQ, &phy1_ctrl->phy_con6);
> +
> + /* Set Debug offsets */
> + writel(RESET_DEBUG_OFFSET_VAL, &phy0_ctrl->phy_con10);
> + writel(RESET_DEBUG_OFFSET_VAL, &phy1_ctrl->phy_con10);
> +
> + /* Reset DLL Locking */
> + val = PHY_CON12_RESET_VAL;
> + CONFIG_CTRL_START(val, RESET);
> + writel(val, &phy0_ctrl->phy_con12);
> + writel(val, &phy1_ctrl->phy_con12);
> + sdelay(0x10000);
> + val = PHY_CON12_RESET_VAL;
> + CONFIG_CTRL_START(val, SET);
> + writel(val, &phy0_ctrl->phy_con12);
> + writel(val, &phy1_ctrl->phy_con12);
> +
> + sdelay(0x10000);
> + sdelay(0x10000);
> +
> + update_reset_dll(dmc);
> + update_reset_dll(dmc);
> +
> + /* Set DMC Concontrol
> + * rd_fetch = 0x3
> + * empty = 0
> + * Basically here we are stopping dfi_init_start done above.
> + */
> + val = DMC_CONCONTROL_RESET_VAL;
> + SET_RD_FETCH(val);
> + val &= ~EMPTY;
> + writel(val, &dmc->concontrol);
> +
> + config_memory(dmc);
> +
> + /* Memory Channel Inteleaving Size: 128 Bytes */
> + writel(CONFIG_IV_SIZE, &dmc->ivcontrol);
> +
> + /* Precharge Configuration */
> + writel(DMC_PRECHCONFIG_VAL, &dmc->prechconfig);
> +
> + /* Power Down mode Configuration */
> + writel(DMC_PWRDNCONFIG_VAL, &dmc->pwrdnconfig);
> +
> + /* Periodic Refresh Interval */
> + writel(DMC_TIMINGREF_VAL, &dmc->timingref);
> +
> + /*
> + * TimingRow, TimingData, TimingPower Setting:
> + * Values as per Memory AC Parameters
> + */
> + writel(DMC_TIMINGROW_VAL, &dmc->timingrow);
> +
> + writel(DMC_TIMINGDATA_VAL, &dmc->timingdata);
> +
> + writel(DMC_TIMINGPOWER_VAL, &dmc->timingpower);
> +
> + dmc_directcmd(dmc);
> +
> + /* Updating MDLL control register*/
> + val = readl(&phy0_ctrl->phy_con13);
> + val &= (0x3F << 10);
> + val >>= 2;
> + tmp = PHY_CON12_RESET_VAL;
> + CONFIG_CTRL_DLL_ON(tmp, RESET);
> + val += tmp;
> + writel(val, &phy0_ctrl->phy_con12);
> +
> + val = readl(&phy1_ctrl->phy_con13);
> + val &= (0x3F << 10);
> + val >>= 2;
> + tmp = PHY_CON12_RESET_VAL;
> + CONFIG_CTRL_DLL_ON(tmp, RESET);
> + val += tmp;
> + writel(val, &phy1_ctrl->phy_con12);
> +
> + sdelay(0x10000);
> +
> + update_reset_dll(dmc);
> +
> + writel(SET_RDLVL_RDDATA_ADJ, &phy0_ctrl->phy_con1);
> + writel(SET_RDLVL_RDDATA_ADJ, &phy1_ctrl->phy_con1);
> +
> + writel(DDR3_ADDR, &phy0_ctrl->phy_con24);
> + writel(DDR3_ADDR, &phy1_ctrl->phy_con24);
> +
> + /* Set rddata margin as 0x2
> + * Enabling byte_rdlvl
> + */
> + val = SET_T_RDDATA_MARGIN(0x2);
> + val |= BYTE_RDLVL_EN;
> + writel(val, &phy0_ctrl->phy_con0);
> + writel(val, &phy1_ctrl->phy_con0);
> +
> + /* Enable Read Leveling */
> + val = PHY_CON2_RESET_VAL | RDLVL_EN;
> + writel(val, &phy0_ctrl->phy_con2);
> + writel(val, &phy1_ctrl->phy_con2);
> +
> + /* Enable data eye training*/
> + val = RDLVL_CONFIG_RESET_VAL | CTRL_RDLVL_DATA_EN;
> + writel(val, &dmc->rdlvl_config);
> +
> + sdelay(0x10000);
> +
> + /* Disable data eye training*/
> + val = RDLVL_CONFIG_RESET_VAL & ~CTRL_RDLVL_DATA_EN;
> + writel(val, &dmc->rdlvl_config);
> +
> + /* Updating MDLL control register*/
> + val = readl(&phy0_ctrl->phy_con13);
> + val &= (0x3F << 10);
> + val >>= 2;
> + tmp = PHY_CON12_RESET_VAL;
> + CONFIG_CTRL_DLL_ON(tmp, SET);
> + val += tmp;
> + writel(val, &phy0_ctrl->phy_con12);
> +
> + val = readl(&phy1_ctrl->phy_con13);
> + val &= (0x3F << 10);
> + val >>= 2;
> + tmp = PHY_CON12_RESET_VAL;
> + CONFIG_CTRL_DLL_ON(tmp, SET);
> + val += tmp;
> + writel(val, &phy1_ctrl->phy_con12);
> +
> + sdelay(0x10000);
> +
> + update_reset_dll(dmc);
> +
> + dmc_directcmd_PALL(dmc);
> +
> + update_reset_dll(dmc);
> +
> + sdelay(0x10000);
> +
> + /* Set rddata margin as 0x2
> + * Enabling byte_rdlvl
> + */
> + val = SET_T_RDDATA_MARGIN(0x2);
> + val |= BYTE_RDLVL_EN;
> + writel(val, &phy0_ctrl->phy_con0);
> + writel(val, &phy1_ctrl->phy_con0);
> +
> + /* Enable Read Leveling */
> + writel(SET_RDLVL_RDDATA_ADJ, &phy0_ctrl->phy_con1);
> + writel(SET_RDLVL_RDDATA_ADJ, &phy1_ctrl->phy_con1);
> +
> + /*
> + * 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
> + */
> + writel(DMC_MEMCONTROL_VAL, &dmc->memcontrol);
> +
> + /* Set DMC Concontrol
> + * rd_fetch = 0x3
> + * empty = 0
> + * Auto refresh counter enable
> + */
> + val = DMC_CONCONTROL_RESET_VAL;
> + SET_RD_FETCH(val);
> + val &= ~EMPTY;
> + val |= AREF_EN;
> + writel(val, &dmc->concontrol);
> +}
> diff --git a/board/samsung/smdk5250/setup.h b/board/samsung/smdk5250/setup.h
> index 1276fd3..2d7e5a4 100644
> --- a/board/samsung/smdk5250/setup.h
> +++ b/board/samsung/smdk5250/setup.h
> @@ -113,8 +113,13 @@
> #define VPLL_CON1_VAL 0x00000000
> #define VPLL_CON2_VAL 0x00000080
>
> +#ifdef CONFIG_LPDDR2
> #define BPLL_MDIV 0x215
> #define BPLL_PDIV 0xC
> +#elif defined CONFIG_DDR3
> +#define BPLL_MDIV 0x185
> +#define BPLL_PDIV 0x7
> +#endif
> #define BPLL_SDIV 0x1
>
> #define BPLL_CON1_VAL 0x00203800
> @@ -154,13 +159,19 @@
> #define MCLK_CDREX_RATIO 0x0
> #define ACLK_C2C_200_RATIO 0x1
> #define C2C_CLK_400_RATIO 0x1
> +#ifdef CONFIG_DDR3
> +#define PCLK_CDREX_RATIO 0x4 /* CDREX = 667 Mhz*/
> +#else
> #define PCLK_CDREX_RATIO 0x3
> +#endif
> #define ACLK_CDREX_RATIO 0x1
> -#define CLK_DIV_CDREX_VAL ((MCLK_DPHY_RATIO << 20) \
> - | (MCLK_CDREX_RATIO << 16) \
> +#define CLK_DIV_CDREX_VAL ((MCLK_CDREX2_RATIO << 28) \
> + | (ACLK_EFCON_RATIO << 24) \
> + | (MCLK_DPHY_RATIO << 20) \
> + | (MCLK_CDREX_RATIO << 16) \
> | (ACLK_C2C_200_RATIO << 12) \
> - | (C2C_CLK_400_RATIO << 8) \
> - | (PCLK_CDREX_RATIO << 4) \
> + | (C2C_CLK_400_RATIO << 8) \
> + | (PCLK_CDREX_RATIO << 4) \
Unwanted Additions of above two lines.
> | (ACLK_CDREX_RATIO))
>
> #define MCLK_EFPHY_RATIO 0x4
> @@ -354,12 +365,18 @@
> #define CONFIG_IV_SIZE 0x07
>
> #define PHY_RESET_VAL (0 << 0)
> +#define PHY_SET_VAL (1 << 0)
>
> /*ZQ Configurations */
> #define PHY_CON16_RESET_VAL 0x08000304
> -
> +#define ZQ_CLK_EN (1 << 27)
> +#ifdef CONFIG_LPDDR2
> #define ZQ_MODE_DDS_VAL (0x5 << 24)
> #define ZQ_MODE_TERM_VAL (0x5 << 21)
> +#elif defined CONFIG_DDR3
> +#define ZQ_MODE_DDS_VAL (0x7 << 24)
> +#define ZQ_MODE_TERM_VAL (0x2 << 21)
> +#endif
> #define SET_ZQ_MODE_DDS_VAL(x) (x = (x & ~(0x7 << 24)) | ZQ_MODE_DDS_VAL)
> #define SET_ZQ_MODE_TERM_VAL(x) (x = (x & ~(0x7 << 21)) | ZQ_MODE_TERM_VAL)
>
> @@ -376,55 +393,107 @@
>
> /* Diret Command */
> #define DIRECT_CMD_NOP 0x07000000
> +#define DIRECT_CMD_PALL 0x01000000
> +#define DIRECT_CMD_ZQINIT 0x0A000000
> +#ifdef CONFIG_LPDDR2
> #define DIRECT_CMD_MRS1 0x00071C00
> #define DIRECT_CMD_MRS2 0x00010BFC
> #define DIRECT_CMD_MRS3 0x00000708
> #define DIRECT_CMD_MRS4 0x00000818
> -#define DIRECT_CMD_PALL 0x01000000
> +#elif defined CONFIG_DDR3
> +#define DIRECT_CMD_MRS1 0x00020010 /* CDREX = 667Mhz*/
> +#define DIRECT_CMD_MRS2 0x00030000
> +#define DIRECT_CMD_MRS3 0x00010042
> +#define DIRECT_CMD_MRS4 0x00000B50 /* CDREX = 667Mhz*/
> +#endif
>
> -/* DLL Resync */
> -#define FP_RSYNC (1 << 3)
> +/* DMC PHY Control0 register */
> +#define PHY_CONTROL0_RESET_VAL 0x0
> +#define MEM_TERM_EN (1 << 31) /*Termination enable for memory*/
> +#define PHY_TERM_EN (1 << 30) /*Termination enable for PHY*/
> +#define CTRL_SHGATE (1 << 29) /*Duration of DQS gating signal*/
> +#define FP_RSYNC (1 << 3) /*Force DLL resyncronization*/
>
> +/* MDLL control */
> +#define PHY_CON12_RESET_VAL 0x10100070
> #define CONFIG_CTRL_DLL_ON(x, y) (x = (x & ~(1 << 5)) | y << 5)
> #define CONFIG_CTRL_START(x, y) (x = (x & ~(1 << 6)) | y << 6)
> #define SET_CTRL_FORCE_VAL(x, y) (x = (x & ~(0x7F << 8)) | y << 8)
>
> -/* RDLVL */
> -#define PHY_CON0_RESET_VAL 0x17023240
> -#define DDR_MODE_LPDDR2 0x2
> +/* PHY Control */
> +#define PHY_CON0_RESET_VAL 0x17020A40
> +#define DDR3 0x1
> +#define LPDDR2 0x2
> +#define LPDDR3 0x3
> #define BYTE_RDLVL_EN (1 << 13)
> #define CTRL_ATGATE (1 << 6)
> -#define SET_CTRL_DDR_MODE(x, y) (x = (x & ~(0x3 << 11)) | y << 11)
> +#define CTRL_DDR_MODE(x) ((PHY_CON0_RESET_VAL & ~(0x3 << 11)) \
> + |(x << 11))
> +#define SET_T_RDDATA_MARGIN(x) ((PHY_CON0_RESET_VAL & ~(0x7 << 17)) \
> + |(x << 17))
> +
> +#define PHY_CON1_RESET_VAL 0x09210100
> +#ifdef CONFIG_DDR3
> +#define RDLVL_RDDATA_ADJ 0xFF00
> +#elif defined CONFIG_LPDDR2
> +#define RDLVL_RDDATA_ADJ 0x1
> +#endif
> +#define SET_RDLVL_RDDATA_ADJ ((PHY_CON1_RESET_VAL & ~(0xFFFF << 0))\
> + | RDLVL_RDDATA_ADJ << 0)
>
> -#define PHY_CON1_RESET_VAL 0x9210100
> -#define RDLVL_RDDATAPADJ 0x1
> -#define SET_RDLVL_RDDATAPADJ ((PHY_CON1_RESET_VAL & ~(0xFFFF << 0))\
> - | RDLVL_RDDATAPADJ << 0)
> +#define DDR3_ADDR 0x0208
>
> #define PHY_CON2_RESET_VAL 0x00010004
> #define RDLVL_EN (1 << 25)
> #define RDDSKEW_CLEAR (1 << 13)
>
> +#define RDLVL_CONFIG_RESET_VAL 0x0
> #define CTRL_RDLVL_DATA_EN (1 << 1)
> #define LPDDR2_ADDR 0x00000208
>
> -#define DMC_MEMCONFIG0_VAL 0x00001323
> -#define DMC_MEMCONFIG1_VAL 0x00001323
> #define DMC_MEMBASECONFIG0_VAL 0x00400780
> #define DMC_MEMBASECONFIG1_VAL 0x00800780
> +#ifdef CONFIG_LPDDR2
> #define DMC_MEMCONTROL_VAL 0x00212500
> +#define DMC_MEMCONFIG0_VAL 0x00001323
> +#define DMC_MEMCONFIG1_VAL 0x00001323
> +#elif defined CONFIG_DDR3
> +#define DMC_MEMCONTROL_VAL 0x00302600
> +#define DMC_MEMCONFIG0_VAL 0x00001333
> +#define DMC_MEMCONFIG1_VAL 0x00001333
> +#endif
> +
> #define DMC_PRECHCONFIG_VAL 0xFF000000
> #define DMC_PWRDNCONFIG_VAL 0xFFFF00FF
> +#ifdef CONFIG_LPDDR2
> #define DMC_TIMINGREF_VAL 0x0000005D
> #define DMC_TIMINGROW_VAL 0x2336544C
> #define DMC_TIMINGDATA_VAL 0x24202408
> #define DMC_TIMINGPOWER_VAL 0x38260235
> +#elif defined CONFIG_DDR3
> +#define DMC_TIMINGREF_VAL 0x000000BB
> +#define DMC_TIMINGROW_VAL 0x7645644d /* CDREX = 667 Mhz*/
> +#define DMC_TIMINGDATA_VAL 0x45414709 /* CDREX = 667 Mhz*/
> +#define DMC_TIMINGPOWER_VAL 0x3a000a3c /* CDREX = 667 Mhz*/
> +#endif
>
> +#ifdef CONFIG_LPDDR2
> #define CTRL_BSTLEN 0x04
> #define CTRL_RDLAT 0x08
> +#elif defined CONFIG_DDR3
> +#define CTRL_BSTLEN 0x08
> +#define CTRL_RDLAT 0x09 /* CDREX = 667 Mhz*/
> +#endif
> #define PHY_CON42_VAL (CTRL_BSTLEN << 8 | CTRL_RDLAT << 0)
>
> /* DQS, DQ, DEBUG offsets */
> +#ifdef CONFIG_DDR3 /* CDREX = 667 Mhz */
> +#define DDR3_PHY0_DQS 0x08080808
> +#define DDR3_PHY1_DQS 0x08080808
> +#define DDR3_PHY0_DQ 0x08080808
> +#define DDR3_PHY1_DQ 0x00080808
> +#endif
> +
> #define SET_DQS_OFFSET_VAL 0x7F7F7F7F
> #define SET_DQ_OFFSET_VAL 0x7F7F7F7F
> #define SET_DEBUG_OFFSET_VAL 0x7F
> @@ -436,13 +505,21 @@
> #define CTRL_PULLD_DQ (0x0F << 8)
> #define CTRL_PULLD_DQS (0x0F << 0)
>
> +#define DMC_CONCONTROL_RESET_VAL 0x0FFF1100
> +#ifdef CONFIG_LPDDR2
> +#define RD_FETCH 0x3
> +#elif defined CONFIG_DDR3
> +#define RD_FETCH 0x2 /* CDREX = 667 Mhz */
> +#endif
> +#define SET_RD_FETCH(x) (x = (x & ~(0x7 << 12)) | RD_FETCH << 12)
> #define DFI_INIT_START (1 << 28)
> +#define EMPTY (1 << 8)
> +#define AREF_EN (1 << 5)
>
> #define CLK_STOP_EN (1 << 0)
> #define DPWRDN_EN (1 << 1)
> #define DSREF_EN (1 << 5)
>
> -#define AREF_EN (1 << 5)
> void sdelay(unsigned long);
> void mem_ctrl_init(void);
> void system_clock_init(void);
> diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h
> index f54d7ac..11a8f4d 100644
> --- a/include/configs/smdk5250.h
> +++ b/include/configs/smdk5250.h
> @@ -37,6 +37,14 @@
> #define CONFIG_DISPLAY_CPUINFO
> #define CONFIG_DISPLAY_BOARDINFO
>
> +/* Choose DDR Type below
> + * * Uncomment the type of DDR present on your board
> + * */
Remove extra * in comment.
> +#define CONFIG_DDR3
> +/*
> + * #define CONFIG_LPDDR2
> + */
> +
> /* Keep L2 Cache Disabled */
> #define CONFIG_SYS_DCACHE_OFF
>
> --
> 1.7.2.3
>
--
with warm regards,
Chander Kashyap
More information about the U-Boot
mailing list