|
@@ -0,0 +1,294 @@
|
|
|
+/**
|
|
|
+*
|
|
|
+* Copyright (C) 2021, Semihalf.
|
|
|
+*
|
|
|
+* SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
+*
|
|
|
+**/
|
|
|
+
|
|
|
+#include <Uefi.h>
|
|
|
+
|
|
|
+#include <Library/ArmadaBoardDescLib.h>
|
|
|
+#include <Library/BaseMemoryLib.h>
|
|
|
+#include <Library/DebugLib.h>
|
|
|
+#include <Library/IoLib.h>
|
|
|
+#include <Library/MemoryAllocationLib.h>
|
|
|
+#include <Library/MvGpioLib.h>
|
|
|
+#include <Library/UefiBootServicesTableLib.h>
|
|
|
+
|
|
|
+#include "BoardDescriptionLib.h"
|
|
|
+
|
|
|
+STATIC
|
|
|
+VOID
|
|
|
+ConfigureIoWindow (
|
|
|
+ UINT64 WinBaseAddress,
|
|
|
+ UINT64 WinSize,
|
|
|
+ UINTN WinId,
|
|
|
+ UINT32 WinTargetId
|
|
|
+ )
|
|
|
+{
|
|
|
+ UINT32 AddressHigh;
|
|
|
+ UINT32 AddressLow;
|
|
|
+ UINT64 MaxAddress;
|
|
|
+
|
|
|
+ /* Disable IO window. */
|
|
|
+ MmioWrite32 (IO_WIN_ALR_OFFSET(WinId), 0);
|
|
|
+
|
|
|
+ /* Calculate the end address. */
|
|
|
+ MaxAddress = (WinBaseAddress + WinSize - 1);
|
|
|
+
|
|
|
+ AddressLow = (UINT32)((WinBaseAddress >> IO_WIN_ADDRESS_SHIFT) & IO_WIN_ADDRESS_MASK);
|
|
|
+ AddressLow |= IO_WIN_ENABLE_BIT;
|
|
|
+ AddressHigh = (UINT32)((MaxAddress >> IO_WIN_ADDRESS_SHIFT) & IO_WIN_ADDRESS_MASK);
|
|
|
+
|
|
|
+ /* Write start address and end address for IO window. */
|
|
|
+ MmioWrite32 (IO_WIN_ALR_OFFSET(WinId), AddressLow);
|
|
|
+ MmioWrite32 (IO_WIN_AHR_OFFSET(WinId), AddressHigh);
|
|
|
+
|
|
|
+ /* Write window target. */
|
|
|
+ MmioWrite32 (IO_WIN_CR_OFFSET(WinId), WinTargetId);
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+// General purpose routine for per-board initalization
|
|
|
+//
|
|
|
+EFI_STATUS
|
|
|
+ArmadaBoardInit (
|
|
|
+ VOID
|
|
|
+ )
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * Due to lack of sufficient number of IO windows registers,
|
|
|
+ * the CP1/CP2 PCIE configuration must be performed after the
|
|
|
+ * early firmware stages. Replace the MCI 0/1 indirect
|
|
|
+ * windows, which are no longer needed.
|
|
|
+ */
|
|
|
+ ConfigureIoWindow (
|
|
|
+ CP1_PCIE_WIN64_BASE,
|
|
|
+ CP1_PCIE_WIN64_SIZE,
|
|
|
+ CP1_PCIE_WIN64_ID,
|
|
|
+ MCI0_TARGET_ID
|
|
|
+ );
|
|
|
+
|
|
|
+ ConfigureIoWindow (
|
|
|
+ CP2_PCIE_WIN64_BASE,
|
|
|
+ CP2_PCIE_WIN64_SIZE,
|
|
|
+ CP2_PCIE_WIN64_ID,
|
|
|
+ MCI1_TARGET_ID
|
|
|
+ );
|
|
|
+
|
|
|
+ /* Enable FAN */
|
|
|
+ MmioAnd32 (CP0_GPIO1_DATA_OUT_REG, ~CP0_GPIO1_PIN_MASK);
|
|
|
+ MmioAnd32 (CP0_GPIO1_OUT_EN_REG, ~CP0_GPIO1_PIN_MASK);
|
|
|
+
|
|
|
+ return EFI_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+// GPIO Expander
|
|
|
+//
|
|
|
+EFI_STATUS
|
|
|
+EFIAPI
|
|
|
+ArmadaBoardGpioExpanderGet (
|
|
|
+ IN OUT MV_GPIO_EXPANDER **GpioExpanders,
|
|
|
+ IN OUT UINTN *GpioExpanderCount
|
|
|
+ )
|
|
|
+{
|
|
|
+ /* No GPIO expanders on board */
|
|
|
+ *GpioExpanders = NULL;
|
|
|
+ *GpioExpanderCount = 0;
|
|
|
+
|
|
|
+ return EFI_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+// PCIE
|
|
|
+//
|
|
|
+STATIC
|
|
|
+MV_PCIE_CONTROLLER mPcieController[] = {
|
|
|
+ { /* CP0 PCIE0 @0xF2600000 */
|
|
|
+ .PcieDbiAddress = 0xF2600000,
|
|
|
+ .ConfigSpaceAddress = 0x800000000,
|
|
|
+ .HaveResetGpio = FALSE,
|
|
|
+ .PcieResetGpio = { 0 },
|
|
|
+ .PcieBusMin = 0,
|
|
|
+ .PcieBusMax = 0xFE,
|
|
|
+ .PcieIoTranslation = 0x80FF00000,
|
|
|
+ .PcieIoWinBase = 0x0,
|
|
|
+ .PcieIoWinSize = 0x10000,
|
|
|
+ .PcieMmio32Translation = 0,
|
|
|
+ .PcieMmio32WinBase = 0xC0000000,
|
|
|
+ .PcieMmio32WinSize = 0x20000000,
|
|
|
+ .PcieMmio64Translation = 0,
|
|
|
+ .PcieMmio64WinBase = 0x810000000,
|
|
|
+ .PcieMmio64WinSize = 0x80000000,
|
|
|
+ },
|
|
|
+ { /* CP1 PCIE0 @0xF4600000 */
|
|
|
+ .PcieDbiAddress = 0xF4600000,
|
|
|
+ .ConfigSpaceAddress = 0xE2000000,
|
|
|
+ .HaveResetGpio = FALSE,
|
|
|
+ .PcieResetGpio = { 0 },
|
|
|
+ .PcieBusMin = 0,
|
|
|
+ .PcieBusMax = 0xE,
|
|
|
+ .PcieIoTranslation = 0xE2F00000,
|
|
|
+ .PcieIoWinBase = 0x0,
|
|
|
+ .PcieIoWinSize = 0x10000,
|
|
|
+ .PcieMmio32Translation = 0,
|
|
|
+ .PcieMmio32WinBase = 0xE3000000,
|
|
|
+ .PcieMmio32WinSize = 0x1000000,
|
|
|
+ .PcieMmio64Translation = 0,
|
|
|
+ .PcieMmio64WinBase = 0x890000000,
|
|
|
+ .PcieMmio64WinSize = 0x10000000,
|
|
|
+ },
|
|
|
+ { /* CP1 PCIE1 @0xF4620000 */
|
|
|
+ .PcieDbiAddress = 0xF4620000,
|
|
|
+ .ConfigSpaceAddress = 0xE4000000,
|
|
|
+ .HaveResetGpio = FALSE,
|
|
|
+ .PcieResetGpio = { 0 },
|
|
|
+ .PcieBusMin = 0,
|
|
|
+ .PcieBusMax = 0xE,
|
|
|
+ .PcieIoTranslation = 0xE4F00000,
|
|
|
+ .PcieIoWinBase = 0x0,
|
|
|
+ .PcieIoWinSize = 0x10000,
|
|
|
+ .PcieMmio32Translation = 0,
|
|
|
+ .PcieMmio32WinBase = 0xE5000000,
|
|
|
+ .PcieMmio32WinSize = 0x1000000,
|
|
|
+ .PcieMmio64Translation = 0,
|
|
|
+ .PcieMmio64WinBase = 0x8A0000000,
|
|
|
+ .PcieMmio64WinSize = 0x10000000,
|
|
|
+ },
|
|
|
+ { /* CP1 PCIE2 @0xF4640000 */
|
|
|
+ .PcieDbiAddress = 0xF4640000,
|
|
|
+ .ConfigSpaceAddress = 0xE6000000,
|
|
|
+ .HaveResetGpio = FALSE,
|
|
|
+ .PcieResetGpio = { 0 },
|
|
|
+ .PcieBusMin = 0,
|
|
|
+ .PcieBusMax = 0xE,
|
|
|
+ .PcieIoTranslation = 0xE6F00000,
|
|
|
+ .PcieIoWinBase = 0x0,
|
|
|
+ .PcieIoWinSize = 0x10000,
|
|
|
+ .PcieMmio32Translation = 0,
|
|
|
+ .PcieMmio32WinBase = 0xE7000000,
|
|
|
+ .PcieMmio32WinSize = 0x1000000,
|
|
|
+ .PcieMmio64Translation = 0,
|
|
|
+ .PcieMmio64WinBase = 0x8B0000000,
|
|
|
+ .PcieMmio64WinSize = 0x10000000,
|
|
|
+ },
|
|
|
+ { /* CP2 PCIE0 @0xF6600000 */
|
|
|
+ .PcieDbiAddress = 0xF6600000,
|
|
|
+ .ConfigSpaceAddress = 0xE9000000,
|
|
|
+ .HaveResetGpio = FALSE,
|
|
|
+ .PcieResetGpio = { 0 },
|
|
|
+ .PcieBusMin = 0,
|
|
|
+ .PcieBusMax = 0xE,
|
|
|
+ .PcieIoTranslation = 0xE9F00000,
|
|
|
+ .PcieIoWinBase = 0x0,
|
|
|
+ .PcieIoWinSize = 0x10000,
|
|
|
+ .PcieMmio32Translation = 0,
|
|
|
+ .PcieMmio32WinBase = 0xEA000000,
|
|
|
+ .PcieMmio32WinSize = 0x1000000,
|
|
|
+ .PcieMmio64Translation = 0,
|
|
|
+ .PcieMmio64WinBase = 0x8C0000000,
|
|
|
+ .PcieMmio64WinSize = 0x10000000,
|
|
|
+ },
|
|
|
+ { /* CP2 PCIE1 @0xF6620000 */
|
|
|
+ .PcieDbiAddress = 0xF6620000,
|
|
|
+ .ConfigSpaceAddress = 0xEB000000,
|
|
|
+ .HaveResetGpio = FALSE,
|
|
|
+ .PcieResetGpio = { 0 },
|
|
|
+ .PcieBusMin = 0,
|
|
|
+ .PcieBusMax = 0xE,
|
|
|
+ .PcieIoTranslation = 0xEBF00000,
|
|
|
+ .PcieIoWinBase = 0x0,
|
|
|
+ .PcieIoWinSize = 0x10000,
|
|
|
+ .PcieMmio32Translation = 0,
|
|
|
+ .PcieMmio32WinBase = 0xEC000000,
|
|
|
+ .PcieMmio32WinSize = 0x1000000,
|
|
|
+ .PcieMmio64Translation = 0,
|
|
|
+ .PcieMmio64WinBase = 0x8D0000000,
|
|
|
+ .PcieMmio64WinSize = 0x10000000,
|
|
|
+ },
|
|
|
+ { /* CP2 PCIE2 @0xF6640000 */
|
|
|
+ .PcieDbiAddress = 0xF6640000,
|
|
|
+ .ConfigSpaceAddress = 0xED000000,
|
|
|
+ .HaveResetGpio = FALSE,
|
|
|
+ .PcieResetGpio = { 0 },
|
|
|
+ .PcieBusMin = 0,
|
|
|
+ .PcieBusMax = 0xE,
|
|
|
+ .PcieIoTranslation = 0xEDF00000,
|
|
|
+ .PcieIoWinBase = 0x0,
|
|
|
+ .PcieIoWinSize = 0x10000,
|
|
|
+ .PcieMmio32Translation = 0,
|
|
|
+ .PcieMmio32WinBase = 0xEE000000,
|
|
|
+ .PcieMmio32WinSize = 0x1000000,
|
|
|
+ .PcieMmio64Translation = 0,
|
|
|
+ .PcieMmio64WinBase = 0x8E0000000,
|
|
|
+ .PcieMmio64WinSize = 0x10000000,
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ Return the number and description of PCIE controllers used on the platform.
|
|
|
+
|
|
|
+ @param[in out] **PcieControllers Array containing PCIE controllers'
|
|
|
+ description.
|
|
|
+ @param[in out] *PcieControllerCount Amount of used PCIE controllers.
|
|
|
+
|
|
|
+ @retval EFI_SUCCESS The data were obtained successfully.
|
|
|
+ @retval other Return error status.
|
|
|
+
|
|
|
+**/
|
|
|
+EFI_STATUS
|
|
|
+EFIAPI
|
|
|
+ArmadaBoardPcieControllerGet (
|
|
|
+ IN OUT MV_PCIE_CONTROLLER CONST **PcieControllers,
|
|
|
+ IN OUT UINTN *PcieControllerCount
|
|
|
+ )
|
|
|
+{
|
|
|
+ *PcieControllers = mPcieController;
|
|
|
+ *PcieControllerCount = ARRAY_SIZE (mPcieController);
|
|
|
+
|
|
|
+ return EFI_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+// Order of devices in SdMmcDescTemplate has to be in par with ArmadaSoCDescLib
|
|
|
+//
|
|
|
+STATIC
|
|
|
+MV_BOARD_SDMMC_DESC mSdMmcDescTemplate[] = {
|
|
|
+ { /* eMMC 0xF06E0000 */
|
|
|
+ 0, /* SOC will be filled by MvBoardDescDxe */
|
|
|
+ 0, /* SdMmcDevCount will be filled by MvBoardDescDxe */
|
|
|
+ TRUE, /* Xenon1v8Enabled */
|
|
|
+ /*
|
|
|
+ * Force 4-bit bus width - work-around for non
|
|
|
+ * functional HS400 mode.
|
|
|
+ */
|
|
|
+ FALSE, /* Xenon8BitBusEnabled */
|
|
|
+ FALSE, /* XenonSlowModeEnabled */
|
|
|
+ 0x40, /* XenonTuningStepDivisor */
|
|
|
+ EmbeddedSlot /* SlotType */
|
|
|
+ },
|
|
|
+ { /* SD/MMC 0xF2780000 */
|
|
|
+ 0, /* SOC will be filled by MvBoardDescDxe */
|
|
|
+ 0, /* SdMmcDevCount will be filled by MvBoardDescDxe */
|
|
|
+ FALSE, /* Xenon1v8Enabled */
|
|
|
+ FALSE, /* Xenon8BitBusEnabled */
|
|
|
+ FALSE, /* XenonSlowModeEnabled */
|
|
|
+ 0x19, /* XenonTuningStepDivisor */
|
|
|
+ EmbeddedSlot /* SlotType */
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+EFI_STATUS
|
|
|
+EFIAPI
|
|
|
+ArmadaBoardDescSdMmcGet (
|
|
|
+ OUT UINTN *SdMmcDevCount,
|
|
|
+ OUT MV_BOARD_SDMMC_DESC **SdMmcDesc
|
|
|
+ )
|
|
|
+{
|
|
|
+ *SdMmcDesc = mSdMmcDescTemplate;
|
|
|
+ *SdMmcDevCount = ARRAY_SIZE (mSdMmcDescTemplate);
|
|
|
+
|
|
|
+ return EFI_SUCCESS;
|
|
|
+}
|