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::242; helo=mail-lj1-x242.google.com; envelope-from=mw@semihalf.com; receiver=edk2-devel@lists.01.org Received: from mail-lj1-x242.google.com (mail-lj1-x242.google.com [IPv6:2a00:1450:4864:20::242]) (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 015A921163244 for ; Fri, 5 Oct 2018 06:25:31 -0700 (PDT) Received: by mail-lj1-x242.google.com with SMTP id r8-v6so11568160ljc.10 for ; Fri, 05 Oct 2018 06:25:31 -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=z1CED6UeX+zbfCw459BccralfXVBuugyzx7l/+jn9V4=; b=jnsslG8Gg2ugmzpOFn1dzwyQOsy0/JBZ26aoQ/8pjWJ7hT2GeiobJ6Rrn7b1WdSGv+ ojt6NH+DV/LsY2xnehYy+8l0yhXOjNs90FYul9GI8sPGdoNKQsxZ3Z+S2lNOdv0781ur 4/wWnOeCqV+QGo483ZxD3BlzqEvdr1FvdGVsE3PaEuw+yOUB3varnCeuUL2pN7Zs/5n3 V+ruMW+bOb5Qo3XkvG5wkyu9dXbVJxbzlmHbovciS8saomJvv2U3j5Q9cvqrctXVMNtM lqLBwa0Xk1A0pZLj97U/5BUbMvR7hzVCfM53VYkrpJT4C5pprkRfQIK/gEdfRvIrJEyo TOaA== 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=z1CED6UeX+zbfCw459BccralfXVBuugyzx7l/+jn9V4=; b=X8gP3bSiNl2uZMFu8rnAD3yem4fDwl55ibIZ4t8senw0nMkLElkMA+a4zQp38w6HmA 47FfZlKujJ2Oni82e/SlD9nlBVKAHxWZyFh9W4HfQsoSwNKGK6zVRyBYIAtu4f2O08lO cPZ6oNqACiltD+FEv5TZJxYxT+sSNxa7bV0n6wx5aH7ThpfEeWNff9jzdFbWONijifoS 19Dn7/HH5nZPOneXHaNNJR2RbB1Q2ACCkk0fGF06fNkBDxj8HWtUgroOsFVHVuGjC6Qp 0rdqdcBtXm1/qLLYq7T/PfEC9BoN02Xnd6a9383RFFeDF29zvV9RoDEAFEuF/oDEW4Q0 IRNw== X-Gm-Message-State: ABuFfogv2eGzxIYsYBXBIe+C8bRLQ0pPMxIGyVvtAXs3DZevQZCndK5B b1G4RjIs1bjip6ScD4B9HxUteSsjfeU= X-Google-Smtp-Source: ACcGV61mn045qHJRDgnMzWU8bPXXkh4wVxqoD8Ob4jCsEcSw3ovsYJbkIFhkWF6XwTvLCyXTtu+DSg== X-Received: by 2002:a2e:2bd5:: with SMTP id r82-v6mr7272196ljr.63.1538745929322; Fri, 05 Oct 2018 06:25:29 -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 l14-v6sm1836581ljc.68.2018.10.05.06.25.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 05 Oct 2018 06:25:28 -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, hao.a.wu@intel.com, ard.biesheuvel@linaro.org, nadavh@marvell.com, mw@semihalf.com, jsd@semihalf.com, tm@semihalf.com Date: Fri, 5 Oct 2018 15:25:09 +0200 Message-Id: <1538745911-22484-3-git-send-email-mw@semihalf.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1538745911-22484-1-git-send-email-mw@semihalf.com> References: <1538745911-22484-1-git-send-email-mw@semihalf.com> Subject: [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: Fri, 05 Oct 2018 13:25:32 -0000 From: Tomasz Michalec 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. 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 | 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(-) 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 // +// 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 // @@ -508,4 +541,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 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__ +#include #include #define EDKII_SD_MMC_OVERRIDE_PROTOCOL_GUID \ @@ -31,6 +32,7 @@ typedef enum { EdkiiSdMmcResetPost, EdkiiSdMmcInitHostPre, EdkiiSdMmcInitHostPost, + EdkiiSdMmcUhsSignaling, } EDKII_SD_MMC_PHASE_TYPE; /** 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 = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru); Status = EmmcSwitchBusWidth (PciIo, PassThru, Slot, Rca, IsDdr, BusWidth); if (EFI_ERROR (Status)) { @@ -758,27 +761,37 @@ 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->NotifyPhase != NULL) { + Status = 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 = SdMmcHcUhsSignaling (PciIo, Slot, Timing); + if (EFI_ERROR (Status)) { + return Status; + } } HsTiming = 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 = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru); if ((BusWidth != 4) && (BusWidth != 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 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->NotifyPhase != NULL) { + Status = 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 = SdMmcHcUhsSignaling (PciIo, Slot, Timing); + if (EFI_ERROR (Status)) { + return Status; + } } // // Wait Internal Clock Stable in the Clock Control register to be 1 before 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 = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru); Status = 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 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->NotifyPhase != NULL) { + Status = 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 = 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..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; 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,27 @@ 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->NotifyPhase != NULL) { + Status = 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 = 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 02eb4ad..38d6202 100644 --- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c @@ -1137,6 +1137,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