From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: mateusz.albecki@intel.com) Received: from mga04.intel.com (mga04.intel.com []) by groups.io with SMTP; Thu, 26 Sep 2019 07:28:21 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 26 Sep 2019 07:28:21 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,552,1559545200"; d="scan'208";a="364746411" Received: from gklab-27-32.ger.corp.intel.com ([10.102.28.45]) by orsmga005.jf.intel.com with ESMTP; 26 Sep 2019 07:28:19 -0700 From: "Albecki, Mateusz" To: devel@edk2.groups.io Cc: "Albecki, Mateusz" , Hao A Wu , Marcin Wojtas Subject: [PATCHv2 2/3] MdeModulePkg/SdMmcPciHcDxe: Fix bus timing switch sequence Date: Thu, 26 Sep 2019 16:27:43 +0200 Message-Id: <20190926142744.3356-3-mateusz.albecki@intel.com> X-Mailer: git-send-email 2.14.1.windows.1 In-Reply-To: <20190926142744.3356-1-mateusz.albecki@intel.com> References: <20190926142744.3356-1-mateusz.albecki@intel.com> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2218 SD specification recommends switching card bus timing before switching bus timing in controller. Emmc driver used to do this switch other way around. This commit adds controller timing switch in EmmcSwitchBusTiming function to enforce this order and removes all controller timing programing from EmmcSwitchToXXX functions. Signed-off-by: Mateusz Albecki Cc: Hao A Wu Cc: Marcin Wojtas --- MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c | 70 +++++++++---------------- 1 file changed, 26 insertions(+), 44 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c index bd70490286..3598a8538a 100644 --- a/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c +++ b/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c @@ -671,6 +671,7 @@ EmmcSwitchBusTiming ( UINT8 CmdSet; UINT32 DevStatus; SD_MMC_HC_PRIVATE_DATA *Private; + UINT8 HostCtrl1; Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru); // @@ -704,6 +705,25 @@ EmmcSwitchBusTiming ( return Status; } + if (BusTiming == SdMmcMmcHsSdr || BusTiming == SdMmcMmcHsDdr) { + HostCtrl1 = BIT2; + Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1); + if (EFI_ERROR (Status)) { + return Status; + } + } else { + HostCtrl1 = (UINT8)~BIT2; + Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1); + if (EFI_ERROR (Status)) { + return Status; + } + } + + Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, BusTiming); + if (EFI_ERROR (Status)) { + return Status; + } + // // Convert the clock freq unit from MHz to KHz. // @@ -771,12 +791,8 @@ EmmcSwitchToHighSpeed ( IN SD_MMC_BUS_SETTINGS *BusMode ) { - EFI_STATUS Status; - UINT8 HostCtrl1; - SD_MMC_HC_PRIVATE_DATA *Private; - BOOLEAN IsDdr; - - Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru); + EFI_STATUS Status; + BOOLEAN IsDdr; if ((BusMode->BusTiming != SdMmcMmcHsSdr && BusMode->BusTiming != SdMmcMmcHsDdr) || BusMode->ClockFreq > 52) { @@ -794,20 +810,6 @@ EmmcSwitchToHighSpeed ( return Status; } - // - // Set to High Speed timing - // - HostCtrl1 = BIT2; - Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, BusMode->BusTiming); - if (EFI_ERROR (Status)) { - return Status; - } - return EmmcSwitchBusTiming (PciIo, PassThru, Slot, Rca, BusMode->DriverStrength, BusMode->BusTiming, BusMode->ClockFreq); } @@ -836,10 +838,7 @@ EmmcSwitchToHS200 ( IN SD_MMC_BUS_SETTINGS *BusMode ) { - EFI_STATUS Status; - SD_MMC_HC_PRIVATE_DATA *Private; - - Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru); + EFI_STATUS Status; if (BusMode->BusTiming != SdMmcMmcHs200 || (BusMode->BusWidth != 4 && BusMode->BusWidth != 8)) { @@ -851,11 +850,6 @@ EmmcSwitchToHS200 ( return Status; } - Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, BusMode->BusTiming); - if (EFI_ERROR (Status)) { - return Status; - } - Status = EmmcSwitchBusTiming (PciIo, PassThru, Slot, Rca, BusMode->DriverStrength, BusMode->BusTiming, BusMode->ClockFreq); if (EFI_ERROR (Status)) { return Status; @@ -891,17 +885,15 @@ EmmcSwitchToHS400 ( IN SD_MMC_BUS_SETTINGS *BusMode ) { - EFI_STATUS Status; - SD_MMC_HC_PRIVATE_DATA *Private; - SD_MMC_BUS_SETTINGS Hs200BusMode; - UINT32 HsFreq; + EFI_STATUS Status; + SD_MMC_BUS_SETTINGS Hs200BusMode; + UINT32 HsFreq; if (BusMode->BusTiming != SdMmcMmcHs400 || BusMode->BusWidth != 8) { return EFI_INVALID_PARAMETER; } - Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru); Hs200BusMode.BusTiming = SdMmcMmcHs200; Hs200BusMode.BusWidth = BusMode->BusWidth; Hs200BusMode.ClockFreq = BusMode->ClockFreq; @@ -916,11 +908,6 @@ EmmcSwitchToHS400 ( // Set to High Speed timing and set the clock frequency to a value less than or equal to 52MHz. // This step is necessary to be able to switch Bus into 8 bit DDR mode which is unsupported in HS200. // - Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, SdMmcMmcHsSdr); - if (EFI_ERROR (Status)) { - return Status; - } - HsFreq = BusMode->ClockFreq < 52 ? BusMode->ClockFreq : 52; Status = EmmcSwitchBusTiming (PciIo, PassThru, Slot, Rca, BusMode->DriverStrength, SdMmcMmcHsSdr, HsFreq); if (EFI_ERROR (Status)) { @@ -932,11 +919,6 @@ EmmcSwitchToHS400 ( return Status; } - Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, BusMode->BusTiming); - if (EFI_ERROR (Status)) { - return Status; - } - return EmmcSwitchBusTiming (PciIo, PassThru, Slot, Rca, BusMode->DriverStrength, BusMode->BusTiming, BusMode->ClockFreq); } -- 2.14.1.windows.1 -------------------------------------------------------------------- Intel Technology Poland sp. z o.o. ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | Kapital zakladowy 200.000 PLN. Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i moze zawierac informacje poufne. W razie przypadkowego otrzymania tej wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; jakiekolwiek przegladanie lub rozpowszechnianie jest zabronione. This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.