From 22cf8d68d0f50f53f26595e5a04106da7ab40bc4 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Tue, 12 Oct 2021 18:15:14 -0300 Subject: [PATCH 01/10] riscv: linker.ld: Fix undefined reference linker error The commit a28830b aligned the data and rename some symbols. However there are two symbols at riscv linker script that were missing, which causes below linker error: kernel/xip.c:28: undefined reference to `__itcm_load_start' kernel/xip.c:43: undefined reference to `__dtcm_data_load_start' Rename below symbols to fix the issues. __itcm_rom_start -> __itcm_load_start __dtcm_data_rom_start -> __dtcm_data_load_start Signed-off-by: Gerson Fernando Budke --- include/arch/riscv/common/linker.ld | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/arch/riscv/common/linker.ld b/include/arch/riscv/common/linker.ld index d032c6e442d83..564f1288f30d2 100644 --- a/include/arch/riscv/common/linker.ld +++ b/include/arch/riscv/common/linker.ld @@ -320,7 +320,7 @@ GROUP_START(ITCM) } GROUP_LINK_IN(ITCM AT> ROMABLE_REGION) __itcm_size = __itcm_end - __itcm_start; - __itcm_rom_start = LOADADDR(_ITCM_SECTION_NAME); + __itcm_load_start = LOADADDR(_ITCM_SECTION_NAME); GROUP_END(ITCM) #endif @@ -355,7 +355,7 @@ GROUP_START(DTCM) __dtcm_end = .; - __dtcm_data_rom_start = LOADADDR(_DTCM_DATA_SECTION_NAME); + __dtcm_data_load_start = LOADADDR(_DTCM_DATA_SECTION_NAME); GROUP_END(DTCM) #endif From f420690705a507ec4c2533fea29aef010a2718ef Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Sat, 17 Jul 2021 22:49:40 -0300 Subject: [PATCH 02/10] west: Introduce hal bouffalo lab Add initial version. Signed-off-by: Gerson Fernando Budke --- modules/Kconfig | 3 + modules/hal_bouffalolab/CMakeLists.txt | 61 +++++++++++++++++++ modules/hal_bouffalolab/Kconfig | 58 ++++++++++++++++++ .../hal_bouffalolab/include/bl_ld_sections.h | 24 ++++++++ west.yml | 8 +++ 5 files changed, 154 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 6cf510adcce14..3a599534d168d 100644 --- a/modules/Kconfig +++ b/modules/Kconfig @@ -46,6 +46,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..edb14061323e0 --- /dev/null +++ b/modules/hal_bouffalolab/CMakeLists.txt @@ -0,0 +1,61 @@ + +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_SOC_FAMILY_BFLB) + +zephyr_library_named(hal_bouffalolab) + +zephyr_compile_definitions( + ARCH_RISCV +) + +zephyr_library_compile_definitions( + BFLB_USE_HAL_DRIVER + BFLB_USE_CUSTOM_LD_SECTIONS +) + +set(bflb_soc ${CONFIG_SOC_SUB_SERIES}) +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 to be used outside hal_gigadevice +zephyr_include_directories( + 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() diff --git a/modules/hal_bouffalolab/Kconfig b/modules/hal_bouffalolab/Kconfig new file mode 100644 index 0000000000000..801fa4b3c4878 --- /dev/null +++ b/modules/hal_bouffalolab/Kconfig @@ -0,0 +1,58 @@ +# Copyright (c) 2021 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..69e3ef3ba9864 --- /dev/null +++ b/modules/hal_bouffalolab/include/bl_ld_sections.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 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_UNI_SYMBOL __FILE__ ATTR_TOSTRING(__LINE__) +#define ATTR_CLOCK_SECTION __attribute__((section(".itcm.sclock_rlt_code." ATTR_UNI_SYMBOL))) +#define ATTR_CLOCK_CONST_SECTION __attribute__((section(".itcm.sclock_rlt_const." ATTR_UNI_SYMBOL))) +#define ATTR_TCM_SECTION __attribute__((section(".itcm.code." ATTR_UNI_SYMBOL))) +#define ATTR_TCM_CONST_SECTION __attribute__((section(".itcm.const." ATTR_UNI_SYMBOL))) +#define ATTR_DTCM_SECTION __attribute__((section(".dtcm.data"))) +#define ATTR_HSRAM_SECTION __attribute__((section(".hsram_code"))) +#define ATTR_DMA_RAM_SECTION __attribute__((section(".system_ram"))) +#define ATTR_HBN_RAM_SECTION __attribute__((section(".hbn_ram_code"))) +#define ATTR_HBN_RAM_CONST_SECTION __attribute__((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 d59033c9d85a8..d805c34f519cd 100644 --- a/west.yml +++ b/west.yml @@ -21,6 +21,8 @@ manifest: remotes: - name: upstream url-base: https://github.com/zephyrproject-rtos + - name: nandojve + url-base: https://github.com/nandojve # # Please add items below based on alphabetical order @@ -61,6 +63,12 @@ manifest: path: modules/hal/atmel groups: - hal + - name: bl_mcu_sdk + remote: nandojve + path: modules/hal/bouffalolab + revision: f33ca054e51fd77bc6768e70b9e06be230015b48 + groups: + - hal - name: hal_cypress revision: 81a059f21435bc7e315bccd720da5a9b615bbb50 path: modules/hal/cypress From 531f50fe83e77b5537f7201ef6d6da9f8fa300a7 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Mon, 2 Aug 2021 22:54:21 -0300 Subject: [PATCH 03/10] dts: riscv: bouffalolab: Add bl6 series cpu Introduce Bouffalo Lab vendor with BL602 cpu. Signed-off-by: Gerson Fernando Budke --- dts/bindings/vendor-prefixes.txt | 1 + dts/riscv/bouffalolab/bl6.dtsi | 103 +++++++++++++++++++++++++++++++ dts/riscv/bouffalolab/bl602.dtsi | 15 +++++ 3 files changed, 119 insertions(+) create mode 100644 dts/riscv/bouffalolab/bl6.dtsi create mode 100644 dts/riscv/bouffalolab/bl602.dtsi diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index 352177db2902a..5d1247e343d57 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -87,6 +87,7 @@ baikal BAIKAL ELECTRONICS, JSC bananapi BIPAI KEJI LIMITED beacon Compass Electronics Group, LLC beagle BeagleBoard.org Foundation +bflb Bouffalo Lab bhf Beckhoff Automation GmbH & Co. KG bitmain Bitmain Technologies blutek BluTek Power diff --git a/dts/riscv/bouffalolab/bl6.dtsi b/dts/riscv/bouffalolab/bl6.dtsi new file mode 100644 index 0000000000000..6e966cef9020b --- /dev/null +++ b/dts/riscv/bouffalolab/bl6.dtsi @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2021, ATL Electronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + clock-frequency = <0>; + compatible = "riscv,sifive-e24", "riscv"; + device_type = "cpu"; + hardware-exec-breakpoint-count = <4>; + reg = <0>; + riscv,isa = "rv32imafcb"; + riscv,pmpregions = <4>; + + ictrl: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges; + + itcm: itcm@22010000 { + compatible = "sifive,dtim0"; + reg = <0x22010000 DT_SIZE_K(16)>; + }; + dtcm: dtcm@42014000 { + compatible = "sifive,dtim0"; + reg = <0x42014000 DT_SIZE_K(48)>; + }; + + sram0: memory@42020000 { + compatible = "mmio-sram"; + }; + sram1: memory@42030000 { + compatible = "mmio-sram"; + reg = <0x42030000 DT_SIZE_K(112)>; + }; + + clint: clint@2000000 { + #interrupt-cells = <1>; + interrupt-controller; + compatible = "riscv,clint0"; + interrupts-extended = <&ictrl 3 &ictrl 7>; + reg = <0x2000000 0x10000>; + reg-names = "control"; + }; + + clic: clic@2000000 { + #interrupt-cells = <1>; + interrupt-controller; + compatible = "sifive,clic0"; + interrupts-extended = <&ictrl 3 &ictrl 7 &ictrl 11>; + reg = <0x2000000 0x10000>; + reg-names = "control"; + + sifive,numintbits = <4>; + sifive,numints = <64>; + sifive,numlevels = <16>; + }; + + spi0: spi@4000a200 { + compatible = "bflb,bl-spi"; + reg = <0x4000a200 0x100>; + peripheral-id = <0>; + interrupts = <27 0>; + interrupt-parent = <&ictrl>; + status = "disabled"; + label = "spi_0"; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi1: spi@4000b000 { + compatible = "bflb,bl-qspi"; + reg = <0x4000b000 0x1000>; + peripheral-id = <0>; + interrupts = <23 0>; + interrupt-parent = <&ictrl>; + status = "disabled"; + label = "qspi_0"; + #address-cells = <1>; + #size-cells = <0>; + }; + }; +}; diff --git a/dts/riscv/bouffalolab/bl602.dtsi b/dts/riscv/bouffalolab/bl602.dtsi new file mode 100644 index 0000000000000..2398e7f81e9e3 --- /dev/null +++ b/dts/riscv/bouffalolab/bl602.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2021 ATL Electronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + soc { + sram0: memory@42020000 { + reg = <0x42020000 DT_SIZE_K(64)>; + }; + }; +}; From 52dad4fbbf7dd292542a7aa1a649ac3293252978 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Mon, 2 Aug 2021 23:04:17 -0300 Subject: [PATCH 04/10] soc: riscv: bouffalolab: Add bl6 series cpu Add initial version. Signed-off-by: Gerson Fernando Budke --- modules/hal_bouffalolab/include/bflb_glb.h | 13 ++ modules/hal_bouffalolab/include/bflb_hbn.h | 13 ++ soc/riscv/bouffalolab/CMakeLists.txt | 7 + soc/riscv/bouffalolab/Kconfig | 19 +++ soc/riscv/bouffalolab/Kconfig.defconfig | 4 + soc/riscv/bouffalolab/Kconfig.soc | 4 + soc/riscv/bouffalolab/bflb/CMakeLists.txt | 9 + .../bouffalolab/bflb/Kconfig.defconfig.bl6 | 25 +++ .../bouffalolab/bflb/Kconfig.defconfig.series | 4 + soc/riscv/bouffalolab/bflb/Kconfig.series | 15 ++ soc/riscv/bouffalolab/bflb/Kconfig.soc | 4 + soc/riscv/bouffalolab/bflb/Kconfig.soc.bl6 | 17 ++ soc/riscv/bouffalolab/bflb/linker.ld | 6 + soc/riscv/bouffalolab/bflb/rodata.ld | 22 +++ soc/riscv/bouffalolab/bflb/soc.c | 144 ++++++++++++++++ soc/riscv/bouffalolab/bflb/soc.h | 49 ++++++ soc/riscv/bouffalolab/common/CMakeLists.txt | 10 ++ soc/riscv/bouffalolab/common/clic.h | 25 +++ soc/riscv/bouffalolab/common/idle.c | 59 +++++++ soc/riscv/bouffalolab/common/oldvector.S | 158 ++++++++++++++++++ soc/riscv/bouffalolab/common/soc_common.h | 78 +++++++++ soc/riscv/bouffalolab/common/soc_common_irq.c | 96 +++++++++++ soc/riscv/bouffalolab/common/soc_irq.S | 58 +++++++ soc/riscv/bouffalolab/common/vector.S | 51 ++++++ 24 files changed, 890 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/riscv/bouffalolab/CMakeLists.txt create mode 100644 soc/riscv/bouffalolab/Kconfig create mode 100644 soc/riscv/bouffalolab/Kconfig.defconfig create mode 100644 soc/riscv/bouffalolab/Kconfig.soc create mode 100644 soc/riscv/bouffalolab/bflb/CMakeLists.txt create mode 100644 soc/riscv/bouffalolab/bflb/Kconfig.defconfig.bl6 create mode 100644 soc/riscv/bouffalolab/bflb/Kconfig.defconfig.series create mode 100644 soc/riscv/bouffalolab/bflb/Kconfig.series create mode 100644 soc/riscv/bouffalolab/bflb/Kconfig.soc create mode 100644 soc/riscv/bouffalolab/bflb/Kconfig.soc.bl6 create mode 100644 soc/riscv/bouffalolab/bflb/linker.ld create mode 100644 soc/riscv/bouffalolab/bflb/rodata.ld create mode 100644 soc/riscv/bouffalolab/bflb/soc.c create mode 100644 soc/riscv/bouffalolab/bflb/soc.h create mode 100644 soc/riscv/bouffalolab/common/CMakeLists.txt create mode 100644 soc/riscv/bouffalolab/common/clic.h create mode 100644 soc/riscv/bouffalolab/common/idle.c create mode 100644 soc/riscv/bouffalolab/common/oldvector.S create mode 100644 soc/riscv/bouffalolab/common/soc_common.h create mode 100644 soc/riscv/bouffalolab/common/soc_common_irq.c create mode 100644 soc/riscv/bouffalolab/common/soc_irq.S create mode 100644 soc/riscv/bouffalolab/common/vector.S diff --git a/modules/hal_bouffalolab/include/bflb_glb.h b/modules/hal_bouffalolab/include/bflb_glb.h new file mode 100644 index 0000000000000..d04d67c62a520 --- /dev/null +++ b/modules/hal_bouffalolab/include/bflb_glb.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2021 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_BL6 + #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..9b0e4eee1f05c --- /dev/null +++ b/modules/hal_bouffalolab/include/bflb_hbn.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2021 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_BL6 + #include +#endif + +#endif /* ZEPHYR_HAL_BFLB_HBN_H_ */ diff --git a/soc/riscv/bouffalolab/CMakeLists.txt b/soc/riscv/bouffalolab/CMakeLists.txt new file mode 100644 index 0000000000000..4a02603db81f5 --- /dev/null +++ b/soc/riscv/bouffalolab/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) 2021, ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 +# + +add_subdirectory(common) +add_subdirectory(${SOC_SERIES}) diff --git a/soc/riscv/bouffalolab/Kconfig b/soc/riscv/bouffalolab/Kconfig new file mode 100644 index 0000000000000..950a4918735dd --- /dev/null +++ b/soc/riscv/bouffalolab/Kconfig @@ -0,0 +1,19 @@ +# Copyright (c) 2021, ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_BFLB + bool + select HAS_BFLB_HAL + select BUILD_OUTPUT_HEX + select PINCTRL + +config SOC_FAMILY + string + default "bouffalolab" + depends on SOC_FAMILY_BFLB + +if SOC_FAMILY_BFLB + +source "soc/riscv/bouffalolab/*/Kconfig.soc" + +endif # SOC_FAMILY_BFLB diff --git a/soc/riscv/bouffalolab/Kconfig.defconfig b/soc/riscv/bouffalolab/Kconfig.defconfig new file mode 100644 index 0000000000000..a8c37dd291008 --- /dev/null +++ b/soc/riscv/bouffalolab/Kconfig.defconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2021, ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/bouffalolab/*/Kconfig.defconfig.series" diff --git a/soc/riscv/bouffalolab/Kconfig.soc b/soc/riscv/bouffalolab/Kconfig.soc new file mode 100644 index 0000000000000..68c645781f421 --- /dev/null +++ b/soc/riscv/bouffalolab/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2021, ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/bouffalolab/*/Kconfig.series" diff --git a/soc/riscv/bouffalolab/bflb/CMakeLists.txt b/soc/riscv/bouffalolab/bflb/CMakeLists.txt new file mode 100644 index 0000000000000..73221684eaadf --- /dev/null +++ b/soc/riscv/bouffalolab/bflb/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (c) 2021, ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 +# + +zephyr_include_directories(.) +zephyr_sources(soc.c) + +zephyr_linker_sources_ifdef(CONFIG_SOC_FAMILY_BFLB RODATA rodata.ld) diff --git a/soc/riscv/bouffalolab/bflb/Kconfig.defconfig.bl6 b/soc/riscv/bouffalolab/bflb/Kconfig.defconfig.bl6 new file mode 100644 index 0000000000000..c8e76e31c833f --- /dev/null +++ b/soc/riscv/bouffalolab/bflb/Kconfig.defconfig.bl6 @@ -0,0 +1,25 @@ +# Copyright (c) 2021, ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_BL6 + +config SOC_SERIES + default "bflb" + +config SOC_SUB_SERIES + string + default "bl602" + +config SOC_PART_NUMBER + string + default "bl602c00q2i" if SOC_PART_NUMBER_BL602C00Q2I + default "bl602c20q2i" if SOC_PART_NUMBER_BL602C20Q2I + default "bl604e20q2i" if SOC_PART_NUMBER_BL604C20Q2I + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 192000000 + +config NUM_IRQS + default 64 + +endif # SOC_SERIES_BL6 diff --git a/soc/riscv/bouffalolab/bflb/Kconfig.defconfig.series b/soc/riscv/bouffalolab/bflb/Kconfig.defconfig.series new file mode 100644 index 0000000000000..4cb7f20c4b52a --- /dev/null +++ b/soc/riscv/bouffalolab/bflb/Kconfig.defconfig.series @@ -0,0 +1,4 @@ +# Copyright (c) 2021, ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/bouffalolab/bflb/Kconfig.defconfig.bl*" diff --git a/soc/riscv/bouffalolab/bflb/Kconfig.series b/soc/riscv/bouffalolab/bflb/Kconfig.series new file mode 100644 index 0000000000000..195502b12a43a --- /dev/null +++ b/soc/riscv/bouffalolab/bflb/Kconfig.series @@ -0,0 +1,15 @@ +# Copyright (c) 2021, ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_BL6 + bool "Bouffalo Lab BL6 series MCU" + select RISCV +# select RISCV_GP + select RISCV_HAS_CPU_IDLE + select RISCV_MACHINE_TIMER + select ATOMIC_OPERATIONS_C + select COMPRESSED_ISA + select SOC_FAMILY_BFLB + select CPU_HAS_FPU + help + Enable support for Bouffalo Lab BL6 MCU series diff --git a/soc/riscv/bouffalolab/bflb/Kconfig.soc b/soc/riscv/bouffalolab/bflb/Kconfig.soc new file mode 100644 index 0000000000000..c17d43c3b4102 --- /dev/null +++ b/soc/riscv/bouffalolab/bflb/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2021, ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/bouffalolab/bflb/Kconfig.soc.bl*" diff --git a/soc/riscv/bouffalolab/bflb/Kconfig.soc.bl6 b/soc/riscv/bouffalolab/bflb/Kconfig.soc.bl6 new file mode 100644 index 0000000000000..a946f365d4045 --- /dev/null +++ b/soc/riscv/bouffalolab/bflb/Kconfig.soc.bl6 @@ -0,0 +1,17 @@ +# Copyright (c) 2021, ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +choice + prompt "bouffalo Lab BL6 MCU Selection" + depends on SOC_SERIES_BL6 + + config SOC_PART_NUMBER_BL602C00Q2I + bool "BL602C00Q2I" + + config SOC_PART_NUMBER_BL602C20Q2I + bool "BL602C20Q2I" + + config SOC_PART_NUMBER_BL604C20Q2I + bool "BL604E20Q2I" + +endchoice diff --git a/soc/riscv/bouffalolab/bflb/linker.ld b/soc/riscv/bouffalolab/bflb/linker.ld new file mode 100644 index 0000000000000..4b7aedd9f9616 --- /dev/null +++ b/soc/riscv/bouffalolab/bflb/linker.ld @@ -0,0 +1,6 @@ +/* + * Copyright (c) 2021, ATL Electronics + * SPDX-License-Identifier: Apache-2.0 + */ + +#include diff --git a/soc/riscv/bouffalolab/bflb/rodata.ld b/soc/riscv/bouffalolab/bflb/rodata.ld new file mode 100644 index 0000000000000..8c5b01869bd6a --- /dev/null +++ b/soc/riscv/bouffalolab/bflb/rodata.ld @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2021, ATL Electronics + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#if defined(CONFIG_SOC_SERIES_BL6) + +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*))) + +#endif diff --git a/soc/riscv/bouffalolab/bflb/soc.c b/soc/riscv/bouffalolab/bflb/soc.c new file mode 100644 index 0000000000000..9187f5cec9d2f --- /dev/null +++ b/soc/riscv/bouffalolab/bflb/soc.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2021, ATL Electronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Bouffalo Lab RISC-V MCU series initialization code + */ + +#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); +} + +#ifdef CONFIG_RISCV_GP +ulong_t __soc_get_gp_initial_value(void) +{ + extern uint32_t __global_pointer$; + return (ulong_t)&__global_pointer$; +} +#endif + +/** + * @brief Perform basic hardware initialization at boot. + * + * This needs to be run from the very beginning. + * So the init priority has to be 0 (zero). + * + * @return 0 + */ + +static int bl_riscv_init(const struct device *arg) +{ + uint32_t key; + uint32_t *p; + uint32_t i = 0; + uint32_t tmpVal = 0; + + ARG_UNUSED(arg); + + key = irq_lock(); + + __disable_irq(); + + /* disable hardware_pullup_pull_down (reg_en_hw_pu_pd = 0) */ + tmpVal = BL_RD_REG(HBN_BASE, HBN_IRQ_MODE); + tmpVal = BL_CLR_REG_BIT(tmpVal, HBN_REG_EN_HW_PU_PD); + BL_WR_REG(HBN_BASE, HBN_IRQ_MODE, tmpVal); + + /* GLB_Set_EM_Sel(GLB_EM_0KB); */ + tmpVal = BL_RD_REG(GLB_BASE, GLB_SEAM_MISC); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_EM_SEL, GLB_EM_0KB); + BL_WR_REG(GLB_BASE, GLB_SEAM_MISC, tmpVal); + + /* Fix 26M xtal clkpll_sdmin */ + tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_SDM); + + if (BL_GET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_SDMIN) == 0x49D39D) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_SDMIN, 0x49D89E); + BL_WR_REG(PDS_BASE, PDS_CLKPLL_SDM, tmpVal); + } + + /* Restore default setting*/ + + /* GLB_UART_Sig_Swap_Set(UART_SIG_SWAP_NONE); */ + tmpVal = BL_RD_REG(GLB_BASE, GLB_PARM); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_UART_SWAP_SET, UART_SIG_SWAP_NONE); + BL_WR_REG(GLB_BASE, GLB_PARM, tmpVal); + + /* GLB_JTAG_Sig_Swap_Set(JTAG_SIG_SWAP_NONE); */ + tmpVal = BL_RD_REG(GLB_BASE, GLB_PARM); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_JTAG_SWAP_SET, JTAG_SIG_SWAP_NONE); + BL_WR_REG(GLB_BASE, GLB_PARM, tmpVal); + + /* 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); + + return 0; +} + +/* identify flash config automatically */ +extern BL_Err_Type flash_init(void); + +void System_Post_Init(void) +{ + PDS_Trim_RC32M(); + HBN_Trim_RC32K(); + flash_init(); +} + +SYS_INIT(bl_riscv_init, PRE_KERNEL_1, 0); diff --git a/soc/riscv/bouffalolab/bflb/soc.h b/soc/riscv/bouffalolab/bflb/soc.h new file mode 100644 index 0000000000000..a3a06b6c9de88 --- /dev/null +++ b/soc/riscv/bouffalolab/bflb/soc.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021, 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_BL6) +#include +#else +#error Library does not support the specified device. +#endif + +/* 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) + +#ifdef CONFIG_RISCV_GP +ulong_t __soc_get_gp_initial_value(void); +#endif + +#endif /* !_ASMLANGUAGE */ + +#endif /* _SOC__H_ */ diff --git a/soc/riscv/bouffalolab/common/CMakeLists.txt b/soc/riscv/bouffalolab/common/CMakeLists.txt new file mode 100644 index 0000000000000..50ee91a2c33bd --- /dev/null +++ b/soc/riscv/bouffalolab/common/CMakeLists.txt @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) + +zephyr_sources( + idle.c + soc_irq.S + soc_common_irq.c + vector.S + ) diff --git a/soc/riscv/bouffalolab/common/clic.h b/soc/riscv/bouffalolab/common/clic.h new file mode 100644 index 0000000000000..f13de0dfe4ba8 --- /dev/null +++ b/soc/riscv/bouffalolab/common/clic.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021, ATL Electronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SIFIVE_CLIC_H +#define _SIFIVE_CLIC_H + +#define CLIC_CTRL_ADDR 0x02000000UL +#define CLIC_HART0_ADDR 0x02800000UL + +#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/riscv/bouffalolab/common/idle.c b/soc/riscv/bouffalolab/common/idle.c new file mode 100644 index 0000000000000..d14bac3fed013 --- /dev/null +++ b/soc/riscv/bouffalolab/common/idle.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017 Jean-Paul Etienne + * Contributors: 2018 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include + +static ALWAYS_INLINE void riscv_idle(unsigned int key) +{ + sys_trace_idle(); + /* unlock interrupts */ + irq_unlock(key); + + /* Wait for interrupt */ + __asm__ volatile("wfi"); +} + +/** + * + * @brief Power save idle routine + * + * This function will be called by the kernel idle loop or possibly within + * an implementation of _pm_save_idle in the kernel when the + * '_pm_save_flag' variable is non-zero. + * + * @return N/A + */ +void arch_cpu_idle(void) +{ + riscv_idle(MSTATUS_IEN); +} + +/** + * + * @brief Atomically re-enable interrupts and enter low power mode + * + * INTERNAL + * The requirements for arch_cpu_atomic_idle() are as follows: + * 1) The enablement of interrupts and entering a low-power mode needs to be + * atomic, i.e. there should be no period of time where interrupts are + * enabled before the processor enters a low-power mode. See the comments + * in k_lifo_get(), for example, of the race condition that + * occurs if this requirement is not met. + * + * 2) After waking up from the low-power mode, the interrupt lockout state + * must be restored as indicated in the 'imask' input parameter. + * + * @return N/A + */ +void arch_cpu_atomic_idle(unsigned int key) +{ + riscv_idle(key); +} diff --git a/soc/riscv/bouffalolab/common/oldvector.S b/soc/riscv/bouffalolab/common/oldvector.S new file mode 100644 index 0000000000000..a084f140f906d --- /dev/null +++ b/soc/riscv/bouffalolab/common/oldvector.S @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2017 Jean-Paul Etienne + * Contributors: 2018 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define __metal_chicken_bit 0 + +/* exports */ +GTEXT(__start) + +/* imports */ +GTEXT(__initialize) +GTEXT(__irq_wrapper) + +SECTION_FUNC(exception, ivt) + .option norvc + + /* Interrupts */ + j __irq_wrapper /* IRQ 0 */ + j __irq_wrapper /* IRQ 1 */ + j __irq_wrapper /* IRQ 2 */ + j __irq_wrapper /* IRQ 3 - clic_msip */ + j __irq_wrapper /* IRQ 4 */ + j __irq_wrapper /* IRQ 5 */ + j __irq_wrapper /* IRQ 6 */ + j __irq_wrapper /* IRQ 7 - clic_mtimer */ + j __irq_wrapper /* IRQ 8 - ? */ + j __irq_wrapper /* IRQ 9 - ? */ + j __irq_wrapper /* IRQ 10 - ? */ + j __irq_wrapper /* IRQ 11 - clic_mext */ + j __irq_wrapper /* IRQ 12 - clic_csoft */ + j __irq_wrapper /* IRQ 13 - ? */ + j __irq_wrapper /* IRQ 14 - Debug interrupt */ + j __irq_wrapper /* IRQ 15 */ + + /* CLIC Local Interrupts */ + j __irq_wrapper /* IRQ 16 + 0 - BMX_ERR */ + j __irq_wrapper /* IRQ 16 + 1 - BMX_TO */ + j __irq_wrapper /* IRQ 16 + 2 - L1C_BMX_ERR */ + j __irq_wrapper /* IRQ 16 + 3 - L1C_BMX_TO */ + j __irq_wrapper /* IRQ 16 + 4 - SEC_BMX_ERR */ + j __irq_wrapper /* IRQ 16 + 5 - RF_TOP_INT0 */ + j __irq_wrapper /* IRQ 16 + 6 - RF_TOP_INT1 */ + j __irq_wrapper /* IRQ 16 + 7 - SDIO */ + j __irq_wrapper /* IRQ 16 + 8 - DMA_BMX_ERR */ + j __irq_wrapper /* IRQ 16 + 9 - SEC_GMAC */ + j __irq_wrapper /* IRQ 16 + 10 - SEC_CDET */ + j __irq_wrapper /* IRQ 16 + 11 - SEC_PKA */ + j __irq_wrapper /* IRQ 16 + 12 - SEC_TRNG */ + j __irq_wrapper /* IRQ 16 + 13 - SEC_AES */ + j __irq_wrapper /* IRQ 16 + 14 - SEC_SHA */ + j __irq_wrapper /* IRQ 16 + 15 - DMA_ALL */ + j __irq_wrapper /* IRQ 16 + 16 */ + j __irq_wrapper /* IRQ 16 + 17 */ + j __irq_wrapper /* IRQ 16 + 18 */ + j __irq_wrapper /* IRQ 16 + 19 - IRTX */ + j __irq_wrapper /* IRQ 16 + 20 - IRRX */ + j __irq_wrapper /* IRQ 16 + 21 */ + j __irq_wrapper /* IRQ 16 + 22 */ + j __irq_wrapper /* IRQ 16 + 23 - SF_CTRL */ + j __irq_wrapper /* IRQ 16 + 24 */ + j __irq_wrapper /* IRQ 16 + 25 - GPADC_DMA */ + j __irq_wrapper /* IRQ 16 + 26 - EFUSE */ + j __irq_wrapper /* IRQ 16 + 27 - SPI */ + j __irq_wrapper /* IRQ 16 + 28 */ + j __irq_wrapper /* IRQ 16 + 29 - UART0 */ + j __irq_wrapper /* IRQ 16 + 30 - UART1 */ + j __irq_wrapper /* IRQ 16 + 31 */ + j __irq_wrapper /* IRQ 16 + 32 - I2C */ + j __irq_wrapper /* IRQ 16 + 33 */ + j __irq_wrapper /* IRQ 16 + 34 - PWM */ + j __irq_wrapper /* IRQ 16 + 35 */ + j __irq_wrapper /* IRQ 16 + 36 - TIMER_CH0 */ + j __irq_wrapper /* IRQ 16 + 37 - TIMER_CH1 */ + j __irq_wrapper /* IRQ 16 + 38 - TIMER_WDT */ + j __irq_wrapper /* IRQ 16 + 39 */ + j __irq_wrapper /* IRQ 16 + 40 */ + j __irq_wrapper /* IRQ 16 + 41 */ + j __irq_wrapper /* IRQ 16 + 42 */ + j __irq_wrapper /* IRQ 16 + 43 */ + j __irq_wrapper /* IRQ 16 + 44 - GPIO_INT0 */ + j __irq_wrapper /* IRQ 16 + 45 */ + j __irq_wrapper /* IRQ 16 + 46 */ + j __irq_wrapper /* IRQ 16 + 47 */ + j __irq_wrapper /* IRQ 16 + 48 */ + j __irq_wrapper /* IRQ 16 + 49 */ + j __irq_wrapper /* IRQ 16 + 50 - PDS_WAKEUP */ + j __irq_wrapper /* IRQ 16 + 51 - HBN_OUT0 */ + j __irq_wrapper /* IRQ 16 + 52 - HBN_OUT1 */ + j __irq_wrapper /* IRQ 16 + 53 - BOR */ + j __irq_wrapper /* IRQ 16 + 54 - WIFI */ + j __irq_wrapper /* IRQ 16 + 55 - BZ_PHY */ + j __irq_wrapper /* IRQ 16 + 56 - BLE */ + j __irq_wrapper /* IRQ 16 + 57 - MAC_TXRX_TIMER */ + j __irq_wrapper /* IRQ 16 + 58 - MAC_TXRX_MISC */ + j __irq_wrapper /* IRQ 16 + 59 - MAC_RX_TRG */ + j __irq_wrapper /* IRQ 16 + 60 - MAC_TX_TRG */ + j __irq_wrapper /* IRQ 16 + 61 - MAC_GEN */ + j __irq_wrapper /* IRQ 16 + 62 - MAC_PORT */ + j __irq_wrapper /* IRQ 16 + 63 - WIFI_IPC */ + +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 + + /* The absolute first thing that must happen is configuring the global + * pointer register, which must be done with relaxation disabled + * because it's not valid to obtain the address of any symbol without + * GP configured. The C environment might go ahead and do this again, + * but that's safe as it's a fixed register. */ + .option push + .option norelax + la gp, __data_global_pointer + .option pop + + /* Set mtvec (Machine Trap-Vector Base-Address Register) */ + la t0, __irq_wrapper + + /* enable CLIC Vectored mode */ + /* ori t0, t0, 3 */ + /* enable CLINT Direct mode */ + ori t0, t0, 0 + csrw mtvec, t0 + + /* enable chicken bit if core is bullet series*/ + la t0, __metal_chicken_bit + beqz t0, 1f + csrwi 0x7C1, 0 +1: + + /* Check for an initialization routine and call it if one exists, + * otherwise just skip over the call entirely. Note that + * __metal_initialize isn't actually a full C function, as it doesn't + * end up with the .bss or .data segments having been initialized. + * This is done to avoid putting a burden on systems that can be + * initialized without having a C environment set up.*/ + call SystemInit + + /* start load code to itcm like.*/ + call start_load + + /* Jump to __initialize */ + tail __initialize + + .cfi_endproc diff --git a/soc/riscv/bouffalolab/common/soc_common.h b/soc/riscv/bouffalolab/common/soc_common.h new file mode 100644 index 0000000000000..67fb90beb845e --- /dev/null +++ b/soc/riscv/bouffalolab/common/soc_common.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2021 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_ + +/* 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) + +#endif /* __SOC_COMMON_H_ */ diff --git a/soc/riscv/bouffalolab/common/soc_common_irq.c b/soc/riscv/bouffalolab/common/soc_common_irq.c new file mode 100644 index 0000000000000..53601cd0b625f --- /dev/null +++ b/soc/riscv/bouffalolab/common/soc_common_irq.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2021 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief interrupt management code for riscv SOCs supporting the SiFive clic + */ +#include +#include +#include + +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); +} diff --git a/soc/riscv/bouffalolab/common/soc_irq.S b/soc/riscv/bouffalolab/common/soc_irq.S new file mode 100644 index 0000000000000..3a8904d043762 --- /dev/null +++ b/soc/riscv/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/riscv/bouffalolab/common/vector.S b/soc/riscv/bouffalolab/common/vector.S new file mode 100644 index 0000000000000..d6780f32b32f4 --- /dev/null +++ b/soc/riscv/bouffalolab/common/vector.S @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* exports */ +GTEXT(__start) + +/* imports */ +GTEXT(__initialize) +GTEXT(__irq_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 + +#ifdef CONFIG_RISCV_GP + /* The absolute first thing that must happen is configuring the global + * pointer register, which must be done with relaxation disabled + * because it's not valid to obtain the address of any symbol without + * GP configured. The C environment might go ahead and do this again, + * but that's safe as it's a fixed register. */ + .option push + .option norelax + la gp, __global_pointer$ + .option pop +#endif + + /* + * Set mtvec (Machine Trap-Vector Base-Address Register) + * CLINT Direct mode + */ + la t0, __irq_wrapper + csrw mtvec, t0 + + /* Jump to __initialize */ + tail __initialize + + .cfi_endproc From e3dd54c3e557f0c2c4db313877c3e44ebf7440b0 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Mon, 2 Aug 2021 23:15:51 -0300 Subject: [PATCH 05/10] drivers: timer: Enable mtimer support for bflb cpu The Bouffalo Lab cpu supports RISC-V Machine Timer. This enable support for this riscv cpu series. Signed-off-by: Gerson Fernando Budke --- drivers/timer/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index 864bea683238f..fe8fe8cbe1d45 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -218,7 +218,7 @@ source "drivers/timer/Kconfig.stm32_lptim" config RISCV_MACHINE_TIMER bool "RISCV Machine Timer" - depends on SOC_FAMILY_RISCV_PRIVILEGE + depends on SOC_FAMILY_RISCV_PRIVILEGE || SOC_FAMILY_BFLB select TICKLESS_CAPABLE help This module implements a kernel device driver for the generic RISCV machine From db422fde1162f19659392aff6423471f3a6e32e8 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Mon, 25 Oct 2021 20:16:13 -0300 Subject: [PATCH 06/10] 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 | 2 + drivers/pinctrl/Kconfig.bflb | 9 ++ drivers/pinctrl/pinctrl_bflb.c | 39 ++++++ dts/bindings/gpio/bflb,bl-gpio.yaml | 40 ++++++ dts/bindings/pinctrl/bflb,bl-pinctrl.yaml | 90 ++++++++++++++ dts/riscv/bouffalolab/bl6.dtsi | 20 +++ include/dt-bindings/pinctrl/bflb-pinctrl.h | 131 ++++++++++++++++++++ modules/hal_bouffalolab/include/bflb_gpio.h | 13 ++ soc/riscv/bouffalolab/common/pinctrl_soc.h | 104 ++++++++++++++++ 10 files changed, 449 insertions(+) create mode 100644 drivers/pinctrl/Kconfig.bflb create mode 100644 drivers/pinctrl/pinctrl_bflb.c create mode 100644 dts/bindings/gpio/bflb,bl-gpio.yaml create mode 100644 dts/bindings/pinctrl/bflb,bl-pinctrl.yaml create mode 100644 include/dt-bindings/pinctrl/bflb-pinctrl.h create mode 100644 modules/hal_bouffalolab/include/bflb_gpio.h create mode 100644 soc/riscv/bouffalolab/common/pinctrl_soc.h diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index cd3eca95d8d74..1fa8829a040ff 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -3,3 +3,4 @@ zephyr_library() zephyr_library_sources(common.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_BFLB pinctrl_bflb.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 7e1a67175b84c..8825e7cd22385 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -29,4 +29,6 @@ config PINCTRL_DYNAMIC runtime. This can be useful, for example, to change the pins assigned to a peripheral at early boot stages depending on a certain input. +source "drivers/pinctrl/Kconfig.bflb" + endif # PINCTRL diff --git a/drivers/pinctrl/Kconfig.bflb b/drivers/pinctrl/Kconfig.bflb new file mode 100644 index 0000000000000..8d9060ad80064 --- /dev/null +++ b/drivers/pinctrl/Kconfig.bflb @@ -0,0 +1,9 @@ +# Copyright (c) 2021 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +config PINCTRL_BFLB + bool "Bouffalo Lab pin control driver" + depends on SOC_FAMILY_BFLB + 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..789e120123f00 --- /dev/null +++ b/drivers/pinctrl/pinctrl_bflb.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 Gerson Fernando Budke + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +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_FUN_2_FUNC(pins[i].fun); + pincfg.gpioMode = BFLB_FUN_2_MODE(pins[i].fun); + pincfg.gpioPin = pins[i].pin; + pincfg.pullType = BFLB_CFG_2_GPIO_MODE(pins[i].cfg); + pincfg.smtCtrl = BFLB_CFG_2_GPIO_INP_SMT(pins[i].cfg); + pincfg.drive = BFLB_CFG_2_GPIO_DRV_STR(pins[i].cfg); + + if (pincfg.gpioFun == GPIO_FUN_UART) { + GLB_UART_Fun_Sel(pincfg.gpioPin % 8, + (BFLB_FUN_2_INST(pins[i].fun)) + * BFLB_SIG_UART_LEN + + (pins[i].flags & BFLB_SIG_UART_MASK) + ); + } + + GLB_GPIO_Init(&pincfg); + } + + return 0; +} diff --git a/dts/bindings/gpio/bflb,bl-gpio.yaml b/dts/bindings/gpio/bflb,bl-gpio.yaml new file mode 100644 index 0000000000000..4e17f8db26a88 --- /dev/null +++ b/dts/bindings/gpio/bflb,bl-gpio.yaml @@ -0,0 +1,40 @@ +# Copyright (c) 2021, Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +description: Bouffalo Lab GPIO node + +compatible: "bflb,bl-gpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + + interrupts: + required: false + + label: + required: true + + "#gpio-cells": + const: 0 + + "#bflb,pin-cells": + type: int + required: true + const: 2 + description: Number of items to expect in a bflb,pins specifier + + "#bflb,signal-cells": + type: int + required: false + const: 1 + description: Number of items to expect in a bflb,signals specifier + +bflb,pin-cells: + - fun + - pin + +bflb,signal-cells: + - flags diff --git a/dts/bindings/pinctrl/bflb,bl-pinctrl.yaml b/dts/bindings/pinctrl/bflb,bl-pinctrl.yaml new file mode 100644 index 0000000000000..00b7ab07f6d4b --- /dev/null +++ b/dts/bindings/pinctrl/bflb,bl-pinctrl.yaml @@ -0,0 +1,90 @@ +# Copyright (c) 2021, Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +description: Bouffalo Lab Pinctrl node + +compatible: "bflb,bl-pinctrl" + +include: + - name: base.yaml + - name: pincfg-node-group.yaml + child-binding: + child-binding: + property-allowlist: + - bias-high-impedance + - bias-pull-down + - bias-pull-up + - input-enable + - input-schmitt-enable + - output-enable + +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) */ + pins1 { + /* configure to uart0 function plus modem interrupt, pin 7 as UART_RX + pin 16 as UART_TX and finally pin 18 as gpio */ + bflb,pins = , + , + ; + bflb,signals = , + ; + bias-pull-up; + input-schmitt-enable; + }; + }; + 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. + properties: + "bflb,pins": + required: true + type: phandle-array + description: | + An phandle-array of pins sharing the same group properties. The pins + should be defined using the BFLB_PIN utility macro that encode + function and pin. Some special functions require a signal to complete + route matrix. + "bflb,signals": + required: false + type: array + description: | + An optional array that add flags to a pin. The signal flag is defined + at bflb-pinctrl.h and have BFLB_SIG_ as prefix. It don't require same + len that bflb,pins property. + drive-strength: + required: false + 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. diff --git a/dts/riscv/bouffalolab/bl6.dtsi b/dts/riscv/bouffalolab/bl6.dtsi index 6e966cef9020b..d03037ddb9f0d 100644 --- a/dts/riscv/bouffalolab/bl6.dtsi +++ b/dts/riscv/bouffalolab/bl6.dtsi @@ -5,6 +5,7 @@ */ #include +#include / { #address-cells = <1>; @@ -76,6 +77,25 @@ sifive,numlevels = <16>; }; + pinctrl: pinctrl@40000000 { + compatible = "bflb,bl-pinctrl"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x40000000 0x40000000 0x1000>; + + glb: gpio@40000000 { + compatible = "bflb,bl-gpio"; + reg = <0x40000000 0x1000>; + label = "GLB"; + interrupts = <1 0>; + interrupt-parent = <&ictrl>; + gpio-controller; + #gpio-cells = <0>; + #bflb,pin-cells = <2>; + #bflb,signal-cells = <1>; + }; + }; + spi0: spi@4000a200 { compatible = "bflb,bl-spi"; reg = <0x4000a200 0x100>; diff --git a/include/dt-bindings/pinctrl/bflb-pinctrl.h b/include/dt-bindings/pinctrl/bflb-pinctrl.h new file mode 100644 index 0000000000000..f18ad9140eed8 --- /dev/null +++ b/include/dt-bindings/pinctrl/bflb-pinctrl.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2021 Gerson Fernando Budke + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_BFLB_PINCTRL_H_ +#define ZEPHYR_BFLB_PINCTRL_H_ + +/** + * @brief FUN configuration bitfield + * + * The Zephyr version of Bouffalo Lab function field encode 3 information: + * - The pin function itself + * - The peripheral instance (ex. uart0, uart1, etc) + * - The pin mode + * + * Because GPIO is a subset of functions, it is necessary define all modes + * when a pin is configured. To keep it simple, mode is already defined for all + * alternate functions and analog. In the case of GPIO, the pincfg-node should + * be used to configure GPIO function. + * + * Pin function configuration is coded using 2 bytes with the following fields + * Byte 0 - Function + * Byte 1 - Pin Mode [ 0 : 1 ] + * - Peripheral Instance [ 4 : 5 ] + * + * ex.: + * uart1 - 0x1207 + * 1 2 07 + * Instance Alternate Mode Function UART + * + * gpio - 0x010b + * 0 2 0b + * Instance Output Function GPIO + */ + +#define BFLB_FUN_clk_out 0x0200 +#define BFLB_FUN_bt_coexist 0x0201 +#define BFLB_FUN_flash_psram 0x0202 +#define BFLB_FUN_qspi 0x0202 +#define BFLB_FUN_i2s 0x0203 +#define BFLB_FUN_spi 0x0204 +#define BFLB_FUN_i2c 0x0206 +#define BFLB_FUN_uart0 0x0207 +#define BFLB_FUN_uart1 0x1207 +#define BFLB_FUN_pwm 0x0208 +#define BFLB_FUN_cam 0x0209 +#define BFLB_FUN_analog 0x030a +#define BFLB_FUN_gpio 0x000b +#define BFLB_FUN_rf_test 0x020c +#define BFLB_FUN_scan 0x020d +#define BFLB_FUN_jtag 0x020e +#define BFLB_FUN_debug 0x020f +#define BFLB_FUN_external_pa 0x0210 +#define BFLB_FUN_usb_transceiver 0x0211 +#define BFLB_FUN_usb_controller 0x0212 +#define BFLB_FUN_ether_mac 0x0213 +#define BFLB_FUN_emca 0x0213 +#define BFLB_FUN_qdec 0x0014 +#define BFLB_FUN_key_scan_in 0x0215 +#define BFLB_FUN_key_scan_row 0x0215 +#define BFLB_FUN_key_scan_drive 0x0216 +#define BFLB_FUN_key_scan_col 0x0216 +#define BFLB_FUN_cam_misc 0x0217 +#define BFLB_FUN_FUNC_POS 0U +#define BFLB_FUN_FUNC_MASK 0x1F + +#define BFLB_FUN_MODE_POS 8U +#define BFLB_FUN_MODE_MASK 0x03 +#define BFLB_FUN_MODE_INPUT (0x0 << BFLB_FUN_MODE_POS) +#define BFLB_FUN_MODE_OUTPUT (0x1 << BFLB_FUN_MODE_POS) +#define BFLB_FUN_MODE_AF (0x2 << BFLB_FUN_MODE_POS) +#define BFLB_FUN_MODE_ANALOG (0x3 << BFLB_FUN_MODE_POS) + +#define BFLB_FUN_INST_POS 12U +#define BFLB_FUN_INST_MASK 0x03 +#define BFLB_FUN_INST_0 (0x0 << BFLB_FUN_INST_POS) +#define BFLB_FUN_INST_1 (0x1 << BFLB_FUN_INST_POS) + +#define BFLB_SIG_UART_RTS 0x0 +#define BFLB_SIG_UART_CTS 0x1 +#define BFLB_SIG_UART_TXD 0x2 +#define BFLB_SIG_UART_RXD 0x3 +#define BFLB_SIG_UART_LEN 0x4 +#define BFLB_SIG_UART_MASK 0x3 + +/** + * @brief helper macro to encode an IO port pin in a numerical format + * + * - fun Function value. It should be lower case value defined by a + * BFLB_FUN_function. + * - pin Pin number. + * + * ex.: How to define uart0 rx/tx pins, which is define as BFLB_FUN_uart0 + * + * bflb,pins = , + * ; + */ +#define BFLB_PIN(fun, pin) &glb BFLB_FUN_##fun pin + +#define BFLB_FUN_2_FUNC(fun) (((fun) >> BFLB_FUN_FUNC_POS) & BFLB_FUN_FUNC_MASK) +#define BFLB_FUN_2_MODE(fun) (((fun) >> BFLB_FUN_MODE_POS) & BFLB_FUN_MODE_MASK) +#define BFLB_FUN_2_INST(fun) (((fun) >> BFLB_FUN_INST_POS) & BFLB_FUN_INST_MASK) + +/* + * Pin configuration is coded following below bit fields: + * - GPIO Mode [ 0 : 1 ] + * - GPIO Schmitt Trigger [ 2 ] + * - GPIO Drive Strength [ 3 : 4 ] + */ + +/* GPIO Pull-up/pull-down/High impedance */ +#define BFLB_GPIO_MODE_POS 0U +#define BFLB_GPIO_MODE_MASK 0x3 +#define BFLB_GPIO_MODE_HIGH_IMPEDANCE (0x0 << BFLB_GPIO_MODE_POS) +#define BFLB_GPIO_MODE_PULL_UP (0x1 << BFLB_GPIO_MODE_POS) +#define BFLB_GPIO_MODE_PULL_DOWN (0x2 << BFLB_GPIO_MODE_POS) +#define BFLB_CFG_2_GPIO_MODE(cfg) (((cfg) >> BFLB_GPIO_MODE_POS) & BFLB_GPIO_MODE_MASK) + +/* GPIO Input Schmitt trigger */ +#define BFLB_GPIO_INP_SMT_POS 2U +#define BFLB_GPIO_INP_SMT_MASK 0x1 +#define BFLB_GPIO_INP_SMT_EN (0x1 << BFLB_GPIO_INP_SMT_POS) +#define BFLB_CFG_2_GPIO_INP_SMT(cfg) (((cfg) >> BFLB_GPIO_INP_SMT_POS) & BFLB_GPIO_INP_SMT_MASK) + +/* GPIO Output Drive Strength */ +#define BFLB_GPIO_DRV_STR_POS 3U +#define BFLB_GPIO_DRV_STR_MASK 0x3 +#define BFLB_CFG_2_GPIO_DRV_STR(cfg) (((cfg) >> BFLB_GPIO_DRV_STR_POS) & BFLB_GPIO_DRV_STR_MASK) + +#endif /* ZEPHYR_BFLB_PINCTRL_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..769c4db3c25f5 --- /dev/null +++ b/modules/hal_bouffalolab/include/bflb_gpio.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2021 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_BL6 + #include +#endif + +#endif /* ZEPHYR_HAL_BFLB_GPIO_H_ */ diff --git a/soc/riscv/bouffalolab/common/pinctrl_soc.h b/soc/riscv/bouffalolab/common/pinctrl_soc.h new file mode 100644 index 0000000000000..7853d8a1da8a8 --- /dev/null +++ b/soc/riscv/bouffalolab/common/pinctrl_soc.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2021 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 +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond INTERNAL_HIDDEN */ + +typedef struct pinctrl_soc_pin { + uint16_t fun; + uint16_t cfg; + uint8_t pin; + uint8_t flags; +} pinctrl_soc_pin_t; + +/** + * @brief Utility macro to initialize fun field in #pinctrl_soc_pin_t. + * + * @param node_id Node identifier. + */ +#define Z_PINCTRL_BFLB_FUN_INIT(node_id, prop, idx) \ + ( \ + DT_PHA_BY_IDX(node_id, prop, idx, fun) | \ + (BFLB_FUN_MODE_INPUT * DT_PROP_OR(node_id, input_enable, 0)) | \ + (BFLB_FUN_MODE_OUTPUT * DT_PROP_OR(node_id, output_enable, 0)) \ + ) + +/** + * @brief Utility macro to initialize flags field in #pinctrl_soc_pin_t. + * + * @param node_id Node identifier. + */ +#define Z_PINCTRL_BFLB_CFG_INIT(node_id) \ + ( \ + (BFLB_GPIO_MODE_PULL_UP * DT_PROP_OR(node_id, bias_pull_up, 0)) | \ + (BFLB_GPIO_MODE_PULL_DOWN * DT_PROP_OR(node_id, bias_pull_down, 0)) | \ + (BFLB_GPIO_INP_SMT_EN * DT_PROP_OR(node_id, input_schmitt_enable, 0)) |\ + (DT_PROP_OR(node_id, drive_strength, 0) << BFLB_GPIO_DRV_STR_POS) \ + ) + +/** + * @brief Utility macro to initialize pin field in #pinctrl_soc_pin_t. + * + * @param node_id Node identifier. + */ +#define Z_PINCTRL_BFLB_PIN_INIT(node_id, prop, idx) \ + DT_PHA_BY_IDX(node_id, prop, idx, pin) + +/** + * @brief Utility macro to initialize flags field in #pinctrl_soc_pin_t. + * + * @param node_id Node identifier. + */ +#define Z_PINCTRL_BFLB_FLAGS_INIT(node_id, prop, idx) \ + COND_CODE_1(DT_PROP_HAS_IDX(node_id, prop, idx), \ + (DT_PROP_BY_IDX(node_id, prop, idx)), (0)) + +/** + * @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) \ + { .fun = Z_PINCTRL_BFLB_FUN_INIT(node_id, prop, idx), \ + .cfg = Z_PINCTRL_BFLB_CFG_INIT(node_id), \ + .pin = Z_PINCTRL_BFLB_PIN_INIT(node_id, prop, idx), \ + .flags = Z_PINCTRL_BFLB_FLAGS_INIT(node_id, bflb_signals, idx), \ + }, + +/** + * @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_PROP_BY_IDX(node_id, prop, 0), \ + DT_FOREACH_PROP_ELEM, bflb_pins, \ + Z_PINCTRL_STATE_PIN_INIT)} + +/** @endcond */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_SOC_RISCV_BFLB_COMMON_PINCTRL_SOC_H_ */ From 3b68a0f894e20746755bd822f11d54c7fa9ffa97 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Mon, 2 Aug 2021 23:07:11 -0300 Subject: [PATCH 07/10] 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 | 2 + drivers/serial/Kconfig.bflb | 16 +++ drivers/serial/uart_bflb.c | 124 ++++++++++++++++++++ dts/bindings/serial/bflb,bl-uart.yaml | 17 +++ dts/riscv/bouffalolab/bl6.dtsi | 19 +++ modules/hal_bouffalolab/include/bflb_uart.h | 13 ++ 7 files changed, 192 insertions(+) create mode 100644 drivers/serial/Kconfig.bflb create mode 100644 drivers/serial/uart_bflb.c create mode 100644 dts/bindings/serial/bflb,bl-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 a5c8c87c6c110..c245bba7702fc 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -44,6 +44,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_XEC uart_mchp_xec.c) zephyr_library_sources_ifdef(CONFIG_UART_NEORV32 uart_neorv32.c) zephyr_library_sources_ifdef(CONFIG_USART_GD32 usart_gd32.c) zephyr_library_sources_ifdef(CONFIG_UART_XEN_HVC uart_hvc_xen.c) +zephyr_library_sources_ifdef(CONFIG_UART_BFLB uart_bflb.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE uart_handlers.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 2729390b1806c..4d5bdaab89b53 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -169,4 +169,6 @@ source "drivers/serial/Kconfig.neorv32" source "drivers/serial/Kconfig.xen" +source "drivers/serial/Kconfig.bflb" + endif # SERIAL diff --git a/drivers/serial/Kconfig.bflb b/drivers/serial/Kconfig.bflb new file mode 100644 index 0000000000000..5e11ac54ce5a6 --- /dev/null +++ b/drivers/serial/Kconfig.bflb @@ -0,0 +1,16 @@ +# Bouffalo Lab UART configuration +# +# Copyright (c) 2021 ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +# Workaround for not being able to have commas in macro arguments +DT_COMPAT_BFLB_BL_UART := bflb,bl-uart + +config UART_BFLB + bool "Bouffalo Lab serial driver" + default $(dt_compat_enabled,$(DT_COMPAT_BFLB_BL_UART)) + depends on SOC_FAMILY_BFLB + 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..045068fd009e3 --- /dev/null +++ b/drivers/serial/uart_bflb.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2021, ATL Electronics + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT bflb_bl_uart + +/** + * @brief UART driver for Bouffalo Lab MCU family. + */ +#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 bl_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_bl_init(const struct device *dev) +{ + const struct bl_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_bl_poll_in(const struct device *dev, unsigned char *c) +{ + const struct bl_config *cfg = dev->config; + + return UART_ReceiveData(cfg->periph_id, (uint8_t *)c, 1); +} + +static void uart_bl_poll_out(const struct device *dev, unsigned char c) +{ + const struct bl_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_bl_pm_control(const struct device *dev, + enum pm_device_action action) +{ + const struct bl_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 const struct uart_driver_api uart_bl_driver_api = { + .poll_in = uart_bl_poll_in, + .poll_out = uart_bl_poll_out, +}; + +#define BL_UART_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n) \ + static const struct bl_config bl_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_bl_init, \ + uart_bl_pm_control, \ + NULL, \ + &bl_uart##n##_config, PRE_KERNEL_1, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ + &uart_bl_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(BL_UART_INIT) diff --git a/dts/bindings/serial/bflb,bl-uart.yaml b/dts/bindings/serial/bflb,bl-uart.yaml new file mode 100644 index 0000000000000..d20d2f1ef01ea --- /dev/null +++ b/dts/bindings/serial/bflb,bl-uart.yaml @@ -0,0 +1,17 @@ +# Copyright (c) 2021, ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +description: Bouffalo Lab UART + +compatible: "bflb,bl-uart" + +include: [uart-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + peripheral-id: + type: int + description: peripheral ID + required: true diff --git a/dts/riscv/bouffalolab/bl6.dtsi b/dts/riscv/bouffalolab/bl6.dtsi index d03037ddb9f0d..9662f1f7e93d9 100644 --- a/dts/riscv/bouffalolab/bl6.dtsi +++ b/dts/riscv/bouffalolab/bl6.dtsi @@ -119,5 +119,24 @@ #address-cells = <1>; #size-cells = <0>; }; + + uart0: uart@4000a000 { + compatible = "bflb,bl-uart"; + reg = <0x4000a000 0x100>; + peripheral-id = <0>; + interrupts = <29 0>; + interrupt-parent = <&ictrl>; + status = "disabled"; + label = "uart_0"; + }; + uart1: uart@4000a100 { + compatible = "bflb,bl-uart"; + reg = <0x4000a100 0x100>; + peripheral-id = <1>; + interrupts = <30 0>; + interrupt-parent = <&ictrl>; + status = "disabled"; + label = "uart_1"; + }; }; }; diff --git a/modules/hal_bouffalolab/include/bflb_uart.h b/modules/hal_bouffalolab/include/bflb_uart.h new file mode 100644 index 0000000000000..8173f21df4b5b --- /dev/null +++ b/modules/hal_bouffalolab/include/bflb_uart.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2021 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_BL6 + #include +#endif + +#endif /* ZEPHYR_HAL_BFLB_UART_H_ */ From b18af6e15220e0bbb46e8be22f864a0eac9086d1 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Sat, 7 Aug 2021 15:04:13 -0300 Subject: [PATCH 08/10] scripts: runner: Introduce blflash runner Add Bouffalo Lab ISP console flash runner. This tool enable bootloader to flash devices using serial port. The blflash Rust tool can be found at https://github.com/spacemeowx2/blflash Signed-off-by: Gerson Fernando Budke --- CODEOWNERS | 1 + boards/common/blflash.board.cmake | 4 ++ scripts/west_commands/runners/__init__.py | 1 + scripts/west_commands/runners/blflash.py | 59 +++++++++++++++++++++ scripts/west_commands/tests/test_imports.py | 1 + 5 files changed, 66 insertions(+) create mode 100644 boards/common/blflash.board.cmake create mode 100644 scripts/west_commands/runners/blflash.py diff --git a/CODEOWNERS b/CODEOWNERS index df2803d80e08f..b741a0e8c9240 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -645,6 +645,7 @@ /scripts/twister @nashif /scripts/series-push-hook.sh @erwango /scripts/west_commands/ @mbolivar-nordic +/scripts/west_commands/runners/blflash.py @mbolivar-nordic @nandojve /scripts/west-commands.yml @mbolivar-nordic /scripts/zephyr_module.py @tejlmand /scripts/uf2conv.py @petejohanson diff --git a/boards/common/blflash.board.cmake b/boards/common/blflash.board.cmake new file mode 100644 index 0000000000000..5c99a2b913bf1 --- /dev/null +++ b/boards/common/blflash.board.cmake @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_set_flasher_ifnset(blflash) +board_finalize_runner_args(blflash) diff --git a/scripts/west_commands/runners/__init__.py b/scripts/west_commands/runners/__init__.py index eb4816a9e1d12..167b59fd8f248 100644 --- a/scripts/west_commands/runners/__init__.py +++ b/scripts/west_commands/runners/__init__.py @@ -26,6 +26,7 @@ def _import_runner_module(runner_name): _names = [ 'blackmagicprobe', + 'blflash', 'bossac', 'canopen_program', 'dediprog', diff --git a/scripts/west_commands/runners/blflash.py b/scripts/west_commands/runners/blflash.py new file mode 100644 index 0000000000000..0fca611b2f6e9 --- /dev/null +++ b/scripts/west_commands/runners/blflash.py @@ -0,0 +1,59 @@ +# Copyright (c) 2021 Gerson Fernando Budke +# +# SPDX-License-Identifier: Apache-2.0 + +'''Bouffalo Lab flash tool (blflash) runner for serial boot ROM''' + +from runners.core import ZephyrBinaryRunner, RunnerCaps + +DEFAULT_BLFLASH_PORT = '/dev/ttyUSB0' +DEFAULT_BLFLASH_SPEED = '2000000' + +class BlFlashBinaryRunner(ZephyrBinaryRunner): + '''Runner front-end for blflash.''' + + def __init__(self, cfg, blflash='blflash', + port=DEFAULT_BLFLASH_PORT, + speed=DEFAULT_BLFLASH_SPEED): + super().__init__(cfg) + self.blflash = blflash + self.port = port + self.speed = speed + + @classmethod + def name(cls): + return 'blflash' + + @classmethod + def capabilities(cls): + return RunnerCaps(commands={'flash'}) + + @classmethod + def do_add_parser(cls, parser): + parser.add_argument('--blflash', default='blflash', + help='path to blflash, default is blflash') + parser.add_argument('--port', default=DEFAULT_BLFLASH_PORT, + help='serial port to use, default is ' + + str(DEFAULT_BLFLASH_PORT)) + parser.add_argument('--speed', default=DEFAULT_BLFLASH_SPEED, + help='serial port speed to use, default is ' + + DEFAULT_BLFLASH_SPEED) + + @classmethod + def do_create(cls, cfg, args): + return BlFlashBinaryRunner(cfg, + blflash=args.blflash, + port=args.port, + speed=args.speed) + + def do_run(self, command, **kwargs): + self.require(self.blflash) + self.ensure_output('bin') + + cmd_flash = [self.blflash, + 'flash', + self.cfg.bin_file, + '-p', self.port, + '-b', self.speed] + + self.check_call(cmd_flash) diff --git a/scripts/west_commands/tests/test_imports.py b/scripts/west_commands/tests/test_imports.py index 079f6b7607ae6..8aeba86eb85ac 100644 --- a/scripts/west_commands/tests/test_imports.py +++ b/scripts/west_commands/tests/test_imports.py @@ -16,6 +16,7 @@ def test_runner_imports(): # Please keep this sorted alphabetically. expected = set(('arc-nsim', 'blackmagicprobe', + 'blflash', 'bossac', 'canopen', 'dediprog', From 6bfee9c85ccaed4086a5623486e823e120fb7e58 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Mon, 2 Aug 2021 23:10:31 -0300 Subject: [PATCH 09/10] boards: riscv: Introduce dt_bl10_devkit Add initial version. Signed-off-by: Gerson Fernando Budke --- boards/riscv/dt_bl10_devkit/Kconfig.board | 8 + boards/riscv/dt_bl10_devkit/Kconfig.defconfig | 11 ++ boards/riscv/dt_bl10_devkit/board.cmake | 4 + .../dt_bl10_devkit/doc/img/dt_bl10_devkit.jpg | Bin 0 -> 53776 bytes boards/riscv/dt_bl10_devkit/doc/index.rst | 187 ++++++++++++++++++ .../dt_bl10_devkit-pinctrl.dtsi | 28 +++ .../riscv/dt_bl10_devkit/dt_bl10_devkit.dts | 50 +++++ .../riscv/dt_bl10_devkit/dt_bl10_devkit.yaml | 14 ++ .../dt_bl10_devkit/dt_bl10_devkit_defconfig | 10 + 9 files changed, 312 insertions(+) create mode 100644 boards/riscv/dt_bl10_devkit/Kconfig.board create mode 100644 boards/riscv/dt_bl10_devkit/Kconfig.defconfig create mode 100644 boards/riscv/dt_bl10_devkit/board.cmake create mode 100644 boards/riscv/dt_bl10_devkit/doc/img/dt_bl10_devkit.jpg create mode 100644 boards/riscv/dt_bl10_devkit/doc/index.rst create mode 100644 boards/riscv/dt_bl10_devkit/dt_bl10_devkit-pinctrl.dtsi create mode 100644 boards/riscv/dt_bl10_devkit/dt_bl10_devkit.dts create mode 100644 boards/riscv/dt_bl10_devkit/dt_bl10_devkit.yaml create mode 100644 boards/riscv/dt_bl10_devkit/dt_bl10_devkit_defconfig diff --git a/boards/riscv/dt_bl10_devkit/Kconfig.board b/boards/riscv/dt_bl10_devkit/Kconfig.board new file mode 100644 index 0000000000000..98544424fe7ce --- /dev/null +++ b/boards/riscv/dt_bl10_devkit/Kconfig.board @@ -0,0 +1,8 @@ +# Bouffalo Lab BL602 DevKit +# +# Copyright (c) 2021 ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_DT_BL10_DEVKIT + bool "2.4GHz Wi-Fi and BLE coexistence Module Development Kit" + depends on SOC_PART_NUMBER_BL602C20Q2I diff --git a/boards/riscv/dt_bl10_devkit/Kconfig.defconfig b/boards/riscv/dt_bl10_devkit/Kconfig.defconfig new file mode 100644 index 0000000000000..2bf6b64554aaf --- /dev/null +++ b/boards/riscv/dt_bl10_devkit/Kconfig.defconfig @@ -0,0 +1,11 @@ +# Bouffalo Lab BL602 DevKit +# +# Copyright (c) 2021 ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_DT_BL10_DEVKIT + +config BOARD + default "dt_bl10_devkit" + +endif # BOARD_DT_BL10_DEVKIT diff --git a/boards/riscv/dt_bl10_devkit/board.cmake b/boards/riscv/dt_bl10_devkit/board.cmake new file mode 100644 index 0000000000000..02dcd61a225d6 --- /dev/null +++ b/boards/riscv/dt_bl10_devkit/board.cmake @@ -0,0 +1,4 @@ +# Copyright (c) 2021, ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/boards/common/blflash.board.cmake) diff --git a/boards/riscv/dt_bl10_devkit/doc/img/dt_bl10_devkit.jpg b/boards/riscv/dt_bl10_devkit/doc/img/dt_bl10_devkit.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6dbe75cd8146dc566050956cc4d01a136117ef0e GIT binary patch literal 53776 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 literal 0 HcmV?d00001 diff --git a/boards/riscv/dt_bl10_devkit/doc/index.rst b/boards/riscv/dt_bl10_devkit/doc/index.rst new file mode 100644 index 0000000000000..f3952c3cce588 --- /dev/null +++ b/boards/riscv/dt_bl10_devkit/doc/index.rst @@ -0,0 +1,187 @@ +.. _dt_bl10_devkit: + +BL602 Development Board +####################### + +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). + +.. image:: img/dt_bl10_devkit.jpg + :width: 450px + :align: center + :alt: dt_bl10_devkit + +Hardware +******** + +For more information about the Bouffalo Lab BL-602 MCU: + +- `Bouffalo Lab BL602 MCU Website`_ +- `Bouffalo Lab BL602 MCU Datasheet`_ +- `Bouffalo Lab Development Zone`_ +- `dt_bl10_devkit Schematic`_ +- `Doctors of Intelligence & Technology (www.doiting.com)`_ +- `The RISC-V BL602 Book`_ + +Supported Features +================== + +The board configuration supports the following hardware features: + ++-----------+------------+-----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=======================+ +| MTIMER | on-chip | RISC-V Machine Timer | ++-----------+------------+-----------------------+ +| PINCTRL | on-chip | pin muxing | ++-----------+------------+-----------------------+ +| UART | on-chip | serial port-polling | ++-----------+------------+-----------------------+ + + +The default configurations can be found in the Kconfig +:zephyr_file:`boards/risc/dt_bl10_devkit/dt_bl10_devkit_defconfig`. + +System Clock +============ + +The BL602 Development Board is configured to run at max speed (192MHz). + +Serial Port +=========== + +The dt_bl10_devkit_ 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 +************************* + +BL Flash tool +============= + +The BL-602 have a ROM bootloader that allows user flash device by serial port. +There are some tools available at internet and this will describe one of them. +The below guide was created based on RISC-V BL602 Book, chapter 3 +`Flashing Firmware to BL602`_. + +#. `Install Rustup`_ + +#. Clone blflash rust version + + .. code-block:: console + + $ git clone --recursive https://github.com/spacemeowx2/blflash + +#. Build blflash + + .. code-block:: console + + $ cd blflash + $ cargo build --release + +#. Install blflash. The recommended use is copy to home folder + + .. code-block:: console + + $ cp blflash ~/bin/ + +#. Test + + .. code-block:: console + + $ blflash -V + + It will print blflash version + + .. code-block:: console + + $ blflash 0.3.3 + +Samples +======= + +#. Build the Zephyr kernel and the :ref:`hello_world` sample application: + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: dt_bl10_devkit + :goals: build + :compact: + +#. To flash an image using blflash runner: + + #. Press D8 button + + #. Press and release EN button + + #. Release D8 button + + .. code-block:: console + + west flash -r blflash + +#. Run your favorite terminal program to listen for output. Under Linux the + terminal should be :code:`/dev/ttyUSB0`. For example: + + .. code-block:: console + + $ minicom -D /dev/ttyUSB0 -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 EN button + + .. code-block:: console + + *** Booting Zephyr OS build zephyr-v2.6.0-1729-g22140c728537 *** + Hello World! dt_bl10_devkit + +Congratulations, you have `dt_bl10_devkit`_ configured and running Zephyr. + + +.. _Bouffalo Lab BL602 MCU Website: + https://www.bouffalolab.com/bl602 + +.. _Bouffalo Lab BL602 MCU Datasheet: + https://github.com/bouffalolab/bl_docs/tree/main/BL602_DS/en + +.. _Bouffalo Lab Development Zone: + https://dev.bouffalolab.com/home?id=guest + +.. _dt_bl10_devkit Schematic: + https://github.com/SmartArduino/Doiting_BL/blob/master/board/DT-BL10%20User%20Mannual.pdf + +.. _Doctors of Intelligence & Technology (www.doiting.com): + https://www.doiting.com + +.. _Install Rustup: + https://rustup.rs/ + +.. _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/riscv/dt_bl10_devkit/dt_bl10_devkit-pinctrl.dtsi b/boards/riscv/dt_bl10_devkit/dt_bl10_devkit-pinctrl.dtsi new file mode 100644 index 0000000000000..6ec019a59d821 --- /dev/null +++ b/boards/riscv/dt_bl10_devkit/dt_bl10_devkit-pinctrl.dtsi @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021, ATL Electronics + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + uart0_default: uart0_default { + pins1 { + bflb,pins = , + ; + bflb,signals = , + ; + bias-pull-up; + input-schmitt-enable; + }; + }; + uart0_sleep: uart0_sleep { + pins1 { + bflb,pins = , + ; + bflb,signals = , + ; + bias-high-impedance; + }; + }; +}; diff --git a/boards/riscv/dt_bl10_devkit/dt_bl10_devkit.dts b/boards/riscv/dt_bl10_devkit/dt_bl10_devkit.dts new file mode 100644 index 0000000000000..70e0e37b78eb3 --- /dev/null +++ b/boards/riscv/dt_bl10_devkit/dt_bl10_devkit.dts @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021, ATL Electronics + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "dt_bl10_devkit-pinctrl.dtsi" + +/ { + model = "2.4GHz Wi-Fi and BLE coexistence Module Development Kit"; + compatible = "bflb,bl602"; + + chosen { + zephyr,flash = &flash0; + zephyr,itcm = &itcm; + zephyr,dtcm = &dtcm; + zephyr,sram = &sram0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + }; +}; + +&cpu0 { + clock-frequency = <160000000>; +}; + +&spi1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x4000b000 0x1000 0x23000000 0xc00000>; + flash0: flash@0 { + compatible = "issi,is25lp128", "jedec,spi-nor"; + size = <134217728>; + label = "FLASH0"; + jedec-id = [96 60 18]; + reg = <0>; + // Dummy entry + spi-max-frequency = <0>; + }; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + + pinctrl-0 = <&uart0_default>; + pinctrl-1 = <&uart0_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/boards/riscv/dt_bl10_devkit/dt_bl10_devkit.yaml b/boards/riscv/dt_bl10_devkit/dt_bl10_devkit.yaml new file mode 100644 index 0000000000000..f2c752513ee7d --- /dev/null +++ b/boards/riscv/dt_bl10_devkit/dt_bl10_devkit.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2021, ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +identifier: dt_bl10_devkit +name: 2.4GHz Wi-Fi and BLE coexistence Module Development Kit +type: mcu +arch: riscv32 +ram: 64 +toolchain: + - zephyr +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/riscv/dt_bl10_devkit/dt_bl10_devkit_defconfig b/boards/riscv/dt_bl10_devkit/dt_bl10_devkit_defconfig new file mode 100644 index 0000000000000..576174027c6d0 --- /dev/null +++ b/boards/riscv/dt_bl10_devkit/dt_bl10_devkit_defconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2021, ATL Electronics +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_BL6=y +CONFIG_SOC_PART_NUMBER_BL602C20Q2I=y +CONFIG_BOARD_DT_BL10_DEVKIT=y + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y From 6896bf977b5cd220d763af7db3d7e2109cade246 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Wed, 13 Oct 2021 22:16:53 -0300 Subject: [PATCH 10/10] CODEOWNERS: Add nandojve for bouffalolab Add myself as codeowners for Bouffalo Lab related files. Signed-off-by: Gerson Fernando Budke --- CODEOWNERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CODEOWNERS b/CODEOWNERS index b741a0e8c9240..cc97b3f4155b2 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -71,6 +71,7 @@ /arch/riscv/ @kgugala @pgielda /soc/posix/ @aescolar @daor-oti /soc/riscv/ @kgugala @pgielda +/soc/riscv/bouffalolab/ @nandojve /soc/riscv/openisa*/ @dleach02 /soc/riscv/riscv-privilege/andes_v5/ @cwshu @Teng-Shih-Wei /soc/riscv/riscv-privilege/neorv32/ @henrikbrixandersen @@ -149,6 +150,7 @@ /boards/posix/ @aescolar @daor-oti /boards/posix/nrf52_bsim/ @aescolar @wopu-ot /boards/riscv/ @kgugala @pgielda +/boards/riscv/dt_bl10_devkit/ @nandojve /boards/riscv/rv32m1_vega/ @dleach02 /boards/riscv/beaglev_starlight_jh7100/ @rajnesh-kanwal /boards/riscv/adp_xc7k_ae350/ @cwshu @Teng-Shih-Wei @@ -188,6 +190,7 @@ /drivers/debug/ @nashif /drivers/*/*sam4l* @nandojve /drivers/*/*cc13xx_cc26xx* @bwitherspoon +/drivers/*/*bflb* @nandojve /drivers/*/*gd32* @nandojve /drivers/*/*litex* @mateusz-holenko @kgugala @pgielda /drivers/*/*mcux* @mmahadevan108 @dleach02 @@ -298,6 +301,7 @@ /drivers/pcie/ @dcpleung @nashif @jhedberg /drivers/peci/ @albertofloyd @franciscomunoz @scottwcpg /drivers/pinctrl/ @gmarull +/drivers/pinctrl/*bflb* @nandojve /drivers/pinmux/*b91* @yurvyn /drivers/pinmux/*hsdk* @iriszzw /drivers/pinmux/*it8xxx2* @ite @@ -429,6 +433,7 @@ /dts/arm/silabs/efr32mg21* @l-alfred /dts/arm/silabs/efr32fg13* @yonsch /dts/riscv/ @kgugala @pgielda +/dts/riscv/bouffalolab/ @nandojve /dts/riscv/it8xxx2.dtsi @ite /dts/riscv/microsemi-miv.dtsi @galak /dts/riscv/rv32m1* @dleach02 @@ -453,6 +458,7 @@ /dts/bindings/modem/*hl7800.yaml @LairdCP/zephyr /dts/bindings/serial/ns16550.yaml @dcpleung @nashif /dts/bindings/wifi/*esp-at.yaml @mniestroj +/dts/bindings/*/*bflb* @nandojve /dts/bindings/*/*gd32* @nandojve /dts/bindings/*/*npcx* @MulinChao @WealianLiao @ChiHuaL /dts/bindings/*/*psoc6* @nandojve @@ -530,6 +536,7 @@ /include/dt-bindings/clock/kinetis_scg.h @henrikbrixandersen /include/dt-bindings/ethernet/xlnx_gem.h @ibirnbaum /include/dt-bindings/pcie/ @dcpleung +/include/dt-bindings/pinctrl/*bflb* @nandojve /include/dt-bindings/pwm/*it8xxx2* @RuibinChang /include/dt-bindings/usb/usb.h @galak /include/drivers/emul.h @sjg20 @@ -576,6 +583,7 @@ /lib/libc/arcmwdt/ @abrodkin @ruuddw @evgeniy-paltsev /modules/ @nashif /modules/canopennode/ @henrikbrixandersen +/modules/hal_bouffalolab/ @nandojve /modules/mbedtls/ @ceolin @d3zd3z /modules/hal_gigadevice/ @nandojve /modules/trusted-firmware-m/ @ioannisg @microbuilder