diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 3731470db07e5..c6b0e18b13f6f 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3475,6 +3475,19 @@ ADI Platforms: labels: - "platform: ADI" +Bouffalolab Platforms: + status: maintained + maintainers: + - nandojve + files: + - boards/bouffalolab/ + - drivers/*/*bflb* + - dts/riscv/bouffalolab/ + - dts/bindings/*/bflb,* + - soc/bouffalolab/ + labels: + - "platform: bouffalolab" + Broadcom Platforms: status: odd fixes files: @@ -4906,6 +4919,15 @@ West: labels: - "platform: Microchip SAM" +"West project: hal_bouffalolab": + status: maintained + maintainers: + - nandojve + files: + - modules/hal_bouffalolab/ + labels: + - "platform: Bouffalo Lab" + "West project: hal_cypress": status: maintained maintainers: diff --git a/boards/bouffalolab/bl60x/bl604e_iot_dvk/Kconfig.bl604e_iot_dvk b/boards/bouffalolab/bl60x/bl604e_iot_dvk/Kconfig.bl604e_iot_dvk new file mode 100644 index 0000000000000..806d0c5ca0030 --- /dev/null +++ b/boards/bouffalolab/bl60x/bl604e_iot_dvk/Kconfig.bl604e_iot_dvk @@ -0,0 +1,6 @@ +# Copyright (c) 2022-2025 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_BL604E_IOT_DVK + select SOC_BL604E20Q2I diff --git a/boards/bouffalolab/bl60x/bl604e_iot_dvk/bl604e_iot_dvk-pinctrl.dtsi b/boards/bouffalolab/bl60x/bl604e_iot_dvk/bl604e_iot_dvk-pinctrl.dtsi new file mode 100644 index 0000000000000..f5cce349d3caa --- /dev/null +++ b/boards/bouffalolab/bl60x/bl604e_iot_dvk/bl604e_iot_dvk-pinctrl.dtsi @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2021-2025 ATL Electronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + uart0_default: uart0_default { + group1 { + pinmux = , + ; + bias-pull-up; + input-schmitt-enable; + }; + }; + + uart0_sleep: uart0_sleep { + group1 { + pinmux = , + ; + bias-high-impedance; + }; + }; +}; diff --git a/boards/bouffalolab/bl60x/bl604e_iot_dvk/bl604e_iot_dvk.dts b/boards/bouffalolab/bl60x/bl604e_iot_dvk/bl604e_iot_dvk.dts new file mode 100644 index 0000000000000..e81d9cc6b37f7 --- /dev/null +++ b/boards/bouffalolab/bl60x/bl604e_iot_dvk/bl604e_iot_dvk.dts @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022-2025 ATL Electronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "bl604e_iot_dvk-pinctrl.dtsi" + +/ { + model = "BL604E IOT DVK development board"; + compatible = "bflb,bl604"; + + chosen { + zephyr,flash = &flash0; + zephyr,itcm = &itcm; + zephyr,dtcm = &dtcm; + zephyr,sram = &sram0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + }; +}; + +&cpu0 { + clock-frequency = ; +}; + +&spi1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x4000b000 0x1000 0x23000000 0xc00000>; + + flash0: flash@0 { + compatible = "issi,is25lp128", "jedec,spi-nor"; + status = "disabled"; + size = ; + jedec-id = [96 60 18]; + reg = <0>; + spi-max-frequency = ; + }; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + + pinctrl-0 = <&uart0_default>; + pinctrl-1 = <&uart0_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/boards/bouffalolab/bl60x/bl604e_iot_dvk/bl604e_iot_dvk.yaml b/boards/bouffalolab/bl60x/bl604e_iot_dvk/bl604e_iot_dvk.yaml new file mode 100644 index 0000000000000..51b1065ff2288 --- /dev/null +++ b/boards/bouffalolab/bl60x/bl604e_iot_dvk/bl604e_iot_dvk.yaml @@ -0,0 +1,19 @@ +# Copyright (c) 2022-2025 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +identifier: bl604e_iot_dvk +name: BL604E IOT DVK development board +type: mcu +arch: riscv +ram: 64 +toolchain: + - zephyr +testing: + ignore_tags: + - net + - bluetooth +supported: + - pinctrl + - uart +vendor: bflb diff --git a/boards/bouffalolab/bl60x/bl604e_iot_dvk/bl604e_iot_dvk_defconfig b/boards/bouffalolab/bl60x/bl604e_iot_dvk/bl604e_iot_dvk_defconfig new file mode 100644 index 0000000000000..2b274c4a841c6 --- /dev/null +++ b/boards/bouffalolab/bl60x/bl604e_iot_dvk/bl604e_iot_dvk_defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2022-2025 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CONSOLE=y +CONFIG_SERIAL=y + +CONFIG_UART_CONSOLE=y +CONFIG_UART_BFLB=y diff --git a/boards/bouffalolab/bl60x/bl604e_iot_dvk/board.cmake b/boards/bouffalolab/bl60x/bl604e_iot_dvk/board.cmake new file mode 100644 index 0000000000000..a8e089640bd60 --- /dev/null +++ b/boards/bouffalolab/bl60x/bl604e_iot_dvk/board.cmake @@ -0,0 +1,20 @@ +# Copyright (c) 2022-2025 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(openocd --cmd-pre-init "source [find bl60x.cfg]") + +board_runner_args(openocd --use-elf --no-load --no-init) +board_runner_args(openocd --gdb-init "set mem inaccessible-by-default off") +board_runner_args(openocd --gdb-init "set architecture riscv:rv32") +board_runner_args(openocd --gdb-init "set remotetimeout 250") +board_runner_args(openocd --gdb-init "set print asm-demangle on") +board_runner_args(openocd --gdb-init "set backtrace limit 32") +board_runner_args(openocd --gdb-init "mem 0x22008000 0x22014000 rw") +board_runner_args(openocd --gdb-init "mem 0x42008000 0x42014000 rw") +board_runner_args(openocd --gdb-init "mem 0x22014000 0x22020000 rw") +board_runner_args(openocd --gdb-init "mem 0x42014000 0x42020000 rw") +board_runner_args(openocd --gdb-init "mem 0x22020000 0x2203C000 rw") +board_runner_args(openocd --gdb-init "mem 0x42020000 0x4203C000 rw") +board_runner_args(openocd --gdb-init "mem 0x23000000 0x23400000 ro") +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/bouffalolab/bl60x/bl604e_iot_dvk/board.yml b/boards/bouffalolab/bl60x/bl604e_iot_dvk/board.yml new file mode 100644 index 0000000000000..843d38b0e8a2f --- /dev/null +++ b/boards/bouffalolab/bl60x/bl604e_iot_dvk/board.yml @@ -0,0 +1,6 @@ +board: + name: bl604e_iot_dvk + full_name: BL604E IOT DVK development board + vendor: bflb + socs: + - name: bl604e20q2i diff --git a/boards/bouffalolab/bl60x/bl604e_iot_dvk/doc/img/bl_604e.webp b/boards/bouffalolab/bl60x/bl604e_iot_dvk/doc/img/bl_604e.webp new file mode 100644 index 0000000000000..a4e60232febd0 Binary files /dev/null and b/boards/bouffalolab/bl60x/bl604e_iot_dvk/doc/img/bl_604e.webp differ diff --git a/boards/bouffalolab/bl60x/bl604e_iot_dvk/doc/index.rst b/boards/bouffalolab/bl60x/bl604e_iot_dvk/doc/index.rst new file mode 100644 index 0000000000000..76522129e4148 --- /dev/null +++ b/boards/bouffalolab/bl60x/bl604e_iot_dvk/doc/index.rst @@ -0,0 +1,104 @@ +.. zephyr:board:: bl604e_iot_dvk + +Overview +******** + +BL602/BL604 is a Wi-Fi+BLE chipset introduced by Bouffalo Lab, which is used +for low power consumption and high performance application development. The +wireless subsystem includes 2.4G radio, Wi-Fi 802.11b/g/n and BLE 5.0 +baseband/MAC design. The microcontroller subsystem includes a 32-bit RISC CPU +with low power consumption, cache and memory. The power management unit +controls the low power consumption mode. In addition, it also supports +various security features. The external interfaces include SDIO, SPI, UART, +I2C, IR remote, PWM, ADC, DAC, PIR and GPIO. + +The BL602 Development Board features a SiFive E24 32 bit RISC-V CPU with FPU, +it supports High Frequency clock up to 192Mhz, have 128k ROM, 276kB RAM, +2.4 GHz WIFI 1T1R mode, support 20 MHz, data rate up to 72.2 Mbps, BLE 5.0 +with 2MB phy. It is a secure MCU which supports Secure boot, ECC-256 signed +image, QSPI/SPI Flash On-The-Fly AES Decryption and PKA (Public Key +Accelerator). + +Hardware +******** + +For more information about the Bouffalo Lab BL-60x MCU: + +- `Bouffalo Lab BL60x MCU Website`_ +- `Bouffalo Lab BL60x MCU Datasheet`_ +- `Bouffalo Lab Development Zone`_ +- `The RISC-V BL602 Book`_ + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +The default configuration can be found in the Kconfig +:zephyr_file:`boards/bouffalolab/bl60x/bl604e_iot_dvk/bl604e_iot_dvk_defconfig`. + +System Clock +============ + +The BL604E Development Board is configured to run at max speed (192MHz). + +Serial Port +=========== + +The ``bl604e_iot_dvk`` board uses UART0 as default serial port. It is connected +to USB Serial converter and port is used for both program and console. + + +Programming and Debugging +************************* + +Samples +======= + +#. Build the Zephyr kernel and the :zephyr:code-sample:`hello_world` sample +application: + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: bl604e_iot_dvk + :goals: build flash + +#. Run your favorite terminal program to listen for output. Under Linux the + terminal should be :code:`/dev/ttyACM0`. For example: + + .. code-block:: console + + $ minicom -D /dev/ttyACM0 -o + + The -o option tells minicom not to send the modem initialization + string. Connection should be configured as follows: + + - Speed: 115200 + - Data: 8 bits + - Parity: None + - Stop bits: 1 + + Then, press and release RST button + + .. code-block:: console + + *** Booting Zephyr OS build v4.1.0 *** + Hello World! bl604e_iot_dvk/bl604e20q2i + +Congratulations, you have ``bl604e_iot_dvk`` configured and running Zephyr. + + +.. _Bouffalo Lab BL60x MCU Website: + https://en.bouffalolab.com/product/?type=detail&id=6 + +.. _Bouffalo Lab BL60x MCU Datasheet: + https://github.com/bouffalolab/bl_docs/tree/main/BL602_DS/en + +.. _Bouffalo Lab Development Zone: + https://dev.bouffalolab.com/home?id=guest + +.. _The RISC-V BL602 Book: + https://lupyuen.github.io/articles/book + +.. _Flashing Firmware to BL602: + https://lupyuen.github.io/articles/book#flashing-firmware-to-bl602 diff --git a/boards/bouffalolab/bl60x/bl604e_iot_dvk/support/bl60x.cfg b/boards/bouffalolab/bl60x/bl604e_iot_dvk/support/bl60x.cfg new file mode 100644 index 0000000000000..fcabb2c4e7c04 --- /dev/null +++ b/boards/bouffalolab/bl60x/bl604e_iot_dvk/support/bl60x.cfg @@ -0,0 +1,79 @@ +# Copyright (c) 2022-2025 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME riscv +} + +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x10000 +} + +if { [info exists WORKAREAADDR] } { + set _WORKAREAADDR $WORKAREAADDR +} else { + set _WORKAREAADDR 0x22020000 +} + +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + set _CPUTAPID 0x20000c05 +} + +transport select jtag +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME + +$_TARGETNAME.0 configure -work-area-phys $_WORKAREAADDR -work-area-size $_WORKAREASIZE -work-area-backup 1 + +echo "Ready for Remote Connections" + +$_TARGETNAME.0 configure -event reset-assert-pre { + echo "reset-assert-pre" + adapter speed 100 +} + +$_TARGETNAME.0 configure -event reset-deassert-post { + echo "reset-deassert-post" + + adapter speed 100 + + reg mstatus 0x7800 + reg mie 0x0 +# reg pc 0x23000000 +} + +$_TARGETNAME.0 configure -event reset-init { + echo "reset-init" + + adapter speed 3000 +} + +$_TARGETNAME.0 configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME.0 configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} + +gdb_memory_map enable +gdb_flash_program enable + +# 'progbuf', 'sysbus' or 'abstract' +riscv set_mem_access sysbus +riscv set_command_timeout_sec 1 + +init +reset init diff --git a/boards/bouffalolab/bl60x/bl604e_iot_dvk/support/openocd.cfg b/boards/bouffalolab/bl60x/bl604e_iot_dvk/support/openocd.cfg new file mode 100644 index 0000000000000..ffd60cfb196c2 --- /dev/null +++ b/boards/bouffalolab/bl60x/bl604e_iot_dvk/support/openocd.cfg @@ -0,0 +1,19 @@ +# OpenOCD Script for PineCone connected via Sipeed JTAG Debugger (FTDI FT2232D) +# Ref: bl_iot_sdk/tools/debug/if_bflb_link.cfg +# source [find interface/if_bflb_link.cfg] + +# Uncomment to enable debug messages +# debug_level 4 + +# BouffaloLab USB-JTAG/TTL adapter +# Or Sipeed JTAG Debugger based on FTDI FT2232D + +adapter driver ftdi +ftdi vid_pid 0x0403 0x6010 + +# Sipeed JTAG Debugger uses FTDI Channel 0, not 1 +ftdi channel 0 +# ftdi_channel 1 + +ftdi layout_init 0x00f8 0x00fb +adapter speed 4000 diff --git a/boards/bouffalolab/index.rst b/boards/bouffalolab/index.rst new file mode 100644 index 0000000000000..f0380b6b45c7e --- /dev/null +++ b/boards/bouffalolab/index.rst @@ -0,0 +1,10 @@ +.. _boards-bouffalolab: + +Bouffalo Lab Intelligent Technology (Nanjing) Co., Ltd. +####################################################### + +.. toctree:: + :maxdepth: 1 + :glob: + + **/* diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index cc5d1c18a532d..60e1741f2b7c7 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -9,6 +9,7 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_AMBIQ pinctrl_ambiq.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_ARM_MPS2 pinctrl_arm_mps2.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_ARM_MPS3 pinctrl_arm_mps3.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_ARM_V2M_BEETLE pinctrl_arm_v2m_beetle.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_BFLB pinctrl_bflb.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_GD32_AF pinctrl_gd32_af.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_GD32_AFIO pinctrl_gd32_afio.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_ITE_IT8XXX2 pinctrl_ite_it8xxx2.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 95dcd8d67d410..9cdbfd4244479 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -35,6 +35,7 @@ config PINCTRL_DYNAMIC peripheral at early boot stages depending on a certain input. source "drivers/pinctrl/Kconfig.b91" +source "drivers/pinctrl/Kconfig.bflb" source "drivers/pinctrl/Kconfig.ambiq" source "drivers/pinctrl/Kconfig.arm_mps2" source "drivers/pinctrl/Kconfig.arm_mps3" diff --git a/drivers/pinctrl/Kconfig.bflb b/drivers/pinctrl/Kconfig.bflb new file mode 100644 index 0000000000000..c49d600f2476b --- /dev/null +++ b/drivers/pinctrl/Kconfig.bflb @@ -0,0 +1,10 @@ +# Copyright (c) 2021-2025 Gerson Fernando Budke +# +# SPDX-License-Identifier: Apache-2.0 + +config PINCTRL_BFLB + bool "Bouffalo Lab pin control driver" + depends on DT_HAS_BFLB_PINCTRL_ENABLED + default y + help + Bouffalo Lab pin control driver diff --git a/drivers/pinctrl/pinctrl_bflb.c b/drivers/pinctrl/pinctrl_bflb.c new file mode 100644 index 0000000000000..b40a555e4440d --- /dev/null +++ b/drivers/pinctrl/pinctrl_bflb.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021-2025 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +/* clang-format off */ + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, + uintptr_t reg) +{ + GLB_GPIO_Cfg_Type pincfg; + uint8_t i; + + ARG_UNUSED(reg); + + for (i = 0U; i < pin_cnt; i++) { + pincfg.gpioFun = BFLB_PINMUX_GET_FUN(pins[i]); + pincfg.gpioMode = BFLB_PINMUX_GET_MODE(pins[i]); + pincfg.gpioPin = BFLB_PINMUX_GET_PIN(pins[i]); + pincfg.pullType = BFLB_PINMUX_GET_PULL_MODES(pins[i]); + pincfg.smtCtrl = BFLB_PINMUX_GET_SMT(pins[i]); + pincfg.drive = BFLB_PINMUX_GET_DRIVER_STRENGTH(pins[i]); + + if (pincfg.gpioFun == BFLB_PINMUX_FUN_INST_uart0) { + GLB_UART_Fun_Sel(pincfg.gpioPin % 8, + (BFLB_PINMUX_GET_INST(pins[i])) + * 0x4U /* rts, cts, rx, tx */ + + BFLB_PINMUX_GET_SIGNAL(pins[i]) + ); + } + + GLB_GPIO_Init(&pincfg); + } + + return 0; +} + +/* clang-format on */ diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index aa97c9e0ae28c..7ff54af293147 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -21,6 +21,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_ALTERA uart_altera.c) zephyr_library_sources_ifdef(CONFIG_UART_ALTERA_JTAG uart_altera_jtag.c) zephyr_library_sources_ifdef(CONFIG_UART_APBUART uart_apbuart.c) zephyr_library_sources_ifdef(CONFIG_UART_BCM2711_MU uart_bcm2711.c) +zephyr_library_sources_ifdef(CONFIG_UART_BFLB uart_bflb.c) zephyr_library_sources_ifdef(CONFIG_UART_BT uart_bt.c) zephyr_library_sources_ifdef(CONFIG_UART_CC13XX_CC26XX uart_cc13xx_cc26xx.c) zephyr_library_sources_ifdef(CONFIG_UART_CC23X0 uart_cc23x0.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index ed68ef1904ec7..f1cb441dcb1b3 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -162,6 +162,7 @@ rsource "Kconfig.altera_jtag" rsource "Kconfig.apbuart" rsource "Kconfig.b91" rsource "Kconfig.bcm2711" +rsource "Kconfig.bflb" rsource "Kconfig.bt" rsource "Kconfig.cc13xx_cc26xx" rsource "Kconfig.cc23x0" diff --git a/drivers/serial/Kconfig.bflb b/drivers/serial/Kconfig.bflb new file mode 100644 index 0000000000000..52df95d521f8f --- /dev/null +++ b/drivers/serial/Kconfig.bflb @@ -0,0 +1,12 @@ +# Copyright (c) 2021-2025 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +config UART_BFLB + bool "Bouffalo Lab serial driver" + depends on DT_HAS_BFLB_UART_ENABLED + select PINCTRL + select SERIAL_HAS_DRIVER + select USE_BFLB_UART + help + This option enables the UART driver for Bouffalo Lab SoC family. diff --git a/drivers/serial/uart_bflb.c b/drivers/serial/uart_bflb.c new file mode 100644 index 0000000000000..504e0f82a5a24 --- /dev/null +++ b/drivers/serial/uart_bflb.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2021-2025 ATL Electronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT bflb_uart + +/** + * @brief UART driver for Bouffalo Lab MCU family. + */ +#include +#include +#include +#include + +#include +#include +#include + +#define UART_CTS_FLOWCONTROL_ENABLE (0) +#define UART_RTS_FLOWCONTROL_ENABLE (0) +#define UART_MSB_FIRST_ENABLE (0) +#define UART_DEFAULT_RTO_TIMEOUT (255) +#define UART_CLOCK_DIV (0) + +struct blfb_config { + const struct pinctrl_dev_config *pinctrl_cfg; + uint32_t periph_id; + UART_CFG_Type uart_cfg; + UART_FifoCfg_Type fifo_cfg; +}; + +static int uart_blfb_init(const struct device *dev) +{ + const struct blfb_config *cfg = dev->config; + + pinctrl_apply_state(cfg->pinctrl_cfg, PINCTRL_STATE_DEFAULT); + + GLB_Set_UART_CLK(1, HBN_UART_CLK_160M, UART_CLOCK_DIV); + + UART_IntMask(cfg->periph_id, UART_INT_ALL, 1); + UART_Disable(cfg->periph_id, UART_TXRX); + + UART_Init(cfg->periph_id, (UART_CFG_Type *)&cfg->uart_cfg); + UART_TxFreeRun(cfg->periph_id, 1); + UART_SetRxTimeoutValue(cfg->periph_id, UART_DEFAULT_RTO_TIMEOUT); + UART_FifoConfig(cfg->periph_id, (UART_FifoCfg_Type *)&cfg->fifo_cfg); + UART_Enable(cfg->periph_id, UART_TXRX); + + return 0; +} + +static int uart_blfb_poll_in(const struct device *dev, unsigned char *c) +{ + const struct blfb_config *cfg = dev->config; + + return UART_ReceiveData(cfg->periph_id, (uint8_t *)c, 1) ? 0 : -1; +} + +static void uart_blfb_poll_out(const struct device *dev, unsigned char c) +{ + const struct blfb_config *cfg = dev->config; + + while (UART_GetTxFifoCount(cfg->periph_id) == 0) { + ; + } + + (void)UART_SendData(cfg->periph_id, (uint8_t *)&c, 1); +} + +#ifdef CONFIG_PM_DEVICE +static int uart_blfb_pm_control(const struct device *dev, + enum pm_device_action action) +{ + const struct blfb_config *cfg = dev->config; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + (void)pinctrl_apply_state(cfg->pinctrl_cfg, PINCTRL_STATE_DEFAULT); + UART_Enable(cfg->periph_id, UART_TXRX); + break; + case PM_DEVICE_ACTION_SUSPEND: + if (pinctrl_apply_state(cfg->pinctrl_cfg, PINCTRL_STATE_SLEEP)) { + return -ENOTSUP; + } + UART_Disable(cfg->periph_id, UART_TXRX); + break; + default: + return -ENOTSUP; + } + + return 0; +} +#endif /* CONFIG_PM_DEVICE */ + +static DEVICE_API(uart, uart_blfb_driver_api) = { + .poll_in = uart_blfb_poll_in, + .poll_out = uart_blfb_poll_out, +}; + +#define BLFB_UART_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + PM_DEVICE_DT_INST_DEFINE(n, uart_blfb_pm_control); \ + static const struct blfb_config blfb_uart##n##_config = { \ + .pinctrl_cfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .periph_id = DT_INST_PROP(n, peripheral_id), \ + \ + .uart_cfg.baudRate = DT_INST_PROP(n, current_speed), \ + .uart_cfg.dataBits = UART_DATABITS_8, \ + .uart_cfg.stopBits = UART_STOPBITS_1, \ + .uart_cfg.parity = UART_PARITY_NONE, \ + .uart_cfg.uartClk = SOC_BOUFFALOLAB_BL_PLL160_FREQ_HZ, \ + .uart_cfg.ctsFlowControl = UART_CTS_FLOWCONTROL_ENABLE, \ + .uart_cfg.rtsSoftwareControl = UART_RTS_FLOWCONTROL_ENABLE, \ + .uart_cfg.byteBitInverse = UART_MSB_FIRST_ENABLE, \ + \ + .fifo_cfg.txFifoDmaThreshold = 1, \ + .fifo_cfg.rxFifoDmaThreshold = 1, \ + .fifo_cfg.txFifoDmaEnable = 0, \ + .fifo_cfg.rxFifoDmaEnable = 0, \ + }; \ + DEVICE_DT_INST_DEFINE(n, &uart_blfb_init, \ + PM_DEVICE_DT_INST_GET(n), \ + NULL, \ + &blfb_uart##n##_config, PRE_KERNEL_1, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ + &uart_blfb_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(BLFB_UART_INIT) diff --git a/dts/bindings/gpio/bflb,gpio.yaml b/dts/bindings/gpio/bflb,gpio.yaml new file mode 100644 index 0000000000000..8692999ddc7d6 --- /dev/null +++ b/dts/bindings/gpio/bflb,gpio.yaml @@ -0,0 +1,35 @@ +# Copyright (c) 2021-2025 Gerson Fernando Budke +# +# SPDX-License-Identifier: Apache-2.0 + +description: Bouffalo Lab GPIO node + +compatible: "bflb,gpio" + +include: + - name: base.yaml + - name: gpio-controller.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + "#gpio-cells": + const: 2 + + "#bflb,pin-cells": + type: int + required: true + const: 2 + description: Number of items to expect in a bflb,pins specifier + +gpio-cells: + - pin + - flags + +bflb,pin-cells: + - pin + - peripheral diff --git a/dts/bindings/pinctrl/bflb,pinctrl.yaml b/dts/bindings/pinctrl/bflb,pinctrl.yaml new file mode 100644 index 0000000000000..b67404dc85d6d --- /dev/null +++ b/dts/bindings/pinctrl/bflb,pinctrl.yaml @@ -0,0 +1,91 @@ +# Copyright (c) 2021-2025 Gerson Fernando Budke +# +# SPDX-License-Identifier: Apache-2.0 + +description: Bouffalo Lab Pinctrl node + +compatible: "bflb,pinctrl" + +include: base.yaml + +properties: + "#address-cells": + required: true + const: 1 + "#size-cells": + required: true + const: 1 + +child-binding: + description: | + Bouffalo Lab pin controller pin configuration nodes. Each node is composed + by one or more groups, each defining the configuration for a set of pins. + + child-binding: + description: | + Bouffalo Lab pin controller pin configuration group. Each group contains + a list of pins sharing the same set of properties. Example: + + uart0_default: uart0_default { + /* group 1 (name is arbitrary) */ + group1 { + /* configure to uart0 function plus modem interrupt, pin 7 as UART_RX + pin 16 as UART_TX and finally pin 18 as gpio */ + pinmux = , + ; + bias-pull-up; + input-schmitt-enable; + }; + }; + + uart0_sleep: uart0_sleep { + group1 { + pinmux = , + ; + bias-high-impedance; + }; + }; + + The list of supported standard properties: + - bias-high-impedance: Disable pull-up/down (default behavior, not + required). + - bias-pull-up: Enable pull-up resistor. + - bias-pull-down: Enable pull-down resistor. + - input-enable: Enable GPIO as input (default behavior, not required). + - input-schmitt-enable: Enable Schimitt Trigger when GPIO is Input. + - output-enable: Enable GPIO as output. + + Note that bias options are mutually exclusive. It is the same with GPIO + input/output enable options. + + include: + - name: pincfg-node.yaml + property-allowlist: + - bias-high-impedance + - bias-pull-down + - bias-pull-up + - input-enable + - input-schmitt-enable + - output-enable + + properties: + pinmux: + required: true + type: array + description: | + An array of pins sharing the same group properties. The pins should be + defined using the BFLB_PINMUX utility macro that encode all the pin + route matrix. + drive-strength: + type: int + default: 0 + enum: + - 0 # Default value, lower strength, 8mA + - 1 # 9.6mA + - 2 # 11.2mA + - 3 # highest strength, 12.8mA + description: | + Pin drive strength. It tunes pin max current where 0 means lower + value, which is the default, and 3 represents max drive strength. + The driver will automatically apply the default value (8mA) to all + pins to save power. diff --git a/dts/bindings/serial/bflb,uart.yaml b/dts/bindings/serial/bflb,uart.yaml new file mode 100644 index 0000000000000..d844435568fb6 --- /dev/null +++ b/dts/bindings/serial/bflb,uart.yaml @@ -0,0 +1,20 @@ +# Copyright (c) 2021-2025 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +description: Bouffalo Lab UART + +compatible: "bflb,uart" + +include: + - name: uart-controller.yaml + - name: pinctrl-device.yaml + +properties: + reg: + required: true + + peripheral-id: + type: int + description: peripheral ID + required: true diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index 4573335abc7f5..1d07470e1b0bf 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -101,6 +101,7 @@ bbc BBC bcdevices Blue Clover Devices beacon Compass Electronics Group, LLC beagle BeagleBoard.org Foundation +bflb Bouffalo Lab (Nanjing) Co., Ltd. bhf Beckhoff Automation GmbH & Co. KG bitmain Bitmain Technologies blues Blues Wireless diff --git a/dts/riscv/bouffalolab/bl60x.dtsi b/dts/riscv/bouffalolab/bl60x.dtsi new file mode 100644 index 0000000000000..7ec4c90802f79 --- /dev/null +++ b/dts/riscv/bouffalolab/bl60x.dtsi @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2021-2025 ATL Electronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "sifive,e24", "riscv"; + reg = <0>; + riscv,isa = "rv32imafcb"; + hardware-exec-breakpoint-count = <4>; + status = "okay"; + + ictrl: interrupt-controller { + #address-cells = <0>; + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + clic: clic@2000000 { + compatible = "sifive,clint0"; + reg = <0x2000000 0x10000>; + #address-cells = <0>; + #interrupt-cells = <2>; + + interrupt-controller; + interrupts-extended = <&ictrl 3 &ictrl 7 &ictrl 11 &ictrl 12>; + interrupt-names = "msip", /* Machine Software Interrupt */ + "mtip", /* Machine Timer interrupt */ + "meip", /* Machine External Interrupt */ + "csip"; /* CLIC Software Interrupt */ + }; + + mtimer: timer@200bff8 { + compatible = "riscv,machine-timer"; + reg = <0x200bff8 0x8 0x2004000 0x8>; + reg-names = "mtime", "mtimecmp"; + + interrupts-extended = <&ictrl 7>; + }; + + pinctrl: pin-controller@40000000 { + compatible = "bflb,pinctrl"; + reg = <0x40000000 0x1000>; + ranges = <0x40000000 0x40000000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + status = "okay"; + + glb: gpio@40000000 { + compatible = "bflb,gpio"; + reg = <0x40000000 0x1000>; + #gpio-cells = <2>; + #bflb,pin-cells = <2>; + status = "disabled"; + + gpio-controller; + interrupts = <1 0>; + interrupt-parent = <&ictrl>; + }; + }; + + uart0: uart@4000a000 { + compatible = "bflb,uart"; + reg = <0x4000a000 0x100>; + peripheral-id = <0>; + interrupts = <29 0>; + interrupt-parent = <&ictrl>; + status = "disabled"; + }; + + uart1: uart@4000a100 { + compatible = "bflb,uart"; + reg = <0x4000a100 0x100>; + peripheral-id = <1>; + interrupts = <30 0>; + interrupt-parent = <&ictrl>; + status = "disabled"; + }; + + spi0: spi@4000a200 { + compatible = "bflb,spi"; + reg = <0x4000a200 0x100>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + peripheral-id = <0>; + interrupts = <27 0>; + interrupt-parent = <&ictrl>; + }; + + spi1: spi@4000b000 { + compatible = "bflb,qspi"; + reg = <0x4000b000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + peripheral-id = <0>; + interrupts = <23 0>; + interrupt-parent = <&ictrl>; + }; + + retram: memory@40010000 { + compatible = "mmio-sram"; + reg = <0x40010000 DT_SIZE_K(4)>; + }; + + itcm: itcm@22010000 { + compatible = "zephyr,memory-region", "sifive,dtim0"; + reg = <0x22010000 DT_SIZE_K(16)>; + zephyr,memory-region = "ITCM"; + }; + + dtcm: dtcm@42014000 { + compatible = "zephyr,memory-region", "sifive,dtim0"; + reg = <0x42014000 DT_SIZE_K(48)>; + zephyr,memory-region = "DTCM"; + }; + + sram0: memory@42020000 { + compatible = "mmio-sram"; + reg = <0x42020000 DT_SIZE_K(64)>; + }; + + sram1: memory@42030000 { + compatible = "mmio-sram"; + reg = <0x42030000 DT_SIZE_K(112)>; + }; + }; +}; diff --git a/include/zephyr/drivers/pinctrl/pinctrl_soc_bflb_common.h b/include/zephyr/drivers/pinctrl/pinctrl_soc_bflb_common.h new file mode 100644 index 0000000000000..7d7404ff75e52 --- /dev/null +++ b/include/zephyr/drivers/pinctrl/pinctrl_soc_bflb_common.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2021-2025 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * Bouffalo Lab SoC specific helpers for pinctrl driver + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_PINCTRL_PINCTRL_SOC_BFLB_COMMON_H_ +#define ZEPHYR_INCLUDE_DRIVERS_PINCTRL_PINCTRL_SOC_BFLB_COMMON_H_ + +#include +#include + +/* clang-format off */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond INTERNAL_HIDDEN */ + +/** + * @brief BFLB pincfg bit field. + * @anchor BFLB_PINMUX + * + * Fields: + * + * - 24..31: pin + * - 20..23: signal + * - 18..19: mode + * - 16..17: instance + * - 8..15: function + * - 7: reserved + * - 6: GPIO Output Enable + * - 5: Pull Down + * - 4: Pull Up + * - 2..3: Driver Strength + * - 1: Schmitt trigger (SMT) + * - 0: reserved + */ +typedef uint32_t pinctrl_soc_pin_t; + +/** + * @brief Utility macro to initialize each pin. + * + * @param node_id Node identifier. + * @param prop Property name. + * @param idx Property entry index. + */ +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + ((DT_PROP_BY_IDX(node_id, prop, idx)) \ + | (DT_PROP(node_id, bias_pull_up) << BFLB_PINMUX_PULL_UP_POS) \ + | (DT_PROP(node_id, bias_pull_down) << BFLB_PINMUX_PULL_DOWN_POS) \ + | (DT_PROP(node_id, output_enable) << BFLB_PINMUX_OE_POS) \ + | (DT_PROP(node_id, input_schmitt_enable) << BFLB_PINMUX_SMT_POS) \ + | (DT_ENUM_IDX(node_id, drive_strength) << BFLB_PINMUX_DRIVER_STRENGTH_POS) \ + ), + +/** + * @brief Utility macro to initialize state pins contained in a given property. + * + * @param node_id Node identifier. + * @param prop Property name describing state pins. + */ +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), \ + DT_FOREACH_PROP_ELEM, pinmux, \ + Z_PINCTRL_STATE_PIN_INIT)} + +/** @endcond */ + +#ifdef __cplusplus +} +#endif + +/* clang-format on */ + +#endif /* ZEPHYR_INCLUDE_DRIVERS_PINCTRL_PINCTRL_SOC_BFLB_COMMON_H_ */ diff --git a/modules/Kconfig b/modules/Kconfig index f1d0f928838ce..3b7f9dcb4baff 100644 --- a/modules/Kconfig +++ b/modules/Kconfig @@ -63,6 +63,9 @@ comment "Unavailable modules, please install those via the project manifest." # config ZEPHYR__MODULE # bool +comment "hal_bouffalolab module not available." + depends on !ZEPHYR_HAL_BOUFFALOLAB_MODULE + comment "hal_gigadevice module not available." depends on !ZEPHYR_HAL_GIGADEVICE_MODULE diff --git a/modules/hal_bouffalolab/CMakeLists.txt b/modules/hal_bouffalolab/CMakeLists.txt new file mode 100644 index 0000000000000..eb56320bb7ca4 --- /dev/null +++ b/modules/hal_bouffalolab/CMakeLists.txt @@ -0,0 +1,55 @@ +# Copyright (c) 2021-2025 Gerson Fernando Budke +# +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_SOC_FAMILY_BOUFFALOLAB_BFLB) + zephyr_library_named(hal_bouffalolab) + + zephyr_library_compile_definitions( + BFLB_USE_HAL_DRIVER + BFLB_USE_CUSTOM_LD_SECTIONS + ) + + set(bflb_soc bl602) + set(bflb_drv_dir ${ZEPHYR_HAL_BOUFFALOLAB_MODULE_DIR}/drivers/${bflb_soc}_driver) + set(bflb_common_dir ${ZEPHYR_HAL_BOUFFALOLAB_MODULE_DIR}/common) + set(bflb_drv_src_dir ${bflb_drv_dir}/std_drv/src) + + # Global includes + zephyr_include_directories( + include + ${ZEPHYR_HAL_BOUFFALOLAB_MODULE_DIR}/include + + ${bflb_drv_dir}/regs + ${bflb_drv_dir}/startup + ${bflb_drv_dir}/std_drv/inc + + ${bflb_common_dir}/misc + ) + + zephyr_library_include_directories( + ${bflb_common_dir}/soft_crc + ) + + zephyr_library_sources( + ${bflb_drv_src_dir}/${bflb_soc}_aon.c + ${bflb_drv_src_dir}/${bflb_soc}_ef_ctrl.c + ${bflb_drv_src_dir}/${bflb_soc}_glb.c + ${bflb_drv_src_dir}/${bflb_soc}_hbn.c + ${bflb_drv_src_dir}/${bflb_soc}_l1c.c + ${bflb_drv_src_dir}/${bflb_soc}_pds.c + ${bflb_drv_src_dir}/${bflb_soc}_romapi.c + + ${bflb_common_dir}/soft_crc/softcrc.c + ) + + zephyr_library_sources_ifdef(CONFIG_USE_BFLB_ACOMP ${bflb_drv_src_dir}/${bflb_soc}_acomp.c) + zephyr_library_sources_ifdef(CONFIG_USE_BFLB_ADC ${bflb_drv_src_dir}/${bflb_soc}_adc.c) + zephyr_library_sources_ifdef(CONFIG_USE_BFLB_DAC ${bflb_drv_src_dir}/${bflb_soc}_dac.c) + zephyr_library_sources_ifdef(CONFIG_USE_BFLB_DMA ${bflb_drv_src_dir}/${bflb_soc}_dma.c) + zephyr_library_sources_ifdef(CONFIG_USE_BFLB_I2C ${bflb_drv_src_dir}/${bflb_soc}_i2c.c) + zephyr_library_sources_ifdef(CONFIG_USE_BFLB_IR ${bflb_drv_src_dir}/${bflb_soc}_ir.c) + zephyr_library_sources_ifdef(CONFIG_USE_BFLB_PWM ${bflb_drv_src_dir}/${bflb_soc}_pwm.c) + zephyr_library_sources_ifdef(CONFIG_USE_BFLB_SPI ${bflb_drv_src_dir}/${bflb_soc}_spi.c) + zephyr_library_sources_ifdef(CONFIG_USE_BFLB_UART ${bflb_drv_src_dir}/${bflb_soc}_uart.c) +endif() # SOC_FAMILY_BOUFFALOLAB_BFLB diff --git a/modules/hal_bouffalolab/Kconfig b/modules/hal_bouffalolab/Kconfig new file mode 100644 index 0000000000000..c6c4469117b46 --- /dev/null +++ b/modules/hal_bouffalolab/Kconfig @@ -0,0 +1,59 @@ +# Copyright (c) 2021-2025 Gerson Fernando Budke +# +# SPDX-License-Identifier: Apache-2.0 + +config ZEPHYR_HAL_BOUFFALOLAB_MODULE + bool + +config HAS_BFLB_HAL + bool + +if HAS_BFLB_HAL + +config USE_BFLB_ACOMP + bool + help + Enable BFLB Analog Comparator (ACOMP) HAL module driver + +config USE_BFLB_ADC + bool + help + Enable BFLB Analog-to-Digital Converter (ADC) HAL module driver + +config USE_BFLB_DAC + bool + help + Enable BFLB Digital-to-Analog Converter (DAC) HAL module driver + +config USE_BFLB_DMA + bool + help + Enable BFLB Direct Memory Access controller (DMA) HAL module driver + +config USE_BFLB_I2C + bool + help + Enable BFLB Inter-Integrated Circuit Interface (I2C) HAL module driver + +config USE_BFLB_IR + bool + help + Enable BFLB Infrared Remote controller (IR) HAL module driver + +config USE_BFLB_PWM + bool + help + Enable BFLB Pulse Width Modulation (PMU) HAL module driver + +config USE_BFLB_SPI + bool + help + Enable BFLB Serial Peripheral Interface(SPI) HAL module driver + +config USE_BFLB_UART + bool + help + Enable BFLB Universal Asynchronous Receiver/Transmitter (UART) + HAL module driver + +endif # HAS_BFLB_HAL diff --git a/modules/hal_bouffalolab/include/bflb_glb.h b/modules/hal_bouffalolab/include/bflb_glb.h new file mode 100644 index 0000000000000..d8aff224df91a --- /dev/null +++ b/modules/hal_bouffalolab/include/bflb_glb.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2021-2025 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_HAL_BFLB_GLB_H_ +#define ZEPHYR_HAL_BFLB_GLB_H_ + +#ifdef CONFIG_SOC_SERIES_BL60X +#include +#endif + +#endif /* ZEPHYR_HAL_BFLB_GLB_H_ */ diff --git a/modules/hal_bouffalolab/include/bflb_gpio.h b/modules/hal_bouffalolab/include/bflb_gpio.h new file mode 100644 index 0000000000000..9ac0ca7bf1d7c --- /dev/null +++ b/modules/hal_bouffalolab/include/bflb_gpio.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2021-2025 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_HAL_BFLB_GPIO_H_ +#define ZEPHYR_HAL_BFLB_GPIO_H_ + +#ifdef CONFIG_SOC_SERIES_BL60X +#include +#endif + +#endif /* ZEPHYR_HAL_BFLB_GPIO_H_ */ diff --git a/modules/hal_bouffalolab/include/bflb_hbn.h b/modules/hal_bouffalolab/include/bflb_hbn.h new file mode 100644 index 0000000000000..1580dea3ffbe5 --- /dev/null +++ b/modules/hal_bouffalolab/include/bflb_hbn.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2021-2025 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_HAL_BFLB_HBN_H_ +#define ZEPHYR_HAL_BFLB_HBN_H_ + +#ifdef CONFIG_SOC_SERIES_BL60X +#include +#endif + +#endif /* ZEPHYR_HAL_BFLB_HBN_H_ */ diff --git a/modules/hal_bouffalolab/include/bflb_pinctrl.h b/modules/hal_bouffalolab/include/bflb_pinctrl.h new file mode 100644 index 0000000000000..8226b01ec5dc0 --- /dev/null +++ b/modules/hal_bouffalolab/include/bflb_pinctrl.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2021-2025 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_HAL_BFLB_PINCTRL_H_ +#define ZEPHYR_HAL_BFLB_PINCTRL_H_ + +#ifdef CONFIG_SOC_SERIES_BL60X +#include +#endif +#include + +#endif /* ZEPHYR_HAL_BFLB_PINCTRL_H_ */ diff --git a/modules/hal_bouffalolab/include/bflb_uart.h b/modules/hal_bouffalolab/include/bflb_uart.h new file mode 100644 index 0000000000000..d2675527297ef --- /dev/null +++ b/modules/hal_bouffalolab/include/bflb_uart.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2021-2025 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_HAL_BFLB_UART_H_ +#define ZEPHYR_HAL_BFLB_UART_H_ + +#ifdef CONFIG_SOC_SERIES_BL60X +#include +#endif + +#endif /* ZEPHYR_HAL_BFLB_UART_H_ */ diff --git a/modules/hal_bouffalolab/include/bl_ld_sections.h b/modules/hal_bouffalolab/include/bl_ld_sections.h new file mode 100644 index 0000000000000..c1a9c11838f51 --- /dev/null +++ b/modules/hal_bouffalolab/include/bl_ld_sections.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2021-2025 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BL_LD_SECTIONS_H +#define __BL_LD_SECTIONS_H + +#define ATTR_STRINGIFY(x) #x +#define ATTR_TOSTRING(x) ATTR_STRINGIFY(x) +#define ATTR_SECTION(x) __attribute__((section(x))) +#define ATTR_UNI_SYMBOL __FILE__ ATTR_TOSTRING(__LINE__) +#define ATTR_CLOCK_SECTION ATTR_SECTION(".itcm.sclock_rlt_code." ATTR_UNI_SYMBOL) +#define ATTR_CLOCK_CONST_SECTION ATTR_SECTION(".itcm.sclock_rlt_const." ATTR_UNI_SYMBOL) +#define ATTR_TCM_SECTION ATTR_SECTION(".itcm.code." ATTR_UNI_SYMBOL) +#define ATTR_TCM_CONST_SECTION ATTR_SECTION(".itcm.const." ATTR_UNI_SYMBOL) +#define ATTR_DTCM_SECTION ATTR_SECTION(".dtcm.data") +#define ATTR_HSRAM_SECTION ATTR_SECTION(".hsram_code") +#define ATTR_DMA_RAM_SECTION ATTR_SECTION(".system_ram") +#define ATTR_HBN_RAM_SECTION ATTR_SECTION(".hbn_ram_code") +#define ATTR_HBN_RAM_CONST_SECTION ATTR_SECTION(".hbn_ram_data") +#define ATTR_FALLTHROUGH() __attribute__((fallthrough)) +#define ATTR_USED __attribute__((__used__)) +#define ATTR_EALIGN(x) __aligned(size) + +#endif /* __BL_LD_SECTIONS_H */ diff --git a/soc/bouffalolab/CMakeLists.txt b/soc/bouffalolab/CMakeLists.txt new file mode 100644 index 0000000000000..435b5b79480fa --- /dev/null +++ b/soc/bouffalolab/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2021-2025 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(common) +add_subdirectory(${SOC_SERIES}) diff --git a/soc/bouffalolab/Kconfig b/soc/bouffalolab/Kconfig new file mode 100644 index 0000000000000..b15605c00f307 --- /dev/null +++ b/soc/bouffalolab/Kconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2021-2025 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_BOUFFALOLAB_BFLB + select HAS_BFLB_HAL + +if SOC_FAMILY_BOUFFALOLAB_BFLB + +rsource "*/Kconfig" + +endif # SOC_FAMILY_BOUFFALOLAB_BFLB diff --git a/soc/bouffalolab/Kconfig.defconfig b/soc/bouffalolab/Kconfig.defconfig new file mode 100644 index 0000000000000..b8e9852b6f9ca --- /dev/null +++ b/soc/bouffalolab/Kconfig.defconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2021-2025 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_BOUFFALOLAB_BFLB + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) + +rsource "*/Kconfig.defconfig" + +endif # SOC_FAMILY_BOUFFALOLAB_BFLB diff --git a/soc/bouffalolab/Kconfig.soc b/soc/bouffalolab/Kconfig.soc new file mode 100644 index 0000000000000..e3841e277bd29 --- /dev/null +++ b/soc/bouffalolab/Kconfig.soc @@ -0,0 +1,11 @@ +# Copyright (c) 2021-2025 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_BOUFFALOLAB_BFLB + bool + +config SOC_FAMILY + default "bouffalolab_bflb" if SOC_FAMILY_BOUFFALOLAB_BFLB + +rsource "*/Kconfig.soc" diff --git a/soc/bouffalolab/bl60x/CMakeLists.txt b/soc/bouffalolab/bl60x/CMakeLists.txt new file mode 100644 index 0000000000000..c5437820149a3 --- /dev/null +++ b/soc/bouffalolab/bl60x/CMakeLists.txt @@ -0,0 +1,13 @@ +# Copyright (c) 2021-2025 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) +zephyr_sources(soc.c) + +zephyr_linker_sources_ifdef(CONFIG_SOC_SERIES_BL60X RODATA rodata.ld) + +set(SOC_LINKER_SCRIPT + ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld + CACHE INTERNAL "" + ) diff --git a/soc/bouffalolab/bl60x/Kconfig b/soc/bouffalolab/bl60x/Kconfig new file mode 100644 index 0000000000000..fa9b22d1f57fd --- /dev/null +++ b/soc/bouffalolab/bl60x/Kconfig @@ -0,0 +1,18 @@ +# Copyright (c) 2021-2025 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_BL60X + select RISCV + select RISCV_MACHINE_TIMER + select RISCV_ISA_RV32I + select RISCV_ISA_EXT_M + select RISCV_ISA_EXT_A + select RISCV_ISA_EXT_C + select RISCV_ISA_EXT_ZICSR + select RISCV_ISA_EXT_ZIFENCEI + select ATOMIC_OPERATIONS_C + select CPU_HAS_FPU + select INCLUDE_RESET_VECTOR + select SOC_EARLY_INIT_HOOK + select XIP diff --git a/soc/bouffalolab/bl60x/Kconfig.defconfig b/soc/bouffalolab/bl60x/Kconfig.defconfig new file mode 100644 index 0000000000000..08653e3e458fd --- /dev/null +++ b/soc/bouffalolab/bl60x/Kconfig.defconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2021-2025 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_BL60X + +config NUM_IRQS + default 80 + +endif # SOC_SERIES_BL60X diff --git a/soc/bouffalolab/bl60x/Kconfig.soc b/soc/bouffalolab/bl60x/Kconfig.soc new file mode 100644 index 0000000000000..69c234b1d3321 --- /dev/null +++ b/soc/bouffalolab/bl60x/Kconfig.soc @@ -0,0 +1,49 @@ +# Copyright (c) 2021-2025 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_BL60X + bool + select SOC_FAMILY_BOUFFALOLAB_BFLB + help + Enable support for BouffaloLab BL6xx MCU series + +config SOC_SERIES + default "bl60x" if SOC_SERIES_BL60X + +config SOC_BL602C00Q2I + bool + select SOC_SERIES_BL60X + +config SOC_BL602C20Q2I + bool + select SOC_SERIES_BL60X + +config SOC_BL602C20Q2IS + bool + select SOC_SERIES_BL60X + +config SOC_BL602C40Q2IS + bool + select SOC_SERIES_BL60X + +config SOC_BL602l10Q2H + bool + select SOC_SERIES_BL60X + +config SOC_BL602l20Q2H + bool + select SOC_SERIES_BL60X + +config SOC_BL604E20Q2I + bool + select SOC_SERIES_BL60X + +config SOC + default "bl602c00q2i" if SOC_BL602C00Q2I + default "bl602c20q2i" if SOC_BL602C20Q2I + default "bl602c20q2is" if SOC_BL602C20Q2IS + default "bl602c40q2is" if SOC_BL602C40Q2IS + default "bl602l10q2h" if SOC_BL602l10Q2H + default "bl602l20q2h" if SOC_BL602l20Q2H + default "bl604e20q2i" if SOC_BL604E20Q2I diff --git a/soc/bouffalolab/bl60x/rodata.ld b/soc/bouffalolab/bl60x/rodata.ld new file mode 100644 index 0000000000000..9cd607d3d99c2 --- /dev/null +++ b/soc/bouffalolab/bl60x/rodata.ld @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2021-2025 ATL Electronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +KEEP(*(SORT_NONE( EXCLUDE_FILE( *bl602_glb.o \ + *bl602_pds.o \ + *bl602_common.o \ + *bl602_sf_cfg.o \ + *bl602_sf_cfg_ext*.o* \ + *bl602_sf_ctrl.o \ + *bl602_sflash.o \ + *bl602_sflash_ext*.o* \ + *bl602_xip_sflash.o \ + *bl602_xip_sflash_ext*.o* \ + *bl602_ef_ctrl.o) .rodata*))) diff --git a/soc/bouffalolab/bl60x/soc.c b/soc/bouffalolab/bl60x/soc.c new file mode 100644 index 0000000000000..96f7bdfecc7a3 --- /dev/null +++ b/soc/bouffalolab/bl60x/soc.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2021-2025 ATL Electronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Bouffalo Lab RISC-V MCU series initialization code + */ + +#include +#include +#include + +#include +#include +#include + +#define ROOT_FCLK_DIV (0) +#define ROOT_BCLK_DIV (1) +#define ROOT_UART_CLOCK_DIV (0) + +static void system_bor_init(void) +{ + HBN_BOR_CFG_Type borCfg = { 1 /* pu_bor */, 0 /* irq_bor_en */, + 1 /* bor_vth */, 1 /* bor_sel */ }; + HBN_Set_BOR_Cfg(&borCfg); +} + +static uint32_t mtimer_get_clk_src_div(void) +{ + return ((SystemCoreClockGet() / (GLB_Get_BCLK_Div() + 1)) + / 1000 / 1000 - 1); +} + +static void system_clock_init(void) +{ + GLB_Set_System_CLK(GLB_PLL_XTAL_40M, GLB_SYS_CLK_PLL160M); + GLB_Set_System_CLK_Div(ROOT_FCLK_DIV, ROOT_BCLK_DIV); + GLB_Set_MTimer_CLK(1, GLB_MTIMER_CLK_BCLK, mtimer_get_clk_src_div()); +} + +static void peripheral_clock_init(void) +{ + GLB_Set_UART_CLK(1, HBN_UART_CLK_160M, ROOT_UART_CLOCK_DIV); +} + +void soc_early_init_hook(void) +{ + uint32_t key; + uint32_t *p; + uint32_t i = 0; + uint32_t tmp = 0; + + key = irq_lock(); + + __disable_irq(); + + /* disable hardware_pullup_pull_down (reg_en_hw_pu_pd = 0) */ + tmp = BL_RD_REG(HBN_BASE, HBN_IRQ_MODE); + tmp = BL_CLR_REG_BIT(tmp, HBN_REG_EN_HW_PU_PD); + BL_WR_REG(HBN_BASE, HBN_IRQ_MODE, tmp); + + /* GLB_Set_EM_Sel(GLB_EM_0KB); */ + tmp = BL_RD_REG(GLB_BASE, GLB_SEAM_MISC); + tmp = BL_SET_REG_BITS_VAL(tmp, GLB_EM_SEL, GLB_EM_0KB); + BL_WR_REG(GLB_BASE, GLB_SEAM_MISC, tmp); + + /* Fix 26M xtal clkpll_sdmin */ + tmp = BL_RD_REG(PDS_BASE, PDS_CLKPLL_SDM); + + if (BL_GET_REG_BITS_VAL(tmp, PDS_CLKPLL_SDMIN) == 0x49D39D) { + tmp = BL_SET_REG_BITS_VAL(tmp, PDS_CLKPLL_SDMIN, 0x49D89E); + BL_WR_REG(PDS_BASE, PDS_CLKPLL_SDM, tmp); + } + + /* Restore default setting*/ + + /* GLB_UART_Sig_Swap_Set(UART_SIG_SWAP_NONE); */ + tmp = BL_RD_REG(GLB_BASE, GLB_PARM); + tmp = BL_SET_REG_BITS_VAL(tmp, GLB_UART_SWAP_SET, UART_SIG_SWAP_NONE); + BL_WR_REG(GLB_BASE, GLB_PARM, tmp); + + /* GLB_JTAG_Sig_Swap_Set(JTAG_SIG_SWAP_NONE); */ + tmp = BL_RD_REG(GLB_BASE, GLB_PARM); + tmp = BL_SET_REG_BITS_VAL(tmp, GLB_JTAG_SWAP_SET, JTAG_SIG_SWAP_NONE); + BL_WR_REG(GLB_BASE, GLB_PARM, tmp); + + /* CLear all interrupt */ + p = (uint32_t *)(CLIC_HART0_ADDR + CLIC_INTIE); + + for (i = 0; i < (IRQn_LAST + 3) / 4; i++) { + p[i] = 0; + } + + p = (uint32_t *)(CLIC_HART0_ADDR + CLIC_INTIP); + + for (i = 0; i < (IRQn_LAST + 3) / 4; i++) { + p[i] = 0; + } + + /* init bor for all platform */ + system_bor_init(); + /* global IRQ enable */ + __enable_irq(); + + system_clock_init(); + peripheral_clock_init(); + + irq_unlock(key); +} + +/* identify flash config automatically */ +extern BL_Err_Type flash_init(void); + +void System_Post_Init(void) +{ + PDS_Trim_RC32M(); + HBN_Trim_RC32K(); + flash_init(); +} diff --git a/soc/bouffalolab/bl60x/soc.h b/soc/bouffalolab/bl60x/soc.h new file mode 100644 index 0000000000000..c24420593593b --- /dev/null +++ b/soc/bouffalolab/bl60x/soc.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021-2025 ATL Electronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Board configuration macros + * + * This header file is used to specify and describe board-level aspects + */ + +#ifndef _SOC__H_ +#define _SOC__H_ + +#include +#include <../common/soc_common.h> + +#ifndef _ASMLANGUAGE + +/* Add include for DTS generated information */ +#include + +#if defined(CONFIG_SOC_SERIES_BL60X) +#include +#else +#error Library does not support the specified device. +#endif + +/* clang-format off */ + +/* RISC-V Machine Timer configuration */ +#define RISCV_MTIME_BASE 0x0200BFF8 +#define RISCV_MTIMECMP_BASE 0x02004000 + +/* lib-c hooks required RAM defined variables */ +#define RISCV_RAM_BASE DT_SRAM_BASE_ADDRESS +#define RISCV_RAM_SIZE KB(DT_SRAM_SIZE) + +#define SOC_BOUFFALOLAB_BL_PLL160_FREQ_HZ (160000000) +#define SOC_BOUFFALOLAB_BL_HCLK_FREQ_HZ \ + DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency) + +/* clang-format on */ + +#endif /* !_ASMLANGUAGE */ + +#endif /* _SOC__H_ */ diff --git a/soc/bouffalolab/common/CMakeLists.txt b/soc/bouffalolab/common/CMakeLists.txt new file mode 100644 index 0000000000000..2675509dd81db --- /dev/null +++ b/soc/bouffalolab/common/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright (c) 2021-2025 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) + +zephyr_sources( + soc_irq.S + soc_common_irq.c + vector.S + ) diff --git a/soc/bouffalolab/common/clic.h b/soc/bouffalolab/common/clic.h new file mode 100644 index 0000000000000..7328a46257c65 --- /dev/null +++ b/soc/bouffalolab/common/clic.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2021-2025 ATL Electronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SIFIVE_CLIC_H +#define _SIFIVE_CLIC_H + +#define CLIC_CTRL_ADDR (DT_REG_ADDR(DT_NODELABEL(clic))) +#define CLIC_HART0_OFFSET (0x800000U) +#define CLIC_HART0_ADDR (CLIC_CTRL_ADDR + CLIC_HART0_OFFSET) + +#define CLIC_MSIP 0x0000 +#define CLIC_MSIP_size 0x4 +#define CLIC_MTIMECMP 0x4000 +#define CLIC_MTIMECMP_size 0x8 +#define CLIC_MTIME 0xBFF8 +#define CLIC_MTIME_size 0x8 + +#define CLIC_INTIP 0x000 +#define CLIC_INTIE 0x400 +#define CLIC_INTCFG 0x800 +#define CLIC_CFG 0xc00 + +#endif /* _SIFIVE_CLIC_H */ diff --git a/soc/bouffalolab/common/pinctrl_soc.h b/soc/bouffalolab/common/pinctrl_soc.h new file mode 100644 index 0000000000000..47077710a8766 --- /dev/null +++ b/soc/bouffalolab/common/pinctrl_soc.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2021-2025 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * Bouffalo Lab SoC specific helpers for pinctrl driver + */ + +#ifndef ZEPHYR_SOC_RISCV_BFLB_COMMON_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_RISCV_BFLB_COMMON_PINCTRL_SOC_H_ + +#include + +#endif /* ZEPHYR_SOC_RISCV_BFLB_COMMON_PINCTRL_SOC_H_ */ diff --git a/soc/bouffalolab/common/soc_common.h b/soc/bouffalolab/common/soc_common.h new file mode 100644 index 0000000000000..534f4175e24a3 --- /dev/null +++ b/soc/bouffalolab/common/soc_common.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2021-2025 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file interrupt management code for riscv SOCs supporting the SiFive clic + */ + +#ifndef __SOC_COMMON_H_ +#define __SOC_COMMON_H_ + +/* clang-format off */ + +/* IRQ numbers */ +#define RISCV_MACHINE_SOFT_IRQ 3 /* Machine Software Interrupt */ +#define RISCV_MACHINE_TIMER_IRQ 7 /* Machine Timer Interrupt */ +#define RISCV_MACHINE_EXT_IRQ 11 /* Machine External Interrupt */ + +/* ECALL Exception numbers */ +#define SOC_MCAUSE_ECALL_EXP 11 /* Machine ECALL instruction */ +#define SOC_MCAUSE_USER_ECALL_EXP 8 /* User ECALL instruction */ + +/* SOC-specific MCAUSE bitfields */ +#ifdef CONFIG_64BIT +/* Interrupt Mask */ +#define SOC_MCAUSE_IRQ_MASK (1 << 63) +/* Exception code Mask */ +#define SOC_MCAUSE_EXP_MASK 0x7FFFFFFFFFFFFFFF +#else +/* Interrupt Mask */ +#define SOC_MCAUSE_IRQ_MASK (1 << 31) +/* Exception code Mask */ +#define SOC_MCAUSE_EXP_MASK 0x7FFFFFFF +#endif + +/* SOC-Specific EXIT ISR command */ +#define SOC_ERET mret + +/* CLINT Base Address */ + +#define CLIC_TIMER_ENABLE_ADDRESS (0x02800407) + +/* In mstatus register */ + +#define SOC_MIE_MSIE (0x1 << 3) /* Machine Software Interrupt Enable */ + +/* IRQ 0-15 : (exception:interrupt=0) */ + +#define SOC_IRQ_IAMISALIGNED (0) /* Instruction Address Misaligned */ +#define SOC_IRQ_IAFAULT (1) /* Instruction Address Fault */ +#define SOC_IRQ_IINSTRUCTION (2) /* Illegal Instruction */ +#define SOC_IRQ_BPOINT (3) /* Break Point */ +#define SOC_IRQ_LAMISALIGNED (4) /* Load Address Misaligned */ +#define SOC_IRQ_LAFAULT (5) /* Load Access Fault */ +#define SOC_IRQ_SAMISALIGNED (6) /* Store/AMO Address Misaligned */ +#define SOC_IRQ_SAFAULT (7) /* Store/AMO Access Fault */ +#define SOC_IRQ_ECALLU (8) /* Environment Call from U-mode */ + /* 9-10: Reserved */ +#define SOC_IRQ_ECALLM (11) /* Environment Call from M-mode */ + /* 12-15: Reserved */ + /* IRQ 16- : (async event:interrupt=1) */ +#define SOC_IRQ_NUM_BASE (16) +#define SOC_IRQ_ASYNC (16) + +/* Machine Software Int */ +#define SOC_IRQ_MSOFT (SOC_IRQ_ASYNC + RISCV_MACHINE_SOFT_IRQ) +/* Machine Timer Int */ +#define SOC_IRQ_MTIMER (SOC_IRQ_ASYNC + RISCV_MACHINE_TIMER_IRQ) +/* Machine External Int */ +#define SOC_IRQ_MEXT (SOC_IRQ_ASYNC + RISCV_MACHINE_EXT_IRQ) + +/* Machine Global External Interrupt */ +#define SOC_NR_MGEI_IRQS (64) + +/* Total number of IRQs */ +#define SOC_NR_IRQS (SOC_NR_MGEI_IRQS + SOC_IRQ_NUM_BASE) + +/* clang-format on */ + +#endif /* __SOC_COMMON_H_ */ diff --git a/soc/bouffalolab/common/soc_common_irq.c b/soc/bouffalolab/common/soc_common_irq.c new file mode 100644 index 0000000000000..82dacbcc4c6aa --- /dev/null +++ b/soc/bouffalolab/common/soc_common_irq.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021-2025 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief interrupt management code for riscv SOCs supporting the SiFive clic + */ +#include +#include +#include + +/* clang-format off */ + +static void clic_irq_enable(unsigned int irq) +{ + *(volatile uint8_t *)(CLIC_HART0_ADDR + CLIC_INTIE + irq) = 1; +} + +static void clic_irq_disable(unsigned int irq) +{ + *(volatile uint8_t *)(CLIC_HART0_ADDR + CLIC_INTIE + irq) = 0; +} + +void arch_irq_enable(unsigned int irq) +{ + uint32_t mie; + + if (irq == SOC_IRQ_MSOFT) { + + /* Read mstatus & set machine software interrupt enable in mie */ + + __asm__ volatile("csrrs %0, mie, %1" + : "=r"(mie) + : "r"(BIT(RISCV_MACHINE_SOFT_IRQ))); + + } else if (irq == SOC_IRQ_MTIMER) { + *(volatile uint8_t *)CLIC_TIMER_ENABLE_ADDRESS = 1; + + /* Read mstatus & set machine timer interrupt enable in mie */ + __asm__ volatile("csrrs %0, mie, %1" + : "=r"(mie) + : "r"(BIT(RISCV_MACHINE_TIMER_IRQ) + | BIT(RISCV_MACHINE_EXT_IRQ))); + } else { + clic_irq_enable(irq - SOC_IRQ_ASYNC); + } +} + +void arch_irq_disable(unsigned int irq) +{ + uint32_t mie; + + if (irq == SOC_IRQ_MSOFT) { + + /* Read mstatus & set machine software interrupt enable in mie */ + + __asm__ volatile("csrrc %0, mie, %1" + : "=r"(mie) + : "r"(BIT(RISCV_MACHINE_SOFT_IRQ))); + + } else if (irq == SOC_IRQ_MTIMER) { + *(volatile uint8_t *)CLIC_TIMER_ENABLE_ADDRESS = 0; + + /* Read mstatus & set machine timer interrupt enable in mie */ + __asm__ volatile("csrrc %0, mie, %1" + : "=r"(mie) + : "r"(BIT(RISCV_MACHINE_TIMER_IRQ) + | BIT(RISCV_MACHINE_EXT_IRQ))); + } else { + clic_irq_disable(irq - SOC_IRQ_ASYNC); + } +} + +void arch_irq_priority_set(unsigned int irq, unsigned int prio) +{ + ARG_UNUSED(irq); + ARG_UNUSED(prio); +} + +int arch_irq_is_enabled(unsigned int irq) +{ + uint32_t mie; + + /* Enable MEIE (machine external interrupt enable) */ + __asm__ volatile("csrrs %0, mie, %1" + : "=r"(mie) + : "r"(BIT(RISCV_MACHINE_EXT_IRQ))); + + /* Read mstatus & set machine interrupt enable (MIE) in mstatus */ + __asm__ volatile("csrrs %0, mstatus, %1" + : "=r"(mie) + : "r"(MSTATUS_MIE)); + + return !!(mie & SOC_MIE_MSIE); +} + +/* clang-format on */ diff --git a/soc/bouffalolab/common/soc_irq.S b/soc/bouffalolab/common/soc_irq.S new file mode 100644 index 0000000000000..b2fabf12035c8 --- /dev/null +++ b/soc/bouffalolab/common/soc_irq.S @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017 Jean-Paul Etienne + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * common interrupt management code for riscv SOCs supporting the riscv + * privileged architecture specification + */ +#include +#include +#include +#include +#include + +/* exports */ +GTEXT(__soc_handle_irq) + +/* + * SOC-specific function to handle pending IRQ number generating the interrupt. + * Exception number is given as parameter via register a0. + */ +SECTION_FUNC(exception.other, __soc_handle_irq) + /* Clear exception number from CSR mip register */ + li t1, 1 + sll t0, t1, a0 + csrrc t1, mip, t0 + + /* Return */ + jalr x0, ra + +/* + * __soc_is_irq is defined as .weak to allow re-implementation by + * SOCs that does not truly follow the riscv privilege specification. + */ +WTEXT(__soc_is_irq) + +/* + * SOC-specific function to determine if the exception is the result of a + * an interrupt or an exception + * return 1 (interrupt) or 0 (exception) + * + */ +SECTION_FUNC(exception.other, __soc_is_irq) + /* Read mcause and check if interrupt bit is set */ + csrr t0, mcause + li t1, SOC_MCAUSE_IRQ_MASK + and t0, t0, t1 + + /* If interrupt bit is not set, return with 0 */ + addi a0, x0, 0 + beqz t0, not_interrupt + addi a0, a0, 1 + +not_interrupt: + /* return */ + jalr x0, ra diff --git a/soc/bouffalolab/common/vector.S b/soc/bouffalolab/common/vector.S new file mode 100644 index 0000000000000..898856f36e8e8 --- /dev/null +++ b/soc/bouffalolab/common/vector.S @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021-2025 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* exports */ +GTEXT(__start) + +/* imports */ +GTEXT(__initialize) +GTEXT(_isr_wrapper) + +SECTION_FUNC(vectors, __start) + .cfi_startproc + + .option norvc + + /* Inform the debugger that there is nowhere to backtrace */ + .cfi_undefined ra + + /* Disable interrupts */ + li t0, MSTATUS_MIE + csrc mstatus, t0 + + /* + * Set mtvec (Machine Trap-Vector Base-Address Register) + * CLINT Direct mode + */ + la t0, _isr_wrapper + csrw mtvec, t0 + + /* Jump to __initialize */ + tail __initialize + + .cfi_endproc diff --git a/soc/bouffalolab/soc.yml b/soc/bouffalolab/soc.yml new file mode 100644 index 0000000000000..8aafe0d436798 --- /dev/null +++ b/soc/bouffalolab/soc.yml @@ -0,0 +1,13 @@ +family: +- name: bouffalolab_bflb + series: + - name: bl60x + socs: + - name: bl602c00q2i + - name: bl602c20q2i + - name: bl602c20q2is + - name: bl602c40q2is + - name: bl602l10q2h + - name: bl602l20q2h + - name: bl604e20q2i +vendor: bflb diff --git a/west.yml b/west.yml index 4721dbb3d294e..76cd4619ed921 100644 --- a/west.yml +++ b/west.yml @@ -161,6 +161,11 @@ manifest: path: modules/hal/atmel groups: - hal + - name: hal_bouffalolab + path: modules/hal/bouffalolab + revision: c6c44b879503d990dfba643c212b606cee414faa + groups: + - hal - name: hal_espressif revision: dbc28ad4c1bdcdb25e79ca225cb5528a75d8dc91 path: modules/hal/espressif