Home | History | Annotate | Download | only in DwUfsHcDxe
      1 /** @file
      2   UfsHcDxe 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 - 2015, Intel Corporation. All rights reserved.<BR>
      6   Copyright (c) 2016 - 2017, Linaro Ltd. All rights reserved.
      7 
      8   This program and the accompanying materials
      9   are licensed and made available under the terms and conditions of the BSD License
     10   which accompanies this distribution.  The full text of the license may be found at
     11   http://opensource.org/licenses/bsd-license.php.
     12 
     13   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     14   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     15 
     16 **/
     17 
     18 #include "DwUfsHcDxe.h"
     19 
     20 #include <IndustryStandard/Pci.h>
     21 
     22 #include <Protocol/PciIo.h>
     23 
     24 //
     25 // Ufs Host Controller Driver Binding Protocol Instance
     26 //
     27 EFI_DRIVER_BINDING_PROTOCOL gUfsHcDriverBinding = {
     28   UfsHcDriverBindingSupported,
     29   UfsHcDriverBindingStart,
     30   UfsHcDriverBindingStop,
     31   0x10,
     32   NULL,
     33   NULL
     34 };
     35 
     36 //
     37 // Template for Ufs host controller private data.
     38 //
     39 UFS_HOST_CONTROLLER_PRIVATE_DATA gUfsHcTemplate = {
     40   UFS_HC_PRIVATE_DATA_SIGNATURE,  // Signature
     41   NULL,                           // Handle
     42   {                               // UfsHcProtocol
     43     UfsHcGetMmioBar,
     44     UfsHcAllocateBuffer,
     45     UfsHcFreeBuffer,
     46     UfsHcMap,
     47     UfsHcUnmap,
     48     UfsHcFlush,
     49     UfsHcMmioRead,
     50     UfsHcMmioWrite,
     51     UfsHcPhyInit,
     52     UfsHcPhySetPowerMode,
     53   },
     54   0                               // RegBase
     55 };
     56 
     57 STATIC
     58 EFI_STATUS
     59 DwUfsDmeSet (
     60   IN  UINTN         RegBase,
     61   IN  UINT16        Attr,
     62   IN  UINT16        Index,
     63   IN  UINT32        Value
     64   )
     65 {
     66   UINT32            Data;
     67 
     68   Data = MmioRead32 (RegBase + UFS_HC_STATUS_OFFSET);
     69   if ((Data & UFS_HC_HCS_UCRDY) == 0) {
     70     return EFI_NOT_READY;
     71   }
     72   MmioWrite32 (RegBase + UFS_HC_IS_OFFSET, ~0);
     73   MmioWrite32 (RegBase + UFS_HC_UCMD_ARG1_OFFSET, (Attr << 16) | Index);
     74   MmioWrite32 (RegBase + UFS_HC_UCMD_ARG2_OFFSET, 0);
     75   MmioWrite32 (RegBase + UFS_HC_UCMD_ARG3_OFFSET, Value);
     76   MmioWrite32 (RegBase + UFS_HC_UIC_CMD_OFFSET, UFS_UIC_DME_SET);
     77   do {
     78     Data = MmioRead32 (RegBase + UFS_HC_IS_OFFSET);
     79     if (Data & UFS_HC_IS_UE) {
     80       return EFI_DEVICE_ERROR;
     81     }
     82   } while ((Data & UFS_HC_IS_UCCS) == 0);
     83   MmioWrite32 (RegBase + UFS_HC_IS_OFFSET, UFS_HC_IS_UCCS);
     84   Data = MmioRead32 (RegBase + UFS_HC_UCMD_ARG2_OFFSET);
     85   if (Data) {
     86     return EFI_DEVICE_ERROR;
     87   }
     88   return EFI_SUCCESS;
     89 }
     90 
     91 STATIC
     92 EFI_STATUS
     93 DwUfsDmeGet (
     94   IN  UINTN         RegBase,
     95   IN  UINT16        Attr,
     96   IN  UINT16        Index,
     97   OUT UINT32        *Value
     98   )
     99 {
    100   UINT32            Data;
    101 
    102   Data = MmioRead32 (RegBase + UFS_HC_STATUS_OFFSET);
    103   if ((Data & UFS_HC_HCS_UCRDY) == 0) {
    104     return EFI_NOT_READY;
    105   }
    106   MmioWrite32 (RegBase + UFS_HC_IS_OFFSET, ~0);
    107   MmioWrite32 (RegBase + UFS_HC_UCMD_ARG1_OFFSET, (Attr << 16) | Index);
    108   MmioWrite32 (RegBase + UFS_HC_UCMD_ARG2_OFFSET, 0);
    109   MmioWrite32 (RegBase + UFS_HC_UCMD_ARG3_OFFSET, 0);
    110   MmioWrite32 (RegBase + UFS_HC_UIC_CMD_OFFSET, UFS_UIC_DME_GET);
    111   do {
    112     Data = MmioRead32 (RegBase + UFS_HC_IS_OFFSET);
    113     if (Data & UFS_HC_IS_UE) {
    114       return EFI_DEVICE_ERROR;
    115     }
    116   } while ((Data & UFS_HC_IS_UCCS) == 0);
    117   MmioWrite32 (RegBase + UFS_HC_IS_OFFSET, UFS_HC_IS_UCCS);
    118   Data = MmioRead32 (RegBase + UFS_HC_UCMD_ARG2_OFFSET);
    119   if (Data) {
    120     return EFI_DEVICE_ERROR;
    121   }
    122   *Value = MmioRead32 (RegBase + UFS_HC_UCMD_ARG3_OFFSET);
    123   return EFI_SUCCESS;
    124 }
    125 
    126 /**
    127   Get the MMIO base of the UFS host controller.
    128 
    129   @param[in]   This             A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance.
    130   @param[out]  MmioBar          The MMIO base address of UFS host controller.
    131 
    132   @retval EFI_SUCCESS           The operation succeeds.
    133   @retval others                The operation fails.
    134 **/
    135 EFI_STATUS
    136 EFIAPI
    137 UfsHcGetMmioBar (
    138   IN     EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This,
    139      OUT UINTN                              *MmioBar
    140   )
    141 {
    142   UFS_HOST_CONTROLLER_PRIVATE_DATA  *Private;
    143 
    144   if ((This == NULL) || (MmioBar == NULL)) {
    145     return EFI_INVALID_PARAMETER;
    146   }
    147 
    148   Private  = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);
    149   *MmioBar = Private->RegBase;
    150   return EFI_SUCCESS;
    151 }
    152 
    153 /**
    154   Provides the UFS controller-specific addresses needed to access system memory.
    155 
    156   @param  This                  A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance.
    157   @param  Operation             Indicates if the bus master is going to read or write to system memory.
    158   @param  HostAddress           The system memory address to map to the UFS controller.
    159   @param  NumberOfBytes         On input the number of bytes to map. On output the number of bytes
    160                                 that were mapped.
    161   @param  DeviceAddress         The resulting map address for the bus master UFS controller to use to
    162                                 access the hosts HostAddress.
    163   @param  Mapping               A resulting value to pass to Unmap().
    164 
    165   @retval EFI_SUCCESS           The range was mapped for the returned NumberOfBytes.
    166   @retval EFI_UNSUPPORTED       The HostAddress cannot be mapped as a common buffer.
    167   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
    168   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
    169   @retval EFI_DEVICE_ERROR      The system hardware could not map the requested address.
    170 
    171 **/
    172 EFI_STATUS
    173 EFIAPI
    174 UfsHcMap (
    175   IN     EDKII_UFS_HOST_CONTROLLER_PROTOCOL   *This,
    176   IN     EDKII_UFS_HOST_CONTROLLER_OPERATION  Operation,
    177   IN     VOID                                 *HostAddress,
    178   IN OUT UINTN                                *NumberOfBytes,
    179      OUT EFI_PHYSICAL_ADDRESS                 *DeviceAddress,
    180      OUT VOID                                 **Mapping
    181   )
    182 {
    183   DMA_MAP_OPERATION   DmaOperation;
    184 
    185   if ((This == NULL) || (HostAddress == NULL) || (NumberOfBytes == NULL) || (DeviceAddress == NULL) || (Mapping == NULL)) {
    186     return EFI_INVALID_PARAMETER;
    187   }
    188 
    189   if (Operation == EdkiiUfsHcOperationBusMasterRead) {
    190     DmaOperation = MapOperationBusMasterRead;
    191   } else if (Operation == EdkiiUfsHcOperationBusMasterWrite) {
    192     DmaOperation = MapOperationBusMasterWrite;
    193   } else if (Operation == EdkiiUfsHcOperationBusMasterCommonBuffer) {
    194     DmaOperation = MapOperationBusMasterCommonBuffer;
    195   } else {
    196     return EFI_INVALID_PARAMETER;
    197   }
    198 
    199   if ((*NumberOfBytes & (BIT0 | BIT1)) != 0) {
    200     *NumberOfBytes += BIT0 | BIT1;
    201     *NumberOfBytes &= ~(BIT0 | BIT1);
    202   }
    203 
    204   return DmaMap (DmaOperation, HostAddress, NumberOfBytes, DeviceAddress, Mapping);
    205 }
    206 
    207 /**
    208   Completes the Map() operation and releases any corresponding resources.
    209 
    210   @param  This                  A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance.
    211   @param  Mapping               The mapping value returned from Map().
    212 
    213   @retval EFI_SUCCESS           The range was unmapped.
    214   @retval EFI_DEVICE_ERROR      The data was not committed to the target system memory.
    215 
    216 **/
    217 EFI_STATUS
    218 EFIAPI
    219 UfsHcUnmap (
    220   IN  EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This,
    221   IN  VOID                               *Mapping
    222   )
    223 {
    224   if ((This == NULL) || (Mapping == NULL)) {
    225     return EFI_INVALID_PARAMETER;
    226   }
    227 
    228   return DmaUnmap (Mapping);
    229 }
    230 
    231 /**
    232   Allocates pages that are suitable for an EfiUfsHcOperationBusMasterCommonBuffer
    233   mapping.
    234 
    235   @param  This                  A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance.
    236   @param  Type                  This parameter is not used and must be ignored.
    237   @param  MemoryType            The type of memory to allocate, EfiBootServicesData or
    238                                 EfiRuntimeServicesData.
    239   @param  Pages                 The number of pages to allocate.
    240   @param  HostAddress           A pointer to store the base system memory address of the
    241                                 allocated range.
    242   @param  Attributes            The requested bit mask of attributes for the allocated range.
    243 
    244   @retval EFI_SUCCESS           The requested memory pages were allocated.
    245   @retval EFI_UNSUPPORTED       Attributes is unsupported. The only legal attribute bits are
    246                                 MEMORY_WRITE_COMBINE and MEMORY_CACHED.
    247   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
    248   @retval EFI_OUT_OF_RESOURCES  The memory pages could not be allocated.
    249 
    250 **/
    251 EFI_STATUS
    252 EFIAPI
    253 UfsHcAllocateBuffer (
    254   IN     EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This,
    255   IN     EFI_ALLOCATE_TYPE                  Type,
    256   IN     EFI_MEMORY_TYPE                    MemoryType,
    257   IN     UINTN                              Pages,
    258      OUT VOID                               **HostAddress,
    259   IN     UINT64                             Attributes
    260   )
    261 {
    262   if ((This == NULL) || (HostAddress == NULL)) {
    263     return EFI_INVALID_PARAMETER;
    264   }
    265 
    266   return DmaAllocateBuffer (MemoryType, Pages, HostAddress);
    267 }
    268 
    269 /**
    270   Frees memory that was allocated with AllocateBuffer().
    271 
    272   @param  This                  A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance.
    273   @param  Pages                 The number of pages to free.
    274   @param  HostAddress           The base system memory address of the allocated range.
    275 
    276   @retval EFI_SUCCESS           The requested memory pages were freed.
    277   @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
    278                                 was not allocated with AllocateBuffer().
    279 
    280 **/
    281 EFI_STATUS
    282 EFIAPI
    283 UfsHcFreeBuffer (
    284   IN  EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This,
    285   IN  UINTN                              Pages,
    286   IN  VOID                               *HostAddress
    287   )
    288 {
    289   if ((This == NULL) || (HostAddress == NULL)) {
    290     return EFI_INVALID_PARAMETER;
    291   }
    292 
    293   return DmaFreeBuffer (Pages, HostAddress);
    294 }
    295 
    296 /**
    297   Flushes all posted write transactions from the UFS bus to attached UFS device.
    298 
    299   @param  This                  A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance.
    300 
    301   @retval EFI_SUCCESS           The posted write transactions were flushed from the UFS bus
    302                                 to attached UFS device.
    303   @retval EFI_DEVICE_ERROR      The posted write transactions were not flushed from the UFS
    304                                 bus to attached UFS device due to a hardware error.
    305 
    306 **/
    307 EFI_STATUS
    308 EFIAPI
    309 UfsHcFlush (
    310   IN  EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This
    311   )
    312 {
    313   return EFI_SUCCESS;
    314 }
    315 
    316 /**
    317   Enable a UFS bus driver to access UFS MMIO registers in the UFS Host Controller memory space.
    318 
    319   @param  This                  A pointer to the EDKII_UFS_HOST_CONTROLLER_PROTOCOL instance.
    320   @param  Width                 Signifies the width of the memory operations.
    321   @param  Offset                The offset within the UFS Host Controller MMIO space to start the
    322                                 memory operation.
    323   @param  Count                 The number of memory operations to perform.
    324   @param  Buffer                For read operations, the destination buffer to store the results.
    325                                 For write operations, the source buffer to write data from.
    326 
    327   @retval EFI_SUCCESS           The data was read from or written to the UFS host controller.
    328   @retval EFI_UNSUPPORTED       The address range specified by Offset, Width, and Count is not
    329                                 valid for the UFS Host Controller memory space.
    330   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
    331   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
    332 
    333 **/
    334 EFI_STATUS
    335 EFIAPI
    336 UfsHcMmioRead (
    337   IN     EDKII_UFS_HOST_CONTROLLER_PROTOCOL        *This,
    338   IN     EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH  Width,
    339   IN     UINT64                                    Offset,
    340   IN     UINTN                                     Count,
    341   IN OUT VOID                                      *Buffer
    342   )
    343 {
    344   UFS_HOST_CONTROLLER_PRIVATE_DATA  *Private;
    345   UINTN                             Index;
    346 
    347   Private  = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);
    348 
    349   switch (Width) {
    350   case EfiUfsHcWidthUint8:
    351     for (Index = 0; Index < Count; Index++) {
    352       *((UINT8 *)Buffer + Index) = MmioRead8 (Private->RegBase + Offset);
    353     }
    354     break;
    355   case EfiUfsHcWidthUint16:
    356     for (Index = 0; Index < Count; Index++) {
    357       *((UINT16 *)Buffer + Index) = MmioRead16 (Private->RegBase + Offset);
    358     }
    359     break;
    360   case EfiUfsHcWidthUint32:
    361     for (Index = 0; Index < Count; Index++) {
    362       *((UINT32 *)Buffer + Index) = MmioRead32 (Private->RegBase + Offset);
    363     }
    364     break;
    365   case EfiUfsHcWidthUint64:
    366     for (Index = 0; Index < Count; Index++) {
    367       *((UINT64 *)Buffer + Index) = MmioRead64 (Private->RegBase + Offset);
    368     }
    369     break;
    370   default:
    371     return EFI_INVALID_PARAMETER;
    372   }
    373 
    374   return EFI_SUCCESS;
    375 }
    376 
    377 /**
    378   Enable a UFS bus driver to access UFS MMIO registers in the UFS Host Controller memory space.
    379 
    380   @param  This                  A pointer to the EDKII_UFS_HOST_CONTROLLER_PROTOCOL instance.
    381   @param  Width                 Signifies the width of the memory operations.
    382   @param  Offset                The offset within the UFS Host Controller MMIO space to start the
    383                                 memory operation.
    384   @param  Count                 The number of memory operations to perform.
    385   @param  Buffer                For read operations, the destination buffer to store the results.
    386                                 For write operations, the source buffer to write data from.
    387 
    388   @retval EFI_SUCCESS           The data was read from or written to the UFS host controller.
    389   @retval EFI_UNSUPPORTED       The address range specified by Offset, Width, and Count is not
    390                                 valid for the UFS Host Controller memory space.
    391   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
    392   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
    393 
    394 **/
    395 EFI_STATUS
    396 EFIAPI
    397 UfsHcMmioWrite (
    398   IN     EDKII_UFS_HOST_CONTROLLER_PROTOCOL        *This,
    399   IN     EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH  Width,
    400   IN     UINT64                                    Offset,
    401   IN     UINTN                                     Count,
    402   IN OUT VOID                                      *Buffer
    403   )
    404 {
    405   UFS_HOST_CONTROLLER_PRIVATE_DATA  *Private;
    406   EFI_STATUS                        Status = EFI_SUCCESS;
    407   UINTN                             Index;
    408 
    409   Private  = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);
    410 
    411   switch (Width) {
    412   case EfiUfsHcWidthUint8:
    413     for (Index = 0; Index < Count; Index++) {
    414       Status = MmioWrite8 (Private->RegBase + Offset, *((UINT8 *)Buffer + Index));
    415     }
    416     break;
    417   case EfiUfsHcWidthUint16:
    418     for (Index = 0; Index < Count; Index++) {
    419       Status = MmioWrite16 (Private->RegBase + Offset, *((UINT16 *)Buffer + Index));
    420     }
    421     break;
    422   case EfiUfsHcWidthUint32:
    423     for (Index = 0; Index < Count; Index++) {
    424       Status = MmioWrite32 (Private->RegBase + Offset, *((UINT32 *)Buffer + Index));
    425     }
    426     break;
    427   case EfiUfsHcWidthUint64:
    428     for (Index = 0; Index < Count; Index++) {
    429       Status = MmioWrite64 (Private->RegBase + Offset, *((UINT64 *)Buffer + Index));
    430     }
    431     break;
    432   default:
    433     return EFI_INVALID_PARAMETER;
    434   }
    435 
    436   return Status;
    437 }
    438 
    439 EFI_STATUS
    440 EFIAPI
    441 UfsHcPhyInit (
    442   IN     EDKII_UFS_HOST_CONTROLLER_PROTOCOL        *This
    443   )
    444 {
    445   UFS_HOST_CONTROLLER_PRIVATE_DATA  *Private;
    446   EFI_STATUS                        Status;
    447   UINT32                            Data, Fsm0, Fsm1;
    448 
    449   Private  = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);
    450   DwUfsDmeSet (Private->RegBase, 0xd0c1, 0, 1);
    451   DwUfsDmeSet (Private->RegBase, 0xd0c1, 0, 1);
    452   DwUfsDmeSet (Private->RegBase, 0x156a, 0, 2);
    453   DwUfsDmeSet (Private->RegBase, 0x8114, 0, 1);
    454   DwUfsDmeSet (Private->RegBase, 0x8121, 0, 0x2d);
    455   DwUfsDmeSet (Private->RegBase, 0x8122, 0, 1);
    456   DwUfsDmeSet (Private->RegBase, 0xd085, 0, 1);
    457   DwUfsDmeSet (Private->RegBase, 0x800d, 4, 0x58);
    458   DwUfsDmeSet (Private->RegBase, 0x800d, 5, 0x58);
    459   DwUfsDmeSet (Private->RegBase, 0x800e, 4, 0xb);
    460   DwUfsDmeSet (Private->RegBase, 0x800e, 5, 0xb);
    461   DwUfsDmeSet (Private->RegBase, 0x8009, 4, 0x1);
    462   DwUfsDmeSet (Private->RegBase, 0x8009, 5, 0x1);
    463   DwUfsDmeSet (Private->RegBase, 0xd085, 0, 1);
    464   DwUfsDmeSet (Private->RegBase, 0x8113, 0, 1);
    465   DwUfsDmeSet (Private->RegBase, 0xd085, 0, 1);
    466   DwUfsDmeSet (Private->RegBase, 0x0095, 4, 0x4a);
    467   DwUfsDmeSet (Private->RegBase, 0x0095, 5, 0x4a);
    468   DwUfsDmeSet (Private->RegBase, 0x0094, 4, 0x4a);
    469   DwUfsDmeSet (Private->RegBase, 0x0094, 5, 0x4a);
    470   DwUfsDmeSet (Private->RegBase, 0x008f, 4, 0x7);
    471   DwUfsDmeSet (Private->RegBase, 0x008f, 5, 0x7);
    472   DwUfsDmeSet (Private->RegBase, 0x000f, 0, 0x5);
    473   DwUfsDmeSet (Private->RegBase, 0x000f, 1, 0x5);
    474   DwUfsDmeSet (Private->RegBase, 0xd085, 0, 1);
    475 
    476   Status = DwUfsDmeGet (Private->RegBase, 0xd0c1, 0, &Data);
    477   ASSERT_EFI_ERROR (Status);
    478   ASSERT (Data == 1);
    479 
    480   DwUfsDmeSet (Private->RegBase, 0xd0c1, 0, 0);
    481   for (;;) {
    482     Status = DwUfsDmeGet (Private->RegBase, 0x0041, 0, &Fsm0);
    483     ASSERT_EFI_ERROR (Status);
    484     Status = DwUfsDmeGet (Private->RegBase, 0x0041, 1, &Fsm1);
    485     ASSERT_EFI_ERROR (Status);
    486     if ((Fsm0 == 1) && (Fsm1 == 1)) {
    487       break;
    488     }
    489   }
    490 
    491   MmioWrite32 (Private->RegBase + UFS_HC_HCLKDIV_OFFSET, 0xE4);
    492   Data = MmioRead32 (Private->RegBase + UFS_HC_AHIT_OFFSET);
    493   Data &= ~0x3FF;
    494   MmioWrite32 (Private->RegBase + UFS_HC_AHIT_OFFSET, Data);
    495 
    496   DwUfsDmeSet (Private->RegBase, 0x155e, 0, 0);
    497   DwUfsDmeSet (Private->RegBase, 0xd0ab, 0, 0);
    498 
    499   Status = DwUfsDmeGet (Private->RegBase, 0xd0ab, 0, &Data);
    500   ASSERT_EFI_ERROR ((Status) && (Data == 0));
    501 
    502   DwUfsDmeSet (Private->RegBase, 0x2044, 0, 0);
    503   DwUfsDmeSet (Private->RegBase, 0x2045, 0, 0);
    504   DwUfsDmeSet (Private->RegBase, 0x2040, 0, 9);
    505   return EFI_SUCCESS;
    506 }
    507 
    508 EFI_STATUS
    509 EFIAPI
    510 UfsHcPhySetPowerMode (
    511   IN     EDKII_UFS_HOST_CONTROLLER_PROTOCOL        *This
    512   )
    513 {
    514   UFS_HOST_CONTROLLER_PRIVATE_DATA  *Private;
    515   UINT32                            Data, TxLanes, RxLanes;
    516 
    517   Private  = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);
    518   // PA_Tactive
    519   DwUfsDmeGet (Private->RegBase, 0x15A8, 0, &Data);
    520   if (Data < 7) {
    521     DwUfsDmeSet (Private->RegBase, 0x15A8, 4, 7);
    522   }
    523   DwUfsDmeGet (Private->RegBase, 0x1561, 0, &TxLanes);
    524   DwUfsDmeGet (Private->RegBase, 0x1581, 0, &RxLanes);
    525 
    526   // PA TxSkip
    527   DwUfsDmeSet (Private->RegBase, 0x155C, 0, 0);
    528   // PA TxGear
    529   DwUfsDmeSet (Private->RegBase, 0x1568, 0, 3);
    530   // PA RxGear
    531   DwUfsDmeSet (Private->RegBase, 0x1583, 0, 3);
    532   // PA HSSeries
    533   DwUfsDmeSet (Private->RegBase, 0x156A, 0, 2);
    534   // PA TxTermination
    535   DwUfsDmeSet (Private->RegBase, 0x1569, 0, 1);
    536   // PA RxTermination
    537   DwUfsDmeSet (Private->RegBase, 0x1584, 0, 1);
    538   // PA Scrambling
    539   DwUfsDmeSet (Private->RegBase, 0x1585, 0, 0);
    540   // PA ActiveTxDataLines
    541   DwUfsDmeSet (Private->RegBase, 0x1560, 0, TxLanes);
    542   // PA ActiveRxDataLines
    543   DwUfsDmeSet (Private->RegBase, 0x1580, 0, RxLanes);
    544   // PA_PWRModeUserData0 = 8191
    545   DwUfsDmeSet (Private->RegBase, 0x15B0, 0, 8191);
    546   // PA_PWRModeUserData1 = 65535
    547   DwUfsDmeSet (Private->RegBase, 0x15B1, 0, 65535);
    548   // PA_PWRModeUserData2 = 32767
    549   DwUfsDmeSet (Private->RegBase, 0x15B2, 0, 32767);
    550   // DME_FC0ProtectionTimeOutVal = 8191
    551   DwUfsDmeSet (Private->RegBase, 0xD041, 0, 8191);
    552   // DME_TC0ReplayTimeOutVal = 65535
    553   DwUfsDmeSet (Private->RegBase, 0xD042, 0, 65535);
    554   // DME_AFC0ReqTimeOutVal = 32767
    555   DwUfsDmeSet (Private->RegBase, 0xD043, 0, 32767);
    556   // PA_PWRModeUserData3 = 8191
    557   DwUfsDmeSet (Private->RegBase, 0x15B3, 0, 8191);
    558   // PA_PWRModeUserData4 = 65535
    559   DwUfsDmeSet (Private->RegBase, 0x15B4, 0, 65535);
    560   // PA_PWRModeUserData5 = 32767
    561   DwUfsDmeSet (Private->RegBase, 0x15B5, 0, 32767);
    562   // DME_FC1ProtectionTimeOutVal = 8191
    563   DwUfsDmeSet (Private->RegBase, 0xD044, 0, 8191);
    564   // DME_TC1ReplayTimeOutVal = 65535
    565   DwUfsDmeSet (Private->RegBase, 0xD045, 0, 65535);
    566   // DME_AFC1ReqTimeOutVal = 32767
    567   DwUfsDmeSet (Private->RegBase, 0xD046, 0, 32767);
    568 
    569   DwUfsDmeSet (Private->RegBase, 0x1571, 0, 0x11);
    570   do {
    571     Data = MmioRead32(Private->RegBase + UFS_HC_IS_OFFSET);
    572   } while ((Data & UFS_INT_UPMS) == 0);
    573   MmioWrite32(Private->RegBase + UFS_HC_IS_OFFSET, UFS_INT_UPMS);
    574   Data = MmioRead32(Private->RegBase + UFS_HC_STATUS_OFFSET);
    575   if ((Data & HCS_UPMCRS_MASK) == HCS_PWR_LOCAL) {
    576     DEBUG ((DEBUG_INFO, "ufs: change power mode success\n"));
    577   } else {
    578     DEBUG ((DEBUG_ERROR, "ufs: HCS.UPMCRS error, HCS:0x%x\n", Data));
    579   }
    580   return EFI_SUCCESS;
    581 }
    582 
    583 /**
    584   Tests to see if this driver supports a given controller. If a child device is provided,
    585   it further tests to see if this driver supports creating a handle for the specified child device.
    586 
    587   This function checks to see if the driver specified by This supports the device specified by
    588   ControllerHandle. Drivers will typically use the device path attached to
    589   ControllerHandle and/or the services from the bus I/O abstraction attached to
    590   ControllerHandle to determine if the driver supports ControllerHandle. This function
    591   may be called many times during platform initialization. In order to reduce boot times, the tests
    592   performed by this function must be very small, and take as little time as possible to execute. This
    593   function must not change the state of any hardware devices, and this function must be aware that the
    594   device specified by ControllerHandle may already be managed by the same driver or a
    595   different driver. This function must match its calls to AllocatePages() with FreePages(),
    596   AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
    597   Since ControllerHandle may have been previously started by the same driver, if a protocol is
    598   already in the opened state, then it must not be closed with CloseProtocol(). This is required
    599   to guarantee the state of ControllerHandle is not modified by this function.
    600 
    601   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
    602   @param[in]  ControllerHandle     The handle of the controller to test. This handle
    603                                    must support a protocol interface that supplies
    604                                    an I/O abstraction to the driver.
    605   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
    606                                    parameter is ignored by device drivers, and is optional for bus
    607                                    drivers. For bus drivers, if this parameter is not NULL, then
    608                                    the bus driver must determine if the bus controller specified
    609                                    by ControllerHandle and the child controller specified
    610                                    by RemainingDevicePath are both supported by this
    611                                    bus driver.
    612 
    613   @retval EFI_SUCCESS              The device specified by ControllerHandle and
    614                                    RemainingDevicePath is supported by the driver specified by This.
    615   @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
    616                                    RemainingDevicePath is already being managed by the driver
    617                                    specified by This.
    618   @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
    619                                    RemainingDevicePath is already being managed by a different
    620                                    driver or an application that requires exclusive access.
    621                                    Currently not implemented.
    622   @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
    623                                    RemainingDevicePath is not supported by the driver specified by This.
    624 **/
    625 EFI_STATUS
    626 EFIAPI
    627 UfsHcDriverBindingSupported (
    628   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
    629   IN EFI_HANDLE                   Controller,
    630   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
    631   )
    632 {
    633   EFI_STATUS                Status;
    634   BOOLEAN                   UfsHcFound;
    635   EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath = NULL;
    636   EFI_PCI_IO_PROTOCOL       *PciIo = NULL;
    637   PCI_TYPE00                PciData;
    638 
    639   ParentDevicePath = NULL;
    640   UfsHcFound       = FALSE;
    641 
    642   //
    643   // UfsHcDxe is a device driver, and should ingore the
    644   // "RemainingDevicePath" according to EFI spec
    645   //
    646   Status = gBS->OpenProtocol (
    647                   Controller,
    648                   &gEfiDevicePathProtocolGuid,
    649                   (VOID *) &ParentDevicePath,
    650                   This->DriverBindingHandle,
    651                   Controller,
    652                   EFI_OPEN_PROTOCOL_BY_DRIVER
    653                   );
    654   if (EFI_ERROR (Status)) {
    655     //
    656     // EFI_ALREADY_STARTED is also an error
    657     //
    658     return Status;
    659   }
    660   //
    661   // Close the protocol because we don't use it here
    662   //
    663   gBS->CloseProtocol (
    664         Controller,
    665         &gEfiDevicePathProtocolGuid,
    666         This->DriverBindingHandle,
    667         Controller
    668         );
    669 
    670   //
    671   // Now test the EfiPciIoProtocol
    672   //
    673   Status = gBS->OpenProtocol (
    674                   Controller,
    675                   &gEfiPciIoProtocolGuid,
    676                   (VOID **) &PciIo,
    677                   This->DriverBindingHandle,
    678                   Controller,
    679                   EFI_OPEN_PROTOCOL_BY_DRIVER
    680                   );
    681   if (EFI_ERROR (Status)) {
    682     return Status;
    683   }
    684   //
    685   // Now further check the PCI header: Base class (offset 0x0B) and
    686   // Sub Class (offset 0x0A). This controller should be an UFS controller
    687   //
    688   Status = PciIo->Pci.Read (
    689                         PciIo,
    690                         EfiPciIoWidthUint8,
    691                         0,
    692                         sizeof (PciData),
    693                         &PciData
    694                         );
    695   if (EFI_ERROR (Status)) {
    696     gBS->CloseProtocol (
    697           Controller,
    698           &gEfiPciIoProtocolGuid,
    699           This->DriverBindingHandle,
    700           Controller
    701           );
    702     return EFI_UNSUPPORTED;
    703   }
    704 
    705   //
    706   // Since we already got the PciData, we can close protocol to avoid to carry it on for multiple exit points.
    707   //
    708   gBS->CloseProtocol (
    709         Controller,
    710         &gEfiPciIoProtocolGuid,
    711         This->DriverBindingHandle,
    712         Controller
    713         );
    714 
    715   //
    716   // Examine UFS Host Controller PCI Configuration table fields
    717   //
    718   if (PciData.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE) {
    719     if (PciData.Hdr.ClassCode[1] == 0x09 ) { //UFS Controller Subclass
    720       UfsHcFound = TRUE;
    721     }
    722   }
    723 
    724   if (!UfsHcFound) {
    725     return EFI_UNSUPPORTED;
    726   }
    727 
    728   return Status;
    729 }
    730 
    731 /**
    732   Starts a device controller or a bus controller.
    733 
    734   The Start() function is designed to be invoked from the EFI boot service ConnectController().
    735   As a result, much of the error checking on the parameters to Start() has been moved into this
    736   common boot service. It is legal to call Start() from other locations,
    737   but the following calling restrictions must be followed or the system behavior will not be deterministic.
    738   1. ControllerHandle must be a valid EFI_HANDLE.
    739   2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
    740      EFI_DEVICE_PATH_PROTOCOL.
    741   3. Prior to calling Start(), the Supported() function for the driver specified by This must
    742      have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
    743 
    744   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
    745   @param[in]  ControllerHandle     The handle of the controller to start. This handle
    746                                    must support a protocol interface that supplies
    747                                    an I/O abstraction to the driver.
    748   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
    749                                    parameter is ignored by device drivers, and is optional for bus
    750                                    drivers. For a bus driver, if this parameter is NULL, then handles
    751                                    for all the children of Controller are created by this driver.
    752                                    If this parameter is not NULL and the first Device Path Node is
    753                                    not the End of Device Path Node, then only the handle for the
    754                                    child device specified by the first Device Path Node of
    755                                    RemainingDevicePath is created by this driver.
    756                                    If the first Device Path Node of RemainingDevicePath is
    757                                    the End of Device Path Node, no child handle is created by this
    758                                    driver.
    759 
    760   @retval EFI_SUCCESS              The device was started.
    761   @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
    762   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
    763   @retval Others                   The driver failded to start the device.
    764 
    765 **/
    766 EFI_STATUS
    767 EFIAPI
    768 UfsHcDriverBindingStart (
    769   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
    770   IN EFI_HANDLE                   Controller,
    771   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
    772   )
    773 {
    774   EFI_STATUS                        Status;
    775   EFI_PCI_IO_PROTOCOL               *PciIo;
    776   UFS_HOST_CONTROLLER_PRIVATE_DATA  *Private;
    777   UINT64                            Supports;
    778   UINT8                             BarIndex;
    779   EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc;
    780   UINT32                            BaseAddress;
    781 
    782   PciIo    = NULL;
    783   Private  = NULL;
    784   Supports = 0;
    785   BarDesc  = NULL;
    786   BaseAddress = PcdGet32 (PcdDwUfsHcDxeBaseAddress);
    787 
    788   //
    789   // Now test and open the EfiPciIoProtocol
    790   //
    791   Status = gBS->OpenProtocol (
    792                   Controller,
    793                   &gEfiPciIoProtocolGuid,
    794                   (VOID **) &PciIo,
    795                   This->DriverBindingHandle,
    796                   Controller,
    797                   EFI_OPEN_PROTOCOL_BY_DRIVER
    798                   );
    799   //
    800   // Status == 0 - A normal execution flow, SUCCESS and the program proceeds.
    801   // Status == ALREADY_STARTED - A non-zero Status code returned. It indicates
    802   //           that the protocol has been opened and should be treated as a
    803   //           normal condition and the program proceeds. The Protocol will not
    804   //           opened 'again' by this call.
    805   // Status != ALREADY_STARTED - Error status, terminate program execution
    806   //
    807   if (EFI_ERROR (Status)) {
    808     //
    809     // EFI_ALREADY_STARTED is also an error
    810     //
    811     return Status;
    812   }
    813 
    814   //BaseAddress = PcdGet32 (PcdDwUfsHcDxeBaseAddress);
    815   Private = AllocateCopyPool (sizeof (UFS_HOST_CONTROLLER_PRIVATE_DATA), &gUfsHcTemplate);
    816   if (Private == NULL) {
    817     Status = EFI_OUT_OF_RESOURCES;
    818     goto Done;
    819   }
    820 
    821   Private->RegBase = (UINTN)BaseAddress;
    822   Private->PciIo = PciIo;
    823 
    824   for (BarIndex = 0; BarIndex < PCI_MAX_BAR; BarIndex++) {
    825     Status = PciIo->GetBarAttributes (
    826                       PciIo,
    827                       BarIndex,
    828                       NULL,
    829                       (VOID**) &BarDesc
    830                       );
    831     if (Status == EFI_UNSUPPORTED) {
    832       continue;
    833     } else if (EFI_ERROR (Status)) {
    834       goto Done;
    835     }
    836 
    837     if (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
    838       Private->BarIndex = BarIndex;
    839       FreePool (BarDesc);
    840       break;
    841     }
    842 
    843     FreePool (BarDesc);
    844   }
    845 
    846   Status = PciIo->Attributes (
    847                     PciIo,
    848                     EfiPciIoAttributeOperationGet,
    849                     0,
    850                     &Private->PciAttributes
    851                     );
    852 
    853   if (EFI_ERROR (Status)) {
    854     goto Done;
    855   }
    856 
    857   Status = PciIo->Attributes (
    858                     PciIo,
    859                     EfiPciIoAttributeOperationSupported,
    860                     0,
    861                     &Supports
    862                     );
    863 
    864   if (!EFI_ERROR (Status)) {
    865     Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
    866     Status    = PciIo->Attributes (
    867                          PciIo,
    868                          EfiPciIoAttributeOperationEnable,
    869                          Supports,
    870                          NULL
    871                          );
    872   } else {
    873     goto Done;
    874   }
    875 
    876   ///
    877   /// Install UFS_HOST_CONTROLLER protocol
    878   ///
    879   Status = gBS->InstallProtocolInterface (
    880                   &Controller,
    881                   &gEdkiiUfsHostControllerProtocolGuid,
    882                   EFI_NATIVE_INTERFACE,
    883                   (VOID*)&(Private->UfsHc)
    884                   );
    885 
    886 Done:
    887   if (EFI_ERROR (Status)) {
    888     if ((Private != NULL) && (Private->PciAttributes != 0)) {
    889       //
    890       // Restore original PCI attributes
    891       //
    892       Status = PciIo->Attributes (
    893                         PciIo,
    894                         EfiPciIoAttributeOperationSet,
    895                         Private->PciAttributes,
    896                         NULL
    897                         );
    898       ASSERT_EFI_ERROR (Status);
    899     }
    900     gBS->CloseProtocol (
    901           Controller,
    902           &gEfiPciIoProtocolGuid,
    903           This->DriverBindingHandle,
    904           Controller
    905           );
    906     if (Private != NULL) {
    907       FreePool (Private);
    908     }
    909   }
    910 
    911   return Status;
    912 }
    913 
    914 /**
    915   Stops a device controller or a bus controller.
    916 
    917   The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
    918   As a result, much of the error checking on the parameters to Stop() has been moved
    919   into this common boot service. It is legal to call Stop() from other locations,
    920   but the following calling restrictions must be followed or the system behavior will not be deterministic.
    921   1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
    922      same driver's Start() function.
    923   2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
    924      EFI_HANDLE. In addition, all of these handles must have been created in this driver's
    925      Start() function, and the Start() function must have called OpenProtocol() on
    926      ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
    927 
    928   @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
    929   @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
    930                                 support a bus specific I/O protocol for the driver
    931                                 to use to stop the device.
    932   @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
    933   @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
    934                                 if NumberOfChildren is 0.
    935 
    936   @retval EFI_SUCCESS           The device was stopped.
    937   @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
    938 
    939 **/
    940 EFI_STATUS
    941 EFIAPI
    942 UfsHcDriverBindingStop (
    943   IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
    944   IN  EFI_HANDLE                      Controller,
    945   IN  UINTN                           NumberOfChildren,
    946   IN  EFI_HANDLE                      *ChildHandleBuffer
    947   )
    948 {
    949   EFI_STATUS                          Status;
    950   UFS_HOST_CONTROLLER_PRIVATE_DATA    *Private;
    951   EDKII_UFS_HOST_CONTROLLER_PROTOCOL  *UfsHc;
    952 
    953   ///
    954   /// Get private data
    955   ///
    956   Status = gBS->OpenProtocol (
    957                   Controller,
    958                   &gEdkiiUfsHostControllerProtocolGuid,
    959                   (VOID **) &UfsHc,
    960                   This->DriverBindingHandle,
    961                   Controller,
    962                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    963                   );
    964 
    965   if (EFI_ERROR (Status)) {
    966     return EFI_DEVICE_ERROR;
    967   }
    968 
    969   Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (UfsHc);
    970 
    971   Status = gBS->UninstallProtocolInterface (
    972                   Controller,
    973                   &gEdkiiUfsHostControllerProtocolGuid,
    974                   &(Private->UfsHc)
    975                   );
    976   if (!EFI_ERROR (Status)) {
    977     //
    978     // Restore original PCI attributes
    979     //
    980     Status = Private->PciIo->Attributes (
    981                                Private->PciIo,
    982                                EfiPciIoAttributeOperationSet,
    983                                Private->PciAttributes,
    984                                NULL
    985                                );
    986     ASSERT_EFI_ERROR (Status);
    987 
    988     //
    989     // Close protocols opened by UFS host controller driver
    990     //
    991     gBS->CloseProtocol (
    992            Controller,
    993            &gEfiPciIoProtocolGuid,
    994            This->DriverBindingHandle,
    995            Controller
    996            );
    997 
    998     FreePool (Private);
    999   }
   1000 
   1001   return Status;
   1002 }
   1003 
   1004 /**
   1005   The entry point for UFS host controller driver, used to install this driver on the ImageHandle.
   1006 
   1007   @param[in]  ImageHandle   The firmware allocated handle for this driver image.
   1008   @param[in]  SystemTable   Pointer to the EFI system table.
   1009 
   1010   @retval EFI_SUCCESS   Driver loaded.
   1011   @retval other         Driver not loaded.
   1012 
   1013 **/
   1014 EFI_STATUS
   1015 EFIAPI
   1016 UfsHcDriverEntry (
   1017   IN EFI_HANDLE        ImageHandle,
   1018   IN EFI_SYSTEM_TABLE  *SystemTable
   1019   )
   1020 {
   1021   EFI_STATUS           Status;
   1022 
   1023   Status = EfiLibInstallDriverBindingComponentName2 (
   1024              ImageHandle,
   1025              SystemTable,
   1026              &gUfsHcDriverBinding,
   1027              ImageHandle,
   1028              &gUfsHcComponentName,
   1029              &gUfsHcComponentName2
   1030              );
   1031   ASSERT_EFI_ERROR (Status);
   1032 
   1033   return Status;
   1034 }
   1035