xref: /openbmc/u-boot/arch/x86/cpu/quark/smc.c (revision 001646c4)
1 /*
2  * Copyright (C) 2013, Intel Corporation
3  * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
4  *
5  * Ported from Intel released Quark UEFI BIOS
6  * QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei
7  *
8  * SPDX-License-Identifier:	Intel
9  */
10 
11 #include <common.h>
12 #include <pci.h>
13 #include <asm/arch/device.h>
14 #include <asm/arch/mrc.h>
15 #include <asm/arch/msg_port.h>
16 #include "mrc_util.h"
17 #include "hte.h"
18 #include "smc.h"
19 
20 /* t_rfc values (in picoseconds) per density */
21 static const uint32_t t_rfc[5] = {
22 	90000,	/* 512Mb */
23 	110000,	/* 1Gb */
24 	160000,	/* 2Gb */
25 	300000,	/* 4Gb */
26 	350000,	/* 8Gb */
27 };
28 
29 /* t_ck clock period in picoseconds per speed index 800, 1066, 1333 */
30 static const uint32_t t_ck[3] = {
31 	2500,
32 	1875,
33 	1500
34 };
35 
36 /* Global variables */
37 static const uint16_t ddr_wclk[] = {193, 158};
38 static const uint16_t ddr_wctl[] = {1, 217};
39 static const uint16_t ddr_wcmd[] = {1, 220};
40 
41 #ifdef BACKUP_RCVN
42 static const uint16_t ddr_rcvn[] = {129, 498};
43 #endif
44 
45 #ifdef BACKUP_WDQS
46 static const uint16_t ddr_wdqs[] = {65, 289};
47 #endif
48 
49 #ifdef BACKUP_RDQS
50 static const uint8_t ddr_rdqs[] = {32, 24};
51 #endif
52 
53 #ifdef BACKUP_WDQ
54 static const uint16_t ddr_wdq[] = {32, 257};
55 #endif
56 
57 /* Stop self refresh driven by MCU */
58 void clear_self_refresh(struct mrc_params *mrc_params)
59 {
60 	ENTERFN();
61 
62 	/* clear the PMSTS Channel Self Refresh bits */
63 	mrc_write_mask(MEM_CTLR, PMSTS, BIT0, BIT0);
64 
65 	LEAVEFN();
66 }
67 
68 /* It will initialize timing registers in the MCU (DTR0..DTR4) */
69 void prog_ddr_timing_control(struct mrc_params *mrc_params)
70 {
71 	uint8_t tcl, wl;
72 	uint8_t trp, trcd, tras, twr, twtr, trrd, trtp, tfaw;
73 	uint32_t tck;
74 	u32 dtr0, dtr1, dtr2, dtr3, dtr4;
75 	u32 tmp1, tmp2;
76 
77 	ENTERFN();
78 
79 	/* mcu_init starts */
80 	mrc_post_code(0x02, 0x00);
81 
82 	dtr0 = msg_port_read(MEM_CTLR, DTR0);
83 	dtr1 = msg_port_read(MEM_CTLR, DTR1);
84 	dtr2 = msg_port_read(MEM_CTLR, DTR2);
85 	dtr3 = msg_port_read(MEM_CTLR, DTR3);
86 	dtr4 = msg_port_read(MEM_CTLR, DTR4);
87 
88 	tck = t_ck[mrc_params->ddr_speed];	/* Clock in picoseconds */
89 	tcl = mrc_params->params.cl;		/* CAS latency in clocks */
90 	trp = tcl;	/* Per CAT MRC */
91 	trcd = tcl;	/* Per CAT MRC */
92 	tras = MCEIL(mrc_params->params.ras, tck);
93 
94 	/* Per JEDEC: tWR=15000ps DDR2/3 from 800-1600 */
95 	twr = MCEIL(15000, tck);
96 
97 	twtr = MCEIL(mrc_params->params.wtr, tck);
98 	trrd = MCEIL(mrc_params->params.rrd, tck);
99 	trtp = 4;	/* Valid for 800 and 1066, use 5 for 1333 */
100 	tfaw = MCEIL(mrc_params->params.faw, tck);
101 
102 	wl = 5 + mrc_params->ddr_speed;
103 
104 	dtr0 &= ~(BIT0 | BIT1);
105 	dtr0 |= mrc_params->ddr_speed;
106 	dtr0 &= ~(BIT12 | BIT13 | BIT14);
107 	tmp1 = tcl - 5;
108 	dtr0 |= ((tcl - 5) << 12);
109 	dtr0 &= ~(BIT4 | BIT5 | BIT6 | BIT7);
110 	dtr0 |= ((trp - 5) << 4);	/* 5 bit DRAM Clock */
111 	dtr0 &= ~(BIT8 | BIT9 | BIT10 | BIT11);
112 	dtr0 |= ((trcd - 5) << 8);	/* 5 bit DRAM Clock */
113 
114 	dtr1 &= ~(BIT0 | BIT1 | BIT2);
115 	tmp2 = wl - 3;
116 	dtr1 |= (wl - 3);
117 	dtr1 &= ~(BIT8 | BIT9 | BIT10 | BIT11);
118 	dtr1 |= ((wl + 4 + twr - 14) << 8);	/* Change to tWTP */
119 	dtr1 &= ~(BIT28 | BIT29 | BIT30);
120 	dtr1 |= ((MMAX(trtp, 4) - 3) << 28);	/* 4 bit DRAM Clock */
121 	dtr1 &= ~(BIT24 | BIT25);
122 	dtr1 |= ((trrd - 4) << 24);		/* 4 bit DRAM Clock */
123 	dtr1 &= ~(BIT4 | BIT5);
124 	dtr1 |= (1 << 4);
125 	dtr1 &= ~(BIT20 | BIT21 | BIT22 | BIT23);
126 	dtr1 |= ((tras - 14) << 20);		/* 6 bit DRAM Clock */
127 	dtr1 &= ~(BIT16 | BIT17 | BIT18 | BIT19);
128 	dtr1 |= ((((tfaw + 1) >> 1) - 5) << 16);/* 4 bit DRAM Clock */
129 	/* Set 4 Clock CAS to CAS delay (multi-burst) */
130 	dtr1 &= ~(BIT12 | BIT13);
131 
132 	dtr2 &= ~(BIT0 | BIT1 | BIT2);
133 	dtr2 |= 1;
134 	dtr2 &= ~(BIT8 | BIT9 | BIT10);
135 	dtr2 |= (2 << 8);
136 	dtr2 &= ~(BIT16 | BIT17 | BIT18 | BIT19);
137 	dtr2 |= (2 << 16);
138 
139 	dtr3 &= ~(BIT0 | BIT1 | BIT2);
140 	dtr3 |= 2;
141 	dtr3 &= ~(BIT4 | BIT5 | BIT6);
142 	dtr3 |= (2 << 4);
143 
144 	dtr3 &= ~(BIT8 | BIT9 | BIT10 | BIT11);
145 	if (mrc_params->ddr_speed == DDRFREQ_800) {
146 		/* Extended RW delay (+1) */
147 		dtr3 |= ((tcl - 5 + 1) << 8);
148 	} else if (mrc_params->ddr_speed == DDRFREQ_1066) {
149 		/* Extended RW delay (+1) */
150 		dtr3 |= ((tcl - 5 + 1) << 8);
151 	}
152 
153 	dtr3 &= ~(BIT13 | BIT14 | BIT15 | BIT16);
154 	dtr3 |= ((4 + wl + twtr - 11) << 13);
155 
156 	dtr3 &= ~(BIT22 | BIT23);
157 	if (mrc_params->ddr_speed == DDRFREQ_800)
158 		dtr3 |= ((MMAX(0, 1 - 1)) << 22);
159 	else
160 		dtr3 |= ((MMAX(0, 2 - 1)) << 22);
161 
162 	dtr4 &= ~(BIT0 | BIT1);
163 	dtr4 |= 1;
164 	dtr4 &= ~(BIT4 | BIT5 | BIT6);
165 	dtr4 |= (1 << 4);
166 	dtr4 &= ~(BIT8 | BIT9 | BIT10);
167 	dtr4 |= ((1 + tmp1 - tmp2 + 2) << 8);
168 	dtr4 &= ~(BIT12 | BIT13 | BIT14);
169 	dtr4 |= ((1 + tmp1 - tmp2 + 2) << 12);
170 	dtr4 &= ~(BIT15 | BIT16);
171 
172 	msg_port_write(MEM_CTLR, DTR0, dtr0);
173 	msg_port_write(MEM_CTLR, DTR1, dtr1);
174 	msg_port_write(MEM_CTLR, DTR2, dtr2);
175 	msg_port_write(MEM_CTLR, DTR3, dtr3);
176 	msg_port_write(MEM_CTLR, DTR4, dtr4);
177 
178 	LEAVEFN();
179 }
180 
181 /* Configure MCU before jedec init sequence */
182 void prog_decode_before_jedec(struct mrc_params *mrc_params)
183 {
184 	u32 drp;
185 	u32 drfc;
186 	u32 dcal;
187 	u32 dsch;
188 	u32 dpmc0;
189 
190 	ENTERFN();
191 
192 	/* Disable power saving features */
193 	dpmc0 = msg_port_read(MEM_CTLR, DPMC0);
194 	dpmc0 |= (BIT24 | BIT25);
195 	dpmc0 &= ~(BIT16 | BIT17 | BIT18);
196 	dpmc0 &= ~BIT23;
197 	msg_port_write(MEM_CTLR, DPMC0, dpmc0);
198 
199 	/* Disable out of order transactions */
200 	dsch = msg_port_read(MEM_CTLR, DSCH);
201 	dsch |= (BIT8 | BIT12);
202 	msg_port_write(MEM_CTLR, DSCH, dsch);
203 
204 	/* Disable issuing the REF command */
205 	drfc = msg_port_read(MEM_CTLR, DRFC);
206 	drfc &= ~(BIT12 | BIT13 | BIT14);
207 	msg_port_write(MEM_CTLR, DRFC, drfc);
208 
209 	/* Disable ZQ calibration short */
210 	dcal = msg_port_read(MEM_CTLR, DCAL);
211 	dcal &= ~(BIT8 | BIT9 | BIT10);
212 	dcal &= ~(BIT12 | BIT13);
213 	msg_port_write(MEM_CTLR, DCAL, dcal);
214 
215 	/*
216 	 * Training performed in address mode 0, rank population has limited
217 	 * impact, however simulator complains if enabled non-existing rank.
218 	 */
219 	drp = 0;
220 	if (mrc_params->rank_enables & 1)
221 		drp |= BIT0;
222 	if (mrc_params->rank_enables & 2)
223 		drp |= BIT1;
224 	msg_port_write(MEM_CTLR, DRP, drp);
225 
226 	LEAVEFN();
227 }
228 
229 /*
230  * After Cold Reset, BIOS should set COLDWAKE bit to 1 before
231  * sending the WAKE message to the Dunit.
232  *
233  * For Standby Exit, or any other mode in which the DRAM is in
234  * SR, this bit must be set to 0.
235  */
236 void perform_ddr_reset(struct mrc_params *mrc_params)
237 {
238 	ENTERFN();
239 
240 	/* Set COLDWAKE bit before sending the WAKE message */
241 	mrc_write_mask(MEM_CTLR, DRMC, BIT16, BIT16);
242 
243 	/* Send wake command to DUNIT (MUST be done before JEDEC) */
244 	dram_wake_command();
245 
246 	/* Set default value */
247 	msg_port_write(MEM_CTLR, DRMC,
248 		       (mrc_params->rd_odt_value == 0 ? BIT12 : 0));
249 
250 	LEAVEFN();
251 }
252 
253 
254 /*
255  * This function performs some initialization on the DDRIO unit.
256  * This function is dependent on BOARD_ID, DDR_SPEED, and CHANNEL_ENABLES.
257  */
258 void ddrphy_init(struct mrc_params *mrc_params)
259 {
260 	uint32_t temp;
261 	uint8_t ch;	/* channel counter */
262 	uint8_t rk;	/* rank counter */
263 	uint8_t bl_grp;	/*  byte lane group counter (2 BLs per module) */
264 	uint8_t bl_divisor = 1;	/* byte lane divisor */
265 	/* For DDR3 --> 0 == 800, 1 == 1066, 2 == 1333 */
266 	uint8_t speed = mrc_params->ddr_speed & (BIT1 | BIT0);
267 	uint8_t cas;
268 	uint8_t cwl;
269 
270 	ENTERFN();
271 
272 	cas = mrc_params->params.cl;
273 	cwl = 5 + mrc_params->ddr_speed;
274 
275 	/* ddrphy_init starts */
276 	mrc_post_code(0x03, 0x00);
277 
278 	/*
279 	 * HSD#231531
280 	 * Make sure IOBUFACT is deasserted before initializing the DDR PHY
281 	 *
282 	 * HSD#234845
283 	 * Make sure WRPTRENABLE is deasserted before initializing the DDR PHY
284 	 */
285 	for (ch = 0; ch < NUM_CHANNELS; ch++) {
286 		if (mrc_params->channel_enables & (1 << ch)) {
287 			/* Deassert DDRPHY Initialization Complete */
288 			mrc_alt_write_mask(DDRPHY,
289 				(CMDPMCONFIG0 + (ch * DDRIOCCC_CH_OFFSET)),
290 				~BIT20, BIT20);	/* SPID_INIT_COMPLETE=0 */
291 			/* Deassert IOBUFACT */
292 			mrc_alt_write_mask(DDRPHY,
293 				(CMDCFGREG0 + (ch * DDRIOCCC_CH_OFFSET)),
294 				~BIT2, BIT2);	/* IOBUFACTRST_N=0 */
295 			/* Disable WRPTR */
296 			mrc_alt_write_mask(DDRPHY,
297 				(CMDPTRREG + (ch * DDRIOCCC_CH_OFFSET)),
298 				~BIT0, BIT0);	/* WRPTRENABLE=0 */
299 		}
300 	}
301 
302 	/* Put PHY in reset */
303 	mrc_alt_write_mask(DDRPHY, MASTERRSTN, 0, BIT0);
304 
305 	/* Initialize DQ01, DQ23, CMD, CLK-CTL, COMP modules */
306 
307 	/* STEP0 */
308 	mrc_post_code(0x03, 0x10);
309 	for (ch = 0; ch < NUM_CHANNELS; ch++) {
310 		if (mrc_params->channel_enables & (1 << ch)) {
311 			/* DQ01-DQ23 */
312 			for (bl_grp = 0;
313 			     bl_grp < ((NUM_BYTE_LANES / bl_divisor) / 2);
314 			     bl_grp++) {
315 				/* Analog MUX select - IO2xCLKSEL */
316 				mrc_alt_write_mask(DDRPHY,
317 					(DQOBSCKEBBCTL +
318 					(bl_grp * DDRIODQ_BL_OFFSET) +
319 					(ch * DDRIODQ_CH_OFFSET)),
320 					((bl_grp) ? (0x00) : (BIT22)), (BIT22));
321 
322 				/* ODT Strength */
323 				switch (mrc_params->rd_odt_value) {
324 				case 1:
325 					temp = 0x3;
326 					break;	/* 60 ohm */
327 				case 2:
328 					temp = 0x3;
329 					break;	/* 120 ohm */
330 				case 3:
331 					temp = 0x3;
332 					break;	/* 180 ohm */
333 				default:
334 					temp = 0x3;
335 					break;	/* 120 ohm */
336 				}
337 
338 				/* ODT strength */
339 				mrc_alt_write_mask(DDRPHY,
340 					(B0RXIOBUFCTL +
341 					(bl_grp * DDRIODQ_BL_OFFSET) +
342 					(ch * DDRIODQ_CH_OFFSET)),
343 					(temp << 5), (BIT6 | BIT5));
344 				/* ODT strength */
345 				mrc_alt_write_mask(DDRPHY,
346 					(B1RXIOBUFCTL +
347 					(bl_grp * DDRIODQ_BL_OFFSET) +
348 					(ch * DDRIODQ_CH_OFFSET)),
349 					(temp << 5), (BIT6 | BIT5));
350 
351 				/* Dynamic ODT/DIFFAMP */
352 				temp = (((cas) << 24) | ((cas) << 16) |
353 					((cas) << 8) | ((cas) << 0));
354 				switch (speed) {
355 				case 0:
356 					temp -= 0x01010101;
357 					break;	/* 800 */
358 				case 1:
359 					temp -= 0x02020202;
360 					break;	/* 1066 */
361 				case 2:
362 					temp -= 0x03030303;
363 					break;	/* 1333 */
364 				case 3:
365 					temp -= 0x04040404;
366 					break;	/* 1600 */
367 				}
368 
369 				/* Launch Time: ODT, DIFFAMP, ODT, DIFFAMP */
370 				mrc_alt_write_mask(DDRPHY,
371 					(B01LATCTL1 +
372 					(bl_grp * DDRIODQ_BL_OFFSET) +
373 					(ch * DDRIODQ_CH_OFFSET)),
374 					temp,
375 					(BIT28 | BIT27 | BIT26 | BIT25 | BIT24 |
376 					BIT20 | BIT19 | BIT18 | BIT17 | BIT16 |
377 					BIT12 | BIT11 | BIT10 | BIT9 | BIT8 |
378 					BIT4 | BIT3 | BIT2 | BIT1 | BIT0));
379 				switch (speed) {
380 				/* HSD#234715 */
381 				case 0:
382 					temp = ((0x06 << 16) | (0x07 << 8));
383 					break;	/* 800 */
384 				case 1:
385 					temp = ((0x07 << 16) | (0x08 << 8));
386 					break;	/* 1066 */
387 				case 2:
388 					temp = ((0x09 << 16) | (0x0A << 8));
389 					break;	/* 1333 */
390 				case 3:
391 					temp = ((0x0A << 16) | (0x0B << 8));
392 					break;	/* 1600 */
393 				}
394 
395 				/* On Duration: ODT, DIFFAMP */
396 				mrc_alt_write_mask(DDRPHY,
397 					(B0ONDURCTL +
398 					(bl_grp * DDRIODQ_BL_OFFSET) +
399 					(ch * DDRIODQ_CH_OFFSET)),
400 					temp,
401 					(BIT21 | BIT20 | BIT19 | BIT18 | BIT17 |
402 					BIT16 | BIT13 | BIT12 | BIT11 | BIT10 |
403 					BIT9 | BIT8));
404 				/* On Duration: ODT, DIFFAMP */
405 				mrc_alt_write_mask(DDRPHY,
406 					(B1ONDURCTL +
407 					(bl_grp * DDRIODQ_BL_OFFSET) +
408 					(ch * DDRIODQ_CH_OFFSET)),
409 					temp,
410 					(BIT21 | BIT20 | BIT19 | BIT18 | BIT17 |
411 					BIT16 | BIT13 | BIT12 | BIT11 | BIT10 |
412 					BIT9 | BIT8));
413 
414 				switch (mrc_params->rd_odt_value) {
415 				case 0:
416 					/* override DIFFAMP=on, ODT=off */
417 					temp = ((0x3F << 16) | (0x3f << 10));
418 					break;
419 				default:
420 					/* override DIFFAMP=on, ODT=on */
421 					temp = ((0x3F << 16) | (0x2A << 10));
422 					break;
423 				}
424 
425 				/* Override: DIFFAMP, ODT */
426 				mrc_alt_write_mask(DDRPHY,
427 					(B0OVRCTL +
428 					(bl_grp * DDRIODQ_BL_OFFSET) +
429 					(ch * DDRIODQ_CH_OFFSET)),
430 					temp,
431 					(BIT21 | BIT20 | BIT19 | BIT18 | BIT17 |
432 					BIT16 | BIT15 | BIT14 | BIT13 | BIT12 |
433 					BIT11 | BIT10));
434 				/* Override: DIFFAMP, ODT */
435 				mrc_alt_write_mask(DDRPHY,
436 					(B1OVRCTL +
437 					(bl_grp * DDRIODQ_BL_OFFSET) +
438 					(ch * DDRIODQ_CH_OFFSET)),
439 					temp,
440 					(BIT21 | BIT20 | BIT19 | BIT18 | BIT17 |
441 					BIT16 | BIT15 | BIT14 | BIT13 | BIT12 |
442 					BIT11 | BIT10));
443 
444 				/* DLL Setup */
445 
446 				/* 1xCLK Domain Timings: tEDP,RCVEN,WDQS (PO) */
447 				mrc_alt_write_mask(DDRPHY,
448 					(B0LATCTL0 +
449 					(bl_grp * DDRIODQ_BL_OFFSET) +
450 					(ch * DDRIODQ_CH_OFFSET)),
451 					(((cas + 7) << 16) | ((cas - 4) << 8) |
452 					((cwl - 2) << 0)),
453 					(BIT21 | BIT20 | BIT19 | BIT18 | BIT17 |
454 					BIT16 | BIT12 | BIT11 | BIT10 | BIT9 |
455 					BIT8 | BIT4 | BIT3 | BIT2 | BIT1 |
456 					BIT0));
457 				mrc_alt_write_mask(DDRPHY,
458 					(B1LATCTL0 +
459 					(bl_grp * DDRIODQ_BL_OFFSET) +
460 					(ch * DDRIODQ_CH_OFFSET)),
461 					(((cas + 7) << 16) | ((cas - 4) << 8) |
462 					((cwl - 2) << 0)),
463 					(BIT21 | BIT20 | BIT19 | BIT18 | BIT17 |
464 					BIT16 | BIT12 | BIT11 | BIT10 | BIT9 |
465 					BIT8 | BIT4 | BIT3 | BIT2 | BIT1 |
466 					BIT0));
467 
468 				/* RCVEN Bypass (PO) */
469 				mrc_alt_write_mask(DDRPHY,
470 					(B0RXIOBUFCTL +
471 					(bl_grp * DDRIODQ_BL_OFFSET) +
472 					(ch * DDRIODQ_CH_OFFSET)),
473 					((0x0 << 7) | (0x0 << 0)),
474 					(BIT7 | BIT0));
475 				mrc_alt_write_mask(DDRPHY,
476 					(B1RXIOBUFCTL +
477 					(bl_grp * DDRIODQ_BL_OFFSET) +
478 					(ch * DDRIODQ_CH_OFFSET)),
479 					((0x0 << 7) | (0x0 << 0)),
480 					(BIT7 | BIT0));
481 
482 				/* TX */
483 				mrc_alt_write_mask(DDRPHY,
484 					(DQCTL +
485 					(bl_grp * DDRIODQ_BL_OFFSET) +
486 					(ch * DDRIODQ_CH_OFFSET)),
487 					(BIT16), (BIT16));
488 				mrc_alt_write_mask(DDRPHY,
489 					(B01PTRCTL1 +
490 					(bl_grp * DDRIODQ_BL_OFFSET) +
491 					(ch * DDRIODQ_CH_OFFSET)),
492 					(BIT8), (BIT8));
493 
494 				/* RX (PO) */
495 				/* Internal Vref Code, Enable#, Ext_or_Int (1=Ext) */
496 				mrc_alt_write_mask(DDRPHY,
497 					(B0VREFCTL +
498 					(bl_grp * DDRIODQ_BL_OFFSET) +
499 					(ch * DDRIODQ_CH_OFFSET)),
500 					((0x03 << 2) | (0x0 << 1) | (0x0 << 0)),
501 					(BIT7 | BIT6 | BIT5 | BIT4 | BIT3 |
502 					BIT2 | BIT1 | BIT0));
503 				/* Internal Vref Code, Enable#, Ext_or_Int (1=Ext) */
504 				mrc_alt_write_mask(DDRPHY,
505 					(B1VREFCTL +
506 					(bl_grp * DDRIODQ_BL_OFFSET) +
507 					(ch * DDRIODQ_CH_OFFSET)),
508 					((0x03 << 2) | (0x0 << 1) | (0x0 << 0)),
509 					(BIT7 | BIT6 | BIT5 | BIT4 | BIT3 |
510 					BIT2 | BIT1 | BIT0));
511 				/* Per-Bit De-Skew Enable */
512 				mrc_alt_write_mask(DDRPHY,
513 					(B0RXIOBUFCTL +
514 					(bl_grp * DDRIODQ_BL_OFFSET) +
515 					(ch * DDRIODQ_CH_OFFSET)),
516 					(0), (BIT4));
517 				/* Per-Bit De-Skew Enable */
518 				mrc_alt_write_mask(DDRPHY,
519 					(B1RXIOBUFCTL +
520 					(bl_grp * DDRIODQ_BL_OFFSET) +
521 					(ch * DDRIODQ_CH_OFFSET)),
522 					(0), (BIT4));
523 			}
524 
525 			/* CLKEBB */
526 			mrc_alt_write_mask(DDRPHY,
527 				(CMDOBSCKEBBCTL + (ch * DDRIOCCC_CH_OFFSET)),
528 				0, (BIT23));
529 
530 			/* Enable tristate control of cmd/address bus */
531 			mrc_alt_write_mask(DDRPHY,
532 				(CMDCFGREG0 + (ch * DDRIOCCC_CH_OFFSET)),
533 				0, (BIT1 | BIT0));
534 
535 			/* ODT RCOMP */
536 			mrc_alt_write_mask(DDRPHY,
537 				(CMDRCOMPODT + (ch * DDRIOCCC_CH_OFFSET)),
538 				((0x03 << 5) | (0x03 << 0)),
539 				(BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 |
540 				BIT3 | BIT2 | BIT1 | BIT0));
541 
542 			/* CMDPM* registers must be programmed in this order */
543 
544 			/* Turn On Delays: SFR (regulator), MPLL */
545 			mrc_alt_write_mask(DDRPHY,
546 				(CMDPMDLYREG4 + (ch * DDRIOCCC_CH_OFFSET)),
547 				((0xFFFFU << 16) | (0xFFFF << 0)),
548 				0xFFFFFFFF);
549 			/*
550 			 * Delays: ASSERT_IOBUFACT_to_ALLON0_for_PM_MSG_3,
551 			 * VREG (MDLL) Turn On, ALLON0_to_DEASSERT_IOBUFACT
552 			 * for_PM_MSG_gt0, MDLL Turn On
553 			 */
554 			mrc_alt_write_mask(DDRPHY,
555 				(CMDPMDLYREG3 + (ch * DDRIOCCC_CH_OFFSET)),
556 				((0xFU << 28) | (0xFFF << 16) | (0xF << 12) |
557 				(0x616 << 0)), 0xFFFFFFFF);
558 			/* MPLL Divider Reset Delays */
559 			mrc_alt_write_mask(DDRPHY,
560 				(CMDPMDLYREG2 + (ch * DDRIOCCC_CH_OFFSET)),
561 				((0xFFU << 24) | (0xFF << 16) | (0xFF << 8) |
562 				(0xFF << 0)), 0xFFFFFFFF);
563 			/* Turn Off Delays: VREG, Staggered MDLL, MDLL, PI */
564 			mrc_alt_write_mask(DDRPHY,
565 				(CMDPMDLYREG1 + (ch * DDRIOCCC_CH_OFFSET)),
566 				((0xFFU << 24) | (0xFF << 16) | (0xFF << 8) |
567 				(0xFF << 0)), 0xFFFFFFFF);
568 			/* Turn On Delays: MPLL, Staggered MDLL, PI, IOBUFACT */
569 			mrc_alt_write_mask(DDRPHY,
570 				(CMDPMDLYREG0 + (ch * DDRIOCCC_CH_OFFSET)),
571 				((0xFFU << 24) | (0xFF << 16) | (0xFF << 8) |
572 				(0xFF << 0)), 0xFFFFFFFF);
573 			/* Allow PUnit signals */
574 			mrc_alt_write_mask(DDRPHY,
575 				(CMDPMCONFIG0 + (ch * DDRIOCCC_CH_OFFSET)),
576 				((0x6 << 8) | BIT6 | (0x4 << 0)),
577 				(BIT31 | BIT30 | BIT29 | BIT28 | BIT27 | BIT26 |
578 				BIT25 | BIT24 | BIT23 | BIT22 | BIT21 | BIT11 |
579 				BIT10 | BIT9 | BIT8 | BIT6 | BIT3 | BIT2 |
580 				BIT1 | BIT0));
581 			/* DLL_VREG Bias Trim, VREF Tuning for DLL_VREG */
582 			mrc_alt_write_mask(DDRPHY,
583 				(CMDMDLLCTL + (ch * DDRIOCCC_CH_OFFSET)),
584 				((0x3 << 4) | (0x7 << 0)),
585 				(BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 |
586 				BIT0));
587 
588 			/* CLK-CTL */
589 			mrc_alt_write_mask(DDRPHY,
590 				(CCOBSCKEBBCTL + (ch * DDRIOCCC_CH_OFFSET)),
591 				0, BIT24);	/* CLKEBB */
592 			/* Buffer Enable: CS,CKE,ODT,CLK */
593 			mrc_alt_write_mask(DDRPHY,
594 				(CCCFGREG0 + (ch * DDRIOCCC_CH_OFFSET)),
595 				((0x0 << 16) | (0x0 << 12) | (0x0 << 8) |
596 				(0xF << 4) | BIT0),
597 				(BIT19 | BIT18 | BIT17 | BIT16 | BIT15 | BIT14 |
598 				BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8 |
599 				BIT7 | BIT6 | BIT5 | BIT4 | BIT0));
600 			/* ODT RCOMP */
601 			mrc_alt_write_mask(DDRPHY,
602 				(CCRCOMPODT + (ch * DDRIOCCC_CH_OFFSET)),
603 				((0x03 << 8) | (0x03 << 0)),
604 				(BIT12 | BIT11 | BIT10 | BIT9 | BIT8 | BIT4 |
605 				BIT3 | BIT2 | BIT1 | BIT0));
606 			/* DLL_VREG Bias Trim, VREF Tuning for DLL_VREG */
607 			mrc_alt_write_mask(DDRPHY,
608 				(CCMDLLCTL + (ch * DDRIOCCC_CH_OFFSET)),
609 				((0x3 << 4) | (0x7 << 0)),
610 				(BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 |
611 				BIT0));
612 
613 			/*
614 			 * COMP (RON channel specific)
615 			 * - DQ/DQS/DM RON: 32 Ohm
616 			 * - CTRL/CMD RON: 27 Ohm
617 			 * - CLK RON: 26 Ohm
618 			 */
619 			/* RCOMP Vref PU/PD */
620 			mrc_alt_write_mask(DDRPHY,
621 				(DQVREFCH0 +  (ch * DDRCOMP_CH_OFFSET)),
622 				((0x08 << 24) | (0x03 << 16)),
623 				(BIT29 | BIT28 | BIT27 | BIT26 | BIT25 |
624 				BIT24 | BIT21 | BIT20 | BIT19 | BIT18 |
625 				BIT17 | BIT16));
626 			/* RCOMP Vref PU/PD */
627 			mrc_alt_write_mask(DDRPHY,
628 				(CMDVREFCH0 + (ch * DDRCOMP_CH_OFFSET)),
629 				((0x0C << 24) | (0x03 << 16)),
630 				(BIT29 | BIT28 | BIT27 | BIT26 | BIT25 |
631 				BIT24 | BIT21 | BIT20 | BIT19 | BIT18 |
632 				BIT17 | BIT16));
633 			/* RCOMP Vref PU/PD */
634 			mrc_alt_write_mask(DDRPHY,
635 				(CLKVREFCH0 + (ch * DDRCOMP_CH_OFFSET)),
636 				((0x0F << 24) | (0x03 << 16)),
637 				(BIT29 | BIT28 | BIT27 | BIT26 | BIT25 |
638 				BIT24 | BIT21 | BIT20 | BIT19 | BIT18 |
639 				BIT17 | BIT16));
640 			/* RCOMP Vref PU/PD */
641 			mrc_alt_write_mask(DDRPHY,
642 				(DQSVREFCH0 + (ch * DDRCOMP_CH_OFFSET)),
643 				((0x08 << 24) | (0x03 << 16)),
644 				(BIT29 | BIT28 | BIT27 | BIT26 | BIT25 |
645 				BIT24 | BIT21 | BIT20 | BIT19 | BIT18 |
646 				BIT17 | BIT16));
647 			/* RCOMP Vref PU/PD */
648 			mrc_alt_write_mask(DDRPHY,
649 				(CTLVREFCH0 + (ch * DDRCOMP_CH_OFFSET)),
650 				((0x0C << 24) | (0x03 << 16)),
651 				(BIT29 | BIT28 | BIT27 | BIT26 | BIT25 |
652 				BIT24 | BIT21 | BIT20 | BIT19 | BIT18 |
653 				BIT17 | BIT16));
654 
655 			/* DQS Swapped Input Enable */
656 			mrc_alt_write_mask(DDRPHY,
657 				(COMPEN1CH0 + (ch * DDRCOMP_CH_OFFSET)),
658 				(BIT19 | BIT17),
659 				(BIT31 | BIT30 | BIT19 | BIT17 |
660 				BIT15 | BIT14));
661 
662 			/* ODT VREF = 1.5 x 274/360+274 = 0.65V (code of ~50) */
663 			/* ODT Vref PU/PD */
664 			mrc_alt_write_mask(DDRPHY,
665 				(DQVREFCH0 + (ch * DDRCOMP_CH_OFFSET)),
666 				((0x32 << 8) | (0x03 << 0)),
667 				(BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8 |
668 				BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0));
669 			/* ODT Vref PU/PD */
670 			mrc_alt_write_mask(DDRPHY,
671 				(DQSVREFCH0 + (ch * DDRCOMP_CH_OFFSET)),
672 				((0x32 << 8) | (0x03 << 0)),
673 				(BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8 |
674 				BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0));
675 			/* ODT Vref PU/PD */
676 			mrc_alt_write_mask(DDRPHY,
677 				(CLKVREFCH0 + (ch * DDRCOMP_CH_OFFSET)),
678 				((0x0E << 8) | (0x05 << 0)),
679 				(BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8 |
680 				BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0));
681 
682 			/*
683 			 * Slew rate settings are frequency specific,
684 			 * numbers below are for 800Mhz (speed == 0)
685 			 * - DQ/DQS/DM/CLK SR: 4V/ns,
686 			 * - CTRL/CMD SR: 1.5V/ns
687 			 */
688 			temp = (0x0E << 16) | (0x0E << 12) | (0x08 << 8) |
689 				(0x0B << 4) | (0x0B << 0);
690 			/* DCOMP Delay Select: CTL,CMD,CLK,DQS,DQ */
691 			mrc_alt_write_mask(DDRPHY,
692 				(DLYSELCH0 + (ch * DDRCOMP_CH_OFFSET)),
693 				temp,
694 				(BIT19 | BIT18 | BIT17 | BIT16 | BIT15 |
695 				BIT14 | BIT13 | BIT12 | BIT11 | BIT10 |
696 				BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 |
697 				BIT3 | BIT2 | BIT1 | BIT0));
698 			/* TCO Vref CLK,DQS,DQ */
699 			mrc_alt_write_mask(DDRPHY,
700 				(TCOVREFCH0 + (ch * DDRCOMP_CH_OFFSET)),
701 				((0x05 << 16) | (0x05 << 8) | (0x05 << 0)),
702 				(BIT21 | BIT20 | BIT19 | BIT18 | BIT17 |
703 				BIT16 | BIT13 | BIT12 | BIT11 | BIT10 |
704 				BIT9 | BIT8 | BIT5 | BIT4 | BIT3 | BIT2 |
705 				BIT1 | BIT0));
706 			/* ODTCOMP CMD/CTL PU/PD */
707 			mrc_alt_write_mask(DDRPHY,
708 				(CCBUFODTCH0 + (ch * DDRCOMP_CH_OFFSET)),
709 				((0x03 << 8) | (0x03 << 0)),
710 				(BIT12 | BIT11 | BIT10 | BIT9 | BIT8 |
711 				BIT4 | BIT3 | BIT2 | BIT1 | BIT0));
712 			/* COMP */
713 			mrc_alt_write_mask(DDRPHY,
714 				(COMPEN0CH0 + (ch * DDRCOMP_CH_OFFSET)),
715 				0, (BIT31 | BIT30 | BIT8));
716 
717 #ifdef BACKUP_COMPS
718 			/* DQ COMP Overrides */
719 			/* RCOMP PU */
720 			mrc_alt_write_mask(DDRPHY,
721 				(DQDRVPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
722 				(BIT31 | (0x0A << 16)),
723 				(BIT31 | BIT20 | BIT19 |
724 				BIT18 | BIT17 | BIT16));
725 			/* RCOMP PD */
726 			mrc_alt_write_mask(DDRPHY,
727 				(DQDRVPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
728 				(BIT31 | (0x0A << 16)),
729 				(BIT31 | BIT20 | BIT19 |
730 				BIT18 | BIT17 | BIT16));
731 			/* DCOMP PU */
732 			mrc_alt_write_mask(DDRPHY,
733 				(DQDLYPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
734 				(BIT31 | (0x10 << 16)),
735 				(BIT31 | BIT20 | BIT19 |
736 				BIT18 | BIT17 | BIT16));
737 			/* DCOMP PD */
738 			mrc_alt_write_mask(DDRPHY,
739 				(DQDLYPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
740 				(BIT31 | (0x10 << 16)),
741 				(BIT31 | BIT20 | BIT19 |
742 				BIT18 | BIT17 | BIT16));
743 			/* ODTCOMP PU */
744 			mrc_alt_write_mask(DDRPHY,
745 				(DQODTPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
746 				(BIT31 | (0x0B << 16)),
747 				(BIT31 | BIT20 | BIT19 |
748 				BIT18 | BIT17 | BIT16));
749 			/* ODTCOMP PD */
750 			mrc_alt_write_mask(DDRPHY,
751 				(DQODTPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
752 				(BIT31 | (0x0B << 16)),
753 				(BIT31 | BIT20 | BIT19 |
754 				BIT18 | BIT17 | BIT16));
755 			/* TCOCOMP PU */
756 			mrc_alt_write_mask(DDRPHY,
757 				(DQTCOPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
758 				(BIT31), (BIT31));
759 			/* TCOCOMP PD */
760 			mrc_alt_write_mask(DDRPHY,
761 				(DQTCOPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
762 				(BIT31), (BIT31));
763 
764 			/* DQS COMP Overrides */
765 			/* RCOMP PU */
766 			mrc_alt_write_mask(DDRPHY,
767 				(DQSDRVPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
768 				(BIT31 | (0x0A << 16)),
769 				(BIT31 | BIT20 | BIT19 |
770 				BIT18 | BIT17 | BIT16));
771 			/* RCOMP PD */
772 			mrc_alt_write_mask(DDRPHY,
773 				(DQSDRVPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
774 				(BIT31 | (0x0A << 16)),
775 				(BIT31 | BIT20 | BIT19 |
776 				BIT18 | BIT17 | BIT16));
777 			/* DCOMP PU */
778 			mrc_alt_write_mask(DDRPHY,
779 				(DQSDLYPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
780 				(BIT31 | (0x10 << 16)),
781 				(BIT31 | BIT20 | BIT19 |
782 				BIT18 | BIT17 | BIT16));
783 			/* DCOMP PD */
784 			mrc_alt_write_mask(DDRPHY,
785 				(DQSDLYPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
786 				(BIT31 | (0x10 << 16)),
787 				(BIT31 | BIT20 | BIT19 |
788 				BIT18 | BIT17 | BIT16));
789 			/* ODTCOMP PU */
790 			mrc_alt_write_mask(DDRPHY,
791 				(DQSODTPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
792 				(BIT31 | (0x0B << 16)),
793 				(BIT31 | BIT20 | BIT19 |
794 				BIT18 | BIT17 | BIT16));
795 			/* ODTCOMP PD */
796 			mrc_alt_write_mask(DDRPHY,
797 				(DQSODTPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
798 				(BIT31 | (0x0B << 16)),
799 				(BIT31 | BIT20 | BIT19 |
800 				BIT18 | BIT17 | BIT16));
801 			/* TCOCOMP PU */
802 			mrc_alt_write_mask(DDRPHY,
803 				(DQSTCOPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
804 				(BIT31), (BIT31));
805 			/* TCOCOMP PD */
806 			mrc_alt_write_mask(DDRPHY,
807 				(DQSTCOPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
808 				(BIT31), (BIT31));
809 
810 			/* CLK COMP Overrides */
811 			/* RCOMP PU */
812 			mrc_alt_write_mask(DDRPHY,
813 				(CLKDRVPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
814 				(BIT31 | (0x0C << 16)),
815 				(BIT31 | (0x0B << 16)),
816 				(BIT31 | BIT20 | BIT19 |
817 				BIT18 | BIT17 | BIT16));
818 			/* RCOMP PD */
819 			mrc_alt_write_mask(DDRPHY,
820 				(CLKDRVPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
821 				(BIT31 | (0x0C << 16)),
822 				(BIT31 | (0x0B << 16)),
823 				(BIT31 | BIT20 | BIT19 |
824 				BIT18 | BIT17 | BIT16));
825 			/* DCOMP PU */
826 			mrc_alt_write_mask(DDRPHY,
827 				(CLKDLYPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
828 				(BIT31 | (0x07 << 16)),
829 				(BIT31 | (0x0B << 16)),
830 				(BIT31 | BIT20 | BIT19 |
831 				BIT18 | BIT17 | BIT16));
832 			/* DCOMP PD */
833 			mrc_alt_write_mask(DDRPHY,
834 				(CLKDLYPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
835 				(BIT31 | (0x07 << 16)),
836 				(BIT31 | (0x0B << 16)),
837 				(BIT31 | BIT20 | BIT19 |
838 				BIT18 | BIT17 | BIT16));
839 			/* ODTCOMP PU */
840 			mrc_alt_write_mask(DDRPHY,
841 				(CLKODTPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
842 				(BIT31 | (0x0B << 16)),
843 				(BIT31 | (0x0B << 16)),
844 				(BIT31 | BIT20 | BIT19 |
845 				BIT18 | BIT17 | BIT16));
846 			/* ODTCOMP PD */
847 			mrc_alt_write_mask(DDRPHY,
848 				(CLKODTPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
849 				(BIT31 | (0x0B << 16)),
850 				(BIT31 | (0x0B << 16)),
851 				(BIT31 | BIT20 | BIT19 |
852 				BIT18 | BIT17 | BIT16));
853 			/* TCOCOMP PU */
854 			mrc_alt_write_mask(DDRPHY,
855 				(CLKTCOPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
856 				(BIT31), (BIT31));
857 			/* TCOCOMP PD */
858 			mrc_alt_write_mask(DDRPHY,
859 				(CLKTCOPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
860 				(BIT31), (BIT31));
861 
862 			/* CMD COMP Overrides */
863 			/* RCOMP PU */
864 			mrc_alt_write_mask(DDRPHY,
865 				(CMDDRVPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
866 				(BIT31 | (0x0D << 16)),
867 				(BIT31 | BIT21 | BIT20 | BIT19 |
868 				BIT18 | BIT17 | BIT16));
869 			/* RCOMP PD */
870 			mrc_alt_write_mask(DDRPHY,
871 				(CMDDRVPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
872 				(BIT31 | (0x0D << 16)),
873 				(BIT31 | BIT21 | BIT20 | BIT19 |
874 				BIT18 | BIT17 | BIT16));
875 			/* DCOMP PU */
876 			mrc_alt_write_mask(DDRPHY,
877 				(CMDDLYPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
878 				(BIT31 | (0x0A << 16)),
879 				(BIT31 | BIT20 | BIT19 |
880 				BIT18 | BIT17 | BIT16));
881 			/* DCOMP PD */
882 			mrc_alt_write_mask(DDRPHY,
883 				(CMDDLYPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
884 				(BIT31 | (0x0A << 16)),
885 				(BIT31 | BIT20 | BIT19 |
886 				BIT18 | BIT17 | BIT16));
887 
888 			/* CTL COMP Overrides */
889 			/* RCOMP PU */
890 			mrc_alt_write_mask(DDRPHY,
891 				(CTLDRVPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
892 				(BIT31 | (0x0D << 16)),
893 				(BIT31 | BIT21 | BIT20 | BIT19 |
894 				BIT18 | BIT17 | BIT16));
895 			/* RCOMP PD */
896 			mrc_alt_write_mask(DDRPHY,
897 				(CTLDRVPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
898 				(BIT31 | (0x0D << 16)),
899 				(BIT31 | BIT21 | BIT20 | BIT19 |
900 				BIT18 | BIT17 | BIT16));
901 			/* DCOMP PU */
902 			mrc_alt_write_mask(DDRPHY,
903 				(CTLDLYPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
904 				(BIT31 | (0x0A << 16)),
905 				(BIT31 | BIT20 | BIT19 |
906 				BIT18 | BIT17 | BIT16));
907 			/* DCOMP PD */
908 			mrc_alt_write_mask(DDRPHY,
909 				(CTLDLYPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
910 				(BIT31 | (0x0A << 16)),
911 				(BIT31 | BIT20 | BIT19 |
912 				BIT18 | BIT17 | BIT16));
913 #else
914 			/* DQ TCOCOMP Overrides */
915 			/* TCOCOMP PU */
916 			mrc_alt_write_mask(DDRPHY,
917 				(DQTCOPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
918 				(BIT31 | (0x1F << 16)),
919 				(BIT31 | BIT20 | BIT19 |
920 				BIT18 | BIT17 | BIT16));
921 			/* TCOCOMP PD */
922 			mrc_alt_write_mask(DDRPHY,
923 				(DQTCOPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
924 				(BIT31 | (0x1F << 16)),
925 				(BIT31 | BIT20 | BIT19 |
926 				BIT18 | BIT17 | BIT16));
927 
928 			/* DQS TCOCOMP Overrides */
929 			/* TCOCOMP PU */
930 			mrc_alt_write_mask(DDRPHY,
931 				(DQSTCOPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
932 				(BIT31 | (0x1F << 16)),
933 				(BIT31 | BIT20 | BIT19 |
934 				BIT18 | BIT17 | BIT16));
935 			/* TCOCOMP PD */
936 			mrc_alt_write_mask(DDRPHY,
937 				(DQSTCOPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
938 				(BIT31 | (0x1F << 16)),
939 				(BIT31 | BIT20 | BIT19 |
940 				BIT18 | BIT17 | BIT16));
941 
942 			/* CLK TCOCOMP Overrides */
943 			/* TCOCOMP PU */
944 			mrc_alt_write_mask(DDRPHY,
945 				(CLKTCOPUCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
946 				(BIT31 | (0x1F << 16)),
947 				(BIT31 | BIT20 | BIT19 |
948 				BIT18 | BIT17 | BIT16));
949 			/* TCOCOMP PD */
950 			mrc_alt_write_mask(DDRPHY,
951 				(CLKTCOPDCTLCH0 + (ch * DDRCOMP_CH_OFFSET)),
952 				(BIT31 | (0x1F << 16)),
953 				(BIT31 | BIT20 | BIT19 |
954 				BIT18 | BIT17 | BIT16));
955 #endif
956 
957 			/* program STATIC delays */
958 #ifdef BACKUP_WCMD
959 			set_wcmd(ch, ddr_wcmd[PLATFORM_ID]);
960 #else
961 			set_wcmd(ch, ddr_wclk[PLATFORM_ID] + HALF_CLK);
962 #endif
963 
964 			for (rk = 0; rk < NUM_RANKS; rk++) {
965 				if (mrc_params->rank_enables & (1<<rk)) {
966 					set_wclk(ch, rk, ddr_wclk[PLATFORM_ID]);
967 #ifdef BACKUP_WCTL
968 					set_wctl(ch, rk, ddr_wctl[PLATFORM_ID]);
969 #else
970 					set_wctl(ch, rk, ddr_wclk[PLATFORM_ID] + HALF_CLK);
971 #endif
972 				}
973 			}
974 		}
975 	}
976 
977 	/* COMP (non channel specific) */
978 	/* RCOMP: Dither PU Enable */
979 	mrc_alt_write_mask(DDRPHY, (DQANADRVPUCTL), (BIT30), (BIT30));
980 	/* RCOMP: Dither PD Enable */
981 	mrc_alt_write_mask(DDRPHY, (DQANADRVPDCTL), (BIT30), (BIT30));
982 	/* RCOMP: Dither PU Enable */
983 	mrc_alt_write_mask(DDRPHY, (CMDANADRVPUCTL), (BIT30), (BIT30));
984 	/* RCOMP: Dither PD Enable */
985 	mrc_alt_write_mask(DDRPHY, (CMDANADRVPDCTL), (BIT30), (BIT30));
986 	/* RCOMP: Dither PU Enable */
987 	mrc_alt_write_mask(DDRPHY, (CLKANADRVPUCTL), (BIT30), (BIT30));
988 	/* RCOMP: Dither PD Enable */
989 	mrc_alt_write_mask(DDRPHY, (CLKANADRVPDCTL), (BIT30), (BIT30));
990 	/* RCOMP: Dither PU Enable */
991 	mrc_alt_write_mask(DDRPHY, (DQSANADRVPUCTL), (BIT30), (BIT30));
992 	/* RCOMP: Dither PD Enable */
993 	mrc_alt_write_mask(DDRPHY, (DQSANADRVPDCTL), (BIT30), (BIT30));
994 	/* RCOMP: Dither PU Enable */
995 	mrc_alt_write_mask(DDRPHY, (CTLANADRVPUCTL), (BIT30), (BIT30));
996 	/* RCOMP: Dither PD Enable */
997 	mrc_alt_write_mask(DDRPHY, (CTLANADRVPDCTL), (BIT30), (BIT30));
998 	/* ODT: Dither PU Enable */
999 	mrc_alt_write_mask(DDRPHY, (DQANAODTPUCTL), (BIT30), (BIT30));
1000 	/* ODT: Dither PD Enable */
1001 	mrc_alt_write_mask(DDRPHY, (DQANAODTPDCTL), (BIT30), (BIT30));
1002 	/* ODT: Dither PU Enable */
1003 	mrc_alt_write_mask(DDRPHY, (CLKANAODTPUCTL), (BIT30), (BIT30));
1004 	/* ODT: Dither PD Enable */
1005 	mrc_alt_write_mask(DDRPHY, (CLKANAODTPDCTL), (BIT30), (BIT30));
1006 	/* ODT: Dither PU Enable */
1007 	mrc_alt_write_mask(DDRPHY, (DQSANAODTPUCTL), (BIT30), (BIT30));
1008 	/* ODT: Dither PD Enable */
1009 	mrc_alt_write_mask(DDRPHY, (DQSANAODTPDCTL), (BIT30), (BIT30));
1010 	/* DCOMP: Dither PU Enable */
1011 	mrc_alt_write_mask(DDRPHY, (DQANADLYPUCTL), (BIT30), (BIT30));
1012 	/* DCOMP: Dither PD Enable */
1013 	mrc_alt_write_mask(DDRPHY, (DQANADLYPDCTL), (BIT30), (BIT30));
1014 	/* DCOMP: Dither PU Enable */
1015 	mrc_alt_write_mask(DDRPHY, (CMDANADLYPUCTL), (BIT30), (BIT30));
1016 	/* DCOMP: Dither PD Enable */
1017 	mrc_alt_write_mask(DDRPHY, (CMDANADLYPDCTL), (BIT30), (BIT30));
1018 	/* DCOMP: Dither PU Enable */
1019 	mrc_alt_write_mask(DDRPHY, (CLKANADLYPUCTL), (BIT30), (BIT30));
1020 	/* DCOMP: Dither PD Enable */
1021 	mrc_alt_write_mask(DDRPHY, (CLKANADLYPDCTL), (BIT30), (BIT30));
1022 	/* DCOMP: Dither PU Enable */
1023 	mrc_alt_write_mask(DDRPHY, (DQSANADLYPUCTL), (BIT30), (BIT30));
1024 	/* DCOMP: Dither PD Enable */
1025 	mrc_alt_write_mask(DDRPHY, (DQSANADLYPDCTL), (BIT30), (BIT30));
1026 	/* DCOMP: Dither PU Enable */
1027 	mrc_alt_write_mask(DDRPHY, (CTLANADLYPUCTL), (BIT30), (BIT30));
1028 	/* DCOMP: Dither PD Enable */
1029 	mrc_alt_write_mask(DDRPHY, (CTLANADLYPDCTL), (BIT30), (BIT30));
1030 	/* TCO: Dither PU Enable */
1031 	mrc_alt_write_mask(DDRPHY, (DQANATCOPUCTL), (BIT30), (BIT30));
1032 	/* TCO: Dither PD Enable */
1033 	mrc_alt_write_mask(DDRPHY, (DQANATCOPDCTL), (BIT30), (BIT30));
1034 	/* TCO: Dither PU Enable */
1035 	mrc_alt_write_mask(DDRPHY, (CLKANATCOPUCTL), (BIT30), (BIT30));
1036 	/* TCO: Dither PD Enable */
1037 	mrc_alt_write_mask(DDRPHY, (CLKANATCOPDCTL), (BIT30), (BIT30));
1038 	/* TCO: Dither PU Enable */
1039 	mrc_alt_write_mask(DDRPHY, (DQSANATCOPUCTL), (BIT30), (BIT30));
1040 	/* TCO: Dither PD Enable */
1041 	mrc_alt_write_mask(DDRPHY, (DQSANATCOPDCTL), (BIT30), (BIT30));
1042 	/* TCOCOMP: Pulse Count */
1043 	mrc_alt_write_mask(DDRPHY, (TCOCNTCTRL), (0x1 << 0), (BIT1 | BIT0));
1044 	/* ODT: CMD/CTL PD/PU */
1045 	mrc_alt_write_mask(DDRPHY,
1046 		(CHNLBUFSTATIC), ((0x03 << 24) | (0x03 << 16)),
1047 		(BIT28 | BIT27 | BIT26 | BIT25 | BIT24 |
1048 		BIT20 | BIT19 | BIT18 | BIT17 | BIT16));
1049 	/* Set 1us counter */
1050 	mrc_alt_write_mask(DDRPHY,
1051 		(MSCNTR), (0x64 << 0),
1052 		(BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0));
1053 	mrc_alt_write_mask(DDRPHY,
1054 		(LATCH1CTL), (0x1 << 28),
1055 		(BIT30 | BIT29 | BIT28));
1056 
1057 	/* Release PHY from reset */
1058 	mrc_alt_write_mask(DDRPHY, MASTERRSTN, BIT0, BIT0);
1059 
1060 	/* STEP1 */
1061 	mrc_post_code(0x03, 0x11);
1062 
1063 	for (ch = 0; ch < NUM_CHANNELS; ch++) {
1064 		if (mrc_params->channel_enables & (1 << ch)) {
1065 			/* DQ01-DQ23 */
1066 			for (bl_grp = 0;
1067 			     bl_grp < ((NUM_BYTE_LANES / bl_divisor) / 2);
1068 			     bl_grp++) {
1069 				mrc_alt_write_mask(DDRPHY,
1070 					(DQMDLLCTL +
1071 					(bl_grp * DDRIODQ_BL_OFFSET) +
1072 					(ch * DDRIODQ_CH_OFFSET)),
1073 					(BIT13),
1074 					(BIT13));	/* Enable VREG */
1075 				delay_n(3);
1076 			}
1077 
1078 			/* ECC */
1079 			mrc_alt_write_mask(DDRPHY, (ECCMDLLCTL),
1080 				(BIT13), (BIT13));	/* Enable VREG */
1081 			delay_n(3);
1082 			/* CMD */
1083 			mrc_alt_write_mask(DDRPHY,
1084 				(CMDMDLLCTL + (ch * DDRIOCCC_CH_OFFSET)),
1085 				(BIT13), (BIT13));	/* Enable VREG */
1086 			delay_n(3);
1087 			/* CLK-CTL */
1088 			mrc_alt_write_mask(DDRPHY,
1089 				(CCMDLLCTL + (ch * DDRIOCCC_CH_OFFSET)),
1090 				(BIT13), (BIT13));	/* Enable VREG */
1091 			delay_n(3);
1092 		}
1093 	}
1094 
1095 	/* STEP2 */
1096 	mrc_post_code(0x03, 0x12);
1097 	delay_n(200);
1098 
1099 	for (ch = 0; ch < NUM_CHANNELS; ch++) {
1100 		if (mrc_params->channel_enables & (1 << ch)) {
1101 			/* DQ01-DQ23 */
1102 			for (bl_grp = 0;
1103 			     bl_grp < ((NUM_BYTE_LANES / bl_divisor) / 2);
1104 			     bl_grp++) {
1105 				mrc_alt_write_mask(DDRPHY,
1106 					(DQMDLLCTL +
1107 					(bl_grp * DDRIODQ_BL_OFFSET) +
1108 					(ch * DDRIODQ_CH_OFFSET)),
1109 					(BIT17),
1110 					(BIT17));	/* Enable MCDLL */
1111 				delay_n(50);
1112 			}
1113 
1114 		/* ECC */
1115 		mrc_alt_write_mask(DDRPHY, (ECCMDLLCTL),
1116 			(BIT17), (BIT17));	/* Enable MCDLL */
1117 		delay_n(50);
1118 		/* CMD */
1119 		mrc_alt_write_mask(DDRPHY,
1120 			(CMDMDLLCTL + (ch * DDRIOCCC_CH_OFFSET)),
1121 			(BIT18), (BIT18));	/* Enable MCDLL */
1122 		delay_n(50);
1123 		/* CLK-CTL */
1124 		mrc_alt_write_mask(DDRPHY,
1125 			(CCMDLLCTL + (ch * DDRIOCCC_CH_OFFSET)),
1126 			(BIT18), (BIT18));	/* Enable MCDLL */
1127 		delay_n(50);
1128 		}
1129 	}
1130 
1131 	/* STEP3: */
1132 	mrc_post_code(0x03, 0x13);
1133 	delay_n(100);
1134 
1135 	for (ch = 0; ch < NUM_CHANNELS; ch++) {
1136 		if (mrc_params->channel_enables & (1 << ch)) {
1137 			/* DQ01-DQ23 */
1138 			for (bl_grp = 0;
1139 			     bl_grp < ((NUM_BYTE_LANES / bl_divisor) / 2);
1140 			     bl_grp++) {
1141 #ifdef FORCE_16BIT_DDRIO
1142 				temp = ((bl_grp) &&
1143 					(mrc_params->channel_width == X16)) ?
1144 					((0x1 << 12) | (0x1 << 8) |
1145 					(0xF << 4) | (0xF << 0)) :
1146 					((0xF << 12) | (0xF << 8) |
1147 					(0xF << 4) | (0xF << 0));
1148 #else
1149 				temp = ((0xF << 12) | (0xF << 8) |
1150 					(0xF << 4) | (0xF << 0));
1151 #endif
1152 				/* Enable TXDLL */
1153 				mrc_alt_write_mask(DDRPHY,
1154 					(DQDLLTXCTL +
1155 					(bl_grp * DDRIODQ_BL_OFFSET) +
1156 					(ch * DDRIODQ_CH_OFFSET)),
1157 					temp, 0xFFFF);
1158 				delay_n(3);
1159 				/* Enable RXDLL */
1160 				mrc_alt_write_mask(DDRPHY,
1161 					(DQDLLRXCTL +
1162 					(bl_grp * DDRIODQ_BL_OFFSET) +
1163 					(ch * DDRIODQ_CH_OFFSET)),
1164 					(BIT3 | BIT2 | BIT1 | BIT0),
1165 					(BIT3 | BIT2 | BIT1 | BIT0));
1166 				delay_n(3);
1167 				/* Enable RXDLL Overrides BL0 */
1168 				mrc_alt_write_mask(DDRPHY,
1169 					(B0OVRCTL +
1170 					(bl_grp * DDRIODQ_BL_OFFSET) +
1171 					(ch * DDRIODQ_CH_OFFSET)),
1172 					(BIT3 | BIT2 | BIT1 | BIT0),
1173 					(BIT3 | BIT2 | BIT1 | BIT0));
1174 			}
1175 
1176 			/* ECC */
1177 			temp = ((0xF << 12) | (0xF << 8) |
1178 				(0xF << 4) | (0xF << 0));
1179 			mrc_alt_write_mask(DDRPHY, (ECCDLLTXCTL),
1180 				temp, 0xFFFF);
1181 			delay_n(3);
1182 
1183 			/* CMD (PO) */
1184 			mrc_alt_write_mask(DDRPHY,
1185 				(CMDDLLTXCTL + (ch * DDRIOCCC_CH_OFFSET)),
1186 				temp, 0xFFFF);
1187 			delay_n(3);
1188 		}
1189 	}
1190 
1191 	/* STEP4 */
1192 	mrc_post_code(0x03, 0x14);
1193 
1194 	for (ch = 0; ch < NUM_CHANNELS; ch++) {
1195 		if (mrc_params->channel_enables & (1 << ch)) {
1196 			/* Host To Memory Clock Alignment (HMC) for 800/1066 */
1197 			for (bl_grp = 0;
1198 			     bl_grp < ((NUM_BYTE_LANES / bl_divisor) / 2);
1199 			     bl_grp++) {
1200 				/* CLK_ALIGN_MOD_ID */
1201 				mrc_alt_write_mask(DDRPHY,
1202 					(DQCLKALIGNREG2 +
1203 					(bl_grp * DDRIODQ_BL_OFFSET) +
1204 					(ch * DDRIODQ_CH_OFFSET)),
1205 					(bl_grp) ? (0x3) : (0x1),
1206 					(BIT3 | BIT2 | BIT1 | BIT0));
1207 			}
1208 
1209 			mrc_alt_write_mask(DDRPHY,
1210 				(ECCCLKALIGNREG2 + (ch * DDRIODQ_CH_OFFSET)),
1211 				0x2,
1212 				(BIT3 | BIT2 | BIT1 | BIT0));
1213 			mrc_alt_write_mask(DDRPHY,
1214 				(CMDCLKALIGNREG2 + (ch * DDRIODQ_CH_OFFSET)),
1215 				0x0,
1216 				(BIT3 | BIT2 | BIT1 | BIT0));
1217 			mrc_alt_write_mask(DDRPHY,
1218 				(CCCLKALIGNREG2 + (ch * DDRIODQ_CH_OFFSET)),
1219 				0x2,
1220 				(BIT3 | BIT2 | BIT1 | BIT0));
1221 			mrc_alt_write_mask(DDRPHY,
1222 				(CMDCLKALIGNREG0 + (ch * DDRIOCCC_CH_OFFSET)),
1223 				(0x2 << 4), (BIT5 | BIT4));
1224 			/*
1225 			 * NUM_SAMPLES, MAX_SAMPLES,
1226 			 * MACRO_PI_STEP, MICRO_PI_STEP
1227 			 */
1228 			mrc_alt_write_mask(DDRPHY,
1229 				(CMDCLKALIGNREG1 + (ch * DDRIOCCC_CH_OFFSET)),
1230 				((0x18 << 16) | (0x10 << 8) |
1231 				(0x8 << 2) | (0x1 << 0)),
1232 				(BIT22 | BIT21 | BIT20 | BIT19 | BIT18 | BIT17 |
1233 				BIT16 | BIT14 | BIT13 | BIT12 | BIT11 | BIT10 |
1234 				BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 |
1235 				BIT2 | BIT1 | BIT0));
1236 			/* TOTAL_NUM_MODULES, FIRST_U_PARTITION */
1237 			mrc_alt_write_mask(DDRPHY,
1238 				(CMDCLKALIGNREG2 + (ch * DDRIOCCC_CH_OFFSET)),
1239 				((0x10 << 16) | (0x4 << 8) | (0x2 << 4)),
1240 				(BIT20 | BIT19 | BIT18 | BIT17 | BIT16 |
1241 				BIT11 | BIT10 | BIT9 | BIT8 | BIT7 | BIT6 |
1242 				BIT5 | BIT4));
1243 #ifdef HMC_TEST
1244 			/* START_CLK_ALIGN=1 */
1245 			mrc_alt_write_mask(DDRPHY,
1246 				(CMDCLKALIGNREG0 + (ch * DDRIOCCC_CH_OFFSET)),
1247 				BIT24, BIT24);
1248 			while (msg_port_alt_read(DDRPHY,
1249 				(CMDCLKALIGNREG0 + (ch * DDRIOCCC_CH_OFFSET))) &
1250 				BIT24)
1251 				;	/* wait for START_CLK_ALIGN=0 */
1252 #endif
1253 
1254 			/* Set RD/WR Pointer Seperation & COUNTEN & FIFOPTREN */
1255 			mrc_alt_write_mask(DDRPHY,
1256 				(CMDPTRREG + (ch * DDRIOCCC_CH_OFFSET)),
1257 				BIT0, BIT0);	/* WRPTRENABLE=1 */
1258 
1259 			/* COMP initial */
1260 			/* enable bypass for CLK buffer (PO) */
1261 			mrc_alt_write_mask(DDRPHY,
1262 				(COMPEN0CH0 + (ch * DDRCOMP_CH_OFFSET)),
1263 				BIT5, BIT5);
1264 			/* Initial COMP Enable */
1265 			mrc_alt_write_mask(DDRPHY, (CMPCTRL),
1266 				(BIT0), (BIT0));
1267 			/* wait for Initial COMP Enable = 0 */
1268 			while (msg_port_alt_read(DDRPHY, (CMPCTRL)) & BIT0)
1269 				;
1270 			/* disable bypass for CLK buffer (PO) */
1271 			mrc_alt_write_mask(DDRPHY,
1272 				(COMPEN0CH0 + (ch * DDRCOMP_CH_OFFSET)),
1273 				~BIT5, BIT5);
1274 
1275 			/* IOBUFACT */
1276 
1277 			/* STEP4a */
1278 			mrc_alt_write_mask(DDRPHY,
1279 				(CMDCFGREG0 + (ch * DDRIOCCC_CH_OFFSET)),
1280 				BIT2, BIT2);	/* IOBUFACTRST_N=1 */
1281 
1282 			/* DDRPHY initialization complete */
1283 			mrc_alt_write_mask(DDRPHY,
1284 				(CMDPMCONFIG0 + (ch * DDRIOCCC_CH_OFFSET)),
1285 				BIT20, BIT20);	/* SPID_INIT_COMPLETE=1 */
1286 		}
1287 	}
1288 
1289 	LEAVEFN();
1290 }
1291 
1292 /* This function performs JEDEC initialization on all enabled channels */
1293 void perform_jedec_init(struct mrc_params *mrc_params)
1294 {
1295 	uint8_t twr, wl, rank;
1296 	uint32_t tck;
1297 	u32 dtr0;
1298 	u32 drp;
1299 	u32 drmc;
1300 	u32 mrs0_cmd = 0;
1301 	u32 emrs1_cmd = 0;
1302 	u32 emrs2_cmd = 0;
1303 	u32 emrs3_cmd = 0;
1304 
1305 	ENTERFN();
1306 
1307 	/* jedec_init starts */
1308 	mrc_post_code(0x04, 0x00);
1309 
1310 	/* DDR3_RESET_SET=0, DDR3_RESET_RESET=1 */
1311 	mrc_alt_write_mask(DDRPHY, CCDDR3RESETCTL, BIT1, (BIT8 | BIT1));
1312 
1313 	/* Assert RESET# for 200us */
1314 	delay_u(200);
1315 
1316 	/* DDR3_RESET_SET=1, DDR3_RESET_RESET=0 */
1317 	mrc_alt_write_mask(DDRPHY, CCDDR3RESETCTL, BIT8, (BIT8 | BIT1));
1318 
1319 	dtr0 = msg_port_read(MEM_CTLR, DTR0);
1320 
1321 	/*
1322 	 * Set CKEVAL for populated ranks
1323 	 * then send NOP to each rank (#4550197)
1324 	 */
1325 
1326 	drp = msg_port_read(MEM_CTLR, DRP);
1327 	drp &= 0x3;
1328 
1329 	drmc = msg_port_read(MEM_CTLR, DRMC);
1330 	drmc &= 0xFFFFFFFC;
1331 	drmc |= (BIT4 | drp);
1332 
1333 	msg_port_write(MEM_CTLR, DRMC, drmc);
1334 
1335 	for (rank = 0; rank < NUM_RANKS; rank++) {
1336 		/* Skip to next populated rank */
1337 		if ((mrc_params->rank_enables & (1 << rank)) == 0)
1338 			continue;
1339 
1340 		dram_init_command(DCMD_NOP(rank));
1341 	}
1342 
1343 	msg_port_write(MEM_CTLR, DRMC,
1344 		(mrc_params->rd_odt_value == 0 ? BIT12 : 0));
1345 
1346 	/*
1347 	 * setup for emrs 2
1348 	 * BIT[15:11] --> Always "0"
1349 	 * BIT[10:09] --> Rtt_WR: want "Dynamic ODT Off" (0)
1350 	 * BIT[08]    --> Always "0"
1351 	 * BIT[07]    --> SRT: use sr_temp_range
1352 	 * BIT[06]    --> ASR: want "Manual SR Reference" (0)
1353 	 * BIT[05:03] --> CWL: use oem_tCWL
1354 	 * BIT[02:00] --> PASR: want "Full Array" (0)
1355 	 */
1356 	emrs2_cmd |= (2 << 3);
1357 	wl = 5 + mrc_params->ddr_speed;
1358 	emrs2_cmd |= ((wl - 5) << 9);
1359 	emrs2_cmd |= (mrc_params->sr_temp_range << 13);
1360 
1361 	/*
1362 	 * setup for emrs 3
1363 	 * BIT[15:03] --> Always "0"
1364 	 * BIT[02]    --> MPR: want "Normal Operation" (0)
1365 	 * BIT[01:00] --> MPR_Loc: want "Predefined Pattern" (0)
1366 	 */
1367 	emrs3_cmd |= (3 << 3);
1368 
1369 	/*
1370 	 * setup for emrs 1
1371 	 * BIT[15:13]     --> Always "0"
1372 	 * BIT[12:12]     --> Qoff: want "Output Buffer Enabled" (0)
1373 	 * BIT[11:11]     --> TDQS: want "Disabled" (0)
1374 	 * BIT[10:10]     --> Always "0"
1375 	 * BIT[09,06,02]  --> Rtt_nom: use rtt_nom_value
1376 	 * BIT[08]        --> Always "0"
1377 	 * BIT[07]        --> WR_LVL: want "Disabled" (0)
1378 	 * BIT[05,01]     --> DIC: use ron_value
1379 	 * BIT[04:03]     --> AL: additive latency want "0" (0)
1380 	 * BIT[00]        --> DLL: want "Enable" (0)
1381 	 *
1382 	 * (BIT5|BIT1) set Ron value
1383 	 * 00 --> RZQ/6 (40ohm)
1384 	 * 01 --> RZQ/7 (34ohm)
1385 	 * 1* --> RESERVED
1386 	 *
1387 	 * (BIT9|BIT6|BIT2) set Rtt_nom value
1388 	 * 000 --> Disabled
1389 	 * 001 --> RZQ/4 ( 60ohm)
1390 	 * 010 --> RZQ/2 (120ohm)
1391 	 * 011 --> RZQ/6 ( 40ohm)
1392 	 * 1** --> RESERVED
1393 	 */
1394 	emrs1_cmd |= (1 << 3);
1395 	emrs1_cmd &= ~BIT6;
1396 
1397 	if (mrc_params->ron_value == 0)
1398 		emrs1_cmd |= BIT7;
1399 	else
1400 		emrs1_cmd &= ~BIT7;
1401 
1402 	if (mrc_params->rtt_nom_value == 0)
1403 		emrs1_cmd |= (DDR3_EMRS1_RTTNOM_40 << 6);
1404 	else if (mrc_params->rtt_nom_value == 1)
1405 		emrs1_cmd |= (DDR3_EMRS1_RTTNOM_60 << 6);
1406 	else if (mrc_params->rtt_nom_value == 2)
1407 		emrs1_cmd |= (DDR3_EMRS1_RTTNOM_120 << 6);
1408 
1409 	/* save MRS1 value (excluding control fields) */
1410 	mrc_params->mrs1 = emrs1_cmd >> 6;
1411 
1412 	/*
1413 	 * setup for mrs 0
1414 	 * BIT[15:13]     --> Always "0"
1415 	 * BIT[12]        --> PPD: for Quark (1)
1416 	 * BIT[11:09]     --> WR: use oem_tWR
1417 	 * BIT[08]        --> DLL: want "Reset" (1, self clearing)
1418 	 * BIT[07]        --> MODE: want "Normal" (0)
1419 	 * BIT[06:04,02]  --> CL: use oem_tCAS
1420 	 * BIT[03]        --> RD_BURST_TYPE: want "Interleave" (1)
1421 	 * BIT[01:00]     --> BL: want "8 Fixed" (0)
1422 	 * WR:
1423 	 * 0 --> 16
1424 	 * 1 --> 5
1425 	 * 2 --> 6
1426 	 * 3 --> 7
1427 	 * 4 --> 8
1428 	 * 5 --> 10
1429 	 * 6 --> 12
1430 	 * 7 --> 14
1431 	 * CL:
1432 	 * BIT[02:02] "0" if oem_tCAS <= 11 (1866?)
1433 	 * BIT[06:04] use oem_tCAS-4
1434 	 */
1435 	mrs0_cmd |= BIT14;
1436 	mrs0_cmd |= BIT18;
1437 	mrs0_cmd |= ((((dtr0 >> 12) & 7) + 1) << 10);
1438 
1439 	tck = t_ck[mrc_params->ddr_speed];
1440 	/* Per JEDEC: tWR=15000ps DDR2/3 from 800-1600 */
1441 	twr = MCEIL(15000, tck);
1442 	mrs0_cmd |= ((twr - 4) << 15);
1443 
1444 	for (rank = 0; rank < NUM_RANKS; rank++) {
1445 		/* Skip to next populated rank */
1446 		if ((mrc_params->rank_enables & (1 << rank)) == 0)
1447 			continue;
1448 
1449 		emrs2_cmd |= (rank << 22);
1450 		dram_init_command(emrs2_cmd);
1451 
1452 		emrs3_cmd |= (rank << 22);
1453 		dram_init_command(emrs3_cmd);
1454 
1455 		emrs1_cmd |= (rank << 22);
1456 		dram_init_command(emrs1_cmd);
1457 
1458 		mrs0_cmd |= (rank << 22);
1459 		dram_init_command(mrs0_cmd);
1460 
1461 		dram_init_command(DCMD_ZQCL(rank));
1462 	}
1463 
1464 	LEAVEFN();
1465 }
1466 
1467 /*
1468  * Dunit Initialization Complete
1469  *
1470  * Indicates that initialization of the Dunit has completed.
1471  *
1472  * Memory accesses are permitted and maintenance operation begins.
1473  * Until this bit is set to a 1, the memory controller will not accept
1474  * DRAM requests from the MEMORY_MANAGER or HTE.
1475  */
1476 void set_ddr_init_complete(struct mrc_params *mrc_params)
1477 {
1478 	u32 dco;
1479 
1480 	ENTERFN();
1481 
1482 	dco = msg_port_read(MEM_CTLR, DCO);
1483 	dco &= ~BIT28;
1484 	dco |= BIT31;
1485 	msg_port_write(MEM_CTLR, DCO, dco);
1486 
1487 	LEAVEFN();
1488 }
1489 
1490 /*
1491  * This function will retrieve relevant timing data
1492  *
1493  * This data will be used on subsequent boots to speed up boot times
1494  * and is required for Suspend To RAM capabilities.
1495  */
1496 void restore_timings(struct mrc_params *mrc_params)
1497 {
1498 	uint8_t ch, rk, bl;
1499 	const struct mrc_timings *mt = &mrc_params->timings;
1500 
1501 	for (ch = 0; ch < NUM_CHANNELS; ch++) {
1502 		for (rk = 0; rk < NUM_RANKS; rk++) {
1503 			for (bl = 0; bl < NUM_BYTE_LANES; bl++) {
1504 				set_rcvn(ch, rk, bl, mt->rcvn[ch][rk][bl]);
1505 				set_rdqs(ch, rk, bl, mt->rdqs[ch][rk][bl]);
1506 				set_wdqs(ch, rk, bl, mt->wdqs[ch][rk][bl]);
1507 				set_wdq(ch, rk, bl, mt->wdq[ch][rk][bl]);
1508 				if (rk == 0) {
1509 					/* VREF (RANK0 only) */
1510 					set_vref(ch, bl, mt->vref[ch][bl]);
1511 				}
1512 			}
1513 			set_wctl(ch, rk, mt->wctl[ch][rk]);
1514 		}
1515 		set_wcmd(ch, mt->wcmd[ch]);
1516 	}
1517 }
1518 
1519 /*
1520  * Configure default settings normally set as part of read training
1521  *
1522  * Some defaults have to be set earlier as they may affect earlier
1523  * training steps.
1524  */
1525 void default_timings(struct mrc_params *mrc_params)
1526 {
1527 	uint8_t ch, rk, bl;
1528 
1529 	for (ch = 0; ch < NUM_CHANNELS; ch++) {
1530 		for (rk = 0; rk < NUM_RANKS; rk++) {
1531 			for (bl = 0; bl < NUM_BYTE_LANES; bl++) {
1532 				set_rdqs(ch, rk, bl, 24);
1533 				if (rk == 0) {
1534 					/* VREF (RANK0 only) */
1535 					set_vref(ch, bl, 32);
1536 				}
1537 			}
1538 		}
1539 	}
1540 }
1541 
1542 /*
1543  * This function will perform our RCVEN Calibration Algorithm.
1544  * We will only use the 2xCLK domain timings to perform RCVEN Calibration.
1545  * All byte lanes will be calibrated "simultaneously" per channel per rank.
1546  */
1547 void rcvn_cal(struct mrc_params *mrc_params)
1548 {
1549 	uint8_t ch;	/* channel counter */
1550 	uint8_t rk;	/* rank counter */
1551 	uint8_t bl;	/* byte lane counter */
1552 	uint8_t bl_divisor = (mrc_params->channel_width == X16) ? 2 : 1;
1553 
1554 #ifdef R2R_SHARING
1555 	/* used to find placement for rank2rank sharing configs */
1556 	uint32_t final_delay[NUM_CHANNELS][NUM_BYTE_LANES];
1557 #ifndef BACKUP_RCVN
1558 	/* used to find placement for rank2rank sharing configs */
1559 	uint32_t num_ranks_enabled = 0;
1560 #endif
1561 #endif
1562 
1563 #ifdef BACKUP_RCVN
1564 #else
1565 	uint32_t temp;
1566 	/* absolute PI value to be programmed on the byte lane */
1567 	uint32_t delay[NUM_BYTE_LANES];
1568 	u32 dtr1, dtr1_save;
1569 #endif
1570 
1571 	ENTERFN();
1572 
1573 	/* rcvn_cal starts */
1574 	mrc_post_code(0x05, 0x00);
1575 
1576 #ifndef BACKUP_RCVN
1577 	/* need separate burst to sample DQS preamble */
1578 	dtr1 = msg_port_read(MEM_CTLR, DTR1);
1579 	dtr1_save = dtr1;
1580 	dtr1 |= BIT12;
1581 	msg_port_write(MEM_CTLR, DTR1, dtr1);
1582 #endif
1583 
1584 #ifdef R2R_SHARING
1585 	/* need to set "final_delay[][]" elements to "0" */
1586 	memset((void *)(final_delay), 0x00, (size_t)sizeof(final_delay));
1587 #endif
1588 
1589 	/* loop through each enabled channel */
1590 	for (ch = 0; ch < NUM_CHANNELS; ch++) {
1591 		if (mrc_params->channel_enables & (1 << ch)) {
1592 			/* perform RCVEN Calibration on a per rank basis */
1593 			for (rk = 0; rk < NUM_RANKS; rk++) {
1594 				if (mrc_params->rank_enables & (1 << rk)) {
1595 					/*
1596 					 * POST_CODE here indicates the current
1597 					 * channel and rank being calibrated
1598 					 */
1599 					mrc_post_code(0x05, (0x10 + ((ch << 4) | rk)));
1600 
1601 #ifdef BACKUP_RCVN
1602 					/* et hard-coded timing values */
1603 					for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++)
1604 						set_rcvn(ch, rk, bl, ddr_rcvn[PLATFORM_ID]);
1605 #else
1606 					/* enable FIFORST */
1607 					for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl += 2) {
1608 						mrc_alt_write_mask(DDRPHY,
1609 							(B01PTRCTL1 +
1610 							((bl >> 1) * DDRIODQ_BL_OFFSET) +
1611 							(ch * DDRIODQ_CH_OFFSET)),
1612 							0, BIT8);
1613 					}
1614 					/* initialize the starting delay to 128 PI (cas +1 CLK) */
1615 					for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
1616 						/* 1x CLK domain timing is cas-4 */
1617 						delay[bl] = (4 + 1) * FULL_CLK;
1618 
1619 						set_rcvn(ch, rk, bl, delay[bl]);
1620 					}
1621 
1622 					/* now find the rising edge */
1623 					find_rising_edge(mrc_params, delay, ch, rk, true);
1624 
1625 					/* Now increase delay by 32 PI (1/4 CLK) to place in center of high pulse */
1626 					for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
1627 						delay[bl] += QRTR_CLK;
1628 						set_rcvn(ch, rk, bl, delay[bl]);
1629 					}
1630 					/* Now decrement delay by 128 PI (1 CLK) until we sample a "0" */
1631 					do {
1632 						temp = sample_dqs(mrc_params, ch, rk, true);
1633 						for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
1634 							if (temp & (1 << bl)) {
1635 								if (delay[bl] >= FULL_CLK) {
1636 									delay[bl] -= FULL_CLK;
1637 									set_rcvn(ch, rk, bl, delay[bl]);
1638 								} else {
1639 									/* not enough delay */
1640 									training_message(ch, rk, bl);
1641 									mrc_post_code(0xEE, 0x50);
1642 								}
1643 							}
1644 						}
1645 					} while (temp & 0xFF);
1646 
1647 #ifdef R2R_SHARING
1648 					/* increment "num_ranks_enabled" */
1649 					num_ranks_enabled++;
1650 					/* Finally increment delay by 32 PI (1/4 CLK) to place in center of preamble */
1651 					for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
1652 						delay[bl] += QRTR_CLK;
1653 						/* add "delay[]" values to "final_delay[][]" for rolling average */
1654 						final_delay[ch][bl] += delay[bl];
1655 						/* set timing based on rolling average values */
1656 						set_rcvn(ch, rk, bl, ((final_delay[ch][bl]) / num_ranks_enabled));
1657 					}
1658 #else
1659 					/* Finally increment delay by 32 PI (1/4 CLK) to place in center of preamble */
1660 					for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
1661 						delay[bl] += QRTR_CLK;
1662 						set_rcvn(ch, rk, bl, delay[bl]);
1663 					}
1664 #endif
1665 
1666 					/* disable FIFORST */
1667 					for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl += 2) {
1668 						mrc_alt_write_mask(DDRPHY,
1669 							(B01PTRCTL1 +
1670 							((bl >> 1) * DDRIODQ_BL_OFFSET) +
1671 							(ch * DDRIODQ_CH_OFFSET)),
1672 							BIT8, BIT8);
1673 					}
1674 #endif
1675 				}
1676 			}
1677 		}
1678 	}
1679 
1680 #ifndef BACKUP_RCVN
1681 	/* restore original */
1682 	msg_port_write(MEM_CTLR, DTR1, dtr1_save);
1683 #endif
1684 
1685 	LEAVEFN();
1686 }
1687 
1688 /*
1689  * This function will perform the Write Levelling algorithm
1690  * (align WCLK and WDQS).
1691  *
1692  * This algorithm will act on each rank in each channel separately.
1693  */
1694 void wr_level(struct mrc_params *mrc_params)
1695 {
1696 	uint8_t ch;	/* channel counter */
1697 	uint8_t rk;	/* rank counter */
1698 	uint8_t bl;	/* byte lane counter */
1699 	uint8_t bl_divisor = (mrc_params->channel_width == X16) ? 2 : 1;
1700 
1701 #ifdef R2R_SHARING
1702 	/* used to find placement for rank2rank sharing configs */
1703 	uint32_t final_delay[NUM_CHANNELS][NUM_BYTE_LANES];
1704 #ifndef BACKUP_WDQS
1705 	/* used to find placement for rank2rank sharing configs */
1706 	uint32_t num_ranks_enabled = 0;
1707 #endif
1708 #endif
1709 
1710 #ifdef BACKUP_WDQS
1711 #else
1712 	/* determines stop condition for CRS_WR_LVL */
1713 	bool all_edges_found;
1714 	/* absolute PI value to be programmed on the byte lane */
1715 	uint32_t delay[NUM_BYTE_LANES];
1716 	/*
1717 	 * static makes it so the data is loaded in the heap once by shadow(),
1718 	 * where non-static copies the data onto the stack every time this
1719 	 * function is called
1720 	 */
1721 	uint32_t address;	/* address to be checked during COARSE_WR_LVL */
1722 	u32 dtr4, dtr4_save;
1723 #endif
1724 
1725 	ENTERFN();
1726 
1727 	/* wr_level starts */
1728 	mrc_post_code(0x06, 0x00);
1729 
1730 #ifdef R2R_SHARING
1731 	/* need to set "final_delay[][]" elements to "0" */
1732 	memset((void *)(final_delay), 0x00, (size_t)sizeof(final_delay));
1733 #endif
1734 
1735 	/* loop through each enabled channel */
1736 	for (ch = 0; ch < NUM_CHANNELS; ch++) {
1737 		if (mrc_params->channel_enables & (1 << ch)) {
1738 			/* perform WRITE LEVELING algorithm on a per rank basis */
1739 			for (rk = 0; rk < NUM_RANKS; rk++) {
1740 				if (mrc_params->rank_enables & (1 << rk)) {
1741 					/*
1742 					 * POST_CODE here indicates the current
1743 					 * rank and channel being calibrated
1744 					 */
1745 					mrc_post_code(0x06, (0x10 + ((ch << 4) | rk)));
1746 
1747 #ifdef BACKUP_WDQS
1748 					for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
1749 						set_wdqs(ch, rk, bl, ddr_wdqs[PLATFORM_ID]);
1750 						set_wdq(ch, rk, bl, (ddr_wdqs[PLATFORM_ID] - QRTR_CLK));
1751 					}
1752 #else
1753 					/*
1754 					 * perform a single PRECHARGE_ALL command to
1755 					 * make DRAM state machine go to IDLE state
1756 					 */
1757 					dram_init_command(DCMD_PREA(rk));
1758 
1759 					/*
1760 					 * enable Write Levelling Mode
1761 					 * (EMRS1 w/ Write Levelling Mode Enable)
1762 					 */
1763 					dram_init_command(DCMD_MRS1(rk, 0x0082));
1764 
1765 					/*
1766 					 * set ODT DRAM Full Time Termination
1767 					 * disable in MCU
1768 					 */
1769 
1770 					dtr4 = msg_port_read(MEM_CTLR, DTR4);
1771 					dtr4_save = dtr4;
1772 					dtr4 |= BIT15;
1773 					msg_port_write(MEM_CTLR, DTR4, dtr4);
1774 
1775 					for (bl = 0; bl < ((NUM_BYTE_LANES / bl_divisor) / 2); bl++) {
1776 						/*
1777 						 * Enable Sandy Bridge Mode (WDQ Tri-State) &
1778 						 * Ensure 5 WDQS pulses during Write Leveling
1779 						 */
1780 						mrc_alt_write_mask(DDRPHY,
1781 							DQCTL + (DDRIODQ_BL_OFFSET * bl) + (DDRIODQ_CH_OFFSET * ch),
1782 							(BIT28 | BIT8 | BIT6 | BIT4 | BIT2),
1783 							(BIT28 | BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2));
1784 					}
1785 
1786 					/* Write Leveling Mode enabled in IO */
1787 					mrc_alt_write_mask(DDRPHY,
1788 						CCDDR3RESETCTL + (DDRIOCCC_CH_OFFSET * ch),
1789 						BIT16, BIT16);
1790 
1791 					/* Initialize the starting delay to WCLK */
1792 					for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
1793 						/*
1794 						 * CLK0 --> RK0
1795 						 * CLK1 --> RK1
1796 						 */
1797 						delay[bl] = get_wclk(ch, rk);
1798 
1799 						set_wdqs(ch, rk, bl, delay[bl]);
1800 					}
1801 
1802 					/* now find the rising edge */
1803 					find_rising_edge(mrc_params, delay, ch, rk, false);
1804 
1805 					/* disable Write Levelling Mode */
1806 					mrc_alt_write_mask(DDRPHY,
1807 						CCDDR3RESETCTL + (DDRIOCCC_CH_OFFSET * ch),
1808 						0, BIT16);
1809 
1810 					for (bl = 0; bl < ((NUM_BYTE_LANES / bl_divisor) / 2); bl++) {
1811 						/* Disable Sandy Bridge Mode & Ensure 4 WDQS pulses during normal operation */
1812 						mrc_alt_write_mask(DDRPHY,
1813 							DQCTL + (DDRIODQ_BL_OFFSET * bl) + (DDRIODQ_CH_OFFSET * ch),
1814 							(BIT8 | BIT6 | BIT4 | BIT2),
1815 							(BIT28 | BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2));
1816 					}
1817 
1818 					/* restore original DTR4 */
1819 					msg_port_write(MEM_CTLR, DTR4, dtr4_save);
1820 
1821 					/*
1822 					 * restore original value
1823 					 * (Write Levelling Mode Disable)
1824 					 */
1825 					dram_init_command(DCMD_MRS1(rk, mrc_params->mrs1));
1826 
1827 					/*
1828 					 * perform a single PRECHARGE_ALL command to
1829 					 * make DRAM state machine go to IDLE state
1830 					 */
1831 					dram_init_command(DCMD_PREA(rk));
1832 
1833 					mrc_post_code(0x06, (0x30 + ((ch << 4) | rk)));
1834 
1835 					/*
1836 					 * COARSE WRITE LEVEL:
1837 					 * check that we're on the correct clock edge
1838 					 */
1839 
1840 					/* hte reconfiguration request */
1841 					mrc_params->hte_setup = 1;
1842 
1843 					/* start CRS_WR_LVL with WDQS = WDQS + 128 PI */
1844 					for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
1845 						delay[bl] = get_wdqs(ch, rk, bl) + FULL_CLK;
1846 						set_wdqs(ch, rk, bl, delay[bl]);
1847 						/*
1848 						 * program WDQ timings based on WDQS
1849 						 * (WDQ = WDQS - 32 PI)
1850 						 */
1851 						set_wdq(ch, rk, bl, (delay[bl] - QRTR_CLK));
1852 					}
1853 
1854 					/* get an address in the targeted channel/rank */
1855 					address = get_addr(ch, rk);
1856 					do {
1857 						uint32_t coarse_result = 0x00;
1858 						uint32_t coarse_result_mask = byte_lane_mask(mrc_params);
1859 						/* assume pass */
1860 						all_edges_found = true;
1861 
1862 						mrc_params->hte_setup = 1;
1863 						coarse_result = check_rw_coarse(mrc_params, address);
1864 
1865 						/* check for failures and margin the byte lane back 128 PI (1 CLK) */
1866 						for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
1867 							if (coarse_result & (coarse_result_mask << bl)) {
1868 								all_edges_found = false;
1869 								delay[bl] -= FULL_CLK;
1870 								set_wdqs(ch, rk, bl, delay[bl]);
1871 								/* program WDQ timings based on WDQS (WDQ = WDQS - 32 PI) */
1872 								set_wdq(ch, rk, bl, (delay[bl] - QRTR_CLK));
1873 							}
1874 						}
1875 					} while (!all_edges_found);
1876 
1877 #ifdef R2R_SHARING
1878 					/* increment "num_ranks_enabled" */
1879 					 num_ranks_enabled++;
1880 					/* accumulate "final_delay[][]" values from "delay[]" values for rolling average */
1881 					for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
1882 						final_delay[ch][bl] += delay[bl];
1883 						set_wdqs(ch, rk, bl, ((final_delay[ch][bl]) / num_ranks_enabled));
1884 						/* program WDQ timings based on WDQS (WDQ = WDQS - 32 PI) */
1885 						set_wdq(ch, rk, bl, ((final_delay[ch][bl]) / num_ranks_enabled) - QRTR_CLK);
1886 					}
1887 #endif
1888 #endif
1889 				}
1890 			}
1891 		}
1892 	}
1893 
1894 	LEAVEFN();
1895 }
1896 
1897 void prog_page_ctrl(struct mrc_params *mrc_params)
1898 {
1899 	u32 dpmc0;
1900 
1901 	ENTERFN();
1902 
1903 	dpmc0 = msg_port_read(MEM_CTLR, DPMC0);
1904 	dpmc0 &= ~(BIT16 | BIT17 | BIT18);
1905 	dpmc0 |= (4 << 16);
1906 	dpmc0 |= BIT21;
1907 	msg_port_write(MEM_CTLR, DPMC0, dpmc0);
1908 }
1909 
1910 /*
1911  * This function will perform the READ TRAINING Algorithm on all
1912  * channels/ranks/byte_lanes simultaneously to minimize execution time.
1913  *
1914  * The idea here is to train the VREF and RDQS (and eventually RDQ) values
1915  * to achieve maximum READ margins. The algorithm will first determine the
1916  * X coordinate (RDQS setting). This is done by collapsing the VREF eye
1917  * until we find a minimum required RDQS eye for VREF_MIN and VREF_MAX.
1918  * Then we take the averages of the RDQS eye at VREF_MIN and VREF_MAX,
1919  * then average those; this will be the final X coordinate. The algorithm
1920  * will then determine the Y coordinate (VREF setting). This is done by
1921  * collapsing the RDQS eye until we find a minimum required VREF eye for
1922  * RDQS_MIN and RDQS_MAX. Then we take the averages of the VREF eye at
1923  * RDQS_MIN and RDQS_MAX, then average those; this will be the final Y
1924  * coordinate.
1925  *
1926  * NOTE: this algorithm assumes the eye curves have a one-to-one relationship,
1927  * meaning for each X the curve has only one Y and vice-a-versa.
1928  */
1929 void rd_train(struct mrc_params *mrc_params)
1930 {
1931 	uint8_t ch;	/* channel counter */
1932 	uint8_t rk;	/* rank counter */
1933 	uint8_t bl;	/* byte lane counter */
1934 	uint8_t bl_divisor = (mrc_params->channel_width == X16) ? 2 : 1;
1935 #ifdef BACKUP_RDQS
1936 #else
1937 	uint8_t side_x;	/* tracks LEFT/RIGHT approach vectors */
1938 	uint8_t side_y;	/* tracks BOTTOM/TOP approach vectors */
1939 	/* X coordinate data (passing RDQS values) for approach vectors */
1940 	uint8_t x_coordinate[2][2][NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES];
1941 	/* Y coordinate data (passing VREF values) for approach vectors */
1942 	uint8_t y_coordinate[2][2][NUM_CHANNELS][NUM_BYTE_LANES];
1943 	/* centered X (RDQS) */
1944 	uint8_t x_center[NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES];
1945 	/* centered Y (VREF) */
1946 	uint8_t y_center[NUM_CHANNELS][NUM_BYTE_LANES];
1947 	uint32_t address;	/* target address for check_bls_ex() */
1948 	uint32_t result;	/* result of check_bls_ex() */
1949 	uint32_t bl_mask;	/* byte lane mask for result checking */
1950 #ifdef R2R_SHARING
1951 	/* used to find placement for rank2rank sharing configs */
1952 	uint32_t final_delay[NUM_CHANNELS][NUM_BYTE_LANES];
1953 	/* used to find placement for rank2rank sharing configs */
1954 	uint32_t num_ranks_enabled = 0;
1955 #endif
1956 #endif
1957 
1958 	/* rd_train starts */
1959 	mrc_post_code(0x07, 0x00);
1960 
1961 	ENTERFN();
1962 
1963 #ifdef BACKUP_RDQS
1964 	for (ch = 0; ch < NUM_CHANNELS; ch++) {
1965 		if (mrc_params->channel_enables & (1 << ch)) {
1966 			for (rk = 0; rk < NUM_RANKS; rk++) {
1967 				if (mrc_params->rank_enables & (1 << rk)) {
1968 					for (bl = 0;
1969 					     bl < (NUM_BYTE_LANES / bl_divisor);
1970 					     bl++) {
1971 						set_rdqs(ch, rk, bl, ddr_rdqs[PLATFORM_ID]);
1972 					}
1973 				}
1974 			}
1975 		}
1976 	}
1977 #else
1978 	/* initialize x/y_coordinate arrays */
1979 	for (ch = 0; ch < NUM_CHANNELS; ch++) {
1980 		if (mrc_params->channel_enables & (1 << ch)) {
1981 			for (rk = 0; rk < NUM_RANKS; rk++) {
1982 				if (mrc_params->rank_enables & (1 << rk)) {
1983 					for (bl = 0;
1984 					     bl < (NUM_BYTE_LANES / bl_divisor);
1985 					     bl++) {
1986 						/* x_coordinate */
1987 						x_coordinate[L][B][ch][rk][bl] = RDQS_MIN;
1988 						x_coordinate[R][B][ch][rk][bl] = RDQS_MAX;
1989 						x_coordinate[L][T][ch][rk][bl] = RDQS_MIN;
1990 						x_coordinate[R][T][ch][rk][bl] = RDQS_MAX;
1991 						/* y_coordinate */
1992 						y_coordinate[L][B][ch][bl] = VREF_MIN;
1993 						y_coordinate[R][B][ch][bl] = VREF_MIN;
1994 						y_coordinate[L][T][ch][bl] = VREF_MAX;
1995 						y_coordinate[R][T][ch][bl] = VREF_MAX;
1996 					}
1997 				}
1998 			}
1999 		}
2000 	}
2001 
2002 	/* initialize other variables */
2003 	bl_mask = byte_lane_mask(mrc_params);
2004 	address = get_addr(0, 0);
2005 
2006 #ifdef R2R_SHARING
2007 	/* need to set "final_delay[][]" elements to "0" */
2008 	memset((void *)(final_delay), 0x00, (size_t)sizeof(final_delay));
2009 #endif
2010 
2011 	/* look for passing coordinates */
2012 	for (side_y = B; side_y <= T; side_y++) {
2013 		for (side_x = L; side_x <= R; side_x++) {
2014 			mrc_post_code(0x07, (0x10 + (side_y * 2) + (side_x)));
2015 
2016 			/* find passing values */
2017 			for (ch = 0; ch < NUM_CHANNELS; ch++) {
2018 				if (mrc_params->channel_enables & (0x1 << ch)) {
2019 					for (rk = 0; rk < NUM_RANKS; rk++) {
2020 						if (mrc_params->rank_enables &
2021 							(0x1 << rk)) {
2022 							/* set x/y_coordinate search starting settings */
2023 							for (bl = 0;
2024 							     bl < (NUM_BYTE_LANES / bl_divisor);
2025 							     bl++) {
2026 								set_rdqs(ch, rk, bl,
2027 									 x_coordinate[side_x][side_y][ch][rk][bl]);
2028 								set_vref(ch, bl,
2029 									 y_coordinate[side_x][side_y][ch][bl]);
2030 							}
2031 
2032 							/* get an address in the target channel/rank */
2033 							address = get_addr(ch, rk);
2034 
2035 							/* request HTE reconfiguration */
2036 							mrc_params->hte_setup = 1;
2037 
2038 							/* test the settings */
2039 							do {
2040 								/* result[07:00] == failing byte lane (MAX 8) */
2041 								result = check_bls_ex(mrc_params, address);
2042 
2043 								/* check for failures */
2044 								if (result & 0xFF) {
2045 									/* at least 1 byte lane failed */
2046 									for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
2047 										if (result &
2048 											(bl_mask << bl)) {
2049 											/* adjust the RDQS values accordingly */
2050 											if (side_x == L)
2051 												x_coordinate[L][side_y][ch][rk][bl] += RDQS_STEP;
2052 											else
2053 												x_coordinate[R][side_y][ch][rk][bl] -= RDQS_STEP;
2054 
2055 											/* check that we haven't closed the RDQS_EYE too much */
2056 											if ((x_coordinate[L][side_y][ch][rk][bl] > (RDQS_MAX - MIN_RDQS_EYE)) ||
2057 												(x_coordinate[R][side_y][ch][rk][bl] < (RDQS_MIN + MIN_RDQS_EYE)) ||
2058 												(x_coordinate[L][side_y][ch][rk][bl] ==
2059 												x_coordinate[R][side_y][ch][rk][bl])) {
2060 												/*
2061 												 * not enough RDQS margin available at this VREF
2062 												 * update VREF values accordingly
2063 												 */
2064 												if (side_y == B)
2065 													y_coordinate[side_x][B][ch][bl] += VREF_STEP;
2066 												else
2067 													y_coordinate[side_x][T][ch][bl] -= VREF_STEP;
2068 
2069 												/* check that we haven't closed the VREF_EYE too much */
2070 												if ((y_coordinate[side_x][B][ch][bl] > (VREF_MAX - MIN_VREF_EYE)) ||
2071 													(y_coordinate[side_x][T][ch][bl] < (VREF_MIN + MIN_VREF_EYE)) ||
2072 													(y_coordinate[side_x][B][ch][bl] == y_coordinate[side_x][T][ch][bl])) {
2073 													/* VREF_EYE collapsed below MIN_VREF_EYE */
2074 													training_message(ch, rk, bl);
2075 													mrc_post_code(0xEE, (0x70 + (side_y * 2) + (side_x)));
2076 												} else {
2077 													/* update the VREF setting */
2078 													set_vref(ch, bl, y_coordinate[side_x][side_y][ch][bl]);
2079 													/* reset the X coordinate to begin the search at the new VREF */
2080 													x_coordinate[side_x][side_y][ch][rk][bl] =
2081 														(side_x == L) ? (RDQS_MIN) : (RDQS_MAX);
2082 												}
2083 											}
2084 
2085 											/* update the RDQS setting */
2086 											set_rdqs(ch, rk, bl, x_coordinate[side_x][side_y][ch][rk][bl]);
2087 										}
2088 									}
2089 								}
2090 							} while (result & 0xFF);
2091 						}
2092 					}
2093 				}
2094 			}
2095 		}
2096 	}
2097 
2098 	mrc_post_code(0x07, 0x20);
2099 
2100 	/* find final RDQS (X coordinate) & final VREF (Y coordinate) */
2101 	for (ch = 0; ch < NUM_CHANNELS; ch++) {
2102 		if (mrc_params->channel_enables & (1 << ch)) {
2103 			for (rk = 0; rk < NUM_RANKS; rk++) {
2104 				if (mrc_params->rank_enables & (1 << rk)) {
2105 					for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
2106 						uint32_t temp1;
2107 						uint32_t temp2;
2108 
2109 						/* x_coordinate */
2110 						DPF(D_INFO,
2111 						    "RDQS T/B eye rank%d lane%d : %d-%d %d-%d\n",
2112 						    rk, bl,
2113 						    x_coordinate[L][T][ch][rk][bl],
2114 						    x_coordinate[R][T][ch][rk][bl],
2115 						    x_coordinate[L][B][ch][rk][bl],
2116 						    x_coordinate[R][B][ch][rk][bl]);
2117 
2118 						/* average the TOP side LEFT & RIGHT values */
2119 						temp1 = (x_coordinate[R][T][ch][rk][bl] + x_coordinate[L][T][ch][rk][bl]) / 2;
2120 						/* average the BOTTOM side LEFT & RIGHT values */
2121 						temp2 = (x_coordinate[R][B][ch][rk][bl] + x_coordinate[L][B][ch][rk][bl]) / 2;
2122 						/* average the above averages */
2123 						x_center[ch][rk][bl] = (uint8_t) ((temp1 + temp2) / 2);
2124 
2125 						/* y_coordinate */
2126 						DPF(D_INFO,
2127 						    "VREF R/L eye lane%d : %d-%d %d-%d\n",
2128 						    bl,
2129 						    y_coordinate[R][B][ch][bl],
2130 						    y_coordinate[R][T][ch][bl],
2131 						    y_coordinate[L][B][ch][bl],
2132 						    y_coordinate[L][T][ch][bl]);
2133 
2134 						/* average the RIGHT side TOP & BOTTOM values */
2135 						temp1 = (y_coordinate[R][T][ch][bl] + y_coordinate[R][B][ch][bl]) / 2;
2136 						/* average the LEFT side TOP & BOTTOM values */
2137 						temp2 = (y_coordinate[L][T][ch][bl] + y_coordinate[L][B][ch][bl]) / 2;
2138 						/* average the above averages */
2139 						y_center[ch][bl] = (uint8_t) ((temp1 + temp2) / 2);
2140 					}
2141 				}
2142 			}
2143 		}
2144 	}
2145 
2146 #ifdef RX_EYE_CHECK
2147 	/* perform an eye check */
2148 	for (side_y = B; side_y <= T; side_y++) {
2149 		for (side_x = L; side_x <= R; side_x++) {
2150 			mrc_post_code(0x07, (0x30 + (side_y * 2) + (side_x)));
2151 
2152 			/* update the settings for the eye check */
2153 			for (ch = 0; ch < NUM_CHANNELS; ch++) {
2154 				if (mrc_params->channel_enables & (1 << ch)) {
2155 					for (rk = 0; rk < NUM_RANKS; rk++) {
2156 						if (mrc_params->rank_enables & (1 << rk)) {
2157 							for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
2158 								if (side_x == L)
2159 									set_rdqs(ch, rk, bl, (x_center[ch][rk][bl] - (MIN_RDQS_EYE / 2)));
2160 								else
2161 									set_rdqs(ch, rk, bl, (x_center[ch][rk][bl] + (MIN_RDQS_EYE / 2)));
2162 
2163 								if (side_y == B)
2164 									set_vref(ch, bl, (y_center[ch][bl] - (MIN_VREF_EYE / 2)));
2165 								else
2166 									set_vref(ch, bl, (y_center[ch][bl] + (MIN_VREF_EYE / 2)));
2167 							}
2168 						}
2169 					}
2170 				}
2171 			}
2172 
2173 			/* request HTE reconfiguration */
2174 			mrc_params->hte_setup = 1;
2175 
2176 			/* check the eye */
2177 			if (check_bls_ex(mrc_params, address) & 0xFF) {
2178 				/* one or more byte lanes failed */
2179 				mrc_post_code(0xEE, (0x74 + (side_x * 2) + (side_y)));
2180 			}
2181 		}
2182 	}
2183 #endif
2184 
2185 	mrc_post_code(0x07, 0x40);
2186 
2187 	/* set final placements */
2188 	for (ch = 0; ch < NUM_CHANNELS; ch++) {
2189 		if (mrc_params->channel_enables & (1 << ch)) {
2190 			for (rk = 0; rk < NUM_RANKS; rk++) {
2191 				if (mrc_params->rank_enables & (1 << rk)) {
2192 #ifdef R2R_SHARING
2193 					/* increment "num_ranks_enabled" */
2194 					num_ranks_enabled++;
2195 #endif
2196 					for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
2197 						/* x_coordinate */
2198 #ifdef R2R_SHARING
2199 						final_delay[ch][bl] += x_center[ch][rk][bl];
2200 						set_rdqs(ch, rk, bl, ((final_delay[ch][bl]) / num_ranks_enabled));
2201 #else
2202 						set_rdqs(ch, rk, bl, x_center[ch][rk][bl]);
2203 #endif
2204 						/* y_coordinate */
2205 						set_vref(ch, bl, y_center[ch][bl]);
2206 					}
2207 				}
2208 			}
2209 		}
2210 	}
2211 #endif
2212 
2213 	LEAVEFN();
2214 }
2215 
2216 /*
2217  * This function will perform the WRITE TRAINING Algorithm on all
2218  * channels/ranks/byte_lanes simultaneously to minimize execution time.
2219  *
2220  * The idea here is to train the WDQ timings to achieve maximum WRITE margins.
2221  * The algorithm will start with WDQ at the current WDQ setting (tracks WDQS
2222  * in WR_LVL) +/- 32 PIs (+/- 1/4 CLK) and collapse the eye until all data
2223  * patterns pass. This is because WDQS will be aligned to WCLK by the
2224  * Write Leveling algorithm and WDQ will only ever have a 1/2 CLK window
2225  * of validity.
2226  */
2227 void wr_train(struct mrc_params *mrc_params)
2228 {
2229 	uint8_t ch;	/* channel counter */
2230 	uint8_t rk;	/* rank counter */
2231 	uint8_t bl;	/* byte lane counter */
2232 	uint8_t bl_divisor = (mrc_params->channel_width == X16) ? 2 : 1;
2233 #ifdef BACKUP_WDQ
2234 #else
2235 	uint8_t side;		/* LEFT/RIGHT side indicator (0=L, 1=R) */
2236 	uint32_t temp;		/* temporary DWORD */
2237 	/* 2 arrays, for L & R side passing delays */
2238 	uint32_t delay[2][NUM_CHANNELS][NUM_RANKS][NUM_BYTE_LANES];
2239 	uint32_t address;	/* target address for check_bls_ex() */
2240 	uint32_t result;	/* result of check_bls_ex() */
2241 	uint32_t bl_mask;	/* byte lane mask for result checking */
2242 #ifdef R2R_SHARING
2243 	/* used to find placement for rank2rank sharing configs */
2244 	uint32_t final_delay[NUM_CHANNELS][NUM_BYTE_LANES];
2245 	/* used to find placement for rank2rank sharing configs */
2246 	uint32_t num_ranks_enabled = 0;
2247 #endif
2248 #endif
2249 
2250 	/* wr_train starts */
2251 	mrc_post_code(0x08, 0x00);
2252 
2253 	ENTERFN();
2254 
2255 #ifdef BACKUP_WDQ
2256 	for (ch = 0; ch < NUM_CHANNELS; ch++) {
2257 		if (mrc_params->channel_enables & (1 << ch)) {
2258 			for (rk = 0; rk < NUM_RANKS; rk++) {
2259 				if (mrc_params->rank_enables & (1 << rk)) {
2260 					for (bl = 0;
2261 					     bl < (NUM_BYTE_LANES / bl_divisor);
2262 					     bl++) {
2263 						set_wdq(ch, rk, bl, ddr_wdq[PLATFORM_ID]);
2264 					}
2265 				}
2266 			}
2267 		}
2268 	}
2269 #else
2270 	/* initialize "delay" */
2271 	for (ch = 0; ch < NUM_CHANNELS; ch++) {
2272 		if (mrc_params->channel_enables & (1 << ch)) {
2273 			for (rk = 0; rk < NUM_RANKS; rk++) {
2274 				if (mrc_params->rank_enables & (1 << rk)) {
2275 					for (bl = 0;
2276 					     bl < (NUM_BYTE_LANES / bl_divisor);
2277 					     bl++) {
2278 						/*
2279 						 * want to start with
2280 						 * WDQ = (WDQS - QRTR_CLK)
2281 						 * +/- QRTR_CLK
2282 						 */
2283 						temp = get_wdqs(ch, rk, bl) - QRTR_CLK;
2284 						delay[L][ch][rk][bl] = temp - QRTR_CLK;
2285 						delay[R][ch][rk][bl] = temp + QRTR_CLK;
2286 					}
2287 				}
2288 			}
2289 		}
2290 	}
2291 
2292 	/* initialize other variables */
2293 	bl_mask = byte_lane_mask(mrc_params);
2294 	address = get_addr(0, 0);
2295 
2296 #ifdef R2R_SHARING
2297 	/* need to set "final_delay[][]" elements to "0" */
2298 	memset((void *)(final_delay), 0x00, (size_t)sizeof(final_delay));
2299 #endif
2300 
2301 	/*
2302 	 * start algorithm on the LEFT side and train each channel/bl
2303 	 * until no failures are observed, then repeat for the RIGHT side.
2304 	 */
2305 	for (side = L; side <= R; side++) {
2306 		mrc_post_code(0x08, (0x10 + (side)));
2307 
2308 		/* set starting values */
2309 		for (ch = 0; ch < NUM_CHANNELS; ch++) {
2310 			if (mrc_params->channel_enables & (1 << ch)) {
2311 				for (rk = 0; rk < NUM_RANKS; rk++) {
2312 					if (mrc_params->rank_enables &
2313 						(1 << rk)) {
2314 						for (bl = 0;
2315 						     bl < (NUM_BYTE_LANES / bl_divisor);
2316 						     bl++) {
2317 							set_wdq(ch, rk, bl, delay[side][ch][rk][bl]);
2318 						}
2319 					}
2320 				}
2321 			}
2322 		}
2323 
2324 		/* find passing values */
2325 		for (ch = 0; ch < NUM_CHANNELS; ch++) {
2326 			if (mrc_params->channel_enables & (1 << ch)) {
2327 				for (rk = 0; rk < NUM_RANKS; rk++) {
2328 					if (mrc_params->rank_enables &
2329 						(1 << rk)) {
2330 						/* get an address in the target channel/rank */
2331 						address = get_addr(ch, rk);
2332 
2333 						/* request HTE reconfiguration */
2334 						mrc_params->hte_setup = 1;
2335 
2336 						/* check the settings */
2337 						do {
2338 							/* result[07:00] == failing byte lane (MAX 8) */
2339 							result = check_bls_ex(mrc_params, address);
2340 							/* check for failures */
2341 							if (result & 0xFF) {
2342 								/* at least 1 byte lane failed */
2343 								for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
2344 									if (result &
2345 										(bl_mask << bl)) {
2346 										if (side == L)
2347 											delay[L][ch][rk][bl] += WDQ_STEP;
2348 										else
2349 											delay[R][ch][rk][bl] -= WDQ_STEP;
2350 
2351 										/* check for algorithm failure */
2352 										if (delay[L][ch][rk][bl] != delay[R][ch][rk][bl]) {
2353 											/*
2354 											 * margin available
2355 											 * update delay setting
2356 											 */
2357 											set_wdq(ch, rk, bl,
2358 												delay[side][ch][rk][bl]);
2359 										} else {
2360 											/*
2361 											 * no margin available
2362 											 * notify the user and halt
2363 											 */
2364 											training_message(ch, rk, bl);
2365 											mrc_post_code(0xEE, (0x80 + side));
2366 										}
2367 									}
2368 								}
2369 							}
2370 						/* stop when all byte lanes pass */
2371 						} while (result & 0xFF);
2372 					}
2373 				}
2374 			}
2375 		}
2376 	}
2377 
2378 	/* program WDQ to the middle of passing window */
2379 	for (ch = 0; ch < NUM_CHANNELS; ch++) {
2380 		if (mrc_params->channel_enables & (1 << ch)) {
2381 			for (rk = 0; rk < NUM_RANKS; rk++) {
2382 				if (mrc_params->rank_enables & (1 << rk)) {
2383 #ifdef R2R_SHARING
2384 					/* increment "num_ranks_enabled" */
2385 					num_ranks_enabled++;
2386 #endif
2387 					for (bl = 0; bl < (NUM_BYTE_LANES / bl_divisor); bl++) {
2388 						DPF(D_INFO,
2389 						    "WDQ eye rank%d lane%d : %d-%d\n",
2390 						    rk, bl,
2391 						    delay[L][ch][rk][bl],
2392 						    delay[R][ch][rk][bl]);
2393 
2394 						temp = (delay[R][ch][rk][bl] + delay[L][ch][rk][bl]) / 2;
2395 
2396 #ifdef R2R_SHARING
2397 						final_delay[ch][bl] += temp;
2398 						set_wdq(ch, rk, bl,
2399 							((final_delay[ch][bl]) / num_ranks_enabled));
2400 #else
2401 						set_wdq(ch, rk, bl, temp);
2402 #endif
2403 					}
2404 				}
2405 			}
2406 		}
2407 	}
2408 #endif
2409 
2410 	LEAVEFN();
2411 }
2412 
2413 /*
2414  * This function will store relevant timing data
2415  *
2416  * This data will be used on subsequent boots to speed up boot times
2417  * and is required for Suspend To RAM capabilities.
2418  */
2419 void store_timings(struct mrc_params *mrc_params)
2420 {
2421 	uint8_t ch, rk, bl;
2422 	struct mrc_timings *mt = &mrc_params->timings;
2423 
2424 	for (ch = 0; ch < NUM_CHANNELS; ch++) {
2425 		for (rk = 0; rk < NUM_RANKS; rk++) {
2426 			for (bl = 0; bl < NUM_BYTE_LANES; bl++) {
2427 				mt->rcvn[ch][rk][bl] = get_rcvn(ch, rk, bl);
2428 				mt->rdqs[ch][rk][bl] = get_rdqs(ch, rk, bl);
2429 				mt->wdqs[ch][rk][bl] = get_wdqs(ch, rk, bl);
2430 				mt->wdq[ch][rk][bl] = get_wdq(ch, rk, bl);
2431 
2432 				if (rk == 0)
2433 					mt->vref[ch][bl] = get_vref(ch, bl);
2434 			}
2435 
2436 			mt->wctl[ch][rk] = get_wctl(ch, rk);
2437 		}
2438 
2439 		mt->wcmd[ch] = get_wcmd(ch);
2440 	}
2441 
2442 	/* need to save for a case of changing frequency after warm reset */
2443 	mt->ddr_speed = mrc_params->ddr_speed;
2444 }
2445 
2446 /*
2447  * The purpose of this function is to ensure the SEC comes out of reset
2448  * and IA initiates the SEC enabling Memory Scrambling.
2449  */
2450 void enable_scrambling(struct mrc_params *mrc_params)
2451 {
2452 	uint32_t lfsr = 0;
2453 	uint8_t i;
2454 
2455 	if (mrc_params->scrambling_enables == 0)
2456 		return;
2457 
2458 	ENTERFN();
2459 
2460 	/* 32 bit seed is always stored in BIOS NVM */
2461 	lfsr = mrc_params->timings.scrambler_seed;
2462 
2463 	if (mrc_params->boot_mode == BM_COLD) {
2464 		/*
2465 		 * factory value is 0 and in first boot,
2466 		 * a clock based seed is loaded.
2467 		 */
2468 		if (lfsr == 0) {
2469 			/*
2470 			 * get seed from system clock
2471 			 * and make sure it is not all 1's
2472 			 */
2473 			lfsr = rdtsc() & 0x0FFFFFFF;
2474 		} else {
2475 			/*
2476 			 * Need to replace scrambler
2477 			 *
2478 			 * get next 32bit LFSR 16 times which is the last
2479 			 * part of the previous scrambler vector
2480 			 */
2481 			for (i = 0; i < 16; i++)
2482 				lfsr32(&lfsr);
2483 		}
2484 
2485 		/* save new seed */
2486 		mrc_params->timings.scrambler_seed = lfsr;
2487 	}
2488 
2489 	/*
2490 	 * In warm boot or S3 exit, we have the previous seed.
2491 	 * In cold boot, we have the last 32bit LFSR which is the new seed.
2492 	 */
2493 	lfsr32(&lfsr);	/* shift to next value */
2494 	msg_port_write(MEM_CTLR, SCRMSEED, (lfsr & 0x0003FFFF));
2495 
2496 	for (i = 0; i < 2; i++)
2497 		msg_port_write(MEM_CTLR, SCRMLO + i, (lfsr & 0xAAAAAAAA));
2498 
2499 	LEAVEFN();
2500 }
2501 
2502 /*
2503  * Configure MCU Power Management Control Register
2504  * and Scheduler Control Register
2505  */
2506 void prog_ddr_control(struct mrc_params *mrc_params)
2507 {
2508 	u32 dsch;
2509 	u32 dpmc0;
2510 
2511 	ENTERFN();
2512 
2513 	dsch = msg_port_read(MEM_CTLR, DSCH);
2514 	dsch &= ~(BIT8 | BIT9 | BIT12);
2515 	msg_port_write(MEM_CTLR, DSCH, dsch);
2516 
2517 	dpmc0 = msg_port_read(MEM_CTLR, DPMC0);
2518 	dpmc0 &= ~BIT25;
2519 	dpmc0 |= (mrc_params->power_down_disable << 25);
2520 	dpmc0 &= ~BIT24;
2521 	dpmc0 &= ~(BIT16 | BIT17 | BIT18);
2522 	dpmc0 |= (4 << 16);
2523 	dpmc0 |= BIT21;
2524 	msg_port_write(MEM_CTLR, DPMC0, dpmc0);
2525 
2526 	/* CMDTRIST = 2h - CMD/ADDR are tristated when no valid command */
2527 	mrc_write_mask(MEM_CTLR, DPMC1, 2 << 4, BIT4 | BIT5);
2528 
2529 	LEAVEFN();
2530 }
2531 
2532 /*
2533  * After training complete configure MCU Rank Population Register
2534  * specifying: ranks enabled, device width, density, address mode
2535  */
2536 void prog_dra_drb(struct mrc_params *mrc_params)
2537 {
2538 	u32 drp;
2539 	u32 dco;
2540 	u8 density = mrc_params->params.density;
2541 
2542 	ENTERFN();
2543 
2544 	dco = msg_port_read(MEM_CTLR, DCO);
2545 	dco &= ~BIT31;
2546 	msg_port_write(MEM_CTLR, DCO, dco);
2547 
2548 	drp = 0;
2549 	if (mrc_params->rank_enables & 1)
2550 		drp |= BIT0;
2551 	if (mrc_params->rank_enables & 2)
2552 		drp |= BIT1;
2553 	if (mrc_params->dram_width == X16) {
2554 		drp |= (1 << 4);
2555 		drp |= (1 << 9);
2556 	}
2557 
2558 	/*
2559 	 * Density encoding in struct dram_params: 0=512Mb, 1=Gb, 2=2Gb, 3=4Gb
2560 	 * has to be mapped RANKDENSx encoding (0=1Gb)
2561 	 */
2562 	if (density == 0)
2563 		density = 4;
2564 
2565 	drp |= ((density - 1) << 6);
2566 	drp |= ((density - 1) << 11);
2567 
2568 	/* Address mode can be overwritten if ECC enabled */
2569 	drp |= (mrc_params->address_mode << 14);
2570 
2571 	msg_port_write(MEM_CTLR, DRP, drp);
2572 
2573 	dco &= ~BIT28;
2574 	dco |= BIT31;
2575 	msg_port_write(MEM_CTLR, DCO, dco);
2576 
2577 	LEAVEFN();
2578 }
2579 
2580 /* Send DRAM wake command */
2581 void perform_wake(struct mrc_params *mrc_params)
2582 {
2583 	ENTERFN();
2584 
2585 	dram_wake_command();
2586 
2587 	LEAVEFN();
2588 }
2589 
2590 /*
2591  * Configure refresh rate and short ZQ calibration interval
2592  * Activate dynamic self refresh
2593  */
2594 void change_refresh_period(struct mrc_params *mrc_params)
2595 {
2596 	u32 drfc;
2597 	u32 dcal;
2598 	u32 dpmc0;
2599 
2600 	ENTERFN();
2601 
2602 	drfc = msg_port_read(MEM_CTLR, DRFC);
2603 	drfc &= ~(BIT12 | BIT13 | BIT14);
2604 	drfc |= (mrc_params->refresh_rate << 12);
2605 	drfc |= BIT21;
2606 	msg_port_write(MEM_CTLR, DRFC, drfc);
2607 
2608 	dcal = msg_port_read(MEM_CTLR, DCAL);
2609 	dcal &= ~(BIT8 | BIT9 | BIT10);
2610 	dcal |= (3 << 8);	/* 63ms */
2611 	msg_port_write(MEM_CTLR, DCAL, dcal);
2612 
2613 	dpmc0 = msg_port_read(MEM_CTLR, DPMC0);
2614 	dpmc0 |= (BIT23 | BIT29);
2615 	msg_port_write(MEM_CTLR, DPMC0, dpmc0);
2616 
2617 	LEAVEFN();
2618 }
2619 
2620 /*
2621  * Configure DDRPHY for Auto-Refresh, Periodic Compensations,
2622  * Dynamic Diff-Amp, ZQSPERIOD, Auto-Precharge, CKE Power-Down
2623  */
2624 void set_auto_refresh(struct mrc_params *mrc_params)
2625 {
2626 	uint32_t channel;
2627 	uint32_t rank;
2628 	uint32_t bl;
2629 	uint32_t bl_divisor = 1;
2630 	uint32_t temp;
2631 
2632 	ENTERFN();
2633 
2634 	/*
2635 	 * Enable Auto-Refresh, Periodic Compensations, Dynamic Diff-Amp,
2636 	 * ZQSPERIOD, Auto-Precharge, CKE Power-Down
2637 	 */
2638 	for (channel = 0; channel < NUM_CHANNELS; channel++) {
2639 		if (mrc_params->channel_enables & (1 << channel)) {
2640 			/* Enable Periodic RCOMPS */
2641 			mrc_alt_write_mask(DDRPHY, CMPCTRL, BIT1, BIT1);
2642 
2643 			/* Enable Dynamic DiffAmp & Set Read ODT Value */
2644 			switch (mrc_params->rd_odt_value) {
2645 			case 0:
2646 				temp = 0x3F;	/* OFF */
2647 				break;
2648 			default:
2649 				temp = 0x00;	/* Auto */
2650 				break;
2651 			}
2652 
2653 			for (bl = 0; bl < ((NUM_BYTE_LANES / bl_divisor) / 2); bl++) {
2654 				/* Override: DIFFAMP, ODT */
2655 				mrc_alt_write_mask(DDRPHY,
2656 					(B0OVRCTL + (bl * DDRIODQ_BL_OFFSET) +
2657 					(channel * DDRIODQ_CH_OFFSET)),
2658 					(0x00 << 16) | (temp << 10),
2659 					(BIT21 | BIT20 | BIT19 | BIT18 |
2660 					 BIT17 | BIT16 | BIT15 | BIT14 |
2661 					 BIT13 | BIT12 | BIT11 | BIT10));
2662 
2663 				/* Override: DIFFAMP, ODT */
2664 				mrc_alt_write_mask(DDRPHY,
2665 					(B1OVRCTL + (bl * DDRIODQ_BL_OFFSET) +
2666 					(channel * DDRIODQ_CH_OFFSET)),
2667 					(0x00 << 16) | (temp << 10),
2668 					(BIT21 | BIT20 | BIT19 | BIT18 |
2669 					 BIT17 | BIT16 | BIT15 | BIT14 |
2670 					 BIT13 | BIT12 | BIT11 | BIT10));
2671 			}
2672 
2673 			/* Issue ZQCS command */
2674 			for (rank = 0; rank < NUM_RANKS; rank++) {
2675 				if (mrc_params->rank_enables & (1 << rank))
2676 					dram_init_command(DCMD_ZQCS(rank));
2677 			}
2678 		}
2679 	}
2680 
2681 	clear_pointers();
2682 
2683 	LEAVEFN();
2684 }
2685 
2686 /*
2687  * Depending on configuration enables ECC support
2688  *
2689  * Available memory size is decreased, and updated with 0s
2690  * in order to clear error status. Address mode 2 forced.
2691  */
2692 void ecc_enable(struct mrc_params *mrc_params)
2693 {
2694 	u32 drp;
2695 	u32 dsch;
2696 	u32 ecc_ctrl;
2697 
2698 	if (mrc_params->ecc_enables == 0)
2699 		return;
2700 
2701 	ENTERFN();
2702 
2703 	/* Configuration required in ECC mode */
2704 	drp = msg_port_read(MEM_CTLR, DRP);
2705 	drp &= ~(BIT14 | BIT15);
2706 	drp |= BIT15;
2707 	drp |= BIT13;
2708 	msg_port_write(MEM_CTLR, DRP, drp);
2709 
2710 	/* Disable new request bypass */
2711 	dsch = msg_port_read(MEM_CTLR, DSCH);
2712 	dsch |= BIT12;
2713 	msg_port_write(MEM_CTLR, DSCH, dsch);
2714 
2715 	/* Enable ECC */
2716 	ecc_ctrl = (BIT0 | BIT1 | BIT17);
2717 	msg_port_write(MEM_CTLR, DECCCTRL, ecc_ctrl);
2718 
2719 	/* Assume 8 bank memory, one bank is gone for ECC */
2720 	mrc_params->mem_size -= mrc_params->mem_size / 8;
2721 
2722 	/* For S3 resume memory content has to be preserved */
2723 	if (mrc_params->boot_mode != BM_S3) {
2724 		select_hte();
2725 		hte_mem_init(mrc_params, MRC_MEM_INIT);
2726 		select_mem_mgr();
2727 	}
2728 
2729 	LEAVEFN();
2730 }
2731 
2732 /*
2733  * Execute memory test
2734  * if error detected it is indicated in mrc_params->status
2735  */
2736 void memory_test(struct mrc_params *mrc_params)
2737 {
2738 	uint32_t result = 0;
2739 
2740 	ENTERFN();
2741 
2742 	select_hte();
2743 	result = hte_mem_init(mrc_params, MRC_MEM_TEST);
2744 	select_mem_mgr();
2745 
2746 	DPF(D_INFO, "Memory test result %x\n", result);
2747 	mrc_params->status = ((result == 0) ? MRC_SUCCESS : MRC_E_MEMTEST);
2748 	LEAVEFN();
2749 }
2750 
2751 /* Lock MCU registers at the end of initialization sequence */
2752 void lock_registers(struct mrc_params *mrc_params)
2753 {
2754 	u32 dco;
2755 
2756 	ENTERFN();
2757 
2758 	dco = msg_port_read(MEM_CTLR, DCO);
2759 	dco &= ~(BIT28 | BIT29);
2760 	dco |= (BIT0 | BIT8);
2761 	msg_port_write(MEM_CTLR, DCO, dco);
2762 
2763 	LEAVEFN();
2764 }
2765