DDR3 support for AMD Fam10.
[coreboot.git] / src / northbridge / amd / amdmct / mct_ddr3 / mctsrc2p.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2010 Advanced Micro Devices, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
19  */
20
21 u8 mct_checkNumberOfDqsRcvEn_Pass(u8 pass)
22 {
23         return 1;
24 }
25
26 u32 SetupDqsPattern_PassA(u8 Pass)
27 {
28         u32 ret;
29         if(Pass == FirstPass)
30                 ret = (u32) TestPattern1_D;
31         else
32                 ret = (u32) TestPattern2_D;
33
34         return ret;
35 }
36
37 u32 SetupDqsPattern_PassB(u8 Pass)
38 {
39         u32 ret;
40         if(Pass == FirstPass)
41                 ret = (u32) TestPattern0_D;
42         else
43                 ret = (u32) TestPattern2_D;
44
45         return ret;
46 }
47
48 u8 mct_Get_Start_RcvrEnDly_Pass(struct DCTStatStruc *pDCTstat,
49                                         u8 Channel, u8 Receiver,
50                                         u8 Pass)
51 {
52         u8 RcvrEnDly;
53
54         if (Pass == FirstPass)
55                 RcvrEnDly = 0;
56         else {
57                 u8 max = 0;
58                 u8 val;
59                 u8 i;
60                 u8 *p = pDCTstat->CH_D_B_RCVRDLY[Channel][Receiver>>1];
61                 u8 bn;
62                 bn = 8;
63
64                 for ( i=0;i<bn; i++) {
65                         val  = p[i];
66
67                         if(val > max) {
68                                 max = val;
69                         }
70                 }
71                 RcvrEnDly = max;
72         }
73
74         return RcvrEnDly;
75 }
76
77 u8 mct_Average_RcvrEnDly_Pass(struct DCTStatStruc *pDCTstat,
78                                 u8 RcvrEnDly, u8 RcvrEnDlyLimit,
79                                 u8 Channel, u8 Receiver, u8 Pass)
80 {
81         u8 i;
82         u8 *p;
83         u8 *p_1;
84         u8 val;
85         u8 val_1;
86         u8 valid = 1;
87         u8 bn;
88
89         bn = 8;
90
91         p = pDCTstat->CH_D_B_RCVRDLY[Channel][Receiver>>1];
92
93         if (Pass == SecondPass) { /* second pass must average values */
94                 /* FIXME: which byte? */
95                 p_1 = pDCTstat->B_RCVRDLY_1;
96                 /* p_1 = pDCTstat->CH_D_B_RCVRDLY_1[Channel][Receiver>>1]; */
97                 for(i=0; i<bn; i++) {
98                         val = p[i];
99                         /* left edge */
100                         if (val != (RcvrEnDlyLimit - 1)) {
101                                 val -= Pass1MemClkDly;
102                                 val_1 = p_1[i];
103                                 val += val_1;
104                                 val >>= 1;
105                                 p[i] = val;
106                         } else {
107                                 valid = 0;
108                                 break;
109                         }
110                 }
111                 if (!valid) {
112                         pDCTstat->ErrStatus |= 1<<SB_NORCVREN;
113                 } else {
114                         pDCTstat->DimmTrainFail &= ~(1<<(Receiver + Channel));
115                 }
116         } else {
117                 for(i=0; i < bn; i++) {
118                         val = p[i];
119                         /* Add 1/2 Memlock delay */
120                         /* val += Pass1MemClkDly; */
121                         val += 0x5; /* NOTE: middle value with DQSRCVEN_SAVED_GOOD_TIMES */
122                         /* val += 0x02; */
123                         p[i] = val;
124                         pDCTstat->DimmTrainFail &= ~(1<<(Receiver + Channel));
125                 }
126         }
127
128         return RcvrEnDly;
129 }