Re: [U-Boot] [PATCH 4/9 V9] Exynos5420: Add DDR3 initialization for 5420

Dear Rajeshwari S Shinde,
On 02/12/13 20:47, Rajeshwari S Shinde wrote:
This patch intends to add DDR3 initialization code for Exynos5420.
Signed-off-by: Rajeshwari S Shinde rajeshwari.s@samsung.com Signed-off-by: Akshay Saraswat akshay.s@samsung.com Acked-by: Simon Glass sjg@chromium.org
Changes in V2:
- Corrected a compilation issue for SMDK5250.
Changes in V3:
- None
Changes in V4:
- None
Changes in V5:
- None
Changes in V6:
- None
Changes in V7:
- Fixed multi line comment.
Changes in V8:
- None
Changes in V9:
- Used samsung_get base to get the dmc base address
arch/arm/cpu/armv7/exynos/dmc_common.c | 10 +- arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c | 425 +++++++++++++++++++++++++++++- arch/arm/cpu/armv7/exynos/exynos5_setup.h | 2 + arch/arm/include/asm/arch-exynos/cpu.h | 4 + arch/arm/include/asm/arch-exynos/dmc.h | 123 ++++++--- arch/arm/include/asm/arch-exynos/power.h | 6 + 6 files changed, 525 insertions(+), 45 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/dmc_common.c b/arch/arm/cpu/armv7/exynos/dmc_common.c index 53cfe6e..9e432c2 100644 --- a/arch/arm/cpu/armv7/exynos/dmc_common.c +++ b/arch/arm/cpu/armv7/exynos/dmc_common.c @@ -1,5 +1,5 @@ /*
- Mem setup common file for different types of DDR present on SMDK5250 boards.
- Mem setup common file for different types of DDR present on Exynos boards.
- Copyright (C) 2012 Samsung Electronics
@@ -152,14 +152,6 @@ void dmc_config_prech(struct mem_timings *mem, struct exynos5_dmc *dmc) } }
-void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc) -{
- writel(mem->memconfig, &dmc->memconfig0);
- writel(mem->memconfig, &dmc->memconfig1);
- writel(DMC_MEMBASECONFIG0_VAL, &dmc->membaseconfig0);
- writel(DMC_MEMBASECONFIG1_VAL, &dmc->membaseconfig1);
-}
void mem_ctrl_init(int reset) { struct spl_machine_param *param = spl_get_machine_params(); diff --git a/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c b/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c index 5f5914e..aa46a43 100644 --- a/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c +++ b/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c @@ -1,5 +1,5 @@ /*
- DDR3 mem setup file for SMDK5250 board based on EXYNOS5
- DDR3 mem setup file for board based on EXYNOS5
- Copyright (C) 2012 Samsung Electronics
@@ -11,12 +11,14 @@ #include <asm/arch/clock.h> #include <asm/arch/cpu.h> #include <asm/arch/dmc.h> +#include <asm/arch/power.h> #include "common_setup.h" #include "exynos5_setup.h" #include "clock_init.h"
-#define RDLVL_COMPLETE_TIMEOUT 10000 +#define TIMEOUT 10000
+#ifdef CONFIG_EXYNOS5250 static void reset_phy_ctrl(void) { struct exynos5_clock *clk = @@ -108,7 +110,7 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
/* Precharge Configuration */ writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
&dmc->prechconfig);
&dmc->prechconfig0);
/* Power Down mode Configuration */ writel(mem->dpwrdn_cyc << PWRDNCONFIG_DPWRDN_CYC_SHIFT |
@@ -174,7 +176,7 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size, writel(val, &phy1_ctrl->phy_con1);
writel(CTRL_RDLVL_GATE_ENABLE, &dmc->rdlvl_config);
i = RDLVL_COMPLETE_TIMEOUT;
while ((readl(&dmc->phystatus) & (RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1)) != (RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1) && i > 0) {i = TIMEOUT;
@@ -215,3 +217,418 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size, | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT), &dmc->concontrol); return 0; } +#endif
+#ifdef CONFIG_EXYNOS5420
we can avoid ifdef here.
int ddr3_mem_ctrl_init(...) { if (proid_is_exynos5250()) exynos5250_ddr3_mem_ctrl_init(); else exynos5420_ddr3_mem_ctrl_init(); }
+int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
int reset)
+{
- struct exynos5420_clock *clk =
(struct exynos5420_clock *)samsung_get_base_clock();
- struct exynos5_power *power =
(struct exynos5_power *)samsung_get_base_power();
- struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl;
- struct exynos5_dmc *drex0, *drex1;
- struct exynos5_tzasc *tzasc0, *tzasc1;
- uint32_t val, n_lock_r, n_lock_w_phy0, n_lock_w_phy1;
- int chip;
- int i;
- phy0_ctrl = (struct exynos5_phy_control *)samsung_get_base_dmc_phy();
- phy1_ctrl = (struct exynos5_phy_control *)(samsung_get_base_dmc_phy()
+ DMC_OFFSET);
- drex0 = (struct exynos5_dmc *)samsung_get_base_dmc_ctrl();
- drex1 = (struct exynos5_dmc *)(samsung_get_base_dmc_ctrl()
+ DMC_OFFSET);
- tzasc0 = (struct exynos5_tzasc *)samsung_get_base_dmc_tzasc0();
- tzasc1 = (struct exynos5_tzasc *)(samsung_get_base_dmc_tzasc0()
+ DMC_OFFSET);
- /* Enable PAUSE for DREX */
- setbits_le32(&clk->pause, ENABLE_BIT);
- /* Enable BYPASS mode */
- setbits_le32(&clk->bpll_con1, BYPASS_EN);
- writel(MUX_BPLL_SEL_FOUTBPLL, &clk->src_cdrex);
- do {
val = readl(&clk->mux_stat_cdrex);
val &= BPLL_SEL_MASK;
- } while (val != FOUTBPLL);
- clrbits_le32(&clk->bpll_con1, BYPASS_EN);
- /* Specify the DDR memory type as DDR3 */
- val = readl(&phy0_ctrl->phy_con0);
- val &= ~(PHY_CON0_CTRL_DDR_MODE_MASK << PHY_CON0_CTRL_DDR_MODE_SHIFT);
- val |= (DDR_MODE_DDR3 << PHY_CON0_CTRL_DDR_MODE_SHIFT);
- writel(val, &phy0_ctrl->phy_con0);
- val = readl(&phy1_ctrl->phy_con0);
- val &= ~(PHY_CON0_CTRL_DDR_MODE_MASK << PHY_CON0_CTRL_DDR_MODE_SHIFT);
- val |= (DDR_MODE_DDR3 << PHY_CON0_CTRL_DDR_MODE_SHIFT);
- writel(val, &phy1_ctrl->phy_con0);
- /* Set Read Latency and Burst Length for PHY0 and PHY1 */
- val = (mem->ctrl_bstlen << PHY_CON42_CTRL_BSTLEN_SHIFT) |
(mem->ctrl_rdlat << PHY_CON42_CTRL_RDLAT_SHIFT);
- writel(val, &phy0_ctrl->phy_con42);
- writel(val, &phy1_ctrl->phy_con42);
- val = readl(&phy0_ctrl->phy_con26);
- val &= ~(T_WRDATA_EN_MASK << T_WRDATA_EN_OFFSET);
- val |= (T_WRDATA_EN_DDR3 << T_WRDATA_EN_OFFSET);
- writel(val, &phy0_ctrl->phy_con26);
- val = readl(&phy1_ctrl->phy_con26);
- val &= ~(T_WRDATA_EN_MASK << T_WRDATA_EN_OFFSET);
- val |= (T_WRDATA_EN_DDR3 << T_WRDATA_EN_OFFSET);
- writel(val, &phy1_ctrl->phy_con26);
- /*
* Set Driver strength for CK, CKE, CS & CA to 0x7
* Set Driver strength for Data Slice 0~3 to 0x7
*/
- val = (0x7 << CA_CK_DRVR_DS_OFFSET) | (0x7 << CA_CKE_DRVR_DS_OFFSET) |
(0x7 << CA_CS_DRVR_DS_OFFSET) | (0x7 << CA_ADR_DRVR_DS_OFFSET);
- val |= (0x7 << DA_3_DS_OFFSET) | (0x7 << DA_2_DS_OFFSET) |
(0x7 << DA_1_DS_OFFSET) | (0x7 << DA_0_DS_OFFSET);
- writel(val, &phy0_ctrl->phy_con39);
- writel(val, &phy1_ctrl->phy_con39);
- /* ZQ Calibration */
- if (dmc_config_zq(mem, phy0_ctrl, phy1_ctrl))
return SETUP_ERR_ZQ_CALIBRATION_FAILURE;
- clrbits_le32(&phy0_ctrl->phy_con16, ZQ_CLK_DIV_EN);
- clrbits_le32(&phy1_ctrl->phy_con16, ZQ_CLK_DIV_EN);
- /* DQ Signal */
- val = readl(&phy0_ctrl->phy_con14);
- val |= mem->phy0_pulld_dqs;
- writel(val, &phy0_ctrl->phy_con14);
- val = readl(&phy1_ctrl->phy_con14);
- val |= mem->phy1_pulld_dqs;
- writel(val, &phy1_ctrl->phy_con14);
- val = MEM_TERM_EN | PHY_TERM_EN;
- writel(val, &drex0->phycontrol0);
- writel(val, &drex1->phycontrol0);
- writel(mem->concontrol |
(mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT) |
(mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT),
&drex0->concontrol);
- writel(mem->concontrol |
(mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT) |
(mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT),
&drex1->concontrol);
- do {
val = readl(&drex0->phystatus);
- } while ((val & DFI_INIT_COMPLETE) != DFI_INIT_COMPLETE);
- do {
val = readl(&drex1->phystatus);
- } while ((val & DFI_INIT_COMPLETE) != DFI_INIT_COMPLETE);
- clrbits_le32(&drex0->concontrol, DFI_INIT_START);
- clrbits_le32(&drex1->concontrol, DFI_INIT_START);
- update_reset_dll(drex0, DDR_MODE_DDR3);
- update_reset_dll(drex1, DDR_MODE_DDR3);
- /*
* Set Base Address:
* 0x2000_0000 ~ 0x5FFF_FFFF
* 0x6000_0000 ~ 0x9FFF_FFFF
*/
- /* MEMBASECONFIG0 */
- val = DMC_MEMBASECONFIGX_CHIP_BASE(DMC_CHIP_BASE_0) |
DMC_MEMBASECONFIGX_CHIP_MASK(DMC_CHIP_MASK);
- writel(val, &tzasc0->membaseconfig0);
- writel(val, &tzasc1->membaseconfig0);
- /* MEMBASECONFIG1 */
- val = DMC_MEMBASECONFIGX_CHIP_BASE(DMC_CHIP_BASE_1) |
DMC_MEMBASECONFIGX_CHIP_MASK(DMC_CHIP_MASK);
- writel(val, &tzasc0->membaseconfig1);
- writel(val, &tzasc1->membaseconfig1);
- /*
* Memory Channel Inteleaving Size
* Ares Channel interleaving = 128 bytes
*/
- /* MEMCONFIG0/1 */
- writel(mem->memconfig, &tzasc0->memconfig0);
- writel(mem->memconfig, &tzasc1->memconfig0);
- writel(mem->memconfig, &tzasc0->memconfig1);
- writel(mem->memconfig, &tzasc1->memconfig1);
- /* Precharge Configuration */
- writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
&drex0->prechconfig0);
- writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
&drex1->prechconfig0);
- /*
* TimingRow, TimingData, TimingPower and Timingaref
* values as per Memory AC parameters
*/
- writel(mem->timing_ref, &drex0->timingref);
- writel(mem->timing_ref, &drex1->timingref);
- writel(mem->timing_row, &drex0->timingrow);
- writel(mem->timing_row, &drex1->timingrow);
- writel(mem->timing_data, &drex0->timingdata);
- writel(mem->timing_data, &drex1->timingdata);
- writel(mem->timing_power, &drex0->timingpower);
- writel(mem->timing_power, &drex1->timingpower);
- if (reset) {
/*
* Send NOP, MRS and ZQINIT commands
* Sending MRS command will reset the DRAM. We should not be
* reseting the DRAM after resume, this will lead to memory
* corruption as DRAM content is lost after DRAM reset
*/
dmc_config_mrs(mem, drex0);
dmc_config_mrs(mem, drex1);
- } else {
/*
* During Suspend-Resume & S/W-Reset, as soon as PMU releases
* pad retention, CKE goes high. This causes memory contents
* not to be retained during DRAM initialization. Therfore,
* there is a new control register(0x100431e8[28]) which lets us
* release pad retention and retain the memory content until the
* initialization is complete.
*/
writel(PAD_RETENTION_DRAM_COREBLK_VAL,
&power->pad_retention_dram_coreblk_option);
do {
val = readl(&power->pad_retention_dram_status);
} while (val != 0x1);
/*
* CKE PAD retention disables DRAM self-refresh mode.
* Send auto refresh command for DRAM refresh.
*/
for (i = 0; i < 128; i++) {
for (chip = 0; chip < mem->chips_to_configure; chip++) {
writel(DIRECT_CMD_REFA |
(chip << DIRECT_CMD_CHIP_SHIFT),
&drex0->directcmd);
writel(DIRECT_CMD_REFA |
(chip << DIRECT_CMD_CHIP_SHIFT),
&drex1->directcmd);
}
}
- }
- if (mem->gate_leveling_enable) {
writel(PHY_CON0_RESET_VAL, &phy0_ctrl->phy_con0);
writel(PHY_CON0_RESET_VAL, &phy1_ctrl->phy_con0);
setbits_le32(&phy0_ctrl->phy_con0, P0_CMD_EN);
setbits_le32(&phy1_ctrl->phy_con0, P0_CMD_EN);
val = PHY_CON2_RESET_VAL;
val |= INIT_DESKEW_EN;
writel(val, &phy0_ctrl->phy_con2);
writel(val, &phy1_ctrl->phy_con2);
val = readl(&phy0_ctrl->phy_con1);
val |= (RDLVL_PASS_ADJ_VAL << RDLVL_PASS_ADJ_OFFSET);
writel(val, &phy0_ctrl->phy_con1);
val = readl(&phy1_ctrl->phy_con1);
val |= (RDLVL_PASS_ADJ_VAL << RDLVL_PASS_ADJ_OFFSET);
writel(val, &phy1_ctrl->phy_con1);
n_lock_r = readl(&phy0_ctrl->phy_con13);
n_lock_w_phy0 = (n_lock_r & CTRL_LOCK_COARSE_MASK) >> 2;
n_lock_r = readl(&phy0_ctrl->phy_con12);
n_lock_r &= ~CTRL_DLL_ON;
n_lock_r |= n_lock_w_phy0;
writel(n_lock_r, &phy0_ctrl->phy_con12);
n_lock_r = readl(&phy1_ctrl->phy_con13);
n_lock_w_phy1 = (n_lock_r & CTRL_LOCK_COARSE_MASK) >> 2;
n_lock_r = readl(&phy1_ctrl->phy_con12);
n_lock_r &= ~CTRL_DLL_ON;
n_lock_r |= n_lock_w_phy1;
writel(n_lock_r, &phy1_ctrl->phy_con12);
val = (0x3 << DIRECT_CMD_BANK_SHIFT) | 0x4;
for (chip = 0; chip < mem->chips_to_configure; chip++) {
writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
&drex0->directcmd);
writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
&drex1->directcmd);
}
setbits_le32(&phy0_ctrl->phy_con2, RDLVL_GATE_EN);
setbits_le32(&phy1_ctrl->phy_con2, RDLVL_GATE_EN);
setbits_le32(&phy0_ctrl->phy_con0, CTRL_SHGATE);
setbits_le32(&phy1_ctrl->phy_con0, CTRL_SHGATE);
val = readl(&phy0_ctrl->phy_con1);
val &= ~(CTRL_GATEDURADJ_MASK);
writel(val, &phy0_ctrl->phy_con1);
val = readl(&phy1_ctrl->phy_con1);
val &= ~(CTRL_GATEDURADJ_MASK);
writel(val, &phy1_ctrl->phy_con1);
writel(CTRL_RDLVL_GATE_ENABLE, &drex0->rdlvl_config);
i = TIMEOUT;
while (((readl(&drex0->phystatus) & RDLVL_COMPLETE_CHO) !=
RDLVL_COMPLETE_CHO) && (i > 0)) {
/*
* TODO(waihong): Comment on how long this take to
* timeout
*/
sdelay(100);
i--;
}
if (!i)
return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
writel(CTRL_RDLVL_GATE_DISABLE, &drex0->rdlvl_config);
writel(CTRL_RDLVL_GATE_ENABLE, &drex1->rdlvl_config);
i = TIMEOUT;
while (((readl(&drex1->phystatus) & RDLVL_COMPLETE_CHO) !=
RDLVL_COMPLETE_CHO) && (i > 0)) {
/*
* TODO(waihong): Comment on how long this take to
* timeout
*/
sdelay(100);
i--;
}
if (!i)
return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
writel(CTRL_RDLVL_GATE_DISABLE, &drex1->rdlvl_config);
writel(0, &phy0_ctrl->phy_con14);
writel(0, &phy1_ctrl->phy_con14);
val = (0x3 << DIRECT_CMD_BANK_SHIFT);
for (chip = 0; chip < mem->chips_to_configure; chip++) {
writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
&drex0->directcmd);
writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
&drex1->directcmd);
}
if (mem->read_leveling_enable) {
/* Set Read DQ Calibration */
val = (0x3 << DIRECT_CMD_BANK_SHIFT) | 0x4;
for (chip = 0; chip < mem->chips_to_configure; chip++) {
writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
&drex0->directcmd);
writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
&drex1->directcmd);
}
val = readl(&phy0_ctrl->phy_con1);
val |= READ_LEVELLING_DDR3;
writel(val, &phy0_ctrl->phy_con1);
val = readl(&phy1_ctrl->phy_con1);
val |= READ_LEVELLING_DDR3;
writel(val, &phy1_ctrl->phy_con1);
val = readl(&phy0_ctrl->phy_con2);
val |= (RDLVL_EN | RDLVL_INCR_ADJ);
writel(val, &phy0_ctrl->phy_con2);
val = readl(&phy1_ctrl->phy_con2);
val |= (RDLVL_EN | RDLVL_INCR_ADJ);
writel(val, &phy1_ctrl->phy_con2);
setbits_le32(&drex0->rdlvl_config,
CTRL_RDLVL_DATA_ENABLE);
i = TIMEOUT;
while (((readl(&drex0->phystatus) & RDLVL_COMPLETE_CHO)
!= RDLVL_COMPLETE_CHO) && (i > 0)) {
/*
* TODO(waihong): Comment on how long this take
* to timeout
*/
sdelay(100);
i--;
}
if (!i)
return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
clrbits_le32(&drex0->rdlvl_config,
CTRL_RDLVL_DATA_ENABLE);
setbits_le32(&drex1->rdlvl_config,
CTRL_RDLVL_DATA_ENABLE);
i = TIMEOUT;
while (((readl(&drex1->phystatus) & RDLVL_COMPLETE_CHO)
!= RDLVL_COMPLETE_CHO) && (i > 0)) {
/*
* TODO(waihong): Comment on how long this take
* to timeout
*/
sdelay(100);
i--;
}
if (!i)
return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
clrbits_le32(&drex1->rdlvl_config,
CTRL_RDLVL_DATA_ENABLE);
val = (0x3 << DIRECT_CMD_BANK_SHIFT);
for (chip = 0; chip < mem->chips_to_configure; chip++) {
writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
&drex0->directcmd);
writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
&drex1->directcmd);
}
update_reset_dll(drex0, DDR_MODE_DDR3);
update_reset_dll(drex1, DDR_MODE_DDR3);
}
/* Common Settings for Leveling */
val = PHY_CON12_RESET_VAL;
writel((val + n_lock_w_phy0), &phy0_ctrl->phy_con12);
writel((val + n_lock_w_phy1), &phy1_ctrl->phy_con12);
setbits_le32(&phy0_ctrl->phy_con2, DLL_DESKEW_EN);
setbits_le32(&phy1_ctrl->phy_con2, DLL_DESKEW_EN);
- }
- /* Send PALL command */
- dmc_config_prech(mem, drex0);
- dmc_config_prech(mem, drex1);
- writel(mem->memcontrol, &drex0->memcontrol);
- writel(mem->memcontrol, &drex1->memcontrol);
- /*
* Set DMC Concontrol: Enable auto-refresh counter, provide
* read data fetch cycles and enable DREX auto set powerdown
* for input buffer of I/O in none read memory state.
*/
- writel(mem->concontrol | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT) |
(mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)|
DMC_CONCONTROL_IO_PD_CON(0x2),
&drex0->concontrol);
- writel(mem->concontrol | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT) |
(mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)|
DMC_CONCONTROL_IO_PD_CON(0x2),
&drex1->concontrol);
- /*
* Enable Clock Gating Control for DMC
* this saves around 25 mw dmc power as compared to the power
* consumption without these bits enabled
*/
- setbits_le32(&drex0->cgcontrol, DMC_INTERNAL_CG);
- setbits_le32(&drex1->cgcontrol, DMC_INTERNAL_CG);
- return 0;
+} +#endif diff --git a/arch/arm/cpu/armv7/exynos/exynos5_setup.h b/arch/arm/cpu/armv7/exynos/exynos5_setup.h index c8d6515..42a7fb8 100644 --- a/arch/arm/cpu/armv7/exynos/exynos5_setup.h +++ b/arch/arm/cpu/armv7/exynos/exynos5_setup.h @@ -436,6 +436,7 @@ */ #ifndef CONFIG_SMDK5420
unnecessary blank line.
/* APLL_CON1 */ #define APLL_CON1_VAL (0x00203800)
@@ -696,6 +697,7 @@ #define CLK_DIV_CPERI1_VAL NOT_AVAILABLE
#else +#define PAD_RETENTION_DRAM_COREBLK_VAL 0x10000000
/* APLL_CON1 */ #define APLL_CON1_VAL (0x0020F300) diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h index 2b44210..2c642ba 100644 --- a/arch/arm/include/asm/arch-exynos/cpu.h +++ b/arch/arm/include/asm/arch-exynos/cpu.h @@ -53,6 +53,7 @@ #define EXYNOS4_AUDIOSS_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4_USB_HOST_XHCI_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4_USB3PHY_BASE DEVICE_NOT_AVAILABLE +#define EXYNOS4_DMC_TZASC0_BASE DEVICE_NOT_AVAILABLE
/* EXYNOS4X12 */ #define EXYNOS4X12_GPIO_PART3_BASE 0x03860000 @@ -91,6 +92,7 @@ #define EXYNOS4X12_AUDIOSS_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4X12_USB_HOST_XHCI_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4X12_USB3PHY_BASE DEVICE_NOT_AVAILABLE +#define EXYNOS4X12_DMC_TZASC0_BASE DEVICE_NOT_AVAILABLE
/* EXYNOS5 */ #define EXYNOS5_I2C_SPACING 0x10000 @@ -129,6 +131,7 @@
#define EXYNOS5_ADC_BASE DEVICE_NOT_AVAILABLE #define EXYNOS5_MODEM_BASE DEVICE_NOT_AVAILABLE +#define EXYNOS5_DMC_TZASC0_BASE DEVICE_NOT_AVAILABLE
/* EXYNOS5420 */ #define EXYNOS5420_AUDIOSS_BASE 0x03810000 @@ -284,6 +287,7 @@ SAMSUNG_BASE(spi_isp, SPI_ISP_BASE) SAMSUNG_BASE(tzpc, TZPC_BASE) SAMSUNG_BASE(dmc_ctrl, DMC_CTRL_BASE) SAMSUNG_BASE(dmc_phy, DMC_PHY_BASE) +SAMSUNG_BASE(dmc_tzasc0, DMC_TZASC0_BASE)
then do we need to define two base addresses for TZASC? you never use TZASC1.
SAMSUNG_BASE(audio_ass, AUDIOSS_BASE) #endif
diff --git a/arch/arm/include/asm/arch-exynos/dmc.h b/arch/arm/include/asm/arch-exynos/dmc.h index f65c676..0913299 100644 --- a/arch/arm/include/asm/arch-exynos/dmc.h +++ b/arch/arm/include/asm/arch-exynos/dmc.h @@ -114,13 +114,24 @@ struct exynos4_dmc { struct exynos5_dmc { unsigned int concontrol; unsigned int memcontrol;
+/*
- Between 5250 and 5420, the DMC Register differs only at 0x8 offset.
- So to use the same structure and simplify the code put a define to
- distinguish between memconfig0 and cgcontrol register
- */
+#ifdef CONFIG_EXYNOS5250
No. we don't allow ifdef.
unsigned int memconfig0; +#else
- unsigned int cgcontrol;
+#endif unsigned int memconfig1; unsigned int directcmd;
- unsigned int prechconfig;
- unsigned int prechconfig0; unsigned int phycontrol0;
- unsigned char res1[0xc];
- unsigned int pwrdnconfig;
- unsigned int prechconfig1;
- unsigned char res1[0x8];
- unsigned int pwrdnconfig; /* 0x0028*/ unsigned int timingpzq; unsigned int timingref; unsigned int timingrow;
@@ -128,12 +139,12 @@ struct exynos5_dmc { unsigned int timingpower; unsigned int phystatus; unsigned char res2[0x4];
- unsigned int chipstatus_ch0;
- unsigned int chipstatus_ch0; /* 0x0048 */ unsigned int chipstatus_ch1; unsigned char res3[0x4]; unsigned int mrstatus; unsigned char res4[0x8];
- unsigned int qoscontrol0;
- unsigned int qoscontrol0; /* 0x0060 */ unsigned char resr5[0x4]; unsigned int qoscontrol1; unsigned char res6[0x4];
@@ -164,45 +175,83 @@ struct exynos5_dmc { unsigned int qoscontrol14; unsigned char res19[0x4]; unsigned int qoscontrol15;
- unsigned char res20[0x14];
- unsigned char res20[0x4];
- unsigned int timing_set_sw; /* 0x00e0 */
- unsigned int timingrow1;
- unsigned int timingdata1;
- unsigned int timingpower1; unsigned int ivcontrol; unsigned int wrtra_config; unsigned int rdlvl_config;
- unsigned char res21[0x8];
- unsigned char res21[0x4];
- unsigned int brbrsvcontrol; /* 0x0100*/ unsigned int brbrsvconfig; unsigned int brbqosconfig; unsigned int membaseconfig0;
- unsigned int membaseconfig1;
- unsigned int membaseconfig1; /* 0x0110 */ unsigned char res22[0xc];
- unsigned int wrlvl_config;
- unsigned char res23[0xc];
- unsigned int perevcontrol;
- unsigned int wrlvl_config0; /* 0x0120 */
- unsigned int wrlvl_config1;
- unsigned int wrlvl_status;
- unsigned char res23[0x4];
- unsigned int perevcontrol; /* 0x0130 */ unsigned int perev0config; unsigned int perev1config; unsigned int perev2config; unsigned int perev3config;
- unsigned char res24[0xdebc];
- unsigned int pmnc_ppc_a;
- unsigned char res25[0xc];
- unsigned int cntens_ppc_a;
- unsigned char res26[0xc];
- unsigned int cntenc_ppc_a;
- unsigned char res27[0xc];
- unsigned int intens_ppc_a;
- unsigned char res28[0xc];
- unsigned int intenc_ppc_a;
- unsigned char res29[0xc];
- unsigned int flag_ppc_a;
- unsigned char res30[0xac];
- unsigned int ccnt_ppc_a;
- unsigned char res31[0xc];
- unsigned int pmcnt0_ppc_a;
- unsigned char res22a[0xc];
- unsigned int ctrl_io_rdata_ch0;
- unsigned int ctrl_io_rdata_ch1;
- unsigned char res23a[0x8];
- unsigned int cacal_config0;
- unsigned int cacal_config1;
- unsigned int cacal_status;
- unsigned char res24[0x94];
- unsigned int emergent_config0; /* 0x0200 */
- unsigned int emergent_config1;
- unsigned char res25[0x8];
- unsigned int bp_control0;
- unsigned int bp_control0_r;
- unsigned int bp_control0_w;
- unsigned char res26[0x4];
- unsigned int bp_control1;
- unsigned int bp_control1_r;
- unsigned int bp_control1_w;
- unsigned char res27[0x4];
- unsigned int bp_control2;
- unsigned int bp_control2_r;
- unsigned int bp_control2_w;
- unsigned char res28[0x4];
- unsigned int bp_control3;
- unsigned int bp_control3_r;
- unsigned int bp_control3_w;
- unsigned char res29[0xb4];
- unsigned int winconfig_odt_w; /* 0x0300 */
- unsigned char res30[0x4];
- unsigned int winconfig_ctrl_read;
- unsigned int winconfig_ctrl_gate;
- unsigned char res31[0xdcf0];
- unsigned int pmnc_ppc; unsigned char res32[0xc];
- unsigned int pmcnt1_ppc_a;
- unsigned int cntens_ppc; unsigned char res33[0xc];
- unsigned int pmcnt2_ppc_a;
- unsigned int cntenc_ppc; unsigned char res34[0xc];
- unsigned int pmcnt3_ppc_a;
- unsigned int intens_ppc;
- unsigned char res35[0xc];
- unsigned int intenc_ppc;
- unsigned char res36[0xc];
- unsigned int flag_ppc; /* 0xe050 */
- unsigned char res37[0xac];
- unsigned int ccnt_ppc;
- unsigned char res38[0xc];
- unsigned int pmcnt0_ppc;
- unsigned char res39[0xc];
- unsigned int pmcnt1_ppc;
- unsigned char res40[0xc];
- unsigned int pmcnt2_ppc;
- unsigned char res41[0xc];
- unsigned int pmcnt3_ppc; /* 0xe140 */
};
struct exynos5_phy_control { @@ -211,13 +260,13 @@ struct exynos5_phy_control { unsigned int phy_con2; unsigned int phy_con3; unsigned int phy_con4;
- unsigned char res1[4];
- unsigned int phy_con5; unsigned int phy_con6; unsigned char res2[4]; unsigned int phy_con8; unsigned int phy_con9; unsigned int phy_con10;
- unsigned char res3[4];
- unsigned int phy_con11; unsigned int phy_con12; unsigned int phy_con13; unsigned int phy_con14;
@@ -252,6 +301,15 @@ struct exynos5_phy_control { unsigned int phy_con42; };
+struct exynos5_tzasc {
- unsigned char res1[0xf00];
- unsigned int membaseconfig0;
- unsigned int membaseconfig1;
- unsigned char res2[0x8];
- unsigned int memconfig0;
- unsigned int memconfig1;
+};
enum ddr_mode { DDR_MODE_DDR2, DDR_MODE_DDR3, @@ -286,6 +344,7 @@ enum mem_manuf { #define PHY_CON0_T_WRRDCMD_SHIFT 17 #define PHY_CON0_T_WRRDCMD_MASK (0x7 << PHY_CON0_T_WRRDCMD_SHIFT) #define PHY_CON0_CTRL_DDR_MODE_SHIFT 11 +#define PHY_CON0_CTRL_DDR_MODE_MASK 0x3
/* PHY_CON1 register fields */ #define PHY_CON1_RDLVL_RDDATA_ADJ_SHIFT 0 diff --git a/arch/arm/include/asm/arch-exynos/power.h b/arch/arm/include/asm/arch-exynos/power.h index 8db18c5..6077fc3 100644 --- a/arch/arm/include/asm/arch-exynos/power.h +++ b/arch/arm/include/asm/arch-exynos/power.h @@ -690,9 +690,15 @@ struct exynos5_power { unsigned int pad_retention_spi_status; unsigned int pad_retention_spi_option; unsigned char res117[0x14];
- #ifdef CONFIG_EXYNOS5250
ditto.
unsigned int pad_retention_gpio_dmc_configuration; unsigned int pad_retention_gpio_dmc_status; unsigned int pad_retention_gpio_dmc_option;
- #else
- unsigned int pad_retention_dram_coreblk_configuration;
- unsigned int pad_retention_dram_coreblk_status;
- unsigned int pad_retention_dram_coreblk_option;
- #endif unsigned char res118[0x14]; unsigned int pad_isolation_configuration; unsigned int pad_isolation_status;
Thanks, Minkyu Kang.

Hi Minkyu Kang,
Thank you for comments.
On Tue, Dec 3, 2013 at 11:45 AM, Minkyu Kang mk7.kang@samsung.com wrote:
Dear Rajeshwari S Shinde,
On 02/12/13 20:47, Rajeshwari S Shinde wrote:
This patch intends to add DDR3 initialization code for Exynos5420.
Signed-off-by: Rajeshwari S Shinde rajeshwari.s@samsung.com Signed-off-by: Akshay Saraswat akshay.s@samsung.com Acked-by: Simon Glass sjg@chromium.org
Changes in V2: - Corrected a compilation issue for SMDK5250. Changes in V3: - None Changes in V4: - None Changes in V5: - None Changes in V6: - None Changes in V7: - Fixed multi line comment. Changes in V8: - None Changes in V9: - Used samsung_get base to get the dmc base address arch/arm/cpu/armv7/exynos/dmc_common.c | 10 +- arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c | 425 +++++++++++++++++++++++++++++- arch/arm/cpu/armv7/exynos/exynos5_setup.h | 2 + arch/arm/include/asm/arch-exynos/cpu.h | 4 + arch/arm/include/asm/arch-exynos/dmc.h | 123 ++++++--- arch/arm/include/asm/arch-exynos/power.h | 6 + 6 files changed, 525 insertions(+), 45 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/dmc_common.c b/arch/arm/cpu/armv7/exynos/dmc_common.c index 53cfe6e..9e432c2 100644 --- a/arch/arm/cpu/armv7/exynos/dmc_common.c +++ b/arch/arm/cpu/armv7/exynos/dmc_common.c @@ -1,5 +1,5 @@ /*
- Mem setup common file for different types of DDR present on SMDK5250 boards.
- Mem setup common file for different types of DDR present on Exynos boards.
- Copyright (C) 2012 Samsung Electronics
@@ -152,14 +152,6 @@ void dmc_config_prech(struct mem_timings *mem, struct exynos5_dmc *dmc) } }
-void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc) -{
writel(mem->memconfig, &dmc->memconfig0);
writel(mem->memconfig, &dmc->memconfig1);
writel(DMC_MEMBASECONFIG0_VAL, &dmc->membaseconfig0);
writel(DMC_MEMBASECONFIG1_VAL, &dmc->membaseconfig1);
-}
void mem_ctrl_init(int reset) { struct spl_machine_param *param = spl_get_machine_params(); diff --git a/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c b/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c index 5f5914e..aa46a43 100644 --- a/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c +++ b/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c @@ -1,5 +1,5 @@ /*
- DDR3 mem setup file for SMDK5250 board based on EXYNOS5
- DDR3 mem setup file for board based on EXYNOS5
- Copyright (C) 2012 Samsung Electronics
@@ -11,12 +11,14 @@ #include <asm/arch/clock.h> #include <asm/arch/cpu.h> #include <asm/arch/dmc.h> +#include <asm/arch/power.h> #include "common_setup.h" #include "exynos5_setup.h" #include "clock_init.h"
-#define RDLVL_COMPLETE_TIMEOUT 10000 +#define TIMEOUT 10000
+#ifdef CONFIG_EXYNOS5250 static void reset_phy_ctrl(void) { struct exynos5_clock *clk = @@ -108,7 +110,7 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
/* Precharge Configuration */ writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
&dmc->prechconfig);
&dmc->prechconfig0); /* Power Down mode Configuration */ writel(mem->dpwrdn_cyc << PWRDNCONFIG_DPWRDN_CYC_SHIFT |
@@ -174,7 +176,7 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size, writel(val, &phy1_ctrl->phy_con1);
writel(CTRL_RDLVL_GATE_ENABLE, &dmc->rdlvl_config);
i = RDLVL_COMPLETE_TIMEOUT;
i = TIMEOUT; while ((readl(&dmc->phystatus) & (RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1)) != (RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1) && i > 0) {
@@ -215,3 +217,418 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size, | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT), &dmc->concontrol); return 0; } +#endif
+#ifdef CONFIG_EXYNOS5420
we can avoid ifdef here.
int ddr3_mem_ctrl_init(...) { if (proid_is_exynos5250()) exynos5250_ddr3_mem_ctrl_init(); else exynos5420_ddr3_mem_ctrl_init(); }
Will do it this way
+int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
int reset)
+{
struct exynos5420_clock *clk =
(struct exynos5420_clock *)samsung_get_base_clock();
struct exynos5_power *power =
(struct exynos5_power *)samsung_get_base_power();
struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl;
struct exynos5_dmc *drex0, *drex1;
struct exynos5_tzasc *tzasc0, *tzasc1;
uint32_t val, n_lock_r, n_lock_w_phy0, n_lock_w_phy1;
int chip;
int i;
phy0_ctrl = (struct exynos5_phy_control *)samsung_get_base_dmc_phy();
phy1_ctrl = (struct exynos5_phy_control *)(samsung_get_base_dmc_phy()
+ DMC_OFFSET);
drex0 = (struct exynos5_dmc *)samsung_get_base_dmc_ctrl();
drex1 = (struct exynos5_dmc *)(samsung_get_base_dmc_ctrl()
+ DMC_OFFSET);
tzasc0 = (struct exynos5_tzasc *)samsung_get_base_dmc_tzasc0();
tzasc1 = (struct exynos5_tzasc *)(samsung_get_base_dmc_tzasc0()
+ DMC_OFFSET);
/* Enable PAUSE for DREX */
setbits_le32(&clk->pause, ENABLE_BIT);
/* Enable BYPASS mode */
setbits_le32(&clk->bpll_con1, BYPASS_EN);
writel(MUX_BPLL_SEL_FOUTBPLL, &clk->src_cdrex);
do {
val = readl(&clk->mux_stat_cdrex);
val &= BPLL_SEL_MASK;
} while (val != FOUTBPLL);
clrbits_le32(&clk->bpll_con1, BYPASS_EN);
/* Specify the DDR memory type as DDR3 */
val = readl(&phy0_ctrl->phy_con0);
val &= ~(PHY_CON0_CTRL_DDR_MODE_MASK << PHY_CON0_CTRL_DDR_MODE_SHIFT);
val |= (DDR_MODE_DDR3 << PHY_CON0_CTRL_DDR_MODE_SHIFT);
writel(val, &phy0_ctrl->phy_con0);
val = readl(&phy1_ctrl->phy_con0);
val &= ~(PHY_CON0_CTRL_DDR_MODE_MASK << PHY_CON0_CTRL_DDR_MODE_SHIFT);
val |= (DDR_MODE_DDR3 << PHY_CON0_CTRL_DDR_MODE_SHIFT);
writel(val, &phy1_ctrl->phy_con0);
/* Set Read Latency and Burst Length for PHY0 and PHY1 */
val = (mem->ctrl_bstlen << PHY_CON42_CTRL_BSTLEN_SHIFT) |
(mem->ctrl_rdlat << PHY_CON42_CTRL_RDLAT_SHIFT);
writel(val, &phy0_ctrl->phy_con42);
writel(val, &phy1_ctrl->phy_con42);
val = readl(&phy0_ctrl->phy_con26);
val &= ~(T_WRDATA_EN_MASK << T_WRDATA_EN_OFFSET);
val |= (T_WRDATA_EN_DDR3 << T_WRDATA_EN_OFFSET);
writel(val, &phy0_ctrl->phy_con26);
val = readl(&phy1_ctrl->phy_con26);
val &= ~(T_WRDATA_EN_MASK << T_WRDATA_EN_OFFSET);
val |= (T_WRDATA_EN_DDR3 << T_WRDATA_EN_OFFSET);
writel(val, &phy1_ctrl->phy_con26);
/*
* Set Driver strength for CK, CKE, CS & CA to 0x7
* Set Driver strength for Data Slice 0~3 to 0x7
*/
val = (0x7 << CA_CK_DRVR_DS_OFFSET) | (0x7 << CA_CKE_DRVR_DS_OFFSET) |
(0x7 << CA_CS_DRVR_DS_OFFSET) | (0x7 << CA_ADR_DRVR_DS_OFFSET);
val |= (0x7 << DA_3_DS_OFFSET) | (0x7 << DA_2_DS_OFFSET) |
(0x7 << DA_1_DS_OFFSET) | (0x7 << DA_0_DS_OFFSET);
writel(val, &phy0_ctrl->phy_con39);
writel(val, &phy1_ctrl->phy_con39);
/* ZQ Calibration */
if (dmc_config_zq(mem, phy0_ctrl, phy1_ctrl))
return SETUP_ERR_ZQ_CALIBRATION_FAILURE;
clrbits_le32(&phy0_ctrl->phy_con16, ZQ_CLK_DIV_EN);
clrbits_le32(&phy1_ctrl->phy_con16, ZQ_CLK_DIV_EN);
/* DQ Signal */
val = readl(&phy0_ctrl->phy_con14);
val |= mem->phy0_pulld_dqs;
writel(val, &phy0_ctrl->phy_con14);
val = readl(&phy1_ctrl->phy_con14);
val |= mem->phy1_pulld_dqs;
writel(val, &phy1_ctrl->phy_con14);
val = MEM_TERM_EN | PHY_TERM_EN;
writel(val, &drex0->phycontrol0);
writel(val, &drex1->phycontrol0);
writel(mem->concontrol |
(mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT) |
(mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT),
&drex0->concontrol);
writel(mem->concontrol |
(mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT) |
(mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT),
&drex1->concontrol);
do {
val = readl(&drex0->phystatus);
} while ((val & DFI_INIT_COMPLETE) != DFI_INIT_COMPLETE);
do {
val = readl(&drex1->phystatus);
} while ((val & DFI_INIT_COMPLETE) != DFI_INIT_COMPLETE);
clrbits_le32(&drex0->concontrol, DFI_INIT_START);
clrbits_le32(&drex1->concontrol, DFI_INIT_START);
update_reset_dll(drex0, DDR_MODE_DDR3);
update_reset_dll(drex1, DDR_MODE_DDR3);
/*
* Set Base Address:
* 0x2000_0000 ~ 0x5FFF_FFFF
* 0x6000_0000 ~ 0x9FFF_FFFF
*/
/* MEMBASECONFIG0 */
val = DMC_MEMBASECONFIGX_CHIP_BASE(DMC_CHIP_BASE_0) |
DMC_MEMBASECONFIGX_CHIP_MASK(DMC_CHIP_MASK);
writel(val, &tzasc0->membaseconfig0);
writel(val, &tzasc1->membaseconfig0);
/* MEMBASECONFIG1 */
val = DMC_MEMBASECONFIGX_CHIP_BASE(DMC_CHIP_BASE_1) |
DMC_MEMBASECONFIGX_CHIP_MASK(DMC_CHIP_MASK);
writel(val, &tzasc0->membaseconfig1);
writel(val, &tzasc1->membaseconfig1);
/*
* Memory Channel Inteleaving Size
* Ares Channel interleaving = 128 bytes
*/
/* MEMCONFIG0/1 */
writel(mem->memconfig, &tzasc0->memconfig0);
writel(mem->memconfig, &tzasc1->memconfig0);
writel(mem->memconfig, &tzasc0->memconfig1);
writel(mem->memconfig, &tzasc1->memconfig1);
/* Precharge Configuration */
writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
&drex0->prechconfig0);
writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
&drex1->prechconfig0);
/*
* TimingRow, TimingData, TimingPower and Timingaref
* values as per Memory AC parameters
*/
writel(mem->timing_ref, &drex0->timingref);
writel(mem->timing_ref, &drex1->timingref);
writel(mem->timing_row, &drex0->timingrow);
writel(mem->timing_row, &drex1->timingrow);
writel(mem->timing_data, &drex0->timingdata);
writel(mem->timing_data, &drex1->timingdata);
writel(mem->timing_power, &drex0->timingpower);
writel(mem->timing_power, &drex1->timingpower);
if (reset) {
/*
* Send NOP, MRS and ZQINIT commands
* Sending MRS command will reset the DRAM. We should not be
* reseting the DRAM after resume, this will lead to memory
* corruption as DRAM content is lost after DRAM reset
*/
dmc_config_mrs(mem, drex0);
dmc_config_mrs(mem, drex1);
} else {
/*
* During Suspend-Resume & S/W-Reset, as soon as PMU releases
* pad retention, CKE goes high. This causes memory contents
* not to be retained during DRAM initialization. Therfore,
* there is a new control register(0x100431e8[28]) which lets us
* release pad retention and retain the memory content until the
* initialization is complete.
*/
writel(PAD_RETENTION_DRAM_COREBLK_VAL,
&power->pad_retention_dram_coreblk_option);
do {
val = readl(&power->pad_retention_dram_status);
} while (val != 0x1);
/*
* CKE PAD retention disables DRAM self-refresh mode.
* Send auto refresh command for DRAM refresh.
*/
for (i = 0; i < 128; i++) {
for (chip = 0; chip < mem->chips_to_configure; chip++) {
writel(DIRECT_CMD_REFA |
(chip << DIRECT_CMD_CHIP_SHIFT),
&drex0->directcmd);
writel(DIRECT_CMD_REFA |
(chip << DIRECT_CMD_CHIP_SHIFT),
&drex1->directcmd);
}
}
}
if (mem->gate_leveling_enable) {
writel(PHY_CON0_RESET_VAL, &phy0_ctrl->phy_con0);
writel(PHY_CON0_RESET_VAL, &phy1_ctrl->phy_con0);
setbits_le32(&phy0_ctrl->phy_con0, P0_CMD_EN);
setbits_le32(&phy1_ctrl->phy_con0, P0_CMD_EN);
val = PHY_CON2_RESET_VAL;
val |= INIT_DESKEW_EN;
writel(val, &phy0_ctrl->phy_con2);
writel(val, &phy1_ctrl->phy_con2);
val = readl(&phy0_ctrl->phy_con1);
val |= (RDLVL_PASS_ADJ_VAL << RDLVL_PASS_ADJ_OFFSET);
writel(val, &phy0_ctrl->phy_con1);
val = readl(&phy1_ctrl->phy_con1);
val |= (RDLVL_PASS_ADJ_VAL << RDLVL_PASS_ADJ_OFFSET);
writel(val, &phy1_ctrl->phy_con1);
n_lock_r = readl(&phy0_ctrl->phy_con13);
n_lock_w_phy0 = (n_lock_r & CTRL_LOCK_COARSE_MASK) >> 2;
n_lock_r = readl(&phy0_ctrl->phy_con12);
n_lock_r &= ~CTRL_DLL_ON;
n_lock_r |= n_lock_w_phy0;
writel(n_lock_r, &phy0_ctrl->phy_con12);
n_lock_r = readl(&phy1_ctrl->phy_con13);
n_lock_w_phy1 = (n_lock_r & CTRL_LOCK_COARSE_MASK) >> 2;
n_lock_r = readl(&phy1_ctrl->phy_con12);
n_lock_r &= ~CTRL_DLL_ON;
n_lock_r |= n_lock_w_phy1;
writel(n_lock_r, &phy1_ctrl->phy_con12);
val = (0x3 << DIRECT_CMD_BANK_SHIFT) | 0x4;
for (chip = 0; chip < mem->chips_to_configure; chip++) {
writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
&drex0->directcmd);
writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
&drex1->directcmd);
}
setbits_le32(&phy0_ctrl->phy_con2, RDLVL_GATE_EN);
setbits_le32(&phy1_ctrl->phy_con2, RDLVL_GATE_EN);
setbits_le32(&phy0_ctrl->phy_con0, CTRL_SHGATE);
setbits_le32(&phy1_ctrl->phy_con0, CTRL_SHGATE);
val = readl(&phy0_ctrl->phy_con1);
val &= ~(CTRL_GATEDURADJ_MASK);
writel(val, &phy0_ctrl->phy_con1);
val = readl(&phy1_ctrl->phy_con1);
val &= ~(CTRL_GATEDURADJ_MASK);
writel(val, &phy1_ctrl->phy_con1);
writel(CTRL_RDLVL_GATE_ENABLE, &drex0->rdlvl_config);
i = TIMEOUT;
while (((readl(&drex0->phystatus) & RDLVL_COMPLETE_CHO) !=
RDLVL_COMPLETE_CHO) && (i > 0)) {
/*
* TODO(waihong): Comment on how long this take to
* timeout
*/
sdelay(100);
i--;
}
if (!i)
return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
writel(CTRL_RDLVL_GATE_DISABLE, &drex0->rdlvl_config);
writel(CTRL_RDLVL_GATE_ENABLE, &drex1->rdlvl_config);
i = TIMEOUT;
while (((readl(&drex1->phystatus) & RDLVL_COMPLETE_CHO) !=
RDLVL_COMPLETE_CHO) && (i > 0)) {
/*
* TODO(waihong): Comment on how long this take to
* timeout
*/
sdelay(100);
i--;
}
if (!i)
return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
writel(CTRL_RDLVL_GATE_DISABLE, &drex1->rdlvl_config);
writel(0, &phy0_ctrl->phy_con14);
writel(0, &phy1_ctrl->phy_con14);
val = (0x3 << DIRECT_CMD_BANK_SHIFT);
for (chip = 0; chip < mem->chips_to_configure; chip++) {
writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
&drex0->directcmd);
writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
&drex1->directcmd);
}
if (mem->read_leveling_enable) {
/* Set Read DQ Calibration */
val = (0x3 << DIRECT_CMD_BANK_SHIFT) | 0x4;
for (chip = 0; chip < mem->chips_to_configure; chip++) {
writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
&drex0->directcmd);
writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
&drex1->directcmd);
}
val = readl(&phy0_ctrl->phy_con1);
val |= READ_LEVELLING_DDR3;
writel(val, &phy0_ctrl->phy_con1);
val = readl(&phy1_ctrl->phy_con1);
val |= READ_LEVELLING_DDR3;
writel(val, &phy1_ctrl->phy_con1);
val = readl(&phy0_ctrl->phy_con2);
val |= (RDLVL_EN | RDLVL_INCR_ADJ);
writel(val, &phy0_ctrl->phy_con2);
val = readl(&phy1_ctrl->phy_con2);
val |= (RDLVL_EN | RDLVL_INCR_ADJ);
writel(val, &phy1_ctrl->phy_con2);
setbits_le32(&drex0->rdlvl_config,
CTRL_RDLVL_DATA_ENABLE);
i = TIMEOUT;
while (((readl(&drex0->phystatus) & RDLVL_COMPLETE_CHO)
!= RDLVL_COMPLETE_CHO) && (i > 0)) {
/*
* TODO(waihong): Comment on how long this take
* to timeout
*/
sdelay(100);
i--;
}
if (!i)
return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
clrbits_le32(&drex0->rdlvl_config,
CTRL_RDLVL_DATA_ENABLE);
setbits_le32(&drex1->rdlvl_config,
CTRL_RDLVL_DATA_ENABLE);
i = TIMEOUT;
while (((readl(&drex1->phystatus) & RDLVL_COMPLETE_CHO)
!= RDLVL_COMPLETE_CHO) && (i > 0)) {
/*
* TODO(waihong): Comment on how long this take
* to timeout
*/
sdelay(100);
i--;
}
if (!i)
return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
clrbits_le32(&drex1->rdlvl_config,
CTRL_RDLVL_DATA_ENABLE);
val = (0x3 << DIRECT_CMD_BANK_SHIFT);
for (chip = 0; chip < mem->chips_to_configure; chip++) {
writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
&drex0->directcmd);
writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
&drex1->directcmd);
}
update_reset_dll(drex0, DDR_MODE_DDR3);
update_reset_dll(drex1, DDR_MODE_DDR3);
}
/* Common Settings for Leveling */
val = PHY_CON12_RESET_VAL;
writel((val + n_lock_w_phy0), &phy0_ctrl->phy_con12);
writel((val + n_lock_w_phy1), &phy1_ctrl->phy_con12);
setbits_le32(&phy0_ctrl->phy_con2, DLL_DESKEW_EN);
setbits_le32(&phy1_ctrl->phy_con2, DLL_DESKEW_EN);
}
/* Send PALL command */
dmc_config_prech(mem, drex0);
dmc_config_prech(mem, drex1);
writel(mem->memcontrol, &drex0->memcontrol);
writel(mem->memcontrol, &drex1->memcontrol);
/*
* Set DMC Concontrol: Enable auto-refresh counter, provide
* read data fetch cycles and enable DREX auto set powerdown
* for input buffer of I/O in none read memory state.
*/
writel(mem->concontrol | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT) |
(mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)|
DMC_CONCONTROL_IO_PD_CON(0x2),
&drex0->concontrol);
writel(mem->concontrol | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT) |
(mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)|
DMC_CONCONTROL_IO_PD_CON(0x2),
&drex1->concontrol);
/*
* Enable Clock Gating Control for DMC
* this saves around 25 mw dmc power as compared to the power
* consumption without these bits enabled
*/
setbits_le32(&drex0->cgcontrol, DMC_INTERNAL_CG);
setbits_le32(&drex1->cgcontrol, DMC_INTERNAL_CG);
return 0;
+} +#endif diff --git a/arch/arm/cpu/armv7/exynos/exynos5_setup.h b/arch/arm/cpu/armv7/exynos/exynos5_setup.h index c8d6515..42a7fb8 100644 --- a/arch/arm/cpu/armv7/exynos/exynos5_setup.h +++ b/arch/arm/cpu/armv7/exynos/exynos5_setup.h @@ -436,6 +436,7 @@ */ #ifndef CONFIG_SMDK5420
unnecessary blank line.
will remove this
/* APLL_CON1 */ #define APLL_CON1_VAL (0x00203800)
@@ -696,6 +697,7 @@ #define CLK_DIV_CPERI1_VAL NOT_AVAILABLE
#else +#define PAD_RETENTION_DRAM_COREBLK_VAL 0x10000000
/* APLL_CON1 */ #define APLL_CON1_VAL (0x0020F300) diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h index 2b44210..2c642ba 100644 --- a/arch/arm/include/asm/arch-exynos/cpu.h +++ b/arch/arm/include/asm/arch-exynos/cpu.h @@ -53,6 +53,7 @@ #define EXYNOS4_AUDIOSS_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4_USB_HOST_XHCI_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4_USB3PHY_BASE DEVICE_NOT_AVAILABLE +#define EXYNOS4_DMC_TZASC0_BASE DEVICE_NOT_AVAILABLE
/* EXYNOS4X12 */ #define EXYNOS4X12_GPIO_PART3_BASE 0x03860000 @@ -91,6 +92,7 @@ #define EXYNOS4X12_AUDIOSS_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4X12_USB_HOST_XHCI_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4X12_USB3PHY_BASE DEVICE_NOT_AVAILABLE +#define EXYNOS4X12_DMC_TZASC0_BASE DEVICE_NOT_AVAILABLE
/* EXYNOS5 */ #define EXYNOS5_I2C_SPACING 0x10000 @@ -129,6 +131,7 @@
#define EXYNOS5_ADC_BASE DEVICE_NOT_AVAILABLE #define EXYNOS5_MODEM_BASE DEVICE_NOT_AVAILABLE +#define EXYNOS5_DMC_TZASC0_BASE DEVICE_NOT_AVAILABLE
/* EXYNOS5420 */ #define EXYNOS5420_AUDIOSS_BASE 0x03810000 @@ -284,6 +287,7 @@ SAMSUNG_BASE(spi_isp, SPI_ISP_BASE) SAMSUNG_BASE(tzpc, TZPC_BASE) SAMSUNG_BASE(dmc_ctrl, DMC_CTRL_BASE) SAMSUNG_BASE(dmc_phy, DMC_PHY_BASE) +SAMSUNG_BASE(dmc_tzasc0, DMC_TZASC0_BASE)
then do we need to define two base addresses for TZASC? you never use TZASC1.
Acessing base address for TZASC1 in following manner. Hence added only SAMSUNG_BASE(dmc_tzasc0, DMC_TZASC0_BASE) "tzasc1 = (struct exynos5_tzasc *)(samsung_get_base_dmc_tzasc0() + DMC_OFFSET);"
SAMSUNG_BASE(audio_ass, AUDIOSS_BASE) #endif
diff --git a/arch/arm/include/asm/arch-exynos/dmc.h b/arch/arm/include/asm/arch-exynos/dmc.h index f65c676..0913299 100644 --- a/arch/arm/include/asm/arch-exynos/dmc.h +++ b/arch/arm/include/asm/arch-exynos/dmc.h @@ -114,13 +114,24 @@ struct exynos4_dmc { struct exynos5_dmc { unsigned int concontrol; unsigned int memcontrol;
+/*
- Between 5250 and 5420, the DMC Register differs only at 0x8 offset.
- So to use the same structure and simplify the code put a define to
- distinguish between memconfig0 and cgcontrol register
- */
+#ifdef CONFIG_EXYNOS5250
No. we don't allow ifdef.
Will add separate structure for 5420
unsigned int memconfig0;
+#else
unsigned int cgcontrol;
+#endif unsigned int memconfig1; unsigned int directcmd;
unsigned int prechconfig;
unsigned int prechconfig0; unsigned int phycontrol0;
unsigned char res1[0xc];
unsigned int pwrdnconfig;
unsigned int prechconfig1;
unsigned char res1[0x8];
unsigned int pwrdnconfig; /* 0x0028*/ unsigned int timingpzq; unsigned int timingref; unsigned int timingrow;
@@ -128,12 +139,12 @@ struct exynos5_dmc { unsigned int timingpower; unsigned int phystatus; unsigned char res2[0x4];
unsigned int chipstatus_ch0;
unsigned int chipstatus_ch0; /* 0x0048 */ unsigned int chipstatus_ch1; unsigned char res3[0x4]; unsigned int mrstatus; unsigned char res4[0x8];
unsigned int qoscontrol0;
unsigned int qoscontrol0; /* 0x0060 */ unsigned char resr5[0x4]; unsigned int qoscontrol1; unsigned char res6[0x4];
@@ -164,45 +175,83 @@ struct exynos5_dmc { unsigned int qoscontrol14; unsigned char res19[0x4]; unsigned int qoscontrol15;
unsigned char res20[0x14];
unsigned char res20[0x4];
unsigned int timing_set_sw; /* 0x00e0 */
unsigned int timingrow1;
unsigned int timingdata1;
unsigned int timingpower1; unsigned int ivcontrol; unsigned int wrtra_config; unsigned int rdlvl_config;
unsigned char res21[0x8];
unsigned char res21[0x4];
unsigned int brbrsvcontrol; /* 0x0100*/ unsigned int brbrsvconfig; unsigned int brbqosconfig; unsigned int membaseconfig0;
unsigned int membaseconfig1;
unsigned int membaseconfig1; /* 0x0110 */ unsigned char res22[0xc];
unsigned int wrlvl_config;
unsigned char res23[0xc];
unsigned int perevcontrol;
unsigned int wrlvl_config0; /* 0x0120 */
unsigned int wrlvl_config1;
unsigned int wrlvl_status;
unsigned char res23[0x4];
unsigned int perevcontrol; /* 0x0130 */ unsigned int perev0config; unsigned int perev1config; unsigned int perev2config; unsigned int perev3config;
unsigned char res24[0xdebc];
unsigned int pmnc_ppc_a;
unsigned char res25[0xc];
unsigned int cntens_ppc_a;
unsigned char res26[0xc];
unsigned int cntenc_ppc_a;
unsigned char res27[0xc];
unsigned int intens_ppc_a;
unsigned char res28[0xc];
unsigned int intenc_ppc_a;
unsigned char res29[0xc];
unsigned int flag_ppc_a;
unsigned char res30[0xac];
unsigned int ccnt_ppc_a;
unsigned char res31[0xc];
unsigned int pmcnt0_ppc_a;
unsigned char res22a[0xc];
unsigned int ctrl_io_rdata_ch0;
unsigned int ctrl_io_rdata_ch1;
unsigned char res23a[0x8];
unsigned int cacal_config0;
unsigned int cacal_config1;
unsigned int cacal_status;
unsigned char res24[0x94];
unsigned int emergent_config0; /* 0x0200 */
unsigned int emergent_config1;
unsigned char res25[0x8];
unsigned int bp_control0;
unsigned int bp_control0_r;
unsigned int bp_control0_w;
unsigned char res26[0x4];
unsigned int bp_control1;
unsigned int bp_control1_r;
unsigned int bp_control1_w;
unsigned char res27[0x4];
unsigned int bp_control2;
unsigned int bp_control2_r;
unsigned int bp_control2_w;
unsigned char res28[0x4];
unsigned int bp_control3;
unsigned int bp_control3_r;
unsigned int bp_control3_w;
unsigned char res29[0xb4];
unsigned int winconfig_odt_w; /* 0x0300 */
unsigned char res30[0x4];
unsigned int winconfig_ctrl_read;
unsigned int winconfig_ctrl_gate;
unsigned char res31[0xdcf0];
unsigned int pmnc_ppc; unsigned char res32[0xc];
unsigned int pmcnt1_ppc_a;
unsigned int cntens_ppc; unsigned char res33[0xc];
unsigned int pmcnt2_ppc_a;
unsigned int cntenc_ppc; unsigned char res34[0xc];
unsigned int pmcnt3_ppc_a;
unsigned int intens_ppc;
unsigned char res35[0xc];
unsigned int intenc_ppc;
unsigned char res36[0xc];
unsigned int flag_ppc; /* 0xe050 */
unsigned char res37[0xac];
unsigned int ccnt_ppc;
unsigned char res38[0xc];
unsigned int pmcnt0_ppc;
unsigned char res39[0xc];
unsigned int pmcnt1_ppc;
unsigned char res40[0xc];
unsigned int pmcnt2_ppc;
unsigned char res41[0xc];
unsigned int pmcnt3_ppc; /* 0xe140 */
};
struct exynos5_phy_control { @@ -211,13 +260,13 @@ struct exynos5_phy_control { unsigned int phy_con2; unsigned int phy_con3; unsigned int phy_con4;
unsigned char res1[4];
unsigned int phy_con5; unsigned int phy_con6; unsigned char res2[4]; unsigned int phy_con8; unsigned int phy_con9; unsigned int phy_con10;
unsigned char res3[4];
unsigned int phy_con11; unsigned int phy_con12; unsigned int phy_con13; unsigned int phy_con14;
@@ -252,6 +301,15 @@ struct exynos5_phy_control { unsigned int phy_con42; };
+struct exynos5_tzasc {
unsigned char res1[0xf00];
unsigned int membaseconfig0;
unsigned int membaseconfig1;
unsigned char res2[0x8];
unsigned int memconfig0;
unsigned int memconfig1;
+};
enum ddr_mode { DDR_MODE_DDR2, DDR_MODE_DDR3, @@ -286,6 +344,7 @@ enum mem_manuf { #define PHY_CON0_T_WRRDCMD_SHIFT 17 #define PHY_CON0_T_WRRDCMD_MASK (0x7 << PHY_CON0_T_WRRDCMD_SHIFT) #define PHY_CON0_CTRL_DDR_MODE_SHIFT 11 +#define PHY_CON0_CTRL_DDR_MODE_MASK 0x3
/* PHY_CON1 register fields */ #define PHY_CON1_RDLVL_RDDATA_ADJ_SHIFT 0 diff --git a/arch/arm/include/asm/arch-exynos/power.h b/arch/arm/include/asm/arch-exynos/power.h index 8db18c5..6077fc3 100644 --- a/arch/arm/include/asm/arch-exynos/power.h +++ b/arch/arm/include/asm/arch-exynos/power.h @@ -690,9 +690,15 @@ struct exynos5_power { unsigned int pad_retention_spi_status; unsigned int pad_retention_spi_option; unsigned char res117[0x14];
#ifdef CONFIG_EXYNOS5250
ditto.
Will add separate structure for 5420
unsigned int pad_retention_gpio_dmc_configuration; unsigned int pad_retention_gpio_dmc_status; unsigned int pad_retention_gpio_dmc_option;
#else
unsigned int pad_retention_dram_coreblk_configuration;
unsigned int pad_retention_dram_coreblk_status;
unsigned int pad_retention_dram_coreblk_option;
#endif unsigned char res118[0x14]; unsigned int pad_isolation_configuration; unsigned int pad_isolation_status;
Thanks, Minkyu Kang. _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On 05/12/13 16:25, Rajeshwari Birje wrote:
Hi Minkyu Kang,
Thank you for comments.
On Tue, Dec 3, 2013 at 11:45 AM, Minkyu Kang mk7.kang@samsung.com wrote:
Dear Rajeshwari S Shinde,
On 02/12/13 20:47, Rajeshwari S Shinde wrote:
This patch intends to add DDR3 initialization code for Exynos5420.
Signed-off-by: Rajeshwari S Shinde rajeshwari.s@samsung.com Signed-off-by: Akshay Saraswat akshay.s@samsung.com Acked-by: Simon Glass sjg@chromium.org
Changes in V2: - Corrected a compilation issue for SMDK5250. Changes in V3: - None Changes in V4: - None Changes in V5: - None Changes in V6: - None Changes in V7: - Fixed multi line comment. Changes in V8: - None Changes in V9: - Used samsung_get base to get the dmc base address arch/arm/cpu/armv7/exynos/dmc_common.c | 10 +- arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c | 425 +++++++++++++++++++++++++++++- arch/arm/cpu/armv7/exynos/exynos5_setup.h | 2 + arch/arm/include/asm/arch-exynos/cpu.h | 4 + arch/arm/include/asm/arch-exynos/dmc.h | 123 ++++++--- arch/arm/include/asm/arch-exynos/power.h | 6 + 6 files changed, 525 insertions(+), 45 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/exynos5_setup.h b/arch/arm/cpu/armv7/exynos/exynos5_setup.h index c8d6515..42a7fb8 100644 --- a/arch/arm/cpu/armv7/exynos/exynos5_setup.h +++ b/arch/arm/cpu/armv7/exynos/exynos5_setup.h @@ -436,6 +436,7 @@ */ #ifndef CONFIG_SMDK5420
unnecessary blank line.
will remove this
/* APLL_CON1 */ #define APLL_CON1_VAL (0x00203800)
@@ -696,6 +697,7 @@ #define CLK_DIV_CPERI1_VAL NOT_AVAILABLE
#else +#define PAD_RETENTION_DRAM_COREBLK_VAL 0x10000000
/* APLL_CON1 */ #define APLL_CON1_VAL (0x0020F300) diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h index 2b44210..2c642ba 100644 --- a/arch/arm/include/asm/arch-exynos/cpu.h +++ b/arch/arm/include/asm/arch-exynos/cpu.h @@ -53,6 +53,7 @@ #define EXYNOS4_AUDIOSS_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4_USB_HOST_XHCI_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4_USB3PHY_BASE DEVICE_NOT_AVAILABLE +#define EXYNOS4_DMC_TZASC0_BASE DEVICE_NOT_AVAILABLE
/* EXYNOS4X12 */ #define EXYNOS4X12_GPIO_PART3_BASE 0x03860000 @@ -91,6 +92,7 @@ #define EXYNOS4X12_AUDIOSS_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4X12_USB_HOST_XHCI_BASE DEVICE_NOT_AVAILABLE #define EXYNOS4X12_USB3PHY_BASE DEVICE_NOT_AVAILABLE +#define EXYNOS4X12_DMC_TZASC0_BASE DEVICE_NOT_AVAILABLE
/* EXYNOS5 */ #define EXYNOS5_I2C_SPACING 0x10000 @@ -129,6 +131,7 @@
#define EXYNOS5_ADC_BASE DEVICE_NOT_AVAILABLE #define EXYNOS5_MODEM_BASE DEVICE_NOT_AVAILABLE +#define EXYNOS5_DMC_TZASC0_BASE DEVICE_NOT_AVAILABLE
/* EXYNOS5420 */ #define EXYNOS5420_AUDIOSS_BASE 0x03810000 @@ -284,6 +287,7 @@ SAMSUNG_BASE(spi_isp, SPI_ISP_BASE) SAMSUNG_BASE(tzpc, TZPC_BASE) SAMSUNG_BASE(dmc_ctrl, DMC_CTRL_BASE) SAMSUNG_BASE(dmc_phy, DMC_PHY_BASE) +SAMSUNG_BASE(dmc_tzasc0, DMC_TZASC0_BASE)
then do we need to define two base addresses for TZASC? you never use TZASC1.
Acessing base address for TZASC1 in following manner. Hence added only SAMSUNG_BASE(dmc_tzasc0, DMC_TZASC0_BASE) "tzasc1 = (struct exynos5_tzasc *)(samsung_get_base_dmc_tzasc0() + DMC_OFFSET);"
Yes, so my suggestion is defining TZASC only.
#define EXYNOS5420_DMC_TZASC_BASE 0x10D40000 SAMSUNG_BASE(dmc_tzasc, DMC_TZASC_BASE)
SAMSUNG_BASE(audio_ass, AUDIOSS_BASE) #endif
Thanks, Minkyu Kang.

Hi Minkyu Kang,
Please do find the comment bellow.
On Thu, Dec 5, 2013 at 12:55 PM, Rajeshwari Birje rajeshwari.birje@gmail.com wrote:
Hi Minkyu Kang,
Thank you for comments.
On Tue, Dec 3, 2013 at 11:45 AM, Minkyu Kang mk7.kang@samsung.com wrote:
Dear Rajeshwari S Shinde,
On 02/12/13 20:47, Rajeshwari S Shinde wrote:
This patch intends to add DDR3 initialization code for Exynos5420.
Signed-off-by: Rajeshwari S Shinde rajeshwari.s@samsung.com Signed-off-by: Akshay Saraswat akshay.s@samsung.com Acked-by: Simon Glass sjg@chromium.org
Changes in V2: - Corrected a compilation issue for SMDK5250. Changes in V3: - None Changes in V4: - None Changes in V5: - None Changes in V6: - None Changes in V7: - Fixed multi line comment. Changes in V8: - None Changes in V9: - Used samsung_get base to get the dmc base address arch/arm/cpu/armv7/exynos/dmc_common.c | 10 +- arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c | 425 +++++++++++++++++++++++++++++- arch/arm/cpu/armv7/exynos/exynos5_setup.h | 2 + arch/arm/include/asm/arch-exynos/cpu.h | 4 + arch/arm/include/asm/arch-exynos/dmc.h | 123 ++++++--- arch/arm/include/asm/arch-exynos/power.h | 6 + 6 files changed, 525 insertions(+), 45 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/dmc_common.c b/arch/arm/cpu/armv7/exynos/dmc_common.c index 53cfe6e..9e432c2 100644 --- a/arch/arm/cpu/armv7/exynos/dmc_common.c +++ b/arch/arm/cpu/armv7/exynos/dmc_common.c @@ -1,5 +1,5 @@ /*
- Mem setup common file for different types of DDR present on SMDK5250 boards.
- Mem setup common file for different types of DDR present on Exynos boards.
- Copyright (C) 2012 Samsung Electronics
@@ -152,14 +152,6 @@ void dmc_config_prech(struct mem_timings *mem, struct exynos5_dmc *dmc) } }
-void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc) -{
writel(mem->memconfig, &dmc->memconfig0);
writel(mem->memconfig, &dmc->memconfig1);
writel(DMC_MEMBASECONFIG0_VAL, &dmc->membaseconfig0);
writel(DMC_MEMBASECONFIG1_VAL, &dmc->membaseconfig1);
-}
void mem_ctrl_init(int reset) { struct spl_machine_param *param = spl_get_machine_params(); diff --git a/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c b/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c index 5f5914e..aa46a43 100644 --- a/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c +++ b/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c @@ -1,5 +1,5 @@ /*
- DDR3 mem setup file for SMDK5250 board based on EXYNOS5
- DDR3 mem setup file for board based on EXYNOS5
- Copyright (C) 2012 Samsung Electronics
@@ -11,12 +11,14 @@ #include <asm/arch/clock.h> #include <asm/arch/cpu.h> #include <asm/arch/dmc.h> +#include <asm/arch/power.h> #include "common_setup.h" #include "exynos5_setup.h" #include "clock_init.h"
-#define RDLVL_COMPLETE_TIMEOUT 10000 +#define TIMEOUT 10000
+#ifdef CONFIG_EXYNOS5250 static void reset_phy_ctrl(void) { struct exynos5_clock *clk = @@ -108,7 +110,7 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
/* Precharge Configuration */ writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
&dmc->prechconfig);
&dmc->prechconfig0); /* Power Down mode Configuration */ writel(mem->dpwrdn_cyc << PWRDNCONFIG_DPWRDN_CYC_SHIFT |
@@ -174,7 +176,7 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size, writel(val, &phy1_ctrl->phy_con1);
writel(CTRL_RDLVL_GATE_ENABLE, &dmc->rdlvl_config);
i = RDLVL_COMPLETE_TIMEOUT;
i = TIMEOUT; while ((readl(&dmc->phystatus) & (RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1)) != (RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1) && i > 0) {
@@ -215,3 +217,418 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size, | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT), &dmc->concontrol); return 0; } +#endif
+#ifdef CONFIG_EXYNOS5420
we can avoid ifdef here.
int ddr3_mem_ctrl_init(...) { if (proid_is_exynos5250()) exynos5250_ddr3_mem_ctrl_init(); else exynos5420_ddr3_mem_ctrl_init(); }
Will do it this way
Doing it this way increases the spl size. hence will keep the #ifdef defines.
participants (2)
-
Minkyu Kang
-
Rajeshwari Birje