commit 1e1bad99529751b8bc6335b78fa02da7deeabe47
Author: Erick Narvaez <e-narvaez@ti.com>
Date:   Fri Mar 1 14:30:27 2024 -0600

    patch: CL6529585_Enable_cached_mappings_in_KM_on_ARM64_for_DDK_1.15
    
    On TI platforms with MSMC (SnoopFilter) and UMA systems with PIPT caches
    when device mappings are un-cached in KM there is a risk of pre-fetching
    of cache lines by the Linux Kernel leading to incorrect view of memory
    from the GPU when Linux direct map (cached) being snooped by the device
    causing invalid data read.
    
    As these TI platforms have an one-way coherency using ACE-Lite where the
    GPU can snoop from CPU caches, the KM mappings to be cached. Making all
    allocations cached solves the above issue due to the nature of PIPT and
    implicit cache maintenance performed by the system. If the CPU cache is
    being correctly invalidated in response to GPU writes (as our testing
    has shown) then the DDK would not require any cache maintenance at all,
    hence every device memory allocation can be CPU-cached.
    
    Signed-off-by: Erick Narvaez <e-narvaez@ti.com>

diff --git a/services/server/common/physmem.c b/services/server/common/physmem.c
index 277f804..4a8124f 100644
--- a/services/server/common/physmem.c
+++ b/services/server/common/physmem.c
@@ -448,6 +448,23 @@ static PVRSRV_ERROR _DevPhysHeapFromFlags(PVRSRV_MEMALLOCFLAGS_T uiFlags,
 	return PVRSRV_OK;
 }
 
+static INLINE void _PromoteToCpuCached(PVRSRV_MEMALLOCFLAGS_T *puiFlags)
+{
+	if ((*puiFlags & (PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+	                  PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+	                  PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE)) == 0)
+	{
+		/* We don't need to upgrade if we don't map into the CPU */
+		return;
+	}
+
+	/* Clear the existing CPU cache flags */
+	*puiFlags &= ~(PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK);
+
+	/* Add CPU cached flags */
+	*puiFlags |= PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT;
+}
+
 PVRSRV_ERROR
 PhysmemNewRamBackedPMR_direct(CONNECTION_DATA *psConnection,
                        PVRSRV_DEVICE_NODE *psDevNode,
@@ -471,6 +488,12 @@ PhysmemNewRamBackedPMR_direct(CONNECTION_DATA *psConnection,
 
 	PVR_UNREFERENCED_PARAMETER(uiAnnotationLength);
 
+	if (PVRSRVSystemSnoopingOfCPUCache(psDevNode->psDevConfig) &&
+		psDevNode->pfnGetDeviceSnoopMode(psDevNode) == PVRSRV_DEVICE_SNOOP_CPU_ONLY)
+	{
+		_PromoteToCpuCached(&uiFlags);
+	}
+
 	eError = _ValidateParams(ui32NumPhysChunks,
 	                         ui32NumVirtChunks,
 	                         uiFlags,
diff --git a/services/server/devices/rogue/rgxinit.c b/services/server/devices/rogue/rgxinit.c
index 5357ab8..0e9f7a3 100644
--- a/services/server/devices/rogue/rgxinit.c
+++ b/services/server/devices/rogue/rgxinit.c
@@ -1227,6 +1227,26 @@ static MMU_DEVICEATTRIBS *RGXDevMMUAttributes(PVRSRV_DEVICE_NODE *psDeviceNode,
 	return psMMUDevAttrs;
 }
 
+/*
+	RGXDevSnoopMode
+*/
+static PVRSRV_DEVICE_SNOOP_MODE RGXDevSnoopMode(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	PVRSRV_RGXDEV_INFO *psDevInfo;
+
+	PVR_ASSERT(psDeviceNode != NULL);
+	PVR_ASSERT(psDeviceNode->pvDevice != NULL);
+
+	psDevInfo = (PVRSRV_RGXDEV_INFO *) psDeviceNode->pvDevice;
+
+	if (RGX_IS_FEATURE_SUPPORTED(psDevInfo, AXI_ACELITE))
+	{
+		return PVRSRV_DEVICE_SNOOP_CPU_ONLY;
+	}
+
+	return PVRSRV_DEVICE_SNOOP_NONE;
+}
+
 /*
  * RGXInitDevPart2
  */
@@ -4516,6 +4536,7 @@ PVRSRV_ERROR RGXRegisterDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
 
 	psDeviceNode->pfnValidateOrTweakPhysAddrs = NULL;
 
+	psDeviceNode->pfnGetDeviceSnoopMode = RGXDevSnoopMode;
 	psDeviceNode->pfnMMUCacheInvalidate = RGXMMUCacheInvalidate;
 
 	psDeviceNode->pfnMMUCacheInvalidateKick = RGXMMUCacheInvalidateKick;
diff --git a/services/server/devices/volcanic/rgxinit.c b/services/server/devices/volcanic/rgxinit.c
index d8172a0..ab7eae6 100644
--- a/services/server/devices/volcanic/rgxinit.c
+++ b/services/server/devices/volcanic/rgxinit.c
@@ -1124,6 +1124,17 @@ static MMU_DEVICEATTRIBS *RGXDevMMUAttributes(PVRSRV_DEVICE_NODE *psDeviceNode,
 	return psMMUDevAttrs;
 }
 
+
+/*
+	RGXDevSnoopMode
+*/
+static PVRSRV_DEVICE_SNOOP_MODE RGXDevSnoopMode(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+	PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+
+	return PVRSRV_DEVICE_SNOOP_NONE;
+}
+
 /*
  * RGXInitDevPart2
  */
@@ -4090,6 +4101,7 @@ PVRSRV_ERROR RGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode)
 
 	psDeviceNode->pfnValidateOrTweakPhysAddrs = NULL;
 
+	psDeviceNode->pfnGetDeviceSnoopMode = RGXDevSnoopMode;
 	psDeviceNode->pfnMMUCacheInvalidate = RGXMMUCacheInvalidate;
 
 	psDeviceNode->pfnMMUCacheInvalidateKick = RGXMMUCacheInvalidateKick;
diff --git a/services/server/include/device.h b/services/server/include/device.h
index 1a92688..badc2ea 100644
--- a/services/server/include/device.h
+++ b/services/server/include/device.h
@@ -337,6 +337,8 @@ typedef struct _PVRSRV_DEVICE_NODE_
 
 	MMU_DEVICEATTRIBS* (*pfnGetMMUDeviceAttributes)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_BOOL bKernelMemoryCtx);
 
+	PVRSRV_DEVICE_SNOOP_MODE (*pfnGetDeviceSnoopMode)(struct _PVRSRV_DEVICE_NODE_ *psDevNode);
+
 	PVRSRV_DEVICE_CONFIG	*psDevConfig;
 
 	/* device post-finalise compatibility check */
diff --git a/services/system/rogue/rgx_j721e/sysconfig.c b/services/system/rogue/rgx_j721e/sysconfig.c
index b16e82b..d23e843 100644
--- a/services/system/rogue/rgx_j721e/sysconfig.c
+++ b/services/system/rogue/rgx_j721e/sysconfig.c
@@ -139,7 +139,7 @@ static void SysDevFeatureDepInit(PVRSRV_DEVICE_CONFIG *psDevConfig, IMG_UINT64 u
 		else
 #endif
 		{
-			psDevConfig->eCacheSnoopingMode = PVRSRV_DEVICE_SNOOP_NONE;
+			psDevConfig->eCacheSnoopingMode = PVRSRV_DEVICE_SNOOP_CPU_ONLY;
 		}
 }
 
diff --git a/services/system/rogue/rgx_j721s2/sysconfig.c b/services/system/rogue/rgx_j721s2/sysconfig.c
index b738398..9836741 100644
--- a/services/system/rogue/rgx_j721s2/sysconfig.c
+++ b/services/system/rogue/rgx_j721s2/sysconfig.c
@@ -136,7 +136,7 @@ static void SysDevFeatureDepInit(PVRSRV_DEVICE_CONFIG *psDevConfig, IMG_UINT64 u
 		else
 #endif
 		{
-			psDevConfig->eCacheSnoopingMode		= PVRSRV_DEVICE_SNOOP_NONE;
+			psDevConfig->eCacheSnoopingMode		= PVRSRV_DEVICE_SNOOP_CPU_ONLY;
 		}
 }
 
