Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

适配 Milk-V Duo #1

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions boards/riscv/milkv_duo/Kconfig.board
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copyright (c) 2023-2024 Chen Xingyu <[email protected]>
# SPDX-License-Identifier: Apache-2.0

config BOARD_MILKV_DUO
bool "Milk-V Duo"
depends on SOC_CV180X
9 changes: 9 additions & 0 deletions boards/riscv/milkv_duo/Kconfig.defconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2023-2024 Chen Xingyu <[email protected]>
# SPDX-License-Identifier: Apache-2.0

if BOARD_MILKV_DUO

config BOARD
default "milkv_duo"

endif # BOARD_MILKV_DUO
79 changes: 79 additions & 0 deletions boards/riscv/milkv_duo/doc/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
.. milkv_duo:

Milk-V Duo
##########

Overview
********
See <https://milkv.io/duo>.

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 <https://github.com/milkv-duo/duo-buildroot-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 <https://github.com/milkv-duo/duo-buildroot-sdk/blob/develop/build/boards/cv180x/cv1800b_milkv_duo_sd/u-boot/cvi_board_init.c>`_
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``.
59 changes: 59 additions & 0 deletions boards/riscv/milkv_duo/milkv_duo.dts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2023-2024 Chen Xingyu <[email protected]>
* SPDX-License-Identifier: Apache-2.0
*/

/dts-v1/;

#include <sophgo/cv180x.dtsi>
#include <zephyr/dt-bindings/gpio/gpio.h>

/ {
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 = <SOPHGO_PINMUX(IIC0_SCL, UART1_TX)>,
<SOPHGO_PINMUX(IIC0_SDA, UART1_RX)>;
};
};
};

&gpioc {
status = "okay";
};

&uart1 {
status = "okay";
pinctrl-0 = <&uart1_default>;
pinctrl-names = "default";
current-speed = <115200>;
};
11 changes: 11 additions & 0 deletions boards/riscv/milkv_duo/milkv_duo.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
identifier: milkv_duo
name: Milk-V Duo
type: mcu
arch: riscv64
toolchain:
- zephyr
supported:
- clock
- gpio
- interrupt-controller
- serial
14 changes: 14 additions & 0 deletions boards/riscv/milkv_duo/milkv_duo_defconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright (c) 2023-2024 Chen Xingyu <[email protected]>
# 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
4 changes: 2 additions & 2 deletions drivers/gpio/gpio_dw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down
6 changes: 6 additions & 0 deletions drivers/interrupt_controller/Kconfig.plic
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions drivers/interrupt_controller/intc_plic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions drivers/mbox/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
1 change: 1 addition & 0 deletions drivers/mbox/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
9 changes: 9 additions & 0 deletions drivers/mbox/Kconfig.sophgo
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2024 honglin leng <[email protected]>
# 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.
139 changes: 139 additions & 0 deletions drivers/mbox/mbox_sophgo_cv18xx.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* Copyright (c) 2024 honglin leng <[email protected]>
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/drivers/mbox.h>
#include <zephyr/irq.h>
#include <string.h>

#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);
1 change: 1 addition & 0 deletions drivers/pinctrl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Loading