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
PlatformUsbErratasPostMrc(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
PlatformErratasPostMrc(VOID)178 PlatformErratasPostMrc (
179   VOID
180   )
181 {
182   PlatformUsbErratasPostMrc ();
183   return EFI_SUCCESS;
184 }
185