From df28d8fc3d6064a93a44332715de425ed216f2e0 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Sat, 17 Jul 2021 22:49:40 -0300 Subject: [PATCH 1/8] west: Introduce hal bouffalo lab Add initial version that uses bouffalo_sdk 1.4.5. Signed-off-by: Gerson Fernando Budke --- modules/Kconfig | 3 + modules/hal_bouffalolab/CMakeLists.txt | 55 +++++++++++++++++ modules/hal_bouffalolab/Kconfig | 59 +++++++++++++++++++ .../hal_bouffalolab/include/bl_ld_sections.h | 26 ++++++++ west.yml | 5 ++ 5 files changed, 148 insertions(+) create mode 100644 modules/hal_bouffalolab/CMakeLists.txt create mode 100644 modules/hal_bouffalolab/Kconfig create mode 100644 modules/hal_bouffalolab/include/bl_ld_sections.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/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/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 From 44b939afd73d0946af336bfeb0babcf377e99f16 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Mon, 14 Oct 2024 20:38:17 +0200 Subject: [PATCH 2/8] dts: bindings: vendor-prefixes: Add Bouffalo Lab prefix Add necessary bflb prefix to be used on devicetree bindings and identify the board vendor. Signed-off-by: Gerson Fernando Budke --- dts/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) 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 From 398fedd0a02f724fb967661ca8c5e1503ec3cf66 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Mon, 2 Aug 2021 22:54:21 -0300 Subject: [PATCH 3/8] dts: riscv: bouffalolab: Add bl60x series cpu Introduce Bouffalo Lab vendor with BL60x cpu. Signed-off-by: Gerson Fernando Budke --- dts/riscv/bouffalolab/bl60x.dtsi | 114 +++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 dts/riscv/bouffalolab/bl60x.dtsi diff --git a/dts/riscv/bouffalolab/bl60x.dtsi b/dts/riscv/bouffalolab/bl60x.dtsi new file mode 100644 index 0000000000000..9571136ee9fc4 --- /dev/null +++ b/dts/riscv/bouffalolab/bl60x.dtsi @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2021-2025 ATL Electronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#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>; + }; + + 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)>; + }; + }; +}; From ada9ce3d9cbc739c0289bce2b27712eb3882f063 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Mon, 2 Aug 2021 23:04:17 -0300 Subject: [PATCH 4/8] soc: riscv: bouffalolab: Add bl60x series cpu Add initial version. Signed-off-by: Gerson Fernando Budke --- modules/hal_bouffalolab/include/bflb_glb.h | 14 +++ modules/hal_bouffalolab/include/bflb_hbn.h | 14 +++ soc/bouffalolab/CMakeLists.txt | 6 + soc/bouffalolab/Kconfig | 12 ++ soc/bouffalolab/Kconfig.defconfig | 12 ++ soc/bouffalolab/Kconfig.soc | 11 ++ soc/bouffalolab/bl60x/CMakeLists.txt | 13 +++ soc/bouffalolab/bl60x/Kconfig | 18 +++ soc/bouffalolab/bl60x/Kconfig.defconfig | 10 ++ soc/bouffalolab/bl60x/Kconfig.soc | 49 +++++++++ soc/bouffalolab/bl60x/rodata.ld | 17 +++ soc/bouffalolab/bl60x/soc.c | 122 +++++++++++++++++++++ soc/bouffalolab/bl60x/soc.h | 49 +++++++++ soc/bouffalolab/common/CMakeLists.txt | 11 ++ soc/bouffalolab/common/clic.h | 26 +++++ soc/bouffalolab/common/soc_common.h | 82 ++++++++++++++ soc/bouffalolab/common/soc_common_irq.c | 100 +++++++++++++++++ soc/bouffalolab/common/soc_irq.S | 58 ++++++++++ soc/bouffalolab/common/vector.S | 39 +++++++ soc/bouffalolab/soc.yml | 13 +++ 20 files changed, 676 insertions(+) create mode 100644 modules/hal_bouffalolab/include/bflb_glb.h create mode 100644 modules/hal_bouffalolab/include/bflb_hbn.h create mode 100644 soc/bouffalolab/CMakeLists.txt create mode 100644 soc/bouffalolab/Kconfig create mode 100644 soc/bouffalolab/Kconfig.defconfig create mode 100644 soc/bouffalolab/Kconfig.soc create mode 100644 soc/bouffalolab/bl60x/CMakeLists.txt create mode 100644 soc/bouffalolab/bl60x/Kconfig create mode 100644 soc/bouffalolab/bl60x/Kconfig.defconfig create mode 100644 soc/bouffalolab/bl60x/Kconfig.soc create mode 100644 soc/bouffalolab/bl60x/rodata.ld create mode 100644 soc/bouffalolab/bl60x/soc.c create mode 100644 soc/bouffalolab/bl60x/soc.h create mode 100644 soc/bouffalolab/common/CMakeLists.txt create mode 100644 soc/bouffalolab/common/clic.h create mode 100644 soc/bouffalolab/common/soc_common.h create mode 100644 soc/bouffalolab/common/soc_common_irq.c create mode 100644 soc/bouffalolab/common/soc_irq.S create mode 100644 soc/bouffalolab/common/vector.S create mode 100644 soc/bouffalolab/soc.yml 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_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/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/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 From 2187a3294b258ecdac47bc48a80a9f4e18e61359 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Sat, 27 Jan 2024 10:54:29 +0100 Subject: [PATCH 5/8] drivers: pinctrl: bouffalolab: Add bflb pinctrl driver Add Bouffalo Lab pinctrl driver. Signed-off-by: Gerson Fernando Budke --- drivers/pinctrl/CMakeLists.txt | 1 + drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/Kconfig.bflb | 10 ++ drivers/pinctrl/pinctrl_bflb.c | 45 +++++++++ dts/bindings/gpio/bflb,gpio.yaml | 35 +++++++ dts/bindings/pinctrl/bflb,pinctrl.yaml | 91 +++++++++++++++++++ dts/riscv/bouffalolab/bl60x.dtsi | 23 +++++ .../drivers/pinctrl/pinctrl_soc_bflb_common.h | 82 +++++++++++++++++ modules/hal_bouffalolab/include/bflb_gpio.h | 14 +++ .../hal_bouffalolab/include/bflb_pinctrl.h | 15 +++ soc/bouffalolab/common/pinctrl_soc.h | 17 ++++ 11 files changed, 334 insertions(+) create mode 100644 drivers/pinctrl/Kconfig.bflb create mode 100644 drivers/pinctrl/pinctrl_bflb.c create mode 100644 dts/bindings/gpio/bflb,gpio.yaml create mode 100644 dts/bindings/pinctrl/bflb,pinctrl.yaml create mode 100644 include/zephyr/drivers/pinctrl/pinctrl_soc_bflb_common.h create mode 100644 modules/hal_bouffalolab/include/bflb_gpio.h create mode 100644 modules/hal_bouffalolab/include/bflb_pinctrl.h create mode 100644 soc/bouffalolab/common/pinctrl_soc.h 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/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/riscv/bouffalolab/bl60x.dtsi b/dts/riscv/bouffalolab/bl60x.dtsi index 9571136ee9fc4..cf6d73df6111e 100644 --- a/dts/riscv/bouffalolab/bl60x.dtsi +++ b/dts/riscv/bouffalolab/bl60x.dtsi @@ -6,6 +6,8 @@ #include #include +#include +#include / { #address-cells = <1>; @@ -60,6 +62,27 @@ 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>; + }; + }; + spi0: spi@4000a200 { compatible = "bflb,spi"; reg = <0x4000a200 0x100>; 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/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_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/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_ */ From 35a401ed2db2432d68521e66c106423f47337881 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Mon, 2 Aug 2021 23:07:11 -0300 Subject: [PATCH 6/8] drivers: serial: bouffalolab: Add bflb serial driver Add Bouffalo Lab serial driver. The driver uses pinctrl to configure pins and have power management capabilities. Signed-off-by: Gerson Fernando Budke --- drivers/serial/CMakeLists.txt | 1 + drivers/serial/Kconfig | 1 + drivers/serial/Kconfig.bflb | 12 ++ drivers/serial/uart_bflb.c | 130 ++++++++++++++++++++ dts/bindings/serial/bflb,uart.yaml | 20 +++ dts/riscv/bouffalolab/bl60x.dtsi | 18 +++ modules/hal_bouffalolab/include/bflb_uart.h | 14 +++ 7 files changed, 196 insertions(+) create mode 100644 drivers/serial/Kconfig.bflb create mode 100644 drivers/serial/uart_bflb.c create mode 100644 dts/bindings/serial/bflb,uart.yaml create mode 100644 modules/hal_bouffalolab/include/bflb_uart.h 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/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/riscv/bouffalolab/bl60x.dtsi b/dts/riscv/bouffalolab/bl60x.dtsi index cf6d73df6111e..7ec4c90802f79 100644 --- a/dts/riscv/bouffalolab/bl60x.dtsi +++ b/dts/riscv/bouffalolab/bl60x.dtsi @@ -83,6 +83,24 @@ }; }; + 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>; 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_ */ From 2ce920be23762cf8a5d3fb2d57c67b562227aaec Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Sat, 2 Apr 2022 12:09:04 -0300 Subject: [PATCH 7/8] boards: riscv: Introduce bl604e_iot_dvk Add initial version. Signed-off-by: Gerson Fernando Budke --- .../bl604e_iot_dvk/Kconfig.bl604e_iot_dvk | 6 + .../bl604e_iot_dvk-pinctrl.dtsi | 26 +++++ .../bl60x/bl604e_iot_dvk/bl604e_iot_dvk.dts | 52 +++++++++ .../bl60x/bl604e_iot_dvk/bl604e_iot_dvk.yaml | 19 ++++ .../bl604e_iot_dvk/bl604e_iot_dvk_defconfig | 9 ++ .../bl60x/bl604e_iot_dvk/board.cmake | 20 ++++ .../bl60x/bl604e_iot_dvk/board.yml | 6 + .../bl60x/bl604e_iot_dvk/doc/img/bl_604e.webp | Bin 0 -> 76856 bytes .../bl60x/bl604e_iot_dvk/doc/index.rst | 104 ++++++++++++++++++ .../bl60x/bl604e_iot_dvk/support/bl60x.cfg | 79 +++++++++++++ .../bl60x/bl604e_iot_dvk/support/openocd.cfg | 19 ++++ boards/bouffalolab/index.rst | 10 ++ 12 files changed, 350 insertions(+) create mode 100644 boards/bouffalolab/bl60x/bl604e_iot_dvk/Kconfig.bl604e_iot_dvk create mode 100644 boards/bouffalolab/bl60x/bl604e_iot_dvk/bl604e_iot_dvk-pinctrl.dtsi create mode 100644 boards/bouffalolab/bl60x/bl604e_iot_dvk/bl604e_iot_dvk.dts create mode 100644 boards/bouffalolab/bl60x/bl604e_iot_dvk/bl604e_iot_dvk.yaml create mode 100644 boards/bouffalolab/bl60x/bl604e_iot_dvk/bl604e_iot_dvk_defconfig create mode 100644 boards/bouffalolab/bl60x/bl604e_iot_dvk/board.cmake create mode 100644 boards/bouffalolab/bl60x/bl604e_iot_dvk/board.yml create mode 100644 boards/bouffalolab/bl60x/bl604e_iot_dvk/doc/img/bl_604e.webp create mode 100644 boards/bouffalolab/bl60x/bl604e_iot_dvk/doc/index.rst create mode 100644 boards/bouffalolab/bl60x/bl604e_iot_dvk/support/bl60x.cfg create mode 100644 boards/bouffalolab/bl60x/bl604e_iot_dvk/support/openocd.cfg create mode 100644 boards/bouffalolab/index.rst 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 0000000000000000000000000000000000000000..a4e60232febd02e399dd4296820b31c96f229825 GIT binary patch literal 76856 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 Date: Sat, 21 Sep 2024 18:09:14 +0200 Subject: [PATCH 8/8] MAINTAINERS.yml: Add Bouffalo Lab entries Introduce Bouffalo Lab platform. Signed-off-by: Gerson Fernando Budke --- MAINTAINERS.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) 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: