diff --git a/boards/riscv/milkv_duo/Kconfig.board b/boards/riscv/milkv_duo/Kconfig.board new file mode 100644 index 000000000000..99ed5669bc8d --- /dev/null +++ b/boards/riscv/milkv_duo/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright (c) 2023-2024 Chen Xingyu +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_MILKV_DUO + bool "Milk-V Duo" + depends on SOC_CV180X diff --git a/boards/riscv/milkv_duo/Kconfig.defconfig b/boards/riscv/milkv_duo/Kconfig.defconfig new file mode 100644 index 000000000000..f583ee6ee01b --- /dev/null +++ b/boards/riscv/milkv_duo/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2023-2024 Chen Xingyu +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_MILKV_DUO + +config BOARD + default "milkv_duo" + +endif # BOARD_MILKV_DUO diff --git a/boards/riscv/milkv_duo/doc/index.rst b/boards/riscv/milkv_duo/doc/index.rst new file mode 100644 index 000000000000..164fe4c4e9be --- /dev/null +++ b/boards/riscv/milkv_duo/doc/index.rst @@ -0,0 +1,79 @@ +.. milkv_duo: + +Milk-V Duo +########## + +Overview +******** +See . + +Supported Features +================== +The Milk-V Duo board configuration supports the following hardware features: + +.. list-table:: + :header-rows: 1 + + * - Peripheral + - Kconfig option + - Devicetree compatible + * - Mailbox + - :kconfig:option:`CONFIG_MBOX` + - :dtcompatible:`sophgo,cv18xx-mailbox` + * - Pin controller + - :kconfig:option:`CONFIG_PINCTRL` + - :dtcompatible:`sophgo,cv180x-pinctrl` + * - GPIO + - :kconfig:option:`CONFIG_GPIO` + - :dtcompatible:`snps,designware-gpio` + * - PWM + - :kconfig:option:`CONFIG_PWM` + - :dtcompatible:`sophgo,cv180x-pwm` + * - UART + - :kconfig:option:`CONFIG_SERIAL` + - :dtcompatible:`ns16550` + * - PLIC + - N/A + - :dtcompatible:`sifive,plic-1.0.0` + * - CLINT + - N/A + - :dtcompatible:`sifive,clint0` + +Other hardware features have not been enabled yet for this board. + +The default configuration can be found in the defconfig file: + + ``boards/riscv/milkv_duo/milkv_duo_defconfig`` + +Programming and Debugging +************************* + +Prepare a TF card and follow the instructions in the +`official SDK `_ to build and +flash the image. + +After that, you will get a ``fip.bin`` file at the root of the TF card. Use the +following command to replace the RTOS image with Zephyr: + +.. code-block:: sh + + python3 /path/to/duo-buildroot-sdk/fsbl/plat/cv180x/fiptool.py \ + -v genfip "/path/to/target/fip.bin" \ + --OLD_FIP="/path/to/original/fip.bin" \ + --BLCP_2ND="build/zephyr/zephyr.bin" + +Replace the original ``fip.bin`` on the TF card with the new one. + +.. admonition:: Notes for the official buildroot SDK + + 1. The Linux running on the big core uses UART0 (GP12/GP13) for the console, + while to avoid conflict, the Zephyr application (in the default board + configuration) uses UART1 (GP0/GP1). + 2. Thus, you need to recompile the Buildroot SDK to disable any unused + `PINMUX configs `_ + from the U-Boot source code, so they won't override the configuration + set by Zephyr. + 3. By default, the Linux running on the big core will blink the LED on the + board. For the demonstration of Zephyr (more specifically, the + ``samples/basic/blinky`` sample), you need to delete that script from the + Linux filesystem. The script is located at ``/mnt/system/blink.sh``. diff --git a/boards/riscv/milkv_duo/milkv_duo.dts b/boards/riscv/milkv_duo/milkv_duo.dts new file mode 100644 index 000000000000..00eaf4545aa0 --- /dev/null +++ b/boards/riscv/milkv_duo/milkv_duo.dts @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023-2024 Chen Xingyu + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include + +/ { + model = "Milk-V Duo"; + compatible = "milkv,duo"; + + chosen { + zephyr,sram = &sram; + zephyr,console = &uart1; + zephyr,shell-uart = &uart1; + }; + + aliases { + led0 = &led; + }; + + leds { + compatible = "gpio-leds"; + + led: led { + gpios = <&gpioc 24 GPIO_ACTIVE_HIGH>; + }; + }; + + soc { + sram: memory@83f40000 { + compatible = "mmio-sram"; + reg = <0x83f40000 DT_SIZE_K(768)>; + }; + }; +}; + +&pinctrl { + uart1_default: uart1_default { + group1 { + pinmux = , + ; + }; + }; +}; + +&gpioc { + status = "okay"; +}; + +&uart1 { + status = "okay"; + pinctrl-0 = <&uart1_default>; + pinctrl-names = "default"; + current-speed = <115200>; +}; diff --git a/boards/riscv/milkv_duo/milkv_duo.yaml b/boards/riscv/milkv_duo/milkv_duo.yaml new file mode 100644 index 000000000000..3e555a1a3ef0 --- /dev/null +++ b/boards/riscv/milkv_duo/milkv_duo.yaml @@ -0,0 +1,11 @@ +identifier: milkv_duo +name: Milk-V Duo +type: mcu +arch: riscv64 +toolchain: + - zephyr +supported: + - clock + - gpio + - interrupt-controller + - serial diff --git a/boards/riscv/milkv_duo/milkv_duo_defconfig b/boards/riscv/milkv_duo/milkv_duo_defconfig new file mode 100644 index 000000000000..f6fa874002aa --- /dev/null +++ b/boards/riscv/milkv_duo/milkv_duo_defconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2023-2024 Chen Xingyu +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_SOPHGO=y +CONFIG_SOC_CV180X=y +CONFIG_BOARD_MILKV_DUO=y + +CONFIG_XIP=n + +CONFIG_PINCTRL=y +CONFIG_SERIAL=y + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/drivers/gpio/gpio_dw.c b/drivers/gpio/gpio_dw.c index cd1a97a6afa2..182a841417c3 100644 --- a/drivers/gpio/gpio_dw.c +++ b/drivers/gpio/gpio_dw.c @@ -437,10 +437,10 @@ static int gpio_dw_initialize(const struct device *port) COND_CODE_1(DT_INST_IRQ_HAS_CELL(n, flags), (DT_INST_IRQ(n, flags)), (0)) #define GPIO_CFG_IRQ(idx, n) \ - IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, idx, irq), \ + IRQ_CONNECT(DT_INST_IRQN_BY_IDX(n, idx), \ DT_INST_IRQ(n, priority), gpio_dw_isr, \ DEVICE_DT_INST_GET(n), INST_IRQ_FLAGS(n)); \ - irq_enable(DT_INST_IRQ_BY_IDX(n, idx, irq)); \ + irq_enable(DT_INST_IRQN_BY_IDX(n, idx)); \ #define GPIO_DW_INIT(n) \ static void gpio_config_##n##_irq(const struct device *port) \ diff --git a/drivers/interrupt_controller/Kconfig.plic b/drivers/interrupt_controller/Kconfig.plic index d4f91a3fbd22..e1426478ebfd 100644 --- a/drivers/interrupt_controller/Kconfig.plic +++ b/drivers/interrupt_controller/Kconfig.plic @@ -13,6 +13,12 @@ config PLIC if PLIC +config PLIC_HAS_EDGE_TRIGGER + bool "PLIC supports edge-triggered interrupts" + default y + help + Claims that the PLIC supports edge-triggered interrupts. + config PLIC_SHELL bool "PLIC shell commands" depends on SHELL diff --git a/drivers/interrupt_controller/intc_plic.c b/drivers/interrupt_controller/intc_plic.c index b8ca3234d122..ee856f29c613 100644 --- a/drivers/interrupt_controller/intc_plic.c +++ b/drivers/interrupt_controller/intc_plic.c @@ -137,10 +137,17 @@ static inline const struct device *get_plic_dev_from_irq(uint32_t irq) */ static int riscv_plic_is_edge_irq(const struct device *dev, uint32_t local_irq) { +#ifdef CONFIG_PLIC_HAS_EDGE_TRIGGER const struct plic_config *config = dev->config; mem_addr_t trig_addr = config->trig + local_irq_to_reg_offset(local_irq); return sys_read32(trig_addr) & BIT(local_irq & PLIC_REG_MASK); +#else + ARG_UNUSED(dev); + ARG_UNUSED(local_irq); + + return 0; +#endif } static void plic_irq_enable_set_state(uint32_t irq, bool enable) diff --git a/drivers/mbox/CMakeLists.txt b/drivers/mbox/CMakeLists.txt index b81a3bb679f0..d8b1ec64a622 100644 --- a/drivers/mbox/CMakeLists.txt +++ b/drivers/mbox/CMakeLists.txt @@ -9,3 +9,4 @@ zephyr_library_sources_ifdef(CONFIG_MBOX_NRFX_IPC mbox_nrfx_ipc.c) zephyr_library_sources_ifdef(CONFIG_MBOX_NXP_S32_MRU mbox_nxp_s32_mru.c) zephyr_library_sources_ifdef(CONFIG_MBOX_NXP_IMX_MU mbox_nxp_imx_mu.c) zephyr_library_sources_ifdef(CONFIG_MBOX_ANDES_PLIC_SW mbox_andes_plic_sw.c) +zephyr_library_sources_ifdef(CONFIG_MBOX_SOPHGO_CV18XX mbox_sophgo_cv18xx.c) diff --git a/drivers/mbox/Kconfig b/drivers/mbox/Kconfig index 0668c9aab8b0..7b5bad762563 100644 --- a/drivers/mbox/Kconfig +++ b/drivers/mbox/Kconfig @@ -15,6 +15,7 @@ source "drivers/mbox/Kconfig.nrfx" source "drivers/mbox/Kconfig.nxp_s32" source "drivers/mbox/Kconfig.nxp_imx" source "drivers/mbox/Kconfig.andes" +source "drivers/mbox/Kconfig.sophgo" config MBOX_INIT_PRIORITY int "MBOX init priority" diff --git a/drivers/mbox/Kconfig.sophgo b/drivers/mbox/Kconfig.sophgo new file mode 100644 index 000000000000..69bd4fc48633 --- /dev/null +++ b/drivers/mbox/Kconfig.sophgo @@ -0,0 +1,9 @@ +# Copyright (c) 2024 honglin leng +# SPDX-License-Identifier: Apache-2.0 + +config MBOX_SOPHGO_CV18XX + bool "SOPHGO CV18xx Mailbox controller" + default y + depends on DT_HAS_SOPHGO_CV18XX_MAILBOX_ENABLED + help + Enable driver for the SOPHGO CV18xx Mailbox. diff --git a/drivers/mbox/mbox_sophgo_cv18xx.c b/drivers/mbox/mbox_sophgo_cv18xx.c new file mode 100644 index 000000000000..76a131e8ca3c --- /dev/null +++ b/drivers/mbox/mbox_sophgo_cv18xx.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2024 honglin leng + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#define DT_DRV_COMPAT sophgo_cv18xx_mailbox + +#define GET_CPUx(base, cpu_num) (base + 0x10 + (0x10 * (cpu_num))) + +#define MBOX_INT_CLR_OFFSET 0x00 +#define MBOX_INT_DONE_OFFSET 0x08 +#define MBOX_INT_TRIGER_OFFSET 0x60 +#define MBOX_BUFFER_OFFSET 0x400 + +#define CPUx_INT_DONE(base, cpu) (GET_CPUx(base, cpu) + MBOX_INT_DONE_OFFSET) +#define CPUx_INT_CLEAR(base, cpu) (GET_CPUx(base, cpu) + MBOX_INT_CLR_OFFSET) +#define CPUx_INT_TRIGER(base, cpu) (base + MBOX_INT_TRIGER_OFFSET) +#define CPUx_BUFFER(base) (base + MBOX_BUFFER_OFFSET) + +#define CPUx_INT_ENABLE(base, cpu) (base + (cpu * 0x04)) + +#define MAILBOX_MAX_NUM 8 + +struct mbox_cv18xx_data { + mbox_callback_t cb[MAILBOX_MAX_NUM]; + void *user_data[MAILBOX_MAX_NUM]; + const struct device *dev; +}; + +static struct mbox_cv18xx_data cv18xx_mbox_data; +static struct mbox_cv18xx_conf { + mm_reg_t base; + mm_reg_t mbox_buffer; + uint32_t rx_cpu; + uint32_t tx_cpu; +} cv18xx_mbox_conf = { + .base = DT_INST_REG_ADDR(0), + .mbox_buffer = DT_INST_REG_ADDR(0) + MBOX_BUFFER_OFFSET, + .tx_cpu = DT_INST_PROP(0, tx_cpu), + .rx_cpu = DT_INST_PROP(0, rx_cpu), +}; + +static void mbox_isr(const struct device *dev) +{ + uint8_t set_val; + uint8_t valid_val; + uint8_t tmp_valid_val; + struct mbox_msg msg; + struct mbox_cv18xx_data *data = dev->data; + const struct mbox_cv18xx_conf *conf = dev->config; + + set_val = sys_read8(CPUx_INT_DONE(conf->base, conf->rx_cpu)); + if (set_val) { + for (int i = 0; i < MAILBOX_MAX_NUM; i++) { + valid_val = set_val & (1 << i); + if (valid_val) { + msg.data = (unsigned long *)conf->mbox_buffer + i; + sys_write8(valid_val, CPUx_INT_CLEAR(conf->base, conf->rx_cpu)); + tmp_valid_val = + sys_read8(CPUx_INT_ENABLE(conf->base, conf->rx_cpu)); + tmp_valid_val &= ~valid_val; + sys_write8(tmp_valid_val, + CPUx_INT_ENABLE(conf->base, conf->rx_cpu)); + if (data->cb[i] != NULL) { + data->cb[i](dev, i, data->user_data[i], &msg); + *(unsigned long *)msg.data = 0x0; + } + } + } + } +} + +static int mbox_cv18xx_send(const struct device *dev, uint32_t channel, const struct mbox_msg *msg) +{ + uint8_t tmp_mbox_info; + const struct mbox_cv18xx_conf *conf = dev->config; + void *data = (unsigned long *)conf->mbox_buffer + channel; + + memcpy(data, msg->data, msg->size); + sys_write8(1 << channel, CPUx_INT_CLEAR(conf->base, conf->tx_cpu)); + tmp_mbox_info = sys_read8(CPUx_INT_ENABLE(conf->base, conf->tx_cpu)); + tmp_mbox_info |= (1 << channel); + sys_write8(tmp_mbox_info, CPUx_INT_ENABLE(conf->base, conf->tx_cpu)); + sys_write8(1 << channel, CPUx_INT_TRIGER(conf->base, conf->tx_cpu)); + return 0; +} + +static int mbox_cv18xx_register_callback(const struct device *dev, uint32_t channel, + mbox_callback_t cb, void *user_data) +{ + struct mbox_cv18xx_data *data = dev->data; + + if (channel >= MAILBOX_MAX_NUM) { + return -EINVAL; + } + + data->cb[channel] = cb; + data->user_data[channel] = user_data; + + return 0; +} + +static int mbox_cv18xx_mtu_get(const struct device *dev) +{ + /* We only support signalling */ + return 0; +} + +static uint32_t mbox_cv18xx_max_channels_get(const struct device *dev) +{ + return MAILBOX_MAX_NUM; +} + +static int mbox_cv18xx_set_enabled(const struct device *dev, uint32_t channel, bool enable) +{ + return 0; +} + +static int mbox_cv18xx_init(const struct device *dev) +{ + IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), mbox_isr, DEVICE_DT_INST_GET(0), 0); + irq_enable(DT_INST_IRQN(0)); + return 0; +} + +static const struct mbox_driver_api mbox_cv18xx_driver_api = { + .send = mbox_cv18xx_send, + .register_callback = mbox_cv18xx_register_callback, + .mtu_get = mbox_cv18xx_mtu_get, + .max_channels_get = mbox_cv18xx_max_channels_get, + .set_enabled = mbox_cv18xx_set_enabled, +}; + +DEVICE_DT_INST_DEFINE(0, mbox_cv18xx_init, NULL, &cv18xx_mbox_data, &cv18xx_mbox_conf, POST_KERNEL, + CONFIG_MBOX_INIT_PRIORITY, &mbox_cv18xx_driver_api); diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index 9455b6e7c78c..0971babf6a3d 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -38,3 +38,4 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_QUICKLOGIC_EOS_S3 pinctrl_eos_s3.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_RA pinctrl_ra.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_IMX_SCU pinctrl_imx_scu.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_RZT2M pinctrl_rzt2m.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_SOPHGO_CV180X pinctrl_sophgo_cv180x.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 8a165725e4d5..fb37642b445b 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -66,5 +66,6 @@ source "drivers/pinctrl/Kconfig.numaker" source "drivers/pinctrl/Kconfig.eos_s3" source "drivers/pinctrl/Kconfig.ra" source "drivers/pinctrl/Kconfig.rzt2m" +source "drivers/pinctrl/Kconfig.sophgo" endif # PINCTRL diff --git a/drivers/pinctrl/Kconfig.sophgo b/drivers/pinctrl/Kconfig.sophgo new file mode 100644 index 000000000000..c9de0dab2396 --- /dev/null +++ b/drivers/pinctrl/Kconfig.sophgo @@ -0,0 +1,9 @@ +# Copyright (c) 2023-2024 Chen Xingyu +# SPDX-License-Identifier: Apache-2.0 + +config PINCTRL_SOPHGO_CV180X + bool "SOPHGO CV180x pin controller driver" + default y + depends on DT_HAS_SOPHGO_CV180X_PINCTRL_ENABLED + help + Enables support for the SOPHGO CV180x pin controller. diff --git a/drivers/pinctrl/pinctrl_sophgo_cv180x.c b/drivers/pinctrl/pinctrl_sophgo_cv180x.c new file mode 100644 index 000000000000..6b82905a54fd --- /dev/null +++ b/drivers/pinctrl/pinctrl_sophgo_cv180x.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023-2024 Chen Xingyu + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT sophgo_cv180x_pinctrl + +#include +#include +#include + +#define PINCTRL_BASE DT_INST_REG_ADDR(0) + +#define PINCTRL_FMUX(base, n) (base + 0x00 + (n) * 4) + +#define FMUX_MASK BIT_MASK(3) + +static void pinctrl_configure_pin(const pinctrl_soc_pin_t *pin) +{ + uint32_t regval; + + regval = sys_read32(PINCTRL_FMUX(PINCTRL_BASE, pin->fmux_idx)); + regval &= ~FMUX_MASK; + regval |= pin->fmux_sel; + sys_write32(regval, PINCTRL_FMUX(PINCTRL_BASE, pin->fmux_idx)); +} + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + ARG_UNUSED(reg); + + for (uint8_t i = 0; i < pin_cnt; i++) { + pinctrl_configure_pin(&pins[i]); + } + + return 0; +} diff --git a/drivers/pwm/CMakeLists.txt b/drivers/pwm/CMakeLists.txt index 2bf100aceb20..3c64592212b0 100644 --- a/drivers/pwm/CMakeLists.txt +++ b/drivers/pwm/CMakeLists.txt @@ -40,6 +40,7 @@ zephyr_library_sources_ifdef(CONFIG_PWM_XMC4XXX_CCU8 pwm_xmc4xxx_ccu8.c) zephyr_library_sources_ifdef(CONFIG_PWM_MCUX_CTIMER pwm_mcux_ctimer.c) zephyr_library_sources_ifdef(CONFIG_PWM_NUMAKER pwm_numaker.c) zephyr_library_sources_ifdef(CONFIG_PWM_NXP_S32_EMIOS pwm_nxp_s32_emios.c) +zephyr_library_sources_ifdef(CONFIG_PWM_SOPHGO_CV180X pwm_sophgo_cv180x.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE pwm_handlers.c) zephyr_library_sources_ifdef(CONFIG_PWM_CAPTURE pwm_capture.c) diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 8942ebd89b08..9e13fd9959ee 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -100,4 +100,6 @@ source "drivers/pwm/Kconfig.numaker" source "drivers/pwm/Kconfig.nxp_s32_emios" +source "drivers/pwm/Kconfig.sophgo" + endif # PWM diff --git a/drivers/pwm/Kconfig.sophgo b/drivers/pwm/Kconfig.sophgo new file mode 100644 index 000000000000..a944a30e4442 --- /dev/null +++ b/drivers/pwm/Kconfig.sophgo @@ -0,0 +1,9 @@ +# Copyright (c) 2023-2024 Chen Xingyu +# SPDX-License-Identifier: Apache-2.0 + +config PWM_SOPHGO_CV180X + bool "SOPHGO CV180x PWM driver" + default y + depends on DT_HAS_SOPHGO_CV180X_PWM_ENABLED + help + Enables support for the SOPHGO CV180x PWM. diff --git a/drivers/pwm/pwm_sophgo_cv180x.c b/drivers/pwm/pwm_sophgo_cv180x.c new file mode 100644 index 000000000000..9dd690524a9d --- /dev/null +++ b/drivers/pwm/pwm_sophgo_cv180x.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2023-2024 Chen Xingyu + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT sophgo_cv180x_pwm + +#include +#include +#include +#include + +#define HLPERIOD(base, n) (base + 0x000 + (n) * 8) +#define PERIOD(base, n) (base + 0x004 + (n) * 8) +#define PWMCONFIG(base) (base + 0x040) +#define PWMSTART(base) (base + 0x044) +#define PWMDONE(base) (base + 0x048) +#define PWMUPDATE(base) (base + 0x04c) +#define PCOUNT(base, n) (base + 0x050 + (n) * 4) +#define PULSECOUNT(base, n) (base + 0x060 + (n) * 4) +#define SHIFTCOUNT(base, n) (base + 0x080 + (n) * 4) +#define SHIFTSTART(base) (base + 0x090) +#define PWM_OE(base) (base + 0x0d0) + +/* PWMCONFIG */ +#define CFG_POLARITY(n) BIT(n + 0) +#define CFG_PWMMODE(n) BIT(n + 8) +#define CFG_SHIFTMODE BIT(16) + +#define PWM_CH_MAX 4 + +struct pwm_cvi_config { + mm_reg_t base; + uint32_t clk_pwm; + const struct pinctrl_dev_config *pcfg; +}; + +static int pwm_cvi_set_cycles(const struct device *dev, uint32_t channel, uint32_t period_cycles, + uint32_t pulse_cycles, pwm_flags_t flags) +{ + const struct pwm_cvi_config *cfg = dev->config; + uint32_t regval; + + if (channel > PWM_CH_MAX) { + return -EINVAL; + } + + if (period_cycles > cfg->clk_pwm) { + return -EINVAL; + } + + if (pulse_cycles >= period_cycles) { + pulse_cycles = period_cycles - 1; + } + + /* Configure output */ + regval = sys_read32(PWM_OE(cfg->base)); + regval |= BIT(channel); + sys_write32(regval, PWM_OE(cfg->base)); + + /* Set polarity and mode */ + regval = sys_read32(PWMCONFIG(cfg->base)); + if (flags & PWM_POLARITY_INVERTED) { + regval &= ~CFG_POLARITY(channel); /* active low */ + } else { + regval |= CFG_POLARITY(channel); /* active high */ + } + regval &= ~CFG_PWMMODE(channel); /* continuous mode */ + sys_write32(regval, PWMCONFIG(cfg->base)); + + /* Set period and pulse */ + sys_write32(period_cycles, PERIOD(cfg->base, channel)); + sys_write32(pulse_cycles, HLPERIOD(cfg->base, channel)); + + if (sys_read32(PWMSTART(cfg->base)) & BIT(channel)) { + /* Update channel */ + regval = sys_read32(PWMUPDATE(cfg->base)); + regval |= BIT(channel); + sys_write32(regval, PWMUPDATE(cfg->base)); + regval &= ~BIT(channel); + sys_write32(regval, PWMUPDATE(cfg->base)); + } else { + /* Start channel */ + regval = sys_read32(PWMSTART(cfg->base)); + regval &= ~BIT(channel); + sys_write32(regval, PWMSTART(cfg->base)); + regval |= BIT(channel); + sys_write32(regval, PWMSTART(cfg->base)); + } + + return 0; +} + +static int pwm_cvi_get_cycles_per_sec(const struct device *dev, uint32_t channel, uint64_t *cycles) +{ + const struct pwm_cvi_config *cfg = dev->config; + + if (channel > PWM_CH_MAX) { + return -EINVAL; + } + + *cycles = cfg->clk_pwm; + + return 0; +} + +static int pwm_cvi_init(const struct device *dev) +{ + const struct pwm_cvi_config *cfg = dev->config; + int ret; + + ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } + + return 0; +} + +static const struct pwm_driver_api pwm_cvi_api = { + .set_cycles = pwm_cvi_set_cycles, + .get_cycles_per_sec = pwm_cvi_get_cycles_per_sec, +}; + +#define PWM_CVI_INST(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + \ + static const struct pwm_cvi_config pwm_cvi_cfg_##n = { \ + .base = DT_INST_REG_ADDR(n), \ + .clk_pwm = DT_INST_PROP(n, clock_frequency), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, &pwm_cvi_init, NULL, NULL, &pwm_cvi_cfg_##n, PRE_KERNEL_1, \ + CONFIG_PWM_INIT_PRIORITY, &pwm_cvi_api); + +DT_INST_FOREACH_STATUS_OKAY(PWM_CVI_INST) diff --git a/drivers/timer/riscv_machine_timer.c b/drivers/timer/riscv_machine_timer.c index abfb28a9628a..70489849dd90 100644 --- a/drivers/timer/riscv_machine_timer.c +++ b/drivers/timer/riscv_machine_timer.c @@ -95,7 +95,7 @@ static uintptr_t get_hart_mtimecmp(void) static void set_mtimecmp(uint64_t time) { -#ifdef CONFIG_64BIT +#if defined(CONFIG_64BIT) && !defined(CONFIG_SOC_CV180X) *(volatile uint64_t *)get_hart_mtimecmp() = time; #else volatile uint32_t *r = (uint32_t *)get_hart_mtimecmp(); @@ -122,7 +122,13 @@ static void set_divider(void) static uint64_t mtime(void) { -#ifdef CONFIG_64BIT +#if defined(CONFIG_SOC_CV180X) + uint64_t mtime; + + __asm__ volatile ("rdtime %0" : "=r" (mtime)); + + return mtime; +#elif defined(CONFIG_64BIT) return *(volatile uint64_t *)MTIME_REG; #else volatile uint32_t *r = (uint32_t *)MTIME_REG; diff --git a/dts/bindings/cpu/thead,c906.yaml b/dts/bindings/cpu/thead,c906.yaml new file mode 100644 index 000000000000..02464bd89dca --- /dev/null +++ b/dts/bindings/cpu/thead,c906.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023-2024 Chen Xingyu +# SPDX-License-Identifier: Apache-2.0 + +description: T-Head C906 RISC-V CPU + +compatible: "thead,c906" + +include: riscv,cpus.yaml diff --git a/dts/bindings/mbox/sophgo,cv18xx-mbox.yaml b/dts/bindings/mbox/sophgo,cv18xx-mbox.yaml new file mode 100644 index 000000000000..3904eb72800d --- /dev/null +++ b/dts/bindings/mbox/sophgo,cv18xx-mbox.yaml @@ -0,0 +1,39 @@ +# Copyright (c) 2024 honglin leng +# SPDX-License-Identifier: Apache-2.0 + +description: SOPHGO CV18xx Mailbox controller + +compatible: "sophgo,cv18xx-mailbox" + +include: [base.yaml, mailbox-controller.yaml] + +properties: + reg: + required: true + + interrupt-parent: + required: true + + interrupts: + required: true + + channel-max: + type: int + required: true + description: Supported channels max + + rx-cpu: + type: int + enum: [1, 2, 3, 4] + description: | + Receiver CPU Index. + + tx-cpu: + type: int + enum: [1, 2, 3, 4] + description: | + Sender CPU Index.The CV18xx platform has a total of 4 CPUs, each with its own mailbox. + The mailbox controller can be used to send messages between CPUs. + +mbox-cells: + - channel diff --git a/dts/bindings/pinctrl/sophgo,cv180x-pinctrl.yaml b/dts/bindings/pinctrl/sophgo,cv180x-pinctrl.yaml new file mode 100644 index 000000000000..07c5e7617921 --- /dev/null +++ b/dts/bindings/pinctrl/sophgo,cv180x-pinctrl.yaml @@ -0,0 +1,17 @@ +# Copyright (c) 2023-2024Z Chen Xingyu +# SPDX-License-Identifier: Apache-2.0 + +description: SOPHGO CV180x pin controller driver + +compatible: "sophgo,cv180x-pinctrl" + +include: base.yaml + +child-binding: + description: CV180x pinmux group + + child-binding: + properties: + pinmux: + required: true + type: array diff --git a/dts/bindings/pwm/sophgo,cv180x-pwm.yaml b/dts/bindings/pwm/sophgo,cv180x-pwm.yaml new file mode 100644 index 000000000000..e6147014f7cb --- /dev/null +++ b/dts/bindings/pwm/sophgo,cv180x-pwm.yaml @@ -0,0 +1,27 @@ +# Copyright (c) 2023-2024 Chen Xingyu +# SPDX-License-Identifier: Apache-2.0 + +description: SOPHGO CV180x PWM + +compatible: "sophgo,cv180x-pwm" + +include: [pwm-controller.yaml, pinctrl-device.yaml, base.yaml] + +properties: + clock-frequency: + type: int + required: true + + pinctrl-0: + required: true + + pinctrl-names: + required: true + + "#pwm-cells": + const: 3 + +pwm-cells: +- channel +- period +- flags diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index 29a7b78aa70c..2df6070346e6 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -387,6 +387,7 @@ microcrystal Micro Crystal AG micron Micron Technology Inc. microsoft Microsoft Corporation microsys MicroSys Electronics GmbH +milkv Shenzhen MilkV Technology Co., Ltd mikroe MikroElektronika d.o.o. mikrotik MikroTik miniand Miniand Tech @@ -581,6 +582,7 @@ socionext Socionext Inc. solidrun SolidRun solomon Solomon Systech Limited sony Sony Corporation +sophgo SOPHGO Technologies spansion Spansion Inc. sparkfun SparkFun Electronics sprd Spreadtrum Communications Inc. @@ -615,6 +617,7 @@ tempo Tempo Semiconductor techstar Shenzhen Techstar Electronics Co., Ltd. terasic Terasic Inc. tfc Three Five Corp +thead T-Head Semiconductor Co., Ltd. thine THine Electronics, Inc. thingyjp thingy.jp ti Texas Instruments diff --git a/dts/riscv/sophgo/cv180x.dtsi b/dts/riscv/sophgo/cv180x.dtsi new file mode 100644 index 000000000000..ba52f66b9a56 --- /dev/null +++ b/dts/riscv/sophgo/cv180x.dtsi @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2023-2024 Chen Xingyu + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "thead,c906"; + reg = <0>; + clock-frequency = ; + mmu-type = "riscv,none"; + riscv,isa = "rv64imafdc_zicsr_zifencei"; + + hlic: interrupt-controller { + compatible = "riscv,cpu-intc"; + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + }; + }; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + + mbox: mailbox@1900000 { + compatible = "sophgo,cv18xx-mailbox"; + reg = <0x1900000 DT_SIZE_K(4)>; + interrupt-parent = <&plic0>; + interrupts = <61 1>; + channel-max = <8>; + tx-cpu = <1>; + rx-cpu = <2>; + #mbox-cells = <1>; + status = "disabled"; + }; + + pinctrl: pin-controller@3001000 { + compatible = "sophgo,cv180x-pinctrl"; + reg = <0x3001000 DT_SIZE_K(4)>; + }; + + gpioa: gpio@3020000 { + compatible = "snps,designware-gpio"; + reg = <0x3020000 DT_SIZE_K(4)>; + interrupt-parent = <&plic0>; + interrupts = <41 1>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpiob: gpio@3021000 { + compatible = "snps,designware-gpio"; + reg = <0x3021000 DT_SIZE_K(4)>; + interrupt-parent = <&plic0>; + interrupts = <42 1>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpioc: gpio@3022000 { + compatible = "snps,designware-gpio"; + reg = <0x3022000 DT_SIZE_K(4)>; + interrupt-parent = <&plic0>; + interrupts = <43 1>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpiod: gpio@3023000 { + compatible = "snps,designware-gpio"; + reg = <0x3023000 DT_SIZE_K(4)>; + interrupt-parent = <&plic0>; + interrupts = <44 1>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + pwm0: pwm@3060000 { + compatible = "sophgo,cv180x-pwm"; + reg = <0x3060000 DT_SIZE_K(4)>; + clock-frequency = ; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm1: pwm@3061000 { + compatible = "sophgo,cv180x-pwm"; + reg = <0x3061000 DT_SIZE_K(4)>; + clock-frequency = ; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm2: pwm@3062000 { + compatible = "sophgo,cv180x-pwm"; + reg = <0x3062000 DT_SIZE_K(4)>; + clock-frequency = ; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm3: pwm@3063000 { + compatible = "sophgo,cv180x-pwm"; + reg = <0x3063000 DT_SIZE_K(4)>; + clock-frequency = ; + #pwm-cells = <3>; + status = "disabled"; + }; + + uart0: uart@4140000 { + compatible = "ns16550"; + reg = <0x4140000 DT_SIZE_K(64)>; + interrupt-parent = <&plic0>; + interrupts = <30 1>; + reg-shift = <2>; + clock-frequency = ; + status = "disabled"; + }; + + uart1: uart@4150000 { + compatible = "ns16550"; + reg = <0x4150000 DT_SIZE_K(64)>; + interrupt-parent = <&plic0>; + interrupts = <31 1>; + reg-shift = <2>; + clock-frequency = ; + status = "disabled"; + }; + + uart2: uart@4160000 { + compatible = "ns16550"; + reg = <0x4160000 DT_SIZE_K(64)>; + /* interrupt is not supported */ + reg-shift = <2>; + clock-frequency = ; + status = "disabled"; + }; + + uart3: uart@4170000 { + compatible = "ns16550"; + reg = <0x4170000 DT_SIZE_K(64)>; + /* interrupt is not supported */ + reg-shift = <2>; + clock-frequency = ; + status = "disabled"; + }; + + uart4: uart@41c0000 { + compatible = "ns16550"; + reg = <0x41c0000 DT_SIZE_K(64)>; + /* interrupt is not supported */ + reg-shift = <2>; + clock-frequency = ; + status = "disabled"; + }; + + plic0: interrupt-controller@70000000 { + compatible = "sifive,plic-1.0.0"; + reg = <0x70000000 0x4000000>; + interrupts-extended = <&hlic 11>; + interrupt-controller; + riscv,max-priority = <7>; + riscv,ndev = <101>; + #address-cells = <0>; + #interrupt-cells = <2>; + }; + + clint: clint@74000000 { + compatible = "sifive,clint0"; + reg = <0x74000000 DT_SIZE_K(64)>; + interrupts-extended = <&hlic 3 &hlic 7>; + }; + }; +}; diff --git a/include/zephyr/dt-bindings/pinctrl/sophgo-cv180x-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/sophgo-cv180x-pinctrl.h new file mode 100644 index 000000000000..ba2fb8d43aec --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/sophgo-cv180x-pinctrl.h @@ -0,0 +1,486 @@ +/* + * Copyright (c) 2023 Chen Xingyu + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DT_SOPHGO_CV180X_PINCTRL_H_ +#define ZEPHYR_DT_SOPHGO_CV180X_PINCTRL_H_ + +#include + +#define FMUX_IDX_SD0_CLK 0 +#define FMUX_IDX_SD0_CMD 1 +#define FMUX_IDX_SD0_D0 2 +#define FMUX_IDX_SD0_D1 3 +#define FMUX_IDX_SD0_D2 4 +#define FMUX_IDX_SD0_D3 5 +#define FMUX_IDX_SD0_CD 6 +#define FMUX_IDX_SD0_PWR_EN 7 +#define FMUX_IDX_SPK_EN 8 +#define FMUX_IDX_UART0_TX 9 +#define FMUX_IDX_UART0_RX 10 +#define FMUX_IDX_SPINOR_HOLD_X 11 +#define FMUX_IDX_SPINOR_SCK 12 +#define FMUX_IDX_SPINOR_MOSI 13 +#define FMUX_IDX_SPINOR_WP_X 14 +#define FMUX_IDX_SPINOR_MISO 15 +#define FMUX_IDX_SPINOR_CS_X 16 +#define FMUX_IDX_JTAG_CPU_TMS 17 +#define FMUX_IDX_JTAG_CPU_TCK 18 +#define FMUX_IDX_IIC0_SCL 19 +#define FMUX_IDX_IIC0_SDA 20 +#define FMUX_IDX_AUX0 21 +#define FMUX_IDX_GPIO_ZQ 22 +#define FMUX_IDX_PWR_VBAT_DET 23 +#define FMUX_IDX_PWR_RSTN 24 +#define FMUX_IDX_PWR_SEQ1 25 +#define FMUX_IDX_PWR_SEQ2 26 +#define FMUX_IDX_PWR_WAKEUP0 27 +#define FMUX_IDX_PWR_BUTTON1 28 +#define FMUX_IDX_XTAL_XIN 29 +#define FMUX_IDX_PWR_GPIO0 30 +#define FMUX_IDX_PWR_GPIO1 31 +#define FMUX_IDX_PWR_GPIO2 32 +#define FMUX_IDX_SD1_GPIO1 33 +#define FMUX_IDX_SD1_GPIO0 34 +#define FMUX_IDX_SD1_D3 35 +#define FMUX_IDX_SD1_D2 36 +#define FMUX_IDX_SD1_D1 37 +#define FMUX_IDX_SD1_D0 38 +#define FMUX_IDX_SD1_CMD 39 +#define FMUX_IDX_SD1_CLK 40 +#define FMUX_IDX_PWM0_BUCK 41 +#define FMUX_IDX_ADC1 42 +#define FMUX_IDX_USB_VBUS_DET 43 +#define FMUX_IDX_MUX_SPI1_MISO 44 +#define FMUX_IDX_MUX_SPI1_MOSI 45 +#define FMUX_IDX_MUX_SPI1_CS 46 +#define FMUX_IDX_MUX_SPI1_SCK 47 +#define FMUX_IDX_PAD_ETH_TXP 48 +#define FMUX_IDX_PAD_ETH_TXM 49 +#define FMUX_IDX_PAD_ETH_RXP 50 +#define FMUX_IDX_PAD_ETH_RXM 51 +#define FMUX_IDX_GPIO_RTX 52 +#define FMUX_IDX_PAD_MIPIRX4N 53 +#define FMUX_IDX_PAD_MIPIRX4P 54 +#define FMUX_IDX_PAD_MIPIRX3N 55 +#define FMUX_IDX_PAD_MIPIRX3P 56 +#define FMUX_IDX_PAD_MIPIRX2N 57 +#define FMUX_IDX_PAD_MIPIRX2P 58 +#define FMUX_IDX_PAD_MIPIRX1N 59 +#define FMUX_IDX_PAD_MIPIRX1P 60 +#define FMUX_IDX_PAD_MIPIRX0N 61 +#define FMUX_IDX_PAD_MIPIRX0P 62 +#define FMUX_IDX_PAD_MIPI_TXM2 63 +#define FMUX_IDX_PAD_MIPI_TXP2 64 +#define FMUX_IDX_PAD_MIPI_TXM1 65 +#define FMUX_IDX_PAD_MIPI_TXP1 66 +#define FMUX_IDX_PAD_MIPI_TXM0 67 +#define FMUX_IDX_PAD_MIPI_TXP0 68 +#define FMUX_IDX_PKG_TYPE0 69 +#define FMUX_IDX_PKG_TYPE1 70 +#define FMUX_IDX_PKG_TYPE2 71 +#define FMUX_IDX_PAD_AUD_AINL_MIC 72 +#define FMUX_IDX_PAD_AUD_AINR_MIC 73 +#define FMUX_IDX_PAD_AUD_AOUTL 74 +#define FMUX_IDX_PAD_AUD_AOUTR 75 + +#define FMUX_SEL_SD0_CLK__SDIO0_CLK 0 +#define FMUX_SEL_SD0_CLK__IIC1_SDA 1 +#define FMUX_SEL_SD0_CLK__SPI0_SCK 2 +#define FMUX_SEL_SD0_CLK__XGPIOA_7 3 +#define FMUX_SEL_SD0_CLK__PWM_15 5 +#define FMUX_SEL_SD0_CLK__EPHY_LNK_LED 6 +#define FMUX_SEL_SD0_CLK__DBG_0 7 +#define FMUX_SEL_SD0_CMD__SDIO0_CMD 0 +#define FMUX_SEL_SD0_CMD__IIC1_SCL 1 +#define FMUX_SEL_SD0_CMD__SPI0_SDO 2 +#define FMUX_SEL_SD0_CMD__XGPIOA_8 3 +#define FMUX_SEL_SD0_CMD__PWM_14 5 +#define FMUX_SEL_SD0_CMD__EPHY_SPD_LED 6 +#define FMUX_SEL_SD0_CMD__DBG_1 7 +#define FMUX_SEL_SD0_D0__SDIO0_D_0 0 +#define FMUX_SEL_SD0_D0__CAM_MCLK1 1 +#define FMUX_SEL_SD0_D0__SPI0_SDI 2 +#define FMUX_SEL_SD0_D0__XGPIOA_9 3 +#define FMUX_SEL_SD0_D0__UART3_TX 4 +#define FMUX_SEL_SD0_D0__PWM_13 5 +#define FMUX_SEL_SD0_D0__WG0_D0 6 +#define FMUX_SEL_SD0_D0__DBG_2 7 +#define FMUX_SEL_SD0_D1__SDIO0_D_1 0 +#define FMUX_SEL_SD0_D1__IIC1_SDA 1 +#define FMUX_SEL_SD0_D1__AUX0 2 +#define FMUX_SEL_SD0_D1__XGPIOA_10 3 +#define FMUX_SEL_SD0_D1__UART1_TX 4 +#define FMUX_SEL_SD0_D1__PWM_12 5 +#define FMUX_SEL_SD0_D1__WG0_D1 6 +#define FMUX_SEL_SD0_D1__DBG_3 7 +#define FMUX_SEL_SD0_D2__SDIO0_D_2 0 +#define FMUX_SEL_SD0_D2__IIC1_SCL 1 +#define FMUX_SEL_SD0_D2__AUX1 2 +#define FMUX_SEL_SD0_D2__XGPIOA_11 3 +#define FMUX_SEL_SD0_D2__UART1_RX 4 +#define FMUX_SEL_SD0_D2__PWM_11 5 +#define FMUX_SEL_SD0_D2__WG1_D0 6 +#define FMUX_SEL_SD0_D2__DBG_4 7 +#define FMUX_SEL_SD0_D3__SDIO0_D_3 0 +#define FMUX_SEL_SD0_D3__CAM_MCLK0 1 +#define FMUX_SEL_SD0_D3__SPI0_CS_X 2 +#define FMUX_SEL_SD0_D3__XGPIOA_12 3 +#define FMUX_SEL_SD0_D3__UART3_RX 4 +#define FMUX_SEL_SD0_D3__PWM_10 5 +#define FMUX_SEL_SD0_D3__WG1_D1 6 +#define FMUX_SEL_SD0_D3__DBG_5 7 +#define FMUX_SEL_SD0_CD__SDIO0_CD 0 +#define FMUX_SEL_SD0_CD__XGPIOA_13 3 +#define FMUX_SEL_SD0_PWR_EN__SDIO0_PWR_EN 0 +#define FMUX_SEL_SD0_PWR_EN__XGPIOA_14 3 +#define FMUX_SEL_SPK_EN__XGPIOA_15 3 +#define FMUX_SEL_UART0_TX__UART0_TX 0 +#define FMUX_SEL_UART0_TX__CAM_MCLK1 1 +#define FMUX_SEL_UART0_TX__PWM_4 2 +#define FMUX_SEL_UART0_TX__XGPIOA_16 3 +#define FMUX_SEL_UART0_TX__UART1_TX 4 +#define FMUX_SEL_UART0_TX__AUX1 5 +#define FMUX_SEL_UART0_TX__JTAG_TMS 6 +#define FMUX_SEL_UART0_TX__DBG_6 7 +#define FMUX_SEL_UART0_RX__UART0_RX 0 +#define FMUX_SEL_UART0_RX__CAM_MCLK0 1 +#define FMUX_SEL_UART0_RX__PWM_5 2 +#define FMUX_SEL_UART0_RX__XGPIOA_17 3 +#define FMUX_SEL_UART0_RX__UART1_RX 4 +#define FMUX_SEL_UART0_RX__AUX0 5 +#define FMUX_SEL_UART0_RX__JTAG_TCK 6 +#define FMUX_SEL_UART0_RX__DBG_7 7 +#define FMUX_SEL_SPINOR_HOLD_X__SPINOR_HOLD_X 1 +#define FMUX_SEL_SPINOR_HOLD_X__SPINAND_HOLD 2 +#define FMUX_SEL_SPINOR_HOLD_X__XGPIOA_26 3 +#define FMUX_SEL_SPINOR_SCK__SPINOR_SCK 1 +#define FMUX_SEL_SPINOR_SCK__SPINAND_CLK 2 +#define FMUX_SEL_SPINOR_SCK__XGPIOA_22 3 +#define FMUX_SEL_SPINOR_MOSI__SPINOR_MOSI 1 +#define FMUX_SEL_SPINOR_MOSI__SPINAND_MOSI 2 +#define FMUX_SEL_SPINOR_MOSI__XGPIOA_25 3 +#define FMUX_SEL_SPINOR_WP_X__SPINOR_WP_X 1 +#define FMUX_SEL_SPINOR_WP_X__SPINAND_WP 2 +#define FMUX_SEL_SPINOR_WP_X__XGPIOA_27 3 +#define FMUX_SEL_SPINOR_MISO__SPINOR_MISO 1 +#define FMUX_SEL_SPINOR_MISO__SPINAND_MISO 2 +#define FMUX_SEL_SPINOR_MISO__XGPIOA_23 3 +#define FMUX_SEL_SPINOR_CS_X__SPINOR_CS_X 1 +#define FMUX_SEL_SPINOR_CS_X__SPINAND_CS 2 +#define FMUX_SEL_SPINOR_CS_X__XGPIOA_24 3 +#define FMUX_SEL_JTAG_CPU_TMS__JTAG_TMS 0 +#define FMUX_SEL_JTAG_CPU_TMS__CAM_MCLK0 1 +#define FMUX_SEL_JTAG_CPU_TMS__PWM_7 2 +#define FMUX_SEL_JTAG_CPU_TMS__XGPIOA_19 3 +#define FMUX_SEL_JTAG_CPU_TMS__UART1_RTS 4 +#define FMUX_SEL_JTAG_CPU_TMS__AUX0 5 +#define FMUX_SEL_JTAG_CPU_TMS__UART1_TX 6 +#define FMUX_SEL_JTAG_CPU_TCK__JTAG_TCK 0 +#define FMUX_SEL_JTAG_CPU_TCK__CAM_MCLK1 1 +#define FMUX_SEL_JTAG_CPU_TCK__PWM_6 2 +#define FMUX_SEL_JTAG_CPU_TCK__XGPIOA_18 3 +#define FMUX_SEL_JTAG_CPU_TCK__UART1_CTS 4 +#define FMUX_SEL_JTAG_CPU_TCK__AUX1 5 +#define FMUX_SEL_JTAG_CPU_TCK__UART1_RX 6 +#define FMUX_SEL_IIC0_SCL__CV_SCL0__CR_4WTDI 0 +#define FMUX_SEL_IIC0_SDA__CV_SDA0__CR_4WTDO 0 +#define FMUX_SEL_IIC0_SCL__JTAG_TDI 0 +#define FMUX_SEL_IIC0_SCL__UART1_TX 1 +#define FMUX_SEL_IIC0_SCL__UART2_TX 2 +#define FMUX_SEL_IIC0_SCL__XGPIOA_28 3 +#define FMUX_SEL_IIC0_SCL__IIC0_SCL 4 +#define FMUX_SEL_IIC0_SCL__WG0_D0 5 +#define FMUX_SEL_IIC0_SCL__DBG_10 7 +#define FMUX_SEL_IIC0_SDA__JTAG_TDO 0 +#define FMUX_SEL_IIC0_SDA__UART1_RX 1 +#define FMUX_SEL_IIC0_SDA__UART2_RX 2 +#define FMUX_SEL_IIC0_SDA__XGPIOA_29 3 +#define FMUX_SEL_IIC0_SDA__IIC0_SDA 4 +#define FMUX_SEL_IIC0_SDA__WG0_D1 5 +#define FMUX_SEL_IIC0_SDA__WG1_D0 6 +#define FMUX_SEL_IIC0_SDA__DBG_11 7 +#define FMUX_SEL_AUX0__AUX0 0 +#define FMUX_SEL_AUX0__XGPIOA_30 3 +#define FMUX_SEL_AUX0__IIS1_MCLK 4 +#define FMUX_SEL_AUX0__WG1_D1 6 +#define FMUX_SEL_AUX0__DBG_12 7 +#define FMUX_SEL_GPIO_ZQ__PWR_GPIO_24 3 +#define FMUX_SEL_GPIO_ZQ__PWM_2 4 +#define FMUX_SEL_PWR_VBAT_DET__PWR_VBAT_DET 0 +#define FMUX_SEL_PWR_RSTN__PWR_RSTN 0 +#define FMUX_SEL_PWR_SEQ1__PWR_SEQ1 0 +#define FMUX_SEL_PWR_SEQ1__PWR_GPIO_3 3 +#define FMUX_SEL_PWR_SEQ2__PWR_SEQ2 0 +#define FMUX_SEL_PWR_SEQ2__PWR_GPIO_4 3 +#define FMUX_SEL_PTEST__PWR_PTEST 0 +#define FMUX_SEL_PWR_WAKEUP0__PWR_WAKEUP0 0 +#define FMUX_SEL_PWR_WAKEUP0__PWR_IR0 1 +#define FMUX_SEL_PWR_WAKEUP0__PWR_UART0_TX 2 +#define FMUX_SEL_PWR_WAKEUP0__PWR_GPIO_6 3 +#define FMUX_SEL_PWR_WAKEUP0__UART1_TX 4 +#define FMUX_SEL_PWR_WAKEUP0__IIC4_SCL 5 +#define FMUX_SEL_PWR_WAKEUP0__EPHY_LNK_LED 6 +#define FMUX_SEL_PWR_WAKEUP0__WG2_D0 7 +#define FMUX_SEL_PWR_BUTTON1__PWR_BUTTON1 0 +#define FMUX_SEL_PWR_BUTTON1__PWR_GPIO_8 3 +#define FMUX_SEL_PWR_BUTTON1__UART1_RX 4 +#define FMUX_SEL_PWR_BUTTON1__IIC4_SDA 5 +#define FMUX_SEL_PWR_BUTTON1__EPHY_SPD_LED 6 +#define FMUX_SEL_PWR_BUTTON1__WG2_D1 7 +#define FMUX_SEL_XTAL_XIN__PWR_XTAL_CLKIN 0 +#define FMUX_SEL_PWR_GPIO0__PWR_GPIO_0 0 +#define FMUX_SEL_PWR_GPIO0__UART2_TX 1 +#define FMUX_SEL_PWR_GPIO0__PWR_UART0_RX 2 +#define FMUX_SEL_PWR_GPIO0__PWM_8 4 +#define FMUX_SEL_PWR_GPIO1__PWR_GPIO_1 0 +#define FMUX_SEL_PWR_GPIO1__UART2_RX 1 +#define FMUX_SEL_PWR_GPIO1__EPHY_LNK_LED 3 +#define FMUX_SEL_PWR_GPIO1__PWM_9 4 +#define FMUX_SEL_PWR_GPIO1__PWR_IIC_SCL 5 +#define FMUX_SEL_PWR_GPIO1__IIC2_SCL 6 +#define FMUX_SEL_PWR_GPIO1__IIC0_SDA 7 +#define FMUX_SEL_PWR_GPIO2__PWR_GPIO_2 0 +#define FMUX_SEL_PWR_GPIO2__PWR_SECTICK 2 +#define FMUX_SEL_PWR_GPIO2__EPHY_SPD_LED 3 +#define FMUX_SEL_PWR_GPIO2__PWM_10 4 +#define FMUX_SEL_PWR_GPIO2__PWR_IIC_SDA 5 +#define FMUX_SEL_PWR_GPIO2__IIC2_SDA 6 +#define FMUX_SEL_PWR_GPIO2__IIC0_SCL 7 +#define FMUX_SEL_SD1_GPIO1__UART4_TX 1 +#define FMUX_SEL_SD1_GPIO1__PWR_GPIO_26 3 +#define FMUX_SEL_SD1_GPIO1__PWM_10 7 +#define FMUX_SEL_SD1_GPIO0__UART4_RX 1 +#define FMUX_SEL_SD1_GPIO0__PWR_GPIO_25 3 +#define FMUX_SEL_SD1_GPIO0__PWM_11 7 +#define FMUX_SEL_SD1_D3__PWR_SD1_D3 0 +#define FMUX_SEL_SD1_D3__SPI2_CS_X 1 +#define FMUX_SEL_SD1_D3__IIC1_SCL 2 +#define FMUX_SEL_SD1_D3__PWR_GPIO_18 3 +#define FMUX_SEL_SD1_D3__CAM_MCLK0 4 +#define FMUX_SEL_SD1_D3__UART3_CTS 5 +#define FMUX_SEL_SD1_D3__PWR_SPINOR1_CS_X 6 +#define FMUX_SEL_SD1_D3__PWM_4 7 +#define FMUX_SEL_SD1_D2__PWR_SD1_D2 0 +#define FMUX_SEL_SD1_D2__IIC1_SCL 1 +#define FMUX_SEL_SD1_D2__UART2_TX 2 +#define FMUX_SEL_SD1_D2__PWR_GPIO_19 3 +#define FMUX_SEL_SD1_D2__CAM_MCLK0 4 +#define FMUX_SEL_SD1_D2__UART3_TX 5 +#define FMUX_SEL_SD1_D2__PWR_SPINOR1_HOLD_X 6 +#define FMUX_SEL_SD1_D2__PWM_5 7 +#define FMUX_SEL_SD1_D1__PWR_SD1_D1 0 +#define FMUX_SEL_SD1_D1__IIC1_SDA 1 +#define FMUX_SEL_SD1_D1__UART2_RX 2 +#define FMUX_SEL_SD1_D1__PWR_GPIO_20 3 +#define FMUX_SEL_SD1_D1__CAM_MCLK1 4 +#define FMUX_SEL_SD1_D1__UART3_RX 5 +#define FMUX_SEL_SD1_D1__PWR_SPINOR1_WP_X 6 +#define FMUX_SEL_SD1_D1__PWM_6 7 +#define FMUX_SEL_SD1_D0__PWR_SD1_D0 0 +#define FMUX_SEL_SD1_D0__SPI2_SDI 1 +#define FMUX_SEL_SD1_D0__IIC1_SDA 2 +#define FMUX_SEL_SD1_D0__PWR_GPIO_21 3 +#define FMUX_SEL_SD1_D0__CAM_MCLK1 4 +#define FMUX_SEL_SD1_D0__UART3_RTS 5 +#define FMUX_SEL_SD1_D0__PWR_SPINOR1_MISO 6 +#define FMUX_SEL_SD1_D0__PWM_7 7 +#define FMUX_SEL_SD1_CMD__PWR_SD1_CMD 0 +#define FMUX_SEL_SD1_CMD__SPI2_SDO 1 +#define FMUX_SEL_SD1_CMD__IIC3_SCL 2 +#define FMUX_SEL_SD1_CMD__PWR_GPIO_22 3 +#define FMUX_SEL_SD1_CMD__CAM_VS0 4 +#define FMUX_SEL_SD1_CMD__EPHY_LNK_LED 5 +#define FMUX_SEL_SD1_CMD__PWR_SPINOR1_MOSI 6 +#define FMUX_SEL_SD1_CMD__PWM_8 7 +#define FMUX_SEL_SD1_CLK__PWR_SD1_CLK 0 +#define FMUX_SEL_SD1_CLK__SPI2_SCK 1 +#define FMUX_SEL_SD1_CLK__IIC3_SDA 2 +#define FMUX_SEL_SD1_CLK__PWR_GPIO_23 3 +#define FMUX_SEL_SD1_CLK__CAM_HS0 4 +#define FMUX_SEL_SD1_CLK__EPHY_SPD_LED 5 +#define FMUX_SEL_SD1_CLK__PWR_SPINOR1_SCK 6 +#define FMUX_SEL_SD1_CLK__PWM_9 7 +#define FMUX_SEL_PWM0_BUCK__PWM_0 0 +#define FMUX_SEL_PWM0_BUCK__XGPIOB_0 3 +#define FMUX_SEL_ADC1__XGPIOB_3 3 +#define FMUX_SEL_ADC1__KEY_COL2 4 +#define FMUX_SEL_ADC1__PWM_3 6 +#define FMUX_SEL_USB_VBUS_DET__USB_VBUS_DET 0 +#define FMUX_SEL_USB_VBUS_DET__XGPIOB_6 3 +#define FMUX_SEL_USB_VBUS_DET__CAM_MCLK0 4 +#define FMUX_SEL_USB_VBUS_DET__CAM_MCLK1 5 +#define FMUX_SEL_USB_VBUS_DET__PWM_4 6 +#define FMUX_SEL_MUX_SPI1_MISO__UART3_RTS 1 +#define FMUX_SEL_MUX_SPI1_MISO__IIC1_SDA 2 +#define FMUX_SEL_MUX_SPI1_MISO__XGPIOB_8 3 +#define FMUX_SEL_MUX_SPI1_MISO__PWM_9 4 +#define FMUX_SEL_MUX_SPI1_MISO__KEY_COL1 5 +#define FMUX_SEL_MUX_SPI1_MISO__SPI1_SDI 6 +#define FMUX_SEL_MUX_SPI1_MISO__DBG_14 7 +#define FMUX_SEL_MUX_SPI1_MOSI__UART3_RX 1 +#define FMUX_SEL_MUX_SPI1_MOSI__IIC1_SCL 2 +#define FMUX_SEL_MUX_SPI1_MOSI__XGPIOB_7 3 +#define FMUX_SEL_MUX_SPI1_MOSI__PWM_8 4 +#define FMUX_SEL_MUX_SPI1_MOSI__KEY_COL0 5 +#define FMUX_SEL_MUX_SPI1_MOSI__SPI1_SDO 6 +#define FMUX_SEL_MUX_SPI1_MOSI__DBG_13 7 +#define FMUX_SEL_MUX_SPI1_CS__UART3_CTS 1 +#define FMUX_SEL_MUX_SPI1_CS__CAM_MCLK0 2 +#define FMUX_SEL_MUX_SPI1_CS__XGPIOB_10 3 +#define FMUX_SEL_MUX_SPI1_CS__PWM_11 4 +#define FMUX_SEL_MUX_SPI1_CS__KEY_ROW3 5 +#define FMUX_SEL_MUX_SPI1_CS__SPI1_CS_X 6 +#define FMUX_SEL_MUX_SPI1_CS__DBG_16 7 +#define FMUX_SEL_MUX_SPI1_SCK__UART3_TX 1 +#define FMUX_SEL_MUX_SPI1_SCK__CAM_MCLK1 2 +#define FMUX_SEL_MUX_SPI1_SCK__XGPIOB_9 3 +#define FMUX_SEL_MUX_SPI1_SCK__PWM_10 4 +#define FMUX_SEL_MUX_SPI1_SCK__KEY_ROW2 5 +#define FMUX_SEL_MUX_SPI1_SCK__SPI1_SCK 6 +#define FMUX_SEL_MUX_SPI1_SCK__DBG_15 7 +#define FMUX_SEL_PAD_ETH_TXP__UART3_RX 1 +#define FMUX_SEL_PAD_ETH_TXP__IIC1_SCL 2 +#define FMUX_SEL_PAD_ETH_TXP__XGPIOB_25 3 +#define FMUX_SEL_PAD_ETH_TXP__PWM_13 4 +#define FMUX_SEL_PAD_ETH_TXP__CAM_MCLK0 5 +#define FMUX_SEL_PAD_ETH_TXP__SPI1_SDO 6 +#define FMUX_SEL_PAD_ETH_TXP__IIS2_LRCK 7 +#define FMUX_SEL_PAD_ETH_TXM__UART3_RTS 1 +#define FMUX_SEL_PAD_ETH_TXM__IIC1_SDA 2 +#define FMUX_SEL_PAD_ETH_TXM__XGPIOB_24 3 +#define FMUX_SEL_PAD_ETH_TXM__PWM_12 4 +#define FMUX_SEL_PAD_ETH_TXM__CAM_MCLK1 5 +#define FMUX_SEL_PAD_ETH_TXM__SPI1_SDI 6 +#define FMUX_SEL_PAD_ETH_TXM__IIS2_BCLK 7 +#define FMUX_SEL_PAD_ETH_RXP__UART3_TX 1 +#define FMUX_SEL_PAD_ETH_RXP__CAM_MCLK1 2 +#define FMUX_SEL_PAD_ETH_RXP__XGPIOB_27 3 +#define FMUX_SEL_PAD_ETH_RXP__PWM_15 4 +#define FMUX_SEL_PAD_ETH_RXP__CAM_HS0 5 +#define FMUX_SEL_PAD_ETH_RXP__SPI1_SCK 6 +#define FMUX_SEL_PAD_ETH_RXP__IIS2_DO 7 +#define FMUX_SEL_PAD_ETH_RXM__UART3_CTS 1 +#define FMUX_SEL_PAD_ETH_RXM__CAM_MCLK0 2 +#define FMUX_SEL_PAD_ETH_RXM__XGPIOB_26 3 +#define FMUX_SEL_PAD_ETH_RXM__PWM_14 4 +#define FMUX_SEL_PAD_ETH_RXM__CAM_VS0 5 +#define FMUX_SEL_PAD_ETH_RXM__SPI1_CS_X 6 +#define FMUX_SEL_PAD_ETH_RXM__IIS2_DI 7 +#define FMUX_SEL_GPIO_RTX__VI0_D_15 1 +#define FMUX_SEL_GPIO_RTX__XGPIOB_23 3 +#define FMUX_SEL_GPIO_RTX__PWM_1 4 +#define FMUX_SEL_GPIO_RTX__CAM_MCLK0 5 +#define FMUX_SEL_GPIO_RTX__IIS2_MCLK 7 +#define FMUX_SEL_PAD_MIPIRX4N__VI0_CLK 1 +#define FMUX_SEL_PAD_MIPIRX4N__IIC0_SCL 2 +#define FMUX_SEL_PAD_MIPIRX4N__XGPIOC_2 3 +#define FMUX_SEL_PAD_MIPIRX4N__IIC1_SDA 4 +#define FMUX_SEL_PAD_MIPIRX4N__CAM_MCLK0 5 +#define FMUX_SEL_PAD_MIPIRX4N__KEY_ROW0 6 +#define FMUX_SEL_PAD_MIPIRX4N__MUX_SPI1_SCK 7 +#define FMUX_SEL_PAD_MIPIRX4P__VI0_D_0 1 +#define FMUX_SEL_PAD_MIPIRX4P__IIC0_SDA 2 +#define FMUX_SEL_PAD_MIPIRX4P__XGPIOC_3 3 +#define FMUX_SEL_PAD_MIPIRX4P__IIC1_SCL 4 +#define FMUX_SEL_PAD_MIPIRX4P__CAM_MCLK1 5 +#define FMUX_SEL_PAD_MIPIRX4P__KEY_ROW1 6 +#define FMUX_SEL_PAD_MIPIRX4P__MUX_SPI1_CS 7 +#define FMUX_SEL_PAD_MIPIRX3N__VI0_D_1 1 +#define FMUX_SEL_PAD_MIPIRX3N__XGPIOC_4 3 +#define FMUX_SEL_PAD_MIPIRX3N__CAM_MCLK0 4 +#define FMUX_SEL_PAD_MIPIRX3N__MUX_SPI1_MISO 7 +#define FMUX_SEL_PAD_MIPIRX3P__VI0_D_2 1 +#define FMUX_SEL_PAD_MIPIRX3P__XGPIOC_5 3 +#define FMUX_SEL_PAD_MIPIRX3P__MUX_SPI1_MOSI 7 +#define FMUX_SEL_PAD_MIPIRX2N__VI0_D_3 1 +#define FMUX_SEL_PAD_MIPIRX2N__XGPIOC_6 3 +#define FMUX_SEL_PAD_MIPIRX2N__IIC4_SCL 5 +#define FMUX_SEL_PAD_MIPIRX2N__DBG_6 7 +#define FMUX_SEL_PAD_MIPIRX2P__VI0_D_4 1 +#define FMUX_SEL_PAD_MIPIRX2P__XGPIOC_7 3 +#define FMUX_SEL_PAD_MIPIRX2P__IIC4_SDA 5 +#define FMUX_SEL_PAD_MIPIRX2P__DBG_7 7 +#define FMUX_SEL_PAD_MIPIRX1N__VI0_D_5 1 +#define FMUX_SEL_PAD_MIPIRX1N__XGPIOC_8 3 +#define FMUX_SEL_PAD_MIPIRX1N__KEY_ROW3 6 +#define FMUX_SEL_PAD_MIPIRX1N__DBG_8 7 +#define FMUX_SEL_PAD_MIPIRX1P__VI0_D_6 1 +#define FMUX_SEL_PAD_MIPIRX1P__XGPIOC_9 3 +#define FMUX_SEL_PAD_MIPIRX1P__IIC1_SDA 4 +#define FMUX_SEL_PAD_MIPIRX1P__KEY_ROW2 6 +#define FMUX_SEL_PAD_MIPIRX1P__DBG_9 7 +#define FMUX_SEL_PAD_MIPIRX0N__VI0_D_7 1 +#define FMUX_SEL_PAD_MIPIRX0N__XGPIOC_10 3 +#define FMUX_SEL_PAD_MIPIRX0N__IIC1_SCL 4 +#define FMUX_SEL_PAD_MIPIRX0N__CAM_MCLK1 5 +#define FMUX_SEL_PAD_MIPIRX0N__DBG_10 7 +#define FMUX_SEL_PAD_MIPIRX0P__VI0_D_8 1 +#define FMUX_SEL_PAD_MIPIRX0P__XGPIOC_11 3 +#define FMUX_SEL_PAD_MIPIRX0P__CAM_MCLK0 4 +#define FMUX_SEL_PAD_MIPIRX0P__DBG_11 7 +#define FMUX_SEL_PAD_MIPI_TXM2__VI0_D_13 1 +#define FMUX_SEL_PAD_MIPI_TXM2__IIC0_SDA 2 +#define FMUX_SEL_PAD_MIPI_TXM2__XGPIOC_16 3 +#define FMUX_SEL_PAD_MIPI_TXM2__IIC1_SDA 4 +#define FMUX_SEL_PAD_MIPI_TXM2__PWM_8 5 +#define FMUX_SEL_PAD_MIPI_TXM2__SPI0_SCK 6 +#define FMUX_SEL_PAD_MIPI_TXP2__VI0_D_14 1 +#define FMUX_SEL_PAD_MIPI_TXP2__IIC0_SCL 2 +#define FMUX_SEL_PAD_MIPI_TXP2__XGPIOC_17 3 +#define FMUX_SEL_PAD_MIPI_TXP2__IIC1_SCL 4 +#define FMUX_SEL_PAD_MIPI_TXP2__PWM_9 5 +#define FMUX_SEL_PAD_MIPI_TXP2__SPI0_CS_X 6 +#define FMUX_SEL_PAD_MIPI_TXP2__IIS1_MCLK 7 +#define FMUX_SEL_PAD_MIPI_TXM1__SPI3_SDO 0 +#define FMUX_SEL_PAD_MIPI_TXM1__VI0_D_11 1 +#define FMUX_SEL_PAD_MIPI_TXM1__IIS1_LRCK 2 +#define FMUX_SEL_PAD_MIPI_TXM1__XGPIOC_14 3 +#define FMUX_SEL_PAD_MIPI_TXM1__IIC2_SDA 4 +#define FMUX_SEL_PAD_MIPI_TXM1__PWM_10 5 +#define FMUX_SEL_PAD_MIPI_TXM1__SPI0_SDO 6 +#define FMUX_SEL_PAD_MIPI_TXM1__DBG_14 7 +#define FMUX_SEL_PAD_MIPI_TXP1__SPI3_SDI 0 +#define FMUX_SEL_PAD_MIPI_TXP1__VI0_D_12 1 +#define FMUX_SEL_PAD_MIPI_TXP1__IIS1_DO 2 +#define FMUX_SEL_PAD_MIPI_TXP1__XGPIOC_15 3 +#define FMUX_SEL_PAD_MIPI_TXP1__IIC2_SCL 4 +#define FMUX_SEL_PAD_MIPI_TXP1__PWM_11 5 +#define FMUX_SEL_PAD_MIPI_TXP1__SPI0_SDI 6 +#define FMUX_SEL_PAD_MIPI_TXP1__DBG_15 7 +#define FMUX_SEL_PAD_MIPI_TXM0__SPI3_SCK 0 +#define FMUX_SEL_PAD_MIPI_TXM0__VI0_D_9 1 +#define FMUX_SEL_PAD_MIPI_TXM0__IIS1_DI 2 +#define FMUX_SEL_PAD_MIPI_TXM0__XGPIOC_12 3 +#define FMUX_SEL_PAD_MIPI_TXM0__CAM_MCLK1 4 +#define FMUX_SEL_PAD_MIPI_TXM0__PWM_14 5 +#define FMUX_SEL_PAD_MIPI_TXM0__CAM_VS0 6 +#define FMUX_SEL_PAD_MIPI_TXM0__DBG_12 7 +#define FMUX_SEL_PAD_MIPI_TXP0__SPI3_CS_X 0 +#define FMUX_SEL_PAD_MIPI_TXP0__VI0_D_10 1 +#define FMUX_SEL_PAD_MIPI_TXP0__IIS1_BCLK 2 +#define FMUX_SEL_PAD_MIPI_TXP0__XGPIOC_13 3 +#define FMUX_SEL_PAD_MIPI_TXP0__CAM_MCLK0 4 +#define FMUX_SEL_PAD_MIPI_TXP0__PWM_15 5 +#define FMUX_SEL_PAD_MIPI_TXP0__CAM_HS0 6 +#define FMUX_SEL_PAD_MIPI_TXP0__DBG_13 7 +#define FMUX_SEL_PKG_TYPE0__PKG_TYPE0 0 +#define FMUX_SEL_PKG_TYPE1__PKG_TYPE1 0 +#define FMUX_SEL_PKG_TYPE2__PKG_TYPE2 0 +#define FMUX_SEL_PAD_AUD_AINL_MIC__XGPIOC_23 3 +#define FMUX_SEL_PAD_AUD_AINL_MIC__IIS1_BCLK 4 +#define FMUX_SEL_PAD_AUD_AINL_MIC__IIS2_BCLK 5 +#define FMUX_SEL_PAD_AUD_AINR_MIC__XGPIOC_22 3 +#define FMUX_SEL_PAD_AUD_AINR_MIC__IIS1_DO 4 +#define FMUX_SEL_PAD_AUD_AINR_MIC__IIS2_DI 5 +#define FMUX_SEL_PAD_AUD_AINR_MIC__IIS1_DI 6 +#define FMUX_SEL_PAD_AUD_AOUTL__XGPIOC_25 3 +#define FMUX_SEL_PAD_AUD_AOUTL__IIS1_LRCK 4 +#define FMUX_SEL_PAD_AUD_AOUTL__IIS2_LRCK 5 +#define FMUX_SEL_PAD_AUD_AOUTR__XGPIOC_24 3 +#define FMUX_SEL_PAD_AUD_AOUTR__IIS1_DI 4 +#define FMUX_SEL_PAD_AUD_AOUTR__IIS2_DO 5 +#define FMUX_SEL_PAD_AUD_AOUTR__IIS1_DO 6 + +#endif /* ZEPHYR_DT_SOPHGO_CV180X_PINCTRL_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/sophgo-pinctrl-common.h b/include/zephyr/dt-bindings/pinctrl/sophgo-pinctrl-common.h new file mode 100644 index 000000000000..9166835d65a2 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/sophgo-pinctrl-common.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 Chen Xingyu + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DT_SOPHGO_PINCTRL_COMMON_H_ +#define ZEPHYR_DT_SOPHGO_PINCTRL_COMMON_H_ + +#include + +#define SOPHGO_PINMUX_FMUX_IDX_S (0) +#define SOPHGO_PINMUX_FMUX_IDX_M BIT_MASK(8) + +#define SOPHGO_PINMUX_FMUX_SEL_S (8) +#define SOPHGO_PINMUX_FMUX_SEL_M BIT_MASK(3) + +#define SOPHGO_PINMUX(pin, func) \ + ((((FMUX_IDX_##pin) & SOPHGO_PINMUX_FMUX_IDX_M) << SOPHGO_PINMUX_FMUX_IDX_S) | \ + (((FMUX_SEL_##pin##__##func) & SOPHGO_PINMUX_FMUX_SEL_M) << SOPHGO_PINMUX_FMUX_SEL_S)) + +#endif /* ZEPHYR_DT_SOPHGO_PINCTRL_COMMON_H_ */ diff --git a/samples/boards/milkv_duo/mbox/CMakeLists.txt b/samples/boards/milkv_duo/mbox/CMakeLists.txt new file mode 100644 index 000000000000..df3628878637 --- /dev/null +++ b/samples/boards/milkv_duo/mbox/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(mbox) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/boards/milkv_duo/mbox/boards/milkv_duo.overlay b/samples/boards/milkv_duo/mbox/boards/milkv_duo.overlay new file mode 100644 index 000000000000..2fc7f198f82f --- /dev/null +++ b/samples/boards/milkv_duo/mbox/boards/milkv_duo.overlay @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2024 honglin leng + * SPDX-License-Identifier: Apache-2.0 + */ + +&mbox { + status = "okay"; +}; diff --git a/samples/boards/milkv_duo/mbox/prj.conf b/samples/boards/milkv_duo/mbox/prj.conf new file mode 100644 index 000000000000..5eaa6dd76ab3 --- /dev/null +++ b/samples/boards/milkv_duo/mbox/prj.conf @@ -0,0 +1,4 @@ +CONFIG_PRINTK=y +CONFIG_MBOX=y +CONFIG_LOG=y +CONFIG_GPIO=y diff --git a/samples/boards/milkv_duo/mbox/src/main.c b/samples/boards/milkv_duo/mbox/src/main.c new file mode 100644 index 000000000000..68a0d27caf12 --- /dev/null +++ b/samples/boards/milkv_duo/mbox/src/main.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2024 honglin leng + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#define TX_ID (1) +#define RX_ID (0) + +#define QUEUE_DEPTH 10 + +struct k_msgq msgq; + +static const struct device *mbox = DEVICE_DT_GET(DT_NODELABEL(mbox)); +static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios); + +struct valid_t { + unsigned char linux_valid; + unsigned char rtos_valid; +}; +typedef union resv_t { + struct valid_t valid; + unsigned short mstime; +} resv_t; + +typedef struct cmdqu_t cmdqu_t; +/* cmdqu size should be 8 bytes because of mailbox buffer size */ +struct cmdqu_t { + unsigned char ip_id; + unsigned char cmd_id: 7; + unsigned char block: 1; + union resv_t resv; + unsigned int param_ptr; +} __packed; + +enum SYS_CMD_ID { + CMD_TEST_A = 0x10, + CMD_TEST_B, + CMD_TEST_C, + CMD_DUO_LED, + SYS_CMD_INFO_LIMIT, +}; + +enum DUO_LED_STATUS { + DUO_LED_ON = 0x02, + DUO_LED_OFF, + DUO_LED_DONE, +}; + +cmdqu_t main_cmdq[QUEUE_DEPTH]; + +static void callback(const struct device *dev, uint32_t channel, void *user_data, + struct mbox_msg *data) +{ + cmdqu_t cmdq; + + memcpy(&cmdq, data->data, sizeof(cmdqu_t)); + k_msgq_put(&msgq, &cmdq, K_NO_WAIT); +} + +int main(void) +{ + struct mbox_channel tx_channel; + struct mbox_channel rx_channel; + struct mbox_msg mbox_msg; + int ret; + cmdqu_t cmdq; + + k_msgq_init(&msgq, (char *)main_cmdq, sizeof(cmdqu_t), QUEUE_DEPTH); + + mbox_init_channel(&tx_channel, mbox, TX_ID); + mbox_init_channel(&rx_channel, mbox, RX_ID); + + if (mbox_register_callback(&rx_channel, callback, NULL)) { + printk("mbox_register_callback() error\n"); + return 0; + } + + if (mbox_set_enabled(&rx_channel, 1)) { + printk("mbox_set_enable() error\n"); + return 0; + } + + if (!gpio_is_ready_dt(&led)) { + return 0; + } + + ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE); + if (ret < 0) { + return 0; + } + + while (1) { + ret = k_msgq_get(&msgq, &cmdq, K_FOREVER); + if (ret == 0) { + printk("cmdq->ip_id =%d\n", cmdq.ip_id); + printk("cmdq->cmd_id =%d\n", cmdq.cmd_id); + printk("cmdq->param_ptr =%x\n", cmdq.param_ptr); + printk("Ping (on channel %d)\n", tx_channel.id); + + switch (cmdq.cmd_id) { + case CMD_TEST_A: + /* send to C906B */ + cmdq.cmd_id = CMD_TEST_A; + cmdq.param_ptr = 0x12345678; + cmdq.resv.valid.rtos_valid = 1; + cmdq.resv.valid.linux_valid = 0; + printk("recv cmd(%d) from C906B...send [0x%x] to C906B\n", + cmdq.cmd_id, cmdq.param_ptr); + goto send_label; + case CMD_TEST_B: + printk("nothing to do...\n"); + break; + case CMD_TEST_C: + cmdq.cmd_id = CMD_TEST_C; + cmdq.param_ptr = 0x55aa; + cmdq.resv.valid.rtos_valid = 1; + cmdq.resv.valid.linux_valid = 0; + printk("recv cmd(%d) from C906B...send [0x%x] to C906B\n", + cmdq.cmd_id, cmdq.param_ptr); + goto send_label; + case CMD_DUO_LED: + cmdq.cmd_id = CMD_DUO_LED; + printk("recv cmd(%d) from C906B, param_ptr [0x%x]\n", cmdq.cmd_id, + cmdq.param_ptr); + if (cmdq.param_ptr == DUO_LED_ON) { + gpio_pin_set_dt(&led, 1); + } else { + gpio_pin_set_dt(&led, 0); + } + cmdq.param_ptr = DUO_LED_DONE; + cmdq.resv.valid.rtos_valid = 1; + cmdq.resv.valid.linux_valid = 0; + printk("recv cmd(%d) from C906B...send [0x%x] to C906B\n", + cmdq.cmd_id, cmdq.param_ptr); + goto send_label; + default: + send_label: + mbox_msg.data = &cmdq; + mbox_msg.size = sizeof(cmdqu_t); + if (mbox_send(&tx_channel, &mbox_msg) < 0) { + printk("mbox_send() error\n"); + return 0; + } + break; + } + } + } + return 0; +} diff --git a/soc/riscv/riscv-privileged/sophgo/CMakeLists.txt b/soc/riscv/riscv-privileged/sophgo/CMakeLists.txt new file mode 100644 index 000000000000..187982e82160 --- /dev/null +++ b/soc/riscv/riscv-privileged/sophgo/CMakeLists.txt @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/riscv-privileged/sophgo/Kconfig.defconfig.cv180x b/soc/riscv/riscv-privileged/sophgo/Kconfig.defconfig.cv180x new file mode 100644 index 000000000000..2dab4722748a --- /dev/null +++ b/soc/riscv/riscv-privileged/sophgo/Kconfig.defconfig.cv180x @@ -0,0 +1,31 @@ +# Copyright (c) 2023-2024 Chen Xingyu +# SPDX-License-Identifier: Apache-2.0 + +if SOC_CV180X + +config SOC + default "cv180x" + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 25000000 + +config NUM_IRQS + int + default 128 + +config RISCV_GP + default y + +config RISCV_SOC_INTERRUPT_INIT + default y + +config RISCV_HAS_PLIC + default y + +config PLIC_HAS_EDGE_TRIGGER + default n + +config 2ND_LVL_INTR_00_OFFSET + default 11 + +endif # SOC_CV180X diff --git a/soc/riscv/riscv-privileged/sophgo/Kconfig.defconfig.series b/soc/riscv/riscv-privileged/sophgo/Kconfig.defconfig.series new file mode 100644 index 000000000000..5df2b7ec9fbd --- /dev/null +++ b/soc/riscv/riscv-privileged/sophgo/Kconfig.defconfig.series @@ -0,0 +1,11 @@ +# Copyright (c) 2023-2024 Chen Xingyu +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_SOPHGO + +config SOC_SERIES + default "sophgo" + +rsource "Kconfig.defconfig.cv180x" + +endif # SOC_SERIES_SOPHGO diff --git a/soc/riscv/riscv-privileged/sophgo/Kconfig.series b/soc/riscv/riscv-privileged/sophgo/Kconfig.series new file mode 100644 index 000000000000..8339eddf3437 --- /dev/null +++ b/soc/riscv/riscv-privileged/sophgo/Kconfig.series @@ -0,0 +1,9 @@ +# Copyright (c) 2023-2024 Chen Xingyu +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_SOPHGO + bool "SOPHGO RISC-V series" + select RISCV + select SOC_FAMILY_RISCV_PRIVILEGED + select INCLUDE_RESET_VECTOR + select ATOMIC_OPERATIONS_C diff --git a/soc/riscv/riscv-privileged/sophgo/Kconfig.soc b/soc/riscv/riscv-privileged/sophgo/Kconfig.soc new file mode 100644 index 000000000000..ac9c9bc82134 --- /dev/null +++ b/soc/riscv/riscv-privileged/sophgo/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2023-2024 Chen Xingyu +# SPDX-License-Identifier: Apache-2.0 + +rsource "Kconfig.soc.cv180x" diff --git a/soc/riscv/riscv-privileged/sophgo/Kconfig.soc.cv180x b/soc/riscv/riscv-privileged/sophgo/Kconfig.soc.cv180x new file mode 100644 index 000000000000..bae795863387 --- /dev/null +++ b/soc/riscv/riscv-privileged/sophgo/Kconfig.soc.cv180x @@ -0,0 +1,15 @@ +# Copyright (c) 2023-2024 Chen Xingyu +# SPDX-License-Identifier: Apache-2.0 + +config SOC_CV180X + bool "SOPHGO CV180x" + depends on SOC_SERIES_SOPHGO + select 64BIT + select RISCV_ISA_RV64I + select RISCV_ISA_EXT_M + select RISCV_ISA_EXT_A + select RISCV_ISA_EXT_F + select RISCV_ISA_EXT_D + select RISCV_ISA_EXT_C + select RISCV_ISA_EXT_ZICSR + select RISCV_ISA_EXT_ZIFENCEI diff --git a/soc/riscv/riscv-privileged/sophgo/pinctrl_soc.h b/soc/riscv/riscv-privileged/sophgo/pinctrl_soc.h new file mode 100644 index 000000000000..486f64f0412c --- /dev/null +++ b/soc/riscv/riscv-privileged/sophgo/pinctrl_soc.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023-2024 Chen Xingyu + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __SOC_SOPHGO_PINCTRL_H__ +#define __SOC_SOPHGO_PINCTRL_H__ + +#include +#include + +struct pinctrl_soc_pin { + uint32_t fmux_idx; + uint32_t fmux_sel; +}; + +typedef struct pinctrl_soc_pin pinctrl_soc_pin_t; + +#define SOPHGO_PINMUX_GET(pinmux, field) \ + ((pinmux >> SOPHGO_PINMUX_##field##_S) & SOPHGO_PINMUX_##field##_M) + +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + { \ + .fmux_idx = SOPHGO_PINMUX_GET(DT_PROP_BY_IDX(node_id, prop, idx), FMUX_IDX), \ + .fmux_sel = SOPHGO_PINMUX_GET(DT_PROP_BY_IDX(node_id, prop, idx), FMUX_SEL), \ + }, + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + { \ + DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, pinmux, \ + Z_PINCTRL_STATE_PIN_INIT) \ + } + +#endif /* __SOC_SOPHGO_PINCTRL_H__ */ diff --git a/soc/riscv/riscv-privileged/sophgo/soc.h b/soc/riscv/riscv-privileged/sophgo/soc.h new file mode 100644 index 000000000000..89eca6edc450 --- /dev/null +++ b/soc/riscv/riscv-privileged/sophgo/soc.h @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2023-2024 Chen Xingyu + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __SOC_H__ +#define __SOC_H__ + +#include + +#endif /* __SOC_H__ */ diff --git a/tests/drivers/pwm/pwm_api/boards/milkv_duo.overlay b/tests/drivers/pwm/pwm_api/boards/milkv_duo.overlay new file mode 100644 index 000000000000..0da38cc9b111 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/milkv_duo.overlay @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023-2024 Chen Xingyu + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + pwm-0 = &pwm1; + }; +}; + +&pinctrl { + pwm1_default: pwm1_default { + group1 { + pinmux = ; + }; + }; +}; + +&pwm1 { + status = "okay"; + pinctrl-0 = <&pwm1_default>; + pinctrl-names = "default"; +}; diff --git a/tests/drivers/pwm/pwm_api/src/test_pwm.c b/tests/drivers/pwm/pwm_api/src/test_pwm.c index 867025d99b14..4e1d49a19515 100644 --- a/tests/drivers/pwm/pwm_api/src/test_pwm.c +++ b/tests/drivers/pwm/pwm_api/src/test_pwm.c @@ -83,6 +83,8 @@ #define DEFAULT_PWM_PORT 7 /* D3 on Arduino connector J27 */ #elif defined CONFIG_BOARD_LPCXPRESSO55S69_CPU0 #define DEFAULT_PWM_PORT 2 /* D2 on Arduino connector P18 */ +#elif defined CONFIG_BOARD_MILKV_DUO +#define DEFAULT_PWM_PORT 1 #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_pwm) /* Default port should be adapted per board to fit the channel * associated to the PWM pin. For intsance, for following device,