blob: a187f6e090dd073d4c61ab6feeab5892b3d80828 [file] [log] [blame]
Patrick Georgiafd4c872020-05-05 23:43:18 +02001/* DDR3 mem setup file for EXYNOS5 based board */
Patrick Georgiac959032020-05-05 22:49:26 +02002/* SPDX-License-Identifier: GPL-2.0-or-later */
Gabe Black607c0b62013-05-16 05:45:57 -07003
Kyösti Mälkki13f66502019-03-03 08:01:05 +02004#include <device/mmio.h>
Julius Werner80af4422014-10-20 13:18:56 -07005#include <delay.h>
6#include <soc/clk.h>
7#include <soc/dmc.h>
8#include <soc/power.h>
9#include <soc/setup.h>
Gabe Black607c0b62013-05-16 05:45:57 -070010
Ronald G. Minniche6af9292013-06-03 13:03:50 -070011#define TIMEOUT 10000
Gabe Black607c0b62013-05-16 05:45:57 -070012
Ronald G. Minniche6af9292013-06-03 13:03:50 -070013/* 'reset' field is currently ignored. */
14
15int ddr3_mem_ctrl_init(struct mem_timings *mem, int interleave_size, int reset)
Gabe Black607c0b62013-05-16 05:45:57 -070016{
Ronald G. Minniche6af9292013-06-03 13:03:50 -070017 u32 val, nLockR, nLockW_phy0, nLockW_phy1;
David Hendricks72a42882013-08-23 15:25:07 -070018 int i, chip;
Gabe Black607c0b62013-05-16 05:45:57 -070019
Ronald G. Minniche6af9292013-06-03 13:03:50 -070020 /* Enable PAUSE for DREX */
Julius Werner55009af2019-12-02 22:03:27 -080021 setbits32(&exynos_clock->pause, ENABLE_BIT);
Gabe Black607c0b62013-05-16 05:45:57 -070022
Ronald G. Minniche6af9292013-06-03 13:03:50 -070023 /* Enable BYPASS mode */
Julius Werner55009af2019-12-02 22:03:27 -080024 setbits32(&exynos_clock->bpll_con1, BYPASS_EN);
Ronald G. Minniche6af9292013-06-03 13:03:50 -070025
Julius Werner2f37bd62015-02-19 14:51:15 -080026 write32(&exynos_clock->clk_src_cdrex, MUX_BPLL_SEL_FOUTBPLL);
Ronald G. Minniche6af9292013-06-03 13:03:50 -070027 do {
Julius Werner2f37bd62015-02-19 14:51:15 -080028 val = read32(&exynos_clock->clk_mux_stat_cdrex);
Ronald G. Minniche6af9292013-06-03 13:03:50 -070029 val &= BPLL_SEL_MASK;
30 } while (val != FOUTBPLL);
31
Julius Werner55009af2019-12-02 22:03:27 -080032 clrbits32(&exynos_clock->bpll_con1, BYPASS_EN);
Ronald G. Minniche6af9292013-06-03 13:03:50 -070033
34 /* Specify the DDR memory type as DDR3 */
Julius Werner2f37bd62015-02-19 14:51:15 -080035 val = read32(&exynos_phy0_control->phy_con0);
Ronald G. Minniche6af9292013-06-03 13:03:50 -070036 val &= ~(PHY_CON0_CTRL_DDR_MODE_MASK << PHY_CON0_CTRL_DDR_MODE_SHIFT);
David Hendricks5a0fdb42013-08-29 13:12:56 -070037 val |= (mem->mem_type << PHY_CON0_CTRL_DDR_MODE_SHIFT);
Julius Werner2f37bd62015-02-19 14:51:15 -080038 write32(&exynos_phy0_control->phy_con0, val);
Ronald G. Minniche6af9292013-06-03 13:03:50 -070039
Julius Werner2f37bd62015-02-19 14:51:15 -080040 val = read32(&exynos_phy1_control->phy_con0);
Ronald G. Minniche6af9292013-06-03 13:03:50 -070041 val &= ~(PHY_CON0_CTRL_DDR_MODE_MASK << PHY_CON0_CTRL_DDR_MODE_SHIFT);
David Hendricks5a0fdb42013-08-29 13:12:56 -070042 val |= (mem->mem_type << PHY_CON0_CTRL_DDR_MODE_SHIFT);
Julius Werner2f37bd62015-02-19 14:51:15 -080043 write32(&exynos_phy1_control->phy_con0, val);
Gabe Black607c0b62013-05-16 05:45:57 -070044
45 /* Set Read Latency and Burst Length for PHY0 and PHY1 */
Gabe Black607c0b62013-05-16 05:45:57 -070046 val = (mem->ctrl_bstlen << PHY_CON42_CTRL_BSTLEN_SHIFT) |
47 (mem->ctrl_rdlat << PHY_CON42_CTRL_RDLAT_SHIFT);
Julius Werner2f37bd62015-02-19 14:51:15 -080048 write32(&exynos_phy0_control->phy_con42, val);
49 write32(&exynos_phy1_control->phy_con42, val);
Gabe Black607c0b62013-05-16 05:45:57 -070050
Julius Werner2f37bd62015-02-19 14:51:15 -080051 val = read32(&exynos_phy0_control->phy_con26);
Ronald G. Minniche6af9292013-06-03 13:03:50 -070052 val &= ~(T_WRDATA_EN_MASK << T_WRDATA_EN_OFFSET);
53 val |= (T_WRDATA_EN_DDR3 << T_WRDATA_EN_OFFSET);
Julius Werner2f37bd62015-02-19 14:51:15 -080054 write32(&exynos_phy0_control->phy_con26, val);
Ronald G. Minniche6af9292013-06-03 13:03:50 -070055
Julius Werner2f37bd62015-02-19 14:51:15 -080056 val = read32(&exynos_phy1_control->phy_con26);
Ronald G. Minniche6af9292013-06-03 13:03:50 -070057 val &= ~(T_WRDATA_EN_MASK << T_WRDATA_EN_OFFSET);
58 val |= (T_WRDATA_EN_DDR3 << T_WRDATA_EN_OFFSET);
Julius Werner2f37bd62015-02-19 14:51:15 -080059 write32(&exynos_phy1_control->phy_con26, val);
Ronald G. Minniche6af9292013-06-03 13:03:50 -070060
61 /* Set Driver strength for CK, CKE, CS & CA to 0x7
62 * Set Driver strength for Data Slice 0~3 to 0x6
63 */
64 val = (0x7 << CA_CK_DRVR_DS_OFFSET) | (0x7 << CA_CKE_DRVR_DS_OFFSET) |
65 (0x7 << CA_CS_DRVR_DS_OFFSET) | (0x7 << CA_ADR_DRVR_DS_OFFSET);
David Hendricks42b1b802013-08-26 15:12:12 -070066 val |= (0x7 << DA_3_DS_OFFSET) | (0x7 << DA_2_DS_OFFSET) |
67 (0x7 << DA_1_DS_OFFSET) | (0x7 << DA_0_DS_OFFSET);
Julius Werner2f37bd62015-02-19 14:51:15 -080068 write32(&exynos_phy0_control->phy_con39, val);
69 write32(&exynos_phy1_control->phy_con39, val);
Ronald G. Minniche6af9292013-06-03 13:03:50 -070070
Gabe Black607c0b62013-05-16 05:45:57 -070071 /* ZQ Calibration */
Julius Wernerfa938c72013-08-29 14:17:36 -070072 if (dmc_config_zq(mem, exynos_phy0_control, exynos_phy1_control))
Gabe Black607c0b62013-05-16 05:45:57 -070073 return SETUP_ERR_ZQ_CALIBRATION_FAILURE;
74
Julius Werner55009af2019-12-02 22:03:27 -080075 clrbits32(&exynos_phy0_control->phy_con16, ZQ_CLK_DIV_EN);
76 clrbits32(&exynos_phy1_control->phy_con16, ZQ_CLK_DIV_EN);
Ronald G. Minniche6af9292013-06-03 13:03:50 -070077
Gabe Black607c0b62013-05-16 05:45:57 -070078 /* DQ Signal */
Julius Werner2f37bd62015-02-19 14:51:15 -080079 val = read32(&exynos_phy0_control->phy_con14);
David Hendricks42b1b802013-08-26 15:12:12 -070080 val |= mem->phy0_pulld_dqs;
Julius Werner2f37bd62015-02-19 14:51:15 -080081 write32(&exynos_phy0_control->phy_con14, val);
82 val = read32(&exynos_phy1_control->phy_con14);
David Hendricks42b1b802013-08-26 15:12:12 -070083 val |= mem->phy1_pulld_dqs;
Julius Werner2f37bd62015-02-19 14:51:15 -080084 write32(&exynos_phy1_control->phy_con14, val);
Gabe Black607c0b62013-05-16 05:45:57 -070085
Ronald G. Minniche6af9292013-06-03 13:03:50 -070086 val = MEM_TERM_EN | PHY_TERM_EN;
Julius Werner2f37bd62015-02-19 14:51:15 -080087 write32(&exynos_drex0->phycontrol0, val);
88 write32(&exynos_drex1->phycontrol0, val);
Gabe Black607c0b62013-05-16 05:45:57 -070089
Julius Werner94184762015-02-19 20:19:23 -080090 write32(&exynos_drex0->concontrol, mem->concontrol |
91 (mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT) |
92 (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT));
93 write32(&exynos_drex1->concontrol, mem->concontrol |
94 (mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT) |
95 (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT));
Gabe Black607c0b62013-05-16 05:45:57 -070096
Ronald G. Minniche6af9292013-06-03 13:03:50 -070097 do {
Julius Werner2f37bd62015-02-19 14:51:15 -080098 val = read32(&exynos_drex0->phystatus);
Ronald G. Minniche6af9292013-06-03 13:03:50 -070099 } while ((val & DFI_INIT_COMPLETE) != DFI_INIT_COMPLETE);
100 do {
Julius Werner2f37bd62015-02-19 14:51:15 -0800101 val = read32(&exynos_drex1->phystatus);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700102 } while ((val & DFI_INIT_COMPLETE) != DFI_INIT_COMPLETE);
Gabe Black607c0b62013-05-16 05:45:57 -0700103
Julius Werner55009af2019-12-02 22:03:27 -0800104 clrbits32(&exynos_drex0->concontrol, DFI_INIT_START);
105 clrbits32(&exynos_drex1->concontrol, DFI_INIT_START);
Gabe Black607c0b62013-05-16 05:45:57 -0700106
Julius Wernerfa938c72013-08-29 14:17:36 -0700107 update_reset_dll(exynos_drex0, mem->mem_type);
108 update_reset_dll(exynos_drex1, mem->mem_type);
Gabe Black607c0b62013-05-16 05:45:57 -0700109
David Hendricks122b6d62013-08-29 14:05:21 -0700110 /* MEMBASECONFIG0 (CS0) */
Julius Werner2f37bd62015-02-19 14:51:15 -0800111 write32(&exynos_tzasc0->membaseconfig0, mem->membaseconfig0);
112 write32(&exynos_tzasc1->membaseconfig0, mem->membaseconfig0);
Gabe Black607c0b62013-05-16 05:45:57 -0700113
David Hendricks122b6d62013-08-29 14:05:21 -0700114 /* MEMBASECONFIG1 (CS1) */
115 if (mem->chips_per_channel == 2) {
Julius Werner2f37bd62015-02-19 14:51:15 -0800116 write32(&exynos_tzasc0->membaseconfig1, mem->membaseconfig1);
117 write32(&exynos_tzasc1->membaseconfig1, mem->membaseconfig1);
David Hendricks122b6d62013-08-29 14:05:21 -0700118 }
Gabe Black607c0b62013-05-16 05:45:57 -0700119
Martin Roth1fc2ba52014-12-07 14:59:11 -0700120 /* Memory Channel Interleaving Size
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700121 * Exynos5420 Channel interleaving = 128 bytes
122 */
123 /* MEMCONFIG0/1 */
Julius Werner2f37bd62015-02-19 14:51:15 -0800124 write32(&exynos_tzasc0->memconfig0, mem->memconfig);
125 write32(&exynos_tzasc1->memconfig0, mem->memconfig);
126 write32(&exynos_tzasc0->memconfig1, mem->memconfig);
127 write32(&exynos_tzasc1->memconfig1, mem->memconfig);
Gabe Black607c0b62013-05-16 05:45:57 -0700128
129 /* Precharge Configuration */
Julius Werner2f37bd62015-02-19 14:51:15 -0800130 write32(&exynos_drex0->prechconfig0,
131 mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT);
132 write32(&exynos_drex1->prechconfig0,
133 mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT);
Gabe Black607c0b62013-05-16 05:45:57 -0700134
Martin Roth1fc2ba52014-12-07 14:59:11 -0700135 /* TimingRow, TimingData, TimingPower and Timingref
Gabe Black607c0b62013-05-16 05:45:57 -0700136 * values as per Memory AC parameters
137 */
Julius Werner2f37bd62015-02-19 14:51:15 -0800138 write32(&exynos_drex0->timingref, mem->timing_ref);
139 write32(&exynos_drex1->timingref, mem->timing_ref);
140 write32(&exynos_drex0->timingrow, mem->timing_row);
141 write32(&exynos_drex1->timingrow, mem->timing_row);
142 write32(&exynos_drex0->timingdata, mem->timing_data);
143 write32(&exynos_drex1->timingdata, mem->timing_data);
144 write32(&exynos_drex0->timingpower, mem->timing_power);
145 write32(&exynos_drex1->timingpower, mem->timing_power);
Gabe Black607c0b62013-05-16 05:45:57 -0700146
Hung-Te Linc0491d42013-08-06 10:48:48 +0800147 if (reset) {
David Hendricks2f3dadd2013-08-20 17:13:01 -0700148 /* Send NOP, MRS and ZQINIT commands.
149 * Sending MRS command will reset the DRAM. We should not be
Martin Roth26f97f92021-10-01 14:53:22 -0600150 * resetting the DRAM after resume, this will lead to memory
David Hendricks2f3dadd2013-08-20 17:13:01 -0700151 * corruption as DRAM content is lost after DRAM reset.
152 */
Julius Wernerfa938c72013-08-29 14:17:36 -0700153 dmc_config_mrs(mem, exynos_drex0);
154 dmc_config_mrs(mem, exynos_drex1);
David Hendricks2f3dadd2013-08-20 17:13:01 -0700155 } else {
156 u32 ret;
157
158 /*
159 * During Suspend-Resume & S/W-Reset, as soon as PMU releases
160 * pad retention, CKE goes high. This causes memory contents
Martin Roth1fc2ba52014-12-07 14:59:11 -0700161 * not to be retained during DRAM initialization. Therefore,
David Hendricks2f3dadd2013-08-20 17:13:01 -0700162 * there is a new control register(0x100431e8[28]) which lets us
163 * release pad retention and retain the memory content until the
164 * initialization is complete.
165 */
Julius Werner2f37bd62015-02-19 14:51:15 -0800166 write32(&exynos_power->padret_dram_cblk_opt,
167 PAD_RETENTION_DRAM_COREBLK_VAL);
David Hendricks2f3dadd2013-08-20 17:13:01 -0700168 do {
Julius Wernerfa938c72013-08-29 14:17:36 -0700169 ret = read32(&exynos_power->padret_dram_status);
David Hendricks2f3dadd2013-08-20 17:13:01 -0700170 } while (ret != 0x1);
171
172 /*
173 * CKE PAD retention disables DRAM self-refresh mode.
174 * Send auto refresh command for DRAM refresh.
175 */
176 for (i = 0; i < 128; i++) {
David Hendricks72a42882013-08-23 15:25:07 -0700177 for (chip = 0; chip < mem->chips_to_configure; chip++) {
Julius Werner2f37bd62015-02-19 14:51:15 -0800178 write32(&exynos_drex0->directcmd,
Julius Werner94184762015-02-19 20:19:23 -0800179 DIRECT_CMD_REFA |
180 (chip << DIRECT_CMD_CHIP_SHIFT));
Julius Werner2f37bd62015-02-19 14:51:15 -0800181 write32(&exynos_drex1->directcmd,
Julius Werner94184762015-02-19 20:19:23 -0800182 DIRECT_CMD_REFA |
183 (chip << DIRECT_CMD_CHIP_SHIFT));
David Hendricks72a42882013-08-23 15:25:07 -0700184 }
David Hendricks2f3dadd2013-08-20 17:13:01 -0700185 }
Hung-Te Linc0491d42013-08-06 10:48:48 +0800186 }
Gabe Black607c0b62013-05-16 05:45:57 -0700187
188 if (mem->gate_leveling_enable) {
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700189
Julius Werner2f37bd62015-02-19 14:51:15 -0800190 write32(&exynos_phy0_control->phy_con0, PHY_CON0_RESET_VAL);
191 write32(&exynos_phy1_control->phy_con0, PHY_CON0_RESET_VAL);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700192
Julius Werner55009af2019-12-02 22:03:27 -0800193 setbits32(&exynos_phy0_control->phy_con0, P0_CMD_EN);
194 setbits32(&exynos_phy1_control->phy_con0, P0_CMD_EN);
Gabe Black607c0b62013-05-16 05:45:57 -0700195
196 val = PHY_CON2_RESET_VAL;
197 val |= INIT_DESKEW_EN;
Julius Werner2f37bd62015-02-19 14:51:15 -0800198 write32(&exynos_phy0_control->phy_con2, val);
199 write32(&exynos_phy1_control->phy_con2, val);
Gabe Black607c0b62013-05-16 05:45:57 -0700200
Julius Werner2f37bd62015-02-19 14:51:15 -0800201 val = read32(&exynos_phy0_control->phy_con1);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700202 val |= (RDLVL_PASS_ADJ_VAL << RDLVL_PASS_ADJ_OFFSET);
Julius Werner2f37bd62015-02-19 14:51:15 -0800203 write32(&exynos_phy0_control->phy_con1, val);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700204
Julius Werner2f37bd62015-02-19 14:51:15 -0800205 val = read32(&exynos_phy1_control->phy_con1);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700206 val |= (RDLVL_PASS_ADJ_VAL << RDLVL_PASS_ADJ_OFFSET);
Julius Werner2f37bd62015-02-19 14:51:15 -0800207 write32(&exynos_phy1_control->phy_con1, val);
Gabe Black607c0b62013-05-16 05:45:57 -0700208
Julius Werner2f37bd62015-02-19 14:51:15 -0800209 nLockR = read32(&exynos_phy0_control->phy_con13);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700210 nLockW_phy0 = (nLockR & CTRL_LOCK_COARSE_MASK) >> 2;
Julius Werner2f37bd62015-02-19 14:51:15 -0800211 nLockR = read32(&exynos_phy0_control->phy_con12);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700212 nLockR &= ~CTRL_DLL_ON;
213 nLockR |= nLockW_phy0;
Julius Werner2f37bd62015-02-19 14:51:15 -0800214 write32(&exynos_phy0_control->phy_con12, nLockR);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700215
Julius Werner2f37bd62015-02-19 14:51:15 -0800216 nLockR = read32(&exynos_phy1_control->phy_con13);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700217 nLockW_phy1 = (nLockR & CTRL_LOCK_COARSE_MASK) >> 2;
Julius Werner2f37bd62015-02-19 14:51:15 -0800218 nLockR = read32(&exynos_phy1_control->phy_con12);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700219 nLockR &= ~CTRL_DLL_ON;
220 nLockR |= nLockW_phy1;
Julius Werner2f37bd62015-02-19 14:51:15 -0800221 write32(&exynos_phy1_control->phy_con12, nLockR);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700222
David Hendricks0f0c7202013-08-22 18:45:10 -0700223 val = (0x3 << DIRECT_CMD_BANK_SHIFT) | 0x4;
David Hendricks72a42882013-08-23 15:25:07 -0700224 for (chip = 0; chip < mem->chips_to_configure; chip++) {
Julius Werner2f37bd62015-02-19 14:51:15 -0800225 write32(&exynos_drex0->directcmd,
226 val | (chip << DIRECT_CMD_CHIP_SHIFT));
227 write32(&exynos_drex1->directcmd,
228 val | (chip << DIRECT_CMD_CHIP_SHIFT));
David Hendricks72a42882013-08-23 15:25:07 -0700229 }
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700230
Julius Werner55009af2019-12-02 22:03:27 -0800231 setbits32(&exynos_phy0_control->phy_con2, RDLVL_GATE_EN);
232 setbits32(&exynos_phy1_control->phy_con2, RDLVL_GATE_EN);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700233
Julius Werner55009af2019-12-02 22:03:27 -0800234 setbits32(&exynos_phy0_control->phy_con0, CTRL_SHGATE);
235 setbits32(&exynos_phy1_control->phy_con0, CTRL_SHGATE);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700236
Julius Werner2f37bd62015-02-19 14:51:15 -0800237 val = read32(&exynos_phy0_control->phy_con1);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700238 val &= ~(CTRL_GATEDURADJ_MASK);
Julius Werner2f37bd62015-02-19 14:51:15 -0800239 write32(&exynos_phy0_control->phy_con1, val);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700240
Julius Werner2f37bd62015-02-19 14:51:15 -0800241 val = read32(&exynos_phy1_control->phy_con1);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700242 val &= ~(CTRL_GATEDURADJ_MASK);
Julius Werner2f37bd62015-02-19 14:51:15 -0800243 write32(&exynos_phy1_control->phy_con1, val);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700244
Julius Werner2f37bd62015-02-19 14:51:15 -0800245 write32(&exynos_drex0->rdlvl_config, CTRL_RDLVL_GATE_ENABLE);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700246 i = TIMEOUT;
Julius Werner2f37bd62015-02-19 14:51:15 -0800247 while (((read32(&exynos_drex0->phystatus) & RDLVL_COMPLETE_CHO)
Julius Wernerfa938c72013-08-29 14:17:36 -0700248 != RDLVL_COMPLETE_CHO) && (i > 0)) {
Gabe Black607c0b62013-05-16 05:45:57 -0700249 /*
250 * TODO(waihong): Comment on how long this take to
251 * timeout
252 */
253 udelay(1);
254 i--;
255 }
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700256 if (!i)
Gabe Black607c0b62013-05-16 05:45:57 -0700257 return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
Julius Werner2f37bd62015-02-19 14:51:15 -0800258 write32(&exynos_drex0->rdlvl_config, CTRL_RDLVL_GATE_DISABLE);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700259
Julius Werner2f37bd62015-02-19 14:51:15 -0800260 write32(&exynos_drex1->rdlvl_config, CTRL_RDLVL_GATE_ENABLE);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700261 i = TIMEOUT;
Julius Werner2f37bd62015-02-19 14:51:15 -0800262 while (((read32(&exynos_drex1->phystatus) & RDLVL_COMPLETE_CHO)
Julius Wernerfa938c72013-08-29 14:17:36 -0700263 != RDLVL_COMPLETE_CHO) && (i > 0)) {
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700264 /*
265 * TODO(waihong): Comment on how long this take to
266 * timeout
267 */
268 udelay(1);
269 i--;
Gabe Black607c0b62013-05-16 05:45:57 -0700270 }
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700271 if (!i)
272 return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
Julius Werner2f37bd62015-02-19 14:51:15 -0800273 write32(&exynos_drex1->rdlvl_config, CTRL_RDLVL_GATE_DISABLE);
Gabe Black607c0b62013-05-16 05:45:57 -0700274
Julius Werner2f37bd62015-02-19 14:51:15 -0800275 write32(&exynos_phy0_control->phy_con14, 0);
276 write32(&exynos_phy1_control->phy_con14, 0);
Gabe Black607c0b62013-05-16 05:45:57 -0700277
David Hendricks0f0c7202013-08-22 18:45:10 -0700278 val = (0x3 << DIRECT_CMD_BANK_SHIFT);
David Hendricks72a42882013-08-23 15:25:07 -0700279 for (chip = 0; chip < mem->chips_to_configure; chip++) {
Julius Werner2f37bd62015-02-19 14:51:15 -0800280 write32(&exynos_drex0->directcmd,
281 val | (chip << DIRECT_CMD_CHIP_SHIFT));
282 write32(&exynos_drex1->directcmd,
283 val | (chip << DIRECT_CMD_CHIP_SHIFT));
David Hendricks72a42882013-08-23 15:25:07 -0700284 }
Gabe Black607c0b62013-05-16 05:45:57 -0700285
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700286 /* Common Settings for Leveling */
287 val = PHY_CON12_RESET_VAL;
Julius Werner2f37bd62015-02-19 14:51:15 -0800288 write32(&exynos_phy0_control->phy_con12, (val + nLockW_phy0));
289 write32(&exynos_phy1_control->phy_con12, (val + nLockW_phy1));
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700290
Julius Werner55009af2019-12-02 22:03:27 -0800291 setbits32(&exynos_phy0_control->phy_con2, DLL_DESKEW_EN);
292 setbits32(&exynos_phy1_control->phy_con2, DLL_DESKEW_EN);
Gabe Black607c0b62013-05-16 05:45:57 -0700293 }
294
295 /* Send PALL command */
Julius Wernerfa938c72013-08-29 14:17:36 -0700296 dmc_config_prech(mem, exynos_drex0);
297 dmc_config_prech(mem, exynos_drex1);
Gabe Black607c0b62013-05-16 05:45:57 -0700298
Julius Werner2f37bd62015-02-19 14:51:15 -0800299 write32(&exynos_drex0->memcontrol, mem->memcontrol);
300 write32(&exynos_drex1->memcontrol, mem->memcontrol);
Gabe Black607c0b62013-05-16 05:45:57 -0700301
David Hendricks42b1b802013-08-26 15:12:12 -0700302 /*
303 * Set DMC Concontrol: Enable auto-refresh counter, provide
304 * read data fetch cycles and enable DREX auto set powerdown
305 * for input buffer of I/O in none read memory state.
306 */
Julius Werner94184762015-02-19 20:19:23 -0800307 write32(&exynos_drex0->concontrol, mem->concontrol |
308 (mem->aref_en << CONCONTROL_AREF_EN_SHIFT) |
309 (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT) |
310 DMC_CONCONTROL_IO_PD_CON(0x2));
311 write32(&exynos_drex1->concontrol, mem->concontrol |
312 (mem->aref_en << CONCONTROL_AREF_EN_SHIFT) |
313 (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT) |
314 DMC_CONCONTROL_IO_PD_CON(0x2));
David Hendricksb7743132013-08-09 18:19:29 -0700315
316 /* Enable Clock Gating Control for DMC
317 * this saves around 25 mw dmc power as compared to the power
318 * consumption without these bits enabled
319 */
Julius Werner55009af2019-12-02 22:03:27 -0800320 setbits32(&exynos_drex0->cgcontrol, DMC_INTERNAL_CG);
321 setbits32(&exynos_drex1->cgcontrol, DMC_INTERNAL_CG);
David Hendricksb7743132013-08-09 18:19:29 -0700322
Gabe Black607c0b62013-05-16 05:45:57 -0700323 return 0;
324}