xref: /aosp_15_r20/external/coreboot/src/soc/mediatek/mt8183/dramc_pi_basic_api.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/mmio.h>
4 #include <delay.h>
5 #include <soc/emi.h>
6 #include <soc/spm.h>
7 #include <soc/dramc_register.h>
8 #include <soc/dramc_pi_api.h>
9 
get_freq_fsq(u8 freq)10 u8 get_freq_fsq(u8 freq)
11 {
12 	if (freq == LP4X_DDR1600 || freq == LP4X_DDR2400)
13 		return FSP_0;
14 	else
15 		return FSP_1;
16 }
17 
dramc_sw_imp_cal_vref_sel(u8 term_option,u8 impcal_stage)18 static void dramc_sw_imp_cal_vref_sel(u8 term_option, u8 impcal_stage)
19 {
20 	u8 vref_sel = 0;
21 
22 	if (term_option == ODT_ON)
23 		vref_sel = IMP_LP4X_TERM_VREF_SEL;
24 	else {
25 		switch (impcal_stage) {
26 		case IMPCAL_STAGE_DRVP:
27 			vref_sel = IMP_DRVP_LP4X_UNTERM_VREF_SEL;
28 			break;
29 		case IMPCAL_STAGE_DRVN:
30 			vref_sel = IMP_DRVN_LP4X_UNTERM_VREF_SEL;
31 			break;
32 		default:
33 			vref_sel = IMP_TRACK_LP4X_UNTERM_VREF_SEL;
34 			break;
35 		}
36 	}
37 
38 	clrsetbits32(&ch[0].phy.shu[0].ca_cmd[11], 0x3f << 8, vref_sel << 8);
39 }
40 
dramc_sw_impedance_cal(const struct sdram_params * params,u8 term,struct dram_impedance * impedance)41 void dramc_sw_impedance_cal(const struct sdram_params *params, u8 term,
42 			    struct dram_impedance *impedance)
43 {
44 	u32 broadcast_bak, impcal_bak, imp_cal_result;
45 	u32 DRVP_result = 0xff, ODTN_result = 0xff, DRVN_result = 0x9;
46 
47 	broadcast_bak = dramc_get_broadcast();
48 	dramc_set_broadcast(DRAMC_BROADCAST_OFF);
49 
50 	for (u8 chn = 0; chn < CHANNEL_MAX; chn++) {
51 		clrbits32(&ch[chn].phy.misc_spm_ctrl1, 0xf << 0);
52 		write32(&ch[chn].phy.misc_spm_ctrl2, 0x0);
53 		write32(&ch[chn].phy.misc_spm_ctrl0, 0x0);
54 		clrbits32(&ch[chn].ao.impcal, 0x1 << 31);
55 	}
56 
57 	impcal_bak = read32(&ch[0].ao.impcal);
58 	dramc_sw_imp_cal_vref_sel(term, IMPCAL_STAGE_DRVP);
59 	clrbits32(&ch[0].phy.misc_imp_ctrl1, 0x1 << 6);
60 	clrsetbits32(&ch[0].ao.impcal, 0x1 << 21, 0x3 << 24);
61 	clrsetbits32(&ch[0].phy.misc_imp_ctrl0, 0x7 << 4, 0x3 << 4);
62 	udelay(1);
63 
64 	dramc_dbg("impedance: K DRVP\n");
65 	setbits32(&ch[0].ao.impcal, 0x1 << 23);
66 	setbits32(&ch[0].ao.impcal, 0x1 << 22);
67 	clrbits32(&ch[0].ao.impcal, 0x1 << 21);
68 	clrbits32(&ch[0].ao.shu[0].impcal1, 0x1f << 4 | 0x1f << 11);
69 	clrsetbits32(&ch[0].phy.shu[0].ca_cmd[11], 0xff << 0, 0x3);
70 
71 	for (u8 impx_drv = 0; impx_drv < 32; impx_drv++) {
72 		impx_drv = (impx_drv == 16) ? 29 : impx_drv;
73 
74 		clrsetbits32(&ch[0].ao.shu[0].impcal1,
75 				0x1f << 4, impx_drv << 4);
76 		udelay(1);
77 		imp_cal_result = (read32(&ch[0].phy_nao.misc_phy_rgs_cmd) >>
78 				  24) & 0x1;
79 		dramc_dbg("1. OCD DRVP=%d CALOUT=%d\n",
80 			  impx_drv, imp_cal_result);
81 
82 		if (imp_cal_result == 1 && DRVP_result == 0xff) {
83 			DRVP_result = impx_drv;
84 			dramc_dbg("1. OCD DRVP calibration OK! DRVP=%d\n",
85 				  DRVP_result);
86 			break;
87 		}
88 	}
89 
90 	dramc_dbg("impedance: K ODTN\n");
91 	dramc_sw_imp_cal_vref_sel(term, IMPCAL_STAGE_DRVN);
92 	clrbits32(&ch[0].ao.impcal, 0x1 << 22);
93 	if (term == ODT_ON)
94 		setbits32(&ch[0].ao.impcal, 0x1 << 21);
95 	clrsetbits32(&ch[0].ao.shu[0].impcal1, 0x1f << 4 | 0x1f << 11,
96 		DRVP_result << 4);
97 	clrsetbits32(&ch[0].phy.shu[0].ca_cmd[11], 0xff << 0, 0x3);
98 
99 	for (u8 impx_drv = 0; impx_drv < 32; impx_drv++) {
100 		impx_drv = (impx_drv == 16) ? 29 : impx_drv;
101 
102 		clrsetbits32(&ch[0].ao.shu[0].impcal1,
103 				0x1f << 11, impx_drv << 11);
104 		udelay(1);
105 		imp_cal_result = (read32(&ch[0].phy_nao.misc_phy_rgs_cmd) >>
106 				  24) & 0x1;
107 		dramc_dbg("3. OCD ODTN=%d CALOUT=%d\n",
108 			  impx_drv, imp_cal_result);
109 
110 		if (imp_cal_result == 0 && ODTN_result == 0xff) {
111 			ODTN_result = impx_drv;
112 			dramc_dbg("3. OCD ODTN calibration OK! ODTN=%d\n",
113 				  ODTN_result);
114 			break;
115 		}
116 	}
117 
118 	write32(&ch[0].ao.impcal, impcal_bak);
119 
120 	dramc_dbg("impedance: term=%d, DRVP=%d, DRVN=%d, ODTN=%d\n",
121 		  term, DRVP_result, DRVN_result, ODTN_result);
122 	u32 *imp = impedance->data[term];
123 	if (term == ODT_OFF) {
124 		imp[0] = DRVP_result;
125 		imp[1] = ODTN_result;
126 		imp[2] = 0;
127 		imp[3] = 15;
128 	} else {
129 		imp[0] = (DRVP_result <= 3) ? (DRVP_result * 3) : DRVP_result;
130 		imp[1] = (DRVN_result <= 3) ? (DRVN_result * 3) : DRVN_result;
131 		imp[2] = 0;
132 		imp[3] = (ODTN_result <= 3) ? (ODTN_result * 3) : ODTN_result;
133 	}
134 	dramc_sw_imp_cal_vref_sel(term, IMPCAL_STAGE_TRACKING);
135 
136 	dramc_set_broadcast(broadcast_bak);
137 }
138 
dramc_sw_impedance_save_reg(u8 freq_group,const struct dram_impedance * impedance)139 void dramc_sw_impedance_save_reg(u8 freq_group,
140 				 const struct dram_impedance *impedance)
141 {
142 	u8 ca_term = ODT_OFF, dq_term = ODT_ON;
143 	u32 sw_impedance[2][4] = {0};
144 
145 	if (get_freq_fsq(freq_group) == FSP_0)
146 		dq_term = ODT_OFF;
147 
148 	for (u8 term = 0; term < 2; term++)
149 		for (u8 i = 0; i < 4; i++)
150 			sw_impedance[term][i] = impedance->data[term][i];
151 
152 	sw_impedance[ODT_OFF][2] = sw_impedance[ODT_ON][2];
153 	sw_impedance[ODT_OFF][3] = sw_impedance[ODT_ON][3];
154 
155 	/* DQ */
156 	clrsetbits32(&ch[0].ao.shu[0].drving[0], (0x1f << 5) | (0x1f << 0),
157 		(sw_impedance[dq_term][0] << 5) |
158 		(sw_impedance[dq_term][1] << 0));
159 	clrsetbits32(&ch[0].ao.shu[0].drving[1],
160 		(0x1f << 25) | (0x1f << 20) | (1 << 31),
161 		(sw_impedance[dq_term][0] << 25) |
162 		(sw_impedance[dq_term][1] << 20) | (!dq_term << 31));
163 	clrsetbits32(&ch[0].ao.shu[0].drving[2], (0x1f << 5) | (0x1f << 0),
164 		(sw_impedance[dq_term][2] << 5) |
165 		(sw_impedance[dq_term][3] << 0));
166 	clrsetbits32(&ch[0].ao.shu[0].drving[3], (0x1f << 25) | (0x1f << 20),
167 		(sw_impedance[dq_term][2] << 25) |
168 		(sw_impedance[dq_term][3] << 20));
169 
170 	/* DQS */
171 	for (u8 i = 0; i <= 2; i += 2) {
172 		clrsetbits32(&ch[0].ao.shu[0].drving[i],
173 			(0x1f << 25) | (0x1f << 20),
174 			(sw_impedance[dq_term][i] << 25) |
175 			(sw_impedance[dq_term][i + 1] << 20));
176 		clrsetbits32(&ch[0].ao.shu[0].drving[i],
177 			(0x1f << 15) | (0x1f << 10),
178 			(sw_impedance[dq_term][i] << 15) |
179 			(sw_impedance[dq_term][i + 1] << 10));
180 	}
181 
182 	/* CMD & CLK */
183 	for (u8 i = 1; i <= 3; i += 2) {
184 		clrsetbits32(&ch[0].ao.shu[0].drving[i],
185 			(0x1f << 15) | (0x1f << 10),
186 			(sw_impedance[ca_term][i - 1] << 15) |
187 			(sw_impedance[ca_term][i] << 10));
188 		clrsetbits32(&ch[0].ao.shu[0].drving[i],
189 			(0x1f << 5) | (0x1f << 0),
190 			(sw_impedance[ca_term][i - 1] << 5) |
191 			(sw_impedance[ca_term][i] << 0));
192 	}
193 
194 	clrsetbits32(&ch[0].phy.shu[0].ca_cmd[11], 0x1f << 17,
195 		sw_impedance[ca_term][0] << 17);
196 	clrsetbits32(&ch[0].phy.shu[0].ca_cmd[11], 0x1f << 22,
197 		sw_impedance[ca_term][1] << 22);
198 
199 	SET32_BITFIELDS(&ch[0].phy.shu[0].ca_cmd[3],
200 			SHU1_CA_CMD3_RG_TX_ARCMD_PU_PRE, 1);
201 	SET32_BITFIELDS(&ch[0].phy.shu[0].ca_cmd[0],
202 			SHU1_CA_CMD0_RG_TX_ARCLK_DRVN_PRE, 0);
203 
204 	dramc_set_broadcast(DRAMC_BROADCAST_OFF);
205 	clrsetbits32(&ch[0].phy.shu[0].ca_dll[1], 0x1f << 16, 0x9 << 16);
206 	clrsetbits32(&ch[1].phy.shu[0].ca_dll[1], 0x1f << 16, 0x9 << 16);
207 	dramc_set_broadcast(DRAMC_BROADCAST_ON);
208 }
209 
transfer_pll_to_spm_control(void)210 static void transfer_pll_to_spm_control(void)
211 {
212 	u8 shu_lev = (read32(&ch[0].ao.shustatus) >> 1) & 0x3;
213 
214 	clrsetbits32(&mtk_spm->poweron_config_set,
215 		(0xffff << 16) | (0x1 << 0),
216 		(0xb16 << 16) | (0x1 << 0));
217 
218 	/* Set SPM pinmux */
219 	clrbits32(&mtk_spm->pcm_pwr_io_en, (0xff << 0) | (0xff << 16));
220 	setbits32(&mtk_spm->dramc_dpy_clk_sw_con_sel, 0xffffffff);
221 	setbits32(&mtk_spm->dramc_dpy_clk_sw_con_sel2, 0xffffffff);
222 
223 	setbits32(&mtk_spm->spm_power_on_val0, (0x1 << 8) | (0xf << 12));
224 	setbits32(&mtk_spm->spm_s1_mode_ch, 0x3 << 0);
225 
226 	shu_lev = (shu_lev == 1) ? 2 : 1;
227 	clrsetbits32(&mtk_spm->spm_power_on_val0, 0x3 << 28, shu_lev << 28);
228 	clrsetbits32(&mtk_spm->dramc_dpy_clk_sw_con2,
229 		0x3 << 2, shu_lev << 2);
230 
231 	udelay(1);
232 	for (size_t chn = CHANNEL_A; chn < CHANNEL_MAX; chn++) {
233 		clrbits32(&ch[chn].phy.pll1, 0x1 << 31);
234 		clrbits32(&ch[chn].phy.pll2, 0x1 << 31);
235 	}
236 }
237 
dramc_rx_input_delay_tracking(u8 chn)238 static void dramc_rx_input_delay_tracking(u8 chn)
239 {
240 	/* Enable RX_FIFO macro DIV4 clock CG */
241 	write32(&ch[chn].phy.misc_cg_ctrl1, 0xffffffff);
242 
243 	/* DVS mode to RG mode */
244 	for (size_t r = 0; r < 2; r++)
245 		for (size_t b = 0; b < 2; b++)
246 			clrbits32(&ch[chn].phy.r[r].b[b].rxdvs[2], 3 << 30);
247 
248 	clrsetbits32(&ch[chn].phy.b0_rxdvs[0], 0x1 << 19, 0x1 << 9);
249 	clrsetbits32(&ch[chn].phy.b1_rxdvs[0], 0x1 << 19, 0x1 << 9);
250 
251 	for (size_t r = 0; r < 2; r++)
252 		for (size_t b = 0; b < 2; b++) {
253 			clrbits32(&ch[chn].phy.r[r].b[b].rxdvs[2], 1 << 29);
254 			clrsetbits32(&ch[chn].phy.r[r].b[b].rxdvs[7],
255 				(0x3f << 0) | (0x3f << 8) |
256 				(0x7f << 16) | (0x7f << 24),
257 				(0x0 << 0) | (0x3f << 8) |
258 				(0x0 << 16) | (0x7f << 24));
259 			clrsetbits32(&ch[chn].phy.r[r].b[b].rxdvs[1],
260 				(0xffff << 16) | (0xffff << 0),
261 				(0x2 << 16) | (0x2 << 0));
262 
263 			/* DQ/DQS Rx DLY adjustment for tracking mode */
264 			clrbits32(&ch[chn].phy.r[r].b[b].rxdvs[2],
265 				(0x3 << 26) | (0x3 << 24) |
266 				(0x3 << 18) | (0x3 << 16));
267 		}
268 
269 	/* Rx DLY tracking setting (Static) */
270 	clrsetbits32(&ch[chn].phy.b0_rxdvs[0],
271 		(0x1 << 29) | (0xf << 4) | (0x1 << 0),
272 		(0x1 << 29) | (0x0 << 4) | (0x1 << 0));
273 	clrsetbits32(&ch[chn].phy.b1_rxdvs[0],
274 		(0x1 << 29) | (0xf << 4) | (0x1 << 0),
275 		(0x1 << 29) | (0x0 << 4) | (0x1 << 0));
276 
277 	for (u8 b = 0; b < 2; b++)
278 		clrsetbits32(&ch[chn].phy.b[b].dq[9],
279 			     (0x7 << 28) | (0x7 << 24),
280 			     (0x1 << 28) | (0x0 << 24));
281 	clrbits32(&ch[chn].phy.ca_cmd[10], (0x7 << 28) | (0x7 << 24));
282 	for (u8 b = 0; b < 2; b++)
283 		setbits32(&ch[chn].phy.b[b].dq[5], 0x1 << 31);
284 
285 	setbits32(&ch[chn].phy.b0_rxdvs[0], (0x1 << 28) | (0x1 << 31));
286 	setbits32(&ch[chn].phy.b1_rxdvs[0], (0x1 << 28) | (0x1 << 31));
287 	for (u8 rank = RANK_0; rank < RANK_MAX; rank++)
288 		for (u8 b = 0; b < 2; b++)
289 			clrsetbits32(&ch[chn].phy.r[rank].b[b].rxdvs[2],
290 				(0x3 << 30) | (0x1 << 28) | (0x1 << 23),
291 				(0x2 << 30) | (0x1 << 28) | (0x1 << 23));
292 }
293 
dramc_hw_dqs_gating_tracking(u8 chn)294 static void dramc_hw_dqs_gating_tracking(u8 chn)
295 {
296 	clrsetbits32(&ch[chn].ao.stbcal,
297 		(0x1 << 21) | (0x3 << 15) | (0x1f << 8) | (0x1 << 4),
298 		(0x3 << 26) | (0x1 << 0));
299 	clrsetbits32(&ch[chn].ao.stbcal1,
300 		(0xffff << 16) | (0x1 << 8) | (0x1 << 6),
301 		(0x1 << 16) | (0x1 << 8) | (0x1 << 6));
302 
303 	clrsetbits32(&ch[chn].phy.misc_ctrl0,
304 		(0x1 << 24) | (0x1f << 11) | (0xf << 0),
305 		(0x1 << 24) | (0x0 << 11) | (0x0 << 0));
306 
307 	clrbits32(&ch[chn].phy.b[0].dq[6], 0x1 << 31);
308 	clrbits32(&ch[chn].phy.b[1].dq[6], 0x1 << 31);
309 	clrbits32(&ch[chn].phy.ca_cmd[6], 0x1 << 31);
310 }
311 
dramc_hw_gating_init(u8 chn)312 static void dramc_hw_gating_init(u8 chn)
313 {
314 	clrbits32(&ch[chn].ao.stbcal,
315 		  (0x7 << 22) | (0x3 << 14) | (0x1 << 19) | (0x1 << 21));
316 	setbits32(&ch[chn].ao.stbcal, (0x1 << 20) | (0x3 << 28));
317 	setbits32(&ch[chn].phy.misc_ctrl1, 0x1 << 24);
318 
319 	dramc_hw_dqs_gating_tracking(chn);
320 }
321 
dramc_impedance_tracking_enable(void)322 static void dramc_impedance_tracking_enable(void)
323 {
324 	setbits32(&ch[0].phy.misc_ctrl0, 0x1 << 10);
325 	for (size_t chn = 0; chn < CHANNEL_MAX; chn++) {
326 		setbits32(&ch[chn].ao.impcal, (0x1 << 31) | (0x1 << 29) |
327 			(0x1 << 26) | (0x1 << 17) | (0x7 << 11));
328 		clrbits32(&ch[chn].ao.impcal, 0x1 << 30);
329 		setbits32(&ch[chn].phy.misc_ctrl0, 0x1 << 18);
330 		setbits32(&ch[chn].ao.impcal, 0x1 << 19);
331 	}
332 	setbits32(&ch[0].ao.impcal, 0x1 << 14);
333 	for (size_t chn = 0; chn < CHANNEL_MAX; chn++)
334 		setbits32(&ch[chn].ao.refctrl0, (0x1 << 2) | (0x1 << 3));
335 }
336 
dramc_phy_low_power_enable(u8 chn)337 static void dramc_phy_low_power_enable(u8 chn)
338 {
339 	for (u8 b = 0; b < 2; b++) {
340 		clrbits32(&ch[chn].phy.b[b].dll_fine_tune[2], 0x3fffff << 10);
341 		write32(&ch[chn].phy.b[b].dll_fine_tune[3], 0x2e800);
342 	}
343 	clrsetbits32(&ch[chn].phy.ca_dll_fine_tune[2],
344 		     0x3fffff << 10, 0x2 << 10);
345 	write32(&ch[chn].phy.ca_dll_fine_tune[3],
346 		(chn == CHANNEL_A) ? 0xba000 : 0x3a000);
347 }
348 
dramc_dummy_read_for_tracking_enable(u8 chn,u32 rk_num)349 static void dramc_dummy_read_for_tracking_enable(u8 chn, u32 rk_num)
350 {
351 	setbits32(&ch[chn].ao.dummy_rd, rk_num << 16);
352 
353 	for (size_t r = 0; r < 2; r++)
354 		for (size_t i = 0; i < 4; i++)
355 			write32(&ch[chn].ao.rk[r].dummy_rd_wdata[i],
356 				0xaaaa5555);
357 
358 	clrsetbits32(&ch[chn].ao.test2_4, 0x7 << 28, 0x4 << 28);
359 	for (size_t r = 0; r < 2; r++) {
360 		clrsetbits32(&ch[chn].ao.rk[r].dummy_rd_adr,
361 			(0x1ffff << 0) | (0x7ff << 17) | (0xf << 28),
362 			(0xffff << 0) | (0x3f0 << 17));
363 		clrbits32(&ch[chn].ao.rk[r].dummy_rd_bk, 0x7 << 0);
364 	}
365 
366 	clrbits32(&ch[chn].ao.dummy_rd, 0x1 << 25 | 0x1 << 20);
367 }
368 
dramc_set_CKE_2_rank_independent(u8 chn)369 static void dramc_set_CKE_2_rank_independent(u8 chn)
370 {
371 	clrsetbits32(&ch[chn].ao.rkcfg, (0x1 << 15) | (0x1 << 12), 0x1 << 2);
372 	clrsetbits32(&ch[chn].ao.ckectrl,
373 		(0x1 << 1) | (0xf << 8) | (0x7 << 13),
374 		(0x4 << 8) | (0x2 << 13));
375 
376 	for (u8 shu = 0; shu < DRAM_DFS_SHUFFLE_MAX; shu++)
377 		setbits32(&ch[chn].ao.shu[shu].conf[2],
378 			(0x1 << 29) | (0x1 << 31));
379 	clrbits32(&ch[chn].ao.dramctrl, 0x1 << 9);
380 }
381 
dramc_pa_improve(u8 chn)382 static void dramc_pa_improve(u8 chn)
383 {
384 	clrbits32(&ch[chn].ao.clkar, 0xffff);
385 	clrbits32(&ch[chn].ao.srefctrl, 0xf << 12);
386 	clrbits32(&ch[chn].ao.zqcs, 0x1 << 19);
387 	clrbits32(&ch[chn].ao.pre_tdqsck[0], 0x1 << 17);
388 	clrbits32(&ch[chn].ao.zqcs, 0x1 << 19);
389 	clrbits32(&ch[chn].ao.pre_tdqsck[0], 0x1 << 17);
390 
391 	for (u8 shu = 0; shu < DRAM_DFS_SHUFFLE_MAX; shu++)
392 		clrbits32(&ch[chn].ao.shu[shu].odtctrl, 0x3 << 2);
393 }
394 
dramc_enable_dramc_dcm(void)395 static void dramc_enable_dramc_dcm(void)
396 {
397 	for (size_t chn = 0; chn < CHANNEL_MAX; chn++) {
398 		clrsetbits32(&ch[chn].ao.dramc_pd_ctrl,
399 			(0x7 << 0) | (0x1 << 26) | (0x1 << 30) | (0x1 << 31),
400 			(0x7 << 0) | (0x1 << 30) | (0x1 << 31));
401 		setbits32(&ch[chn].ao.clkar, 0x1 << 31);
402 	}
403 }
404 
dramc_runtime_config(u32 rk_num)405 void dramc_runtime_config(u32 rk_num)
406 {
407 	for (u8 chn = 0; chn < CHANNEL_MAX; chn++)
408 		clrbits32(&ch[chn].ao.refctrl0, 0x1 << 29);
409 
410 	transfer_pll_to_spm_control();
411 	setbits32(&mtk_spm->spm_power_on_val0, 0x1 << 25);
412 
413 	for (u8 chn = 0; chn < CHANNEL_MAX; chn++) {
414 		dramc_hw_dqsosc(chn, rk_num);
415 
416 		/* RX_TRACKING: ON */
417 		dramc_rx_input_delay_tracking(chn);
418 
419 		/* HW_GATING: ON */
420 		dramc_hw_gating_init(chn);
421 		dramc_hw_gating_onoff(chn, true);
422 
423 		/* HW_GATING DBG: OFF */
424 		clrbits32(&ch[chn].ao.stbcal2,
425 			  (0x3 << 4) | (0x3 << 8) | (0x1 << 28));
426 
427 		/* DUMMY_READ_FOR_TRACKING: ON */
428 		dramc_dummy_read_for_tracking_enable(chn, rk_num);
429 
430 		/* ZQCS_ENABLE_LP4: ON */
431 		clrbits32(&ch[chn].ao.spcmdctrl, 0x1 << 30);
432 
433 		/* LOWPOWER_GOLDEN_SETTINGS(DCM): ON */
434 		dramc_phy_low_power_enable(chn);
435 		dramc_enable_phy_dcm(chn, true);
436 
437 		/* DUMMY_READ_FOR_DQS_GATING_RETRY: OFF */
438 		for (size_t shu = 0; shu < DRAM_DFS_SHUFFLE_MAX; shu++)
439 			clrbits32(&ch[chn].ao.shu[shu].dqsg_retry,
440 				  (0x1 << 1) | (0x3 << 13));
441 	}
442 
443 	/* SPM_CONTROL_AFTERK: ON */
444 	write32(&ch[0].phy.misc_spm_ctrl0, 0xfbffefff);
445 	write32(&ch[1].phy.misc_spm_ctrl0, 0xfbffefff);
446 	write32(&ch[0].phy.misc_spm_ctrl2, 0xffffffef);
447 	write32(&ch[1].phy.misc_spm_ctrl2, 0x7fffffef);
448 
449 	/* IMPEDANCE_TRACKING: ON */
450 	dramc_impedance_tracking_enable();
451 
452 	for (size_t chn = 0; chn < CHANNEL_MAX; chn++) {
453 		/* TEMP_SENSOR: ON */
454 		clrbits32(&ch[chn].ao.spcmdctrl, 0x3 << 28);
455 		setbits32(&ch[chn].ao.hw_mrr_fun, (0x1 << 0) | (0x1 << 11));
456 
457 		/* PER_BANK_REFRESH: ON */
458 		clrbits32(&ch[chn].ao.refctrl0, 0x1 << 18);
459 
460 		/* HW_SAVE_FOR_SR: ON */
461 		clrbits32(&ch[chn].ao.rstmask, (0x1 << 25) | (0x1 << 28));
462 		setbits32(&ch[chn].ao.refctrl1, 0x1 << 0);
463 		clrsetbits32(&ch[chn].ao.srefctrl, 0x1 << 20, 0x1 << 22);
464 
465 		/* SET_CKE_2_RANK_INDEPENDENT_RUN_TIME: ON */
466 		dramc_set_CKE_2_rank_independent(chn);
467 
468 		/* CLK_FREE_FUN_FOR_DRAMC_PSEL: ON */
469 		clrbits32(&ch[chn].ao.refctrl1, (0x1 << 6) | (0x3 << 2));
470 		clrbits32(&ch[chn].ao.clkar, 0x1 << 19);
471 
472 		/* PA_IMPROVEMENT_FOR_DRAMC_ACTIVE_POWER: ON */
473 		dramc_pa_improve(chn);
474 
475 		/* DRAM DRS DISABLE */
476 		clrsetbits32(&ch[chn].ao.drsctrl,
477 			(0x1 << 0) | (0x1 << 2) | (0x1 << 4) | (0x1 << 5) | (0x1 << 6) |
478 			(0xf << 8) | (0x7f << 12) | (0x1 << 19) | (0x1 << 21),
479 			(0x1 << 0) | (0x0 << 2) | (0x0 << 4) | (0x1 << 5) | (0x0 << 6) |
480 			(0x8 << 8) | (0x3 << 12) | (0x1 << 19) | (0x0 << 21));
481 		setbits32(&ch[chn].ao.dummy_rd, 0x3 << 26);
482 	}
483 	dramc_dqs_precalculation_preset();
484 
485 	enable_emi_dcm();
486 	dramc_enable_dramc_dcm();
487 }
488