ARM: tegra: colibri_t20: fix nand pinmux
[platform/kernel/u-boot.git] / arch / x86 / cpu / quark / smc.c
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 }