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; }; /**