From 512184f1a74ada3414d865b9a8356531a4fdb70f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20B=C4=83l=C4=83nic=C4=83?= Date: Fri, 29 Dec 2023 02:56:03 +0200 Subject: [PATCH 05/16] Platform/RPi5: Add RP1 USB support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Requires "pciex4_reset=0" in config.txt so that PCIe 2 is left configured by the VPU firmware, until we add our own host bridge driver. Signed-off-by: Mario Bălănică --- Platform/RaspberryPi/RPi5/RPi5.dsc | 13 ++ Platform/RaspberryPi/RPi5/RPi5.fdf | 6 + .../Drivers/Rp1BusDxe/Rp1BusDxe.c | 98 +++++++++ .../Drivers/Rp1BusDxe/Rp1BusDxe.inf | 39 ++++ .../RaspberryPi/RpiSiliconPkg/Include/Rp1.asi | 60 ++++++ .../RaspberryPi/RpiSiliconPkg/Include/Rp1.h | 191 ++++++++++++++++++ .../RpiSiliconPkg/RpiSiliconPkg.dec | 22 ++ 7 files changed, 429 insertions(+) create mode 100644 Silicon/RaspberryPi/RpiSiliconPkg/Drivers/Rp1BusDxe/Rp1BusDxe.c create mode 100644 Silicon/RaspberryPi/RpiSiliconPkg/Drivers/Rp1BusDxe/Rp1BusDxe.inf create mode 100644 Silicon/RaspberryPi/RpiSiliconPkg/Include/Rp1.asi create mode 100644 Silicon/RaspberryPi/RpiSiliconPkg/Include/Rp1.h create mode 100644 Silicon/RaspberryPi/RpiSiliconPkg/RpiSiliconPkg.dec diff --git a/Platform/RaspberryPi/RPi5/RPi5.dsc b/Platform/RaspberryPi/RPi5/RPi5.dsc index 79aa4f1b..6850203e 100644 --- a/Platform/RaspberryPi/RPi5/RPi5.dsc +++ b/Platform/RaspberryPi/RPi5/RPi5.dsc @@ -186,6 +186,8 @@ BoardInfoLib|Platform/RaspberryPi/Library/BoardInfoLib/BoardInfoLib.inf BoardRevisionHelperLib|Platform/RaspberryPi/Library/BoardRevisionHelperLib/BoardRevisionHelperLib.inf + NonDiscoverableDeviceRegistrationLib|MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.inf + [LibraryClasses.common.SEC] PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf @@ -434,6 +436,11 @@ # gRaspberryPiTokenSpaceGuid.PcdFwMailboxBaseAddress|0x107c013880 + # + # RP1 BAR1 preconfigured by the VPU + # + gRpiSiliconTokenSpaceGuid.Rp1PciPeripheralsBar|0x1f00000000 + ## Default Terminal Type ## 0-PCANSI, 1-VT100, 2-VT00+, 3-UTF8, 4-TTYTERM gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4 @@ -634,12 +641,18 @@ ArmPkg/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf # MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf + MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.inf EmbeddedPkg/Drivers/NonCoherentIoMmuDxe/NonCoherentIoMmuDxe.inf { gEmbeddedTokenSpaceGuid.PcdDmaDeviceOffset|0x00000000 gEmbeddedTokenSpaceGuid.PcdDmaDeviceLimit|0xbfffffff } + # + # RP1 I/O bridge + # + Silicon/RaspberryPi/RpiSiliconPkg/Drivers/Rp1BusDxe/Rp1BusDxe.inf + # # NVMe boot devices # diff --git a/Platform/RaspberryPi/RPi5/RPi5.fdf b/Platform/RaspberryPi/RPi5/RPi5.fdf index 8391c195..8cd67254 100644 --- a/Platform/RaspberryPi/RPi5/RPi5.fdf +++ b/Platform/RaspberryPi/RPi5/RPi5.fdf @@ -281,8 +281,14 @@ READ_LOCK_STATUS = TRUE INF ArmPkg/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf # INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf + INF MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.inf INF EmbeddedPkg/Drivers/NonCoherentIoMmuDxe/NonCoherentIoMmuDxe.inf + # + # RP1 I/O bridge + # + INF Silicon/RaspberryPi/RpiSiliconPkg/Drivers/Rp1BusDxe/Rp1BusDxe.inf + # # NVMe boot devices # diff --git a/Silicon/RaspberryPi/RpiSiliconPkg/Drivers/Rp1BusDxe/Rp1BusDxe.c b/Silicon/RaspberryPi/RpiSiliconPkg/Drivers/Rp1BusDxe/Rp1BusDxe.c new file mode 100644 index 00000000..7d7012b5 --- /dev/null +++ b/Silicon/RaspberryPi/RpiSiliconPkg/Drivers/Rp1BusDxe/Rp1BusDxe.c @@ -0,0 +1,98 @@ +/** @file + * + * Copyright (c) 2023, Mario Bălănică + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include +#include +#include +#include + +#include + +typedef struct { + EFI_PHYSICAL_ADDRESS Bar; + UINT32 ChipId; +} RP1_DEVICE; + +STATIC +EFI_STATUS +EFIAPI +Rp1RegisterDwc3Controllers ( + IN RP1_DEVICE *This + ) +{ + EFI_STATUS Status; + UINTN Index; + EFI_PHYSICAL_ADDRESS FullBase; + + EFI_PHYSICAL_ADDRESS Dwc3Addresses[] = { + RP1_USBHOST0_BASE, RP1_USBHOST1_BASE + }; + + for (Index = 0; Index < ARRAY_SIZE (Dwc3Addresses); Index++) { + FullBase = This->Bar + Dwc3Addresses[Index]; + Status = RegisterNonDiscoverableMmioDevice ( + NonDiscoverableDeviceTypeXhci, + NonDiscoverableDeviceDmaTypeNonCoherent, + NULL, + NULL, + 1, + FullBase, + RP1_USBHOST_SIZE + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, + "%a: Failed to register DWC3 controller at 0x%lx. Status=%r\n", + __func__, FullBase, Status)); + return Status; + } + } + return EFI_SUCCESS; +} + +STATIC +VOID +EFIAPI +Rp1RegisterDevices ( + IN RP1_DEVICE *This + ) +{ + Rp1RegisterDwc3Controllers (This); +} + +STATIC +VOID +EFIAPI +Rp1EnableInterrupts ( + IN RP1_DEVICE *This + ) +{ + MmioWrite32 (This->Bar + RP1_PCIE_REG_SET + RP1_PCIE_MSIX_CFG (RP1_INT_USBHOST0_0), + RP1_PCIE_MSIX_CFG_ENABLE); + MmioWrite32 (This->Bar + RP1_PCIE_REG_SET + RP1_PCIE_MSIX_CFG (RP1_INT_USBHOST1_0), + RP1_PCIE_MSIX_CFG_ENABLE); +} + +EFI_STATUS +EFIAPI +Rp1BusDxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + RP1_DEVICE Dev; + Dev.Bar = PcdGet64 (Rp1PciPeripheralsBar); + Dev.ChipId = MmioRead32 (Dev.Bar + RP1_SYSINFO_BASE); + + DEBUG ((DEBUG_INFO, "RP1 chip id: %x, peripheral BAR at CPU address 0x%lx\n", + Dev.ChipId, Dev.Bar)); + + Rp1RegisterDevices (&Dev); + Rp1EnableInterrupts (&Dev); + + return EFI_SUCCESS; +} diff --git a/Silicon/RaspberryPi/RpiSiliconPkg/Drivers/Rp1BusDxe/Rp1BusDxe.inf b/Silicon/RaspberryPi/RpiSiliconPkg/Drivers/Rp1BusDxe/Rp1BusDxe.inf new file mode 100644 index 00000000..ffc8c143 --- /dev/null +++ b/Silicon/RaspberryPi/RpiSiliconPkg/Drivers/Rp1BusDxe/Rp1BusDxe.inf @@ -0,0 +1,39 @@ +#/** @file +# +# Copyright (c) 2023, Mario Bălănică +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#**/ + +[Defines] + INF_VERSION = 0x0001001A + BASE_NAME = Rp1BusDxe + FILE_GUID = 7d4843f2-f474-40b1-87de-4d67fad8b00f + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = Rp1BusDxeEntryPoint + +[Sources] + Rp1BusDxe.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + Silicon/RaspberryPi/RpiSiliconPkg/RpiSiliconPkg.dec + +[LibraryClasses] + DebugLib + IoLib + NonDiscoverableDeviceRegistrationLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiLib + +[Protocols] + +[Pcd] + gRpiSiliconTokenSpaceGuid.Rp1PciPeripheralsBar + +[Depex] + TRUE diff --git a/Silicon/RaspberryPi/RpiSiliconPkg/Include/Rp1.asi b/Silicon/RaspberryPi/RpiSiliconPkg/Include/Rp1.asi new file mode 100644 index 00000000..9de562ba --- /dev/null +++ b/Silicon/RaspberryPi/RpiSiliconPkg/Include/Rp1.asi @@ -0,0 +1,60 @@ +/** @file + * + * Copyright (c) 2023, Mario Bălănică + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include + +#define RP1_QWORDMEMORY_BUF(Index) \ + QWordMemory (ResourceConsumer,, \ + MinFixed, MaxFixed, NonCacheable, ReadWrite, \ + 0x0, 0x0, 0x0, 0x0, 0x1,,, RB ## Index) + +#define RP1_QWORDMEMORY_SET(Index, Offset, Length) \ + CreateQwordField (RBUF, RB ## Index._MIN, MI ## Index) \ + CreateQwordField (RBUF, RB ## Index._MAX, MA ## Index) \ + CreateQwordField (RBUF, RB ## Index._LEN, LE ## Index) \ + LE ## Index = Length \ + MI ## Index = PBAR + Offset \ + MA ## Index = MI ## Index + LE ## Index - 1 + +#define RP1_INTERRUPT_BUF(Index) \ + Interrupt (ResourceConsumer, Level, ActiveHigh, Shared,,, \ + RB ## Index) { 0 } \ + +#define RP1_INTERRUPT_SET(Index) \ + CreateDwordField (RBUF, RB ## Index._INT, IN ## Index) \ + IN ## Index = PINT + +Device (XHC0) { + Name (_HID, "PNP0D10") + Name (_UID, 0x0) + + Method (_CRS, 0, Serialized) { + Name (RBUF, ResourceTemplate () { + RP1_QWORDMEMORY_BUF (00) + RP1_INTERRUPT_BUF (01) + }) + RP1_QWORDMEMORY_SET (00, RP1_USBHOST0_BASE, RP1_USBHOST_SIZE) + RP1_INTERRUPT_SET (01) + Return (RBUF) + } +} + +Device (XHC1) { + Name (_HID, "PNP0D10") + Name (_UID, 0x1) + + Method (_CRS, 0, Serialized) { + Name (RBUF, ResourceTemplate () { + RP1_QWORDMEMORY_BUF (00) + RP1_INTERRUPT_BUF (01) + }) + RP1_QWORDMEMORY_SET (00, RP1_USBHOST1_BASE, RP1_USBHOST_SIZE) + RP1_INTERRUPT_SET (01) + Return (RBUF) + } +} diff --git a/Silicon/RaspberryPi/RpiSiliconPkg/Include/Rp1.h b/Silicon/RaspberryPi/RpiSiliconPkg/Include/Rp1.h new file mode 100644 index 00000000..13a33fc6 --- /dev/null +++ b/Silicon/RaspberryPi/RpiSiliconPkg/Include/Rp1.h @@ -0,0 +1,191 @@ +/** @file + * + * Copyright (c) 2023, Mario Bălănică + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#ifndef __RP1_H__ +#define __RP1_H__ + +// +// BAR1 Peripherals +// +#define RP1_SYSINFO_BASE 0x00000000 +#define RP1_SYSCFG_BASE 0x00008000 +#define RP1_OTP_BASE 0x0000c000 +#define RP1_POWER_BASE 0x00010000 +#define RP1_RESETS_BASE 0x00014000 +#define RP1_CLOCKS_MAIN_BASE 0x00018000 +#define RP1_CLOCKS_VIDEO_BASE 0x0001c000 +#define RP1_PLL_SYS_BASE 0x00020000 +#define RP1_PLL_AUDIO_BASE 0x00024000 +#define RP1_PLL_VIDEO_BASE 0x00028000 +#define RP1_UART0_BASE 0x00030000 +#define RP1_UART1_BASE 0x00034000 +#define RP1_UART2_BASE 0x00038000 +#define RP1_UART3_BASE 0x0003c000 +#define RP1_UART4_BASE 0x00040000 +#define RP1_UART5_BASE 0x00044000 +#define RP1_SPI8_BASE 0x0004c000 +#define RP1_SPI0_BASE 0x00050000 +#define RP1_SPI1_BASE 0x00054000 +#define RP1_SPI2_BASE 0x00058000 +#define RP1_SPI3_BASE 0x0005c000 +#define RP1_SPI4_BASE 0x00060000 +#define RP1_SPI5_BASE 0x00064000 +#define RP1_SPI6_BASE 0x00068000 +#define RP1_SPI7_BASE 0x0006c000 +#define RP1_I2C0_BASE 0x00070000 +#define RP1_I2C1_BASE 0x00074000 +#define RP1_I2C2_BASE 0x00078000 +#define RP1_I2C3_BASE 0x0007c000 +#define RP1_I2C4_BASE 0x00080000 +#define RP1_I2C5_BASE 0x00084000 +#define RP1_I2C6_BASE 0x00088000 +#define RP1_AUDIO_IN_BASE 0x00090000 +#define RP1_AUDIO_OUT_BASE 0x00094000 +#define RP1_PWM0_BASE 0x00098000 +#define RP1_PWM1_BASE 0x0009c000 +#define RP1_I2S0_BASE 0x000a0000 +#define RP1_I2S1_BASE 0x000a4000 +#define RP1_I2S2_BASE 0x000a8000 +#define RP1_TIMER_BASE 0x000ac000 +#define RP1_SDIO0_CFG_BASE 0x000b0000 +#define RP1_SDIO1_CFG_BASE 0x000b4000 +#define RP1_BUSFABRIC_MONITOR_BASE 0x000c0000 +#define RP1_BUSFABRIC_AXISHIM_BASE 0x000c4000 +#define RP1_ADC_BASE 0x000c8000 +#define RP1_IO_BANK0_BASE 0x000d0000 +#define RP1_IO_BANK1_BASE 0x000d4000 +#define RP1_IO_BANK2_BASE 0x000d8000 +#define RP1_SYS_RIO0_BASE 0x000e0000 +#define RP1_SYS_RIO1_BASE 0x000e4000 +#define RP1_SYS_RIO2_BASE 0x000e8000 +#define RP1_PADS_BANK0_BASE 0x000f0000 +#define RP1_PADS_BANK1_BASE 0x000f4000 +#define RP1_PADS_BANK2_BASE 0x000f8000 +#define RP1_PADS_ETH_BASE 0x000fc000 +#define RP1_ETH_BASE 0x00100000 +#define RP1_ETH_CFG_BASE 0x00104000 +#define RP1_PCIE_BASE 0x00108000 +#define RP1_MIPI0_CSIDMA_BASE 0x00110000 +#define RP1_MIPI0_CSIHOST_BASE 0x00114000 +#define RP1_MIPI0_DSIDMA_BASE 0x00118000 +#define RP1_MIPI0_DSIHOST_BASE 0x0011c000 +#define RP1_MIPI0_CFG_BASE 0x00120000 +#define RP1_MIPI0_ISP_BASE 0x00124000 +#define RP1_MIPI1_CSIDMA_BASE 0x00128000 +#define RP1_MIPI1_CSIHOST_BASE 0x0012c000 +#define RP1_MIPI1_DSIDMA_BASE 0x00130000 +#define RP1_MIPI1_DSIHOST_BASE 0x00134000 +#define RP1_MIPI1_CFG_BASE 0x00138000 +#define RP1_MIPI1_ISP_BASE 0x0013c000 +#define RP1_VIDEO_OUT_CFG_BASE 0x00140000 +#define RP1_VIDEO_OUT_VEC_BASE 0x00144000 +#define RP1_VIDEO_OUT_DPI_BASE 0x00148000 +#define RP1_XOSC_BASE 0x00150000 +#define RP1_WATCHDOG_BASE 0x00154000 +#define RP1_DMA_TICK_BASE 0x00158000 +#define RP1_USBHOST0_CFG_BASE 0x00160000 +#define RP1_USBHOST1_CFG_BASE 0x00164000 +#define RP1_ROSC0_BASE 0x00168000 +#define RP1_ROSC1_BASE 0x0016c000 +#define RP1_VBUSCTRL_BASE 0x00170000 +#define RP1_TICKS_BASE 0x00174000 +#define RP1_PIO_BASE 0x00178000 +#define RP1_SDIO0_BASE 0x00180000 +#define RP1_SDIO1_BASE 0x00184000 +#define RP1_DMA_BASE 0x00188000 +#define RP1_USBHOST0_BASE 0x00200000 +#define RP1_USBHOST1_BASE 0x00300000 +#define RP1_EXAC_BASE 0x00400000 + +#define RP1_USBHOST_SIZE 0x00100000 + +// +// Local MSI-X vectors +// +#define RP1_INT_IO_BANK0 0 +#define RP1_INT_IO_BANK1 1 +#define RP1_INT_IO_BANK2 2 +#define RP1_INT_AUDIO_IN 3 +#define RP1_INT_AUDIO_OUT 4 +#define RP1_INT_PWM0 5 +#define RP1_INT_ETH 6 +#define RP1_INT_I2C0 7 +#define RP1_INT_I2C1 8 +#define RP1_INT_I2C2 9 +#define RP1_INT_I2C3 10 +#define RP1_INT_I2C4 11 +#define RP1_INT_I2C5 12 +#define RP1_INT_I2C6 13 +#define RP1_INT_I2S0 14 +#define RP1_INT_I2S1 15 +#define RP1_INT_I2S2 16 +#define RP1_INT_SDIO0 17 +#define RP1_INT_SDIO1 18 +#define RP1_INT_SPI0 19 +#define RP1_INT_SPI1 20 +#define RP1_INT_SPI2 21 +#define RP1_INT_SPI3 22 +#define RP1_INT_SPI4 23 +#define RP1_INT_SPI5 24 +#define RP1_INT_UART0 25 +#define RP1_INT_TIMER_0 26 +#define RP1_INT_TIMER_1 27 +#define RP1_INT_TIMER_2 28 +#define RP1_INT_TIMER_3 29 +#define RP1_INT_USBHOST0 30 +#define RP1_INT_USBHOST0_0 31 +#define RP1_INT_USBHOST0_1 32 +#define RP1_INT_USBHOST0_2 33 +#define RP1_INT_USBHOST0_3 34 +#define RP1_INT_USBHOST1 35 +#define RP1_INT_USBHOST1_0 36 +#define RP1_INT_USBHOST1_1 37 +#define RP1_INT_USBHOST1_2 38 +#define RP1_INT_USBHOST1_3 39 +#define RP1_INT_DMA 40 +#define RP1_INT_PWM1 41 +#define RP1_INT_UART1 42 +#define RP1_INT_UART2 43 +#define RP1_INT_UART3 44 +#define RP1_INT_UART4 45 +#define RP1_INT_UART5 46 +#define RP1_INT_MIPI0 47 +#define RP1_INT_MIPI1 48 +#define RP1_INT_VIDEO_OUT 49 +#define RP1_INT_PIO_0 50 +#define RP1_INT_PIO_1 51 +#define RP1_INT_ADC_FIFO 52 +#define RP1_INT_PCIE_OUT 53 +#define RP1_INT_SPI6 54 +#define RP1_INT_SPI7 55 +#define RP1_INT_SPI8 56 +#define RP1_INT_PROC_MISC 57 +#define RP1_INT_SYSCFG 58 +#define RP1_INT_CLOCKS_DEFAULT 59 +#define RP1_INT_VBUSCTRL 60 + +// +// System information registers +// +#define RP1_SYSINFO_CHIP_ID 0x0 + +// +// PCIe endpoint configuration registers +// +#define RP1_PCIE_REG_RW (RP1_PCIE_BASE + 0x000) +#define RP1_PCIE_REG_SET (RP1_PCIE_BASE + 0x800) +#define RP1_PCIE_REG_CLR (RP1_PCIE_BASE + 0xc00) + +// MSI-X vectors configuration +#define RP1_PCIE_MSIX_CFG(Irq) (0x008 + ((Irq) * 4)) +#define RP1_PCIE_MSIX_CFG_IACK_EN BIT3 +#define RP1_PCIE_MSIX_CFG_IACK BIT2 +#define RP1_PCIE_MSIX_CFG_TEST BIT1 +#define RP1_PCIE_MSIX_CFG_ENABLE BIT0 + +#endif // __RP1_H__ diff --git a/Silicon/RaspberryPi/RpiSiliconPkg/RpiSiliconPkg.dec b/Silicon/RaspberryPi/RpiSiliconPkg/RpiSiliconPkg.dec new file mode 100644 index 00000000..d66041e0 --- /dev/null +++ b/Silicon/RaspberryPi/RpiSiliconPkg/RpiSiliconPkg.dec @@ -0,0 +1,22 @@ +#/** @file +# +# Copyright (c) 2023, Mario Bălănică +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#**/ + +[Defines] + DEC_SPECIFICATION = 0x0001001A + PACKAGE_NAME = RpiSiliconPkg + PACKAGE_GUID = 6dd4364e-9b8a-449e-b0a7-60095c5a0f15 + PACKAGE_VERSION = 1.0 + +[Includes] + Include + +[Guids] + gRpiSiliconTokenSpaceGuid = { 0x0b3ce57a, 0xa82b, 0x4ada, { 0x8f, 0xb5, 0x52, 0xc8, 0x72, 0x30, 0x1f, 0xdb } } + +[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] + gRpiSiliconTokenSpaceGuid.Rp1PciPeripheralsBar|0x0|UINT64|0x00000001 -- 2.51.2