[U-Boot] [PATCH 5/5] AM3517: Add support for EMIF4

hvaibhav at ti.com
2009-11-23T11:09:15Z

From: Vaibhav Hiremath <hvaibhav@ti.com>

Changes:-

- Created 2 seperate config option
* CONFIG_SDRC (omap34xx family)
* CONFIG_EMIF4 (am3517 family)
- Changed all omap3 dependent file for CONFIG_SDRC

Tested On:-

- AM3517EVM board
- OMAP3EVM board
- BEAGLE board

I would need help here from people to validate this change for SDP/ZOOMx
and other OMAP3 version of boards.

Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
---
cpu/arm_cortexa8/omap3/board.c | 11 ++-
cpu/arm_cortexa8/omap3/mem.c | 110 ++++++++++++++++++++++++++------
cpu/arm_cortexa8/omap3/sys_info.c | 12 +++-
include/asm-arm/arch-omap3/cpu.h | 26 ++++++++
include/asm-arm/arch-omap3/mem.h | 58 ++++++++++++++++-
include/asm-arm/arch-omap3/sys_proto.h | 4 +
include/configs/am3517_evm.h | 6 ++
include/configs/devkit8000.h | 4 +
include/configs/omap3_beagle.h | 4 +
include/configs/omap3_evm.h | 4 +
include/configs/omap3_overo.h | 4 +
include/configs/omap3_pandora.h | 4 +
include/configs/omap3_sdp3430.h | 4 +
include/configs/omap3_zoom1.h | 4 +
include/configs/omap3_zoom2.h | 4 +
15 files changed, 233 insertions(+), 26 deletions(-)

diff --git a/cpu/arm_cortexa8/omap3/board.c b/cpu/arm_cortexa8/omap3/board.c
index dd2c940..ce60f99 100644
--- a/cpu/arm_cortexa8/omap3/board.c
+++ b/cpu/arm_cortexa8/omap3/board.c
@@ -227,7 +227,11 @@ void s_init(void)
per_clocks_enable();

if (!in_sdram)
+#if defined(CONFIG_SDRC)
sdrc_init();
+#elif defined(CONFIG_EMIF4)
+ emif4_init();
+#endif
}

/******************************************************************************
@@ -276,19 +280,20 @@ int dram_init(void)
DECLARE_GLOBAL_DATA_PTR;
unsigned int size0 = 0, size1 = 0;

+ size0 = get_sdr_cs_size(CS0);
/*
* If a second bank of DDR is attached to CS1 this is
* where it can be started. Early init code will init
* memory on CS0.
*/
if ((sysinfo.mtype == DDR_COMBO) || (sysinfo.mtype == DDR_STACKED)) {
+#if defined(CONFIG_SDRC)
do_sdrc_init(CS1, NOT_EARLY);
make_cs1_contiguous();
+#endif
+ size1 = get_sdr_cs_size(CS1);
}

- size0 = get_sdr_cs_size(CS0);
- size1 = get_sdr_cs_size(CS1);
-
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = size0;
gd->bd->bi_dram[1].start = PHYS_SDRAM_1 + get_sdr_cs_offset(CS1);
diff --git a/cpu/arm_cortexa8/omap3/mem.c b/cpu/arm_cortexa8/omap3/mem.c
index dfb7e4c..73e0918 100644
--- a/cpu/arm_cortexa8/omap3/mem.c
+++ b/cpu/arm_cortexa8/omap3/mem.c
@@ -79,26 +79,6 @@ static const u32 gpmc_onenand[GPMC_MAX_REG] = {

#endif

-static struct sdrc *sdrc_base = (struct sdrc *)OMAP34XX_SDRC_BASE;
-
-/**************************************************************************
- * make_cs1_contiguous() - for es2 and above remap cs1 behind cs0 to allow
- * command line mem=xyz use all memory with out discontinuous support
- * compiled in. Could do it at the ATAG, but there really is two banks...
- * Called as part of 2nd phase DDR init.
- **************************************************************************/
-void make_cs1_contiguous(void)
-{
- u32 size, a_add_low, a_add_high;
-
- size = get_sdr_cs_size(CS0);
- size >>= 25; /* divide by 32 MiB to find size to offset CS1 */
- a_add_high = (size & 3) << 8; /* set up low field */
- a_add_low = (size & 0x3C) >> 2; /* set up high field */
- writel((a_add_high | a_add_low), &sdrc_base->cs_cfg);
-
-}
-
/********************************************************
* mem_ok() - test used to see if timings are correct
* for a part. Helps in guessing which part
@@ -123,6 +103,27 @@ u32 mem_ok(u32 cs)
return 1;
}

+#if defined(CONFIG_SDRC)
+static struct sdrc *sdrc_base = (struct sdrc *)OMAP34XX_SDRC_BASE;
+
+/**************************************************************************
+ * make_cs1_contiguous() - for es2 and above remap cs1 behind cs0 to allow
+ * command line mem=xyz use all memory with out discontinuous support
+ * compiled in. Could do it at the ATAG, but there really is two banks...
+ * Called as part of 2nd phase DDR init.
+ **************************************************************************/
+void make_cs1_contiguous(void)
+{
+ u32 size, a_add_low, a_add_high;
+
+ size = get_sdr_cs_size(CS0);
+ size >>= 25; /* divide by 32 MiB to find size to offset CS1 */
+ a_add_high = (size & 3) << 8; /* set up low field */
+ a_add_low = (size & 0x3C) >> 2; /* set up high field */
+ writel((a_add_high | a_add_low), &sdrc_base->cs_cfg);
+
+}
+
/********************************************************
* sdrc_init() - init the sdrc chip selects CS0 and CS1
* - early init routines, called from flash or
@@ -192,6 +193,75 @@ void do_sdrc_init(u32 cs, u32 early)
if (!mem_ok(cs))
writel(0, &sdrc_base->cs[cs].mcfg);
}
+#elif defined(CONFIG_EMIF4) /* #if define (CONFIG_SDRC) */
+
+static emif4_t *emif4_base = (emif4_t *)OMAP34XX_SDRC_BASE;
+
+/********************************************************
+ * emif4 _init() - init the emif4 module for DDR access
+ * - early init routines, called from flash or
+ * SRAM.
+ *******************************************************/
+void emif4_init(void)
+{
+ unsigned int regval;
+ /* Set the DDR PHY parameters in PHY ctrl registers */
+ regval = (EMIF4_DDR1_READ_LAT | EMIF4_DDR1_PWRDN_DIS |
+ EMIF4_DDR1_EXT_STRB_DIS);
+ writel(regval, &emif4_base->ddr_phyctrl1);
+ writel(regval, &emif4_base->ddr_phyctrl1_shdw);
+ writel(0, &emif4_base->ddr_phyctrl2);
+
+ /* Reset the DDR PHY and wait till completed */
+ regval = readl(&emif4_base->sdram_iodft_tlgc);
+ regval |= (1<<10);
+ writel(regval, &emif4_base->sdram_iodft_tlgc);
+ /*Wait till that bit clears*/
+ while ((readl(&emif4_base->sdram_iodft_tlgc) & (1<<10)) == 0x1);
+ /*Re-verify the DDR PHY status*/
+ while ((readl(&emif4_base->sdram_sts) & (1<<2)) == 0x0);
+
+ regval |= (1<<0);
+ writel(regval, &emif4_base->sdram_iodft_tlgc);
+ /* Set SDR timing registers */
+ regval = (EMIF4_TIM1_T_WTR | EMIF4_TIM1_T_RRD |
+ EMIF4_TIM1_T_RC | EMIF4_TIM1_T_RAS |
+ EMIF4_TIM1_T_WR | EMIF4_TIM1_T_RCD |
+ EMIF4_TIM1_T_RP);
+ writel(regval, &emif4_base->sdram_time1);
+ writel(regval, &emif4_base->sdram_time1_shdw);
+
+ regval = (EMIF4_TIM2_T_CKE | EMIF4_TIM2_T_RTP |
+ EMIF4_TIM2_T_XSRD | EMIF4_TIM2_T_XSNR |
+ EMIF4_TIM2_T_ODT | EMIF4_TIM2_T_XP);
+ writel(regval, &emif4_base->sdram_time2);
+ writel(regval, &emif4_base->sdram_time2_shdw);
+
+ regval = (EMIF4_TIM3_T_RAS_MAX | EMIF4_TIM3_T_RFC);
+ writel(regval, &emif4_base->sdram_time3);
+ writel(regval, &emif4_base->sdram_time3_shdw);
+
+ /* Set the PWR control register */
+ regval = (EMIF4_PWR_PM_TIM | EMIF4_PWR_LP_MODE |
+ EMIF4_PWR_DPD_DIS | EMIF4_PWR_IDLE_MODE);
+ writel(regval, &emif4_base->sdram_pwr_mgmt);
+ writel(regval, &emif4_base->sdram_pwr_mgmt_shdw);
+
+ /* Set the DDR refresh rate control register */
+ regval = (EMIF4_REFRESH_RATE | EMIF4_INITREF_DIS);
+ writel(regval, &emif4_base->sdram_refresh_ctrl);
+ writel(regval, &emif4_base->sdram_refresh_ctrl_shdw);
+
+ /* set the SDRAM configuration register */
+ regval = (EMIF4_CFG_PGSIZE | EMIF4_CFG_EBANK |
+ EMIF4_CFG_IBANK | EMIF4_CFG_ROWSIZE |
+ EMIF4_CFG_CL | EMIF4_CFG_NARROW_MD |
+ EMIF4_CFG_SDR_DRV | EMIF4_CFG_DDR_DIS_DLL |
+ EMIF4_CFG_DDR2_DDQS | EMIF4_CFG_DDR_TERM |
+ EMIF4_CFG_IBANK_POS | EMIF4_CFG_SDRAM_TYP);
+ writel(regval, &emif4_base->sdram_config);
+}
+#endif /* #if define (CONFIG_SDRC) */

void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
u32 size)
diff --git a/cpu/arm_cortexa8/omap3/sys_info.c b/cpu/arm_cortexa8/omap3/sys_info.c
index 08fb32e..f396898 100644
--- a/cpu/arm_cortexa8/omap3/sys_info.c
+++ b/cpu/arm_cortexa8/omap3/sys_info.c
@@ -109,8 +109,10 @@ u32 get_cpu_rev(void)
****************************************************/
u32 is_mem_sdr(void)
{
+#if defined(CONFIG_SDRC)
if (readl(&sdrc_base->cs[CS0].mr) == SDRC_MR_0_SDR)
return 1;
+#endif
return 0;
}

@@ -121,10 +123,16 @@ u32 get_sdr_cs_size(u32 cs)
{
u32 size;

+#if defined(CONFIG_EMIF4)
+ /* TODO: Calculate the size based on EMIF4 configuration */
+ size = CONFIG_SYS_CS0_SIZE;
+#elif defined(CONFIG_SDRC)
/* get ram size field */
size = readl(&sdrc_base->cs[cs].mcfg) >> 8;
size &= 0x3FF; /* remove unwanted bits */
size <<= 21; /* multiply by 2 MiB to find size in MB */
+#endif
+
return size;
}

@@ -133,13 +141,15 @@ u32 get_sdr_cs_size(u32 cs)
************************************************************************/
u32 get_sdr_cs_offset(u32 cs)
{
- u32 offset;
+ u32 offset = 0;

if (!cs)
return 0;

+#if defined(CONFIG_SDRC)
offset = readl(&sdrc_base->cs_cfg);
offset = (offset & 15) << 27 | (offset & 0x30) >> 17;
+#endif

return offset;
}
diff --git a/include/asm-arm/arch-omap3/cpu.h b/include/asm-arm/arch-omap3/cpu.h
index e51c4f3..f9aacb4 100644
--- a/include/asm-arm/arch-omap3/cpu.h
+++ b/include/asm-arm/arch-omap3/cpu.h
@@ -214,6 +214,32 @@ struct sdrc {
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL_STRICT_NAMES */

+/* EMIF4 */
+#ifndef __ASSEMBLY__
+typedef struct emif4 {
+ unsigned int sdram_sts;
+ unsigned int sdram_config;
+ unsigned int res1;
+ unsigned int sdram_refresh_ctrl;
+ unsigned int sdram_refresh_ctrl_shdw;
+ unsigned int sdram_time1;
+ unsigned int sdram_time1_shdw;
+ unsigned int sdram_time2;
+ unsigned int sdram_time2_shdw;
+ unsigned int sdram_time3;
+ unsigned int sdram_time3_shdw;
+ unsigned char res2[8];
+ unsigned int sdram_pwr_mgmt;
+ unsigned int sdram_pwr_mgmt_shdw;
+ unsigned char res3[32];
+ unsigned int sdram_iodft_tlgc;
+ unsigned char res4[128];
+ unsigned int ddr_phyctrl1;
+ unsigned int ddr_phyctrl1_shdw;
+ unsigned int ddr_phyctrl2;
+} emif4_t;
+#endif /* __ASSEMBLY__ */
+
#define DLLPHASE_90 (0x1 << 1)
#define LOADDLL (0x1 << 2)
#define ENADLL (0x1 << 3)
diff --git a/include/asm-arm/arch-omap3/mem.h b/include/asm-arm/arch-omap3/mem.h
index 7dbfc92..8e7df37 100644
--- a/include/asm-arm/arch-omap3/mem.h
+++ b/include/asm-arm/arch-omap3/mem.h
@@ -39,6 +39,60 @@ enum {

#define EARLY_INIT 1

+/*
+ * EMIF4 -
+ * Configuration values
+ */
+#define EMIF4_TIM1_T_RP (0x3 << 25)
+#define EMIF4_TIM1_T_RCD (0x3 << 21)
+#define EMIF4_TIM1_T_WR (0x3 << 17)
+#define EMIF4_TIM1_T_RAS (0x8 << 12)
+#define EMIF4_TIM1_T_RC (0xA << 6)
+#define EMIF4_TIM1_T_RRD (0x2 << 3)
+#define EMIF4_TIM1_T_WTR (0x2 << 0)
+
+#define EMIF4_TIM2_T_XP (0x2 << 28)
+#define EMIF4_TIM2_T_ODT (0x0 << 25)
+#define EMIF4_TIM2_T_XSNR (0x1C << 16)
+#define EMIF4_TIM2_T_XSRD (0xC8 << 6)
+#define EMIF4_TIM2_T_RTP (0x1 << 3)
+#define EMIF4_TIM2_T_CKE (0x2 << 0)
+
+#define EMIF4_TIM3_T_RFC (0x25 << 4)
+#define EMIF4_TIM3_T_RAS_MAX (0x7 << 0)
+
+#define EMIF4_PWR_IDLE_MODE (0x2 << 30)
+#define EMIF4_PWR_DPD_DIS (0x0 << 10)
+#define EMIF4_PWR_DPD_EN (0x1 << 10)
+#define EMIF4_PWR_LP_MODE (0x0 << 8)
+#define EMIF4_PWR_PM_TIM (0x0 << 0)
+
+#define EMIF4_INITREF_DIS (0x0 << 31)
+#define EMIF4_REFRESH_RATE (0x50F << 0)
+
+#define EMIF4_CFG_SDRAM_TYP (0x2 << 29)
+#define EMIF4_CFG_IBANK_POS (0x0 << 27)
+#define EMIF4_CFG_DDR_TERM (0x0 << 24)
+#define EMIF4_CFG_DDR2_DDQS (0x1 << 23)
+#define EMIF4_CFG_DDR_DIS_DLL (0x0 << 20)
+#define EMIF4_CFG_SDR_DRV (0x0 << 18)
+#define EMIF4_CFG_NARROW_MD (0x0 << 14)
+#define EMIF4_CFG_CL (0x5 << 10)
+#define EMIF4_CFG_ROWSIZE (0x0 << 7)
+#define EMIF4_CFG_IBANK (0x3 << 4)
+#define EMIF4_CFG_EBANK (0x0 << 3)
+#define EMIF4_CFG_PGSIZE (0x2 << 0)
+/*
+ * EMIF4 PHY Control 1 register configuration
+ */
+#define EMIF4_DDR1_READ_LAT (0x6 << 0)
+#define EMIF4_DDR1_PWRDN_DIS (0x0 << 6)
+#define EMIF4_DDR1_PWRDN_EN (0x1 << 6)
+#define EMIF4_DDR1_EXT_STRB_EN (0x1 << 7)
+#define EMIF4_DDR1_EXT_STRB_DIS (0x0 << 7)
+
+#if defined(CONFIG_SDRC)
+
/* Slower full frequency range default timings for x32 operation*/
#define SDRC_SHARING 0x00000100
#define SDRC_MR_0_SDR 0x00000031
@@ -140,7 +194,7 @@ enum {
#if !defined(V_ACTIMA_165) || !defined(V_ACTIMB_165)
#error "Please choose the right DDR type in config header"
#endif
-
+#endif /* #if defined (CONFIG_SDRC) */
/*
* GPMC settings -
* Definitions is as per the following format
@@ -191,7 +245,7 @@ enum {
#define SMNAND_GPMC_CONFIG6 0x1F0F0A80
#define SMNAND_GPMC_CONFIG7 0x00000C44

-#if defined (CONFIG_OMAP3_AM3517EVM)
+#if defined(CONFIG_OMAP3_AM3517EVM)
#define M_NAND_GPMC_CONFIG1 0x00001800
#define M_NAND_GPMC_CONFIG2 0x00080800
#define M_NAND_GPMC_CONFIG3 0x00080800
diff --git a/include/asm-arm/arch-omap3/sys_proto.h b/include/asm-arm/arch-omap3/sys_proto.h
index 34bd515..cfbc84b 100644
--- a/include/asm-arm/arch-omap3/sys_proto.h
+++ b/include/asm-arm/arch-omap3/sys_proto.h
@@ -31,8 +31,12 @@ void prcm_init(void);
void per_clocks_enable(void);

void memif_init(void);
+#if defined(CONFIG_SDRC)
void sdrc_init(void);
void do_sdrc_init(u32, u32);
+#elif defined(CONFIG_EMIF4)
+void emif4_init(void);
+#endif
void gpmc_init(void);
void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
u32 size);
diff --git a/include/configs/am3517_evm.h b/include/configs/am3517_evm.h
index d7eef73..74e52c1 100644
--- a/include/configs/am3517_evm.h
+++ b/include/configs/am3517_evm.h
@@ -62,6 +62,12 @@
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (128 << 10))
#define CONFIG_SYS_GBL_DATA_SIZE 128 /* bytes reserved for */
/* initial data */
+
+/*
+ * Support for EMIF4
+ */
+#define CONFIG_EMIF4 1
+
/*
* DDR size interfaced
*/
diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h
index 1011770..8041416 100644
--- a/include/configs/devkit8000.h
+++ b/include/configs/devkit8000.h
@@ -66,6 +66,10 @@

/* Hardware drivers */

+/*
+ * Support for SDRC
+ */
+#define CONFIG_SDRC 1
/* DDR - I use Micron DDR */
#define CONFIG_OMAP3_MICRON_DDR 1

diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h
index 024b9b8..7fb3434 100644
--- a/include/configs/omap3_beagle.h
+++ b/include/configs/omap3_beagle.h
@@ -97,6 +97,10 @@
#define CONFIG_OMAP3_MMC 1
#define CONFIG_DOS_PARTITION 1

+/*
+ * Support for SDRC
+ */
+#define CONFIG_SDRC 1
/* DDR - I use Micron DDR */
#define CONFIG_OMAP3_MICRON_DDR 1

diff --git a/include/configs/omap3_evm.h b/include/configs/omap3_evm.h
index 36cb5e0..68e0569 100644
--- a/include/configs/omap3_evm.h
+++ b/include/configs/omap3_evm.h
@@ -101,6 +101,10 @@
#define CONFIG_OMAP3_MMC 1
#define CONFIG_DOS_PARTITION 1

+/*
+ * Support for SDRC
+ */
+#define CONFIG_SDRC 1
/* DDR - I use Micron DDR */
#define CONFIG_OMAP3_MICRON_DDR 1

diff --git a/include/configs/omap3_overo.h b/include/configs/omap3_overo.h
index 0f812a7..7ae4f0c 100644
--- a/include/configs/omap3_overo.h
+++ b/include/configs/omap3_overo.h
@@ -89,6 +89,10 @@
#define CONFIG_OMAP3_MMC 1
#define CONFIG_DOS_PARTITION 1

+/*
+ * Support for SDRC
+ */
+#define CONFIG_SDRC 1
/* DDR - I use Micron DDR */
#define CONFIG_OMAP3_MICRON_DDR 1

diff --git a/include/configs/omap3_pandora.h b/include/configs/omap3_pandora.h
index 0cafeb8..45c38bf 100644
--- a/include/configs/omap3_pandora.h
+++ b/include/configs/omap3_pandora.h
@@ -92,6 +92,10 @@
#define CONFIG_OMAP3_MMC 1
#define CONFIG_DOS_PARTITION 1

+/*
+ * Support for SDRC
+ */
+#define CONFIG_SDRC 1
/* DDR - I use Micron DDR */
#define CONFIG_OMAP3_MICRON_DDR 1

diff --git a/include/configs/omap3_sdp3430.h b/include/configs/omap3_sdp3430.h
index d91c8ff..a8deab5 100644
--- a/include/configs/omap3_sdp3430.h
+++ b/include/configs/omap3_sdp3430.h
@@ -137,6 +137,10 @@
#define CONFIG_SYS_I2C_BUS_SELECT 1
#define CONFIG_DRIVER_OMAP34XX_I2C 1

+/*
+ * Support for SDRC
+ */
+#define CONFIG_SDRC 1
/* DDR - I use Infineon DDR */
#define CONFIG_OMAP3_INFINEON_DDR 1

diff --git a/include/configs/omap3_zoom1.h b/include/configs/omap3_zoom1.h
index 2aef973..17cb3fb 100644
--- a/include/configs/omap3_zoom1.h
+++ b/include/configs/omap3_zoom1.h
@@ -98,6 +98,10 @@
#define CONFIG_OMAP3_MMC 1
#define CONFIG_DOS_PARTITION 1

+/*
+ * Support for SDRC
+ */
+#define CONFIG_SDRC 1
/* DDR - I use Micron DDR */
#define CONFIG_OMAP3_MICRON_DDR 1

diff --git a/include/configs/omap3_zoom2.h b/include/configs/omap3_zoom2.h
index 5b03fb6..cf09832 100644
--- a/include/configs/omap3_zoom2.h
+++ b/include/configs/omap3_zoom2.h
@@ -98,6 +98,10 @@
#define CONFIG_OMAP3_MMC 1
#define CONFIG_DOS_PARTITION 1

+/*
+ * Support for SDRC
+ */
+#define CONFIG_SDRC 1
/* DDR - I use Micron DDR */
#define CONFIG_OMAP3_MICRON_DDR 1

--
1.6.2.4