blob: 74ee7e93a1ff670ba4c4c4e1691cfc14f2c9c763 [file] [log] [blame]
Gabe Black607c0b62013-05-16 05:45:57 -07001/*
2 * This file is part of the coreboot project.
3 *
Ronald G. Minniche6af9292013-06-03 13:03:50 -07004 * DDR3 mem setup file for EXYNOS5 based board
5 *
Gabe Black607c0b62013-05-16 05:45:57 -07006 * Copyright (C) 2012 Samsung Electronics
7 *
Ronald G. Minniche6af9292013-06-03 13:03:50 -07008 * See file CREDITS for list of people who contributed to this
9 * project.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
Gabe Black607c0b62013-05-16 05:45:57 -070015 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
Ronald G. Minniche6af9292013-06-03 13:03:50 -070023 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24 * MA 02111-1307 USA
Gabe Black607c0b62013-05-16 05:45:57 -070025 */
26
Gabe Black607c0b62013-05-16 05:45:57 -070027#include <console/console.h>
28#include <delay.h>
29#include <arch/io.h>
Gabe Black607c0b62013-05-16 05:45:57 -070030#include "dmc.h"
31#include "setup.h"
Ronald G. Minniche6af9292013-06-03 13:03:50 -070032#include "cpu.h"
33#include "clk.h"
Gabe Black607c0b62013-05-16 05:45:57 -070034
Ronald G. Minniche6af9292013-06-03 13:03:50 -070035#define TIMEOUT 10000
Gabe Black607c0b62013-05-16 05:45:57 -070036
Ronald G. Minniche6af9292013-06-03 13:03:50 -070037/* 'reset' field is currently ignored. */
38
39int ddr3_mem_ctrl_init(struct mem_timings *mem, int interleave_size, int reset)
Gabe Black607c0b62013-05-16 05:45:57 -070040{
Ronald G. Minniche6af9292013-06-03 13:03:50 -070041 struct exynos5420_clock *clk =
42 (struct exynos5420_clock *)EXYNOS5_CLOCK_BASE;
Gabe Black607c0b62013-05-16 05:45:57 -070043 struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl;
Ronald G. Minniche6af9292013-06-03 13:03:50 -070044 struct exynos5_dmc *drex0, *drex1;
45 struct exynos5_tzasc *tzasc0, *tzasc1;
46 u32 val, nLockR, nLockW_phy0, nLockW_phy1;
Gabe Black607c0b62013-05-16 05:45:57 -070047 int i;
48
49 phy0_ctrl = (struct exynos5_phy_control *)EXYNOS5_DMC_PHY0_BASE;
50 phy1_ctrl = (struct exynos5_phy_control *)EXYNOS5_DMC_PHY1_BASE;
Ronald G. Minniche6af9292013-06-03 13:03:50 -070051 drex0 = (struct exynos5_dmc *)EXYNOS5420_DMC_DREXI_0;
52 drex1 = (struct exynos5_dmc *)EXYNOS5420_DMC_DREXI_1;
53 tzasc0 = (struct exynos5_tzasc *)EXYNOS5420_DMC_TZASC_0;
54 tzasc1 = (struct exynos5_tzasc *)EXYNOS5420_DMC_TZASC_1;
Gabe Black607c0b62013-05-16 05:45:57 -070055
Ronald G. Minniche6af9292013-06-03 13:03:50 -070056 /* Enable PAUSE for DREX */
57 setbits_le32(&clk->pause, ENABLE_BIT);
Gabe Black607c0b62013-05-16 05:45:57 -070058
Ronald G. Minniche6af9292013-06-03 13:03:50 -070059 /* Enable BYPASS mode */
60 setbits_le32(&clk->bpll_con1, BYPASS_EN);
61
62 writel(MUX_BPLL_SEL_FOUTBPLL, &clk->clk_src_cdrex);
63 do {
64 val = readl(&clk->clk_mux_stat_cdrex);
65 val &= BPLL_SEL_MASK;
66 } while (val != FOUTBPLL);
67
68 clrbits_le32(&clk->bpll_con1, BYPASS_EN);
69
70 /* Specify the DDR memory type as DDR3 */
71 val = readl(&phy0_ctrl->phy_con0);
72 val &= ~(PHY_CON0_CTRL_DDR_MODE_MASK << PHY_CON0_CTRL_DDR_MODE_SHIFT);
73 val |= (DDR_MODE_DDR3 << PHY_CON0_CTRL_DDR_MODE_SHIFT);
74 writel(val, &phy0_ctrl->phy_con0);
75
76 val = readl(&phy1_ctrl->phy_con0);
77 val &= ~(PHY_CON0_CTRL_DDR_MODE_MASK << PHY_CON0_CTRL_DDR_MODE_SHIFT);
78 val |= (DDR_MODE_DDR3 << PHY_CON0_CTRL_DDR_MODE_SHIFT);
79 writel(val, &phy1_ctrl->phy_con0);
Gabe Black607c0b62013-05-16 05:45:57 -070080
81 /* Set Read Latency and Burst Length for PHY0 and PHY1 */
Gabe Black607c0b62013-05-16 05:45:57 -070082 val = (mem->ctrl_bstlen << PHY_CON42_CTRL_BSTLEN_SHIFT) |
83 (mem->ctrl_rdlat << PHY_CON42_CTRL_RDLAT_SHIFT);
84 writel(val, &phy0_ctrl->phy_con42);
85 writel(val, &phy1_ctrl->phy_con42);
86
Ronald G. Minniche6af9292013-06-03 13:03:50 -070087 val = readl(&phy0_ctrl->phy_con26);
88 val &= ~(T_WRDATA_EN_MASK << T_WRDATA_EN_OFFSET);
89 val |= (T_WRDATA_EN_DDR3 << T_WRDATA_EN_OFFSET);
90 writel(val, &phy0_ctrl->phy_con26);
91
92 val = readl(&phy1_ctrl->phy_con26);
93 val &= ~(T_WRDATA_EN_MASK << T_WRDATA_EN_OFFSET);
94 val |= (T_WRDATA_EN_DDR3 << T_WRDATA_EN_OFFSET);
95 writel(val, &phy1_ctrl->phy_con26);
96
97 /* Set Driver strength for CK, CKE, CS & CA to 0x7
98 * Set Driver strength for Data Slice 0~3 to 0x6
99 */
100 val = (0x7 << CA_CK_DRVR_DS_OFFSET) | (0x7 << CA_CKE_DRVR_DS_OFFSET) |
101 (0x7 << CA_CS_DRVR_DS_OFFSET) | (0x7 << CA_ADR_DRVR_DS_OFFSET);
102 val |= (0x6 << DA_3_DS_OFFSET) | (0x6 << DA_2_DS_OFFSET) |
103 (0x6 << DA_1_DS_OFFSET) | (0x6 << DA_0_DS_OFFSET);
104 writel(val, &phy0_ctrl->phy_con39);
105 writel(val, &phy1_ctrl->phy_con39);
106
Gabe Black607c0b62013-05-16 05:45:57 -0700107 /* ZQ Calibration */
Gabe Black607c0b62013-05-16 05:45:57 -0700108 if (dmc_config_zq(mem, phy0_ctrl, phy1_ctrl))
109 return SETUP_ERR_ZQ_CALIBRATION_FAILURE;
110
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700111 clrbits_le32(&phy0_ctrl->phy_con16, ZQ_CLK_DIV_EN);
112 clrbits_le32(&phy1_ctrl->phy_con16, ZQ_CLK_DIV_EN);
113
Gabe Black607c0b62013-05-16 05:45:57 -0700114 /* DQ Signal */
Gabe Black607c0b62013-05-16 05:45:57 -0700115 writel(mem->phy0_pulld_dqs, &phy0_ctrl->phy_con14);
116 writel(mem->phy1_pulld_dqs, &phy1_ctrl->phy_con14);
117
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700118 val = MEM_TERM_EN | PHY_TERM_EN;
119 writel(val, &drex0->phycontrol0);
120 writel(val, &drex1->phycontrol0);
Gabe Black607c0b62013-05-16 05:45:57 -0700121
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700122 writel(mem->concontrol |
123 (mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT) |
124 (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT),
125 &drex0->concontrol);
126 writel(mem->concontrol |
127 (mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT) |
128 (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT),
129 &drex1->concontrol);
Gabe Black607c0b62013-05-16 05:45:57 -0700130
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700131 do {
132 val = readl(&drex0->phystatus);
133 } while ((val & DFI_INIT_COMPLETE) != DFI_INIT_COMPLETE);
134 do {
135 val = readl(&drex1->phystatus);
136 } while ((val & DFI_INIT_COMPLETE) != DFI_INIT_COMPLETE);
Gabe Black607c0b62013-05-16 05:45:57 -0700137
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700138 clrbits_le32(&drex0->concontrol, DFI_INIT_START);
139 clrbits_le32(&drex1->concontrol, DFI_INIT_START);
Gabe Black607c0b62013-05-16 05:45:57 -0700140
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700141 update_reset_dll(drex0, DDR_MODE_DDR3);
142 update_reset_dll(drex1, DDR_MODE_DDR3);
Gabe Black607c0b62013-05-16 05:45:57 -0700143
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700144 /* Set Base Address:
145 * 0x2000_0000 ~ 0x5FFF_FFFF
146 * 0x6000_0000 ~ 0x9FFF_FFFF
147 */
148 /* MEMBASECONFIG0 */
149 val = DMC_MEMBASECONFIGx_CHIP_BASE(DMC_CHIP_BASE_0) |
150 DMC_MEMBASECONFIGx_CHIP_MASK(DMC_CHIP_MASK);
151 writel(val, &tzasc0->membaseconfig0);
152 writel(val, &tzasc1->membaseconfig0);
Gabe Black607c0b62013-05-16 05:45:57 -0700153
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700154 /* MEMBASECONFIG1 */
155 val = DMC_MEMBASECONFIGx_CHIP_BASE(DMC_CHIP_BASE_1) |
156 DMC_MEMBASECONFIGx_CHIP_MASK(DMC_CHIP_MASK);
157 writel(val, &tzasc0->membaseconfig1);
158 writel(val, &tzasc1->membaseconfig1);
Gabe Black607c0b62013-05-16 05:45:57 -0700159
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700160 /* Memory Channel Inteleaving Size
161 * Exynos5420 Channel interleaving = 128 bytes
162 */
163 /* MEMCONFIG0/1 */
164 writel(mem->memconfig, &tzasc0->memconfig0);
165 writel(mem->memconfig, &tzasc1->memconfig0);
166 writel(mem->memconfig, &tzasc0->memconfig1);
167 writel(mem->memconfig, &tzasc1->memconfig1);
Gabe Black607c0b62013-05-16 05:45:57 -0700168
169 /* Precharge Configuration */
Gabe Black607c0b62013-05-16 05:45:57 -0700170 writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700171 &drex0->prechconfig0);
172 writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
173 &drex1->prechconfig0);
Gabe Black607c0b62013-05-16 05:45:57 -0700174
175 /* TimingRow, TimingData, TimingPower and Timingaref
176 * values as per Memory AC parameters
177 */
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700178 writel(mem->timing_ref, &drex0->timingref);
179 writel(mem->timing_ref, &drex1->timingref);
180 writel(mem->timing_row, &drex0->timingrow);
181 writel(mem->timing_row, &drex1->timingrow);
182 writel(mem->timing_data, &drex0->timingdata);
183 writel(mem->timing_data, &drex1->timingdata);
184 writel(mem->timing_power, &drex0->timingpower);
185 writel(mem->timing_power, &drex1->timingpower);
Gabe Black607c0b62013-05-16 05:45:57 -0700186
187 /* Send NOP, MRS and ZQINIT commands */
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700188 dmc_config_mrs(mem, drex0);
189 dmc_config_mrs(mem, drex1);
Gabe Black607c0b62013-05-16 05:45:57 -0700190
191 if (mem->gate_leveling_enable) {
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700192
193 setbits_le32(&phy0_ctrl->phy_con0, CTRL_ATGATE);
194 setbits_le32(&phy1_ctrl->phy_con0, CTRL_ATGATE);
195
196 setbits_le32(&phy0_ctrl->phy_con0, P0_CMD_EN);
197 setbits_le32(&phy1_ctrl->phy_con0, P0_CMD_EN);
Gabe Black607c0b62013-05-16 05:45:57 -0700198
199 val = PHY_CON2_RESET_VAL;
200 val |= INIT_DESKEW_EN;
201 writel(val, &phy0_ctrl->phy_con2);
202 writel(val, &phy1_ctrl->phy_con2);
203
204 val = PHY_CON0_RESET_VAL;
205 val |= P0_CMD_EN;
206 val |= BYTE_RDLVL_EN;
207 writel(val, &phy0_ctrl->phy_con0);
208 writel(val, &phy1_ctrl->phy_con0);
209
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700210 val = readl(&phy0_ctrl->phy_con1);
211 val |= (RDLVL_PASS_ADJ_VAL << RDLVL_PASS_ADJ_OFFSET);
Gabe Black607c0b62013-05-16 05:45:57 -0700212 writel(val, &phy0_ctrl->phy_con1);
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700213
214 val = readl(&phy1_ctrl->phy_con1);
215 val |= (RDLVL_PASS_ADJ_VAL << RDLVL_PASS_ADJ_OFFSET);
Gabe Black607c0b62013-05-16 05:45:57 -0700216 writel(val, &phy1_ctrl->phy_con1);
217
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700218 nLockR = readl(&phy0_ctrl->phy_con13);
219 nLockW_phy0 = (nLockR & CTRL_LOCK_COARSE_MASK) >> 2;
220 nLockR = readl(&phy0_ctrl->phy_con12);
221 nLockR &= ~CTRL_DLL_ON;
222 nLockR |= nLockW_phy0;
223 writel(nLockR, &phy0_ctrl->phy_con12);
224
225 nLockR = readl(&phy1_ctrl->phy_con13);
226 nLockW_phy1 = (nLockR & CTRL_LOCK_COARSE_MASK) >> 2;
227 nLockR = readl(&phy1_ctrl->phy_con12);
228 nLockR &= ~CTRL_DLL_ON;
229 nLockR |= nLockW_phy1;
230 writel(nLockR, &phy1_ctrl->phy_con12);
231
232 writel(0x00030004, &drex0->directcmd);
233 writel(0x00130004, &drex0->directcmd);
234 writel(0x00030004, &drex1->directcmd);
235 writel(0x00130004, &drex1->directcmd);
236
237 setbits_le32(&phy0_ctrl->phy_con2, RDLVL_GATE_EN);
238 setbits_le32(&phy1_ctrl->phy_con2, RDLVL_GATE_EN);
239
240 setbits_le32(&phy0_ctrl->phy_con0, CTRL_SHGATE);
241 setbits_le32(&phy1_ctrl->phy_con0, CTRL_SHGATE);
242
243 val = readl(&phy0_ctrl->phy_con1);
244 val &= ~(CTRL_GATEDURADJ_MASK);
245 writel(val, &phy0_ctrl->phy_con1);
246
247 val = readl(&phy1_ctrl->phy_con1);
248 val &= ~(CTRL_GATEDURADJ_MASK);
249 writel(val, &phy1_ctrl->phy_con1);
250
251 writel(CTRL_RDLVL_GATE_ENABLE, &drex0->rdlvl_config);
252 i = TIMEOUT;
253 while (((readl(&drex0->phystatus) & RDLVL_COMPLETE_CHO) !=
254 RDLVL_COMPLETE_CHO) && (i > 0)) {
Gabe Black607c0b62013-05-16 05:45:57 -0700255 /*
256 * TODO(waihong): Comment on how long this take to
257 * timeout
258 */
259 udelay(1);
260 i--;
261 }
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700262 if (!i)
Gabe Black607c0b62013-05-16 05:45:57 -0700263 return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700264 writel(CTRL_RDLVL_GATE_DISABLE, &drex0->rdlvl_config);
265
266 writel(CTRL_RDLVL_GATE_ENABLE, &drex1->rdlvl_config);
267 i = TIMEOUT;
268 while (((readl(&drex1->phystatus) & RDLVL_COMPLETE_CHO) !=
269 RDLVL_COMPLETE_CHO) && (i > 0)) {
270 /*
271 * TODO(waihong): Comment on how long this take to
272 * timeout
273 */
274 udelay(1);
275 i--;
Gabe Black607c0b62013-05-16 05:45:57 -0700276 }
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700277 if (!i)
278 return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
279 writel(CTRL_RDLVL_GATE_DISABLE, &drex1->rdlvl_config);
Gabe Black607c0b62013-05-16 05:45:57 -0700280
281 writel(0, &phy0_ctrl->phy_con14);
282 writel(0, &phy1_ctrl->phy_con14);
283
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700284 writel(0x00030000, &drex0->directcmd);
285 writel(0x00130000, &drex0->directcmd);
286 writel(0x00030000, &drex1->directcmd);
287 writel(0x00130000, &drex1->directcmd);
Gabe Black607c0b62013-05-16 05:45:57 -0700288
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700289 /* Set Read DQ Calibration */
290 writel(0x00030004, &drex0->directcmd);
291 writel(0x00130004, &drex0->directcmd);
292 writel(0x00030004, &drex1->directcmd);
293 writel(0x00130004, &drex1->directcmd);
294
295 val = readl(&phy0_ctrl->phy_con1);
296 val |= READ_LEVELLING_DDR3;
297 writel(val, &phy0_ctrl->phy_con1);
298 val = readl(&phy1_ctrl->phy_con1);
299 val |= READ_LEVELLING_DDR3;
300 writel(val, &phy1_ctrl->phy_con1);
301
302 val = readl(&phy0_ctrl->phy_con2);
303 val |= (RDLVL_EN | RDLVL_INCR_ADJ);
304 writel(val, &phy0_ctrl->phy_con2);
305 val = readl(&phy1_ctrl->phy_con2);
306 val |= (RDLVL_EN | RDLVL_INCR_ADJ);
307 writel(val, &phy1_ctrl->phy_con2);
308
309 setbits_le32(&drex0->rdlvl_config, CTRL_RDLVL_DATA_ENABLE);
310 i = TIMEOUT;
311 while (((readl(&drex0->phystatus) & RDLVL_COMPLETE_CHO) !=
312 RDLVL_COMPLETE_CHO) && (i > 0)) {
313 /*
314 * TODO(waihong): Comment on how long this take to
315 * timeout
316 */
317 udelay(1);
318 i--;
319 }
320 if (!i)
321 return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
322 clrbits_le32(&drex0->rdlvl_config, CTRL_RDLVL_DATA_ENABLE);
323
324 setbits_le32(&drex1->rdlvl_config, CTRL_RDLVL_DATA_ENABLE);
325 i = TIMEOUT;
326 while (((readl(&drex1->phystatus) & RDLVL_COMPLETE_CHO) !=
327 RDLVL_COMPLETE_CHO) && (i > 0)) {
328 /*
329 * TODO(waihong): Comment on how long this take to
330 * timeout
331 */
332 udelay(1);
333 i--;
334 }
335 if (!i)
336 return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
337 clrbits_le32(&drex1->rdlvl_config, CTRL_RDLVL_DATA_ENABLE);
338
339 writel(0x00030000, &drex0->directcmd);
340 writel(0x00130000, &drex0->directcmd);
341 writel(0x00030000, &drex1->directcmd);
342 writel(0x00130000, &drex1->directcmd);
343
344 update_reset_dll(drex0, DDR_MODE_DDR3);
345 update_reset_dll(drex1, DDR_MODE_DDR3);
346
347 /* Common Settings for Leveling */
348 val = PHY_CON12_RESET_VAL;
349 writel((val + nLockW_phy0), &phy0_ctrl->phy_con12);
350 writel((val + nLockW_phy1), &phy1_ctrl->phy_con12);
351
352 setbits_le32(&phy0_ctrl->phy_con2, DLL_DESKEW_EN);
353 setbits_le32(&phy1_ctrl->phy_con2, DLL_DESKEW_EN);
354
355 update_reset_dll(drex0, DDR_MODE_DDR3);
356 update_reset_dll(drex1, DDR_MODE_DDR3);
Gabe Black607c0b62013-05-16 05:45:57 -0700357 }
358
359 /* Send PALL command */
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700360 dmc_config_prech(mem, drex0);
361 dmc_config_prech(mem, drex1);
Gabe Black607c0b62013-05-16 05:45:57 -0700362
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700363 writel(mem->memcontrol, &drex0->memcontrol);
364 writel(mem->memcontrol, &drex1->memcontrol);
Gabe Black607c0b62013-05-16 05:45:57 -0700365
366 /* Set DMC Concontrol and enable auto-refresh counter */
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700367 writel(mem->concontrol | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT) |
368 (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT),
369 &drex0->concontrol);
370 writel(mem->concontrol | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT) |
371 (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT),
372 &drex1->concontrol);
Gabe Black607c0b62013-05-16 05:45:57 -0700373 return 0;
374}