]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c
Merge branch 'u-boot-tegra/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / arch / arm / cpu / armv7 / exynos / dmc_init_ddr3.c
1 /*
2  * DDR3 mem setup file for board based on EXYNOS5
3  *
4  * Copyright (C) 2012 Samsung Electronics
5  *
6  * SPDX-License-Identifier:     GPL-2.0+
7  */
8
9 #include <config.h>
10 #include <asm/io.h>
11 #include <asm/arch/clock.h>
12 #include <asm/arch/cpu.h>
13 #include <asm/arch/dmc.h>
14 #include <asm/arch/power.h>
15 #include "common_setup.h"
16 #include "exynos5_setup.h"
17 #include "clock_init.h"
18
19 #define TIMEOUT 10000
20
21 #ifdef CONFIG_EXYNOS5250
22 static void reset_phy_ctrl(void)
23 {
24         struct exynos5_clock *clk =
25                 (struct exynos5_clock *)samsung_get_base_clock();
26
27         writel(DDR3PHY_CTRL_PHY_RESET_OFF, &clk->lpddr3phy_ctrl);
28         writel(DDR3PHY_CTRL_PHY_RESET, &clk->lpddr3phy_ctrl);
29 }
30
31 int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
32                        int reset)
33 {
34         unsigned int val;
35         struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl;
36         struct exynos5_dmc *dmc;
37         int i;
38
39         phy0_ctrl = (struct exynos5_phy_control *)samsung_get_base_dmc_phy();
40         phy1_ctrl = (struct exynos5_phy_control *)(samsung_get_base_dmc_phy()
41                                                         + DMC_OFFSET);
42         dmc = (struct exynos5_dmc *)samsung_get_base_dmc_ctrl();
43
44         if (reset)
45                 reset_phy_ctrl();
46
47         /* Set Impedance Output Driver */
48         val = (mem->impedance << CA_CK_DRVR_DS_OFFSET) |
49                 (mem->impedance << CA_CKE_DRVR_DS_OFFSET) |
50                 (mem->impedance << CA_CS_DRVR_DS_OFFSET) |
51                 (mem->impedance << CA_ADR_DRVR_DS_OFFSET);
52         writel(val, &phy0_ctrl->phy_con39);
53         writel(val, &phy1_ctrl->phy_con39);
54
55         /* Set Read Latency and Burst Length for PHY0 and PHY1 */
56         val = (mem->ctrl_bstlen << PHY_CON42_CTRL_BSTLEN_SHIFT) |
57                 (mem->ctrl_rdlat << PHY_CON42_CTRL_RDLAT_SHIFT);
58         writel(val, &phy0_ctrl->phy_con42);
59         writel(val, &phy1_ctrl->phy_con42);
60
61         /* ZQ Calibration */
62         if (dmc_config_zq(mem, &phy0_ctrl->phy_con16, &phy1_ctrl->phy_con16,
63                           &phy0_ctrl->phy_con17, &phy1_ctrl->phy_con17))
64                 return SETUP_ERR_ZQ_CALIBRATION_FAILURE;
65
66         /* DQ Signal */
67         writel(mem->phy0_pulld_dqs, &phy0_ctrl->phy_con14);
68         writel(mem->phy1_pulld_dqs, &phy1_ctrl->phy_con14);
69
70         writel(mem->concontrol | (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)
71                 | (mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT),
72                 &dmc->concontrol);
73
74         update_reset_dll(&dmc->phycontrol0, DDR_MODE_DDR3);
75
76         /* DQS Signal */
77         writel(mem->phy0_dqs, &phy0_ctrl->phy_con4);
78         writel(mem->phy1_dqs, &phy1_ctrl->phy_con4);
79
80         writel(mem->phy0_dq, &phy0_ctrl->phy_con6);
81         writel(mem->phy1_dq, &phy1_ctrl->phy_con6);
82
83         writel(mem->phy0_tFS, &phy0_ctrl->phy_con10);
84         writel(mem->phy1_tFS, &phy1_ctrl->phy_con10);
85
86         val = (mem->ctrl_start_point << PHY_CON12_CTRL_START_POINT_SHIFT) |
87                 (mem->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) |
88                 (mem->ctrl_dll_on << PHY_CON12_CTRL_DLL_ON_SHIFT) |
89                 (mem->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT);
90         writel(val, &phy0_ctrl->phy_con12);
91         writel(val, &phy1_ctrl->phy_con12);
92
93         /* Start DLL locking */
94         writel(val | (mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT),
95                &phy0_ctrl->phy_con12);
96         writel(val | (mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT),
97                &phy1_ctrl->phy_con12);
98
99         update_reset_dll(&dmc->phycontrol0, DDR_MODE_DDR3);
100
101         writel(mem->concontrol | (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT),
102                &dmc->concontrol);
103
104         /* Memory Channel Inteleaving Size */
105         writel(mem->iv_size, &dmc->ivcontrol);
106
107         writel(mem->memconfig, &dmc->memconfig0);
108         writel(mem->memconfig, &dmc->memconfig1);
109         writel(mem->membaseconfig0, &dmc->membaseconfig0);
110         writel(mem->membaseconfig1, &dmc->membaseconfig1);
111
112         /* Precharge Configuration */
113         writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
114                &dmc->prechconfig);
115
116         /* Power Down mode Configuration */
117         writel(mem->dpwrdn_cyc << PWRDNCONFIG_DPWRDN_CYC_SHIFT |
118                 mem->dsref_cyc << PWRDNCONFIG_DSREF_CYC_SHIFT,
119                 &dmc->pwrdnconfig);
120
121         /* TimingRow, TimingData, TimingPower and Timingaref
122          * values as per Memory AC parameters
123          */
124         writel(mem->timing_ref, &dmc->timingref);
125         writel(mem->timing_row, &dmc->timingrow);
126         writel(mem->timing_data, &dmc->timingdata);
127         writel(mem->timing_power, &dmc->timingpower);
128
129         /* Send PALL command */
130         dmc_config_prech(mem, &dmc->directcmd);
131
132         /* Send NOP, MRS and ZQINIT commands */
133         dmc_config_mrs(mem, &dmc->directcmd);
134
135         if (mem->gate_leveling_enable) {
136                 val = PHY_CON0_RESET_VAL;
137                 val |= P0_CMD_EN;
138                 writel(val, &phy0_ctrl->phy_con0);
139                 writel(val, &phy1_ctrl->phy_con0);
140
141                 val = PHY_CON2_RESET_VAL;
142                 val |= INIT_DESKEW_EN;
143                 writel(val, &phy0_ctrl->phy_con2);
144                 writel(val, &phy1_ctrl->phy_con2);
145
146                 val = PHY_CON0_RESET_VAL;
147                 val |= P0_CMD_EN;
148                 val |= BYTE_RDLVL_EN;
149                 writel(val, &phy0_ctrl->phy_con0);
150                 writel(val, &phy1_ctrl->phy_con0);
151
152                 val = (mem->ctrl_start_point <<
153                                 PHY_CON12_CTRL_START_POINT_SHIFT) |
154                         (mem->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) |
155                         (mem->ctrl_force << PHY_CON12_CTRL_FORCE_SHIFT) |
156                         (mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT) |
157                         (mem->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT);
158                 writel(val, &phy0_ctrl->phy_con12);
159                 writel(val, &phy1_ctrl->phy_con12);
160
161                 val = PHY_CON2_RESET_VAL;
162                 val |= INIT_DESKEW_EN;
163                 val |= RDLVL_GATE_EN;
164                 writel(val, &phy0_ctrl->phy_con2);
165                 writel(val, &phy1_ctrl->phy_con2);
166
167                 val = PHY_CON0_RESET_VAL;
168                 val |= P0_CMD_EN;
169                 val |= BYTE_RDLVL_EN;
170                 val |= CTRL_SHGATE;
171                 writel(val, &phy0_ctrl->phy_con0);
172                 writel(val, &phy1_ctrl->phy_con0);
173
174                 val = PHY_CON1_RESET_VAL;
175                 val &= ~(CTRL_GATEDURADJ_MASK);
176                 writel(val, &phy0_ctrl->phy_con1);
177                 writel(val, &phy1_ctrl->phy_con1);
178
179                 writel(CTRL_RDLVL_GATE_ENABLE, &dmc->rdlvl_config);
180                 i = TIMEOUT;
181                 while ((readl(&dmc->phystatus) &
182                         (RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1)) !=
183                         (RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1) && i > 0) {
184                         /*
185                          * TODO(waihong): Comment on how long this take to
186                          * timeout
187                          */
188                         sdelay(100);
189                         i--;
190                 }
191                 if (!i)
192                         return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
193                 writel(CTRL_RDLVL_GATE_DISABLE, &dmc->rdlvl_config);
194
195                 writel(0, &phy0_ctrl->phy_con14);
196                 writel(0, &phy1_ctrl->phy_con14);
197
198                 val = (mem->ctrl_start_point <<
199                                 PHY_CON12_CTRL_START_POINT_SHIFT) |
200                         (mem->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) |
201                         (mem->ctrl_force << PHY_CON12_CTRL_FORCE_SHIFT) |
202                         (mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT) |
203                         (mem->ctrl_dll_on << PHY_CON12_CTRL_DLL_ON_SHIFT) |
204                         (mem->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT);
205                 writel(val, &phy0_ctrl->phy_con12);
206                 writel(val, &phy1_ctrl->phy_con12);
207
208                 update_reset_dll(&dmc->phycontrol0, DDR_MODE_DDR3);
209         }
210
211         /* Send PALL command */
212         dmc_config_prech(mem, &dmc->directcmd);
213
214         writel(mem->memcontrol, &dmc->memcontrol);
215
216         /* Set DMC Concontrol and enable auto-refresh counter */
217         writel(mem->concontrol | (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)
218                 | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT), &dmc->concontrol);
219         return 0;
220 }
221 #endif
222
223 #ifdef CONFIG_EXYNOS5420
224 int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size,
225                        int reset)
226 {
227         struct exynos5420_clock *clk =
228                 (struct exynos5420_clock *)samsung_get_base_clock();
229         struct exynos5420_power *power =
230                 (struct exynos5420_power *)samsung_get_base_power();
231         struct exynos5420_phy_control *phy0_ctrl, *phy1_ctrl;
232         struct exynos5420_dmc *drex0, *drex1;
233         struct exynos5420_tzasc *tzasc0, *tzasc1;
234         uint32_t val, n_lock_r, n_lock_w_phy0, n_lock_w_phy1;
235         int chip;
236         int i;
237
238         phy0_ctrl = (struct exynos5420_phy_control *)samsung_get_base_dmc_phy();
239         phy1_ctrl = (struct exynos5420_phy_control *)(samsung_get_base_dmc_phy()
240                                                         + DMC_OFFSET);
241         drex0 = (struct exynos5420_dmc *)samsung_get_base_dmc_ctrl();
242         drex1 = (struct exynos5420_dmc *)(samsung_get_base_dmc_ctrl()
243                                                         + DMC_OFFSET);
244         tzasc0 = (struct exynos5420_tzasc *)samsung_get_base_dmc_tzasc();
245         tzasc1 = (struct exynos5420_tzasc *)(samsung_get_base_dmc_tzasc()
246                                                         + DMC_OFFSET);
247
248         /* Enable PAUSE for DREX */
249         setbits_le32(&clk->pause, ENABLE_BIT);
250
251         /* Enable BYPASS mode */
252         setbits_le32(&clk->bpll_con1, BYPASS_EN);
253
254         writel(MUX_BPLL_SEL_FOUTBPLL, &clk->src_cdrex);
255         do {
256                 val = readl(&clk->mux_stat_cdrex);
257                 val &= BPLL_SEL_MASK;
258         } while (val != FOUTBPLL);
259
260         clrbits_le32(&clk->bpll_con1, BYPASS_EN);
261
262         /* Specify the DDR memory type as DDR3 */
263         val = readl(&phy0_ctrl->phy_con0);
264         val &= ~(PHY_CON0_CTRL_DDR_MODE_MASK << PHY_CON0_CTRL_DDR_MODE_SHIFT);
265         val |= (DDR_MODE_DDR3 << PHY_CON0_CTRL_DDR_MODE_SHIFT);
266         writel(val, &phy0_ctrl->phy_con0);
267
268         val = readl(&phy1_ctrl->phy_con0);
269         val &= ~(PHY_CON0_CTRL_DDR_MODE_MASK << PHY_CON0_CTRL_DDR_MODE_SHIFT);
270         val |= (DDR_MODE_DDR3 << PHY_CON0_CTRL_DDR_MODE_SHIFT);
271         writel(val, &phy1_ctrl->phy_con0);
272
273         /* Set Read Latency and Burst Length for PHY0 and PHY1 */
274         val = (mem->ctrl_bstlen << PHY_CON42_CTRL_BSTLEN_SHIFT) |
275                 (mem->ctrl_rdlat << PHY_CON42_CTRL_RDLAT_SHIFT);
276         writel(val, &phy0_ctrl->phy_con42);
277         writel(val, &phy1_ctrl->phy_con42);
278
279         val = readl(&phy0_ctrl->phy_con26);
280         val &= ~(T_WRDATA_EN_MASK << T_WRDATA_EN_OFFSET);
281         val |= (T_WRDATA_EN_DDR3 << T_WRDATA_EN_OFFSET);
282         writel(val, &phy0_ctrl->phy_con26);
283
284         val = readl(&phy1_ctrl->phy_con26);
285         val &= ~(T_WRDATA_EN_MASK << T_WRDATA_EN_OFFSET);
286         val |= (T_WRDATA_EN_DDR3 << T_WRDATA_EN_OFFSET);
287         writel(val, &phy1_ctrl->phy_con26);
288
289         /*
290          * Set Driver strength for CK, CKE, CS & CA to 0x7
291          * Set Driver strength for Data Slice 0~3 to 0x7
292          */
293         val = (0x7 << CA_CK_DRVR_DS_OFFSET) | (0x7 << CA_CKE_DRVR_DS_OFFSET) |
294                 (0x7 << CA_CS_DRVR_DS_OFFSET) | (0x7 << CA_ADR_DRVR_DS_OFFSET);
295         val |= (0x7 << DA_3_DS_OFFSET) | (0x7 << DA_2_DS_OFFSET) |
296                 (0x7 << DA_1_DS_OFFSET) | (0x7 << DA_0_DS_OFFSET);
297         writel(val, &phy0_ctrl->phy_con39);
298         writel(val, &phy1_ctrl->phy_con39);
299
300         /* ZQ Calibration */
301         if (dmc_config_zq(mem, &phy0_ctrl->phy_con16, &phy1_ctrl->phy_con16,
302                           &phy0_ctrl->phy_con17, &phy1_ctrl->phy_con17))
303                 return SETUP_ERR_ZQ_CALIBRATION_FAILURE;
304
305         clrbits_le32(&phy0_ctrl->phy_con16, ZQ_CLK_DIV_EN);
306         clrbits_le32(&phy1_ctrl->phy_con16, ZQ_CLK_DIV_EN);
307
308         /* DQ Signal */
309         val = readl(&phy0_ctrl->phy_con14);
310         val |= mem->phy0_pulld_dqs;
311         writel(val, &phy0_ctrl->phy_con14);
312         val = readl(&phy1_ctrl->phy_con14);
313         val |= mem->phy1_pulld_dqs;
314         writel(val, &phy1_ctrl->phy_con14);
315
316         val = MEM_TERM_EN | PHY_TERM_EN;
317         writel(val, &drex0->phycontrol0);
318         writel(val, &drex1->phycontrol0);
319
320         writel(mem->concontrol |
321                 (mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT) |
322                 (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT),
323                 &drex0->concontrol);
324         writel(mem->concontrol |
325                 (mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT) |
326                 (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT),
327                 &drex1->concontrol);
328
329         do {
330                 val = readl(&drex0->phystatus);
331         } while ((val & DFI_INIT_COMPLETE) != DFI_INIT_COMPLETE);
332         do {
333                 val = readl(&drex1->phystatus);
334         } while ((val & DFI_INIT_COMPLETE) != DFI_INIT_COMPLETE);
335
336         clrbits_le32(&drex0->concontrol, DFI_INIT_START);
337         clrbits_le32(&drex1->concontrol, DFI_INIT_START);
338
339         update_reset_dll(&drex0->phycontrol0, DDR_MODE_DDR3);
340         update_reset_dll(&drex1->phycontrol0, DDR_MODE_DDR3);
341
342         /*
343          * Set Base Address:
344          * 0x2000_0000 ~ 0x5FFF_FFFF
345          * 0x6000_0000 ~ 0x9FFF_FFFF
346          */
347         /* MEMBASECONFIG0 */
348         val = DMC_MEMBASECONFIGX_CHIP_BASE(DMC_CHIP_BASE_0) |
349                 DMC_MEMBASECONFIGX_CHIP_MASK(DMC_CHIP_MASK);
350         writel(val, &tzasc0->membaseconfig0);
351         writel(val, &tzasc1->membaseconfig0);
352
353         /* MEMBASECONFIG1 */
354         val = DMC_MEMBASECONFIGX_CHIP_BASE(DMC_CHIP_BASE_1) |
355                 DMC_MEMBASECONFIGX_CHIP_MASK(DMC_CHIP_MASK);
356         writel(val, &tzasc0->membaseconfig1);
357         writel(val, &tzasc1->membaseconfig1);
358
359         /*
360          * Memory Channel Inteleaving Size
361          * Ares Channel interleaving = 128 bytes
362          */
363         /* MEMCONFIG0/1 */
364         writel(mem->memconfig, &tzasc0->memconfig0);
365         writel(mem->memconfig, &tzasc1->memconfig0);
366         writel(mem->memconfig, &tzasc0->memconfig1);
367         writel(mem->memconfig, &tzasc1->memconfig1);
368
369         /* Precharge Configuration */
370         writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
371                &drex0->prechconfig0);
372         writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT,
373                &drex1->prechconfig0);
374
375         /*
376          * TimingRow, TimingData, TimingPower and Timingaref
377          * values as per Memory AC parameters
378          */
379         writel(mem->timing_ref, &drex0->timingref);
380         writel(mem->timing_ref, &drex1->timingref);
381         writel(mem->timing_row, &drex0->timingrow0);
382         writel(mem->timing_row, &drex1->timingrow0);
383         writel(mem->timing_data, &drex0->timingdata0);
384         writel(mem->timing_data, &drex1->timingdata0);
385         writel(mem->timing_power, &drex0->timingpower0);
386         writel(mem->timing_power, &drex1->timingpower0);
387
388         if (reset) {
389                 /*
390                  * Send NOP, MRS and ZQINIT commands
391                  * Sending MRS command will reset the DRAM. We should not be
392                  * reseting the DRAM after resume, this will lead to memory
393                  * corruption as DRAM content is lost after DRAM reset
394                  */
395                 dmc_config_mrs(mem, &drex0->directcmd);
396                 dmc_config_mrs(mem, &drex1->directcmd);
397         } else {
398                 /*
399                  * During Suspend-Resume & S/W-Reset, as soon as PMU releases
400                  * pad retention, CKE goes high. This causes memory contents
401                  * not to be retained during DRAM initialization. Therfore,
402                  * there is a new control register(0x100431e8[28]) which lets us
403                  * release pad retention and retain the memory content until the
404                  * initialization is complete.
405                  */
406                 writel(PAD_RETENTION_DRAM_COREBLK_VAL,
407                        &power->pad_retention_dram_coreblk_option);
408                 do {
409                         val = readl(&power->pad_retention_dram_status);
410                 } while (val != 0x1);
411
412                 /*
413                  * CKE PAD retention disables DRAM self-refresh mode.
414                  * Send auto refresh command for DRAM refresh.
415                  */
416                 for (i = 0; i < 128; i++) {
417                         for (chip = 0; chip < mem->chips_to_configure; chip++) {
418                                 writel(DIRECT_CMD_REFA |
419                                        (chip << DIRECT_CMD_CHIP_SHIFT),
420                                        &drex0->directcmd);
421                                 writel(DIRECT_CMD_REFA |
422                                        (chip << DIRECT_CMD_CHIP_SHIFT),
423                                        &drex1->directcmd);
424                         }
425                 }
426         }
427
428         if (mem->gate_leveling_enable) {
429                 writel(PHY_CON0_RESET_VAL, &phy0_ctrl->phy_con0);
430                 writel(PHY_CON0_RESET_VAL, &phy1_ctrl->phy_con0);
431
432                 setbits_le32(&phy0_ctrl->phy_con0, P0_CMD_EN);
433                 setbits_le32(&phy1_ctrl->phy_con0, P0_CMD_EN);
434
435                 val = PHY_CON2_RESET_VAL;
436                 val |= INIT_DESKEW_EN;
437                 writel(val, &phy0_ctrl->phy_con2);
438                 writel(val, &phy1_ctrl->phy_con2);
439
440                 val =  readl(&phy0_ctrl->phy_con1);
441                 val |= (RDLVL_PASS_ADJ_VAL << RDLVL_PASS_ADJ_OFFSET);
442                 writel(val, &phy0_ctrl->phy_con1);
443
444                 val =  readl(&phy1_ctrl->phy_con1);
445                 val |= (RDLVL_PASS_ADJ_VAL << RDLVL_PASS_ADJ_OFFSET);
446                 writel(val, &phy1_ctrl->phy_con1);
447
448                 n_lock_r = readl(&phy0_ctrl->phy_con13);
449                 n_lock_w_phy0 = (n_lock_r & CTRL_LOCK_COARSE_MASK) >> 2;
450                 n_lock_r = readl(&phy0_ctrl->phy_con12);
451                 n_lock_r &= ~CTRL_DLL_ON;
452                 n_lock_r |= n_lock_w_phy0;
453                 writel(n_lock_r, &phy0_ctrl->phy_con12);
454
455                 n_lock_r = readl(&phy1_ctrl->phy_con13);
456                 n_lock_w_phy1 = (n_lock_r & CTRL_LOCK_COARSE_MASK) >> 2;
457                 n_lock_r = readl(&phy1_ctrl->phy_con12);
458                 n_lock_r &= ~CTRL_DLL_ON;
459                 n_lock_r |= n_lock_w_phy1;
460                 writel(n_lock_r, &phy1_ctrl->phy_con12);
461
462                 val = (0x3 << DIRECT_CMD_BANK_SHIFT) | 0x4;
463                 for (chip = 0; chip < mem->chips_to_configure; chip++) {
464                         writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
465                                &drex0->directcmd);
466                         writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
467                                &drex1->directcmd);
468                 }
469
470                 setbits_le32(&phy0_ctrl->phy_con2, RDLVL_GATE_EN);
471                 setbits_le32(&phy1_ctrl->phy_con2, RDLVL_GATE_EN);
472
473                 setbits_le32(&phy0_ctrl->phy_con0, CTRL_SHGATE);
474                 setbits_le32(&phy1_ctrl->phy_con0, CTRL_SHGATE);
475
476                 val = readl(&phy0_ctrl->phy_con1);
477                 val &= ~(CTRL_GATEDURADJ_MASK);
478                 writel(val, &phy0_ctrl->phy_con1);
479
480                 val = readl(&phy1_ctrl->phy_con1);
481                 val &= ~(CTRL_GATEDURADJ_MASK);
482                 writel(val, &phy1_ctrl->phy_con1);
483
484                 writel(CTRL_RDLVL_GATE_ENABLE, &drex0->rdlvl_config);
485                 i = TIMEOUT;
486                 while (((readl(&drex0->phystatus) & RDLVL_COMPLETE_CHO) !=
487                         RDLVL_COMPLETE_CHO) && (i > 0)) {
488                         /*
489                          * TODO(waihong): Comment on how long this take to
490                          * timeout
491                          */
492                         sdelay(100);
493                         i--;
494                 }
495                 if (!i)
496                         return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
497                 writel(CTRL_RDLVL_GATE_DISABLE, &drex0->rdlvl_config);
498
499                 writel(CTRL_RDLVL_GATE_ENABLE, &drex1->rdlvl_config);
500                 i = TIMEOUT;
501                 while (((readl(&drex1->phystatus) & RDLVL_COMPLETE_CHO) !=
502                         RDLVL_COMPLETE_CHO) && (i > 0)) {
503                         /*
504                          * TODO(waihong): Comment on how long this take to
505                          * timeout
506                          */
507                         sdelay(100);
508                         i--;
509                 }
510                 if (!i)
511                         return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
512                 writel(CTRL_RDLVL_GATE_DISABLE, &drex1->rdlvl_config);
513
514                 writel(0, &phy0_ctrl->phy_con14);
515                 writel(0, &phy1_ctrl->phy_con14);
516
517                 val = (0x3 << DIRECT_CMD_BANK_SHIFT);
518                 for (chip = 0; chip < mem->chips_to_configure; chip++) {
519                         writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
520                                &drex0->directcmd);
521                         writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
522                                &drex1->directcmd);
523                 }
524
525                 if (mem->read_leveling_enable) {
526                         /* Set Read DQ Calibration */
527                         val = (0x3 << DIRECT_CMD_BANK_SHIFT) | 0x4;
528                         for (chip = 0; chip < mem->chips_to_configure; chip++) {
529                                 writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
530                                        &drex0->directcmd);
531                                 writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
532                                        &drex1->directcmd);
533                         }
534
535                         val = readl(&phy0_ctrl->phy_con1);
536                         val |= READ_LEVELLING_DDR3;
537                         writel(val, &phy0_ctrl->phy_con1);
538                         val = readl(&phy1_ctrl->phy_con1);
539                         val |= READ_LEVELLING_DDR3;
540                         writel(val, &phy1_ctrl->phy_con1);
541
542                         val = readl(&phy0_ctrl->phy_con2);
543                         val |= (RDLVL_EN | RDLVL_INCR_ADJ);
544                         writel(val, &phy0_ctrl->phy_con2);
545                         val = readl(&phy1_ctrl->phy_con2);
546                         val |= (RDLVL_EN | RDLVL_INCR_ADJ);
547                         writel(val, &phy1_ctrl->phy_con2);
548
549                         setbits_le32(&drex0->rdlvl_config,
550                                      CTRL_RDLVL_DATA_ENABLE);
551                         i = TIMEOUT;
552                         while (((readl(&drex0->phystatus) & RDLVL_COMPLETE_CHO)
553                                  != RDLVL_COMPLETE_CHO) && (i > 0)) {
554                                 /*
555                                  * TODO(waihong): Comment on how long this take
556                                  * to timeout
557                                  */
558                                 sdelay(100);
559                                 i--;
560                         }
561                         if (!i)
562                                 return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
563
564                         clrbits_le32(&drex0->rdlvl_config,
565                                      CTRL_RDLVL_DATA_ENABLE);
566                         setbits_le32(&drex1->rdlvl_config,
567                                      CTRL_RDLVL_DATA_ENABLE);
568                         i = TIMEOUT;
569                         while (((readl(&drex1->phystatus) & RDLVL_COMPLETE_CHO)
570                                  != RDLVL_COMPLETE_CHO) && (i > 0)) {
571                                 /*
572                                  * TODO(waihong): Comment on how long this take
573                                  * to timeout
574                                  */
575                                 sdelay(100);
576                                 i--;
577                         }
578                         if (!i)
579                                 return SETUP_ERR_RDLV_COMPLETE_TIMEOUT;
580
581                         clrbits_le32(&drex1->rdlvl_config,
582                                      CTRL_RDLVL_DATA_ENABLE);
583
584                         val = (0x3 << DIRECT_CMD_BANK_SHIFT);
585                         for (chip = 0; chip < mem->chips_to_configure; chip++) {
586                                 writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
587                                        &drex0->directcmd);
588                                 writel(val | (chip << DIRECT_CMD_CHIP_SHIFT),
589                                        &drex1->directcmd);
590                         }
591
592                         update_reset_dll(&drex0->phycontrol0, DDR_MODE_DDR3);
593                         update_reset_dll(&drex1->phycontrol0, DDR_MODE_DDR3);
594                 }
595
596                 /* Common Settings for Leveling */
597                 val = PHY_CON12_RESET_VAL;
598                 writel((val + n_lock_w_phy0), &phy0_ctrl->phy_con12);
599                 writel((val + n_lock_w_phy1), &phy1_ctrl->phy_con12);
600
601                 setbits_le32(&phy0_ctrl->phy_con2, DLL_DESKEW_EN);
602                 setbits_le32(&phy1_ctrl->phy_con2, DLL_DESKEW_EN);
603         }
604
605         /* Send PALL command */
606         dmc_config_prech(mem, &drex0->directcmd);
607         dmc_config_prech(mem, &drex1->directcmd);
608
609         writel(mem->memcontrol, &drex0->memcontrol);
610         writel(mem->memcontrol, &drex1->memcontrol);
611
612         /*
613          * Set DMC Concontrol: Enable auto-refresh counter, provide
614          * read data fetch cycles and enable DREX auto set powerdown
615          * for input buffer of I/O in none read memory state.
616          */
617         writel(mem->concontrol | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT) |
618                 (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)|
619                 DMC_CONCONTROL_IO_PD_CON(0x2),
620                 &drex0->concontrol);
621         writel(mem->concontrol | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT) |
622                 (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)|
623                 DMC_CONCONTROL_IO_PD_CON(0x2),
624                 &drex1->concontrol);
625
626         /*
627          * Enable Clock Gating Control for DMC
628          * this saves around 25 mw dmc power as compared to the power
629          * consumption without these bits enabled
630          */
631         setbits_le32(&drex0->cgcontrol, DMC_INTERNAL_CG);
632         setbits_le32(&drex1->cgcontrol, DMC_INTERNAL_CG);
633
634         return 0;
635 }
636 #endif