diff options
author | Sricharan <r.sricharan@ti.com> | 2011-11-15 09:50:00 -0500 |
---|---|---|
committer | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2011-11-15 22:25:50 +0100 |
commit | bb772a594493092adfb18a56889e0bce855eed99 (patch) | |
tree | 603065b8d5e7a79bf8bac988b566dbf076141154 /arch/arm/cpu | |
parent | 2e5ba489284a28990530a5c0e86a4c361e88dbe5 (diff) | |
download | u-boot-imx-bb772a594493092adfb18a56889e0bce855eed99.zip u-boot-imx-bb772a594493092adfb18a56889e0bce855eed99.tar.gz u-boot-imx-bb772a594493092adfb18a56889e0bce855eed99.tar.bz2 |
omap5: emif: Add emif/ddr configurations required for omap5 evm
Add the emif configurations required for omap5 soc.Add the
correct ddr part configurations required for omap5 evm board.
EDB8164B3PH from ELPIDA is the part used on the board.
Also changes are done to retain some part of the code
common for OMAP4/5 and keep only the remaining in the Soc
specific directories.
Signed-off-by: sricharan <r.sricharan@ti.com>
Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com>
Diffstat (limited to 'arch/arm/cpu')
-rw-r--r-- | arch/arm/cpu/armv7/omap-common/emif-common.c | 290 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap-common/hwinit-common.c | 20 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap4/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap4/emif.c | 129 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap4/hwinit.c | 2 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap4/sdram_elpida.c | 2 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap5/emif.c | 105 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap5/sdram_elpida.c | 178 |
8 files changed, 514 insertions, 213 deletions
diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c index 9d82c7c..ce03b5c 100644 --- a/arch/arm/cpu/armv7/omap-common/emif-common.c +++ b/arch/arm/cpu/armv7/omap-common/emif-common.c @@ -26,28 +26,29 @@ */ #include <common.h> -#include <asm/arch/emif.h> +#include <asm/emif.h> #include <asm/arch/clocks.h> #include <asm/arch/sys_proto.h> #include <asm/omap_common.h> #include <asm/utils.h> -static inline u32 emif_num(u32 base) +inline u32 emif_num(u32 base) { - if (base == OMAP44XX_EMIF1) + if (base == EMIF1_BASE) return 1; - else if (base == OMAP44XX_EMIF2) + else if (base == EMIF2_BASE) return 2; else return 0; } + static inline u32 get_mr(u32 base, u32 cs, u32 mr_addr) { u32 mr; struct emif_reg_struct *emif = (struct emif_reg_struct *)base; - mr_addr |= cs << OMAP44XX_REG_CS_SHIFT; + mr_addr |= cs << EMIF_REG_CS_SHIFT; writel(mr_addr, &emif->emif_lpddr2_mode_reg_cfg); if (omap_revision() == OMAP4430_ES2_0) mr = readl(&emif->emif_lpddr2_mode_reg_data_es2); @@ -62,7 +63,7 @@ static inline void set_mr(u32 base, u32 cs, u32 mr_addr, u32 mr_val) { struct emif_reg_struct *emif = (struct emif_reg_struct *)base; - mr_addr |= cs << OMAP44XX_REG_CS_SHIFT; + mr_addr |= cs << EMIF_REG_CS_SHIFT; writel(mr_addr, &emif->emif_lpddr2_mode_reg_cfg); writel(mr_val, &emif->emif_lpddr2_mode_reg_data); } @@ -73,7 +74,7 @@ void emif_reset_phy(u32 base) u32 iodft; iodft = readl(&emif->emif_iodft_tlgc); - iodft |= OMAP44XX_REG_RESET_PHY_MASK; + iodft |= EMIF_REG_RESET_PHY_MASK; writel(iodft, &emif->emif_iodft_tlgc); } @@ -96,7 +97,7 @@ static void do_lpddr2_init(u32 base, u32 cs) * Enable refresh along with writing MR2 * Encoding of RL in MR2 is (RL - 2) */ - mr_addr = LPDDR2_MR2 | OMAP44XX_REG_REFRESH_EN_MASK; + mr_addr = LPDDR2_MR2 | EMIF_REG_REFRESH_EN_MASK; set_mr(base, cs, mr_addr, RL_FINAL - 2); } @@ -105,13 +106,13 @@ static void lpddr2_init(u32 base, const struct emif_regs *regs) struct emif_reg_struct *emif = (struct emif_reg_struct *)base; /* Not NVM */ - clrbits_le32(&emif->emif_lpddr2_nvm_config, OMAP44XX_REG_CS1NVMEN_MASK); + clrbits_le32(&emif->emif_lpddr2_nvm_config, EMIF_REG_CS1NVMEN_MASK); /* * Keep REG_INITREF_DIS = 1 to prevent re-initialization of SDRAM * when EMIF_SDRAM_CONFIG register is written */ - setbits_le32(&emif->emif_sdram_ref_ctrl, OMAP44XX_REG_INITREF_DIS_MASK); + setbits_le32(&emif->emif_sdram_ref_ctrl, EMIF_REG_INITREF_DIS_MASK); /* * Set the SDRAM_CONFIG and PHY_CTRL for the @@ -121,18 +122,18 @@ static void lpddr2_init(u32 base, const struct emif_regs *regs) writel(regs->emif_ddr_phy_ctlr_1_init, &emif->emif_ddr_phy_ctrl_1); do_lpddr2_init(base, CS0); - if (regs->sdram_config & OMAP44XX_REG_EBANK_MASK) + if (regs->sdram_config & EMIF_REG_EBANK_MASK) do_lpddr2_init(base, CS1); writel(regs->sdram_config, &emif->emif_sdram_config); writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1); /* Enable refresh now */ - clrbits_le32(&emif->emif_sdram_ref_ctrl, OMAP44XX_REG_INITREF_DIS_MASK); + clrbits_le32(&emif->emif_sdram_ref_ctrl, EMIF_REG_INITREF_DIS_MASK); } -static void emif_update_timings(u32 base, const struct emif_regs *regs) +void emif_update_timings(u32 base, const struct emif_regs *regs) { struct emif_reg_struct *emif = (struct emif_reg_struct *)base; @@ -152,7 +153,10 @@ static void emif_update_timings(u32 base, const struct emif_regs *regs) writel(regs->temp_alert_config, &emif->emif_temp_alert_config); writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1_shdw); - if (omap_revision() >= OMAP4460_ES1_0) { + if (omap_revision() == OMAP5430_ES1_0) { + writel(EMIF_L3_CONFIG_VAL_SYS_10_MPU_5_LL_0, + &emif->emif_l3_config); + } else if (omap_revision() >= OMAP4460_ES1_0) { writel(EMIF_L3_CONFIG_VAL_SYS_10_MPU_3_LL_0, &emif->emif_l3_config); } else { @@ -164,10 +168,6 @@ static void emif_update_timings(u32 base, const struct emif_regs *regs) #ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS #define print_timing_reg(reg) debug(#reg" - 0x%08x\n", (reg)) -static u32 *const T_num = (u32 *)OMAP4_SRAM_SCRATCH_EMIF_T_NUM; -static u32 *const T_den = (u32 *)OMAP4_SRAM_SCRATCH_EMIF_T_DEN; -static u32 *const emif_sizes = (u32 *)OMAP4_SRAM_SCRATCH_EMIF_SIZE; - /* * Organization and refresh requirements for LPDDR2 devices of different * types and densities. Derived from JESD209-2 section 2.4 @@ -311,24 +311,24 @@ static u32 get_sdram_config_reg(const struct lpddr2_device_details *cs0_device, { u32 config_reg = 0; - config_reg |= (cs0_device->type + 4) << OMAP44XX_REG_SDRAM_TYPE_SHIFT; + config_reg |= (cs0_device->type + 4) << EMIF_REG_SDRAM_TYPE_SHIFT; config_reg |= EMIF_INTERLEAVING_POLICY_MAX_INTERLEAVING << - OMAP44XX_REG_IBANK_POS_SHIFT; + EMIF_REG_IBANK_POS_SHIFT; - config_reg |= cs0_device->io_width << OMAP44XX_REG_NARROW_MODE_SHIFT; + config_reg |= cs0_device->io_width << EMIF_REG_NARROW_MODE_SHIFT; - config_reg |= RL << OMAP44XX_REG_CL_SHIFT; + config_reg |= RL << EMIF_REG_CL_SHIFT; config_reg |= addressing->row_sz[cs0_device->io_width] << - OMAP44XX_REG_ROWSIZE_SHIFT; + EMIF_REG_ROWSIZE_SHIFT; - config_reg |= addressing->num_banks << OMAP44XX_REG_IBANK_SHIFT; + config_reg |= addressing->num_banks << EMIF_REG_IBANK_SHIFT; config_reg |= (cs1_device ? EBANK_CS1_EN : EBANK_CS1_DIS) << - OMAP44XX_REG_EBANK_SHIFT; + EMIF_REG_EBANK_SHIFT; config_reg |= addressing->col_sz[cs0_device->io_width] << - OMAP44XX_REG_PAGESIZE_SHIFT; + EMIF_REG_PAGESIZE_SHIFT; return config_reg; } @@ -343,7 +343,7 @@ static u32 get_sdram_ref_ctrl(u32 freq, * division by 10000 to account for khz and x10 in t_REFI_us_x10 */ val = addressing->t_REFI_us_x10 * freq_khz / 10000; - ref_ctrl |= val << OMAP44XX_REG_REFRESH_RATE_SHIFT; + ref_ctrl |= val << EMIF_REG_REFRESH_RATE_SHIFT; return ref_ctrl; } @@ -354,7 +354,7 @@ static u32 get_sdram_tim_1_reg(const struct lpddr2_ac_timings *timings, { u32 tim1 = 0, val = 0; val = max(min_tck->tWTR, ns_x2_2_cycles(timings->tWTRx2)) - 1; - tim1 |= val << OMAP44XX_REG_T_WTR_SHIFT; + tim1 |= val << EMIF_REG_T_WTR_SHIFT; if (addressing->num_banks == BANKS8) val = (timings->tFAW * (*T_den) + 4 * (*T_num) - 1) / @@ -362,22 +362,22 @@ static u32 get_sdram_tim_1_reg(const struct lpddr2_ac_timings *timings, else val = max(min_tck->tRRD, ns_2_cycles(timings->tRRD)) - 1; - tim1 |= val << OMAP44XX_REG_T_RRD_SHIFT; + tim1 |= val << EMIF_REG_T_RRD_SHIFT; val = ns_2_cycles(timings->tRASmin + timings->tRPab) - 1; - tim1 |= val << OMAP44XX_REG_T_RC_SHIFT; + tim1 |= val << EMIF_REG_T_RC_SHIFT; val = max(min_tck->tRAS_MIN, ns_2_cycles(timings->tRASmin)) - 1; - tim1 |= val << OMAP44XX_REG_T_RAS_SHIFT; + tim1 |= val << EMIF_REG_T_RAS_SHIFT; val = max(min_tck->tWR, ns_2_cycles(timings->tWR)) - 1; - tim1 |= val << OMAP44XX_REG_T_WR_SHIFT; + tim1 |= val << EMIF_REG_T_WR_SHIFT; val = max(min_tck->tRCD, ns_2_cycles(timings->tRCD)) - 1; - tim1 |= val << OMAP44XX_REG_T_RCD_SHIFT; + tim1 |= val << EMIF_REG_T_RCD_SHIFT; val = max(min_tck->tRP_AB, ns_2_cycles(timings->tRPab)) - 1; - tim1 |= val << OMAP44XX_REG_T_RP_SHIFT; + tim1 |= val << EMIF_REG_T_RP_SHIFT; return tim1; } @@ -387,21 +387,21 @@ static u32 get_sdram_tim_2_reg(const struct lpddr2_ac_timings *timings, { u32 tim2 = 0, val = 0; val = max(min_tck->tCKE, timings->tCKE) - 1; - tim2 |= val << OMAP44XX_REG_T_CKE_SHIFT; + tim2 |= val << EMIF_REG_T_CKE_SHIFT; val = max(min_tck->tRTP, ns_x2_2_cycles(timings->tRTPx2)) - 1; - tim2 |= val << OMAP44XX_REG_T_RTP_SHIFT; + tim2 |= val << EMIF_REG_T_RTP_SHIFT; /* * tXSRD = tRFCab + 10 ns. XSRD and XSNR should have the * same value */ val = ns_2_cycles(timings->tXSR) - 1; - tim2 |= val << OMAP44XX_REG_T_XSRD_SHIFT; - tim2 |= val << OMAP44XX_REG_T_XSNR_SHIFT; + tim2 |= val << EMIF_REG_T_XSRD_SHIFT; + tim2 |= val << EMIF_REG_T_XSNR_SHIFT; val = max(min_tck->tXP, ns_x2_2_cycles(timings->tXPx2)) - 1; - tim2 |= val << OMAP44XX_REG_T_XP_SHIFT; + tim2 |= val << EMIF_REG_T_XP_SHIFT; return tim2; } @@ -412,19 +412,19 @@ static u32 get_sdram_tim_3_reg(const struct lpddr2_ac_timings *timings, { u32 tim3 = 0, val = 0; val = min(timings->tRASmax * 10 / addressing->t_REFI_us_x10 - 1, 0xF); - tim3 |= val << OMAP44XX_REG_T_RAS_MAX_SHIFT; + tim3 |= val << EMIF_REG_T_RAS_MAX_SHIFT; val = ns_2_cycles(timings->tRFCab) - 1; - tim3 |= val << OMAP44XX_REG_T_RFC_SHIFT; + tim3 |= val << EMIF_REG_T_RFC_SHIFT; val = ns_x2_2_cycles(timings->tDQSCKMAXx2) - 1; - tim3 |= val << OMAP44XX_REG_T_TDQSCKMAX_SHIFT; + tim3 |= val << EMIF_REG_T_TDQSCKMAX_SHIFT; val = ns_2_cycles(timings->tZQCS) - 1; - tim3 |= val << OMAP44XX_REG_ZQ_ZQCS_SHIFT; + tim3 |= val << EMIF_REG_ZQ_ZQCS_SHIFT; val = max(min_tck->tCKESR, ns_2_cycles(timings->tCKESR)) - 1; - tim3 |= val << OMAP44XX_REG_T_CKESR_SHIFT; + tim3 |= val << EMIF_REG_T_CKESR_SHIFT; return tim3; } @@ -442,13 +442,13 @@ static u32 get_zq_config_reg(const struct lpddr2_device_details *cs1_device, val = EMIF_ZQCS_INTERVAL_NORMAL_IN_US * 10 / addressing->t_REFI_us_x10; - zq |= val << OMAP44XX_REG_ZQ_REFINTERVAL_SHIFT; + zq |= val << EMIF_REG_ZQ_REFINTERVAL_SHIFT; - zq |= (REG_ZQ_ZQCL_MULT - 1) << OMAP44XX_REG_ZQ_ZQCL_MULT_SHIFT; + zq |= (REG_ZQ_ZQCL_MULT - 1) << EMIF_REG_ZQ_ZQCL_MULT_SHIFT; - zq |= (REG_ZQ_ZQINIT_MULT - 1) << OMAP44XX_REG_ZQ_ZQINIT_MULT_SHIFT; + zq |= (REG_ZQ_ZQINIT_MULT - 1) << EMIF_REG_ZQ_ZQINIT_MULT_SHIFT; - zq |= REG_ZQ_SFEXITEN_ENABLE << OMAP44XX_REG_ZQ_SFEXITEN_SHIFT; + zq |= REG_ZQ_SFEXITEN_ENABLE << EMIF_REG_ZQ_SFEXITEN_SHIFT; /* * Assuming that two chipselects have a single calibration resistor @@ -458,11 +458,11 @@ static u32 get_zq_config_reg(const struct lpddr2_device_details *cs1_device, * that none of the boards today have calibration resistors per CS, * it would be an unnecessary overhead. */ - zq |= REG_ZQ_DUALCALEN_DISABLE << OMAP44XX_REG_ZQ_DUALCALEN_SHIFT; + zq |= REG_ZQ_DUALCALEN_DISABLE << EMIF_REG_ZQ_DUALCALEN_SHIFT; - zq |= REG_ZQ_CS0EN_ENABLE << OMAP44XX_REG_ZQ_CS0EN_SHIFT; + zq |= REG_ZQ_CS0EN_ENABLE << EMIF_REG_ZQ_CS0EN_SHIFT; - zq |= (cs1_device ? 1 : 0) << OMAP44XX_REG_ZQ_CS1EN_SHIFT; + zq |= (cs1_device ? 1 : 0) << EMIF_REG_ZQ_CS1EN_SHIFT; return zq; } @@ -476,17 +476,17 @@ static u32 get_temp_alert_config(const struct lpddr2_device_details *cs1_device, TEMP_ALERT_POLL_INTERVAL_MS * 10000 / addressing->t_REFI_us_x10; if (is_derated) interval *= 4; - alert |= interval << OMAP44XX_REG_TA_REFINTERVAL_SHIFT; + alert |= interval << EMIF_REG_TA_REFINTERVAL_SHIFT; - alert |= TEMP_ALERT_CONFIG_DEVCT_1 << OMAP44XX_REG_TA_DEVCNT_SHIFT; + alert |= TEMP_ALERT_CONFIG_DEVCT_1 << EMIF_REG_TA_DEVCNT_SHIFT; - alert |= TEMP_ALERT_CONFIG_DEVWDT_32 << OMAP44XX_REG_TA_DEVWDT_SHIFT; + alert |= TEMP_ALERT_CONFIG_DEVWDT_32 << EMIF_REG_TA_DEVWDT_SHIFT; - alert |= 1 << OMAP44XX_REG_TA_SFEXITEN_SHIFT; + alert |= 1 << EMIF_REG_TA_SFEXITEN_SHIFT; - alert |= 1 << OMAP44XX_REG_TA_CS0EN_SHIFT; + alert |= 1 << EMIF_REG_TA_CS0EN_SHIFT; - alert |= (cs1_device ? 1 : 0) << OMAP44XX_REG_TA_CS1EN_SHIFT; + alert |= (cs1_device ? 1 : 0) << EMIF_REG_TA_CS1EN_SHIFT; return alert; } @@ -499,9 +499,9 @@ static u32 get_read_idle_ctrl_reg(u8 volt_ramp) else /*Maximum value in normal conditions - suggested by hw team */ val = 0x1FF; - idle |= val << OMAP44XX_REG_READ_IDLE_INTERVAL_SHIFT; + idle |= val << EMIF_REG_READ_IDLE_INTERVAL_SHIFT; - idle |= EMIF_REG_READ_IDLE_LEN_VAL << OMAP44XX_REG_READ_IDLE_LEN_SHIFT; + idle |= EMIF_REG_READ_IDLE_LEN_VAL << EMIF_REG_READ_IDLE_LEN_SHIFT; return idle; } @@ -510,7 +510,7 @@ static u32 get_ddr_phy_ctrl_1(u32 freq, u8 RL) { u32 phy = 0, val = 0; - phy |= (RL + 2) << OMAP44XX_REG_READ_LATENCY_SHIFT; + phy |= (RL + 2) << EMIF_REG_READ_LATENCY_SHIFT; if (freq <= 100000000) val = EMIF_DLL_SLAVE_DLY_CTRL_100_MHZ_AND_LESS; @@ -518,11 +518,11 @@ static u32 get_ddr_phy_ctrl_1(u32 freq, u8 RL) val = EMIF_DLL_SLAVE_DLY_CTRL_200_MHZ; else val = EMIF_DLL_SLAVE_DLY_CTRL_400_MHZ; - phy |= val << OMAP44XX_REG_DLL_SLAVE_DLY_CTRL_SHIFT; + phy |= val << EMIF_REG_DLL_SLAVE_DLY_CTRL_SHIFT; /* Other fields are constant magic values. Hardcode them together */ phy |= EMIF_DDR_PHY_CTRL_1_BASE_VAL << - OMAP44XX_EMIF_DDR_PHY_CTRL_1_BASE_VAL_SHIFT; + EMIF_EMIF_DDR_PHY_CTRL_1_BASE_VAL_SHIFT; return phy; } @@ -666,123 +666,6 @@ static void emif_calculate_regs( } #endif /* CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS */ -#ifdef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS -/* Base AC Timing values specified by JESD209-2 for 400MHz operation */ -static const struct lpddr2_ac_timings timings_jedec_400_mhz = { - .max_freq = 400000000, - .RL = 6, - .tRPab = 21, - .tRCD = 18, - .tWR = 15, - .tRASmin = 42, - .tRRD = 10, - .tWTRx2 = 15, - .tXSR = 140, - .tXPx2 = 15, - .tRFCab = 130, - .tRTPx2 = 15, - .tCKE = 3, - .tCKESR = 15, - .tZQCS = 90, - .tZQCL = 360, - .tZQINIT = 1000, - .tDQSCKMAXx2 = 11, - .tRASmax = 70, - .tFAW = 50 -}; - -/* Base AC Timing values specified by JESD209-2 for 333 MHz operation */ -static const struct lpddr2_ac_timings timings_jedec_333_mhz = { - .max_freq = 333000000, - .RL = 5, - .tRPab = 21, - .tRCD = 18, - .tWR = 15, - .tRASmin = 42, - .tRRD = 10, - .tWTRx2 = 15, - .tXSR = 140, - .tXPx2 = 15, - .tRFCab = 130, - .tRTPx2 = 15, - .tCKE = 3, - .tCKESR = 15, - .tZQCS = 90, - .tZQCL = 360, - .tZQINIT = 1000, - .tDQSCKMAXx2 = 11, - .tRASmax = 70, - .tFAW = 50 -}; - -/* Base AC Timing values specified by JESD209-2 for 200 MHz operation */ -static const struct lpddr2_ac_timings timings_jedec_200_mhz = { - .max_freq = 200000000, - .RL = 3, - .tRPab = 21, - .tRCD = 18, - .tWR = 15, - .tRASmin = 42, - .tRRD = 10, - .tWTRx2 = 20, - .tXSR = 140, - .tXPx2 = 15, - .tRFCab = 130, - .tRTPx2 = 15, - .tCKE = 3, - .tCKESR = 15, - .tZQCS = 90, - .tZQCL = 360, - .tZQINIT = 1000, - .tDQSCKMAXx2 = 11, - .tRASmax = 70, - .tFAW = 50 -}; - -/* - * Min tCK values specified by JESD209-2 - * Min tCK specifies the minimum duration of some AC timing parameters in terms - * of the number of cycles. If the calculated number of cycles based on the - * absolute time value is less than the min tCK value, min tCK value should - * be used instead. This typically happens at low frequencies. - */ -static const struct lpddr2_min_tck min_tck_jedec = { - .tRL = 3, - .tRP_AB = 3, - .tRCD = 3, - .tWR = 3, - .tRAS_MIN = 3, - .tRRD = 2, - .tWTR = 2, - .tXP = 2, - .tRTP = 2, - .tCKE = 3, - .tCKESR = 3, - .tFAW = 8 -}; - -static const struct lpddr2_ac_timings const* - jedec_ac_timings[MAX_NUM_SPEEDBINS] = { - &timings_jedec_200_mhz, - &timings_jedec_333_mhz, - &timings_jedec_400_mhz -}; - -static const struct lpddr2_device_timings jedec_default_timings = { - .ac_timings = jedec_ac_timings, - .min_tck = &min_tck_jedec -}; - -void emif_get_device_timings(u32 emif_nr, - const struct lpddr2_device_timings **cs0_device_timings, - const struct lpddr2_device_timings **cs1_device_timings) -{ - /* Assume Identical devices on EMIF1 & EMIF2 */ - *cs0_device_timings = &jedec_default_timings; - *cs1_device_timings = &jedec_default_timings; -} -#endif /* CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS */ - #ifdef CONFIG_SYS_AUTOMATIC_SDRAM_DETECTION const char *get_lpddr2_type(u8 type_id) { @@ -967,7 +850,8 @@ struct lpddr2_device_details *emif_get_device_details(u32 emif_nr, u8 cs, struct lpddr2_device_details *lpddr2_dev_details) { u32 phy; - u32 base = (emif_nr == 1) ? OMAP44XX_EMIF1 : OMAP44XX_EMIF2; + u32 base = (emif_nr == 1) ? EMIF1_BASE : EMIF2_BASE; + struct emif_reg_struct *emif = (struct emif_reg_struct *)base; if (!lpddr2_dev_details) @@ -996,7 +880,7 @@ static void do_sdram_init(u32 base) debug(">>do_sdram_init() %x\n", base); in_sdram = running_from_sdram(); - emif_nr = (base == OMAP44XX_EMIF1) ? 1 : 2; + emif_nr = (base == EMIF1_BASE) ? 1 : 2; #ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS emif_get_reg_dump(emif_nr, ®s); @@ -1063,21 +947,24 @@ static void do_sdram_init(u32 base) debug("<<do_sdram_init() %x\n", base); } -static void emif_post_init_config(u32 base) +void emif_post_init_config(u32 base) { struct emif_reg_struct *emif = (struct emif_reg_struct *)base; - u32 omap4_rev = omap_revision(); + u32 omap_rev = omap_revision(); + + if (omap_rev == OMAP5430_ES1_0) + return; /* reset phy on ES2.0 */ - if (omap4_rev == OMAP4430_ES2_0) + if (omap_rev == OMAP4430_ES2_0) emif_reset_phy(base); /* Put EMIF back in smart idle on ES1.0 */ - if (omap4_rev == OMAP4430_ES1_0) + if (omap_rev == OMAP4430_ES1_0) writel(0x80000000, &emif->emif_pwr_mgmt_ctrl); } -static void dmm_init(u32 base) +void dmm_init(u32 base) { const struct dmm_lisa_map_regs *lisa_map_regs; @@ -1102,12 +989,12 @@ static void dmm_init(u32 base) if (emif1_size && emif2_size) { mapped_size = min(emif1_size, emif2_size); section_map = DMM_LISA_MAP_INTERLEAVED_BASE_VAL; - section_map |= 0 << OMAP44XX_SDRC_ADDR_SHIFT; + section_map |= 0 << EMIF_SDRC_ADDR_SHIFT; /* only MSB */ section_map |= (sys_addr >> 24) << - OMAP44XX_SYS_ADDR_SHIFT; + EMIF_SYS_ADDR_SHIFT; section_map |= get_dmm_section_size_map(mapped_size * 2) - << OMAP44XX_SYS_SIZE_SHIFT; + << EMIF_SYS_SIZE_SHIFT; lis_map_regs_calculated.dmm_lisa_map_3 = section_map; emif1_size -= mapped_size; emif2_size -= mapped_size; @@ -1122,22 +1009,22 @@ static void dmm_init(u32 base) if (emif1_size) { section_map = DMM_LISA_MAP_EMIF1_ONLY_BASE_VAL; section_map |= get_dmm_section_size_map(emif1_size) - << OMAP44XX_SYS_SIZE_SHIFT; + << EMIF_SYS_SIZE_SHIFT; /* only MSB */ section_map |= (mapped_size >> 24) << - OMAP44XX_SDRC_ADDR_SHIFT; + EMIF_SDRC_ADDR_SHIFT; /* only MSB */ - section_map |= (sys_addr >> 24) << OMAP44XX_SYS_ADDR_SHIFT; + section_map |= (sys_addr >> 24) << EMIF_SYS_ADDR_SHIFT; section_cnt--; } if (emif2_size) { section_map = DMM_LISA_MAP_EMIF2_ONLY_BASE_VAL; section_map |= get_dmm_section_size_map(emif2_size) << - OMAP44XX_SYS_SIZE_SHIFT; + EMIF_SYS_SIZE_SHIFT; /* only MSB */ - section_map |= mapped_size >> 24 << OMAP44XX_SDRC_ADDR_SHIFT; + section_map |= mapped_size >> 24 << EMIF_SDRC_ADDR_SHIFT; /* only MSB */ - section_map |= sys_addr >> 24 << OMAP44XX_SYS_ADDR_SHIFT; + section_map |= sys_addr >> 24 << EMIF_SYS_ADDR_SHIFT; section_cnt--; } @@ -1176,7 +1063,7 @@ static void dmm_init(u32 base) if (omap_revision() >= OMAP4460_ES1_0) { hw_lisa_map_regs = - (struct dmm_lisa_map_regs *)OMAP44XX_MA_LISA_MAP_BASE; + (struct dmm_lisa_map_regs *)MA_BASE; writel(lisa_map_regs->dmm_lisa_map_3, &hw_lisa_map_regs->dmm_lisa_map_3); @@ -1222,14 +1109,13 @@ void sdram_init(void) bypass_dpll(&prcm->cm_clkmode_dpll_core); - do_sdram_init(OMAP44XX_EMIF1); - do_sdram_init(OMAP44XX_EMIF2); + do_sdram_init(EMIF1_BASE); + do_sdram_init(EMIF2_BASE); if (!in_sdram) { - dmm_init(OMAP44XX_DMM_LISA_MAP_BASE); - emif_post_init_config(OMAP44XX_EMIF1); - emif_post_init_config(OMAP44XX_EMIF2); - + dmm_init(DMM_BASE); + emif_post_init_config(EMIF1_BASE); + emif_post_init_config(EMIF2_BASE); } /* for the shadow registers to take effect */ diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c index 2ab16bf..5cf4e2b 100644 --- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c +++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c @@ -30,7 +30,7 @@ #include <common.h> #include <asm/arch/sys_proto.h> #include <asm/sizes.h> -#include <asm/arch/emif.h> +#include <asm/emif.h> DECLARE_GLOBAL_DATA_PTR; @@ -169,19 +169,21 @@ void watchdog_init(void) u32 omap_sdram_size(void) { u32 section, i, total_size = 0, size, addr; + for (i = 0; i < 4; i++) { - section = __raw_readl(OMAP44XX_DMM_LISA_MAP_BASE + i*4); - addr = section & OMAP44XX_SYS_ADDR_MASK; + section = __raw_readl(DMM_BASE + i*4); + addr = section & EMIF_SYS_ADDR_MASK; /* See if the address is valid */ - if ((addr >= OMAP44XX_DRAM_ADDR_SPACE_START) && - (addr < OMAP44XX_DRAM_ADDR_SPACE_END)) { - size = ((section & OMAP44XX_SYS_SIZE_MASK) >> - OMAP44XX_SYS_SIZE_SHIFT); - size = 1 << size; - size *= SZ_16M; + if ((addr >= DRAM_ADDR_SPACE_START) && + (addr < DRAM_ADDR_SPACE_END)) { + size = ((section & EMIF_SYS_SIZE_MASK) >> + EMIF_SYS_SIZE_SHIFT); + size = 1 << size; + size *= SZ_16M; total_size += size; } } + return total_size; } diff --git a/arch/arm/cpu/armv7/omap4/Makefile b/arch/arm/cpu/armv7/omap4/Makefile index c7bfa27..83160a2 100644 --- a/arch/arm/cpu/armv7/omap4/Makefile +++ b/arch/arm/cpu/armv7/omap4/Makefile @@ -28,6 +28,7 @@ LIB = $(obj)lib$(SOC).o COBJS += sdram_elpida.o COBJS += hwinit.o COBJS += clocks.o +COBJS += emif.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) diff --git a/arch/arm/cpu/armv7/omap4/emif.c b/arch/arm/cpu/armv7/omap4/emif.c new file mode 100644 index 0000000..ca4823d --- /dev/null +++ b/arch/arm/cpu/armv7/omap4/emif.c @@ -0,0 +1,129 @@ +/* + * EMIF programming + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Aneesh V <aneesh@ti.com> + * + * 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 <common.h> +#include <asm/emif.h> +#include <asm/arch/sys_proto.h> +#include <asm/utils.h> + +#ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS +u32 *const T_num = (u32 *)OMAP4_SRAM_SCRATCH_EMIF_T_NUM; +u32 *const T_den = (u32 *)OMAP4_SRAM_SCRATCH_EMIF_T_DEN; +u32 *const emif_sizes = (u32 *)OMAP4_SRAM_SCRATCH_EMIF_SIZE; +#endif + +#ifdef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS +/* Base AC Timing values specified by JESD209-2 for 400MHz operation */ +static const struct lpddr2_ac_timings timings_jedec_400_mhz = { + .max_freq = 400000000, + .RL = 6, + .tRPab = 21, + .tRCD = 18, + .tWR = 15, + .tRASmin = 42, + .tRRD = 10, + .tWTRx2 = 15, + .tXSR = 140, + .tXPx2 = 15, + .tRFCab = 130, + .tRTPx2 = 15, + .tCKE = 3, + .tCKESR = 15, + .tZQCS = 90, + .tZQCL = 360, + .tZQINIT = 1000, + .tDQSCKMAXx2 = 11, + .tRASmax = 70, + .tFAW = 50 +}; + +/* Base AC Timing values specified by JESD209-2 for 200 MHz operation */ +static const struct lpddr2_ac_timings timings_jedec_200_mhz = { + .max_freq = 200000000, + .RL = 3, + .tRPab = 21, + .tRCD = 18, + .tWR = 15, + .tRASmin = 42, + .tRRD = 10, + .tWTRx2 = 20, + .tXSR = 140, + .tXPx2 = 15, + .tRFCab = 130, + .tRTPx2 = 15, + .tCKE = 3, + .tCKESR = 15, + .tZQCS = 90, + .tZQCL = 360, + .tZQINIT = 1000, + .tDQSCKMAXx2 = 11, + .tRASmax = 70, + .tFAW = 50 +}; + +/* + * Min tCK values specified by JESD209-2 + * Min tCK specifies the minimum duration of some AC timing parameters in terms + * of the number of cycles. If the calculated number of cycles based on the + * absolute time value is less than the min tCK value, min tCK value should + * be used instead. This typically happens at low frequencies. + */ +static const struct lpddr2_min_tck min_tck_jedec = { + .tRL = 3, + .tRP_AB = 3, + .tRCD = 3, + .tWR = 3, + .tRAS_MIN = 3, + .tRRD = 2, + .tWTR = 2, + .tXP = 2, + .tRTP = 2, + .tCKE = 3, + .tCKESR = 3, + .tFAW = 8 +}; + +static const struct lpddr2_ac_timings const* + jedec_ac_timings[MAX_NUM_SPEEDBINS] = { + &timings_jedec_200_mhz, + &timings_jedec_400_mhz +}; + +static const struct lpddr2_device_timings jedec_default_timings = { + .ac_timings = jedec_ac_timings, + .min_tck = &min_tck_jedec +}; + +void emif_get_device_timings(u32 emif_nr, + const struct lpddr2_device_timings **cs0_device_timings, + const struct lpddr2_device_timings **cs1_device_timings) +{ + /* Assume Identical devices on EMIF1 & EMIF2 */ + *cs0_device_timings = &jedec_default_timings; + *cs1_device_timings = &jedec_default_timings; +} +#endif /* CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS */ diff --git a/arch/arm/cpu/armv7/omap4/hwinit.c b/arch/arm/cpu/armv7/omap4/hwinit.c index 78b3cab..52c9b19 100644 --- a/arch/arm/cpu/armv7/omap4/hwinit.c +++ b/arch/arm/cpu/armv7/omap4/hwinit.c @@ -32,7 +32,7 @@ #include <asm/arch/cpu.h> #include <asm/arch/sys_proto.h> #include <asm/sizes.h> -#include <asm/arch/emif.h> +#include <asm/emif.h> #include <asm/arch/gpio.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/arch/arm/cpu/armv7/omap4/sdram_elpida.c b/arch/arm/cpu/armv7/omap4/sdram_elpida.c index edc5326..a5ec7d3 100644 --- a/arch/arm/cpu/armv7/omap4/sdram_elpida.c +++ b/arch/arm/cpu/armv7/omap4/sdram_elpida.c @@ -26,7 +26,7 @@ * MA 02111-1307 USA */ -#include <asm/arch/emif.h> +#include <asm/emif.h> #include <asm/arch/sys_proto.h> /* diff --git a/arch/arm/cpu/armv7/omap5/emif.c b/arch/arm/cpu/armv7/omap5/emif.c new file mode 100644 index 0000000..8019ffe --- /dev/null +++ b/arch/arm/cpu/armv7/omap5/emif.c @@ -0,0 +1,105 @@ +/* + * EMIF programming + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Aneesh V <aneesh@ti.com> for OMAP4 + * + * 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 <common.h> +#include <asm/emif.h> +#include <asm/arch/sys_proto.h> +#include <asm/utils.h> + +#ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS +#define print_timing_reg(reg) debug(#reg" - 0x%08x\n", (reg)) +static u32 *const T_num = (u32 *)OMAP5_SRAM_SCRATCH_EMIF_T_NUM; +static u32 *const T_den = (u32 *)OMAP5_SRAM_SCRATCH_EMIF_T_DEN; +static u32 *const emif_sizes = (u32 *)OMAP5_SRAM_SCRATCH_EMIF_SIZE; +#endif + +#ifdef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS +/* Base AC Timing values specified by JESD209-2 for 532MHz operation */ +static const struct lpddr2_ac_timings timings_jedec_532_mhz = { + .max_freq = 532000000, + .RL = 8, + .tRPab = 21, + .tRCD = 18, + .tWR = 15, + .tRASmin = 42, + .tRRD = 10, + .tWTRx2 = 15, + .tXSR = 140, + .tXPx2 = 15, + .tRFCab = 130, + .tRTPx2 = 15, + .tCKE = 3, + .tCKESR = 15, + .tZQCS = 90, + .tZQCL = 360, + .tZQINIT = 1000, + .tDQSCKMAXx2 = 11, + .tRASmax = 70, + .tFAW = 50 +}; + +/* + * Min tCK values specified by JESD209-2 + * Min tCK specifies the minimum duration of some AC timing parameters in terms + * of the number of cycles. If the calculated number of cycles based on the + * absolute time value is less than the min tCK value, min tCK value should + * be used instead. This typically happens at low frequencies. + */ +static const struct lpddr2_min_tck min_tck_jedec = { + .tRL = 3, + .tRP_AB = 3, + .tRCD = 3, + .tWR = 3, + .tRAS_MIN = 3, + .tRRD = 2, + .tWTR = 2, + .tXP = 2, + .tRTP = 2, + .tCKE = 3, + .tCKESR = 3, + .tFAW = 8 +}; + +static const struct lpddr2_ac_timings const* + jedec_ac_timings[MAX_NUM_SPEEDBINS] = { + &timings_jedec_532_mhz +}; + +static const struct lpddr2_device_timings jedec_default_timings = { + .ac_timings = jedec_ac_timings, + .min_tck = &min_tck_jedec +}; + +void emif_get_device_timings(u32 emif_nr, + const struct lpddr2_device_timings **cs0_device_timings, + const struct lpddr2_device_timings **cs1_device_timings) +{ + /* Assume Identical devices on EMIF1 & EMIF2 */ + *cs0_device_timings = &jedec_default_timings; + *cs1_device_timings = NULL; +} +#endif /* CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS */ diff --git a/arch/arm/cpu/armv7/omap5/sdram_elpida.c b/arch/arm/cpu/armv7/omap5/sdram_elpida.c new file mode 100644 index 0000000..ad198e6 --- /dev/null +++ b/arch/arm/cpu/armv7/omap5/sdram_elpida.c @@ -0,0 +1,178 @@ +/* + * Timing and Organization details of the Elpida parts used in OMAP5 + * EVM + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Aneesh V <aneesh@ti.com> + * Sricharan R <r.sricharan@ti.com> + * + * 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 <asm/emif.h> +#include <asm/arch/sys_proto.h> + +/* + * This file provides details of the LPDDR2 SDRAM parts used on OMAP5 + * EVM. Since the parts used and geometry are identical for + * evm for a given OMAP5 revision, this information is kept + * here instead of being in board directory. However the key functions + * exported are weakly linked so that they can be over-ridden in the board + * directory if there is a OMAP5 board in the future that uses a different + * memory device or geometry. + * + * For any new board with different memory devices over-ride one or more + * of the following functions as per the CONFIG flags you intend to enable: + * - emif_get_reg_dump() + * - emif_get_dmm_regs() + * - emif_get_device_details() + * - emif_get_device_timings() + */ + +#ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS + +const struct emif_regs emif_regs_elpida_532_mhz_1cs = { + .sdram_config_init = 0x80801aB2, + .sdram_config = 0x808022B2, + .ref_ctrl = 0x0000081A, + .sdram_tim1 = 0x772F6873, + .sdram_tim2 = 0x304A129A, + .sdram_tim3 = 0x02F7E45F, + .read_idle_ctrl = 0x00050000, + .zq_config = 0x000B3215, + .temp_alert_config = 0x08000A05, + .emif_ddr_phy_ctlr_1_init = 0x0E38200D, + .emif_ddr_phy_ctlr_1 = 0x0E38200D +}; + +const struct dmm_lisa_map_regs lisa_map_4G_x_1_x_2 = { + .dmm_lisa_map_0 = 0xFF020100, + .dmm_lisa_map_1 = 0, + .dmm_lisa_map_2 = 0, + .dmm_lisa_map_3 = 0x80640300 +}; + +static void emif_get_reg_dump_sdp(u32 emif_nr, const struct emif_regs **regs) +{ + *regs = &emif_regs_elpida_532_mhz_1cs; +} +void emif_get_reg_dump(u32 emif_nr, const struct emif_regs **regs) + __attribute__((weak, alias("emif_get_reg_dump_sdp"))); + +static void emif_get_dmm_regs_sdp(const struct dmm_lisa_map_regs + **dmm_lisa_regs) +{ + *dmm_lisa_regs = &lisa_map_4G_x_1_x_2; +} + +void emif_get_dmm_regs(const struct dmm_lisa_map_regs **dmm_lisa_regs) + __attribute__((weak, alias("emif_get_dmm_regs_sdp"))); + +#else + +static const struct lpddr2_device_details elpida_4G_S4_details = { + .type = LPDDR2_TYPE_S4, + .density = LPDDR2_DENSITY_4Gb, + .io_width = LPDDR2_IO_WIDTH_32, + .manufacturer = LPDDR2_MANUFACTURER_ELPIDA +}; + +static void emif_get_device_details_sdp(u32 emif_nr, + struct lpddr2_device_details *cs0_device_details, + struct lpddr2_device_details *cs1_device_details) +{ + /* EMIF1 & EMIF2 have identical configuration */ + *cs0_device_details = elpida_4G_S4_details; + + /* Nothing is conected on cs1 */ + cs1_device_details = NULL; +} + +void emif_get_device_details(u32 emif_nr, + struct lpddr2_device_details *cs0_device_details, + struct lpddr2_device_details *cs1_device_details) + __attribute__((weak, alias("emif_get_device_details_sdp"))); + +#endif /* CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS */ + +#ifndef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS +static const struct lpddr2_ac_timings timings_jedec_532_mhz = { + .max_freq = 532000000, + .RL = 8, + .tRPab = 21, + .tRCD = 18, + .tWR = 15, + .tRASmin = 42, + .tRRD = 10, + .tWTRx2 = 15, + .tXSR = 140, + .tXPx2 = 15, + .tRFCab = 130, + .tRTPx2 = 15, + .tCKE = 3, + .tCKESR = 15, + .tZQCS = 90, + .tZQCL = 360, + .tZQINIT = 1000, + .tDQSCKMAXx2 = 11, + .tRASmax = 70, + .tFAW = 50 +}; + +static const struct lpddr2_min_tck min_tck_elpida = { + .tRL = 3, + .tRP_AB = 3, + .tRCD = 3, + .tWR = 3, + .tRAS_MIN = 3, + .tRRD = 2, + .tWTR = 2, + .tXP = 2, + .tRTP = 2, + .tCKE = 3, + .tCKESR = 3, + .tFAW = 8 +}; + +static const struct lpddr2_ac_timings *elpida_ac_timings[MAX_NUM_SPEEDBINS] = { + &timings_jedec_532_mhz +}; + +static const struct lpddr2_device_timings elpida_4G_S4_timings = { + .ac_timings = elpida_ac_timings, + .min_tck = &min_tck_elpida, +}; + +void emif_get_device_timings_sdp(u32 emif_nr, + const struct lpddr2_device_timings **cs0_device_timings, + const struct lpddr2_device_timings **cs1_device_timings) +{ + /* Identical devices on EMIF1 & EMIF2 */ + *cs0_device_timings = &elpida_4G_S4_timings; + *cs1_device_timings = NULL; +} + +void emif_get_device_timings(u32 emif_nr, + const struct lpddr2_device_timings **cs0_device_timings, + const struct lpddr2_device_timings **cs1_device_timings) + __attribute__((weak, alias("emif_get_device_timings_sdp"))); + +#endif /* CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS */ |