sigh
[coreboot.git] / src / vendorcode / amd / cimx / sb900 / SbPeLib.c
1 /**
2  * @file
3  *
4  * Southbridge IO access common routine
5  *
6  *
7  *
8  * @xrefitem bom "File Content Label" "Release Content"
9  * @e project:      CIMx-SB
10  * @e sub-project:
11  * @e \$Revision:$   @e \$Date:$
12  *
13  */
14 /*;********************************************************************************
15 ;
16 ; Copyright (c) 2011, Advanced Micro Devices, Inc.
17 ; All rights reserved.
18
19 ; Redistribution and use in source and binary forms, with or without
20 ; modification, are permitted provided that the following conditions are met:
21 ;     * Redistributions of source code must retain the above copyright
22 ;       notice, this list of conditions and the following disclaimer.
23 ;     * Redistributions in binary form must reproduce the above copyright
24 ;       notice, this list of conditions and the following disclaimer in the
25 ;       documentation and/or other materials provided with the distribution.
26 ;     * Neither the name of Advanced Micro Devices, Inc. nor the names of 
27 ;       its contributors may be used to endorse or promote products derived 
28 ;       from this software without specific prior written permission.
29
30 ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
31 ; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 ; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33 ; DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
34 ; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35 ; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36 ; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37 ; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39 ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40
41 ;*********************************************************************************/
42
43 #include "SbPlatform.h"
44 #include "cbtypes.h"
45 #include "AmdSbLib.h"
46
47 /**
48  * Read Southbridge Revision ID cie Base
49  *
50  *
51  * @retval  0xXXXXXXXX   Revision ID
52  *
53  */
54 UINT8
55 getRevisionID (
56   OUT VOID
57   )
58 {
59   UINT8  dbVar0;
60   ReadPCI (((SMBUS_BUS_DEV_FUN << 16) + SB_CFG_REG08), AccWidthUint8, &dbVar0);
61   return dbVar0;
62 }
63
64 /**
65  * Is SB A11?
66  *
67  *
68  * @retval  TRUE or FALSE
69  *
70  */
71 BOOLEAN
72 IsSbA11 (
73   OUT VOID
74   )
75 {
76   return ( getRevisionID () == AMD_SB_A11 );
77 }
78
79 /**
80  * Is SB A12?
81  *
82  *
83  * @retval  TRUE or FALSE
84  *
85  */
86 BOOLEAN
87 IsSbA12 (
88   OUT VOID
89   )
90 {
91   return ( getRevisionID () == AMD_SB_A12 );
92 }
93
94 /**
95  * Is SB A12 Plus?
96  *
97  *
98  * @retval  TRUE or FALSE
99  *
100  */
101 BOOLEAN
102 IsSbA12Plus (
103   OUT VOID
104   )
105 {
106   return ( getRevisionID () >= AMD_SB_A12 );
107 }
108
109 /**
110  * Is SB A13 Plus?
111  *
112  *
113  * @retval  TRUE or FALSE
114  *
115  */
116 BOOLEAN
117 IsSbA13Plus (
118   OUT VOID
119   )
120 {
121   return ( getRevisionID () >= AMD_SB_A13 );
122 }
123
124 /**
125  * Is External Clock Mode?
126  *
127  *
128  * @retval  TRUE or FALSE
129  *
130  */
131 BOOLEAN
132 IsExternalClockMode (
133   OUT VOID
134   )
135 {
136   return ( (BOOLEAN) ((ACPIMMIO32 (ACPI_MMIO_BASE + MISC_BASE + SB_MISC_REG80) & BIT4) == 0) );
137 }
138
139 /**
140  * Is LPC Rom?
141  *
142  *
143  * @retval  TRUE or FALSE
144  *
145  */
146 BOOLEAN
147 IsLpcRom (
148   OUT VOID
149   )
150 {
151   return ( (BOOLEAN) ((ACPIMMIO32 (ACPI_MMIO_BASE + MISC_BASE + SB_MISC_REG80) & BIT1) == 0) );
152 }
153
154 /**
155  * Memory Copy
156  *
157  *
158  * @retval  VOID
159  *
160  */
161 VOID
162 MemoryCopy (
163   IN       UINT8 *Dest,
164   IN       UINT8 *Source,
165   IN       UINTN Size
166   )
167 {
168   UINTN i;
169   for ( i = 0; i < Size; i++  ) {
170     *Dest = *Source;
171     Dest++;
172     Source++;
173   }
174 }
175
176 /*----------------------------------------------------------------------------------------*/
177 /**
178  * programPciByteTable - Program PCI register by table (8 bits data)
179  *
180  *
181  *
182  * @param[in] pPciByteTable    - Table data pointer
183  * @param[in] dwTableSize      - Table length
184  *
185  */
186 VOID
187 programPciByteTable (
188   IN       REG8MASK* pPciByteTable,
189   IN       UINT16 dwTableSize
190   )
191 {
192   UINT8  i;
193   UINT8  dbBusNo;
194   UINT8  dbDevFnNo;
195   UINT32  ddBDFR;
196
197   dbBusNo = pPciByteTable->bRegIndex;
198   dbDevFnNo = pPciByteTable->bANDMask;
199   pPciByteTable++;
200
201   for ( i = 1; i < dwTableSize; i++ ) {
202     if ( (pPciByteTable->bRegIndex == 0xFF) && (pPciByteTable->bANDMask == 0xFF) && (pPciByteTable->bORMask == 0xFF) ) {
203       pPciByteTable++;
204       dbBusNo = pPciByteTable->bRegIndex;
205       dbDevFnNo = pPciByteTable->bANDMask;
206       pPciByteTable++;
207       i++;
208     } else {
209       ddBDFR = (dbBusNo << 24) + (dbDevFnNo << 16) + (pPciByteTable->bRegIndex) ;
210       TRACE ((DMSG_SB_TRACE, "PFA = %X  AND = %X, OR = %X", ddBDFR, pPciByteTable->bANDMask, pPciByteTable->bORMask));
211       RWPCI (ddBDFR, AccWidthUint8 | S3_SAVE, pPciByteTable->bANDMask, pPciByteTable->bORMask);
212       pPciByteTable++;
213     }
214   }
215 }
216
217 /*----------------------------------------------------------------------------------------*/
218 /**
219  * programSbAcpiMmioTbl - Program SB ACPI MMIO register by table (8 bits data)
220  *
221  *
222  *
223  * @param[in] pAcpiTbl   - Table data pointer
224  *
225  */
226 VOID
227 programSbAcpiMmioTbl (
228   IN       AcpiRegWrite *pAcpiTbl
229   )
230 {
231   UINT8 i;
232   UINT32 ddtempVar;
233   if (pAcpiTbl != NULL) {
234     if ((pAcpiTbl->MmioReg == 0) && (pAcpiTbl->MmioBase == 0) && (pAcpiTbl->DataANDMask == 0xB0) && (pAcpiTbl->DataOrMask == 0xAC)) {
235       // Signature Checking
236       pAcpiTbl++;
237       for ( i = 1; pAcpiTbl->MmioBase < 0x1D; i++ ) {
238         ddtempVar = 0xFED80000 | (pAcpiTbl->MmioBase) << 8 | pAcpiTbl->MmioReg;
239         RWMEM (ddtempVar, AccWidthUint8, ((pAcpiTbl->DataANDMask) | 0xFFFFFF00), pAcpiTbl->DataOrMask);
240         pAcpiTbl++;
241       }
242     }
243   }
244 }
245
246 /**
247  * getChipSysMode - Get Chip status
248  *
249  *
250  * @param[in] Value - Return Chip strap status
251  *   StrapStatus [15.0] - Hudson-2 chip Strap Status
252  *    @li <b>0001</b> - Not USED FWH
253  *    @li <b>0002</b> - Not USED LPC ROM
254  *    @li <b>0004</b> - EC enabled
255  *    @li <b>0008</b> - Reserved
256  *    @li <b>0010</b> - Internal Clock mode
257  *
258  */
259 VOID
260 getChipSysMode (
261   IN       VOID* Value
262   )
263 {
264   ReadMEM (ACPI_MMIO_BASE + MISC_BASE + SB_MISC_REG80, AccWidthUint8, Value);
265 }
266
267 /**
268  * isImcEnabled - Is IMC Enabled
269  * @retval  TRUE for IMC Enabled; FALSE for IMC Disabled
270  */
271 BOOLEAN
272 isImcEnabled (
273   )
274 {
275   UINT8   dbSysConfig;
276   getChipSysMode (&dbSysConfig);
277   if (dbSysConfig & ChipSysEcEnable) {
278     return TRUE;
279   } else {
280     return FALSE;
281   }
282 }
283
284 /*----------------------------------------------------------------------------------------*/
285 /**
286  * Read Southbridge CIMx configuration structure pointer
287  *
288  *
289  *
290  * @retval  0xXXXXXXXX   CIMx configuration structure pointer.
291  *
292  */
293 AMDSBCFG*
294 getConfigPointer (
295   OUT VOID
296   )
297 {
298   UINT8  dbReg;
299   UINT8  dbValue;
300   UINT8  i;
301   UINT32  ddValue;
302   ddValue = 0;
303   dbReg = SB_ECMOS_REG08;
304
305   for ( i = 0; i <= 3; i++ ) {
306     WriteIO (SB_IOMAP_REG72, AccWidthUint8, &dbReg);
307     ReadIO (SB_IOMAP_REG73, AccWidthUint8, &dbValue);
308     ddValue |= (dbValue << (i * 8));
309     dbReg++;
310   }
311   return ( (AMDSBCFG*) (UINTN)ddValue);
312 }
313
314 /**
315  * getEfuseStatue - Get Efuse status
316  *
317  *
318  * @param[in] Value - Return Chip strap status
319  *
320  */
321 VOID
322 getEfuseStatus (
323   IN       VOID* Value
324   )
325 {
326   RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGC8, AccWidthUint8, ~BIT5, BIT5);
327   WriteMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGD8, AccWidthUint8, Value);
328   ReadMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGD8 + 1, AccWidthUint8, Value);
329   RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGC8, AccWidthUint8, ~BIT5, 0);
330 }
331
332 /**
333  * getEfuseByte - Get Efuse Byte
334  *
335  *
336  * @param[in] Index - Efuse Index value
337  *
338  */
339 UINT8
340 getEfuseByte (
341   IN       UINT8 Index
342   )
343 {
344   UINT8 Data;
345   WriteMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGD8, AccWidthUint8, &Index);
346   ReadMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGD8 + 1, AccWidthUint8, &Data);
347   return Data;
348 }
349
350
351 /**
352  * SbResetGppDevice - Toggle GEVENT4 to assert/deassert GPP device reset
353  *
354  *
355  * @param[in] ResetBlock - PCIE reset for SB GPP or NB PCIE
356  * @param[in] ResetOp    - Assert or deassert PCIE reset
357  *
358  */
359 VOID
360 SbResetPcie (
361   IN       RESET_BLOCK  ResetBlock,
362   IN       RESET_OP     ResetOp
363   )
364 {
365
366   if (ResetBlock == NbBlock) {
367     if (ResetOp == AssertReset) {
368       RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGC4, AccWidthUint8, 0xFF, BIT4);
369     } else if (ResetOp == DeassertReset) {
370       RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGC4, AccWidthUint8, ~BIT4, 0);
371     }
372   } else if (ResetBlock == SbBlock) {
373     RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + SB_GEVENT_REG04, AccWidthUint8, ~(BIT1 + BIT0), 0x02);
374     if (ResetOp == AssertReset) {
375       RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GEVENT_REG04, AccWidthUint8, ~BIT5, 0);
376       RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGBF, AccWidthUint8, 0xFF, BIT4);
377     } else if (ResetOp == DeassertReset) {
378       RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGBF, AccWidthUint8, ~BIT4, 0);
379       RWMEM (ACPI_MMIO_BASE + GPIO_BASE + SB_GEVENT_REG04, AccWidthUint8, 0xff, BIT5);
380     }
381   }
382 }
383
384
385 /**
386  * sbGppTogglePcieReset - Toggle PCIE_RST2#
387  *
388  *
389  * @param[in] pConfig
390  *
391  */
392 VOID
393 sbGppTogglePcieReset (
394   IN     AMDSBCFG*   pConfig
395   )
396 {
397   if (pConfig->GppToggleReset) {
398     SbResetPcie (SbBlock, AssertReset);
399     SbStall (500);
400     SbResetPcie (SbBlock, DeassertReset);
401   }
402 }
403
404 /**
405  * sbSpiUnlock - Sb SPI Unlock
406  *
407  *
408  * @param[in] pConfig
409  *
410  */
411 VOID
412 sbSpiUnlock (
413   IN     AMDSBCFG*   pConfig
414   )
415 {
416   RWPCI ((LPC_BUS_DEV_FUN << 16) + SB_LPC_REG50, AccWidthUint32, ~(BIT0 + BIT1), 0);
417   RWPCI ((LPC_BUS_DEV_FUN << 16) + SB_LPC_REG54, AccWidthUint32, ~(BIT0 + BIT1), 0);
418   RWPCI ((LPC_BUS_DEV_FUN << 16) + SB_LPC_REG58, AccWidthUint32, ~(BIT0 + BIT1), 0);
419   RWPCI ((LPC_BUS_DEV_FUN << 16) + SB_LPC_REG5C, AccWidthUint32, ~(BIT0 + BIT1), 0);
420   RWMEM ((pConfig->BuildParameters.SpiRomBaseAddress) + SB_SPI_MMIO_REG00, AccWidthUint32, ~(BIT22 + BIT23), (BIT22 + BIT23));
421 }
422
423 /**
424  * sbSpilock - Sb SPI lock
425  *
426  *
427  * @param[in] pConfig
428  *
429  */
430 VOID
431 sbSpilock (
432   IN     AMDSBCFG*   pConfig
433   )
434 {
435   RWPCI ((LPC_BUS_DEV_FUN << 16) + SB_LPC_REG50, AccWidthUint32, ~(BIT0 + BIT1), (BIT0 + BIT1));
436   RWPCI ((LPC_BUS_DEV_FUN << 16) + SB_LPC_REG54, AccWidthUint32, ~(BIT0 + BIT1), (BIT0 + BIT1));
437   RWPCI ((LPC_BUS_DEV_FUN << 16) + SB_LPC_REG58, AccWidthUint32, ~(BIT0 + BIT1), (BIT0 + BIT1));
438   RWPCI ((LPC_BUS_DEV_FUN << 16) + SB_LPC_REG5C, AccWidthUint32, ~(BIT0 + BIT1), (BIT0 + BIT1));
439   RWMEM ((pConfig->BuildParameters.SpiRomBaseAddress) + SB_SPI_MMIO_REG00, AccWidthUint32, ~(BIT22 + BIT23), 0);
440 }
441
442 /**
443  * TurnOffCG2
444  *
445  *
446  * @retval  VOID
447  *
448  */
449 VOID
450 TurnOffCG2 (
451   OUT VOID
452   )
453 {
454   RWMEM (ACPI_MMIO_BASE + MISC_BASE + 0x40, AccWidthUint8, ~BIT6, 0);
455   RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGDA, AccWidthUint8, 0x0F, 0xA0);
456   RWMEM (ACPI_MMIO_BASE + IOMUX_BASE + 0x41, AccWidthUint8, ~(BIT1 + BIT0), (BIT1 + BIT0));
457   RWMEM (ACPI_MMIO_BASE + MISC_BASE + 0x41, AccWidthUint8, ~( BIT4), (BIT4));
458   RWMEM (ACPI_MMIO_BASE + MISC_BASE + 0x41, AccWidthUint8, ~(BIT6), (BIT6));
459   RWMEM (ACPI_MMIO_BASE + MISC_BASE + 0x08, AccWidthUint8, ~BIT6, BIT6);
460   RWMEM (ACPI_MMIO_BASE + MISC_BASE + 0x1C, AccWidthUint8, ~BIT6, BIT6);
461 }
462
463 /**
464  * BackUpCG2
465  *
466  *
467  * @retval  VOID
468  *
469  */
470 VOID
471 BackUpCG2 (
472   OUT VOID
473   )
474 {
475   UINT8 dByte;
476   ReadMEM (ACPI_MMIO_BASE + MISC_BASE + 0x1C, AccWidthUint8, &dByte);
477   if (dByte & BIT6) {
478     RWMEM (ACPI_MMIO_BASE + MISC_BASE + 0x41, AccWidthUint8, ~(BIT6), (0));
479   }
480 }