sigh
[coreboot.git] / src / vendorcode / amd / cimx / sb900 / Usb.c
1 /**
2  * @file
3  *
4  * Config Southbridge USB controller
5  *
6  * Init USB features.
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 #include "SbPlatform.h"
43 #include "cbtypes.h"
44 #include "AmdSbLib.h"
45 #include "Hudson-2.h"
46
47 //
48 // Declaration of local functions
49 //
50 VOID
51 usbOverCurrentControl (
52   IN       AMDSBCFG* pConfig
53   );
54
55 UINT32
56 SetEhciPllWr (
57   IN       UINT32 Value,
58   IN       AMDSBCFG* pConfig
59   );
60
61 /**
62  * EhciInitAfterPciInit - Config USB controller after PCI emulation
63  *
64  * @param[in] Value Controller PCI config address (bus# + device# + function#)
65  * @param[in] pConfig Southbridge configuration structure pointer.
66  */
67 VOID EhciInitAfterPciInit (IN UINT32 Value, IN AMDSBCFG* pConfig);
68
69 /**
70  * OhciInitAfterPciInit - Config USB OHCI controller after PCI emulation
71  *
72  * @param[in] Value  Controller PCI config address (bus# + device# + function#)
73  * @param[in] pConfig Southbridge configuration structure pointer.
74  */
75 VOID OhciInitAfterPciInit (IN UINT32 Value, IN AMDSBCFG* pConfig);
76
77 #ifdef XHCI_SUPPORT
78   VOID XhciInitBeforePciInit (IN AMDSBCFG* pConfig);
79   VOID XhciInitAfterPciInit (IN AMDSBCFG* pConfig);
80   VOID XhciInitLate (IN AMDSBCFG* pConfig);
81 #endif
82 /**
83  * usbInitBeforePciEnum - Config USB controller before PCI emulation
84  *
85  *
86  *
87  * @param[in] pConfig Southbridge configuration structure pointer.
88  *
89  */
90 VOID
91 usbInitBeforePciEnum (
92   IN       AMDSBCFG* pConfig
93   )
94 {
95   UINT8     XhciEfuse;
96   // add Efuse checking for Xhci enable/disable
97   XhciEfuse = XHCI_EFUSE_LOCATION;
98   TRACE ((DMSG_SB_TRACE, "Entering PreInit Usb \n"));
99   // Disabled All USB controller
100   // RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGEF, AccWidthUint8, BIT7, 0);
101   // Clear PM_IO 0x65[4] UsbResetByPciRstEnable, Set this bit so that usb gets reset whenever there is PCIRST.
102   // Enable UsbResumeEnable (USB PME) * Default value
103   // In SB700 USB SleepCtrl set as BIT10+BIT9, but Hudson-2 default is BIT9+BIT8 (6 uframes)
104   RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGF0, AccWidthUint16 | S3_SAVE, ~BIT2, BIT2 + BIT7 + BIT8 + BIT9);
105   // Overwrite EHCI bit by OHCI bit
106   pConfig->USBMODE.UsbModeReg = pConfig->USBMODE.UsbMode.Ohci1 \
107     + (pConfig->USBMODE.UsbMode.Ohci1 << 1) \
108     + (pConfig->USBMODE.UsbMode.Ohci2 << 2) \
109     + (pConfig->USBMODE.UsbMode.Ohci2 << 3) \
110     + (pConfig->USBMODE.UsbMode.Ohci3 << 4) \
111     + (pConfig->USBMODE.UsbMode.Ohci3 << 5) \
112     + (pConfig->USBMODE.UsbMode.Ohci4 << 6);
113
114   // Overwrite EHCI3/OHCI3 by XhciSwitch
115   if (pConfig->XhciSwitch) {
116     pConfig->USBMODE.UsbModeReg &= 0xCF;
117     pConfig->USBMODE.UsbModeReg |= 0x80;
118   } else {
119     pConfig->USBMODE.UsbModeReg &= 0x7F;
120 #ifdef USB_LOGO_SUPPORT
121     if (pConfig->USBMODE.UsbMode.Ohci3) {
122       RWMEM (ACPI_MMIO_BASE + SMI_BASE + SB_SMI_Usbwakup2, AccWidthUint8, 0, 0x0B);
123     }
124 #endif
125   }
126   RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGEF, AccWidthUint8, 0, (pConfig->USBMODE.UsbModeReg));
127   RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGEE, AccWidthUint8, ~(BIT2), 0 );
128 //  RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGEF, AccWidthUint8, 0, (pConfig->USBMODE.UsbModeReg & ~( 0x15 << 1 )) + (( pConfig->USBMODE.UsbModeReg & 0x15 ) << 1 ) );
129
130 //  if ( pConfig->XhciSwitch == 1 && pConfig->S3Resume == 0 && pConfig->S4Resume == 0  ) {
131 //    RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGEF, AccWidthUint8, ~(BIT7) , BIT7);
132 //    RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGEF, AccWidthUint8, ~(BIT4 + BIT5) , 0);
133 //    RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGEE, AccWidthUint8, ~(BIT0 + BIT1 + BIT2), (BIT1 + BIT0 + BIT2) );
134 //  }
135 //  else {
136 //    RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGEF, AccWidthUint8, ~(BIT7) , ~(BIT7));
137 //  }
138 //  RWMEM (ACPI_MMIO_BASE + MISC_BASE + 0x40, AccWidthUint8, ~BIT6, 0);
139 //  RWMEM (ACPI_MMIO_BASE + PMIO_BASE + 0xF3, AccWidthUint8, ~BIT4, BIT4);
140 //  SbStall (500);
141 //  RWMEM (ACPI_MMIO_BASE + PMIO_BASE + 0xF3, AccWidthUint8, ~BIT4, 0);
142
143 #ifdef XHCI_SUPPORT
144 #ifndef XHCI_INIT_IN_ROM_SUPPORT
145   if ( pConfig->XhciSwitch == 1 ) {
146     if ( pConfig->S3Resume == 0 ) {
147       XhciInitBeforePciInit (pConfig);
148     } else {
149       XhciInitIndirectReg ();
150     }
151   } else {
152     // for power saving.
153
154     // add Efuse checking for Xhci enable/disable
155     getEfuseStatus (&XhciEfuse);
156     if ((XhciEfuse & (BIT0 + BIT1)) != (BIT0 + BIT1)) {
157       RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccWidthUint32, 0xF0FFFBFF, 0x0);
158     }
159   }
160 #endif
161 #endif
162
163 }
164
165 /**
166  * usbInitAfterPciInit - Config USB controller after PCI emulation
167  *
168  *
169  *
170  * @param[in] pConfig Southbridge configuration structure pointer.
171  *
172  */
173 VOID
174 usbInitAfterPciInit (
175   IN       AMDSBCFG* pConfig
176   )
177 {
178   if (IsSbA11 ()) {
179     RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGEF, AccWidthUint8, BIT7, 0x7F);
180   }
181
182   usb1EhciInitAfterPciInit (pConfig);
183   usb2EhciInitAfterPciInit (pConfig);
184   usb3EhciInitAfterPciInit (pConfig);
185   usb3OhciInitAfterPciInit (pConfig);
186   usb1OhciInitAfterPciInit (pConfig);
187   usb2OhciInitAfterPciInit (pConfig);
188   usb4OhciInitAfterPciInit (pConfig);
189   // Restore back
190   if (IsSbA11 ()) {
191     RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGEF, AccWidthUint8, BIT7, (pConfig->USBMODE.UsbModeReg));
192   }
193 #ifdef XHCI_SUPPORT
194   if ( pConfig->XhciSwitch == 1 ) {
195     XhciInitAfterPciInit (pConfig);
196   }
197 #endif
198
199   if ( pConfig->UsbPhyPowerDown ) {
200     RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGF0, AccWidthUint8, ~BIT0, BIT0);
201   } else  {
202     RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGF0, AccWidthUint8, ~BIT0, 0);
203   }
204
205   if (IsSbA13Plus ()) {
206     //SB02643
207     RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGB4, AccWidthUint8, ~BIT7, BIT7);
208     //RPR7.27 SB02686
209     RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGED, AccWidthUint8, ~BIT2, BIT2);
210   }
211 }
212
213 /**
214  * usbOverCurrentControl - Config USB Over Current Control
215  *
216  *
217  *
218  * @param[in] pConfig Southbridge configuration structure pointer.
219  *
220  */
221 VOID
222 usbOverCurrentControl (
223   IN       AMDSBCFG* pConfig
224   )
225 {
226
227 #ifdef SB_USB1_OVER_CURRENT_CONTROL
228   RWPCI ((USB1_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG58, AccWidthUint32 | S3_SAVE, 0xfff00000, SB_USB1_OVER_CURRENT_CONTROL & 0x000FFFFF);
229 #endif
230
231 #ifdef SB_USB2_OVER_CURRENT_CONTROL
232   RWPCI ((USB2_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG58, AccWidthUint32 | S3_SAVE, 0xfff00000, SB_USB2_OVER_CURRENT_CONTROL & 0x000FFFFF);
233 #endif
234
235 #ifdef SB_USB3_OVER_CURRENT_CONTROL
236   RWPCI ((USB3_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG58, AccWidthUint32 | S3_SAVE, 0xffff0000, SB_USB3_OVER_CURRENT_CONTROL & 0x0000FFFF);
237 #endif
238
239 #ifdef SB_USB4_OVER_CURRENT_CONTROL
240   RWPCI ((USB4_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG58, AccWidthUint32 | S3_SAVE, 0xffffff00, SB_USB4_OVER_CURRENT_CONTROL & 0x000000FF);
241 #endif
242
243 #ifdef SB_XHCI0_OVER_CURRENT_CONTROL
244   RWXhci0IndReg ( SB_XHCI_IND_REG04, 0xFF00FFFF, (SB_XHCI0_OVER_CURRENT_CONTROL & 0xFF) << 16);
245 #endif
246
247 #ifdef SB_XHCI1_OVER_CURRENT_CONTROL
248   RWXhci1IndReg ( SB_XHCI_IND_REG04, 0xFF00FFFF, (SB_XHCI1_OVER_CURRENT_CONTROL & 0xFF) << 16);
249 #endif
250
251 }
252
253 /**
254  * usbInitLate - Config USB controller after PCI emulation
255  *
256  *
257  *
258  * @param[in] pConfig Southbridge configuration structure pointer.
259  *
260  */
261 VOID
262 usbInitLate (
263   IN       AMDSBCFG* pConfig
264   )
265 {
266   if (pConfig->S4Resume) {
267     //RWPCI (0x9004, AccWidthUint8, 0, 0x10);
268     //RWPCI (0x9804, AccWidthUint8, 0, 0x10);
269     //RWPCI (0xA504, AccWidthUint8, 0, 0x10);
270     //RWPCI (0xB004, AccWidthUint8, 0, 0x10);
271     //RWPCI (0x903C, AccWidthUint8, 0, 0x12);
272     //RWPCI (0x983C, AccWidthUint8, 0, 0x12);
273     //RWPCI (0xA53C, AccWidthUint8, 0, 0x12);
274     //RWPCI (0xB03C, AccWidthUint8, 0, 0x12);
275   }
276 #ifdef XHCI_SUPPORT
277   if ( pConfig->XhciSwitch == 1 ) {
278     XhciInitLate (pConfig);
279   }
280 #endif
281   SbEnableUsbIrq1Irq12ToPicApic ();
282   usbOverCurrentControl (pConfig);
283 }
284
285 /**
286  * usb1EhciInitAfterPciInit - Config USB1 EHCI controller after PCI emulation
287  *
288  *
289  *
290  * @param[in] pConfig Southbridge configuration structure pointer.
291  *
292  */
293 VOID
294 usb1EhciInitAfterPciInit (
295   IN       AMDSBCFG* pConfig
296   )
297 {
298   UINT32  ddDeviceId;
299   ddDeviceId = (USB1_EHCI_BUS_DEV_FUN << 16);
300   EhciInitAfterPciInit (ddDeviceId, pConfig);
301 }
302
303 /**
304  * usb2EhciInitAfterPciInit - Config USB2 EHCI controller after PCI emulation
305  *
306  *
307  *
308  * @param[in] pConfig Southbridge configuration structure pointer.
309  *
310  */
311 VOID
312 usb2EhciInitAfterPciInit (
313   IN       AMDSBCFG* pConfig
314   )
315 {
316   UINT32  ddDeviceId;
317   ddDeviceId = (USB2_EHCI_BUS_DEV_FUN << 16);
318   EhciInitAfterPciInit (ddDeviceId, pConfig);
319 }
320
321 /**
322  * usb3EhciInitAfterPciInit - Config USB3 EHCI controller after PCI emulation
323  *
324  *
325  *
326  * @param[in] pConfig Southbridge configuration structure pointer.
327  *
328  */
329
330 VOID
331 usb3EhciInitAfterPciInit (
332   IN       AMDSBCFG* pConfig
333   )
334 {
335   UINT32  ddDeviceId;
336   ddDeviceId = (USB3_EHCI_BUS_DEV_FUN << 16);
337   EhciInitAfterPciInit (ddDeviceId, pConfig);
338 }
339
340
341 VOID
342 EhciInitAfterPciInit (
343   IN       UINT32 Value,
344   IN       AMDSBCFG* pConfig
345   )
346 {
347   UINT32  ddBarAddress;
348   UINT32  ddVar;
349   UINT32  ddDrivingStrength;
350   UINT32  ddPortDrivingStrength;
351   UINT32  portNumber;
352   UINT32  port;
353   ddDrivingStrength = 0;
354   portNumber = 0;
355   //Get BAR address
356   ReadPCI ((UINT32) Value + SB_EHCI_REG10, AccWidthUint32, &ddBarAddress);
357   if ( (ddBarAddress != - 1) && (ddBarAddress != 0) ) {
358     //Enable Memory access
359     RWPCI ((UINT32) Value + SB_EHCI_REG04, AccWidthUint8, 0, BIT1);
360     if (pConfig->BuildParameters.EhciSsid != NULL ) {
361       RWPCI ((UINT32) Value + SB_EHCI_REG2C, AccWidthUint32 | S3_SAVE, 0x00, pConfig->BuildParameters.EhciSsid);
362     }
363     //USB Common PHY CAL & Control Register setting
364     ddVar = 0x00020F00;
365     WriteMEM (ddBarAddress + SB_EHCI_BAR_REGC0, AccWidthUint32, &ddVar);
366     // RPR IN AND OUT DATA PACKET FIFO THRESHOLD
367     // EHCI BAR 0xA4 //IN threshold bits[7:0]=0x40 //OUT threshold bits[23:16]=0x40
368     RWMEM (ddBarAddress + SB_EHCI_BAR_REGA4, AccWidthUint32, 0xFF00FF00, 0x00400040);
369     // RPR EHCI Dynamic Clock Gating Feature
370     // RPR Enable Global Clock Gating (BIT14)
371     RWMEM (ddBarAddress + SB_EHCI_BAR_REGBC, AccWidthUint32, ~(BIT12 + BIT14), BIT12 + BIT14);
372     RWMEM (ddBarAddress + SB_EHCI_BAR_REGB0, AccWidthUint32, ~BIT5, BIT5);
373     RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGF0, AccWidthUint16, ~BIT12, BIT12);
374     // RPR Enable adding extra flops to PHY rsync path
375     // Step 1:
376     //  EHCI_BAR 0xB4 [6] = 1
377     //  EHCI_BAR 0xB4 [7] = 0
378     //  EHCI_BAR 0xB4 [12] = 0 ("VLoad")
379     //  All other bit field untouched
380     // Step 2:
381     //  EHCI_BAR 0xB4[12] = 1
382     //RWMEM (ddBarAddress + SB_EHCI_BAR_REGB4, AccWidthUint32, ~(BIT6 + BIT7 + BIT12), 0x00);
383     //RWMEM (ddBarAddress + SB_EHCI_BAR_REGB4, AccWidthUint32, ~BIT12, BIT12);
384
385     // RPR7.8 USB 2.0 Ports Driving Strength
386     // Step1 is done by default
387     // Add support USBx_EHCI_DRIVING_STRENGTH port4 is at [19:16] and  port0 is [3:0]; 4 bits for per port, [3] is enable,[2:0] is driving strength.
388     // For Cobia, USB3_EHCI_DRIVING_STRENGTH = 0x00CC
389 #ifdef USB1_EHCI_DRIVING_STRENGTH
390     if (Value == (USB1_EHCI_BUS_DEV_FUN << 16)) {
391       ddDrivingStrength = USB1_EHCI_DRIVING_STRENGTH;
392       portNumber = 5;
393     }
394 #endif
395 #ifdef USB2_EHCI_DRIVING_STRENGTH
396     if (Value == (USB2_EHCI_BUS_DEV_FUN << 16)) {
397       ddDrivingStrength = USB2_EHCI_DRIVING_STRENGTH;
398       portNumber = 5;
399     }
400 #endif
401 #ifdef USB3_EHCI_DRIVING_STRENGTH
402     if (Value == (USB3_EHCI_BUS_DEV_FUN << 16)) {
403       ddDrivingStrength = USB3_EHCI_DRIVING_STRENGTH;
404       portNumber = 4;
405     }
406 #endif
407     if (portNumber > 0) {
408       for (port = 0; port < portNumber; port ++) {
409         ddPortDrivingStrength = (ddDrivingStrength >> (port * 4)) & 0x0F;
410         if (ddPortDrivingStrength & BIT3) {
411           ddPortDrivingStrength &= 0x7;
412           RWMEM (ddBarAddress + SB_EHCI_BAR_REGB4, AccWidthUint32, ~ (BIT16 + BIT15 + BIT14 + BIT13 + BIT12 + BIT2 + BIT1 + BIT0), (port << 13) + ddPortDrivingStrength);
413           RWMEM (ddBarAddress + SB_EHCI_BAR_REGB4, AccWidthUint32, ~BIT12, BIT12);
414         }
415       }
416     }
417     // Step2
418     RWMEM (ddBarAddress + SB_EHCI_BAR_REGB4, AccWidthUint32, ~BIT12, BIT12);
419     // Step3
420     if (IsSbA11 ()) {
421       RWMEM (ddBarAddress + SB_EHCI_BAR_REGC4, AccWidthUint32, (UINT32) (~ 0x00000f00), 0x00000000);
422       RWMEM (ddBarAddress + SB_EHCI_BAR_REGC0, AccWidthUint32, (UINT32) (~ 0x0000ff00), 0x00001500);
423     } else {
424       RWMEM (ddBarAddress + SB_EHCI_BAR_REGC4, AccWidthUint32, (UINT32) (~ 0x00000f00), 0x00000200);
425       RWMEM (ddBarAddress + SB_EHCI_BAR_REGC0, AccWidthUint32, (UINT32) (~ 0x0000ff00), 0x00000f00);
426     }
427     //Set EHCI_pci_configx50[6]='1' to disable EHCI MSI support
428     RWPCI ((UINT32) Value + SB_EHCI_REG50, AccWidthUint32 | S3_SAVE, ~ ((UINT32) (0x01 << 6)), (0x01 << 6));
429     //RPR 7.13 EHCI Async Park Mode
430     //Set EHCI_pci_configx50[11:8]=0x1
431     //Set EHCI_pci_configx50[15:12]=0x1
432     //Set EHCI_pci_configx50[17]=0x1
433     RWPCI ((UINT32) Value + SB_EHCI_REG50, AccWidthUint32 | S3_SAVE, ~ ((UINT32) (0x0F << 8)), (0x01 << 8));
434     RWPCI ((UINT32) Value + SB_EHCI_REG50, AccWidthUint32 | S3_SAVE, ~ ((UINT32) (0x0F << 12)), (0x01 << 12));
435     RWPCI ((UINT32) Value + SB_EHCI_REG50, AccWidthUint32 | S3_SAVE, ~ ((UINT32) (0x01 << 17)), (0x01 << 17));
436     //RPR Enabling EHCI Async Stop Enhancement
437     //Set EHCI_pci_configx50[29]='1' to disableEnabling EHCI Async Stop Enhancement
438     RWPCI ((UINT32) Value + SB_EHCI_REG50, AccWidthUint32 | S3_SAVE, ~ ((UINT32) (0x01 << 29)), (0x01 << 29));
439     //RWPCI ((UINT32) Value + SB_EHCI_REG50, AccWidthUint32 | S3_SAVE, 0xFF7F0FFF, 0x20221140);
440     // RPR recommended setting "EHCI Advance PHY Power Savings"
441     // Set EHCI_pci_configx50[31]='1'
442     // Fix for EHCI controller driver  yellow sign issue under device manager
443     // when used in conjunction with HSET tool driver. EHCI PCI config 0x50[20]=1
444     RWPCI ((UINT32) Value + SB_EHCI_REG50 + 2, AccWidthUint16 | S3_SAVE, (UINT16)0xFFFF, BIT15);
445     // ENH246436: Disable USB data cache to resolve USB controller hang issue with Lan adaptor.
446     // EHCI PCI config register 50h bit 26 to `1'.
447     if (pConfig->EhciDataCacheDis) {
448       RWPCI ((UINT32) Value + SB_EHCI_REG50 + 2, AccWidthUint16 | S3_SAVE, (UINT16)0xFFFF, BIT10);
449     }
450
451     if (IsSbA13Plus ()) {
452       //RPR 7.25  SB02674
453       RWPCI ((UINT32) Value + SB_EHCI_REG54, AccWidthUint16 | S3_SAVE, (UINT16)0x5FFF, BIT13 + BIT15);
454       //RPR 7.26  SB02684
455       RWPCI ((UINT32) Value + SB_EHCI_REG50 + 2, AccWidthUint16 | S3_SAVE, ~ (BIT3), BIT3);
456       //RPR 7.26  SB02687
457       RWPCI ((UINT32) Value + SB_EHCI_REG54 + 2, AccWidthUint16 | S3_SAVE, (UINT16)0xFFFC, BIT0 + BIT1);
458       //RPR 7.28  SB02700
459       RWPCI ((UINT32) Value + SB_EHCI_REG54 + 2, AccWidthUint16 | S3_SAVE, (UINT16)0xFFFB, BIT2);
460       //RPR 7.29  SB02703
461       RWPCI ((UINT32) Value + SB_EHCI_REG54 + 2, AccWidthUint16 | S3_SAVE, (UINT16)0xFFF7, BIT3);
462     }
463
464     // RPR USB Delay A-Link Express L1 State
465     // RPR PING Response Fix Enable EHCI_PCI_Config  x54[1] = 1
466     // RPR Enable empty list mode. x54[3]
467     // RPR Enable "L1 Early Exit" functionality. 0x54 [6:5] = 0x3 0x54 [9:7] = 0x4
468     // RPR EHCI PING Response Fix Enable 0x54 [1] = 0x1
469     RWPCI ((UINT32) Value + SB_EHCI_REG54, AccWidthUint32 | S3_SAVE, ~BIT0, 0x0000026b);
470     if ( pConfig->BuildParameters.UsbMsi) {
471       RWPCI ((UINT32) Value + SB_EHCI_REG50, AccWidthUint32 | S3_SAVE, ~BIT6, 0x00);
472     }
473     if (IsSbA12Plus ()) {
474       // RPR 7.24 Long Delay on Framelist Read Causing EHCI DMA to Address 0 - Fix
475       // RWPCI ((UINT32) Value + SB_EHCI_REG54, AccWidthUint32 | S3_SAVE, ~BIT13, BIT13);
476       // RPR 7.25 LS connection can't wake up system from S3/S4/S5 when EHCI owns the port - Fix
477       RWPCI ((UINT32) Value + SB_EHCI_REG54, AccWidthUint32 | S3_SAVE, ~BIT4, BIT4);
478       // RPR 7.30 EHCI lMU Hangs when Run/Stop is Set First and PDC is Enabled Near End uFrame 7 - Fix Enable
479       RWPCI ((UINT32) Value + SB_EHCI_REG54, AccWidthUint32 | S3_SAVE, ~BIT11, BIT11);
480     }
481     // ENH244924: Platform specific Hudson-2/3 settings for all Sabine Platforms
482     // EHCI_PCI_Config 0x50[21]=1
483     // EHCI_PCI_Config 0x54[9:7] = 0x4
484     if ( IsGCPU () ) {
485       RWPCI ((UINT32) Value + SB_EHCI_REG50, AccWidthUint32 | S3_SAVE, ~ ((UINT32) (0x01 << 21)), (0x01 << 21));
486       RWPCI ((UINT32) Value + SB_EHCI_REG54, AccWidthUint32 | S3_SAVE, ~ ((UINT32) (0x07 << 7)), (0x04 << 7));
487     }
488 //    RWMEM (ddBarAddress + SB_EHCI_BAR_REGB0, AccWidthUint32, ~BIT5, BIT5);
489   } else {
490     // Fake Bar
491     ddBarAddress = 0x58830000;
492     WritePCI ((UINT32) Value + SB_EHCI_REG10, AccWidthUint32, &ddBarAddress);
493     //Enable Memory access
494     RWPCI ((UINT32) Value + SB_EHCI_REG04, AccWidthUint8, 0, BIT1);
495     // RPR Enable Global Clock Gating (BIT14)
496     RWMEM (ddBarAddress + SB_EHCI_BAR_REGBC, AccWidthUint32, ~(BIT12 + BIT14), BIT12 + BIT14);
497     RWMEM (ddBarAddress + SB_EHCI_BAR_REGB0, AccWidthUint32, ~BIT5, BIT5);
498     RWPCI ((UINT32) Value + SB_EHCI_REG04, AccWidthUint8, 0, 0);
499 //    RWMEM (ddBarAddress + SB_EHCI_BAR_REGB0, AccWidthUint32, ~BIT5, BIT5);
500   }
501 }
502
503 /**
504  * usb1OhciInitAfterPciInit - Config USB1 OHCI controller after PCI emulation
505  *
506  *
507  *
508  * @param[in] pConfig Southbridge configuration structure pointer.
509  *
510  */
511 VOID
512 usb1OhciInitAfterPciInit (
513   IN       AMDSBCFG* pConfig
514   )
515 {
516   UINT32  ddDeviceId;
517   ddDeviceId = (USB1_OHCI_BUS_DEV_FUN << 16);
518   OhciInitAfterPciInit (ddDeviceId, pConfig);
519   RWPCI ((USB1_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG78, AccWidthUint32 | S3_SAVE, 0xffffffff, BIT28 + BIT29);
520 }
521
522 /**
523  * usb2OhciInitAfterPciInit - Config USB2 OHCI controller after PCI emulation
524  *
525  *
526  *
527  * @param[in] pConfig Southbridge configuration structure pointer.
528  *
529  */
530 VOID
531 usb2OhciInitAfterPciInit (
532   IN       AMDSBCFG* pConfig
533   )
534 {
535   UINT32  ddDeviceId;
536   ddDeviceId = (USB2_OHCI_BUS_DEV_FUN << 16);
537   OhciInitAfterPciInit (ddDeviceId, pConfig);
538 }
539
540 /**
541  * usb3OhciInitAfterPciInit - Config USB3 OHCI controller after PCI emulation
542  *
543  *
544  *
545  * @param[in] pConfig Southbridge configuration structure pointer.
546  *
547  */
548 VOID
549 usb3OhciInitAfterPciInit (
550   IN       AMDSBCFG* pConfig
551   )
552 {
553   UINT32  ddDeviceId;
554   ddDeviceId = (USB3_OHCI_BUS_DEV_FUN << 16);
555   OhciInitAfterPciInit (ddDeviceId, pConfig);
556 }
557
558 /**
559  * usb4OhciInitAfterPciInit - Config USB4 OHCI controller after PCI emulation
560  *
561  *
562  *
563  * @param[in] pConfig Southbridge configuration structure pointer.
564  *
565  */
566 VOID
567 usb4OhciInitAfterPciInit (
568   IN       AMDSBCFG* pConfig
569   )
570 {
571   UINT32  ddDeviceId;
572   ddDeviceId = (USB4_OHCI_BUS_DEV_FUN << 16);
573   OhciInitAfterPciInit (ddDeviceId, pConfig);
574   if (pConfig->BuildParameters.Ohci4Ssid != NULL ) {
575     RWPCI ((USB4_OHCI_BUS_DEV_FUN << 16) + SB_OHCI_REG2C, AccWidthUint32 | S3_SAVE, 0x00, pConfig->BuildParameters.Ohci4Ssid);
576   }
577 }
578
579 VOID
580 OhciInitAfterPciInit (
581   IN       UINT32 Value,
582   IN       AMDSBCFG* pConfig
583   )
584 {
585 #ifdef SB_USB_BATTERY_CHARGE_SUPPORT
586   RWPCI ((UINT32) Value + SB_OHCI_REG40 + 6, AccWidthUint8 | S3_SAVE, 0xFF, 0x1F);
587 #endif
588   // Disable the MSI capability of USB host controllers
589   RWPCI ((UINT32) Value + SB_OHCI_REG40 + 1, AccWidthUint8 | S3_SAVE, 0xFF, BIT0);
590   if ((IsSbA11 ()) || (IsSbA12 ())) {
591     RWPCI ((UINT32) Value + SB_OHCI_REG50, AccWidthUint8 | S3_SAVE, ~(BIT0 + BIT5 + BIT12), 0);
592   } else {
593     RWPCI ((UINT32) Value + SB_OHCI_REG50, AccWidthUint8 | S3_SAVE, ~(BIT0 + BIT5 + BIT12), BIT0);
594   }
595   // RPR USB SMI Handshake
596   RWPCI ((UINT32) Value + SB_OHCI_REG50 + 1, AccWidthUint8 | S3_SAVE, ~BIT4, 0x00);
597   if (Value != (USB4_OHCI_BUS_DEV_FUN << 16)) {
598     if ( pConfig->BuildParameters.OhciSsid != NULL ) {
599       RWPCI ((UINT32) Value + SB_OHCI_REG2C, AccWidthUint32 | S3_SAVE, 0x00, pConfig->BuildParameters.OhciSsid);
600     }
601   }
602   //RPR recommended setting to, enable fix to cover the corner case S3 wake up issue from some USB 1.1 devices
603   //OHCI 0_PCI_Config 0x50[30] = 1
604   RWPCI ((UINT32) Value + SB_OHCI_REG50 + 3, AccWidthUint8 | S3_SAVE, ~BIT6, BIT6);
605   // RPR L1 Early Exit
606   // RPR Set OHCI Arbiter Mode.
607   // RPR Set Enable Global Clock Gating.
608   RWPCI ((UINT32) Value + SB_OHCI_REG80, AccWidthUint8 | S3_SAVE, ~(BIT0 + BIT4 + BIT5 + BIT6 + BIT7), BIT0 + BIT4 + BIT7);
609   //   SB02698
610   RWPCI ((UINT32) Value + SB_OHCI_REG50, AccWidthUint8 | S3_SAVE, ~BIT0, 0);
611   // RPR 7.21 OHCI Arbiter Mode
612   // A13 Remove Arbitor Reset
613   if ( IsSbA12Plus () ) {
614     RWPCI ((UINT32) Value + SB_OHCI_REG80, AccWidthUint16 | S3_SAVE, ~(BIT4 + BIT5 + BIT8), (BIT4 + BIT5 + BIT8));
615   } else {
616     RWPCI ((UINT32) Value + SB_OHCI_REG80, AccWidthUint16 | S3_SAVE, ~(BIT4 + BIT5), (BIT4));
617   }
618   // RPR Enable OHCI SOF Synchronization.
619   // RPR Enable OHCI Periodic List Advance.
620   RWPCI ((UINT32) Value + SB_OHCI_REG50 + 2, AccWidthUint8 | S3_SAVE, ~(BIT3 + BIT4), BIT3 + BIT4);
621   if ( pConfig->BuildParameters.UsbMsi) {
622     RWPCI ((UINT32) Value + SB_OHCI_REG40 + 1, AccWidthUint8 | S3_SAVE, ~BIT0, 0x00);
623     RWPCI ((UINT32) Value + SB_OHCI_REG50, AccWidthUint8 | S3_SAVE, ~BIT5, BIT5);
624   }
625   //7.23  USB1.1 full-speed false crc errors detected. Issue - fix enable
626   if ( IsSbA12Plus () ) {
627     RWPCI ((UINT32) Value + SB_OHCI_REG80, AccWidthUint32 | S3_SAVE, (UINT32) (~(0x01 << 10)), (UINT32) (0x01 << 10));
628   }
629 }
630
631
632 UINT32
633 SetEhciPllWr (
634   IN       UINT32 Value,
635   IN       AMDSBCFG* pConfig
636   )
637 {
638   UINT32  ddRetureValue;
639   UINT32  ddBarAddress;
640   UINT16  dwVar;
641   UINT16  dwData;
642   UINT8  portSC;
643   ddRetureValue = 0;
644   dwData = 0;
645   // Memory, and etc.
646   //_asm { jmp $};
647   RWPCI ((UINT32) Value + 0xC4, AccWidthUint8, 0xF0, 0x00);
648   RWPCI ((UINT32) Value + 0x04, AccWidthUint8, 0xFF, 0x02);
649   // Get Bar address
650   ReadPCI ((UINT32) Value + 0x10, AccWidthUint32, &ddBarAddress);
651   for (portSC = 0x64; portSC < 0x75; portSC += 0x04 ) {
652     // Get OHCI command registers
653     ReadMEM (ddBarAddress + portSC, AccWidthUint16, &dwVar);
654     if ( dwVar & BIT6 ) {
655       ddRetureValue = ddBarAddress + portSC;
656       RWMEM (ddBarAddress + portSC, AccWidthUint16, ~BIT6, 0);
657       for (;;) {
658         SbStall (5);
659         ReadMEM (ddBarAddress + portSC, AccWidthUint16, &dwData);
660         if (dwData == 0x1005) break;
661       }
662       dwData = 0;
663     }
664   }
665   return ddRetureValue;
666 }
667
668 #ifdef XHCI_SUPPORT
669 /*
670 VOID
671 XhciInitIndirectReg (
672   )
673 {
674   UINT32 ddDrivingStrength;
675   UINT32 port;
676   ddDrivingStrength = 0;
677   port = 0;
678 #ifdef SB_USB_BATTERY_CHARGE_SUPPORT
679   RWXhciIndReg ( 0x40000018, 0xFFFFFFFF, 0x00000030);
680 #endif
681 //
682 // RPR SuperSpeed PHY Configuration (adaptation mode setting)
683 //
684   RWXhciIndReg ( SB_XHCI_IND_REG94, 0xFFFFFC00, 0x00000021);
685   RWXhciIndReg ( SB_XHCI_IND_REGD4, 0xFFFFFC00, 0x00000021);
686 //
687 // RPR SuperSpeed PHY Configuration (CR phase and frequency filter settings)
688 //
689   RWXhciIndReg ( SB_XHCI_IND_REG98, 0xFFFFFFC0, 0x0000000A);
690   RWXhciIndReg ( SB_XHCI_IND_REGD8, 0xFFFFFFC0, 0x0000000A);
691
692 //
693 // RPR BLM Meaasge
694 //
695   RWXhciIndReg ( SB_XHCI_IND_REG00, 0xF8FFFFFF, 0x07000000);
696
697 #ifdef USB3_EHCI_DRIVING_STRENGTH
698 //
699 // RPR 8.13 xHCI USB 2.0 PHY Settings
700 // Step 1 is done by hardware default
701 // Step 2
702   for (port = 0; port < 4; port ++) {
703     ddDrivingStrength = (USB3_EHCI_DRIVING_STRENGTH >> (port * 4)) & 0xF;
704     if (ddDrivingStrength & BIT3) {
705       ddDrivingStrength &= 0x07;
706       if (port < 2) {
707         RWXhci0IndReg ( SB_XHCI_IND60_REG00, 0xFFFE0E78, (port << 13) + ddDrivingStrength);
708         RWXhci0IndReg ( SB_XHCI_IND60_REG00, 0xFFFFEFFF, 0x00001000);
709       } else {
710         RWXhci1IndReg ( SB_XHCI_IND60_REG00, 0xFFFE0E78, ((port - 2) << 13) + ddDrivingStrength);
711         RWXhci1IndReg ( SB_XHCI_IND60_REG00, 0xFFFFEFFF, 0x00001000);
712       }
713     }
714   }
715 #endif
716
717 #ifdef USB_LOGO_SUPPORT
718 //for D3 USB LOGO [6:0]= 4; [8:7] = 3; [12] = 0; [16:13] port;
719   for (port = 0; port < 4; port ++) {
720     if (port < 2) {
721       RWXhci0IndReg ( SB_XHCI_IND60_REG00, 0xFFFE0E00, (port << 13) + 0x184 );
722     } else {
723       RWXhci1IndReg ( SB_XHCI_IND60_REG00, 0xFFFE0E00, ((port - 2) << 13) + 0x184 );
724     }
725   }
726 #endif
727
728 // Step 3
729   if (IsSbA11 ()) {
730     RWXhciIndReg ( SB_XHCI_IND60_REG0C, ~ ((UINT32) (0x0f << 8)), ((UINT32) (0x00 << 8)));
731     RWXhciIndReg ( SB_XHCI_IND60_REG08, ~ ((UINT32) (0xff << 8)), ((UINT32) (0x15 << 8)));
732   } else {
733     RWXhciIndReg ( SB_XHCI_IND60_REG0C, ~ ((UINT32) (0x0f << 8)), ((UINT32) (0x02 << 8)));
734     RWXhciIndReg ( SB_XHCI_IND60_REG08, ~ ((UINT32) (0xff << 8)), ((UINT32) (0x0f << 8)));
735   }
736 }
737 */
738
739 VOID
740 XhciA12Fix (
741   VOID
742   )
743 {
744 //
745 // 8.14 PLUG/UNPLUG of USB 2.0 devices make the XHCI USB 2.0 ports unfunctional - fix enable
746 // ACPI_USB3.0_REG 0x20[12:11] = 2'b11
747   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccWidthUint32, ~((UINT32) (0x3 << 11)), (UINT32) (0x3 << 11));
748 //
749 // 8.15 XHC 2 USB2 ports interactional issue - fix enable
750 // ACPI_USB3.0_REG 0x20[16] = 1'b1
751   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccWidthUint32, ~((UINT32) (0x1 << 16)), (UINT32) (0x1 << 16));
752 //
753 // 8.16 xHCI USB 2.0 Ports Suspend Enhancement
754 // ACPI_USB3.0_REG 0x20[15] = 1'b1
755 //
756   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccWidthUint32, ~((UINT32) (0x1 << 15)), (UINT32) (0x1 << 15));
757 //
758 // 8.17 XHC HS/FS IN Data Buffer Underflow issue - fix enable
759 // ACPI_USB3.0_REG 0x20[20:18] = 0x7
760 //
761   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccWidthUint32, ~((UINT32) (0x7 << 18)), (UINT32) (0x7 << 18));
762 //
763 // 8.18 Allow XHCI to Resume from S3 Enhancement
764 // ACPI_USB3.0_REG 0x98[19] = 1'b1
765 //
766   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG98, AccWidthUint32, ~((UINT32) (0x1 << 19)), (UINT32) (0x1 << 19));
767 //
768 // 8.19 Assign xHC1 ( Dev 16 function 1) Interrupt Pin register to INTB#
769 // ACPI_PMIO_F0[18] =1
770 //
771   RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGF0, AccWidthUint32, ~((UINT32) (0x1 << 18)), (UINT32) (0x1 << 18));
772 //
773 // 8.20 Allow B-Link Clock Gating when EHCI3/OHCI3 is only Controller Enabled
774 // ACPI_PMIO_F0[13] =1
775 //
776   RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGF0, AccWidthUint32, ~((UINT32) (0x1 << 13)), (UINT32) (0x1 << 13));
777 //
778 // 8.21 Access register through JTAG fail when switch from XHCI to EHCI/OHCI - Fix enable
779 // ACPI_PMIO_F0[17] =1
780 //
781   RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGF0, AccWidthUint32, ~((UINT32) (0x1 << 17)), (UINT32) (0x1 << 17));
782 //
783 // 8.22 USB leakage current on differential lines when ports are switched to XHCI - Fix enable
784 // ACPI_PMIO_F0[14] =1
785 //
786   RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGF0, AccWidthUint32, ~((UINT32) (0x1 << 14)), (UINT32) (0x1 << 14));
787 //  RWMEM (ACPI_MMIO_BASE + SMI_BASE + SB_SMI_xHC0Pme, AccWidthUint16, 0, 0x0B0B);
788 //
789 // 8.26 Fix for Incorrect Gated Signals in xhc_to_s5
790 // ACPI_PMIO_F0[16] =1
791 //
792   RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGF0, AccWidthUint32, ~((UINT32) (0x1 << 16)), (UINT32) (0x1 << 16));
793 }
794
795 VOID
796 XhciInitBeforePciInit (
797   IN       AMDSBCFG* pConfig
798   )
799 {
800   UINT16  BcdAddress;
801   UINT16  BcdSize;
802   UINT16  AcdAddress;
803   UINT16  AcdSize;
804   UINT16  FwAddress;
805   UINT16  FwSize;
806   UINTN   XhciFwStarting;
807   UINT32  SpiValidBase;
808   UINT32  RegData;
809   UINT16  i;
810
811   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccWidthUint32, 0x00000000, 0x00400700);
812   SbStall (20);
813 //
814 // Get ROM SIG starting address for USB firmware starting address (offset 0x0C to SIG address)
815 //
816   GetRomSigPtr (&XhciFwStarting);
817
818   if (XhciFwStarting == 0) {
819     return;
820   }
821
822   XhciFwStarting = ACPIMMIO32 (XhciFwStarting + FW_TO_SIGADDR_OFFSET);
823   if (IsLpcRom ()) {
824   //XHCI firmware re-load
825     RWPCI ((LPC_BUS_DEV_FUN << 16) + SB_LPC_REGCC, AccWidthUint32 | S3_SAVE, ~BIT2, (BIT2 + BIT1 + BIT0));
826     RWPCI ((LPC_BUS_DEV_FUN << 16) + SB_LPC_REGCC, AccWidthUint32 | S3_SAVE, 0x00000FFF, (UINT32) (XhciFwStarting));
827   }
828 //
829 // RPR Enable SuperSpeed receive special error case logic. 0x20 bit8
830 // RPR Enable USB2.0 RX_Valid Synchronization. 0x20 bit9
831 // Enable USB2.0 DIN/SE0 Synchronization. 0x20 bit10
832 //
833   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccWidthUint32, 0xFFFFF8FF, 0x00000700);
834 //
835 // RPR SuperSpeed PHY Configuration (adaptation timer setting)
836 //
837   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG90, AccWidthUint32, 0xFFF00000, 0x000AAAAA);
838   //RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG90 + 0x40, AccWidthUint32, 0xFFF00000, 0x000AAAAA);
839
840 //
841 // Step 1. to enable Xhci IO and Firmware load mode
842 //
843 #ifdef XHCI_SUPPORT_ONE_CONTROLLER
844   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccWidthUint32, 0xF0FFFFFC, 0x00000001);
845 #else
846   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccWidthUint32, 0xF0FFFFFC, 0x00000003);
847 #endif
848   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccWidthUint32, 0xEFFFFFFF, 0x10000000);
849
850 //
851 // Step 2. to read a portion of the USB3_APPLICATION_CODE from BIOS ROM area and program certain registers.
852 //
853
854   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA0, AccWidthUint32, 0x00000000, (SPI_HEAD_LENGTH << 16));
855
856   BcdAddress = ACPIMMIO16 (XhciFwStarting + BCD_ADDR_OFFSET);
857   BcdSize = ACPIMMIO16 (XhciFwStarting + BCD_SIZE_OFFSET);
858   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA4, AccWidthUint16, 0x0000, BcdAddress);
859   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA4 + 2, AccWidthUint16, 0x0000, BcdSize);
860
861   AcdAddress = ACPIMMIO16 (XhciFwStarting + ACD_ADDR_OFFSET);
862   AcdSize = ACPIMMIO16 (XhciFwStarting + ACD_SIZE_OFFSET);
863   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA8, AccWidthUint16, 0x0000, AcdAddress);
864   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA8 + 2, AccWidthUint16, 0x0000, AcdSize);
865
866   SpiValidBase = SPI_BASE2 (XhciFwStarting + 4) | SPI_BAR0_VLD | SPI_BASE0 | SPI_BAR1_VLD | SPI_BASE1 | SPI_BAR2_VLD;
867   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB0, AccWidthUint32, 0x00000000, SpiValidBase);
868
869     //
870     // Copy Type0/1/2 data block from ROM image to MMIO starting from 0xC0
871     //
872   for (i = 0; i < SPI_HEAD_LENGTH; i++) {
873     RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGC0 + i, AccWidthUint8, 0, ACPIMMIO8 (XhciFwStarting + i));
874   }
875
876   for (i = 0; i < BcdSize; i++) {
877     RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGC0 + SPI_HEAD_LENGTH + i, AccWidthUint8, 0, ACPIMMIO8 (XhciFwStarting + BcdAddress + i));
878   }
879
880   for (i = 0; i < AcdSize; i++) {
881     RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGC0 + SPI_HEAD_LENGTH + BcdSize + i, AccWidthUint8, 0, ACPIMMIO8 (XhciFwStarting + AcdAddress + i));
882   }
883
884 //
885 // Step 3. to enable the instruction RAM preload functionality.
886 //
887   FwAddress = ACPIMMIO16 (XhciFwStarting + FW_ADDR_OFFSET);
888   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccWidthUint16, 0x0000, ACPIMMIO16 (XhciFwStarting + FwAddress));
889   FwAddress += 2;
890   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG04, AccWidthUint16, 0x0000, FwAddress);
891
892   FwSize = ACPIMMIO16 (XhciFwStarting + FW_SIZE_OFFSET);
893   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG04 + 2, AccWidthUint16, 0x0000, FwSize);
894
895     //
896     // Set the starting address offset for Instruction RAM preload.
897     //
898   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG08, AccWidthUint16, 0x0000, 0);
899
900   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccWidthUint32, ~BIT29, BIT29);
901
902   for (;;) {
903     ReadMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00 , AccWidthUint32, &RegData);
904     if (RegData & BIT30) break;
905   }
906   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccWidthUint32, ~BIT29, 0);
907
908 //
909 // Step 4. to release resets in XHCI_ACPI_MMIO_AMD_REG00. wait for USPLL to lock by polling USPLL lock.
910 //
911
912   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccWidthUint32, ~U3PLL_RESET, 0); //Release U3PLLreset
913   for (;;) {
914     ReadMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00 , AccWidthUint32, &RegData);
915     if (RegData & U3PLL_LOCK) break;
916   }
917
918   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccWidthUint32, ~U3PHY_RESET, 0); //Release U3PHY
919   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccWidthUint32, ~U3CORE_RESET, 0); //Release core reset
920
921 // RPR 8.8 SuperSpeed PHY Configuration, it is only for A11.
922   if (IsSbA11 ()) {
923     RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG90, AccWidthUint32, 0xFFF00000, 0x000AAAAA); //
924     RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGD0, AccWidthUint32, 0xFFF00000, 0x000AAAAA); //
925   }
926
927   XhciInitIndirectReg ();
928
929   RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGEF, AccWidthUint8, ~(BIT4 + BIT5), 0); // Disable Device 22
930   RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGEF, AccWidthUint8, ~(BIT7), BIT7); // Enable 2.0 devices
931   if (!(pConfig->S4Resume)) {
932     RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccWidthUint32, ~(BIT21), BIT21); //SMI
933   }
934 //
935 // Step 5.
936 //
937   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccWidthUint32, ~(BIT17 + BIT18 + BIT19), BIT17 + BIT18);
938
939 // Step 5.
940   if (IsSbA12Plus ()) {
941     XhciA12Fix ();
942   }
943   //8.22 UMI Lane Configuration Information for XHCI Firmware to Calculate the Bandwidth for USB 3.0 ISOC Devices
944   if (!(IsUmiOneLaneGen1Mode ())) {
945     RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccWidthUint32, ~(BIT25 + BIT24), BIT24);
946   }
947 }
948
949 VOID
950 XhciInitAfterPciInit (
951   IN       AMDSBCFG* pConfig
952   )
953 {
954   // RPR8.12 Block Write to DID & SID to pass DTM
955   RWXhciIndReg ( SB_XHCI_IND_REG04, ~BIT8, BIT8);
956
957   if (IsSbA13Plus ()) {
958     //8.23 FS/LS devices not functional after resume from S4 fix enable (SB02699)
959     RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccWidthUint32, ~(BIT22), BIT22);
960   }
961   //8.24 XHC USB2.0 Hub disable issue fix enable (SB02702)
962   RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccWidthUint32, ~(BIT20), BIT20);
963 }
964
965 VOID
966 XhciInitLate (
967   IN       AMDSBCFG* pConfig
968   )
969 {
970   //OBS221599: USB 3.0 controller shows bang in Windows Device Manager
971   UINT8  Data;
972   if ( IsSbA11 () ) {
973     Data = 0xB5; //
974     WriteIO (SB_IOMAP_REGC00, AccWidthUint8, &Data);
975     Data = 0x12; //
976     WriteIO (SB_IOMAP_REGC01, AccWidthUint8, &Data);
977   }
978   if (pConfig->S4Resume) {
979     RWMEM (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccWidthUint32, ~(BIT21), BIT21); //SMI
980     SbFlashUsbSmi ();
981   }
982 }
983 #endif