diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 95ff7342ab3d..43c79cf02f38 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -1201,12 +1201,14 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ rv1126b-evb2-v10-tb-400w-spi-nor.dtb \ rv1126b-evb2-v12.dtb \ rv1126b-evb2-v12-aov-dual-cam.dtb \ + rv1126b-evb2-v12-fastboot-emmc.dtb \ rv1126b-evb3-v10.dtb \ rv1126b-evb4-v10.dtb \ rv1126b-iotest-v10.dtb \ rv1126bp-evb-v14.dtb \ rv1126bp-evb-v14-dual-cam.dtb \ rv1126bp-evb1-v12.dtb \ + rv1126bp-evb1-v12-fastboot-emmc.dtb \ rk3036-evb.dtb \ rk3036-evb1-ddr3-v10.dtb \ rk3036-kylin.dtb \ diff --git a/arch/arm/boot/dts/rv1126b-evb2-v12-fastboot-emmc.dts b/arch/arm/boot/dts/rv1126b-evb2-v12-fastboot-emmc.dts new file mode 100644 index 000000000000..446a1569b8f8 --- /dev/null +++ b/arch/arm/boot/dts/rv1126b-evb2-v12-fastboot-emmc.dts @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + */ + +#include "arm64/rockchip/rv1126b-evb2-v12-fastboot-emmc.dts" + +/ { + model = "Rockchip RV1126B EVB2 V12 Board"; + compatible = "rockchip,rv1126b-evb2-v12-fastboot-emmc", "rockchip,rv1126b"; + + chosen { + bootargs = "loglevel=0 initcall_debug=0 earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 root=/dev/rd0 rootfstype=erofs rootflags=dax snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K"; + }; +}; + +&ramdisk_r { + reg = <0x48c40000 (40 * 0x00100000)>; +}; + +&ramdisk_c { + reg = <0x4b440000 (20 * 0x00100000)>; +}; diff --git a/arch/arm/boot/dts/rv1126bp-evb1-v12-fastboot-emmc.dts b/arch/arm/boot/dts/rv1126bp-evb1-v12-fastboot-emmc.dts new file mode 100644 index 000000000000..56cfb978192f --- /dev/null +++ b/arch/arm/boot/dts/rv1126bp-evb1-v12-fastboot-emmc.dts @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + */ + +#include "arm64/rockchip/rv1126bp-evb1-v12-fastboot-emmc.dts" + +/ { + model = "Rockchip RV1126B-P EVB1 V12 Fastboot Board"; + compatible = "rockchip,rv1126bp-evb1-v12-fastboot", "rockchip,rv1126b"; + + chosen { + bootargs = "loglevel=0 initcall_debug=0 earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 root=/dev/rd0 rootfstype=erofs rootflags=dax snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K"; + }; +}; + +&ramdisk_r { + reg = <0x48c40000 (40 * 0x00100000)>; +}; + +&ramdisk_c { + reg = <0x4b440000 (20 * 0x00100000)>; +}; diff --git a/arch/arm/configs/rv1126b-fastboot.config b/arch/arm/configs/rv1126b-fastboot.config index 6c54b1bdd8db..86cea8d84307 100644 --- a/arch/arm/configs/rv1126b-fastboot.config +++ b/arch/arm/configs/rv1126b-fastboot.config @@ -28,8 +28,10 @@ CONFIG_ROCKCHIP_THUNDER_BOOT=y CONFIG_ROCKCHIP_THUNDER_BOOT_DEFER_FREE_MEMBLOCK=y CONFIG_ROCKCHIP_VENDOR_STORAGE=m # CONFIG_SLUB_SYSFS is not set -# CONFIG_SND_SIMPLE_CARD is not set +CONFIG_SND_SIMPLE_CARD=m +CONFIG_SND_SIMPLE_CARD_UTILS=m CONFIG_SND_SOC_DUMMY_CODEC=m +CONFIG_SND_SOC_RK817=m CONFIG_SND_SOC_RK_DSM=m CONFIG_SND_SOC_ROCKCHIP=m CONFIG_SND_SOC_ROCKCHIP_ASRC=m @@ -551,6 +553,8 @@ CONFIG_SPI_ROCKCHIP_SFC=y # CONFIG_TI_TSC2046 is not set # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_VIDEO_GS1662 is not set +# CONFIG_VIDEO_MS41908 is not set +# CONFIG_VIDEO_MS41968 is not set # CONFIG_VIDEO_ROCKCHIP_PREISP is not set # CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP is not set CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_SETUP=y diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index bbb382e7b13c..a2129674aedc 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -402,9 +402,11 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10-mcu-k350c4516t.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10-rgb-Q7050ITH2641AA1T.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10-sii9022-bt1120-to-hdmi.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v12.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v12-fastboot-emmc.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb3-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb4-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-iotest-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126bp-evb-v14.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126bp-evb-v14-dual-cam.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126bp-evb1-v12.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126bp-evb1-v12-fastboot-emmc.dtb diff --git a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v23.dts b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v23.dts index fd91b7a16ffa..2fe3877cd304 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v23.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v23.dts @@ -775,6 +775,18 @@ }; }; +&pmic_pins { + rockchip,pins = + /* pmic_int_l */ + <0 RK_PA7 0 &pcfg_pull_up>, + /* pmic_sleep1 */ + <0 RK_PA2 1 &pcfg_pull_none>, + /* pmic_sleep2 */ + <0 RK_PA3 1 &pcfg_pull_none>, + /* pmic_sleep3 */ + <0 RK_PC1 1 &pcfg_pull_none>; +}; + &rockchip_suspend { rockchip,sleep-mode-config = < (0 diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v12-fastboot-emmc.dts b/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v12-fastboot-emmc.dts new file mode 100644 index 000000000000..69d28e24ca7f --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v12-fastboot-emmc.dts @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + */ + +#include "rv1126b-evb2-v12.dts" +#include "rv1126b-fastboot-emmc.dtsi"" + +/ { + model = "Rockchip RV1126B EVB2 V12 Arm64 Fastboot Board"; + compatible = "rockchip,rv1126b-evb2-v12-fastboot", "rockchip,rv1126b"; + + chosen { + bootargs = "loglevel=0 initcall_debug=0 earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 root=/dev/rd0 rootfstype=erofs rootflags=dax snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K"; + }; +}; + +&ramdisk_r { + reg = <0x48c40000 (40 * 0x00100000)>; +}; + +&ramdisk_c { + reg = <0x4b440000 (20 * 0x00100000)>; +}; diff --git a/arch/arm64/boot/dts/rockchip/rv1126bp-evb1-v12-fastboot-emmc.dts b/arch/arm64/boot/dts/rockchip/rv1126bp-evb1-v12-fastboot-emmc.dts new file mode 100644 index 000000000000..38b20d6f0337 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rv1126bp-evb1-v12-fastboot-emmc.dts @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + */ + +#include "rv1126bp-evb1-v12.dts" +#include "rv1126b-fastboot-emmc.dtsi" + +/ { + model = "Rockchip RV1126B-P EVB1 V12 Arm64 Fastboot Board"; + compatible = "rockchip,rv1126bp-evb1-v12-fastboot", "rockchip,rv1126b"; + + chosen { + bootargs = "loglevel=0 initcall_debug=0 earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 root=/dev/rd0 rootfstype=erofs rootflags=dax snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K"; + }; +}; + +&ramdisk_r { + reg = <0x48c40000 (40 * 0x00100000)>; +}; + +&ramdisk_c { + reg = <0x4b440000 (20 * 0x00100000)>; +}; diff --git a/drivers/dma-buf/rk_heaps/rk-dma-heap.c b/drivers/dma-buf/rk_heaps/rk-dma-heap.c index def5252336b3..1c68a7549e8a 100644 --- a/drivers/dma-buf/rk_heaps/rk-dma-heap.c +++ b/drivers/dma-buf/rk_heaps/rk-dma-heap.c @@ -361,6 +361,7 @@ void rk_dma_heap_put(struct rk_dma_heap *h) kref_put(&h->refcount, rk_dma_heap_release); mutex_unlock(&rk_heap_list_lock); } +EXPORT_SYMBOL_GPL(rk_dma_heap_put); /** * rk_dma_heap_get_dev() - get device struct for the heap diff --git a/drivers/gpu/drm/rockchip/dw-dp.c b/drivers/gpu/drm/rockchip/dw-dp.c index 8b3413ab11cb..1251dda60286 100644 --- a/drivers/gpu/drm/rockchip/dw-dp.c +++ b/drivers/gpu/drm/rockchip/dw-dp.c @@ -1047,6 +1047,17 @@ static const struct dw_dp_output_format *dw_dp_get_output_format(u32 bus_format) return &possible_output_fmts[1]; } +static const struct dw_dp_output_format *dw_dp_get_bus_format_by_video_mapping(u8 video_mapping) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(possible_output_fmts); i++) + if (possible_output_fmts[i].video_mapping == video_mapping) + return &possible_output_fmts[i]; + + return &possible_output_fmts[1]; +} + static inline struct dw_dp *connector_to_dp(struct drm_connector *c) { return container_of(c, struct dw_dp, connector); @@ -1545,14 +1556,13 @@ static int dw_dp_connector_atomic_check(struct drm_connector *conn, struct drm_atomic_state *state) { struct drm_connector_state *old_state, *new_state; - struct dw_dp_state *dp_old_state, *dp_new_state; + struct dw_dp_state *dp_new_state; struct drm_crtc_state *crtc_state; struct dw_dp *dp = connector_to_dp(conn); int ret; old_state = drm_atomic_get_old_connector_state(state, conn); new_state = drm_atomic_get_new_connector_state(state, conn); - dp_old_state = connector_to_dp_state(old_state); dp_new_state = connector_to_dp_state(new_state); dw_dp_hdcp_atomic_check(conn, state); @@ -1577,10 +1587,6 @@ static int dw_dp_connector_atomic_check(struct drm_connector *conn, return -EINVAL; } - if ((dp_old_state->bpc != dp_new_state->bpc) || - (dp_old_state->color_format != dp_new_state->color_format)) - crtc_state->mode_changed = true; - if (dp->mst_mgr.cbs) { ret = drm_dp_mst_root_conn_atomic_check(new_state, &dp->mst_mgr); if (ret) @@ -3240,8 +3246,10 @@ dw_dp_bridge_mode_valid(struct drm_bridge *bridge, static void _dw_dp_loader_protect(struct dw_dp *dp, bool on) { struct dw_dp_link *link = &dp->link; + struct dw_dp_video *video = &dp->video; struct drm_connector *conn = &dp->connector; struct drm_display_info *di = &conn->display_info; + const struct dw_dp_output_format *output_format; u32 value; @@ -3287,6 +3295,10 @@ static void _dw_dp_loader_protect(struct dw_dp *dp, bool on) break; } + regmap_read(dp->regmap, DPTX_VSAMPLE_CTRL_N(0), &value); + output_format = + dw_dp_get_bus_format_by_video_mapping(FIELD_GET(VIDEO_MAPPING, value)); + video->bus_format = output_format->bus_format; extcon_set_state_sync(dp->audio->extcon, EXTCON_DISP_DP, true); dw_dp_audio_handle_plugged_change(dp->audio, true); phy_power_on(dp->phy); @@ -4751,6 +4763,9 @@ static int dw_dp_bridge_atomic_check(struct drm_bridge *bridge, bridge_state->input_bus_cfg.format, bridge_state->output_bus_cfg.format); + if (video->bus_format != fmt->bus_format) + crtc_state->mode_changed = true; + video->video_mapping = fmt->video_mapping; video->color_format = fmt->color_format; video->bus_format = fmt->bus_format; diff --git a/drivers/media/common/videobuf2/videobuf2-cma-sg.c b/drivers/media/common/videobuf2/videobuf2-cma-sg.c index b2f8340ddb7e..5b246aadb401 100644 --- a/drivers/media/common/videobuf2/videobuf2-cma-sg.c +++ b/drivers/media/common/videobuf2/videobuf2-cma-sg.c @@ -42,6 +42,8 @@ struct vb2_cma_sg_buf { struct dma_buf_attachment *db_attach; struct vb2_buffer *vb; + + struct rk_dma_heap *contig_heap; }; static void vb2_cma_sg_put(void *buf_priv); @@ -108,12 +110,14 @@ static int vb2_cma_sg_alloc_contiguous(struct vb2_cma_sg_buf *buf) struct rk_dma_heap *heap = rk_dma_heap_find("rk-dma-heap-cma"); cma_en = true; - if (heap) + if (heap) { page = rk_dma_heap_alloc_contig_pages(heap, buf->size, dev_name(buf->dev)); - else + buf->contig_heap = heap; + } else { page = cma_alloc(dev_get_cma_area(buf->dev), buf->num_pages, get_order(buf->size), GFP_KERNEL); + } } if (IS_ERR_OR_NULL(page)) { pr_err("%s: cma_en:%d alloc pages fail\n", __func__, cma_en); @@ -128,14 +132,15 @@ static int vb2_cma_sg_alloc_contiguous(struct vb2_cma_sg_buf *buf) static void vb2_cma_sg_free_contiguous(struct vb2_cma_sg_buf *buf) { if (IS_ENABLED(CONFIG_CMA)) { - struct rk_dma_heap *heap = rk_dma_heap_find("rk-dma-heap-cma"); - - if (heap) - rk_dma_heap_free_contig_pages(heap, buf->pages[0], + if (buf->contig_heap) { + rk_dma_heap_free_contig_pages(buf->contig_heap, buf->pages[0], buf->size, dev_name(buf->dev)); - else + rk_dma_heap_put(buf->contig_heap); + buf->contig_heap = NULL; + } else { cma_release(dev_get_cma_area(buf->dev), buf->pages[0], buf->num_pages); + } } } diff --git a/drivers/misc/rockchip/pcie-rkep.c b/drivers/misc/rockchip/pcie-rkep.c index 2803c59f09fd..feaa8b757636 100644 --- a/drivers/misc/rockchip/pcie-rkep.c +++ b/drivers/misc/rockchip/pcie-rkep.c @@ -34,7 +34,7 @@ #endif #define DRV_NAME "pcie-rkep" -#define DRV_VERSION 0x00030000 +#define DRV_VERSION 0x00030200 #ifndef PCI_VENDOR_ID_ROCKCHIP #define PCI_VENDOR_ID_ROCKCHIP 0x1d87 @@ -115,7 +115,6 @@ struct pcie_rkep { void __iomem *bar0; void __iomem *bar2; void __iomem *bar4; - int cur_mmap_res; struct pcie_rkep_irq_context irq_ctx[RKEP_NUM_IRQ_VECTORS]; int irq_valid; @@ -129,10 +128,22 @@ struct pcie_rkep { wait_queue_head_t wq_head; }; +struct pcie_ep_continuous_buffer_req { + struct list_head cont_buffer_list; + uint64_t dma_addr; + void *vir_addr; + u32 size; +}; + struct pcie_file { struct mutex file_lock_mutex; struct pcie_rkep *pcie_rkep; DECLARE_BITMAP(child_vid_bitmap, RKEP_EP_VIRTUAL_ID_MAX); /* The virtual IDs applied for each task */ + int cur_mmap_res; + u64 cur_mmap_addr; + + /* memory manager */ + struct list_head cont_buffer_list; }; static bool pcie_rkep_wait_for_link_up(struct pci_dev *pdev) @@ -325,6 +336,66 @@ static int rkep_ep_poll_irq_user(struct pcie_file *pcie_file, struct pcie_ep_obj return 0; } +static int rkep_mem_continuous_buffer_alloc(struct pcie_file *pcie_file, + struct pcie_ep_continuous_buffer_param *param) +{ + struct pcie_ep_continuous_buffer_req *buffer_req; + struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep; + dma_addr_t dma_addr; + void *vir_addr; + int ret = 0; + + mutex_lock(&pcie_file->file_lock_mutex); + + vir_addr = dma_alloc_coherent(&pcie_rkep->pdev->dev, param->size, + &dma_addr, GFP_KERNEL); + if (!vir_addr) { + ret = -ENOMEM; + goto unlock; + } + + buffer_req = kzalloc(sizeof(*buffer_req), GFP_KERNEL); + if (!buffer_req) { + dma_free_coherent(&pcie_rkep->pdev->dev, param->size, vir_addr, dma_addr); + ret = -ENOMEM; + goto unlock; + } + + buffer_req->dma_addr = dma_addr; + + param->dma_addr = dma_addr; + + list_add(&buffer_req->cont_buffer_list, &pcie_file->cont_buffer_list); + +unlock: + mutex_unlock(&pcie_file->file_lock_mutex); + return ret; +} + +static int rkep_mem_continuous_buffer_free(struct pcie_file *pcie_file, + struct pcie_ep_continuous_buffer_param *param) +{ + struct pcie_ep_continuous_buffer_req *buffer_req, *tmp; + struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep; + int ret = -ENOENT; + + mutex_lock(&pcie_file->file_lock_mutex); + + list_for_each_entry_safe(buffer_req, tmp, &pcie_file->cont_buffer_list, cont_buffer_list) { + if (buffer_req->dma_addr == param->dma_addr && buffer_req->size == param->size) { + dma_free_coherent(&pcie_rkep->pdev->dev, buffer_req->size, + buffer_req->vir_addr, buffer_req->dma_addr); + list_del(&buffer_req->cont_buffer_list); + kfree(buffer_req); + ret = 0; + break; + } + } + + mutex_unlock(&pcie_file->file_lock_mutex); + return ret; +} + static int pcie_rkep_open(struct inode *inode, struct file *file) { struct miscdevice *miscdev = file->private_data; @@ -338,6 +409,7 @@ static int pcie_rkep_open(struct inode *inode, struct file *file) pcie_file->pcie_rkep = pcie_rkep; mutex_init(&pcie_file->file_lock_mutex); + INIT_LIST_HEAD(&pcie_file->cont_buffer_list); file->private_data = pcie_file; @@ -348,6 +420,7 @@ static int pcie_rkep_release(struct inode *inode, struct file *file) { struct pcie_file *pcie_file = file->private_data; struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep; + struct pcie_ep_continuous_buffer_req *buffer_req, *tmp; int index; while (1) { @@ -369,7 +442,14 @@ static int pcie_rkep_release(struct inode *inode, struct file *file) dev_dbg(&pcie_rkep->pdev->dev, "release virtual id %d\n", index); } - devm_kfree(&pcie_rkep->pdev->dev, pcie_file); + mutex_lock(&pcie_file->file_lock_mutex); + list_for_each_entry_safe(buffer_req, tmp, &pcie_file->cont_buffer_list, cont_buffer_list) { + dma_free_coherent(&pcie_rkep->pdev->dev, buffer_req->size, + buffer_req->vir_addr, buffer_req->dma_addr); + list_del(&buffer_req->cont_buffer_list); + kfree(buffer_req); + } + mutex_unlock(&pcie_file->file_lock_mutex); return 0; } @@ -541,7 +621,7 @@ static int pcie_rkep_mmap(struct file *file, struct vm_area_struct *vma) resource_size_t bar_size; int err; - switch (pcie_rkep->cur_mmap_res) { + switch (pcie_file->cur_mmap_res) { case PCIE_EP_MMAP_RESOURCE_RK3568_RC_DBI: if (size > PCIE_DBI_SIZE) { dev_warn(&pcie_rkep->pdev->dev, "dbi mmap size is out of limitation\n"); @@ -608,12 +688,16 @@ static int pcie_rkep_mmap(struct file *file, struct vm_area_struct *vma) } addr = page_to_phys(pcie_rkep->user_pages); break; + case PCIE_EP_MMAP_RESOURCE_CONTINUOUS_BUFFER: + addr = pcie_file->cur_mmap_addr; + break; default: - dev_err(&pcie_rkep->pdev->dev, "cur mmap_res %d is unsurreport\n", pcie_rkep->cur_mmap_res); + dev_err(&pcie_rkep->pdev->dev, "cur mmap_res %d is unsurreport\n", pcie_file->cur_mmap_res); return -EINVAL; } - if (pcie_rkep->cur_mmap_res == PCIE_EP_MMAP_RESOURCE_USER_MEM) + if (pcie_file->cur_mmap_res == PCIE_EP_MMAP_RESOURCE_USER_MEM || + pcie_file->cur_mmap_res == PCIE_EP_MMAP_RESOURCE_CONTINUOUS_BUFFER) vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); else vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); @@ -629,21 +713,19 @@ static int pcie_rkep_mmap(struct file *file, struct vm_area_struct *vma) static long pcie_rkep_ioctl(struct file *file, unsigned int cmd, unsigned long args) { - void __user *argp; struct pcie_file *pcie_file = file->private_data; struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep; struct pcie_ep_dma_cache_cfg cfg; struct pcie_ep_dma_block_req dma; void __user *uarg = (void __user *)args; struct pcie_ep_obj_poll_virtual_id_cfg poll_cfg; + struct pcie_ep_continuous_buffer_param cont_buf_pram; int mmap_res; int ret; int index; u64 addr; u32 val; - argp = (void __user *)args; - switch (cmd) { case 0x4: /* get mapped physical address */ @@ -652,7 +734,7 @@ static long pcie_rkep_ioctl(struct file *file, unsigned int cmd, unsigned long a return -EINVAL; } addr = page_to_phys(pcie_rkep->user_pages); - if (copy_to_user(argp, &addr, sizeof(addr))) + if (copy_to_user(uarg, &addr, sizeof(addr))) return -EFAULT; break; case PCIE_DMA_CACHE_INVALIDE: @@ -695,7 +777,7 @@ static long pcie_rkep_ioctl(struct file *file, unsigned int cmd, unsigned long a return -EFAULT; } - if (copy_to_user(argp, &index, sizeof(index))) + if (copy_to_user(uarg, &index, sizeof(index))) return -EFAULT; break; case PCIE_EP_RELEASE_VIRTUAL_ID: @@ -738,7 +820,7 @@ static long pcie_rkep_ioctl(struct file *file, unsigned int cmd, unsigned long a if (ret < 0) return -EFAULT; - if (copy_to_user(argp, &poll_cfg, sizeof(poll_cfg))) + if (copy_to_user(uarg, &poll_cfg, sizeof(poll_cfg))) return -EFAULT; break; case PCIE_EP_RAISE_ELBI: @@ -768,14 +850,13 @@ static long pcie_rkep_ioctl(struct file *file, unsigned int cmd, unsigned long a return -EINVAL; } - pcie_rkep->cur_mmap_res = mmap_res; + pcie_file->cur_mmap_res = mmap_res; break; case PCIE_EP_GET_FUNC_DRV_VERSION: val = DRV_VERSION; - if (copy_to_user(argp, &val, sizeof(val))) + if (copy_to_user(uarg, &val, sizeof(val))) return -EFAULT; break; - case PCIE_EP_RESET_CTRL: #ifdef CONFIG_PCIEASPM_EXT dev_info(&pcie_rkep->pdev->dev, "reset controller\n"); return rockchip_dw_pcie_pm_ctrl_for_user(pcie_rkep->pdev, ROCKCHIP_PCIE_PM_CTRL_RESET); @@ -783,6 +864,27 @@ static long pcie_rkep_ioctl(struct file *file, unsigned int cmd, unsigned long a dev_warn(&pcie_rkep->pdev->dev, "reset controller not support\n"); return -EINVAL; #endif + case PCIE_EP_CONTINUOUS_BUFFER_ALLOC: + if (copy_from_user(&cont_buf_pram, uarg, sizeof(cont_buf_pram))) + return -EFAULT; + ret = rkep_mem_continuous_buffer_alloc(pcie_file, &cont_buf_pram); + if (ret) { + dev_err(&pcie_rkep->pdev->dev, "buffer alloc failed, ret=%d\n", ret); + return ret; + } + if (copy_to_user(uarg, &cont_buf_pram, sizeof(cont_buf_pram))) + return -EFAULT; + break; + case PCIE_EP_CONTINUOUS_BUFFER_FREE: + if (copy_from_user(&cont_buf_pram, uarg, sizeof(cont_buf_pram))) + return -EFAULT; + return rkep_mem_continuous_buffer_free(pcie_file, &cont_buf_pram); + case PCIE_EP_SET_MMAP_RESOURCE_CONTINUOUS_BUFFER: + if (copy_from_user(&cont_buf_pram, uarg, sizeof(cont_buf_pram))) + return -EFAULT; + pcie_file->cur_mmap_res = PCIE_EP_MMAP_RESOURCE_CONTINUOUS_BUFFER; + pcie_file->cur_mmap_addr = cont_buf_pram.dma_addr; + break; default: break; } @@ -1232,7 +1334,6 @@ static ssize_t rkep_store(struct device *dev, struct device_attribute *attr, else if (val == 3) writel(RKEP_CMD_LOADER_RUN, pcie_rkep->bar0 + 0x400); - dev_info(dev, "%s done\n", __func__); return count; } @@ -1348,7 +1449,6 @@ static int pcie_rkep_probe(struct pci_dev *pdev, const struct pci_device_id *id) pcie_dw_dmatest_unregister(pcie_rkep->dma_obj); goto err_register_obj; } - pcie_rkep->cur_mmap_res = PCIE_EP_MMAP_RESOURCE_USER_MEM; dev_info(&pdev->dev, "successfully allocate continuouse buffer for userspace\n"); pci_read_config_word(pcie_rkep->pdev, PCI_VENDOR_ID, &val); diff --git a/include/linux/rk-dma-heap.h b/include/linux/rk-dma-heap.h index 01a1bb50de36..f9b06cc18068 100644 --- a/include/linux/rk-dma-heap.h +++ b/include/linux/rk-dma-heap.h @@ -33,6 +33,12 @@ static inline int rk_dma_heap_cma_setup(void) */ int rk_dma_heap_set_dev(struct device *heap_dev); +/** + * rk_dma_heap_put - drops a reference to a dmabuf heaps, potentially freeing it + * @heap: heap pointer + */ +void rk_dma_heap_put(struct rk_dma_heap *heap); + /** * rk_dma_heap_find - Returns the registered dma_heap with the specified name * @name: Name of the heap to find @@ -100,6 +106,10 @@ static inline int rk_dma_heap_set_dev(struct device *heap_dev) return -ENODEV; } +static inline void rk_dma_heap_put(struct rk_dma_heap *heap) +{ +} + static inline struct rk_dma_heap *rk_dma_heap_find(const char *name) { return NULL; diff --git a/include/uapi/linux/rk-pcie-ep.h b/include/uapi/linux/rk-pcie-ep.h index ca1acb00f856..4717037afe92 100644 --- a/include/uapi/linux/rk-pcie-ep.h +++ b/include/uapi/linux/rk-pcie-ep.h @@ -71,6 +71,7 @@ enum pcie_ep_mmap_resource { PCIE_EP_MMAP_RESOURCE_RK3588_RC_DBI, PCIE_EP_MMAP_RESOURCE_BAR1, PCIE_EP_MMAP_RESOURCE_BAR5, + PCIE_EP_MMAP_RESOURCE_CONTINUOUS_BUFFER, PCIE_EP_MMAP_RESOURCE_MAX, }; @@ -109,19 +110,28 @@ struct pcie_ep_obj_poll_virtual_id_cfg { __u32 poll_status; }; +struct pcie_ep_continuous_buffer_param { + __u64 dma_addr; + __u32 size; +}; + #define PCIE_BASE 'P' -#define PCIE_EP_GET_FUNC_DRV_VERSION _IOR(PCIE_BASE, 0, unsigned int) -#define PCIE_DMA_CACHE_INVALIDE _IOW(PCIE_BASE, 1, struct pcie_ep_dma_cache_cfg) -#define PCIE_DMA_CACHE_FLUSH _IOW(PCIE_BASE, 2, struct pcie_ep_dma_cache_cfg) -#define PCIE_DMA_IRQ_MASK_ALL _IOW(PCIE_BASE, 3, int) -#define PCIE_EP_RAISE_MSI _IOW(PCIE_BASE, 4, int) -#define PCIE_EP_SET_MMAP_RESOURCE _IOW(PCIE_BASE, 6, int) -#define PCIE_EP_RAISE_ELBI _IOW(PCIE_BASE, 7, int) -#define PCIE_EP_RESET_CTRL _IOW(PCIE_BASE, 8, int) -#define PCIE_EP_REQUEST_VIRTUAL_ID _IOR(PCIE_BASE, 16, int) -#define PCIE_EP_RELEASE_VIRTUAL_ID _IOW(PCIE_BASE, 17, int) -#define PCIE_EP_RAISE_IRQ_USER _IOW(PCIE_BASE, 18, int) -#define PCIE_EP_POLL_IRQ_USER _IOW(PCIE_BASE, 19, struct pcie_ep_obj_poll_virtual_id_cfg) -#define PCIE_EP_DMA_XFER_BLOCK _IOW(PCIE_BASE, 32, struct pcie_ep_dma_block_req) +#define PCIE_EP_GET_FUNC_DRV_VERSION _IOR(PCIE_BASE, 0x00, unsigned int) +#define PCIE_DMA_CACHE_INVALIDE _IOW(PCIE_BASE, 0x01, struct pcie_ep_dma_cache_cfg) +#define PCIE_DMA_CACHE_FLUSH _IOW(PCIE_BASE, 0x02, struct pcie_ep_dma_cache_cfg) +#define PCIE_DMA_IRQ_MASK_ALL _IOW(PCIE_BASE, 0x03, int) +#define PCIE_EP_RAISE_MSI _IOW(PCIE_BASE, 0x04, int) +#define PCIE_EP_SET_MMAP_RESOURCE _IOW(PCIE_BASE, 0x06, int) +#define PCIE_EP_RAISE_ELBI _IOW(PCIE_BASE, 0x07, int) +#define PCIE_EP_RESET_CTRL _IOW(PCIE_BASE, 0x08, int) +#define PCIE_EP_REQUEST_VIRTUAL_ID _IOR(PCIE_BASE, 0x10, int) +#define PCIE_EP_RELEASE_VIRTUAL_ID _IOW(PCIE_BASE, 0x11, int) +#define PCIE_EP_RAISE_IRQ_USER _IOW(PCIE_BASE, 0x12, int) +#define PCIE_EP_POLL_IRQ_USER _IOW(PCIE_BASE, 0x13, struct pcie_ep_obj_poll_virtual_id_cfg) +#define PCIE_EP_DMA_XFER_BLOCK _IOW(PCIE_BASE, 0x20, struct pcie_ep_dma_block_req) + +#define PCIE_EP_CONTINUOUS_BUFFER_ALLOC _IOWR(PCIE_BASE, 0x30, struct pcie_ep_continuous_buffer_param) +#define PCIE_EP_CONTINUOUS_BUFFER_FREE _IOW(PCIE_BASE, 0x31, struct pcie_ep_continuous_buffer_param) +#define PCIE_EP_SET_MMAP_RESOURCE_CONTINUOUS_BUFFER _IOW(PCIE_BASE, 0x32, struct pcie_ep_continuous_buffer_param) #endif