]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[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 UINT8 SubClass;
80 UINT8 BaseClass;
81 UFS_HC_PEI_PRIVATE_DATA *Private;
82
83 //
84 // Shadow this PEIM to run from memory
85 //
86 if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) {
87 return EFI_SUCCESS;
88 }
89
90 Status = PeiServicesGetBootMode (&BootMode);
91 ///
92 /// We do not export this in S3 boot path, because it is only for recovery.
93 ///
94 if (BootMode == BOOT_ON_S3_RESUME) {
95 return EFI_SUCCESS;
96 }
97
98 Private = (UFS_HC_PEI_PRIVATE_DATA *) AllocateZeroPool (sizeof (UFS_HC_PEI_PRIVATE_DATA));
99 if (Private == NULL) {
100 DEBUG ((EFI_D_ERROR, "Failed to allocate memory for UFS_HC_PEI_PRIVATE_DATA! \n"));
101 return EFI_OUT_OF_RESOURCES;
102 }
103
104 Private->Signature = UFS_HC_PEI_SIGNATURE;
105 Private->UfsHostControllerPpi = mUfsHostControllerPpi;
106 Private->PpiList = mPpiList;
107 Private->PpiList.Ppi = &Private->UfsHostControllerPpi;
108
109 for (Bus = 0; Bus < 256; Bus++) {
110 for (Device = 0; Device < 32; Device++) {
111 for (Function = 0; Function < 8; Function++) {
112 SubClass = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x0A));
113 BaseClass = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x0B));
114
115 if ((SubClass == 0x09) && (BaseClass == PCI_CLASS_MASS_STORAGE)) {
116 //
117 // Get the Ufs Pci host controller's MMIO region size.
118 //
119 PciAnd16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET), (UINT16)~(EFI_PCI_COMMAND_BUS_MASTER | EFI_PCI_COMMAND_MEMORY_SPACE));
120 PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET), 0xFFFFFFFF);
121 Size = PciRead32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET));
122 //
123 // Assign resource to the Ufs Pci host controller's MMIO BAR.
124 // Enable the Ufs Pci host controller by setting BME and MSE bits of PCI_CMD register.
125 //
126 PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET), (UINT32)(PcdGet32 (PcdUfsPciHostControllerMmioBase) + Size * Private->TotalUfsHcs));
127 PciOr16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET), (EFI_PCI_COMMAND_BUS_MASTER | EFI_PCI_COMMAND_MEMORY_SPACE));
128 //
129 // Record the allocated Mmio base address.
130 //
131 Private->UfsHcPciAddr[Private->TotalUfsHcs] = PcdGet32 (PcdUfsPciHostControllerMmioBase) + Size * Private->TotalUfsHcs;
132 Private->TotalUfsHcs++;
133 ASSERT (Private->TotalUfsHcs < MAX_UFS_HCS);
134 }
135 }
136 }
137 }
138
139 ///
140 /// Install Ufs Host Controller PPI
141 ///
142 Status = PeiServicesInstallPpi (&Private->PpiList);
143
144 ASSERT_EFI_ERROR (Status);
145 return Status;
146 }