diff --git a/boards/aithinker/ai_wb2_12f/ai_wb2_12f.dts b/boards/aithinker/ai_wb2_12f/ai_wb2_12f.dts index d3e99d7a45fa..7cecb09a1a04 100644 --- a/boards/aithinker/ai_wb2_12f/ai_wb2_12f.dts +++ b/boards/aithinker/ai_wb2_12f/ai_wb2_12f.dts @@ -6,7 +6,7 @@ /dts-v1/; -#include +#include #include "ai_wb2_12f-pinctrl.dtsi" / { @@ -15,6 +15,7 @@ chosen { zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; zephyr,itcm = &itcm; zephyr,dtcm = &dtcm; zephyr,sram = &sram0; @@ -27,18 +28,30 @@ clock-frequency = ; }; -&spi1 { - #address-cells = <1>; - #size-cells = <0>; - reg = <0x4000b000 0x1000 0x23000000 0x400000>; - - flash0: flash@0 { - compatible = "zb,25vq32", "jedec,spi-nor"; - status = "disabled"; - size = ; - jedec-id = [5e 40 16]; - reg = <0>; - spi-max-frequency = ; +&flashctrl { + flash0: flash@23000000 { + compatible = "soc-nv-flash", "zb,25vq32"; + reg = <0x23000000 (0x400000 - 0x2000)>; + write-block-size = <256>; + erase-block-size = ; + /* jedec-id = [5e 40 16]; */ + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + slot0_partition: partition@0 { + label = "image-0"; + reg = <0x00000000 0x00100000>; + read-only; + }; + + storage_partition: partition@100000 { + label = "storage"; + reg = <0x00100000 (0x300000 - 0x2000)>; + }; + }; }; }; diff --git a/boards/aithinker/ai_wb2_12f/support/bl60x.cfg b/boards/aithinker/ai_wb2_12f/support/bl60x.cfg index fcabb2c4e7c0..25b8f1dc798c 100644 --- a/boards/aithinker/ai_wb2_12f/support/bl60x.cfg +++ b/boards/aithinker/ai_wb2_12f/support/bl60x.cfg @@ -38,23 +38,22 @@ echo "Ready for Remote Connections" $_TARGETNAME.0 configure -event reset-assert-pre { echo "reset-assert-pre" - adapter speed 100 + adapter speed 400 } $_TARGETNAME.0 configure -event reset-deassert-post { echo "reset-deassert-post" - adapter speed 100 + adapter speed 400 - reg mstatus 0x7800 - reg mie 0x0 -# reg pc 0x23000000 + reg mstatus 0x0 + reg pc 0x21000000 } $_TARGETNAME.0 configure -event reset-init { echo "reset-init" - adapter speed 3000 + adapter speed 400 } $_TARGETNAME.0 configure -event gdb-attach { diff --git a/boards/aithinker/ai_wb2_12f/support/openocd.cfg b/boards/aithinker/ai_wb2_12f/support/openocd.cfg index 9a3b1644e96d..ea9daa4d8b52 100644 --- a/boards/aithinker/ai_wb2_12f/support/openocd.cfg +++ b/boards/aithinker/ai_wb2_12f/support/openocd.cfg @@ -2,4 +2,4 @@ interface cmsis-dap -adapter speed 1000 +adapter speed 400 diff --git a/boards/bflb/bl60x/bl604e_iot_dvk/bl604e_iot_dvk.dts b/boards/bflb/bl60x/bl604e_iot_dvk/bl604e_iot_dvk.dts index 87e986cbfe4e..c559df972188 100644 --- a/boards/bflb/bl60x/bl604e_iot_dvk/bl604e_iot_dvk.dts +++ b/boards/bflb/bl60x/bl604e_iot_dvk/bl604e_iot_dvk.dts @@ -6,7 +6,7 @@ /dts-v1/; -#include +#include #include "bl604e_iot_dvk-pinctrl.dtsi" / { @@ -15,6 +15,7 @@ chosen { zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; zephyr,itcm = &itcm; zephyr,dtcm = &dtcm; zephyr,sram = &sram0; @@ -27,18 +28,30 @@ 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 = ; +&flashctrl { + flash0: flash@23000000 { + compatible = "soc-nv-flash", "issi,is25lp128"; + reg = <0x23000000 (0x1000000 - 0x2000)>; + write-block-size = <256>; + erase-block-size = ; + /* jedec-id = [96 60 18]; */ + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + slot0_partition: partition@0 { + label = "image-0"; + reg = <0x00000000 0x100000>; + read-only; + }; + + storage_partition: partition@100000 { + label = "storage"; + reg = <0x00100000 (0xF00000 - 0x2000)>; + }; + }; }; }; diff --git a/boards/doiting/dt_bl10_devkit/dt_bl10_devkit.dts b/boards/doiting/dt_bl10_devkit/dt_bl10_devkit.dts index 34ce0613736a..c765bdb2525a 100644 --- a/boards/doiting/dt_bl10_devkit/dt_bl10_devkit.dts +++ b/boards/doiting/dt_bl10_devkit/dt_bl10_devkit.dts @@ -14,6 +14,7 @@ chosen { zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; zephyr,itcm = &itcm; zephyr,dtcm = &dtcm; zephyr,sram = &sram0; @@ -26,18 +27,30 @@ 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 = ; +&flashctrl { + flash0: flash@23000000 { + compatible = "soc-nv-flash", "issi,is25lp128"; + reg = <0x23000000 (0x1000000 - 0x2000)>; + write-block-size = <256>; + erase-block-size = ; + /* jedec-id = [96 60 18]; */ + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + slot0_partition: partition@0 { + label = "image-0"; + reg = <0x00000000 0x100000>; + read-only; + }; + + storage_partition: partition@100000 { + label = "storage"; + reg = <0x00100000 (0xF00000 - 0x2000)>; + }; + }; }; }; diff --git a/drivers/clock_control/clock_control_bl60x.c b/drivers/clock_control/clock_control_bl60x.c index eb81b04eec88..271b073359b3 100644 --- a/drivers/clock_control/clock_control_bl60x.c +++ b/drivers/clock_control/clock_control_bl60x.c @@ -91,7 +91,7 @@ const static uint32_t clock_control_bl60x_crystal_SDMIN_table[5] = { static inline void clock_control_bl60x_clock_settle(void) { - __asm__ volatile(".rept 15 ; nop ; .endr"); + __asm__ volatile(".rept 20 ; nop ; .endr"); } /* 32 Mhz Oscillator: 0 @@ -848,6 +848,8 @@ static int clock_control_bl60x_init(const struct device *dev) clock_control_bl60x_peripheral_clock_init(); + clock_control_bl60x_clock_settle(); + irq_unlock(key); return 0; diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index 839c288c394e..e81490132a48 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -10,7 +10,6 @@ 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_MPS4 pinctrl_arm_mps4.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) @@ -58,3 +57,8 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_WCH_20X_30X_AFIO pinctrl_wch_20x_30x zephyr_library_sources_ifdef(CONFIG_PINCTRL_WCH_00X_AFIO pinctrl_wch_00x_afio.c) add_subdirectory(renesas) + +if (CONFIG_PINCTRL_BFLB) + zephyr_library_sources(pinctrl_bflb.c) + zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_BL60X pinctrl_bflb_bl60x_70x.c) +endif() diff --git a/drivers/pinctrl/pinctrl_bflb.c b/drivers/pinctrl/pinctrl_bflb.c index b40a555e4440..f41055c0794d 100644 --- a/drivers/pinctrl/pinctrl_bflb.c +++ b/drivers/pinctrl/pinctrl_bflb.c @@ -6,40 +6,35 @@ #include #include -#include -#include -#include -/* clang-format off */ +#include -int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, - uintptr_t reg) +#if defined(CONFIG_SOC_SERIES_BL60X) +#include +#else +#error "Unsupported Platform" +#endif + +void pinctrl_bflb_configure_uart(uint8_t pin, uint8_t func); +void pinctrl_bflb_init_pin(pinctrl_soc_pin_t pin); + +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]) - ); + + if ((BFLB_PINMUX_GET_FUN(pins[i]) & BFLB_PINMUX_FUN_MASK) + == BFLB_PINMUX_FUN_INST_uart0) { + pinctrl_bflb_configure_uart(BFLB_PINMUX_GET_PIN(pins[i]), + BFLB_PINMUX_GET_SIGNAL(pins[i]) + 4 * BFLB_PINMUX_GET_INST(pins[i])); } - GLB_GPIO_Init(&pincfg); + /* gpio init*/ + pinctrl_bflb_init_pin(pins[i]); } return 0; } - -/* clang-format on */ diff --git a/drivers/pinctrl/pinctrl_bflb_bl60x_70x.c b/drivers/pinctrl/pinctrl_bflb_bl60x_70x.c new file mode 100644 index 000000000000..f804e24d7d65 --- /dev/null +++ b/drivers/pinctrl/pinctrl_bflb_bl60x_70x.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include +#include + +#if defined(CONFIG_SOC_SERIES_BL60X) +#include +#else +#error "Unsupported Platform" +#endif + +void pinctrl_bflb_configure_uart(uint8_t pin, uint8_t func) +{ + /* uart func for BL602 and BL702 Only*/ + uint32_t regval; + uint8_t sig; + uint8_t sig_pos; + + regval = sys_read32(GLB_BASE + GLB_UART_SIG_SEL_0_OFFSET); + + sig = pin % 8; + sig_pos = sig << 2; + + regval &= (~(0x0f << sig_pos)); + regval |= (func << sig_pos); + + for (uint8_t i = 0; i < 8; i++) { + /* reset other sigs which are the same with uart_func */ + sig_pos = i << 2; + if (((regval & (0x0f << sig_pos)) == (func << sig_pos)) && (i != sig) && (func != +0x0f)) { + regval &= (~(0x0f << sig_pos)); + regval |= (0x0f << sig_pos); + } + } + + sys_write32(regval, GLB_BASE + GLB_UART_SIG_SEL_0_OFFSET); +} + +void pinctrl_bflb_init_pin(pinctrl_soc_pin_t pin) +{ + uint8_t drive; + uint8_t function; + uint16_t mode; + uint32_t regval; + uint8_t real_pin; + uint8_t is_odd = 0; + uint32_t cfg = 0; + uint32_t cfg_address; + + real_pin = BFLB_PINMUX_GET_PIN(pin); + function = BFLB_PINMUX_GET_FUN(pin); + mode = BFLB_PINMUX_GET_MODE(pin); + drive = BFLB_PINMUX_GET_DRIVER_STRENGTH(pin); + + /* Disable output anyway */ + regval = sys_read32(GLB_BASE + GLB_GPIO_CFGCTL34_OFFSET + ((real_pin >> 5) << 2)); + regval &= ~(1 << (real_pin & 0x1f)); + sys_write32(regval, GLB_BASE + GLB_GPIO_CFGCTL34_OFFSET + ((real_pin >> 5) << 2)); + + is_odd = real_pin & 1; + + cfg_address = GLB_BASE + GLB_GPIO_CFGCTL0_OFFSET + (real_pin / 2 * 4); + cfg = sys_read32(cfg_address); + cfg &= ~(0xffff << (16 * is_odd)); + + regval = sys_read32(GLB_BASE + GLB_GPIO_CFGCTL34_OFFSET + ((real_pin >> 5) << 2)); + + if (mode == BFLB_PINMUX_MODE_analog) { + regval &= ~(1 << (real_pin & 0x1f)); + function = 10; + } else if (mode == BFLB_PINMUX_MODE_periph) { + cfg |= (1 << (is_odd * 16 + 0)); + regval &= ~(1 << (real_pin & 0x1f)); + } else { + function = 11; + + if (mode == BFLB_PINMUX_MODE_input) { + cfg |= (1 << (is_odd * 16 + 0)); + } + + if (mode == BFLB_PINMUX_MODE_output) { + regval |= (1 << (real_pin & 0x1f)); + } + } + + sys_write32(regval, GLB_BASE + GLB_GPIO_CFGCTL34_OFFSET + ((real_pin >> 5) << 2)); + + uint8_t pull_up = BFLB_PINMUX_GET_PULL_UP(pin); + uint8_t pull_down = BFLB_PINMUX_GET_PULL_DOWN(pin); + + if (pull_up) { + cfg |= (1 << (is_odd * 16 + 4)); + } else if (pull_down) { + cfg |= (1 << (is_odd * 16 + 5)); + } else { + } + + if (BFLB_PINMUX_GET_SMT(pin)) { + cfg |= (1 << (is_odd * 16 + 1)); + } + + cfg |= (drive << (is_odd * 16 + 2)); + cfg |= (function << (is_odd * 16 + 8)); + sys_write32(cfg, cfg_address); +} diff --git a/drivers/serial/Kconfig.bflb b/drivers/serial/Kconfig.bflb index cc67bf07f6cf..0577b173063d 100644 --- a/drivers/serial/Kconfig.bflb +++ b/drivers/serial/Kconfig.bflb @@ -9,6 +9,5 @@ config UART_BFLB select PINCTRL select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT - 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 index 30b56df978ff..a24e962822a3 100644 --- a/drivers/serial/uart_bflb.c +++ b/drivers/serial/uart_bflb.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2021-2025 ATL Electronics + * Copyright (c) 2024-2025, MASSDRIVER EI (massdriver.space) * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,28 +10,39 @@ /** * @brief UART driver for Bouffalo Lab MCU family. */ + #include #include #include +#include +#include +#include #include + +#include + + #include +#include +#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 bflb_config { - uint32_t *reg; - const struct pinctrl_dev_config *pinctrl_cfg; - uint32_t periph_id; - UART_CFG_Type uart_cfg; - UART_FifoCfg_Type fifo_cfg; + const struct pinctrl_dev_config *pincfg; + uint32_t baudrate; + uint8_t direction; + uint8_t data_bits; + uint8_t stop_bits; + uint8_t parity; + uint8_t bit_order; + uint8_t flow_ctrl; + uint8_t tx_fifo_threshold; + uint8_t rx_fifo_threshold; + uint32_t base_reg; #ifdef CONFIG_UART_INTERRUPT_DRIVEN uart_irq_config_func_t irq_config_func; #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ @@ -43,88 +55,100 @@ struct bflb_data { #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ }; -static int uart_bflb_init(const struct device *dev) +static void uart_bflb_enabled(const struct device *dev, uint32_t enable) { const struct bflb_config *cfg = dev->config; + uint32_t rxt = 0; + uint32_t txt = 0; - 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); - -#ifdef CONFIG_UART_INTERRUPT_DRIVEN - cfg->irq_config_func(dev); -#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + if (enable > 1) { + enable = 1; + } - return 0; + txt = sys_read32(cfg->base_reg + UART_UTX_CONFIG_OFFSET); + txt = (txt & ~UART_CR_UTX_EN) | enable; + rxt = sys_read32(cfg->base_reg + UART_URX_CONFIG_OFFSET); + rxt = (rxt & ~UART_CR_URX_EN) | enable; + sys_write32(rxt, cfg->base_reg + UART_URX_CONFIG_OFFSET); + sys_write32(txt, cfg->base_reg + UART_UTX_CONFIG_OFFSET); } -static int uart_bflb_poll_in(const struct device *dev, unsigned char *c) +static uint32_t uart_bflb_get_clock(void) { - const struct bflb_config *cfg = dev->config; - - return UART_ReceiveData(cfg->periph_id, (uint8_t *)c, 1) ? 0 : -1; + uint32_t uart_divider = 0; + uint32_t uclk; + const struct device *clock_ctrl = DEVICE_DT_GET_ANY(bflb_clock_controller); + +#if defined(CONFIG_SOC_SERIES_BL60X) + uart_divider = sys_read32(GLB_BASE + GLB_CLK_CFG2_OFFSET); + uart_divider = (uart_divider & GLB_UART_CLK_DIV_MSK) >> GLB_UART_CLK_DIV_POS; + clock_control_get_rate(clock_ctrl, (void *)BFLB_CLKID_CLK_ROOT, &uclk); +#else + uart_divider = sys_read32(GLB_BASE + GLB_UART_CFG0_OFFSET); + uart_divider = (uart_divider & GLB_UART_CLK_DIV_MSK) >> GLB_UART_CLK_DIV_POS; + clock_control_get_rate(clock_ctrl, (void *)BFLB_CLKID_CLK_BCLK, &uclk); +#endif + + return uclk / (uart_divider + 1); } -static void uart_bflb_poll_out(const struct device *dev, unsigned char c) -{ - const struct bflb_config *cfg = dev->config; - - while (UART_GetTxFifoCount(cfg->periph_id) == 0) { - ; - } - - (void)UART_SendData(cfg->periph_id, (uint8_t *)&c, 1); -} #ifdef CONFIG_UART_INTERRUPT_DRIVEN + static int uart_bflb_err_check(const struct device *dev) { const struct bflb_config *const cfg = dev->config; - uint32_t status = BL_RD_REG(cfg->reg, UART_INT_STS); - uint32_t clear_mask = 0; + uint32_t status = 0; + uint32_t tmp = 0; int errors = 0; - if (status & BIT(UART_INT_RX_FER)) { - clear_mask |= BIT(UART_INT_RX_FER); + status = sys_read32(cfg->base_reg + UART_INT_STS_OFFSET); + tmp = sys_read32(cfg->base_reg + UART_INT_CLEAR_OFFSET); + if (status & UART_URX_FER_INT) { errors |= UART_ERROR_OVERRUN; } - if (status & BIT(UART_INT_TX_FER)) { - clear_mask |= BIT(UART_INT_TX_FER); - + if (status & UART_UTX_FER_INT) { errors |= UART_ERROR_OVERRUN; } - if (status & BIT(UART_INT_PCE)) { - clear_mask |= BIT(UART_INT_PCE); + if (status & UART_URX_PCE_INT) { + tmp |= UART_CR_URX_PCE_CLR; errors |= UART_ERROR_PARITY; } - if (clear_mask != 0) { - BL_WR_REG(cfg->reg, UART_INT_CLEAR, clear_mask); - } + sys_write32(tmp, cfg->base_reg + UART_INT_CLEAR_OFFSET); return errors; } +int uart_bflb_irq_tx_ready(const struct device *dev) +{ + const struct bflb_config *const cfg = dev->config; + uint32_t tmp = 0; + + tmp = sys_read32(cfg->base_reg + UART_FIFO_CONFIG_1_OFFSET); + return (tmp & UART_TX_FIFO_CNT_MASK) > 0; +} + +int uart_bflb_irq_rx_ready(const struct device *dev) +{ + const struct bflb_config *const cfg = dev->config; + uint32_t tmp = 0; + + tmp = sys_read32(cfg->base_reg + UART_FIFO_CONFIG_1_OFFSET); + return (tmp & UART_RX_FIFO_CNT_MASK) > 0; +} + int uart_bflb_fifo_fill(const struct device *dev, const uint8_t *tx_data, int len) { const struct bflb_config *const cfg = dev->config; uint8_t num_tx = 0U; - while ((len - num_tx > 0) && (UART_GetTxFifoCount(cfg->periph_id) > 0)) { - BL_WR_BYTE(cfg->reg + UART_FIFO_WDATA_OFFSET, tx_data[num_tx++]); + while (num_tx < len && uart_bflb_irq_tx_ready(dev) > 0) { + sys_write32(tx_data[num_tx++], cfg->base_reg + UART_FIFO_WDATA_OFFSET); } return num_tx; @@ -135,8 +159,8 @@ int uart_bflb_fifo_read(const struct device *dev, uint8_t *rx_data, const int si const struct bflb_config *const cfg = dev->config; uint8_t num_rx = 0U; - while ((size - num_rx > 0) && (UART_GetRxFifoCount(cfg->periph_id) > 0)) { - rx_data[num_rx++] = BL_RD_BYTE(cfg->reg + UART_FIFO_RDATA_OFFSET); + while ((num_rx < size) && uart_bflb_irq_rx_ready(dev) > 0) { + rx_data[num_rx++] = sys_read32(cfg->base_reg + UART_FIFO_RDATA_OFFSET); } return num_rx; @@ -145,82 +169,93 @@ int uart_bflb_fifo_read(const struct device *dev, uint8_t *rx_data, const int si void uart_bflb_irq_tx_enable(const struct device *dev) { const struct bflb_config *const cfg = dev->config; + uint32_t tmp = 0; - UART_IntMask(cfg->periph_id, UART_INT_TX_FIFO_REQ, 1); + tmp = sys_read32(cfg->base_reg + UART_INT_MASK_OFFSET); + tmp = tmp & ~UART_CR_UTX_FIFO_MASK; + sys_write32(tmp, cfg->base_reg + UART_INT_MASK_OFFSET); } void uart_bflb_irq_tx_disable(const struct device *dev) { const struct bflb_config *const cfg = dev->config; + uint32_t tmp = 0; - UART_IntMask(cfg->periph_id, UART_INT_TX_FIFO_REQ, 0); + tmp = sys_read32(cfg->base_reg + UART_INT_MASK_OFFSET); + tmp = tmp | UART_CR_UTX_FIFO_MASK; + sys_write32(tmp, cfg->base_reg + UART_INT_MASK_OFFSET); } -int uart_bflb_irq_tx_ready(const struct device *dev) -{ - const struct bflb_config *const cfg = dev->config; - uint32_t maskVal = BL_RD_REG(cfg->reg, UART_INT_MASK); - - return (UART_GetTxFifoCount(cfg->periph_id) > 0) - && BL_IS_REG_BIT_SET(maskVal, UART_CR_UTX_FIFO_MASK); -} int uart_bflb_irq_tx_complete(const struct device *dev) { const struct bflb_config *const cfg = dev->config; + uint32_t tmp; - return !UART_GetTxBusBusyStatus(cfg->periph_id); + tmp = sys_read32(cfg->base_reg + UART_STATUS_OFFSET); + if (tmp & UART_STS_UTX_BUS_BUSY) { + return 0; + } + + tmp = sys_read32(cfg->base_reg + UART_FIFO_CONFIG_1_OFFSET); + if ((tmp & UART_TX_FIFO_CNT_MASK) >= cfg->tx_fifo_threshold) { + return 1; + } + return 0; } void uart_bflb_irq_rx_enable(const struct device *dev) { const struct bflb_config *const cfg = dev->config; + uint32_t tmp = 0; - UART_IntMask(cfg->periph_id, UART_INT_RX_FIFO_REQ, 1); + tmp = sys_read32(cfg->base_reg + UART_INT_MASK_OFFSET); + tmp = tmp & ~UART_CR_URX_FIFO_MASK; + sys_write32(tmp, cfg->base_reg + UART_INT_MASK_OFFSET); } void uart_bflb_irq_rx_disable(const struct device *dev) { const struct bflb_config *const cfg = dev->config; + uint32_t tmp = 0; - UART_IntMask(cfg->periph_id, UART_INT_RX_FIFO_REQ, 0); -} - -int uart_bflb_irq_rx_ready(const struct device *dev) -{ - const struct bflb_config *const cfg = dev->config; - - return UART_GetRxFifoCount(cfg->periph_id) > 0; + tmp = sys_read32(cfg->base_reg + UART_INT_MASK_OFFSET); + tmp = tmp | UART_CR_URX_FIFO_MASK; + sys_write32(tmp, cfg->base_reg + UART_INT_MASK_OFFSET); } void uart_bflb_irq_err_enable(const struct device *dev) { const struct bflb_config *const cfg = dev->config; + uint32_t tmp = 0; - UART_IntMask(cfg->periph_id, UART_INT_PCE - | UART_INT_TX_FER - | UART_INT_RX_FER, 1); + tmp = sys_read32(cfg->base_reg + UART_INT_MASK_OFFSET); + tmp = tmp & ~UART_CR_URX_PCE_MASK; + tmp = tmp & ~UART_CR_UTX_FER_MASK; + tmp = tmp & ~UART_CR_URX_FER_MASK; + sys_write32(tmp, cfg->base_reg + UART_INT_MASK_OFFSET); } void uart_bflb_irq_err_disable(const struct device *dev) { const struct bflb_config *const cfg = dev->config; + uint32_t tmp = 0; - UART_IntMask(cfg->periph_id, UART_INT_PCE - | UART_INT_TX_FER - | UART_INT_RX_FER, 0); + tmp = sys_read32(cfg->base_reg + UART_INT_MASK_OFFSET); + tmp = tmp | UART_CR_URX_PCE_MASK; + tmp = tmp | UART_CR_UTX_FER_MASK; + tmp = tmp | UART_CR_URX_FER_MASK; + sys_write32(tmp, cfg->base_reg + UART_INT_MASK_OFFSET); } int uart_bflb_irq_is_pending(const struct device *dev) { const struct bflb_config *const cfg = dev->config; - uint32_t tmp = BL_RD_REG(cfg->reg, UART_INT_STS); - uint32_t maskVal = BL_RD_REG(cfg->reg, UART_INT_MASK); + uint32_t tmp = sys_read32(cfg->base_reg + UART_INT_STS_OFFSET); + uint32_t maskVal = sys_read32(cfg->base_reg + UART_INT_MASK_OFFSET); - return ((BL_IS_REG_BIT_SET(tmp, UART_URX_FIFO_INT) && - BL_IS_REG_BIT_SET(maskVal, UART_CR_URX_FIFO_MASK)) || - (BL_IS_REG_BIT_SET(tmp, UART_UTX_FIFO_INT) && - BL_IS_REG_BIT_SET(maskVal, UART_CR_UTX_FIFO_MASK))); + /* only first 8 bits are not reserved */ + return (((tmp & ~maskVal) & 0xFF) != 0 ? 1 : 0); } int uart_bflb_irq_update(const struct device *dev) @@ -243,32 +278,219 @@ void uart_bflb_irq_callback_set(const struct device *dev, static void uart_bflb_isr(const struct device *dev) { struct bflb_data *const data = dev->data; + const struct bflb_config *const cfg = dev->config; + uint32_t tmp = 0; if (data->user_cb) { data->user_cb(dev, data->user_data); } + /* clear interrupts that require ack*/ + tmp = sys_read32(cfg->base_reg + UART_INT_CLEAR_OFFSET); + tmp = tmp | UART_CR_URX_RTO_CLR; + sys_write32(tmp, cfg->base_reg + UART_INT_CLEAR_OFFSET); } #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +static int uart_bflb_configure(const struct device *dev) +{ + const struct bflb_config *cfg = dev->config; + uint32_t tx_cfg = 0; + uint32_t rx_cfg = 0; + uint32_t divider = 0; + uint32_t tmp = 0; + + divider = (uart_bflb_get_clock() * 10 / cfg->baudrate + 5) / 10; + if (divider >= 0xFFFF) { + divider = 0xFFFF - 1; + } + + uart_bflb_enabled(dev, 0); + + sys_write32(((divider - 1) << 0x10) | ((divider - 1) & 0xFFFF), cfg->base_reg ++ UART_BIT_PRD_OFFSET); + + + /* Configure Parity */ + tx_cfg = sys_read32(cfg->base_reg + UART_UTX_CONFIG_OFFSET); + rx_cfg = sys_read32(cfg->base_reg + UART_URX_CONFIG_OFFSET); + + switch (cfg->parity) { + case UART_PARITY_NONE: + tx_cfg &= ~UART_CR_UTX_PRT_EN; + rx_cfg &= ~UART_CR_URX_PRT_EN; + break; + case UART_PARITY_ODD: + tx_cfg |= UART_CR_UTX_PRT_EN; + tx_cfg |= UART_CR_UTX_PRT_SEL; + rx_cfg |= UART_CR_URX_PRT_EN; + rx_cfg |= UART_CR_URX_PRT_SEL; + break; + case UART_PARITY_EVEN: + tx_cfg |= UART_CR_UTX_PRT_EN; + tx_cfg &= ~UART_CR_UTX_PRT_SEL; + rx_cfg |= UART_CR_URX_PRT_EN; + rx_cfg &= ~UART_CR_URX_PRT_SEL; + break; + default: + break; + } + + /* Configure data bits */ + tx_cfg &= ~UART_CR_UTX_BIT_CNT_D_MASK; + tx_cfg |= (cfg->data_bits + 4) << UART_CR_UTX_BIT_CNT_D_SHIFT; + rx_cfg &= ~UART_CR_URX_BIT_CNT_D_MASK; + rx_cfg |= (cfg->data_bits + 4) << UART_CR_URX_BIT_CNT_D_SHIFT; + + /* Configure tx stop bits */ + tx_cfg &= ~UART_CR_UTX_BIT_CNT_P_MASK; + tx_cfg |= cfg->stop_bits << UART_CR_UTX_BIT_CNT_P_SHIFT; + + /* Configure tx cts flow control function */ + if (cfg->flow_ctrl & UART_FLOWCTRL_CTS) { + tx_cfg |= UART_CR_UTX_CTS_EN; + } else { + tx_cfg &= ~UART_CR_UTX_CTS_EN; + } + + /* disable de-glitch function */ + rx_cfg &= ~UART_CR_URX_DEG_EN; + + /* Write config */ + sys_write32(tx_cfg, cfg->base_reg + UART_UTX_CONFIG_OFFSET); + sys_write32(rx_cfg, cfg->base_reg + UART_URX_CONFIG_OFFSET); + + /* enable hardware control RTS */ + #if defined(CONFIG_SOC_SERIES_BL60X) + tmp = sys_read32(cfg->base_reg + UART_URX_CONFIG_OFFSET); + tmp &= ~UART_CR_URX_RTS_SW_MODE; + sys_write32(tmp, cfg->base_reg + UART_URX_CONFIG_OFFSET); + #else + tmp = sys_read32(cfg->base_reg + UART_SW_MODE_OFFSET); + tmp &= ~UART_CR_URX_RTS_SW_MODE; + sys_write32(tmp, cfg->base_reg + UART_SW_MODE_OFFSET); + #endif + + /* disable inversion */ + tmp = sys_read32(cfg->base_reg + UART_DATA_CONFIG_OFFSET); + tmp &= ~UART_CR_UART_BIT_INV; + sys_write32(tmp, cfg->base_reg + UART_DATA_CONFIG_OFFSET); + + + /* TX free run enable */ + tmp = sys_read32(cfg->base_reg + UART_UTX_CONFIG_OFFSET); + tmp |= UART_CR_UTX_FRM_EN; + sys_write32(tmp, cfg->base_reg + UART_UTX_CONFIG_OFFSET); + + + /* Configure FIFO thresholds */ + tmp = sys_read32(cfg->base_reg + UART_FIFO_CONFIG_1_OFFSET); + tmp &= ~UART_TX_FIFO_TH_MASK; + tmp &= ~UART_RX_FIFO_TH_MASK; + tmp |= (cfg->tx_fifo_threshold << UART_TX_FIFO_TH_SHIFT) & UART_TX_FIFO_TH_MASK; + tmp |= (cfg->rx_fifo_threshold << UART_RX_FIFO_TH_SHIFT) & UART_RX_FIFO_TH_MASK; + sys_write32(tmp, cfg->base_reg + UART_FIFO_CONFIG_1_OFFSET); + + /* Clear FIFO */ + tmp = sys_read32(cfg->base_reg + UART_FIFO_CONFIG_0_OFFSET); + tmp |= UART_TX_FIFO_CLR; + tmp |= UART_RX_FIFO_CLR; + tmp &= ~UART_DMA_TX_EN; + tmp &= ~UART_DMA_RX_EN; + sys_write32(tmp, cfg->base_reg + UART_FIFO_CONFIG_0_OFFSET); + + return 0; +} + +static int uart_bflb_init(const struct device *dev) +{ + const struct bflb_config *cfg = dev->config; + int rc = 0; + + pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT); + rc = uart_bflb_configure(dev); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + /* disable all irqs */ + sys_write32(0x0, cfg->base_reg + UART_INT_EN_OFFSET); + /* clear all IRQS */ + sys_write32(0xFF, cfg->base_reg + UART_INT_CLEAR_OFFSET); + /* mask all IRQs */ + sys_write32(0xFFFFFFFFU, cfg->base_reg + UART_INT_MASK_OFFSET); + /* unmask necessary irqs */ + uart_bflb_irq_rx_enable(dev); + uart_bflb_irq_err_enable(dev); + /* enable all irqs */ + sys_write32(0xFF, cfg->base_reg + UART_INT_EN_OFFSET); + cfg->irq_config_func(dev); +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + uart_bflb_enabled(dev, 1); + return rc; +} + +static int uart_bflb_poll_in(const struct device *dev, unsigned char *c) +{ + const struct bflb_config *cfg = dev->config; + + if ((sys_read32(cfg->base_reg + UART_FIFO_CONFIG_1_OFFSET) & UART_RX_FIFO_CNT_MASK) != 0) { + *c = sys_read8(cfg->base_reg + UART_FIFO_RDATA_OFFSET); + return 0; + } + + return -1; +} + +static void uart_bflb_poll_out(const struct device *dev, unsigned char c) +{ + const struct bflb_config *cfg = dev->config; + + while ((sys_read32(cfg->base_reg + UART_FIFO_CONFIG_1_OFFSET) & UART_TX_FIFO_CNT_MASK) == +0) { + } + sys_write8(c, cfg->base_reg + UART_FIFO_WDATA_OFFSET); +} + #ifdef CONFIG_PM_DEVICE static int uart_bflb_pm_control(const struct device *dev, - enum pm_device_action action) + enum pm_device_action action) { const struct bflb_config *cfg = dev->config; + uint32_t tmp; + int ret; switch (action) { case PM_DEVICE_ACTION_RESUME: - (void)pinctrl_apply_state(cfg->pinctrl_cfg, PINCTRL_STATE_DEFAULT); - UART_Enable(cfg->periph_id, UART_TXRX); + ret = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } + tmp = sys_read32(GLB_BASE + GLB_CGEN_CFG1_OFFSET); + /* Ungate clock to peripheral */ + if (cfg->base_reg == UART0_BASE) { + tmp |= (1 << 16); + } else if (cfg->base_reg == UART1_BASE) { + tmp |= (1 << 17); + } else { + return -EINVAL; + } + sys_write32(tmp, GLB_BASE + GLB_CGEN_CFG1_OFFSET); break; case PM_DEVICE_ACTION_SUSPEND: - if (pinctrl_apply_state(cfg->pinctrl_cfg, PINCTRL_STATE_SLEEP)) { - return -ENOTSUP; + ret = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_SLEEP); + if (ret < 0) { + return ret; } - UART_Disable(cfg->periph_id, UART_TXRX); + tmp = sys_read32(GLB_BASE + GLB_CGEN_CFG1_OFFSET); + /* Gate clock to peripheral */ + if (cfg->base_reg == UART0_BASE) { + tmp &= ~(1 << 16); + } else if (cfg->base_reg == UART1_BASE) { + tmp &= ~(1 << 17); + } else { + return -EINVAL; + } + sys_write32(tmp, GLB_BASE + GLB_CGEN_CFG1_OFFSET); break; default: - return -ENOTSUP; + return -EINVAL; } return 0; @@ -298,55 +520,54 @@ static const struct uart_driver_api uart_bflb_driver_api = { }; #ifdef CONFIG_UART_INTERRUPT_DRIVEN -#define BFLB_UART_IRQ_HANDLER_DECL(n) \ - static void uart_bflb_config_func_##n(const struct device *dev) \ - { \ - IRQ_CONNECT(DT_INST_IRQN(n), \ - DT_INST_IRQ(n, priority), \ - uart_bflb_isr, \ - DEVICE_DT_INST_GET(n), \ - 0); \ - irq_enable(DT_INST_IRQN(n)); \ +#define BFLB_UART_IRQ_HANDLER_DECL(instance) \ + static void uart_bflb_config_func_##instance(const struct device *dev); +#define BFLB_UART_IRQ_HANDLER_FUNC(instance) \ + .irq_config_func = uart_bflb_config_func_##instance +#define BFLB_UART_IRQ_HANDLER(instance) \ + static void uart_bflb_config_func_##instance(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(instance), \ + DT_INST_IRQ(instance, priority), \ + uart_bflb_isr, \ + DEVICE_DT_INST_GET(instance), \ + 0); \ + irq_enable(DT_INST_IRQN(instance)); \ } -#define BFLB_UART_IRQ_HANDLER_FUNC(n) \ - .irq_config_func = uart_bflb_config_func_##n, #else /* CONFIG_UART_INTERRUPT_DRIVEN */ -#define BFLB_UART_IRQ_HANDLER_DECL(n) -#define BFLB_UART_IRQ_HANDLER_FUNC(n) +#define BFLB_UART_IRQ_HANDLER_DECL(instance) +#define BFLB_UART_IRQ_HANDLER_FUNC(instance) +#define BFLB_UART_IRQ_HANDLER(instance) #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ -#define BFLB_UART_INIT(n) \ - PINCTRL_DT_INST_DEFINE(n); \ - PM_DEVICE_DT_INST_DEFINE(n, uart_bflb_pm_control); \ - BFLB_UART_IRQ_HANDLER_DECL(n); \ - \ - static struct bflb_data bflb_uart##n##_data; \ - static const struct bflb_config bflb_uart##n##_config = { \ - .reg = (uint32_t *)DT_INST_REG_ADDR(n), \ - .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, \ + +#define BFLB_UART_INIT(instance) \ + PINCTRL_DT_INST_DEFINE(instance); \ + PM_DEVICE_DT_INST_DEFINE(instance, uart_bflb_pm_control); \ + BFLB_UART_IRQ_HANDLER_DECL(instance) \ + static struct bflb_data uart##instance##_bflb_data; \ + static const struct bflb_config uart##instance##_bflb_config = { \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(instance), \ + .base_reg = DT_INST_REG_ADDR(instance), \ \ - BFLB_UART_IRQ_HANDLER_FUNC(n) \ + .baudrate = DT_INST_PROP(instance, current_speed), \ + .data_bits = UART_DATA_BITS_8, \ + .stop_bits = UART_STOP_BITS_1, \ + .parity = UART_PARITY_NONE, \ + .bit_order = UART_MSB_FIRST, \ + .flow_ctrl = UART_FLOWCTRL_NONE, \ + /* overflow interrupt threshold, size is 32 bytes*/ \ + .tx_fifo_threshold = 8, \ + .rx_fifo_threshold = 0, \ + BFLB_UART_IRQ_HANDLER_FUNC(instance) \ }; \ - DEVICE_DT_INST_DEFINE(n, &uart_bflb_init, \ - PM_DEVICE_DT_INST_GET(n), \ - &bflb_uart##n##_data, \ - &bflb_uart##n##_config, PRE_KERNEL_1, \ + DEVICE_DT_INST_DEFINE(instance, &uart_bflb_init, \ + PM_DEVICE_DT_INST_GET(instance), \ + &uart##instance##_bflb_data, \ + &uart##instance##_bflb_config, PRE_KERNEL_1, \ CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ - &uart_bflb_driver_api); + &uart_bflb_driver_api); \ + \ + BFLB_UART_IRQ_HANDLER(instance) DT_INST_FOREACH_STATUS_OKAY(BFLB_UART_INIT) diff --git a/drivers/syscon/syscon_bflb_efuse.c b/drivers/syscon/syscon_bflb_efuse.c index 6738b9fd2ce6..41280e6126e5 100644 --- a/drivers/syscon/syscon_bflb_efuse.c +++ b/drivers/syscon/syscon_bflb_efuse.c @@ -29,7 +29,7 @@ struct efuse_bflb_config { static inline void efuse_bflb_clock_settle(void) { - __asm__ volatile (".rept 15 ; nop ; .endr"); + __asm__ volatile (".rept 20 ; nop ; .endr"); } /* 32 Mhz Oscillator: 0 @@ -173,6 +173,9 @@ static void efuse_bflb_cache(const struct device *dev) const struct efuse_bflb_config *config = dev->config; uint32_t tmp; uint8_t old_clock_root; + uint32_t key; + + key = irq_lock(); tmp = sys_read32(HBN_BASE + HBN_GLB_OFFSET); old_clock_root = (tmp & HBN_ROOT_CLK_SEL_MSK) >> HBN_ROOT_CLK_SEL_POS; @@ -193,6 +196,8 @@ static void efuse_bflb_cache(const struct device *dev) efuse_bflb_set_root_clock(old_clock_root); efuse_bflb_clock_settle(); data->cached = true; + + irq_unlock(key); } static int efuse_bflb_read(const struct device *dev, uint16_t reg, uint32_t *val) diff --git a/dts/bindings/flash_controller/bflb,flash-controller.yaml b/dts/bindings/flash_controller/bflb,flash-controller.yaml new file mode 100644 index 000000000000..9e1abbeaf624 --- /dev/null +++ b/dts/bindings/flash_controller/bflb,flash-controller.yaml @@ -0,0 +1,5 @@ +description: Bouffalolab Flash Controller + +compatible: "bflb,flash-controller" + +include: flash-controller.yaml diff --git a/dts/bindings/interrupt-controller/sifive,legacy-clic.yaml b/dts/bindings/interrupt-controller/sifive,legacy-clic.yaml new file mode 100644 index 000000000000..a9464c34c739 --- /dev/null +++ b/dts/bindings/interrupt-controller/sifive,legacy-clic.yaml @@ -0,0 +1,20 @@ +# Copyright (c) 2025 MASSDRIVER EI (massdrive.space) +# SPDX-License-Identifier: Apache-2.0 + +description: Even Older RISC-V core local interrupt controller + it uses different offsets than the newer memory-mapped legacy CLIC + +compatible: "sifive,legacy-clic" + +include: [interrupt-controller.yaml, base.yaml] + +properties: + reg: + required: true + + "#interrupt-cells": + const: 2 + +interrupt-cells: + - irq + - priority diff --git a/dts/bindings/serial/bflb,uart.yaml b/dts/bindings/serial/bflb,uart.yaml index d844435568fb..9fa1580a071a 100644 --- a/dts/bindings/serial/bflb,uart.yaml +++ b/dts/bindings/serial/bflb,uart.yaml @@ -13,8 +13,3 @@ include: properties: reg: required: true - - peripheral-id: - type: int - description: peripheral ID - required: true diff --git a/dts/riscv/bflb/bl602.dtsi b/dts/riscv/bflb/bl602.dtsi new file mode 100644 index 000000000000..e9a3946a3762 --- /dev/null +++ b/dts/riscv/bflb/bl602.dtsi @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include diff --git a/dts/riscv/bflb/bl604.dtsi b/dts/riscv/bflb/bl604.dtsi new file mode 100644 index 000000000000..8f6564d00203 --- /dev/null +++ b/dts/riscv/bflb/bl604.dtsi @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include diff --git a/dts/riscv/bflb/bl60x.dtsi b/dts/riscv/bflb/bl60x.dtsi index e42e4a4fa6c5..7e5009eef928 100644 --- a/dts/riscv/bflb/bl60x.dtsi +++ b/dts/riscv/bflb/bl60x.dtsi @@ -7,8 +7,8 @@ #include #include -#include #include +#include #include / { @@ -48,7 +48,7 @@ clk_bclk: clk-bclk { #clock-cells = <0>; compatible = "bflb,bclk"; - divider = <2>; + divider = <4>; status = "okay"; }; }; @@ -82,7 +82,7 @@ ranges; clic: clic@2000000 { - compatible = "sifive,clint0"; + compatible = "sifive,legacy-clic"; reg = <0x2000000 0x10000>; #address-cells = <0>; #interrupt-cells = <2>; @@ -111,7 +111,7 @@ #size-cells = <1>; status = "okay"; - glb: gpio@40000000 { + gpio0: gpio@40000000 { compatible = "bflb,gpio"; reg = <0x40000000 0x1000>; #gpio-cells = <2>; @@ -119,8 +119,8 @@ status = "disabled"; gpio-controller; - interrupts = <1 0>; - interrupt-parent = <&ictrl>; + interrupts = <60 0>; + interrupt-parent = <&clic>; }; }; @@ -135,7 +135,6 @@ clock-names = "rc32m", "crystal", "root", "bclk", "pll_192", "pll_160", "pll_120", "pll_48"; - zephyr,deferred-init; }; efuse: efuse@40007000 { @@ -148,18 +147,16 @@ uart0: uart@4000a000 { compatible = "bflb,uart"; reg = <0x4000a000 0x100>; - peripheral-id = <0>; - interrupts = <29 0>; - interrupt-parent = <&ictrl>; + interrupts = <45 0>; + interrupt-parent = <&clic>; status = "disabled"; }; uart1: uart@4000a100 { compatible = "bflb,uart"; reg = <0x4000a100 0x100>; - peripheral-id = <1>; - interrupts = <30 0>; - interrupt-parent = <&ictrl>; + interrupts = <46 0>; + interrupt-parent = <&clic>; status = "disabled"; }; @@ -170,21 +167,19 @@ #size-cells = <0>; status = "disabled"; - peripheral-id = <0>; - interrupts = <27 0>; - interrupt-parent = <&ictrl>; + interrupts = <43 0>; + interrupt-parent = <&clic>; }; - spi1: spi@4000b000 { - compatible = "bflb,qspi"; + flashctrl: flash-controller@4000b000 { + compatible = "bflb,flash-controller"; reg = <0x4000b000 0x1000>; #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; status = "disabled"; - peripheral-id = <0>; - interrupts = <23 0>; - interrupt-parent = <&ictrl>; + interrupts = <39 0>; + interrupt-parent = <&clic>; }; retram: memory@40010000 { @@ -206,12 +201,7 @@ sram0: memory@42020000 { compatible = "mmio-sram"; - reg = <0x42020000 DT_SIZE_K(64)>; - }; - - sram1: memory@42030000 { - compatible = "mmio-sram"; - reg = <0x42030000 DT_SIZE_K(112)>; + reg = <0x42020000 DT_SIZE_K(176)>; }; }; }; diff --git a/include/zephyr/drivers/pinctrl/pinctrl_soc_bflb_common.h b/include/zephyr/drivers/pinctrl/pinctrl_soc_bflb_common.h index 7d7404ff75e5..b5013d469c4d 100644 --- a/include/zephyr/drivers/pinctrl/pinctrl_soc_bflb_common.h +++ b/include/zephyr/drivers/pinctrl/pinctrl_soc_bflb_common.h @@ -14,6 +14,7 @@ #include #include +#include /* clang-format off */ diff --git a/modules/hal_bouffalolab/CMakeLists.txt b/modules/hal_bouffalolab/CMakeLists.txt index e4b66aeafe62..fdbe58cb1498 100644 --- a/modules/hal_bouffalolab/CMakeLists.txt +++ b/modules/hal_bouffalolab/CMakeLists.txt @@ -1,55 +1,9 @@ # Copyright (c) 2021-2025 Gerson Fernando Budke +# Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) # # SPDX-License-Identifier: Apache-2.0 if(CONFIG_SOC_FAMILY_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) + zephyr_include_directories(${ZEPHYR_HAL_BOUFFALOLAB_MODULE_DIR}/include) + zephyr_include_directories(${ZEPHYR_HAL_BOUFFALOLAB_MODULE_DIR}/include/bouffalolab/${SOC_SERIES}) endif() # SOC_FAMILY_BFLB diff --git a/modules/hal_bouffalolab/Kconfig b/modules/hal_bouffalolab/Kconfig index c6c4469117b4..18ca0fc63f57 100644 --- a/modules/hal_bouffalolab/Kconfig +++ b/modules/hal_bouffalolab/Kconfig @@ -1,59 +1,7 @@ # Copyright (c) 2021-2025 Gerson Fernando Budke +# Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) # # SPDX-License-Identifier: Apache-2.0 config ZEPHYR_HAL_BOUFFALOLAB_MODULE bool - -config HAS_BFLB_HAL - bool - -if HAS_BFLB_HAL - -config USE_BFLB_ACOMP - bool - help - Enable BFLB Analog Comparator (ACOMP) HAL module driver - -config USE_BFLB_ADC - bool - help - Enable BFLB Analog-to-Digital Converter (ADC) HAL module driver - -config USE_BFLB_DAC - bool - help - Enable BFLB Digital-to-Analog Converter (DAC) HAL module driver - -config USE_BFLB_DMA - bool - help - Enable BFLB Direct Memory Access controller (DMA) HAL module driver - -config USE_BFLB_I2C - bool - help - Enable BFLB Inter-Integrated Circuit Interface (I2C) HAL module driver - -config USE_BFLB_IR - bool - help - Enable BFLB Infrared Remote controller (IR) HAL module driver - -config USE_BFLB_PWM - bool - help - Enable BFLB Pulse Width Modulation (PMU) HAL module driver - -config USE_BFLB_SPI - bool - help - Enable BFLB Serial Peripheral Interface(SPI) HAL module driver - -config USE_BFLB_UART - bool - help - Enable BFLB Universal Asynchronous Receiver/Transmitter (UART) - HAL module driver - -endif # HAS_BFLB_HAL diff --git a/modules/hal_bouffalolab/include/bflb_glb.h b/modules/hal_bouffalolab/include/bflb_glb.h deleted file mode 100644 index d8aff224df91..000000000000 --- a/modules/hal_bouffalolab/include/bflb_glb.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2021-2025 Gerson Fernando Budke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_HAL_BFLB_GLB_H_ -#define ZEPHYR_HAL_BFLB_GLB_H_ - -#ifdef CONFIG_SOC_SERIES_BL60X -#include -#endif - -#endif /* ZEPHYR_HAL_BFLB_GLB_H_ */ diff --git a/modules/hal_bouffalolab/include/bflb_gpio.h b/modules/hal_bouffalolab/include/bflb_gpio.h deleted file mode 100644 index 9ac0ca7bf1d7..000000000000 --- a/modules/hal_bouffalolab/include/bflb_gpio.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2021-2025 Gerson Fernando Budke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_HAL_BFLB_GPIO_H_ -#define ZEPHYR_HAL_BFLB_GPIO_H_ - -#ifdef CONFIG_SOC_SERIES_BL60X -#include -#endif - -#endif /* ZEPHYR_HAL_BFLB_GPIO_H_ */ diff --git a/modules/hal_bouffalolab/include/bflb_hbn.h b/modules/hal_bouffalolab/include/bflb_hbn.h deleted file mode 100644 index 1580dea3ffbe..000000000000 --- a/modules/hal_bouffalolab/include/bflb_hbn.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2021-2025 Gerson Fernando Budke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_HAL_BFLB_HBN_H_ -#define ZEPHYR_HAL_BFLB_HBN_H_ - -#ifdef CONFIG_SOC_SERIES_BL60X -#include -#endif - -#endif /* ZEPHYR_HAL_BFLB_HBN_H_ */ diff --git a/modules/hal_bouffalolab/include/bflb_pinctrl.h b/modules/hal_bouffalolab/include/bflb_pinctrl.h deleted file mode 100644 index 8226b01ec5dc..000000000000 --- a/modules/hal_bouffalolab/include/bflb_pinctrl.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2021-2025 Gerson Fernando Budke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_HAL_BFLB_PINCTRL_H_ -#define ZEPHYR_HAL_BFLB_PINCTRL_H_ - -#ifdef CONFIG_SOC_SERIES_BL60X -#include -#endif -#include - -#endif /* ZEPHYR_HAL_BFLB_PINCTRL_H_ */ diff --git a/modules/hal_bouffalolab/include/bflb_uart.h b/modules/hal_bouffalolab/include/bflb_uart.h deleted file mode 100644 index d2675527297e..000000000000 --- a/modules/hal_bouffalolab/include/bflb_uart.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2021-2025 Gerson Fernando Budke - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_HAL_BFLB_UART_H_ -#define ZEPHYR_HAL_BFLB_UART_H_ - -#ifdef CONFIG_SOC_SERIES_BL60X -#include -#endif - -#endif /* ZEPHYR_HAL_BFLB_UART_H_ */ diff --git a/modules/hal_bouffalolab/include/bl_ld_sections.h b/modules/hal_bouffalolab/include/bl_ld_sections.h deleted file mode 100644 index c1a9c11838f5..000000000000 --- a/modules/hal_bouffalolab/include/bl_ld_sections.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2021-2025 Gerson Fernando Budke - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef __BL_LD_SECTIONS_H -#define __BL_LD_SECTIONS_H - -#define ATTR_STRINGIFY(x) #x -#define ATTR_TOSTRING(x) ATTR_STRINGIFY(x) -#define ATTR_SECTION(x) __attribute__((section(x))) -#define ATTR_UNI_SYMBOL __FILE__ ATTR_TOSTRING(__LINE__) -#define ATTR_CLOCK_SECTION ATTR_SECTION(".itcm.sclock_rlt_code." ATTR_UNI_SYMBOL) -#define ATTR_CLOCK_CONST_SECTION ATTR_SECTION(".itcm.sclock_rlt_const." ATTR_UNI_SYMBOL) -#define ATTR_TCM_SECTION ATTR_SECTION(".itcm.code." ATTR_UNI_SYMBOL) -#define ATTR_TCM_CONST_SECTION ATTR_SECTION(".itcm.const." ATTR_UNI_SYMBOL) -#define ATTR_DTCM_SECTION ATTR_SECTION(".dtcm.data") -#define ATTR_HSRAM_SECTION ATTR_SECTION(".hsram_code") -#define ATTR_DMA_RAM_SECTION ATTR_SECTION(".system_ram") -#define ATTR_HBN_RAM_SECTION ATTR_SECTION(".hbn_ram_code") -#define ATTR_HBN_RAM_CONST_SECTION ATTR_SECTION(".hbn_ram_data") -#define ATTR_FALLTHROUGH() __attribute__((fallthrough)) -#define ATTR_USED __attribute__((__used__)) -#define ATTR_EALIGN(x) __aligned(size) - -#endif /* __BL_LD_SECTIONS_H */ diff --git a/soc/bflb/Kconfig b/soc/bflb/Kconfig index ae7fa94f4882..131808846d5d 100644 --- a/soc/bflb/Kconfig +++ b/soc/bflb/Kconfig @@ -2,9 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -config SOC_FAMILY_BFLB - select HAS_BFLB_HAL - if SOC_FAMILY_BFLB rsource "*/Kconfig" diff --git a/soc/bflb/bl60x/CMakeLists.txt b/soc/bflb/bl60x/CMakeLists.txt index c5437820149a..14b616bf76b0 100644 --- a/soc/bflb/bl60x/CMakeLists.txt +++ b/soc/bflb/bl60x/CMakeLists.txt @@ -1,13 +1,13 @@ # Copyright (c) 2021-2025 ATL Electronics +# Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) # # 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 "") -set(SOC_LINKER_SCRIPT - ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld - CACHE INTERNAL "" - ) +zephyr_code_relocate_ifdef(CONFIG_UART_BFLB LIBRARY drivers__serial LOCATION ITCM NOKEEP) +zephyr_code_relocate_ifdef(CONFIG_RISCV_MACHINE_TIMER LIBRARY drivers__timer LOCATION ITCM NOKEEP) +zephyr_code_relocate_ifdef(CONFIG_PINCTRL_BFLB LIBRARY drivers__pinctrl LOCATION ITCM NOKEEP) diff --git a/soc/bflb/bl60x/Kconfig b/soc/bflb/bl60x/Kconfig index c4102067669c..d0a0f226365c 100644 --- a/soc/bflb/bl60x/Kconfig +++ b/soc/bflb/bl60x/Kconfig @@ -1,20 +1,30 @@ # Copyright (c) 2021-2025 ATL Electronics +# Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) # # SPDX-License-Identifier: Apache-2.0 config SOC_SERIES_BL60X select ATOMIC_OPERATIONS_C select CLOCK_CONTROL + select CODE_DATA_RELOCATION select CPU_HAS_FPU + select FLOAT_HARD + select FPU + select GEN_IRQ_VECTOR_TABLE select INCLUDE_RESET_VECTOR select RISCV + select RISCV_HAS_CLIC select RISCV_MACHINE_TIMER + select RISCV_SOC_HAS_CUSTOM_IRQ_HANDLING + select RISCV_PRIVILEGED select RISCV_ISA_RV32I select RISCV_ISA_EXT_M select RISCV_ISA_EXT_A + select RISCV_ISA_EXT_F select RISCV_ISA_EXT_C select RISCV_ISA_EXT_ZICSR select RISCV_ISA_EXT_ZIFENCEI + select RISCV_VECTORED_MODE select SOC_EARLY_INIT_HOOK select SYSCON select XIP diff --git a/soc/bflb/bl60x/Kconfig.defconfig b/soc/bflb/bl60x/Kconfig.defconfig index 08653e3e458f..b7038e238f0e 100644 --- a/soc/bflb/bl60x/Kconfig.defconfig +++ b/soc/bflb/bl60x/Kconfig.defconfig @@ -4,7 +4,16 @@ if SOC_SERIES_BL60X +config SYS_CLOCK_TICKS_PER_SEC + default 1000 + config NUM_IRQS default 80 +config ARCH_SW_ISR_TABLE_ALIGN + default 64 + +config RISCV_MCAUSE_EXCEPTION_MASK + default 0x3FF + endif # SOC_SERIES_BL60X diff --git a/soc/bflb/bl60x/rodata.ld b/soc/bflb/bl60x/rodata.ld deleted file mode 100644 index 9cd607d3d99c..000000000000 --- a/soc/bflb/bl60x/rodata.ld +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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/bflb/bl60x/soc.c b/soc/bflb/bl60x/soc.c index 96f7bdfecc7a..852af2db7bde 100644 --- a/soc/bflb/bl60x/soc.c +++ b/soc/bflb/bl60x/soc.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2021-2025 ATL Electronics + * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,41 +10,36 @@ * @brief Bouffalo Lab RISC-V MCU series initialization code */ +#include #include #include #include -#include -#include #include +#include +#include +#include +#include -#define ROOT_FCLK_DIV (0) -#define ROOT_BCLK_DIV (1) -#define ROOT_UART_CLOCK_DIV (0) - +/* Set Embedded Flash Pullup */ 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); -} + uint32_t tmp = 0; -static uint32_t mtimer_get_clk_src_div(void) -{ - return ((SystemCoreClockGet() / (GLB_Get_BCLK_Div() + 1)) - / 1000 / 1000 - 1); -} + tmp = sys_read32(HBN_BASE + HBN_BOR_CFG_OFFSET); + /* borThreshold = 1 */ + tmp = (tmp & HBN_BOR_VTH_UMSK) | ((uint32_t)(1) << HBN_BOR_VTH_POS); + /* enablePorInBor true*/ + tmp = (tmp & HBN_BOR_SEL_UMSK) | ((uint32_t)(1) << HBN_BOR_SEL_POS); + /* enableBor true*/ + tmp = (tmp & HBN_PU_BOR_UMSK) | ((uint32_t)(1) << HBN_PU_BOR_POS); + sys_write32(tmp, HBN_BASE + HBN_BOR_CFG_OFFSET); -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); + /* enableBorInt false */ + tmp = sys_read32(HBN_BASE + HBN_IRQ_MODE_OFFSET); + tmp = tmp & HBN_IRQ_BOR_EN_UMSK; + sys_write32(tmp, HBN_BASE + HBN_IRQ_MODE_OFFSET); } void soc_early_init_hook(void) @@ -55,37 +51,37 @@ void soc_early_init_hook(void) 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); + tmp = sys_read32(HBN_BASE + HBN_IRQ_MODE_OFFSET); + /* "BL_CLR_REG_BIT" */ + tmp = tmp & HBN_REG_EN_HW_PU_PD_UMSK; + sys_write32(tmp, HBN_BASE + HBN_IRQ_MODE_OFFSET); - /* 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); + /* 'seam' 0kb, undocumented */ + tmp = sys_read32(GLB_BASE + GLB_SEAM_MISC_OFFSET); + tmp = (tmp & GLB_EM_SEL_UMSK) | ((uint32_t)(0) << GLB_EM_SEL_POS); + sys_write32(tmp, GLB_BASE + GLB_SEAM_MISC_OFFSET); /* Fix 26M xtal clkpll_sdmin */ - tmp = BL_RD_REG(PDS_BASE, PDS_CLKPLL_SDM); + tmp = sys_read32(PDS_BASE + PDS_CLKPLL_SDM_OFFSET); - 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); + if ((tmp & PDS_CLKPLL_SDMIN_MSK) == 0x49D39D) { + tmp = (tmp & PDS_CLKPLL_SDMIN_UMSK) | (uint32_t)(0x49D89E); + sys_write32(tmp, PDS_BASE + PDS_CLKPLL_SDM_OFFSET); } - /* 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); - + tmp = sys_read32(GLB_BASE + GLB_PARM_OFFSET); + /* GLB_UART_Sig_Swap_Set(UART_SIG_SWAP_NONE); + * no swap = 0 + * see bl602_glb.h for other possible values + */ + tmp = (tmp & GLB_UART_SWAP_SET_UMSK) | ((uint32_t)(0) << +GLB_UART_SWAP_SET_POS); /* 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); + tmp = (tmp & GLB_JTAG_SWAP_SET_UMSK) | ((uint32_t)(0) << +GLB_JTAG_SWAP_SET_POS); + sys_write32(tmp, GLB_BASE + GLB_PARM_OFFSET); /* CLear all interrupt */ p = (uint32_t *)(CLIC_HART0_ADDR + CLIC_INTIE); @@ -102,21 +98,6 @@ void soc_early_init_hook(void) /* 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/bflb/bl60x/soc.h b/soc/bflb/bl60x/soc.h index c24420593593..19cb5f75ea9d 100644 --- a/soc/bflb/bl60x/soc.h +++ b/soc/bflb/bl60x/soc.h @@ -15,35 +15,12 @@ #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/bflb/common/CMakeLists.txt b/soc/bflb/common/CMakeLists.txt index 2675509dd81d..17c2403f6189 100644 --- a/soc/bflb/common/CMakeLists.txt +++ b/soc/bflb/common/CMakeLists.txt @@ -4,8 +4,9 @@ zephyr_include_directories(.) +if(CONFIG_SOC_SERIES_BL60X) +zephyr_include_directories(e24) zephyr_sources( - soc_irq.S - soc_common_irq.c - vector.S - ) +e24/soc_irq_privileged.c +e24/intc_clic.S) +endif() diff --git a/soc/bflb/common/clic.h b/soc/bflb/common/e24/clic.h similarity index 74% rename from soc/bflb/common/clic.h rename to soc/bflb/common/e24/clic.h index 7328a46257c6..5c1d8c38ae56 100644 --- a/soc/bflb/common/clic.h +++ b/soc/bflb/common/e24/clic.h @@ -23,4 +23,12 @@ #define CLIC_INTCFG 0x800 #define CLIC_CFG 0xc00 +/* CLIC relative CSR number */ +#define CSR_MTVT (0x307) +#define CSR_MNXTI (0x345) +#define CSR_MINTTHRESH (0x347) +#define CSR_MISELECT (0x350) +#define CSR_MIREG (0x351) +#define CSR_MIREG2 (0x352) + #endif /* _SIFIVE_CLIC_H */ diff --git a/soc/bflb/common/e24/intc_clic.S b/soc/bflb/common/e24/intc_clic.S new file mode 100644 index 000000000000..418e332c67ab --- /dev/null +++ b/soc/bflb/common/e24/intc_clic.S @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2024 Baumer Electric AG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief Assembler-hooks specific to RISC-V Core Local Interrupt Controller + */ + +#include +#include "clic.h" + + +/* register-wide load/store based on lw/sw (XLEN = 32) */ + +.macro lr, rd, mem +lw \rd, \mem +.endm + +.macro sr, rs, mem +sw \rs, \mem +.endm + + +GTEXT(__soc_handle_irq) +/* + * In an CLIC, pending interrupts don't have to be cleared by hand. + * In vectored mode, interrupts are cleared automatically. + * In non-vectored mode, interrupts are cleared when writing the mnxti register (done in + * __soc_handle_all_irqs). + * Thus this function can directly return. + */ +SECTION_FUNC(exception.other, __soc_handle_irq) + ret + +GTEXT(__soc_handle_all_irqs) + +#ifdef CONFIG_TRACING +/* imports */ +GTEXT(sys_trace_isr_enter) +GTEXT(sys_trace_isr_exit) +#endif + +/* + * This function services and clears all pending interrupts for an CLIC in non-vectored mode. + */ +SECTION_FUNC(exception.other, __soc_handle_all_irqs) + addi sp, sp, -16 + sr ra, 0(sp) + + /* Read and clear mnxti to get highest current interrupt and enable interrupts. Will return + * original interrupt if no others appear. */ + csrrci a0, CSR_MNXTI, MSTATUS_IEN + beqz a0, irq_done /* Check if original interrupt vanished. */ + +irq_loop: + +#ifdef CONFIG_TRACING_ISR + call sys_trace_isr_enter +#endif + + /* Call corresponding registered function in _sw_isr_table. a0 is offset in pointer with + * the mtvt, sw irq table is 2-pointer wide -> shift by one. */ + csrr t0, CSR_MTVT + sub a0, a0, t0 + la t0, _sw_isr_table + slli a0, a0, (1) + add t0, t0, a0 + + /* Load argument in a0 register */ + lr a0, 0(t0) + + /* Load ISR function address in register t1 */ + lr t1, RV_REGSIZE(t0) + + /* Call ISR function */ + jalr ra, t1, 0 + +#ifdef CONFIG_TRACING_ISR + call sys_trace_isr_exit +#endif + + /* Read and clear mnxti to get highest current interrupt and enable interrupts. */ + csrrci a0, CSR_MNXTI, MSTATUS_IEN + bnez a0, irq_loop + +irq_done: + lr ra, 0(sp) + addi sp, sp, 16 + ret diff --git a/soc/bflb/common/e24/soc_irq_privileged.c b/soc/bflb/common/e24/soc_irq_privileged.c new file mode 100644 index 000000000000..370f0aac383f --- /dev/null +++ b/soc/bflb/common/e24/soc_irq_privileged.c @@ -0,0 +1,37 @@ +/* + * 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 "clic.h" + +#define CLIC_INTCFG_PADDING_BITS 4 + +void riscv_clic_irq_enable(unsigned int irq) +{ + *(volatile uint8_t *)(CLIC_HART0_ADDR + CLIC_INTIE + irq) = 1; +} + +void riscv_clic_irq_disable(unsigned int irq) +{ + *(volatile uint8_t *)(CLIC_HART0_ADDR + CLIC_INTIE + irq) = 0; +} + +void riscv_clic_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) +{ + *(volatile uint8_t *)(CLIC_HART0_ADDR + CLIC_INTCFG + irq) = + (prio & 0xF) << CLIC_INTCFG_PADDING_BITS; + ARG_UNUSED(flags); +} + +int riscv_clic_irq_is_enabled(unsigned int irq) +{ + return *(volatile uint8_t *)(CLIC_HART0_ADDR + CLIC_INTIE + irq); +} diff --git a/soc/bflb/common/soc_common.h b/soc/bflb/common/soc_common.h deleted file mode 100644 index 534f4175e24a..000000000000 --- a/soc/bflb/common/soc_common.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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/bflb/common/soc_common_irq.c b/soc/bflb/common/soc_common_irq.c deleted file mode 100644 index 82dacbcc4c6a..000000000000 --- a/soc/bflb/common/soc_common_irq.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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/bflb/common/soc_irq.S b/soc/bflb/common/soc_irq.S deleted file mode 100644 index b2fabf12035c..000000000000 --- a/soc/bflb/common/soc_irq.S +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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/bflb/common/vector.S b/soc/bflb/common/vector.S deleted file mode 100644 index 898856f36e8e..000000000000 --- a/soc/bflb/common/vector.S +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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