[U-Boot] [PATCH 4/9 V9] Exynos5420: Add DDR3 initialization for 5420
Rajeshwari Birje
rajeshwari.birje at gmail.com
Mon Dec 9 09:11:30 CET 2013
Hi Minkyu Kang,
Please do find the comment bellow.
On Thu, Dec 5, 2013 at 12:55 PM, Rajeshwari Birje
<rajeshwari.birje at gmail.com> wrote:
> Hi Minkyu Kang,
>
> Thank you for comments.
>
> On Tue, Dec 3, 2013 at 11:45 AM, Minkyu Kang <mk7.kang at 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 at samsung.com>
>>> Signed-off-by: Akshay Saraswat <akshay.s at samsung.com>
>>> Acked-by: Simon Glass <sjg at 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 at lists.denx.de
>> http://lists.denx.de/mailman/listinfo/u-boot
>
> --
> Regards,
> Rajeshwari Shinde
More information about the U-Boot
mailing list