1 /* $NoKeywords:$ */
2 /**
3 * @file
4 *
5 * FCH IMC lib
6 *
7 *
8 *
9 * @xrefitem bom "File Content Label" "Release Content"
10 * @e project: AGESA
11 * @e sub-project: FCH
12 * @e \$Revision: 87213 $ @e \$Date: 2013-01-30 15:37:54 -0600 (Wed, 30 Jan 2013) $
13 *
14 */
15 /*
16 *****************************************************************************
17 *
18 * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc.
19 * All rights reserved.
20 *
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions are met:
23 * * Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * * Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
29 * its contributors may be used to endorse or promote products derived
30 * from this software without specific prior written permission.
31 *
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
36 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 ****************************************************************************
43 */
44 #include "FchPlatform.h"
45 #include "Filecode.h"
46 #define FILECODE PROC_FCH_IMC_IMCLIB_FILECODE
47
48 /**
49 * WriteECmsg
50 *
51 *
52 *
53 * @param[in] Address - Address
54 * @param[in] OpFlag - Access width
55 * @param[in] *Value - Out Value pointer
56 * @param[in] StdHeader
57 *
58 */
59 VOID
WriteECmsg(IN UINT8 Address,IN UINT8 OpFlag,IN VOID * Value,IN AMD_CONFIG_PARAMS * StdHeader)60 WriteECmsg (
61 IN UINT8 Address,
62 IN UINT8 OpFlag,
63 IN VOID *Value,
64 IN AMD_CONFIG_PARAMS *StdHeader
65 )
66 {
67 UINT8 Index;
68
69 ASSERT (OpFlag < AccessWidth64); /* TODO: Add the assertion to make it not crash for now. */
70 OpFlag = (OpFlag & 0x7f) - 1;
71 if (OpFlag == 0x02) {
72 OpFlag = 0x03;
73 }
74
75 for (Index = 0; Index <= OpFlag; Index++) {
76 /// EC_LDN9_MAILBOX_BASE_ADDRESS
77 LibAmdIoWrite (AccessWidth8, MailBoxPort, &Address, StdHeader);
78 Address++;
79 /// EC_LDN9_MAILBOX_BASE_ADDRESS
80 LibAmdIoWrite (AccessWidth8, MailBoxPort + 1, (UINT8 *)Value + Index, StdHeader);
81 }
82 }
83
84 /**
85 * ReadECmsg
86 *
87 *
88 *
89 * @param[in] Address - Address
90 * @param[in] OpFlag - Access width
91 * @param[out] *Value - Out Value pointer
92 * @param[in] StdHeader
93 *
94 */
95 VOID
ReadECmsg(IN UINT8 Address,IN UINT8 OpFlag,OUT VOID * Value,IN AMD_CONFIG_PARAMS * StdHeader)96 ReadECmsg (
97 IN UINT8 Address,
98 IN UINT8 OpFlag,
99 OUT VOID *Value,
100 IN AMD_CONFIG_PARAMS *StdHeader
101 )
102 {
103 UINT8 Index;
104
105 ASSERT (OpFlag < AccessWidth64); /* TODO: Add the assertion to make it not crash for now. */
106 OpFlag = (OpFlag & 0x7f) - 1;
107 if (OpFlag == 0x02) {
108 OpFlag = 0x03;
109 }
110
111 for (Index = 0; Index <= OpFlag; Index++) {
112 /// EC_LDN9_MAILBOX_BASE_ADDRESS
113 LibAmdIoWrite (AccessWidth8, MailBoxPort, &Address, StdHeader);
114 Address++;
115 /// EC_LDN9_MAILBOX_BASE_ADDRESS
116 LibAmdIoRead (AccessWidth8, MailBoxPort + 1, (UINT8 *)Value + Index, StdHeader);
117 }
118 }
119
120 /**
121 * WaitForEcLDN9MailboxCmdAck
122 *
123 *
124 * @param[in] StdHeader
125 *
126 */
127 VOID
WaitForEcLDN9MailboxCmdAck(IN AMD_CONFIG_PARAMS * StdHeader)128 WaitForEcLDN9MailboxCmdAck (
129 IN AMD_CONFIG_PARAMS *StdHeader
130 )
131 {
132 UINT8 Msgdata;
133 UINT16 Delaytime;
134
135 Msgdata = 0;
136
137 for (Delaytime = 0; Delaytime < 0xFFFF; Delaytime++) {
138 ReadECmsg (MSG_REG0, AccessWidth8, &Msgdata, StdHeader);
139 if ( Msgdata == 0xfa) {
140 break;
141 }
142
143 FchStall (5, StdHeader); /// Wait for 1ms
144 }
145 }
146
147 /**
148 * ImcSleep - IMC Sleep.
149 *
150 *
151 * @param[in] FchDataPtr Fch configuration structure pointer.
152 *
153 */
154 VOID
ImcSleep(IN VOID * FchDataPtr)155 ImcSleep (
156 IN VOID *FchDataPtr
157 )
158 {
159 UINT8 Msgdata;
160 FCH_DATA_BLOCK *LocalCfgPtr;
161 AMD_CONFIG_PARAMS *StdHeader;
162
163 LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr;
164 StdHeader = LocalCfgPtr->StdHeader;
165
166 if (!(IsImcEnabled (StdHeader)) ) {
167 return; ///IMC is not enabled
168 }
169
170 Msgdata = 0x00;
171 WriteECmsg (MSG_REG0, AccessWidth8, &Msgdata, StdHeader);
172 Msgdata = 0xB4;
173 WriteECmsg (MSG_REG1, AccessWidth8, &Msgdata, StdHeader);
174 Msgdata = 0x00;
175 WriteECmsg (MSG_REG2, AccessWidth8, &Msgdata, StdHeader);
176 Msgdata = 0x96;
177 WriteECmsg (MSG_SYS_TO_IMC, AccessWidth8, &Msgdata, StdHeader);
178 WaitForEcLDN9MailboxCmdAck (StdHeader);
179 }
180
181 /**
182 * SoftwareDisableImc - Software disable IMC strap
183 *
184 *
185 * @param[in] FchDataPtr Fch configuration structure pointer.
186 *
187 */
188 VOID
SoftwareDisableImc(IN VOID * FchDataPtr)189 SoftwareDisableImc (
190 IN VOID *FchDataPtr
191 )
192 {
193 UINT8 ValueByte;
194 UINT8 PortStatusByte;
195 UINT32 AbValue;
196 UINT32 ABStrapOverrideReg;
197 AMD_CONFIG_PARAMS *StdHeader;
198
199 StdHeader = ((FCH_DATA_BLOCK *) FchDataPtr)->StdHeader;
200 GetChipSysMode (&PortStatusByte, StdHeader);
201
202 RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGC8 + 3, AccessWidth8, 0x7F, BIT7, StdHeader);
203 ReadPmio (0xBF, AccessWidth8, &ValueByte, StdHeader);
204
205 ReadMem ((ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG80), AccessWidth32, &AbValue);
206 ABStrapOverrideReg = AbValue;
207 ABStrapOverrideReg &= ~BIT2; // bit2=0 EcEnableStrap
208 WriteMem ((ACPI_MMIO_BASE + MISC_BASE + 0x84), AccessWidth32, &ABStrapOverrideReg);
209
210 ReadPmio (FCH_PMIOA_REGD7, AccessWidth8, &ValueByte, StdHeader);
211 ValueByte |= BIT1;
212 WritePmio (FCH_PMIOA_REGD7, AccessWidth8, &ValueByte, StdHeader);
213
214 ValueByte = 06;
215 LibAmdIoWrite (AccessWidth8, 0xcf9, &ValueByte, StdHeader);
216 FchStall (0xffffffff, StdHeader);
217 }
218
219 /**
220 * ImcDisableSurebootTimer - IMC Disable Sureboot Timer.
221 *
222 *
223 * @param[in] FchDataPtr Fch configuration structure pointer.
224 *
225 */
226 VOID
ImcDisableSurebootTimer(IN VOID * FchDataPtr)227 ImcDisableSurebootTimer (
228 IN VOID *FchDataPtr
229 )
230 {
231 UINT8 Msgdata;
232 AMD_CONFIG_PARAMS *StdHeader;
233
234 StdHeader = ((FCH_DATA_BLOCK *) FchDataPtr)->StdHeader;
235
236 if (!(IsImcEnabled (StdHeader)) ) {
237 return; ///IMC is not enabled
238 }
239
240 ImcWakeup (FchDataPtr);
241 Msgdata = 0x00;
242 WriteECmsg (MSG_REG0, AccessWidth8, &Msgdata, StdHeader);
243 Msgdata = 0x01;
244 WriteECmsg (MSG_REG1, AccessWidth8, &Msgdata, StdHeader);
245 Msgdata = 0x00;
246 WriteECmsg (MSG_REG2, AccessWidth8, &Msgdata, StdHeader);
247 Msgdata = 0x94;
248 WriteECmsg (MSG_SYS_TO_IMC, AccessWidth8, &Msgdata, StdHeader);
249 WaitForEcLDN9MailboxCmdAck (StdHeader);
250 ImcSleep (FchDataPtr);
251 }
252
253 /**
254 * ImcWakeup - IMC Wakeup.
255 *
256 *
257 * @param[in] FchDataPtr Fch configuration structure pointer.
258 *
259 */
260 VOID
ImcWakeup(IN VOID * FchDataPtr)261 ImcWakeup (
262 IN VOID *FchDataPtr
263 )
264 {
265 UINT8 Msgdata;
266 AMD_CONFIG_PARAMS *StdHeader;
267
268 StdHeader = ((FCH_DATA_BLOCK *) FchDataPtr)->StdHeader;
269 if (!(IsImcEnabled (StdHeader)) ) {
270 return; ///IMC is not enabled
271 }
272
273 Msgdata = 0x00;
274 WriteECmsg (MSG_REG0, AccessWidth8, &Msgdata, StdHeader);
275 Msgdata = 0xB5;
276 WriteECmsg (MSG_REG1, AccessWidth8, &Msgdata, StdHeader);
277 Msgdata = 0x00;
278 WriteECmsg (MSG_REG2, AccessWidth8, &Msgdata, StdHeader);
279 Msgdata = 0x96;
280 WriteECmsg (MSG_SYS_TO_IMC, AccessWidth8, &Msgdata, StdHeader);
281 WaitForEcLDN9MailboxCmdAck (StdHeader);
282 }
283
284 /**
285 * ImcIdle - IMC Idle.
286 *
287 *
288 * @param[in] FchDataPtr Fch configuration structure pointer.
289 *
290 */
291 VOID
ImcIdle(IN VOID * FchDataPtr)292 ImcIdle (
293 IN VOID *FchDataPtr
294 )
295 {
296 UINT8 Msgdata;
297 AMD_CONFIG_PARAMS *StdHeader;
298
299 StdHeader = ((FCH_DATA_BLOCK *) FchDataPtr)->StdHeader;
300
301 if (!(IsImcEnabled (StdHeader)) ) {
302 return; ///IMC is not enabled
303 }
304
305 Msgdata = 0x00;
306 WriteECmsg (MSG_REG0, AccessWidth8, &Msgdata, StdHeader);
307 Msgdata = 0x01;
308 WriteECmsg (MSG_REG1, AccessWidth8, &Msgdata, StdHeader);
309 Msgdata = 0x00;
310 WriteECmsg (MSG_REG2, AccessWidth8, &Msgdata, StdHeader);
311 Msgdata = 0x98;
312 WriteECmsg (MSG_SYS_TO_IMC, AccessWidth8, &Msgdata, StdHeader);
313 WaitForEcLDN9MailboxCmdAck (StdHeader);
314 }
315