]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.c
MdeModulePkg: Change use of EFI_D_* to DEBUG_*
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / UfsPciHcPei / UfsPciHcPei.c
1 /** @file
2 UfsPciHcPei driver is used to provide platform-dependent info, mainly UFS host controller
3 MMIO base, to upper layer UFS drivers.
4
5 Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "UfsPciHcPei.h"
11
12 EDKII_UFS_HOST_CONTROLLER_PPI mUfsHostControllerPpi = { GetUfsHcMmioBar };
13
14 EFI_PEI_PPI_DESCRIPTOR mPpiList = {
15 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
16 &gEdkiiPeiUfsHostControllerPpiGuid,
17 &mUfsHostControllerPpi
18 };
19
20 /**
21 Get the MMIO base address of UFS host controller.
22
23 @param[in] This The protocol instance pointer.
24 @param[in] ControllerId The ID of the UFS host controller.
25 @param[out] MmioBar Pointer to the UFS host controller MMIO base address.
26
27 @retval EFI_SUCCESS The operation succeeds.
28 @retval EFI_INVALID_PARAMETER The parameters are invalid.
29
30 **/
31 EFI_STATUS
32 EFIAPI
33 GetUfsHcMmioBar (
34 IN EDKII_UFS_HOST_CONTROLLER_PPI *This,
35 IN UINT8 ControllerId,
36 OUT UINTN *MmioBar
37 )
38 {
39 UFS_HC_PEI_PRIVATE_DATA *Private;
40
41 if ((This == NULL) || (MmioBar == NULL)) {
42 return EFI_INVALID_PARAMETER;
43 }
44
45 Private = UFS_HC_PEI_PRIVATE_DATA_FROM_THIS (This);
46
47 if (ControllerId >= Private->TotalUfsHcs) {
48 return EFI_INVALID_PARAMETER;
49 }
50
51 *MmioBar = (UINTN)Private->UfsHcPciAddr[ControllerId];
52
53 return EFI_SUCCESS;
54 }
55
56 /**
57 The user code starts with this function.
58
59 @param FileHandle Handle of the file being invoked.
60 @param PeiServices Describes the list of possible PEI Services.
61
62 @retval EFI_SUCCESS The driver is successfully initialized.
63 @retval Others Can't initialize the driver.
64
65 **/
66 EFI_STATUS
67 EFIAPI
68 InitializeUfsHcPeim (
69 IN EFI_PEI_FILE_HANDLE FileHandle,
70 IN CONST EFI_PEI_SERVICES **PeiServices
71 )
72 {
73 EFI_BOOT_MODE BootMode;
74 EFI_STATUS Status;
75 UINT16 Bus;
76 UINT16 Device;
77 UINT16 Function;
78 UINT32 Size;
79 UINT64 MmioSize;
80 UINT32 BarAddr;
81 UINT8 SubClass;
82 UINT8 BaseClass;
83 UFS_HC_PEI_PRIVATE_DATA *Private;
84
85 //
86 // Shadow this PEIM to run from memory
87 //
88 if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) {
89 return EFI_SUCCESS;
90 }
91
92 Status = PeiServicesGetBootMode (&BootMode);
93 ///
94 /// We do not export this in S3 boot path, because it is only for recovery.
95 ///
96 if (BootMode == BOOT_ON_S3_RESUME) {
97 return EFI_SUCCESS;
98 }
99
100 Private = (UFS_HC_PEI_PRIVATE_DATA *) AllocateZeroPool (sizeof (UFS_HC_PEI_PRIVATE_DATA));
101 if (Private == NULL) {
102 DEBUG ((DEBUG_ERROR, "Failed to allocate memory for UFS_HC_PEI_PRIVATE_DATA! \n"));
103 return EFI_OUT_OF_RESOURCES;
104 }
105
106 Private->Signature = UFS_HC_PEI_SIGNATURE;
107 Private->UfsHostControllerPpi = mUfsHostControllerPpi;
108 Private->PpiList = mPpiList;
109 Private->PpiList.Ppi = &Private->UfsHostControllerPpi;
110
111 BarAddr = PcdGet32 (PcdUfsPciHostControllerMmioBase);
112 for (Bus = 0; Bus < 256; Bus++) {
113 for (Device = 0; Device < 32; Device++) {
114 for (Function = 0; Function < 8; Function++) {
115 SubClass = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x0A));
116 BaseClass = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x0B));
117
118 if ((SubClass == 0x09) && (BaseClass == PCI_CLASS_MASS_STORAGE)) {
119 //
120 // Get the Ufs Pci host controller's MMIO region size.
121 //
122 PciAnd16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET), (UINT16)~(EFI_PCI_COMMAND_BUS_MASTER | EFI_PCI_COMMAND_MEMORY_SPACE));
123 PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET), 0xFFFFFFFF);
124 Size = PciRead32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET));
125
126 switch (Size & 0x07) {
127 case 0x0:
128 //
129 // Memory space: anywhere in 32 bit address space
130 //
131 MmioSize = (~(Size & 0xFFFFFFF0)) + 1;
132 break;
133 case 0x4:
134 //
135 // Memory space: anywhere in 64 bit address space
136 //
137 MmioSize = Size & 0xFFFFFFF0;
138 PciWrite32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4), 0xFFFFFFFF);
139 Size = PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4));
140
141 //
142 // Fix the length to support some specific 64 bit BAR
143 //
144 Size |= ((UINT32)(-1) << HighBitSet32 (Size));
145
146 //
147 // Calculate the size of 64bit bar
148 //
149 MmioSize |= LShiftU64 ((UINT64) Size, 32);
150 MmioSize = (~(MmioSize)) + 1;
151
152 //
153 // Clean the high 32bits of this 64bit BAR to 0 as we only allow a 32bit BAR.
154 //
155 PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4), 0);
156 break;
157 default:
158 //
159 // Unknown BAR type
160 //
161 ASSERT (FALSE);
162 continue;
163 };
164 //
165 // Assign resource to the Ufs Pci host controller's MMIO BAR.
166 // Enable the Ufs Pci host controller by setting BME and MSE bits of PCI_CMD register.
167 //
168 PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET), BarAddr);
169 PciOr16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET), (EFI_PCI_COMMAND_BUS_MASTER | EFI_PCI_COMMAND_MEMORY_SPACE));
170 //
171 // Record the allocated Mmio base address.
172 //
173 Private->UfsHcPciAddr[Private->TotalUfsHcs] = BarAddr;
174 Private->TotalUfsHcs++;
175 BarAddr += (UINT32)MmioSize;
176 ASSERT (Private->TotalUfsHcs < MAX_UFS_HCS);
177 }
178 }
179 }
180 }
181
182 ///
183 /// Install Ufs Host Controller PPI
184 ///
185 Status = PeiServicesInstallPpi (&Private->PpiList);
186
187 ASSERT_EFI_ERROR (Status);
188 return Status;
189 }