RD890 Northbridge: AMD RD890/SR56X0 Northbridge CIMX code
[coreboot.git] / src / vendorcode / amd / cimx / rd890 / nbPcieEarlyHwLib.c
1 /**
2  * @file
3  *
4  *  PCIe silicon specific functions library.
5  *
6  *
7  *
8  * @xrefitem bom "File Content Label" "Release Content"
9  * @e project:      CIMx-NB
10  * @e sub-project:
11  * @e \$Revision:$   @e \$Date:$
12  *
13  */
14 /*****************************************************************************
15  *
16  * Copyright (C) 2012 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 /*----------------------------------------------------------------------------------------
44  *                             M O D U L E S    U S E D
45  *----------------------------------------------------------------------------------------
46  */
47
48 #include "NbPlatform.h"
49 #include "HotplugFirmware.h"
50 /*----------------------------------------------------------------------------------------
51  *                   D E F I N I T I O N S    A N D    M A C R O S
52  *----------------------------------------------------------------------------------------
53  */
54
55 #define MCU_CLEAR_BLOCK_LENGTH  16
56
57 /*----------------------------------------------------------------------------------------
58  *                  T Y P E D E F S     A N D     S T R U C T U  R E S
59  *----------------------------------------------------------------------------------------
60  */
61
62
63 /*----------------------------------------------------------------------------------------
64  *           P R O T O T Y P E S     O F     L O C A L     F U  N C T I O N S
65  *----------------------------------------------------------------------------------------
66  */
67
68
69 /*----------------------------------------------------------------------------------------
70  *                          E X P O R T E D    F U N C T I O N S
71  *----------------------------------------------------------------------------------------
72  */
73
74 INDIRECT_REG_ENTRY
75 STATIC
76 PcieMiscInitTable[] = {
77   {
78     NB_MISC_REG20,
79     (UINT32)~BIT1,
80     0x0
81   }, //enable static device remapping by default
82   {
83     NB_MISC_REG22,
84     0xffffffff,
85     BIT27 | (0x8 << 12) | (0x8 << 16) | (0x8 << 20)
86   },
87   {
88     NB_MISC_REG2B,
89     0xffffffff,
90     (0x8 << 12)
91   },
92   {
93     NB_MISC_REG6C,
94     0xffffffff,
95     (0x8 << 16)
96   },
97   {
98     NB_MISC_REG6B,
99     0xffffffff,
100     (UINT32) (0x1f << 27)
101   }, //[13][12]Turn Off Offset Cancellation
102   {
103     NB_MISC_REG37,
104     (UINT32)~(BIT11 + BIT12 + BIT13),
105     0x0
106   }, //[14][13]Disables Rx Clock gating in CDR
107   {
108     NB_MISC_REG67,
109     (UINT32)~(BIT26 + BIT10 + BIT11),
110     BIT11
111   }, //[13]Disables Rx Clock gating in CDR
112      //[16]Sets Electrical  Idle Threshold
113   {
114     NB_MISC_REG2C,
115     (UINT32)~(BIT10),
116     0x0
117   }, //[13]Disables Rx Clock gating in CDR
118   {
119     NB_MISC_REG2A,
120     (UINT32)~(BIT17 + BIT16),
121     BIT17
122   }, //[16]Sets Electrical l Idle Threshold
123   {
124     NB_MISC_REG32,
125     (UINT32)~(0x3F << 20),
126     (UINT32) (0x2A << 20)
127   }  //[17][16]Sets Electrical Idle Threshold
128 };
129
130 /*----------------------------------------------------------------------------------------*/
131 /**
132  * Misc Initialization prior port training.
133  *
134  *
135  *
136  * @param[in] pConfig   Northbridge configuration structure pointer.
137  *
138  */
139
140 VOID
141 PcieLibPreTrainingInit (
142   IN      AMD_NB_CONFIG     *pConfig
143   )
144 {
145   UINT32      Value;
146   PCIE_CONFIG *pPcieConfig;
147   UINT32      ServerHotplugMask;
148   BOOLEAN     SmuWa;
149   CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibPreTrainingInit Enter\n"));
150   pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
151   ServerHotplugMask = 0;
152 //Init Misc registers
153   LibNbIndirectTableInit (
154     pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX,
155     0,
156     (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieMiscInitTable[0],NULL),
157     (sizeof (PcieMiscInitTable) / sizeof (INDIRECT_REG_ENTRY)),
158     pConfig
159     );
160 //Setup peer-to-peer
161   if (pPcieConfig->PcieConfiguration.Peer2Peer == ON) {
162     if (pPcieConfig->CoreConfiguration[PcieLibGetCoreId (3, pConfig)] == GFX_CONFIG_AABB) {
163       Value = 0x08080404;
164     } else {
165       Value = 0x08080008;
166     }
167     LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG49, AccessWidth32, 0, Value, pConfig);
168     if (pPcieConfig->CoreConfiguration[PcieLibGetCoreId (12, pConfig)] == GFX_CONFIG_AABB) {
169       Value = 0xFFFF0404;
170     } else {
171       Value = 0xFFFF0008;
172     }
173     LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG2F, AccessWidth32, 0, Value, pConfig);
174     LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG48, AccessWidth32, (UINT32)~(BIT8), 0xffff0000, pConfig);
175   }
176
177  //Remap device number
178 #ifndef DEVICE_REMAP_DISABLE
179   if (PciePortRemapInit (pConfig) != AGESA_SUCCESS ) {
180     REPORT_EVENT (AGESA_ERROR, PCIE_ERROR_DEVICE_REMAP, 0, 0, 0, 0, pConfig);
181   }
182 #endif
183
184 #ifndef HOTPLUG_SUPPORT_DISABLED
185   ServerHotplugMask = PcieInitHotplug (pConfig);
186 #endif
187
188   LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG4A, AccessWidth32, &Value, pConfig);
189   SmuWa = ((Value & BIT21) != 0) ? TRUE : FALSE;
190
191   if (SmuWa || ServerHotplugMask != 0) {
192     UINT32  BlockIndex;
193     UINT32  SmuWaData;
194     UINT16  Address;
195     UINT32  Data[MCU_CLEAR_BLOCK_LENGTH];
196
197     LibNbMcuControl (AssertReset, pConfig);
198     // clear SMU RAM
199     LibAmdMemFill (&Data[0], 0, sizeof (Data), (AMD_CONFIG_PARAMS *)&(pConfig->sHeader));
200     for (Address = 0; Address < (16 * 1024); Address = Address + 4 * MCU_CLEAR_BLOCK_LENGTH) {
201       LibNbLoadMcuFirmwareBlock (Address, MCU_CLEAR_BLOCK_LENGTH, &Data[0], pConfig);
202     }
203     //Load SMU firmware
204     for (BlockIndex = 0; BlockIndex < Fm.NumberOfBlock; BlockIndex++) {
205       LibNbLoadMcuFirmwareBlock (Fm.BlockArray[BlockIndex].Address, Fm.BlockArray[BlockIndex].Length, Fm.BlockArray[BlockIndex].Data, pConfig);
206     }
207     if (SmuWa) {
208       SmuWaData = LibHtGetSmuWaData (pConfig);
209       LibNbLoadMcuFirmwareBlock (0xFE70, 0x1, &SmuWaData, pConfig);
210     }
211     SmuWaData = ((SmuWa == TRUE) ? 0x100 : 0x100) | ((ServerHotplugMask != 0) ?  0x1 : 0);
212     LibNbLoadMcuFirmwareBlock (0xFE74, 0x1, &SmuWaData, pConfig);
213
214     LibNbMcuControl (DeAssertReset, pConfig);
215   }
216
217 #ifndef HOTPLUG_SUPPORT_DISABLED
218   PcieCheckHotplug (ServerHotplugMask, pConfig);
219 #endif
220
221 }
222
223 INDIRECT_REG_ENTRY  PcieCoreInitTable[] = {
224   {
225     NB_BIFNB_REG10,
226     (UINT32)~(BIT10 + BIT11 + BIT12),
227     BIT12
228   },
229   {
230     NB_BIFNB_REG20,
231     (UINT32)~(BIT8 + BIT9),
232     BIT9
233   },
234   {
235     NB_BIFNB_REG02,
236     (UINT32)~(BIT0),
237     BIT0
238   },
239   {
240     NB_BIFNB_REG40,
241     (UINT32)~(BIT14 + BIT15),
242     BIT15
243   },
244   {
245     NB_BIFNB_REGC2,
246     (UINT32)~(BIT25),
247     BIT25
248   },
249   {
250     NB_BIFNB_REGC1,
251     (UINT32)~(BIT0),
252     (BIT0 + BIT1 + BIT2)
253   },
254   {
255     NB_BIFNB_REG1C,
256     0x0,
257     (4 << 6) + (4 << 1) + 1
258   }
259 };
260
261 INDIRECT_REG_ENTRY  PcieRd790CoreInitTable[] = {
262   {
263     NB_BIFNB_REGC2,
264     (UINT32)~(BIT14),
265     (BIT14)
266   },
267   {
268     NB_BIFNB_REGC1,
269     (UINT32)~(BIT2),
270     0x0
271   },
272 };
273
274 /*----------------------------------------------------------------------------------------*/
275 /**
276  * Init Core registers
277  *
278  *
279  *
280  * @param[in] CoreId    PCI Express Core ID
281  * @param[in] pConfig   Northbridge configuration structure pointer.
282  */
283 VOID
284 PcieLibCommonCoreInit (
285   IN       CORE              CoreId,
286   IN       AMD_NB_CONFIG     *pConfig
287   )
288 {
289   UINT32  CoreAddress;
290   NB_INFO NbInfo;
291
292   CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCommonCoreInit (CoreId = %d) Enter\n", CoreId));
293   CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig);
294   NbInfo = LibNbGetRevisionInfo (pConfig);
295
296   LibNbIndirectTableInit (
297     pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX,
298     CoreAddress,
299     (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieCoreInitTable[0],NULL),
300     (sizeof (PcieCoreInitTable) / sizeof (INDIRECT_REG_ENTRY)),
301     pConfig
302     );
303
304   if (CoreAddress == SB_CORE) {
305     LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG10 | CoreAddress, AccessWidth32, (UINT32)~BIT9, BIT9, pConfig);
306     LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG06, AccessWidth32, (UINT32)~BIT26, BIT26 + BIT1, pConfig);
307     LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG1C | CoreAddress, AccessWidth32, (UINT32)~BIT0, 0x0, pConfig);
308   }
309   if ( NbInfo.Type < NB_SR5690 ) {
310     LibNbIndirectTableInit (
311       pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX,
312       CoreAddress,
313       (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieRd790CoreInitTable[0], NULL),
314       (sizeof (PcieRd790CoreInitTable) / sizeof (INDIRECT_REG_ENTRY)),
315       pConfig
316       );
317   }
318   CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCommonCoreInit Exit\n"));
319 };
320
321
322 /*----------------------------------------------------------------------------------------*/
323 /**
324  * Init Core after training is completed
325  *
326  *
327  *
328  * @param[in] CoreId    PCI Express Core ID
329  * @param[in] pConfig   Northbridge configuration structure pointer.  *
330  */
331
332
333 VOID
334 PcieLibCoreAfterTrainingInit (
335   IN       CORE              CoreId,
336   IN       AMD_NB_CONFIG     *pConfig
337   )
338 {
339   UINT32      CoreAddress;
340   PCIE_CONFIG *pPcieConfig;
341   PCI_ADDR    ClkPciAddress;
342
343   pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
344   CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig);
345   ClkPciAddress = pConfig->NbPciAddress;
346   ClkPciAddress.Address.Function = 1;
347   LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG20 | CoreAddress, AccessWidth32, (UINT32)~(BIT9), 0, pConfig);
348 //Save core setting in scratch register
349   LibNbPciIndexWrite (
350     pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX,
351     NB_BIFNB_REG01 | CoreAddress,
352     AccessWidth32,
353     (UINT32*)&pPcieConfig->CoreSetting[CoreId],
354     pConfig
355     );
356 //Save general setting in scratch
357   LibNbEnableClkConfig (pConfig);
358   LibNbPciWrite (ClkPciAddress.AddressValue | NB_CLK_REG78, AccessWidth32, &pPcieConfig->PcieConfiguration, pConfig);
359   LibNbDisableClkConfig (pConfig);
360
361 }
362
363
364 INDIRECT_REG_ENTRY  PciePortInitTable[] = {
365   {
366     NB_BIFNBP_REG02,
367     (UINT32)~(BIT15),
368     BIT15
369   },
370   {
371     NB_BIFNBP_REGA1,
372     (UINT32)~(BIT24 + BIT26),
373     BIT11
374   },
375   {
376     NB_BIFNBP_REGB1,
377     0xffffffff,
378     BIT28 + BIT23 + BIT19 + BIT20
379   },
380   {
381     NB_BIFNBP_REGA4,
382     (UINT32)~(BIT0),
383     0x0
384   },
385   {
386     NB_BIFNBP_REGA2,
387     (UINT32)~(BIT13),
388     BIT13
389   },
390   {
391     NB_BIFNBP_REGA3,
392     (UINT32)~(BIT9),
393     BIT9
394   },
395   {
396     NB_BIFNBP_REGA0,
397     0xffff000f,
398     0x6830
399   },
400   {
401     NB_BIFNBP_REGC1,
402     0xfffffff0,
403     0xC
404   },
405   {
406     NB_BIFNBP_REG70,
407     (UINT32)~(BIT16 + BIT17 + BIT18),
408     BIT16 + BIT18
409   }
410 };
411 /*----------------------------------------------------------------------------------------*/
412 /**
413  * Init port registers
414  *
415  *
416  *
417  * @param[in] PortId    PCI Express Port ID
418  * @param[in] pConfig   Northbridge configuration structure pointer.
419  *
420  */
421 VOID
422 PcieLibCommonPortInit (
423   IN       PORT              PortId,
424   IN       AMD_NB_CONFIG     *pConfig
425   )
426 {
427   PCI_ADDR    Port;
428   PCIE_CONFIG *pPcieConfig;
429   UINT32      PcieSlotCapability;
430   UINT32      CoreAddress;
431
432   CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCommonPortInit PortId %d Enter\n", PortId));
433   Port = PcieLibGetPortPciAddress (PortId, pConfig);
434   CoreAddress = PcieLibGetCoreAddress (PcieLibGetCoreId (PortId, pConfig), pConfig);
435   pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig);
436
437   LibNbIndirectTableInit (
438     Port.AddressValue | NB_BIF_INDEX,
439     0x0,
440     (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PciePortInitTable[0],NULL),
441     (sizeof (PciePortInitTable) / sizeof (INDIRECT_REG_ENTRY)),
442     pConfig
443     );
444   if (CoreAddress == GPP3a_CORE || CoreAddress == SB_CORE || CoreAddress == GPP3b_CORE) {
445     LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG70, AccessWidth32, (UINT32)~(BIT16 + BIT17 + BIT18), (BIT17 + BIT18), pConfig);
446     if (CoreAddress == GPP3a_CORE) {
447       LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGB1, AccessWidth32, (UINT32)~(BIT22), BIT22, pConfig);
448     }
449   }
450 // Set completion timeout
451   LibNbPciRMW (Port.AddressValue | NB_PCIP_REG80, AccessS3SaveWidth8, 0xF0, 0x6, pConfig);
452   //if (CoreAddress != SB_CORE) {
453   //  LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG10, AccessWidth32, (UINT32)~BIT0, 0x0, pConfig);
454   //}
455 //For hotplug ports
456   //if (pPcieConfig->PortConfiguration[PortId].PortHotplug != OFF ||
457   //    pPcieConfig->PcieConfiguration.DisableHideUnusedPorts == ON ||
458   //    LibNbGetRevisionInfo (pConfig).Revision == NB_REV_A11) {
459   LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG20, AccessWidth32, (UINT32)~BIT19, 0x0, pConfig);
460   //}
461
462 // Enable Immediate ACK
463   if (pPcieConfig->ExtPortConfiguration[PortId].PortL1ImmediateACK == ON) {
464     LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA0, AccessWidth32, (UINT32)~BIT23, BIT23, pConfig);
465   }
466 //Set up slot capability
467   PcieSlotCapability = (pPcieConfig->ExtPortConfiguration[PortId].PortPowerLimit << 7) |
468                        ((Port.Address.Device | Port.Address.Bus << 5 ) << 19);
469   LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessS3SaveWidth32, (UINT32)~((0x3ff << 7) | (0x1fff << 19)), PcieSlotCapability, pConfig);
470   LibNbPciRMW (Port.AddressValue | NB_PCIP_REG5A, AccessS3SaveWidth16, (UINT32)~BIT8, BIT8, pConfig);
471 //Set interrupt pin info
472   LibNbPciRMW (Port.AddressValue | NB_PCIP_REG3D, AccessS3SaveWidth8, 0x0, 0x1, pConfig);
473
474   CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCommonPortInit Exit\n"));
475 };