mirror of https://github.com/acidanthera/audk.git
MdeModulePkg/Ufs: Refine EDKII_UFS_HOST_CONTROLLER_PROTOCOL interface
The EDKII_UFS_HOST_CONTROLLER_PROTOCOL is refined to provide interfaces accessing UFS host controller MMIO register. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Feng Tian <feng.tian@intel.com> Reviewed-by: Star Zeng <star.zeng@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17533 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
500e2ac246
commit
095f077993
|
@ -2,7 +2,7 @@
|
||||||
UfsHcDxe driver is used to provide platform-dependent info, mainly UFS host controller
|
UfsHcDxe driver is used to provide platform-dependent info, mainly UFS host controller
|
||||||
MMIO base, to upper layer UFS drivers.
|
MMIO base, to upper layer UFS drivers.
|
||||||
|
|
||||||
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -39,9 +39,12 @@ UFS_HOST_CONTROLLER_PRIVATE_DATA gUfsHcTemplate = {
|
||||||
UfsHcFreeBuffer,
|
UfsHcFreeBuffer,
|
||||||
UfsHcMap,
|
UfsHcMap,
|
||||||
UfsHcUnmap,
|
UfsHcUnmap,
|
||||||
UfsHcFlush
|
UfsHcFlush,
|
||||||
|
UfsHcMmioRead,
|
||||||
|
UfsHcMmioWrite
|
||||||
},
|
},
|
||||||
NULL, // PciIo
|
NULL, // PciIo
|
||||||
|
0, // BarIndex
|
||||||
0 // PciAttributes
|
0 // PciAttributes
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -64,25 +67,32 @@ UfsHcGetMmioBar (
|
||||||
UFS_HOST_CONTROLLER_PRIVATE_DATA *Private;
|
UFS_HOST_CONTROLLER_PRIVATE_DATA *Private;
|
||||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
UINT8 BarIndex;
|
||||||
|
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc;
|
||||||
|
|
||||||
if ((This == NULL) || (MmioBar == NULL)) {
|
if ((This == NULL) || (MmioBar == NULL)) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);
|
BarDesc = NULL;
|
||||||
PciIo = Private->PciIo;
|
Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);
|
||||||
|
PciIo = Private->PciIo;
|
||||||
|
BarIndex = Private->BarIndex;
|
||||||
|
|
||||||
Status = PciIo->Pci.Read (
|
Status = PciIo->GetBarAttributes (
|
||||||
PciIo,
|
PciIo,
|
||||||
EfiPciIoWidthUint8,
|
BarIndex,
|
||||||
PCI_BASE_ADDRESSREG_OFFSET,
|
NULL,
|
||||||
sizeof (UINT32),
|
(VOID**) &BarDesc
|
||||||
MmioBar
|
);
|
||||||
);
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
if (!EFI_ERROR (Status)) {
|
|
||||||
*MmioBar &= (UINTN)~0xF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*MmioBar = (UINTN)BarDesc->AddrRangeMin;
|
||||||
|
|
||||||
|
FreePool (BarDesc);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,6 +282,90 @@ UfsHcFlush (
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enable a UFS bus driver to access UFS MMIO registers in the UFS Host Controller memory space.
|
||||||
|
|
||||||
|
@param This A pointer to the EDKII_UFS_HOST_CONTROLLER_PROTOCOL instance.
|
||||||
|
@param Width Signifies the width of the memory operations.
|
||||||
|
@param Offset The offset within the UFS Host Controller MMIO space to start the
|
||||||
|
memory operation.
|
||||||
|
@param Count The number of memory operations to perform.
|
||||||
|
@param Buffer For read operations, the destination buffer to store the results.
|
||||||
|
For write operations, the source buffer to write data from.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The data was read from or written to the UFS host controller.
|
||||||
|
@retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not
|
||||||
|
valid for the UFS Host Controller memory space.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
UfsHcMmioRead (
|
||||||
|
IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This,
|
||||||
|
IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH Width,
|
||||||
|
IN UINT64 Offset,
|
||||||
|
IN UINTN Count,
|
||||||
|
IN OUT VOID *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UFS_HOST_CONTROLLER_PRIVATE_DATA *Private;
|
||||||
|
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINT8 BarIndex;
|
||||||
|
|
||||||
|
Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);
|
||||||
|
PciIo = Private->PciIo;
|
||||||
|
BarIndex = Private->BarIndex;
|
||||||
|
|
||||||
|
Status = PciIo->Mem.Read (PciIo, (EFI_PCI_IO_PROTOCOL_WIDTH)Width, BarIndex, Offset, Count, Buffer);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enable a UFS bus driver to access UFS MMIO registers in the UFS Host Controller memory space.
|
||||||
|
|
||||||
|
@param This A pointer to the EDKII_UFS_HOST_CONTROLLER_PROTOCOL instance.
|
||||||
|
@param Width Signifies the width of the memory operations.
|
||||||
|
@param Offset The offset within the UFS Host Controller MMIO space to start the
|
||||||
|
memory operation.
|
||||||
|
@param Count The number of memory operations to perform.
|
||||||
|
@param Buffer For read operations, the destination buffer to store the results.
|
||||||
|
For write operations, the source buffer to write data from.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The data was read from or written to the UFS host controller.
|
||||||
|
@retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not
|
||||||
|
valid for the UFS Host Controller memory space.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
UfsHcMmioWrite (
|
||||||
|
IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This,
|
||||||
|
IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH Width,
|
||||||
|
IN UINT64 Offset,
|
||||||
|
IN UINTN Count,
|
||||||
|
IN OUT VOID *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UFS_HOST_CONTROLLER_PRIVATE_DATA *Private;
|
||||||
|
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINT8 BarIndex;
|
||||||
|
|
||||||
|
Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);
|
||||||
|
PciIo = Private->PciIo;
|
||||||
|
BarIndex = Private->BarIndex;
|
||||||
|
|
||||||
|
Status = PciIo->Mem.Write (PciIo, (EFI_PCI_IO_PROTOCOL_WIDTH)Width, BarIndex, Offset, Count, Buffer);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Tests to see if this driver supports a given controller. If a child device is provided,
|
Tests to see if this driver supports a given controller. If a child device is provided,
|
||||||
it further tests to see if this driver supports creating a handle for the specified child device.
|
it further tests to see if this driver supports creating a handle for the specified child device.
|
||||||
|
@ -468,10 +562,13 @@ UfsHcDriverBindingStart (
|
||||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||||
UFS_HOST_CONTROLLER_PRIVATE_DATA *Private;
|
UFS_HOST_CONTROLLER_PRIVATE_DATA *Private;
|
||||||
UINT64 Supports;
|
UINT64 Supports;
|
||||||
|
UINT8 BarIndex;
|
||||||
|
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc;
|
||||||
|
|
||||||
PciIo = NULL;
|
PciIo = NULL;
|
||||||
Private = NULL;
|
Private = NULL;
|
||||||
Supports = 0;
|
Supports = 0;
|
||||||
|
BarDesc = NULL;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Now test and open the EfiPciIoProtocol
|
// Now test and open the EfiPciIoProtocol
|
||||||
|
@ -507,6 +604,28 @@ UfsHcDriverBindingStart (
|
||||||
|
|
||||||
Private->PciIo = PciIo;
|
Private->PciIo = PciIo;
|
||||||
|
|
||||||
|
for (BarIndex = 0; BarIndex < PCI_MAX_BAR; BarIndex++) {
|
||||||
|
Status = PciIo->GetBarAttributes (
|
||||||
|
PciIo,
|
||||||
|
BarIndex,
|
||||||
|
NULL,
|
||||||
|
(VOID**) &BarDesc
|
||||||
|
);
|
||||||
|
if (Status == EFI_UNSUPPORTED) {
|
||||||
|
continue;
|
||||||
|
} else if (EFI_ERROR (Status)) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
|
||||||
|
Private->BarIndex = BarIndex;
|
||||||
|
FreePool (BarDesc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
FreePool (BarDesc);
|
||||||
|
}
|
||||||
|
|
||||||
Status = PciIo->Attributes (
|
Status = PciIo->Attributes (
|
||||||
PciIo,
|
PciIo,
|
||||||
EfiPciIoAttributeOperationGet,
|
EfiPciIoAttributeOperationGet,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
UfsHcDxe driver is used to provide platform-dependent info, mainly UFS host controller
|
UfsHcDxe driver is used to provide platform-dependent info, mainly UFS host controller
|
||||||
MMIO base, to upper layer UFS drivers.
|
MMIO base, to upper layer UFS drivers.
|
||||||
|
|
||||||
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -19,6 +19,7 @@
|
||||||
#include <Uefi.h>
|
#include <Uefi.h>
|
||||||
|
|
||||||
#include <IndustryStandard/Pci.h>
|
#include <IndustryStandard/Pci.h>
|
||||||
|
#include <IndustryStandard/Acpi.h>
|
||||||
|
|
||||||
#include <Protocol/ComponentName.h>
|
#include <Protocol/ComponentName.h>
|
||||||
#include <Protocol/ComponentName2.h>
|
#include <Protocol/ComponentName2.h>
|
||||||
|
@ -56,6 +57,7 @@ struct _UFS_HOST_CONTROLLER_PRIVATE_DATA {
|
||||||
|
|
||||||
EDKII_UFS_HOST_CONTROLLER_PROTOCOL UfsHc;
|
EDKII_UFS_HOST_CONTROLLER_PROTOCOL UfsHc;
|
||||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||||
|
UINT8 BarIndex;
|
||||||
UINT64 PciAttributes;
|
UINT64 PciAttributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -450,4 +452,60 @@ UfsHcFlush (
|
||||||
IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This
|
IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enable a UFS bus driver to access UFS MMIO registers in the UFS Host Controller memory space.
|
||||||
|
|
||||||
|
@param This A pointer to the EDKII_UFS_HOST_CONTROLLER_PROTOCOL instance.
|
||||||
|
@param Width Signifies the width of the memory operations.
|
||||||
|
@param Offset The offset within the UFS Host Controller MMIO space to start the
|
||||||
|
memory operation.
|
||||||
|
@param Count The number of memory operations to perform.
|
||||||
|
@param Buffer For read operations, the destination buffer to store the results.
|
||||||
|
For write operations, the source buffer to write data from.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The data was read from or written to the UFS host controller.
|
||||||
|
@retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not
|
||||||
|
valid for the UFS Host Controller memory space.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
UfsHcMmioRead (
|
||||||
|
IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This,
|
||||||
|
IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH Width,
|
||||||
|
IN UINT64 Offset,
|
||||||
|
IN UINTN Count,
|
||||||
|
IN OUT VOID *Buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enable a UFS bus driver to access UFS MMIO registers in the UFS Host Controller memory space.
|
||||||
|
|
||||||
|
@param This A pointer to the EDKII_UFS_HOST_CONTROLLER_PROTOCOL instance.
|
||||||
|
@param Width Signifies the width of the memory operations.
|
||||||
|
@param Offset The offset within the UFS Host Controller MMIO space to start the
|
||||||
|
memory operation.
|
||||||
|
@param Count The number of memory operations to perform.
|
||||||
|
@param Buffer For read operations, the destination buffer to store the results.
|
||||||
|
For write operations, the source buffer to write data from.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The data was read from or written to the UFS host controller.
|
||||||
|
@retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not
|
||||||
|
valid for the UFS Host Controller memory space.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
UfsHcMmioWrite (
|
||||||
|
IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This,
|
||||||
|
IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH Width,
|
||||||
|
IN UINT64 Offset,
|
||||||
|
IN UINTN Count,
|
||||||
|
IN OUT VOID *Buffer
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/** @file
|
/** @file
|
||||||
|
|
||||||
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -27,7 +27,6 @@
|
||||||
#include <Library/MemoryAllocationLib.h>
|
#include <Library/MemoryAllocationLib.h>
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
#include <Library/DevicePathLib.h>
|
#include <Library/DevicePathLib.h>
|
||||||
#include <Library/IoLib.h>
|
|
||||||
#include <Library/TimerLib.h>
|
#include <Library/TimerLib.h>
|
||||||
|
|
||||||
#include "UfsPassThruHci.h"
|
#include "UfsPassThruHci.h"
|
||||||
|
|
|
@ -52,7 +52,6 @@
|
||||||
UefiDriverEntryPoint
|
UefiDriverEntryPoint
|
||||||
DebugLib
|
DebugLib
|
||||||
DevicePathLib
|
DevicePathLib
|
||||||
IoLib
|
|
||||||
TimerLib
|
TimerLib
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
UfsPassThruDxe driver is used to produce EFI_EXT_SCSI_PASS_THRU protocol interface
|
UfsPassThruDxe driver is used to produce EFI_EXT_SCSI_PASS_THRU protocol interface
|
||||||
for upper layer application to execute UFS-supported SCSI cmds.
|
for upper layer application to execute UFS-supported SCSI cmds.
|
||||||
|
|
||||||
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -16,29 +16,93 @@
|
||||||
#include "UfsPassThru.h"
|
#include "UfsPassThru.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Wait for the value of the specified system memory set to the test value.
|
Read 32bits data from specified UFS MMIO register.
|
||||||
|
|
||||||
@param Address The system memory address to test.
|
@param[in] Private The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.
|
||||||
@param MaskValue The mask value of memory.
|
@param[in] Offset The offset within the UFS Host Controller MMIO space to start
|
||||||
@param TestValue The test value of memory.
|
the memory operation.
|
||||||
@param Timeout The time out value for wait memory set, uses 100ns as a unit.
|
@param[out] Value The data buffer to store.
|
||||||
|
|
||||||
@retval EFI_TIMEOUT The system memory setting is time out.
|
@retval EFI_TIMEOUT The operation is time out.
|
||||||
@retval EFI_SUCCESS The system memory is correct set.
|
@retval EFI_SUCCESS The operation succeeds.
|
||||||
|
@retval Others The operation fails.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
UfsMmioRead32 (
|
||||||
|
IN UFS_PASS_THRU_PRIVATE_DATA *Private,
|
||||||
|
IN UINTN Offset,
|
||||||
|
OUT UINT32 *Value
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EDKII_UFS_HOST_CONTROLLER_PROTOCOL *UfsHc;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
UfsHc = Private->UfsHostController;
|
||||||
|
|
||||||
|
Status = UfsHc->Read (UfsHc, EfiUfsHcWidthUint32, Offset, 1, Value);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Write 32bits data to specified UFS MMIO register.
|
||||||
|
|
||||||
|
@param[in] Private The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.
|
||||||
|
@param[in] Offset The offset within the UFS Host Controller MMIO space to start
|
||||||
|
the memory operation.
|
||||||
|
@param[in] Value The data to write.
|
||||||
|
|
||||||
|
@retval EFI_TIMEOUT The operation is time out.
|
||||||
|
@retval EFI_SUCCESS The operation succeeds.
|
||||||
|
@retval Others The operation fails.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
UfsMmioWrite32 (
|
||||||
|
IN UFS_PASS_THRU_PRIVATE_DATA *Private,
|
||||||
|
IN UINTN Offset,
|
||||||
|
IN UINT32 Value
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EDKII_UFS_HOST_CONTROLLER_PROTOCOL *UfsHc;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
UfsHc = Private->UfsHostController;
|
||||||
|
|
||||||
|
Status = UfsHc->Write (UfsHc, EfiUfsHcWidthUint32, Offset, 1, &Value);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Wait for the value of the specified system memory set to the test value.
|
||||||
|
|
||||||
|
@param[in] Private The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.
|
||||||
|
@param[in] Offset The offset within the UFS Host Controller MMIO space to start
|
||||||
|
the memory operation.
|
||||||
|
@param[in] MaskValue The mask value of memory.
|
||||||
|
@param[in] TestValue The test value of memory.
|
||||||
|
@param[in] Timeout The time out value for wait memory set, uses 100ns as a unit.
|
||||||
|
|
||||||
|
@retval EFI_TIMEOUT The system memory setting is time out.
|
||||||
|
@retval EFI_SUCCESS The system memory is correct set.
|
||||||
|
@retval Others The operation fails.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
|
||||||
UfsWaitMemSet (
|
UfsWaitMemSet (
|
||||||
IN UINTN Address,
|
IN UFS_PASS_THRU_PRIVATE_DATA *Private,
|
||||||
IN UINT32 MaskValue,
|
IN UINTN Offset,
|
||||||
IN UINT32 TestValue,
|
IN UINT32 MaskValue,
|
||||||
IN UINT64 Timeout
|
IN UINT32 TestValue,
|
||||||
|
IN UINT64 Timeout
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT32 Value;
|
UINT32 Value;
|
||||||
UINT64 Delay;
|
UINT64 Delay;
|
||||||
BOOLEAN InfiniteWait;
|
BOOLEAN InfiniteWait;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
if (Timeout == 0) {
|
if (Timeout == 0) {
|
||||||
InfiniteWait = TRUE;
|
InfiniteWait = TRUE;
|
||||||
|
@ -52,7 +116,12 @@ UfsWaitMemSet (
|
||||||
//
|
//
|
||||||
// Access PCI MMIO space to see if the value is the tested one.
|
// Access PCI MMIO space to see if the value is the tested one.
|
||||||
//
|
//
|
||||||
Value = MmioRead32 (Address) & MaskValue;
|
Status = UfsMmioRead32 (Private, Offset, &Value);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value &= MaskValue;
|
||||||
|
|
||||||
if (Value == TestValue) {
|
if (Value == TestValue) {
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
@ -712,26 +781,33 @@ UfsFindAvailableSlotInTmrl (
|
||||||
@param[in] Slot The slot to be started.
|
@param[in] Slot The slot to be started.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
VOID
|
EFI_STATUS
|
||||||
UfsStartExecCmd (
|
UfsStartExecCmd (
|
||||||
IN UFS_PASS_THRU_PRIVATE_DATA *Private,
|
IN UFS_PASS_THRU_PRIVATE_DATA *Private,
|
||||||
IN UINT8 Slot
|
IN UINT8 Slot
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN UfsHcBase;
|
|
||||||
UINTN Address;
|
|
||||||
UINT32 Data;
|
UINT32 Data;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
UfsHcBase = Private->UfsHcBase;
|
Status = UfsMmioRead32 (Private, UFS_HC_UTRLRSR_OFFSET, &Data);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
Address = UfsHcBase + UFS_HC_UTRLRSR_OFFSET;
|
return Status;
|
||||||
Data = MmioRead32 (Address);
|
|
||||||
if ((Data & UFS_HC_UTRLRSR) != UFS_HC_UTRLRSR) {
|
|
||||||
MmioWrite32 (Address, UFS_HC_UTRLRSR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Address = UfsHcBase + UFS_HC_UTRLDBR_OFFSET;
|
if ((Data & UFS_HC_UTRLRSR) != UFS_HC_UTRLRSR) {
|
||||||
MmioWrite32 (Address, BIT0 << Slot);
|
Status = UfsMmioWrite32 (Private, UFS_HC_UTRLRSR_OFFSET, UFS_HC_UTRLRSR);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = UfsMmioWrite32 (Private, UFS_HC_UTRLDBR_OFFSET, BIT0 << Slot);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -741,25 +817,33 @@ UfsStartExecCmd (
|
||||||
@param[in] Slot The slot to be stop.
|
@param[in] Slot The slot to be stop.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
VOID
|
EFI_STATUS
|
||||||
UfsStopExecCmd (
|
UfsStopExecCmd (
|
||||||
IN UFS_PASS_THRU_PRIVATE_DATA *Private,
|
IN UFS_PASS_THRU_PRIVATE_DATA *Private,
|
||||||
IN UINT8 Slot
|
IN UINT8 Slot
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN UfsHcBase;
|
|
||||||
UINTN Address;
|
|
||||||
UINT32 Data;
|
UINT32 Data;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
UfsHcBase = Private->UfsHcBase;
|
Status = UfsMmioRead32 (Private, UFS_HC_UTRLDBR_OFFSET, &Data);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
Address = UfsHcBase + UFS_HC_UTRLDBR_OFFSET;
|
return Status;
|
||||||
Data = MmioRead32 (Address);
|
|
||||||
if ((Data & (BIT0 << Slot)) != 0) {
|
|
||||||
Address = UfsHcBase + UFS_HC_UTRLCLR_OFFSET;
|
|
||||||
Data = MmioRead32 (Address);
|
|
||||||
MmioWrite32 (Address, (Data & ~(BIT0 << Slot)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((Data & (BIT0 << Slot)) != 0) {
|
||||||
|
Status = UfsMmioRead32 (Private, UFS_HC_UTRLCLR_OFFSET, &Data);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = UfsMmioWrite32 (Private, UFS_HC_UTRLCLR_OFFSET, Data & ~(BIT0 << Slot));
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -793,7 +877,6 @@ UfsRwDeviceDesc (
|
||||||
UFS_DEVICE_MANAGEMENT_REQUEST_PACKET Packet;
|
UFS_DEVICE_MANAGEMENT_REQUEST_PACKET Packet;
|
||||||
UINT8 Slot;
|
UINT8 Slot;
|
||||||
UTP_TRD *Trd;
|
UTP_TRD *Trd;
|
||||||
UINTN Address;
|
|
||||||
UTP_QUERY_RESP_UPIU *QueryResp;
|
UTP_QUERY_RESP_UPIU *QueryResp;
|
||||||
UINT32 CmdDescSize;
|
UINT32 CmdDescSize;
|
||||||
UINT16 ReturnDataSize;
|
UINT16 ReturnDataSize;
|
||||||
|
@ -852,8 +935,7 @@ UfsRwDeviceDesc (
|
||||||
//
|
//
|
||||||
// Wait for the completion of the transfer request.
|
// Wait for the completion of the transfer request.
|
||||||
//
|
//
|
||||||
Address = Private->UfsHcBase + UFS_HC_UTRLDBR_OFFSET;
|
Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0, 0, Packet.Timeout);
|
||||||
Status = UfsWaitMemSet (Address, BIT0, 0, Packet.Timeout);
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
@ -922,7 +1004,6 @@ UfsRwAttributes (
|
||||||
UFS_DEVICE_MANAGEMENT_REQUEST_PACKET Packet;
|
UFS_DEVICE_MANAGEMENT_REQUEST_PACKET Packet;
|
||||||
UINT8 Slot;
|
UINT8 Slot;
|
||||||
UTP_TRD *Trd;
|
UTP_TRD *Trd;
|
||||||
UINTN Address;
|
|
||||||
UTP_QUERY_RESP_UPIU *QueryResp;
|
UTP_QUERY_RESP_UPIU *QueryResp;
|
||||||
UINT32 CmdDescSize;
|
UINT32 CmdDescSize;
|
||||||
UINT32 ReturnData;
|
UINT32 ReturnData;
|
||||||
|
@ -977,8 +1058,7 @@ UfsRwAttributes (
|
||||||
//
|
//
|
||||||
// Wait for the completion of the transfer request.
|
// Wait for the completion of the transfer request.
|
||||||
//
|
//
|
||||||
Address = Private->UfsHcBase + UFS_HC_UTRLDBR_OFFSET;
|
Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0, 0, Packet.Timeout);
|
||||||
Status = UfsWaitMemSet (Address, BIT0, 0, Packet.Timeout);
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
@ -1038,7 +1118,6 @@ UfsRwFlags (
|
||||||
UFS_DEVICE_MANAGEMENT_REQUEST_PACKET Packet;
|
UFS_DEVICE_MANAGEMENT_REQUEST_PACKET Packet;
|
||||||
UINT8 Slot;
|
UINT8 Slot;
|
||||||
UTP_TRD *Trd;
|
UTP_TRD *Trd;
|
||||||
UINTN Address;
|
|
||||||
UTP_QUERY_RESP_UPIU *QueryResp;
|
UTP_QUERY_RESP_UPIU *QueryResp;
|
||||||
UINT32 CmdDescSize;
|
UINT32 CmdDescSize;
|
||||||
VOID *CmdDescHost;
|
VOID *CmdDescHost;
|
||||||
|
@ -1103,8 +1182,7 @@ UfsRwFlags (
|
||||||
//
|
//
|
||||||
// Wait for the completion of the transfer request.
|
// Wait for the completion of the transfer request.
|
||||||
//
|
//
|
||||||
Address = Private->UfsHcBase + UFS_HC_UTRLDBR_OFFSET;
|
Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0, 0, Packet.Timeout);
|
||||||
Status = UfsWaitMemSet (Address, BIT0, 0, Packet.Timeout);
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
@ -1237,7 +1315,6 @@ UfsExecNopCmds (
|
||||||
UTP_TRD *Trd;
|
UTP_TRD *Trd;
|
||||||
UTP_NOP_IN_UPIU *NopInUpiu;
|
UTP_NOP_IN_UPIU *NopInUpiu;
|
||||||
UINT32 CmdDescSize;
|
UINT32 CmdDescSize;
|
||||||
UINTN Address;
|
|
||||||
VOID *CmdDescHost;
|
VOID *CmdDescHost;
|
||||||
VOID *CmdDescMapping;
|
VOID *CmdDescMapping;
|
||||||
EDKII_UFS_HOST_CONTROLLER_PROTOCOL *UfsHc;
|
EDKII_UFS_HOST_CONTROLLER_PROTOCOL *UfsHc;
|
||||||
|
@ -1272,8 +1349,7 @@ UfsExecNopCmds (
|
||||||
//
|
//
|
||||||
// Wait for the completion of the transfer request.
|
// Wait for the completion of the transfer request.
|
||||||
//
|
//
|
||||||
Address = Private->UfsHcBase + UFS_HC_UTRLDBR_OFFSET;
|
Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0, 0, UFS_TIMEOUT);
|
||||||
Status = UfsWaitMemSet (Address, BIT0, 0, UFS_TIMEOUT);
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
@ -1328,7 +1404,6 @@ UfsExecScsiCmds (
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT8 Slot;
|
UINT8 Slot;
|
||||||
UTP_TRD *Trd;
|
UTP_TRD *Trd;
|
||||||
UINTN Address;
|
|
||||||
UINT32 CmdDescSize;
|
UINT32 CmdDescSize;
|
||||||
UTP_RESPONSE_UPIU *Response;
|
UTP_RESPONSE_UPIU *Response;
|
||||||
UINT16 SenseDataLen;
|
UINT16 SenseDataLen;
|
||||||
|
@ -1414,9 +1489,8 @@ UfsExecScsiCmds (
|
||||||
|
|
||||||
//
|
//
|
||||||
// Wait for the completion of the transfer request.
|
// Wait for the completion of the transfer request.
|
||||||
//
|
//
|
||||||
Address = Private->UfsHcBase + UFS_HC_UTRLDBR_OFFSET;
|
Status = UfsWaitMemSet (Private, UFS_HC_UTRLDBR_OFFSET, BIT0, 0, Packet->Timeout);
|
||||||
Status = UfsWaitMemSet (Address, BIT0, 0, Packet->Timeout);
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
@ -1506,18 +1580,21 @@ UfsExecUicCommands (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINTN Address;
|
|
||||||
UINT32 Data;
|
UINT32 Data;
|
||||||
UINTN UfsHcBase;
|
|
||||||
|
|
||||||
UfsHcBase = Private->UfsHcBase;
|
Status = UfsMmioRead32 (Private, UFS_HC_IS_OFFSET, &Data);
|
||||||
Address = UfsHcBase + UFS_HC_IS_OFFSET;
|
if (EFI_ERROR (Status)) {
|
||||||
Data = MmioRead32 (Address);
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
if ((Data & UFS_HC_IS_UCCS) == UFS_HC_IS_UCCS) {
|
if ((Data & UFS_HC_IS_UCCS) == UFS_HC_IS_UCCS) {
|
||||||
//
|
//
|
||||||
// Clear IS.BIT10 UIC Command Completion Status (UCCS) at first.
|
// Clear IS.BIT10 UIC Command Completion Status (UCCS) at first.
|
||||||
//
|
//
|
||||||
MmioWrite32 (Address, Data);
|
Status = UfsMmioWrite32 (Private, UFS_HC_IS_OFFSET, Data);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1525,41 +1602,48 @@ UfsExecUicCommands (
|
||||||
// only after all the UIC command argument registers (UICCMDARG1, UICCMDARG2 and UICCMDARG3)
|
// only after all the UIC command argument registers (UICCMDARG1, UICCMDARG2 and UICCMDARG3)
|
||||||
// are set.
|
// are set.
|
||||||
//
|
//
|
||||||
Address = UfsHcBase + UFS_HC_UCMD_ARG1_OFFSET;
|
Status = UfsMmioWrite32 (Private, UFS_HC_UCMD_ARG1_OFFSET, Arg1);
|
||||||
MmioWrite32 (Address, Arg1);
|
|
||||||
|
|
||||||
Address = UfsHcBase + UFS_HC_UCMD_ARG2_OFFSET;
|
|
||||||
MmioWrite32 (Address, Arg2);
|
|
||||||
|
|
||||||
Address = UfsHcBase + UFS_HC_UCMD_ARG3_OFFSET;
|
|
||||||
MmioWrite32 (Address, Arg3);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Host software shall only set the UICCMD if HCS.UCRDY is set to 1.
|
|
||||||
//
|
|
||||||
Address = Private->UfsHcBase + UFS_HC_STATUS_OFFSET;
|
|
||||||
Status = UfsWaitMemSet (Address, UFS_HC_HCS_UCRDY, UFS_HC_HCS_UCRDY, UFS_TIMEOUT);
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Address = UfsHcBase + UFS_HC_UIC_CMD_OFFSET;
|
Status = UfsMmioWrite32 (Private, UFS_HC_UCMD_ARG2_OFFSET, Arg2);
|
||||||
MmioWrite32 (Address, (UINT32)UicOpcode);
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = UfsMmioWrite32 (Private, UFS_HC_UCMD_ARG3_OFFSET, Arg3);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Host software shall only set the UICCMD if HCS.UCRDY is set to 1.
|
||||||
|
//
|
||||||
|
Status = UfsWaitMemSet (Private, UFS_HC_STATUS_OFFSET, UFS_HC_HCS_UCRDY, UFS_HC_HCS_UCRDY, UFS_TIMEOUT);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = UfsMmioWrite32 (Private, UFS_HC_UIC_CMD_OFFSET, (UINT32)UicOpcode);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// UFS 2.0 spec section 5.3.1 Offset:0x20 IS.Bit10 UIC Command Completion Status (UCCS)
|
// UFS 2.0 spec section 5.3.1 Offset:0x20 IS.Bit10 UIC Command Completion Status (UCCS)
|
||||||
// This bit is set to '1' by the host controller upon completion of a UIC command.
|
// This bit is set to '1' by the host controller upon completion of a UIC command.
|
||||||
//
|
//
|
||||||
Address = UfsHcBase + UFS_HC_IS_OFFSET;
|
Status = UfsWaitMemSet (Private, UFS_HC_IS_OFFSET, UFS_HC_IS_UCCS, UFS_HC_IS_UCCS, UFS_TIMEOUT);
|
||||||
Data = MmioRead32 (Address);
|
|
||||||
Status = UfsWaitMemSet (Address, UFS_HC_IS_UCCS, UFS_HC_IS_UCCS, UFS_TIMEOUT);
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UicOpcode != UfsUicDmeReset) {
|
if (UicOpcode != UfsUicDmeReset) {
|
||||||
Address = UfsHcBase + UFS_HC_UCMD_ARG2_OFFSET;
|
Status = UfsMmioRead32 (Private, UFS_HC_UCMD_ARG2_OFFSET, &Data);
|
||||||
Data = MmioRead32 (Address);
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
if ((Data & 0xFF) != 0) {
|
if ((Data & 0xFF) != 0) {
|
||||||
DEBUG_CODE_BEGIN();
|
DEBUG_CODE_BEGIN();
|
||||||
DumpUicCmdExecResult (UicOpcode, (UINT8)(Data & 0xFF));
|
DumpUicCmdExecResult (UicOpcode, (UINT8)(Data & 0xFF));
|
||||||
|
@ -1571,11 +1655,13 @@ UfsExecUicCommands (
|
||||||
//
|
//
|
||||||
// Check value of HCS.DP and make sure that there is a device attached to the Link.
|
// Check value of HCS.DP and make sure that there is a device attached to the Link.
|
||||||
//
|
//
|
||||||
Address = UfsHcBase + UFS_HC_STATUS_OFFSET;
|
Status = UfsMmioRead32 (Private, UFS_HC_STATUS_OFFSET, &Data);
|
||||||
Data = MmioRead32 (Address);
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
if ((Data & UFS_HC_HCS_DP) == 0) {
|
if ((Data & UFS_HC_HCS_DP) == 0) {
|
||||||
Address = UfsHcBase + UFS_HC_IS_OFFSET;
|
Status = UfsWaitMemSet (Private, UFS_HC_IS_OFFSET, UFS_HC_IS_ULSS, UFS_HC_IS_ULSS, UFS_TIMEOUT);
|
||||||
Status = UfsWaitMemSet (Address, UFS_HC_IS_ULSS, UFS_HC_IS_ULSS, UFS_TIMEOUT);
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -1694,7 +1780,6 @@ UfsEnableHostController (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINTN Address;
|
|
||||||
UINT32 Data;
|
UINT32 Data;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1702,17 +1787,23 @@ UfsEnableHostController (
|
||||||
//
|
//
|
||||||
// Reinitialize the UFS host controller if HCE bit of HC register is set.
|
// Reinitialize the UFS host controller if HCE bit of HC register is set.
|
||||||
//
|
//
|
||||||
Address = Private->UfsHcBase + UFS_HC_ENABLE_OFFSET;
|
Status = UfsMmioRead32 (Private, UFS_HC_ENABLE_OFFSET, &Data);
|
||||||
Data = MmioRead32 (Address);
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
if ((Data & UFS_HC_HCE_EN) == UFS_HC_HCE_EN) {
|
if ((Data & UFS_HC_HCE_EN) == UFS_HC_HCE_EN) {
|
||||||
//
|
//
|
||||||
// Write a 0 to the HCE register at first to disable the host controller.
|
// Write a 0 to the HCE register at first to disable the host controller.
|
||||||
//
|
//
|
||||||
MmioWrite32 (Address, 0);
|
Status = UfsMmioWrite32 (Private, UFS_HC_ENABLE_OFFSET, 0);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// Wait until HCE is read as '0' before continuing.
|
// Wait until HCE is read as '0' before continuing.
|
||||||
//
|
//
|
||||||
Status = UfsWaitMemSet (Address, UFS_HC_HCE_EN, 0, UFS_TIMEOUT);
|
Status = UfsWaitMemSet (Private, UFS_HC_ENABLE_OFFSET, UFS_HC_HCE_EN, 0, UFS_TIMEOUT);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -1721,11 +1812,15 @@ UfsEnableHostController (
|
||||||
//
|
//
|
||||||
// Write a 1 to the HCE register to enable the UFS host controller.
|
// Write a 1 to the HCE register to enable the UFS host controller.
|
||||||
//
|
//
|
||||||
MmioWrite32 (Address, UFS_HC_HCE_EN);
|
Status = UfsMmioWrite32 (Private, UFS_HC_ENABLE_OFFSET, UFS_HC_HCE_EN);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Wait until HCE is read as '1' before continuing.
|
// Wait until HCE is read as '1' before continuing.
|
||||||
//
|
//
|
||||||
Status = UfsWaitMemSet (Address, UFS_HC_HCE_EN, UFS_HC_HCE_EN, UFS_TIMEOUT);
|
Status = UfsWaitMemSet (Private, UFS_HC_ENABLE_OFFSET, UFS_HC_HCE_EN, UFS_HC_HCE_EN, UFS_TIMEOUT);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -1789,7 +1884,6 @@ UfsInitTaskManagementRequestList (
|
||||||
IN UFS_PASS_THRU_PRIVATE_DATA *Private
|
IN UFS_PASS_THRU_PRIVATE_DATA *Private
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN Address;
|
|
||||||
UINT32 Data;
|
UINT32 Data;
|
||||||
UINT8 Nutmrs;
|
UINT8 Nutmrs;
|
||||||
VOID *CmdDescHost;
|
VOID *CmdDescHost;
|
||||||
|
@ -1803,8 +1897,12 @@ UfsInitTaskManagementRequestList (
|
||||||
CmdDescHost = NULL;
|
CmdDescHost = NULL;
|
||||||
CmdDescMapping = NULL;
|
CmdDescMapping = NULL;
|
||||||
CmdDescPhyAddr = 0;
|
CmdDescPhyAddr = 0;
|
||||||
Address = Private->UfsHcBase + UFS_HC_CAP_OFFSET;
|
|
||||||
Data = MmioRead32 (Address);
|
Status = UfsMmioRead32 (Private, UFS_HC_CAP_OFFSET, &Data);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
Private->Capabilities = Data;
|
Private->Capabilities = Data;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1820,10 +1918,15 @@ UfsInitTaskManagementRequestList (
|
||||||
// Program the UTP Task Management Request List Base Address and UTP Task Management
|
// Program the UTP Task Management Request List Base Address and UTP Task Management
|
||||||
// Request List Base Address with a 64-bit address allocated at step 6.
|
// Request List Base Address with a 64-bit address allocated at step 6.
|
||||||
//
|
//
|
||||||
Address = Private->UfsHcBase + UFS_HC_UTMRLBA_OFFSET;
|
Status = UfsMmioWrite32 (Private, UFS_HC_UTMRLBA_OFFSET, (UINT32)(UINTN)CmdDescPhyAddr);
|
||||||
MmioWrite32 (Address, (UINT32)(UINTN)CmdDescPhyAddr);
|
if (EFI_ERROR (Status)) {
|
||||||
Address = Private->UfsHcBase + UFS_HC_UTMRLBAU_OFFSET;
|
return Status;
|
||||||
MmioWrite32 (Address, (UINT32)RShiftU64 ((UINT64)CmdDescPhyAddr, 32));
|
}
|
||||||
|
|
||||||
|
Status = UfsMmioWrite32 (Private, UFS_HC_UTMRLBAU_OFFSET, (UINT32)RShiftU64 ((UINT64)CmdDescPhyAddr, 32));
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
Private->UtpTmrlBase = CmdDescHost;
|
Private->UtpTmrlBase = CmdDescHost;
|
||||||
Private->Nutmrs = Nutmrs;
|
Private->Nutmrs = Nutmrs;
|
||||||
Private->TmrlMapping = CmdDescMapping;
|
Private->TmrlMapping = CmdDescMapping;
|
||||||
|
@ -1832,8 +1935,10 @@ UfsInitTaskManagementRequestList (
|
||||||
// Enable the UTP Task Management Request List by setting the UTP Task Management
|
// Enable the UTP Task Management Request List by setting the UTP Task Management
|
||||||
// Request List RunStop Register (UTMRLRSR) to '1'.
|
// Request List RunStop Register (UTMRLRSR) to '1'.
|
||||||
//
|
//
|
||||||
Address = Private->UfsHcBase + UFS_HC_UTMRLRSR_OFFSET;
|
Status = UfsMmioWrite32 (Private, UFS_HC_UTMRLRSR_OFFSET, UFS_HC_UTMRLRSR);
|
||||||
MmioWrite32 (Address, UFS_HC_UTMRLRSR);
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1852,7 +1957,6 @@ UfsInitTransferRequestList (
|
||||||
IN UFS_PASS_THRU_PRIVATE_DATA *Private
|
IN UFS_PASS_THRU_PRIVATE_DATA *Private
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN Address;
|
|
||||||
UINT32 Data;
|
UINT32 Data;
|
||||||
UINT8 Nutrs;
|
UINT8 Nutrs;
|
||||||
VOID *CmdDescHost;
|
VOID *CmdDescHost;
|
||||||
|
@ -1866,8 +1970,12 @@ UfsInitTransferRequestList (
|
||||||
CmdDescHost = NULL;
|
CmdDescHost = NULL;
|
||||||
CmdDescMapping = NULL;
|
CmdDescMapping = NULL;
|
||||||
CmdDescPhyAddr = 0;
|
CmdDescPhyAddr = 0;
|
||||||
Address = Private->UfsHcBase + UFS_HC_CAP_OFFSET;
|
|
||||||
Data = MmioRead32 (Address);
|
Status = UfsMmioRead32 (Private, UFS_HC_CAP_OFFSET, &Data);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
Private->Capabilities = Data;
|
Private->Capabilities = Data;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1883,10 +1991,16 @@ UfsInitTransferRequestList (
|
||||||
// Program the UTP Transfer Request List Base Address and UTP Transfer Request List
|
// Program the UTP Transfer Request List Base Address and UTP Transfer Request List
|
||||||
// Base Address with a 64-bit address allocated at step 8.
|
// Base Address with a 64-bit address allocated at step 8.
|
||||||
//
|
//
|
||||||
Address = Private->UfsHcBase + UFS_HC_UTRLBA_OFFSET;
|
Status = UfsMmioWrite32 (Private, UFS_HC_UTRLBA_OFFSET, (UINT32)(UINTN)CmdDescPhyAddr);
|
||||||
MmioWrite32 (Address, (UINT32)(UINTN)CmdDescPhyAddr);
|
if (EFI_ERROR (Status)) {
|
||||||
Address = Private->UfsHcBase + UFS_HC_UTRLBAU_OFFSET;
|
return Status;
|
||||||
MmioWrite32 (Address, (UINT32)RShiftU64 ((UINT64)CmdDescPhyAddr, 32));
|
}
|
||||||
|
|
||||||
|
Status = UfsMmioWrite32 (Private, UFS_HC_UTRLBAU_OFFSET, (UINT32)RShiftU64 ((UINT64)CmdDescPhyAddr, 32));
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
Private->UtpTrlBase = CmdDescHost;
|
Private->UtpTrlBase = CmdDescHost;
|
||||||
Private->Nutrs = Nutrs;
|
Private->Nutrs = Nutrs;
|
||||||
Private->TrlMapping = CmdDescMapping;
|
Private->TrlMapping = CmdDescMapping;
|
||||||
|
@ -1895,8 +2009,10 @@ UfsInitTransferRequestList (
|
||||||
// Enable the UTP Transfer Request List by setting the UTP Transfer Request List
|
// Enable the UTP Transfer Request List by setting the UTP Transfer Request List
|
||||||
// RunStop Register (UTRLRSR) to '1'.
|
// RunStop Register (UTRLRSR) to '1'.
|
||||||
//
|
//
|
||||||
Address = Private->UfsHcBase + UFS_HC_UTRLRSR_OFFSET;
|
Status = UfsMmioWrite32 (Private, UFS_HC_UTRLRSR_OFFSET, UFS_HC_UTRLRSR);
|
||||||
MmioWrite32 (Address, UFS_HC_UTRLRSR);
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1960,35 +2076,44 @@ UfsControllerStop (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINTN Address;
|
|
||||||
UINT32 Data;
|
UINT32 Data;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Enable the UTP Task Management Request List by setting the UTP Task Management
|
// Enable the UTP Task Management Request List by setting the UTP Task Management
|
||||||
// Request List RunStop Register (UTMRLRSR) to '1'.
|
// Request List RunStop Register (UTMRLRSR) to '1'.
|
||||||
//
|
//
|
||||||
Address = Private->UfsHcBase + UFS_HC_UTMRLRSR_OFFSET;
|
Status = UfsMmioWrite32 (Private, UFS_HC_UTMRLRSR_OFFSET, 0);
|
||||||
MmioWrite32 (Address, 0);
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Enable the UTP Transfer Request List by setting the UTP Transfer Request List
|
// Enable the UTP Transfer Request List by setting the UTP Transfer Request List
|
||||||
// RunStop Register (UTRLRSR) to '1'.
|
// RunStop Register (UTRLRSR) to '1'.
|
||||||
//
|
//
|
||||||
Address = Private->UfsHcBase + UFS_HC_UTRLRSR_OFFSET;
|
Status = UfsMmioWrite32 (Private, UFS_HC_UTRLRSR_OFFSET, 0);
|
||||||
MmioWrite32 (Address, 0);
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Write a 0 to the HCE register in order to disable the host controller.
|
// Write a 0 to the HCE register in order to disable the host controller.
|
||||||
//
|
//
|
||||||
Address = Private->UfsHcBase + UFS_HC_ENABLE_OFFSET;
|
Status = UfsMmioRead32 (Private, UFS_HC_ENABLE_OFFSET, &Data);
|
||||||
Data = MmioRead32 (Address);
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
ASSERT ((Data & UFS_HC_HCE_EN) == UFS_HC_HCE_EN);
|
ASSERT ((Data & UFS_HC_HCE_EN) == UFS_HC_HCE_EN);
|
||||||
MmioWrite32 (Address, 0);
|
|
||||||
|
Status = UfsMmioWrite32 (Private, UFS_HC_ENABLE_OFFSET, 0);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Wait until HCE is read as '0' before continuing.
|
// Wait until HCE is read as '0' before continuing.
|
||||||
//
|
//
|
||||||
Status = UfsWaitMemSet (Address, UFS_HC_HCE_EN, 0, UFS_TIMEOUT);
|
Status = UfsWaitMemSet (Private, UFS_HC_ENABLE_OFFSET, UFS_HC_HCE_EN, 0, UFS_TIMEOUT);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
EDKII Universal Flash Storage Host Controller Protocol.
|
EDKII Universal Flash Storage Host Controller Protocol.
|
||||||
|
|
||||||
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials are licensed and made available under
|
This program and the accompanying materials are licensed and made available under
|
||||||
the terms and conditions of the BSD License that accompanies this distribution.
|
the terms and conditions of the BSD License that accompanies this distribution.
|
||||||
The full text of the license may be found at
|
The full text of the license may be found at
|
||||||
|
@ -185,6 +185,42 @@ EFI_STATUS
|
||||||
IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This
|
IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This
|
||||||
);
|
);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
EfiUfsHcWidthUint8 = 0,
|
||||||
|
EfiUfsHcWidthUint16,
|
||||||
|
EfiUfsHcWidthUint32,
|
||||||
|
EfiUfsHcWidthUint64,
|
||||||
|
EfiUfsHcWidthMaximum
|
||||||
|
} EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enable a UFS bus driver to access UFS MMIO registers in the UFS Host Controller memory space.
|
||||||
|
|
||||||
|
@param This A pointer to the EDKII_UFS_HOST_CONTROLLER_PROTOCOL instance.
|
||||||
|
@param Width Signifies the width of the memory operations.
|
||||||
|
@param Offset The offset within the UFS Host Controller MMIO space to start the
|
||||||
|
memory operation.
|
||||||
|
@param Count The number of memory operations to perform.
|
||||||
|
@param Buffer For read operations, the destination buffer to store the results.
|
||||||
|
For write operations, the source buffer to write data from.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The data was read from or written to the UFS host controller.
|
||||||
|
@retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not
|
||||||
|
valid for the UFS Host Controller memory space.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||||
|
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
||||||
|
|
||||||
|
**/
|
||||||
|
typedef
|
||||||
|
EFI_STATUS
|
||||||
|
(EFIAPI *EDKII_UFS_HC_MMIO_READ_WRITE)(
|
||||||
|
IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This,
|
||||||
|
IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH Width,
|
||||||
|
IN UINT64 Offset,
|
||||||
|
IN UINTN Count,
|
||||||
|
IN OUT VOID *Buffer
|
||||||
|
);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// UFS Host Controller Protocol structure.
|
/// UFS Host Controller Protocol structure.
|
||||||
///
|
///
|
||||||
|
@ -195,6 +231,8 @@ struct _EDKII_UFS_HOST_CONTROLLER_PROTOCOL {
|
||||||
EDKII_UFS_HC_MAP Map;
|
EDKII_UFS_HC_MAP Map;
|
||||||
EDKII_UFS_HC_UNMAP Unmap;
|
EDKII_UFS_HC_UNMAP Unmap;
|
||||||
EDKII_UFS_HC_FLUSH Flush;
|
EDKII_UFS_HC_FLUSH Flush;
|
||||||
|
EDKII_UFS_HC_MMIO_READ_WRITE Read;
|
||||||
|
EDKII_UFS_HC_MMIO_READ_WRITE Write;
|
||||||
};
|
};
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
Loading…
Reference in New Issue