diff --git a/build/boards/cv180x/cv1800b_milkv_duo_musl_riscv64_sd/linux/cvitek_cv1800b_milkv_duo_musl_riscv64_sd_defconfig b/build/boards/cv180x/cv1800b_milkv_duo_musl_riscv64_sd/linux/cvitek_cv1800b_milkv_duo_musl_riscv64_sd_defconfig index 8491646cb4..59109a2430 100644 --- a/build/boards/cv180x/cv1800b_milkv_duo_musl_riscv64_sd/linux/cvitek_cv1800b_milkv_duo_musl_riscv64_sd_defconfig +++ b/build/boards/cv180x/cv1800b_milkv_duo_musl_riscv64_sd/linux/cvitek_cv1800b_milkv_duo_musl_riscv64_sd_defconfig @@ -208,6 +208,11 @@ CONFIG_FB_TFT=y CONFIG_FB_TFT_SSD1306=y CONFIG_FB_TFT_ST7789V=y # CONFIG_IOMMU_SUPPORT is not set +CONFIG_REMOTEPROC=y +CONFIG_REMOTEPROC_CDEV=y +CONFIG_CVITEK_REMOTEPROC=y +CONFIG_RPMSG_CHAR=y +CONFIG_RPMSG_VIRTIO=y CONFIG_CV1835_SYSDMA_REMAP=y CONFIG_PWM=y CONFIG_SIFIVE_PLIC=y diff --git a/build/boards/cv180x/cv1800b_milkv_duo_musl_riscv64_sd/memmap.py b/build/boards/cv180x/cv1800b_milkv_duo_musl_riscv64_sd/memmap.py index c925028096..78188b07ff 100644 --- a/build/boards/cv180x/cv1800b_milkv_duo_musl_riscv64_sd/memmap.py +++ b/build/boards/cv180x/cv1800b_milkv_duo_musl_riscv64_sd/memmap.py @@ -42,7 +42,7 @@ class MemoryMap: # ================= # Multimedia buffer. Used by u-boot/kernel/FreeRTOS # ================= - ION_SIZE = 26.5 * SIZE_1M + ION_SIZE = 0 * SIZE_1M H26X_BITSTREAM_SIZE = 0 * SIZE_1M H26X_ENC_BUFF_SIZE = 0 ISP_MEM_BASE_SIZE = 0 * SIZE_1M diff --git a/build/boards/cv181x/sg2000_milkv_duos_musl_riscv64_sd/linux/cvitek_sg2000_milkv_duos_musl_riscv64_sd_defconfig b/build/boards/cv181x/sg2000_milkv_duos_musl_riscv64_sd/linux/cvitek_sg2000_milkv_duos_musl_riscv64_sd_defconfig index 5b1067cf11..b5ae384cc4 100644 --- a/build/boards/cv181x/sg2000_milkv_duos_musl_riscv64_sd/linux/cvitek_sg2000_milkv_duos_musl_riscv64_sd_defconfig +++ b/build/boards/cv181x/sg2000_milkv_duos_musl_riscv64_sd/linux/cvitek_sg2000_milkv_duos_musl_riscv64_sd_defconfig @@ -263,3 +263,8 @@ CONFIG_DYNAMIC_DEBUG=y # CONFIG_RCU_TRACE is not set # CONFIG_FTRACE is not set # CONFIG_RUNTIME_TESTING_MENU is not set +CONFIG_REMOTEPROC=y +CONFIG_REMOTEPROC_CDEV=y +CONFIG_CVITEK_REMOTEPROC=y +CONFIG_RPMSG_CHAR=y +CONFIG_RPMSG_VIRTIO=y \ No newline at end of file diff --git a/build/boards/cv181x/sg2002_milkv_duo256m_musl_riscv64_sd/linux/cvitek_sg2002_milkv_duo256m_musl_riscv64_sd_defconfig b/build/boards/cv181x/sg2002_milkv_duo256m_musl_riscv64_sd/linux/cvitek_sg2002_milkv_duo256m_musl_riscv64_sd_defconfig index e5824f7b96..a2c96dee1c 100644 --- a/build/boards/cv181x/sg2002_milkv_duo256m_musl_riscv64_sd/linux/cvitek_sg2002_milkv_duo256m_musl_riscv64_sd_defconfig +++ b/build/boards/cv181x/sg2002_milkv_duo256m_musl_riscv64_sd/linux/cvitek_sg2002_milkv_duo256m_musl_riscv64_sd_defconfig @@ -203,6 +203,11 @@ CONFIG_ION_SYSTEM_HEAP=y CONFIG_ION_CARVEOUT_HEAP=y CONFIG_ION_CMA_HEAP=y # CONFIG_IOMMU_SUPPORT is not set +CONFIG_REMOTEPROC=y +CONFIG_REMOTEPROC_CDEV=y +CONFIG_CVITEK_REMOTEPROC=y +CONFIG_RPMSG_CHAR=y +CONFIG_RPMSG_VIRTIO=y CONFIG_CV1835_SYSDMA_REMAP=y CONFIG_PWM=y CONFIG_SIFIVE_PLIC=y diff --git a/build/boards/default/dts/cv180x/cv180x_default_memmap.dtsi b/build/boards/default/dts/cv180x/cv180x_default_memmap.dtsi index bb362511c5..c98be2f632 100644 --- a/build/boards/default/dts/cv180x/cv180x_default_memmap.dtsi +++ b/build/boards/default/dts/cv180x/cv180x_default_memmap.dtsi @@ -21,5 +21,19 @@ compatible = "ion-region"; size = <0x0 CVIMMAP_ION_SIZE>; }; + + + c906l: rtos_dram@CVIMMAP_FREERTOS_ADDR { + reg = <0x0 CVIMMAP_FREERTOS_ADDR 0x0 CVIMMAP_FREERTOS_SIZE>; + no-map; + }; + }; + + c906l_rproc: c906l_rproc@0 { + compatible = "cvitek,cv18xx-c906l-rproc"; + memory-region = <&c906l>; + core-name = "cv18xx-c906l"; + firmware-name = "cvirtos.elf"; + status = "okay"; }; }; diff --git a/build/boards/default/dts/cv181x/cv181x_default_memmap.dtsi b/build/boards/default/dts/cv181x/cv181x_default_memmap.dtsi index bb362511c5..c98be2f632 100644 --- a/build/boards/default/dts/cv181x/cv181x_default_memmap.dtsi +++ b/build/boards/default/dts/cv181x/cv181x_default_memmap.dtsi @@ -21,5 +21,19 @@ compatible = "ion-region"; size = <0x0 CVIMMAP_ION_SIZE>; }; + + + c906l: rtos_dram@CVIMMAP_FREERTOS_ADDR { + reg = <0x0 CVIMMAP_FREERTOS_ADDR 0x0 CVIMMAP_FREERTOS_SIZE>; + no-map; + }; + }; + + c906l_rproc: c906l_rproc@0 { + compatible = "cvitek,cv18xx-c906l-rproc"; + memory-region = <&c906l>; + core-name = "cv18xx-c906l"; + firmware-name = "cvirtos.elf"; + status = "okay"; }; }; diff --git a/cvi_mpi/sample/vdec/Makefile b/cvi_mpi/sample/vdec/Makefile index 1427840c0f..fd33a151fc 100644 --- a/cvi_mpi/sample/vdec/Makefile +++ b/cvi_mpi/sample/vdec/Makefile @@ -36,9 +36,9 @@ VDEC_DEPS = $(VDEC_SRCS:.c=.d) TARGET = sample_vdec ifeq ($(TARGET_MACHINE),arm-linux-gnueabihf) -TARGET_WITH_ASAN = sample_vdec_asan +#TARGET_WITH_ASAN = sample_vdec_asan else ifeq ($(TARGET_MACHINE),aarch64-linux-gnu) -TARGET_WITH_ASAN = sample_vdec_asan +#TARGET_WITH_ASAN = sample_vdec_asan else TARGET_WITH_ASAN = endif diff --git a/cvi_mpi/sample/vdecvo/Makefile b/cvi_mpi/sample/vdecvo/Makefile index 4464df954c..ddeb91d8d2 100644 --- a/cvi_mpi/sample/vdecvo/Makefile +++ b/cvi_mpi/sample/vdecvo/Makefile @@ -24,9 +24,9 @@ VDEC_DEPS = $(VDEC_SRCS:.c=.d) TARGET = sample_vdecvo # ifeq ($(TARGET_MACHINE), arm-linux-gnueabihf) -TARGET_WITH_ASAN = sample_vdecvo_asan +#TARGET_WITH_ASAN = sample_vdecvo_asan else ifeq ($(TARGET_MACHINE), aarch64-linux-gnu) -TARGET_WITH_ASAN = sample_vdecvo_asan +#TARGET_WITH_ASAN = sample_vdecvo_asan else TARGET_WITH_ASAN = endif diff --git a/cvi_mpi/sample/venc/Makefile b/cvi_mpi/sample/venc/Makefile index f7b7fd4ba3..6d0df3290c 100644 --- a/cvi_mpi/sample/venc/Makefile +++ b/cvi_mpi/sample/venc/Makefile @@ -45,11 +45,11 @@ VCODEC_DEPS = $(VCODEC_SRCS:.c=.d) TARGET_VENC = sample_venc TARGET_VCODEC = sample_vcodec ifeq ($(TARGET_MACHINE),arm-linux-gnueabihf) -TARGET_VENC_WITH_ASAN = sample_venc_asan -TARGET_VCODEC_WITH_ASAN = sample_vcodec_asan +#TARGET_VENC_WITH_ASAN = sample_venc_asan +#TARGET_VCODEC_WITH_ASAN = sample_vcodec_asan else ifeq ($(TARGET_MACHINE), aarch64-linux-gnu) -TARGET_VENC_WITH_ASAN = sample_venc_asan -TARGET_VCODEC_WITH_ASAN = sample_vcodec_asan +#TARGET_VENC_WITH_ASAN = sample_venc_asan +#TARGET_VCODEC_WITH_ASAN = sample_vcodec_asan else TARGET_VENC_WITH_ASAN = TARGET_VCODEC_WITH_ASAN = @@ -67,7 +67,7 @@ endif EXTRA_CFLAGS = $(INCS) $(DEFS) EXTRA_LDFLAGS = $(LIBS) -lini -lpthread - +EXTRA_LDFLAGS = $(LIBS) -lpthread -lm -lini -latomic EXTRA_LDFLAGS_WITH_ASAN = -Wl,-Bdynamic $(LIBS) -lini -lpthread ifeq ($(DEBUG), 1) diff --git a/device/generic/rootfs_overlay/common/mnt/system/burnd b/device/generic/rootfs_overlay/common/mnt/system/burnd new file mode 100644 index 0000000000..8a68ec8890 Binary files /dev/null and b/device/generic/rootfs_overlay/common/mnt/system/burnd differ diff --git a/device/generic/rootfs_overlay/duo256m/mnt/system/usb-ncm.sh b/device/generic/rootfs_overlay/duo256m/mnt/system/usb-ncm.sh index ec5be66255..a2681f0242 100755 --- a/device/generic/rootfs_overlay/duo256m/mnt/system/usb-ncm.sh +++ b/device/generic/rootfs_overlay/duo256m/mnt/system/usb-ncm.sh @@ -2,6 +2,9 @@ /etc/uhubon.sh device >> /tmp/ncm.log 2>&1 /etc/run_usb.sh probe ncm >> /tmp/ncm.log 2>&1 +if test -e /mnt/system/burnd; then + /etc/run_usb.sh probe acm >> /tmp/ncm.log 2>&1 +fi /etc/run_usb.sh start ncm >> /tmp/ncm.log 2>&1 sleep 0.5 @@ -13,3 +16,13 @@ if [ ${count} -lt 1 ] ;then /etc/init.d/S80dnsmasq start >> /tmp/ncm.log 2>&1 fi +sleep 2 +mkdir -p /lib/firmware +if test -e /mnt/system/burnd; then + burnd & + if test -e /lib/firmware/arduino.elf; then + sleep 2 + echo stop > /sys/class/remoteproc/remoteproc0/state + echo start > /sys/class/remoteproc/remoteproc0/state + fi +fi diff --git a/device/generic/rootfs_overlay/duos/mnt/system/usb-ncm.sh b/device/generic/rootfs_overlay/duos/mnt/system/usb-ncm.sh index bf91939360..b8b8c72adf 100755 --- a/device/generic/rootfs_overlay/duos/mnt/system/usb-ncm.sh +++ b/device/generic/rootfs_overlay/duos/mnt/system/usb-ncm.sh @@ -27,6 +27,9 @@ sleep 0.5 /etc/uhubon.sh device >> /tmp/ncm.log 2>&1 /etc/run_usb.sh probe ncm >> /tmp/ncm.log 2>&1 +if test -e /mnt/system/burnd; then + /etc/run_usb.sh probe acm >> /tmp/ncm.log 2>&1 +fi /etc/run_usb.sh start ncm >> /tmp/ncm.log 2>&1 sleep 0.5 @@ -38,3 +41,13 @@ if [ ${count} -lt 1 ] ;then /etc/init.d/S80dnsmasq start >> /tmp/ncm.log 2>&1 fi +sleep 2 +mkdir -p /lib/firmware +if test -e /mnt/system/burnd; then + burnd & + if test -e /lib/firmware/arduino.elf; then + sleep 2 + echo stop > /sys/class/remoteproc/remoteproc0/state + echo start > /sys/class/remoteproc/remoteproc0/state + fi +fi diff --git a/linux_5.10/arch/riscv/kernel/setup.c b/linux_5.10/arch/riscv/kernel/setup.c index 117f3212a8..49d262cd00 100644 --- a/linux_5.10/arch/riscv/kernel/setup.c +++ b/linux_5.10/arch/riscv/kernel/setup.c @@ -89,7 +89,7 @@ void __init setup_arch(char **cmdline_p) else pr_err("No DTB found in kernel mappings\n"); #endif - +early_init_fdt_scan_reserved_mem(); #ifdef CONFIG_SWIOTLB swiotlb_init(1); #endif diff --git a/linux_5.10/arch/riscv/mm/init.c b/linux_5.10/arch/riscv/mm/init.c index 016091819c..b42ccd806c 100644 --- a/linux_5.10/arch/riscv/mm/init.c +++ b/linux_5.10/arch/riscv/mm/init.c @@ -206,7 +206,6 @@ void __init setup_bootmem(void) else memblock_reserve(__pa(PAGE_OFFSET), LOAD_OFFSET); - early_init_fdt_scan_reserved_mem(); memblock_allow_resize(); memblock_dump_all(); } diff --git a/linux_5.10/drivers/of/of_reserved_mem.c b/linux_5.10/drivers/of/of_reserved_mem.c index 29750d724e..bbc072acf2 100644 --- a/linux_5.10/drivers/of/of_reserved_mem.c +++ b/linux_5.10/drivers/of/of_reserved_mem.c @@ -69,7 +69,11 @@ void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname, } rmem->fdt_node = node; +#if defined(CONFIG_ARCH_CVITEK) && !defined(CONFIG_CVITEK_REMOTEPROC) strncpy(rmem->name, uname, 8); +#else + rmem->name = uname; +#endif rmem->base = base; rmem->size = size; diff --git a/linux_5.10/drivers/remoteproc/Kconfig b/linux_5.10/drivers/remoteproc/Kconfig index d99548fb5d..5deeb6281a 100644 --- a/linux_5.10/drivers/remoteproc/Kconfig +++ b/linux_5.10/drivers/remoteproc/Kconfig @@ -288,6 +288,13 @@ config TI_K3_R5_REMOTEPROC It's safe to say N here if you're not interested in utilizing a slave processor. +config CVITEK_REMOTEPROC + tristate "cvitek remoteproc support" + depends on ARCH_CVITEK + help + Say y here to support CVITEK's processors via the remote + processor framework. + This can be either built-in or a loadable module. endif # REMOTEPROC endmenu diff --git a/linux_5.10/drivers/remoteproc/Makefile b/linux_5.10/drivers/remoteproc/Makefile index da2ace4ec8..331d4f381e 100644 --- a/linux_5.10/drivers/remoteproc/Makefile +++ b/linux_5.10/drivers/remoteproc/Makefile @@ -34,3 +34,4 @@ obj-$(CONFIG_ST_SLIM_REMOTEPROC) += st_slim_rproc.o obj-$(CONFIG_STM32_RPROC) += stm32_rproc.o obj-$(CONFIG_TI_K3_DSP_REMOTEPROC) += ti_k3_dsp_remoteproc.o obj-$(CONFIG_TI_K3_R5_REMOTEPROC) += ti_k3_r5_remoteproc.o +obj-$(CONFIG_CVITEK_REMOTEPROC) += cvitek_remoteproc.o \ No newline at end of file diff --git a/linux_5.10/drivers/remoteproc/cvitek_remoteproc.c b/linux_5.10/drivers/remoteproc/cvitek_remoteproc.c new file mode 100644 index 0000000000..d31ba16a6e --- /dev/null +++ b/linux_5.10/drivers/remoteproc/cvitek_remoteproc.c @@ -0,0 +1,268 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "remoteproc_internal.h" + +#define SEC_SUBSYS_BASE 0x02000000 +#define SEC_SYS_BASE (SEC_SUBSYS_BASE + 0x000B0000) +#define SEC_CLK_ADDR ((__u32)0x3003024) + +struct cvitek_rproc_mem { + void __iomem *cpu_addr; + phys_addr_t bus_addr; + u32 dev_addr; + size_t size; +}; + +struct cvitek_rproc { + struct rproc *rproc; + struct cvitek_rproc_mem mem[4]; + struct reset_control *reset; + struct clk *clk; + u32 clk_rate; + struct regmap *boot_base; + u32 boot_offset; + int num_mems; + struct platform_device *pdev; +}; + +static inline void clrbits_32(void __iomem *reg, u32 clear) +{ + iowrite32((ioread32(reg) & ~clear), reg); +} + +static inline void setbits_32(void __iomem *reg, u32 set) +{ + iowrite32(ioread32(reg) | set, reg); +} + +static int cvitek_rproc_start(struct rproc *rproc) +{ + struct device *dev = rproc->dev.parent; + + void __iomem *clk_reset = ioremap(SEC_CLK_ADDR, 4); + + clrbits_32(clk_reset, 1 << 6); + + udelay(10); + + setbits_32(clk_reset, 1 << 6); + + iounmap(clk_reset); + + dev_info(dev, "Started from 0x%llx\n", rproc->bootaddr); + + return 0; +} + +static int cvitek_rproc_stop(struct rproc *rproc) +{ + void __iomem *clk_reset = ioremap(SEC_CLK_ADDR, 4); + + clrbits_32(clk_reset, 1 << 6); + + iounmap(clk_reset); + + return 0; +} + +static int cvitek_rproc_mem_alloc(struct rproc *rproc, + struct rproc_mem_entry *mem) +{ + struct device *dev = rproc->dev.parent; + void *va; + + va = ioremap_wc(mem->dma, mem->len); + if (!va) { + dev_err(dev, "Unable to map memory region: %pa+%zx\n", + &mem->dma, mem->len); + return -ENOMEM; + } + + /* Update memory entry va */ + mem->va = va; + + return 0; +} + +static int cvitek_rproc_mem_release(struct rproc *rproc, + struct rproc_mem_entry *mem) +{ + iounmap(mem->va); + + return 0; +} + +static int cvitek_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw) +{ + struct device *dev = rproc->dev.parent; + struct device_node *np = dev->of_node; + struct rproc_mem_entry *mem; + struct reserved_mem *rmem; + struct of_phandle_iterator it; + int index = 0; + + of_phandle_iterator_init(&it, np, "memory-region", NULL, 0); + while (of_phandle_iterator_next(&it) == 0) { + rmem = of_reserved_mem_lookup(it.node); + if (!rmem) { + dev_err(dev, "unable to acquire memory-region\n"); + return -EINVAL; + } + + /* No need to map vdev buffer */ + if (strcmp(it.node->name, "vdev0buffer")) { + /* Register memory region */ + mem = rproc_mem_entry_init( + dev, NULL, (dma_addr_t)rmem->base, rmem->size, + rmem->base, cvitek_rproc_mem_alloc, + cvitek_rproc_mem_release, it.node->name); + } else { + /* Register reserved memory for vdev buffer allocation */ + mem = rproc_of_resm_mem_entry_init(dev, index, + rmem->size, + rmem->base, + it.node->name); + } + + if (!mem) + return -ENOMEM; + + rproc_add_carveout(rproc, mem); + index++; + } + + if (rproc_elf_load_rsc_table(rproc, fw)) + dev_warn(&rproc->dev, "no resource table found for this firmware\n"); + + return 0; +} + +static const struct rproc_ops cvitek_rproc_ops = { + .start = cvitek_rproc_start, + .stop = cvitek_rproc_stop, + .parse_fw = cvitek_rproc_parse_fw, + .load = rproc_elf_load_segments, + .find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table, + .sanity_check = rproc_elf_sanity_check, + .get_boot_addr = rproc_elf_get_boot_addr, +}; + +static const struct of_device_id cvitek_rproc_match[] = { + { .compatible = "cvitek,cv18xx-c906l-rproc", }, + {}, +}; +MODULE_DEVICE_TABLE(of, cvitek_rproc_match); + +static const char *cvitek_rproc_get_firmware(struct platform_device *pdev) +{ + const char *fw_name; + int ret; + + ret = of_property_read_string(pdev->dev.of_node, "firmware-name", + &fw_name); + if (ret) + return ERR_PTR(ret); + + return fw_name; +} + +static int cvitek_rproc_parse_dt(struct platform_device *pdev) +{ + //TODO + return 0; +} + +static int cvitek_rproc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + const struct of_device_id *match; + struct cvitek_rproc *cproc; + struct device_node *np = dev->of_node; + struct rproc *rproc; + const char *firmware; + int ret; + int i; + + match = of_match_device(cvitek_rproc_match, dev); + if (!match) { + dev_err(dev, "No device match found\n"); + return -ENODEV; + } + + firmware = cvitek_rproc_get_firmware(pdev); + if (IS_ERR(firmware)) + return PTR_ERR(firmware); + + rproc = rproc_alloc(dev, dev_name(dev), &cvitek_rproc_ops, firmware, + sizeof(*cproc)); + if (!rproc) + return -ENOMEM; + + cproc = rproc->priv; + + rproc->has_iommu = false; + cproc->pdev = pdev; + + platform_set_drvdata(pdev, rproc); + + ret = cvitek_rproc_parse_dt(pdev); + if (ret) + goto free_rproc; + + ret = rproc_add(rproc); + if (ret) + goto free_clk; + + return 0; + +free_clk: + clk_unprepare(cproc->clk); + +free_rproc: + rproc_free(rproc); + return ret; +} + +static int cvitek_rproc_remove(struct platform_device *pdev) +{ + struct rproc *rproc = platform_get_drvdata(pdev); + struct cvitek_rproc *cproc = rproc->priv; + int i; + + rproc_del(rproc); + + clk_disable_unprepare(cproc->clk); + + rproc_free(rproc); + + return 0; +} + +static struct platform_driver cvitek_rproc_driver = { + .probe = cvitek_rproc_probe, + .remove = cvitek_rproc_remove, + .driver = { + .name = "cvitek-rproc", + .of_match_table = of_match_ptr(cvitek_rproc_match), + }, +}; +module_platform_driver(cvitek_rproc_driver); +MODULE_DESCRIPTION("Cvitek Remote Processor Control Driver"); +MODULE_LICENSE("GPL v2"); \ No newline at end of file diff --git a/linux_5.10/include/linux/of_reserved_mem.h b/linux_5.10/include/linux/of_reserved_mem.h index e418313a50..5ddc2c4232 100644 --- a/linux_5.10/include/linux/of_reserved_mem.h +++ b/linux_5.10/include/linux/of_reserved_mem.h @@ -9,7 +9,11 @@ struct of_phandle_args; struct reserved_mem_ops; struct reserved_mem { +#if defined(CONFIG_ARCH_CVITEK) && !defined(CONFIG_CVITEK_REMOTEPROC) char name[8]; +#else + char *name; +#endif unsigned long fdt_node; unsigned long phandle; const struct reserved_mem_ops *ops;