From b31d855bc45d6d050768d0f6b77db65d03866c0e Mon Sep 17 00:00:00 2001 From: Vadim Berezhnoi Date: Sun, 19 Oct 2025 13:17:28 -0700 Subject: [PATCH] snps_accel_app: add shared memory mapping writecombine option This change allows to configure per an application node in the device tree the shared memory mapping protection properties, namely noncached or writecombine. This can be used as a performance optimization on some platforms. --- arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 4 ++++ drivers/misc/snps_accel/snps_accel_drv.c | 23 ++++++++++++++++++++++- drivers/misc/snps_accel/snps_accel_drv.h | 3 ++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi index d0484ad0cdb13e..379c8fdb2cfc4a 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi @@ -949,6 +949,8 @@ /* This interrupt must be the same as the GIC interrupt 122 index in the arcsync node interrupts */ /* ARCsync v0c0arc_irq1_a -> VPX irq19_a in the FPGA bitfile */ interrupts = <0 90 4>; + /* Shared memory mapping protection properties: 0 - noncached, 1 - write-combine */ + /* snps,pgprot-bits = <1>; */ /* How many address bits the VPX master can use for DMA to system RAM */ snps,dma-bits = <0x1f>; #stream-id-cells = <0x01>; @@ -967,6 +969,8 @@ /* This interrupt must be the same as the GIC interrupt 122 index in the arcsync node interrupts */ /* ARCsync v0c0arc_irq1_a -> VPX irq19_a in the FPGA bitfile */ interrupts = <0 90 4>; + /* Shared memory mapping protection properties: 0 - noncached, 1 - write-combine */ + /* snps,pgprot-bits = <1>; */ /* How many address bits the VPX master can use for DMA to system RAM */ snps,dma-bits = <0x1f>; #stream-id-cells = <0x01>; diff --git a/drivers/misc/snps_accel/snps_accel_drv.c b/drivers/misc/snps_accel/snps_accel_drv.c index 74887773cc8de5..166bb970b2e0fa 100644 --- a/drivers/misc/snps_accel/snps_accel_drv.c +++ b/drivers/misc/snps_accel/snps_accel_drv.c @@ -28,6 +28,10 @@ static struct class *snps_accel_class; static unsigned int snps_accel_major; +static const enum { + snps_accel_pgprot_noncached, + snps_accel_pgprot_writecombine = 1 +}; static int snps_accel_info_shmem(struct snps_accel_app *accel_app, char __user *argp) @@ -276,7 +280,12 @@ static int snps_accel_mmap(struct file *filp, struct vm_area_struct *vma) dev_dbg(accel_app->device, "Shared memory size mismatch\n"); return -EINVAL; } - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + if (accel_app->pgprot_bits & snps_accel_pgprot_writecombine) { + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + } + else { + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + } ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, size, @@ -365,6 +374,7 @@ snps_accel_add_app(struct platform_device *pdev, struct device_node *node) struct resource ctrl; struct resource shmem; u32 dma_bits = 32; + u32 pgprot_bits = snps_accel_pgprot_noncached; ret = snps_accel_get_ctrl_mem(node, &ctrl); if (ret < 0) { @@ -440,6 +450,17 @@ snps_accel_add_app(struct platform_device *pdev, struct device_node *node) accel_app->device->dma_mask ? *accel_app->device->dma_mask : 0, accel_app->device->coherent_dma_mask); + ret = of_property_read_u32(node, "snps,pgprot-bits", &pgprot_bits); + if (ret) { + dev_warn(accel_app->device, + "snps,pgprot-bits DTS property read error %d, use noncached\n", + ret); + } + else { + accel_app->pgprot_bits = pgprot_bits; + dev_dbg(accel_app->device, "shmem pgprot 0x%x\n", accel_app->pgprot_bits); + } + #if IS_ENABLED(CONFIG_OF_IOMMU) accel_app->device->bus = pdev->dev.bus; accel_app->device->of_node = node; diff --git a/drivers/misc/snps_accel/snps_accel_drv.h b/drivers/misc/snps_accel/snps_accel_drv.h index aa3a14668b4a96..7522ea4e5d0498 100644 --- a/drivers/misc/snps_accel/snps_accel_drv.h +++ b/drivers/misc/snps_accel/snps_accel_drv.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (C) 2024 Synopsys, Inc. (www.synopsys.com) + * Copyright (C) 2024-2025 Synopsys, Inc. (www.synopsys.com) */ #ifndef _SNPS_ACCEL_DRV_H @@ -55,6 +55,7 @@ struct snps_accel_app { resource_size_t shmem_size; resource_size_t ctrl_base; resource_size_t ctrl_size; + u32 pgprot_bits; }; /**