1 /** @file 2 Platform Erratas performed by early init PEIM driver. 3 4 Copyright (c) 2013 Intel Corporation. 5 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 #include "CommonHeader.h" 17 #include "PlatformEarlyInit.h" 18 19 // 20 // Constants. 21 // 22 23 // 24 // Platform EHCI Packet Buffer OUT/IN Thresholds, values in number of DWORDs. 25 // 26 #define EHCI_OUT_THRESHOLD_VALUE (0x7f) 27 #define EHCI_IN_THRESHOLD_VALUE (0x7f) 28 29 // 30 // Platform init USB device interrupt masks. 31 // 32 #define V_IOH_USBDEVICE_D_INTR_MSK_UDC_REG (0x0000007f) 33 #define V_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG (B_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG_OUT_EP_MASK | B_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG_IN_EP_MASK) 34 35 // 36 // Global variables defined within this source module. 37 // 38 39 UINTN IohEhciPciReg[IOH_MAX_EHCI_USB_CONTROLLERS] = { 40 PCI_LIB_ADDRESS (IOH_USB_BUS_NUMBER, IOH_USB_EHCI_DEVICE_NUMBER, IOH_EHCI_FUNCTION_NUMBER, 0), 41 }; 42 43 UINTN IohUsbDevicePciReg[IOH_MAX_USBDEVICE_USB_CONTROLLERS] = { 44 PCI_LIB_ADDRESS (IOH_USB_BUS_NUMBER, IOH_USBDEVICE_DEVICE_NUMBER, IOH_USBDEVICE_FUNCTION_NUMBER, 0), 45 }; 46 47 // 48 // Routines local to this source module. 49 // 50 51 /** Perform USB erratas after MRC init. 52 53 **/ 54 VOID 55 PlatformUsbErratasPostMrc ( 56 VOID 57 ) 58 { 59 UINT32 Index; 60 UINT32 TempBar0Addr; 61 UINT16 SaveCmdReg; 62 UINT32 SaveBar0Reg; 63 64 TempBar0Addr = PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress); 65 66 // 67 // Apply EHCI controller erratas. 68 // 69 for (Index = 0; Index < IOH_MAX_EHCI_USB_CONTROLLERS; Index++, TempBar0Addr += IOH_USB_CONTROLLER_MMIO_RANGE) { 70 71 if ((PciRead16 (IohEhciPciReg[Index] + R_IOH_USB_VENDOR_ID)) != V_IOH_USB_VENDOR_ID) { 72 continue; // Device not enabled, skip. 73 } 74 75 // 76 // Save current settings for PCI CMD/BAR0 registers 77 // 78 SaveCmdReg = PciRead16 (IohEhciPciReg[Index] + R_IOH_USB_COMMAND); 79 SaveBar0Reg = PciRead32 (IohEhciPciReg[Index] + R_IOH_USB_MEMBAR); 80 81 // 82 // Temp. assign base address register, Enable Memory Space. 83 // 84 PciWrite32 ((IohEhciPciReg[Index] + R_IOH_USB_MEMBAR), TempBar0Addr); 85 PciWrite16 (IohEhciPciReg[Index] + R_IOH_USB_COMMAND, SaveCmdReg | B_IOH_USB_COMMAND_MSE); 86 87 88 // 89 // Set packet buffer OUT/IN thresholds. 90 // 91 MmioAndThenOr32 ( 92 TempBar0Addr + R_IOH_EHCI_INSNREG01, 93 (UINT32) (~(B_IOH_EHCI_INSNREG01_OUT_THRESHOLD_MASK | B_IOH_EHCI_INSNREG01_IN_THRESHOLD_MASK)), 94 (UINT32) ((EHCI_OUT_THRESHOLD_VALUE << B_IOH_EHCI_INSNREG01_OUT_THRESHOLD_BP) | (EHCI_IN_THRESHOLD_VALUE << B_IOH_EHCI_INSNREG01_IN_THRESHOLD_BP)) 95 ); 96 97 // 98 // Restore settings for PCI CMD/BAR0 registers 99 // 100 PciWrite32 ((IohEhciPciReg[Index] + R_IOH_USB_MEMBAR), SaveBar0Reg); 101 PciWrite16 (IohEhciPciReg[Index] + R_IOH_USB_COMMAND, SaveCmdReg); 102 } 103 104 // 105 // Apply USB device controller erratas. 106 // 107 for (Index = 0; Index < IOH_MAX_USBDEVICE_USB_CONTROLLERS; Index++, TempBar0Addr += IOH_USB_CONTROLLER_MMIO_RANGE) { 108 109 if ((PciRead16 (IohUsbDevicePciReg[Index] + R_IOH_USB_VENDOR_ID)) != V_IOH_USB_VENDOR_ID) { 110 continue; // Device not enabled, skip. 111 } 112 113 // 114 // Save current settings for PCI CMD/BAR0 registers 115 // 116 SaveCmdReg = PciRead16 (IohUsbDevicePciReg[Index] + R_IOH_USB_COMMAND); 117 SaveBar0Reg = PciRead32 (IohUsbDevicePciReg[Index] + R_IOH_USB_MEMBAR); 118 119 // 120 // Temp. assign base address register, Enable Memory Space. 121 // 122 PciWrite32 ((IohUsbDevicePciReg[Index] + R_IOH_USB_MEMBAR), TempBar0Addr); 123 PciWrite16 (IohUsbDevicePciReg[Index] + R_IOH_USB_COMMAND, SaveCmdReg | B_IOH_USB_COMMAND_MSE); 124 125 // 126 // Erratas for USB Device interrupt registers. 127 // 128 129 // 130 // 1st Mask interrupts. 131 // 132 MmioWrite32 ( 133 TempBar0Addr + R_IOH_USBDEVICE_D_INTR_MSK_UDC_REG, 134 V_IOH_USBDEVICE_D_INTR_MSK_UDC_REG 135 ); 136 // 137 // 2nd RW/1C of equivalent status bits. 138 // 139 MmioWrite32 ( 140 TempBar0Addr + R_IOH_USBDEVICE_D_INTR_UDC_REG, 141 V_IOH_USBDEVICE_D_INTR_MSK_UDC_REG 142 ); 143 144 // 145 // 1st Mask end point interrupts. 146 // 147 MmioWrite32 ( 148 TempBar0Addr + R_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG, 149 V_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG 150 ); 151 // 152 // 2nd RW/1C of equivalent end point status bits. 153 // 154 MmioWrite32 ( 155 TempBar0Addr + R_IOH_USBDEVICE_EP_INTR_UDC_REG, 156 V_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG 157 ); 158 159 // 160 // Restore settings for PCI CMD/BAR0 registers 161 // 162 PciWrite32 ((IohUsbDevicePciReg[Index] + R_IOH_USB_MEMBAR), SaveBar0Reg); 163 PciWrite16 (IohUsbDevicePciReg[Index] + R_IOH_USB_COMMAND, SaveCmdReg); 164 } 165 } 166 167 // 168 // Routines exported by this source module. 169 // 170 171 /** Perform Platform Erratas after MRC. 172 173 @retval EFI_SUCCESS Operation success. 174 175 **/ 176 EFI_STATUS 177 EFIAPI 178 PlatformErratasPostMrc ( 179 VOID 180 ) 181 { 182 PlatformUsbErratasPostMrc (); 183 return EFI_SUCCESS; 184 } 185