From: Jan Dąbroś jsd@semihalf.com
SD/MMC PHY on Armada70x0 platforms can be configured to work in two modes: 1. Connected to SD/MMC controller 2. Used as MPP multiplexer
In order to allow SD/MMC controller to work properly, mode 1 must be used.
Implemented configuration utilizes Pcd (PcdPciESdhci), which is also used in PciEmulation driver for marking Sdhci interfaces as enabled/disabled.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jan Dabros jsd@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com --- Platforms/Marvell/Library/MppLib/MppLib.c | 45 +++++++++++++++++++++++++++++ Platforms/Marvell/Library/MppLib/MppLib.inf | 1 + 2 files changed, 46 insertions(+)
diff --git a/Platforms/Marvell/Library/MppLib/MppLib.c b/Platforms/Marvell/Library/MppLib/MppLib.c index b24743c..6251bd8 100644 --- a/Platforms/Marvell/Library/MppLib/MppLib.c +++ b/Platforms/Marvell/Library/MppLib/MppLib.c @@ -44,6 +44,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define MPP_PINS_PER_REG 8 #define PCD_PINS_PER_GROUP 10
+#define SD_MMC_PHY_MPP_OFFSET 0x100 +#define MPP_ON_SDPHY_ENABLE (1 << 0) + #define MAX_CHIPS 4
#define GET_PCD_PTR(id,num) PcdGetPtr(PcdChip##id##MppSel##num) @@ -135,6 +138,42 @@ PcdToMppRegs ( return MppRegCount; }
+STATIC +VOID +SetSdMmcPhyMpp ( + UINTN BaseAddr + ) +{ + UINTN Index, Size; + UINTN *Ptr; + UINT32 Reg; + + Size = PcdGetSize(PcdPciESdhci); + Ptr = (UINTN *) PcdGetPtr(PcdPciESdhci); + if (Ptr == NULL) { + return; + } + + /* Check if there is SDHCI controller present on platform */ + for (Index = 0; Index < Size; Index ++) { + if (Ptr[Index] == 1) { + break; + } + } + + /* + * If there is SDHCI controller on platform, connect SD/MMC PHY to + * SD/MMC controller insted of using it as MPP multiplexer + */ + if (Index == Size) { + return; + } else { + Reg = MmioRead32 (BaseAddr + SD_MMC_PHY_MPP_OFFSET); + Reg &= ~MPP_ON_SDPHY_ENABLE; + MmioWrite32 (BaseAddr + SD_MMC_PHY_MPP_OFFSET, Reg); + } +} + EFI_STATUS MppInitialize ( ) @@ -159,5 +198,11 @@ MppInitialize ( SetRegisterValue (RegCount, MppRegPcd[i], BaseAddr[i], ReverseFlag[i]); }
+ /* + * eMMC PHY IP has its own MPP configuration. + * It's controlled from Chip0. + */ + SetSdMmcPhyMpp (BaseAddr[0]); + return EFI_SUCCESS; } diff --git a/Platforms/Marvell/Library/MppLib/MppLib.inf b/Platforms/Marvell/Library/MppLib/MppLib.inf index 510064f..82716f4 100644 --- a/Platforms/Marvell/Library/MppLib/MppLib.inf +++ b/Platforms/Marvell/Library/MppLib/MppLib.inf @@ -105,3 +105,4 @@ gMarvellTokenSpaceGuid.PcdChip3MppSel6 gMarvellTokenSpaceGuid.PcdChip3MppSel7
+ gMarvellTokenSpaceGuid.PcdPciESdhci