diff --git a/.gitignore b/.gitignore
index 3ce6c058f5..d33d4372d6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,6 +42,8 @@
/.config-*
/.config\ *
/.cproject
+/.cache
+/.clang-format
/.gdbinit
/.gdb_history
/.project
@@ -80,4 +82,4 @@ SAVEMake.defs
SAVEconfig
.aider*
imx9-norimage.img
-
+config.txt
diff --git a/Documentation/platforms/arm64/bcm2711/boards/raspberrypi-4b/index.rst b/Documentation/platforms/arm64/bcm2711/boards/raspberrypi-4b/index.rst
new file mode 100644
index 0000000000..cf2ad9ace0
--- /dev/null
+++ b/Documentation/platforms/arm64/bcm2711/boards/raspberrypi-4b/index.rst
@@ -0,0 +1,158 @@
+===============
+Raspberry Pi 4B
+===============
+
+The `Raspberry Pi 4B `_ is an ARM64
+hobbyist board created by Raspberry Pi.
+
+.. figure:: raspberrypi-4b.png
+ :figwidth: 70%
+ :align: center
+ :alt: Raspberry Pi 4B board
+
+Features
+=========
+
+- Broadcom BCM2711 @1.8GHz
+- 1, 2, 4 and 8GB LPDDR4-3200 SDRAM models
+- 2.4GHz and 5.0GHz IEEE 802.11ac wireless
+- Bluetooth 5.0
+- Gigabit Ethernet
+- 2 USB 3.0 ports
+- 2 USB 2.0 ports
+- 2 micro-HDMI ports (4kp60)
+- 2-lane MIPI DSI display port
+- 2-lane MIPI CSI camera port
+- 4-pole stereo audio and composite video port
+- Micro SD card slot
+
+ARM64 Toolchain
+===============
+
+Before building NuttX for the Raspberry Pi 4B, download the ARM64 Toolchain for
+**AArch64 Bare-Metal Target** ``aarch64-none-elf`` from
+`Arm GNU Toolchain Downloads `_.
+(Skip the section for Beta Releases.)
+
+Add the downloaded toolchain ``gcc-arm-...-aarch64-none-elf/bin`` to the ``PATH`` Environment Variable.
+
+If you are running Arch Linux, you can also get the toolchain by installing from the AUR:
+
+.. code:: console
+
+ $ yay -S aarch64-none-elf-gcc-bin aarch64-none-elf-toolchain
+
+Check the ARM64 Toolchain:
+
+.. code:: console
+
+ $ aarch64-none-elf-gcc -v
+
+Building
+========
+
+To build NuttX for the Raspberry Pi 4B, :doc:`install the prerequisites ` and :doc:`clone the git
+repositories ` for ``nuttx`` and ``apps``.
+
+Configure the NuttX project to use the Raspberry Pi 4B and build it (this example uses the ``nsh`` configuration).
+
+.. code:: console
+
+ $ cd nutxx
+ $ tools/configure.sh raspberrypi-4b:nsh
+ $ make
+
+Booting
+========
+
+In order to boot NuttX on the Raspberry Pi 4B, you will need to have a formatted micro SD card. The SD card should
+contain a FAT32 partition that is marked as bootable and which contains the generated ``nuttx.bin`` and ``config.txt``
+files from the build process. In addition to those files, you will also need the following files from the Raspberry Pi
+repository for loading the image:
+
+- `bcm2711-rpi-4-b.dtb `_
+- `fixup4.dat `_
+- `fixup4cd.dat `_
+- `fixup4db.dat `_
+- `fixup4x.dat `_
+- `start4.elf `_
+- `start4cd.elf `_
+- `start4db.elf `_
+- `start4x.elf `_
+
+You can download all of these files with the shell script in ``tools/bcm2711/bootfiles.sh``.
+
+SD Card Formatting
+------------------
+
+Here is a list of ``fdisk`` commands for formatting the SD card on Linux. The tutorial assumes the SD card is at
+``/dev/sda``, but you can find the location of your SD card with ``lsblk``. **Make very sure you verify that the name is
+correct, or you can lose data by formatting a different device.**
+
+.. code:: console
+
+ $ sudo fdisk /dev/sda
+
+Print the partition table on the card with ``p`` to see what's there. If anything appears, continue to use the ``d``
+command to remove all partitions.
+
+- ``o`` to create a new, empty DOS partition table
+- ``n`` to create a new partition
+- ``p`` to make it primary
+- Hit enter to select the default partition of "1"
+- Hit enter for the default start and end sizes, which will use the full SD card size
+- ``t`` to change the type of the partition (hit enter to select default of partition 1)
+- ``c`` as the type, which is for Windows FAT32
+- ``a`` to mark the partition as bootable
+- ``w`` to write all the changes and save
+
+Now when you run ``lsblk``, you should see ``/dev/sda1`` (or an equivalent for your SD card). That is the new partition
+just created. Running the following command will then format the SD card to an empty FAT32 file system.
+
+.. code:: console
+
+ $ sudo mkfs.vfat /dev/sda1
+
+Once this completes, you can copy all of the aforementioned boot files, ``nuttx.bin`` and ``config.txt`` to your SD card
+in your preferred way (through a file explorer or by using ``mount``).
+
+Once all the files are copied, you can then eject the SD card and insert it onto your Raspberry Pi. The default console
+is the Mini UART, which requires an adapter such as `USB to TTL serial converter cable
+`_ to read. You should connect the ground to one of the Pi's ground pins, and then
+connect the RX to GPIO 14 and TX to GPIO 15. **Do not connect the red power wire**.
+
+Once the converter is connected and plugged into your host computer, you can open up a serial terminal of your choice. I
+use Minicom. Then, power your Raspberry Pi 4B with a USB-C cable and wait for the Pi to boot and the NSH prompt to
+appear onscreen:
+
+.. code:: console
+
+ NuttShell (NSH) NuttX-12.6.0-RC0
+ nsh> uname -a
+ NuttX 12.6.0-RC0 c4f3a42131-dirty Aug 6 2024 21:17:01 arm64 raspberrypi-4b
+ nsh>
+
+Board Peripheral Support
+========================
+
+SMP is currently unsupported.
+
+NuttX for the Raspberry Pi 4 supports these on-board peripherals:
+
+======================== =======
+Peripheral Support
+======================== =======
+I2C Partial (able to read, that's it)
+UART Mini UART yes, PL011 no
+GPIO Partial
+PWM No
+SPI No
+PCM No
+AV port No
+HDMI No
+WiFi No
+Ethernet No
+USB 3.0 No
+USB 2.0 No
+Bluetooth No
+======================== =======
diff --git a/Documentation/platforms/arm64/bcm2711/boards/raspberrypi-4b/raspberrypi-4b.png b/Documentation/platforms/arm64/bcm2711/boards/raspberrypi-4b/raspberrypi-4b.png
new file mode 100644
index 0000000000..929d0cf22c
Binary files /dev/null and b/Documentation/platforms/arm64/bcm2711/boards/raspberrypi-4b/raspberrypi-4b.png differ
diff --git a/Documentation/platforms/arm64/bcm2711/index.rst b/Documentation/platforms/arm64/bcm2711/index.rst
new file mode 100644
index 0000000000..fd8f44a93d
--- /dev/null
+++ b/Documentation/platforms/arm64/bcm2711/index.rst
@@ -0,0 +1,18 @@
+=======
+BCM2711
+=======
+
+The `BCM2711 `_ is a Broadcom SoC used for
+the Raspberry Pi 4B board.
+
+- **CPU:** Quad-core ARM Cortex-A72
+- **Interrupt Controller:** GIC400
+
+Supported Boards
+================
+
+.. toctree::
+ :glob:
+ :maxdepth: 1
+
+ boards/*/*
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index d5eae21baa..bc9acd8a90 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -109,6 +109,19 @@ config ARCH_CHIP_ZYNQ_MPSOC
---help---
XilinX ZYNQ MPSOC
+config ARCH_CHIP_BCM2711
+ bool "Broadcom BCM2711"
+ select ARCH_CORTEX_A72
+ select ARCH_HAVE_ADDRENV
+ select ARCH_HAVE_RESET
+ select ARCH_HAVE_IRQTRIGGER
+ select ARCH_NEED_ADDRENV_MAPPING
+ select ARCH_HAVE_MULTICPU
+ select ARCH_USE_MMU # Required for up_testset
+ select ARMV8A_HAVE_GICv2
+ ---help---
+ Broadcom BCM2711 quad-core ARM Cortex A72
+
config ARCH_CHIP_ARM64_CUSTOM
bool "Custom ARM64 chip"
select ARCH_CHIP_CUSTOM
@@ -312,6 +325,7 @@ config ARCH_CHIP
default "fvp-v8r" if ARCH_CHIP_FVP_ARMV8R
default "imx8" if ARCH_CHIP_IMX8
default "imx9" if ARCH_CHIP_IMX9
+ default "bcm2711" if ARCH_CHIP_BCM2711
config ARM64_HAVE_PSCI
bool "ARM PCSI (Power State Coordination Interface) Support"
@@ -351,7 +365,7 @@ config ARM64_DECODEFIQ
config ARM64_GIC_VERSION
int "GIC version"
- default 2 if ARCH_CHIP_A64
+ default 2 if ARCH_CHIP_A64 || ARCH_CHIP_BCM2711
default 3
range 2 4
---help---
@@ -474,4 +488,8 @@ if ARCH_CHIP_ZYNQ_MPSOC
source "arch/arm64/src/zynq-mpsoc/Kconfig"
endif
+if ARCH_CHIP_BCM2711
+source "arch/arm64/src/bcm2711/Kconfig"
+endif
+
endif # ARCH_ARM64
diff --git a/arch/arm64/include/bcm2711/chip.h b/arch/arm64/include/bcm2711/chip.h
new file mode 100644
index 0000000000..6b2eafe486
--- /dev/null
+++ b/arch/arm64/include/bcm2711/chip.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+ * arch/arm64/include/bcm2711/chip.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_INCLUDE_BCM2711_CHIP_H
+#define __ARCH_ARM64_INCLUDE_BCM2711_CHIP_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Number of bytes in x kilobytes/megabytes/gigabytes */
+
+#define KB(x) ((x) << 10)
+#define MB(x) (KB(x) << 10)
+#define GB(x) (MB(UINT64_C(x)) << 10)
+
+/* TODO: config option for low peripheral mode */
+
+/* TODO: config option for GIC400 interrupt controller or legacy one */
+
+/* GIC-400 base address.
+ * The GIC-400 uses GICv2 architecture.
+ */
+
+#if defined(CONFIG_BCM2711_LOW_PERIPHERAL)
+
+/* Low peripheral GIC address */
+
+#define BCM_GIC400_BASEADDR 0xff840000
+
+#else
+
+/* Used for both 35-bit addressing and legacy mode. */
+
+#define BCM_GIC400_BASEADDR 0x4c0040000
+
+#endif // defined(CONFIG_BCM2711_LOW_PERIPHERAL)
+
+#define BCM_GIC400_DISTOFFSET 0x00001000 /* Distributor */
+#define BCM_GIC400_RDISTOFFSET 0x00002000 /* CPU Interfaces */
+#define CONFIG_GICD_BASE (BCM_GIC400_BASEADDR + BCM_GIC400_DISTOFFSET)
+#define CONFIG_GICR_BASE (BCM_GIC400_BASEADDR + BCM_GIC400_RDISTOFFSET)
+#define CONFIG_GICR_OFFSET BCM_GIC400_RDISTOFFSET
+
+/* BCM2711 memory map: RAM and Device I/O
+ * TODO: verify and test against all variants (1, 2, 4 & 8GB)
+ */
+
+#define CONFIG_RAMBANK1_ADDR (0x000000000)
+
+/* Both the 4GB and 8GB ram variants use all the size in RAMBANK1 */
+
+#if defined(CONFIG_RPI4B_RAM_4GB) || defined(CONFIG_RPI4B_RAM_8GB)
+#define CONFIG_RAMBANK1_SIZE GB(4) - MB(64)
+#endif /* defined(CONFIG_RPI4B_RAM_4GB) || defined(CONFIG_RPI4B_RAM_8GB) */
+
+/* The 8GB version begins to use a second RAM bank.
+ * TODO: verify this works on 8GB
+ */
+
+#if defined(CONFIG_RPI4B_RAM_8GB)
+#define CONFIG_RAMBANK2_ADDR (0x100000000)
+#define CONFIG_RAMBANK2_SIZE GB(4)
+#endif /* defined(CONFIG_RPI4B_RAM_8GB) */
+
+/* TODO: for low peripheral mode this is valid, otherwise it might change */
+#define CONFIG_DEVICEIO_BASEADDR (0x0fc000000)
+#define CONFIG_DEVICEIO_SIZE MB(64)
+
+/* Raspberry Pi 4B loads NuttX at this address */
+
+#define CONFIG_LOAD_BASE 0x480000
+
+#define MPID_TO_CLUSTER_ID(mpid) ((mpid) & ~0xff)
+
+/****************************************************************************
+ * Assembly Macros
+ ****************************************************************************/
+
+#ifdef __ASSEMBLY__
+
+.macro get_cpu_id xreg0
+ mrs \xreg0, mpidr_el1
+ ubfx \xreg0, \xreg0, #0, #8
+.endm
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ARCH_ARM64_INCLUDE_BCM2711_CHIP_H */
diff --git a/arch/arm64/include/bcm2711/irq.h b/arch/arm64/include/bcm2711/irq.h
new file mode 100644
index 0000000000..1275fda79e
--- /dev/null
+++ b/arch/arm64/include/bcm2711/irq.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+ * arch/arm64/include/bcm2711/irq.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_IRQ_H
+#define __ARCH_ARM64_SRC_BCM2711_IRQ_H
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define NR_IRQS 216
+#define MPID_TO_CORE(mpid) (((mpid) >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK)
+
+/* ARMC interrupts */
+
+#define BCM_IRQ_ARMC_BASE 64
+#define BCM_IRQ_ARMC(n) (BCM_IRQ_ARMC_BASE + n)
+
+#define BCM_IRQ_ARMC_TIMER BCM_IRQ_ARMC(0) /* Timer */
+#define BCM_IRQ_ARMC_MAILBOX BCM_IRQ_ARMC(1) /* Mailbox */
+#define BCM_IRQ_ARMC_DOORBELL0 BCM_IRQ_ARMC(2) /* Doorbell 0 */
+#define BCM_IRQ_ARMC_DOORBELL1 BCM_IRQ_ARMC(3) /* Doorbell 1 */
+#define BCM_IRQ_ARMC_VPU0HALT BCM_IRQ_ARMC(4) /* VPU 0 halted */
+#define BCM_IRQ_ARMC_VPU1HALT BCM_IRQ_ARMC(5) /* VPU 1 halted */
+#define BCM_IRQ_ARMC_ARMADDRERR BCM_IRQ_ARMC(6) /* ARM address error */
+#define BCM_IRQ_ARMC_ARMAXIERR BCM_IRQ_ARMC(7) /* ARM AXI error */
+#define BCM_IRQ_ARMC_SWI0 BCM_IRQ_ARMC(8) /* Software interrupt 0 */
+#define BCM_IRQ_ARMC_SWI1 BCM_IRQ_ARMC(9) /* Software interrupt 1 */
+#define BCM_IRQ_ARMC_SWI2 BCM_IRQ_ARMC(10) /* Software interrupt 2 */
+#define BCM_IRQ_ARMC_SWI3 BCM_IRQ_ARMC(11) /* Software interrupt 3 */
+#define BCM_IRQ_ARMC_SWI4 BCM_IRQ_ARMC(12) /* Software interrupt 4 */
+#define BCM_IRQ_ARMC_SWI5 BCM_IRQ_ARMC(13) /* Software interrupt 5 */
+#define BCM_IRQ_ARMC_SWI6 BCM_IRQ_ARMC(14) /* Software interrupt 6 */
+#define BCM_IRQ_ARMC_SWI7 BCM_IRQ_ARMC(15) /* Software interrupt 7 */
+
+/* VideoCore interrupts */
+
+#define BCM_IRQ_VC_BASE 96
+#define BCM_IRQ_VC(n) (BCM_IRQ_VC_BASE + n)
+
+#define BCM_IRQ_VC_TIMER0 BCM_IRQ_VC(0)
+#define BCM_IRQ_VC_TIMER1 BCM_IRQ_VC(1)
+#define BCM_IRQ_VC_TIMER2 BCM_IRQ_VC(2)
+#define BCM_IRQ_VC_TIMER3 BCM_IRQ_VC(3)
+#define BCM_IRQ_VC_H2640 BCM_IRQ_VC(4)
+#define BCM_IRQ_VC_H2641 BCM_IRQ_VC(5)
+#define BCM_IRQ_VC_H2642 BCM_IRQ_VC(6)
+#define BCM_IRQ_VC_JPEG BCM_IRQ_VC(7)
+#define BCM_IRQ_VC_ISP BCM_IRQ_VC(8)
+#define BCM_IRQ_VC_USB BCM_IRQ_VC(9)
+#define BCM_IRQ_VC_V3D BCM_IRQ_VC(10)
+#define BCM_IRQ_VC_TRANSPOSE BCM_IRQ_VC(11)
+#define BCM_IRQ_VC_MCSYNC0 BCM_IRQ_VC(12)
+#define BCM_IRQ_VC_MCSYNC1 BCM_IRQ_VC(13)
+#define BCM_IRQ_VC_MCSYNC2 BCM_IRQ_VC(14)
+#define BCM_IRQ_VC_MCSYNC3 BCM_IRQ_VC(15)
+#define BCM_IRQ_VC_DMA0 BCM_IRQ_VC(16)
+#define BCM_IRQ_VC_DMA1 BCM_IRQ_VC(17)
+#define BCM_IRQ_VC_DMA2 BCM_IRQ_VC(18)
+#define BCM_IRQ_VC_DMA3 BCM_IRQ_VC(19)
+#define BCM_IRQ_VC_DMA4 BCM_IRQ_VC(20)
+#define BCM_IRQ_VC_DMA5 BCM_IRQ_VC(21)
+#define BCM_IRQ_VC_DMA6 BCM_IRQ_VC(22)
+#define BCM_IRQ_VC_DMA7N8 BCM_IRQ_VC(23)
+#define BCM_IRQ_VC_DMA9N10 BCM_IRQ_VC(24)
+#define BCM_IRQ_VC_DMA11 BCM_IRQ_VC(25)
+#define BCM_IRQ_VC_DMA12 BCM_IRQ_VC(26)
+#define BCM_IRQ_VC_DMA13 BCM_IRQ_VC(27)
+#define BCM_IRQ_VC_DMA14 BCM_IRQ_VC(28)
+#define BCM_IRQ_VC_AUX BCM_IRQ_VC(29)
+#define BCM_IRQ_VC_ARM BCM_IRQ_VC(30)
+#define BCM_IRQ_VC_DMA15 BCM_IRQ_VC(31)
+#define BCM_IRQ_VC_HDMICEC BCM_IRQ_VC(32)
+#define BCM_IRQ_VC_HVS BCM_IRQ_VC(33)
+#define BCM_IRQ_VC_RPIVID BCM_IRQ_VC(34)
+#define BCM_IRQ_VC_SDC BCM_IRQ_VC(35)
+#define BCM_IRQ_VC_DSI0 BCM_IRQ_VC(36)
+#define BCM_IRQ_VC_PIXVLV2 BCM_IRQ_VC(37)
+#define BCM_IRQ_VC_CAM0 BCM_IRQ_VC(38)
+#define BCM_IRQ_VC_CAM1 BCM_IRQ_VC(39)
+#define BCM_IRQ_VC_HDMI0 BCM_IRQ_VC(40)
+#define BCM_IRQ_VC_HDMI1 BCM_IRQ_VC(41)
+#define BCM_IRQ_VC_PIXVLV3 BCM_IRQ_VC(42)
+#define BCM_IRQ_VC_SPIBSCSLV BCM_IRQ_VC(43)
+#define BCM_IRQ_VC_DSI1 BCM_IRQ_VC(44)
+#define BCM_IRQ_VC_PXLVLV0 BCM_IRQ_VC(45)
+#define BCM_IRQ_VC_PXLVLV1N4 BCM_IRQ_VC(46)
+#define BCM_IRQ_VC_CPR BCM_IRQ_VC(47)
+#define BCM_IRQ_VC_SMI BCM_IRQ_VC(48)
+#define BCM_IRQ_VC_GPIO0 BCM_IRQ_VC(49)
+#define BCM_IRQ_VC_GPIO1 BCM_IRQ_VC(50)
+#define BCM_IRQ_VC_GPIO2 BCM_IRQ_VC(51)
+#define BCM_IRQ_VC_GPIO3 BCM_IRQ_VC(52)
+#define BCM_IRQ_VC_I2C BCM_IRQ_VC(53)
+#define BCM_IRQ_VC_SPI BCM_IRQ_VC(54)
+#define BCM_IRQ_VC_PCMI2S BCM_IRQ_VC(55)
+#define BCM_IRQ_VC_SDHOST BCM_IRQ_VC(56)
+#define BCM_IRQ_VC_PL011UART BCM_IRQ_VC(57)
+#define BCM_IRQ_VC_ETHPCIE BCM_IRQ_VC(58)
+#define BCM_IRQ_VC_VEC BCM_IRQ_VC(59)
+#define BCM_IRQ_VC_CPG BCM_IRQ_VC(60)
+#define BCM_IRQ_VC_RNG BCM_IRQ_VC(61)
+#define BCM_IRQ_VC_EMMC BCM_IRQ_VC(62)
+#define BCM_IRQ_VC_ETHPCIESEC BCM_IRQ_VC(63)
+
+/* TODO: what about PACTL_CS address section 6.2.4? */
+
+/* ETH_PCIe interrupts */
+
+#define BCM_IRQ_ETH_BASE 160
+#define BCM_IRQ_ETH(n) (BCM_IRQ_ETH_BASE + n)
+
+#define BCM_IRQ_ETH_AVS BCM_IRQ_ETH(9)
+#define BCM_IRQ_ETH_PCIE0_INTA BCM_IRQ_ETH(15)
+#define BCM_IRQ_ETH_PCIE0_INTB BCM_IRQ_ETH(16)
+#define BCM_IRQ_ETH_PCIE0_INTC BCM_IRQ_ETH(17)
+#define BCM_IRQ_ETH_PCIE0_INTD BCM_IRQ_ETH(18)
+#define BCM_IRQ_ETH_PCIE0_MSI BCM_IRQ_ETH(20)
+#define BCM_IRQ_ETH_GENET0_A BCM_IRQ_ETH(29)
+#define BCM_IRQ_ETH_GENET0_B BCM_IRQ_ETH(30)
+#define BCM_IRQ_ETH_USB0_XHCI0 BCM_IRQ_ETH(48)
+
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCEN_MAILBOX_CORE2_IRQ (1 << 5)
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCEN_MAILBOX_CORE3_IRQ (1 << 4)
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCEN_CNT_V_IRQ (1 << 3)
+
+#endif // __ARCH_ARM64_SRC_BCM2711_IRQ_H
diff --git a/arch/arm64/src/bcm2711/Kconfig b/arch/arm64/src/bcm2711/Kconfig
new file mode 100644
index 0000000000..0b9f667f4c
--- /dev/null
+++ b/arch/arm64/src/bcm2711/Kconfig
@@ -0,0 +1,122 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+if ARCH_CHIP_BCM2711
+
+comment "BCM2711 configuration options"
+
+#####################################################################
+# Peripheral selection
+#####################################################################
+
+menu "Broadcom BCM2711 Peripheral Selection"
+
+config BCM2711_LOW_PERIPHERAL
+ bool "BCM2711 Low Peripheral Mode"
+ default y
+ ---help---
+ Use the Broadcom BCM2711 in low peripheral addressing mode.
+
+#####################################################################
+# I2C Configuration (master)
+#####################################################################
+
+config BCM2711_I2C
+ bool "I2C Master"
+ select I2C
+ ---help---
+ Support for I2C in master mode.
+
+if BCM2711_I2C
+
+config BCM2711_I2C0
+ bool "I2C0"
+ default n
+ ---help---
+ Enable the I2C0 interface.
+ See board selection menu to configure the pins used by I2C0.
+
+config BCM2711_I2C1
+ bool "I2C1"
+ default n
+ ---help---
+ Enable the I2C1 interface.
+ See board selection menu to configure the pins used by I2C1.
+
+config BCM2711_I2C2
+ bool "I2C2"
+ default n
+ ---help---
+ Enable the I2C2 interface.
+ See board selection menu to configure the pins used by I2C2.
+
+config BCM2711_I2C3
+ bool "I2C3"
+ default n
+ ---help---
+ Enable the I2C3 interface.
+ See board selection menu to configure the pins used by I2C3.
+
+config BCM2711_I2C4
+ bool "I2C4"
+ default n
+ ---help---
+ Enable the I2C4 interface.
+ See board selection menu to configure the pins used by I2C4.
+
+config BCM2711_I2C5
+ bool "I2C5"
+ default n
+ ---help---
+ Enable the I2C5 interface.
+ See board selection menu to configure the pins used by I2C5.
+
+config BCM2711_I2C6
+ bool "I2C6"
+ default n
+ ---help---
+ Enable the I2C6 interface.
+ See board selection menu to configure the pins used by I2C6.
+
+config BCM2711_I2C_DRIVER
+ bool "I2C character driver"
+ default n
+ select I2C_DRIVER
+ ---help---
+ Support for the I2C character driver at /dev/i2c[N]. Can be used
+ for I2C bus transfers from application code. This driver is intended
+ for testing, not for use in any real driver application.
+
+endif # BCM2711_I2C
+
+#####################################################################
+# SPI Configuration
+#####################################################################
+
+config BCM2711_SPI
+ bool "SPI support"
+ select SPI
+ ---help---
+ Support for SPI interfaces.
+
+if BCM2711_SPI
+
+config BCM2711_SPI1
+ bool "SPI1"
+ default n
+ ---help---
+ Enable the SPI1 interface.
+
+config BCM2711_SPI2
+ bool "SPI2"
+ default n
+ ---help---
+ Enable the SPI2 interface.
+
+endif # BCM2711_SPI
+
+endmenu # Broadcom BCM2711 Peripheral Selection
+
+endif # ARCH_CHIP_BCM2711
diff --git a/arch/arm64/src/bcm2711/Make.defs b/arch/arm64/src/bcm2711/Make.defs
new file mode 100644
index 0000000000..fbb70dc0eb
--- /dev/null
+++ b/arch/arm64/src/bcm2711/Make.defs
@@ -0,0 +1,46 @@
+############################################################################
+# arch/arm64/src/bcm2711/Make.defs
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+include common/Make.defs
+
+# BCM2711 specific C source files
+
+CHIP_CSRCS += bcm2711_boot.c
+CHIP_CSRCS += bcm2711_serial.c
+CHIP_CSRCS += bcm2711_gpio.c
+CHIP_CSRCS += bcm2711_timer.c
+
+# Early boot logging
+
+ifeq ($(CONFIG_ARCH_EARLY_PRINT),y)
+CHIP_CSRCS += bcm2711_lowputc.c
+endif
+
+# I2C interfaces
+
+ifeq ($(CONFIG_BCM2711_I2C),y)
+CHIP_CSRCS += bcm2711_i2c.c
+endif
+
+# SPI interfaces
+#
+ifeq ($(CONFIG_BCM2711_SPI),y)
+CHIP_CSRCS += bcm2711_spi.c
+endif
diff --git a/arch/arm64/src/bcm2711/bcm2711_boot.c b/arch/arm64/src/bcm2711/bcm2711_boot.c
new file mode 100644
index 0000000000..5d64c54334
--- /dev/null
+++ b/arch/arm64/src/bcm2711/bcm2711_boot.c
@@ -0,0 +1,162 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/bcm2711_boot.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include
+#include
+
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "arm64_mmu.h"
+#include "bcm2711_boot.h"
+#include "bcm2711_serial.h"
+#include
+
+#ifdef CONFIG_SMP
+#include "arm64_smp.h"
+#endif
+
+#include
+#ifdef CONFIG_LEGACY_PAGING
+#include
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct arm_mmu_region g_mmu_regions[] =
+{
+ MMU_REGION_FLAT_ENTRY("DEVICE_REGION", CONFIG_DEVICEIO_BASEADDR,
+ CONFIG_DEVICEIO_SIZE,
+ MT_DEVICE_NGNRNE | MT_RW | MT_SECURE),
+
+ MMU_REGION_FLAT_ENTRY("DRAM0_S0", CONFIG_RAMBANK1_ADDR,
+ CONFIG_RAMBANK1_SIZE,
+ MT_NORMAL | MT_RW | MT_SECURE),
+
+ /* TODO: verify this works on the 8GB variant */
+
+#if defined(CONFIG_RPI4B_RAM_8GB)
+ MMU_REGION_FLAT_ENTRY("DRAM0_S1",
+ CONFIG_RAMBANK2_ADDR, CONFIG_RAMBANK2_SIZE,
+ MT_NORMAL | MT_RW | MT_SECURE),
+#endif /* defined(CONFIG_RPI4B_RAM_8GB) */
+};
+
+const struct arm_mmu_config g_mmu_config =
+{
+ .num_regions = nitems(g_mmu_regions),
+ .mmu_regions = g_mmu_regions,
+};
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+#ifdef CONFIG_SMP
+
+/****************************************************************************
+ * Name: arm64_get_mpid
+ *
+ * Description:
+ * The function from cpu index to get cpu mpid which is reading
+ * from mpidr_el1 register. Different ARM64 Core will use different
+ * Affn define, the mpidr_el1 value is not CPU number, So we need
+ * to change CPU number to mpid and vice versa
+ *
+ ****************************************************************************/
+
+uint64_t arm64_get_mpid(int cpu)
+{
+ return CORE_TO_MPID(cpu, 0);
+}
+
+/****************************************************************************
+ * Name: arm64_get_cpuid
+ *
+ * Description:
+ * The function from mpid to get cpu id
+ *
+ ****************************************************************************/
+
+int arm64_get_cpuid(uint64_t mpid)
+{
+ return MPID_TO_CORE(mpid);
+}
+
+#endif /* CONFIG_SMP */
+
+/****************************************************************************
+ * Name: arm64_el_init
+ *
+ * Description:
+ * The function called from arm64_head.S at very early stage for this
+ * platform. It's used to:
+ * - Handle special hardware initialization routines which need to
+ * run at high ELs
+ * - Initialize system software such as hypervisor or security firmware
+ * which needs to run at high ELs
+ *
+ ****************************************************************************/
+
+void arm64_el_init(void)
+{
+ /* TODO: what goes here? */
+}
+
+/****************************************************************************
+ * Name: arm64_chip_boot
+ *
+ * Description:
+ * Complete boot operations started in arm64_head.S
+ *
+ ****************************************************************************/
+
+void arm64_chip_boot(void)
+{
+ /* MAP IO and DRAM, enable MMU. */
+
+ arm64_mmu_init(true);
+
+#if defined(CONFIG_ARM64_PSCI)
+ arm64_psci_init("smc");
+
+#endif
+
+ /* Perform board-specific device initialization. This would include
+ * configuration of board specific resources such as GPIOs, LEDs, etc.
+ */
+
+ bcm2711_board_initialize();
+
+#ifdef USE_EARLYSERIALINIT
+ /* Perform early serial initialization if we are going to use the serial
+ * driver.
+ */
+
+ arm64_earlyserialinit();
+#endif
+}
diff --git a/arch/arm64/src/bcm2711/bcm2711_boot.h b/arch/arm64/src/bcm2711/bcm2711_boot.h
new file mode 100644
index 0000000000..431699cadd
--- /dev/null
+++ b/arch/arm64/src/bcm2711/bcm2711_boot.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/bcm2711_boot.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_BCM2711_BOOT_H
+#define __ARCH_ARM64_SRC_BCM2711_BCM2711_BOOT_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+/****************************************************************************
+ * Name: bcm2711_board_initialize
+ *
+ * Description:
+ * All BCM2711 architectures must provide the following entry point. This
+ * entry point is called in the initialization phase -- after
+ * bcm2711_memory_initialize and after all memory has been configured and
+ * mapped but before any devices have been initialized.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void bcm2711_board_initialize(void);
+
+#endif // __ASSEMBLY__
+
+#endif // __ARCH_ARM64_SRC_BCM2711_BCM2711_BOOT_H
diff --git a/arch/arm64/src/bcm2711/bcm2711_gpio.c b/arch/arm64/src/bcm2711/bcm2711_gpio.c
new file mode 100644
index 0000000000..f3c2e4d5e9
--- /dev/null
+++ b/arch/arm64/src/bcm2711/bcm2711_gpio.c
@@ -0,0 +1,664 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/bcm2711_gpio.c
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include "arm64_arch.h"
+#include "arm64_gic.h"
+#include "arm64_internal.h"
+#include "bcm2711_gpio.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Number of IRQs for GPIO interrupts */
+
+#define NUM_GPIO_IRQS (sizeof(g_gpio_irqs) / sizeof(g_gpio_irqs[0]))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* True if the primary interrupt handler (which call pin-specific handlers)
+ * has already been attached to GPIO 0-3 IRQs. False otherwise.
+ */
+
+static bool g_gpio_irqs_init = false;
+
+/* GPIO pin interrupt handler functions. */
+
+static xcpt_t g_gpio_pin_isrs[BCM_GPIO_NUM] =
+{
+ 0
+};
+
+/* Arguments to GPIO pin interrupt handlers. */
+
+static void *g_gpio_pin_isr_args[BCM_GPIO_NUM] =
+{
+ 0
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* TODO: Which GPIO pins are associated with VC IRQ 49 (GPIO 0), 50, 51 and
+ * 52?
+ */
+
+/* TODO: is it necessary to encode the alternate function possibilities for
+ * each pin in a lookup table?
+ */
+
+/* Mapping from function selection enum to BCM2711 function selection
+ * representation.
+ */
+
+static const uint8_t g_fsel_map[] =
+{
+ [BCM_GPIO_FUNC0] = BCM_GPIO_FS_ALT0, [BCM_GPIO_FUNC1] = BCM_GPIO_FS_ALT1,
+ [BCM_GPIO_FUNC2] = BCM_GPIO_FS_ALT2, [BCM_GPIO_FUNC3] = BCM_GPIO_FS_ALT3,
+ [BCM_GPIO_FUNC4] = BCM_GPIO_FS_ALT4, [BCM_GPIO_FUNC5] = BCM_GPIO_FS_ALT5,
+ [BCM_GPIO_INPUT] = BCM_GPIO_FS_IN, [BCM_GPIO_OUTPUT] = BCM_GPIO_FS_OUT,
+};
+
+/* IRQs for GPIO interrupts */
+
+static const uint32_t g_gpio_irqs[] =
+{
+ BCM_IRQ_VC_GPIO0,
+ BCM_IRQ_VC_GPIO1,
+ BCM_IRQ_VC_GPIO2,
+ BCM_IRQ_VC_GPIO3,
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static inline void bcm2711_gpio_help_set(uint32_t gpio, uint32_t reg1,
+ uint32_t reg2, bool val);
+static inline bool bcm2711_gpio_help_get(uint32_t gpio, uint32_t reg1,
+ uint32_t reg2);
+
+static int bcm2711_gpio_interrupt_handler(int irq, void *context, void *arg);
+static int bcm2711_gpio_irqs_init(void);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: bcm2711_gpio_help_set
+ *
+ * Description:
+ * Helper function for setting a GPIO pin value on the BCM2711 GPIO
+ * register where one register is for pins 0-31 and the second is pins
+ * 32-57.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set the value of.
+ * reg1 - The GPIO register for pins 0-31.
+ * reg2 - The GPIO register for pins 0-33.
+ * val - The value to set (true for 1, false for 0).
+ *
+ ****************************************************************************/
+
+static inline void bcm2711_gpio_help_set(uint32_t gpio, uint32_t reg1,
+ uint32_t reg2, bool val)
+{
+ /* Choose appropriate bit and register */
+
+ uint32_t bitmask;
+ uint32_t reg;
+
+ if (gpio <= 31)
+ {
+ bitmask = (1 << gpio);
+ reg = reg1;
+ }
+ else
+ {
+ bitmask = (1 << (gpio - 32));
+ reg = reg2;
+ }
+
+ /* Set or clear bit */
+
+ if (val)
+ {
+ modreg32(bitmask, bitmask, reg);
+ }
+ else
+ {
+ modreg32(0, bitmask, reg);
+ }
+}
+
+/****************************************************************************
+ * Name: bcm2711_gpio_help_get
+ *
+ * Description:
+ * Helper function for reading a GPIO pin value on the BCM2711 GPIO
+ * register where one register is for pins 0-31 and the second is pins
+ * 32-57.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to get the value of.
+ * reg1 - The GPIO register for pins 0-31.
+ * reg2 - The GPIO register for pins 0-33.
+ *
+ ****************************************************************************/
+
+static inline bool bcm2711_gpio_help_get(uint32_t gpio, uint32_t reg1,
+ uint32_t reg2)
+{
+ /* Choose appropriate bit and register */
+
+ uint32_t bitmask;
+ uint32_t reg;
+
+ if (gpio <= 31)
+ {
+ bitmask = (1 << gpio);
+ reg = reg1;
+ }
+ else
+ {
+ bitmask = (1 << (gpio - 32));
+ reg = reg2;
+ }
+
+ return getreg32(reg) & bitmask;
+}
+
+/****************************************************************************
+ * Name: bcm2711_gpio_interrupt_handler
+ *
+ * Description:
+ * Interrupt handler for GPIO 1, GPIO 2 and GPIO 3 IRQs.
+ *
+ * Input parameters:
+ * irq - The IRQ number
+ * context - The interrupt context.
+ * arg - The argument passed to the interrupt handler.
+ *
+ ****************************************************************************/
+
+static int bcm2711_gpio_interrupt_handler(int irq, void *context, void *arg)
+{
+ /* TODO: depending on irq number, decide which GPIO handlers to search
+ * through and call
+ */
+
+ /* TODO: test interrupt handling */
+
+ xcpt_t isr;
+
+ /* Since I don't know which IRQ corresponds to which GPIO pins, for now
+ * I'll search all 58 GPIOs on an interrupt
+ */
+
+ for (uint32_t gpio = 0; gpio < BCM_GPIO_NUM; gpio++)
+ {
+ isr = g_gpio_pin_isrs[gpio];
+ if (bcm2711_gpio_event_get(gpio) && isr != NULL)
+ {
+ isr(gpio, context, g_gpio_pin_isr_args[gpio]);
+ }
+ }
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: bcm2711_gpio_irqs_init
+ *
+ * Description:
+ * Attach the primary GPIO interrupt handler to GPIO 0, 1, 2 and 3 IRQs.
+ *
+ * Returns:
+ * 0 if successful, negated errno otherwise.
+ *
+ ****************************************************************************/
+
+static int bcm2711_gpio_irqs_init(void)
+{
+ int err;
+
+ /* Attach all interrupt handlers for primary IRQs. */
+
+ for (int i = 0; i < NUM_GPIO_IRQS; i++)
+ {
+ err = irq_attach(g_gpio_irqs[i], bcm2711_gpio_interrupt_handler, NULL);
+ if (err) return err;
+ }
+
+ /* Enable all GPIO IRQs. */
+
+ for (int i = 0; i < NUM_GPIO_IRQS; i++)
+ {
+ up_enable_irq(g_gpio_irqs[i]);
+ arm64_gic_irq_set_priority(g_gpio_irqs[i], 0, IRQ_TYPE_LEVEL);
+ }
+
+ /* Mark as initialized. */
+
+ g_gpio_irqs_init = true;
+ return 0;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: bcm2711_gpio_set_pulls
+ *
+ * Description:
+ * Set the specified GPIO pin to have pull up, pull down or no
+ * resistor. With both `up` and `down` as false, the resistor will be set
+ * to none. It is not possible to set both pull-up and pull-down.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set the resistors on.
+ * up - True to set pull-up resistor, false otherwise.
+ * down - True to set pull-down resistor, false otherwise.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_set_pulls(uint32_t gpio, bool up, bool down)
+{
+ DEBUGASSERT(gpio < BCM_GPIO_NUM);
+ DEBUGASSERT(!(up && down)); /* Not valid to set pull-up and pull-down */
+
+ /* Pick direction. */
+
+ uint32_t direction = 0;
+ if (up)
+ {
+ direction = BCM_GPIO_PULLUP;
+ }
+ else if (down)
+ {
+ direction = BCM_GPIO_PULLDOWN;
+ }
+ else
+ {
+ direction = BCM_GPIO_NORES;
+ }
+
+ /* Set GPIO pin resistor. */
+
+ uint32_t value = 0;
+ if (gpio <= 15)
+ {
+ value = (direction << (gpio * 2));
+ modreg32(value, value, BCM_GPIO_PUP_PDN_CNTRL_REG0);
+ }
+ else if (gpio <= 31 && gpio > 15)
+ {
+ value = (direction << ((gpio - 16) * 2));
+ modreg32(value, value, BCM_GPIO_PUP_PDN_CNTRL_REG1);
+ }
+ else if (gpio <= 47 && gpio > 31)
+ {
+ value = (direction << ((gpio - 32) * 2));
+ modreg32(value, value, BCM_GPIO_PUP_PDN_CNTRL_REG2);
+ }
+ else if (gpio <= 57 && gpio > 47)
+ {
+ value = (direction << ((gpio - 48) * 2));
+ modreg32(value, value, BCM_GPIO_PUP_PDN_CNTRL_REG3);
+ }
+}
+
+/****************************************************************************
+ * Name: bcm2711_gpio_set_func
+ *
+ * Description:
+ * Set the specified GPIO pin to be input, output or use one of its
+ * alternative functions.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set the function of.
+ * func - The function to set the GPIO pin to use.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_set_func(uint32_t gpio, enum bcm2711_gpio_func_e func)
+{
+ DEBUGASSERT(gpio < BCM_GPIO_NUM);
+
+ uint32_t value = 0;
+ if (gpio <= 9)
+ {
+ value = (g_fsel_map[func] << (gpio * 3));
+ modreg32(value, value, BCM_GPIO_GPFSEL0);
+ }
+ else if (gpio <= 19 && gpio > 9)
+ {
+ value = (g_fsel_map[func] << ((gpio - 10) * 3));
+ modreg32(value, value, BCM_GPIO_GPFSEL1);
+ }
+ else if (gpio <= 29 && gpio > 20)
+ {
+ value = (g_fsel_map[func] << ((gpio - 20) * 3));
+ modreg32(value, value, BCM_GPIO_GPFSEL2);
+ }
+ else if (gpio <= 39 && gpio > 30)
+ {
+ value = (g_fsel_map[func] << ((gpio - 30) * 3));
+ modreg32(value, value, BCM_GPIO_GPFSEL3);
+ }
+ else if (gpio <= 49 && gpio > 40)
+ {
+ value = (g_fsel_map[func] << ((gpio - 40) * 3));
+ modreg32(value, value, BCM_GPIO_GPFSEL4);
+ }
+ else if (gpio <= 57 && gpio > 50)
+ {
+ value = (g_fsel_map[func] << ((gpio - 50) * 3));
+ modreg32(value, value, BCM_GPIO_GPFSEL5);
+ }
+}
+
+/****************************************************************************
+ * Name: bcm2711_gpio_pin_set
+ *
+ * Description:
+ * Set the output of a GPIO output pin to high or low.
+ * Calling this function on a GPIO pin set as an input does nothing.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set high or low.
+ * high - True to set the pin high, false to set the pin low.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_pin_set(uint32_t gpio, bool set)
+{
+ DEBUGASSERT(gpio < BCM_GPIO_NUM);
+
+ if (set)
+ {
+ bcm2711_gpio_help_set(gpio, BCM_GPIO_GPSET0, BCM_GPIO_GPSET0, true);
+ }
+ else
+ {
+ bcm2711_gpio_help_set(gpio, BCM_GPIO_GPCLR0, BCM_GPIO_GPCLR0, true);
+ }
+}
+
+/****************************************************************************
+ * Name: bcm2711_gpio_pin_get
+ *
+ * Description:
+ * Get the current value of the GPIO.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set high or low.
+ *
+ * Return:
+ * True for high, false for low.
+ *
+ ****************************************************************************/
+
+bool bcm2711_gpio_pin_get(uint32_t gpio)
+{
+ DEBUGASSERT(gpio < BCM_GPIO_NUM);
+
+ if (gpio <= 31)
+ {
+ return getreg32(BCM_GPIO_GPLEV0) & (1 << gpio);
+ }
+ else
+ {
+ return getreg32(BCM_GPIO_GPLEV1) & (1 << (gpio - 32));
+ }
+}
+
+/****************************************************************************
+ * Name: bcm2711_gpio_event_get
+ *
+ * Description:
+ * Check if an event was detected for the given GPIO pin.
+ * The event bit will be set if an event has happened that matches the
+ * event detection configuration for the given pin (rising edge, falling
+ * edge, level).
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to check for an event.
+ *
+ * Return:
+ * True if an event was detected, false otherwise.
+ *
+ ****************************************************************************/
+
+bool bcm2711_gpio_event_get(uint32_t gpio)
+{
+ DEBUGASSERT(gpio < BCM_GPIO_NUM);
+ return bcm2711_gpio_help_get(gpio, BCM_GPIO_GPEDS0, BCM_GPIO_GPEDS1);
+}
+
+/****************************************************************************
+ * Name: bcm2711_gpio_event_clear
+ *
+ * Description:
+ * Clear the event detect status for the given GPIO pin.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to clear the event status of.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_event_clear(uint32_t gpio)
+{
+ DEBUGASSERT(gpio < BCM_GPIO_NUM);
+ bcm2711_gpio_help_set(gpio, BCM_GPIO_GPEDS0, BCM_GPIO_GPEDS1, false);
+}
+
+/****************************************************************************
+ * Name: bcm2711_gpio_rising_edge
+ *
+ * Description:
+ * Set/clear rising edge event detection for the given GPIO pin.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set the event detection of.
+ * set - True to set, false to clear.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_rising_edge(uint32_t gpio, bool set)
+{
+ DEBUGASSERT(gpio < BCM_GPIO_NUM);
+ bcm2711_gpio_help_set(gpio, BCM_GPIO_GPREN0, BCM_GPIO_GPREN1, set);
+}
+
+/****************************************************************************
+ * Name: bcm2711_gpio_falling_edge
+ *
+ * Description:
+ * Set/clear falling edge event detection for the given GPIO pin.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set the event detection of.
+ * set - True to set, false to clear.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_falling_edge(uint32_t gpio, bool set)
+{
+ DEBUGASSERT(gpio < BCM_GPIO_NUM);
+ bcm2711_gpio_help_set(gpio, BCM_GPIO_GPFEN0, BCM_GPIO_GPFEN1, set);
+}
+
+/****************************************************************************
+ * Name: bcm2711_gpio_high_level
+ *
+ * Description:
+ * Set/clear high level event detection for the given GPIO pin.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set the event detection of.
+ * set - True to set, false to clear.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_high_level(uint32_t gpio, bool set)
+{
+ DEBUGASSERT(gpio < BCM_GPIO_NUM);
+ bcm2711_gpio_help_set(gpio, BCM_GPIO_GPHEN0, BCM_GPIO_GPHEN1, set);
+}
+
+/****************************************************************************
+ * Name: bcm2711_gpio_low_level
+ *
+ * Description:
+ * Set/clear low level event detection for the given GPIO pin.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set the event detection of.
+ * set - True to set, false to clear.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_low_level(uint32_t gpio, bool set)
+{
+ DEBUGASSERT(gpio < BCM_GPIO_NUM);
+ bcm2711_gpio_help_set(gpio, BCM_GPIO_GPLEN0, BCM_GPIO_GPLEN1, set);
+}
+
+/****************************************************************************
+ * Name: bcm2711_gpio_rising_edge_async
+ *
+ * Description:
+ * Set/clear async rising edge event detection for the given GPIO pin.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set the event detection of.
+ * set - True to set, false to clear.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_rising_edge_async(uint32_t gpio, bool set)
+{
+ DEBUGASSERT(gpio < BCM_GPIO_NUM);
+ bcm2711_gpio_help_set(gpio, BCM_GPIO_GPAREN0, BCM_GPIO_GPAREN1, set);
+}
+
+/****************************************************************************
+ * Name: bcm2711_gpio_falling_edge_async
+ *
+ * Description:
+ * Set/clear async falling edge event detection for the given GPIO pin.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set the event detection of.
+ * set - True to set, false to clear.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_falling_edge_async(uint32_t gpio, bool set)
+{
+ DEBUGASSERT(gpio < BCM_GPIO_NUM);
+ bcm2711_gpio_help_set(gpio, BCM_GPIO_GPAFEN0, BCM_GPIO_GPAFEN1, set);
+}
+
+/****************************************************************************
+ * Name: bcm2711_gpio_irq_attach
+ *
+ * Description:
+ * Attach an interrupt handler for the specified GPIO pin.
+ * NOTE: Interrupt mode (rising edge, falling edge, etc.) is configured
+ * separately. Once configured, the IRQ is enabled for that event type.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to attach the handler for.
+ * isr - The interrupt handler function.
+ * arg - The argument to be passed to the interrupt handler.
+ *
+ ****************************************************************************/
+
+int bcm2711_gpio_irq_attach(uint32_t gpio, xcpt_t isr, void *arg)
+{
+ DEBUGASSERT(gpio < BCM_GPIO_NUM);
+ int ret = 0;
+
+ /* If primary interrupt handler has not been attached to IRQs yet, do that
+ * first.
+ */
+
+ if (!g_gpio_irqs_init)
+ {
+ ret = bcm2711_gpio_irqs_init();
+ if (ret < 0) return ret; /* Early return if primary attach failed. */
+ }
+
+ /* Save handler information for this pin. */
+
+ g_gpio_pin_isrs[gpio] = isr;
+ g_gpio_pin_isr_args[gpio] = arg;
+
+ /* Clear pending interrupts for this pin. */
+
+ bcm2711_gpio_event_clear(gpio);
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: bcm2711_gpio_irq_detach
+ *
+ * Description:
+ * Detach an interrupt handler for a GPIO pin. NOTE: this does not disable
+ * interrupts for that particular pin; this must be done by disabling event
+ * detection for that pin separately.
+ * This function just detaches the pin's ISR, ensuring it won't be called
+ * when an interrupt is triggered.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to detach the handler of.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_irq_detach(uint32_t gpio)
+{
+ DEBUGASSERT(gpio < BCM_GPIO_NUM);
+ g_gpio_pin_isrs[gpio] = NULL;
+ g_gpio_pin_isr_args[gpio] = NULL;
+}
diff --git a/arch/arm64/src/bcm2711/bcm2711_gpio.h b/arch/arm64/src/bcm2711/bcm2711_gpio.h
new file mode 100644
index 0000000000..d30de4326c
--- /dev/null
+++ b/arch/arm64/src/bcm2711/bcm2711_gpio.h
@@ -0,0 +1,277 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/bcm2711_gpio.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_BCM2711_GPIO_H
+#define __ARCH_ARM64_SRC_BCM2711_BCM2711_GPIO_H
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "hardware/bcm2711_gpio.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* Possible functions for the BCM2711 GPIO pins */
+
+enum bcm2711_gpio_func_e
+{
+ BCM_GPIO_FUNC0 = 0, /* Alternative function 0 */
+ BCM_GPIO_FUNC1 = 1, /* Alternative function 1 */
+ BCM_GPIO_FUNC2 = 2, /* Alternative function 2 */
+ BCM_GPIO_FUNC3 = 3, /* Alternative function 3 */
+ BCM_GPIO_FUNC4 = 4, /* Alternative function 4 */
+ BCM_GPIO_FUNC5 = 5, /* Alternative function 5 */
+ BCM_GPIO_INPUT = 6, /* Input */
+ BCM_GPIO_OUTPUT = 7, /* Output */
+};
+
+/****************************************************************************
+ * Name: bcm2711_gpio_set_pulls
+ *
+ * Description:
+ * Set the specified GPIO pin to have pull up, pull down or no resistor.
+ * With both `up` and `down` as false, the resistor will be set to none.
+ * It is not possible to set both pull-up and pull-down.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set the resistors on.
+ * up - True to set pull-up resistor, false otherwise.
+ * down - True to set pull-down resistor, false otherwise.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_set_pulls(uint32_t gpio, bool up, bool down);
+
+/****************************************************************************
+ * Name: bcm2711_gpio_set_func
+ *
+ * Description:
+ * Set the specified GPIO pin to be input, output or use one of its
+ * alternative functions.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set the function of.
+ * func - The function to set the GPIO pin to use.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_set_func(uint32_t gpio, enum bcm2711_gpio_func_e func);
+
+/****************************************************************************
+ * Name: bcm2711_gpio_pin_set
+ *
+ * Description:
+ * Set the output of a GPIO output pin to high or low.
+ * Calling this function on a GPIO pin set as an input does nothing.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set high or low.
+ * high - True to set the pin high, false to set the pin low.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_pin_set(uint32_t gpio, bool set);
+
+/****************************************************************************
+ * Name: bcm2711_gpio_pin_get
+ *
+ * Description:
+ * Get the current value of the GPIO.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set high or low.
+ *
+ * Return:
+ * True for high, false for low.
+ *
+ ****************************************************************************/
+
+bool bcm2711_gpio_pin_get(uint32_t gpio);
+
+/****************************************************************************
+ * Name: bcm2711_gpio_event_get
+ *
+ * Description:
+ * Check if an event was detected for the given GPIO pin.
+ * The event bit will be set if an event has happened that matches the
+ * event detection configuration for the given pin (rising edge,
+ * falling edge, level).
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to check for an event.
+ *
+ * Return:
+ * True if an event was detected, false otherwise.
+ *
+ ****************************************************************************/
+
+bool bcm2711_gpio_event_get(uint32_t gpio);
+
+/****************************************************************************
+ * Name: bcm2711_gpio_event_clear
+ *
+ * Description:
+ * Clear the event detect status for the given GPIO pin.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to clear the event status of.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_event_clear(uint32_t gpio);
+
+/****************************************************************************
+ * Name: bcm2711_gpio_rising_edge
+ *
+ * Description:
+ * Set/clear rising edge event detection for the given GPIO pin.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set the event detection of.
+ * set - True to set, false to clear.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_rising_edge(uint32_t gpio, bool set);
+
+/****************************************************************************
+ * Name: bcm2711_gpio_falling_edge
+ *
+ * Description:
+ * Set/clear falling edge event detection for the given GPIO pin.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set the event detection of.
+ * set - True to set, false to clear.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_falling_edge(uint32_t gpio, bool set);
+
+/****************************************************************************
+ * Name: bcm2711_gpio_high_level
+ *
+ * Description:
+ * Set/clear high level event detection for the given GPIO pin.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set the event detection of.
+ * set - True to set, false to clear.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_high_level(uint32_t gpio, bool set);
+
+/****************************************************************************
+ * Name: bcm2711_gpio_low_level
+ *
+ * Description:
+ * Set/clear low level event detection for the given GPIO pin.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set the event detection of.
+ * set - True to set, false to clear.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_low_level(uint32_t gpio, bool set);
+
+/****************************************************************************
+ * Name: bcm2711_gpio_rising_edge_async
+ *
+ * Description:
+ * Set/clear async rising edge event detection for the given GPIO pin.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set the event detection of.
+ * set - True to set, false to clear.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_rising_edge_async(uint32_t gpio, bool set);
+
+/****************************************************************************
+ * Name: bcm2711_gpio_falling_edge_async
+ *
+ * Description:
+ * Set/clear async falling edge event detection for the given GPIO pin.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to set the event detection of.
+ * set - True to set, false to clear.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_falling_edge_async(uint32_t gpio, bool set);
+
+/****************************************************************************
+ * Name: bcm2711_gpio_irq_attach
+ *
+ * Description:
+ * Attach an interrupt handler for the specified GPIO pin.
+ * NOTE: Interrupt mode (rising edge, falling edge, etc.) is configured
+ * separately.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to attach the handler for.
+ * isr - The interrupt handler function.
+ * arg - The argument to be passed to the interrupt handler.
+ *
+ ****************************************************************************/
+
+int bcm2711_gpio_irq_attach(uint32_t gpio, xcpt_t isr, void *arg);
+
+/****************************************************************************
+ * Name: bcm2711_gpio_irq_detach
+ *
+ * Description:
+ * Detach an interrupt handler for a GPIO pin. NOTE: this does not disable
+ * interrupts for that particular pin; this must be done by disabling event
+ * detection for that pin separately.
+ * This function just detaches the pin's ISR, ensuring it won't be called
+ * when an interrupt is triggered.
+ *
+ * Input parameters:
+ * gpio - The GPIO pin number to detach the handler of.
+ *
+ ****************************************************************************/
+
+void bcm2711_gpio_irq_detach(uint32_t gpio);
+
+#endif /* __ARCH_ARM64_SRC_BCM2711_BCM2711_GPIO_H */
diff --git a/arch/arm64/src/bcm2711/bcm2711_i2c.c b/arch/arm64/src/bcm2711/bcm2711_i2c.c
new file mode 100644
index 0000000000..9a9edc60e3
--- /dev/null
+++ b/arch/arm64/src/bcm2711/bcm2711_i2c.c
@@ -0,0 +1,1108 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/bcm2711_i2c.c
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include "arm64_arch.h"
+#include "arm64_gic.h"
+#include "bcm2711_gpio.h"
+#include "bcm2711_i2c.h"
+#include "chip.h"
+#include "hardware/bcm2711_bsc.h"
+
+#if defined(CONFIG_BCM2711_I2C)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Timeout duration in ms for transfers waiting on interrupt handler. */
+
+#define I2C_TIMEOUT_MS 50
+
+/* Default bus frequency at 400kbps. */
+
+#define I2C_DEFAULT_FREQUENCY 400000
+
+/* Core clock nominal frequency in Hz */
+
+#define CORE_CLOCK_FREQUENCY 150000000
+
+/* Get divisor for desired I2C bus frequency */
+
+#define CLK_DIVISOR(freq) (CORE_CLOCK_FREQUENCY / (freq))
+
+/* The FIFO buffer length of the I2C interfaces */
+
+#define FIFO_DEPTH 16
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* BCM2711 I2C device. */
+
+struct bcm2711_i2cdev_s
+{
+ struct i2c_master_s dev; /* Generic I2C device */
+ uint32_t base; /* Base address of I2C interface */
+ uint8_t port; /* Port number */
+
+ mutex_t lock; /* Exclusive access */
+ sem_t wait; /* Wait for transfer completion */
+ uint32_t frequency; /* I2C bus frequency */
+
+ struct i2c_msg_s *msgs; /* Messages to send */
+ size_t reg_buff_offset; /* Offset into message buffer */
+ uint8_t rw_size; /* max(FIFO_DEPTH, remaining message size) */
+ bool done; /* If `wait` was posted due to done condition. */
+
+ int err; /* Error status of transfers */
+ int refs; /* Reference count */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int bcm2711_i2c_semtimedwait(struct bcm2711_i2cdev_s *priv,
+ uint32_t ms);
+static void bcm2711_i2c_clearfifos(struct bcm2711_i2cdev_s *priv);
+static void bcm2711_i2c_setfrequency(struct bcm2711_i2cdev_s *priv,
+ uint32_t frequency);
+static void bcm2711_i2c_setaddr(struct bcm2711_i2cdev_s *priv,
+ uint16_t addr);
+static void bcm2711_i2c_starttransfer(struct bcm2711_i2cdev_s *priv);
+static int bcm2711_i2c_interrupted(struct bcm2711_i2cdev_s *priv);
+static void bcm2711_i2c_disable(struct bcm2711_i2cdev_s *priv);
+static void bcm2711_i2c_enable(struct bcm2711_i2cdev_s *priv);
+static void bcm2711_i2c_drainrxfifo(struct bcm2711_i2cdev_s *priv);
+static int bcm2711_i2c_send(struct bcm2711_i2cdev_s *priv, bool stop);
+static int bcm2711_i2c_receive(struct bcm2711_i2cdev_s *priv, bool stop);
+
+static int bcm2711_i2c_secondary_handler(struct bcm2711_i2cdev_s *priv);
+
+static int bcm2711_i2c_transfer(struct i2c_master_s *dev,
+ struct i2c_msg_s *msgs, int count);
+#ifdef CONFIG_I2C_RESET
+static int bcm2711_i2c_reset(struct i2c_master_s *dev);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* True if the IRQ for all I2C interrupts has been set up. */
+
+static bool g_i2c_irqinit = false;
+
+/* The number of I2C interfaces currently initialized. */
+
+static uint8_t g_i2c_devsinit = 0;
+
+/* I2C operations for BCM2711 I2C interfaces. */
+
+struct i2c_ops_s bcm2711_i2c_ops =
+{
+ .transfer = bcm2711_i2c_transfer,
+#if defined(CONFIG_I2C_RESET)
+ .reset = bcm2711_i2c_reset,
+#endif // defined(CONFIG_I2C_RESET)
+};
+
+#ifdef CONFIG_BCM2711_I2C1
+
+/* I2C1 interface. */
+
+static struct bcm2711_i2cdev_s g_i2c1dev =
+{
+ .base = BCM_BSC1,
+ .lock = NXMUTEX_INITIALIZER,
+ .wait = SEM_INITIALIZER(0),
+ .port = 1,
+ .refs = 0,
+ .err = 0,
+ .done = false,
+};
+
+#endif // CONFIG_BCM2711_I2C1
+
+/* I2C interfaces */
+
+static struct bcm2711_i2cdev_s *g_i2c_devices[BCM_BSCS_NUM] =
+{
+#ifdef CONFIG_BCM2711_I2C0
+#warning "I2C0 unsupported"
+#else
+ [0] = NULL,
+#endif // CONFIG_BCM2711_I2C0
+
+#ifdef CONFIG_BCM2711_I2C1
+ [1] = &g_i2c1dev,
+#else
+ [1] = NULL,
+#endif // CONFIG_BCM2711_I2C1
+
+#ifdef CONFIG_BCM2711_I2C2
+#warning "I2C2 unsupported"
+#else
+ [2] = NULL,
+#endif // CONFIG_BCM2711_I2C2
+
+#ifdef CONFIG_BCM2711_I2C3
+#warning "I2C3 unsupported"
+#else
+ [3] = NULL,
+#endif // CONFIG_BCM2711_I2C3
+
+#ifdef CONFIG_BCM2711_I2C4
+#warning "I2C4 unsupported"
+#else
+ [4] = NULL,
+#endif // CONFIG_BCM2711_I2C4
+
+#ifdef CONFIG_BCM2711_I2C5
+#warning "I2C5 unsupported"
+#else
+ [5] = NULL,
+#endif // CONFIG_BCM2711_I2C5
+
+#ifdef CONFIG_BCM2711_I2C6
+#warning "I2C6 unsupported"
+#else
+ [6] = NULL,
+#endif // CONFIG_BCM2711_I2C6
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/* TODO: remove */
+
+static void bcm2711_i2c_print(struct bcm2711_i2cdev_s *priv)
+{
+ i2cerr("Port: %d\n", priv->port);
+ i2cerr("Err: %d\n", priv->err);
+ i2cerr("Refs: %d\n", priv->refs);
+ i2cerr("Done: %s\n", priv->done ? "true" : "false");
+ int val;
+ nxsem_get_value(&priv->wait, &val);
+ i2cerr("Semaphore: %d\n", val);
+ i2cerr("Frequency: %d\n", priv->frequency);
+ i2cerr("Cur msg: %p\n", priv->msgs);
+ if (priv->msgs != NULL)
+ {
+ i2cerr("Cur msg len: %ld\n", priv->msgs->length);
+ }
+}
+
+/****************************************************************************
+ * Name: bcm2711_i2c_semtimedwait
+ *
+ * Description:
+ * Wait on the I2C interface semaphore for a given number of milliseconds.
+ *
+ * Input Parameters:
+ * priv - The BCM2711 I2C interface to wait on.
+ * ms - The number of milliseconds before timeout
+ *
+ * Returns:
+ * 0 for success, negated errno otherwise.
+ *
+ ****************************************************************************/
+
+static int bcm2711_i2c_semtimedwait(struct bcm2711_i2cdev_s *priv,
+ uint32_t ms)
+{
+ struct timespec future;
+ int ret = 0;
+
+ ret = clock_gettime(CLOCK_REALTIME, &future);
+ if (ret < 0)
+ {
+ i2cerr("Timed wait failed on I2C%u.\n", priv->port);
+ return ret;
+ }
+
+ future.tv_sec += (ms / 1000);
+ future.tv_nsec += ((ms % 1000) * 1000);
+
+ return nxsem_timedwait_uninterruptible(&priv->wait, &future);
+}
+
+/****************************************************************************
+ * Name: bcm2711_i2c_clearfifos
+ *
+ * Description:
+ * Clear the FIFOs of the I2C interface.
+ *
+ * Input Parameters:
+ * priv - The BCM2711 I2C interface to clear the FIFOs of.
+ *
+ ****************************************************************************/
+
+static void bcm2711_i2c_clearfifos(struct bcm2711_i2cdev_s *priv)
+{
+ modreg32(0, BCM_BSC_C_CLRFIFO, BCM_BSC_C(priv->base));
+}
+
+/****************************************************************************
+ * Name: bcm2711_i2c_setfrequency
+ *
+ * Description:
+ * Set the frequency for the next transfer.
+ *
+ * Input Parameters:
+ * priv - The BCM2711 I2C interface to set the frequency of.
+ * frequency - The new frequency.
+ *
+ ****************************************************************************/
+
+static void bcm2711_i2c_setfrequency(struct bcm2711_i2cdev_s *priv,
+ uint32_t frequency)
+{
+ putreg32(CLK_DIVISOR(frequency), BCM_BSC_DIV(priv->base));
+ priv->frequency = frequency;
+}
+
+/****************************************************************************
+ * Name: bcm2711_i2c_setaddr
+ *
+ * Description:
+ * Set the slave address for the next transfer.
+ *
+ * Input Parameters:
+ * priv - The BCM2711 I2C interface to set the slave address on.
+ * addr - The slave address.
+ *
+ ****************************************************************************/
+
+static void bcm2711_i2c_setaddr(struct bcm2711_i2cdev_s *priv, uint16_t addr)
+{
+ /* TODO: handle 10-bit addresses */
+
+ putreg32(addr & 0x7f, BCM_BSC_A(priv->base));
+}
+
+/****************************************************************************
+ * Name: bcm2711_i2c_starttransfer
+ *
+ * Description:
+ * Start the next transfer.
+ *
+ * Input Parameters:
+ * priv - The BCM2711 I2C interface to start the transfer on.
+ *
+ ****************************************************************************/
+
+static void bcm2711_i2c_starttransfer(struct bcm2711_i2cdev_s *priv)
+{
+ i2cinfo("Transfer started\n");
+ modreg32(BCM_BSC_C_ST, BCM_BSC_C_ST, BCM_BSC_C(priv->base));
+}
+
+/****************************************************************************
+ * Name: bcm2711_i2c_interrupted
+ *
+ * Description:
+ * Checks if the I2C device has a pending interrupt.
+ *
+ * Input Parameters:
+ * priv - The BCM2711 I2C interface to check for a pending interrupt.
+ *
+ * Returns:
+ * 0 if no interrupt pending, non-zero if interrupt pending.
+ *
+ ****************************************************************************/
+
+static int bcm2711_i2c_interrupted(struct bcm2711_i2cdev_s *priv)
+{
+ return getreg32(BCM_BSC_S(priv->base)) &
+ (BCM_BSC_S_DONE | BCM_BSC_S_RXR | BCM_BSC_S_TXW);
+}
+
+/****************************************************************************
+ * Name: bcm2711_i2c_disable
+ *
+ * Description:
+ * Disable the I2C interface.
+ *
+ * Input Parameters:
+ * priv - The BCM2711 I2C interface to disable.
+ *
+ ****************************************************************************/
+
+static void bcm2711_i2c_disable(struct bcm2711_i2cdev_s *priv)
+{
+ i2cinfo("Disabled I2C%u\n", priv->port);
+
+ /* Disable interrupts */
+
+ modreg32(0, BCM_BSC_C_INTD, BCM_BSC_C(priv->base));
+ modreg32(0, BCM_BSC_C_INTR, BCM_BSC_C(priv->base));
+ modreg32(0, BCM_BSC_C_INTT, BCM_BSC_C(priv->base));
+
+ /* Clear FIFO */
+
+ bcm2711_i2c_clearfifos(priv);
+
+ /* Disable interface */
+
+ modreg32(0, BCM_BSC_C_I2CEN, BCM_BSC_C(priv->base));
+}
+
+/****************************************************************************
+ * Name: bcm2711_i2c_enable
+ *
+ * Description:
+ * Enable the I2C interface.
+ *
+ * Input Parameters:
+ * priv - The BCM2711 I2C interface to enable.
+ *
+ ****************************************************************************/
+
+static void bcm2711_i2c_enable(struct bcm2711_i2cdev_s *priv)
+{
+ /* Enable interface */
+
+ modreg32(BCM_BSC_C_I2CEN, BCM_BSC_C_I2CEN, BCM_BSC_C(priv->base));
+
+ /* Clear FIFO */
+
+ bcm2711_i2c_clearfifos(priv);
+
+ /* Enable interrupts */
+
+ modreg32(BCM_BSC_C_INTD, BCM_BSC_C_INTD, BCM_BSC_C(priv->base));
+ modreg32(BCM_BSC_C_INTR, BCM_BSC_C_INTR, BCM_BSC_C(priv->base));
+ modreg32(BCM_BSC_C_INTT, BCM_BSC_C_INTT, BCM_BSC_C(priv->base));
+
+ i2cinfo("Enabled I2C%u\n", priv->port);
+}
+
+/****************************************************************************
+ * Name: bcm2711_i2c_drainrxfifo
+ *
+ * Description:
+ * Drain the RX FIFO into the receive message buffer of the I2C device.
+ *
+ * Input Parameters:
+ * priv - The BCM2711 I2C interface to receive on.
+ *
+ ****************************************************************************/
+
+static void bcm2711_i2c_drainrxfifo(struct bcm2711_i2cdev_s *priv)
+{
+ struct i2c_msg_s *msg = priv->msgs;
+ uint32_t status_addr = BCM_BSC_S(priv->base);
+ uint32_t fifo_addr = BCM_BSC_FIFO(priv->base);
+ size_t i;
+
+ DEBUGASSERT(msg != NULL);
+
+ /* While the RX FIFO contains data to be received, drain it into the
+ * message buffer. Do not read more than the `rw_size` to avoid
+ * overflowing the message buffer.
+ */
+
+ for (i = 0; (i < priv->rw_size) &&
+ (getreg32(status_addr) & BCM_BSC_S_RXD);
+ )
+ {
+ msg->buffer[priv->reg_buff_offset + i] = getreg32(fifo_addr) & 0xff;
+ i++;
+ }
+
+ /* We have either reached the rw_size or the RX FIFO is out of data.
+ * Update the buffer offset with the amount of data we have read.
+ */
+
+ priv->reg_buff_offset += i;
+}
+
+/****************************************************************************
+ * Name: bcm2711_i2c_receive
+ *
+ * Description:
+ * Receive I2C data.
+ *
+ * Input Parameters:
+ * dev - The I2C interface to receive on.
+ * stop - Whether to send a stop condition at the end of the transfer.
+ ****************************************************************************/
+
+static int bcm2711_i2c_receive(struct bcm2711_i2cdev_s *priv, bool stop)
+{
+ struct i2c_msg_s *msg = priv->msgs;
+ ssize_t msg_length;
+ int ret = 0;
+
+ DEBUGASSERT(msg != NULL);
+
+ /* Set read bit */
+
+ modreg32(BCM_BSC_C_READ, BCM_BSC_C_READ, BCM_BSC_C(priv->base));
+
+ /* Set message length */
+
+ putreg32(msg->length, BCM_BSC_DLEN(priv->base));
+
+ /* Start buffer fresh for receiving full message. */
+
+ priv->reg_buff_offset = 0;
+ msg_length = msg->length;
+
+ /* Start transfer. */
+
+ bcm2711_i2c_starttransfer(priv);
+
+ /* Handle special 0 byte read case by waiting for DONE signal. */
+
+ if (msg->length == 0)
+ {
+ ret = bcm2711_i2c_semtimedwait(priv, I2C_TIMEOUT_MS);
+ }
+
+ /* Continuously read until message has been completely read. */
+
+ while (msg_length > 0)
+ {
+ /* Read maximum FIFO depth or the remaining message length. */
+
+ if (msg_length <= FIFO_DEPTH)
+ {
+ priv->rw_size = msg_length;
+ }
+ else
+ {
+ priv->rw_size = FIFO_DEPTH;
+ }
+
+ /* Wait here for interrupt handler to signal that RX FIFO has data.
+ * We can then continue reading.
+ */
+
+ ret = bcm2711_i2c_semtimedwait(priv, I2C_TIMEOUT_MS);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ /* The semaphore was posted without a timeout, so we have to handle
+ * some reading.
+ */
+
+ if (priv->err != 0)
+ {
+ return priv->err;
+ }
+
+ bcm2711_i2c_drainrxfifo(priv);
+
+ /* The remaining message length is the total length minus how far into
+ * the message we are.
+ */
+
+ msg_length = msg->length - priv->reg_buff_offset;
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: bcm2711_i2c_filltxfifo
+ *
+ * Description:
+ * Fill the TX FIFO with data to be sent.
+ *
+ * Input Parameters:
+ * priv - The BCM2711 I2C interface to send on.
+ *
+ ****************************************************************************/
+
+static void bcm2711_i2c_filltxfifo(struct bcm2711_i2cdev_s *priv)
+{
+ struct i2c_msg_s *msg = priv->msgs;
+ uint32_t status_addr = BCM_BSC_S(priv->base);
+ uint32_t fifo_addr = BCM_BSC_FIFO(priv->base);
+ size_t i;
+
+ DEBUGASSERT(msg != NULL);
+
+ /* While there is data to be sent, and the TX FIFO is not full, write the
+ * data to the TX FIFO. Stop when full or data stream is over.
+ */
+
+ for (i = 0; (i < priv->rw_size) &&
+ (getreg32(status_addr) & BCM_BSC_S_TXD);
+ )
+ {
+ putreg32(fifo_addr, msg->buffer[priv->reg_buff_offset + i] & 0xff);
+ i++;
+ }
+
+ /* We have either reached the rw_size or the RX FIFO is out of data.
+ * Update the buffer offset with the amount of data we have read.
+ */
+
+ priv->reg_buff_offset += i;
+}
+
+/****************************************************************************
+ * Name: bcm2711_i2c_send
+ *
+ * Description:
+ * Send I2C data.
+ *
+ * Input Parameters:
+ * dev - The I2C interface to send on.
+ * stop - Whether to send a stop condition at the end of the transfer.
+ ****************************************************************************/
+
+static int bcm2711_i2c_send(struct bcm2711_i2cdev_s *priv, bool stop)
+{
+ struct i2c_msg_s *msg = priv->msgs;
+ ssize_t msg_length;
+ int ret = OK;
+
+ DEBUGASSERT(msg != NULL);
+
+ /* Set write bit */
+
+ modreg32(0, BCM_BSC_C_READ, BCM_BSC_C(priv->base));
+
+ /* Set message length */
+
+ putreg32(msg->length, BCM_BSC_DLEN(priv->base));
+
+ /* Start buffer fresh for sending message */
+
+ priv->reg_buff_offset = 0;
+ msg_length = msg->length;
+
+ /* Start transfer. */
+
+ bcm2711_i2c_starttransfer(priv);
+
+ /* Send the entire message */
+
+ do
+ {
+ /* Write maximum FIFO depth or the remaining message length. */
+
+ if (msg_length <= FIFO_DEPTH)
+ {
+ priv->rw_size = msg_length;
+ }
+ else
+ {
+ priv->rw_size = FIFO_DEPTH;
+ }
+
+ /* Write data to FIFO. */
+
+ i2cerr("Filling FIFO\n");
+ bcm2711_i2c_filltxfifo(priv);
+
+ /* The remaining message length is the total length minus how far into
+ * the message we are.
+ */
+
+ msg_length = msg->length - priv->reg_buff_offset;
+
+ /* Here we wait for an interrupt. There are two scenarios:
+ *
+ * 1) If there is still message data left to write AND we receive an
+ * interrupt, then we can continue on another iteration of the outer
+ * do-while loop to keep writing.
+ *
+ * 2) If there is no more message data left to write, then we need to
+ * get a DONE interrupt to indicate the end of the transfer. If we
+ * don't get a DONE interrupt, but instead get a TXW, we ignore it and
+ * wait on the semaphore again. If we never get a done interrupt we
+ * return the applicable error (timeout). If we do get a done
+ * interrupt, we'll be able to exit the waiting loop.
+ */
+
+ while (msg_length == 0)
+ {
+ /* Wait for interrupt (timed). */
+
+ ret = bcm2711_i2c_semtimedwait(priv, I2C_TIMEOUT_MS);
+
+ /* First check for IO error because it's more important to report
+ * that.
+ */
+
+ i2cerr("sem: %d\n", ret);
+ i2cerr("dev: %d\n", priv->err);
+
+ if (priv->err != 0)
+ {
+ return priv->err;
+ }
+
+ /* Now check if semaphore timed out. */
+
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ /* Now check if the received interrupt was a done condition.
+ * Otherwise we loop again.
+ */
+
+ if (priv->done)
+ {
+ priv->done = false;
+ break;
+ }
+ }
+
+ /* If we're here, the semaphore got posted with an interrupt and there
+ * is still data left to write. Do another iteration.
+ */
+ }
+ while (msg_length > 0);
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: bcm2711_i2c_transfer
+ *
+ * Description:
+ * Perform a sequence of I2C transfers.
+ *
+ * Input Parameters:
+ * dev - The I2C master interface to transfer on.
+ * msgs - The messages to transfer.
+ * count - The number of messages to transfer.
+ ****************************************************************************/
+
+static int bcm2711_i2c_transfer(struct i2c_master_s *dev,
+ struct i2c_msg_s *msgs, int count)
+{
+ struct bcm2711_i2cdev_s *priv = (struct bcm2711_i2cdev_s *)dev;
+ int i;
+ int ret = 0;
+ bool stop = true;
+ int semval = 0;
+
+ DEBUGASSERT(dev != NULL);
+
+ i2cerr("Device state:\n");
+ bcm2711_i2c_print(priv);
+
+ /* Get exclusive access before doing a transfer */
+
+ nxmutex_lock(&priv->lock);
+
+ /* If the semaphore value is not 0, we must be waiting on something, so a
+ * transfer cannot be started. This state should never happen.
+ */
+
+ ret = nxsem_get_value(&priv->wait, &semval);
+ DEBUGASSERT(ret == 0 && semval == 0);
+
+ /* Perform send/receive operations for each message */
+
+ for (i = 0; i < count; i++, msgs++)
+ {
+ /* Put message in device context */
+
+ priv->msgs = msgs;
+ priv->err = 0; /* No errors yet */
+ priv->done = false;
+
+ /* Configure I2C interface according to message. */
+
+ bcm2711_i2c_disable(priv);
+ bcm2711_i2c_setfrequency(priv, msgs->frequency);
+ bcm2711_i2c_setaddr(priv, msgs->addr);
+ bcm2711_i2c_clearfifos(priv);
+ bcm2711_i2c_enable(priv);
+
+ i2cinfo("I2C%u interface configured for message\n", priv->port);
+
+ /* TODO: do I need to support I2C_M_NOSTART? */
+
+ /* TODO: Support restart condition (no stop) */
+
+ if (msgs->flags & I2C_M_NOSTOP)
+ {
+ stop = false;
+ }
+ else
+ {
+ stop = true;
+ }
+
+ /* Set read/write bit according to message configuration, and then
+ * perform the corresponding operation.
+ */
+
+ if (msgs->flags & I2C_M_READ)
+ {
+ ret = bcm2711_i2c_receive(priv, stop);
+ }
+ else
+ {
+ ret = bcm2711_i2c_send(priv, stop);
+ }
+
+ /* Check if there was an error during the send/receive operation and
+ * return early if so.
+ */
+
+ if (ret < 0)
+ {
+ break;
+ }
+
+ if (priv->err != 0)
+ {
+ ret = priv->err;
+ break;
+ }
+
+ /* If no error occurred, we are here. TODO: Something about NULL `msgs`
+ * for illegal access in interrupt.
+ */
+ }
+
+ /* If our last message had a stop condition, we can safely disable this I2C
+ * interface until it's used again.
+ */
+
+ if (stop)
+ {
+ bcm2711_i2c_disable(priv);
+ }
+
+ i2cerr("Device state:\n");
+ bcm2711_i2c_print(priv);
+ i2cerr("Return: %d\n", ret);
+
+ nxmutex_unlock(&priv->lock);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: bcm2711_i2c_primary_handler
+ *
+ * Description:
+ * Handle I2C interrupts.
+ *
+ * Input Parameters:
+ * irq - The IRQ number
+ * context - The interrupt context
+ * arg - The argument passed to the interrupt handler
+ ****************************************************************************/
+
+static int bcm2711_i2c_primary_handler(int irq, void *context, void *arg)
+{
+ int ret = 0;
+ int tempret = 0;
+ struct bcm2711_i2cdev_s *priv;
+
+ /* Check all I2C interfaces for an interrupt */
+
+ for (int i = 0; i < BCM_BSCS_NUM; i++)
+ {
+ priv = g_i2c_devices[i];
+ if (priv == NULL)
+ {
+ continue;
+ }
+
+ /* If interface had interrupt triggered, call its handler. */
+
+ if (bcm2711_i2c_interrupted(priv))
+ {
+ tempret = bcm2711_i2c_secondary_handler(priv);
+
+ /* If there was an error, record it. Otherwise don't overwrite the
+ * ret value, it may contain an error from a previous iteration
+ * that we still need to report.
+ */
+
+ if (tempret < 0)
+ {
+ ret = tempret;
+ }
+ }
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: bcm2711_i2c_secondary_handler
+ *
+ * Description:
+ * Handle I2C interrupts on a per-device basis.
+ *
+ * Input Parameters:
+ * priv - The I2C interface device which has an interrupt triggered.
+ ****************************************************************************/
+
+static int bcm2711_i2c_secondary_handler(struct bcm2711_i2cdev_s *priv)
+{
+ int ret = OK;
+ uint32_t status;
+ uint32_t status_addr;
+ bool post_sem = false;
+
+ /* Get interrupt status for this device. */
+
+ status_addr = BCM_BSC_S(priv->base);
+ status = getreg32(status_addr);
+
+ /* Decide what to do with the status */
+
+ /* There was an ACK error */
+
+ if (status & BCM_BSC_S_ERR)
+ {
+ modreg32(BCM_BSC_S_ERR, BCM_BSC_S_ERR,
+ status_addr); /* Acknowledge err */
+ priv->err = -EIO;
+ ret = -EIO;
+ post_sem = true;
+ }
+
+ /* There was a clock stretch timeout */
+
+ if (status & BCM_BSC_S_CLKT)
+ {
+ modreg32(BCM_BSC_S_CLKT, BCM_BSC_S_CLKT,
+ status_addr); /* Acknowledge err */
+ priv->err = -EIO;
+ ret = -EIO;
+ post_sem = true;
+ }
+
+ /* RX FIFO needs reading */
+
+ if (status & BCM_BSC_S_RXR)
+ {
+ post_sem = true;
+ }
+
+ /* TX FIFO needs writing */
+
+ if (status & BCM_BSC_S_TXW)
+ {
+ i2cerr("Need w\n");
+ post_sem = true;
+ }
+
+ /* Transfer is done */
+
+ if (status & BCM_BSC_S_DONE)
+ {
+ i2cerr("DONE");
+ priv->done = true;
+ modreg32(BCM_BSC_S_DONE, BCM_BSC_S_DONE, status_addr);
+ post_sem = true;
+ }
+
+ if (post_sem)
+ {
+ nxsem_post(&priv->wait);
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: bcm2711_i2cbus_initialize
+ *
+ * Description:
+ * Initialise an I2C device for the BCM2711.
+ *
+ * Input parameters:
+ * port - The bus number for the I2C interface.
+ *
+ ****************************************************************************/
+
+struct i2c_master_s *bcm2711_i2cbus_initialize(int port)
+{
+ int ret;
+ struct bcm2711_i2cdev_s *priv;
+
+ DEBUGASSERT(0 <= port && port < BCM_BSCS_NUM);
+
+ /* Initialize selected port */
+
+ switch (port)
+ {
+#if defined(CONFIG_BCM2711_I2C1)
+ case 1:
+ priv = &g_i2c1dev;
+ priv->dev.ops = &bcm2711_i2c_ops;
+ break;
+#endif
+ default:
+ i2cerr("Port %d is unsupported.\n", port);
+ return NULL;
+ }
+
+ i2cinfo("Initializing I2C%u\n", port);
+
+ /* Exclusive access */
+
+ nxmutex_lock(&priv->lock);
+
+ /* Test for previous initialization. If already initialized, nothing more
+ * needs to be done.
+ */
+
+ if (1 < ++priv->refs)
+ {
+ nxmutex_unlock(&priv->lock);
+ i2cinfo("I2C%u already initialized\n", port);
+ return &priv->dev;
+ }
+
+ /* Not yet initialized, little more work to do. */
+
+ /* TODO: allow pins to be configured for different I2C interfaces.
+ * Currently hard-coded for default I2C1 interface.
+ */
+
+ bcm2711_gpio_set_pulls(2, false, false);
+ bcm2711_gpio_set_pulls(3, false, false);
+ bcm2711_gpio_set_func(2, BCM_GPIO_FUNC0);
+ bcm2711_gpio_set_func(3, BCM_GPIO_FUNC0);
+
+ bcm2711_i2c_disable(priv); /* Only enabled when used. */
+ bcm2711_i2c_setfrequency(priv, I2C_DEFAULT_FREQUENCY);
+
+ /* Attach interrupt handler if it hasn't been already */
+
+ if (!g_i2c_irqinit)
+ {
+ ret = irq_attach(BCM_IRQ_VC_I2C, bcm2711_i2c_primary_handler, NULL);
+ if (ret < 0)
+ {
+ i2cerr("Could not attach interrupt handler for port %d: %d\n",
+ port, ret);
+ return NULL;
+ }
+
+ i2cinfo("I2C interrupt handler attached\n");
+
+ /* Enable interrupt handler */
+
+ arm64_gic_irq_set_priority(BCM_IRQ_VC_I2C, 0, IRQ_TYPE_EDGE);
+ up_enable_irq(BCM_IRQ_VC_I2C);
+ i2cinfo("I2C IRQ enabled\n");
+ g_i2c_irqinit = true; /* Mark IRQ handler as initialized */
+ }
+
+ g_i2c_devsinit++; /* Another device initialized */
+ nxmutex_unlock(&priv->lock);
+ return &priv->dev;
+}
+
+/****************************************************************************
+ * Name: bcm2711_i2cbus_uninitialize
+ *
+ * Description:
+ * Uninitialize an I2C device on the BCM2711.
+ *
+ * Input parameters;
+ * dev - The device to uninitialize.
+ *
+ ****************************************************************************/
+
+int bcm2711_i2cbus_uninitialize(struct i2c_master_s *dev)
+{
+ int ret = 0;
+ struct bcm2711_i2cdev_s *priv = (struct bcm2711_i2cdev_s *)dev;
+
+ if (priv->refs == 0)
+ {
+ return -1;
+ }
+
+ /* If there are still references to the device, just decrement references.
+ */
+
+ nxmutex_lock(&priv->lock);
+ if (--priv->refs)
+ {
+ nxmutex_unlock(&priv->lock);
+ return ret;
+ }
+
+ /* This was the last reference to the I2C device. */
+
+ bcm2711_i2c_disable(priv);
+ g_i2c_devsinit--; /* One less device initialized */
+
+ /* If there are no more I2C devices initialized, turn off interrupts. */
+
+ if (g_i2c_devsinit == 0)
+ {
+ up_disable_irq(BCM_IRQ_VC_I2C);
+ irq_detach(BCM_IRQ_VC_I2C);
+ g_i2c_irqinit = false;
+ i2cinfo("Detached I2C interrupt handler and disabled IRQ.\n");
+ }
+
+ nxmutex_unlock(&priv->lock);
+ return ret;
+}
+
+#endif // defined(CONFIG_BCM2711_I2C)
diff --git a/arch/arm64/src/bcm2711/bcm2711_i2c.h b/arch/arm64/src/bcm2711/bcm2711_i2c.h
new file mode 100644
index 0000000000..1533ef917a
--- /dev/null
+++ b/arch/arm64/src/bcm2711/bcm2711_i2c.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/bcm2711_i2c.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_BCM2711_I2C_H
+#define __ARCH_ARM64_SRC_BCM2711_BCM2711_I2C_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "hardware/bcm2711_bsc.h"
+#include
+#include
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: bcm2711_i2cbus_initialize
+ *
+ * Description:
+ * Initialise an I2C device for the BCM2711.
+ *
+ * Input parameters:
+ * port - The bus number for the I2C interface.
+ *
+ ****************************************************************************/
+
+struct i2c_master_s *bcm2711_i2cbus_initialize(int port);
+
+/****************************************************************************
+ * Name: bcm2711_i2cbus_uninitialize
+ *
+ * Description:
+ * Uninitialize an I2C device on the BCM2711.
+ *
+ * Input parameters;
+ * dev - The device to uninitialize.
+ *
+ ****************************************************************************/
+
+int bcm2711_i2cbus_uninitialize(struct i2c_master_s *dev);
+
+#endif // __ARCH_ARM64_SRC_BCM2711_BCM2711_I2C_H
diff --git a/arch/arm64/src/bcm2711/bcm2711_lowputc.c b/arch/arm64/src/bcm2711/bcm2711_lowputc.c
new file mode 100644
index 0000000000..930acd6803
--- /dev/null
+++ b/arch/arm64/src/bcm2711/bcm2711_lowputc.c
@@ -0,0 +1,150 @@
+/***************************************************************************
+ * arch/arm64/src/bcm2711/bcm2711_lowputc.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ***************************************************************************/
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include "arm64_arch.h"
+#include "bcm2711_gpio.h"
+#include "hardware/bcm2711_aux.h"
+#include
+
+/***************************************************************************
+ * Pre-processor definitions
+ ***************************************************************************/
+
+/* Clock starts at 5MHz. */
+
+#define SYSTEM_CLOCK_FREQUENCY 500000000
+
+/* Early serial baud rate. */
+
+#ifndef BCM_EARLYSERIAL_BAUD
+#define BCM_EARLYSERIAL_BAUD 115200
+#endif // BCM_EARLYSERIAL_BAUD
+
+/* Baud rate calculation */
+
+#define AUX_MU_BAUD(baud) ((SYSTEM_CLOCK_FREQUENCY / (baud * 8)) - 1)
+
+/***************************************************************************
+ * Public Functions
+ ***************************************************************************/
+
+#ifdef CONFIG_ARCH_EARLY_PRINT
+
+/***************************************************************************
+ * Name: arm64_earlyprintinit
+ *
+ * Description:
+ * Configure BCM2711 Mini UART for polling driven operation.
+ *
+ ***************************************************************************/
+
+void arm64_earlyprintinit(char ch)
+{
+ /* Enable Mini UART */
+
+ modreg32(BCM_AUX_ENABLE_MU, BCM_AUX_ENABLE_MU, BCM_AUX_ENABLES);
+
+ /* Disable interrupts. */
+
+ modreg32(0, (BCM_AUX_MU_IER_RXD | BCM_AUX_MU_IER_TXD),
+ BCM_AUX_MU_IER_REG);
+
+ /* Disable TX and RX of the UART */
+
+ modreg32(0, BCM_AUX_MU_CNTL_RXENABLE, BCM_AUX_MU_CNTL_REG);
+ modreg32(0, BCM_AUX_MU_CNTL_TXENABLE, BCM_AUX_MU_CNTL_REG);
+
+ /* Put the UART in 8 bit mode */
+
+ modreg32(BCM_AUX_MU_LCR_DATA8B, BCM_AUX_MU_LCR_DATA8B,
+ BCM_AUX_MU_LCR_REG);
+
+ /* Ensure RTS line is low. */
+
+ modreg32(0, BCM_AUX_MU_MCR_RTS, BCM_AUX_MU_MCR_REG);
+
+ /* Clear the TX and RX FIFOs */
+
+ putreg32(BCM_AUX_MU_IIR_RXCLEAR | BCM_AUX_MU_IIR_TXCLEAR,
+ BCM_AUX_MU_IIR_REG);
+
+ /* Set baud rate. */
+
+ putreg32(AUX_MU_BAUD(BCM_EARLYSERIAL_BAUD), BCM_AUX_MU_BAUD_REG);
+
+ /* GPIO 14 and GPIO 15 are used as TX and RX. */
+
+ /* Turn off pull-up/pull-down resistors. */
+
+ bcm2711_gpio_set_pulls(14, false, false);
+ bcm2711_gpio_set_pulls(15, false, false);
+
+ /* Use alternative function 5 (UART1). */
+
+ bcm2711_gpio_set_func(14, BCM_GPIO_FUNC5);
+ bcm2711_gpio_set_func(15, BCM_GPIO_FUNC5);
+
+ /* Enable TX and RX again. */
+
+ modreg32(BCM_AUX_MU_CNTL_TXENABLE, BCM_AUX_MU_CNTL_TXENABLE,
+ BCM_AUX_MU_CNTL_REG);
+ modreg32(BCM_AUX_MU_CNTL_RXENABLE, BCM_AUX_MU_CNTL_RXENABLE,
+ BCM_AUX_MU_CNTL_REG);
+}
+
+/***************************************************************************
+ * Name: arm64_lowputc
+ *
+ * Description:
+ * Output a byte with as few system dependencies as possible.
+ * This implementation uses the BCM2711's Mini UART with polling
+ * to output bytes.
+ *
+ ***************************************************************************/
+
+void arm64_lowputc(char ch)
+{
+ /* Wait until space for one byte is free */
+
+ while (!(getreg32(BCM_AUX_MU_STAT_REG) & BCM_AUX_MU_STAT_SPACEAVAIL))
+ ;
+
+ /* Add carriage return when there is a newline */
+
+ if (ch == '\n')
+ {
+ putreg32('\r', BCM_AUX_MU_IO_REG);
+
+ /* Wait for space again to add new line character */
+
+ while (!(getreg32(BCM_AUX_MU_STAT_REG) & BCM_AUX_MU_STAT_SPACEAVAIL))
+ ;
+ }
+
+ /* Send one byte */
+
+ putreg32(ch, BCM_AUX_MU_IO_REG);
+}
+
+#endif // CONFIG_ARCH_EARLY_PRINT
diff --git a/arch/arm64/src/bcm2711/bcm2711_serial.c b/arch/arm64/src/bcm2711/bcm2711_serial.c
new file mode 100644
index 0000000000..9d353877c2
--- /dev/null
+++ b/arch/arm64/src/bcm2711/bcm2711_serial.c
@@ -0,0 +1,780 @@
+/***************************************************************************
+ * arch/arm64/src/bcm2711/bcm2711_serial.c
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ***************************************************************************/
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include "bcm2711_gpio.h"
+#include "bcm2711_serial.h"
+#include "hardware/bcm2711_aux.h"
+
+/***************************************************************************
+ * Pre-processor Definitions
+ ***************************************************************************/
+
+/* Mini UART settings. */
+
+#ifndef CONFIG_MINIUART_BAUD
+#define CONFIG_MINIUART_BAUD 115200
+#endif
+
+#ifndef CONFIG_MINIUART_BITS
+#define CONFIG_MINIUART_BITS 8
+#endif
+
+#ifndef CONFIG_MINIUART_PARITY
+#define CONFIG_MINIUART_PARITY 0
+#endif
+
+#ifndef CONFIG_MINIUART_RXBUFSIZE
+#define CONFIG_MINIUART_RXBUFSIZE 256
+#endif
+
+#ifndef CONFIG_MINIUART_TXBUFSIZE
+#define CONFIG_MINIUART_TXBUFSIZE 256
+#endif
+
+#define CONSOLE_DEV g_miniuartport /* Mini UART is console */
+#define TTYS0_DEV g_miniuartport /* Mini UART is ttys0 */
+
+/* System clock frequency for Mini UART in Hz */
+
+#define SYSTEM_CLOCK_FREQUENCY 500000000
+
+/* Baud rate calculation */
+
+#define AUX_MU_BAUD(baud) ((SYSTEM_CLOCK_FREQUENCY / (baud * 8)) - 1)
+
+/***************************************************************************
+ * Private Types
+ ***************************************************************************/
+
+/* UART configuration parameters for all UART ports */
+
+struct bcm2711_uart_config_s
+{
+ uint32_t baud_rate; /* UART baud rate */
+ uint8_t parity; /* 0 = N, 1 = Odd, 2 = even */
+ uint8_t data_bits; /* Number of data bits per baud */
+};
+
+/* UART port definition for Mini UART port */
+
+struct bcm2711_miniuart_port_s
+{
+ struct bcm2711_uart_config_s config; /* UART port configuration */
+};
+
+/* UART port definition for PL011 UART port */
+
+struct bcm2711_uart_port_s
+{
+ struct bcm2711_uart_config_s config; /* UART port configuration */
+ unsigned long base_addr; /* UART port base address */
+};
+
+/***************************************************************************
+ * Private Function Prototypes
+ ***************************************************************************/
+
+/* Mini UART helper functions */
+
+static void bcm2711_miniuart_wait_send(struct uart_dev_s *dev, char c);
+static int bcm2711_miniuart_irq_handler(int irq, void *context, void *arg);
+
+/* Mini UART operations */
+
+static int bcm2711_miniuart_setup(struct uart_dev_s *dev);
+static void bcm2711_miniuart_shutdown(struct uart_dev_s *dev);
+static int bcm2711_miniuart_attach(struct uart_dev_s *dev);
+static void bcm2711_miniuart_detach(struct uart_dev_s *dev);
+static int bcm2711_miniuart_ioctl(struct file *filep, int cmd,
+ unsigned long arg);
+static int bcm2711_miniuart_receive(struct uart_dev_s *dev,
+ unsigned int *status);
+static void bcm2711_miniuart_rxint(struct uart_dev_s *dev, bool enable);
+static bool bcm2711_miniuart_rxavailable(struct uart_dev_s *dev);
+static void bcm2711_miniuart_send(struct uart_dev_s *dev, int c);
+static void bcm2711_miniuart_txint(struct uart_dev_s *dev, bool enable);
+static bool bcm2711_miniuart_txready(struct uart_dev_s *dev);
+static bool bcm2711_miniuart_txempty(struct uart_dev_s *dev);
+
+/***************************************************************************
+ * Private Data
+ ***************************************************************************/
+
+/* UART operations for serial driver */
+
+static const struct uart_ops_s g_miniuart_ops =
+{
+ .setup = bcm2711_miniuart_setup,
+ .shutdown = bcm2711_miniuart_shutdown,
+ .attach = bcm2711_miniuart_attach,
+ .detach = bcm2711_miniuart_detach,
+ .ioctl = bcm2711_miniuart_ioctl,
+ .receive = bcm2711_miniuart_receive,
+ .rxint = bcm2711_miniuart_rxint,
+ .rxavailable = bcm2711_miniuart_rxavailable,
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+ .rxflowcontrol = NULL,
+#endif
+ .send = bcm2711_miniuart_send,
+ .txint = bcm2711_miniuart_txint,
+ .txready = bcm2711_miniuart_txready,
+ .txempty = bcm2711_miniuart_txempty,
+};
+
+/* Mini UART I/O Buffers (Console) */
+
+static char g_miniuartrxbuffer[CONFIG_MINIUART_RXBUFSIZE];
+static char g_miniuarttxbuffer[CONFIG_MINIUART_TXBUFSIZE];
+
+static struct bcm2711_miniuart_port_s g_miniuartpriv =
+{
+ .config =
+ {
+ .baud_rate = CONFIG_MINIUART_BAUD,
+ .parity = CONFIG_MINIUART_PARITY,
+ .data_bits = CONFIG_MINIUART_BITS,
+ },
+};
+
+static struct uart_dev_s g_miniuartport =
+{
+ .recv =
+ {
+ .size = CONFIG_MINIUART_RXBUFSIZE,
+ .buffer = g_miniuartrxbuffer,
+ },
+
+ .xmit =
+ {
+ .size = CONFIG_MINIUART_TXBUFSIZE,
+ .buffer = g_miniuarttxbuffer,
+ },
+
+ .ops = &g_miniuart_ops,
+ .priv = &g_miniuartpriv,
+};
+
+/***************************************************************************
+ * Private Functions
+ ***************************************************************************/
+
+/***************************************************************************
+ * Name: bcm2711_miniuart_txint
+ *
+ * Description:
+ * Call to enable or disable TX interrupts
+ *
+ * Input Parameters:
+ * dev - UART Device
+ * enable - True to enable TX interrupts; false to disable
+ *
+ * Returned Value:
+ * None
+ *
+ ***************************************************************************/
+
+static void bcm2711_miniuart_txint(struct uart_dev_s *dev, bool enable)
+{
+ if (enable)
+ {
+ modreg32(BCM_AUX_MU_IER_TXD, BCM_AUX_MU_IER_TXD, BCM_AUX_MU_IER_REG);
+ }
+ else
+ {
+ modreg32(0, BCM_AUX_MU_IER_TXD, BCM_AUX_MU_IER_REG);
+ }
+}
+
+/***************************************************************************
+ * Name: bcm2711_miniuart_rxint
+ *
+ * Description:
+ * Call to enable or disable RX interrupts
+ *
+ * Input Parameters:
+ * dev - UART Device
+ * enable - True to enable RX interrupts; false to disable
+ *
+ * Returned Value:
+ * None
+ *
+ ***************************************************************************/
+
+static void bcm2711_miniuart_rxint(struct uart_dev_s *dev, bool enable)
+{
+ if (enable)
+ {
+ modreg32(BCM_AUX_MU_IER_RXD, BCM_AUX_MU_IER_RXD, BCM_AUX_MU_IER_REG);
+ }
+ else
+ {
+ modreg32(0, BCM_AUX_MU_IER_RXD, BCM_AUX_MU_IER_REG);
+ }
+}
+
+/***************************************************************************
+ * Name: bcm2711_miniuart_shutdown
+ *
+ * Description:
+ * Disable the UART Port. This method is called when the serial
+ * port is closed.
+ *
+ * Input Parameters:
+ * dev - UART Device
+ *
+ * Returned Value:
+ * None
+ *
+ ***************************************************************************/
+
+static void bcm2711_miniuart_shutdown(struct uart_dev_s *dev)
+{
+ /* Disable interrupts */
+
+ bcm2711_miniuart_rxint(dev, false);
+ bcm2711_miniuart_txint(dev, false);
+
+ /* Disable Mini UART peripheral. */
+
+ modreg32(BCM_AUX_ENABLE_MU, BCM_AUX_ENABLE_MU, BCM_AUX_ENABLES);
+}
+
+/***************************************************************************
+ * Name: bcm2711_miniuart_setup
+ *
+ * Description:
+ * Configure the UART baud, bits, parity, fifos, etc. This method is
+ * called the first time that the serial port is opened.
+ *
+ * Input Parameters:
+ * dev - UART Device
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value is returned on any failure.
+ *
+ ***************************************************************************/
+
+static int bcm2711_miniuart_setup(struct uart_dev_s *dev)
+{
+ struct bcm2711_miniuart_port_s *port =
+ (struct bcm2711_miniuart_port_s *)dev->priv;
+
+ /* Enable Mini UART */
+
+ modreg32(BCM_AUX_ENABLE_MU, BCM_AUX_ENABLE_MU, BCM_AUX_ENABLES);
+
+ /* Disable interrupts. */
+
+ bcm2711_miniuart_txint(dev, false);
+ bcm2711_miniuart_rxint(dev, false);
+
+ /* Disable TX and RX of the UART */
+
+ modreg32(0, BCM_AUX_MU_CNTL_RXENABLE, BCM_AUX_MU_CNTL_REG);
+ modreg32(0, BCM_AUX_MU_CNTL_TXENABLE, BCM_AUX_MU_CNTL_REG);
+
+ /* Set data bit count */
+
+ if (port->config.data_bits == 7)
+ {
+ /* 7 data bits */
+
+ modreg32(0, BCM_AUX_MU_LCR_DATA8B, BCM_AUX_MU_LCR_REG);
+ }
+ else
+ {
+ /* 8 data bits */
+
+ modreg32(BCM_AUX_MU_LCR_DATA8B, BCM_AUX_MU_LCR_DATA8B,
+ BCM_AUX_MU_LCR_REG);
+ }
+
+ /* Ensure RTS line is low. */
+
+ modreg32(0, BCM_AUX_MU_MCR_RTS, BCM_AUX_MU_MCR_REG);
+
+ /* Clear the TX and RX FIFOs */
+
+ modreg32(BCM_AUX_MU_IIR_RXCLEAR, BCM_AUX_MU_IIR_RXCLEAR,
+ BCM_AUX_MU_IIR_REG);
+ modreg32(BCM_AUX_MU_IIR_TXCLEAR, BCM_AUX_MU_IIR_TXCLEAR,
+ BCM_AUX_MU_IIR_REG);
+
+ /* Set baud rate. */
+
+ putreg32(AUX_MU_BAUD(port->config.baud_rate), BCM_AUX_MU_BAUD_REG);
+
+ /* GPIO 14 and GPIO 15 are used as TX and RX.
+ * TODO: Make pins configurable.
+ */
+
+ /* Turn off pull-up/pull-down resistors. */
+
+ bcm2711_gpio_set_pulls(14, false, false);
+ bcm2711_gpio_set_pulls(15, false, false);
+
+ /* Use alternative function 5 (UART1). */
+
+ bcm2711_gpio_set_func(14, BCM_GPIO_FUNC5);
+ bcm2711_gpio_set_func(15, BCM_GPIO_FUNC5);
+
+ /* Enable TX and RX again. */
+
+ modreg32(BCM_AUX_MU_CNTL_TXENABLE, BCM_AUX_MU_CNTL_TXENABLE,
+ BCM_AUX_MU_CNTL_REG);
+ modreg32(BCM_AUX_MU_CNTL_RXENABLE, BCM_AUX_MU_CNTL_RXENABLE,
+ BCM_AUX_MU_CNTL_REG);
+
+ return 0;
+}
+
+/***************************************************************************
+ * Name: bcm2711_miniuart_txready
+ *
+ * Description:
+ * Return true if the Transmit FIFO is not full
+ *
+ * Input Parameters:
+ * dev - UART Device
+ *
+ * Returned Value:
+ * True if the Transmit FIFO is not full; false otherwise
+ *
+ ***************************************************************************/
+
+static bool bcm2711_miniuart_txready(struct uart_dev_s *dev)
+{
+ return getreg32(BCM_AUX_MU_STAT_REG) & BCM_AUX_MU_STAT_SPACEAVAIL;
+}
+
+/***************************************************************************
+ * Name: bcm2711_miniuart_txempty
+ *
+ * Description:
+ * Return true if the Transmit FIFO is empty
+ *
+ * Input Parameters:
+ * dev - UART Device
+ *
+ * Returned Value:
+ * True if the Transmit FIFO is empty; false otherwise
+ *
+ ***************************************************************************/
+
+static bool bcm2711_miniuart_txempty(struct uart_dev_s *dev)
+{
+ return getreg32(BCM_AUX_MU_STAT_REG) & BCM_AUX_MU_STAT_TXEMPTY;
+}
+
+/***************************************************************************
+ * Name: bcm2711_miniuart_rxavailable
+ *
+ * Description:
+ * Return true if the Receive FIFO is not empty
+ *
+ * Input Parameters:
+ * dev - UART Device
+ *
+ * Returned Value:
+ * True if the Receive FIFO is not empty; false otherwise
+ *
+ ***************************************************************************/
+
+static bool bcm2711_miniuart_rxavailable(struct uart_dev_s *dev)
+{
+ return getreg32(BCM_AUX_MU_STAT_REG) & BCM_AUX_MU_STAT_SYMAVAIL;
+}
+
+/***************************************************************************
+ * Name: bcm2711_miniuart_wait_send
+ *
+ * Description:
+ * Wait for Transmit FIFO until it is not full, then transmit the
+ * character over UART.
+ *
+ * Input Parameters:
+ * dev - UART Device
+ * c - Character to be sent
+ *
+ * Returned Value:
+ * None
+ *
+ ***************************************************************************/
+
+static void bcm2711_miniuart_wait_send(struct uart_dev_s *dev, char c)
+{
+ while (!bcm2711_miniuart_txready(dev))
+ ;
+
+ /* Write byte (do I need to mask to avoid writing to LS8 baud rate
+ * bits?)
+ */
+
+ bcm2711_miniuart_send(dev, c);
+}
+
+/***************************************************************************
+ * Name: bcm2711_miniuart_send
+ *
+ * Description:
+ * This method will send one byte on the UART
+ *
+ * Input Parameters:
+ * dev - UART Device
+ * c - Character to be sent
+ *
+ * Returned Value:
+ * None
+ *
+ ***************************************************************************/
+
+static void bcm2711_miniuart_send(struct uart_dev_s *dev, int c)
+{
+ putreg32(c, BCM_AUX_MU_IO_REG);
+}
+
+/***************************************************************************
+ * Name: bcm2711_miniuart_receive
+ *
+ * Description:
+ * Called (usually) from the interrupt level to receive one
+ * character from the UART. Error bits associated with the
+ * receipt are provided in the return 'status'.
+ *
+ * Input Parameters:
+ * dev - UART Device
+ * status - Return status, zero on success
+ *
+ * Returned Value:
+ * Received character
+ *
+ ***************************************************************************/
+
+static int bcm2711_miniuart_receive(struct uart_dev_s *dev,
+ unsigned int *status)
+{
+ /* TODO proper status */
+
+ *status = 0; /* OK */
+ return getreg32(BCM_AUX_MU_IO_REG) & 0xff; /* Read byte */
+}
+
+/***************************************************************************
+ * Name: bcm2711_miniuart_ioctl
+ *
+ * Description:
+ * All ioctl calls will be routed through this method.
+ *
+ * Input Parameters:
+ * filep - File Struct
+ * cmd - ioctl Command
+ * arg - ioctl Argument
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value is returned on any failure.
+ *
+ ***************************************************************************/
+
+static int bcm2711_miniuart_ioctl(struct file *filep, int cmd,
+ unsigned long arg)
+{
+ int ret = OK;
+ UNUSED(filep);
+ UNUSED(arg);
+
+ switch (cmd)
+ {
+ case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
+ case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */
+ default:
+ ret = -ENOTTY;
+ break;
+ }
+
+ /* TODO: implement actual commands */
+
+ return ret;
+}
+
+/***************************************************************************
+ * Name: bcm2711_miniuart_attach
+ *
+ * Description:
+ * Configure the UART to operate in interrupt driven mode.
+ * This method is called when the serial port is opened.
+ * Normally, this is just after the setup() method is called,
+ * however, the serial console may operate in
+ * a non-interrupt driven mode during the boot phase.
+ *
+ * RX and TX interrupts are not enabled by the attach method
+ * (unless the hardware supports multiple levels of interrupt
+ * enabling). The RX and TX interrupts are not enabled until
+ * the txint() and rxint() methods are called.
+ *
+ * Input Parameters:
+ * dev - UART Device
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value is returned on any failure.
+ *
+ ***************************************************************************/
+
+static int bcm2711_miniuart_attach(struct uart_dev_s *dev)
+{
+ int ret = -ENOSYS;
+ const struct bcm2711_miniuart_port_s *port =
+ (struct bcm2711_miniuart_port_s *)dev->priv;
+
+ DEBUGASSERT(port != NULL);
+
+ /* Attach interrupt handler. TODO: this is for all AUX interrupts */
+
+ ret = irq_attach(BCM_IRQ_VC_AUX, bcm2711_miniuart_irq_handler, dev);
+
+ /* Set interrupt priority in GICv2 */
+
+ arm64_gic_irq_set_priority(BCM_IRQ_VC_AUX, 0, IRQ_TYPE_LEVEL);
+
+ /* Enable UART interrupt */
+
+ if (ret == OK)
+ {
+ up_enable_irq(BCM_IRQ_VC_AUX);
+ irqinfo("Attached AUX interrupt handler");
+ }
+ else
+ {
+ irqerr("Could not attach Mini UART IRQ handler, ret=%d\n", ret);
+ }
+
+ return ret;
+}
+
+/***************************************************************************
+ * Name: bcm2711_miniuart_detach
+ *
+ * Description:
+ * Detach UART interrupts. This method is called when the serial port is
+ * closed normally just before the shutdown method is called. The
+ * exception is the serial console which is never shutdown.
+ *
+ * Input Parameters:
+ * dev - UART Device
+ *
+ * Returned Value:
+ * None
+ *
+ ***************************************************************************/
+
+static void bcm2711_miniuart_detach(struct uart_dev_s *dev)
+{
+ const struct bcm2711_miniuart_port_s *port =
+ (struct bcm2711_miniuart_port_s *)dev->priv;
+
+ DEBUGASSERT(port != NULL);
+
+ /* Disable the Mini UART interrupt. TODO: This will disable all AUX
+ * interrupts
+ */
+
+ up_disable_irq(BCM_IRQ_VC_AUX);
+
+ /* Detach the interrupt handler */
+
+ irq_detach(BCM_IRQ_VC_AUX);
+}
+
+/***************************************************************************
+ * Name: bcm2711_miniuart_irq_handler
+ *
+ * Description:
+ * Handles Mini UART IRQ. Performs the appropriate data transfers.
+ *
+ * Input Parameters:
+ * irq - The IRQ number
+ * context - The interrupt context
+ * arg - A UART device for the Mini UART port
+ *
+ * Returned Value:
+ * OK, or -EIO if the interrupt ID is invalid.
+ *
+ ***************************************************************************/
+
+static int bcm2711_miniuart_irq_handler(int irq, void *context, void *arg)
+{
+ int ret = OK;
+ struct uart_dev_s *dev = (struct uart_dev_s *)arg;
+ const struct bcm2711_miniuart_port_s *port =
+ (struct bcm2711_miniuart_port_s *)dev->priv;
+
+ DEBUGASSERT(dev != NULL && port != NULL);
+
+ /* Check if the interrupt is the Mini UART, return early otherwise. */
+
+ if (!(getreg32(BCM_AUX_IRQ) & BCM_AUX_IRQ_MU))
+ {
+ return ret;
+ }
+
+ /* Check the Mini UART interrupt status */
+
+ uint32_t aux_iir = getreg32(BCM_AUX_MU_IIR_REG);
+ if (aux_iir & BCM_AUX_MU_IIR_PENDING)
+ {
+ /* Bit is set when no interrupt is pending */
+
+ return ret;
+ }
+
+ /* Check interrupt ID */
+
+ switch (aux_iir & 0b110)
+ {
+ case BCM_AUX_MU_IIR_RXBYTE:
+
+ /* Receiver holds valid byte */
+
+ uart_recvchars(dev);
+ break;
+
+ case BCM_AUX_MU_IIR_TXEMPTY:
+
+ /* Transmit holding register is empty */
+
+ uart_xmitchars(dev);
+ break;
+
+ case BCM_AUX_MU_IIR_NONE:
+
+ /* No interrupt, do nothing */
+
+ break;
+
+ default:
+
+ /* Impossible case of 0b11 */
+
+ ret = -EIO;
+ break;
+ }
+
+ return ret;
+}
+
+/***************************************************************************
+ * Public Functions
+ ***************************************************************************/
+
+/***************************************************************************
+ * Name: arm64_earlyserialinit
+ *
+ * Description:
+ * Performs the low level UART initialization early in
+ * debug so that the serial console will be available
+ * during bootup. This must be called before arm64_serialinit.
+ *
+ * Returned Value:
+ * None
+ *
+ ***************************************************************************/
+
+void arm64_earlyserialinit(void)
+{
+#ifdef CONSOLE_DEV
+ bcm2711_miniuart_setup(&CONSOLE_DEV);
+#endif
+}
+
+/***************************************************************************
+ * Name: up_putc
+ *
+ * Description:
+ * Provide priority, low-level access to support OS debug
+ * writes
+ *
+ * Input Parameters:
+ * ch - Character to be transmitted over UART
+ *
+ ***************************************************************************/
+
+void up_putc(int ch)
+{
+#ifdef CONSOLE_DEV
+ struct uart_dev_s *dev = &CONSOLE_DEV;
+
+ /* Check for LF */
+
+ if (ch == '\n')
+ {
+ /* Add CR */
+
+ bcm2711_miniuart_wait_send(dev, '\r');
+ }
+
+ bcm2711_miniuart_wait_send(dev, ch);
+#endif /* CONSOLE_DEV */
+}
+
+/***************************************************************************
+ * Name: arm64_serialinit
+ *
+ * Description:
+ * Register serial console and serial ports. This assumes
+ * that bcm2711_earlyserialinit was called previously.
+ *
+ * Returned Value:
+ * None
+ *
+ ***************************************************************************/
+
+void arm64_serialinit(void)
+{
+#if defined(CONSOLE_DEV)
+
+ /* Mark the console. */
+
+ CONSOLE_DEV.isconsole = 1;
+
+ int ret;
+ ret = uart_register("/dev/console", &CONSOLE_DEV);
+ if (ret < 0)
+ {
+ _err("Could not register /dev/console, ret=%d\n", ret);
+ }
+#endif /* defined(CONSOLE_DEV) */
+}
diff --git a/arch/arm64/src/bcm2711/bcm2711_serial.h b/arch/arm64/src/bcm2711/bcm2711_serial.h
new file mode 100644
index 0000000000..97dc398c19
--- /dev/null
+++ b/arch/arm64/src/bcm2711/bcm2711_serial.h
@@ -0,0 +1,37 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/bcm2711_serial.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_BCM2711_SERIAL_H
+#define __ARCH_ARM64_SRC_BCM2711_BCM2711_SERIAL_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include "arm64_internal.h"
+#include "arm64_gic.h"
+
+#ifndef __ASSEMBLY__
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ARCH_ARM64_SRC_BCM2711_BCM2711_SERIAL_H */
diff --git a/arch/arm64/src/bcm2711/bcm2711_spi.c b/arch/arm64/src/bcm2711/bcm2711_spi.c
new file mode 100644
index 0000000000..c09067739e
--- /dev/null
+++ b/arch/arm64/src/bcm2711/bcm2711_spi.c
@@ -0,0 +1,263 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/bcm2711_spi.c
+ *
+ * Contributed by Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include "arm64_arch.h"
+#include "arm64_gic.h"
+#include "chip.h"
+#include "hardware/bcm2711_aux.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Core clock nominal frequency in Hz */
+
+#define CORE_CLOCK_FREQUENCY 150000000
+
+/* Calculate the value required in the speed register for the correct
+ * frequency.
+ */
+
+#define SPI_SPEED_FIELD(spiclk) ((CORE_CLOCK_FREQUENCY / (2 * (spiclk))) - 1)
+
+/* Calculate the actual frequency based on the speed field. */
+
+#define SPI_ACTUAL_FREQ(speedfield) \
+ (CORE_CLOCK_FREQUENCY / (2 * ((speedfield) + 1)))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* SPI driver state for BCM2711. */
+
+struct bcm2711_spidev_s
+{
+ struct spi_dev_s spidev; /* Externally visible */
+ uint32_t base; /* Base address of SPI interface register */
+ mutex_t lock; /* Mutual exclusion during chip select */
+ uint32_t freq; /* Request clock frequency */
+ uint32_t actualfreq; /* Actual clock frequency */
+ uint8_t nbits; /* Word bit-width */
+ uint8_t mode; /* 0, 1, 2 or 3 */
+ uint8_t port; /* 1 or 2 */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* SPI methods */
+
+static int spi_lock(struct spi_dev_s *dev, bool lock);
+static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency);
+static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode);
+static void spi_setbits(struct spi_dev_s *dev, int nbits);
+static uint32_t spi_send(struct spi_dev_s *dev, uint32_t wd);
+static void unused_code spi_exchange(struct spi_dev_s *dev,
+ const void *txbuffer, void *rxbuffer,
+ size_t nwords);
+
+#ifndef CONFIG_SPI_EXCHANGE
+static void spi_sndblock(struct spi_dev_s *dev, const void *buffer,
+ size_t nwords);
+static void spi_recvblock(struct spi_dev_s *dev, void *buffer,
+ size_t nwords);
+#endif /* CONFIG_SPI_EXCHANGE */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Operations for SPI interfaces */
+
+static const struct spi_ops_s g_spiops =
+{
+ .lock = spi_lock,
+ .setfrequency = spi_setfrequency,
+ .setmode = spi_setmode,
+ .setbits = spi_setbits,
+ .send = spi_send,
+#ifdef CONFIG_SPI_EXCHANGE
+ .exchange = spi_exchange,
+#else
+ .sndblock = spi_sndblock,
+ .recvblock = spi_recvblock,
+#endif /* CONFIG_SPI_EXCHANGE */
+#ifdef CONFIG_SPI_HWFEATURES
+ .hwfeatures = NULL,
+#endif /* CONFIG_SPI_HWFEATURES */
+#ifdef CONFIG_SPI_CALLBACK
+ .registercallback = /* TODO */, /* Provided externally */
+#else
+ .registercallback = 0, /* Not implemented */
+#endif
+};
+
+#define CONFIG_BCM2711_SPI1 // TODO remove
+#if defined(CONFIG_BCM2711_SPI1)
+
+static struct bcm2711_spidev_s g_spi1dev =
+{
+ .spidev =
+ {
+ .ops = &g_spiops,
+ },
+ .base = BCM_AUX_SPI1_BASEADDR,
+ .frequency = 0,
+ .port = 1,
+ .lock = NXMUTEX_INITIALIZER,
+};
+
+#endif /* defined(CONFIG_BCM2711_SPI1) */
+
+#define CONFIG_BCM2711_SPI2 // TODO remove
+#if defined(CONFIG_BCM2711_SPI2)
+
+static struct bcm2711_spidev_s g_spi2dev =
+{
+ .spidev =
+ {
+ .ops = &g_spiops,
+ },
+ .base = BCM_AUX_SPI2_BASEADDR,
+ .frequency = 0,
+ .port = 2,
+ .lock = NXMUTEX_INITIALIZER,
+};
+
+#endif /* defined(CONFIG_BCM2711_SPI2) */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: spi_lock
+ *
+ * Description:
+ * On SPI buses where there are multiple devices, it will be necessary to
+ * lock SPI to have exclusive access to the buses for a sequence of
+ * transfers. The bus should be locked before the chip is selected. After
+ * locking the SPI bus, the caller should then also call the setfrequency,
+ * setbits, and setmode methods to make sure that the SPI is properly
+ * configured for the device. If the SPI bus is being shared, then it
+ * may have been left in an incompatible state.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ * lock - true: Lock spi bus, false: unlock SPI bus
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static int spi_lock(struct spi_dev_s *dev, bool lock)
+{
+ struct bcm2711_spidev_s *priv = (struct bcm2711_spidev_s *)dev;
+
+ if (lock)
+ {
+ return nxmutex_lock(&priv->lock);
+ }
+ else
+ {
+ return nxmutex_unlock(&priv->lock);
+ }
+}
+
+/****************************************************************************
+ * Name: spi_setfrequency
+ *
+ * Description:
+ * Set the SPI frequency.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ * frequency - The SPI frequency requested
+ *
+ * Returned Value:
+ * Returns the actual frequency selected
+ *
+ ****************************************************************************/
+
+static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency)
+{
+ struct bcm2711_spidev_s *priv = (struct bcm2711_spidev_s *)dev;
+
+ /* Calculate the speed field value needed */
+
+ uint32_t speed = SPI_SPEED_FIELD(frequency);
+
+ /* Save the speed field to take effect */
+
+ modreg32(BCM_SPI_CNTL0_SPEED, speed << 20, BCM_SPI_CNTL0_REG(priv->base));
+
+ /* Calculate the new actual and save settings */
+
+ priv->freq = frequency;
+ priv->actualfreq = SPI_ACTUAL_FREQ(speed);
+
+ spiinfo("Frequency %" PRId32 "->%" PRId32 "\n",
+ frequency, priv->actualfreq);
+ return priv->actualfreq;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: bcm2711_spibus_initialize
+ *
+ * Description:
+ * Initialize the selected SPI port.
+ *
+ * Input Parameter:
+ * port - Port number
+ *
+ * Returned Value:
+ * Valid SPI device structure reference on success; a NULL on failure.
+ *
+ ****************************************************************************/
+
+struct spi_dev_s *bcm2711_spibus_initialize(int port)
+{
+ return NULL;
+}
diff --git a/arch/arm64/src/bcm2711/bcm2711_spi.h b/arch/arm64/src/bcm2711/bcm2711_spi.h
new file mode 100644
index 0000000000..89c992694c
--- /dev/null
+++ b/arch/arm64/src/bcm2711/bcm2711_spi.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/bcm2711_spi.h
+ *
+ * Contributed by Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_BCM2711_SPI_H
+#define __ARCH_ARM64_SRC_BCM2711_BCM2711_SPI_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+#include
+
+#include
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: bcm2711_spibus_initialize
+ *
+ * Description:
+ * Initialize the selected SPI port.
+ *
+ * Input Parameter:
+ * port - Port number
+ *
+ * Returned Value:
+ * Valid SPI device structure reference on success; a NULL on failure.
+ *
+ ****************************************************************************/
+
+struct spi_dev_s *bcm2711_spibus_initialize(int port);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM64_SRC_BCM2711_BCM2711_SPI_H */
diff --git a/arch/arm64/src/bcm2711/bcm2711_timer.c b/arch/arm64/src/bcm2711/bcm2711_timer.c
new file mode 100644
index 0000000000..5fe6f30b8c
--- /dev/null
+++ b/arch/arm64/src/bcm2711/bcm2711_timer.c
@@ -0,0 +1,37 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/bcm2711_timer.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include "arm64_arch_timer.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+void up_timer_initialize(void)
+{
+ up_alarm_set_lowerhalf(arm64_oneshot_initialize());
+}
+
diff --git a/arch/arm64/src/bcm2711/chip.h b/arch/arm64/src/bcm2711/chip.h
new file mode 100644
index 0000000000..86e8ccae95
--- /dev/null
+++ b/arch/arm64/src/bcm2711/chip.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/chip.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_CHIP_H
+#define __ARCH_ARM64_SRC_BCM2711_CHIP_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#ifndef __ASSEMBLY__
+# include
+#endif
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Macro Definitions
+ ****************************************************************************/
+
+#endif /* __ARCH_ARM64_SRC_BCM2711_CHIP_H */
diff --git a/arch/arm64/src/bcm2711/hardware/bcm2711_armtimer.h b/arch/arm64/src/bcm2711/hardware/bcm2711_armtimer.h
new file mode 100644
index 0000000000..ba052953cb
--- /dev/null
+++ b/arch/arm64/src/bcm2711/hardware/bcm2711_armtimer.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/hardware/bcm2711_armtimer.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_ARMTIMER_H
+#define __ARCH_ARM64_SRC_BCM2711_ARMTIMER_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "bcm2711_memmap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* ARM timer register offsets */
+
+#define BCM_ARMT_LOAD_OFFSET 0x400
+#define BCM_ARMT_VALUE_OFFSET 0x404
+#define BCM_ARMT_CONTROL_OFFSET 0x408
+#define BCM_ARMT_IRQCNTL_OFFSET 0x40c
+#define BCM_ARMT_RAWIRQ_OFFSET 0x410
+#define BCM_ARMT_MSKIRQ_OFFSET 0x414
+#define BCM_ARMT_RELOAD_OFFSET 0x418
+#define BCM_ARMT_PREDIV_OFFSET 0x41c
+#define BCM_ARMT_FREECNT_OFFSET 0x420
+
+/* ARM timer register addresses */
+
+#define _BCM_ARMT(offset) (BCM_ARMT_BASEADDR + (offset))
+
+#define BCM_ARMT_LOAD _BCM_ARMT(BCM_ARMT_LOAD_OFFSET)
+#define BCM_ARMT_VALUE _BCM_ARMT(BCM_ARMT_VALUE_OFFSET)
+#define BCM_ARMT_CONTROL _BCM_ARMT(BCM_ARMT_CONTROL_OFFSET)
+#define BCM_ARMT_IRQCNTL _BCM_ARMT(BCM_ARMT_IRQCNTL_OFFSET)
+#define BCM_ARMT_RAWIRQ _BCM_ARMT(BCM_ARMT_RAWIRQ_OFFSET)
+#define BCM_ARMT_MSKIRQ _BCM_ARMT(BCM_ARMT_MSKIRQ_OFFSET)
+#define BCM_ARMT_RELOAD _BCM_ARMT(BCM_ARMT_RELOAD_OFFSET)
+#define BCM_ARMT_PREDIV _BCM_ARMT(BCM_ARMT_PREDIV_OFFSET)
+#define BCM_ARMT_FREECNT _BCM_ARMT(BCM_ARMT_FREECNT_OFFSET)
+
+/* ARM timer register bit definitions */
+
+#define BCM_ARMT_CONTROL_FREEDIV (0xff << 16)
+#define BCM_ARMT_CONTROL_ENAFREE (1 << 9)
+#define BCM_ARMT_CONTROL_DBGHALT (1 << 8)
+#define BCM_ARMT_CONTROL_ENABLE (1 << 7)
+#define BCM_ARMT_CONTROL_IE (1 << 6)
+#define BCM_ARMT_CONTROL_DIV (0x3 << 2)
+#define BCM_ARMT_CONTROL_DIVNONE (0 << 2)
+#define BCM_ARMT_CONTROL_DIV16 (1 << 2)
+#define BCM_ARMT_CONTROL_DIV256 (2 << 2)
+#define BCM_ARMT_CONTROL_32BIT (1 << 1)
+
+#define BCM_ARMT_IRQCNTL_INT (1 << 0)
+
+#define BCM_ARMT_RAWIRQ_INT (1 << 0)
+
+#define BCM_ARMT_MSKIRQ_INT (1 << 0)
+
+#define BCM_ARMT_PREDIV_PREDIV (0x3ff << 0)
+
+#endif /* __ARCH_ARM64_SRC_BCM2711_ARMTIMER_H */
diff --git a/arch/arm64/src/bcm2711/hardware/bcm2711_aux.h b/arch/arm64/src/bcm2711/hardware/bcm2711_aux.h
new file mode 100644
index 0000000000..7832154264
--- /dev/null
+++ b/arch/arm64/src/bcm2711/hardware/bcm2711_aux.h
@@ -0,0 +1,226 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/hardware/bcm2711_aux.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_AUX_H
+#define __ARCH_ARM64_SRC_BCM2711_AUX_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "bcm2711_memmap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* BCM2711 auxiliary register offsets. **************************************/
+
+#define BCM_AUX_IRQ_OFFSET 0x00 /* Auxiliary interrupt status */
+#define BCM_AUX_ENABLES_OFFSET 0x04 /* Auxiliary enables */
+
+/* BCM2711 mini UART register offsets. */
+
+#define BCM_AUX_MU_IO_REG_OFFSET 0x40 /* Mini UART I/O Data */
+#define BCM_AUX_MU_IER_REG_OFFSET 0x44 /* Mini UART interrupt enable */
+#define BCM_AUX_MU_IIR_REG_OFFSET 0x48 /* Mini UART interrupt identify */
+#define BCM_AUX_MU_LCR_REG_OFFSET 0x4c /* Mini UART line control */
+#define BCM_AUX_MU_MCR_REG_OFFSET 0x50 /* Mini UART modem control */
+#define BCM_AUX_MU_LSR_REG_OFFSET 0x54 /* Mini UART Line Status */
+#define BCM_AUX_MU_MSR_REG_OFFSET 0x58 /* Mini UART Modem Status */
+#define BCM_AUX_MU_SCRATCH_OFFSET 0x5c /* Mini UART Scratch */
+#define BCM_AUX_MU_CNTL_REG_OFFSET 0x60 /* Mini UART Extra Control */
+#define BCM_AUX_MU_STAT_REG_OFFSET 0x64 /* Mini UART Extra Status */
+#define BCM_AUX_MU_BAUD_REG_OFFSET 0x68 /* Mini UART Baudrate */
+
+/* BCM2711 SPI registers. */
+
+#define BCM_AUX_SPI1_OFFSET (0x80)
+#define BCM_AUX_SPI1_BASEADDR (BCM_AUX_BASEADDR + BCM_AUX_SPI1_OFFSET)
+
+#define BCM_AUX_SPI2_OFFSET (0xc0)
+#define BCM_AUX_SPI2_BASEADDR (BCM_AUX_BASEADDR + BCM_AUX_SPI2_OFFSET)
+
+/* BCM2711 SPI register offsets (offset from SPI base register) */
+
+#define BCM_AUX_SPI_CNTL0_REG_OFFSET 0x00 /* SPI Control register 0 */
+#define BCM_AUX_SPI_CNTL1_REG_OFFSET 0x04 /* SPI Control register 1 */
+#define BCM_AUX_SPI_STAT_REG_OFFSET 0x08 /* SPI Status */
+#define BCM_AUX_SPI_PEEK_REG_OFFSET 0x0c /* SPI Peek */
+#define BCM_AUX_SPI_IO_REGa_OFFSET 0x20 /* SPI Data */
+#define BCM_AUX_SPI_IO_REGb_OFFSET 0x24 /* SPI Data */
+#define BCM_AUX_SPI_IO_REGc_OFFSET 0x28 /* SPI Data */
+#define BCM_AUX_SPI_IO_REGd_OFFSET 0x2c /* SPI Data */
+#define BCM_AUX_SPI_TXHOLD_REGa_OFFSET 0x30 /* SPI Extended Data */
+#define BCM_AUX_SPI_TXHOLD_REGb_OFFSET 0x34 /* SPI Extended Data */
+#define BCM_AUX_SPI_TXHOLD_REGc_OFFSET 0x38 /* SPI Extended Data */
+#define BCM_AUX_SPI_TXHOLD_REGd_OFFSET 0x3c /* SPI Extended Data */
+
+/* BCM2711 auxiliary registers. *********************************************/
+
+#define BCM_AUX_REG(offset) (BCM_AUX_BASEADDR + (offset))
+
+/* BCM2711 mini UART registers. */
+
+#define BCM_AUX_IRQ BCM_AUX_REG(BCM_AUX_IRQ_OFFSET)
+#define BCM_AUX_ENABLES BCM_AUX_REG(BCM_AUX_ENABLES_OFFSET)
+#define BCM_AUX_MU_IO_REG BCM_AUX_REG(BCM_AUX_MU_IO_REG_OFFSET)
+#define BCM_AUX_MU_IER_REG BCM_AUX_REG(BCM_AUX_MU_IER_REG_OFFSET)
+#define BCM_AUX_MU_IIR_REG BCM_AUX_REG(BCM_AUX_MU_IIR_REG_OFFSET)
+#define BCM_AUX_MU_LCR_REG BCM_AUX_REG(BCM_AUX_MU_LCR_REG_OFFSET)
+#define BCM_AUX_MU_MCR_REG BCM_AUX_REG(BCM_AUX_MU_MCR_REG_OFFSET)
+#define BCM_AUX_MU_LSR_REG BCM_AUX_REG(BCM_AUX_MU_LSR_REG_OFFSET)
+#define BCM_AUX_MU_MSR_REG BCM_AUX_REG(BCM_AUX_MU_MSR_REG_OFFSET)
+#define BCM_AUX_MU_SCRATCH BCM_AUX_REG(BCM_AUX_MU_SCRATCH_OFFSET)
+#define BCM_AUX_MU_CNTL_REG BCM_AUX_REG(BCM_AUX_MU_CNTL_REG_OFFSET)
+#define BCM_AUX_MU_STAT_REG BCM_AUX_REG(BCM_AUX_MU_STAT_REG_OFFSET)
+#define BCM_AUX_MU_BAUD_REG BCM_AUX_REG(BCM_AUX_MU_BAUD_REG_OFFSET)
+
+/* BCM2711 SPI registers. */
+
+#define BCM_SPI_CNTL0_REG(base) ((base) + BCM_AUX_SPI_CNTL0_REG_OFFSET)
+#define BCM_SPI_CNTL1_REG(base) ((base) + BCM_AUX_SPI_CNTL1_REG_OFFSET)
+#define BCM_SPI_STAT_REG(base) ((base) + BCM_AUX_SPI_STAT_REG_OFFSET)
+#define BCM_SPI_PEEK_REG(base) ((base) + BCM_AUX_SPI_PEEK_REG_OFFSET)
+#define BCM_SPI_IO_REGa(base) ((base) + BCM_AUX_SPI_IO_REGa_OFFSET)
+#define BCM_SPI_IO_REGb(base) ((base) + BCM_AUX_SPI_IO_REGb_OFFSET)
+#define BCM_SPI_IO_REGc(base) ((base) + BCM_AUX_SPI_IO_REGc_OFFSET)
+#define BCM_SPI_IO_REGd(base) ((base) + BCM_AUX_SPI_IO_REGd_OFFSET)
+#define BCM_SPI_TXHOLD_REGa(base) ((base) + BCM_AUX_SPI_TXHOLD_REGa_OFFSET)
+#define BCM_SPI_TXHOLD_REGb(base) ((base) + BCM_AUX_SPI_TXHOLD_REGb_OFFSET)
+#define BCM_SPI_TXHOLD_REGc(base) ((base) + BCM_AUX_SPI_TXHOLD_REGc_OFFSET)
+#define BCM_SPI_TXHOLD_REGd(base) ((base) + BCM_AUX_SPI_TXHOLD_REGd_OFFSET)
+
+/* BCM2711 auxiliary register bit definitions. */
+
+#define BCM_AUX_IRQ_MU (1 << 0) /* Mini UART interrupt pending */
+#define BCM_AUX_IRQ_SPI1 (1 << 1) /* SPI1 interrupt pending */
+#define BCM_AUX_IRQ_SPI2 (1 << 2) /* SPI2 interrupt pending */
+
+#define BCM_AUX_ENABLE_MU (1 << 0) /* Mini UART enable */
+#define BCM_AUX_ENABLE_SPI1 (1 << 1) /* SPI1 enable */
+#define BCM_AUX_ENABLE_SPI2 (1 << 2) /* SPI2 enable */
+
+#define BCM_AUX_MU_IO_BAUDRATE (0xff) /* LS 8 bits of baudrate register */
+#define BCM_AUX_MU_IO_TXD (0xff) /* If DLAB=0, write-only */
+#define BCM_AUX_MU_IO_RXD (0xff) /* If DLAB=0, read-only */
+
+#define BCM_AUX_MU_IER_BAUDRATE (0xff) /* MS 8 bits of baudrate register */
+
+/* NOTE: The RXD and TXD interrupts here are swapped when compared to what is
+ * visible on the BCM2711 datasheet. This is because the data sheet contains
+ * an error.
+ */
+
+#define BCM_AUX_MU_IER_RXD (1 << 0) /* Enable receive interrupt */
+#define BCM_AUX_MU_IER_TXD (1 << 1) /* Enable transmit interrupt */
+
+#define BCM_AUX_MU_IIR_PENDING (1 << 0) /* Clear when interrupt pending */
+#define BCM_AUX_MU_IIR_MASK (0x03 << 1) /* Mask interrupt ID bits */
+#define BCM_AUX_MU_IIR_TXEMPTY (1 << 1) /* TX holding register empty (RO) */
+#define BCM_AUX_MU_IIR_RXBYTE (2 << 1) /* RX holding valid byte (RO) */
+#define BCM_AUX_MU_IIR_NONE (0 << 1) /* No interrupts (RO) */
+#define BCM_AUX_MU_IIR_RXCLEAR (1 << 1) /* Clear RX FIFO (WO) */
+#define BCM_AUX_MU_IIR_TXCLEAR (1 << 2) /* Clear TX FIFO (WO) */
+
+#define BCM_AUX_MU_LCR_DLAB (1 << 7) /* Gives access to baudrate */
+#define BCM_AUX_MU_LCR_BREAK (1 << 6) /* Pull TX line low */
+#define BCM_AUX_MU_LCR_DATA8B (1 << 0) /* 7-bit if clear, 8-bit if set */
+
+#define BCM_AUX_MU_MCR_RTS (1 << 1) /* RTS high = 0, RTS low = 1 */
+
+#define BCM_AUX_MU_LSR_TXIDLE (1 << 6) /* Transmitter is idle */
+#define BCM_AUX_MU_LSR_TXEMPTY (1 << 5) /* Transmitter FIFO has space */
+#define BCM_AUX_MU_LSR_RXOVERRUN (1 << 1) /* Receiver overrun */
+#define BCM_AUX_MU_LSR_DREADY (1 << 0) /* RX data is ready */
+
+#define BCM_AUX_MU_MSR_CTS (1 << 4) /* CTS low = 1, CTS high = 0 */
+
+#define BCM_AUX_MU_SCRATCHMASK (0xff) /* Byte of extra storage */
+
+#define BCM_AUX_MU_CNTL_CTSLVL (1 << 7) /* CTS flow assert low = 1 */
+#define BCM_AUX_MU_CNTL_RTSLVL (1 << 6) /* RTS flow assert low = 1 */
+#define BCM_AUX_MU_CNTL_RTSFLOWMSK (0x3 << 4) /* RTS auto flow level mask */
+#define BCM_AUX_MU_CNTL_FLOWLVL4 (3 << 4) /* De-assert FIFO 4 empty */
+#define BCM_AUX_MU_CNTL_FLOWLVL3 (0 << 4) /* De-assert FIFO 3 empty */
+#define BCM_AUX_MU_CNTL_FLOWLVL2 (1 << 4) /* De-assert FIFO 2 empty */
+#define BCM_AUX_MU_CNTL_FLOWLVL1 (2 << 4) /* De-assert FIFO 1 empty */
+#define BCM_AUX_MU_CNTL_TXAUTOFLOW (1 << 3) /* Enable TX auto flow */
+#define BCM_AUX_MU_CNTL_RXAUTOFLOW (1 << 2) /* Enable RX auto flow */
+#define BCM_AUX_MU_CNTL_TXENABLE (1 << 1) /* Enable transmitter */
+#define BCM_AUX_MU_CNTL_RXENABLE (1 << 0) /* Enable receiver */
+
+#define BCM_AUX_MU_STAT_TXFIFOFILL (0xf << 24) /* How many symbols 0-8 */
+#define BCM_AUX_MU_STAT_RXFIFOFILL (0xf << 16) /* How many symbols 0-8 */
+#define BCM_AUX_MU_STAT_TXDONE (1 << 9) /* TX idle and FIFO empty */
+#define BCM_AUX_MU_STAT_TXEMPTY (1 << 8) /* TX FIFO is empty */
+#define BCM_AUX_MU_STAT_CTSLINE (1 << 7) /* Status of CTS line */
+#define BCM_AUX_MU_STAT_RTSLINE (1 << 6) /* Status of RTS line */
+#define BCM_AUX_MU_STAT_TXFULL (1 << 5) /* TX FIFO full */
+#define BCM_AUX_MU_STAT_RXOVERRUN (1 << 4) /* RX overrun */
+#define BCM_AUX_MU_STAT_TXIDLE (1 << 3) /* TX idle */
+#define BCM_AUX_MU_STAT_RXIDLE (1 << 2) /* RX idle */
+#define BCM_AUX_MU_STAT_SPACEAVAIL (1 << 1) /* TX has space */
+#define BCM_AUX_MU_STAT_SYMAVAIL (1 << 0) /* RX has symbol */
+
+#define BCM_AUX_MU_BAUD_MASK (0xffff) /* Baudrate counter */
+
+#define BCM_SPI_CNTL0_SPEED (0xfff << 20) /* SPI clock speed */
+#define BCM_SPI_CNTL0_CS (0x7 << 17) /* SPI clock speed */
+#define BCM_SPI_CNTL0_PIMODE (1 << 16) /* Post input mode */
+#define BCM_SPI_CNTL0_VARCS (1 << 15) /* Variable chip select */
+#define BCM_SPI_CNTL0_VARWIDTH (1 << 14) /* Variable width */
+#define BCM_SPI_CNTL0_DOUTHOLD (0x3 << 12) /* DOUT hold time mask */
+#define BCM_SPI_CNTL0_DOUTNONE (0 << 12) /* No hold */
+#define BCM_SPI_CNTL0_DOUT1 (1 << 12) /* 1 system clock hold */
+#define BCM_SPI_CNTL0_DOUT4 (2 << 12) /* 4 system clocks hold */
+#define BCM_SPI_CNTL0_DOUT7 (3 << 12) /* 7 system clocks hold */
+#define BCM_SPI_CNTL0_EN (1 << 11) /* Enable SPI interface */
+#define BCM_SPI_CNTL0_INRISE (1 << 10) /* Data clock on rising */
+#define BCM_SPI_CNTL0_FIFOCLR (1 << 9) /* Clear FIFOs */
+#define BCM_SPI_CNTL0_OUTRISE (1 << 8) /* Data clock on rising */
+#define BCM_SPI_CNTL0_CLKINV (1 << 7) /* Invert SPI clock */
+#define BCM_SPI_CNTL0_SHIFTMS (1 << 6) /* Shift out MS bit */
+#define BCM_SPI_CNTL0_SHIFTLEN (0x2f) /* Bit shift count mask */
+
+#define BCM_SPI_CNTL1_CSHTIME (0x7 << 8) /* CS high time */
+#define BCM_SPI_CNTL1_TXEMPTYIRQ (1 << 7) /* Int line high = 1 */
+#define BCM_SPI_CNTL1_DONEIRQ (1 << 6) /* Interrupt while idle = 1 */
+#define BCM_SPI_CNTL1_SHIFTMS (1 << 1) /* Shift in MS bit first */
+#define BCM_SPI_CNTL1_KEEPIN (1 << 0) /* Do not clear RX shift reg */
+
+#define BCM_SPI_STAT_TXLVL (0xf << 24) /* TX FIFO level mask */
+#define BCM_SPI_STAT_RXLVL (0xf << 16) /* RX FIFO level mask */
+#define BCM_SPI_STAT_TXFULL (1 << 10) /* TX FIFO full */
+#define BCM_SPI_STAT_TXEMPTY (1 << 9) /* TX FIFO empty */
+#define BCM_SPI_STAT_RXFULL (1 << 8) /* RX FIFO empty */
+#define BCM_SPI_STAT_RXEMPTY (1 << 7) /* RX FIFO empty */
+#define BCM_SPI_STAT_BUSY (1 << 6) /* Module is busy */
+#define BCM_SPI_STAT_BITCOUNT (0x3f) /* Bits to be processed */
+
+#define BMX_SPI_PEEK_DATA (0xffff) /* Data mask */
+
+#define BMX_SPI_IO_DATA (0xffff) /* Data mask */
+
+#define BMX_SPI_TXHOLD_DATA (0xffff) /* Data mask */
+
+#endif /* __ARCH_ARM64_SRC_BCM2711_AUX_H */
diff --git a/arch/arm64/src/bcm2711/hardware/bcm2711_bsc.h b/arch/arm64/src/bcm2711/hardware/bcm2711_bsc.h
new file mode 100644
index 0000000000..5863fda958
--- /dev/null
+++ b/arch/arm64/src/bcm2711/hardware/bcm2711_bsc.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/hardware/bcm2711_bsc.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_BSC_H
+#define __ARCH_ARM64_SRC_BCM2711_BSC_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "bcm2711_memmap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* BSC interface base addresses */
+
+#define BCM_BSC0 \
+ (BCM_PERIPHERAL_BASEADDR + 0x000205000) /* BSC/I2C interface 0 */
+#define BCM_BSC1 \
+ (BCM_PERIPHERAL_BASEADDR + 0x000804000) /* BSC/I2C interface 1 */
+#define BCM_BSC3 \
+ (BCM_PERIPHERAL_BASEADDR + 0x000205600) /* BSC/I2C interface 2 */
+#define BCM_BSC4 \
+ (BCM_PERIPHERAL_BASEADDR + 0x000205800) /* BSC/I2C interface 3 */
+#define BCM_BSC5 \
+ (BCM_PERIPHERAL_BASEADDR + 0x000205a80) /* BSC/I2C interface 4 */
+#define BCM_BSC6 \
+ (BCM_PERIPHERAL_BASEADDR + 0x000205c00) /* BSC/I2C interface 5 */
+
+/* Number of BSC interfaces. */
+
+#define BCM_BSCS_NUM 7
+
+/* BSC register offsets */
+
+#define BCM_BSC_C_OFFSET 0x00 /* Control */
+#define BCM_BSC_S_OFFSET 0x04 /* Status */
+#define BCM_BSC_DLEN_OFFSET 0x08 /* Data Length */
+#define BCM_BSC_A_OFFSET 0x0c /* Slave Address */
+#define BCM_BSC_FIFO_OFFSET 0x10 /* Data FIFO */
+#define BCM_BSC_DIV_OFFSET 0x14 /* Clock Divider */
+#define BCM_BSC_DEL_OFFSET 0x18 /* Data Delay */
+#define BCM_BSC_CLKT_OFFSET 0x1c /* Clock Stretch Timeout */
+
+/* BSC registers */
+
+#define BCM_BSC_C(reg) (reg + BCM_BSC_C_OFFSET) /* Control */
+#define BCM_BSC_S(reg) (reg + BCM_BSC_S_OFFSET) /* Status */
+#define BCM_BSC_DLEN(reg) (reg + BCM_BSC_DLEN_OFFSET) /* Data Length */
+#define BCM_BSC_A(reg) (reg + BCM_BSC_A_OFFSET) /* Slave Address */
+#define BCM_BSC_FIFO(reg) (reg + BCM_BSC_FIFO_OFFSET) /* Data FIFO */
+#define BCM_BSC_DIV(reg) (reg + BCM_BSC_DIV_OFFSET) /* Clock Divider */
+#define BCM_BSC_DEL(reg) (reg + BCM_BSC_DEL_OFFSET) /* Data Delay */
+#define BCM_BSC_CLKT(reg) \
+ (reg + BCM_BSC_CLKT_OFFSET) /* Clock Stretch Timeout */
+
+/* BSC register bit definitions */
+
+#define BCM_BSC_C_I2CEN (1 << 15) /* Enable I2C */
+#define BCM_BSC_C_INTR (1 << 10) /* Interrupt on RX */
+#define BCM_BSC_C_INTT (1 << 9) /* Interrupt on TX */
+#define BCM_BSC_C_INTD (1 << 8) /* Interrupt on DONE */
+#define BCM_BSC_C_ST (1 << 7) /* Start transfer */
+#define BCM_BSC_C_CLRMSK (0x3 << 3) /* FIFO clear mask */
+#define BCM_BSC_C_NOCLR (0 << 3) /* No clear action */
+#define BCM_BSC_C_CLRFIFO (1 << 3) /* Clear FIFO one shot */
+#define BCM_BSC_C_READ (1 << 0) /* Read = 1, Write = 0 */
+
+#define BCM_BSC_S_CLKT (1 << 9) /* CLK stretch detected */
+#define BCM_BSC_S_ERR (1 << 8) /* ACK error */
+#define BCM_BSC_S_RXF (1 << 7) /* FIFO full */
+#define BCM_BSC_S_TXE (1 << 6) /* FIFO empty */
+#define BCM_BSC_S_RXD (1 << 5) /* FIFO has data */
+#define BCM_BSC_S_TXD (1 << 4) /* FIFO can accept data */
+#define BCM_BSC_S_RXR (1 << 3) /* FIFO needs reading */
+#define BCM_BSC_S_TXW (1 << 2) /* FIFO needs writing */
+#define BCM_BSC_S_DONE (1 << 1) /* Transfer done */
+#define BCM_BSC_S_TA (1 << 0) /* Transfer active */
+
+#define BCM_BSC_DLEN_MASK (0xffff) /* Data length mask */
+
+#define BCM_BSC_A_ADDR (0x7f) /* Slave address */
+
+#define BCM_BSC_FIFO_DATA (0xff) /* FIFO data (RW) */
+
+#define BCM_BSC_DIV_CDIV (0xffff) /* Clock divider */
+
+#define BCM_BSC_DEL_FEDL (0xffff << 16) /* Falling edge delay */
+#define BCM_BSC_DEL_REDL (0xffff) /* Rising edge delay */
+
+#define BCM_BSC_CLKT_TOUT (0xffff) /* Clock stretch timeout value */
+
+#endif /* __ARCH_ARM64_SRC_BCM2711_BSC_H */
diff --git a/arch/arm64/src/bcm2711/hardware/bcm2711_dma.h b/arch/arm64/src/bcm2711/hardware/bcm2711_dma.h
new file mode 100644
index 0000000000..f967621ecf
--- /dev/null
+++ b/arch/arm64/src/bcm2711/hardware/bcm2711_dma.h
@@ -0,0 +1,280 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/hardware/bcm2711_dma.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_DMA_H
+#define __ARCH_ARM64_SRC_BCM2711_DMA_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "bcm2711_memmap.h"
+#include
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* DMA channel offsets */
+
+#define BCM_DMA_CH0_OFFSET 0x000
+#define BCM_DMA_CH1_OFFSET 0x100
+#define BCM_DMA_CH2_OFFSET 0x200
+#define BCM_DMA_CH3_OFFSET 0x300
+#define BCM_DMA_CH4_OFFSET 0x400
+#define BCM_DMA_CH5_OFFSET 0x500
+#define BCM_DMA_CH6_OFFSET 0x600
+#define BCM_DMA_CH7_OFFSET 0x700
+#define BCM_DMA_CH8_OFFSET 0x800
+#define BCM_DMA_CH9_OFFSET 0x900
+#define BCM_DMA_CH10_OFFSET 0xa00
+#define BCM_DMA_CH11_OFFSET 0xb00
+#define BCM_DMA_CH12_OFFSET 0xc00
+#define BCM_DMA_CH13_OFFSET 0xd00
+#define BCM_DMA_CH14_OFFSET 0xe00
+#define BCM_DMA_CH15_OFFSET 0x000
+
+/* DMA channel addresses */
+
+#define BCM_DMA0 (BCM_DMA0_BASE + BCM_DMA_CH0_OFFSET)
+#define BCM_DMA1 (BCM_DMA0_BASE + BCM_DMA_CH1_OFFSET)
+#define BCM_DMA2 (BCM_DMA0_BASE + BCM_DMA_CH2_OFFSET)
+#define BCM_DMA3 (BCM_DMA0_BASE + BCM_DMA_CH3_OFFSET)
+#define BCM_DMA4 (BCM_DMA0_BASE + BCM_DMA_CH4_OFFSET)
+#define BCM_DMA5 (BCM_DMA0_BASE + BCM_DMA_CH5_OFFSET)
+#define BCM_DMA6 (BCM_DMA0_BASE + BCM_DMA_CH6_OFFSET)
+#define BCM_DMA7 (BCM_DMA0_BASE + BCM_DMA_CH7_OFFSET) /* Lite */
+#define BCM_DMA8 (BCM_DMA0_BASE + BCM_DMA_CH8_OFFSET) /* Lite */
+#define BCM_DMA9 (BCM_DMA0_BASE + BCM_DMA_CH9_OFFSET) /* Lite */
+#define BCM_DMA10 (BCM_DMA0_BASE + BCM_DMA_CH10_OFFSET) /* Lite */
+#define BCM_DMA11 (BCM_DMA0_BASE + BCM_DMA_CH11_OFFSET) /* DMA4 */
+#define BCM_DMA12 (BCM_DMA0_BASE + BCM_DMA_CH12_OFFSET) /* DMA4 */
+#define BCM_DMA13 (BCM_DMA0_BASE + BCM_DMA_CH13_OFFSET) /* DMA4 */
+#define BCM_DMA14 (BCM_DMA0_BASE + BCM_DMA_CH14_OFFSET) /* DMA4 */
+#define BCM_DMA15 (BCM_DMA15_BASE + BCM_DMA_CH15_OFFSET)
+
+/* DMA control block data structures */
+
+/* DMA control block definition */
+
+struct bcm2711_dma_cb_s
+{
+ _uint32_t ti; /* Transfer information */
+ _uint32_t source_ad; /* Source address */
+ _uint32_t dest_ad; /* Destination address */
+ _uint32_t txfr_len; /* Transfer length */
+ _uint32_t stride; /* 2D mode stride */
+ _uint32_t nextconbk; /* Next control block address */
+ _uint32_t _reserved1;
+ _uint32_t _reserved2;
+};
+
+/* DMA Lite control block definition */
+
+struct bcm2711_dmalite_cb_s
+{
+ _uint32_t ti; /* Transfer information */
+ _uint32_t source_ad; /* Source address */
+ _uint32_t dest_ad; /* Destination address */
+ _uint32_t txfr_len; /* Transfer length */
+ _uint32_t _reserved1;
+ _uint32_t nextconbk; /* Next control block address */
+ _uint32_t _reserved2;
+ _uint32_t _reserved3;
+};
+
+/* DMA 4 control block definition */
+
+struct bcm2711_dma4_cb_s
+{
+ _uint32_t ti; /* Transfer information */
+ _uint32_t src; /* Source address */
+ _uint32_t srci; /* Source information */
+ _uint32_t dest; /* Destination address */
+ _uint32_t desti; /* Destination information */
+ _uint32_t len; /* Transfer length */
+ _uint32_t nextconbk; /* Next control block address */
+ _uint32_t _reserved;
+};
+
+/* DMA registers offsets */
+
+#define BCM_DMA_CS_OFFSET 0x00 /* Control and status */
+#define BCM_DMA_CONBLK_AD_OFFSET 0x04 /* Control block address */
+#define BCM_DMA_DEBUG 0x020 /* Debug */
+
+/* TODO: Do I need to do base + offset for the above three for all 14
+ * channels?
+ */
+
+/* DMA registers */
+
+#define BCM_DMA_INT_STATUS (BCM_DMA0_BASE + 0xfe0) /* Interrupt status */
+#define BCM_DMA_INT_ENABLE (BCM_DMA0_BASE + 0xff0) /* Enable bits */
+
+/* DMA register bit definitions */
+
+#define BCM_DMA_CS_RESET (1 << 31) /* Channel reset */
+#define BCM_DMA_CS_ABORT (1 << 30) /* Abort DMA */
+#define BCM_DMA_CS_DISDEBUG (1 << 29) /* Disable debug pause */
+#define BCM_DMA_CS_WAIT (1 << 28) /* Wait for outstanding writes */
+#define BCM_DMA_CS_PANICPRIO (0xf << 20) /* AXI panic priority level */
+#define BCM_DMA_CS_PRIO (0xf << 16) /* AXI priority level */
+#define BCM_DMA_CS_ERROR (1 << 8) /* DMA error */
+#define BCM_DMA_CS_WAITING (1 << 6) /* Waiting for outstanding write */
+#define BCM_DMA_CS_DREQ_STOPS (1 << 5) /* DMA paused by DREQ */
+#define BCM_DMA_CS_PAUSED (1 << 4) /* DMA paused */
+#define BCM_DMA_CS_DREQ (1 << 3) /* Requesting = 1, no request = 0*/
+#define BCM_DMA_CS_INT (1 << 2) /* Interrupt status */
+#define BCM_DMA_CS_END (1 << 1) /* DMA end flag */
+#define BCM_DMA_CS_ACTIVE (1 << 0) /* Activate DMA (CB_ADDR non-zero) */
+
+#define BCM_DMA_TI_NOWIBURST (1 << 26) /* Wide writes not 2 beat burst */
+#define BCM_DMA_TI_WAITS (0x1f << 21) /* Add wait cycles mask */
+#define BCM_DMA_TI_PERMAP (0x1f << 16) /* Peripheral mapping mask */
+#define BCM_DMA_TI_BURSTLEN (0xf << 12) /* Burst transfer length */
+#define BCM_DMA_TI_SRC_IGNORE (1 << 11) /* Ignore reads */
+#define BCM_DMA_TI_SRC_DREQ (1 << 10) /* Control source reads with DREQ */
+#define BCM_DMA_TI_SRC_WIDTH (1 << 9) /* 1 = 128 bit, 0 = 32 bit */
+#define BCM_DMA_TI_SRC_INC (1 << 8) /* Increment src addr after read */
+#define BCM_DMA_TI_DEST_IGNORE (1 << 7) /* Ignore writes */
+#define BCM_DMA_TI_DEST_DREQ (1 << 6) /* Control dest writes with DREQ */
+#define BCM_DMA_TI_DEST_WIDTH (1 << 5) /* 1 = 128 bit, 0 = 32 bit */
+#define BCM_DMA_TI_DEST_INC (1 << 4) /* Increment destination address */
+#define BCM_DMA_TI_WAIT_RESP (1 << 3) /* Wait for write response */
+#define BCM_DMA_TI_TDMODE (1 << 1) /* 2D mode */
+#define BCM_DMA_TI_INTEN (1 << 0) /* Interrupt enable */
+
+#define BCM_DMA_TXFR_LEN_YLENGTH (0x3fff << 16) /* Y txfr len in 2D mode */
+#define BCM_DMA_TXFR_LEN_XLENGTH (0xffff) /* Transfer len in bytes */
+
+#define BCM_DMA_STRIDE_D_STRIDE (0xffff << 16) /* Dest stride in 2D mode */
+#define BCM_DMA_STRIDE_S_STRIDE (0xffff) /* Source stride in 2D mode */
+
+#define BCM_DMA_DEBUG_LITE (1 << 28) /* DMA lite */
+#define BCM_DMA_DEBUG_VERSION (0x7 << 25) /* DMA version number */
+#define BCM_DMA_DEBUG_DMA_STATE (0x1ff << 16) /* DMA state machine state */
+#define BCM_DMA_DEBUG_DMA_ID (0xff << 8) /* DMA AXI ID */
+#define BCM_DMA_DEBUG_OUTSWRITES (0xf << 4) /* Outstanding writes count */
+#define BCM_DMA_DEBUG_READ_ERROR (1 << 2) /* Slave read response error */
+#define BCM_DMA_DEBUG_FIFO_ERROR (1 << 1) /* FIFO error */
+#define BCM_DMA_DEBUG_RDLASTNSET_ERR (1 << 0) /* Read last not set error */
+
+/* DMA4 registers; TODO: how to differentiate from other types? */
+
+#define BCM_DMA_CS_HALT (1 << 31) /* Halt current DMA transfer */
+#define BCM_DMA_CS_OUTSTRANS (1 << 25) /* Outstanding transactions */
+#define BCM_DMA_CS_DMABUSY (1 << 24) /* DMA4 is busy */
+#define BCM_DMA_CS_PANICQOS (0xf << 20) /* AXI panic QOS level */
+#define BCM_DMA_CS_QOS (0xf << 16) /* AXI QOS level */
+#define BCM_DMA4_CS_ERROR (1 << 10) /* AXI QOS level */
+#define BCM_DMA4_CS_WAITING (1 << 7) /* Waiting for outstanding writes */
+#define BCM_DMA4_CS_DREQ_STOPS (1 << 6) /* Paused by DREQ */
+#define BCM_DMA_CS_WR_PAUSED (1 << 5) /* Write paused */
+#define BCM_DMA_CS_RD_PAUSED (1 << 4) /* Read paused */
+#define BCM_DMA4_CS_DREQ (1 << 3) /* DREQ state */
+
+#define BCM_DMA4_DEBUG_VERSION (0xf << 28) /* DMA version number */
+#define BCM_DMA4_DEBUG_ID (0xf << 24) /* DMA ID */
+#define BCM_DMA4_DEBUG_RESET (1 << 23) /* DMA reset */
+#define BCM_DMA4_DEBUG_W_STATE (0xf << 18) /* Write state machine state */
+#define BCM_DMA4_DEBUG_R_STATE (0xf << 14) /* Read state machine state */
+#define BCM_DMA4_DEBUG_DIS_CLKGATE (1 << 11) /* Disable clk gating logic */
+#define BCM_DMA4_DEBUG_ABORT_ERR (1 << 10) /* Abort on error */
+#define BCM_DMA4_DEBUG_HALT_ERR (1 << 9) /* Halt on error */
+#define BCM_DMA4_DEBUG_INT_ERR (1 << 8) /* Interrupt on error */
+#define BCM_DMA4_DEBUG_READ_CB_ERR (1 << 3) /* Slave error on CB read */
+#define BCM_DMA4_DEBUG_READ_ERROR (1 << 2) /* Slave read response error */
+#define BCM_DMA4_DEBUG_FIFO_ERROR (1 << 1) /* FIFO error */
+#define BCM_DMA4_DEBUG_WRITE_ERROR (1 << 0) /* Slave write response error */
+
+#define BCM_DMA4_TI_D_WAITS (0xff << 24) /* Write wait cycles */
+#define BCM_DMA4_TI_S_WAITS (0xff << 16) /* Read wait cycles */
+#define BCM_DMA4_TI_D_DREQ (1 << 15) /* Control dest writes with DREQ */
+#define BCM_DMA4_TI_S_DREQ (1 << 14) /* Control src reads with DREQ */
+#define BCM_DMA4_TI_S_PERMAP (0x1f << 9) /* Peripheral mapping */
+#define BCM_DMA4_TI_WAIT_RD_RESP (1 << 3) /* Wait for read response */
+#define BCM_DMA4_TI_WAIT_RESP (1 << 2) /* Wait for rite response */
+#define BCM_DMA4_TI_TDMODE (1 << 1) /* 2D mode transfer */
+#define BCM_DMA4_TI_INTEN (1 << 0) /* Interrupt enable */
+
+#define BCM_DMA4_SRCI_STRIDE (0xffff << 16) /* Source stride */
+#define BCM_DMA4_SRCI_IGNORE (1 << 15) /* Ignore reads */
+#define BCM_DMA4_SRCI_SIZE (0x3 << 13) /* Source transfer width */
+#define BCM_DMA4_SRCI_INC (1 << 12) /* Increment source address */
+#define BCM_DMA4_SRCI_BURSTLEN (0xf << 8) /* Burst transfer length */
+#define BCM_DMA4_SRCI_ADDR (0xff) /* High bits of source address */
+
+#define BCM_DMA4_DESTI_STRIDE (0xffff << 16) /* Destination stride */
+#define BCM_DMA4_DESTI_IGNORE (1 << 15) /* Ignore writes */
+#define BCM_DMA4_DESTI_SIZE (0x3 << 13) /* Destination transfer width */
+#define BCM_DMA4_DESTI_INC (1 << 12) /* Increment dest address */
+#define BCM_DMA4_DESTI_BURSTLEN (0xf << 8) /* Burst transfer length */
+#define BCM_DMA4_DESTI_ADDR (0xff) /* High bits of dest address */
+
+#define BCM_DMA4_LEN_YLENGTH (0x3fff << 16) /* Y transfer len in 2D mode */
+#define BCM_DMA4_LEN_XLENGTH (0xffff) /* X transfer len in bytes */
+
+#define BCM_DMA4_DEBUG2_OUTSREADS (0x1ff << 16) /* Outstanding read count */
+#define BCM_DMA4_DEBUG2_OUTSWRITE (0xff) /* Outstanding write count */
+
+/* Interrupt status register bit definitions */
+
+#define BCM_DMA_INT15 (1 << 15) /* Interrupt status of DMA15 */
+#define BCM_DMA_INT14 (1 << 14) /* Interrupt status of DMA14 */
+#define BCM_DMA_INT13 (1 << 13) /* Interrupt status of DMA13 */
+#define BCM_DMA_INT12 (1 << 12) /* Interrupt status of DMA12 */
+#define BCM_DMA_INT11 (1 << 11) /* Interrupt status of DMA11 */
+#define BCM_DMA_INT10 (1 << 10) /* Interrupt status of DMA10 */
+#define BCM_DMA_INT9 (1 << 9) /* Interrupt status of DMA9 */
+#define BCM_DMA_INT8 (1 << 8) /* Interrupt status of DMA8 */
+#define BCM_DMA_INT7 (1 << 7) /* Interrupt status of DMA7 */
+#define BCM_DMA_INT6 (1 << 6) /* Interrupt status of DMA6 */
+#define BCM_DMA_INT5 (1 << 5) /* Interrupt status of DMA5 */
+#define BCM_DMA_INT4 (1 << 4) /* Interrupt status of DMA4 */
+#define BCM_DMA_INT2 (1 << 2) /* Interrupt status of DMA2 */
+#define BCM_DMA_INT1 (1 << 1) /* Interrupt status of DMA1 */
+#define BCM_DMA_INT0 (1 << 0) /* Interrupt status of DMA0 */
+
+/* Enable register bit definitions */
+
+#define BCM_DMA_ENABLE_PAGELITE (0xf << 28) /* Set 1G SDRAM page */
+#define BCM_DMA_ENABLE_PAGE (0xf << 24) /* Set 1G SDRAM page */
+#define BCM_DMA_ENABLE_EN14 (1 << 14) /* Enable DMA14 */
+#define BCM_DMA_ENABLE_EN13 (1 << 13) /* Enable DMA13 */
+#define BCM_DMA_ENABLE_EN12 (1 << 12) /* Enable DMA12 */
+#define BCM_DMA_ENABLE_EN11 (1 << 11) /* Enable DMA11 */
+#define BCM_DMA_ENABLE_EN10 (1 << 10) /* Enable DMA10 */
+#define BCM_DMA_ENABLE_EN9 (1 << 9) /* Enable DMA9 */
+#define BCM_DMA_ENABLE_EN8 (1 << 8) /* Enable DMA8 */
+#define BCM_DMA_ENABLE_EN7 (1 << 7) /* Enable DMA7 */
+#define BCM_DMA_ENABLE_EN6 (1 << 6) /* Enable DMA6 */
+#define BCM_DMA_ENABLE_EN5 (1 << 5) /* Enable DMA5 */
+#define BCM_DMA_ENABLE_EN4 (1 << 4) /* Enable DMA4 */
+#define BCM_DMA_ENABLE_EN3 (1 << 3) /* Enable DMA3 */
+#define BCM_DMA_ENABLE_EN2 (1 << 2) /* Enable DMA2 */
+#define BCM_DMA_ENABLE_EN1 (1 << 1) /* Enable DMA1 */
+#define BCM_DMA_ENABLE_EN0 (1 << 0) /* Enable DMA0 */
+
+/* TODO: Section 4.2.1.3 Peripheral DREQ Signals of Datasheet */
+
+#endif /* __ARCH_ARM64_SRC_BCM2711_DMA_H */
diff --git a/arch/arm64/src/bcm2711/hardware/bcm2711_gpclk.h b/arch/arm64/src/bcm2711/hardware/bcm2711_gpclk.h
new file mode 100644
index 0000000000..7778ea9957
--- /dev/null
+++ b/arch/arm64/src/bcm2711/hardware/bcm2711_gpclk.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/hardware/bcm2711_gpclk.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_GPCLK_H
+#define __ARCH_ARM64_SRC_BCM2711_GPCLK_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "bcm2711_memmap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* General purpose clock register offsets */
+
+#define BCM_GPCLK_CM_GP0CTL_OFFSET 0x70
+#define BCM_GPCLK_CM_GP0DIV_OFFSET 0x74
+#define BCM_GPCLK_CM_GP1CTL_OFFSET 0x78
+#define BCM_GPCLK_CM_GP1DIV_OFFSET 0x7c
+#define BCM_GPCLK_CM_GP2CTL_OFFSET 0x80
+#define BCM_GPCLK_CM_GP2DIV_OFFSET 0x84
+
+/* General purpose clock registers */
+
+#define BCM_GPCLK_CM_GP0CTL (BCM_GPCLK_BASEADDR + BCM_GPCLK_CM_GP0CTL_OFFSET)
+#define BCM_GPCLK_CM_GP0DIV (BCM_GPCLK_BASEADDR + BCM_GPCLK_CM_GP0DIV_OFFSET)
+#define BCM_GPCLK_CM_GP1CTL (BCM_GPCLK_BASEADDR + BCM_GPCLK_CM_GP1CTL_OFFSET)
+#define BCM_GPCLK_CM_GP1DIV (BCM_GPCLK_BASEADDR + BCM_GPCLK_CM_GP1DIV_OFFSET)
+#define BCM_GPCLK_CM_GP2CTL (BCM_GPCLK_BASEADDR + BCM_GPCLK_CM_GP2CTL_OFFSET)
+#define BCM_GPCLK_CM_GP2DIV (BCM_GPCLK_BASEADDR + BCM_GPCLK_CM_GP2DIV_OFFSET)
+
+/* General purpose clock bit definitions */
+
+#define BCM_GPCLK_PASSWD 0x5a /* Clock manager password */
+
+#define BCM_GPCLK_CM_CTL_PASSWD (0xff << 24) /* CLK manager password mask */
+#define BCM_GPCLK_CM_CTL_MASH (0x3 << 9) /* MASH control */
+#define BCM_GPCLK_MASH_INTDIV (0 << 9) /* Integer division */
+#define BCM_GPCLK_MASH_STG1 (1 << 9) /* One stage MASH */
+#define BCM_GPCLK_MASH_STG2 (2 << 9) /* Two stage MASH */
+#define BCM_GPCLK_MASH_STG3 (3 << 9) /* Three stage MASH */
+#define BCM_GPCLK_CM_CTL_FLIP (1 << 8) /* Invert CLK gen output */
+#define BCM_GPCLK_CM_CTL_BUSY (1 << 7) /* CLK gen running */
+#define BCM_GPCLK_CM_CTL_KILL (1 << 5) /* Kill CLK gen */
+#define BCM_GPCLK_CM_CTL_ENAB (1 << 4) /* Enable CLK gen */
+#define BCM_GPCLK_CM_CTL_SRC (0xf) /* Clock source */
+#define BCM_GPCLK_CLKSRC_GND (0) /* GND */
+#define BCM_GPCLK_CLKSRC_OSC (1) /* Oscillator */
+#define BCM_GPCLK_CLKSRC_DBG0 (2) /* testdebug0 */
+#define BCM_GPCLK_CLKSRC_DBG1 (3) /* testdebug1 */
+#define BCM_GPCLK_CLKSRC_PLLA (4) /* PLLA per */
+#define BCM_GPCLK_CLKSRC_PLLC (5) /* PLLC per */
+#define BCM_GPCLK_CLKSRC_PLLD (6) /* PLLD per */
+#define BCM_GPCLK_CLKSRC_HDMI (7) /* HDMI auxiliary */
+
+#define BCM_GPCLK_CM_DIV_PASSWD (0xff << 24) /* CLK manager password mask */
+#define BCM_GPCLK_CM_DIV_DIVI (0xfff << 12) /* Integer part of divisor */
+#define BCM_GPCLK_CM_DIV_DIVF (0xfff) /* Fractional part of divisor */
+
+#endif /* __ARCH_ARM64_SRC_BCM2711_GPCLK_H */
diff --git a/arch/arm64/src/bcm2711/hardware/bcm2711_gpio.h b/arch/arm64/src/bcm2711/hardware/bcm2711_gpio.h
new file mode 100644
index 0000000000..49eb54c1ec
--- /dev/null
+++ b/arch/arm64/src/bcm2711/hardware/bcm2711_gpio.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/hardware/bcm2711_gpio.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_GPIO_H
+#define __ARCH_ARM64_SRC_BCM2711_GPIO_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "bcm2711_memmap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BCM_GPIO_NUM 58 /* Number of GPIO pins */
+
+/* GPIO register offset definitions */
+
+#define BCM_GPIO_GPFSEL0_OFFSET 0x00 /* GPIO function select 0 */
+#define BCM_GPIO_GPFSEL1_OFFSET 0x04 /* GPIO function select 1 */
+#define BCM_GPIO_GPFSEL2_OFFSET 0x08 /* GPIO function select 2 */
+#define BCM_GPIO_GPFSEL3_OFFSET 0x0c /* GPIO function select 3 */
+#define BCM_GPIO_GPFSEL4_OFFSET 0x10 /* GPIO function select 4 */
+#define BCM_GPIO_GPFSEL5_OFFSET 0x14 /* GPIO function select 5 */
+#define BCM_GPIO_GPSET0_OFFSET 0x1c /* GPIO pin output set 0 */
+#define BCM_GPIO_GPSET1_OFFSET 0x20 /* GPIO pin output set 1 */
+#define BCM_GPIO_GPCLR0_OFFSET 0x28 /* GPIO pin output clear 0 */
+#define BCM_GPIO_GPCLR1_OFFSET 0x2c /* GPIO pin output clear 1 */
+#define BCM_GPIO_GPLEV0_OFFSET 0x34 /* GPIO pin level 0 */
+#define BCM_GPIO_GPLEV1_OFFSET 0x38 /* GPIO pin level 1 */
+
+#define BCM_GPIO_GPEDS0_OFFSET 0x40 /* GPIO pin event detect status 0 */
+#define BCM_GPIO_GPEDS1_OFFSET 0x44 /* GPIO pin event detect status 1 */
+#define BCM_GPIO_GPREN0_OFFSET 0x4c /* GPIO pin rise edge detect enable 0 */
+#define BCM_GPIO_GPREN1_OFFSET 0x50 /* GPIO pin rise edge detect enable 1 */
+#define BCM_GPIO_GPFEN0_OFFSET 0x58 /* GPIO pin fall edge detect enable 0 */
+#define BCM_GPIO_GPFEN1_OFFSET 0x5c /* GPIO pin fall edge detect enable 1 */
+#define BCM_GPIO_GPHEN0_OFFSET 0x64 /* GPIO pin high detect enable 0 */
+#define BCM_GPIO_GPHEN1_OFFSET 0x68 /* GPIO pin high detect enable 1 */
+#define BCM_GPIO_GPLEN0_OFFSET 0x70 /* GPIO pin low detect enable 0 */
+#define BCM_GPIO_GPLEN1_OFFSET 0x74 /* GPIO pin low detect enable 1 */
+#define BCM_GPIO_GPAREN0_OFFSET 0x7c /* GPIO pin async rise edge detect 0 */
+#define BCM_GPIO_GPAREN1_OFFSET 0x80 /* GPIO pin async rise edge detect 1 */
+#define BCM_GPIO_GPAFEN0_OFFSET 0x88 /* GPIO pin async fall edge detect 0 */
+#define BCM_GPIO_GPAFEN1_OFFSET 0x8c /* GPIO pin async fall edge detect 1 */
+
+#define BCM_GPIO_PUP_PDN_REG0_OFFSET 0xe4 /* GPIO pullup/down reg 0 */
+#define BCM_GPIO_PUP_PDN_REG1_OFFSET 0xe8 /* GPIO pullup/down reg 1 */
+#define BCM_GPIO_PUP_PDN_REG2_OFFSET 0xec /* GPIO pullup/down reg 2 */
+#define BCM_GPIO_PUP_PDN_REG3_OFFSET 0xf0 /* GPIO pullup/down reg 3 */
+
+/* GPIO register address definitions */
+
+#define _BCM_GP_REG(reg) (BCM_GPIO_BASEADDR + (reg))
+
+#define BCM_GPIO_GPFSEL0 _BCM_GP_REG(BCM_GPIO_GPFSEL0_OFFSET)
+#define BCM_GPIO_GPFSEL1 _BCM_GP_REG(BCM_GPIO_GPFSEL1_OFFSET)
+#define BCM_GPIO_GPFSEL2 _BCM_GP_REG(BCM_GPIO_GPFSEL2_OFFSET)
+#define BCM_GPIO_GPFSEL3 _BCM_GP_REG(BCM_GPIO_GPFSEL3_OFFSET)
+#define BCM_GPIO_GPFSEL4 _BCM_GP_REG(BCM_GPIO_GPFSEL4_OFFSET)
+#define BCM_GPIO_GPFSEL5 _BCM_GP_REG(BCM_GPIO_GPFSEL5_OFFSET)
+#define BCM_GPIO_GPSET0 _BCM_GP_REG(BCM_GPIO_GPSET0_OFFSET)
+#define BCM_GPIO_GPSET1 _BCM_GP_REG(BCM_GPIO_GPSET1_OFFSET)
+#define BCM_GPIO_GPCLR0 _BCM_GP_REG(BCM_GPIO_GPCLR0_OFFSET)
+#define BCM_GPIO_GPCLR1 _BCM_GP_REG(BCM_GPIO_GPCLR1_OFFSET)
+#define BCM_GPIO_GPLEV0 _BCM_GP_REG(BCM_GPIO_GPLEV0_OFFSET)
+#define BCM_GPIO_GPLEV1 _BCM_GP_REG(BCM_GPIO_GPLEV1_OFFSET)
+#define BCM_GPIO_GPEDS0 _BCM_GP_REG(BCM_GPIO_GPEDS0_OFFSET)
+#define BCM_GPIO_GPEDS1 _BCM_GP_REG(BCM_GPIO_GPEDS1_OFFSET)
+#define BCM_GPIO_GPREN0 _BCM_GP_REG(BCM_GPIO_GPREN0_OFFSET)
+#define BCM_GPIO_GPREN1 _BCM_GP_REG(BCM_GPIO_GPREN1_OFFSET)
+#define BCM_GPIO_GPFEN0 _BCM_GP_REG(BCM_GPIO_GPFEN0_OFFSET)
+#define BCM_GPIO_GPFEN1 _BCM_GP_REG(BCM_GPIO_GPFEN1_OFFSET)
+#define BCM_GPIO_GPHEN0 _BCM_GP_REG(BCM_GPIO_GPHEN0_OFFSET)
+#define BCM_GPIO_GPHEN1 _BCM_GP_REG(BCM_GPIO_GPHEN1_OFFSET)
+#define BCM_GPIO_GPLEN0 _BCM_GP_REG(BCM_GPIO_GPLEN0_OFFSET)
+#define BCM_GPIO_GPLEN1 _BCM_GP_REG(BCM_GPIO_GPLEN1_OFFSET)
+#define BCM_GPIO_GPAREN0 _BCM_GP_REG(BCM_GPIO_GPAREN0_OFFSET)
+#define BCM_GPIO_GPAREN1 _BCM_GP_REG(BCM_GPIO_GPAREN1_OFFSET)
+#define BCM_GPIO_GPAFEN0 _BCM_GP_REG(BCM_GPIO_GPAFEN0_OFFSET)
+#define BCM_GPIO_GPAFEN1 _BCM_GP_REG(BCM_GPIO_GPAFEN1_OFFSET)
+#define BCM_GPIO_PUP_PDN_CNTRL_REG0 _BCM_GP_REG(BCM_GPIO_PUP_PDN_REG0_OFFSET)
+#define BCM_GPIO_PUP_PDN_CNTRL_REG1 _BCM_GP_REG(BCM_GPIO_PUP_PDN_REG1_OFFSET)
+#define BCM_GPIO_PUP_PDN_CNTRL_REG2 _BCM_GP_REG(BCM_GPIO_PUP_PDN_REG2_OFFSET)
+#define BCM_GPIO_PUP_PDN_CNTRL_REG3 _BCM_GP_REG(BCM_GPIO_PUP_PDN_REG3_OFFSET)
+
+/* GPIO register bit definitions */
+
+#define BCM_GPIO_FS_IN 0x0 /* Pin is input */
+#define BCM_GPIO_FS_OUT 0x1 /* Pin is output */
+#define BCM_GPIO_FS_ALT0 0x4 /* Pin is alternate func 0 */
+#define BCM_GPIO_FS_ALT1 0x5 /* Pin is alternate func 1 */
+#define BCM_GPIO_FS_ALT2 0x6 /* Pin is alternate func 2 */
+#define BCM_GPIO_FS_ALT3 0x7 /* Pin is alternate func 3 */
+#define BCM_GPIO_FS_ALT4 0x3 /* Pin is alternate func 4 */
+#define BCM_GPIO_FS_ALT5 0x2 /* Pin is alternate func 5 */
+
+/* Any register that does not have specific bit masks listed here is omitted
+ * because the control is done via a single bit, which corresponds bit N to
+ * pin N. It is up to the programmer to read the data sheet to know whether
+ * to use register 0, 1, ..., n.
+ */
+
+#define BCM_GPIO_NORES 0x0 /* No resistor */
+#define BCM_GPIO_PULLUP 0x1 /* Pull-up resistor */
+#define BCM_GPIO_PULLDOWN 0x2 /* Pull-down resistor */
+
+/* TODO: how to encode alternative function table to preproc definitions? */
+
+#endif // __ARCH_ARM64_SRC_BCM2711_GPIO_H
diff --git a/arch/arm64/src/bcm2711/hardware/bcm2711_irq.h b/arch/arm64/src/bcm2711/hardware/bcm2711_irq.h
new file mode 100644
index 0000000000..70315a498a
--- /dev/null
+++ b/arch/arm64/src/bcm2711/hardware/bcm2711_irq.h
@@ -0,0 +1,608 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/hardware/bcm2711_irq.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_IRQ_H
+#define __ARCH_ARM64_SRC_BCM2711_IRQ_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "bcm2711_memmap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* ARM_LOCAL interrupts */
+
+/* ARMC interrupts */
+
+#define BCM_IRQ_ARMC_TIMER 0 /* Timer */
+#define BCM_IRQ_ARMC_MAILBOX 1 /* Mailbox */
+#define BCM_IRQ_ARMC_DOORBELL0 2 /* Doorbell 0 */
+#define BCM_IRQ_ARMC_DOORBELL1 3 /* Doorbell 1 */
+#define BCM_IRQ_ARMC_VPU0HALT 4 /* VPU 0 halted */
+#define BCM_IRQ_ARMC_VPU1HALT 5 /* VPU 1 halted */
+#define BCM_IRQ_ARMC_ARMADDRERR 6 /* ARM address error */
+#define BCM_IRQ_ARMC_ARMAXIERR 7 /* ARM AXI error */
+#define BCM_IRQ_ARMC_SWI0 8 /* Software interrupt 0 */
+#define BCM_IRQ_ARMC_SWI1 9 /* Software interrupt 1 */
+#define BCM_IRQ_ARMC_SWI2 10 /* Software interrupt 2 */
+#define BCM_IRQ_ARMC_SWI3 11 /* Software interrupt 3 */
+#define BCM_IRQ_ARMC_SWI4 12 /* Software interrupt 4 */
+#define BCM_IRQ_ARMC_SWI5 13 /* Software interrupt 5 */
+#define BCM_IRQ_ARMC_SWI6 14 /* Software interrupt 6 */
+#define BCM_IRQ_ARMC_SWI7 15 /* Software interrupt 7 */
+
+/* VideoCore interrupts */
+
+#define BCM_IRQ_VC_TIMER0 0
+#define BCM_IRQ_VC_TIMER1 1
+#define BCM_IRQ_VC_TIMER2 2
+#define BCM_IRQ_VC_TIMER3 3
+#define BCM_IRQ_VC_H2640 4
+#define BCM_IRQ_VC_H2641 5
+#define BCM_IRQ_VC_H2642 6
+#define BCM_IRQ_VC_JPEG 7
+#define BCM_IRQ_VC_ISP 8
+#define BCM_IRQ_VC_USB 9
+#define BCM_IRQ_VC_V3D 10
+#define BCM_IRQ_VC_TRANSPOSE 11
+#define BCM_IRQ_VC_MCSYNC0 12
+#define BCM_IRQ_VC_MCSYNC1 13
+#define BCM_IRQ_VC_MCSYNC2 14
+#define BCM_IRQ_VC_MCSYNC3 15
+#define BCM_IRQ_VC_DMA0 16
+#define BCM_IRQ_VC_DMA1 17
+#define BCM_IRQ_VC_DMA2 18
+#define BCM_IRQ_VC_DMA3 19
+#define BCM_IRQ_VC_DMA4 20
+#define BCM_IRQ_VC_DMA5 21
+#define BCM_IRQ_VC_DMA6 22
+#define BCM_IRQ_VC_DMA7N8 23
+#define BCM_IRQ_VC_DMA9N10 24
+#define BCM_IRQ_VC_DMA11 25
+#define BCM_IRQ_VC_DMA12 26
+#define BCM_IRQ_VC_DMA13 27
+#define BCM_IRQ_VC_DMA14 28
+#define BCM_IRQ_VC_AUX 29
+#define BCM_IRQ_VC_ARM 30
+#define BCM_IRQ_VC_DMA15 31
+#define BCM_IRQ_VC_HDMICEC 32
+#define BCM_IRQ_VC_HVS 33
+#define BCM_IRQ_VC_RPIVID 34
+#define BCM_IRQ_VC_SDC 35
+#define BCM_IRQ_VC_DSI0 36
+#define BCM_IRQ_VC_PIXVLV2 37
+#define BCM_IRQ_VC_CAM0 38
+#define BCM_IRQ_VC_CAM1 39
+#define BCM_IRQ_VC_HDMI0 40
+#define BCM_IRQ_VC_HDMI1 41
+#define BCM_IRQ_VC_PIXVLV3 42
+#define BCM_IRQ_VC_SPIBSCSLV 43
+#define BCM_IRQ_VC_DSI1 44
+#define BCM_IRQ_VC_PXLVLV0 45
+#define BCM_IRQ_VC_PXLVLV1N4 46
+#define BCM_IRQ_VC_CPR 47
+#define BCM_IRQ_VC_SMI 48
+#define BCM_IRQ_VC_GPIO0 49
+#define BCM_IRQ_VC_GPIO1 50
+#define BCM_IRQ_VC_GPIO2 51
+#define BCM_IRQ_VC_GPIO3 52
+#define BCM_IRQ_VC_I2C 53
+#define BCM_IRQ_VC_SPI 54
+#define BCM_IRQ_VC_PCMI2S 55
+#define BCM_IRQ_VC_SDHOST 56
+#define BCM_IRQ_VC_PL011UART 57
+#define BCM_IRQ_VC_ETHPCIE 58
+#define BCM_IRQ_VC_VEC 59
+#define BCM_IRQ_VC_CPG 60
+#define BCM_IRQ_VC_RNG 61
+#define BCM_IRQ_VC_EMMC 62
+#define BCM_IRQ_VC_ETHPCIESEC 63
+
+/* TODO: what about PACTL_CS address section 6.2.4? */
+
+/* ETH_PCIe interrupts */
+
+#define BCM_IRQ_ETH_AVS 9
+#define BCM_IRQ_ETH_PCIE0_INTA 15
+#define BCM_IRQ_ETH_PCIE0_INTB 16
+#define BCM_IRQ_ETH_PCIE0_INTC 17
+#define BCM_IRQ_ETH_PCIE0_INTD 18
+#define BCM_IRQ_ETH_PCIE0_MSI 20
+#define BCM_IRQ_ETH_GENET0_A 29
+#define BCM_IRQ_ETH_GENET0_B 30
+#define BCM_IRQ_ETH_USB0_XHCI0 48
+
+/* ARM_LOCAL interrupt register offsets */
+
+#define BCM_IRQ_ARMLOCAL_ARM_CONTROL_OFFSET 0x00
+#define BCM_IRQ_ARMLOCAL_CORE_IRQ_CONTROL_OFFSET 0x0c
+#define BCM_IRQ_ARMLOCAL_PMU_CONTROL_SET_OFFSET 0x10
+#define BCM_IRQ_ARMLOCAL_PMU_CONTROL_CLR_OFFSET 0x14
+#define BCM_IRQ_ARMLOCAL_PERI_IRQ_ROUTE0_OFFSET 0x24
+#define BCM_IRQ_ARMLOCAL_AXI_QUIET_TIME_OFFSET 0x30
+#define BCM_IRQ_ARMLOCAL_LOCAL_TIMER_CONTROL_OFFSET 0x34
+#define BCM_IRQ_ARMLOCAL_LOCAL_TIMER_IRQ_OFFSET 0x38
+#define BCM_IRQ_ARMLOCAL_TIMER_CNTRL0_OFFSET 0x40
+#define BCM_IRQ_ARMLOCAL_TIMER_CNTRL1_OFFSET 0x44
+#define BCM_IRQ_ARMLOCAL_TIMER_CNTRL2_OFFSET 0x48
+#define BCM_IRQ_ARMLOCAL_TIMER_CNTRL3_OFFSET 0x4c
+#define BCM_IRQ_ARMLOCAL_MAILBOX_CNTRL0_OFFSET 0x50
+#define BCM_IRQ_ARMLOCAL_MAILBOX_CNTRL1_OFFSET 0x54
+#define BCM_IRQ_ARMLOCAL_MAILBOX_CNTRL2_OFFSET 0x58
+#define BCM_IRQ_ARMLOCAL_MAILBOX_CNTRL3_OFFSET 0x5c
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCE0_OFFSET 0x60
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCE1_OFFSET 0x64
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCE2_OFFSET 0x68
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCE3_OFFSET 0x6c
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCE0_OFFSET 0x70
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCE1_OFFSET 0x74
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCE2_OFFSET 0x78
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCE3_OFFSET 0x7c
+
+/* ARM_LOCAL interrupt register addresses */
+
+#define _BCM_ARMLOCAL(offset) (BCM_ARMLOCAL_BASEADDR + offset)
+
+#define BCM_IRQ_ARMLOCAL_ARM_CONTROL \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_ARM_CONTROL_OFFSET)
+#define BCM_IRQ_ARMLOCAL_CORE_IRQ_CONTROL \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_CORE_IRQ_CONTROL_OFFSET)
+#define BCM_IRQ_ARMLOCAL_PMU_CONTROL_SET \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_PMU_CONTROL_SET_OFFSET)
+#define BCM_IRQ_ARMLOCAL_PMU_CONTROL_CLR \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_PMU_CONTROL_CLR_OFFSET)
+#define BCM_IRQ_ARMLOCAL_PERI_IRQ_ROUTE0 \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_PERI_IRQ_ROUTE0_OFFSET)
+#define BCM_IRQ_ARMLOCAL_AXI_QUIET_TIME \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_AXI_QUIET_TIME_OFFSET)
+#define BCM_IRQ_ARMLOCAL_LOCAL_TIMER_CONTROL \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_LOCAL_TIMER_CONTROL_OFFSET)
+#define BCM_IRQ_ARMLOCAL_LOCAL_TIMER_IRQ \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_LOCAL_TIMER_IRQ_OFFSET)
+#define BCM_IRQ_ARMLOCAL_TIMER_CNTRL0 \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_TIMER_CNTRL0_OFFSET)
+#define BCM_IRQ_ARMLOCAL_TIMER_CNTRL1 \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_TIMER_CNTRL1_OFFSET)
+#define BCM_IRQ_ARMLOCAL_TIMER_CNTRL2 \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_TIMER_CNTRL2_OFFSET)
+#define BCM_IRQ_ARMLOCAL_TIMER_CNTRL3 \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_TIMER_CNTRL3_OFFSET)
+#define BCM_IRQ_ARMLOCAL_MAILBOX_CNTRL0 \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_MAILBOX_CNTRL0_OFFSET)
+#define BCM_IRQ_ARMLOCAL_MAILBOX_CNTRL1 \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_MAILBOX_CNTRL1_OFFSET)
+#define BCM_IRQ_ARMLOCAL_MAILBOX_CNTRL2 \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_MAILBOX_CNTRL2_OFFSET)
+#define BCM_IRQ_ARMLOCAL_MAILBOX_CNTRL3 \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_MAILBOX_CNTRL3_OFFSET)
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCE0 \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_IRQ_SOURCE0_OFFSET)
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCE1 \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_IRQ_SOURCE1_OFFSET)
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCE2 \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_IRQ_SOURCE2_OFFSET)
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCE3 \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_IRQ_SOURCE3_OFFSET)
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCE0 \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_FIQ_SOURCE0_OFFSET)
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCE1 \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_FIQ_SOURCE1_OFFSET)
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCE2 \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_FIQ_SOURCE2_OFFSET)
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCE3 \
+ _BCM_ARMLOCAL(BCM_IRQ_ARMLOCAL_FIQ_SOURCE3_OFFSET)
+
+/* ARM_LOCAL register bit definitions */
+
+#define BCM_IRQ_ARMLOCAL_ARM_CONTROL_TIMERINC (1 << 8)
+#define BCM_IRQ_ARMLOCAL_ARM_CONTROL_PROC_CLK_TIMER (1 << 7)
+#define BCM_IRQ_ARMLOCAL_ARM_CONTROL_AXIERRIRQ_EN (1 << 6)
+#define BCM_IRQ_ARMLOCAL_ARM_CONTROL_AXI_ERR_CORE (0x7 << 4)
+#define BCM_IRQ_ARMLOCAL_ARM_CONTROL_CORE0_IRQ (0 << 4)
+#define BCM_IRQ_ARMLOCAL_ARM_CONTROL_CORE1_IRQ (1 << 4)
+#define BCM_IRQ_ARMLOCAL_ARM_CONTROL_CORE2_IRQ (2 << 4)
+#define BCM_IRQ_ARMLOCAL_ARM_CONTROL_CORE3_IRQ (3 << 4)
+#define BCM_IRQ_ARMLOCAL_ARM_CONTROL_CORE0_FIQ (4 << 4)
+#define BCM_IRQ_ARMLOCAL_ARM_CONTROL_CORE1_FIQ (5 << 4)
+#define BCM_IRQ_ARMLOCAL_ARM_CONTROL_CORE2_FIQ (6 << 4)
+#define BCM_IRQ_ARMLOCAL_ARM_CONTROL_CORE3_FIQ (7 << 4)
+
+#define BCM_IRQ_ARMLOCAL_PMU_CONTROL_SET_PMU_FIQ (0xf << 4)
+#define BCM_IRQ_ARMLOCAL_PMU_CONTROL_SET_PMU_IRQ (0xf)
+
+#define BCM_IRQ_ARMLOCAL_PMU_CONTROL_CLR_PMU_FIQ (0xf << 4)
+#define BCM_IRQ_ARMLOCAL_PMU_CONTROL_CLR_PMU_IRQ (0xf)
+
+#define BCM_IRQ_ARMLOCAL_PERI_IRQ_ROUTE0_WRITE_MASKS (0xff << 24)
+#define BCM_IRQ_ARMLOCAL_PERI_IRQ_ROUTE0_LOCAL_TIMER_IRQ (0x3)
+
+#define BCM_IRQ_ARMLOCAL_AXI_QUIET_TIME_AXI_QUIET_IRQ_ENB (1 << 20)
+#define BCM_IRQ_ARMLOCAL_AXI_QUIET_TIME_AXI_QUIET_TIME (0xfffff)
+
+#define BCM_IRQ_ARMLOCAL_LOCAL_TIMER_CONTROL_TIMER_IRQ_FLAG (1 << 31)
+#define BCM_IRQ_ARMLOCAL_LOCAL_TIMER_CONTROL_TIMER_IRQ_EN (1 << 29)
+#define BCM_IRQ_ARMLOCAL_LOCAL_TIMER_CONTROL_TIMER_EN (1 << 28)
+#define BCM_IRQ_ARMLOCAL_LOCAL_TIMER_CONTROL_TIMER_TIMEOUT (0xfffffff)
+
+#define BCM_IRQ_ARMLOCAL_LOCAL_TIMER_IRQ_IRQ_CLEAR (1 << 31)
+#define BCM_IRQ_ARMLOCAL_LOCAL_TIMER_IRQ_RELOAD (1 << 30)
+
+#define BCM_IRQ_ARMLOCAL_TIMER_CNTRLN_CNT_V_IRQ_FIQ (1 << 7)
+#define BCM_IRQ_ARMLOCAL_TIMER_CNTRLN_CNT_HP_IRQ_FIQ (1 << 6)
+#define BCM_IRQ_ARMLOCAL_TIMER_CNTRLN_CNT_PNS_IRQ_FIQ (1 << 5)
+#define BCM_IRQ_ARMLOCAL_TIMER_CNTRLN_CNT_PS_IRQ_FIQ (1 << 4)
+#define BCM_IRQ_ARMLOCAL_TIMER_CNTRLN_CNT_V_IRQ (1 << 3)
+#define BCM_IRQ_ARMLOCAL_TIMER_CNTRLN_CNT_HP_IRQ (1 << 2)
+#define BCM_IRQ_ARMLOCAL_TIMER_CNTRLN_CNT_PNS_IRQ (1 << 1)
+#define BCM_IRQ_ARMLOCAL_TIMER_CNTRLN_CNT_PS_IRQ (1 << 0)
+
+#define BCM_IRQ_ARMLOCAL_MAILBOX_CNTRLN_MBOX3_FIQ (1 << 7)
+#define BCM_IRQ_ARMLOCAL_MAILBOX_CNTRLN_MBOX2_FIQ (1 << 6)
+#define BCM_IRQ_ARMLOCAL_MAILBOX_CNTRLN_MBOX1_FIQ (1 << 5)
+#define BCM_IRQ_ARMLOCAL_MAILBOX_CNTRLN_MBOX0_FIQ (1 << 4)
+#define BCM_IRQ_ARMLOCAL_MAILBOX_CNTRLN_MBOX3_IRQ (1 << 3)
+#define BCM_IRQ_ARMLOCAL_MAILBOX_CNTRLN_MBOX2_IRQ (1 << 2)
+#define BCM_IRQ_ARMLOCAL_MAILBOX_CNTRLN_MBOX1_IRQ (1 << 1)
+#define BCM_IRQ_ARMLOCAL_MAILBOX_CNTRLN_MBOX0_IRQ (1 << 0)
+
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCEN_AXI_IRQ (1 << 30)
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCEN_TIMER_IRQ (1 << 11)
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCEN_AXI_QUIET (1 << 10)
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCEN_PMU_IRQ (1 << 9)
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCEN_CORE_IRQ (1 << 8)
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCEN_MAILBOX_CORE0_IRQ (1 << 7)
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCEN_MAILBOX_CORE1_IRQ (1 << 6)
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCEN_MAILBOX_CORE2_IRQ (1 << 5)
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCEN_MAILBOX_CORE3_IRQ (1 << 4)
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCEN_CNT_V_IRQ (1 << 3)
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCEN_CNT_HP_IRQ (1 << 2)
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCEN_CNT_PNS_IRQ (1 << 1)
+#define BCM_IRQ_ARMLOCAL_IRQ_SOURCEN_CNT_PS_IRQ (1 << 0)
+
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCEN_AXI_FIQ (1 << 30)
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCEN_LOCAL_TIMER_FIQ (1 << 11)
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCEN_PMU_FIQ (1 << 9)
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCEN_CORE_FIQ (1 << 8)
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCEN_MAILBOX_CORE0_FIQ (1 << 7)
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCEN_MAILBOX_CORE1_FIQ (1 << 6)
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCEN_MAILBOX_CORE2_FIQ (1 << 5)
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCEN_MAILBOX_CORE3_FIQ (1 << 4)
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCEN_CNT_V_FIQ (1 << 3)
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCEN_CNT_HP_FIQ (1 << 2)
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCEN_CNT_PNS_FIQ (1 << 1)
+#define BCM_IRQ_ARMLOCAL_FIQ_SOURCEN_CNT_PS_FIQ (1 << 0)
+
+/* ARMC register offsets */
+
+#define BCM_IRQ_ARMC_BASEADDR 0x7e00b000
+
+#define BCM_IRQ_ARMC_IRQ0_PENDING0_OFFSET 0x200
+#define BCM_IRQ_ARMC_IRQ0_PENDING1_OFFSET 0x204
+#define BCM_IRQ_ARMC_IRQ0_PENDING2_OFFSET 0x208
+#define BCM_IRQ_ARMC_IRQ0_SET_EN_0_OFFSET 0x210
+#define BCM_IRQ_ARMC_IRQ0_SET_EN_1_OFFSET 0x214
+#define BCM_IRQ_ARMC_IRQ0_SET_EN_2_OFFSET 0x218
+#define BCM_IRQ_ARMC_IRQ0_CLR_EN_0_OFFSET 0x220
+#define BCM_IRQ_ARMC_IRQ0_CLR_EN_1_OFFSET 0x224
+#define BCM_IRQ_ARMC_IRQ0_CLR_EN_2_OFFSET 0x228
+#define BCM_IRQ_ARMC_IRQ_STATUS0_OFFSET 0x230
+#define BCM_IRQ_ARMC_IRQ_STATUS1_OFFSET 0x234
+#define BCM_IRQ_ARMC_IRQ_STATUS2_OFFSET 0x238
+#define BCM_IRQ_ARMC_IRQ1_PENDING0_OFFSET 0x240
+#define BCM_IRQ_ARMC_IRQ1_PENDING1_OFFSET 0x244
+#define BCM_IRQ_ARMC_IRQ1_PENDING2_OFFSET 0x248
+#define BCM_IRQ_ARMC_IRQ1_SET_EN_0_OFFSET 0x250
+#define BCM_IRQ_ARMC_IRQ1_SET_EN_1_OFFSET 0x254
+#define BCM_IRQ_ARMC_IRQ1_SET_EN_2_OFFSET 0x258
+#define BCM_IRQ_ARMC_IRQ1_CLR_EN_0_OFFSET 0x260
+#define BCM_IRQ_ARMC_IRQ1_CLR_EN_1_OFFSET 0x264
+#define BCM_IRQ_ARMC_IRQ1_CLR_EN_2_OFFSET 0x268
+#define BCM_IRQ_ARMC_IRQ2_PENDING0_OFFSET 0x280
+#define BCM_IRQ_ARMC_IRQ2_PENDING1_OFFSET 0x284
+#define BCM_IRQ_ARMC_IRQ2_PENDING2_OFFSET 0x288
+#define BCM_IRQ_ARMC_IRQ2_SET_EN_0_OFFSET 0x290
+#define BCM_IRQ_ARMC_IRQ2_SET_EN_1_OFFSET 0x294
+#define BCM_IRQ_ARMC_IRQ2_SET_EN_2_OFFSET 0x298
+#define BCM_IRQ_ARMC_IRQ2_CLR_EN_0_OFFSET 0x2a0
+#define BCM_IRQ_ARMC_IRQ2_CLR_EN_1_OFFSET 0x2a4
+#define BCM_IRQ_ARMC_IRQ2_CLR_EN_2_OFFSET 0x2a8
+#define BCM_IRQ_ARMC_IRQ3_PENDING0_OFFSET 0x2c0
+#define BCM_IRQ_ARMC_IRQ3_PENDING1_OFFSET 0x2c4
+#define BCM_IRQ_ARMC_IRQ3_PENDING2_OFFSET 0x2c8
+#define BCM_IRQ_ARMC_IRQ3_SET_EN_0_OFFSET 0x2d0
+#define BCM_IRQ_ARMC_IRQ3_SET_EN_1_OFFSET 0x2d4
+#define BCM_IRQ_ARMC_IRQ3_SET_EN_2_OFFSET 0x2d8
+#define BCM_IRQ_ARMC_IRQ3_CLR_EN_0_OFFSET 0x2e0
+#define BCM_IRQ_ARMC_IRQ3_CLR_EN_1_OFFSET 0x2e4
+#define BCM_IRQ_ARMC_IRQ3_CLR_EN_2_OFFSET 0x2e8
+#define BCM_IRQ_ARMC_FIQ0_PENDING0_OFFSET 0x300
+#define BCM_IRQ_ARMC_FIQ0_PENDING1_OFFSET 0x304
+#define BCM_IRQ_ARMC_FIQ0_PENDING2_OFFSET 0x308
+#define BCM_IRQ_ARMC_FIQ0_SET_EN_0_OFFSET 0x310
+#define BCM_IRQ_ARMC_FIQ0_SET_EN_1_OFFSET 0x314
+#define BCM_IRQ_ARMC_FIQ0_SET_EN_2_OFFSET 0x318
+#define BCM_IRQ_ARMC_FIQ0_CLR_EN_0_OFFSET 0x320
+#define BCM_IRQ_ARMC_FIQ0_CLR_EN_1_OFFSET 0x324
+#define BCM_IRQ_ARMC_FIQ0_CLR_EN_2_OFFSET 0x328
+#define BCM_IRQ_ARMC_FIQ1_PENDING0_OFFSET 0x340
+#define BCM_IRQ_ARMC_FIQ1_PENDING1_OFFSET 0x344
+#define BCM_IRQ_ARMC_FIQ1_PENDING2_OFFSET 0x348
+#define BCM_IRQ_ARMC_FIQ1_SET_EN_0_OFFSET 0x350
+#define BCM_IRQ_ARMC_FIQ1_SET_EN_1_OFFSET 0x354
+#define BCM_IRQ_ARMC_FIQ1_SET_EN_2_OFFSET 0x358
+#define BCM_IRQ_ARMC_FIQ1_CLR_EN_0_OFFSET 0x360
+#define BCM_IRQ_ARMC_FIQ1_CLR_EN_1_OFFSET 0x364
+#define BCM_IRQ_ARMC_FIQ1_CLR_EN_2_OFFSET 0x368
+#define BCM_IRQ_ARMC_FIQ2_PENDING0_OFFSET 0x380
+#define BCM_IRQ_ARMC_FIQ2_PENDING1_OFFSET 0x384
+#define BCM_IRQ_ARMC_FIQ2_PENDING2_OFFSET 0x388
+#define BCM_IRQ_ARMC_FIQ2_SET_EN_0_OFFSET 0x390
+#define BCM_IRQ_ARMC_FIQ2_SET_EN_1_OFFSET 0x394
+#define BCM_IRQ_ARMC_FIQ2_SET_EN_2_OFFSET 0x398
+#define BCM_IRQ_ARMC_FIQ2_CLR_EN_0_OFFSET 0x3a0
+#define BCM_IRQ_ARMC_FIQ2_CLR_EN_1_OFFSET 0x3a4
+#define BCM_IRQ_ARMC_FIQ2_CLR_EN_2_OFFSET 0x3a8
+#define BCM_IRQ_ARMC_FIQ3_PENDING0_OFFSET 0x3c0
+#define BCM_IRQ_ARMC_FIQ3_PENDING1_OFFSET 0x3c4
+#define BCM_IRQ_ARMC_FIQ3_PENDING2_OFFSET 0x3c8
+#define BCM_IRQ_ARMC_FIQ3_SET_EN_0_OFFSET 0x3d0
+#define BCM_IRQ_ARMC_FIQ3_SET_EN_1_OFFSET 0x3d4
+#define BCM_IRQ_ARMC_FIQ3_SET_EN_2_OFFSET 0x3d8
+#define BCM_IRQ_ARMC_FIQ3_CLR_EN_0_OFFSET 0x3e0
+#define BCM_IRQ_ARMC_FIQ3_CLR_EN_1_OFFSET 0x3e4
+#define BCM_IRQ_ARMC_FIQ3_CLR_EN_2_OFFSET 0x3e8
+#define BCM_IRQ_ARMC_SWIRQ_SET_OFFSET 0x3f0
+#define BCM_IRQ_ARMC_SWIRQ_CLEAR_OFFSET 0x3f4
+
+/* ARMC register addresses */
+
+#define _BCM_ARMC(offset) (BCM_IRQ_ARMC_BASEADDR + (offset))
+
+#define BCM_IRQ_ARMC_IRQ0_PENDING0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ0_PENDING0_OFFSET)
+#define BCM_IRQ_ARMC_IRQ0_PENDING1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ0_PENDING1_OFFSET)
+#define BCM_IRQ_ARMC_IRQ0_PENDING2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ0_PENDING2_OFFSET)
+#define BCM_IRQ_ARMC_IRQ0_SET_EN_0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ0_SET_EN_0_OFFSET)
+#define BCM_IRQ_ARMC_IRQ0_SET_EN_1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ0_SET_EN_1_OFFSET)
+#define BCM_IRQ_ARMC_IRQ0_SET_EN_2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ0_SET_EN_2_OFFSET)
+#define BCM_IRQ_ARMC_IRQ0_CLR_EN_0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ0_CLR_EN_0_OFFSET)
+#define BCM_IRQ_ARMC_IRQ0_CLR_EN_1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ0_CLR_EN_1_OFFSET)
+#define BCM_IRQ_ARMC_IRQ0_CLR_EN_2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ0_CLR_EN_2_OFFSET)
+#define BCM_IRQ_ARMC_IRQ_STATUS0 _BCM_ARMC(BCM_IRQ_ARMC_IRQ_STATUS0_OFFSET)
+#define BCM_IRQ_ARMC_IRQ_STATUS1 _BCM_ARMC(BCM_IRQ_ARMC_IRQ_STATUS1_OFFSET)
+#define BCM_IRQ_ARMC_IRQ_STATUS2 _BCM_ARMC(BCM_IRQ_ARMC_IRQ_STATUS2_OFFSET)
+#define BCM_IRQ_ARMC_IRQ1_PENDING0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ1_PENDING0_OFFSET)
+#define BCM_IRQ_ARMC_IRQ1_PENDING1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ1_PENDING1_OFFSET)
+#define BCM_IRQ_ARMC_IRQ1_PENDING2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ1_PENDING2_OFFSET)
+#define BCM_IRQ_ARMC_IRQ1_SET_EN_0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ1_SET_EN_0_OFFSET)
+#define BCM_IRQ_ARMC_IRQ1_SET_EN_1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ1_SET_EN_1_OFFSET)
+#define BCM_IRQ_ARMC_IRQ1_SET_EN_2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ1_SET_EN_2_OFFSET)
+#define BCM_IRQ_ARMC_IRQ1_CLR_EN_0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ1_CLR_EN_0_OFFSET)
+#define BCM_IRQ_ARMC_IRQ1_CLR_EN_1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ1_CLR_EN_1_OFFSET)
+#define BCM_IRQ_ARMC_IRQ1_CLR_EN_2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ1_CLR_EN_2_OFFSET)
+#define BCM_IRQ_ARMC_IRQ2_PENDING0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ2_PENDING0_OFFSET)
+#define BCM_IRQ_ARMC_IRQ2_PENDING1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ2_PENDING1_OFFSET)
+#define BCM_IRQ_ARMC_IRQ2_PENDING2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ2_PENDING2_OFFSET)
+#define BCM_IRQ_ARMC_IRQ2_SET_EN_0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ2_SET_EN_0_OFFSET)
+#define BCM_IRQ_ARMC_IRQ2_SET_EN_1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ2_SET_EN_1_OFFSET)
+#define BCM_IRQ_ARMC_IRQ2_SET_EN_2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ2_SET_EN_2_OFFSET)
+#define BCM_IRQ_ARMC_IRQ2_CLR_EN_0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ2_CLR_EN_0_OFFSET)
+#define BCM_IRQ_ARMC_IRQ2_CLR_EN_1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ2_CLR_EN_1_OFFSET)
+#define BCM_IRQ_ARMC_IRQ2_CLR_EN_2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ2_CLR_EN_2_OFFSET)
+#define BCM_IRQ_ARMC_IRQ3_PENDING0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ3_PENDING0_OFFSET)
+#define BCM_IRQ_ARMC_IRQ3_PENDING1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ3_PENDING1_OFFSET)
+#define BCM_IRQ_ARMC_IRQ3_PENDING2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ3_PENDING2_OFFSET)
+#define BCM_IRQ_ARMC_IRQ3_SET_EN_0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ3_SET_EN_0_OFFSET)
+#define BCM_IRQ_ARMC_IRQ3_SET_EN_1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ3_SET_EN_1_OFFSET)
+#define BCM_IRQ_ARMC_IRQ3_SET_EN_2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ3_SET_EN_2_OFFSET)
+#define BCM_IRQ_ARMC_IRQ3_CLR_EN_0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ3_CLR_EN_0_OFFSET)
+#define BCM_IRQ_ARMC_IRQ3_CLR_EN_1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ3_CLR_EN_1_OFFSET)
+#define BCM_IRQ_ARMC_IRQ3_CLR_EN_2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_IRQ3_CLR_EN_2_OFFSET)
+#define BCM_IRQ_ARMC_FIQ0_PENDING0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ0_PENDING0_OFFSET)
+#define BCM_IRQ_ARMC_FIQ0_PENDING1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ0_PENDING1_OFFSET)
+#define BCM_IRQ_ARMC_FIQ0_PENDING2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ0_PENDING2_OFFSET)
+#define BCM_IRQ_ARMC_FIQ0_SET_EN_0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ0_SET_EN_0_OFFSET)
+#define BCM_IRQ_ARMC_FIQ0_SET_EN_1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ0_SET_EN_1_OFFSET)
+#define BCM_IRQ_ARMC_FIQ0_SET_EN_2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ0_SET_EN_2_OFFSET)
+#define BCM_IRQ_ARMC_FIQ0_CLR_EN_0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ0_CLR_EN_0_OFFSET)
+#define BCM_IRQ_ARMC_FIQ0_CLR_EN_1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ0_CLR_EN_1_OFFSET)
+#define BCM_IRQ_ARMC_FIQ0_CLR_EN_2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ0_CLR_EN_2_OFFSET)
+#define BCM_IRQ_ARMC_FIQ1_PENDING0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ1_PENDING0_OFFSET)
+#define BCM_IRQ_ARMC_FIQ1_PENDING1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ1_PENDING1_OFFSET)
+#define BCM_IRQ_ARMC_FIQ1_PENDING2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ1_PENDING2_OFFSET)
+#define BCM_IRQ_ARMC_FIQ1_SET_EN_0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ1_SET_EN_0_OFFSET)
+#define BCM_IRQ_ARMC_FIQ1_SET_EN_1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ1_SET_EN_1_OFFSET)
+#define BCM_IRQ_ARMC_FIQ1_SET_EN_2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ1_SET_EN_2_OFFSET)
+#define BCM_IRQ_ARMC_FIQ1_CLR_EN_0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ1_CLR_EN_0_OFFSET)
+#define BCM_IRQ_ARMC_FIQ1_CLR_EN_1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ1_CLR_EN_1_OFFSET)
+#define BCM_IRQ_ARMC_FIQ1_CLR_EN_2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ1_CLR_EN_2_OFFSET)
+#define BCM_IRQ_ARMC_FIQ2_PENDING0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ2_PENDING0_OFFSET)
+#define BCM_IRQ_ARMC_FIQ2_PENDING1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ2_PENDING1_OFFSET)
+#define BCM_IRQ_ARMC_FIQ2_PENDING2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ2_PENDING2_OFFSET)
+#define BCM_IRQ_ARMC_FIQ2_SET_EN_0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ2_SET_EN_0_OFFSET)
+#define BCM_IRQ_ARMC_FIQ2_SET_EN_1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ2_SET_EN_1_OFFSET)
+#define BCM_IRQ_ARMC_FIQ2_SET_EN_2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ2_SET_EN_2_OFFSET)
+#define BCM_IRQ_ARMC_FIQ2_CLR_EN_0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ2_CLR_EN_0_OFFSET)
+#define BCM_IRQ_ARMC_FIQ2_CLR_EN_1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ2_CLR_EN_1_OFFSET)
+#define BCM_IRQ_ARMC_FIQ2_CLR_EN_2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ2_CLR_EN_2_OFFSET)
+#define BCM_IRQ_ARMC_FIQ3_PENDING0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ3_PENDING0_OFFSET)
+#define BCM_IRQ_ARMC_FIQ3_PENDING1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ3_PENDING1_OFFSET)
+#define BCM_IRQ_ARMC_FIQ3_PENDING2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ3_PENDING2_OFFSET)
+#define BCM_IRQ_ARMC_FIQ3_SET_EN_0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ3_SET_EN_0_OFFSET)
+#define BCM_IRQ_ARMC_FIQ3_SET_EN_1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ3_SET_EN_1_OFFSET)
+#define BCM_IRQ_ARMC_FIQ3_SET_EN_2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ3_SET_EN_2_OFFSET)
+#define BCM_IRQ_ARMC_FIQ3_CLR_EN_0 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ3_CLR_EN_0_OFFSET)
+#define BCM_IRQ_ARMC_FIQ3_CLR_EN_1 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ3_CLR_EN_1_OFFSET)
+#define BCM_IRQ_ARMC_FIQ3_CLR_EN_2 \
+ _BCM_ARMC(BCM_IRQ_ARMC_FIQ3_CLR_EN_2_OFFSET)
+#define BCM_IRQ_ARMC_SWIRQ_SET _BCM_ARMC(BCM_IRQ_ARMC_SWIRQ_SET_OFFSET)
+#define BCM_IRQ_ARMC_SWIRQ_CLEAR _BCM_ARMC(BCM_IRQ_ARMC_SWIRQ_CLEAR_OFFSET)
+
+/* ARMC register bit definitions */
+
+#define BCM_IRQ_ARMC_IRQN_PENDING2_IRQ (1 << 31)
+#define BCM_IRQ_ARMC_IRQN_PENDING2_INT63_32 (1 << 25)
+#define BCM_IRQ_ARMC_IRQN_PENDING2_INT31_0 (1 << 24)
+#define BCM_IRQ_ARMC_IRQN_PENDING2_SW_TRIG_INT (0xff << 8)
+#define BCM_IRQ_ARMC_IRQN_PENDING2_ARM_AXI_ERROR (1 << 7)
+#define BCM_IRQ_ARMC_IRQN_PENDING2_ARM_ADDR_ERROR (1 << 6)
+#define BCM_IRQ_ARMC_IRQN_PENDING2_VPU_C1_HALT (1 << 5)
+#define BCM_IRQ_ARMC_IRQN_PENDING2_VPU_C0_C1_HALT (1 << 4)
+#define BCM_IRQ_ARMC_IRQN_PENDING2_BELL_IRQ1 (1 << 3)
+#define BCM_IRQ_ARMC_IRQN_PENDING2_BELL_IRQ0 (1 << 2)
+#define BCM_IRQ_ARMC_IRQN_PENDING2_MAILBOX_IRQ0 (1 << 1)
+#define BCM_IRQ_ARMC_IRQN_PENDING2_TIMER_IRQ (1 << 0)
+
+#define BCM_IRQ_ARMC_IRQN_SET_EN_2_IRQ (1 << 31)
+#define BCM_IRQ_ARMC_IRQN_SET_EN_2_SW_TRIG_INT (0xf << 8)
+#define BCM_IRQ_ARMC_IRQN_SET_EN_2_ARM_AXI_ERROR (1 << 7)
+#define BCM_IRQ_ARMC_IRQN_SET_EN_2_ARM_ADDR_ERROR (1 << 6)
+#define BCM_IRQ_ARMC_IRQN_SET_EN_2_VPU_C1_HALT (1 << 5)
+#define BCM_IRQ_ARMC_IRQN_SET_EN_2_VPU_C0_C1_HALT (1 << 4)
+#define BCM_IRQ_ARMC_IRQN_SET_EN_2_BELL_IRQ1 (1 << 3)
+#define BCM_IRQ_ARMC_IRQN_SET_EN_2_BELL_IRQ0 (1 << 2)
+#define BCM_IRQ_ARMC_IRQN_SET_EN_2_MAILBOX_IRQ0 (1 << 1)
+#define BCM_IRQ_ARMC_IRQN_SET_EN_2_TIMER_IRQ (1 << 0)
+
+#define BCM_IRQ_ARMC_IRQN_CLR_EN_2_IRQ (1 << 31)
+#define BCM_IRQ_ARMC_IRQN_CLR_EN_2_SW_TRIG_INT (0xf << 8)
+#define BCM_IRQ_ARMC_IRQN_CLR_EN_2_ARM_AXI_ERROR (1 << 7)
+#define BCM_IRQ_ARMC_IRQN_CLR_EN_2_ARM_ADDR_ERROR (1 << 6)
+#define BCM_IRQ_ARMC_IRQN_CLR_EN_2_VPU_C1_HALT (1 << 5)
+#define BCM_IRQ_ARMC_IRQN_CLR_EN_2_VPU_C0_C1_HALT (1 << 4)
+#define BCM_IRQ_ARMC_IRQN_CLR_EN_2_BELL_IRQ1 (1 << 3)
+#define BCM_IRQ_ARMC_IRQN_CLR_EN_2_BELL_IRQ0 (1 << 2)
+#define BCM_IRQ_ARMC_IRQN_CLR_EN_2_MAILBOX_IRQ0 (1 << 1)
+#define BCM_IRQ_ARMC_IRQN_CLR_EN_2_TIMER_IRQ (1 << 0)
+
+#define BCM_IRQ_ARMC_IRQ_STATUS2_IRQ (1 << 31)
+#define BCM_IRQ_ARMC_IRQ_STATUS2_SW_TRIG_INT (0xf << 8)
+#define BCM_IRQ_ARMC_IRQ_STATUS2_ARM_AXI_ERROR (1 << 7)
+#define BCM_IRQ_ARMC_IRQ_STATUS2_ARM_ADDR_ERROR (1 << 6)
+#define BCM_IRQ_ARMC_IRQ_STATUS2_VPU_C1_HALT (1 << 5)
+#define BCM_IRQ_ARMC_IRQ_STATUS2_VPU_C0_C1_HALT (1 << 4)
+#define BCM_IRQ_ARMC_IRQ_STATUS2_BELL_IRQ1 (1 << 3)
+#define BCM_IRQ_ARMC_IRQ_STATUS2_BELL_IRQ0 (1 << 2)
+#define BCM_IRQ_ARMC_IRQ_STATUS2_MAILBOX_IRQ0 (1 << 1)
+#define BCM_IRQ_ARMC_IRQ_STATUS2_TIMER_IRQ (1 << 0)
+
+#define BCM_IRQ_ARMC_FIQ_PENDING2_IRQ (1 << 31)
+#define BCM_IRQ_ARMC_FIQ_PENDING2_INT63_32 (1 << 25)
+#define BCM_IRQ_ARMC_FIQ_PENDING2_INT31_0 (1 << 24)
+#define BCM_IRQ_ARMC_FIQ_PENDING2_SW_TRIG_INT (0xff << 8)
+#define BCM_IRQ_ARMC_FIQ_PENDING2_ARM_AXI_ERROR (1 << 7)
+#define BCM_IRQ_ARMC_FIQ_PENDING2_ARM_ADDR_ERROR (1 << 6)
+#define BCM_IRQ_ARMC_FIQ_PENDING2_VPU_C1_HALT (1 << 5)
+#define BCM_IRQ_ARMC_FIQ_PENDING2_VPU_C0_C1_HALT (1 << 4)
+#define BCM_IRQ_ARMC_FIQ_PENDING2_BELL_IRQ1 (1 << 3)
+#define BCM_IRQ_ARMC_FIQ_PENDING2_BELL_IRQ0 (1 << 2)
+#define BCM_IRQ_ARMC_FIQ_PENDING2_MAILBOX_IRQ0 (1 << 1)
+
+#define BCM_IRQ_ARMC_FIQ_SET_EN_2_IRQ (1 << 31)
+#define BCM_IRQ_ARMC_FIQ_SET_EN_2_SW_TRIG_INT (0xf << 8)
+#define BCM_IRQ_ARMC_FIQ_SET_EN_2_ARM_AXI_ERROR (1 << 7)
+#define BCM_IRQ_ARMC_FIQ_SET_EN_2_ARM_ADDR_ERROR (1 << 6)
+#define BCM_IRQ_ARMC_FIQ_SET_EN_2_VPU_C1_HALT (1 << 5)
+#define BCM_IRQ_ARMC_FIQ_SET_EN_2_VPU_C0_C1_HALT (1 << 4)
+#define BCM_IRQ_ARMC_FIQ_SET_EN_2_BELL_IRQ1 (1 << 3)
+#define BCM_IRQ_ARMC_FIQ_SET_EN_2_BELL_IRQ0 (1 << 2)
+#define BCM_IRQ_ARMC_FIQ_SET_EN_2_MAILBOX_IRQ0 (1 << 1)
+#define BCM_IRQ_ARMC_FIQ_SET_EN_2_TIMER_IRQ (1 << 0)
+
+#define BCM_IRQ_ARMC_SWIRQ_SET_SW_INT (0xff)
+#define BCM_IRQ_ARMC_SWIRQ_CLEAR_SW_INT (0xff)
+
+#endif /* __ARCH_ARM64_SRC_BCM2711_IRQ_H */
diff --git a/arch/arm64/src/bcm2711/hardware/bcm2711_mailbox.h b/arch/arm64/src/bcm2711/hardware/bcm2711_mailbox.h
new file mode 100644
index 0000000000..b7a13720d2
--- /dev/null
+++ b/arch/arm64/src/bcm2711/hardware/bcm2711_mailbox.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/hardware/bcm2711_mailbox.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_MAILBOX_H
+#define __ARCH_ARM64_SRC_BCM2711_MAILBOX_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "bcm2711_memmap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Mailbox register offsets */
+
+#define BCM_MBOX_SET00_OFFSET 0x80
+#define BCM_MBOX_SET01_OFFSET 0x84
+#define BCM_MBOX_SET02_OFFSET 0x88
+#define BCM_MBOX_SET03_OFFSET 0x8c
+#define BCM_MBOX_SET04_OFFSET 0x90
+#define BCM_MBOX_SET05_OFFSET 0x94
+#define BCM_MBOX_SET06_OFFSET 0x98
+#define BCM_MBOX_SET07_OFFSET 0x9c
+#define BCM_MBOX_SET08_OFFSET 0xa0
+#define BCM_MBOX_SET09_OFFSET 0xa4
+#define BCM_MBOX_SET10_OFFSET 0xa8
+#define BCM_MBOX_SET11_OFFSET 0xac
+#define BCM_MBOX_SET12_OFFSET 0xb0
+#define BCM_MBOX_SET13_OFFSET 0xb4
+#define BCM_MBOX_SET14_OFFSET 0xb8
+#define BCM_MBOX_SET15_OFFSET 0xbc
+#define BCM_MBOX_CLR00_OFFSET 0xc0
+#define BCM_MBOX_CLR01_OFFSET 0xc4
+#define BCM_MBOX_CLR02_OFFSET 0xc8
+#define BCM_MBOX_CLR03_OFFSET 0xcc
+#define BCM_MBOX_CLR04_OFFSET 0xd0
+#define BCM_MBOX_CLR05_OFFSET 0xd4
+#define BCM_MBOX_CLR06_OFFSET 0xd8
+#define BCM_MBOX_CLR07_OFFSET 0xdc
+#define BCM_MBOX_CLR08_OFFSET 0xe0
+#define BCM_MBOX_CLR09_OFFSET 0xe4
+#define BCM_MBOX_CLR10_OFFSET 0xe8
+#define BCM_MBOX_CLR11_OFFSET 0xec
+#define BCM_MBOX_CLR12_OFFSET 0xf0
+#define BCM_MBOX_CLR13_OFFSET 0xf4
+#define BCM_MBOX_CLR14_OFFSET 0xf8
+#define BCM_MBOX_CLR15_OFFSET 0xfc
+
+/* Mailbox register addresses */
+
+#define _BCM_MBOX(offset) (BCM_ARMLOCAL_BASEADDR + (offset))
+
+#define BCM_MBOX_SET00 _BCM_MBOX(BCM_MBOX_SET00_OFFSET)
+#define BCM_MBOX_SET01 _BCM_MBOX(BCM_MBOX_SET01_OFFSET)
+#define BCM_MBOX_SET02 _BCM_MBOX(BCM_MBOX_SET02_OFFSET)
+#define BCM_MBOX_SET03 _BCM_MBOX(BCM_MBOX_SET03_OFFSET)
+#define BCM_MBOX_SET04 _BCM_MBOX(BCM_MBOX_SET04_OFFSET)
+#define BCM_MBOX_SET05 _BCM_MBOX(BCM_MBOX_SET05_OFFSET)
+#define BCM_MBOX_SET06 _BCM_MBOX(BCM_MBOX_SET06_OFFSET)
+#define BCM_MBOX_SET07 _BCM_MBOX(BCM_MBOX_SET07_OFFSET)
+#define BCM_MBOX_SET08 _BCM_MBOX(BCM_MBOX_SET08_OFFSET)
+#define BCM_MBOX_SET09 _BCM_MBOX(BCM_MBOX_SET09_OFFSET)
+#define BCM_MBOX_SET10 _BCM_MBOX(BCM_MBOX_SET10_OFFSET)
+#define BCM_MBOX_SET11 _BCM_MBOX(BCM_MBOX_SET11_OFFSET)
+#define BCM_MBOX_SET12 _BCM_MBOX(BCM_MBOX_SET12_OFFSET)
+#define BCM_MBOX_SET13 _BCM_MBOX(BCM_MBOX_SET13_OFFSET)
+#define BCM_MBOX_SET14 _BCM_MBOX(BCM_MBOX_SET14_OFFSET)
+#define BCM_MBOX_SET15 _BCM_MBOX(BCM_MBOX_SET15_OFFSET)
+#define BCM_MBOX_CLR00 _BCM_MBOX(BCM_MBOX_CLR00_OFFSET)
+#define BCM_MBOX_CLR01 _BCM_MBOX(BCM_MBOX_CLR01_OFFSET)
+#define BCM_MBOX_CLR02 _BCM_MBOX(BCM_MBOX_CLR02_OFFSET)
+#define BCM_MBOX_CLR03 _BCM_MBOX(BCM_MBOX_CLR03_OFFSET)
+#define BCM_MBOX_CLR04 _BCM_MBOX(BCM_MBOX_CLR04_OFFSET)
+#define BCM_MBOX_CLR05 _BCM_MBOX(BCM_MBOX_CLR05_OFFSET)
+#define BCM_MBOX_CLR06 _BCM_MBOX(BCM_MBOX_CLR06_OFFSET)
+#define BCM_MBOX_CLR07 _BCM_MBOX(BCM_MBOX_CLR07_OFFSET)
+#define BCM_MBOX_CLR08 _BCM_MBOX(BCM_MBOX_CLR08_OFFSET)
+#define BCM_MBOX_CLR09 _BCM_MBOX(BCM_MBOX_CLR09_OFFSET)
+#define BCM_MBOX_CLR10 _BCM_MBOX(BCM_MBOX_CLR10_OFFSET)
+#define BCM_MBOX_CLR11 _BCM_MBOX(BCM_MBOX_CLR11_OFFSET)
+#define BCM_MBOX_CLR12 _BCM_MBOX(BCM_MBOX_CLR12_OFFSET)
+#define BCM_MBOX_CLR13 _BCM_MBOX(BCM_MBOX_CLR13_OFFSET)
+#define BCM_MBOX_CLR14 _BCM_MBOX(BCM_MBOX_CLR14_OFFSET)
+#define BCM_MBOX_CLR15 _BCM_MBOX(BCM_MBOX_CLR15_OFFSET)
+
+#endif /* __ARCH_ARM64_SRC_BCM2711_MAILBOX_H */
diff --git a/arch/arm64/src/bcm2711/hardware/bcm2711_memmap.h b/arch/arm64/src/bcm2711/hardware/bcm2711_memmap.h
new file mode 100644
index 0000000000..72f249e4ac
--- /dev/null
+++ b/arch/arm64/src/bcm2711/hardware/bcm2711_memmap.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/hardware/bcm2711_memmap.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_MM_H
+#define __ARCH_ARM64_SRC_BCM2711_MM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* BCM2711 peripheral base address */
+
+#if defined(CONFIG_BCM2711_LOW_PERIPHERAL)
+
+/* Low peripheral addressing mode (default for RPi 4B boot) */
+
+#define BCM_PERIPHERAL_BASEADDR 0x0fe000000
+
+#elif defined(CONFIG_BCM2711_LEGACY_ADDR)
+
+/* Legacy addressing mode */
+
+#define BCM_PERIPHERAL_BASEADDR 0x07e000000
+
+#else
+
+/* 35-bit addressing mode */
+
+#define BCM_PERIPHERAL_BASEADDR 0x47e000000
+
+#endif // defined(CONFIG_BCM2711_LOW_PERIPHERAL)
+
+/* Base addresses for chip registers */
+
+#define BCM_ARMT_BASEADDR \
+ (BCM_PERIPHERAL_BASEADDR + 0x0000b000) /* ARM timer */
+#define BCM_AUX_BASEADDR \
+ (BCM_PERIPHERAL_BASEADDR + 0x000215000) /* Auxilliary */
+#define BCM_GPCLK_BASEADDR \
+ (BCM_PERIPHERAL_BASEADDR + 0x000101000) /* General purpose clock */
+#define BCM_GPIO_BASEADDR \
+ (BCM_PERIPHERAL_BASEADDR + 0x000200000) /* GPIO */
+#define BCM_PCM_BASEADDR \
+ (BCM_PERIPHERAL_BASEADDR + 0x000203000) /* PCM */
+#define BCM_SYST_BASEADDR \
+ (BCM_PERIPHERAL_BASEADDR + 0x000003000) /* System timer */
+
+/* SPI interface register base addresses */
+
+#define BCM_SPI0_BASEADDR \
+ (BCM_PERIPHERAL_BASEADDR + 0x000204000) /* SPI interface 0 */
+#define BCM_SPI3_BASEADDR \
+ (BCM_PERIPHERAL_BASEADDR + 0x000204600) /* SPI interface 3 */
+#define BCM_SPI4_BASEADDR \
+ (BCM_PERIPHERAL_BASEADDR + 0x000204800) /* SPI interface 4 */
+#define BCM_SPI5_BASEADDR \
+ (BCM_PERIPHERAL_BASEADDR + 0x000204a00) /* SPI interface 5 */
+#define BCM_SPI6_BASEADDR \
+ (BCM_PERIPHERAL_BASEADDR + 0x000204c00) /* SPI interface 6 */
+
+/* UART interface base addresses */
+
+#define BCM_UART0_BASEADDR \
+ (BCM_PERIPHERAL_BASEADDR + 0x000201000) /* UART interface 0 */
+#define BCM_UART2_BASEADDR \
+ (BCM_PERIPHERAL_BASEADDR + 0x000201400) /* UART interface 2 */
+#define BCM_UART3_BASEADDR \
+ (BCM_PERIPHERAL_BASEADDR + 0x000201600) /* UART interface 3 */
+#define BCM_UART4_BASEADDR \
+ (BCM_PERIPHERAL_BASEADDR + 0x000201800) /* UART interface 4 */
+#define BCM_UART5_BASEADDR \
+ (BCM_PERIPHERAL_BASEADDR + 0x000201a00) /* UART interface 5 */
+
+/* DMA channel base addresses */
+
+#define BCM_DMA0_BASE \
+ (BCM_PERIPHERAL_BASEADDR + 0x000007000) /* DMA Channel 0 */
+#define BCM_DMA15_BASE \
+ (BCM_PERIPHERAL_BASEADDR + 0x000e05000) /* DMA Channel 15 */
+
+/* ARM_LOCAL base address */
+
+#if defined(CONFIG_BCM2711_LOW_PERIPHERAL)
+#define BCM_ARMLOCAL_BASEADDR 0xff800000
+#else
+#define BCM_ARMLOCAL_BASEADDR 0x4c0000000
+#endif /* defined(CONFIG_BCM2711_LOW_PERIPHERAL) */
+
+#endif /* __ARCH_ARM64_SRC_BCM2711_MM_H */
diff --git a/arch/arm64/src/bcm2711/hardware/bcm2711_pcm.h b/arch/arm64/src/bcm2711/hardware/bcm2711_pcm.h
new file mode 100644
index 0000000000..e691de3f73
--- /dev/null
+++ b/arch/arm64/src/bcm2711/hardware/bcm2711_pcm.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/hardware/bcm2711_pcm.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_PCM_H
+#define __ARCH_ARM64_SRC_BCM2711_PCM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "bcm2711_memmap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* PCM register offsets */
+
+#define BCM_PCM_CS_A_OFFSET 0x00
+#define BCM_PCM_FIFO_A_OFFSET 0x04
+#define BCM_PCM_MODE_A_OFFSET 0x08
+#define BCM_PCM_RXC_A_OFFSET 0x0c
+#define BCM_PCM_TXC_A_OFFSET 0x10
+#define BCM_PCM_DREQ_A_OFFSET 0x14
+#define BCM_PCM_INTEN_A_OFFSET 0x18
+#define BCM_PCM_INTSTC_A_OFFSET 0x1c
+#define BCM_PCM_GRAY_OFFSET 0x20
+
+/* PCM register addresses */
+
+#define _BCM_PCM(offset) (BCM_PCM_BASEADDR + offset)
+
+#define BCM_PCM_CS_A _BCM_PCM(BCM_PCM_CS_A_OFFSET) /* Control & status */
+#define BCM_PCM_FIFO_A _BCM_PCM(BCM_PCM_FIFO_A_OFFSET) /* FIFO data */
+#define BCM_PCM_MODE_A _BCM_PCM(BCM_PCM_MODE_A_OFFSET) /* Mode */
+#define BCM_PCM_RXC_A _BCM_PCM(BCM_PCM_RXC_A_OFFSET) /* Receive config */
+#define BCM_PCM_TXC_A _BCM_PCM(BCM_PCM_TXC_A_OFFSET) /* Transmit config */
+#define BCM_PCM_DREQ_A _BCM_PCM(BCM_PCM_DREQ_A_OFFSET) /* DMA rqst lvl */
+#define BCM_PCM_INTEN_A _BCM_PCM(BCM_PCM_INTEN_A_OFFSET)
+#define BCM_PCM_INTSTC_A _BCM_PCM(BCM_PCM_INTSTC_A_OFFSET)
+#define BCM_PCM_GRAY _BCM_PCM(BCM_PCM_GRAY_OFFSET) /* Gray mode control */
+
+/* PCM register bit definitions */
+
+#define BCM_PCM_CS_A_SYNC (1 << 24)
+#define BCM_PCM_CS_A_RXSEX (1 << 23)
+#define BCM_PCM_CS_A_RXF (1 << 22)
+#define BCM_PCM_CS_A_TXE (1 << 21)
+#define BCM_PCM_CS_A_RXD (1 << 20)
+#define BCM_PCM_CS_A_TXD (1 << 19)
+#define BCM_PCM_CS_A_RXR (1 << 18)
+#define BCM_PCM_CS_A_TXW (1 << 17)
+#define BCM_PCM_CS_A_RXERR (1 << 16)
+#define BCM_PCM_CS_A_TXERR (1 << 15)
+#define BCM_PCM_CS_A_RXSYNC (1 << 14)
+#define BCM_PCM_CS_A_TXSYNC (1 << 13)
+#define BCM_PCM_CS_A_DMAEN (1 << 9)
+#define BCM_PCM_CS_A_RXTHR (0x3 << 7)
+#define BCM_PCM_CS_A_RXTHR_SINGLE (0 << 7)
+#define BCM_PCM_CS_A_RXTHR_QUARTER (1 << 7)
+#define BCM_PCM_CS_A_RXTHR_3QUARTER (2 << 7)
+#define BCM_PCM_CS_A_RXTHR_FULL (3 << 7)
+#define BCM_PCM_CS_A_TXTHR (0x3 << 5)
+#define BCM_PCM_CS_A_TXTHR_EMPTY (0 << 5)
+#define BCM_PCM_CS_A_TXTHR_QUARTER (1 << 5)
+#define BCM_PCM_CS_A_TXTHR_3QUARTER (2 << 5)
+#define BCM_PCM_CS_A_TXTHR_FULL (3 << 5)
+#define BCM_PCM_CS_A_RXCLR (1 << 4)
+#define BCM_PCM_CS_A_TXCLR (1 << 3)
+#define BCM_PCM_CS_A_TXON (1 << 2)
+#define BCM_PCM_CS_A_RXON (1 << 1)
+#define BCM_PCM_CS_A_EN (1 << 0)
+
+#define BCM_PCM_MODE_A_CLK_DIS (1 << 28)
+#define BCM_PCM_MODE_A_PDMN (1 << 27)
+#define BCM_PCM_MODE_A_PDME (1 << 26)
+#define BCM_PCM_MODE_A_FRXP (1 << 25)
+#define BCM_PCM_MODE_A_FTXP (1 << 24)
+#define BCM_PCM_MODE_A_CLKM (1 << 23)
+#define BCM_PCM_MODE_A_CLKI (1 << 22)
+#define BCM_PCM_MODE_A_FSM (1 << 21)
+#define BCM_PCM_MODE_A_FSI (1 << 20)
+#define BCM_PCM_MODE_A_FLEN (0x3ff << 10)
+#define BCM_PCM_MODE_A_FSLEN (0x3ff)
+
+#define BCM_PCM_RXC_A_CH1WEX (1 << 31)
+#define BCM_PCM_RXC_A_CH1EN (1 << 30)
+#define BCM_PCM_RXC_A_CH1POS (0x3ff << 20)
+#define BCM_PCM_RXC_A_CH1WID (0xf << 16)
+#define BCM_PCM_RXC_A_CH2WEX (1 << 15)
+#define BCM_PCM_RXC_A_CH2EN (1 << 14)
+#define BCM_PCM_RXC_A_CH2POS (0x3ff << 4)
+#define BCM_PCM_RXC_A_CH2WID (0xf)
+
+#define BCM_PCM_TXC_A_CH1WEX (1 << 31)
+#define BCM_PCM_TXC_A_CH1EN (1 << 30)
+#define BCM_PCM_TXC_A_CH1POS (0x3ff << 20)
+#define BCM_PCM_TXC_A_CH1WID (0xf << 16)
+#define BCM_PCM_TXC_A_CH2WEX (1 << 15)
+#define BCM_PCM_TXC_A_CH2EN (1 << 14)
+#define BCM_PCM_TXC_A_CH2POS (0x3ff << 4)
+#define BCM_PCM_TXC_A_CH2WID (0xf)
+
+#define BCM_PCM_DREQ_A_TX_PANIC (0x7f << 24)
+#define BCM_PCM_DREQ_A_RX_PANIC (0x7f << 16)
+#define BCM_PCM_DREQ_A_RX_REQ (0x7f)
+
+#define BCM_PCM_INTEN_A_RXERR (1 << 3)
+#define BCM_PCM_INTEN_A_TXERR (1 << 2)
+#define BCM_PCM_INTEN_A_RXR (1 << 1)
+#define BCM_PCM_INTEN_A_TXW (1 << 0)
+
+#define BCM_PCM_INTSTC_A_RXERR (1 << 3)
+#define BCM_PCM_INTSTC_A_TXERR (1 << 2)
+#define BCM_PCM_INTSTC_A_RXR (1 << 1)
+#define BCM_PCM_INTSTC_A_TXW (1 << 0)
+
+#define BCM_PCM_GRAY_RXFIFOLEVEL (0x3f << 16)
+#define BCM_PCM_GRAY_FLUSHED (0x3f << 10)
+#define BCM_PCM_GRAY_RXLEVEL (0x3f << 4)
+#define BCM_PCM_GRAY_FLUSH (1 << 2)
+#define BCM_PCM_GRAY_CLR (1 << 1)
+#define BCM_PCM_GRAY_EN (1 << 0)
+
+#endif /* __ARCH_ARM64_SRC_BCM2711_PCM_H */
diff --git a/arch/arm64/src/bcm2711/hardware/bcm2711_pwm.h b/arch/arm64/src/bcm2711/hardware/bcm2711_pwm.h
new file mode 100644
index 0000000000..755f084635
--- /dev/null
+++ b/arch/arm64/src/bcm2711/hardware/bcm2711_pwm.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/hardware/bcm2711_pwm.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_PWM_H
+#define __ARCH_ARM64_SRC_BCM2711_PWM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Base addresses */
+
+#define BCM_PWM0_BASEADDR 0x7e20c000
+#define BCM_PWM1_BASEADDR 0x7e20c800
+
+/* PWM register offsets */
+
+#define BCM_PWM_CTL_OFFSET 0x00
+#define BCM_PWM_STA_OFFSET 0x04
+#define BCM_PWM_DMAC_OFFSET 0x08
+#define BCM_PWM_RNG1_OFFSET 0x10
+#define BCM_PWM_DAT1_OFFSET 0x14
+#define BCM_PWM_FIF1_OFFSET 0x18
+#define BCM_PWM_RNG2_OFFSET 0x20
+#define BCM_PWM_DAT2_OFFSET 0x24
+
+/* PWM register addresses */
+
+#define BCM_PWM0_CTL (BCM_PWM0_BASEADDR + BCM_PWM_CTL_OFFSET)
+#define BCM_PWM0_STA (BCM_PWM0_BASEADDR + BCM_PWM_STA_OFFSET)
+#define BCM_PWM0_DMAC (BCM_PWM0_BASEADDR + BCM_PWM_DMAC_OFFSET)
+#define BCM_PWM0_RNG1 (BCM_PWM0_BASEADDR + BCM_PWM_RNG1_OFFSET)
+#define BCM_PWM0_DAT1 (BCM_PWM0_BASEADDR + BCM_PWM_DAT1_OFFSET)
+#define BCM_PWM0_FIF1 (BCM_PWM0_BASEADDR + BCM_PWM_FIF1_OFFSET)
+#define BCM_PWM0_RNG2 (BCM_PWM0_BASEADDR + BCM_PWM_RNG2_OFFSET)
+#define BCM_PWM0_DAT2 (BCM_PWM0_BASEADDR + BCM_PWM_DAT2_OFFSET)
+
+#define BCM_PWM1_CTL (BCM_PWM0_BASEADDR + BCM_PWM_CTL_OFFSET)
+#define BCM_PWM1_STA (BCM_PWM0_BASEADDR + BCM_PWM_STA_OFFSET)
+#define BCM_PWM1_DMAC (BCM_PWM0_BASEADDR + BCM_PWM_DMAC_OFFSET)
+#define BCM_PWM1_RNG1 (BCM_PWM0_BASEADDR + BCM_PWM_RNG1_OFFSET)
+#define BCM_PWM1_DAT1 (BCM_PWM0_BASEADDR + BCM_PWM_DAT1_OFFSET)
+#define BCM_PWM1_FIF1 (BCM_PWM0_BASEADDR + BCM_PWM_FIF1_OFFSET)
+#define BCM_PWM1_RNG2 (BCM_PWM0_BASEADDR + BCM_PWM_RNG2_OFFSET)
+#define BCM_PWM1_DAT2 (BCM_PWM0_BASEADDR + BCM_PWM_DAT2_OFFSET)
+
+/* PWM register bit definitions */
+
+#define BCM_PWM_CTL_MSEN2 (1 << 15)
+#define BCM_PWM_CTL_USEF2 (1 << 13)
+#define BCM_PWM_CTL_POLA2 (1 << 12)
+#define BCM_PWM_CTL_SBIT2 (1 << 11)
+#define BCM_PWM_CTL_RPTL2 (1 << 10)
+#define BCM_PWM_CTL_MODE2 (1 << 9)
+#define BCM_PWM_CTL_PWEN2 (1 << 8)
+#define BCM_PWM_CTL_MSEN1 (1 << 7)
+#define BCM_PWM_CTL_CLRF (1 << 6)
+#define BCM_PWM_CTL_USEF1 (1 << 5)
+#define BCM_PWM_CTL_POLA1 (1 << 4)
+#define BCM_PWM_CTL_SBIT1 (1 << 3)
+#define BCM_PWM_CTL_RPTL1 (1 << 2)
+#define BCM_PWM_CTL_MODE1 (1 << 1)
+#define BCM_PWM_CTL_PWEN1 (1 << 0)
+
+#define BCM_PWM_STA_STA2 (1 << 10)
+#define BCM_PWM_STA_STA1 (1 << 9)
+#define BCM_PWM_STA_BERR (1 << 8)
+#define BCM_PWM_STA_GAPO2 (1 << 5)
+#define BCM_PWM_STA_GAPO1 (1 << 4)
+#define BCM_PWM_STA_RERR1 (1 << 3)
+#define BCM_PWM_STA_WERR1 (1 << 2)
+#define BCM_PWM_STA_EMPT1 (1 << 1)
+#define BCM_PWM_STA_FULL1 (1 << 0)
+
+#define BCM_PWM_DMAC_ENAB (1 << 31)
+#define BCM_PWM_DMAC_PANIC (0xff << 8)
+#define BCM_PWM_DMAC_DREQ (0xff)
+
+#endif /* __ARCH_ARM64_SRC_BCM2711_PWM_H */
diff --git a/arch/arm64/src/bcm2711/hardware/bcm2711_spi.h b/arch/arm64/src/bcm2711/hardware/bcm2711_spi.h
new file mode 100644
index 0000000000..6131d1653b
--- /dev/null
+++ b/arch/arm64/src/bcm2711/hardware/bcm2711_spi.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/hardware/bcm2711_spi.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_SPI_H
+#define __ARCH_ARM64_SRC_BCM2711_SPI_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "bcm2711_memmap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* SPI register offsets */
+
+#define BCM_SPI_CS_OFFSET 0x00
+#define BCM_SPI_FIFO_OFFSET 0x04
+#define BCM_SPI_CLK_OFFSET 0x08
+#define BCM_SPI_DLEN_OFFSET 0x0c
+#define BCM_SPI_LTOH_OFFSET 0x10
+#define BCM_SPI_DC_OFFSET 0x14
+
+/* SPI register addresses */
+
+#define BCM_SPI0_CS (BCM_SPI0_BASEADDR + BCM_SPI_CS_OFFSET)
+#define BCM_SPI0_FIFO (BCM_SPI0_BASEADDR + BCM_SPI_FIFO_OFFSET)
+#define BCM_SPI0_CLK (BCM_SPI0_BASEADDR + BCM_SPI_CLK_OFFSET)
+#define BCM_SPI0_DLEN (BCM_SPI0_BASEADDR + BCM_SPI_DLEN_OFFSET)
+#define BCM_SPI0_LTOH (BCM_SPI0_BASEADDR + BCM_SPI_LTOH_OFFSET)
+#define BCM_SPI0_DC (BCM_SPI0_BASEADDR + BCM_SPI_DC_OFFSET)
+
+#define BCM_SPI3_CS (BCM_SPI3_BASEADDR + BCM_SPI_CS_OFFSET)
+#define BCM_SPI3_FIFO (BCM_SPI3_BASEADDR + BCM_SPI_FIFO_OFFSET)
+#define BCM_SPI3_CLK (BCM_SPI3_BASEADDR + BCM_SPI_CLK_OFFSET)
+#define BCM_SPI3_DLEN (BCM_SPI3_BASEADDR + BCM_SPI_DLEN_OFFSET)
+#define BCM_SPI3_LTOH (BCM_SPI3_BASEADDR + BCM_SPI_LTOH_OFFSET)
+#define BCM_SPI3_DC (BCM_SPI3_BASEADDR + BCM_SPI_DC_OFFSET)
+
+#define BCM_SPI4_CS (BCM_SPI4_BASEADDR + BCM_SPI_CS_OFFSET)
+#define BCM_SPI4_FIFO (BCM_SPI4_BASEADDR + BCM_SPI_FIFO_OFFSET)
+#define BCM_SPI4_CLK (BCM_SPI4_BASEADDR + BCM_SPI_CLK_OFFSET)
+#define BCM_SPI4_DLEN (BCM_SPI4_BASEADDR + BCM_SPI_DLEN_OFFSET)
+#define BCM_SPI4_LTOH (BCM_SPI4_BASEADDR + BCM_SPI_LTOH_OFFSET)
+#define BCM_SPI4_DC (BCM_SPI4_BASEADDR + BCM_SPI_DC_OFFSET)
+
+#define BCM_SPI5_CS (BCM_SPI5_BASEADDR + BCM_SPI_CS_OFFSET)
+#define BCM_SPI5_FIFO (BCM_SPI5_BASEADDR + BCM_SPI_FIFO_OFFSET)
+#define BCM_SPI5_CLK (BCM_SPI5_BASEADDR + BCM_SPI_CLK_OFFSET)
+#define BCM_SPI5_DLEN (BCM_SPI5_BASEADDR + BCM_SPI_DLEN_OFFSET)
+#define BCM_SPI5_LTOH (BCM_SPI5_BASEADDR + BCM_SPI_LTOH_OFFSET)
+#define BCM_SPI5_DC (BCM_SPI5_BASEADDR + BCM_SPI_DC_OFFSET)
+
+#define BCM_SPI6_CS (BCM_SPI6_BASEADDR + BCM_SPI_CS_OFFSET)
+#define BCM_SPI6_FIFO (BCM_SPI6_BASEADDR + BCM_SPI_FIFO_OFFSET)
+#define BCM_SPI6_CLK (BCM_SPI6_BASEADDR + BCM_SPI_CLK_OFFSET)
+#define BCM_SPI6_DLEN (BCM_SPI6_BASEADDR + BCM_SPI_DLEN_OFFSET)
+#define BCM_SPI6_LTOH (BCM_SPI6_BASEADDR + BCM_SPI_LTOH_OFFSET)
+#define BCM_SPI6_DC (BCM_SPI6_BASEADDR + BCM_SPI_DC_OFFSET)
+
+/* SPI register bit definitions */
+
+#define BCM_SPI_CS_LEN_LONG (1 << 25)
+#define BCM_SPI_CS_DMA_LEN (1 << 24)
+#define BCM_SPI_CS_CSPOL2 (1 << 23)
+#define BCM_SPI_CS_CSPOL1 (1 << 22)
+#define BCM_SPI_CS_CSPOL0 (1 << 21)
+#define BCM_SPI_CS_RXF (1 << 20)
+#define BCM_SPI_CS_RXR (1 << 19)
+#define BCM_SPI_CS_TXD (1 << 18)
+#define BCM_SPI_CS_RXD (1 << 17)
+#define BCM_SPI_CS_DONE (1 << 16)
+#define BCM_SPI_CS_TE_EN (1 << 15)
+#define BCM_SPI_CS_LMONO (1 << 14)
+#define BCM_SPI_CS_LEN (1 << 13)
+#define BCM_SPI_CS_REN (1 << 12)
+#define BCM_SPI_CS_ADCS (1 << 11)
+#define BCM_SPI_CS_INTR (1 << 10)
+#define BCM_SPI_CS_INTD (1 << 9)
+#define BCM_SPI_CS_DMAEN (1 << 8)
+#define BCM_SPI_CS_TA (1 << 7)
+#define BCM_SPI_CS_CSPOL (1 << 6)
+#define BCM_SPI_CS_CLEAR (0x3 << 4)
+#define BCM_SPI_CS_NOCLEAR (0 << 4)
+#define BCM_SPI_CS_CLEARTX (1 << 4)
+#define BCM_SPI_CS_CLEARRX (2 << 4)
+#define BCM_SPI_CS_CPOL (1 << 3)
+#define BCM_SPI_CS_CPHA (1 << 2)
+#define BCM_SPI_CS_CS (0x3 << 0)
+#define BCM_SPI_CS_CS0 (0 << 0)
+#define BCM_SPI_CS_CS1 (1 << 0)
+#define BCM_SPI_CS_CS2 (2 << 0)
+
+#define BCM_SPI_CLK_CDIV (0xffff << 0)
+
+#define BCM_SPI_DLEN_LEN (0xffff << 0)
+
+#define BCM_SPI_LTOH_TOH (0xf << 0)
+
+#define BCM_SPI_DC_RPANIC (0xff << 24)
+#define BCM_SPI_DC_RDREQ (0xff << 16)
+#define BCM_SPI_DC_TPANIC (0xff << 8)
+#define BCM_SPI_DC_TDREQ (0xff << 0)
+
+#endif /* __ARCH_ARM64_SRC_BCM2711_SPI_H */
diff --git a/arch/arm64/src/bcm2711/hardware/bcm2711_systimer.h b/arch/arm64/src/bcm2711/hardware/bcm2711_systimer.h
new file mode 100644
index 0000000000..818985c8ff
--- /dev/null
+++ b/arch/arm64/src/bcm2711/hardware/bcm2711_systimer.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/hardware/bcm2711_systimer.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_SYSTIMER_H
+#define __ARCH_ARM64_SRC_BCM2711_SYSTIMER_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "bcm2711_memmap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* System timer register offsets */
+
+#define BCM_SYST_CS_OFFSET 0x00
+#define BCM_SYST_CLO_OFFSET 0x04
+#define BCM_SYST_CHI_OFFSET 0x08
+#define BCM_SYST_C0_OFFSET 0x0c
+#define BCM_SYST_C1_OFFSET 0x10
+#define BCM_SYST_C2_OFFSET 0x14
+#define BCM_SYST_C3_OFFSET 0x18
+
+/* System timer register addresses */
+
+#define _BCM_SYST(offset) (BCM_SYST_BASEADDR + (offset))
+
+#define BCM_SYST_CS _BCM_SYST(BCM_SYST_CS_OFFSET)
+#define BCM_SYST_CLO _BCM_SYST(BCM_SYST_CLO_OFFSET)
+#define BCM_SYST_CHI _BCM_SYST(BCM_SYST_CHI_OFFSET)
+#define BCM_SYST_C0 _BCM_SYST(BCM_SYST_C0_OFFSET)
+#define BCM_SYST_C1 _BCM_SYST(BCM_SYST_C1_OFFSET)
+#define BCM_SYST_C2 _BCM_SYST(BCM_SYST_C2_OFFSET)
+#define BCM_SYST_C3 _BCM_SYST(BCM_SYST_C3_OFFSET)
+
+/* System timer register bit definitions */
+
+#define BCM_SYST_CS_M3 (1 << 3)
+#define BCM_SYST_CS_M2 (1 << 2)
+#define BCM_SYST_CS_M1 (1 << 1)
+#define BCM_SYST_CS_M0 (1 << 0)
+
+#endif /* __ARCH_ARM64_SRC_BCM2711_SYSTIMER_H */
diff --git a/arch/arm64/src/bcm2711/hardware/bcm2711_uart.h b/arch/arm64/src/bcm2711/hardware/bcm2711_uart.h
new file mode 100644
index 0000000000..08da3e3e11
--- /dev/null
+++ b/arch/arm64/src/bcm2711/hardware/bcm2711_uart.h
@@ -0,0 +1,292 @@
+/****************************************************************************
+ * arch/arm64/src/bcm2711/hardware/bcm2711_uart.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_BCM2711_UART_H
+#define __ARCH_ARM64_SRC_BCM2711_UART_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "bcm2711_memmap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* UART register offsets */
+
+#define BCM_UART_DR_OFFSET 0x00
+#define BCM_UART_RSRECR_OFFSET 0x04
+#define BCM_UART_FR_OFFSET 0x18
+#define BCM_UART_IBRD_OFFSET 0x24
+#define BCM_UART_FBRD_OFFSET 0x28
+#define BCM_UART_LCRH_OFFSET 0x2c
+#define BCM_UART_CR_OFFSET 0x30
+#define BCM_UART_IFLS_OFFSET 0x34
+#define BCM_UART_IMSC_OFFSET 0x38
+#define BCM_UART_RIS_OFFSET 0x3c
+#define BCM_UART_MIS_OFFSET 0x40
+#define BCM_UART_ICR_OFFSET 0x44
+#define BCM_UART_DMACR_OFFSET 0x48
+#define BCM_UART_ITCR_OFFSET 0x80
+#define BCM_UART_ITIP_OFFSET 0x84
+#define BCM_UART_ITOP_OFFSET 0x88
+#define BCM_UART_TDR_OFFSET 0x8c
+
+/* NOTE: ILPR register deliberately omitted because it is not used on this
+ * chip.
+ */
+
+/* UART register addresses */
+
+#define BCM_UART0_DR (BCM_UART0_BASEADDR + BCM_UART_DR_OFFSET)
+#define BCM_UART0_RSRECR (BCM_UART0_BASEADDR + BCM_UART_RSRECR_OFFSET)
+#define BCM_UART0_FR (BCM_UART0_BASEADDR + BCM_UART_FR_OFFSET)
+#define BCM_UART0_IBRD (BCM_UART0_BASEADDR + BCM_UART_IBRD_OFFSET)
+#define BCM_UART0_FBRD (BCM_UART0_BASEADDR + BCM_UART_FBRD_OFFSET)
+#define BCM_UART0_LCRH (BCM_UART0_BASEADDR + BCM_UART_LCRH_OFFSET)
+#define BCM_UART0_CR (BCM_UART0_BASEADDR + BCM_UART_CR_OFFSET)
+#define BCM_UART0_IFLS (BCM_UART0_BASEADDR + BCM_UART_IFLS_OFFSET)
+#define BCM_UART0_IMSC (BCM_UART0_BASEADDR + BCM_UART_IMSC_OFFSET)
+#define BCM_UART0_RIS (BCM_UART0_BASEADDR + BCM_UART_RIS_OFFSET)
+#define BCM_UART0_MIS (BCM_UART0_BASEADDR + BCM_UART_MIS_OFFSET)
+#define BCM_UART0_ICR (BCM_UART0_BASEADDR + BCM_UART_ICR_OFFSET)
+#define BCM_UART0_DMACR (BCM_UART0_BASEADDR + BCM_UART_DMACR_OFFSET)
+#define BCM_UART0_ITCR (BCM_UART0_BASEADDR + BCM_UART_ITCR_OFFSET)
+#define BCM_UART0_ITIP (BCM_UART0_BASEADDR + BCM_UART_ITIP_OFFSET)
+#define BCM_UART0_ITOP (BCM_UART0_BASEADDR + BCM_UART_ITOP_OFFSET)
+#define BCM_UART0_TDR (BCM_UART0_BASEADDR + BCM_UART_TDR_OFFSET)
+
+#define BCM_UART2_DR (BCM_UART2_BASEADDR + BCM_UART_DR_OFFSET)
+#define BCM_UART2_RSRECR (BCM_UART2_BASEADDR + BCM_UART_RSRECR_OFFSET)
+#define BCM_UART2_FR (BCM_UART2_BASEADDR + BCM_UART_FR_OFFSET)
+#define BCM_UART2_IBRD (BCM_UART2_BASEADDR + BCM_UART_IBRD_OFFSET)
+#define BCM_UART2_FBRD (BCM_UART2_BASEADDR + BCM_UART_FBRD_OFFSET)
+#define BCM_UART2_LCRH (BCM_UART2_BASEADDR + BCM_UART_LCRH_OFFSET)
+#define BCM_UART2_CR (BCM_UART2_BASEADDR + BCM_UART_CR_OFFSET)
+#define BCM_UART2_IFLS (BCM_UART2_BASEADDR + BCM_UART_IFLS_OFFSET)
+#define BCM_UART2_IMSC (BCM_UART2_BASEADDR + BCM_UART_IMSC_OFFSET)
+#define BCM_UART2_RIS (BCM_UART2_BASEADDR + BCM_UART_RIS_OFFSET)
+#define BCM_UART2_MIS (BCM_UART2_BASEADDR + BCM_UART_MIS_OFFSET)
+#define BCM_UART2_ICR (BCM_UART2_BASEADDR + BCM_UART_ICR_OFFSET)
+#define BCM_UART2_DMACR (BCM_UART2_BASEADDR + BCM_UART_DMACR_OFFSET)
+#define BCM_UART2_ITCR (BCM_UART2_BASEADDR + BCM_UART_ITCR_OFFSET)
+#define BCM_UART2_ITIP (BCM_UART2_BASEADDR + BCM_UART_ITIP_OFFSET)
+#define BCM_UART2_ITOP (BCM_UART2_BASEADDR + BCM_UART_ITOP_OFFSET)
+#define BCM_UART2_TDR (BCM_UART2_BASEADDR + BCM_UART_TDR_OFFSET)
+
+#define BCM_UART3_DR (BCM_UART3_BASEADDR + BCM_UART_DR_OFFSET)
+#define BCM_UART3_RSRECR (BCM_UART3_BASEADDR + BCM_UART_RSRECR_OFFSET)
+#define BCM_UART3_FR (BCM_UART3_BASEADDR + BCM_UART_FR_OFFSET)
+#define BCM_UART3_IBRD (BCM_UART3_BASEADDR + BCM_UART_IBRD_OFFSET)
+#define BCM_UART3_FBRD (BCM_UART3_BASEADDR + BCM_UART_FBRD_OFFSET)
+#define BCM_UART3_LCRH (BCM_UART3_BASEADDR + BCM_UART_LCRH_OFFSET)
+#define BCM_UART3_CR (BCM_UART3_BASEADDR + BCM_UART_CR_OFFSET)
+#define BCM_UART3_IFLS (BCM_UART3_BASEADDR + BCM_UART_IFLS_OFFSET)
+#define BCM_UART3_IMSC (BCM_UART3_BASEADDR + BCM_UART_IMSC_OFFSET)
+#define BCM_UART3_RIS (BCM_UART3_BASEADDR + BCM_UART_RIS_OFFSET)
+#define BCM_UART3_MIS (BCM_UART3_BASEADDR + BCM_UART_MIS_OFFSET)
+#define BCM_UART3_ICR (BCM_UART3_BASEADDR + BCM_UART_ICR_OFFSET)
+#define BCM_UART3_DMACR (BCM_UART3_BASEADDR + BCM_UART_DMACR_OFFSET)
+#define BCM_UART3_ITCR (BCM_UART3_BASEADDR + BCM_UART_ITCR_OFFSET)
+#define BCM_UART3_ITIP (BCM_UART3_BASEADDR + BCM_UART_ITIP_OFFSET)
+#define BCM_UART3_ITOP (BCM_UART3_BASEADDR + BCM_UART_ITOP_OFFSET)
+#define BCM_UART3_TDR (BCM_UART3_BASEADDR + BCM_UART_TDR_OFFSET)
+
+#define BCM_UART4_DR (BCM_UART4_BASEADDR + BCM_UART_DR_OFFSET)
+#define BCM_UART4_RSRECR (BCM_UART4_BASEADDR + BCM_UART_RSRECR_OFFSET)
+#define BCM_UART4_FR (BCM_UART4_BASEADDR + BCM_UART_FR_OFFSET)
+#define BCM_UART4_IBRD (BCM_UART4_BASEADDR + BCM_UART_IBRD_OFFSET)
+#define BCM_UART4_FBRD (BCM_UART4_BASEADDR + BCM_UART_FBRD_OFFSET)
+#define BCM_UART4_LCRH (BCM_UART4_BASEADDR + BCM_UART_LCRH_OFFSET)
+#define BCM_UART4_CR (BCM_UART4_BASEADDR + BCM_UART_CR_OFFSET)
+#define BCM_UART4_IFLS (BCM_UART4_BASEADDR + BCM_UART_IFLS_OFFSET)
+#define BCM_UART4_IMSC (BCM_UART4_BASEADDR + BCM_UART_IMSC_OFFSET)
+#define BCM_UART4_RIS (BCM_UART4_BASEADDR + BCM_UART_RIS_OFFSET)
+#define BCM_UART4_MIS (BCM_UART4_BASEADDR + BCM_UART_MIS_OFFSET)
+#define BCM_UART4_ICR (BCM_UART4_BASEADDR + BCM_UART_ICR_OFFSET)
+#define BCM_UART4_DMACR (BCM_UART4_BASEADDR + BCM_UART_DMACR_OFFSET)
+#define BCM_UART4_ITCR (BCM_UART4_BASEADDR + BCM_UART_ITCR_OFFSET)
+#define BCM_UART4_ITIP (BCM_UART4_BASEADDR + BCM_UART_ITIP_OFFSET)
+#define BCM_UART4_ITOP (BCM_UART4_BASEADDR + BCM_UART_ITOP_OFFSET)
+#define BCM_UART4_TDR (BCM_UART4_BASEADDR + BCM_UART_TDR_OFFSET)
+
+#define BCM_UART5_DR (BCM_UART5_BASEADDR + BCM_UART_DR_OFFSET)
+#define BCM_UART5_RSRECR (BCM_UART5_BASEADDR + BCM_UART_RSRECR_OFFSET)
+#define BCM_UART5_FR (BCM_UART5_BASEADDR + BCM_UART_FR_OFFSET)
+#define BCM_UART5_IBRD (BCM_UART5_BASEADDR + BCM_UART_IBRD_OFFSET)
+#define BCM_UART5_FBRD (BCM_UART5_BASEADDR + BCM_UART_FBRD_OFFSET)
+#define BCM_UART5_LCRH (BCM_UART5_BASEADDR + BCM_UART_LCRH_OFFSET)
+#define BCM_UART5_CR (BCM_UART5_BASEADDR + BCM_UART_CR_OFFSET)
+#define BCM_UART5_IFLS (BCM_UART5_BASEADDR + BCM_UART_IFLS_OFFSET)
+#define BCM_UART5_IMSC (BCM_UART5_BASEADDR + BCM_UART_IMSC_OFFSET)
+#define BCM_UART5_RIS (BCM_UART5_BASEADDR + BCM_UART_RIS_OFFSET)
+#define BCM_UART5_MIS (BCM_UART5_BASEADDR + BCM_UART_MIS_OFFSET)
+#define BCM_UART5_ICR (BCM_UART5_BASEADDR + BCM_UART_ICR_OFFSET)
+#define BCM_UART5_DMACR (BCM_UART5_BASEADDR + BCM_UART_DMACR_OFFSET)
+#define BCM_UART5_ITCR (BCM_UART5_BASEADDR + BCM_UART_ITCR_OFFSET)
+#define BCM_UART5_ITIP (BCM_UART5_BASEADDR + BCM_UART_ITIP_OFFSET)
+#define BCM_UART5_ITOP (BCM_UART5_BASEADDR + BCM_UART_ITOP_OFFSET)
+#define BCM_UART5_TDR (BCM_UART5_BASEADDR + BCM_UART_TDR_OFFSET)
+
+/* UART register bit definitions */
+
+#define BCM_UART_DR_OE (1 << 11)
+#define BCM_UART_DR_BE (1 << 10)
+#define BCM_UART_DR_PE (1 << 9)
+#define BCM_UART_DR_FE (1 << 8)
+#define BCM_UART_DR_DATA (0xff << 0)
+
+#define BCM_UART_RSRECR_OE (1 << 3)
+#define BCM_UART_RSRECR_BE (1 << 2)
+#define BCM_UART_RSRECR_PE (1 << 1)
+#define BCM_UART_RSRECR_FE (1 << 0)
+
+#define BCM_UART_FR_RI (1 << 8)
+#define BCM_UART_FR_TXFE (1 << 7)
+#define BCM_UART_FR_RXFF (1 << 6)
+#define BCM_UART_FR_TXFF (1 << 5)
+#define BCM_UART_FR_RXFE (1 << 4)
+#define BCM_UART_FR_BUSY (1 << 3)
+#define BCM_UART_FR_DCD (1 << 2)
+#define BCM_UART_FR_DSR (1 << 1)
+#define BCM_UART_FR_CTS (1 << 0)
+
+#define BCM_UART_IBRD_IBRD (0xffff << 0)
+
+#define BCM_UART_FBRD_FBRD (0x3f << 0)
+
+#define BCM_UART_LCRH_SPS (1 << 7)
+#define BCM_UART_LCRH_WLEN (0x3 << 5)
+#define BCM_UART_LCRH_FEN (1 << 4)
+#define BCM_UART_LCRH_STP2 (1 << 3)
+#define BCM_UART_LCRH_EPS (1 << 2)
+#define BCM_UART_LCRH_PEN (1 << 1)
+#define BCM_UART_LCRH_BRK (1 << 0)
+
+#define BCM_UART_CR_CTSEN (1 << 15)
+#define BCM_UART_CR_RTSEN (1 << 14)
+#define BCM_UART_CR_OUT2 (1 << 13)
+#define BCM_UART_CR_OUT1 (1 << 12)
+#define BCM_UART_CR_RTS (1 << 11)
+#define BCM_UART_CR_DTR (1 << 10)
+#define BCM_UART_CR_RXE (1 << 9)
+#define BCM_UART_CR_TXE (1 << 8)
+#define BCM_UART_CR_LBE (1 << 7)
+#define BCM_UART_CR_SIRLP (1 << 2)
+#define BCM_UART_CR_SIREN (1 << 1)
+#define BCM_UART_CR_UARTEN (1 << 0)
+
+#define BCM_UART_IFLS_RXIFPSEL (0x7 << 9)
+#define BCM_UART_IFLS_TXIFPSEL (0x7 << 6)
+#define BCM_UART_IFLS_RXIFLSEL (0x7 << 3)
+#define BCM_UART_IFLS_RXFIFO18 (0 << 3) /* RX FIFO is 1/8 full */
+#define BCM_UART_IFLS_RXFIFO14 (1 << 3) /* RX FIFO is 1/4 full */
+#define BCM_UART_IFLS_RXFIFO12 (2 << 3) /* RX FIFO is 1/2 full */
+#define BCM_UART_IFLS_RXFIFO34 (3 << 3) /* RX FIFO is 3/4 full */
+#define BCM_UART_IFLS_RXFIFO78 (4 << 3) /* RX FIFO is 7/8 full */
+#define BCM_UART_IFLS_TXIFLSEL (0x7 << 0)
+#define BCM_UART_IFLS_TXFIFO18 (0 << 3) /* TX FIFO is 1/8 full */
+#define BCM_UART_IFLS_TXFIFO14 (1 << 3) /* TX FIFO is 1/4 full */
+#define BCM_UART_IFLS_TXFIFO12 (2 << 3) /* TX FIFO is 1/2 full */
+#define BCM_UART_IFLS_TXFIFO34 (3 << 3) /* TX FIFO is 3/4 full */
+#define BCM_UART_IFLS_TXFIFO78 (4 << 3) /* TX FIFO is 7/8 full */
+
+/* NOTE: DSRMIM and DCDMIM are deliberately omitted because they are
+ * unsupported on this chip.
+ */
+
+#define BCM_UART_IMSC_OEIM (1 << 10)
+#define BCM_UART_IMSC_BEIM (1 << 9)
+#define BCM_UART_IMSC_PEIM (1 << 8)
+#define BCM_UART_IMSC_FEIM (1 << 7)
+#define BCM_UART_IMSC_RTIM (1 << 6)
+#define BCM_UART_IMSC_TXIM (1 << 5)
+#define BCM_UART_IMSC_RXIM (1 << 4)
+#define BCM_UART_IMSC_CTSMIM (1 << 1)
+#define BCM_UART_IMSC_RIMIM (1 << 0)
+
+/* NOTE: DSRRMIS and DCDRMIS are deliberately omitted because they are
+ * unsupported on this chip.
+ */
+
+#define BCM_UART_RIS_OERIS (1 << 10)
+#define BCM_UART_RIS_BERIS (1 << 9)
+#define BCM_UART_RIS_PERIS (1 << 8)
+#define BCM_UART_RIS_FERIS (1 << 7)
+#define BCM_UART_RIS_RTRIS (1 << 6)
+#define BCM_UART_RIS_TXRIS (1 << 5)
+#define BCM_UART_RIS_RXRIS (1 << 4)
+#define BCM_UART_RIS_CTSRMIS (1 << 1)
+#define BCM_UART_RIS_RIRMIS (1 << 0)
+
+/* NOTE: DSRMMIS and DCDMMIS are deliberately omitted because they are
+ * unsupported on this chip.
+ */
+
+#define BCM_UART_MIS_OEMIS (1 << 10)
+#define BCM_UART_MIS_BEMIS (1 << 9)
+#define BCM_UART_MIS_PEMIS (1 << 8)
+#define BCM_UART_MIS_FEMIS (1 << 7)
+#define BCM_UART_MIS_RTMIS (1 << 6)
+#define BCM_UART_MIS_TXMIS (1 << 5)
+#define BCM_UART_MIS_RXMIS (1 << 4)
+#define BCM_UART_MIS_CTSMMIS (1 << 1)
+#define BCM_UART_MIS_RIMMIS (1 << 0)
+
+/* NOTE: DSRMIC and DCDMIC are deliberately omitted because they are
+ * unsupported on this chip.
+ */
+
+#define BCM_UART_ICR_OEIC (1 << 10)
+#define BCM_UART_ICR_BEIC (1 << 9)
+#define BCM_UART_ICR_PEIC (1 << 8)
+#define BCM_UART_ICR_FEIC (1 << 7)
+#define BCM_UART_ICR_RTIC (1 << 6)
+#define BCM_UART_ICR_TXIC (1 << 5)
+#define BCM_UART_ICR_RXIC (1 << 4)
+#define BCM_UART_ICR_CTSMIC (1 << 1)
+#define BCM_UART_ICR_RIMIC (1 << 0)
+
+#define BCM_UART_DMACR_DMAONERR (1 << 2)
+#define BCM_UART_DMACR_TXDMAE (1 << 1)
+#define BCM_UART_DMACR_RXDMAE (1 << 0)
+
+#define BCM_UART_ITCR_ITCR1 (1 << 1)
+#define BCM_UART_ITCR_ITCR0 (1 << 0)
+
+#define BCM_UART_ITIP_ITIP3 (1 << 3)
+#define BCM_UART_ITIP_ITIP0 (1 << 0)
+
+#define BCM_UART_ITOP_ITOP11 (1 << 11)
+#define BCM_UART_ITOP_ITOP10 (1 << 10)
+#define BCM_UART_ITOP_ITOP9 (1 << 9)
+#define BCM_UART_ITOP_ITOP8 (1 << 8)
+#define BCM_UART_ITOP_ITOP7 (1 << 7)
+#define BCM_UART_ITOP_ITOP6 (1 << 6)
+#define BCM_UART_ITOP_ITOP3 (1 << 3)
+#define BCM_UART_ITOP_ITOP0 (1 << 0)
+
+#define BCM_UART_TDR_TDR10_0 (0x7ff << 0)
+
+#endif /* __ARCH_ARM64_SRC_BCM2711_UART_H */
diff --git a/boards/Kconfig b/boards/Kconfig
index 15ed928466..2f4e74c236 100644
--- a/boards/Kconfig
+++ b/boards/Kconfig
@@ -1923,6 +1923,12 @@ config ARCH_BOARD_RASPBERRYPI_PICO_W
---help---
This is a port to the Raspberry Pi Pico W board.
+config ARCH_BOARD_RASPBERRYPI_4B
+ bool "Raspberry Pi Model 4B"
+ depends on ARCH_CHIP_BCM2711
+ ---help---
+ This is a port to the Raspberry Pi Model 4B.
+
config ARCH_BOARD_PIMORONI_TINY2040
bool "Pimoroni Tiny2040 board"
depends on ARCH_CHIP_RP2040
@@ -3473,6 +3479,7 @@ config ARCH_BOARD
default "qemu-i486" if ARCH_BOARD_QEMU_I486
default "qemu-intel64" if ARCH_BOARD_INTEL64_QEMU
default "raspberrypi-pico" if ARCH_BOARD_RASPBERRYPI_PICO
+ default "raspberrypi-4b" if ARCH_BOARD_RASPBERRYPI_4B
default "raspberrypi-pico-w" if ARCH_BOARD_RASPBERRYPI_PICO_W
default "pimoroni-tiny2040" if ARCH_BOARD_PIMORONI_TINY2040
default "adafruit-feather-rp2040" if ARCH_BOARD_ADAFRUIT_FEATHER_RP2040
@@ -3930,6 +3937,9 @@ endif
if ARCH_BOARD_RASPBERRYPI_PICO
source "boards/arm/rp2040/raspberrypi-pico/Kconfig"
endif
+if ARCH_BOARD_RASPBERRYPI_4B
+source "boards/arm64/bcm2711/raspberrypi-4b/Kconfig"
+endif
if ARCH_BOARD_RASPBERRYPI_PICO_W
source "boards/arm/rp2040/raspberrypi-pico-w/Kconfig"
endif
diff --git a/boards/arm64/bcm2711/raspberrypi-4b/Kconfig b/boards/arm64/bcm2711/raspberrypi-4b/Kconfig
new file mode 100644
index 0000000000..d8640e8d60
--- /dev/null
+++ b/boards/arm64/bcm2711/raspberrypi-4b/Kconfig
@@ -0,0 +1,41 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+if ARCH_BOARD_RASPBERRYPI_4B
+
+ choice
+ prompt "Raspberry Pi 4B RAM size"
+ default RPI4B_RAM_4GB
+
+ config RPI4B_RAM_1GB
+ bool "1GB RAM"
+ ---help---
+ Support for the 1GB variant of the Raspberry Pi 4B.
+
+ config RPI4B_RAM_2GB
+ bool "2GB RAM"
+ ---help---
+ Support for the 2GB variant of the Raspberry Pi 4B.
+
+ config RPI4B_RAM_4GB
+ bool "4GB RAM"
+ ---help---
+ Support for the 4GB variant of the Raspberry Pi 4B.
+
+ config RPI4B_RAM_8GB
+ bool "8GB RAM"
+ ---help---
+ Support for the 8GB variant of the Raspberry Pi 4B.
+
+ endchoice # Raspberry Pi 4B RAM size
+
+ config RPI4B_DEBUG_BOOT
+ bool "Raspberry Pi 4B bootloader debug output"
+ default n
+ ---help---
+ Enables the debug output of the Raspberry Pi 4B bootloader.
+
+
+endif # ARCH_BOARD_RASPBERRYPI_4B
diff --git a/boards/arm64/bcm2711/raspberrypi-4b/configs/nsh/defconfig b/boards/arm64/bcm2711/raspberrypi-4b/configs/nsh/defconfig
new file mode 100644
index 0000000000..211383847d
--- /dev/null
+++ b/boards/arm64/bcm2711/raspberrypi-4b/configs/nsh/defconfig
@@ -0,0 +1,61 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+CONFIG_ARCH="arm64"
+CONFIG_ARCH_ARM64=y
+CONFIG_ARCH_BOARD="raspberrypi-4b"
+CONFIG_ARCH_BOARD_RASPBERRYPI_4B=y
+CONFIG_ARCH_CHIP="bcm2711"
+CONFIG_ARCH_CHIP_BCM2711=y
+CONFIG_ARCH_EARLY_PRINT=y
+CONFIG_ARCH_INTERRUPTSTACK=4096
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_ASSERTIONS=y
+CONFIG_DEBUG_FEATURES=y
+CONFIG_DEBUG_FULLOPT=y
+CONFIG_DEBUG_SCHED=y
+CONFIG_DEBUG_SCHED_ERROR=y
+CONFIG_DEBUG_SCHED_WARN=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_DEFAULT_TASK_STACKSIZE=8192
+CONFIG_DEV_ZERO=y
+CONFIG_EXAMPLES_HELLO=y
+CONFIG_EXAMPLES_LEDS=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_FS_PROCFS=y
+CONFIG_FS_ROMFS=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_IDLETHREAD_STACKSIZE=8192
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INTELHEX_BINARY=y
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_PTHREAD_STACK_MIN=8192
+CONFIG_RAMLOG=y
+CONFIG_RAM_SIZE=4227858432
+CONFIG_RAM_START=0x00000000
+CONFIG_RAW_BINARY=y
+CONFIG_READLINE_CMD_HISTORY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_HPWORK=y
+CONFIG_SCHED_HPWORKPRIORITY=192
+CONFIG_SPINLOCK=y
+CONFIG_STACK_COLORATION=y
+CONFIG_START_MONTH=11
+CONFIG_START_YEAR=2022
+CONFIG_SYMTAB_ORDEREDBYNAME=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_SYSTEM_SYSTEM=y
+CONFIG_SYSTEM_TIME64=y
+CONFIG_TESTING_GETPRIME=y
+CONFIG_TESTING_OSTEST=y
+CONFIG_USEC_PER_TICK=1000
+CONFIG_USERLED=y
diff --git a/boards/arm64/bcm2711/raspberrypi-4b/include/board.h b/boards/arm64/bcm2711/raspberrypi-4b/include/board.h
new file mode 100644
index 0000000000..b9ffe16a39
--- /dev/null
+++ b/boards/arm64/bcm2711/raspberrypi-4b/include/board.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+ * boards/arm64/bcm2711/raspberrypi-4b/include/board.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __BOARDS_ARM64_BCM2711_RPI4B_INCLUDE_BOARD_H
+#define __BOARDS_ARM64_BCM2711_RPI4B_INCLUDE_BOARD_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* TODO: define all the GPIO pins properly */
+
+#define BOARD_NGPIOOUT 1
+#define BOARD_NGPIOIN 1
+#define BOARD_NGPIOINT 0
+
+#endif /* __BOARDS_ARM64_BCM2711_RPI4B_INCLUDE_BOARD_H */
diff --git a/boards/arm64/bcm2711/raspberrypi-4b/scripts/Make.defs b/boards/arm64/bcm2711/raspberrypi-4b/scripts/Make.defs
new file mode 100644
index 0000000000..6b4b616b7b
--- /dev/null
+++ b/boards/arm64/bcm2711/raspberrypi-4b/scripts/Make.defs
@@ -0,0 +1,49 @@
+############################################################################
+# boards/arm64/bcm2711/raspberrypi-4b/scripts/Make.defs
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+include $(TOPDIR)/.config
+include $(TOPDIR)/tools/Config.mk
+include $(TOPDIR)/tools/bcm2711/Config.mk
+include $(TOPDIR)/arch/arm64/src/Toolchain.defs
+
+LDSCRIPT = dramboot.ld
+
+ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)
+
+CFLAGS := $(ARCHCFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe
+CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
+CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe
+CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
+CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS)
+AFLAGS := $(CFLAGS) -D__ASSEMBLY__
+
+# NXFLAT module definitions
+
+NXFLATLDFLAGS1 = -r -d -warn-common
+NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)$(DELIM)binfmt$(DELIM)libnxflat$(DELIM)gnu-nxflat-pcrel.ld -no-check-sections
+LDNXFLATFLAGS = -e main -s 2048
+
+# ELF module definitions
+
+CELFFLAGS = $(CFLAGS) -mlong-calls # --target1-abs
+CXXELFFLAGS = $(CXXFLAGS) -mlong-calls # --target1-abs
+
+LDELFFLAGS = -r -e main
+LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/binfmt/libelf/gnu-elf.ld)
diff --git a/boards/arm64/bcm2711/raspberrypi-4b/scripts/dramboot.ld b/boards/arm64/bcm2711/raspberrypi-4b/scripts/dramboot.ld
new file mode 100644
index 0000000000..1b55d7dddb
--- /dev/null
+++ b/boards/arm64/bcm2711/raspberrypi-4b/scripts/dramboot.ld
@@ -0,0 +1,129 @@
+/****************************************************************************
+ * boards/arm64/bcm2711/raspberrypi-4b/scripts/dramboot.ld
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+OUTPUT_ARCH(aarch64) /* Architecture to use */
+
+ENTRY(__start) /* Entry point for the program */
+
+PHDRS
+{
+ text PT_LOAD ;
+}
+
+SECTIONS
+{
+ . = 0x480000; /* Kernel load address for aarch64 */
+ _start = .;
+ .text : {
+ _stext = .; /* Text section */
+ *(.start .start.*) /* Place __start here */
+ *(.text)
+ *(.text.cold)
+ *(.text.unlikely)
+ *(.fixup)
+ *(.gnu.warning)
+ } :text = 0x9090
+
+ . = ALIGN(4096);
+
+ .init_section : {
+ _sinit = ABSOLUTE(.);
+ KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP(*(.init_array .ctors))
+ _einit = ABSOLUTE(.);
+ }
+
+ . = ALIGN(4096);
+
+ .vector : {
+ _vector_start = .;
+ KEEP(*(.exc_vector_table))
+ KEEP(*(".exc_vector_table.*"))
+ KEEP(*(.vectors))
+ _vector_end = .;
+ } :text
+ . = ALIGN(4096);
+ _etext = .; /* End_1 of .text */
+ _sztext = _etext - _stext;
+
+ . = ALIGN(4096);
+ .rodata : {
+ _srodata = .; /* Read-only data */
+ *(.rodata)
+ *(.rodata.*)
+ *(.data.rel.ro)
+ *(.data.rel.ro.*)
+ } :text
+ . = ALIGN(4096);
+ _erodata = .; /* End of read-only data */
+ _szrodata = _erodata - _srodata;
+ _eronly = .; /* End of read-only data */
+
+ . = ALIGN(4096);
+ .data : { /* Data */
+ _sdata = .;
+ *(.data.page_aligned)
+ *(.data)
+ . = ALIGN(8);
+ *(.data.rel)
+ *(.data.rel.*)
+ CONSTRUCTORS
+ } :text
+ _edata = .; /* End+1 of .data */
+
+ .bss : { /* BSS */
+ . = ALIGN(8);
+ _sbss = .;
+ *(.bss)
+ . = ALIGN(8);
+ } :text
+ . = ALIGN(4096);
+ _ebss = .;
+ _szbss = _ebss - _sbss;
+
+ .initstack : { /* INIT STACK */
+ _s_initstack = .;
+ *(.initstack)
+ . = ALIGN(16);
+ } :text
+ . = ALIGN(4096);
+ _e_initstack = . ;
+ g_idle_topstack = . ;
+
+ _szdata = _e_initstack - _sdata;
+
+ /* Sections to be discarded */
+ /DISCARD/ : {
+ *(.exit.text)
+ *(.exit.data)
+ *(.exitcall.exit)
+ *(.eh_frame)
+ }
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+}
+
diff --git a/boards/arm64/bcm2711/raspberrypi-4b/src/Makefile b/boards/arm64/bcm2711/raspberrypi-4b/src/Makefile
new file mode 100644
index 0000000000..0895609fa3
--- /dev/null
+++ b/boards/arm64/bcm2711/raspberrypi-4b/src/Makefile
@@ -0,0 +1,41 @@
+############################################################################
+# boards/arm64/bcm2711/raspberrypi-4b/src/Makefile
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+include $(TOPDIR)/Make.defs
+
+CSRCS += rpi4b_boardinitialize.c rpi4b_bringup.c
+
+ifeq ($(CONFIG_BOARDCTL),y)
+CSRCS += rpi4b_appinit.c
+endif
+
+ifeq ($(CONFIG_DEV_GPIO),y)
+CSRCS += rpi4b_gpio.c
+endif
+
+ifeq ($(CONFIG_BCM2711_I2C_DRIVER),y)
+CSRCS += bcm2711_i2cdev.c
+endif
+
+include $(TOPDIR)/boards/Board.mk
+
+.PHONY: distclean
+distclean::
+ $(call DELFILE, ${TOPDIR}${DELIM}config.txt)
diff --git a/boards/arm64/bcm2711/raspberrypi-4b/src/bcm2711_i2cdev.c b/boards/arm64/bcm2711/raspberrypi-4b/src/bcm2711_i2cdev.c
new file mode 100644
index 0000000000..4123d04ab8
--- /dev/null
+++ b/boards/arm64/bcm2711/raspberrypi-4b/src/bcm2711_i2cdev.c
@@ -0,0 +1,75 @@
+/****************************************************************************
+ * boards/arm64/bcm2711/raspberrypi-4b/src/bcm2711_i2cdev.c
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include
+#include
+#include
+
+#include "bcm2711_i2c.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_i2cdev_initialize
+ *
+ * Description:
+ * Initialize and register the I2C character driver for the specified I2C
+ * port/bus number.
+ * NOTE: Driver will be registered at /dev/i2c[`port`]
+ *
+ * Input parameters:
+ * port - The I2C bus number/port number to register the driver for.
+ *
+ ****************************************************************************/
+
+int bcm2711_i2cdev_initialize(int port)
+{
+ int ret;
+ struct i2c_master_s *i2c;
+
+ i2cinfo("Initializing /dev/i2c%d..\n", port);
+
+ /* Initialize I2C device */
+
+ i2c = bcm2711_i2cbus_initialize(port);
+ if (!i2c)
+ {
+ i2cerr("ERROR: Failed to initialize I2C bus %d.\n", port);
+ return -ENODEV;
+ }
+
+ ret = i2c_register(i2c, port);
+ if (ret < 0)
+ {
+ i2cerr("ERROR: Failed to register /dev/i2c%d: %d\n", port, ret);
+ }
+
+ return ret;
+}
diff --git a/boards/arm64/bcm2711/raspberrypi-4b/src/bcm2711_i2cdev.h b/boards/arm64/bcm2711/raspberrypi-4b/src/bcm2711_i2cdev.h
new file mode 100644
index 0000000000..a58c33c5a7
--- /dev/null
+++ b/boards/arm64/bcm2711/raspberrypi-4b/src/bcm2711_i2cdev.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ * boards/arm64/bcm2711/raspberrypi-4b/src/bcm2711_i2cdev.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __BOARDS_ARM64_BCM2711_RASPBERRYPI_4B_INCLUDE_BCM2711_I2CDEV_H
+#define __BOARDS_ARM64_BCM2711_RASPBERRYPI_4B_INCLUDE_BCM2711_I2CDEV_H
+
+/****************************************************************************
+ * Name: board_i2cdev_initialize
+ *
+ * Description:
+ * Initialize and register the I2C character driver for the specified I2C
+ * port/bus number.
+ * NOTE: Driver will be registered at /dev/i2c[`port`]
+ *
+ * Input parameters:
+ * port - The I2C bus number/port number to register the driver for.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_BCM2711_I2C_DRIVER)
+int bcm2711_i2cdev_initialize(int port);
+#endif /* defined(BCM2711_I2C_DRIVER) */
+
+#endif /* __BOARDS_ARM64_BCM2711_RASPBERRYPI_4B_INCLUDE_BCM2711_I2CDEV_H */
diff --git a/boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b.h b/boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b.h
new file mode 100644
index 0000000000..fae66eae46
--- /dev/null
+++ b/boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+ * boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b.h
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __BOARDS_ARM64_BCM2711_RASPBERRYPI_4B_SRC_RPI4B_H
+#define __BOARDS_ARM64_BCM2711_RASPBERRYPI_4B_SRC_RPI4B_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+/****************************************************************************
+ * Public Functions Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rpi4b_bringup
+ *
+ * Description:
+ * Bring up board features
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_BOARDCTL) || defined(CONFIG_BOARD_LATE_INITIALIZE)
+int rpi4b_bringup(void);
+#endif
+
+#if defined(CONFIG_DEV_GPIO)
+int bcm2711_dev_gpio_init(void);
+#endif /* defined(CONFIG_DEV_GPIO) */
+
+#endif /* __BOARDS_ARM64_BCM2711_RASPBERRYPI_4B_SRC_RPI4B_H */
diff --git a/boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b_appinit.c b/boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b_appinit.c
new file mode 100644
index 0000000000..81943a7261
--- /dev/null
+++ b/boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b_appinit.c
@@ -0,0 +1,89 @@
+/****************************************************************************
+ * boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b_appinit.c
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "rpi4b.h"
+#include
+#include
+#include
+#include
+#include
+
+#ifdef CONFIG_BOARDCTL
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_app_initialize
+ *
+ * Description:
+ * Perform application specific initialization. This function is never
+ * called directly from application code, but only indirectly via the
+ * (non-standard) boardctl() interface using the command BOARDIOC_INIT.
+ *
+ * Input Parameters:
+ * arg - The boardctl() argument is passed to the board_app_initialize()
+ * implementation without modification. The argument has no
+ * meaning to NuttX; the meaning of the argument is a contract
+ * between the board-specific initialization logic and the
+ * matching application logic. The value could be such things as a
+ * mode enumeration value, a set of DIP switch switch settings, a
+ * pointer to configuration data read from a file or serial FLASH,
+ * or whatever you would like to do with it. Every implementation
+ * should accept zero/NULL as a default configuration.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned on
+ * any failure to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+int board_app_initialize(uintptr_t arg)
+{
+ UNUSED(arg);
+ int ret = OK;
+
+#ifdef CONFIG_FS_PROCFS
+ /* Mount the proc file system */
+
+ ret = nx_mount(NULL, "/proc", "procfs", 0, NULL);
+ if (ret < 0)
+ {
+ _err("ERROR: Failed to mount procfs at /proc: %d\n", ret);
+ }
+#endif
+
+#ifndef CONFIG_BOARD_LATE_INITIALIZE
+ /* Perform board initialization */
+
+ ret = rpi4b_bringup();
+#endif
+
+ return ret;
+}
+
+#endif /* CONFIG_BOARDCTL */
diff --git a/boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b_boardinitialize.c b/boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b_boardinitialize.c
new file mode 100644
index 0000000000..ddc82e4883
--- /dev/null
+++ b/boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b_boardinitialize.c
@@ -0,0 +1,108 @@
+/****************************************************************************
+ * boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b_boardinitialize.c
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "rpi4b.h"
+#include
+#include
+#include
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: bcm2711_memory_initialize
+ *
+ * Description:
+ * All BCM2711 architectures must provide the following entry point. This
+ * entry point is called early in the initialization before memory has
+ * been configured. This board-specific function is responsible for
+ * configuring any on-board memories.
+ *
+ * Logic in a64_memory_initialize must be careful to avoid using any
+ * global variables because those will be uninitialized at the time this
+ * function is called.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void bcm2711_memory_initialize(void)
+{
+ /* TODO */
+}
+
+/****************************************************************************
+ * Name: bcm2711_board_initialize
+ *
+ * Description:
+ * All BCM2711 architectures must provide the following entry point. This
+ * entry point is called in the initialization phase -- after
+ * bcm2711_memory_initialize and after all memory has been configured and
+ * mapped but before any devices have been initialized.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void bcm2711_board_initialize(void)
+{
+#ifdef CONFIG_ARCH_LEDS
+ /* Configure on-board LEDs if LED support has been selected. */
+
+ board_autoled_initialize();
+#endif
+}
+
+/****************************************************************************
+ * Name: board_late_initialize
+ *
+ * Description:
+ * If CONFIG_BOARD_LATE_INITIALIZE is selected, then an additional
+ * initialization call will be performed in the boot-up sequence to a
+ * function called board_late_initialize(). board_late_initialize() will be
+ * called immediately after up_initialize() is called and just before the
+ * initial application is started. This additional initialization phase
+ * may be used, for example, to initialize board-specific device drivers.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_BOARD_LATE_INITIALIZE
+void board_late_initialize(void)
+{
+ /* Perform board initialization */
+
+ rpi4b_bringup();
+}
+#endif /* CONFIG_BOARD_LATE_INITIALIZE */
diff --git a/boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b_bringup.c b/boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b_bringup.c
new file mode 100644
index 0000000000..d303bf7173
--- /dev/null
+++ b/boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b_bringup.c
@@ -0,0 +1,123 @@
+/****************************************************************************
+ * boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b_bringup.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "rpi4b.h"
+#include
+#include
+#include
+
+#if defined(CONFIG_BCM2711_I2C_DRIVER)
+#include "bcm2711_i2cdev.h"
+#endif /* defined(CONFIG_BCM2711_I2C) */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rpi4b_bringup
+ *
+ * Description:
+ * Bring up board features
+ *
+ ****************************************************************************/
+
+int rpi4b_bringup(void)
+{
+ int ret = OK;
+
+ /* Initialize GPIO driver. */
+
+#if defined(CONFIG_DEV_GPIO)
+ ret = bcm2711_dev_gpio_init();
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "Failed to initialize GPIO driver: %d\n.", ret);
+ }
+#endif // defined(CONFIG_DEV_GPIO)
+
+ /* Initialize I2C interfaces. */
+
+#if defined(CONFIG_BCM2711_I2C)
+
+#if defined(CONFIG_BCM2711_I2C0)
+ ret = bcm2711_i2cdev_initialize(0);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "Failed to initialize I2C0: %d\n", ret);
+ }
+#endif /* defined(CONFIG_BCM2711_I2C0) */
+
+#if defined(CONFIG_BCM2711_I2C1)
+ ret = bcm2711_i2cdev_initialize(1);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "Failed to initialize I2C1: %d\n", ret);
+ }
+#endif /* defined(CONFIG_BCM2711_I2C1) */
+
+#if defined(CONFIG_BCM2711_I2C2)
+ ret = bcm2711_i2cdev_initialize(2);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "Failed to initialize I2C2: %d\n", ret);
+ }
+#endif /* defined(CONFIG_BCM2711_I2C2) */
+
+#if defined(CONFIG_BCM2711_I2C3)
+ ret = bcm2711_i2cdev_initialize(3);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "Failed to initialize I2C3: %d\n", ret);
+ }
+#endif /* defined(CONFIG_BCM2711_I2C3) */
+
+#if defined(CONFIG_BCM2711_I2C4)
+ ret = bcm2711_i2cdev_initialize(4);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "Failed to initialize I2C4: %d\n", ret);
+ }
+#endif /* defined(CONFIG_BCM2711_I2C4) */
+
+#if defined(CONFIG_BCM2711_I2C5)
+ ret = bcm2711_i2cdev_initialize(5);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "Failed to initialize I2C5: %d\n", ret);
+ }
+#endif /* defined(CONFIG_BCM2711_I2C5) */
+
+#if defined(CONFIG_BCM2711_I2C6)
+ ret = bcm2711_i2cdev_initialize(6);
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "Failed to initialize I2C6: %d\n", ret);
+ }
+#endif /* defined(CONFIG_BCM2711_I2C6) */
+
+#endif /* defined(CONFIG_BCM2711_I2C) */
+
+ return ret;
+}
diff --git a/boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b_gpio.c b/boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b_gpio.c
new file mode 100644
index 0000000000..50857fe1e9
--- /dev/null
+++ b/boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b_gpio.c
@@ -0,0 +1,340 @@
+/****************************************************************************
+ * boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b_gpio.c
+ *
+ * Author: Matteo Golin
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+
+#include "bcm2711_gpio.h"
+#include "chip.h"
+
+#if defined(CONFIG_DEV_GPIO) && !defined(CONFIG_GPIO_LOWER_HALF)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input pins */
+
+#define GPIO_IN1 16
+
+/* Output pins */
+
+#define GPIO_OUT1 26
+
+/* Interrupt pins */
+
+/* TODO: why can't you select interrupt event type??? */
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* GPIO device on the BCM2711 */
+
+struct bcm2711_gpio_dev_s
+{
+ struct gpio_dev_s gpio; /* Underlying GPIO device */
+ uint8_t id; /* The index of the pin in its list. */
+};
+
+/* GPIO device with interrupt capabilities on the BCM2711 */
+
+struct bcm2711_gpioint_dev_s
+{
+ struct bcm2711_gpio_dev_s bcm2711_gpio; /* BCM2711 GPIO device */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+#if BOARD_NGPIOOUT > 0
+static int gpout_read(struct gpio_dev_s *dev, bool *value);
+static int gpout_write(struct gpio_dev_s *dev, bool value);
+#endif
+
+#if BOARD_NGPIOIN > 0
+static int gpin_read(struct gpio_dev_s *dev, bool *value);
+#endif
+
+#if BOARD_NGPIOINT > 0
+static int gpint_read(struct gpio_dev_s *dev, bool *value);
+static int gpint_attach(struct gpio_dev_s *dev, pin_interrupt_t callback);
+static int gpint_enable(struct gpio_dev_s *dev, bool enable);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#if BOARD_NGPIOOUT > 0
+
+/* GPIO operations for output pins. */
+
+static const struct gpio_operations_s gpout_ops =
+{
+ .go_read = gpout_read,
+ .go_write = gpout_write,
+ .go_attach = NULL,
+ .go_enable = NULL,
+};
+
+/* This array maps the GPIO pins used as OUTPUT */
+
+static const uint32_t g_gpiooutputs[BOARD_NGPIOOUT] =
+{
+ GPIO_OUT1,
+};
+
+/* GPIO output pin devices */
+
+static struct bcm2711_gpio_dev_s g_gpout[BOARD_NGPIOOUT];
+
+#endif /* BOARD_NGPIOOUT > 0 */
+
+#if BOARD_NGPIOIN > 0
+
+/* GPIO operations for input pins. */
+
+static const struct gpio_operations_s gpin_ops =
+{
+ .go_read = gpin_read,
+ .go_write = NULL,
+ .go_attach = NULL,
+ .go_enable = NULL,
+};
+
+/* This array maps the GPIO pins used as INTERRUPT INPUTS */
+
+static const uint32_t g_gpioinputs[BOARD_NGPIOIN] =
+{
+ GPIO_IN1,
+};
+
+/* GPIO input pin devices */
+
+static struct bcm2711_gpio_dev_s g_gpin[BOARD_NGPIOIN];
+
+#endif /* BOARD_NGPIOIN > 0 */
+
+#if BOARD_NGPIOINT > 0
+
+#warn "Missing functionality for interrupt GPIO pins."
+
+/* GPIO operations for interrupt pins. */
+
+static const struct gpio_operations_s gpint_ops =
+{
+ .go_read = gpint_read,
+ .go_write = NULL,
+ .go_attach = gpint_attach,
+ .go_enable = gpint_enable,
+};
+
+/* This array maps the GPIO pins used as INTERRUPT INPUTS */
+
+static const uint32_t g_gpiointinputs[BOARD_NGPIOINT] =
+{
+ GPIO_IRQPIN1,
+};
+
+/* GPIO interrupt pin devices */
+
+static struct bcm2711_gpioint_dev_s g_gpint[BOARD_NGPIOINT];
+
+#endif /* BOARD_NGPIOINT > 0 */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+#if BOARD_NGPIOOUT > 0
+
+/****************************************************************************
+ * Name: gpout_read
+ *
+ * Description:
+ * Read the output pin's current status (0 or 1).
+ *
+ * Input parameters:
+ * dev - The GPIO device structure.
+ * value - A pointer to the location to store the pin status.
+ ****************************************************************************/
+
+static int gpout_read(struct gpio_dev_s *dev, bool *value)
+{
+ struct bcm2711_gpio_dev_s *bcm2711gpio =
+ (struct bcm2711_gpio_dev_s *)(dev);
+
+ DEBUGASSERT(bcm2711gpio != NULL);
+ DEBUGASSERT(value != NULL);
+ DEBUGASSERT(bcm2711gpio->id < BOARD_NGPIOOUT);
+
+ *value = bcm2711_gpio_pin_get(g_gpiooutputs[bcm2711gpio->id]);
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: gpout_write
+ *
+ * Description:
+ * Write a value to a GPIO output pin.
+ *
+ * Input parameters:
+ * dev - The GPIO device struct of the pin to write to.
+ * value - The value to write to the pin.
+ ****************************************************************************/
+
+static int gpout_write(struct gpio_dev_s *dev, bool value)
+{
+ struct bcm2711_gpio_dev_s *bcm2711gpio =
+ (struct bcm2711_gpio_dev_s *)(dev);
+
+ DEBUGASSERT(bcm2711gpio != NULL);
+ DEBUGASSERT(bcm2711gpio->id < BOARD_NGPIOOUT);
+
+ gpioinfo("Writing %u to pin %u\n", value, g_gpiooutputs[bcm2711gpio->id]);
+ bcm2711_gpio_pin_set(g_gpiooutputs[bcm2711gpio->id], value);
+
+ return 0;
+}
+
+#endif /* BOARD_NGPIOOUT > 0 */
+
+#if BOARD_NGPIOIN > 0
+
+/****************************************************************************
+ * Name: gpin_read
+ *
+ * Description:
+ * Read the input pin's current status (0 or 1).
+ *
+ * Input parameters:
+ * dev - The GPIO device structure.
+ * value - A pointer to the location to store the pin status.
+ ****************************************************************************/
+
+static int gpin_read(struct gpio_dev_s *dev, bool *value)
+{
+ struct bcm2711_gpio_dev_s *bcm2711gpio =
+ (struct bcm2711_gpio_dev_s *)(dev);
+
+ DEBUGASSERT(bcm2711gpio != NULL);
+ DEBUGASSERT(value != NULL);
+ DEBUGASSERT(bcm2711gpio->id < BOARD_NGPIOIN);
+
+ *value = bcm2711_gpio_pin_get(g_gpioinputs[bcm2711gpio->id]);
+
+ return 0;
+}
+
+#endif /* BOARD_NGPIOIN > 0 */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: bcm2711_dev_gpio_init
+ ****************************************************************************/
+
+int bcm2711_dev_gpio_init(void)
+{
+ int i;
+ int ret = OK;
+
+ /* Register output pins. */
+
+#if BOARD_NGPIOOUT > 0
+ for (i = 0; i < BOARD_NGPIOOUT; i++)
+ {
+ /* Setup and register the GPIO pin */
+
+ g_gpout[i].gpio.gp_pintype = GPIO_OUTPUT_PIN;
+ g_gpout[i].gpio.gp_ops = &gpout_ops;
+ g_gpout[i].id = i;
+ ret = gpio_pin_register(&g_gpout[i].gpio, g_gpiooutputs[i]);
+ if (ret < 0)
+ {
+ gpioerr("Failed to register output pin %d (BCM2711 #%u): %d\n", i,
+ g_gpiooutputs[i], ret);
+ return ret;
+ }
+
+ /* Configure the pins that will be used as output.
+ * They will start low and have no pull-up or pull-down resistors.
+ */
+
+ bcm2711_gpio_set_pulls(g_gpiooutputs[i], false, false);
+ bcm2711_gpio_set_func(g_gpiooutputs[i], BCM_GPIO_OUTPUT);
+ bcm2711_gpio_pin_set(g_gpiooutputs[i], false);
+ }
+#endif
+
+ /* Register input pins. */
+
+#if BOARD_NGPIOIN > 0
+ for (i = 0; i < BOARD_NGPIOIN; i++)
+ {
+ /* Setup and register the GPIO pin */
+
+ g_gpin[i].gpio.gp_pintype = GPIO_INPUT_PIN;
+ g_gpin[i].gpio.gp_ops = &gpin_ops;
+ g_gpin[i].id = i;
+ ret = gpio_pin_register(&g_gpin[i].gpio, g_gpioinputs[i]);
+ if (ret < 0)
+ {
+ gpioerr("Failed to register input pin %d (BCM2711 #%u): %d\n", i,
+ g_gpioinputs[i], ret);
+ return ret;
+ }
+
+ /* Configure the pins that will be used as INPUT.
+ * They will have pull-up resistors.
+ */
+
+ bcm2711_gpio_set_func(g_gpioinputs[i], BCM_GPIO_INPUT);
+ bcm2711_gpio_set_pulls(g_gpioinputs[i], true, false);
+
+ /* TODO: pull-up or pull-down should be configurable per pin */
+ }
+#endif
+
+ return OK;
+}
+
+#endif /* defined(CONFIG_DEV_GPIO) && !defined(CONFIG_GPIO_LOWER_HALF) */
diff --git a/tools/bcm2711/.gitignore b/tools/bcm2711/.gitignore
new file mode 100644
index 0000000000..01353ec7d5
--- /dev/null
+++ b/tools/bcm2711/.gitignore
@@ -0,0 +1,2 @@
+*.dat
+*.dtb
diff --git a/tools/bcm2711/Config.mk b/tools/bcm2711/Config.mk
new file mode 100644
index 0000000000..b74ff71ea8
--- /dev/null
+++ b/tools/bcm2711/Config.mk
@@ -0,0 +1,41 @@
+############################################################################
+# tools/bcm2711/Config.mk
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+# These are the macros that will be used in the NuttX make system to compile
+# and assemble source files and to insert the resulting object files into an
+# archive. These replace the default definitions at tools/Config.mk
+
+# POSTBUILD -- Perform post build operations
+
+# Post build logic for the Raspberry Pi 4B
+
+ifeq ($(CONFIG_ARCH_BOARD_RASPBERRYPI_4B),y)
+
+CONFIG_TXT = config.txt
+
+define POSTBUILD
+ $(Q)echo "Generating $(CONFIG_TXT)";
+ $(Q)echo "kernel=nuttx.bin" > $(CONFIG_TXT);
+ $(Q)echo "arm_64bit=1" >> $(CONFIG_TXT);
+ $(Q)echo "core_freq_min=500" >> $(CONFIG_TXT);
+ $(if $(CONFIG_RPI4B_DEBUG_BOOT),$(Q)echo "uart_2ndstage=1" >> $(CONFIG_TXT);)
+endef
+
+endif
diff --git a/tools/bcm2711/bootfiles.sh b/tools/bcm2711/bootfiles.sh
new file mode 100755
index 0000000000..c13a17e347
--- /dev/null
+++ b/tools/bcm2711/bootfiles.sh
@@ -0,0 +1,11 @@
+!#/bin/sh
+
+curl -O -L "https://raw.githubusercontent.com/raspberrypi/firmware/refs/heads/stable/boot/bcm2711-rpi-4-b.dtb"
+curl -O -L "https://raw.githubusercontent.com/raspberrypi/firmware/refs/heads/stable/boot/fixup4.dat"
+curl -O -L "https://raw.githubusercontent.com/raspberrypi/firmware/refs/heads/stable/boot/fixup4cd.dat"
+curl -O -L "https://raw.githubusercontent.com/raspberrypi/firmware/refs/heads/stable/boot/fixup4db.dat"
+curl -O -L "https://raw.githubusercontent.com/raspberrypi/firmware/refs/heads/stable/boot/fixup4x.dat"
+curl -O -L "https://raw.githubusercontent.com/raspberrypi/firmware/refs/heads/stable/boot/start4.elf"
+curl -O -L "https://raw.githubusercontent.com/raspberrypi/firmware/refs/heads/stable/boot/start4cd.elf"
+curl -O -L "https://raw.githubusercontent.com/raspberrypi/firmware/refs/heads/stable/boot/start4db.elf"
+curl -O -L "https://raw.githubusercontent.com/raspberrypi/firmware/refs/heads/stable/boot/start4x.elf"