From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.136; helo=mga12.intel.com; envelope-from=hao.a.wu@intel.com; receiver=edk2-devel@lists.01.org Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 492B22117B570 for ; Thu, 1 Nov 2018 00:06:16 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Nov 2018 00:06:16 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,451,1534834800"; d="scan'208";a="246116092" Received: from fmsmsx103.amr.corp.intel.com ([10.18.124.201]) by orsmga004.jf.intel.com with ESMTP; 01 Nov 2018 00:06:15 -0700 Received: from fmsmsx154.amr.corp.intel.com (10.18.116.70) by FMSMSX103.amr.corp.intel.com (10.18.124.201) with Microsoft SMTP Server (TLS) id 14.3.408.0; Thu, 1 Nov 2018 00:06:01 -0700 Received: from shsmsx102.ccr.corp.intel.com (10.239.4.154) by FMSMSX154.amr.corp.intel.com (10.18.116.70) with Microsoft SMTP Server (TLS) id 14.3.408.0; Thu, 1 Nov 2018 00:06:00 -0700 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.117]) by shsmsx102.ccr.corp.intel.com ([169.254.2.84]) with mapi id 14.03.0415.000; Thu, 1 Nov 2018 15:04:59 +0800 From: "Wu, Hao A" To: 'Marcin Wojtas' , "edk2-devel@lists.01.org" CC: "Kinney, Michael D" , "Gao, Liming" , "leif.lindholm@linaro.org" , "ard.biesheuvel@linaro.org" , "nadavh@marvell.com" , "jsd@semihalf.com" , "tm@semihalf.com" Thread-Topic: [PATCH v2 2/4] MdeModulePkg/SdMmcPciHcDxe: Add UhsSignaling to SdMmcOverride protocol Thread-Index: AQHUXK7s5hpZLYj2dU+NUJr/BC8HcaU3RF8Q Date: Thu, 1 Nov 2018 07:04:59 +0000 Message-ID: References: <1538745911-22484-1-git-send-email-mw@semihalf.com> <1538745911-22484-3-git-send-email-mw@semihalf.com> In-Reply-To: <1538745911-22484-3-git-send-email-mw@semihalf.com> Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH v2 2/4] MdeModulePkg/SdMmcPciHcDxe: Add UhsSignaling to SdMmcOverride protocol X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 Nov 2018 07:06:17 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi Marcin, > -----Original Message----- > From: Marcin Wojtas [mailto:mw@semihalf.com] > Sent: Friday, October 05, 2018 9:25 PM > To: edk2-devel@lists.01.org > Cc: Tian, Feng; Kinney, Michael D; Gao, Liming; leif.lindholm@linaro.org;= Wu, > Hao A; ard.biesheuvel@linaro.org; nadavh@marvell.com; > mw@semihalf.com; jsd@semihalf.com; tm@semihalf.com > Subject: [PATCH v2 2/4] MdeModulePkg/SdMmcPciHcDxe: Add UhsSignaling > to SdMmcOverride protocol >=20 > From: Tomasz Michalec >=20 > Some SD Host Controlers use different values in Host Control 2 Register > to select UHS Mode. This patch adds a new UhsSignaling type routine to > the NotifyPhase of the SdMmcOverride protocol. >=20 > UHS signaling configuration is moved to a common, default routine > (SdMmcHcUhsSignaling), which is called when SdMmcOverride does not > cover this functionality. >=20 > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Marcin Wojtas > --- > MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h | 50 +++++++ > MdeModulePkg/Include/Protocol/SdMmcOverride.h | 2 + > MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c | 153 > ++++++++++++-------- > MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c | 37 +++-- > MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c | 69 +++++++++ > 5 files changed, 243 insertions(+), 68 deletions(-) >=20 > diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h > b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h > index e389d52..a03160d 100644 > --- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h > +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h > @@ -63,6 +63,39 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF > ANY KIND, EITHER EXPRESS OR IMPLIED. > #define SD_MMC_HC_CTRL_VER 0xFE >=20 > // > +// SD Host Controler bits to HOST_CTRL2 register > +// > +#define SD_MMC_HC_CTRL_UHS_MASK 0x0007 > +#define SD_MMC_HC_CTRL_UHS_SDR12 0x0000 > +#define SD_MMC_HC_CTRL_UHS_SDR25 0x0001 > +#define SD_MMC_HC_CTRL_UHS_SDR50 0x0002 > +#define SD_MMC_HC_CTRL_UHS_SDR104 0x0003 > +#define SD_MMC_HC_CTRL_UHS_DDR50 0x0004 > +#define SD_MMC_HC_CTRL_MMC_DDR52 0x0004 > +#define SD_MMC_HC_CTRL_MMC_SDR50 0x0002 I think SD_MMC_HC_CTRL_MMC_SDR50 is not needed here. Since according to the SD Physical Layer Simplified Specification, max cloc= k frequency for SD bus mode SDR50 is 100MHz. And there is no eMMC bus mode wh= ose max clock frequency is at 100MHz in Embedded Multi-Media Card Electrical Standard (5.1). > +#define SD_MMC_HC_CTRL_MMC_SDR25 0x0001 > +#define SD_MMC_HC_CTRL_MMC_SDR12 0x0000 > +#define SD_MMC_HC_CTRL_HS200 0x0003 > +#define SD_MMC_HC_CTRL_HS400 0x0005 How about the below renames & reorder? SD_MMC_HC_CTRL_MMC_LEGACY 0x0000 SD_MMC_HC_CTRL_MMC_HS_SDR 0x0001 SD_MMC_HC_CTRL_MMC_HS_DDR 0x0004 SD_MMC_HC_CTRL_MMC_HS200 0x0003 SD_MMC_HC_CTRL_MMC_HS400 0x0005 > + > +// > +// Timing modes for uhs > +// > +typedef enum { > + SdMmcUhsSdr12, > + SdMmcUhsSdr25, > + SdMmcUhsSdr50, > + SdMmcUhsSdr104, > + SdMmcUhsDdr50, > + SdMmcMmcDdr52, > + SdMmcMmcSdr50, > + SdMmcMmcSdr25, > + SdMmcMmcSdr12, > + SdMmcMmcHs200, > + SdMmcMmcHs400, > +} SD_MMC_UHS_TIMING; Suggest a similar drop of 'SdMmcMmcSdr50' and rename according to the above comments upon HOST_CTRL2 register value definitions. Also, how about a rena= me for enum to SD_MMC_BUS_MODE? > + > +// > // The transfer modes supported by SD Host Controller > // Simplified Spec 3.0 Table 1-2 > // > @@ -508,4 +541,21 @@ SdMmcHcInitTimeoutCtrl ( > IN UINT8 Slot > ); >=20 > +/** > + Set SD Host Controler control 2 registry according to selected speed. > + > + @param[in] PciIo The PCI IO protocol instance. > + @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 timing is set successfully. > + @retval Others The timing isn't set successfully. > +**/ > +EFI_STATUS > +SdMmcHcUhsSignaling ( > + IN EFI_PCI_IO_PROTOCOL *PciIo, > + IN UINT8 Slot, > + IN SD_MMC_UHS_TIMING Timing > + ); > + > #endif > diff --git a/MdeModulePkg/Include/Protocol/SdMmcOverride.h > b/MdeModulePkg/Include/Protocol/SdMmcOverride.h > index 178945f..25db98a 100644 > --- a/MdeModulePkg/Include/Protocol/SdMmcOverride.h > +++ b/MdeModulePkg/Include/Protocol/SdMmcOverride.h > @@ -17,6 +17,7 @@ > #ifndef __SD_MMC_OVERRIDE_H__ > #define __SD_MMC_OVERRIDE_H__ >=20 > +#include Please do not expose a module private header file here. One approach comes to me is to keep the SD/MMC bus mode enumeration structu= re in this protocol header file. SdMmcPciHcDxe driver and producers of the Override protocol keep a version of the HOST_CTRL2 register value macros of their own. > #include >=20 > #define EDKII_SD_MMC_OVERRIDE_PROTOCOL_GUID \ > @@ -31,6 +32,7 @@ typedef enum { > EdkiiSdMmcResetPost, > EdkiiSdMmcInitHostPre, > EdkiiSdMmcInitHostPost, > + EdkiiSdMmcUhsSignaling, > } EDKII_SD_MMC_PHASE_TYPE; >=20 > /** > diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c > b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c > index c5fd214..05bd4a0 100755 > --- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c > +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c > @@ -740,10 +740,13 @@ EmmcSwitchToHighSpeed ( > IN UINT8 BusWidth > ) > { > - EFI_STATUS Status; > - UINT8 HsTiming; > - UINT8 HostCtrl1; > - UINT8 HostCtrl2; > + EFI_STATUS Status; > + UINT8 HsTiming; > + UINT8 HostCtrl1; > + SD_MMC_UHS_TIMING Timing; > + SD_MMC_HC_PRIVATE_DATA *Private; > + > + Private =3D SD_MMC_HC_PRIVATE_FROM_THIS (PassThru); >=20 > Status =3D EmmcSwitchBusWidth (PciIo, PassThru, Slot, Rca, IsDdr, BusW= idth); > if (EFI_ERROR (Status)) { > @@ -758,27 +761,37 @@ EmmcSwitchToHighSpeed ( > return Status; > } >=20 > - // > - // Clean UHS Mode Select field of Host Control 2 reigster before updat= e > - // > - HostCtrl2 =3D (UINT8)~0x7; > - Status =3D SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, > sizeof (HostCtrl2), &HostCtrl2); > - if (EFI_ERROR (Status)) { > - return Status; > - } > - // > - // Set UHS Mode Select field of Host Control 2 reigster to SDR12/25/50 > - // > if (IsDdr) { > - HostCtrl2 =3D BIT2; > + Timing =3D SdMmcMmcDdr52; > } else if (ClockFreq =3D=3D 52) { > - HostCtrl2 =3D BIT0; > + Timing =3D SdMmcMmcSdr50; > + } else if (ClockFreq =3D=3D 26) { > + Timing =3D SdMmcMmcSdr25; > } else { > - HostCtrl2 =3D 0; > + Timing =3D SdMmcMmcSdr12; > } As mentioned above, "SdMmcMmcSdr50" can be dropped here. And considering the rename above, how about: if (IsDdr) { Timing =3D SdMmcMmcHsDdr; } else if (ClockFreq =3D=3D 52) { Timing =3D SdMmcMmcHsSdr; } else { Timing =3D SdMmcMmcLegacy; } > - Status =3D SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof > (HostCtrl2), &HostCtrl2); > - if (EFI_ERROR (Status)) { > - return Status; > + > + if (mOverride !=3D NULL && mOverride->NotifyPhase !=3D NULL) { > + Status =3D mOverride->NotifyPhase ( > + Private->ControllerHandle, > + Slot, > + EdkiiSdMmcUhsSignaling, > + &Timing > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "%a: SD/MMC uhs signaling notifier callback failed - %r\n", > + __FUNCTION__, > + Status > + )); > + return Status; > + } > + } else { > + Status =3D SdMmcHcUhsSignaling (PciIo, Slot, Timing); > + if (EFI_ERROR (Status)) { > + return Status; > + } > } I have concern for this, current existing hook points for the NotifyPhase() service are performing additional operations during the controller initialization process. Producer of the override protocol can simply return EFI_SUCCESS, if there i= s nothing to do for a specific hook point. But this hook here is to override the behavior when setting the "UHS Mode Select" field of Host Control 2 Register. If the override protocol producer does not want to override the behavior at the 'EdkiiSdMmcUhsSignaling' hook= , but has to do something in other hooks, one cannot directly return EFI_SUCC= ESS for the 'EdkiiSdMmcUhsSignaling' hook. For this case, one has to implement = the 'EdkiiSdMmcUhsSignaling' hook even if the behavior will be exactly the same= as the SdMmcPciHcDxe driver. Best Regards, Hao Wu >=20 > HsTiming =3D 1; > @@ -814,10 +827,13 @@ EmmcSwitchToHS200 ( > IN UINT8 BusWidth > ) > { > - EFI_STATUS Status; > - UINT8 HsTiming; > - UINT8 HostCtrl2; > - UINT16 ClockCtrl; > + EFI_STATUS Status; > + UINT8 HsTiming; > + UINT16 ClockCtrl; > + SD_MMC_UHS_TIMING Timing; > + SD_MMC_HC_PRIVATE_DATA *Private; > + > + Private =3D SD_MMC_HC_PRIVATE_FROM_THIS (PassThru); >=20 > if ((BusWidth !=3D 4) && (BusWidth !=3D 8)) { > return EFI_INVALID_PARAMETER; > @@ -837,21 +853,30 @@ EmmcSwitchToHS200 ( > if (EFI_ERROR (Status)) { > return Status; > } > - // > - // Clean UHS Mode Select field of Host Control 2 reigster before updat= e > - // > - HostCtrl2 =3D (UINT8)~0x7; > - Status =3D SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, > sizeof (HostCtrl2), &HostCtrl2); > - if (EFI_ERROR (Status)) { > - return Status; > - } > - // > - // Set UHS Mode Select field of Host Control 2 reigster to SDR104 > - // > - HostCtrl2 =3D BIT0 | BIT1; > - Status =3D SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof > (HostCtrl2), &HostCtrl2); > - if (EFI_ERROR (Status)) { > - return Status; > + > + Timing =3D SdMmcMmcHs200; > + > + if (mOverride !=3D NULL && mOverride->NotifyPhase !=3D NULL) { > + Status =3D mOverride->NotifyPhase ( > + Private->ControllerHandle, > + Slot, > + EdkiiSdMmcUhsSignaling, > + &Timing > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "%a: SD/MMC uhs signaling notifier callback failed - %r\n", > + __FUNCTION__, > + Status > + )); > + return Status; > + } > + } else { > + Status =3D SdMmcHcUhsSignaling (PciIo, Slot, Timing); > + if (EFI_ERROR (Status)) { > + return Status; > + } > } > // > // Wait Internal Clock Stable in the Clock Control register to be 1 be= fore set > SD Clock Enable bit > @@ -910,9 +935,12 @@ EmmcSwitchToHS400 ( > IN UINT32 ClockFreq > ) > { > - EFI_STATUS Status; > - UINT8 HsTiming; > - UINT8 HostCtrl2; > + EFI_STATUS Status; > + UINT8 HsTiming; > + SD_MMC_UHS_TIMING Timing; > + SD_MMC_HC_PRIVATE_DATA *Private; > + > + Private =3D SD_MMC_HC_PRIVATE_FROM_THIS (PassThru); >=20 > Status =3D EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, ClockFreq, 8= ); > if (EFI_ERROR (Status)) { > @@ -933,21 +961,30 @@ EmmcSwitchToHS400 ( > if (EFI_ERROR (Status)) { > return Status; > } > - // > - // Clean UHS Mode Select field of Host Control 2 reigster before updat= e > - // > - HostCtrl2 =3D (UINT8)~0x7; > - Status =3D SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, > sizeof (HostCtrl2), &HostCtrl2); > - if (EFI_ERROR (Status)) { > - return Status; > - } > - // > - // Set UHS Mode Select field of Host Control 2 reigster to HS400 > - // > - HostCtrl2 =3D BIT0 | BIT2; > - Status =3D SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof > (HostCtrl2), &HostCtrl2); > - if (EFI_ERROR (Status)) { > - return Status; > + > + Timing =3D SdMmcMmcHs400; > + > + if (mOverride !=3D NULL && mOverride->NotifyPhase !=3D NULL) { > + Status =3D mOverride->NotifyPhase ( > + Private->ControllerHandle, > + Slot, > + EdkiiSdMmcUhsSignaling, > + &Timing > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "%a: SD/MMC uhs signaling notifier callback failed - %r\n", > + __FUNCTION__, > + Status > + )); > + return Status; > + } > + } else { > + Status =3D SdMmcHcUhsSignaling (PciIo, Slot, Timing); > + if (EFI_ERROR (Status)) { > + return Status; > + } > } >=20 > HsTiming =3D 3; > diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c > b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c > index 8c93933..5645a71 100644 > --- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c > +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c > @@ -784,8 +784,8 @@ SdCardSetBusMode ( > UINT8 BusWidth; > UINT8 AccessMode; > UINT8 HostCtrl1; > - UINT8 HostCtrl2; > UINT8 SwitchResp[64]; > + SD_MMC_UHS_TIMING Timing; > SD_MMC_HC_PRIVATE_DATA *Private; >=20 > Private =3D SD_MMC_HC_PRIVATE_FROM_THIS (PassThru); > @@ -817,18 +817,23 @@ SdCardSetBusMode ( > if (S18A && (Capability->Sdr104 !=3D 0) && ((SwitchResp[13] & BIT3) != =3D 0)) { > ClockFreq =3D 208; > AccessMode =3D 3; > + Timing =3D SdMmcUhsSdr104; > } else if (S18A && (Capability->Sdr50 !=3D 0) && ((SwitchResp[13] & BI= T2) !=3D 0)) > { > ClockFreq =3D 100; > AccessMode =3D 2; > + Timing =3D SdMmcUhsSdr50; > } else if (S18A && (Capability->Ddr50 !=3D 0) && ((SwitchResp[13] & BI= T4) !=3D > 0)) { > ClockFreq =3D 50; > AccessMode =3D 4; > + Timing =3D SdMmcUhsDdr50; > } else if ((SwitchResp[13] & BIT1) !=3D 0) { > ClockFreq =3D 50; > AccessMode =3D 1; > + Timing =3D SdMmcUhsSdr25; > } else { > ClockFreq =3D 25; > AccessMode =3D 0; > + Timing =3D SdMmcUhsSdr12; > } >=20 > Status =3D SdCardSwitch (PassThru, Slot, AccessMode, 0xF, 0xF, 0xF, TR= UE, > SwitchResp); > @@ -854,15 +859,27 @@ SdCardSetBusMode ( > } > } >=20 > - HostCtrl2 =3D (UINT8)~0x7; > - Status =3D SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, > sizeof (HostCtrl2), &HostCtrl2); > - if (EFI_ERROR (Status)) { > - return Status; > - } > - HostCtrl2 =3D AccessMode; > - Status =3D SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof > (HostCtrl2), &HostCtrl2); > - if (EFI_ERROR (Status)) { > - return Status; > + if (mOverride !=3D NULL && mOverride->NotifyPhase !=3D NULL) { > + Status =3D mOverride->NotifyPhase ( > + Private->ControllerHandle, > + Slot, > + EdkiiSdMmcUhsSignaling, > + &Timing > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "%a: SD/MMC uhs signaling notifier callback failed - %r\n", > + __FUNCTION__, > + Status > + )); > + return Status; > + } > + } else { > + Status =3D SdMmcHcUhsSignaling (PciIo, Slot, Timing); > + if (EFI_ERROR (Status)) { > + return Status; > + } > } >=20 > Status =3D SdMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, *Capabil= ity); > diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c > b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c > index 02eb4ad..38d6202 100644 > --- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c > +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c > @@ -1137,6 +1137,75 @@ SdMmcHcInitHost ( > } >=20 > /** > + Set SD Host Controler control 2 registry according to selected speed. > + > + @param[in] PciIo The PCI IO protocol instance. > + @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 timing is set successfully. > + @retval Others The timing isn't set successfully. > +**/ > +EFI_STATUS > +SdMmcHcUhsSignaling ( > + IN EFI_PCI_IO_PROTOCOL *PciIo, > + IN UINT8 Slot, > + IN SD_MMC_UHS_TIMING Timing > + ) > +{ > + EFI_STATUS Status; > + UINT8 HostCtrl2; > + > + HostCtrl2 =3D (UINT8)~SD_MMC_HC_CTRL_UHS_MASK; > + Status =3D SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, > sizeof (HostCtrl2), &HostCtrl2); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + switch (Timing) { > + case SdMmcUhsSdr12: > + HostCtrl2 =3D SD_MMC_HC_CTRL_UHS_SDR12; > + break; > + case SdMmcUhsSdr25: > + HostCtrl2 =3D SD_MMC_HC_CTRL_UHS_SDR25; > + break; > + case SdMmcUhsSdr50: > + HostCtrl2 =3D SD_MMC_HC_CTRL_UHS_SDR50; > + break; > + case SdMmcUhsSdr104: > + HostCtrl2 =3D SD_MMC_HC_CTRL_UHS_SDR104; > + break; > + case SdMmcUhsDdr50: > + HostCtrl2 =3D SD_MMC_HC_CTRL_UHS_DDR50; > + break; > + case SdMmcMmcDdr52: > + HostCtrl2 =3D SD_MMC_HC_CTRL_MMC_DDR52; > + break; > + case SdMmcMmcSdr50: > + HostCtrl2 =3D SD_MMC_HC_CTRL_MMC_SDR50; > + break; > + case SdMmcMmcSdr25: > + HostCtrl2 =3D SD_MMC_HC_CTRL_MMC_SDR25; > + break; > + case SdMmcMmcSdr12: > + HostCtrl2 =3D SD_MMC_HC_CTRL_MMC_SDR12; > + break; > + case SdMmcMmcHs200: > + HostCtrl2 =3D SD_MMC_HC_CTRL_HS200; > + break; > + case SdMmcMmcHs400: > + HostCtrl2 =3D SD_MMC_HC_CTRL_HS400; > + break; > + default: > + HostCtrl2 =3D 0; > + break; > + } > + Status =3D SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof > (HostCtrl2), &HostCtrl2); > + > + return Status; > +} > + > +/** > Turn on/off LED. >=20 > @param[in] PciIo The PCI IO protocol instance. > -- > 2.7.4