Hi Minkyu Kang, Please do find the comment bellow.
On Thu, Dec 5, 2013 at 12:55 PM, Rajeshwari Birje <rajeshwari.bi...@gmail.com> wrote: > Hi Minkyu Kang, > > Thank you for comments. > > On Tue, Dec 3, 2013 at 11:45 AM, Minkyu Kang <mk7.k...@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 <rajeshwar...@samsung.com> >>> Signed-off-by: Akshay Saraswat <aksha...@samsung.com> >>> Acked-by: Simon Glass <s...@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. -- Regards, Rajeshwari Shinde >>> +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_co5420n1); >>> + >>> + 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 > > -- > Regards, > Rajeshwari Shinde _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot