From: Wasim Khan <wasim.k...@nxp.com> Setup PCIe LayerscapeGen4 controller and setup CFG, IO, MMIO and MMIO64 iATU windows. Check for PcdPciLsGen4Ctrl to enable LsGen4 PCIe controller.
Co-authored-by: Vabhav Sharma <vabhav.sha...@nxp.com> Co-authored-by: Wasim Khan <wasim.k...@nxp.com> Signed-off-by: Wasim Khan <wasim.k...@nxp.com> --- Notes: V2: - Removed Signed-off and added Co-authored-by for co-author - Added logic to create MMIO64 ATU windows as per MMIO64 available space Silicon/NXP/NxpQoriqLs.dec | 1 + Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf | 1 + Silicon/NXP/Include/Pcie.h | 120 ++++++++++ Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c | 247 ++++++++++++++++---- 4 files changed, 328 insertions(+), 41 deletions(-) diff --git a/Silicon/NXP/NxpQoriqLs.dec b/Silicon/NXP/NxpQoriqLs.dec index 5358aaeb037e..d4d3057af509 100644 --- a/Silicon/NXP/NxpQoriqLs.dec +++ b/Silicon/NXP/NxpQoriqLs.dec @@ -38,3 +38,4 @@ [PcdsFixedAtBuild.common] [PcdsDynamic.common] gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable|FALSE|BOOLEAN|0x00000600 + gNxpQoriqLsTokenSpaceGuid.PcdPciLsGen4Ctrl|FALSE|BOOLEAN|0x00000601 diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf index 99807d5beb1f..aa5a9dec7c34 100644 --- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf +++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.inf @@ -40,3 +40,4 @@ [FixedPcd] [Pcd] gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable + gNxpQoriqLsTokenSpaceGuid.PcdPciLsGen4Ctrl diff --git a/Silicon/NXP/Include/Pcie.h b/Silicon/NXP/Include/Pcie.h index f7c18c3aa094..b7d46f3a3bd2 100755 --- a/Silicon/NXP/Include/Pcie.h +++ b/Silicon/NXP/Include/Pcie.h @@ -81,5 +81,125 @@ #define SEG_IO_BUS 0x0 #define CFG_SHIFT_ENABLE (PcdGetBool (PcdPciCfgShiftEnable)) +#define PCI_LS_GEN4_CTRL (PcdGetBool (PcdPciLsGen4Ctrl)) +// PCIe Layerscape Gen4 Controller +#define GPEX_CLASSCODE 0x474 +#define GPEX_CLASSCODE_SHIFT 16 +#define GPEX_CLASSCODE_MASK 0xffff +#define PAB_AXI_PIO_CTRL(Idx) (0x840 + 0x10 * Idx) +#define APIO_EN 0x1 +#define MEM_WIN_EN 0x1 << 1 +#define IO_WIN_EN 0x1 << 2 +#define CFG_WIN_EN 0x1 << 3 +#define PAB_PEX_PIO_CTRL(Idx) (0x8c0 + 0x10 * Idx) +#define PPIO_EN (0x1 << 0) +#define PAB_PEX_PIO_STAT(Idx) (0x8c4 + 0x10 * Idx) +#define PAB_PEX_PIO_MT_STAT(Idx) (0x8c8 + 0x10 * Idx) +#define PEX_AMAP_CTRL_TYPE_SHIFT 0x1 +#define PEX_AMAP_CTRL_EN_SHIFT 0x0 +#define PEX_AMAP_CTRL_TYPE_MASK 0x3 +#define PEX_AMAP_CTRL_EN_MASK 0x1 +#define PAB_PEX_AMAP_CTRL(Idx) (0x4ba0 + 0x10 * Idx) +#define PAB_EXT_PEX_AMAP_SIZE(Idx) (0xbef0 + 0x04 * Idx) +#define PAB_PEX_AMAP_AXI_WIN(Idx) (0x4ba4 + 0x10 * Idx) +#define PAB_EXT_PEX_AMAP_AXI_WIN(Idx) (0xb4a0 + 0x04 * Idx) +#define PAB_PEX_AMAP_PEX_WIN_L(Idx) (0x4ba8 + 0x10 * Idx) +#define PAB_PEX_AMAP_PEX_WIN_H(Idx) (0x4bac + 0x10 * Idx) +#define PAB_CTRL 0x808 +#define PAB_CTRL_APIO_EN 0x1 +#define PAB_CTRL_PPIO_EN (0x1 << 1) +#define PAB_CTRL_PAGE_SEL_SHIFT 13 +#define PAB_CTRL_PAGE_SEL_MASK 0x3f +#define INDIRECT_ADDR_BNDRY 0xc00 +#define PAGE_IDX_SHIFT 10 +#define PAGE_ADDR_MASK 0x3ff +#define PAB_AXI_AMAP_CTRL(Idx) (0xba0 + 0x10 * Idx) +#define PAB_EXT_AXI_AMAP_SIZE(Idx) (0xbaf0 + 0x4 * Idx) +#define PAB_AXI_AMAP_AXI_WIN(Idx) (0xba4 + 0x10 * Idx) +#define PAB_EXT_AXI_AMAP_AXI_WIN(Idx) (0x80a0 + 0x4 * Idx) +#define PAB_AXI_AMAP_PEX_WIN_L(Idx) (0xba8 + 0x10 * Idx) +#define PAB_AXI_AMAP_PEX_WIN_H(Idx) (0xbac + 0x10 * Idx) +#define PAB_AXI_TYPE_CFG 0x00 +#define PAB_AXI_TYPE_IO 0x01 +#define PAB_AXI_TYPE_MEM 0x02 +#define AXI_AMAP_CTRL_EN 0x1 +#define AXI_AMAP_CTRL_TYPE_SHIFT 1 +#define AXI_AMAP_CTRL_TYPE_MASK 0x3 +#define AXI_AMAP_CTRL_SIZE_SHIFT 10 +#define AXI_AMAP_CTRL_SIZE_MASK 0x3fffff + + +#define OFFSET_TO_PAGE_IDX(Off) ((Off >> PAGE_IDX_SHIFT) \ + & PAB_CTRL_PAGE_SEL_MASK) + +#define OFFSET_TO_PAGE_ADDR(Off) ((Off & PAGE_ADDR_MASK) \ + | INDIRECT_ADDR_BNDRY) +/** + Function to set page for LsGen4 Ctrl + + @param Dbi GPEX host controller address. + @param PgIdx The page index to select + +**/ +STATIC inline VOID PciLsGen4SetPg ( + IN EFI_PHYSICAL_ADDRESS Dbi, + IN UINT8 PgIdx + ) +{ + UINT32 Val; + Val = MmioRead32 (Dbi + PAB_CTRL); + Val &= ~(PAB_CTRL_PAGE_SEL_MASK << PAB_CTRL_PAGE_SEL_SHIFT); + Val |= (PgIdx & PAB_CTRL_PAGE_SEL_MASK) << PAB_CTRL_PAGE_SEL_SHIFT; + MmioWrite32 (Dbi + PAB_CTRL, Val); +} + +/** + Function to read LsGen4 PCIe controller config space + LsGen4 PCIe controller requires page number to be set + in Bridge Control Register(PAB) for offset > 3KB. + + @param Dbi GPEX host controller address. + @param Offset Offset to read from + +**/ +STATIC inline INTN PciLsGen4Read32 ( + IN EFI_PHYSICAL_ADDRESS Dbi, + IN UINT32 Offset + ) +{ + if (Offset < INDIRECT_ADDR_BNDRY) { + PciLsGen4SetPg (Dbi, 0); + return MmioRead32 (Dbi + Offset); + } else { + // If Offset > 3KB, paging mechanism is used + // Select page index and offset within the page + PciLsGen4SetPg (Dbi, OFFSET_TO_PAGE_IDX (Offset)); + return MmioRead32 (Dbi + OFFSET_TO_PAGE_ADDR (Offset)); + } +} + +/** + Function to write to LsGen4 PCIe controller config space + LsGen4 PCIe controller requires page number to be set + in Bridge Control Register(PAB) for offset > 3KB. + + @param Dbi GPEX host controller address + @param Offset Offset to read from + +**/ +STATIC inline VOID PciLsGen4Write32 ( + IN EFI_PHYSICAL_ADDRESS Dbi, + IN UINT32 Offset, + IN UINT32 Value + ) +{ + if (Offset < INDIRECT_ADDR_BNDRY) { + PciLsGen4SetPg (Dbi, 0); + MmioWrite32 (Dbi + Offset, Value); + } else { + PciLsGen4SetPg (Dbi, OFFSET_TO_PAGE_IDX (Offset)); + MmioWrite32 (Dbi + OFFSET_TO_PAGE_ADDR (Offset), Value); + } +} #endif diff --git a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c index 9fae19095cba..8e39fb25f83e 100644 --- a/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c +++ b/Silicon/NXP/Library/PciHostBridgeLib/PciHostBridgeLib.c @@ -201,7 +201,11 @@ PcieLinkUp ( UINT32 State; UINT32 LtssmMask; - LtssmMask = 0x3f; + if (PCI_LS_GEN4_CTRL) { + LtssmMask = 0x7f; + } else { + LtssmMask = 0x3f; + } PcieOps = GetMmioOperations (FeaturePcdGet (PcdPciLutBigEndian)); State = PcieOps->Read32 ((UINTN)Pcie + PCI_LUT_BASE + PCI_LUT_DBG) & LtssmMask; @@ -237,38 +241,58 @@ PcieOutboundSet ( IN UINT64 Size ) { - // PCIe Layerscape : Outbound Window - MmioWrite32 (Dbi + IATU_VIEWPORT_OFF, - (UINT32)(IATU_VIEWPORT_OUTBOUND | Idx)); + UINT32 Val; - MmioWrite32 (Dbi + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0, - (UINT32)Phys); - - MmioWrite32 (Dbi + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0, - (UINT32)(Phys >> 32)); - - MmioWrite32 (Dbi + IATU_LIMIT_ADDR_OFF_OUTBOUND_0, - (UINT32)(Phys + Size - BIT0)); - - MmioWrite32 (Dbi + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0, - (UINT32)BusAddr); - - MmioWrite32 (Dbi + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0, - (UINT32)(BusAddr >> 32)); - - MmioWrite32 (Dbi + IATU_REGION_CTRL_1_OFF_OUTBOUND_0, - (UINT32)Type); - - if (CFG_SHIFT_ENABLE && - ((Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0) || - (Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1))) { - MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0, - (IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN | - IATU_ENABLE_CFG_SHIFT_FEATURE) - ); + if (PCI_LS_GEN4_CTRL) { + // PCIe Layerscape Gen4: Outbound Window + Size = ~(Size -1 ); + Val = PciLsGen4Read32 ((UINTN)Dbi, PAB_AXI_AMAP_CTRL (Idx)); + Val &= ~((AXI_AMAP_CTRL_TYPE_MASK << AXI_AMAP_CTRL_TYPE_SHIFT) | + (AXI_AMAP_CTRL_SIZE_MASK << AXI_AMAP_CTRL_SIZE_SHIFT) | + AXI_AMAP_CTRL_EN); + Val |= ((Type & AXI_AMAP_CTRL_TYPE_MASK) << AXI_AMAP_CTRL_TYPE_SHIFT) | + (((UINT32)Size >> AXI_AMAP_CTRL_SIZE_SHIFT) << + AXI_AMAP_CTRL_SIZE_SHIFT) | AXI_AMAP_CTRL_EN; + PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_CTRL (Idx), Val); + PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_AXI_WIN (Idx), (UINT32)Phys); + PciLsGen4Write32 ((UINTN)Dbi, PAB_EXT_AXI_AMAP_AXI_WIN (Idx), Phys >> 32); + PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_PEX_WIN_L (Idx), (UINT32)BusAddr); + PciLsGen4Write32 ((UINTN)Dbi, PAB_AXI_AMAP_PEX_WIN_H (Idx), BusAddr >> 32); + PciLsGen4Write32 ((UINTN)Dbi, PAB_EXT_AXI_AMAP_SIZE (Idx), Size >> 32); } else { - MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0, - IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN); + // PCIe Layerscape : Outbound Window + MmioWrite32 (Dbi + IATU_VIEWPORT_OFF, + (UINT32)(IATU_VIEWPORT_OUTBOUND | Idx)); + + MmioWrite32 (Dbi + IATU_LWR_BASE_ADDR_OFF_OUTBOUND_0, + (UINT32)Phys); + + MmioWrite32 (Dbi + IATU_UPPER_BASE_ADDR_OFF_OUTBOUND_0, + (UINT32)(Phys >> 32)); + + MmioWrite32 (Dbi + IATU_LIMIT_ADDR_OFF_OUTBOUND_0, + (UINT32)(Phys + Size - BIT0)); + + MmioWrite32 (Dbi + IATU_LWR_TARGET_ADDR_OFF_OUTBOUND_0, + (UINT32)BusAddr); + + MmioWrite32 (Dbi + IATU_UPPER_TARGET_ADDR_OFF_OUTBOUND_0, + (UINT32)(BusAddr >> 32)); + + MmioWrite32 (Dbi + IATU_REGION_CTRL_1_OFF_OUTBOUND_0, + (UINT32)Type); + + if (CFG_SHIFT_ENABLE && + ((Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG0) || + (Type == IATU_REGION_CTRL_1_OFF_OUTBOUND_0_TYPE_CFG1))) { + MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0, + (IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN | + IATU_ENABLE_CFG_SHIFT_FEATURE) + ); + } else { + MmioWrite32 (Dbi + IATU_REGION_CTRL_2_OFF_OUTBOUND_0, + IATU_REGION_CTRL_2_OFF_OUTBOUND_0_REGION_EN); + } } } @@ -373,6 +397,116 @@ PcieLsSetupAtu ( SEG_IO_SIZE ); } + +/** + Function to set-up ATU windows for PCIe LayerscapeGen4 controller + + @param Pcie Address of PCIe host controller + @param Cfg0Base PCIe controller phy address Type0 Configuration Space. + @param Cfg1Base PCIe controller phy address Type1 Configuration Space. + @param MemBase PCIe controller phy address Memory Space. + @param Mem64Base PCIe controller phy address MMIO64 Space. + @param IoBase PCIe controller phy address IO Space. +**/ +STATIC +VOID +PcieLsGen4SetupAtu ( + IN EFI_PHYSICAL_ADDRESS Pcie, + IN EFI_PHYSICAL_ADDRESS Cfg0Base, + IN EFI_PHYSICAL_ADDRESS Cfg1Base, + IN EFI_PHYSICAL_ADDRESS MemBase, + IN EFI_PHYSICAL_ADDRESS Mem64Base, + IN EFI_PHYSICAL_ADDRESS IoBase + ) +{ + UINT64 Mem64End; + UINT32 Index; + + Index=0; + + // ATU : OUTBOUND WINDOW 1 : CFG0 + PcieOutboundSet (Pcie, Index++, + PAB_AXI_TYPE_CFG, + Cfg0Base, + SEG_CFG_BUS, + SEG_CFG_SIZE); + + // ATU : OUTBOUND WINDOW 2 : IO + PcieOutboundSet (Pcie, Index++, + PAB_AXI_TYPE_IO, + IoBase, + SEG_IO_BUS, + SEG_IO_SIZE); + + // ATU : OUTBOUND WINDOW 3 : MEM + PcieOutboundSet (Pcie, Index++, + PAB_AXI_TYPE_MEM, + MemBase, + SEG_MEM_BUS, + SEG_MEM_SIZE); + + // + // To allow maximum MMIO64 space, MMIO64 window + // size must be multiple of max iATU size (4GB) + // + ASSERT ((PCI_MMIO64_WIN_SIZE & (SIZE_4GB - 1)) == 0); + + Mem64End = Mem64Base + PCI_MMIO64_WIN_SIZE - 1; + while (Mem64Base < Mem64End) { + // ATU : OUTBOUND WINDOW : MMIO64 + PcieOutboundSet (Pcie, Index++, + PAB_AXI_TYPE_MEM, + Mem64Base, + Mem64Base, + SIZE_4GB); + + Mem64Base += SIZE_4GB; + } +} + +/** + Function to set-up PCIe inbound window + + @param Pcie Address of PCIe host controller. + @param Idx Index of inbound window. + @param Type Type(Cfg/Mem/IO) of iATU outbound window. + @param Phys PCIe controller phy address for inbound window. + @param BusAdr PCIe controller bus address for inbound window. + @param Size Window size + +**/ + +STATIC +VOID +PciSetupInBoundWin ( + IN EFI_PHYSICAL_ADDRESS Pcie, + IN UINT32 Idx, + IN UINT32 Type, + IN UINT64 Phys, + IN UINT64 BusAddr, + IN UINT64 Size) +{ + UINT32 Val; + UINT64 WinSize; + + if (PCI_LS_GEN4_CTRL) { + Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_PEX_AMAP_CTRL(Idx)); + Val &= ~(PEX_AMAP_CTRL_TYPE_MASK << PEX_AMAP_CTRL_TYPE_SHIFT); + Val &= ~(PEX_AMAP_CTRL_EN_MASK << PEX_AMAP_CTRL_EN_SHIFT); + Val = (Val | (Type << PEX_AMAP_CTRL_TYPE_SHIFT)); + Val = (Val | (1 << PEX_AMAP_CTRL_EN_SHIFT)); + + WinSize = ~(Size - 1); + PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_CTRL(Idx), + (Val | (UINT32)WinSize)); + PciLsGen4Write32 ((UINTN)Pcie, PAB_EXT_PEX_AMAP_SIZE(Idx), (WinSize>>32)); + PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_AXI_WIN(Idx), (UINT32)Phys); + PciLsGen4Write32 ((UINTN)Pcie, PAB_EXT_PEX_AMAP_AXI_WIN(Idx), (Phys>>32)); + PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_PEX_WIN_L(Idx), (UINT32)BusAddr); + PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_AMAP_PEX_WIN_H(Idx), (BusAddr >>32)); + } +} + /** Helper function to set-up PCIe controller @@ -397,16 +531,47 @@ PcieSetupCntrl ( { UINT32 Val; - // PCIe Layerscape Controller Setup - PcieLsSetupAtu (Pcie, Cfg0Base, Cfg1Base, MemBase, Mem64Base, IoBase); - - // Program Class code for Layerscape PCIe controller - MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 1); - Val = MmioRead32 ((UINTN)Pcie + PCI_CLASS_DEVICE); - Val &= ~(CLASS_CODE_MASK << CLASS_CODE_SHIFT); - Val |= (PCI_CLASS_BRIDGE_PCI << CLASS_CODE_SHIFT); - MmioWrite32 ((UINTN)Pcie + PCI_CLASS_DEVICE, Val); - MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 0); + if (PCI_LS_GEN4_CTRL) { + // PCIe LsGen4 Controller Setup + + //Fix Class Code + Val = PciLsGen4Read32 ((UINTN)Pcie, GPEX_CLASSCODE); + Val &= ~(GPEX_CLASSCODE_MASK << GPEX_CLASSCODE_SHIFT); + Val |= PCI_CLASS_BRIDGE_PCI << GPEX_CLASSCODE_SHIFT; + PciLsGen4Write32 ((UINTN)Pcie, GPEX_CLASSCODE, Val); + + // Enable APIO and Memory/IO/CFG Windows + Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_AXI_PIO_CTRL (0)); + Val |= APIO_EN | MEM_WIN_EN | IO_WIN_EN | CFG_WIN_EN; + PciLsGen4Write32 ((UINTN)Pcie, PAB_AXI_PIO_CTRL (0), Val); + + // LsGen4 Inbound Window Setup + PciSetupInBoundWin (Pcie, 0, PAB_AXI_TYPE_MEM, 0 , 0, SIZE_1TB); + + // LsGen4 Outbound Window Setup + PcieLsGen4SetupAtu (Pcie, Cfg0Base, Cfg1Base, MemBase, Mem64Base, IoBase); + + // Enable AMBA & PEX PIO + Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_CTRL); + Val |= PAB_CTRL_APIO_EN | PAB_CTRL_PPIO_EN; + PciLsGen4Write32 ((UINTN)Pcie, PAB_CTRL, Val); + + Val = PciLsGen4Read32 ((UINTN)Pcie, PAB_PEX_PIO_CTRL(0)); + Val |= PPIO_EN; + PciLsGen4Write32 ((UINTN)Pcie, PAB_PEX_PIO_CTRL(0), Val); + + } else { + // PCIe Layerscape Controller Setup + PcieLsSetupAtu (Pcie, Cfg0Base, Cfg1Base, MemBase, Mem64Base, IoBase); + + // Program Class code for Layerscape PCIe controller + MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 1); + Val = MmioRead32 ((UINTN)Pcie + PCI_CLASS_DEVICE); + Val &= ~(CLASS_CODE_MASK << CLASS_CODE_SHIFT); + Val |= (PCI_CLASS_BRIDGE_PCI << CLASS_CODE_SHIFT); + MmioWrite32 ((UINTN)Pcie + PCI_CLASS_DEVICE, Val); + MmioWrite32 ((UINTN)Pcie + PCI_DBI_RO_WR_EN, 0); + } } /** -- 2.7.4 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#60245): https://edk2.groups.io/g/devel/message/60245 Mute This Topic: https://groups.io/mt/74474402/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-