diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index aa97c9e0ae2..7ff54af2931 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -21,6 +21,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_ALTERA uart_altera.c) zephyr_library_sources_ifdef(CONFIG_UART_ALTERA_JTAG uart_altera_jtag.c) zephyr_library_sources_ifdef(CONFIG_UART_APBUART uart_apbuart.c) zephyr_library_sources_ifdef(CONFIG_UART_BCM2711_MU uart_bcm2711.c) +zephyr_library_sources_ifdef(CONFIG_UART_BFLB uart_bflb.c) zephyr_library_sources_ifdef(CONFIG_UART_BT uart_bt.c) zephyr_library_sources_ifdef(CONFIG_UART_CC13XX_CC26XX uart_cc13xx_cc26xx.c) zephyr_library_sources_ifdef(CONFIG_UART_CC23X0 uart_cc23x0.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index ed68ef1904e..f1cb441dcb1 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -162,6 +162,7 @@ rsource "Kconfig.altera_jtag" rsource "Kconfig.apbuart" rsource "Kconfig.b91" rsource "Kconfig.bcm2711" +rsource "Kconfig.bflb" rsource "Kconfig.bt" rsource "Kconfig.cc13xx_cc26xx" rsource "Kconfig.cc23x0" diff --git a/drivers/serial/Kconfig.bflb b/drivers/serial/Kconfig.bflb new file mode 100644 index 00000000000..52df95d521f --- /dev/null +++ b/drivers/serial/Kconfig.bflb @@ -0,0 +1,12 @@ +# Copyright (c) 2021-2025 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +config UART_BFLB + bool "Bouffalo Lab serial driver" + depends on DT_HAS_BFLB_UART_ENABLED + select PINCTRL + select SERIAL_HAS_DRIVER + select USE_BFLB_UART + help + This option enables the UART driver for Bouffalo Lab SoC family. diff --git a/drivers/serial/uart_bflb.c b/drivers/serial/uart_bflb.c new file mode 100644 index 00000000000..504e0f82a5a --- /dev/null +++ b/drivers/serial/uart_bflb.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2021-2025 ATL Electronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT bflb_uart + +/** + * @brief UART driver for Bouffalo Lab MCU family. + */ +#include +#include +#include +#include + +#include +#include +#include + +#define UART_CTS_FLOWCONTROL_ENABLE (0) +#define UART_RTS_FLOWCONTROL_ENABLE (0) +#define UART_MSB_FIRST_ENABLE (0) +#define UART_DEFAULT_RTO_TIMEOUT (255) +#define UART_CLOCK_DIV (0) + +struct blfb_config { + const struct pinctrl_dev_config *pinctrl_cfg; + uint32_t periph_id; + UART_CFG_Type uart_cfg; + UART_FifoCfg_Type fifo_cfg; +}; + +static int uart_blfb_init(const struct device *dev) +{ + const struct blfb_config *cfg = dev->config; + + pinctrl_apply_state(cfg->pinctrl_cfg, PINCTRL_STATE_DEFAULT); + + GLB_Set_UART_CLK(1, HBN_UART_CLK_160M, UART_CLOCK_DIV); + + UART_IntMask(cfg->periph_id, UART_INT_ALL, 1); + UART_Disable(cfg->periph_id, UART_TXRX); + + UART_Init(cfg->periph_id, (UART_CFG_Type *)&cfg->uart_cfg); + UART_TxFreeRun(cfg->periph_id, 1); + UART_SetRxTimeoutValue(cfg->periph_id, UART_DEFAULT_RTO_TIMEOUT); + UART_FifoConfig(cfg->periph_id, (UART_FifoCfg_Type *)&cfg->fifo_cfg); + UART_Enable(cfg->periph_id, UART_TXRX); + + return 0; +} + +static int uart_blfb_poll_in(const struct device *dev, unsigned char *c) +{ + const struct blfb_config *cfg = dev->config; + + return UART_ReceiveData(cfg->periph_id, (uint8_t *)c, 1) ? 0 : -1; +} + +static void uart_blfb_poll_out(const struct device *dev, unsigned char c) +{ + const struct blfb_config *cfg = dev->config; + + while (UART_GetTxFifoCount(cfg->periph_id) == 0) { + ; + } + + (void)UART_SendData(cfg->periph_id, (uint8_t *)&c, 1); +} + +#ifdef CONFIG_PM_DEVICE +static int uart_blfb_pm_control(const struct device *dev, + enum pm_device_action action) +{ + const struct blfb_config *cfg = dev->config; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + (void)pinctrl_apply_state(cfg->pinctrl_cfg, PINCTRL_STATE_DEFAULT); + UART_Enable(cfg->periph_id, UART_TXRX); + break; + case PM_DEVICE_ACTION_SUSPEND: + if (pinctrl_apply_state(cfg->pinctrl_cfg, PINCTRL_STATE_SLEEP)) { + return -ENOTSUP; + } + UART_Disable(cfg->periph_id, UART_TXRX); + break; + default: + return -ENOTSUP; + } + + return 0; +} +#endif /* CONFIG_PM_DEVICE */ + +static DEVICE_API(uart, uart_blfb_driver_api) = { + .poll_in = uart_blfb_poll_in, + .poll_out = uart_blfb_poll_out, +}; + +#define BLFB_UART_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + PM_DEVICE_DT_INST_DEFINE(n, uart_blfb_pm_control); \ + static const struct blfb_config blfb_uart##n##_config = { \ + .pinctrl_cfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .periph_id = DT_INST_PROP(n, peripheral_id), \ + \ + .uart_cfg.baudRate = DT_INST_PROP(n, current_speed), \ + .uart_cfg.dataBits = UART_DATABITS_8, \ + .uart_cfg.stopBits = UART_STOPBITS_1, \ + .uart_cfg.parity = UART_PARITY_NONE, \ + .uart_cfg.uartClk = SOC_BOUFFALOLAB_BL_PLL160_FREQ_HZ, \ + .uart_cfg.ctsFlowControl = UART_CTS_FLOWCONTROL_ENABLE, \ + .uart_cfg.rtsSoftwareControl = UART_RTS_FLOWCONTROL_ENABLE, \ + .uart_cfg.byteBitInverse = UART_MSB_FIRST_ENABLE, \ + \ + .fifo_cfg.txFifoDmaThreshold = 1, \ + .fifo_cfg.rxFifoDmaThreshold = 1, \ + .fifo_cfg.txFifoDmaEnable = 0, \ + .fifo_cfg.rxFifoDmaEnable = 0, \ + }; \ + DEVICE_DT_INST_DEFINE(n, &uart_blfb_init, \ + PM_DEVICE_DT_INST_GET(n), \ + NULL, \ + &blfb_uart##n##_config, PRE_KERNEL_1, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ + &uart_blfb_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(BLFB_UART_INIT) diff --git a/dts/bindings/serial/bflb,uart.yaml b/dts/bindings/serial/bflb,uart.yaml new file mode 100644 index 00000000000..d844435568f --- /dev/null +++ b/dts/bindings/serial/bflb,uart.yaml @@ -0,0 +1,20 @@ +# Copyright (c) 2021-2025 ATL Electronics +# +# SPDX-License-Identifier: Apache-2.0 + +description: Bouffalo Lab UART + +compatible: "bflb,uart" + +include: + - name: uart-controller.yaml + - name: pinctrl-device.yaml + +properties: + reg: + required: true + + peripheral-id: + type: int + description: peripheral ID + required: true diff --git a/dts/riscv/bouffalolab/bl60x.dtsi b/dts/riscv/bouffalolab/bl60x.dtsi index cf6d73df611..7ec4c90802f 100644 --- a/dts/riscv/bouffalolab/bl60x.dtsi +++ b/dts/riscv/bouffalolab/bl60x.dtsi @@ -83,6 +83,24 @@ }; }; + uart0: uart@4000a000 { + compatible = "bflb,uart"; + reg = <0x4000a000 0x100>; + peripheral-id = <0>; + interrupts = <29 0>; + interrupt-parent = <&ictrl>; + status = "disabled"; + }; + + uart1: uart@4000a100 { + compatible = "bflb,uart"; + reg = <0x4000a100 0x100>; + peripheral-id = <1>; + interrupts = <30 0>; + interrupt-parent = <&ictrl>; + status = "disabled"; + }; + spi0: spi@4000a200 { compatible = "bflb,spi"; reg = <0x4000a200 0x100>; diff --git a/modules/hal_bouffalolab/include/bflb_uart.h b/modules/hal_bouffalolab/include/bflb_uart.h new file mode 100644 index 00000000000..d2675527297 --- /dev/null +++ b/modules/hal_bouffalolab/include/bflb_uart.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2021-2025 Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_HAL_BFLB_UART_H_ +#define ZEPHYR_HAL_BFLB_UART_H_ + +#ifdef CONFIG_SOC_SERIES_BL60X +#include +#endif + +#endif /* ZEPHYR_HAL_BFLB_UART_H_ */