zbao | 7d94cf9 | 2012-07-02 14:19:14 +0800 | [diff] [blame] | 1 | /* $NoKeywords:$ */ |
| 2 | /** |
| 3 | * @file |
| 4 | * |
| 5 | * Config FCH USB3 controller |
| 6 | * |
| 7 | * Init USB3 features. |
| 8 | * |
| 9 | * @xrefitem bom "File Content Label" "Release Content" |
| 10 | * @e project: AGESA |
| 11 | * @e sub-project: FCH |
| 12 | * @e \$Revision: 65854 $ @e \$Date: 2012-02-26 01:52:07 -0600 (Sun, 26 Feb 2012) $ |
| 13 | * |
| 14 | */ |
| 15 | /*;******************************************************************************** |
| 16 | ; |
Siyuan Wang | 641f00c | 2013-06-08 11:50:55 +0800 | [diff] [blame] | 17 | * Copyright (c) 2008 - 2012, Advanced Micro Devices, Inc. |
| 18 | * All rights reserved. |
| 19 | * |
| 20 | * Redistribution and use in source and binary forms, with or without |
| 21 | * modification, are permitted provided that the following conditions are met: |
| 22 | * * Redistributions of source code must retain the above copyright |
| 23 | * notice, this list of conditions and the following disclaimer. |
| 24 | * * Redistributions in binary form must reproduce the above copyright |
| 25 | * notice, this list of conditions and the following disclaimer in the |
| 26 | * documentation and/or other materials provided with the distribution. |
| 27 | * * Neither the name of Advanced Micro Devices, Inc. nor the names of |
| 28 | * its contributors may be used to endorse or promote products derived |
| 29 | * from this software without specific prior written permission. |
| 30 | * |
| 31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| 32 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 33 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 34 | * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY |
| 35 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 36 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 37 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 38 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 39 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 40 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
zbao | 7d94cf9 | 2012-07-02 14:19:14 +0800 | [diff] [blame] | 41 | ;*********************************************************************************/ |
| 42 | #include "FchPlatform.h" |
| 43 | #include "Filecode.h" |
| 44 | #define FILECODE PROC_FCH_USB_FAMILY_HUDSON2_HUDSON2XHCIENVSERVICE_FILECODE |
| 45 | |
| 46 | // |
| 47 | // Declaration of local functions |
| 48 | // |
| 49 | |
| 50 | /** |
| 51 | * FchXhciInitIndirectReg - Config XHCI Indirect Registers |
| 52 | * |
| 53 | * |
| 54 | * |
| 55 | * @param[in] StdHeader AMD Standard Header |
| 56 | * |
| 57 | */ |
| 58 | VOID |
| 59 | FchXhciInitIndirectReg ( |
| 60 | IN AMD_CONFIG_PARAMS *StdHeader |
| 61 | ) |
| 62 | { |
| 63 | UINT32 DrivingStrength; |
| 64 | UINT32 Port; |
| 65 | UINT32 Register; |
| 66 | UINT32 RegValue; |
| 67 | UINT8 Index; |
| 68 | DrivingStrength = 0; |
| 69 | Port = 0; |
| 70 | // |
| 71 | // SuperSpeed PHY Configuration (adaptation mode setting) |
| 72 | // |
| 73 | RwXhciIndReg ( FCH_XHCI_IND_REG94, 0xFFFFFC00, 0x00000021, StdHeader); |
| 74 | RwXhciIndReg ( FCH_XHCI_IND_REGD4, 0xFFFFFC00, 0x00000021, StdHeader); |
| 75 | // |
| 76 | // SuperSpeed PHY Configuration (CR phase and frequency filter settings) |
| 77 | // |
| 78 | RwXhciIndReg ( FCH_XHCI_IND_REG98, 0xFFFFFFC0, 0x0000000A, StdHeader); |
| 79 | RwXhciIndReg ( FCH_XHCI_IND_REGD8, 0xFFFFFFC0, 0x0000000A, StdHeader); |
| 80 | // |
| 81 | // BLM Meaasge |
| 82 | // |
| 83 | RwXhciIndReg ( FCH_XHCI_IND_REG00, 0xF8FFFFFF, 0x07000000, StdHeader); |
| 84 | // |
| 85 | // xHCI USB 2.0 PHY Settings |
| 86 | // Step 1 is done by hardware default |
| 87 | // Step 2 |
| 88 | for (Port = 0; Port < 4; Port ++) { |
| 89 | DrivingStrength = BIT2; |
| 90 | if (Port < 2) { |
| 91 | RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFE1E78, (Port << 13) + DrivingStrength, StdHeader); |
| 92 | RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFE1E78, (Port << 13) + BIT8 + BIT7 + DrivingStrength, StdHeader); |
| 93 | RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFE0E78, (Port << 13) + BIT8 + BIT7 + DrivingStrength, StdHeader); |
| 94 | Register = FCH_XHCI_IND60_REG00; |
| 95 | Index = 0; |
| 96 | do { |
| 97 | WritePci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x48, AccessWidth32, &Register, StdHeader); |
| 98 | ReadPci ((USB_XHCI_BUS_DEV_FUN << 16) + 0x4C, AccessWidth32, &RegValue, StdHeader); |
| 99 | Index++; |
| 100 | FchStall (10, StdHeader); |
| 101 | } while ((RegValue & BIT17) && (Index < 10 )); |
| 102 | RwXhci0IndReg ( FCH_XHCI_IND60_REG00, 0xFFFFEFFF, 0x00001000, StdHeader); |
| 103 | } else { |
| 104 | RwXhci1IndReg ( FCH_XHCI_IND60_REG00, 0xFFFE1E78, ((Port - 2) << 13) + DrivingStrength, StdHeader); |
| 105 | RwXhci1IndReg ( FCH_XHCI_IND60_REG00, 0xFFFE1E78, ((Port - 2) << 13) + BIT8 + BIT7 + DrivingStrength, StdHeader); |
| 106 | RwXhci1IndReg ( FCH_XHCI_IND60_REG00, 0xFFFE0E78, ((Port - 2) << 13) + BIT8 + BIT7 + DrivingStrength, StdHeader); |
| 107 | Register = FCH_XHCI_IND60_REG00; |
| 108 | Index = 0; |
| 109 | do { |
| 110 | WritePci ((USB_XHCI1_BUS_DEV_FUN << 16) + 0x48, AccessWidth32, &Register, StdHeader); |
| 111 | ReadPci ((USB_XHCI1_BUS_DEV_FUN << 16) + 0x4C, AccessWidth32, &RegValue, StdHeader); |
| 112 | Index++; |
| 113 | FchStall (10, StdHeader); |
| 114 | } while ((RegValue & BIT17) && (Index < 10 )); |
| 115 | RwXhci1IndReg ( FCH_XHCI_IND60_REG00, 0xFFFFEFFF, 0x00001000, StdHeader); |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | // Step 3 |
| 120 | RwXhciIndReg ( FCH_XHCI_IND60_REG0C, ~ ((UINT32) (0x0f << 8)), ((UINT32) (0x02 << 8)), StdHeader); |
| 121 | RwXhciIndReg ( FCH_XHCI_IND60_REG08, ~ ((UINT32) (0xff << 8)), ((UINT32) (0x0f << 8)), StdHeader); |
| 122 | } |
| 123 | |
| 124 | /** |
| 125 | * XhciA12Fix - Config XHCI A12 Fix |
| 126 | * |
| 127 | * |
| 128 | */ |
| 129 | STATIC |
| 130 | VOID |
| 131 | XhciA12Fix ( |
| 132 | OUT VOID |
| 133 | ) |
| 134 | { |
| 135 | // |
| 136 | // PLUG/UNPLUG of USB 2.0 devices make the XHCI USB 2.0 ports unfunctional - fix enable |
| 137 | // ACPI_USB3.0_REG 0x20[12:11] = 2'b11 |
| 138 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, ~((UINT32) (0x3 << 11)), (UINT32) (0x3 << 11)); |
| 139 | // |
| 140 | // XHC 2 USB2 ports interactional issue - fix enable |
| 141 | // ACPI_USB3.0_REG 0x20[16] = 1'b1 |
| 142 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, ~((UINT32) (0x1 << 16)), (UINT32) (0x1 << 16)); |
| 143 | // |
| 144 | // XHC USB2.0 Ports suspend Enhancement |
| 145 | // ACPI_USB3.0_REG 0x20[15] = 1'b1 |
| 146 | // |
| 147 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, ~((UINT32) (0x1 << 15)), (UINT32) (0x1 << 15)); |
| 148 | // |
| 149 | // XHC HS/FS IN Data Buffer Underflow issue - fix enable |
| 150 | // ACPI_USB3.0_REG 0x20[20:18] = 0x7 |
| 151 | // |
| 152 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, ~((UINT32) (0x7 << 18)), (UINT32) (0x7 << 18)); |
| 153 | // |
| 154 | // XHC stuck in U3 after system resuming from S3 -fix enable |
| 155 | // ACPI_USB3.0_REG 0x98[19] = 1'b1 |
| 156 | // |
| 157 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG98, AccessWidth32, ~((UINT32) (0x1 << 19)), (UINT32) (0x1 << 19)); |
| 158 | // |
| 159 | // Change XHC1 ( Dev 16 function 1) Interrupt Pin register to INTB# - Fix enable |
| 160 | // ACPI_PMIO_F0[18] =1 |
| 161 | // |
| 162 | RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGF0, AccessWidth32, ~((UINT32) (0x1 << 18)), (UINT32) (0x1 << 18)); |
| 163 | // |
| 164 | // EHCI3/OHCI3 blocks Blink Global Clock Gating when EHCI/OHCI Dev 22 fn 0/2 are disabled |
| 165 | // ACPI_PMIO_F0[13] =1 |
| 166 | // |
| 167 | RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGF0, AccessWidth32, ~((UINT32) (0x1 << 13)), (UINT32) (0x1 << 13)); |
| 168 | // |
| 169 | // Access register through JTAG fail when switch from XHCI to EHCI/OHCI - Fix enable |
| 170 | // ACPI_PMIO_F0[17] =1 |
| 171 | // |
| 172 | RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGF0, AccessWidth32, ~((UINT32) (0x1 << 17)), (UINT32) (0x1 << 17)); |
| 173 | // |
| 174 | // USB leakage current on differential lines when ports are switched to XHCI - Fix enable |
| 175 | // ACPI_PMIO_F0[14] =1 |
| 176 | // |
| 177 | RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGF0, AccessWidth32, ~((UINT32) (0x1 << 14)), (UINT32) (0x1 << 14)); |
| 178 | } |
| 179 | |
| 180 | /** |
| 181 | * IsLpcRom - Is LPC Rom? |
| 182 | * |
| 183 | * |
| 184 | * @retval TRUE or FALSE |
| 185 | * |
| 186 | */ |
| 187 | BOOLEAN |
| 188 | IsLpcRom ( |
| 189 | OUT VOID |
| 190 | ) |
| 191 | { |
| 192 | return ( (BOOLEAN) ((ACPIMMIO32 (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG80) & BIT1) == 0) ); |
| 193 | } |
| 194 | |
| 195 | /** |
| 196 | * FchXhciInitBeforePciInit - Config XHCI controller before PCI |
| 197 | * emulation |
| 198 | * |
| 199 | * |
| 200 | * |
| 201 | * @param[in] FchDataPtr Fch configuration structure pointer. |
| 202 | * |
| 203 | */ |
| 204 | VOID |
| 205 | FchXhciInitBeforePciInit ( |
| 206 | IN FCH_DATA_BLOCK *FchDataPtr |
| 207 | ) |
| 208 | { |
| 209 | UINT16 BcdAddress; |
| 210 | UINT16 BcdSize; |
| 211 | UINT16 AcdAddress; |
| 212 | UINT16 AcdSize; |
| 213 | UINT16 FwAddress; |
| 214 | UINT16 FwSize; |
| 215 | UINTN XhciFwStarting; |
| 216 | UINT32 SpiValidBase; |
| 217 | UINT32 RegData; |
| 218 | UINT16 Index; |
| 219 | BOOLEAN Xhci0Enable; |
| 220 | BOOLEAN Xhci1Enable; |
| 221 | FCH_DATA_BLOCK *LocalCfgPtr; |
| 222 | AMD_CONFIG_PARAMS *StdHeader; |
| 223 | |
| 224 | LocalCfgPtr = (FCH_DATA_BLOCK *)FchDataPtr; |
| 225 | StdHeader = LocalCfgPtr->StdHeader; |
| 226 | Xhci0Enable = LocalCfgPtr->Usb.Xhci0Enable; |
| 227 | Xhci1Enable = LocalCfgPtr->Usb.Xhci1Enable; |
| 228 | |
| 229 | if (( Xhci0Enable == 0 ) && (Xhci1Enable == 0)) { |
| 230 | return; |
| 231 | } |
| 232 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, 0x00000000, 0x00400700); |
| 233 | FchStall (20, StdHeader); |
| 234 | |
| 235 | if ( LocalCfgPtr->Usb.UserDefineXhciRomAddr == 0 ) { |
| 236 | // |
| 237 | // Get ROM SIG starting address for USB firmware starting address (offset 0x0C to SIG address) |
| 238 | // |
| 239 | GetRomSigPtr (&XhciFwStarting, StdHeader); |
| 240 | |
| 241 | if (XhciFwStarting == 0) { |
| 242 | return; |
| 243 | } |
| 244 | XhciFwStarting = ACPIMMIO32 (XhciFwStarting + FW_TO_SIGADDR_OFFSET); |
| 245 | } else { |
| 246 | XhciFwStarting = ( UINTN ) LocalCfgPtr->Usb.UserDefineXhciRomAddr; |
| 247 | } |
| 248 | if (IsLpcRom ()) { |
| 249 | // |
| 250 | // XHCI firmware re-load |
| 251 | // |
| 252 | RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGCC, AccessWidth32, (UINT32)~BIT2, (UINT32)(BIT2 + BIT1 + BIT0), StdHeader); |
| 253 | RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGCC, AccessWidth32, 0x00000FFF, (UINT32) (XhciFwStarting), StdHeader); |
| 254 | } |
| 255 | |
| 256 | // |
| 257 | // Enable SuperSpeed receive special error case logic. 0x20 bit8 |
| 258 | // Enable USB2.0 RX_Valid Synchronization. 0x20 bit9 |
| 259 | // Enable USB2.0 DIN/SE0 Synchronization. 0x20 bit10 |
| 260 | // |
| 261 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, 0xFFFFF8FF, 0x00000700); |
| 262 | // |
| 263 | // SuperSpeed PHY Configuration (adaptation timer setting) |
| 264 | // XHC U1 LFPS Exit time |
| 265 | // |
| 266 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG90, AccessWidth32, 0xCFF00000, 0x000AAAAA); |
| 267 | //RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG90 + 0x40, AccessWidth32, 0xFFF00000, 0x000AAAAA); |
| 268 | |
| 269 | // |
| 270 | // Step 1. to enable Xhci IO and Firmware load mode |
| 271 | // |
| 272 | RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF, AccessWidth8, (UINT32)~(BIT4 + BIT5), 0); /// Disable Device 22 |
| 273 | RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF, AccessWidth8, (UINT32)~(BIT7), (UINT32)BIT7); /// Enable 2.0 devices |
| 274 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, 0xF0FFFFFC, (Xhci0Enable + (Xhci1Enable << 1)) & 0x03); |
| 275 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, 0xEFFFFFFF, 0x10000000); |
| 276 | |
| 277 | // |
| 278 | // Step 2. to read a portion of the USB3_APPLICATION_CODE from BIOS ROM area and program certain registers. |
| 279 | // |
| 280 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA0, AccessWidth32, 0x00000000, (SPI_HEAD_LENGTH << 16)); |
| 281 | |
| 282 | BcdAddress = ACPIMMIO16 (XhciFwStarting + BCD_ADDR_OFFSET); |
| 283 | BcdSize = ACPIMMIO16 (XhciFwStarting + BCD_SIZE_OFFSET); |
| 284 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA4, AccessWidth16, 0x0000, BcdAddress); |
| 285 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA4 + 2, AccessWidth16, 0x0000, BcdSize); |
| 286 | |
| 287 | AcdAddress = ACPIMMIO16 (XhciFwStarting + ACD_ADDR_OFFSET); |
| 288 | AcdSize = ACPIMMIO16 (XhciFwStarting + ACD_SIZE_OFFSET); |
| 289 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA8, AccessWidth16, 0x0000, AcdAddress); |
| 290 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA8 + 2, AccessWidth16, 0x0000, AcdSize); |
| 291 | |
| 292 | SpiValidBase = SPI_BASE2 (XhciFwStarting + 4) | SPI_BAR0_VLD | SPI_BASE0 | SPI_BAR1_VLD | SPI_BASE1 | SPI_BAR2_VLD; |
| 293 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB0, AccessWidth32, 0x00000000, SpiValidBase); |
| 294 | // |
| 295 | // Copy Type0/1/2 data block from ROM image to MMIO starting from 0xC0 |
| 296 | // |
| 297 | for (Index = 0; Index < SPI_HEAD_LENGTH; Index++) { |
| 298 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGC0 + Index, AccessWidth8, 0, ACPIMMIO8 (XhciFwStarting + Index)); |
| 299 | } |
| 300 | |
| 301 | for (Index = 0; Index < BcdSize; Index++) { |
| 302 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGC0 + SPI_HEAD_LENGTH + Index, AccessWidth8, 0, ACPIMMIO8 (XhciFwStarting + BcdAddress + Index)); |
| 303 | } |
| 304 | |
| 305 | for (Index = 0; Index < AcdSize; Index++) { |
| 306 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGC0 + SPI_HEAD_LENGTH + BcdSize + Index, AccessWidth8, 0, ACPIMMIO8 (XhciFwStarting + AcdAddress + Index)); |
| 307 | } |
| 308 | |
| 309 | // |
| 310 | // Step 3. to enable the instruction RAM preload functionality. |
| 311 | // |
| 312 | FwAddress = ACPIMMIO16 (XhciFwStarting + FW_ADDR_OFFSET); |
| 313 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth16, 0x0000, ACPIMMIO16 (XhciFwStarting + FwAddress)); |
| 314 | FwAddress += 2; |
| 315 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG04, AccessWidth16, 0x0000, FwAddress); |
| 316 | |
| 317 | FwSize = ACPIMMIO16 (XhciFwStarting + FW_SIZE_OFFSET); |
| 318 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG04 + 2, AccessWidth16, 0x0000, FwSize); |
| 319 | // |
| 320 | // Set the starting address offset for Instruction RAM preload. |
| 321 | // |
| 322 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG08, AccessWidth16, 0x0000, 0); |
| 323 | |
| 324 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~BIT29, (UINT32)BIT29); |
| 325 | |
| 326 | for (;;) { |
| 327 | ReadMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00 , AccessWidth32, &RegData); |
| 328 | if (RegData & BIT30) { |
| 329 | break; |
| 330 | } |
| 331 | } |
| 332 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~BIT29, 0); |
| 333 | |
| 334 | // |
| 335 | // Step 4. to release resets in XHCI_ACPI_MMIO_AMD_REG00. wait for USPLL to lock by polling USPLL lock. |
| 336 | // |
| 337 | |
| 338 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~U3PLL_RESET, 0); ///Release U3PLLreset |
| 339 | for (;;) { |
| 340 | ReadMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00 , AccessWidth32, &RegData); |
| 341 | if (RegData & U3PLL_LOCK) { |
| 342 | break; |
| 343 | } |
| 344 | } |
| 345 | |
| 346 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~U3PHY_RESET, 0); ///Release U3PHY |
| 347 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~U3CORE_RESET, 0); ///Release core reset |
| 348 | |
| 349 | // |
| 350 | // SuperSpeed PHY Configuration |
| 351 | // |
| 352 | //RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG90, AccessWidth32, 0xFFF00000, 0x000AAAAA); |
| 353 | //RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGD0, AccessWidth32, 0xFFF00000, 0x000AAAAA); |
| 354 | |
| 355 | FchXhciInitIndirectReg (StdHeader); |
| 356 | |
| 357 | RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF, AccessWidth8, (UINT32)~(BIT4 + BIT5), 0); /// Disable Device 22 |
| 358 | RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF, AccessWidth8, (UINT32)~(BIT7), (UINT32)BIT7); /// Enable 2.0 devices |
| 359 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~(BIT21), (UINT32)BIT21); |
| 360 | // |
| 361 | // Step 5. |
| 362 | // |
| 363 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~(BIT17 + BIT18 + BIT19), (UINT32)(BIT17 + BIT18)); |
| 364 | |
| 365 | XhciA12Fix (); |
| 366 | |
| 367 | // |
| 368 | // UMI Lane Configuration Information for XHCI Firmware to Calculate the Bandwidth for USB 3.0 ISOC Devices |
| 369 | // |
| 370 | if (!(IsUmiOneLaneGen1Mode (StdHeader))) { |
| 371 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, (UINT32)~(BIT25 + BIT24), (UINT32)BIT24); |
| 372 | } |
| 373 | // RPR 8.23 FS/LS devices not functional after resume from S4 fix enable (SB02699) |
| 374 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, (UINT32)~(BIT22), (UINT32)BIT22); |
| 375 | // RPR 8.24 XHC USB2.0 Hub disable issue fix enable (SB02702) |
| 376 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth32, (UINT32)~(BIT20), (UINT32)BIT20); |
| 377 | } |
| 378 | |
| 379 | /** |
| 380 | * FchXhciPowerSavingProgram - Config XHCI for Power Saving mode |
| 381 | * |
| 382 | * |
| 383 | * |
| 384 | * @param[in] FchDataPtr Fch configuration structure pointer. |
| 385 | * |
| 386 | */ |
| 387 | VOID |
| 388 | FchXhciPowerSavingProgram ( |
| 389 | IN FCH_DATA_BLOCK *FchDataPtr |
| 390 | ) |
| 391 | { |
| 392 | UINT8 XhciEfuse; |
| 393 | FCH_DATA_BLOCK *LocalCfgPtr; |
| 394 | AMD_CONFIG_PARAMS *StdHeader; |
| 395 | |
| 396 | LocalCfgPtr = (FCH_DATA_BLOCK *)FchDataPtr; |
| 397 | StdHeader = LocalCfgPtr->StdHeader; |
| 398 | |
| 399 | // add Efuse checking for Xhci enable/disable |
| 400 | XhciEfuse = XHCI_EFUSE_LOCATION; |
| 401 | GetEfuseStatus (&XhciEfuse, StdHeader); |
| 402 | if ((XhciEfuse & (BIT0 + BIT1)) != (BIT0 + BIT1)) { |
| 403 | RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, 0xF0FFFBFF, 0x0); |
| 404 | } |
| 405 | } |