summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv7
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/cpu/armv7')
-rw-r--r--arch/arm/cpu/armv7/am33xx/ddr.c101
-rw-r--r--arch/arm/cpu/armv7/am33xx/emif4.c5
-rw-r--r--arch/arm/cpu/armv7/cpu.c47
-rw-r--r--arch/arm/cpu/armv7/exynos/Kconfig11
-rw-r--r--arch/arm/cpu/armv7/omap-common/clocks-common.c30
-rw-r--r--arch/arm/cpu/armv7/omap-common/emif-common.c157
-rw-r--r--arch/arm/cpu/armv7/omap5/Makefile1
-rw-r--r--arch/arm/cpu/armv7/omap5/dra7xx_iodelay.c238
-rw-r--r--arch/arm/cpu/armv7/omap5/hw_data.c15
-rw-r--r--arch/arm/cpu/armv7/omap5/hwinit.c24
-rw-r--r--arch/arm/cpu/armv7/omap5/prcm-regs.c7
-rw-r--r--arch/arm/cpu/armv7/omap5/sdram.c119
-rw-r--r--arch/arm/cpu/armv7/s5pc1xx/Kconfig2
-rw-r--r--arch/arm/cpu/armv7/sunxi/board.c16
-rw-r--r--arch/arm/cpu/armv7/sunxi/usb_phy.c6
-rw-r--r--arch/arm/cpu/armv7/vf610/generic.c7
16 files changed, 669 insertions, 117 deletions
diff --git a/arch/arm/cpu/armv7/am33xx/ddr.c b/arch/arm/cpu/armv7/am33xx/ddr.c
index f5b16b4b72..b3fb0c47ab 100644
--- a/arch/arm/cpu/armv7/am33xx/ddr.c
+++ b/arch/arm/cpu/armv7/am33xx/ddr.c
@@ -123,30 +123,33 @@ void config_sdram_emif4d5(const struct emif_regs *regs, int nr)
writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
- /* Perform hardware leveling. */
- udelay(1000);
- writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36) |
- 0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36);
- writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw) |
- 0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw);
-
- writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_rmp_ctl);
-
- /* Enable read leveling */
- writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_ctl);
-
- /*
- * Enable full read and write leveling. Wait for read and write
- * leveling bit to clear RDWRLVLFULL_START bit 31
- */
- while((readl(&emif_reg[nr]->emif_rd_wr_lvl_ctl) & 0x80000000) != 0)
- ;
-
- /* Check the timeout register to see if leveling is complete */
- if((readl(&emif_reg[nr]->emif_status) & 0x70) != 0)
- puts("DDR3 H/W leveling incomplete with errors\n");
-
- if (emif_sdram_type() == EMIF_SDRAM_TYPE_LPDDR2) {
+ /* Perform hardware leveling for DDR3 */
+ if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3) {
+ udelay(1000);
+ writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36) |
+ 0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36);
+ writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw) |
+ 0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw);
+
+ writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_rmp_ctl);
+
+ /* Enable read leveling */
+ writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_ctl);
+
+ /*
+ * Enable full read and write leveling. Wait for read and write
+ * leveling bit to clear RDWRLVLFULL_START bit 31
+ */
+ while ((readl(&emif_reg[nr]->emif_rd_wr_lvl_ctl) & 0x80000000)
+ != 0)
+ ;
+
+ /* Check the timeout register to see if leveling is complete */
+ if ((readl(&emif_reg[nr]->emif_status) & 0x70) != 0)
+ puts("DDR3 H/W leveling incomplete with errors\n");
+
+ } else {
+ /* DDR2 */
configure_mr(nr, 0);
configure_mr(nr, 1);
}
@@ -183,9 +186,49 @@ void set_sdram_timings(const struct emif_regs *regs, int nr)
}
/*
+ * Configure EXT PHY registers for software leveling
+ */
+static void ext_phy_settings_swlvl(const struct emif_regs *regs, int nr)
+{
+ u32 *ext_phy_ctrl_base = 0;
+ u32 *emif_ext_phy_ctrl_base = 0;
+ __maybe_unused const u32 *ext_phy_ctrl_const_regs;
+ u32 i = 0;
+ __maybe_unused u32 size;
+
+ ext_phy_ctrl_base = (u32 *)&(regs->emif_ddr_ext_phy_ctrl_1);
+ emif_ext_phy_ctrl_base =
+ (u32 *)&(emif_reg[nr]->emif_ddr_ext_phy_ctrl_1);
+
+ /* Configure external phy control timing registers */
+ for (i = 0; i < EMIF_EXT_PHY_CTRL_TIMING_REG; i++) {
+ writel(*ext_phy_ctrl_base, emif_ext_phy_ctrl_base++);
+ /* Update shadow registers */
+ writel(*ext_phy_ctrl_base++, emif_ext_phy_ctrl_base++);
+ }
+
+#ifdef CONFIG_AM43XX
+ /*
+ * External phy 6-24 registers do not change with ddr frequency.
+ * These only need to be set on DDR2 on AM43xx.
+ */
+ emif_get_ext_phy_ctrl_const_regs(&ext_phy_ctrl_const_regs, &size);
+
+ if (!size)
+ return;
+
+ for (i = 0; i < size; i++) {
+ writel(ext_phy_ctrl_const_regs[i], emif_ext_phy_ctrl_base++);
+ /* Update shadow registers */
+ writel(ext_phy_ctrl_const_regs[i], emif_ext_phy_ctrl_base++);
+ }
+#endif
+}
+
+/*
* Configure EXT PHY registers for hardware leveling
*/
-static void ext_phy_settings(const struct emif_regs *regs, int nr)
+static void ext_phy_settings_hwlvl(const struct emif_regs *regs, int nr)
{
/*
* Enable hardware leveling on the EMIF. For details about these
@@ -256,8 +299,12 @@ void config_ddr_phy(const struct emif_regs *regs, int nr)
writel(regs->emif_ddr_phy_ctlr_1,
&emif_reg[nr]->emif_ddr_phy_ctrl_1_shdw);
- if (get_emif_rev((u32)emif_reg[nr]) == EMIF_4D5)
- ext_phy_settings(regs, nr);
+ if (get_emif_rev((u32)emif_reg[nr]) == EMIF_4D5) {
+ if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3)
+ ext_phy_settings_hwlvl(regs, nr);
+ else
+ ext_phy_settings_swlvl(regs, nr);
+ }
}
/**
diff --git a/arch/arm/cpu/armv7/am33xx/emif4.c b/arch/arm/cpu/armv7/am33xx/emif4.c
index 9cf816c89a..27fa3fb462 100644
--- a/arch/arm/cpu/armv7/am33xx/emif4.c
+++ b/arch/arm/cpu/armv7/am33xx/emif4.c
@@ -124,8 +124,9 @@ void config_ddr(unsigned int pll, const struct ctrl_ioregs *ioregs,
/* Set CKE to be controlled by EMIF/DDR PHY */
writel(DDR_CKE_CTRL_NORMAL, &ddrctrl->ddrckectrl);
- /* Allow EMIF to control DDR_RESET */
- writel(0x00000000, &ddrctrl->ddrioctrl);
+ if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3)
+ /* Allow EMIF to control DDR_RESET */
+ writel(0x00000000, &ddrctrl->ddrioctrl);
#endif
/* Program EMIF instance */
diff --git a/arch/arm/cpu/armv7/cpu.c b/arch/arm/cpu/armv7/cpu.c
index c56417dd2f..0b0e5003cc 100644
--- a/arch/arm/cpu/armv7/cpu.c
+++ b/arch/arm/cpu/armv7/cpu.c
@@ -24,7 +24,7 @@
void __weak cpu_cache_initialization(void){}
-int cleanup_before_linux(void)
+int cleanup_before_linux_select(int flags)
{
/*
* this function is called just before we call linux
@@ -42,24 +42,30 @@ int cleanup_before_linux(void)
icache_disable();
invalidate_icache_all();
- /*
- * turn off D-cache
- * dcache_disable() in turn flushes the d-cache and disables MMU
- */
- dcache_disable();
- v7_outer_cache_disable();
+ if (flags & CBL_DISABLE_CACHES) {
+ /*
+ * turn off D-cache
+ * dcache_disable() in turn flushes the d-cache and disables MMU
+ */
+ dcache_disable();
+ v7_outer_cache_disable();
- /*
- * After D-cache is flushed and before it is disabled there may
- * be some new valid entries brought into the cache. We are sure
- * that these lines are not dirty and will not affect our execution.
- * (because unwinding the call-stack and setting a bit in CP15 SCTLR
- * is all we did during this. We have not pushed anything on to the
- * stack. Neither have we affected any static data)
- * So just invalidate the entire d-cache again to avoid coherency
- * problems for kernel
- */
- invalidate_dcache_all();
+ /*
+ * After D-cache is flushed and before it is disabled there may
+ * be some new valid entries brought into the cache. We are
+ * sure that these lines are not dirty and will not affect our
+ * execution. (because unwinding the call-stack and setting a
+ * bit in CP15 SCTRL is all we did during this. We have not
+ * pushed anything on to the stack. Neither have we affected
+ * any static data) So just invalidate the entire d-cache again
+ * to avoid coherency problems for kernel
+ */
+ invalidate_dcache_all();
+ } else {
+ flush_dcache_all();
+ invalidate_icache_all();
+ icache_enable();
+ }
/*
* Some CPU need more cache attention before starting the kernel.
@@ -68,3 +74,8 @@ int cleanup_before_linux(void)
return 0;
}
+
+int cleanup_before_linux(void)
+{
+ return cleanup_before_linux_select(CBL_ALL);
+}
diff --git a/arch/arm/cpu/armv7/exynos/Kconfig b/arch/arm/cpu/armv7/exynos/Kconfig
index c61442578d..4a7d82f74c 100644
--- a/arch/arm/cpu/armv7/exynos/Kconfig
+++ b/arch/arm/cpu/armv7/exynos/Kconfig
@@ -8,6 +8,7 @@ config TARGET_SMDKV310
select SUPPORT_SPL
bool "Exynos4210 SMDKV310 board"
select OF_CONTROL
+ select SPL_DISABLE_OF_CONTROL
config TARGET_TRATS
bool "Exynos4210 Trats board"
@@ -28,6 +29,7 @@ config TARGET_ODROID
config TARGET_ODROID_XU3
bool "Exynos5422 Odroid board"
select OF_CONTROL
+ select SPL_DISABLE_OF_CONTROL
config TARGET_ARNDALE
bool "Exynos5250 Arndale board"
@@ -35,40 +37,43 @@ config TARGET_ARNDALE
select CPU_V7_HAS_VIRT
select SUPPORT_SPL
select OF_CONTROL
+ select SPL_DISABLE_OF_CONTROL
config TARGET_SMDK5250
bool "SMDK5250 board"
select SUPPORT_SPL
select OF_CONTROL
+ select SPL_DISABLE_OF_CONTROL
config TARGET_SNOW
bool "Snow board"
select SUPPORT_SPL
select OF_CONTROL
+ select SPL_DISABLE_OF_CONTROL
config TARGET_SMDK5420
bool "SMDK5420 board"
select SUPPORT_SPL
select OF_CONTROL
+ select SPL_DISABLE_OF_CONTROL
config TARGET_PEACH_PI
bool "Peach Pi board"
select SUPPORT_SPL
select OF_CONTROL
+ select SPL_DISABLE_OF_CONTROL
config TARGET_PEACH_PIT
bool "Peach Pit board"
select SUPPORT_SPL
select OF_CONTROL
+ select SPL_DISABLE_OF_CONTROL
endchoice
config SYS_SOC
default "exynos"
-config DM_USB
- default y
-
source "board/samsung/smdkv310/Kconfig"
source "board/samsung/trats/Kconfig"
source "board/samsung/universal_c210/Kconfig"
diff --git a/arch/arm/cpu/armv7/omap-common/clocks-common.c b/arch/arm/cpu/armv7/omap-common/clocks-common.c
index 03674e609f..c94a807819 100644
--- a/arch/arm/cpu/armv7/omap-common/clocks-common.c
+++ b/arch/arm/cpu/armv7/omap-common/clocks-common.c
@@ -372,6 +372,7 @@ static void setup_dplls(void)
{
u32 temp;
const struct dpll_params *params;
+ struct emif_reg_struct *emif = (struct emif_reg_struct *)EMIF1_BASE;
debug("setup_dplls\n");
@@ -382,7 +383,8 @@ static void setup_dplls(void)
* Core DPLL will be locked after setting up EMIF
* using the FREQ_UPDATE method(freq_update_core())
*/
- if (emif_sdram_type() == EMIF_SDRAM_TYPE_LPDDR2)
+ if (emif_sdram_type(readl(&emif->emif_sdram_config)) ==
+ EMIF_SDRAM_TYPE_LPDDR2)
do_setup_dpll((*prcm)->cm_clkmode_dpll_core, params,
DPLL_NO_LOCK, "core");
else
@@ -508,6 +510,12 @@ static u32 optimize_vcore_voltage(struct volts const *v)
return val;
}
+#ifdef CONFIG_IODELAY_RECALIBRATION
+void __weak recalibrate_iodelay(void)
+{
+}
+#endif
+
/*
* Setup the voltages for the main SoC core power domains.
* We start with the maximum voltages allowed here, as set in the corresponding
@@ -561,6 +569,16 @@ void scale_vcores(struct vcores_data const *vcores)
debug("cor: %d\n", vcores->core.value);
do_scale_vcore(vcores->core.addr, vcores->core.value, vcores->core.pmic);
+ /*
+ * IO delay recalibration should be done immediately after
+ * adjusting AVS voltages for VDD_CORE_L.
+ * Respective boards should call __recalibrate_iodelay()
+ * with proper mux, virtual and manual mode configurations.
+ */
+#ifdef CONFIG_IODELAY_RECALIBRATION
+ recalibrate_iodelay();
+#endif
+
debug("mpu: %d\n", vcores->mpu.value);
do_scale_vcore(vcores->mpu.addr, vcores->mpu.value, vcores->mpu.pmic);
/* Configure MPU ABB LDO after scale */
@@ -587,6 +605,16 @@ void scale_vcores(struct vcores_data const *vcores)
val = optimize_vcore_voltage(&vcores->core);
do_scale_vcore(vcores->core.addr, val, vcores->core.pmic);
+ /*
+ * IO delay recalibration should be done immediately after
+ * adjusting AVS voltages for VDD_CORE_L.
+ * Respective boards should call __recalibrate_iodelay()
+ * with proper mux, virtual and manual mode configurations.
+ */
+#ifdef CONFIG_IODELAY_RECALIBRATION
+ recalibrate_iodelay();
+#endif
+
val = optimize_vcore_voltage(&vcores->mpu);
do_scale_vcore(vcores->mpu.addr, val, vcores->mpu.pmic);
diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c
index c01a98f719..f5b22f6a78 100644
--- a/arch/arm/cpu/armv7/omap-common/emif-common.c
+++ b/arch/arm/cpu/armv7/omap-common/emif-common.c
@@ -242,13 +242,122 @@ static void omap5_ddr3_leveling(u32 base, const struct emif_regs *regs)
__udelay(130);
}
-static void ddr3_leveling(u32 base, const struct emif_regs *regs)
+static void update_hwleveling_output(u32 base, const struct emif_regs *regs)
{
- if (is_omap54xx())
- omap5_ddr3_leveling(base, regs);
+ struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+ u32 *emif_ext_phy_ctrl_reg, *emif_phy_status;
+ u32 reg, i;
+
+ emif_phy_status = (u32 *)&emif->emif_ddr_phy_status[7];
+
+ /* Update PHY_REG_RDDQS_RATIO */
+ emif_ext_phy_ctrl_reg = (u32 *)&emif->emif_ddr_ext_phy_ctrl_7;
+ for (i = 0; i < PHY_RDDQS_RATIO_REGS; i++) {
+ reg = readl(emif_phy_status++);
+ writel(reg, emif_ext_phy_ctrl_reg++);
+ writel(reg, emif_ext_phy_ctrl_reg++);
+ }
+
+ /* Update PHY_REG_FIFO_WE_SLAVE_RATIO */
+ emif_ext_phy_ctrl_reg = (u32 *)&emif->emif_ddr_ext_phy_ctrl_2;
+ for (i = 0; i < PHY_FIFO_WE_SLAVE_RATIO_REGS; i++) {
+ reg = readl(emif_phy_status++);
+ writel(reg, emif_ext_phy_ctrl_reg++);
+ writel(reg, emif_ext_phy_ctrl_reg++);
+ }
+
+ /* Update PHY_REG_WR_DQ/DQS_SLAVE_RATIO */
+ emif_ext_phy_ctrl_reg = (u32 *)&emif->emif_ddr_ext_phy_ctrl_12;
+ for (i = 0; i < PHY_REG_WR_DQ_SLAVE_RATIO_REGS; i++) {
+ reg = readl(emif_phy_status++);
+ writel(reg, emif_ext_phy_ctrl_reg++);
+ writel(reg, emif_ext_phy_ctrl_reg++);
+ }
+
+ /* Disable Leveling */
+ writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1);
+ writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1_shdw);
+ writel(0x0, &emif->emif_rd_wr_lvl_rmp_ctl);
}
-static void ddr3_init(u32 base, const struct emif_regs *regs)
+static void dra7_ddr3_leveling(u32 base, const struct emif_regs *regs)
+{
+ struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+
+ /* Clear Error Status */
+ clrsetbits_le32(&emif->emif_ddr_ext_phy_ctrl_36,
+ EMIF_REG_PHY_FIFO_WE_IN_MISALINED_CLR,
+ EMIF_REG_PHY_FIFO_WE_IN_MISALINED_CLR);
+
+ clrsetbits_le32(&emif->emif_ddr_ext_phy_ctrl_36_shdw,
+ EMIF_REG_PHY_FIFO_WE_IN_MISALINED_CLR,
+ EMIF_REG_PHY_FIFO_WE_IN_MISALINED_CLR);
+
+ /* Disable refreshed before leveling */
+ clrsetbits_le32(&emif->emif_sdram_ref_ctrl, EMIF_REG_INITREF_DIS_SHIFT,
+ EMIF_REG_INITREF_DIS_SHIFT);
+
+ /* Start Full leveling */
+ writel(DDR3_FULL_LVL, &emif->emif_rd_wr_lvl_ctl);
+
+ __udelay(300);
+
+ /* Check for leveling timeout */
+ if (readl(&emif->emif_status) & EMIF_REG_LEVELING_TO_MASK) {
+ printf("Leveling timeout on EMIF%d\n", emif_num(base));
+ return;
+ }
+
+ /* Enable refreshes after leveling */
+ clrbits_le32(&emif->emif_sdram_ref_ctrl, EMIF_REG_INITREF_DIS_SHIFT);
+
+ debug("HW leveling success\n");
+ /*
+ * Update slave ratios in EXT_PHY_CTRLx registers
+ * as per HW leveling output
+ */
+ update_hwleveling_output(base, regs);
+}
+
+static void dra7_ddr3_init(u32 base, const struct emif_regs *regs)
+{
+ struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+
+ if (warm_reset())
+ emif_reset_phy(base);
+ do_ext_phy_settings(base, regs);
+
+ writel(regs->ref_ctrl | EMIF_REG_INITREF_DIS_MASK,
+ &emif->emif_sdram_ref_ctrl);
+ /* Update timing registers */
+ writel(regs->sdram_tim1, &emif->emif_sdram_tim_1);
+ writel(regs->sdram_tim2, &emif->emif_sdram_tim_2);
+ writel(regs->sdram_tim3, &emif->emif_sdram_tim_3);
+
+ writel(EMIF_L3_CONFIG_VAL_SYS_10_MPU_5_LL_0, &emif->emif_l3_config);
+ writel(regs->read_idle_ctrl, &emif->emif_read_idlectrl);
+ writel(regs->zq_config, &emif->emif_zq_config);
+ writel(regs->temp_alert_config, &emif->emif_temp_alert_config);
+ writel(regs->emif_rd_wr_lvl_rmp_ctl, &emif->emif_rd_wr_lvl_rmp_ctl);
+ writel(regs->emif_rd_wr_lvl_ctl, &emif->emif_rd_wr_lvl_ctl);
+
+ writel(regs->emif_ddr_phy_ctlr_1_init, &emif->emif_ddr_phy_ctrl_1);
+ writel(regs->emif_rd_wr_exec_thresh, &emif->emif_rd_wr_exec_thresh);
+
+ writel(regs->ref_ctrl, &emif->emif_sdram_ref_ctrl);
+
+ writel(regs->sdram_config2, &emif->emif_lpddr2_nvm_config);
+ writel(regs->sdram_config_init, &emif->emif_sdram_config);
+
+ __udelay(1000);
+
+ writel(regs->ref_ctrl_final, &emif->emif_sdram_ref_ctrl);
+
+ if (regs->emif_rd_wr_lvl_rmp_ctl & EMIF_REG_RDWRLVL_EN_MASK)
+ dra7_ddr3_leveling(base, regs);
+}
+
+static void omap5_ddr3_init(u32 base, const struct emif_regs *regs)
{
struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
@@ -269,25 +378,20 @@ static void ddr3_init(u32 base, const struct emif_regs *regs)
writel(regs->read_idle_ctrl, &emif->emif_read_idlectrl);
- /*
- * The same sequence should work on OMAP5432 as well. But strange that
- * it is not working
- */
- if (is_dra7xx()) {
- do_ext_phy_settings(base, regs);
- writel(regs->ref_ctrl_final, &emif->emif_sdram_ref_ctrl);
- writel(regs->sdram_config2, &emif->emif_lpddr2_nvm_config);
- writel(regs->sdram_config_init, &emif->emif_sdram_config);
- } else {
- writel(regs->sdram_config2, &emif->emif_lpddr2_nvm_config);
- writel(regs->sdram_config_init, &emif->emif_sdram_config);
- do_ext_phy_settings(base, regs);
- }
+ writel(regs->sdram_config2, &emif->emif_lpddr2_nvm_config);
+ writel(regs->sdram_config_init, &emif->emif_sdram_config);
+ do_ext_phy_settings(base, regs);
- /* enable leveling */
writel(regs->emif_rd_wr_lvl_rmp_ctl, &emif->emif_rd_wr_lvl_rmp_ctl);
+ omap5_ddr3_leveling(base, regs);
+}
- ddr3_leveling(base, regs);
+static void ddr3_init(u32 base, const struct emif_regs *regs)
+{
+ if (is_omap54xx())
+ omap5_ddr3_init(base, regs);
+ else
+ dra7_ddr3_init(base, regs);
}
#ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
@@ -1066,16 +1170,18 @@ static void do_sdram_init(u32 base)
* Changing the timing registers in EMIF can happen(going from one
* OPP to another)
*/
- if (!(in_sdram || warm_reset())) {
- if (emif_sdram_type() == EMIF_SDRAM_TYPE_LPDDR2)
+ if (!in_sdram && (!warm_reset() || is_dra7xx())) {
+ if (emif_sdram_type(regs->sdram_config) ==
+ EMIF_SDRAM_TYPE_LPDDR2)
lpddr2_init(base, regs);
else
ddr3_init(base, regs);
}
- if (warm_reset() && (emif_sdram_type() == EMIF_SDRAM_TYPE_DDR3)) {
+ if (warm_reset() && (emif_sdram_type(regs->sdram_config) ==
+ EMIF_SDRAM_TYPE_DDR3) && !is_dra7xx()) {
set_lpmode_selfrefresh(base);
emif_reset_phy(base);
- ddr3_leveling(base, regs);
+ omap5_ddr3_leveling(base, regs);
}
/* Write to the shadow registers */
@@ -1294,7 +1400,8 @@ static void do_bug0039_workaround(u32 base)
void sdram_init(void)
{
u32 in_sdram, size_prog, size_detect;
- u32 sdram_type = emif_sdram_type();
+ struct emif_reg_struct *emif = (struct emif_reg_struct *)EMIF1_BASE;
+ u32 sdram_type = emif_sdram_type(emif->emif_sdram_config);
debug(">>sdram_init()\n");
diff --git a/arch/arm/cpu/armv7/omap5/Makefile b/arch/arm/cpu/armv7/omap5/Makefile
index 64c68791f1..e709f14a92 100644
--- a/arch/arm/cpu/armv7/omap5/Makefile
+++ b/arch/arm/cpu/armv7/omap5/Makefile
@@ -11,3 +11,4 @@ obj-y += sdram.o
obj-y += prcm-regs.o
obj-y += hw_data.o
obj-y += abb.o
+obj-$(CONFIG_IODELAY_RECALIBRATION) += dra7xx_iodelay.o
diff --git a/arch/arm/cpu/armv7/omap5/dra7xx_iodelay.c b/arch/arm/cpu/armv7/omap5/dra7xx_iodelay.c
new file mode 100644
index 0000000000..9fa6e6991f
--- /dev/null
+++ b/arch/arm/cpu/armv7/omap5/dra7xx_iodelay.c
@@ -0,0 +1,238 @@
+/*
+ * (C) Copyright 2015
+ * Texas Instruments Incorporated, <www.ti.com>
+ *
+ * Lokesh Vutla <lokeshvutla@ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/utils.h>
+#include <asm/arch/dra7xx_iodelay.h>
+#include <asm/arch/omap.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/mux_dra7xx.h>
+#include <asm/omap_common.h>
+
+static int isolate_io(u32 isolate)
+{
+ if (isolate) {
+ clrsetbits_le32((*ctrl)->control_pbias, SDCARD_PWRDNZ,
+ SDCARD_PWRDNZ);
+ clrsetbits_le32((*ctrl)->control_pbias, SDCARD_BIAS_PWRDNZ,
+ SDCARD_BIAS_PWRDNZ);
+ }
+
+ /* Override control on ISOCLKIN signal to IO pad ring. */
+ clrsetbits_le32((*prcm)->prm_io_pmctrl, PMCTRL_ISOCLK_OVERRIDE_MASK,
+ PMCTRL_ISOCLK_OVERRIDE_CTRL);
+ if (!wait_on_value(PMCTRL_ISOCLK_STATUS_MASK, PMCTRL_ISOCLK_STATUS_MASK,
+ (u32 *)(*prcm)->prm_io_pmctrl, LDELAY))
+ return ERR_DEISOLATE_IO << isolate;
+
+ /* Isolate/Deisolate IO */
+ clrsetbits_le32((*ctrl)->ctrl_core_sma_sw_0, CTRL_ISOLATE_MASK,
+ isolate << CTRL_ISOLATE_SHIFT);
+ /* Dummy read to add delay t > 10ns */
+ readl((*ctrl)->ctrl_core_sma_sw_0);
+
+ /* Return control on ISOCLKIN to hardware */
+ clrsetbits_le32((*prcm)->prm_io_pmctrl, PMCTRL_ISOCLK_OVERRIDE_MASK,
+ PMCTRL_ISOCLK_NOT_OVERRIDE_CTRL);
+ if (!wait_on_value(PMCTRL_ISOCLK_STATUS_MASK,
+ 0 << PMCTRL_ISOCLK_STATUS_SHIFT,
+ (u32 *)(*prcm)->prm_io_pmctrl, LDELAY))
+ return ERR_DEISOLATE_IO << isolate;
+
+ return 0;
+}
+
+static int calibrate_iodelay(u32 base)
+{
+ u32 reg;
+
+ /* Configure REFCLK period */
+ reg = readl(base + CFG_REG_2_OFFSET);
+ reg &= ~CFG_REG_REFCLK_PERIOD_MASK;
+ reg |= CFG_REG_REFCLK_PERIOD;
+ writel(reg, base + CFG_REG_2_OFFSET);
+
+ /* Initiate Calibration */
+ clrsetbits_le32(base + CFG_REG_0_OFFSET, CFG_REG_CALIB_STRT_MASK,
+ CFG_REG_CALIB_STRT << CFG_REG_CALIB_STRT_SHIFT);
+ if (!wait_on_value(CFG_REG_CALIB_STRT_MASK, CFG_REG_CALIB_END,
+ (u32 *)(base + CFG_REG_0_OFFSET), LDELAY))
+ return ERR_CALIBRATE_IODELAY;
+
+ return 0;
+}
+
+static int update_delay_mechanism(u32 base)
+{
+ /* Initiate the reload of calibrated values. */
+ clrsetbits_le32(base + CFG_REG_0_OFFSET, CFG_REG_ROM_READ_MASK,
+ CFG_REG_ROM_READ_START);
+ if (!wait_on_value(CFG_REG_ROM_READ_MASK, CFG_REG_ROM_READ_END,
+ (u32 *)(base + CFG_REG_0_OFFSET), LDELAY))
+ return ERR_UPDATE_DELAY;
+
+ return 0;
+}
+
+static u32 calculate_delay(u32 base, u16 offset, u16 den)
+{
+ u16 refclk_period, dly_cnt, ref_cnt;
+ u32 reg, q, r;
+
+ refclk_period = readl(base + CFG_REG_2_OFFSET) &
+ CFG_REG_REFCLK_PERIOD_MASK;
+
+ reg = readl(base + offset);
+ dly_cnt = (reg & CFG_REG_DLY_CNT_MASK) >> CFG_REG_DLY_CNT_SHIFT;
+ ref_cnt = (reg & CFG_REG_REF_CNT_MASK) >> CFG_REG_REF_CNT_SHIFT;
+
+ if (!dly_cnt || !den)
+ return 0;
+
+ /*
+ * To avoid overflow and integer truncation, delay value
+ * is calculated as quotient + remainder.
+ */
+ q = 5 * ((ref_cnt * refclk_period) / (dly_cnt * den));
+ r = (10 * ((ref_cnt * refclk_period) % (dly_cnt * den))) /
+ (2 * dly_cnt * den);
+
+ return q + r;
+}
+
+static u32 get_cfg_reg(u16 a_delay, u16 g_delay, u32 cpde, u32 fpde)
+{
+ u32 g_delay_coarse, g_delay_fine;
+ u32 a_delay_coarse, a_delay_fine;
+ u32 c_elements, f_elements;
+ u32 total_delay, reg = 0;
+
+ g_delay_coarse = g_delay / 920;
+ g_delay_fine = ((g_delay % 920) * 10) / 60;
+
+ a_delay_coarse = a_delay / cpde;
+ a_delay_fine = ((a_delay % cpde) * 10) / fpde;
+
+ c_elements = g_delay_coarse + a_delay_coarse;
+ f_elements = (g_delay_fine + a_delay_fine) / 10;
+
+ if (f_elements > 22) {
+ total_delay = c_elements * cpde + f_elements * fpde;
+
+ c_elements = total_delay / cpde;
+ f_elements = (total_delay % cpde) / fpde;
+ }
+
+ reg = (c_elements << CFG_X_COARSE_DLY_SHIFT) & CFG_X_COARSE_DLY_MASK;
+ reg |= (f_elements << CFG_X_FINE_DLY_SHIFT) & CFG_X_FINE_DLY_MASK;
+ reg |= CFG_X_SIGNATURE << CFG_X_SIGNATURE_SHIFT;
+ reg |= CFG_X_LOCK << CFG_X_LOCK_SHIFT;
+
+ return reg;
+}
+
+static int do_set_iodelay(u32 base, struct iodelay_cfg_entry const *array,
+ int niodelays)
+{
+ struct iodelay_cfg_entry *iodelay = (struct iodelay_cfg_entry *)array;
+ u32 reg, cpde, fpde, i;
+
+ if (!niodelays)
+ return 0;
+
+ cpde = calculate_delay((*ctrl)->iodelay_config_base, CFG_REG_3_OFFSET,
+ 88);
+ if (!cpde)
+ return ERR_CPDE;
+
+ fpde = calculate_delay((*ctrl)->iodelay_config_base, CFG_REG_4_OFFSET,
+ 264);
+ if (!fpde)
+ return ERR_FPDE;
+
+ for (i = 0; i < niodelays; i++, iodelay++) {
+ reg = get_cfg_reg(iodelay->a_delay, iodelay->g_delay, cpde,
+ fpde);
+ writel(reg, base + iodelay->offset);
+ }
+
+ return 0;
+}
+
+void __recalibrate_iodelay(struct pad_conf_entry const *pad, int npads,
+ struct iodelay_cfg_entry const *iodelay,
+ int niodelays)
+{
+ int ret = 0;
+
+ /* IO recalibration should be done only from SRAM */
+ if (OMAP_INIT_CONTEXT_SPL != omap_hw_init_context()) {
+ puts("IODELAY recalibration called from invalid context - use only from SPL in SRAM\n");
+ return;
+ }
+
+ /* unlock IODELAY CONFIG registers */
+ writel(CFG_IODELAY_UNLOCK_KEY, (*ctrl)->iodelay_config_base +
+ CFG_REG_8_OFFSET);
+
+ ret = calibrate_iodelay((*ctrl)->iodelay_config_base);
+ if (ret)
+ goto err;
+
+ ret = isolate_io(ISOLATE_IO);
+ if (ret)
+ goto err;
+
+ ret = update_delay_mechanism((*ctrl)->iodelay_config_base);
+ if (ret)
+ goto err;
+
+ /* Configure Mux settings */
+ do_set_mux32((*ctrl)->control_padconf_core_base, pad, npads);
+
+ /* Configure Manual IO timing modes */
+ ret = do_set_iodelay((*ctrl)->iodelay_config_base, iodelay, niodelays);
+ if (ret)
+ goto err;
+
+ ret = isolate_io(DEISOLATE_IO);
+
+err:
+ /* lock IODELAY CONFIG registers */
+ writel(CFG_IODELAY_LOCK_KEY, (*ctrl)->iodelay_config_base +
+ CFG_REG_8_OFFSET);
+ /*
+ * UART cannot be used during IO recalibration sequence as IOs are in
+ * isolation. So error handling and debug prints are done after
+ * complete IO delay recalibration sequence
+ */
+ switch (ret) {
+ case ERR_CALIBRATE_IODELAY:
+ puts("IODELAY: IO delay calibration sequence failed\n");
+ break;
+ case ERR_ISOLATE_IO:
+ puts("IODELAY: Isolation of Device IOs failed\n");
+ break;
+ case ERR_UPDATE_DELAY:
+ puts("IODELAY: Delay mechanism update with new calibrated values failed\n");
+ break;
+ case ERR_DEISOLATE_IO:
+ puts("IODELAY: De-isolation of Device IOs failed\n");
+ break;
+ case ERR_CPDE:
+ puts("IODELAY: CPDE calculation failed\n");
+ break;
+ case ERR_FPDE:
+ puts("IODELAY: FPDE calculation failed\n");
+ break;
+ default:
+ debug("IODELAY: IO delay recalibration successfully completed\n");
+ }
+}
diff --git a/arch/arm/cpu/armv7/omap5/hw_data.c b/arch/arm/cpu/armv7/omap5/hw_data.c
index 868415d038..3a723cace7 100644
--- a/arch/arm/cpu/armv7/omap5/hw_data.c
+++ b/arch/arm/cpu/armv7/omap5/hw_data.c
@@ -534,6 +534,9 @@ void enable_basic_clocks(void)
void enable_basic_uboot_clocks(void)
{
u32 const clk_domains_essential[] = {
+#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX)
+ (*prcm)->cm_ipu_clkstctrl,
+#endif
0
};
@@ -547,7 +550,11 @@ void enable_basic_uboot_clocks(void)
(*prcm)->cm_l4per_i2c2_clkctrl,
(*prcm)->cm_l4per_i2c3_clkctrl,
(*prcm)->cm_l4per_i2c4_clkctrl,
+#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX)
+ (*prcm)->cm_ipu_i2c5_clkctrl,
+#else
(*prcm)->cm_l4per_i2c5_clkctrl,
+#endif
(*prcm)->cm_l3init_hsusbhost_clkctrl,
(*prcm)->cm_l3init_fsusb_clkctrl,
0
@@ -592,8 +599,8 @@ const struct ctrl_ioregs ioregs_dra7xx_es1 = {
.ctrl_ddrch = 0x40404040,
.ctrl_lpddr2ch = 0x40404040,
.ctrl_ddr3ch = 0x80808080,
- .ctrl_ddrio_0 = 0xA2084210,
- .ctrl_ddrio_1 = 0x84210840,
+ .ctrl_ddrio_0 = 0x00094A40,
+ .ctrl_ddrio_1 = 0x04A52000,
.ctrl_ddrio_2 = 0x84210000,
.ctrl_emif_sdram_config_ext = 0x0001C1A7,
.ctrl_emif_sdram_config_ext_final = 0x0001C1A7,
@@ -604,8 +611,8 @@ const struct ctrl_ioregs ioregs_dra72x_es1 = {
.ctrl_ddrch = 0x40404040,
.ctrl_lpddr2ch = 0x40404040,
.ctrl_ddr3ch = 0x60606080,
- .ctrl_ddrio_0 = 0xA2084210,
- .ctrl_ddrio_1 = 0x84210840,
+ .ctrl_ddrio_0 = 0x00094A40,
+ .ctrl_ddrio_1 = 0x04A52000,
.ctrl_ddrio_2 = 0x84210000,
.ctrl_emif_sdram_config_ext = 0x0001C1A7,
.ctrl_emif_sdram_config_ext_final = 0x0001C1A7,
diff --git a/arch/arm/cpu/armv7/omap5/hwinit.c b/arch/arm/cpu/armv7/omap5/hwinit.c
index 8d6b59eeb0..39f8d0d5e2 100644
--- a/arch/arm/cpu/armv7/omap5/hwinit.c
+++ b/arch/arm/cpu/armv7/omap5/hwinit.c
@@ -40,6 +40,15 @@ static struct gpio_bank gpio_bank_54xx[8] = {
const struct gpio_bank *const omap_gpio_bank = gpio_bank_54xx;
+void do_set_mux32(u32 base, struct pad_conf_entry const *array, int size)
+{
+ int i;
+ struct pad_conf_entry *pad = (struct pad_conf_entry *)array;
+
+ for (i = 0; i < size; i++, pad++)
+ writel(pad->val, base + pad->offset);
+}
+
#ifdef CONFIG_SPL_BUILD
/* LPDDR2 specific IO settings */
static void io_settings_lpddr2(void)
@@ -75,16 +84,20 @@ static void io_settings_ddr3(void)
writel(ioregs->ctrl_ddrio_0, (*ctrl)->control_ddrio_0);
writel(ioregs->ctrl_ddrio_1, (*ctrl)->control_ddrio_1);
- writel(ioregs->ctrl_ddrio_2, (*ctrl)->control_ddrio_2);
+
+ if (!is_dra7xx()) {
+ writel(ioregs->ctrl_ddrio_2, (*ctrl)->control_ddrio_2);
+ writel(ioregs->ctrl_lpddr2ch, (*ctrl)->control_lpddr2ch1_1);
+ }
/* omap5432 does not use lpddr2 */
writel(ioregs->ctrl_lpddr2ch, (*ctrl)->control_lpddr2ch1_0);
- writel(ioregs->ctrl_lpddr2ch, (*ctrl)->control_lpddr2ch1_1);
writel(ioregs->ctrl_emif_sdram_config_ext,
(*ctrl)->control_emif1_sdram_config_ext);
- writel(ioregs->ctrl_emif_sdram_config_ext,
- (*ctrl)->control_emif2_sdram_config_ext);
+ if (!is_dra72x())
+ writel(ioregs->ctrl_emif_sdram_config_ext,
+ (*ctrl)->control_emif2_sdram_config_ext);
if (is_omap54xx()) {
/* Disable DLL select */
@@ -109,6 +122,7 @@ static void io_settings_ddr3(void)
void do_io_settings(void)
{
u32 io_settings = 0, mask = 0;
+ struct emif_reg_struct *emif = (struct emif_reg_struct *)EMIF1_BASE;
/* Impedance settings EMMC, C2C 1,2, hsi2 */
mask = (ds_mask << 2) | (ds_mask << 8) |
@@ -164,7 +178,7 @@ void do_io_settings(void)
(sc_fast << 17) | (sc_fast << 14);
writel(io_settings, (*ctrl)->control_smart3io_padconf_1);
- if (emif_sdram_type() == EMIF_SDRAM_TYPE_LPDDR2)
+ if (emif_sdram_type(emif->emif_sdram_config) == EMIF_SDRAM_TYPE_LPDDR2)
io_settings_lpddr2();
else
io_settings_ddr3();
diff --git a/arch/arm/cpu/armv7/omap5/prcm-regs.c b/arch/arm/cpu/armv7/omap5/prcm-regs.c
index f80d36dc3c..cd51fe7678 100644
--- a/arch/arm/cpu/armv7/omap5/prcm-regs.c
+++ b/arch/arm/cpu/armv7/omap5/prcm-regs.c
@@ -378,6 +378,7 @@ struct omap_sys_ctrl_regs const dra7xx_ctrl = {
.control_status = 0x4A002134,
.control_phy_power_usb = 0x4A002370,
.control_phy_power_sata = 0x4A002374,
+ .ctrl_core_sma_sw_0 = 0x4A0023FC,
.control_core_mac_id_0_lo = 0x4A002514,
.control_core_mac_id_0_hi = 0x4A002518,
.control_core_mac_id_1_lo = 0x4A00251C,
@@ -457,6 +458,7 @@ struct omap_sys_ctrl_regs const dra7xx_ctrl = {
.control_efuse_3 = 0x4AE0C5D0,
.control_efuse_4 = 0x4AE0C5D4,
.control_efuse_13 = 0x4AE0C5F0,
+ .iodelay_config_base = 0x4844A000,
};
struct prcm_regs const omap5_es2_prcm = {
@@ -815,6 +817,10 @@ struct prcm_regs const dra7xx_prcm = {
.cm_dsp_clkstctrl = 0x4a005400,
.cm_dsp_dsp_clkctrl = 0x4a005420,
+ /* cm IPU */
+ .cm_ipu_clkstctrl = 0x4a005540,
+ .cm_ipu_i2c5_clkctrl = 0x4a005578,
+
/* prm irqstatus regs */
.prm_irqstatus_mpu_2 = 0x4ae06014,
@@ -976,6 +982,7 @@ struct prcm_regs const dra7xx_prcm = {
.prm_rstctrl = 0x4ae07d00,
.prm_rstst = 0x4ae07d04,
.prm_rsttime = 0x4ae07d08,
+ .prm_io_pmctrl = 0x4ae07d20,
.prm_vc_val_bypass = 0x4ae07da0,
.prm_vc_cfg_i2c_mode = 0x4ae07db4,
.prm_vc_cfg_i2c_clk = 0x4ae07db8,
diff --git a/arch/arm/cpu/armv7/omap5/sdram.c b/arch/arm/cpu/armv7/omap5/sdram.c
index 5f8daa1ee1..cf4452d260 100644
--- a/arch/arm/cpu/armv7/omap5/sdram.c
+++ b/arch/arm/cpu/armv7/omap5/sdram.c
@@ -146,18 +146,18 @@ const struct emif_regs emif_1_regs_ddr3_532_mhz_1cs_dra_es1 = {
.sdram_tim1 = 0xCCCF36B3,
.sdram_tim2 = 0x308F7FDA,
.sdram_tim3 = 0x027F88A8,
- .read_idle_ctrl = 0x00050001,
+ .read_idle_ctrl = 0x00050000,
.zq_config = 0x0007190B,
.temp_alert_config = 0x00000000,
- .emif_ddr_phy_ctlr_1_init = 0x0E24400A,
- .emif_ddr_phy_ctlr_1 = 0x0E24400A,
+ .emif_ddr_phy_ctlr_1_init = 0x0024400B,
+ .emif_ddr_phy_ctlr_1 = 0x0E24400B,
.emif_ddr_ext_phy_ctrl_1 = 0x10040100,
.emif_ddr_ext_phy_ctrl_2 = 0x00910091,
.emif_ddr_ext_phy_ctrl_3 = 0x00950095,
.emif_ddr_ext_phy_ctrl_4 = 0x009B009B,
.emif_ddr_ext_phy_ctrl_5 = 0x009E009E,
.emif_rd_wr_lvl_rmp_win = 0x00000000,
- .emif_rd_wr_lvl_rmp_ctl = 0x00000000,
+ .emif_rd_wr_lvl_rmp_ctl = 0x80000000,
.emif_rd_wr_lvl_ctl = 0x00000000,
.emif_rd_wr_exec_thresh = 0x00000305
};
@@ -171,18 +171,18 @@ const struct emif_regs emif_2_regs_ddr3_532_mhz_1cs_dra_es1 = {
.sdram_tim1 = 0xCCCF36B3,
.sdram_tim2 = 0x308F7FDA,
.sdram_tim3 = 0x027F88A8,
- .read_idle_ctrl = 0x00050001,
+ .read_idle_ctrl = 0x00050000,
.zq_config = 0x0007190B,
.temp_alert_config = 0x00000000,
- .emif_ddr_phy_ctlr_1_init = 0x0E24400A,
- .emif_ddr_phy_ctlr_1 = 0x0E24400A,
+ .emif_ddr_phy_ctlr_1_init = 0x0024400B,
+ .emif_ddr_phy_ctlr_1 = 0x0E24400B,
.emif_ddr_ext_phy_ctrl_1 = 0x10040100,
.emif_ddr_ext_phy_ctrl_2 = 0x00910091,
.emif_ddr_ext_phy_ctrl_3 = 0x00950095,
.emif_ddr_ext_phy_ctrl_4 = 0x009B009B,
.emif_ddr_ext_phy_ctrl_5 = 0x009E009E,
.emif_rd_wr_lvl_rmp_win = 0x00000000,
- .emif_rd_wr_lvl_rmp_ctl = 0x00000000,
+ .emif_rd_wr_lvl_rmp_ctl = 0x80000000,
.emif_rd_wr_lvl_ctl = 0x00000000,
.emif_rd_wr_exec_thresh = 0x00000305
};
@@ -191,15 +191,15 @@ const struct emif_regs emif_1_regs_ddr3_666_mhz_1cs_dra_es1 = {
.sdram_config_init = 0x61862B32,
.sdram_config = 0x61862B32,
.sdram_config2 = 0x08000000,
- .ref_ctrl = 0x0000493E,
+ .ref_ctrl = 0x0000514C,
.ref_ctrl_final = 0x0000144A,
.sdram_tim1 = 0xD113781C,
- .sdram_tim2 = 0x308F7FE3,
- .sdram_tim3 = 0x009F86A8,
+ .sdram_tim2 = 0x305A7FDA,
+ .sdram_tim3 = 0x409F86A8,
.read_idle_ctrl = 0x00050000,
- .zq_config = 0x0007190B,
+ .zq_config = 0x5007190B,
.temp_alert_config = 0x00000000,
- .emif_ddr_phy_ctlr_1_init = 0x0E24400D,
+ .emif_ddr_phy_ctlr_1_init = 0x0024400D,
.emif_ddr_phy_ctlr_1 = 0x0E24400D,
.emif_ddr_ext_phy_ctrl_1 = 0x10040100,
.emif_ddr_ext_phy_ctrl_2 = 0x00A400A4,
@@ -207,7 +207,7 @@ const struct emif_regs emif_1_regs_ddr3_666_mhz_1cs_dra_es1 = {
.emif_ddr_ext_phy_ctrl_4 = 0x00B000B0,
.emif_ddr_ext_phy_ctrl_5 = 0x00B000B0,
.emif_rd_wr_lvl_rmp_win = 0x00000000,
- .emif_rd_wr_lvl_rmp_ctl = 0x00000000,
+ .emif_rd_wr_lvl_rmp_ctl = 0x80000000,
.emif_rd_wr_lvl_ctl = 0x00000000,
.emif_rd_wr_exec_thresh = 0x00000305
};
@@ -421,8 +421,14 @@ const u32 ddr3_ext_phy_ctrl_const_base_es2[] = {
0x0
};
+/* Ext phy ctrl 1-35 regs */
const u32
dra_ddr3_ext_phy_ctrl_const_base_es1_emif1[] = {
+ 0x10040100,
+ 0x00910091,
+ 0x00950095,
+ 0x009B009B,
+ 0x009E009E,
0x00980098,
0x00340034,
0x00350035,
@@ -441,17 +447,28 @@ dra_ddr3_ext_phy_ctrl_const_base_es1_emif1[] = {
0x00500050,
0x00000000,
0x00600020,
- 0x40010080,
+ 0x40011080,
0x08102040,
0x0,
0x0,
0x0,
0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
0x0
};
+/* Ext phy ctrl 1-35 regs */
const u32
dra_ddr3_ext_phy_ctrl_const_base_es1_emif2[] = {
+ 0x10040100,
+ 0x00910091,
+ 0x00950095,
+ 0x009B009B,
+ 0x009E009E,
0x00980098,
0x00330033,
0x00330033,
@@ -470,17 +487,28 @@ dra_ddr3_ext_phy_ctrl_const_base_es1_emif2[] = {
0x00500050,
0x00000000,
0x00600020,
- 0x40010080,
+ 0x40011080,
0x08102040,
0x0,
0x0,
0x0,
0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
0x0
};
+/* Ext phy ctrl 1-35 regs */
const u32
dra_ddr3_ext_phy_ctrl_const_base_666MHz[] = {
+ 0x10040100,
+ 0x00A400A4,
+ 0x00A900A9,
+ 0x00B000B0,
+ 0x00B000B0,
0x00A400A4,
0x00390039,
0x00320032,
@@ -505,6 +533,11 @@ dra_ddr3_ext_phy_ctrl_const_base_666MHz[] = {
0x0,
0x0,
0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
+ 0x0,
0x0
};
@@ -562,7 +595,7 @@ void get_lpddr2_mr_regs(const struct lpddr2_mr_regs **regs)
*regs = &mr_regs;
}
-void do_ext_phy_settings(u32 base, const struct emif_regs *regs)
+static void do_ext_phy_settings_omap5(u32 base, const struct emif_regs *regs)
{
u32 *ext_phy_ctrl_base = 0;
u32 *emif_ext_phy_ctrl_base = 0;
@@ -601,6 +634,58 @@ void do_ext_phy_settings(u32 base, const struct emif_regs *regs)
}
}
+static void do_ext_phy_settings_dra7(u32 base, const struct emif_regs *regs)
+{
+ struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
+ u32 *emif_ext_phy_ctrl_base = 0;
+ u32 emif_nr;
+ const u32 *ext_phy_ctrl_const_regs;
+ u32 i, hw_leveling, size;
+
+ emif_nr = (base == EMIF1_BASE) ? 1 : 2;
+
+ hw_leveling = regs->emif_rd_wr_lvl_rmp_ctl >> EMIF_REG_RDWRLVL_EN_SHIFT;
+
+ emif_ext_phy_ctrl_base = (u32 *)&(emif->emif_ddr_ext_phy_ctrl_1);
+
+ emif_get_ext_phy_ctrl_const_regs(emif_nr,
+ &ext_phy_ctrl_const_regs, &size);
+
+ writel(ext_phy_ctrl_const_regs[0], &emif_ext_phy_ctrl_base[0]);
+ writel(ext_phy_ctrl_const_regs[0], &emif_ext_phy_ctrl_base[1]);
+
+ if (!hw_leveling) {
+ /*
+ * Copy the predefined PHY register values
+ * in case of sw leveling
+ */
+ for (i = 1; i < 25; i++) {
+ writel(ext_phy_ctrl_const_regs[i],
+ &emif_ext_phy_ctrl_base[i * 2]);
+ writel(ext_phy_ctrl_const_regs[i],
+ &emif_ext_phy_ctrl_base[i * 2 + 1]);
+ }
+ } else {
+ /*
+ * Write the init value for HW levling to occur
+ */
+ for (i = 21; i < 35; i++) {
+ writel(ext_phy_ctrl_const_regs[i],
+ &emif_ext_phy_ctrl_base[i * 2]);
+ writel(ext_phy_ctrl_const_regs[i],
+ &emif_ext_phy_ctrl_base[i * 2 + 1]);
+ }
+ }
+}
+
+void do_ext_phy_settings(u32 base, const struct emif_regs *regs)
+{
+ if (is_omap54xx())
+ do_ext_phy_settings_omap5(base, regs);
+ else
+ do_ext_phy_settings_dra7(base, regs);
+}
+
#ifndef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS
static const struct lpddr2_ac_timings timings_jedec_532_mhz = {
.max_freq = 532000000,
diff --git a/arch/arm/cpu/armv7/s5pc1xx/Kconfig b/arch/arm/cpu/armv7/s5pc1xx/Kconfig
index 04acdaad79..792ef595e4 100644
--- a/arch/arm/cpu/armv7/s5pc1xx/Kconfig
+++ b/arch/arm/cpu/armv7/s5pc1xx/Kconfig
@@ -7,10 +7,12 @@ choice
config TARGET_S5P_GONI
bool "S5P Goni board"
select OF_CONTROL
+ select SPL_DISABLE_OF_CONTROL
config TARGET_SMDKC100
bool "Support smdkc100 board"
select OF_CONTROL
+ select SPL_DISABLE_OF_CONTROL
endchoice
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
index a82c8b9d44..03443629bc 100644
--- a/arch/arm/cpu/armv7/sunxi/board.c
+++ b/arch/arm/cpu/armv7/sunxi/board.c
@@ -119,20 +119,11 @@ void s_init(void)
#ifdef CONFIG_SPL_BUILD
/* The sunxi internal brom will try to loader external bootloader
* from mmc0, nand flash, mmc2.
- *
- * Unfortunately we can't check how SPL was loaded so assume it's
- * always the first SD/MMC controller, unless it was explicitly
- * stated that SPL is on nand flash.
+ * Unfortunately we can't check how SPL was loaded so assume
+ * it's always the first SD/MMC controller
*/
u32 spl_boot_device(void)
{
-#if defined(CONFIG_SPL_NAND_SUPPORT)
- /*
- * This is compile time configuration informing SPL, that it
- * was loaded from nand flash.
- */
- return BOOT_DEVICE_NAND;
-#else
/*
* When booting from the SD card, the "eGON.BT0" signature is expected
* to be found in memory at the address 0x0004 (see the "mksunxiboot"
@@ -153,7 +144,6 @@ u32 spl_boot_device(void)
return BOOT_DEVICE_MMC1;
else
return BOOT_DEVICE_BOARD;
-#endif
}
/* No confirmation data available in SPL yet. Hardcode bootmode */
@@ -202,6 +192,7 @@ void reset_cpu(ulong addr)
writel(WDT_CFG_RESET, &wdog->cfg);
writel(WDT_MODE_EN, &wdog->mode);
writel(WDT_CTRL_KEY | WDT_CTRL_RESTART, &wdog->ctl);
+ while (1) { }
#endif
}
@@ -223,6 +214,7 @@ int cpu_eth_init(bd_t *bis)
__maybe_unused int rc;
#ifdef CONFIG_MACPWR
+ gpio_request(CONFIG_MACPWR, "macpwr");
gpio_direction_output(CONFIG_MACPWR, 1);
mdelay(200);
#endif
diff --git a/arch/arm/cpu/armv7/sunxi/usb_phy.c b/arch/arm/cpu/armv7/sunxi/usb_phy.c
index 410669e548..b07d67ff3f 100644
--- a/arch/arm/cpu/armv7/sunxi/usb_phy.c
+++ b/arch/arm/cpu/armv7/sunxi/usb_phy.c
@@ -128,10 +128,10 @@ static void sunxi_usb_phy_config(struct sunxi_usb_phy *phy)
usb_phy_write(phy, 0x20, 0x14, 5);
/* threshold adjustment disconnect */
-#if defined CONFIG_MACH_SUN4I || defined CONFIG_MACH_SUN6I
- usb_phy_write(phy, 0x2a, 3, 2);
-#else
+#if defined CONFIG_MACH_SUN5I || defined CONFIG_MACH_SUN7I
usb_phy_write(phy, 0x2a, 2, 2);
+#else
+ usb_phy_write(phy, 0x2a, 3, 2);
#endif
return;
diff --git a/arch/arm/cpu/armv7/vf610/generic.c b/arch/arm/cpu/armv7/vf610/generic.c
index 1bb9b8ed1d..05c401dc73 100644
--- a/arch/arm/cpu/armv7/vf610/generic.c
+++ b/arch/arm/cpu/armv7/vf610/generic.c
@@ -198,6 +198,11 @@ static u32 get_i2c_clk(void)
return get_ipg_clk();
}
+static u32 get_dspi_clk(void)
+{
+ return get_ipg_clk();
+}
+
unsigned int mxc_get_clock(enum mxc_clock clk)
{
switch (clk) {
@@ -215,6 +220,8 @@ unsigned int mxc_get_clock(enum mxc_clock clk)
return get_fec_clk();
case MXC_I2C_CLK:
return get_i2c_clk();
+ case MXC_DSPI_CLK:
+ return get_dspi_clk();
default:
break;
}