From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: None (no SPF record) identity=mailfrom; client-ip=2607:f8b0:4864:20::142; helo=mail-it1-x142.google.com; envelope-from=mw@semihalf.com; receiver=edk2-devel@lists.01.org Received: from mail-it1-x142.google.com (mail-it1-x142.google.com [IPv6:2607:f8b0:4864:20::142]) (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 7800421191F41 for ; Sun, 18 Nov 2018 14:20:39 -0800 (PST) Received: by mail-it1-x142.google.com with SMTP id h65so1631410ith.3 for ; Sun, 18 Nov 2018 14:20:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=tKo1dCRKhHOAyJt8QvTYTuT3Uxk20fiuL6U+fGcvEqE=; b=TkQZrXtOtsHsW6WF6NCl1mLrRzK1EdAMFSmGZ9ivEwpJiKwAxmS6TJO1bwWtopvNKk kUDDbdA6sijtpnguhxQFvMUZB2o33eE165xpzWvt+kRMU+hn5lecSWiJp+SJaXet90zr f2z+71Iy3BY+3I2vuaMxgt42Hzp/P7kNIDcOVMOXUeZJ3PPgNUFScN9kKvUl117T/GRZ UgpthU0sm7qNBspUxdGauMblNqX8IAdXrNox1Ye5SzWWbemae47ZgXgqr77PSyX2uQeB CvTDtB4vWbhHaLdfDvDPMFDtDFiPzYophgm9qoQoz+Nsbr1B2Cm9UfZvqYntiIxZrkfP YHMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=tKo1dCRKhHOAyJt8QvTYTuT3Uxk20fiuL6U+fGcvEqE=; b=BJ+U9R/rMnjoori6FowODo5G+DxYH3akruQx4JICpCBZfHBOs3VGmmibM13kclp5tm oLpNH+MFDMKQ3xcy/kohgCBsD9oPoN/o3Lg8IjdB3KnF/y+XmwxcLyGEOJSCtQN6EzGe e+whL+p6AGrrsxRyVmz5Etxa7U1O9b0NuxTCYHx/M5kNjR/MPtkZTbLTU0dNd4UppnBk REpeLcgFWazm0TXHHukKHOrLTuRiM9kza+o73FBs2vEVmT+syFuZe114ssB5wVEnFbd9 LVJW/iH+mdWGY+lXCK4kQigL5VFV+q9ekDILIAANGwvXJ323xO8rM0iwsI+jFIjoyzLT d4CQ== X-Gm-Message-State: AGRZ1gJTf6q8V1sQpdz6QGQg+7Qi3wjCNpLNSLXZJDecZPlOvtnE/Q5a FtZijhnsJVqow/c9nZYNG+JAiN6PsHDQqVjjI8D/9w== X-Google-Smtp-Source: AJdET5cEFVjKHS0BtMOgEEMnIZMsLTeMD6wd9FKpw3UiSui5xTCS4pwDrXbqP2LKplT96VkBQ0ThJ2VOOPxtpsDWxYo= X-Received: by 2002:a05:660c:681:: with SMTP id n1mr5974699itk.37.1542579638281; Sun, 18 Nov 2018 14:20:38 -0800 (PST) MIME-Version: 1.0 References: <1542112371-32546-1-git-send-email-mw@semihalf.com> <1542112371-32546-9-git-send-email-mw@semihalf.com> In-Reply-To: From: Marcin Wojtas Date: Sun, 18 Nov 2018 23:20:25 +0100 Message-ID: To: Ard Biesheuvel Cc: edk2-devel-01 , Leif Lindholm , hao.a.wu@intel.com, nadavh@marvell.com, "jsd@semihalf.com" , Grzegorz Jaszczyk , Kostya Porotchkin , Tomasz Michalec Subject: Re: [platforms: PATCH v5 8/8] Marvell/Drivers: XenonDxe: Switch to use generic SdMmcPciHcDxe 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: Sun, 18 Nov 2018 22:20:39 -0000 Content-Type: text/plain; charset="UTF-8" Hi Ard, > > +**/ > > +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? > XenonHcRwMmio is 1:1 to generic MdeModulePkg's SdMmcHcRwMmio, as well as all other SdMmc mmio accessors. I really prefer not to modify any of them and keep the code aligned as-is. Best regards, Marcin > > + 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 > >