public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
To: Marcin Wojtas <mw@semihalf.com>
Cc: "edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
	"Leif Lindholm" <leif.lindholm@linaro.org>,
	"Wu, Hao A" <hao.a.wu@intel.com>,
	"Nadav Haklai" <nadavh@marvell.com>,
	"Jan Dąbroś" <jsd@semihalf.com>,
	"Grzegorz Jaszczyk" <jaz@semihalf.com>,
	"Kostya Porotchkin" <kostap@marvell.com>,
	"Tomasz Michalec" <tm@semihalf.com>
Subject: Re: [platforms: PATCH v5 8/8] Marvell/Drivers: XenonDxe: Switch to use generic SdMmcPciHcDxe
Date: Thu, 15 Nov 2018 16:56:42 -0800	[thread overview]
Message-ID: <CAKv+Gu_KqnjkUKHCyenfiod8pCD73Cq=CxNkdAGbthVugug3kg@mail.gmail.com> (raw)
In-Reply-To: <1542112371-32546-9-git-send-email-mw@semihalf.com>

On Tue, 13 Nov 2018 at 04:33, Marcin Wojtas <mw@semihalf.com> wrote:
>
> From: Tomasz Michalec <tm@semihalf.com>
>
> XenonDxe was copy of SdMmcPciHcDxe from edk2/MdeModulePkg.
>
> Now it implements SdMmcOverride protocol which allows
> to add quirks to the generic SdMmcPciHcDxe.
>
> Platforms that were using XenonDxe/SdMmcPciHcDxe have fixed *.fdf
> and *.dsc.inc files to use new implementation of XenonDxe.
>
> In the new version of the driver apart from using SdMmcOverride
> protocol, this patch utilizes newly added controllers'
> description in MvBoardDesc protocol, as well as improved
> PHY configuration sequence.
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Marcin Wojtas  <mw@semihalf.com>
> ---
>  Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc               |   2 +
>  Silicon/Marvell/Armada7k8k/Armada7k8k.fdf                   |   2 +
>  Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonDxe.inf         |  55 +++
>  Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonPciHci.h        | 151 +++++++
>  Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdMmcOverride.h |  53 +++
>  Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdhci.h         | 131 +++++-
>  Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonPciHci.c        | 321 +++++++++++++++
>  Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdMmcOverride.c | 432 ++++++++++++++++++++
>  Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdhci.c         | 408 ++++++++++++------
>  9 files changed, 1402 insertions(+), 153 deletions(-)
>  create mode 100644 Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonDxe.inf
>  create mode 100644 Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonPciHci.h
>  create mode 100644 Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdMmcOverride.h
>  create mode 100644 Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonPciHci.c
>  create mode 100644 Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdMmcOverride.c
>
> diff --git a/Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc b/Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc
> index 041fe90..14a1bda 100644
> --- a/Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc
> +++ b/Silicon/Marvell/Armada7k8k/Armada7k8k.dsc.inc
> @@ -509,6 +509,8 @@
>    # SD/MMC
>    MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.inf
>    MdeModulePkg/Bus/Sd/SdDxe/SdDxe.inf
> +  MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf
> +  Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonDxe.inf
>
>    # Console packages
>    MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
> diff --git a/Silicon/Marvell/Armada7k8k/Armada7k8k.fdf b/Silicon/Marvell/Armada7k8k/Armada7k8k.fdf
> index 6ad7c87..e143517 100644
> --- a/Silicon/Marvell/Armada7k8k/Armada7k8k.fdf
> +++ b/Silicon/Marvell/Armada7k8k/Armada7k8k.fdf
> @@ -171,6 +171,8 @@ FvNameGuid         = 5eda4200-2c5f-43cb-9da3-0baf74b1b30c
>    # SD/MMC
>    INF MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.inf
>    INF MdeModulePkg/Bus/Sd/SdDxe/SdDxe.inf
> +  INF MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf
> +  INF Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonDxe.inf
>
>    # Multiple Console IO support
>    INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
> diff --git a/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonDxe.inf b/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonDxe.inf
> new file mode 100644
> index 0000000..f966e5f
> --- /dev/null
> +++ b/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonDxe.inf
> @@ -0,0 +1,55 @@
> +## @file
> +#  SdMmcPciHcDxe driver is used to manage those host controllers which comply with SD
> +#  Host Controller Simplified Specifiction version 3.0.
> +#
> +#  It will produce EFI_SD_MMC_PASS_THRU_PROTOCOL to allow sending SD/MMC/eMMC cmds
> +#  to specified devices from upper layer.
> +#
> +#  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +#  Copyright (C) 2018, Marvell International Ltd. All rights reserved.<BR>
> +#
> +#  This program and the accompanying materials
> +#  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
> +#  http://opensource.org/licenses/bsd-license.php
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001A
> +  BASE_NAME                      = XenonDxe
> +  FILE_GUID                      = 17f56b40-f7c1-435c-ab8d-404872da951e
> +  MODULE_TYPE                    = UEFI_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = InitializeXenonDxe
> +
> +[Sources]
> +  XenonPciHci.c
> +  XenonPciHci.h
> +  XenonSdhci.c
> +  XenonSdhci.h
> +  XenonSdMmcOverride.c
> +  XenonSdMmcOverride.h
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Silicon/Marvell/Marvell.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  MemoryAllocationLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +  UefiRuntimeServicesTableLib
> +
> +[Protocols]
> +  gEdkiiSdMmcOverrideProtocolGuid               ## BY_START

Please change the annotation to ## PRODUCES

> +  gEdkiiNonDiscoverableDeviceProtocolGuid       ## TO_START
> +  gEfiPciIoProtocolGuid                         ## TO_START
> +  gMarvellBoardDescProtocolGuid                 ## TO_START
> diff --git a/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonPciHci.h b/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonPciHci.h
> new file mode 100644
> index 0000000..152ba96
> --- /dev/null
> +++ b/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonPciHci.h
> @@ -0,0 +1,151 @@
> +/** @file
> +
> +  Provides some data structure definitions used by the SD/MMC host controller driver.
> +
> +  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2018, Marvell International, Ltd. All rights reserved.<BR>
> +
> +  This program and the accompanying materials
> +  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
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef _XENON_PCI_HCI_H_
> +#define _XENON_PCI_HCI_H_
> +
> +/**
> +  Read/Write specified SD/MMC host controller mmio register.
> +
> +  @param[in]      PciIo        The PCI IO protocol instance.
> +  @param[in]      BarIndex     The BAR index of the standard PCI Configuration
> +                               header to use as the base address for the memory
> +                               operation to perform.
> +  @param[in]      Offset       The offset within the selected BAR to start the
> +                               memory operation.
> +  @param[in]      Read         A boolean to indicate it's read or write operation.
> +  @param[in]      Count        The width of the mmio register in bytes.
> +                               Must be 1, 2 , 4 or 8 bytes.
> +  @param[in, out] Data         For read operations, the destination buffer to store
> +                               the results. For write operations, the source buffer
> +                               to write data from. The caller is responsible for
> +                               having ownership of the data buffer and ensuring its
> +                               size not less than Count bytes.
> +
> +  @retval EFI_INVALID_PARAMETER The PciIo or Data is NULL or the Count is not valid.
> +  @retval EFI_SUCCESS           The read/write operation succeeds.
> +  @retval Others                The read/write operation fails.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +XenonHcRwMmio (
> +  IN     EFI_PCI_IO_PROTOCOL   *PciIo,
> +  IN     UINT8                 BarIndex,
> +  IN     UINT32                Offset,
> +  IN     BOOLEAN               Read,
> +  IN     UINT8                 Count,
> +  IN OUT VOID                  *Data
> +  );
> +
> +/**
> +  Do OR operation with the value of the specified SD/MMC host controller mmio register.
> +
> +  @param[in] PciIo             The PCI IO protocol instance.
> +  @param[in] BarIndex          The BAR index of the standard PCI Configuration
> +                               header to use as the base address for the memory
> +                               operation to perform.
> +  @param[in] Offset            The offset within the selected BAR to start the
> +                               memory operation.
> +  @param[in] Count             The width of the mmio register in bytes.
> +                               Must be 1, 2 , 4 or 8 bytes.
> +  @param[in] OrData            The pointer to the data used to do OR operation.
> +                               The caller is responsible for having ownership of
> +                               the data buffer and ensuring its size not less than
> +                               Count bytes.
> +
> +  @retval EFI_INVALID_PARAMETER The PciIo or OrData is NULL or the Count is not valid.
> +  @retval EFI_SUCCESS           The OR operation succeeds.
> +  @retval Others                The OR operation fails.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +XenonHcOrMmio (
> +  IN  EFI_PCI_IO_PROTOCOL      *PciIo,
> +  IN  UINT8                    BarIndex,
> +  IN  UINT32                   Offset,
> +  IN  UINT8                    Count,
> +  IN  VOID                     *OrData
> +  );
> +
> +/**
> +  Do AND operation with the value of the specified SD/MMC host controller mmio register.
> +
> +  @param[in] PciIo             The PCI IO protocol instance.
> +  @param[in] BarIndex          The BAR index of the standard PCI Configuration
> +                               header to use as the base address for the memory
> +                               operation to perform.
> +  @param[in] Offset            The offset within the selected BAR to start the
> +                               memory operation.
> +  @param[in] Count             The width of the mmio register in bytes.
> +                               Must be 1, 2 , 4 or 8 bytes.
> +  @param[in] AndData           The pointer to the data used to do AND operation.
> +                               The caller is responsible for having ownership of
> +                               the data buffer and ensuring its size not less than
> +                               Count bytes.
> +
> +  @retval EFI_INVALID_PARAMETER The PciIo or AndData is NULL or the Count is not valid.
> +  @retval EFI_SUCCESS           The AND operation succeeds.
> +  @retval Others                The AND operation fails.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +XenonHcAndMmio (
> +  IN  EFI_PCI_IO_PROTOCOL      *PciIo,
> +  IN  UINT8                    BarIndex,
> +  IN  UINT32                   Offset,
> +  IN  UINT8                    Count,
> +  IN  VOID                     *AndData
> +  );
> +
> +/**
> +  Wait for the value of the specified MMIO register set to the test value.
> +
> +  @param[in]  PciIo         The PCI IO protocol instance.
> +  @param[in]  BarIndex      The BAR index of the standard PCI Configuration
> +                            header to use as the base address for the memory
> +                            operation to perform.
> +  @param[in]  Offset        The offset within the selected BAR to start the
> +                            memory operation.
> +  @param[in]  Count         The width of the mmio register in bytes.
> +                            Must be 1, 2, 4 or 8 bytes.
> +  @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 1
> +                            microsecond as a unit.
> +
> +  @retval EFI_TIMEOUT       The MMIO register hasn't expected value in timeout
> +                            range.
> +  @retval EFI_SUCCESS       The MMIO register has expected value.
> +  @retval Others            The MMIO operation fails.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +XenonHcWaitMmioSet (
> +  IN  EFI_PCI_IO_PROTOCOL       *PciIo,
> +  IN  UINT8                     BarIndex,
> +  IN  UINT32                    Offset,
> +  IN  UINT8                     Count,
> +  IN  UINT64                    MaskValue,
> +  IN  UINT64                    TestValue,
> +  IN  UINT64                    Timeout
> +  );
> +
> +#endif
> diff --git a/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdMmcOverride.h b/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdMmcOverride.h
> new file mode 100644
> index 0000000..0c7a0b7
> --- /dev/null
> +++ b/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdMmcOverride.h
> @@ -0,0 +1,53 @@
> +/*******************************************************************************
> +Copyright (C) 2018 Marvell International Ltd.
> +
> +Marvell BSD License Option
> +
> +If you received this File from Marvell, you may opt to use, redistribute and/or
> +modify this File under the following licensing terms.
> +Redistribution and use in source and binary forms, with or without modification,
> +are permitted provided that the following conditions are met:
> +
> +* Redistributions of source code must retain the above copyright notice,
> +  this list of conditions and the following disclaimer.
> +
> +* Redistributions in binary form must reproduce the above copyright
> +  notice, this list of conditions and the following disclaimer in the
> +  documentation and/or other materials provided with the distribution.
> +
> +* Neither the name of Marvell nor the names of its contributors may be
> +  used to endorse or promote products derived from this software without
> +  specific prior written permission.
> +
> +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
> +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
> +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
> +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> +
> +*******************************************************************************/
> +#ifndef _XENON_SD_MMC_OVERRIDE_H_
> +#define _XENON_SD_MMC_OVERRIDE_H_
> +
> +#include <Uefi.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiLib.h>
> +
> +#include <Protocol/BoardDesc.h>
> +#include <Protocol/NonDiscoverableDevice.h>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/SdMmcOverride.h>
> +
> +#include "XenonPciHci.h"
> +#include "XenonSdhci.h"
> +
> +#endif
> diff --git a/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdhci.h b/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdhci.h
> index 2be0ee6..8bf1835 100644
> --- a/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdhci.h
> +++ b/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdhci.h
> @@ -32,15 +32,65 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>
>  *******************************************************************************/
>
> -#include "SdMmcPciHcDxe.h"
> -
> +#include <Library/DebugLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
>  #include <Library/IoLib.h>
>
> +#include <Protocol/PciIo.h>
> +#include <Protocol/SdMmcOverride.h>
> +
> +#include "XenonPciHci.h"
> +
>  #define SD_BAR_INDEX 0
>
>  #define SIZE_512B    0x200
>
> -/* Register Offset of SD Host Controller SOCP self-defined register */
> +/* Register Offset of SD Host Controller */
> +#define SDHC_SDMA_ADDR                0x0000
> +#define SDHC_ARG2                     0x0000
> +#define SDHC_BLK_SIZE                 0x0004
> +#define SDHC_BLK_COUNT                0x0006
> +#define SDHC_ARG1                     0x0008
> +#define SDHC_TRANS_MOD                0x000C
> +#define SDHC_COMMAND                  0x000E
> +#define SDHC_RESPONSE                 0x0010
> +#define SDHC_BUF_DAT_PORT             0x0020
> +#define SDHC_PRESENT_STATE            0x0024
> +#define SDHC_HOST_CTRL1               0x0028
> +#define SDHC_POWER_CTRL               0x0029
> +#define SDHC_BLK_GAP_CTRL             0x002A
> +#define SDHC_WAKEUP_CTRL              0x002B
> +#define SDHC_CLOCK_CTRL               0x002C
> +#define SDHC_TIMEOUT_CTRL             0x002E
> +#define SDHC_SW_RST                   0x002F
> +#define SDHC_NOR_INT_STS              0x0030
> +#define SDHC_ERR_INT_STS              0x0032
> +#define SDHC_NOR_INT_STS_EN           0x0034
> +#define SDHC_ERR_INT_STS_EN           0x0036
> +#define SDHC_NOR_INT_SIG_EN           0x0038
> +#define SDHC_ERR_INT_SIG_EN           0x003A
> +#define SDHC_AUTO_CMD_ERR_STS         0x003C
> +#define SDHC_HOST_CTRL2               0x003E
> +#define UHS_MODE_SELECT_MASK          0x7
> +#define SDHC_CAP                      0x0040
> +#define SDHC_CAP_BUS_WIDTH8           BIT18
> +#define SDHC_CAP_VOLTAGE_33           BIT24
> +#define SDHC_CAP_VOLTAGE_30           BIT25
> +#define SDHC_CAP_VOLTAGE_18           BIT26
> +#define SDHC_CAP_SLOT_TYPE_OFFSET     30
> +#define SDHC_CAP_SLOT_TYPE_MASK       (BIT30 | BIT31)
> +#define SDHC_CAP_SDR50                BIT32
> +#define SDHC_CAP_SDR104               BIT33
> +#define SDHC_CAP_DDR50                BIT34
> +#define SDHC_MAX_CURRENT_CAP          0x0048
> +#define SDHC_FORCE_EVT_AUTO_CMD       0x0050
> +#define SDHC_FORCE_EVT_ERR_INT        0x0052
> +#define SDHC_ADMA_ERR_STS             0x0054
> +#define SDHC_ADMA_SYS_ADDR            0x0058
> +#define SDHC_PRESET_VAL               0x0060
> +#define SDHC_SHARED_BUS_CTRL          0x00E0
> +#define SDHC_SLOT_INT_STS             0x00FC
> +#define SDHC_CTRL_VER                 0x00FE
>
>  #define SDHC_IPID                     0x0100
>  #define SDHC_SYS_CFG_INFO             0x0104
> @@ -52,10 +102,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>
>  #define SDHC_SYS_OP_CTRL              0x0108
>  #define AUTO_CLKGATE_DISABLE_MASK     (0x1<<20)
> -#define SDCLK_IDLEOFF_ENABLE_SHIFT    8
> +#define SDCLK_IDLEOFF_ENABLE_MASK     (1 << 8)
>  #define SLOT_ENABLE_SHIFT             0
>
>  #define SDHC_SYS_EXT_OP_CTRL          0x010c
> +#define MASK_CMD_CONFLICT_ERR         (1 << 8)
> +
>  #define SDHC_TEST_OUT                 0x0110
>  #define SDHC_TESTOUT_MUXSEL           0x0114
>
> @@ -169,11 +221,27 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>  #define TMR_RETUN_NO_PRESENT          0xf
>  #define XENON_MAX_TUN_COUNT           0xb
>
> +#define XENON_SLOT_OP_STATUS_CTRL     0x0128
> +#define TUN_CONSECUTIVE_TIMES_SHIFT   16
> +#define TUN_CONSECUTIVE_TIMES_MASK    0x7
> +#define TUN_CONSECUTIVE_TIMES         0x4
> +#define TUNING_STEP_SHIFT             12
> +#define TUNING_STEP_MASK              0xF
> +
> +#define XENON_SLOT_EMMC_CTRL          0x130
> +#define ENABLE_DATA_STROBE            (1 << 24)
> +
> +#define XENON_SLOT_EXT_PRESENT_STATE  0x014C
> +#define DLL_LOCK_STATE                0x1
> +
> +#define XENON_SLOT_DLL_CUR_DLY_VAL    0x0150
> +
>  #define EMMC_PHY_REG_BASE                 0x170
>  #define EMMC_PHY_TIMING_ADJUST            EMMC_PHY_REG_BASE
>  #define OUTPUT_QSN_PHASE_SELECT           (1 << 17)
>  #define SAMPL_INV_QSP_PHASE_SELECT        (1 << 18)
>  #define SAMPL_INV_QSP_PHASE_SELECT_SHIFT  18
> +#define QSN_PHASE_SLOW_MODE_BIT           (1 << 29)
>  #define PHY_INITIALIZAION                 (1 << 31)
>  #define WAIT_CYCLE_BEFORE_USING_MASK      0xf
>  #define WAIT_CYCLE_BEFORE_USING_SHIFT     12
> @@ -199,20 +267,42 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>  #define FC_QSN_RECEN              (1 << 27)
>  #define OEN_QSN                   (1 << 28)
>  #define AUTO_RECEN_CTRL           (1 << 30)
> +#define FC_ALL_CMOS_RECEIVER      0xF000
>
>  #define EMMC_PHY_PAD_CONTROL1        (EMMC_PHY_REG_BASE + 0xc)
> +#define EMMC5_1_FC_QSP_PD            (1 << 9)
> +#define EMMC5_1_FC_QSP_PU            (1 << 25)
> +#define EMMC5_1_FC_CMD_PD            (1 << 8)
> +#define EMMC5_1_FC_CMD_PU            (1 << 24)
> +#define EMMC5_1_FC_DQ_PD             0xFF
> +#define EMMC5_1_FC_DQ_PU             (0xFF << 16)
> +
>  #define EMMC_PHY_PAD_CONTROL2        (EMMC_PHY_REG_BASE + 0x10)
> +#define ZNR_MASK                     0x1F
> +#define ZNR_SHIFT                    8
> +#define ZPR_MASK                     0x1F
> +#define ZNR_DEF_VALUE                0xF
> +#define ZPR_DEF_VALUE                0xF
> +
>  #define EMMC_PHY_DLL_CONTROL         (EMMC_PHY_REG_BASE + 0x14)
> -#define DLL_DELAY_TEST_LOWER_SHIFT   8
> -#define DLL_DELAY_TEST_LOWER_MASK    0xff
> -#define DLL_BYPASS_EN                0x1
> +#define DLL_ENABLE                   (1 << 31)
> +#define DLL_UPDATE_STROBE_5_0        (1 << 30)
> +#define DLL_REFCLK_SEL               (1 << 30)
> +#define DLL_UPDATE                   (1 << 23)
> +#define DLL_PHSEL1_SHIFT             24
> +#define DLL_PHSEL0_SHIFT             16
> +#define DLL_PHASE_MASK               0x3F
> +#define DLL_PHASE_90_DEGREE          0x1F
> +#define DLL_FAST_LOCK                (1 << 5)
> +#define DLL_GAIN2X                   (1 << 3)
> +#define DLL_BYPASS_EN                (1 << 0)
>
>  #define EMMC_LOGIC_TIMING_ADJUST       (EMMC_PHY_REG_BASE + 0x18)
>  #define EMMC_LOGIC_TIMING_ADJUST_LOW   (EMMC_PHY_REG_BASE + 0x1c)
>
>  #define LOGIC_TIMING_VALUE             0x5a54 /* Recommend by HW team */
>
> -#define QSN_PHASE_SLOW_MODE_BIT        (1 << 29)
> +#define TUNING_STEP_DIVIDER_SHIFT      6
>
>  /* XENON only have one slot 0 */
>  #define XENON_MMC_SLOT_ID              (0)
> @@ -227,6 +317,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>  #define MMC_TIMING_UHS_DDR50  7
>  #define MMC_TIMING_MMC_HS200  8
>  #define MMC_TIMING_MMC_HS400  10
> +#define MMC_TIMING_MMC_DDR52  11
> +
> +/* Custom UHS signaling field values */
> +#define XENON_SD_MMC_HC_CTRL_HS200    0x5
> +#define XENON_SD_MMC_HC_CTRL_HS400    0x6
>
>  /* Data time out default value 0xE: TMCLK x 227 */
>  #define DATA_TIMEOUT_DEF_VAL          0xE
> @@ -305,7 +400,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>  UINTN
>  XenonSetClk (
>    IN EFI_PCI_IO_PROTOCOL   *PciIo,
> -  IN SD_MMC_HC_PRIVATE_DATA *Private,
>    IN UINT32 Clock
>    );
>
> @@ -316,14 +410,14 @@ XenonPhyInit (
>
>  VOID
>  XenonReset (
> -  IN SD_MMC_HC_PRIVATE_DATA *Private,
> +  IN EFI_PCI_IO_PROTOCOL *PciIo,
>    IN UINT8 Slot,
>    IN UINT8 Mask
>    );
>
>  EFI_STATUS
>  XenonTransferData (
> -  IN SD_MMC_HC_PRIVATE_DATA *Private,
> +  IN EFI_PCI_IO_PROTOCOL *PciIo,
>    IN UINT8 Slot,
>    IN OUT VOID *Buffer,
>    IN UINT32 DataLen,
> @@ -334,13 +428,16 @@ XenonTransferData (
>
>  EFI_STATUS
>  XenonInit (
> -  IN SD_MMC_HC_PRIVATE_DATA *Private
> +  IN EFI_PCI_IO_PROTOCOL   *PciIo,
> +  IN BOOLEAN               Support1v8,
> +  IN BOOLEAN               SlowMode,
> +  IN UINT8                 TuningStepDivisor
>    );
>
>  EFI_STATUS
> -SdCardSendStatus (
> -  IN  EFI_SD_MMC_PASS_THRU_PROTOCOL  *PassThru,
> -  IN  UINT8                          Slot,
> -  IN  UINT16                         Rca,
> -  OUT UINT32                         *DevStatus
> +XenonSetPhy (
> +  IN EFI_PCI_IO_PROTOCOL   *PciIo,
> +  IN BOOLEAN               SlowMode,
> +  IN UINT8                 TuningStepDivisor,
> +  IN SD_MMC_BUS_MODE       Timing
>    );
> diff --git a/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonPciHci.c b/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonPciHci.c
> new file mode 100644
> index 0000000..8a22046
> --- /dev/null
> +++ b/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonPciHci.c
> @@ -0,0 +1,321 @@
> +/** @file
> +  This driver is used to manage SD/MMC PCI host controllers which are compliance
> +  with SD Host Controller Simplified Specification version 3.00.
> +
> +  It would expose EFI_SD_MMC_PASS_THRU_PROTOCOL for upper layer use.
> +
> +  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2018, Marvell International, Ltd. All rights reserved.<BR>
> +
> +  This program and the accompanying materials
> +  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
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "XenonSdMmcOverride.h"
> +
> +/**
> +  Read/Write specified SD/MMC host controller mmio register.
> +
> +  @param[in]      PciIo        The PCI IO protocol instance.
> +  @param[in]      BarIndex     The BAR index of the standard PCI Configuration
> +                               header to use as the base address for the memory
> +                               operation to perform.
> +  @param[in]      Offset       The offset within the selected BAR to start the
> +                               memory operation.
> +  @param[in]      Read         A boolean to indicate it's read or write operation.
> +  @param[in]      Count        The width of the mmio register in bytes.
> +                               Must be 1, 2 , 4 or 8 bytes.
> +  @param[in, out] Data         For read operations, the destination buffer to store
> +                               the results. For write operations, the source buffer
> +                               to write data from. The caller is responsible for
> +                               having ownership of the data buffer and ensuring its
> +                               size not less than Count bytes.
> +
> +  @retval EFI_INVALID_PARAMETER The PciIo or Data is NULL or the Count is not valid.
> +  @retval EFI_SUCCESS           The read/write operation succeeds.
> +  @retval Others                The read/write operation fails.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +XenonHcRwMmio (
> +  IN     EFI_PCI_IO_PROTOCOL   *PciIo,
> +  IN     UINT8                 BarIndex,
> +  IN     UINT32                Offset,
> +  IN     BOOLEAN               Read,
> +  IN     UINT8                 Count,
> +  IN OUT VOID                  *Data
> +  )
> +{
> +  EFI_STATUS                   Status;
> +
> +  if ((PciIo == NULL) || (Data == NULL))  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if ((Count != 1) && (Count != 2) && (Count != 4) && (Count != 8)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (Read) {
> +    Status = PciIo->Mem.Read (
> +                          PciIo,
> +                          EfiPciIoWidthUint8,
> +                          BarIndex,
> +                          (UINT64) Offset,
> +                          Count,
> +                          Data
> +                          );
> +  } else {
> +    Status = PciIo->Mem.Write (
> +                          PciIo,
> +                          EfiPciIoWidthUint8,
> +                          BarIndex,
> +                          (UINT64) Offset,
> +                          Count,
> +                          Data
> +                          );
> +  }
> +

I guess this is an issue that existed before in the code, but it looks
like you are only doing byte for byte reads and writes here. Is that
intentional?

> +  return Status;
> +}
> +
> +/**
> +  Do OR operation with the value of the specified SD/MMC host controller mmio register.
> +
> +  @param[in] PciIo             The PCI IO protocol instance.
> +  @param[in] BarIndex          The BAR index of the standard PCI Configuration
> +                               header to use as the base address for the memory
> +                               operation to perform.
> +  @param[in] Offset            The offset within the selected BAR to start the
> +                               memory operation.
> +  @param[in] Count             The width of the mmio register in bytes.
> +                               Must be 1, 2 , 4 or 8 bytes.
> +  @param[in] OrData            The pointer to the data used to do OR operation.
> +                               The caller is responsible for having ownership of
> +                               the data buffer and ensuring its size not less than
> +                               Count bytes.
> +
> +  @retval EFI_INVALID_PARAMETER The PciIo or OrData is NULL or the Count is not valid.
> +  @retval EFI_SUCCESS           The OR operation succeeds.
> +  @retval Others                The OR operation fails.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +XenonHcOrMmio (
> +  IN  EFI_PCI_IO_PROTOCOL      *PciIo,
> +  IN  UINT8                    BarIndex,
> +  IN  UINT32                   Offset,
> +  IN  UINT8                    Count,
> +  IN  VOID                     *OrData
> +  )
> +{
> +  EFI_STATUS                   Status;
> +  UINT64                       Data;
> +  UINT64                       Or;
> +
> +  Status = XenonHcRwMmio (PciIo, BarIndex, Offset, TRUE, Count, &Data);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  if (Count == 1) {
> +    Or = *(UINT8*) OrData;
> +  } else if (Count == 2) {
> +    Or = *(UINT16*) OrData;
> +  } else if (Count == 4) {
> +    Or = *(UINT32*) OrData;
> +  } else if (Count == 8) {
> +    Or = *(UINT64*) OrData;
> +  } else {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Data  |= Or;
> +  Status = XenonHcRwMmio (PciIo, BarIndex, Offset, FALSE, Count, &Data);
> +
> +  return Status;
> +}
> +
> +/**
> +  Do AND operation with the value of the specified SD/MMC host controller mmio register.
> +
> +  @param[in] PciIo             The PCI IO protocol instance.
> +  @param[in] BarIndex          The BAR index of the standard PCI Configuration
> +                               header to use as the base address for the memory
> +                               operation to perform.
> +  @param[in] Offset            The offset within the selected BAR to start the
> +                               memory operation.
> +  @param[in] Count             The width of the mmio register in bytes.
> +                               Must be 1, 2 , 4 or 8 bytes.
> +  @param[in] AndData           The pointer to the data used to do AND operation.
> +                               The caller is responsible for having ownership of
> +                               the data buffer and ensuring its size not less than
> +                               Count bytes.
> +
> +  @retval EFI_INVALID_PARAMETER The PciIo or AndData is NULL or the Count is not valid.
> +  @retval EFI_SUCCESS           The AND operation succeeds.
> +  @retval Others                The AND operation fails.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +XenonHcAndMmio (
> +  IN  EFI_PCI_IO_PROTOCOL      *PciIo,
> +  IN  UINT8                    BarIndex,
> +  IN  UINT32                   Offset,
> +  IN  UINT8                    Count,
> +  IN  VOID                     *AndData
> +  )
> +{
> +  EFI_STATUS                   Status;
> +  UINT64                       Data;
> +  UINT64                       And;
> +
> +  Status = XenonHcRwMmio (PciIo, BarIndex, Offset, TRUE, Count, &Data);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  if (Count == 1) {
> +    And = *(UINT8*) AndData;
> +  } else if (Count == 2) {
> +    And = *(UINT16*) AndData;
> +  } else if (Count == 4) {
> +    And = *(UINT32*) AndData;
> +  } else if (Count == 8) {
> +    And = *(UINT64*) AndData;
> +  } else {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Data  &= And;
> +  Status = XenonHcRwMmio (PciIo, BarIndex, Offset, FALSE, Count, &Data);
> +
> +  return Status;
> +}
> +
> +/**
> +  Wait for the value of the specified MMIO register set to the test value.
> +
> +  @param[in]  PciIo         The PCI IO protocol instance.
> +  @param[in]  BarIndex      The BAR index of the standard PCI Configuration
> +                            header to use as the base address for the memory
> +                            operation to perform.
> +  @param[in]  Offset        The offset within the selected BAR to start the
> +                            memory operation.
> +  @param[in]  Count         The width of the mmio register in bytes.
> +                            Must be 1, 2, 4 or 8 bytes.
> +  @param[in]  MaskValue     The mask value of memory.
> +  @param[in]  TestValue     The test value of memory.
> +
> +  @retval EFI_NOT_READY     The MMIO register hasn't set to the expected value.
> +  @retval EFI_SUCCESS       The MMIO register has expected value.
> +  @retval Others            The MMIO operation fails.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +XenonHcCheckMmioSet (
> +  IN  EFI_PCI_IO_PROTOCOL       *PciIo,
> +  IN  UINT8                     BarIndex,
> +  IN  UINT32                    Offset,
> +  IN  UINT8                     Count,
> +  IN  UINT64                    MaskValue,
> +  IN  UINT64                    TestValue
> +  )
> +{
> +  EFI_STATUS            Status;
> +  UINT64                Value;
> +
> +  //
> +  // Access PCI MMIO space to see if the value is the tested one.
> +  //
> +  Value  = 0;
> +  Status = XenonHcRwMmio (PciIo, BarIndex, Offset, TRUE, Count, &Value);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Value &= MaskValue;
> +
> +  if (Value == TestValue) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  return EFI_NOT_READY;
> +}
> +
> +/**
> +  Wait for the value of the specified MMIO register set to the test value.
> +
> +  @param[in]  PciIo         The PCI IO protocol instance.
> +  @param[in]  BarIndex      The BAR index of the standard PCI Configuration
> +                            header to use as the base address for the memory
> +                            operation to perform.
> +  @param[in]  Offset        The offset within the selected BAR to start the
> +                            memory operation.
> +  @param[in]  Count         The width of the mmio register in bytes.
> +                            Must be 1, 2, 4 or 8 bytes.
> +  @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 1
> +                            microsecond as a unit.
> +
> +  @retval EFI_TIMEOUT       The MMIO register hasn't expected value in timeout
> +                            range.
> +  @retval EFI_SUCCESS       The MMIO register has expected value.
> +  @retval Others            The MMIO operation fails.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +XenonHcWaitMmioSet (
> +  IN  EFI_PCI_IO_PROTOCOL       *PciIo,
> +  IN  UINT8                     BarIndex,
> +  IN  UINT32                    Offset,
> +  IN  UINT8                     Count,
> +  IN  UINT64                    MaskValue,
> +  IN  UINT64                    TestValue,
> +  IN  UINT64                    Timeout
> +  )
> +{
> +  EFI_STATUS            Status;
> +  BOOLEAN               InfiniteWait;
> +
> +  if (Timeout == 0) {
> +    InfiniteWait = TRUE;
> +  } else {
> +    InfiniteWait = FALSE;
> +  }
> +
> +  while (InfiniteWait || (Timeout > 0)) {
> +    Status = XenonHcCheckMmioSet (
> +               PciIo,
> +               BarIndex,
> +               Offset,
> +               Count,
> +               MaskValue,
> +               TestValue
> +               );
> +    if (Status != EFI_NOT_READY) {
> +      return Status;
> +    }
> +
> +    //
> +    // Stall for 1 microsecond.
> +    //
> +    gBS->Stall (1);
> +
> +    Timeout--;
> +  }
> +
> +  return EFI_TIMEOUT;
> +}
> diff --git a/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdMmcOverride.c b/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdMmcOverride.c
> new file mode 100644
> index 0000000..7babda1
> --- /dev/null
> +++ b/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdMmcOverride.c
> @@ -0,0 +1,432 @@
> +/*******************************************************************************
> +Copyright (C) 2018 Marvell International Ltd.
> +
> +Marvell BSD License Option
> +
> +If you received this File from Marvell, you may opt to use, redistribute and/or
> +modify this File under the following licensing terms.
> +Redistribution and use in source and binary forms, with or without modification,
> +are permitted provided that the following conditions are met:
> +
> +* Redistributions of source code must retain the above copyright notice,
> +  this list of conditions and the following disclaimer.
> +
> +* Redistributions in binary form must reproduce the above copyright
> +  notice, this list of conditions and the following disclaimer in the
> +  documentation and/or other materials provided with the distribution.
> +
> +* Neither the name of Marvell nor the names of its contributors may be
> +  used to endorse or promote products derived from this software without
> +  specific prior written permission.
> +
> +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
> +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
> +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
> +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> +
> +*******************************************************************************/
> +
> +#include "XenonSdMmcOverride.h"
> +
> +STATIC EFI_HANDLE              mXenonSdMmcOverrideHandle;
> +STATIC EDKII_SD_MMC_OVERRIDE  *mSdMmcOverride;
> +
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +XenonGetSdMmcDesc (
> +  IN      EFI_HANDLE              ControllerHandle,
> +  IN OUT  MV_BOARD_SDMMC_DESC     *SdMmcDesc
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  MV_BOARD_SDMMC_DESC             *SdMmcDescs;
> +  NON_DISCOVERABLE_DEVICE         *Device;
> +  MARVELL_BOARD_DESC_PROTOCOL     *BoardDescProtocol;
> +  UINTN                           Index;
> +
> +  Device = NULL;
> +  Status = gBS->OpenProtocol (ControllerHandle,
> +                  &gEdkiiNonDiscoverableDeviceProtocolGuid,
> +                  (VOID **) &Device,
> +                  mXenonSdMmcOverrideHandle,
> +                  ControllerHandle,
> +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  BoardDescProtocol = NULL;
> +  Status = gBS->LocateProtocol (&gMarvellBoardDescProtocolGuid,
> +                  NULL,
> +                  (VOID **) &BoardDescProtocol);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = BoardDescProtocol->BoardDescSdMmcGet (BoardDescProtocol, &SdMmcDescs);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  for (Index = 0; Index < SdMmcDescs->SdMmcDevCount; Index++) {
> +    if (SdMmcDescs[Index].SoC->SdMmcBaseAddress ==
> +        Device->Resources[0].AddrRangeMin) {
> +      *SdMmcDesc = SdMmcDescs[Index];
> +      break;
> +    }
> +  }
> +
> +  if (Index == SdMmcDescs->SdMmcDevCount) {
> +    BoardDescProtocol->BoardDescFree (SdMmcDescs);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  BoardDescProtocol->BoardDescFree (SdMmcDescs);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +XenonGetPciIo (
> +  IN      EFI_HANDLE              ControllerHandle,
> +  IN OUT  EFI_PCI_IO_PROTOCOL     **PciIo
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  *PciIo  = NULL;
> +  Status = gBS->OpenProtocol (ControllerHandle,
> +                  &gEfiPciIoProtocolGuid,
> +                  (VOID **) PciIo,
> +                  mXenonSdMmcOverrideHandle,
> +                  ControllerHandle,
> +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> +  return Status;
> +}
> +
> +/**
> +  Set SD Host Controler control 2 registry according to selected speed.
> +

Controller

> +  @param[in] ControllerHandle The EFI_HANDLE of the controller.
> +  @param[in] Slot             The slot number of the SD card to send the command to.
> +  @param[in] Timing           The timing to select.
> +
> +  @retval EFI_SUCCESS         The override function completed successfully.
> +  @retval EFI_NOT_FOUND       The specified controller or slot does not exist.
> +**/
> +STATIC
> +EFI_STATUS
> +XenonSdMmcHcUhsSignaling (
> +  IN EFI_HANDLE             ControllerHandle,
> +  IN UINT8                  Slot,
> +  IN SD_MMC_BUS_MODE        Timing
> +  )
> +{
> +  EFI_PCI_IO_PROTOCOL      *PciIo;
> +  EFI_STATUS                Status;
> +  UINT8                     HostCtrl2;
> +  UINT8                     XenonUhsSelect;
> +
> +  if (Slot != 0) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // Update Host Control Register 2 only for HS200/HS400.
> +  //
> +  switch (Timing) {
> +    case SdMmcMmcHs200:
> +      XenonUhsSelect = XENON_SD_MMC_HC_CTRL_HS200;
> +      break;
> +    case SdMmcMmcHs400:
> +      XenonUhsSelect = XENON_SD_MMC_HC_CTRL_HS400;
> +      break;
> +    default:
> +      return EFI_SUCCESS;
> +  }
> +
> +  Status = XenonGetPciIo (ControllerHandle, &PciIo);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  HostCtrl2 = (UINT8)~UHS_MODE_SELECT_MASK;
> +  Status = XenonHcAndMmio (PciIo,
> +             Slot,
> +             SDHC_HOST_CTRL2,
> +             sizeof (HostCtrl2),
> +             &HostCtrl2);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = XenonHcOrMmio (PciIo,
> +             Slot,
> +             SDHC_HOST_CTRL2,
> +             sizeof (XenonUhsSelect),
> +             &XenonUhsSelect);
> +
> +  return Status;
> +}
> +
> +/**
> +
> +  Additional operations specific for host controller
> +
> +  @param[in]      ControllerHandle      The EFI_HANDLE of the controller.
> +  @param[in]      Slot                  The 0 based slot index.
> +  @param[in]      Timing                The timing which should be set by
> +                                        host controller.
> +
> +  @retval EFI_SUCCESS           The override function completed successfully.
> +  @retval EFI_NOT_FOUND         The specified controller or slot does not exist.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +XenonSwitchClockFreqPost (
> +  IN      EFI_HANDLE                      ControllerHandle,
> +  IN      UINT8                           Slot,
> +  IN      SD_MMC_BUS_MODE                 Timing
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  MV_BOARD_SDMMC_DESC             SdMmcDesc;
> +  EFI_PCI_IO_PROTOCOL             *PciIo;
> +
> +  if (Slot != 0) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Status = XenonGetPciIo (ControllerHandle, &PciIo);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  Status = XenonGetSdMmcDesc (ControllerHandle, &SdMmcDesc);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = XenonSetPhy (PciIo,
> +             SdMmcDesc.XenonSlowModeEnabled,
> +             SdMmcDesc.XenonTuningStepDivisor,
> +             Timing);
> +
> +  return Status;
> +}
> +
> +/**
> +
> +  Override function for SDHCI controller operations
> +
> +  @param[in]      ControllerHandle      The EFI_HANDLE of the controller.
> +  @param[in]      Slot                  The 0 based slot index.
> +  @param[in]      PhaseType             The type of operation and whether the
> +                                        hook is invoked right before (pre) or
> +                                        right after (post)
> +  @param[in]      PhaseData             The pointer to a phase-specific data.
> +
> +  @retval EFI_SUCCESS           The override function completed successfully.
> +  @retval EFI_NOT_FOUND         The specified controller or slot does not exist.
> +  @retval EFI_UNSUPPORTED       Nothing has been done in connection of PhaseType
> +  @retval EFI_INVALID_PARAMETER PhaseType is invalid
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +XenonSdMmcNotifyPhase (
> +  IN      EFI_HANDLE                      ControllerHandle,
> +  IN      UINT8                           Slot,
> +  IN      EDKII_SD_MMC_PHASE_TYPE         PhaseType,
> +  IN OUT  VOID                           *PhaseData
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  MV_BOARD_SDMMC_DESC             SdMmcDesc;
> +  EFI_PCI_IO_PROTOCOL             *PciIo;
> +  SD_MMC_BUS_MODE                 *Timing;
> +
> +  if (Slot != 0) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  switch (PhaseType) {
> +    case EdkiiSdMmcInitHostPre:
> +      Status = XenonGetPciIo (ControllerHandle, &PciIo);
> +      if (EFI_ERROR (Status)) {
> +        return Status;
> +      }
> +
> +      Status = XenonGetSdMmcDesc (ControllerHandle, &SdMmcDesc);
> +      if (EFI_ERROR (Status)) {
> +        return Status;
> +      }
> +
> +      Status = XenonInit (PciIo,
> +                 SdMmcDesc.Xenon1v8Enabled,
> +                 SdMmcDesc.XenonSlowModeEnabled,
> +                 SdMmcDesc.XenonTuningStepDivisor);
> +      return Status;
> +    case EdkiiSdMmcUhsSignaling:
> +      if (PhaseData == NULL) {
> +        return EFI_INVALID_PARAMETER;
> +      }
> +
> +      Timing = (SD_MMC_BUS_MODE *)PhaseData;
> +
> +      Status = XenonSdMmcHcUhsSignaling (ControllerHandle,
> +                 Slot,
> +                 *Timing);
> +      if (EFI_ERROR (Status)) {
> +        return Status;
> +      }
> +      break;
> +    case EdkiiSdMmcSwitchClockFreqPost:
> +      if (PhaseData == NULL) {
> +        return EFI_INVALID_PARAMETER;
> +      }
> +
> +      Timing = (SD_MMC_BUS_MODE *)PhaseData;
> +
> +      Status = XenonSwitchClockFreqPost (ControllerHandle,
> +                 Slot,
> +                 *Timing);
> +      if (EFI_ERROR (Status)) {
> +        return Status;
> +      }
> +      break;
> +    default:
> +      return EFI_SUCCESS;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +  Override function for SDHCI capability bits
> +
> +  @param[in]      ControllerHandle      The EFI_HANDLE of the controller.
> +  @param[in]      Slot                  The 0 based slot index.
> +  @param[in,out]  SdMmcHcSlotCapability The SDHCI capability structure.
> +  @param[in,out]  BaseClkFreq           The base clock frequency value that
> +                                        optionally can be updated.
> +
> +  @retval EFI_SUCCESS           The override function completed successfully.
> +  @retval EFI_NOT_FOUND         The specified controller or slot does not exist.
> +  @retval EFI_INVALID_PARAMETER SdMmcHcSlotCapability is NULL
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +XenonSdMmcCapability (
> +  IN      EFI_HANDLE                      ControllerHandle,
> +  IN      UINT8                           Slot,
> +  IN OUT  VOID                            *SdMmcHcSlotCapability,
> +  IN OUT  UINT32                          *BaseClkFreq
> +  )
> +{
> +  EFI_STATUS           Status;
> +  MV_BOARD_SDMMC_DESC  SdMmcDesc;
> +  UINT64               Capability;
> +
> +  if (SdMmcHcSlotCapability == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  if (Slot != 0) {
> +    return EFI_NOT_FOUND;
> +  }
> +  Status = XenonGetSdMmcDesc (ControllerHandle, &SdMmcDesc);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Capability = ReadUnaligned64 (SdMmcHcSlotCapability);
> +
> +  //
> +  // Override capabilities structure according to board configuration.
> +  //
> +  if (SdMmcDesc.Xenon1v8Enabled) {
> +    Capability &= ~(UINT64)(SDHC_CAP_VOLTAGE_33 | SDHC_CAP_VOLTAGE_30);
> +  } else {
> +    Capability &= ~(UINT64)(SDHC_CAP_SDR104 | SDHC_CAP_DDR50 |
> +                            SDHC_CAP_SDR50 | SDHC_CAP_VOLTAGE_18);
> +  }
> +
> +  if (!SdMmcDesc.Xenon8BitBusEnabled) {
> +    Capability &= ~(UINT64)(SDHC_CAP_BUS_WIDTH8);
> +  }
> +
> +  if (SdMmcDesc.XenonSlowModeEnabled) {
> +    Capability &= ~(UINT64)(SDHC_CAP_SDR104 | SDHC_CAP_DDR50);
> +  }
> +
> +  Capability &= ~(UINT64)(SDHC_CAP_SLOT_TYPE_MASK);
> +  Capability |= SdMmcDesc.SlotType << SDHC_CAP_SLOT_TYPE_OFFSET;
> +
> +  WriteUnaligned64 (SdMmcHcSlotCapability, Capability);
> +
> +  //
> +  // Override inappropriate base clock frequency from Capabilities Register 1.
> +  // Actual clock speed of Xenon controller is 400MHz.
> +  //
> +  *BaseClkFreq = XENON_MMC_MAX_CLK / 1000 / 1000;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  The entry point for Xenon driver, used to install SdMMcOverrideProtocol
> +  on the ImageHandle.
> +
> +  @param[in]  ImageHandle   The firmware allocated handle for this driver image.
> +  @param[in]  SystemTable   Pointer to the EFI system table.
> +
> +  @retval EFI_SUCCESS   Driver loaded.
> +  @retval other         Driver not loaded.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializeXenonDxe (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  mSdMmcOverride = AllocateZeroPool (sizeof (EDKII_SD_MMC_OVERRIDE));
> +  if (mSdMmcOverride == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a: Cannot allocate memory\n", __FUNCTION__));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  mSdMmcOverride->Version = EDKII_SD_MMC_OVERRIDE_PROTOCOL_VERSION;
> +  mSdMmcOverride->Capability = XenonSdMmcCapability;
> +  mSdMmcOverride->NotifyPhase = XenonSdMmcNotifyPhase;
> +
> +  Status = gBS->InstallProtocolInterface (&ImageHandle,
> +                  &gEdkiiSdMmcOverrideProtocolGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  mSdMmcOverride);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR,
> +      "%a: Filed to install SdMmcOverride protocol\n",
> +      __FUNCTION__));
> +    return Status;
> +  }
> +
> +  mXenonSdMmcOverrideHandle = ImageHandle;
> +
> +  return Status;
> +}
> diff --git a/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdhci.c b/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdhci.c
> index 6bbe5bc..0b4949d 100755
> --- a/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdhci.c
> +++ b/Silicon/Marvell/Drivers/SdMmc/XenonDxe/XenonSdhci.c
> @@ -41,7 +41,7 @@ XenonReadVersion (
>    OUT UINT32 *ControllerVersion
>    )
>  {
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SD_MMC_HC_CTRL_VER, TRUE, SDHC_REG_SIZE_2B, ControllerVersion);
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_CTRL_VER, TRUE, SDHC_REG_SIZE_2B, ControllerVersion);
>  }
>
>  // Auto Clock Gating
> @@ -54,7 +54,7 @@ XenonSetAcg (
>  {
>    UINT32 Var;
>
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_SYS_OP_CTRL, TRUE, SDHC_REG_SIZE_4B, &Var);
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_SYS_OP_CTRL, TRUE, SDHC_REG_SIZE_4B, &Var);
>
>    if (Enable) {
>      Var &= ~AUTO_CLKGATE_DISABLE_MASK;
> @@ -62,7 +62,7 @@ XenonSetAcg (
>      Var |= AUTO_CLKGATE_DISABLE_MASK;
>    }
>
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_SYS_OP_CTRL, FALSE, SDHC_REG_SIZE_4B, &Var);
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_SYS_OP_CTRL, FALSE, SDHC_REG_SIZE_4B, &Var);
>  }
>
>  STATIC
> @@ -75,14 +75,17 @@ XenonSetSlot (
>  {
>    UINT32 Var;
>
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_SYS_OP_CTRL, TRUE, SDHC_REG_SIZE_4B, &Var);
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_SYS_OP_CTRL, TRUE, SDHC_REG_SIZE_4B, &Var);
>    if (Enable) {
>      Var |= ((0x1 << Slot) << SLOT_ENABLE_SHIFT);
>    } else {
>      Var &= ~((0x1 << Slot) << SLOT_ENABLE_SHIFT);
>    }
>
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_SYS_OP_CTRL, FALSE, SDHC_REG_SIZE_4B, &Var);
> +  // Enable SDCLK off while idle
> +  Var |= SDCLK_IDLEOFF_ENABLE_MASK;
> +
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_SYS_OP_CTRL, FALSE, SDHC_REG_SIZE_4B, &Var);
>  }
>
>  //
> @@ -111,7 +114,6 @@ XenonSetPower (
>    )
>  {
>    UINT8 Pwr = 0;
> -  UINT32 Ctrl = 0;
>
>    // Below statement calls routine to set voltage for SDIO devices in either HIGH (1) or LOW (0) mode
>    switch (Vcc) {
> @@ -141,39 +143,36 @@ XenonSetPower (
>    }
>
>    if (Pwr == 0) {
> -    SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SD_MMC_HC_POWER_CTRL, FALSE, SDHC_REG_SIZE_1B, &Pwr);
> +    XenonHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_POWER_CTRL, FALSE, SDHC_REG_SIZE_1B, &Pwr);
>      return;
>    }
>
>    Pwr |= SDHCI_POWER_ON;
>
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX,SD_MMC_HC_POWER_CTRL, FALSE, SDHC_REG_SIZE_1B, &Pwr);
> -
> -  // Set VCCQ
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_SLOT_eMMC_CTRL, TRUE, SDHC_REG_SIZE_4B, &Ctrl);
> -  Ctrl |= Vccq;
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_SLOT_eMMC_CTRL, FALSE, SDHC_REG_SIZE_4B, &Ctrl);
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_POWER_CTRL, FALSE, SDHC_REG_SIZE_1B, &Pwr);
>  }
>
>  UINTN
>  XenonSetClk (
>    IN EFI_PCI_IO_PROTOCOL   *PciIo,
> -  IN SD_MMC_HC_PRIVATE_DATA *Private,
>    IN UINT32 Clock
>    )
>  {
>    UINT32 Div;
>    UINT32 Clk;
>    UINT32 Retry;
> +  UINT32 ControllerVersion;
>    UINT16 Value = 0;
>
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SD_MMC_HC_CLOCK_CTRL, FALSE, SDHC_REG_SIZE_2B, &Value);
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_CLOCK_CTRL, FALSE, SDHC_REG_SIZE_2B, &Value);
>
>    if (Clock == 0) {
>      return 0;
>    }
>
> -  if (Private->ControllerVersion >= SDHCI_SPEC_300) {
> +  XenonReadVersion (PciIo, &ControllerVersion);
> +
> +  if (ControllerVersion >= SDHCI_SPEC_300) {
>      // Version 3.00 Divisors must be a multiple of 2
>      if (XENON_MMC_MAX_CLK <= Clock) {
>        Div = 1;
> @@ -196,7 +195,7 @@ XenonSetClk (
>    Clk |= ((Div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) << SDHCI_DIVIDER_HI_SHIFT;
>    Clk |= SDHCI_CLOCK_INT_EN;
>
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SD_MMC_HC_CLOCK_CTRL, FALSE, SDHC_REG_SIZE_2B, &Clk);
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_CLOCK_CTRL, FALSE, SDHC_REG_SIZE_2B, &Clk);
>
>    //
>    // Poll for internal controller clock to be stabilised
> @@ -205,7 +204,7 @@ XenonSetClk (
>    Retry = 200;
>
>    do {
> -    SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SD_MMC_HC_CLOCK_CTRL, TRUE, SDHC_REG_SIZE_2B, &Clk);
> +    XenonHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_CLOCK_CTRL, TRUE, SDHC_REG_SIZE_2B, &Clk);
>      if (Retry == 0) {
>        DEBUG((DEBUG_ERROR, "SD/MMC: Internal Clock never stabilised\n"));
>        return -1;
> @@ -219,7 +218,7 @@ XenonSetClk (
>    } while (!(Clk & SDHCI_CLOCK_INT_STABLE));
>
>    Clk |= SDHCI_CLOCK_CARD_EN;
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SD_MMC_HC_CLOCK_CTRL, FALSE, SDHC_REG_SIZE_2B, &Clk);
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_CLOCK_CTRL, FALSE, SDHC_REG_SIZE_2B, &Clk);
>
>    return 0;
>  }
> @@ -231,54 +230,11 @@ XenonPhyInit (
>  {
>    UINT32 Var, Wait, Time;
>    UINT32 Clock = XENON_MMC_MAX_CLK;
> -  UINT16 ClkCtrl;
> -
> -  // Need to disable the clock to set EMMC_PHY_TIMING_ADJUST register
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SD_MMC_HC_CLOCK_CTRL, TRUE, SDHC_REG_SIZE_2B, &ClkCtrl);
> -  ClkCtrl &= ~(SDHCI_CLOCK_CARD_EN | SDHCI_CLOCK_INT_EN);
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SD_MMC_HC_CLOCK_CTRL, FALSE, SDHC_REG_SIZE_2B, &ClkCtrl);
> -
> -  // Enable QSP PHASE SELECT
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_TIMING_ADJUST, TRUE, SDHC_REG_SIZE_4B, &Var);
> -  Var |= SAMPL_INV_QSP_PHASE_SELECT;
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_TIMING_ADJUST, FALSE, SDHC_REG_SIZE_4B, &Var);
> -
> -  // Enable internal clock
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SD_MMC_HC_CLOCK_CTRL, TRUE, SDHC_REG_SIZE_2B, &ClkCtrl);
> -  ClkCtrl |= SDHCI_CLOCK_INT_EN;
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SD_MMC_HC_CLOCK_CTRL, FALSE, SDHC_REG_SIZE_2B, &ClkCtrl);
> -
> -  //
> -  // Poll for host MMC PHY clock init to be stable
> -  // Wait up to 100us
> -  //
> -  Time = 100;
> -  while (Time--) {
> -    SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_TIMING_ADJUST, TRUE, SDHC_REG_SIZE_4B, &Var);
> -    if (Var & SDHCI_CLOCK_INT_STABLE) {
> -      break;
> -    }
> -
> -    // Poll interval for MMC PHY clock to be stable is 1us
> -    gBS->Stall (1);
> -  }
> -  if (Time <= 0) {
> -    DEBUG((DEBUG_ERROR, "SD/MMC: Failed to enable MMC internal clock in Time\n"));
> -    return;
> -  }
> -
> -  // Enable bus clock
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SD_MMC_HC_CLOCK_CTRL, TRUE, SDHC_REG_SIZE_2B, &ClkCtrl);
> -  ClkCtrl |= SDHCI_CLOCK_CARD_EN;
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SD_MMC_HC_CLOCK_CTRL, FALSE, SDHC_REG_SIZE_2B, &ClkCtrl);
> -
> -  // Delay 200us to wait for the completion of bus clock
> -  gBS->Stall (200);
>
>    // Init PHY
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_TIMING_ADJUST, TRUE, SDHC_REG_SIZE_4B, &Var);
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_TIMING_ADJUST, TRUE, SDHC_REG_SIZE_4B, &Var);
>    Var |= PHY_INITIALIZAION;
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_TIMING_ADJUST, FALSE, SDHC_REG_SIZE_4B, &Var);
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_TIMING_ADJUST, FALSE, SDHC_REG_SIZE_4B, &Var);
>
>    // Add duration of FC_SYNC_RST
>    Wait = ((Var >> FC_SYNC_RST_DURATION_SHIFT) & FC_SYNC_RST_DURATION_MASK);
> @@ -308,7 +264,7 @@ XenonPhyInit (
>    // Poll for host eMMC PHY init to complete, wait up to 100us
>    Time = 100;
>    while (Time--) {
> -    Var = SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_TIMING_ADJUST, TRUE, SDHC_REG_SIZE_4B, &Var);
> +    Var = XenonHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_TIMING_ADJUST, TRUE, SDHC_REG_SIZE_4B, &Var);
>      Var &= PHY_INITIALIZAION;
>      if (!Var) {
>        break;
> @@ -326,52 +282,227 @@ XenonPhyInit (
>    return;
>  }
>
> +//
> +// Enable eMMC PHY HW DLL
> +// DLL should be enabled and stable before HS200/SDR104 tuning,
> +// and before HS400 data strobe setting.
> +//
>  STATIC
> -VOID
> +EFI_STATUS
> +EmmcPhyEnableDll (
> +  IN EFI_PCI_IO_PROTOCOL   *PciIo
> +  )
> +{
> +  UINT32 Var;
> +  UINT16 SlotState;
> +  UINT8 Retry;
> +
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_DLL_CONTROL, TRUE, SDHC_REG_SIZE_4B, &Var);
> +  if (Var & DLL_ENABLE) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  // Enable DLL
> +  Var |= (DLL_ENABLE | DLL_FAST_LOCK);
> +
> +  //
> +  // Set Phase as 90 degree, which is most common value.
> +  //
> +  Var &= ~((DLL_PHASE_MASK << DLL_PHSEL0_SHIFT) |
> +           (DLL_PHASE_MASK << DLL_PHSEL1_SHIFT));
> +  Var |= ((DLL_PHASE_90_DEGREE << DLL_PHSEL0_SHIFT) |
> +          (DLL_PHASE_90_DEGREE << DLL_PHSEL1_SHIFT));
> +
> +  Var &= ~(DLL_BYPASS_EN | DLL_REFCLK_SEL);
> +  Var |= DLL_UPDATE;
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_DLL_CONTROL, FALSE, SDHC_REG_SIZE_4B, &Var);
> +
> +  // Wait max 32 ms for the DLL to lock
> +  Retry = 32;
> +  do {
> +    XenonHcRwMmio (PciIo, SD_BAR_INDEX, XENON_SLOT_EXT_PRESENT_STATE, TRUE, SDHC_REG_SIZE_2B, &SlotState);
> +
> +    if (Retry == 0) {
> +      DEBUG ((DEBUG_ERROR, "SD/MMC: Fail to lock DLL\n"));
> +      return EFI_TIMEOUT;
> +    }
> +
> +    gBS->Stall (1000);
> +    Retry--;
> +
> +  } while (!(SlotState & DLL_LOCK_STATE));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +//
> +// Config to eMMC PHY to prepare for tuning.
> +// Enable HW DLL and set the TUNING_STEP
> +//
> +STATIC
> +EFI_STATUS
> +EmmcPhyConfigTuning (
> +  IN EFI_PCI_IO_PROTOCOL   *PciIo,
> +  IN UINT8 TuningStepDivisor
> +  )
> +{
> +  UINT32 Var, TuningStep;
> +  EFI_STATUS Status;
> +
> +  Status = EmmcPhyEnableDll (PciIo);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  // Achieve TUNING_STEP with HW DLL help
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, XENON_SLOT_DLL_CUR_DLY_VAL, TRUE, SDHC_REG_SIZE_4B, &Var);
> +  TuningStep = Var / TuningStepDivisor;
> +  if (TuningStep > TUNING_STEP_MASK) {
> +      DEBUG ((DEBUG_ERROR, "HS200 TUNING_STEP %d is larger than MAX value\n", TuningStep));
> +    TuningStep = TUNING_STEP_MASK;
> +  }
> +
> +  // Set TUNING_STEP for later tuning
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, XENON_SLOT_OP_STATUS_CTRL, TRUE, SDHC_REG_SIZE_4B, &Var);
> +  Var &= ~(TUN_CONSECUTIVE_TIMES_MASK << TUN_CONSECUTIVE_TIMES_SHIFT);
> +  Var |= (TUN_CONSECUTIVE_TIMES << TUN_CONSECUTIVE_TIMES_SHIFT);
> +  Var &= ~(TUNING_STEP_MASK << TUNING_STEP_SHIFT);
> +  Var |= (TuningStep << TUNING_STEP_SHIFT);
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, XENON_SLOT_OP_STATUS_CTRL, FALSE, SDHC_REG_SIZE_4B, &Var);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +BOOLEAN
> +XenonPhySlowMode (
> +  IN EFI_PCI_IO_PROTOCOL   *PciIo,
> +  IN SD_MMC_BUS_MODE        Timing,
> +  IN BOOLEAN SlowMode
> +  )
> +{
> +  UINT32 Var = 0;
> +
> +  // Check if Slow Mode is required in lower speed mode in SDR mode
> +  if (((Timing == SdMmcUhsSdr50) ||
> +       (Timing == SdMmcUhsSdr25) ||
> +       (Timing == SdMmcUhsSdr12) ||
> +       (Timing == SdMmcMmcHsDdr) ||
> +       (Timing == SdMmcMmcHsSdr) ||
> +       (Timing == SdMmcMmcLegacy)) && SlowMode) {
> +    Var = QSN_PHASE_SLOW_MODE_BIT;
> +    XenonHcOrMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_TIMING_ADJUST, SDHC_REG_SIZE_4B, &Var);
> +    return TRUE;
> +  }
> +
> +  Var = ~QSN_PHASE_SLOW_MODE_BIT;
> +  XenonHcAndMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_TIMING_ADJUST, SDHC_REG_SIZE_4B, &Var);
> +  return FALSE;
> +}
> +
> +EFI_STATUS
>  XenonSetPhy (
>    IN EFI_PCI_IO_PROTOCOL   *PciIo,
> -  UINT8 Timing
> +  IN BOOLEAN               SlowMode,
> +  IN UINT8                 TuningStepDivisor,
> +  IN SD_MMC_BUS_MODE       Timing
>    )
>  {
>    UINT32 Var = 0;
> +  UINT16 ClkCtrl;
>
> -  // Setup pad, set bit[30], bit[28] and bits[26:24]
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_PAD_CONTROL, TRUE, SDHC_REG_SIZE_4B, &Var);
> -  Var |= (AUTO_RECEN_CTRL | OEN_QSN | FC_QSP_RECEN | FC_CMD_RECEN | FC_DQ_RECEN);
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_PAD_CONTROL, FALSE, SDHC_REG_SIZE_4B, &Var);
> +  // Setup pad, bit[28] and bits[26:24]
> +  Var = OEN_QSN | FC_QSP_RECEN | FC_CMD_RECEN | FC_DQ_RECEN;
> +  // All FC_XX_RECEIVCE should be set as CMOS Type
> +  Var |= FC_ALL_CMOS_RECEIVER;
> +  XenonHcOrMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_PAD_CONTROL, SDHC_REG_SIZE_4B, &Var);
> +
> +  // Set CMD and DQ Pull Up
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_PAD_CONTROL1, TRUE, SDHC_REG_SIZE_4B, &Var);
> +  Var |= (EMMC5_1_FC_CMD_PU | EMMC5_1_FC_DQ_PU);
> +  Var &= ~(EMMC5_1_FC_CMD_PD | EMMC5_1_FC_DQ_PD);
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_PAD_CONTROL1, FALSE, SDHC_REG_SIZE_4B, &Var);
> +
> +  if (Timing == SdMmcUhsSdr12) {
> +    if (SlowMode) {
> +      XenonHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_TIMING_ADJUST, TRUE, SDHC_REG_SIZE_4B, &Var);
> +      Var |= QSN_PHASE_SLOW_MODE_BIT;
> +      XenonHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_TIMING_ADJUST, FALSE, SDHC_REG_SIZE_4B, &Var);
> +    }
> +
> +    goto PhyInit;
> +  }
>
>    //
>    // If Timing belongs to high speed, set bit[17] of
>    // EMMC_PHY_TIMING_ADJUST register
>    //
> -  if ((Timing == MMC_TIMING_MMC_HS400) ||
> -      (Timing == MMC_TIMING_MMC_HS200) ||
> -      (Timing == MMC_TIMING_UHS_SDR50) ||
> -      (Timing == MMC_TIMING_UHS_SDR104) ||
> -      (Timing == MMC_TIMING_UHS_DDR50) ||
> -      (Timing == MMC_TIMING_UHS_SDR25)) {
> -
> -    SdMmcHcRwMmio(PciIo, SD_BAR_INDEX, EMMC_PHY_TIMING_ADJUST, TRUE, SDHC_REG_SIZE_4B, &Var);
> -
> -    // Set SLOW_MODE for PHY
> -    Var |= OUTPUT_QSN_PHASE_SELECT | QSN_PHASE_SLOW_MODE_BIT;
> -    SdMmcHcRwMmio(PciIo, SD_BAR_INDEX, EMMC_PHY_TIMING_ADJUST, FALSE, SDHC_REG_SIZE_4B, &Var);
> +  if ((Timing == SdMmcMmcHs400) ||
> +      (Timing == SdMmcMmcHs200) ||
> +      (Timing == SdMmcUhsDdr50) ||
> +      (Timing == SdMmcUhsSdr50) ||
> +      (Timing == SdMmcUhsSdr104) ||
> +      (Timing == SdMmcUhsSdr25)) {
> +    Var = ~OUTPUT_QSN_PHASE_SELECT;
> +    XenonHcAndMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_TIMING_ADJUST, SDHC_REG_SIZE_4B, &Var);
>    }
>
> -  SdMmcHcRwMmio(PciIo, SD_BAR_INDEX, EMMC_PHY_FUNC_CONTROL, TRUE, SDHC_REG_SIZE_4B, &Var);
> -  Var |= (DQ_DDR_MODE_MASK << DQ_DDR_MODE_SHIFT) | CMD_DDR_MODE;
> -  SdMmcHcRwMmio(PciIo, SD_BAR_INDEX, EMMC_PHY_FUNC_CONTROL, FALSE, SDHC_REG_SIZE_4B, &Var);
> +  if (XenonPhySlowMode (PciIo, Timing, SlowMode)) {
> +    goto PhyInit;
> +  }
> +
> +  // Set default ZNR and ZPR value
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_PAD_CONTROL2, TRUE, SDHC_REG_SIZE_4B, &Var);
> +  Var &= ~((ZNR_MASK << ZNR_SHIFT) | ZPR_MASK);
> +  Var |= ((ZNR_DEF_VALUE << ZNR_SHIFT) | ZPR_DEF_VALUE);
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_PAD_CONTROL2, FALSE, SDHC_REG_SIZE_4B, &Var);
> +
> +  // Need to disable the clock to set EMMC_PHY_FUNC_CONTROL register
> +  ClkCtrl = ~SDHCI_CLOCK_CARD_EN;
> +  XenonHcAndMmio (PciIo, SD_BAR_INDEX, SDHC_CLOCK_CTRL, SDHC_REG_SIZE_2B, &ClkCtrl);
> +
> +  if ((Timing == SdMmcMmcHs400) ||
> +      (Timing == SdMmcUhsDdr50)) {
> +    Var = (DQ_DDR_MODE_MASK << DQ_DDR_MODE_SHIFT) | CMD_DDR_MODE;
> +    XenonHcOrMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_FUNC_CONTROL, SDHC_REG_SIZE_4B, &Var);
> +  } else {
> +    Var = ~((DQ_DDR_MODE_MASK << DQ_DDR_MODE_SHIFT) | CMD_DDR_MODE);
> +    XenonHcAndMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_FUNC_CONTROL, SDHC_REG_SIZE_4B, &Var);
> +  }
> +
> +  if (Timing == SdMmcMmcHs400) {
> +    Var = ~DQ_ASYNC_MODE;
> +    XenonHcAndMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_FUNC_CONTROL, SDHC_REG_SIZE_4B, &Var);
> +  } else {
> +    Var = DQ_ASYNC_MODE;
> +    XenonHcOrMmio (PciIo, SD_BAR_INDEX, EMMC_PHY_FUNC_CONTROL, SDHC_REG_SIZE_4B, &Var);
> +  }
>
> -  if (Timing == MMC_TIMING_MMC_HS400) {
> -    SdMmcHcRwMmio(PciIo, SD_BAR_INDEX, EMMC_PHY_FUNC_CONTROL, TRUE, SDHC_REG_SIZE_4B, &Var);
> -    Var &= ~DQ_ASYNC_MODE;
> -    SdMmcHcRwMmio(PciIo, SD_BAR_INDEX, EMMC_PHY_FUNC_CONTROL, FALSE, SDHC_REG_SIZE_4B, &Var);
> +  // Enable bus clock
> +  ClkCtrl = SDHCI_CLOCK_CARD_EN;
> +  XenonHcOrMmio (PciIo, SD_BAR_INDEX, SDHC_CLOCK_CTRL, SDHC_REG_SIZE_2B, &ClkCtrl);
>
> +  // Delay 200us to wait for the completion of bus clock
> +  gBS->Stall (200);
> +
> +  if (Timing == SdMmcMmcHs400) {
>      Var = LOGIC_TIMING_VALUE;
> -    SdMmcHcRwMmio(PciIo, SD_BAR_INDEX, EMMC_LOGIC_TIMING_ADJUST, FALSE, SDHC_REG_SIZE_4B, &Var);
> +    XenonHcRwMmio (PciIo, SD_BAR_INDEX, EMMC_LOGIC_TIMING_ADJUST, FALSE, SDHC_REG_SIZE_4B, &Var);
> +  } else {
> +    // Disable data strobe
> +    Var = ~ENABLE_DATA_STROBE;
> +    XenonHcAndMmio (PciIo, SD_BAR_INDEX, XENON_SLOT_EMMC_CTRL, SDHC_REG_SIZE_4B, &Var);
>    }
>
> +PhyInit:
>    XenonPhyInit (PciIo);
> +
> +  if ((Timing == SdMmcMmcHs200) ||
> +      (Timing == SdMmcUhsSdr104)) {
> +    return EmmcPhyConfigTuning (PciIo, TuningStepDivisor);
> +  }
> +
> +  return EFI_SUCCESS;
>  }
>
>  STATIC
> @@ -384,16 +515,16 @@ XenonConfigureInterrupts (
>
>    // Clear interrupt status
>    Var = SDHC_CLR_ALL_IRQ_MASK;
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SD_MMC_HC_NOR_INT_STS, FALSE, SDHC_REG_SIZE_4B, &Var);
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SD_MMC_HC_NOR_INT_STS, FALSE, SDHC_REG_SIZE_4B, &Var);
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_NOR_INT_STS, FALSE, SDHC_REG_SIZE_4B, &Var);
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_NOR_INT_STS, FALSE, SDHC_REG_SIZE_4B, &Var);
>
>    // Enable only interrupts served by the SD controller
>    Var = SDHC_CLR_ALL_IRQ_MASK & ~(NOR_INT_STS_CARD_INS | NOR_INT_STS_CARD_INT);
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SD_MMC_HC_NOR_INT_STS_EN, FALSE, SDHC_REG_SIZE_4B, &Var);
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_NOR_INT_STS_EN, FALSE, SDHC_REG_SIZE_4B, &Var);
>
>    // Mask all sdhci interrupt sources
>    Var = SDHC_CLR_ALL_IRQ_MASK & ~NOR_INT_SIG_EN_CARD_INT;
> -  SdMmcHcRwMmio (PciIo, SD_BAR_INDEX, SD_MMC_HC_NOR_INT_SIG_EN, FALSE, SDHC_REG_SIZE_4B, &Var);
> +  XenonHcRwMmio (PciIo, SD_BAR_INDEX, SDHC_NOR_INT_SIG_EN, FALSE, SDHC_REG_SIZE_4B, &Var);
>  }
>
>  // Enable Parallel Transfer Mode
> @@ -407,7 +538,7 @@ XenonSetParallelTransfer (
>  {
>    UINT32 Var;
>
> -  SdMmcHcRwMmio(PciIo, SD_BAR_INDEX, SDHC_SYS_EXT_OP_CTRL, TRUE, SDHC_REG_SIZE_4B, &Var);
> +  XenonHcRwMmio(PciIo, SD_BAR_INDEX, SDHC_SYS_EXT_OP_CTRL, TRUE, SDHC_REG_SIZE_4B, &Var);
>
>    if (Enable) {
>      Var |= (0x1 << Slot);
> @@ -415,7 +546,10 @@ XenonSetParallelTransfer (
>      Var &= ~(0x1 << Slot);
>    }
>
> -  SdMmcHcRwMmio(PciIo, SD_BAR_INDEX, SDHC_SYS_EXT_OP_CTRL, FALSE, SDHC_REG_SIZE_4B, &Var);
> +  // Mask command conflict error
> +  Var |= MASK_CMD_CONFLICT_ERR;
> +
> +  XenonHcRwMmio(PciIo, SD_BAR_INDEX, SDHC_SYS_EXT_OP_CTRL, FALSE, SDHC_REG_SIZE_4B, &Var);
>  }
>
>  STATIC
> @@ -429,7 +563,7 @@ XenonSetTuning (
>    UINT32 Var;
>
>    // Set the Re-Tuning Request functionality
> -  SdMmcHcRwMmio(PciIo, SD_BAR_INDEX, SDHC_SLOT_RETUNING_REQ_CTRL, TRUE, SDHC_REG_SIZE_4B, &Var);
> +  XenonHcRwMmio(PciIo, SD_BAR_INDEX, SDHC_SLOT_RETUNING_REQ_CTRL, TRUE, SDHC_REG_SIZE_4B, &Var);
>
>    if (Enable) {
>      Var |= RETUNING_COMPATIBLE;
> @@ -437,10 +571,10 @@ XenonSetTuning (
>      Var &= ~RETUNING_COMPATIBLE;
>    }
>
> -  SdMmcHcRwMmio(PciIo, SD_BAR_INDEX, SDHC_SLOT_RETUNING_REQ_CTRL, FALSE, SDHC_REG_SIZE_4B, &Var);
> +  XenonHcRwMmio(PciIo, SD_BAR_INDEX, SDHC_SLOT_RETUNING_REQ_CTRL, FALSE, SDHC_REG_SIZE_4B, &Var);
>
>    // Set the Re-tuning Event Signal Enable
> -  SdMmcHcRwMmio(PciIo, SD_BAR_INDEX, SDHCI_SIGNAL_ENABLE, TRUE, SDHC_REG_SIZE_4B, &Var);
> +  XenonHcRwMmio(PciIo, SD_BAR_INDEX, SDHCI_SIGNAL_ENABLE, TRUE, SDHC_REG_SIZE_4B, &Var);
>
>    if (Enable) {
>      Var |= SDHCI_RETUNE_EVT_INTSIG;
> @@ -448,12 +582,12 @@ XenonSetTuning (
>      Var &= ~SDHCI_RETUNE_EVT_INTSIG;
>    }
>
> -  SdMmcHcRwMmio(PciIo, SD_BAR_INDEX, SDHCI_SIGNAL_ENABLE, FALSE, SDHC_REG_SIZE_4B, &Var);
> +  XenonHcRwMmio(PciIo, SD_BAR_INDEX, SDHCI_SIGNAL_ENABLE, FALSE, SDHC_REG_SIZE_4B, &Var);
>  }
>
>  VOID
>  XenonReset (
> -  IN SD_MMC_HC_PRIVATE_DATA *Private,
> +  IN EFI_PCI_IO_PROTOCOL *PciIo,
>    IN UINT8 Slot,
>    IN UINT8 Mask
>    )
> @@ -463,19 +597,19 @@ XenonReset (
>
>    SwReset = Mask;
>
> -  SdMmcHcRwMmio (
> -          Private->PciIo,
> +  XenonHcRwMmio (
> +          PciIo,
>            Slot,
> -          SD_MMC_HC_SW_RST,
> +          SDHC_SW_RST,
>            FALSE,
>            sizeof (SwReset),
>            &SwReset
>          );
>
> -  SdMmcHcRwMmio (
> -          Private->PciIo,
> +  XenonHcRwMmio (
> +          PciIo,
>            Slot,
> -          SD_MMC_HC_SW_RST,
> +          SDHC_SW_RST,
>            TRUE,
>            sizeof (SwReset),
>            &SwReset
> @@ -491,10 +625,10 @@ XenonReset (
>
>      // Poll interval for SwReset is 100us according to SDHCI spec
>      gBS-> Stall (100);
> -    SdMmcHcRwMmio (
> -            Private->PciIo,
> +    XenonHcRwMmio (
> +            PciIo,
>              Slot,
> -            SD_MMC_HC_SW_RST,
> +            SDHC_SW_RST,
>              TRUE,
>              sizeof (SwReset),
>              &SwReset
> @@ -505,7 +639,6 @@ XenonReset (
>  STATIC
>  VOID
>  XenonTransferPio (
> -  IN SD_MMC_HC_PRIVATE_DATA *Private,
>    IN UINT8 Slot,
>    IN OUT VOID *Buffer,
>    IN UINT16 BlockSize,
> @@ -532,7 +665,7 @@ XenonTransferPio (
>
>  EFI_STATUS
>  XenonTransferData (
> -  IN SD_MMC_HC_PRIVATE_DATA *Private,
> +  IN EFI_PCI_IO_PROTOCOL *PciIo,
>    IN UINT8 Slot,
>    IN OUT VOID *Buffer,
>    IN UINT32 DataLen,
> @@ -552,10 +685,10 @@ XenonTransferData (
>    Mask = PRESENT_STATE_BUFFER_RD_EN | PRESENT_STATE_BUFFER_WR_EN;
>
>    do {
> -    SdMmcHcRwMmio (
> -            Private->PciIo,
> +    XenonHcRwMmio (
> +            PciIo,
>              Slot,
> -            SD_MMC_HC_NOR_INT_STS,
> +            SDHC_NOR_INT_STS,
>              TRUE,
>              sizeof (IntStatus),
>              &IntStatus
> @@ -567,10 +700,10 @@ XenonTransferData (
>      }
>
>      if (IntStatus & Rdy) {
> -      SdMmcHcRwMmio (
> -              Private->PciIo,
> +      XenonHcRwMmio (
> +              PciIo,
>                Slot,
> -              SD_MMC_HC_PRESENT_STATE,
> +              SDHC_PRESENT_STATE,
>                TRUE,
>                sizeof (PresentState),
>                &PresentState
> @@ -580,16 +713,16 @@ XenonTransferData (
>          continue;
>        }
>
> -      SdMmcHcRwMmio (
> -              Private->PciIo,
> +      XenonHcRwMmio (
> +              PciIo,
>                Slot,
> -              SD_MMC_HC_NOR_INT_STS,
> +              SDHC_NOR_INT_STS,
>                FALSE,
>                sizeof (Rdy),
>                &Rdy
>              );
>
> -      XenonTransferPio (Private, Slot, Buffer, BlockSize, Read);
> +      XenonTransferPio (Slot, Buffer, BlockSize, Read);
>
>        Buffer += BlockSize;
>        if (++Block >= Blocks) {
> @@ -612,13 +745,13 @@ XenonTransferData (
>
>  EFI_STATUS
>  XenonInit (
> -  IN SD_MMC_HC_PRIVATE_DATA *Private
> +  IN EFI_PCI_IO_PROTOCOL *PciIo,
> +  IN BOOLEAN             Support1v8,
> +  IN BOOLEAN             SlowMode,
> +  IN UINT8               TuningStepDivisor
>    )
>  {
> -  EFI_PCI_IO_PROTOCOL *PciIo = Private->PciIo;
> -
> -  // Read XENON version
> -  XenonReadVersion (PciIo, &Private->ControllerVersion);
> +  EFI_STATUS Status;
>
>    // Disable auto clock generator
>    XenonSetAcg (PciIo, FALSE);
> @@ -626,11 +759,11 @@ XenonInit (
>    // XENON has only one port
>    XenonSetSlot (PciIo, XENON_MMC_SLOT_ID, TRUE);
>
> -  XenonSetPower (PciIo, MMC_VDD_165_195, eMMC_VCCQ_1_8V, XENON_MMC_MODE_SD_SDIO);
> -
> -  // Set MAX_CLOCK for configuring PHY
> -  XenonSetClk (PciIo, Private, XENON_MMC_MAX_CLK);
> -  XenonSetPhy (PciIo, MMC_TIMING_UHS_SDR50);
> +  if (Support1v8) {
> +    XenonSetPower (PciIo, MMC_VDD_165_195, eMMC_VCCQ_1_8V, XENON_MMC_MODE_SD_SDIO);
> +  } else {
> +    XenonSetPower (PciIo, MMC_VDD_32_33, eMMC_VCCQ_3_3V, XENON_MMC_MODE_SD_SDIO);
> +  }
>
>    XenonConfigureInterrupts (PciIo);
>
> @@ -641,9 +774,12 @@ XenonInit (
>    // Enable auto clock generator
>    XenonSetAcg (PciIo, TRUE);
>
> -  // Set proper clock for PHY configuration
> -  XenonSetClk (PciIo, Private, XENON_MMC_BASE_CLK);
> -  XenonPhyInit (PciIo);
> +  // Set lowest clock and the PHY for the initialization phase
> +  XenonSetClk (PciIo, XENON_MMC_BASE_CLK);
> +  Status = XenonSetPhy (PciIo, SlowMode, TuningStepDivisor, SdMmcUhsSdr12);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
>
>    return EFI_SUCCESS;
>  }
> --
> 2.7.4
>


  reply	other threads:[~2018-11-16  0:56 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-13 12:32 [platforms: PATCH v5 0/8] Armada7k8k Xenon driver rework Marcin Wojtas
2018-11-13 12:32 ` [platforms: PATCH v5 1/8] Silicon/SynQuacer/PlatformDxe: adjust to updated SdMmcOverride Marcin Wojtas
2018-11-13 12:32 ` [platforms: PATCH v5 2/8] Marvell/Library: ArmadaBoardDescLib: Extend SDMMC information Marcin Wojtas
2018-11-13 12:32 ` [platforms: PATCH v5 3/8] SolidRun/Armada80x0McBin: Introduce board description library Marcin Wojtas
2018-11-13 12:32 ` [platforms: PATCH v5 4/8] Marvell/Armada70x0Db: " Marcin Wojtas
2018-11-13 12:32 ` [platforms: PATCH v5 5/8] Marvell/Armada80x0Db: " Marcin Wojtas
2018-11-13 12:32 ` [platforms: PATCH v5 6/8] Marvell/Drivers: MvBoardDesc: Extend information for SdMmc Marcin Wojtas
2018-11-13 12:32 ` [platforms: PATCH v5 7/8] Marvell/Drivers: XenonDxe: Remove SdMmcPciHcDxe files Marcin Wojtas
2018-11-13 12:32 ` [platforms: PATCH v5 8/8] Marvell/Drivers: XenonDxe: Switch to use generic SdMmcPciHcDxe Marcin Wojtas
2018-11-16  0:56   ` Ard Biesheuvel [this message]
2018-11-18 22:20     ` Marcin Wojtas
2018-11-19  1:59       ` Ard Biesheuvel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAKv+Gu_KqnjkUKHCyenfiod8pCD73Cq=CxNkdAGbthVugug3kg@mail.gmail.com' \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox