1 /* DDR3 mem setup file for EXYNOS5 based board */
2 /* SPDX-License-Identifier: GPL-2.0-or-later */
4 #include <device/mmio.h>
13 /* 'reset' field is currently ignored. */
15 int ddr3_mem_ctrl_init(struct mem_timings
*mem
, int interleave_size
, int reset
)
17 u32 val
, nLockR
, nLockW_phy0
, nLockW_phy1
;
20 /* Enable PAUSE for DREX */
21 setbits32(&exynos_clock
->pause
, ENABLE_BIT
);
23 /* Enable BYPASS mode */
24 setbits32(&exynos_clock
->bpll_con1
, BYPASS_EN
);
26 write32(&exynos_clock
->clk_src_cdrex
, MUX_BPLL_SEL_FOUTBPLL
);
28 val
= read32(&exynos_clock
->clk_mux_stat_cdrex
);
30 } while (val
!= FOUTBPLL
);
32 clrbits32(&exynos_clock
->bpll_con1
, BYPASS_EN
);
34 /* Specify the DDR memory type as DDR3 */
35 val
= read32(&exynos_phy0_control
->phy_con0
);
36 val
&= ~(PHY_CON0_CTRL_DDR_MODE_MASK
<< PHY_CON0_CTRL_DDR_MODE_SHIFT
);
37 val
|= (mem
->mem_type
<< PHY_CON0_CTRL_DDR_MODE_SHIFT
);
38 write32(&exynos_phy0_control
->phy_con0
, val
);
40 val
= read32(&exynos_phy1_control
->phy_con0
);
41 val
&= ~(PHY_CON0_CTRL_DDR_MODE_MASK
<< PHY_CON0_CTRL_DDR_MODE_SHIFT
);
42 val
|= (mem
->mem_type
<< PHY_CON0_CTRL_DDR_MODE_SHIFT
);
43 write32(&exynos_phy1_control
->phy_con0
, val
);
45 /* Set Read Latency and Burst Length for PHY0 and PHY1 */
46 val
= (mem
->ctrl_bstlen
<< PHY_CON42_CTRL_BSTLEN_SHIFT
) |
47 (mem
->ctrl_rdlat
<< PHY_CON42_CTRL_RDLAT_SHIFT
);
48 write32(&exynos_phy0_control
->phy_con42
, val
);
49 write32(&exynos_phy1_control
->phy_con42
, val
);
51 val
= read32(&exynos_phy0_control
->phy_con26
);
52 val
&= ~(T_WRDATA_EN_MASK
<< T_WRDATA_EN_OFFSET
);
53 val
|= (T_WRDATA_EN_DDR3
<< T_WRDATA_EN_OFFSET
);
54 write32(&exynos_phy0_control
->phy_con26
, val
);
56 val
= read32(&exynos_phy1_control
->phy_con26
);
57 val
&= ~(T_WRDATA_EN_MASK
<< T_WRDATA_EN_OFFSET
);
58 val
|= (T_WRDATA_EN_DDR3
<< T_WRDATA_EN_OFFSET
);
59 write32(&exynos_phy1_control
->phy_con26
, val
);
61 /* Set Driver strength for CK, CKE, CS & CA to 0x7
62 * Set Driver strength for Data Slice 0~3 to 0x6
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
);
66 val
|= (0x7 << DA_3_DS_OFFSET
) | (0x7 << DA_2_DS_OFFSET
) |
67 (0x7 << DA_1_DS_OFFSET
) | (0x7 << DA_0_DS_OFFSET
);
68 write32(&exynos_phy0_control
->phy_con39
, val
);
69 write32(&exynos_phy1_control
->phy_con39
, val
);
72 if (dmc_config_zq(mem
, exynos_phy0_control
, exynos_phy1_control
))
73 return SETUP_ERR_ZQ_CALIBRATION_FAILURE
;
75 clrbits32(&exynos_phy0_control
->phy_con16
, ZQ_CLK_DIV_EN
);
76 clrbits32(&exynos_phy1_control
->phy_con16
, ZQ_CLK_DIV_EN
);
79 val
= read32(&exynos_phy0_control
->phy_con14
);
80 val
|= mem
->phy0_pulld_dqs
;
81 write32(&exynos_phy0_control
->phy_con14
, val
);
82 val
= read32(&exynos_phy1_control
->phy_con14
);
83 val
|= mem
->phy1_pulld_dqs
;
84 write32(&exynos_phy1_control
->phy_con14
, val
);
86 val
= MEM_TERM_EN
| PHY_TERM_EN
;
87 write32(&exynos_drex0
->phycontrol0
, val
);
88 write32(&exynos_drex1
->phycontrol0
, val
);
90 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
));
98 val
= read32(&exynos_drex0
->phystatus
);
99 } while ((val
& DFI_INIT_COMPLETE
) != DFI_INIT_COMPLETE
);
101 val
= read32(&exynos_drex1
->phystatus
);
102 } while ((val
& DFI_INIT_COMPLETE
) != DFI_INIT_COMPLETE
);
104 clrbits32(&exynos_drex0
->concontrol
, DFI_INIT_START
);
105 clrbits32(&exynos_drex1
->concontrol
, DFI_INIT_START
);
107 update_reset_dll(exynos_drex0
, mem
->mem_type
);
108 update_reset_dll(exynos_drex1
, mem
->mem_type
);
110 /* MEMBASECONFIG0 (CS0) */
111 write32(&exynos_tzasc0
->membaseconfig0
, mem
->membaseconfig0
);
112 write32(&exynos_tzasc1
->membaseconfig0
, mem
->membaseconfig0
);
114 /* MEMBASECONFIG1 (CS1) */
115 if (mem
->chips_per_channel
== 2) {
116 write32(&exynos_tzasc0
->membaseconfig1
, mem
->membaseconfig1
);
117 write32(&exynos_tzasc1
->membaseconfig1
, mem
->membaseconfig1
);
120 /* Memory Channel Interleaving Size
121 * Exynos5420 Channel interleaving = 128 bytes
124 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
);
129 /* Precharge Configuration */
130 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
);
135 /* TimingRow, TimingData, TimingPower and Timingref
136 * values as per Memory AC parameters
138 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
);
148 /* Send NOP, MRS and ZQINIT commands.
149 * Sending MRS command will reset the DRAM. We should not be
150 * resetting the DRAM after resume, this will lead to memory
151 * corruption as DRAM content is lost after DRAM reset.
153 dmc_config_mrs(mem
, exynos_drex0
);
154 dmc_config_mrs(mem
, exynos_drex1
);
159 * During Suspend-Resume & S/W-Reset, as soon as PMU releases
160 * pad retention, CKE goes high. This causes memory contents
161 * not to be retained during DRAM initialization. Therefore,
162 * 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.
166 write32(&exynos_power
->padret_dram_cblk_opt
,
167 PAD_RETENTION_DRAM_COREBLK_VAL
);
169 ret
= read32(&exynos_power
->padret_dram_status
);
170 } while (ret
!= 0x1);
173 * CKE PAD retention disables DRAM self-refresh mode.
174 * Send auto refresh command for DRAM refresh.
176 for (i
= 0; i
< 128; i
++) {
177 for (chip
= 0; chip
< mem
->chips_to_configure
; chip
++) {
178 write32(&exynos_drex0
->directcmd
,
180 (chip
<< DIRECT_CMD_CHIP_SHIFT
));
181 write32(&exynos_drex1
->directcmd
,
183 (chip
<< DIRECT_CMD_CHIP_SHIFT
));
188 if (mem
->gate_leveling_enable
) {
189 write32(&exynos_phy0_control
->phy_con0
, PHY_CON0_RESET_VAL
);
190 write32(&exynos_phy1_control
->phy_con0
, PHY_CON0_RESET_VAL
);
192 setbits32(&exynos_phy0_control
->phy_con0
, P0_CMD_EN
);
193 setbits32(&exynos_phy1_control
->phy_con0
, P0_CMD_EN
);
195 val
= PHY_CON2_RESET_VAL
;
196 val
|= INIT_DESKEW_EN
;
197 write32(&exynos_phy0_control
->phy_con2
, val
);
198 write32(&exynos_phy1_control
->phy_con2
, val
);
200 val
= read32(&exynos_phy0_control
->phy_con1
);
201 val
|= (RDLVL_PASS_ADJ_VAL
<< RDLVL_PASS_ADJ_OFFSET
);
202 write32(&exynos_phy0_control
->phy_con1
, val
);
204 val
= read32(&exynos_phy1_control
->phy_con1
);
205 val
|= (RDLVL_PASS_ADJ_VAL
<< RDLVL_PASS_ADJ_OFFSET
);
206 write32(&exynos_phy1_control
->phy_con1
, val
);
208 nLockR
= read32(&exynos_phy0_control
->phy_con13
);
209 nLockW_phy0
= (nLockR
& CTRL_LOCK_COARSE_MASK
) >> 2;
210 nLockR
= read32(&exynos_phy0_control
->phy_con12
);
211 nLockR
&= ~CTRL_DLL_ON
;
212 nLockR
|= nLockW_phy0
;
213 write32(&exynos_phy0_control
->phy_con12
, nLockR
);
215 nLockR
= read32(&exynos_phy1_control
->phy_con13
);
216 nLockW_phy1
= (nLockR
& CTRL_LOCK_COARSE_MASK
) >> 2;
217 nLockR
= read32(&exynos_phy1_control
->phy_con12
);
218 nLockR
&= ~CTRL_DLL_ON
;
219 nLockR
|= nLockW_phy1
;
220 write32(&exynos_phy1_control
->phy_con12
, nLockR
);
222 val
= (0x3 << DIRECT_CMD_BANK_SHIFT
) | 0x4;
223 for (chip
= 0; chip
< mem
->chips_to_configure
; chip
++) {
224 write32(&exynos_drex0
->directcmd
,
225 val
| (chip
<< DIRECT_CMD_CHIP_SHIFT
));
226 write32(&exynos_drex1
->directcmd
,
227 val
| (chip
<< DIRECT_CMD_CHIP_SHIFT
));
230 setbits32(&exynos_phy0_control
->phy_con2
, RDLVL_GATE_EN
);
231 setbits32(&exynos_phy1_control
->phy_con2
, RDLVL_GATE_EN
);
233 setbits32(&exynos_phy0_control
->phy_con0
, CTRL_SHGATE
);
234 setbits32(&exynos_phy1_control
->phy_con0
, CTRL_SHGATE
);
236 val
= read32(&exynos_phy0_control
->phy_con1
);
237 val
&= ~(CTRL_GATEDURADJ_MASK
);
238 write32(&exynos_phy0_control
->phy_con1
, val
);
240 val
= read32(&exynos_phy1_control
->phy_con1
);
241 val
&= ~(CTRL_GATEDURADJ_MASK
);
242 write32(&exynos_phy1_control
->phy_con1
, val
);
244 write32(&exynos_drex0
->rdlvl_config
, CTRL_RDLVL_GATE_ENABLE
);
246 while (((read32(&exynos_drex0
->phystatus
) & RDLVL_COMPLETE_CHO
)
247 != RDLVL_COMPLETE_CHO
) && (i
> 0)) {
249 * TODO(waihong): Comment on how long this take to
256 return SETUP_ERR_RDLV_COMPLETE_TIMEOUT
;
257 write32(&exynos_drex0
->rdlvl_config
, CTRL_RDLVL_GATE_DISABLE
);
259 write32(&exynos_drex1
->rdlvl_config
, CTRL_RDLVL_GATE_ENABLE
);
261 while (((read32(&exynos_drex1
->phystatus
) & RDLVL_COMPLETE_CHO
)
262 != RDLVL_COMPLETE_CHO
) && (i
> 0)) {
264 * TODO(waihong): Comment on how long this take to
271 return SETUP_ERR_RDLV_COMPLETE_TIMEOUT
;
272 write32(&exynos_drex1
->rdlvl_config
, CTRL_RDLVL_GATE_DISABLE
);
274 write32(&exynos_phy0_control
->phy_con14
, 0);
275 write32(&exynos_phy1_control
->phy_con14
, 0);
277 val
= (0x3 << DIRECT_CMD_BANK_SHIFT
);
278 for (chip
= 0; chip
< mem
->chips_to_configure
; chip
++) {
279 write32(&exynos_drex0
->directcmd
,
280 val
| (chip
<< DIRECT_CMD_CHIP_SHIFT
));
281 write32(&exynos_drex1
->directcmd
,
282 val
| (chip
<< DIRECT_CMD_CHIP_SHIFT
));
285 /* Common Settings for Leveling */
286 val
= PHY_CON12_RESET_VAL
;
287 write32(&exynos_phy0_control
->phy_con12
, (val
+ nLockW_phy0
));
288 write32(&exynos_phy1_control
->phy_con12
, (val
+ nLockW_phy1
));
290 setbits32(&exynos_phy0_control
->phy_con2
, DLL_DESKEW_EN
);
291 setbits32(&exynos_phy1_control
->phy_con2
, DLL_DESKEW_EN
);
294 /* Send PALL command */
295 dmc_config_prech(mem
, exynos_drex0
);
296 dmc_config_prech(mem
, exynos_drex1
);
298 write32(&exynos_drex0
->memcontrol
, mem
->memcontrol
);
299 write32(&exynos_drex1
->memcontrol
, mem
->memcontrol
);
302 * Set DMC Concontrol: Enable auto-refresh counter, provide
303 * read data fetch cycles and enable DREX auto set powerdown
304 * for input buffer of I/O in none read memory state.
306 write32(&exynos_drex0
->concontrol
, mem
->concontrol
|
307 (mem
->aref_en
<< CONCONTROL_AREF_EN_SHIFT
) |
308 (mem
->rd_fetch
<< CONCONTROL_RD_FETCH_SHIFT
) |
309 DMC_CONCONTROL_IO_PD_CON(0x2));
310 write32(&exynos_drex1
->concontrol
, mem
->concontrol
|
311 (mem
->aref_en
<< CONCONTROL_AREF_EN_SHIFT
) |
312 (mem
->rd_fetch
<< CONCONTROL_RD_FETCH_SHIFT
) |
313 DMC_CONCONTROL_IO_PD_CON(0x2));
315 /* Enable Clock Gating Control for DMC
316 * this saves around 25 mw dmc power as compared to the power
317 * consumption without these bits enabled
319 setbits32(&exynos_drex0
->cgcontrol
, DMC_INTERNAL_CG
);
320 setbits32(&exynos_drex1
->cgcontrol
, DMC_INTERNAL_CG
);