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"