1 /* SPDX-License-Identifier: GPL-2.0-only */
3 /* DDR3 mem setup file for SMDK5250 board based on EXYNOS5 */
5 #include <device/mmio.h>
6 #include <console/console.h>
11 #include <soc/setup.h>
13 #define RDLVL_COMPLETE_TIMEOUT 10000
15 static void reset_phy_ctrl(void)
17 write32(&exynos_clock
->lpddr3phy_ctrl
,
18 LPDDR3PHY_CTRL_PHY_RESET_ENABLE
);
19 write32(&exynos_clock
->lpddr3phy_ctrl
,
20 LPDDR3PHY_CTRL_PHY_RESET_DISABLE
);
25 int ddr3_mem_ctrl_init(struct mem_timings
*mem
, unsigned long mem_iv_size
,
34 /* Set Impedance Output Driver */
35 val
= (mem
->impedance
<< CA_CK_DRVR_DS_OFFSET
) |
36 (mem
->impedance
<< CA_CKE_DRVR_DS_OFFSET
) |
37 (mem
->impedance
<< CA_CS_DRVR_DS_OFFSET
) |
38 (mem
->impedance
<< CA_ADR_DRVR_DS_OFFSET
);
39 write32(&exynos_phy0_control
->phy_con39
, val
);
40 write32(&exynos_phy1_control
->phy_con39
, val
);
42 /* Set Read Latency and Burst Length for PHY0 and PHY1 */
43 val
= (mem
->ctrl_bstlen
<< PHY_CON42_CTRL_BSTLEN_SHIFT
) |
44 (mem
->ctrl_rdlat
<< PHY_CON42_CTRL_RDLAT_SHIFT
);
45 write32(&exynos_phy0_control
->phy_con42
, val
);
46 write32(&exynos_phy1_control
->phy_con42
, val
);
49 if (dmc_config_zq(mem
, exynos_phy0_control
, exynos_phy1_control
)){
50 printk(BIOS_EMERG
, "DRAM ZQ CALIBRATION FAILURE\n");
51 return SETUP_ERR_ZQ_CALIBRATION_FAILURE
;
55 write32(&exynos_phy0_control
->phy_con14
, mem
->phy0_pulld_dqs
);
56 write32(&exynos_phy1_control
->phy_con14
, mem
->phy1_pulld_dqs
);
58 write32(&exynos_dmc
->concontrol
, mem
->concontrol
|
59 (mem
->rd_fetch
<< CONCONTROL_RD_FETCH_SHIFT
) |
60 (mem
->dfi_init_start
<< CONCONTROL_DFI_INIT_START_SHIFT
));
62 update_reset_dll(exynos_dmc
, DDR_MODE_DDR3
);
65 write32(&exynos_phy0_control
->phy_con4
, mem
->phy0_dqs
);
66 write32(&exynos_phy1_control
->phy_con4
, mem
->phy1_dqs
);
68 write32(&exynos_phy0_control
->phy_con6
, mem
->phy0_dq
);
69 write32(&exynos_phy1_control
->phy_con6
, mem
->phy1_dq
);
71 write32(&exynos_phy0_control
->phy_con10
, mem
->phy0_tFS
);
72 write32(&exynos_phy1_control
->phy_con10
, mem
->phy1_tFS
);
74 val
= (mem
->ctrl_start_point
<< PHY_CON12_CTRL_START_POINT_SHIFT
) |
75 (mem
->ctrl_inc
<< PHY_CON12_CTRL_INC_SHIFT
) |
76 (mem
->ctrl_dll_on
<< PHY_CON12_CTRL_DLL_ON_SHIFT
) |
77 (mem
->ctrl_ref
<< PHY_CON12_CTRL_REF_SHIFT
);
78 write32(&exynos_phy0_control
->phy_con12
, val
);
79 write32(&exynos_phy1_control
->phy_con12
, val
);
81 /* Start DLL locking */
82 write32(&exynos_phy0_control
->phy_con12
,
83 val
| (mem
->ctrl_start
<< PHY_CON12_CTRL_START_SHIFT
));
84 write32(&exynos_phy1_control
->phy_con12
,
85 val
| (mem
->ctrl_start
<< PHY_CON12_CTRL_START_SHIFT
));
87 update_reset_dll(exynos_dmc
, DDR_MODE_DDR3
);
89 write32(&exynos_dmc
->concontrol
,
90 mem
->concontrol
| (mem
->rd_fetch
<< CONCONTROL_RD_FETCH_SHIFT
));
92 /* Memory Channel Inteleaving Size */
93 write32(&exynos_dmc
->ivcontrol
, mem
->iv_size
);
95 /* Set DMC MEMCONTROL register */
96 val
= mem
->memcontrol
& ~DMC_MEMCONTROL_DSREF_ENABLE
;
97 write32(&exynos_dmc
->memcontrol
, val
);
99 write32(&exynos_dmc
->memconfig0
, mem
->memconfig
);
100 write32(&exynos_dmc
->memconfig1
, mem
->memconfig
);
101 write32(&exynos_dmc
->membaseconfig0
, mem
->membaseconfig0
);
102 write32(&exynos_dmc
->membaseconfig1
, mem
->membaseconfig1
);
104 /* Precharge Configuration */
105 write32(&exynos_dmc
->prechconfig
,
106 mem
->prechconfig_tp_cnt
<< PRECHCONFIG_TP_CNT_SHIFT
);
108 /* Power Down mode Configuration */
109 write32(&exynos_dmc
->pwrdnconfig
,
110 mem
->dpwrdn_cyc
<< PWRDNCONFIG_DPWRDN_CYC_SHIFT
|
111 mem
->dsref_cyc
<< PWRDNCONFIG_DSREF_CYC_SHIFT
);
113 /* TimingRow, TimingData, TimingPower and Timingaref
114 * values as per Memory AC parameters
116 write32(&exynos_dmc
->timingref
, mem
->timing_ref
);
117 write32(&exynos_dmc
->timingrow
, mem
->timing_row
);
118 write32(&exynos_dmc
->timingdata
, mem
->timing_data
);
119 write32(&exynos_dmc
->timingpower
, mem
->timing_power
);
121 /* Send PALL command */
122 dmc_config_prech(mem
, exynos_dmc
);
125 /* Send NOP, MRS and ZQINIT commands.
126 * Sending MRS command will reset the DRAM. We should not be
127 * resetting the DRAM after resume, this will lead to memory
128 * corruption as DRAM content is lost after DRAM reset
130 dmc_config_mrs(mem
, exynos_dmc
);
133 if (mem
->gate_leveling_enable
) {
134 val
= PHY_CON0_RESET_VAL
;
136 write32(&exynos_phy0_control
->phy_con0
, val
);
137 write32(&exynos_phy1_control
->phy_con0
, val
);
139 val
= PHY_CON2_RESET_VAL
;
140 val
|= INIT_DESKEW_EN
;
141 write32(&exynos_phy0_control
->phy_con2
, val
);
142 write32(&exynos_phy1_control
->phy_con2
, val
);
144 val
= PHY_CON0_RESET_VAL
;
146 val
|= BYTE_RDLVL_EN
;
147 write32(&exynos_phy0_control
->phy_con0
, val
);
148 write32(&exynos_phy1_control
->phy_con0
, val
);
150 val
= (mem
->ctrl_start_point
<<
151 PHY_CON12_CTRL_START_POINT_SHIFT
) |
152 (mem
->ctrl_inc
<< PHY_CON12_CTRL_INC_SHIFT
) |
153 (mem
->ctrl_force
<< PHY_CON12_CTRL_FORCE_SHIFT
) |
154 (mem
->ctrl_start
<< PHY_CON12_CTRL_START_SHIFT
) |
155 (mem
->ctrl_ref
<< PHY_CON12_CTRL_REF_SHIFT
);
156 write32(&exynos_phy0_control
->phy_con12
, val
);
157 write32(&exynos_phy1_control
->phy_con12
, val
);
159 val
= PHY_CON2_RESET_VAL
;
160 val
|= INIT_DESKEW_EN
;
161 val
|= RDLVL_GATE_EN
;
162 write32(&exynos_phy0_control
->phy_con2
, val
);
163 write32(&exynos_phy1_control
->phy_con2
, val
);
165 val
= PHY_CON0_RESET_VAL
;
167 val
|= BYTE_RDLVL_EN
;
169 write32(&exynos_phy0_control
->phy_con0
, val
);
170 write32(&exynos_phy1_control
->phy_con0
, val
);
172 val
= PHY_CON1_RESET_VAL
;
173 val
&= ~(CTRL_GATEDURADJ_MASK
);
174 write32(&exynos_phy0_control
->phy_con1
, val
);
175 write32(&exynos_phy1_control
->phy_con1
, val
);
177 write32(&exynos_dmc
->rdlvl_config
, CTRL_RDLVL_GATE_ENABLE
);
178 i
= RDLVL_COMPLETE_TIMEOUT
;
179 while ((read32(&exynos_dmc
->phystatus
) &
180 (RDLVL_COMPLETE_CHO
| RDLVL_COMPLETE_CH1
)) !=
181 (RDLVL_COMPLETE_CHO
| RDLVL_COMPLETE_CH1
) && i
> 0) {
183 * TODO(waihong): Comment on how long this take to
190 printk(BIOS_EMERG
, "Timeout on RDLVL. No DRAM.\n");
191 return SETUP_ERR_RDLV_COMPLETE_TIMEOUT
;
193 write32(&exynos_dmc
->rdlvl_config
, CTRL_RDLVL_GATE_DISABLE
);
195 write32(&exynos_phy0_control
->phy_con14
, 0);
196 write32(&exynos_phy1_control
->phy_con14
, 0);
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 write32(&exynos_phy0_control
->phy_con12
, val
);
206 write32(&exynos_phy1_control
->phy_con12
, val
);
208 update_reset_dll(exynos_dmc
, DDR_MODE_DDR3
);
211 /* Send PALL command */
212 dmc_config_prech(mem
, exynos_dmc
);
214 write32(&exynos_dmc
->memcontrol
, mem
->memcontrol
);
216 /* Set DMC Concontrol and enable auto-refresh counter */
217 write32(&exynos_dmc
->concontrol
, mem
->concontrol
|
218 (mem
->rd_fetch
<< CONCONTROL_RD_FETCH_SHIFT
) |
219 (mem
->aref_en
<< CONCONTROL_AREF_EN_SHIFT
));