From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: None (no SPF record) identity=mailfrom; client-ip=2a00:1450:4864:20::241; helo=mail-lj1-x241.google.com; envelope-from=mw@semihalf.com; receiver=edk2-devel@lists.01.org Received: from mail-lj1-x241.google.com (mail-lj1-x241.google.com [IPv6:2a00:1450:4864:20::241]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id A8ABD2110E8A0 for ; Sun, 2 Sep 2018 21:54:29 -0700 (PDT) Received: by mail-lj1-x241.google.com with SMTP id p6-v6so14289488ljc.5 for ; Sun, 02 Sep 2018 21:54:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=0t953W8Vy7wkVs1FB4Pl3vg6/3pcWIhiE9IR1vRyMuA=; b=T3NYnidmttt/F3fgU/h7BpftvwMRVIWbPKbsZ3xCPSltg9s1uLMjCYTTiUZa+og+3M 9E4NV+a742O+TiPH/i7b6Se8HVLqnHjpy555nGkrmQcyz68McMEmgPWBXUXKz2vAQAPN /KckOk7zNtmRmqZx69NUsLyxC6iLRFSafv42Ag7jJB3jCLGBrj372JFKVfQ8pAwgZArv 9I5IDhgOCt2/9w/BtH5+bs3R+pcL6dzhRFraGSty2WOYH6Ksf5DXuxzSMTxytd93sGm6 YZ2SUTUPRxqRtqd8bsfM9c8CX+IV1CbN6kplmmt3HgL/6nb798rBojN+Cj97GmteXn6Y tPkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=0t953W8Vy7wkVs1FB4Pl3vg6/3pcWIhiE9IR1vRyMuA=; b=IGopYIx2GPlu0dy4AEHEVb/QZVQyWGuOY3OBLutmVg1+ZKE1dumoSwLvZ9kme2l5Le 98a6SgrRYzEAVBHzDsXDLMp8iIZaLE5vQFA6eH2zs6ZbGj3azWpiM4Hq9og1Htxr83d2 5yiKYqzEYSIH3kEWN6kU1CpTYeLgoqW2zBN4YYwEDTr5vqoKv2lVjzkYVmzqCm0fdnzx AUB4c2NtHRzQVrTd9OapLIUfqpqlTHDn8Sew0wvKGl43KF9LCWNbM/lzBsuUXyRbggxi 6HR111zO9VBKqhTwVxT2YsIoCE1YhN2RlJrRilTLqOTm87xg2B2c7CqfDYUiqsX8HumT /23Q== X-Gm-Message-State: APzg51AIsmfT+Gl7JquVVxlGlNhU1DNL0X++JkOeSvEd1SXrWOcRFO85 yyjiMtJs/24yVnbSE7d1htcfx9BF+a8= X-Google-Smtp-Source: ANB0VdYR422kwTe63Lp8FDZQWQc4Hg9xG1aTNsrgursWjysaxTmrbrKiLSShhXT0wC1DWXog1aMlcg== X-Received: by 2002:a2e:8147:: with SMTP id t7-v6mr17454506ljg.32.1535950467516; Sun, 02 Sep 2018 21:54:27 -0700 (PDT) Received: from gilgamesh.semihalf.com (31-172-191-173.noc.fibertech.net.pl. [31.172.191.173]) by smtp.gmail.com with ESMTPSA id h16-v6sm3196658ljh.26.2018.09.02.21.54.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 02 Sep 2018 21:54:26 -0700 (PDT) From: Marcin Wojtas To: edk2-devel@lists.01.org Cc: feng.tian@intel.com, michael.d.kinney@intel.com, liming.gao@intel.com, leif.lindholm@linaro.org, ard.biesheuvel@linaro.org, nadavh@marvell.com, mw@semihalf.com, jsd@semihalf.com, Tomasz Michalec Date: Mon, 3 Sep 2018 06:54:08 +0200 Message-Id: <1535950453-27147-3-git-send-email-mw@semihalf.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1535950453-27147-1-git-send-email-mw@semihalf.com> References: <1535950453-27147-1-git-send-email-mw@semihalf.com> Subject: [PATCH 2/7] 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: Mon, 03 Sep 2018 04:54:30 -0000 From: Tomasz Michalec Some SD Host Controlers use different values in Host Control 2 Register to select UHS Mode. This patch adds new UhsSignaling callback to the SdMmcOverride protocol. UHS signaling configuration is moved to a common, default routine (SdMmcHcUhsSignaling), which is called when SdMmcOverride does not cover this functionality. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Marcin Wojtas --- MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h | 50 +++++++ MdeModulePkg/Include/Protocol/SdMmcOverride.h | 26 ++++ MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c | 150 ++++++++++++-------- MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c | 36 +++-- MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c | 69 +++++++++ 5 files changed, 263 insertions(+), 68 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h index e3fadb5..525828c 100644 --- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.h @@ -68,6 +68,39 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define SD_MMC_HC_HOST_CTRL1_HS_ENABLE (1 << 2) // +// 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 +#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 + +// +// Timing modes for uhs +// +typedef enum { + SdMmcUhsSdr12, + SdMmcUhsSdr25, + SdMmcUhsSdr50, + SdMmcUhsSdr104, + SdMmcUhsDdr50, + SdMmcMmcDdr52, + SdMmcMmcSdr50, + SdMmcMmcSdr25, + SdMmcMmcSdr12, + SdMmcMmcHs200, + SdMmcMmcHs400, +} SD_MMC_UHS_TIMING; + +// // The transfer modes supported by SD Host Controller // Simplified Spec 3.0 Table 1-2 // @@ -513,4 +546,21 @@ SdMmcHcInitTimeoutCtrl ( IN UINT8 Slot ); +/** + 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 0766252..a7a57e8 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__ +#include #include #define EDKII_SD_MMC_OVERRIDE_PROTOCOL_GUID \ @@ -77,6 +78,27 @@ EFI_STATUS IN EDKII_SD_MMC_PHASE_TYPE PhaseType ); +/** + + Override function for uhs signaling + + @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. + +**/ +typedef +EFI_STATUS +(EFIAPI * EDKII_SD_MMC_UHS_SIGNALING) ( + IN EFI_HANDLE ControllerHandle, + IN UINT8 Slot, + IN SD_MMC_UHS_TIMING Timing + ); + struct _EDKII_SD_MMC_OVERRIDE { // // Protocol version of this implementation @@ -90,6 +112,10 @@ struct _EDKII_SD_MMC_OVERRIDE { // Callback to invoke SD/MMC override hooks // EDKII_SD_MMC_NOTIFY_PHASE NotifyPhase; + // + // Callback to override SD/MMC host controller uhs signaling + // + EDKII_SD_MMC_UHS_SIGNALING UhsSignaling; }; extern EFI_GUID gEdkiiSdMmcOverrideProtocolGuid; diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c index b3903b4..d285249 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 = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru); Status = EmmcSwitchBusWidth (PciIo, PassThru, Slot, Rca, IsDdr, BusWidth); if (EFI_ERROR (Status)) { @@ -758,27 +761,36 @@ EmmcSwitchToHighSpeed ( return Status; } - // - // Clean UHS Mode Select field of Host Control 2 reigster before update - // - HostCtrl2 = (UINT8)~0x7; - Status = 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 = BIT2; + Timing = SdMmcMmcDdr52; } else if (ClockFreq == 52) { - HostCtrl2 = BIT0; + Timing = SdMmcMmcSdr50; + } else if (ClockFreq == 26) { + Timing = SdMmcMmcSdr25; } else { - HostCtrl2 = 0; + Timing = SdMmcMmcSdr12; } - Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; + + if (mOverride != NULL && mOverride->UhsSignaling != NULL) { + Status = mOverride->UhsSignaling ( + Private->ControllerHandle, + Slot, + Timing + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: SD/MMC uhs signaling notifier callback failed - %r\n", + __FUNCTION__, + Status + )); + return Status; + } + } else { + Status = SdMmcHcUhsSignaling (PciIo, Slot, Timing); + if (EFI_ERROR (Status)) { + return Status; + } } HsTiming = 1; @@ -814,10 +826,13 @@ EmmcSwitchToHS200 ( 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 = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru); if ((BusWidth != 4) && (BusWidth != 8)) { return EFI_INVALID_PARAMETER; @@ -835,21 +850,29 @@ EmmcSwitchToHS200 ( if (EFI_ERROR (Status)) { return Status; } - // - // Clean UHS Mode Select field of Host Control 2 reigster before update - // - HostCtrl2 = (UINT8)~0x7; - Status = 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 = BIT0 | BIT1; - Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; + + Timing = SdMmcMmcHs200; + + if (mOverride != NULL && mOverride->UhsSignaling != NULL) { + Status = mOverride->UhsSignaling ( + Private->ControllerHandle, + Slot, + Timing + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: SD/MMC uhs signaling notifier callback failed - %r\n", + __FUNCTION__, + Status + )); + return Status; + } + } else { + Status = SdMmcHcUhsSignaling (PciIo, Slot, Timing); + if (EFI_ERROR (Status)) { + return Status; + } } HsTiming = 2; @@ -888,9 +911,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 = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru); Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, ClockFreq, 8); if (EFI_ERROR (Status)) { @@ -911,21 +937,29 @@ EmmcSwitchToHS400 ( if (EFI_ERROR (Status)) { return Status; } - // - // Clean UHS Mode Select field of Host Control 2 reigster before update - // - HostCtrl2 = (UINT8)~0x7; - Status = 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 = BIT0 | BIT2; - Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; + + Timing = SdMmcMmcHs400; + + if (mOverride != NULL && mOverride->UhsSignaling != NULL) { + Status = mOverride->UhsSignaling ( + Private->ControllerHandle, + Slot, + Timing + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: SD/MMC uhs signaling notifier callback failed - %r\n", + __FUNCTION__, + Status + )); + return Status; + } + } else { + Status = SdMmcHcUhsSignaling (PciIo, Slot, Timing); + if (EFI_ERROR (Status)) { + return Status; + } } HsTiming = 3; diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c index 8c93933..f45a367 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; Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru); @@ -817,18 +817,23 @@ SdCardSetBusMode ( if (S18A && (Capability->Sdr104 != 0) && ((SwitchResp[13] & BIT3) != 0)) { ClockFreq = 208; AccessMode = 3; + Timing = SdMmcUhsSdr104; } else if (S18A && (Capability->Sdr50 != 0) && ((SwitchResp[13] & BIT2) != 0)) { ClockFreq = 100; AccessMode = 2; + Timing = SdMmcUhsSdr50; } else if (S18A && (Capability->Ddr50 != 0) && ((SwitchResp[13] & BIT4) != 0)) { ClockFreq = 50; AccessMode = 4; + Timing = SdMmcUhsDdr50; } else if ((SwitchResp[13] & BIT1) != 0) { ClockFreq = 50; AccessMode = 1; + Timing = SdMmcUhsSdr25; } else { ClockFreq = 25; AccessMode = 0; + Timing = SdMmcUhsSdr12; } Status = SdCardSwitch (PassThru, Slot, AccessMode, 0xF, 0xF, 0xF, TRUE, SwitchResp); @@ -854,15 +859,26 @@ SdCardSetBusMode ( } } - HostCtrl2 = (UINT8)~0x7; - Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; - } - HostCtrl2 = AccessMode; - Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); - if (EFI_ERROR (Status)) { - return Status; + if (mOverride != NULL && mOverride->UhsSignaling != NULL) { + Status = mOverride->UhsSignaling ( + Private->ControllerHandle, + Slot, + Timing + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: SD/MMC uhs signaling notifier callback failed - %r\n", + __FUNCTION__, + Status + )); + return Status; + } + } else { + Status = SdMmcHcUhsSignaling (PciIo, Slot, Timing); + if (EFI_ERROR (Status)) { + return Status; + } } Status = SdMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, *Capability); diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c index 9672b5b..95627da 100644 --- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c @@ -1133,6 +1133,75 @@ SdMmcHcInitHost ( } /** + 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 = (UINT8)~SD_MMC_HC_CTRL_UHS_MASK; + Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); + if (EFI_ERROR (Status)) { + return Status; + } + + switch (Timing) { + case SdMmcUhsSdr12: + HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR12; + break; + case SdMmcUhsSdr25: + HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR25; + break; + case SdMmcUhsSdr50: + HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR50; + break; + case SdMmcUhsSdr104: + HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR104; + break; + case SdMmcUhsDdr50: + HostCtrl2 = SD_MMC_HC_CTRL_UHS_DDR50; + break; + case SdMmcMmcDdr52: + HostCtrl2 = SD_MMC_HC_CTRL_MMC_DDR52; + break; + case SdMmcMmcSdr50: + HostCtrl2 = SD_MMC_HC_CTRL_MMC_SDR50; + break; + case SdMmcMmcSdr25: + HostCtrl2 = SD_MMC_HC_CTRL_MMC_SDR25; + break; + case SdMmcMmcSdr12: + HostCtrl2 = SD_MMC_HC_CTRL_MMC_SDR12; + break; + case SdMmcMmcHs200: + HostCtrl2 = SD_MMC_HC_CTRL_HS200; + break; + case SdMmcMmcHs400: + HostCtrl2 = SD_MMC_HC_CTRL_HS400; + break; + default: + HostCtrl2 = 0; + break; + } + Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2); + + return Status; +} + +/** Turn on/off LED. @param[in] PciIo The PCI IO protocol instance. -- 2.7.4