bflb: Make BL60x independant from SDK
Reorganize and update soc folder files for SDK-independance Reorganize and update hal_bouffalolab files for SDK-independance Reorganize and update soc dts files for SDK-independance Update serial and pinctrl driver files for SDK-independance Update ai_wb2_12f, bl604e_iot_dvk, and dt_bl10_dvk to new bl60x support and fixup openocd config of ai_wb2_12f Signed-off-by: Camille BAUD <mail@massdriver.space>
This commit is contained in:
committed by
Chris Friedt
parent
0c352f1b3a
commit
bdffc08279
@@ -6,7 +6,7 @@
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include <bflb/bl60x.dtsi>
|
||||
#include <bflb/bl602.dtsi>
|
||||
#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 = <DT_FREQ_M(192)>;
|
||||
};
|
||||
|
||||
&spi1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x4000b000 0x1000 0x23000000 0x400000>;
|
||||
&flashctrl {
|
||||
flash0: flash@23000000 {
|
||||
compatible = "soc-nv-flash", "zb,25vq32";
|
||||
reg = <0x23000000 (0x400000 - 0x2000)>;
|
||||
write-block-size = <256>;
|
||||
erase-block-size = <DT_SIZE_K(4)>;
|
||||
/* jedec-id = [5e 40 16]; */
|
||||
|
||||
flash0: flash@0 {
|
||||
compatible = "zb,25vq32", "jedec,spi-nor";
|
||||
status = "disabled";
|
||||
size = <DT_SIZE_M(128)>;
|
||||
jedec-id = [5e 40 16];
|
||||
reg = <0>;
|
||||
spi-max-frequency = <DT_FREQ_M(133)>;
|
||||
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)>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
interface cmsis-dap
|
||||
|
||||
adapter speed 1000
|
||||
adapter speed 400
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include <bflb/bl60x.dtsi>
|
||||
#include <bflb/bl604.dtsi>
|
||||
#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 = <DT_FREQ_M(192)>;
|
||||
};
|
||||
|
||||
&spi1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x4000b000 0x1000 0x23000000 0xc00000>;
|
||||
&flashctrl {
|
||||
flash0: flash@23000000 {
|
||||
compatible = "soc-nv-flash", "issi,is25lp128";
|
||||
reg = <0x23000000 (0x1000000 - 0x2000)>;
|
||||
write-block-size = <256>;
|
||||
erase-block-size = <DT_SIZE_K(4)>;
|
||||
/* jedec-id = [96 60 18]; */
|
||||
|
||||
flash0: flash@0 {
|
||||
compatible = "issi,is25lp128", "jedec,spi-nor";
|
||||
status = "disabled";
|
||||
size = <DT_SIZE_M(128)>;
|
||||
jedec-id = [96 60 18];
|
||||
reg = <0>;
|
||||
spi-max-frequency = <DT_FREQ_M(133)>;
|
||||
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)>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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 = <DT_FREQ_M(192)>;
|
||||
};
|
||||
|
||||
&spi1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x4000b000 0x1000 0x23000000 0xc00000>;
|
||||
&flashctrl {
|
||||
flash0: flash@23000000 {
|
||||
compatible = "soc-nv-flash", "issi,is25lp128";
|
||||
reg = <0x23000000 (0x1000000 - 0x2000)>;
|
||||
write-block-size = <256>;
|
||||
erase-block-size = <DT_SIZE_K(4)>;
|
||||
/* jedec-id = [96 60 18]; */
|
||||
|
||||
flash0: flash@0 {
|
||||
compatible = "issi,is25lp128", "jedec,spi-nor";
|
||||
status = "disabled";
|
||||
size = <DT_SIZE_M(128)>;
|
||||
jedec-id = [96 60 18];
|
||||
reg = <0>;
|
||||
spi-max-frequency = <DT_FREQ_M(133)>;
|
||||
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)>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -59,3 +58,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()
|
||||
|
||||
@@ -6,40 +6,35 @@
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/drivers/pinctrl.h>
|
||||
#include <bflb_pinctrl.h>
|
||||
#include <bflb_glb.h>
|
||||
#include <bflb_gpio.h>
|
||||
|
||||
/* clang-format off */
|
||||
#include <zephyr/dt-bindings/pinctrl/bflb-common-pinctrl.h>
|
||||
|
||||
int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
|
||||
uintptr_t reg)
|
||||
#if defined(CONFIG_SOC_SERIES_BL60X)
|
||||
#include <zephyr/dt-bindings/pinctrl/bl60x-pinctrl.h>
|
||||
#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 */
|
||||
|
||||
114
drivers/pinctrl/pinctrl_bflb_bl60x_70x.c
Normal file
114
drivers/pinctrl/pinctrl_bflb_bl60x_70x.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2025 MASSDRIVER EI (massdriver.space)
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/drivers/pinctrl.h>
|
||||
|
||||
#include <bflb_soc.h>
|
||||
#include <glb_reg.h>
|
||||
#include <zephyr/dt-bindings/pinctrl/bflb-common-pinctrl.h>
|
||||
|
||||
#if defined(CONFIG_SOC_SERIES_BL60X)
|
||||
#include <zephyr/dt-bindings/pinctrl/bl60x-pinctrl.h>
|
||||
#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);
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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 <zephyr/drivers/uart.h>
|
||||
#include <zephyr/drivers/pinctrl.h>
|
||||
#include <zephyr/pm/device.h>
|
||||
#include <zephyr/arch/common/sys_io.h>
|
||||
#include <zephyr/drivers/timer/system_timer.h>
|
||||
#include <zephyr/drivers/clock_control.h>
|
||||
#include <zephyr/irq.h>
|
||||
|
||||
#include <zephyr/dt-bindings/clock/bflb_clock_common.h>
|
||||
|
||||
|
||||
#include <soc.h>
|
||||
#include <bflb_soc.h>
|
||||
#include <glb_reg.h>
|
||||
#include <common_defines.h>
|
||||
#include <bouffalolab/common/uart_reg.h>
|
||||
#include <bouffalolab/common/bflb_uart.h>
|
||||
|
||||
#include <bflb_pinctrl.h>
|
||||
#include <bflb_uart.h>
|
||||
#include <bflb_glb.h>
|
||||
|
||||
#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);
|
||||
if (enable > 1) {
|
||||
enable = 1;
|
||||
}
|
||||
|
||||
GLB_Set_UART_CLK(1, HBN_UART_CLK_160M, UART_CLOCK_DIV);
|
||||
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);
|
||||
}
|
||||
|
||||
UART_IntMask(cfg->periph_id, UART_INT_ALL, 1);
|
||||
UART_Disable(cfg->periph_id, UART_TXRX);
|
||||
static uint32_t uart_bflb_get_clock(void)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uart_bflb_poll_in(const struct device *dev, unsigned char *c)
|
||||
{
|
||||
const struct bflb_config *cfg = dev->config;
|
||||
|
||||
return UART_ReceiveData(cfg->periph_id, (uint8_t *)c, 1) ? 0 : -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)
|
||||
{
|
||||
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 DEVICE_API(uart, 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) \
|
||||
#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(n), \
|
||||
DT_INST_IRQ(n, priority), \
|
||||
IRQ_CONNECT(DT_INST_IRQN(instance), \
|
||||
DT_INST_IRQ(instance, priority), \
|
||||
uart_bflb_isr, \
|
||||
DEVICE_DT_INST_GET(n), \
|
||||
DEVICE_DT_INST_GET(instance), \
|
||||
0); \
|
||||
irq_enable(DT_INST_IRQN(n)); \
|
||||
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); \
|
||||
|
||||
#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), \
|
||||
\
|
||||
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, \
|
||||
\
|
||||
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)
|
||||
|
||||
5
dts/bindings/flash_controller/bflb,flash-controller.yaml
Normal file
5
dts/bindings/flash_controller/bflb,flash-controller.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
description: Bouffalolab Flash Controller
|
||||
|
||||
compatible: "bflb,flash-controller"
|
||||
|
||||
include: flash-controller.yaml
|
||||
19
dts/bindings/interrupt-controller/sifive,clic-draft.yaml
Normal file
19
dts/bindings/interrupt-controller/sifive,clic-draft.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2025 MASSDRIVER EI (massdrive.space)
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: RISC-V Core Local Interrupt Controller CLIC Pre-Standard v0.9
|
||||
|
||||
compatible: "sifive,clic-draft"
|
||||
|
||||
include: [interrupt-controller.yaml, base.yaml]
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
||||
|
||||
"#interrupt-cells":
|
||||
const: 2
|
||||
|
||||
interrupt-cells:
|
||||
- irq
|
||||
- priority
|
||||
@@ -13,8 +13,3 @@ include:
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
||||
|
||||
peripheral-id:
|
||||
type: int
|
||||
description: peripheral ID
|
||||
required: true
|
||||
|
||||
8
dts/riscv/bflb/bl602.dtsi
Normal file
8
dts/riscv/bflb/bl602.dtsi
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space)
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <bflb/bl60x.dtsi>
|
||||
#include <dt-bindings/pinctrl/bl602x-pinctrl.h>
|
||||
8
dts/riscv/bflb/bl604.dtsi
Normal file
8
dts/riscv/bflb/bl604.dtsi
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space)
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <bflb/bl60x.dtsi>
|
||||
#include <dt-bindings/pinctrl/bl604x-pinctrl.h>
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
#include <freq.h>
|
||||
#include <mem.h>
|
||||
#include <dt-bindings/pinctrl/bl60x-pinctrl.h>
|
||||
#include <dt-bindings/pinctrl/bflb-common-pinctrl.h>
|
||||
#include <dt-bindings/pinctrl/bl60x-pinctrl.h>
|
||||
#include <dt-bindings/clock/bflb_bl60x_clock.h>
|
||||
|
||||
/ {
|
||||
@@ -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,clic-draft";
|
||||
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)>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/types.h>
|
||||
#include <zephyr/dt-bindings/pinctrl/bflb-common-pinctrl.h>
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
|
||||
@@ -1,55 +1,9 @@
|
||||
# Copyright (c) 2021-2025 Gerson Fernando Budke <nandojve@gmail.com>
|
||||
# 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
|
||||
|
||||
@@ -1,59 +1,7 @@
|
||||
# Copyright (c) 2021-2025 Gerson Fernando Budke <nandojve@gmail.com>
|
||||
# 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
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2025 Gerson Fernando Budke <nandojve@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_HAL_BFLB_GLB_H_
|
||||
#define ZEPHYR_HAL_BFLB_GLB_H_
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_BL60X
|
||||
#include <bl602_glb.h>
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_HAL_BFLB_GLB_H_ */
|
||||
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2025 Gerson Fernando Budke <nandojve@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_HAL_BFLB_GPIO_H_
|
||||
#define ZEPHYR_HAL_BFLB_GPIO_H_
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_BL60X
|
||||
#include <bl602_gpio.h>
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_HAL_BFLB_GPIO_H_ */
|
||||
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2025 Gerson Fernando Budke <nandojve@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_HAL_BFLB_HBN_H_
|
||||
#define ZEPHYR_HAL_BFLB_HBN_H_
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_BL60X
|
||||
#include <bl602_hbn.h>
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_HAL_BFLB_HBN_H_ */
|
||||
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2025 Gerson Fernando Budke <nandojve@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_HAL_BFLB_PINCTRL_H_
|
||||
#define ZEPHYR_HAL_BFLB_PINCTRL_H_
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_BL60X
|
||||
#include <zephyr/dt-bindings/pinctrl/bl60x-pinctrl.h>
|
||||
#endif
|
||||
#include <zephyr/dt-bindings/pinctrl/bflb-common-pinctrl.h>
|
||||
|
||||
#endif /* ZEPHYR_HAL_BFLB_PINCTRL_H_ */
|
||||
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2025 Gerson Fernando Budke <nandojve@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_HAL_BFLB_UART_H_
|
||||
#define ZEPHYR_HAL_BFLB_UART_H_
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_BL60X
|
||||
#include <bl602_uart.h>
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_HAL_BFLB_UART_H_ */
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2025 Gerson Fernando Budke <nandojve@gmail.com>
|
||||
*
|
||||
* 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 */
|
||||
@@ -2,9 +2,6 @@
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config SOC_FAMILY_BFLB
|
||||
select HAS_BFLB_HAL
|
||||
|
||||
if SOC_FAMILY_BFLB
|
||||
|
||||
rsource "*/Kconfig"
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
# 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)
|
||||
zephyr_code_relocate_ifdef(CONFIG_SYSCON_BFLB_EFUSE LIBRARY drivers__syscon LOCATION ITCM NOKEEP)
|
||||
zephyr_code_relocate_ifdef(CONFIG_CLOCK_CONTROL_BOUFFALOLAB_BL60X
|
||||
LIBRARY drivers__clock_control LOCATION ITCM NOKEEP)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -4,7 +4,18 @@
|
||||
|
||||
if SOC_SERIES_BL60X
|
||||
|
||||
# On BL602 and BL604, not all values work, here is a list of some that work:
|
||||
# 5000, 1000, 100, 10, 1
|
||||
config SYS_CLOCK_TICKS_PER_SEC
|
||||
default 5000
|
||||
|
||||
config NUM_IRQS
|
||||
default 80
|
||||
|
||||
config ARCH_SW_ISR_TABLE_ALIGN
|
||||
default 64
|
||||
|
||||
config RISCV_MCAUSE_EXCEPTION_MASK
|
||||
default 0x3FF
|
||||
|
||||
endif # SOC_SERIES_BL60X
|
||||
|
||||
@@ -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*)))
|
||||
@@ -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 <zephyr/kernel.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/init.h>
|
||||
#include <zephyr/irq.h>
|
||||
|
||||
#include <bflb_hbn.h>
|
||||
#include <bflb_glb.h>
|
||||
#include <clic.h>
|
||||
#include <bflb_soc.h>
|
||||
#include <glb_reg.h>
|
||||
#include <hbn_reg.h>
|
||||
#include <pds_reg.h>
|
||||
|
||||
#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();
|
||||
}
|
||||
|
||||
@@ -15,35 +15,12 @@
|
||||
#define _SOC__H_
|
||||
|
||||
#include <zephyr/sys/util.h>
|
||||
#include <../common/soc_common.h>
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
|
||||
/* Add include for DTS generated information */
|
||||
#include <zephyr/devicetree.h>
|
||||
|
||||
#if defined(CONFIG_SOC_SERIES_BL60X)
|
||||
#include <bl602.h>
|
||||
#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_ */
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 */
|
||||
91
soc/bflb/common/e24/intc_clic.S
Normal file
91
soc/bflb/common/e24/intc_clic.S
Normal file
@@ -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 <zephyr/arch/cpu.h>
|
||||
#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
|
||||
37
soc/bflb/common/e24/soc_irq_privileged.c
Normal file
37
soc/bflb/common/e24/soc_irq_privileged.c
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Gerson Fernando Budke <nandojve@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief interrupt management code for riscv SOCs supporting the SiFive clic
|
||||
*/
|
||||
#include <zephyr/irq.h>
|
||||
#include <soc.h>
|
||||
#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);
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2025 Gerson Fernando Budke <nandojve@gmail.com>
|
||||
*
|
||||
* 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_ */
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2025 Gerson Fernando Budke <nandojve@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief interrupt management code for riscv SOCs supporting the SiFive clic
|
||||
*/
|
||||
#include <zephyr/irq.h>
|
||||
#include <soc.h>
|
||||
#include <clic.h>
|
||||
|
||||
/* 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 */
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Jean-Paul Etienne <fractalclone@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* common interrupt management code for riscv SOCs supporting the riscv
|
||||
* privileged architecture specification
|
||||
*/
|
||||
#include <zephyr/kernel_structs.h>
|
||||
#include <offsets.h>
|
||||
#include <zephyr/toolchain.h>
|
||||
#include <zephyr/linker/sections.h>
|
||||
#include <soc.h>
|
||||
|
||||
/* 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
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2025 Gerson Fernando Budke <nandojve@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/toolchain.h>
|
||||
#include <zephyr/arch/riscv/csr.h>
|
||||
|
||||
/* 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
|
||||
Reference in New Issue
Block a user