diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index fd8f3c1f1..9749e9142 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -394,6 +394,8 @@ source "drivers/gpu/drm/xlnx/Kconfig"
source "drivers/gpu/drm/verisilicon/Kconfig"
+source "drivers/gpu/drm/img-rogue/Kconfig"
+
# Keep legacy drivers last
menuconfig DRM_LEGACY
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 8d71f338a..11bffc354 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -57,6 +57,8 @@ drm_kms_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/
+obj-$(CONFIG_DRM_POWERVR_ROGUE) += img-rogue/
+
obj-$(CONFIG_DRM) += drm.o
obj-$(CONFIG_DRM_MIPI_DBI) += drm_mipi_dbi.o
obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o
diff --git a/drivers/gpu/drm/img-rogue/Kconfig b/drivers/gpu/drm/img-rogue/Kconfig
new file mode 100644
index 000000000..6862c7539
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/Kconfig
@@ -0,0 +1,24 @@
+config DRM_POWERVR_ROGUE
+ tristate "PowerVR Rogue"
+ depends on HAS_IOMEM
+ depends on DRM
+ select DRM_KMS_HELPER
+ select PM_DEVFREQ
+ select DEVFREQ_GOV_SIMPLE_ONDEMAND
+ select PM_OPP
+ select DEVFREQ_THERMAL
+ select SYNC_FILE
+ help
+ Driver for PowerVR Rogue graphics hardware.
+
+ Say Y here if your SoC contains a PowerVR Rogue GPU. For more
+ information, see .
+
+config DRM_POWERVR_ROGUE_DEBUG
+ bool "Enable PowerVR Rogue debug features"
+ depends on DRM_POWERVR_ROGUE
+ default n
+ help
+ Add additional debug features to the PowerVR Rogue driver.
+ To build a matching userspace, enable the following build options:
+ BUILD=debug SUPPORT_PAGE_FAULT_DEBUG=1 PVRSRV_ENABLE_GPU_MEMORY_INFO=1
diff --git a/drivers/gpu/drm/img-rogue/Makefile b/drivers/gpu/drm/img-rogue/Makefile
new file mode 100644
index 000000000..3ce2e94c4
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/Makefile
@@ -0,0 +1,19 @@
+img_basedir := drivers/gpu/drm/img-rogue
+include $(img_basedir)/config_kernel.mk
+
+obj-$(CONFIG_DRM_POWERVR_ROGUE) += pvrsrvkm.o
+
+ccflags-y += \
+ -include config_kernel.h \
+ -I$(img_basedir)/include/drm \
+ -I$(img_basedir) \
+ -I$(img_basedir)/include \
+ -I$(img_basedir)/km \
+ -I$(img_basedir)/system \
+ -D__linux__
+
+include $(img_basedir)/pvrsrvkm.mk
+
+obj-$(CONFIG_DRM_POWERVR_ROGUE) += drm_nulldisp.o
+
+drm_nulldisp-y += drm_nulldisp_drv.o drm_nulldisp_netlink.o drm_netlink_gem.o drm_nulldisp_gem.o
diff --git a/drivers/gpu/drm/img-rogue/allocmem.c b/drivers/gpu/drm/img-rogue/allocmem.c
new file mode 100644
index 000000000..3b81559a5
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/allocmem.c
@@ -0,0 +1,435 @@
+/*************************************************************************/ /*!
+@File
+@Title Host memory management implementation for Linux
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include
+#include
+#include
+#include
+
+#include "img_defs.h"
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "process_stats.h"
+#if defined(DEBUG) && defined(SUPPORT_VALIDATION)
+#include "pvrsrv.h"
+#endif
+#include "osfunc.h"
+
+/*
+ * DEBUG_MEMSTATS_ALLOC_RECORD_VALUES needs to be different from
+ * DEBUG_MEMSTATS_VALUES defined in process_stats.h.
+ * The reason for this is that the file and line where the allocation happens
+ * are tracked from the OSAllocMem params. If DEBUG_MEMSTATS_VALUES were to be
+ * used, all OSAllocMem allocation statistics would point to allocmem.c, which
+ * is not expected behaviour.
+ */
+#if defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS_ON)
+#define DEBUG_MEMSTATS_ALLOC_RECORD_VALUES ,pvAllocFromFile, ui32AllocFromLine
+#else
+#define DEBUG_MEMSTATS_ALLOC_RECORD_VALUES
+#endif
+
+/*
+ * When memory statistics are disabled, memory records are used instead.
+ * In order for these to work, the PID of the process that requested the
+ * allocation needs to be stored at the end of the kmalloc'd memory, making
+ * sure 4 extra bytes are allocated to fit the PID.
+ *
+ * There is no need for this extra allocation when memory statistics are
+ * enabled, since all allocations are tracked in DebugFS mem_area files.
+ */
+#if defined(PVRSRV_ENABLE_PROCESS_STATS) && !defined(PVRSRV_ENABLE_MEMORY_STATS)
+#define ALLOCMEM_MEMSTATS_PADDING sizeof(IMG_UINT32)
+#else
+#define ALLOCMEM_MEMSTATS_PADDING 0UL
+#endif
+
+/* How many times kmalloc can fail before the allocation threshold is reduced */
+static const IMG_UINT32 g_ui32kmallocFailLimit = 10;
+/* How many kmalloc failures happened since the last allocation threshold change */
+static IMG_UINT32 g_ui32kmallocFailCount = 0;
+/* Current kmalloc threshold value in bytes */
+static IMG_UINT32 g_ui32kmallocThreshold = PVR_LINUX_KMALLOC_ALLOCATION_THRESHOLD;
+/* Spinlock used so that the global variables above may not be modified by more than 1 thread at a time */
+static DEFINE_SPINLOCK(kmalloc_lock);
+
+#if defined(DEBUG) && defined(SUPPORT_VALIDATION)
+static DEFINE_SPINLOCK(kmalloc_leak_lock);
+static IMG_UINT32 g_ui32kmallocLeakCounter = 0;
+#endif
+
+static inline void OSTryDecreaseKmallocThreshold(void)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&kmalloc_lock, flags);
+
+ g_ui32kmallocFailCount++;
+
+ if (g_ui32kmallocFailCount >= g_ui32kmallocFailLimit)
+ {
+ g_ui32kmallocFailCount = 0;
+ if (g_ui32kmallocThreshold > PAGE_SIZE)
+ {
+ g_ui32kmallocThreshold >>= 1;
+ printk(KERN_INFO "Threshold is now set to %d\n", g_ui32kmallocThreshold);
+ }
+ }
+
+ spin_unlock_irqrestore(&kmalloc_lock, flags);
+}
+
+static inline void OSResetKmallocFailCount(void)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&kmalloc_lock, flags);
+
+ g_ui32kmallocFailCount = 0;
+
+ spin_unlock_irqrestore(&kmalloc_lock, flags);
+}
+
+static inline void _pvr_vfree(const void* pvAddr)
+{
+#if defined(DEBUG)
+ /* Size harder to come by for vmalloc and since vmalloc allocates
+ * a whole number of pages, poison the minimum size known to have
+ * been allocated.
+ */
+ OSCachedMemSet((void*)pvAddr, PVRSRV_POISON_ON_ALLOC_VALUE,
+ PAGE_SIZE);
+#endif
+ vfree(pvAddr);
+}
+
+static inline void _pvr_kfree(const void* pvAddr)
+{
+#if defined(DEBUG)
+ /* Poison whole memory block */
+ OSCachedMemSet((void*)pvAddr, PVRSRV_POISON_ON_ALLOC_VALUE,
+ ksize(pvAddr));
+#endif
+ kfree(pvAddr);
+}
+
+static inline void _pvr_alloc_stats_add(void *pvAddr, IMG_UINT32 ui32Size DEBUG_MEMSTATS_PARAMS)
+{
+#if !defined(PVRSRV_ENABLE_PROCESS_STATS)
+ PVR_UNREFERENCED_PARAMETER(pvAddr);
+#else
+ if (!is_vmalloc_addr(pvAddr))
+ {
+#if defined(PVRSRV_ENABLE_MEMORY_STATS)
+ IMG_CPU_PHYADDR sCpuPAddr;
+ sCpuPAddr.uiAddr = 0;
+
+ PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_KMALLOC,
+ pvAddr,
+ sCpuPAddr,
+ ksize(pvAddr),
+ NULL,
+ OSGetCurrentClientProcessIDKM()
+ DEBUG_MEMSTATS_ALLOC_RECORD_VALUES);
+#else
+ {
+ /* Store the PID in the final additional 4 bytes allocated */
+ IMG_UINT32 *puiTemp = IMG_OFFSET_ADDR(pvAddr, ksize(pvAddr) - ALLOCMEM_MEMSTATS_PADDING);
+ *puiTemp = OSGetCurrentClientProcessIDKM();
+ }
+ PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_KMALLOC, ksize(pvAddr), OSGetCurrentClientProcessIDKM());
+#endif /* defined(PVRSRV_ENABLE_MEMORY_STATS) */
+ }
+ else
+ {
+#if defined(PVRSRV_ENABLE_MEMORY_STATS)
+ IMG_CPU_PHYADDR sCpuPAddr;
+ sCpuPAddr.uiAddr = 0;
+
+ PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_VMALLOC,
+ pvAddr,
+ sCpuPAddr,
+ ((ui32Size + PAGE_SIZE-1) & ~(PAGE_SIZE-1)),
+ NULL,
+ OSGetCurrentClientProcessIDKM()
+ DEBUG_MEMSTATS_ALLOC_RECORD_VALUES);
+#else
+ PVRSRVStatsIncrMemAllocStatAndTrack(PVRSRV_MEM_ALLOC_TYPE_VMALLOC,
+ ((ui32Size + PAGE_SIZE-1) & ~(PAGE_SIZE-1)),
+ (IMG_UINT64)(uintptr_t) pvAddr,
+ OSGetCurrentClientProcessIDKM());
+#endif /* defined(PVRSRV_ENABLE_MEMORY_STATS) */
+ }
+#endif /* !defined(PVRSRV_ENABLE_PROCESS_STATS) */
+}
+
+static inline void _pvr_alloc_stats_remove(void *pvAddr)
+{
+#if !defined(PVRSRV_ENABLE_PROCESS_STATS)
+ PVR_UNREFERENCED_PARAMETER(pvAddr);
+#else
+ if (!is_vmalloc_addr(pvAddr))
+ {
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+ {
+ IMG_UINT32 *puiTemp = IMG_OFFSET_ADDR(pvAddr, ksize(pvAddr) - ALLOCMEM_MEMSTATS_PADDING);
+ PVRSRVStatsDecrMemKAllocStat(ksize(pvAddr), *puiTemp);
+ }
+#else
+ PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_KMALLOC,
+ (IMG_UINT64)(uintptr_t) pvAddr,
+ OSGetCurrentClientProcessIDKM());
+#endif
+ }
+ else
+ {
+#if !defined(PVRSRV_ENABLE_MEMORY_STATS)
+ PVRSRVStatsDecrMemAllocStatAndUntrack(PVRSRV_MEM_ALLOC_TYPE_VMALLOC,
+ (IMG_UINT64)(uintptr_t) pvAddr);
+#else
+ PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_VMALLOC,
+ (IMG_UINT64)(uintptr_t) pvAddr,
+ OSGetCurrentClientProcessIDKM());
+#endif
+ }
+#endif /* !defined(PVRSRV_ENABLE_PROCESS_STATS) */
+}
+
+void *(OSAllocMem)(IMG_UINT32 ui32Size DEBUG_MEMSTATS_PARAMS)
+{
+ void *pvRet = NULL;
+
+ if ((ui32Size + ALLOCMEM_MEMSTATS_PADDING) <= g_ui32kmallocThreshold)
+ {
+ pvRet = kmalloc(ui32Size + ALLOCMEM_MEMSTATS_PADDING, GFP_KERNEL);
+ if (pvRet == NULL)
+ {
+ OSTryDecreaseKmallocThreshold();
+ }
+ else
+ {
+ OSResetKmallocFailCount();
+ }
+ }
+
+ if (pvRet == NULL)
+ {
+ pvRet = vmalloc(ui32Size);
+ }
+
+ if (pvRet != NULL)
+ {
+ _pvr_alloc_stats_add(pvRet, ui32Size DEBUG_MEMSTATS_ALLOC_RECORD_VALUES);
+ }
+
+ return pvRet;
+}
+
+void *(OSAllocZMem)(IMG_UINT32 ui32Size DEBUG_MEMSTATS_PARAMS)
+{
+ void *pvRet = NULL;
+
+ if ((ui32Size + ALLOCMEM_MEMSTATS_PADDING) <= g_ui32kmallocThreshold)
+ {
+ pvRet = kzalloc(ui32Size + ALLOCMEM_MEMSTATS_PADDING, GFP_KERNEL);
+ if (pvRet == NULL)
+ {
+ OSTryDecreaseKmallocThreshold();
+ }
+ else
+ {
+ OSResetKmallocFailCount();
+ }
+ }
+
+ if (pvRet == NULL)
+ {
+ pvRet = vzalloc(ui32Size);
+ }
+
+ if (pvRet != NULL)
+ {
+ _pvr_alloc_stats_add(pvRet, ui32Size DEBUG_MEMSTATS_ALLOC_RECORD_VALUES);
+ }
+
+ return pvRet;
+}
+
+/*
+ * The parentheses around OSFreeMem prevent the macro in allocmem.h from
+ * applying, as it would break the function's definition.
+ */
+void (OSFreeMem)(void *pvMem)
+{
+#if defined(DEBUG) && defined(SUPPORT_VALIDATION)
+ unsigned long flags;
+ PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+ if (psPVRSRVData)
+ {
+ IMG_UINT32 ui32kmallocLeakMax = psPVRSRVData->sMemLeakIntervals.ui32OSAlloc;
+
+ spin_lock_irqsave(&kmalloc_leak_lock, flags);
+
+ g_ui32kmallocLeakCounter++;
+ if (ui32kmallocLeakMax && (g_ui32kmallocLeakCounter >= ui32kmallocLeakMax))
+ {
+ g_ui32kmallocLeakCounter = 0;
+ spin_unlock_irqrestore(&kmalloc_leak_lock, flags);
+
+ PVR_DPF((PVR_DBG_WARNING,
+ "%s: Skipped freeing of pointer 0x%p to trigger memory leak.",
+ __func__,
+ pvMem));
+ return;
+ }
+
+ spin_unlock_irqrestore(&kmalloc_leak_lock, flags);
+ }
+#endif
+ if (pvMem != NULL)
+ {
+ _pvr_alloc_stats_remove(pvMem);
+
+ if (!is_vmalloc_addr(pvMem))
+ {
+ _pvr_kfree(pvMem);
+ }
+ else
+ {
+ _pvr_vfree(pvMem);
+ }
+ }
+}
+
+void *OSAllocMemNoStats(IMG_UINT32 ui32Size)
+{
+ void *pvRet = NULL;
+
+ if (ui32Size <= g_ui32kmallocThreshold)
+ {
+ pvRet = kmalloc(ui32Size, GFP_KERNEL);
+ if (pvRet == NULL)
+ {
+ OSTryDecreaseKmallocThreshold();
+ }
+ else
+ {
+ OSResetKmallocFailCount();
+ }
+ }
+
+ if (pvRet == NULL)
+ {
+ pvRet = vmalloc(ui32Size);
+ }
+
+ return pvRet;
+}
+
+void *OSAllocZMemNoStats(IMG_UINT32 ui32Size)
+{
+ void *pvRet = NULL;
+
+ if (ui32Size <= g_ui32kmallocThreshold)
+ {
+ pvRet = kzalloc(ui32Size, GFP_KERNEL);
+ if (pvRet == NULL)
+ {
+ OSTryDecreaseKmallocThreshold();
+ }
+ else
+ {
+ OSResetKmallocFailCount();
+ }
+ }
+
+ if (pvRet == NULL)
+ {
+ pvRet = vzalloc(ui32Size);
+ }
+
+ return pvRet;
+}
+
+/*
+ * The parentheses around OSFreeMemNoStats prevent the macro in allocmem.h from
+ * applying, as it would break the function's definition.
+ */
+void (OSFreeMemNoStats)(void *pvMem)
+{
+#if defined(DEBUG) && defined(SUPPORT_VALIDATION)
+ unsigned long flags;
+ PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+ if (psPVRSRVData)
+ {
+ IMG_UINT32 ui32kmallocLeakMax = psPVRSRVData->sMemLeakIntervals.ui32OSAlloc;
+
+ spin_lock_irqsave(&kmalloc_leak_lock, flags);
+
+ g_ui32kmallocLeakCounter++;
+ if (ui32kmallocLeakMax && (g_ui32kmallocLeakCounter >= ui32kmallocLeakMax))
+ {
+ g_ui32kmallocLeakCounter = 0;
+ spin_unlock_irqrestore(&kmalloc_leak_lock, flags);
+
+ PVR_DPF((PVR_DBG_WARNING,
+ "%s: Skipped freeing of pointer 0x%p to trigger memory leak.",
+ __func__,
+ pvMem));
+ return;
+ }
+
+ spin_unlock_irqrestore(&kmalloc_leak_lock, flags);
+ }
+#endif
+ if (pvMem != NULL)
+ {
+ if (!is_vmalloc_addr(pvMem))
+ {
+ _pvr_kfree(pvMem);
+ }
+ else
+ {
+ _pvr_vfree(pvMem);
+ }
+ }
+}
diff --git a/drivers/gpu/drm/img-rogue/allocmem.h b/drivers/gpu/drm/img-rogue/allocmem.h
new file mode 100644
index 000000000..d0ce7a7ff
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/allocmem.h
@@ -0,0 +1,181 @@
+/*************************************************************************/ /*!
+@File allocmem.h
+@Title memory allocation header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Memory-Allocation API definitions
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef ALLOCMEM_H
+#define ALLOCMEM_H
+
+#include "img_types.h"
+#include "pvr_debug.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if !defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS) || !defined(DEBUG) || !defined(PVRSRV_ENABLE_PROCESS_STATS) || !defined(PVRSRV_ENABLE_MEMORY_STATS) || defined(DOXYGEN)
+
+/**************************************************************************/ /*!
+@Function OSAllocMem
+@Description Allocates CPU memory. Contents are uninitialized.
+ If passed a size of zero, function should not assert,
+ but just return a NULL pointer.
+@Input ui32Size Size of required allocation (in bytes)
+@Return Pointer to allocated memory on success.
+ Otherwise NULL.
+ */ /**************************************************************************/
+void *OSAllocMem(IMG_UINT32 ui32Size);
+#define OSAllocMem(_size) (OSAllocMem)((_size))
+/**************************************************************************/ /*!
+@Function OSAllocZMem
+@Description Allocates CPU memory and initializes the contents to zero.
+ If passed a size of zero, function should not assert,
+ but just return a NULL pointer.
+@Input ui32Size Size of required allocation (in bytes)
+@Return Pointer to allocated memory on success.
+ Otherwise NULL.
+ */ /**************************************************************************/
+void *OSAllocZMem(IMG_UINT32 ui32Size);
+#define OSAllocZMem(_size) (OSAllocZMem)((_size))
+
+#else
+void *OSAllocMem(IMG_UINT32 ui32Size, void *pvAllocFromFile, IMG_UINT32 ui32AllocFromLine);
+void *OSAllocZMem(IMG_UINT32 ui32Size, void *pvAllocFromFile, IMG_UINT32 ui32AllocFromLine);
+#define OSAllocMem(_size) (OSAllocMem)((_size), (__FILE__), (__LINE__))
+#define OSAllocZMem(_size) (OSAllocZMem)((_size), (__FILE__), (__LINE__))
+#endif
+
+/**************************************************************************/ /*!
+@Function OSAllocMemNoStats
+@Description Allocates CPU memory. Contents are uninitialized.
+ If passed a size of zero, function should not assert,
+ but just return a NULL pointer.
+ The allocated memory is not accounted for by process stats.
+ Process stats are an optional feature (enabled only when
+ PVRSRV_ENABLE_PROCESS_STATS is defined) which track the amount
+ of memory allocated to help in debugging. Where this is not
+ required, OSAllocMem() and OSAllocMemNoStats() equate to
+ the same operation.
+@Input ui32Size Size of required allocation (in bytes)
+@Return Pointer to allocated memory on success.
+ Otherwise NULL.
+ */ /**************************************************************************/
+void *OSAllocMemNoStats(IMG_UINT32 ui32Size);
+
+/**************************************************************************/ /*!
+@Function OSAllocZMemNoStats
+@Description Allocates CPU memory and initializes the contents to zero.
+ If passed a size of zero, function should not assert,
+ but just return a NULL pointer.
+ The allocated memory is not accounted for by process stats.
+ Process stats are an optional feature (enabled only when
+ PVRSRV_ENABLE_PROCESS_STATS is defined) which track the amount
+ of memory allocated to help in debugging. Where this is not
+ required, OSAllocZMem() and OSAllocZMemNoStats() equate to
+ the same operation.
+@Input ui32Size Size of required allocation (in bytes)
+@Return Pointer to allocated memory on success.
+ Otherwise NULL.
+ */ /**************************************************************************/
+void *OSAllocZMemNoStats(IMG_UINT32 ui32Size);
+
+/**************************************************************************/ /*!
+@Function OSFreeMem
+@Description Frees previously allocated CPU memory.
+@Input pvCpuVAddr Pointer to the memory to be freed.
+@Return None.
+ */ /**************************************************************************/
+void OSFreeMem(void *pvCpuVAddr);
+
+/**************************************************************************/ /*!
+@Function OSFreeMemNoStats
+@Description Frees previously allocated CPU memory.
+ The freed memory does not update the figures in process stats.
+ Process stats are an optional feature (enabled only when
+ PVRSRV_ENABLE_PROCESS_STATS is defined) which track the amount
+ of memory allocated to help in debugging. Where this is not
+ required, OSFreeMem() and OSFreeMemNoStats() equate to the
+ same operation.
+@Input pvCpuVAddr Pointer to the memory to be freed.
+@Return None.
+ */ /**************************************************************************/
+void OSFreeMemNoStats(void *pvCpuVAddr);
+
+/*
+ * These macros allow us to catch double-free bugs on DEBUG builds and
+ * prevent crashes on RELEASE builds.
+ */
+
+/*! @cond Doxygen_Suppress */
+#if defined(DEBUG)
+#define double_free_sentinel ((void *)&OSFreeMem)
+#define ALLOCMEM_ASSERT(exp) PVR_ASSERT(exp)
+#else
+#define double_free_sentinel NULL
+#define ALLOCMEM_ASSERT(exp) do {} while (0)
+#endif
+/*! @endcond */
+
+/*! Frees memory allocated by OSAllocMem(). */
+#define OSFreeMem(_ptr) do { \
+ ALLOCMEM_ASSERT((_ptr) != double_free_sentinel); \
+ (OSFreeMem)(_ptr); \
+ (_ptr) = double_free_sentinel; \
+ MSC_SUPPRESS_4127 \
+ } while (0)
+
+/*! Frees memory allocated by OSAllocMemNoStats(). */
+#define OSFreeMemNoStats(_ptr) do { \
+ ALLOCMEM_ASSERT((_ptr) != double_free_sentinel); \
+ (OSFreeMemNoStats)(_ptr); \
+ (_ptr) = double_free_sentinel; \
+ MSC_SUPPRESS_4127 \
+ } while (0)
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* ALLOCMEM_H */
+
+/******************************************************************************
+ End of file (allocmem.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/cache_km.c b/drivers/gpu/drm/img-rogue/cache_km.c
new file mode 100644
index 000000000..dc85fc4b9
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/cache_km.c
@@ -0,0 +1,2548 @@
+/*************************************************************************/ /*!
+@File cache_km.c
+@Title CPU d-cache maintenance operations framework
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Implements server side code for CPU d-cache maintenance taking
+ into account the idiosyncrasies of the various types of CPU
+ d-cache instruction-set architecture (ISA) maintenance
+ mechanisms.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#if defined(__linux__)
+#include
+#include
+#include
+#include
+#include
+#include
+#endif
+
+#include "pmr.h"
+#include "log2.h"
+#include "device.h"
+#include "pvrsrv.h"
+#include "osfunc.h"
+#include "cache_km.h"
+#include "pvr_debug.h"
+#include "lock_types.h"
+#include "allocmem.h"
+#include "process_stats.h"
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG)
+#include "ri_server.h"
+#endif
+#include "devicemem.h"
+#include "pvrsrv_apphint.h"
+#include "pvrsrv_sync_server.h"
+#include "km_apphint_defs.h"
+#include "km_apphint_defs_common.h"
+#include "oskm_apphint.h"
+#include "di_server.h"
+
+/* This header must always be included last */
+#if defined(__linux__)
+#include "kernel_compatibility.h"
+#endif
+
+/* Top-level file-local build definitions */
+#if defined(PVRSRV_ENABLE_CACHEOP_STATS) && defined(__linux__)
+#define CACHEOP_DEBUG
+#define CACHEOP_STATS_ITEMS_MAX 32
+#define INCR_WRAP(x) ((x+1) >= CACHEOP_STATS_ITEMS_MAX ? 0 : (x+1))
+#define DECR_WRAP(x) ((x-1) < 0 ? (CACHEOP_STATS_ITEMS_MAX-1) : (x-1))
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG)
+/* Refer to CacheOpStatsExecLogHeader() for header item names */
+#define CACHEOP_RI_PRINTF_HEADER "%-8s %-8s %-10s %-10s %-5s %-16s %-16s %-10s %-10s %-18s %-18s %-12s"
+#define CACHEOP_RI_PRINTF "%-8d %-8d %-10s %-10s %-5s 0x%-14llx 0x%-14llx 0x%-8llx 0x%-8llx %-18llu %-18llu 0x%-10x\n"
+#else
+#define CACHEOP_PRINTF_HEADER "%-8s %-8s %-10s %-10s %-5s %-10s %-10s %-18s %-18s %-12s"
+#define CACHEOP_PRINTF "%-8d %-8d %-10s %-10s %-5s 0x%-8llx 0x%-8llx %-18llu %-18llu 0x%-10x\n"
+#endif
+#endif
+
+//#define CACHEOP_NO_CACHE_LINE_ALIGNED_ROUNDING /* Force OS page (not cache line) flush granularity */
+#define CACHEOP_PVR_ASSERT(x) /* Define as PVR_ASSERT(x), enable for swdev & testing */
+#if defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP)
+#define CACHEOP_THREAD_WAIT_TIMEOUT 0ULL /* Wait indefinitely */
+#else
+#define CACHEOP_THREAD_WAIT_TIMEOUT 500000ULL /* Wait 500ms between wait unless woken-up on demand */
+#endif
+#define CACHEOP_FENCE_WAIT_TIMEOUT 1000ULL /* Wait 1ms between wait events unless woken-up */
+#define CACHEOP_FENCE_RETRY_ABORT 1000ULL /* Fence retries that aborts fence operation */
+#define CACHEOP_SEQ_MIDPOINT (IMG_UINT32) 0x7FFFFFFF /* Where seqNum(s) are rebase, compared at */
+#define CACHEOP_ABORT_FENCE_ERROR_STRING "detected stalled client, retrying cacheop fence"
+#define CACHEOP_DEVMEM_OOR_ERROR_STRING "cacheop device memory request is out of range"
+#define CACHEOP_MAX_DEBUG_MESSAGE_LEN 160
+
+typedef struct _CACHEOP_WORK_ITEM_
+{
+ PMR *psPMR;
+ IMG_UINT32 ui32OpSeqNum;
+ IMG_DEVMEM_SIZE_T uiSize;
+ PVRSRV_CACHE_OP uiCacheOp;
+ IMG_DEVMEM_OFFSET_T uiOffset;
+ PVRSRV_TIMELINE iTimeline;
+ SYNC_TIMELINE_OBJ sSWTimelineObj;
+ PVRSRV_DEVICE_NODE *psDevNode;
+#if defined(CACHEOP_DEBUG)
+ IMG_UINT64 ui64EnqueuedTime;
+ IMG_UINT64 ui64DequeuedTime;
+ IMG_UINT64 ui64ExecuteTime;
+ IMG_BOOL bDeferred;
+ IMG_BOOL bKMReq;
+ IMG_BOOL bUMF;
+ IMG_PID pid;
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG)
+ RGXFWIF_DM eFenceOpType;
+#endif
+#endif
+} CACHEOP_WORK_ITEM;
+
+typedef struct _CACHEOP_STATS_EXEC_ITEM_
+{
+ IMG_UINT32 ui32DeviceID;
+ IMG_PID pid;
+ IMG_UINT32 ui32OpSeqNum;
+ PVRSRV_CACHE_OP uiCacheOp;
+ IMG_DEVMEM_SIZE_T uiOffset;
+ IMG_DEVMEM_SIZE_T uiSize;
+ IMG_UINT64 ui64EnqueuedTime;
+ IMG_UINT64 ui64DequeuedTime;
+ IMG_UINT64 ui64ExecuteTime;
+ IMG_BOOL bIsFence;
+ IMG_BOOL bKMReq;
+ IMG_BOOL bUMF;
+ IMG_BOOL bDeferred;
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG)
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_DEV_PHYADDR sDevPAddr;
+ RGXFWIF_DM eFenceOpType;
+#endif
+} CACHEOP_STATS_EXEC_ITEM;
+
+typedef enum _CACHEOP_CONFIG_
+{
+ CACHEOP_CONFIG_DEFAULT = 0,
+ /* cache flush mechanism types */
+ CACHEOP_CONFIG_URBF = 4,
+ /* sw-emulated deferred flush mechanism */
+ CACHEOP_CONFIG_KDF = 8,
+ /* pseudo configuration items */
+ CACHEOP_CONFIG_LAST = 16,
+ CACHEOP_CONFIG_KLOG = 16,
+ CACHEOP_CONFIG_ALL = 31
+} CACHEOP_CONFIG;
+
+typedef struct _CACHEOP_WORK_QUEUE_
+{
+/*
+ * Init. state & primary device node framework
+ * is anchored on.
+ */
+ IMG_BOOL bInit;
+/*
+ MMU page size/shift & d-cache line size
+ */
+ size_t uiPageSize;
+ IMG_UINT32 uiLineSize;
+ IMG_UINT32 uiLineShift;
+ IMG_UINT32 uiPageShift;
+ OS_CACHE_OP_ADDR_TYPE uiCacheOpAddrType;
+/*
+ CacheOp deferred queueing protocol
+ + Implementation geared for performance, atomic counter based
+ - Value Space is 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> n.
+ - Index Space is 0 -> 1 -> 2 -> 3 -> 0 -> 1 -> 2 -> 3 -> 0 -> m.
+ - Index = Value modulo CACHEOP_INDICES_LOG2_SIZE.
+ + Write counter never collides with read counter in index space
+ - Unless at start of day when both are initialised to zero.
+ - This means we sacrifice one entry when the queue is full.
+ - Incremented by producer
+ - Value space tracks total number of CacheOps queued.
+ - Index space identifies CacheOp CCB queue index.
+ + Read counter increments towards write counter in value space
+ - Empty queue occurs when read equals write counter.
+ - Wrap-round logic handled by consumer as/when needed.
+ - Incremented by consumer
+ - Value space tracks total # of CacheOps executed.
+ - Index space identifies CacheOp CCB queue index.
+ + Total queued size adjusted up/down during write/read activity
+ - Counter might overflow but does not compromise framework.
+ */
+ ATOMIC_T hReadCounter;
+ ATOMIC_T hWriteCounter;
+/*
+ CacheOp sequence numbers
+ + hCommonSeqNum:
+ - Common sequence, numbers every CacheOp operation in both UM/KM.
+ - In KM
+ - Every deferred CacheOp (on behalf of UM) gets a unique seqNum.
+ - Last executed deferred CacheOp updates gsCwq.hCompletedSeqNum.
+ - Under debug, all CacheOp gets a unique seqNum for tracking.
+ - This includes all UM/KM synchronous non-deferred CacheOp(s)
+ - In UM
+ - CacheOp(s) discarding happens in both UM and KM space.
+ + hCompletedSeqNum:
+ - Tracks last executed KM/deferred RBF/Global CacheOp(s)
+ */
+ ATOMIC_T hCommonSeqNum;
+ ATOMIC_T hCompletedSeqNum;
+/*
+ CacheOp information page
+ + psInfoPagePMR:
+ - Single system-wide OS page that is multi-mapped in UM/KM.
+ - Mapped into clients using read-only memory protection.
+ - Mapped into server using read/write memory protection.
+ - Contains information pertaining to cache framework.
+ + pui32InfoPage:
+ - Server linear address pointer to said information page.
+ - Each info-page entry currently of sizeof(IMG_UINT32).
+ */
+ PMR *psInfoPagePMR;
+ IMG_UINT32 *pui32InfoPage;
+/*
+ CacheOp deferred work-item queue
+ + CACHEOP_INDICES_LOG2_SIZE
+ */
+#define CACHEOP_INDICES_LOG2_SIZE (4)
+#define CACHEOP_INDICES_MAX (1 << CACHEOP_INDICES_LOG2_SIZE)
+#define CACHEOP_INDICES_MASK (CACHEOP_INDICES_MAX-1)
+ CACHEOP_WORK_ITEM asWorkItems[CACHEOP_INDICES_MAX];
+#if defined(CACHEOP_DEBUG)
+/*
+ CacheOp statistics
+ */
+ DI_ENTRY *psDIEntry;
+ IMG_HANDLE hStatsExecLock;
+ IMG_UINT32 ui32ServerASync;
+ IMG_UINT32 ui32ServerSyncVA;
+ IMG_UINT32 ui32ServerSync;
+ IMG_UINT32 ui32ServerRBF;
+ IMG_UINT32 ui32ServerDTL;
+ IMG_UINT32 ui32ClientSync;
+ IMG_UINT32 ui32ClientRBF;
+ IMG_UINT32 ui32TotalFenceOps;
+ IMG_UINT32 ui32TotalExecOps;
+ IMG_UINT32 ui32AvgExecTime;
+ IMG_UINT32 ui32AvgExecTimeRemainder;
+ IMG_UINT32 ui32AvgFenceTime;
+ IMG_UINT32 ui32AvgFenceTimeRemainder;
+ IMG_INT32 i32StatsExecWriteIdx;
+ CACHEOP_STATS_EXEC_ITEM asStatsExecuted[CACHEOP_STATS_ITEMS_MAX];
+#endif
+/*
+ CacheOp (re)configuration
+ */
+ DI_ENTRY *psConfigTune;
+ IMG_HANDLE hConfigLock;
+/*
+ CacheOp deferred worker thread
+ + eConfig
+ - Runtime configuration
+ + hWorkerThread
+ - CacheOp thread handler
+ + hThreadWakeUpEvtObj
+ - Event object to drive CacheOp worker thread sleep/wake-ups.
+ + hClientWakeUpEvtObj
+ - Event object to unblock stalled clients waiting on queue.
+ */
+ CACHEOP_CONFIG eConfig;
+ IMG_UINT32 ui32Config;
+ IMG_HANDLE hWorkerThread;
+ IMG_HANDLE hDeferredLock;
+ IMG_HANDLE hThreadWakeUpEvtObj;
+ IMG_HANDLE hClientWakeUpEvtObj;
+ IMG_UINT32 ui32FenceWaitTimeUs;
+ IMG_UINT32 ui32FenceRetryAbort;
+ IMG_BOOL bSupportsUMFlush;
+} CACHEOP_WORK_QUEUE;
+
+/* Top-level CacheOp framework object */
+static CACHEOP_WORK_QUEUE gsCwq;
+
+#define CacheOpConfigSupports(e) ((gsCwq.eConfig & (e)) ? IMG_TRUE : IMG_FALSE)
+
+static INLINE IMG_UINT32 CacheOpIdxRead(ATOMIC_T *phCounter)
+{
+ IMG_UINT32 ui32Idx = OSAtomicRead(phCounter);
+ return ui32Idx & CACHEOP_INDICES_MASK;
+}
+
+static INLINE IMG_UINT32 CacheOpIdxIncrement(ATOMIC_T *phCounter)
+{
+ IMG_UINT32 ui32Idx = OSAtomicIncrement(phCounter);
+ return ui32Idx & CACHEOP_INDICES_MASK;
+}
+
+static INLINE IMG_UINT32 CacheOpIdxNext(ATOMIC_T *phCounter)
+{
+ IMG_UINT32 ui32Idx = OSAtomicRead(phCounter);
+ return ++ui32Idx & CACHEOP_INDICES_MASK;
+}
+
+static INLINE IMG_UINT32 CacheOpIdxSpan(ATOMIC_T *phLhs, ATOMIC_T *phRhs)
+{
+ return OSAtomicRead(phLhs) - OSAtomicRead(phRhs);
+}
+
+/* Callback to dump info of cacheop thread in debug_dump */
+static void CacheOpThreadDumpInfo(DUMPDEBUG_PRINTF_FUNC* pfnDumpDebugPrintf,
+ void *pvDumpDebugFile)
+{
+ PVR_DUMPDEBUG_LOG(" Configuration: QSZ: %d, UKT: %d, KDFT: %d, "
+ "LINESIZE: %d, PGSIZE: %d, KDF: %s, "
+ "URBF: %s",
+ CACHEOP_INDICES_MAX,
+ gsCwq.pui32InfoPage[CACHEOP_INFO_UMKMTHRESHLD],
+ gsCwq.pui32InfoPage[CACHEOP_INFO_KMDFTHRESHLD],
+ gsCwq.pui32InfoPage[CACHEOP_INFO_LINESIZE],
+ gsCwq.pui32InfoPage[CACHEOP_INFO_PGSIZE],
+ gsCwq.eConfig & CACHEOP_CONFIG_KDF ? "Yes" : "No",
+ gsCwq.eConfig & CACHEOP_CONFIG_URBF ? "Yes" : "No"
+ );
+ PVR_DUMPDEBUG_LOG(" Pending deferred CacheOp entries : %u",
+ CacheOpIdxSpan(&gsCwq.hWriteCounter, &gsCwq.hReadCounter));
+}
+
+#if defined(CACHEOP_DEBUG)
+static INLINE void CacheOpStatsExecLogHeader(IMG_CHAR szBuffer[CACHEOP_MAX_DEBUG_MESSAGE_LEN])
+{
+ OSSNPrintf(szBuffer, CACHEOP_MAX_DEBUG_MESSAGE_LEN,
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG)
+ CACHEOP_RI_PRINTF_HEADER,
+#else
+ CACHEOP_PRINTF_HEADER,
+#endif
+ "DevID",
+ "Pid",
+ "CacheOp",
+ " Type",
+ "Mode",
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG)
+ "DevVAddr",
+ "DevPAddr",
+#endif
+ "Offset",
+ "Size",
+ "xTime (us)",
+ "qTime (us)",
+ "SeqNum");
+}
+
+static void CacheOpStatsExecLogWrite(CACHEOP_WORK_ITEM *psCacheOpWorkItem)
+{
+ IMG_UINT64 ui64ExecuteTime;
+ IMG_UINT64 ui64EnqueuedTime;
+ IMG_INT32 i32WriteOffset;
+
+ if (!psCacheOpWorkItem->ui32OpSeqNum && !psCacheOpWorkItem->uiCacheOp)
+ {
+ /* This breaks the logic of read-out, so we do not queue items
+ with zero sequence number and no CacheOp */
+ return;
+ }
+ else if (psCacheOpWorkItem->bKMReq && !CacheOpConfigSupports(CACHEOP_CONFIG_KLOG))
+ {
+ /* KM logs spams the history due to frequency, this removes it completely */
+ return;
+ }
+
+ OSLockAcquire(gsCwq.hStatsExecLock);
+
+ i32WriteOffset = gsCwq.i32StatsExecWriteIdx;
+ gsCwq.asStatsExecuted[i32WriteOffset].ui32DeviceID = psCacheOpWorkItem->psDevNode ? psCacheOpWorkItem->psDevNode->sDevId.ui32InternalID : -1;
+ gsCwq.asStatsExecuted[i32WriteOffset].pid = psCacheOpWorkItem->pid;
+ gsCwq.i32StatsExecWriteIdx = INCR_WRAP(gsCwq.i32StatsExecWriteIdx);
+ gsCwq.asStatsExecuted[i32WriteOffset].bUMF = psCacheOpWorkItem->bUMF;
+ gsCwq.asStatsExecuted[i32WriteOffset].uiSize = psCacheOpWorkItem->uiSize;
+ gsCwq.asStatsExecuted[i32WriteOffset].bKMReq = psCacheOpWorkItem->bKMReq;
+ gsCwq.asStatsExecuted[i32WriteOffset].uiOffset = psCacheOpWorkItem->uiOffset;
+ gsCwq.asStatsExecuted[i32WriteOffset].uiCacheOp = psCacheOpWorkItem->uiCacheOp;
+ gsCwq.asStatsExecuted[i32WriteOffset].bDeferred = psCacheOpWorkItem->bDeferred;
+ gsCwq.asStatsExecuted[i32WriteOffset].ui32OpSeqNum = psCacheOpWorkItem->ui32OpSeqNum;
+ gsCwq.asStatsExecuted[i32WriteOffset].ui64ExecuteTime = psCacheOpWorkItem->ui64ExecuteTime;
+ gsCwq.asStatsExecuted[i32WriteOffset].ui64EnqueuedTime = psCacheOpWorkItem->ui64EnqueuedTime;
+ gsCwq.asStatsExecuted[i32WriteOffset].ui64DequeuedTime = psCacheOpWorkItem->ui64DequeuedTime;
+ /* During early system initialisation, only non-fence & non-PMR CacheOps are processed */
+ gsCwq.asStatsExecuted[i32WriteOffset].bIsFence = gsCwq.bInit && !psCacheOpWorkItem->psPMR;
+ CACHEOP_PVR_ASSERT(gsCwq.asStatsExecuted[i32WriteOffset].pid);
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG)
+ if (gsCwq.bInit && psCacheOpWorkItem->psPMR)
+ {
+ IMG_CPU_PHYADDR sDevPAddr;
+ PVRSRV_ERROR eError, eLockError;
+ IMG_BOOL bValid;
+
+ /* Get more detailed information regarding the sub allocations that
+ PMR has from RI manager for process that requested the CacheOp */
+ eError = RIDumpProcessListKM(psCacheOpWorkItem->psPMR,
+ gsCwq.asStatsExecuted[i32WriteOffset].pid,
+ gsCwq.asStatsExecuted[i32WriteOffset].uiOffset,
+ &gsCwq.asStatsExecuted[i32WriteOffset].sDevVAddr);
+ PVR_GOTO_IF_ERROR(eError, e0);
+
+ /* (Re)lock here as some PMR might have not been locked */
+ eLockError = PMRLockSysPhysAddresses(psCacheOpWorkItem->psPMR);
+ PVR_GOTO_IF_ERROR(eLockError, e0);
+
+ eError = PMR_CpuPhysAddr(psCacheOpWorkItem->psPMR,
+ gsCwq.uiPageShift,
+ 1,
+ gsCwq.asStatsExecuted[i32WriteOffset].uiOffset,
+ &sDevPAddr,
+ &bValid);
+
+ eLockError = PMRUnlockSysPhysAddresses(psCacheOpWorkItem->psPMR);
+ PVR_LOG_IF_ERROR(eLockError, "PMRUnlockSysPhysAddresses");
+
+ PVR_GOTO_IF_ERROR(eError, e0);
+
+
+
+ gsCwq.asStatsExecuted[i32WriteOffset].sDevPAddr.uiAddr = sDevPAddr.uiAddr;
+ }
+
+ if (gsCwq.asStatsExecuted[i32WriteOffset].bIsFence)
+ {
+ gsCwq.asStatsExecuted[i32WriteOffset].eFenceOpType = psCacheOpWorkItem->eFenceOpType;
+ }
+#endif
+
+ {
+ /* Convert timing from nanoseconds to microseconds */
+ IMG_UINT64 ui64ExecuteTimeNs = gsCwq.asStatsExecuted[i32WriteOffset].ui64ExecuteTime;
+ IMG_UINT64 ui64EnqueuedTimeNs = gsCwq.asStatsExecuted[i32WriteOffset].ui64EnqueuedTime;
+
+ do_div(ui64ExecuteTimeNs, 1000);
+ do_div(ui64EnqueuedTimeNs, 1000);
+
+ ui64ExecuteTime = ui64ExecuteTimeNs;
+ ui64EnqueuedTime = ui64EnqueuedTimeNs;
+ }
+
+ /* Coalesced deferred CacheOps do not contribute to statistics,
+ as both enqueue/execute time is identical for these CacheOps */
+ if (!gsCwq.asStatsExecuted[i32WriteOffset].bIsFence)
+ {
+ /* Calculate the approximate cumulative moving average execution time.
+ * This calculation is based on standard equation:
+ *
+ * CMAnext = (new + count * CMAprev) / (count + 1)
+ *
+ * but in simplified form:
+ *
+ * CMAnext = CMAprev + (new - CMAprev) / (count + 1)
+ *
+ * this gets rid of multiplication and prevents overflow.
+ *
+ * Also to increase accuracy that we lose with integer division,
+ * we hold the moving remainder of the division and add it.
+ *
+ * CMAnext = CMAprev + (new - CMAprev + CMRprev) / (count + 1)
+ *
+ * Multiple tests proved it to be the best solution for approximating
+ * CMA using integers.
+ *
+ */
+
+ IMG_UINT32 ui32Time = ui64ExecuteTime - ui64EnqueuedTime;
+ IMG_INT32 i32Div = (IMG_INT32)ui32Time - (IMG_INT32)gsCwq.ui32AvgExecTime + (IMG_INT32)gsCwq.ui32AvgExecTimeRemainder;
+
+ gsCwq.ui32AvgExecTime += i32Div / (IMG_INT32)(gsCwq.ui32TotalExecOps + 1);
+ gsCwq.ui32AvgExecTimeRemainder = i32Div % (IMG_INT32)(gsCwq.ui32TotalExecOps + 1);
+
+ gsCwq.ui32TotalExecOps++;
+ }
+
+ if (!gsCwq.asStatsExecuted[i32WriteOffset].bKMReq)
+ {
+ /* This operation queues only UM CacheOp in per-PID process statistics database */
+ PVRSRVStatsUpdateCacheOpStats(gsCwq.asStatsExecuted[i32WriteOffset].uiCacheOp,
+ gsCwq.asStatsExecuted[i32WriteOffset].ui32OpSeqNum,
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG)
+ gsCwq.asStatsExecuted[i32WriteOffset].sDevVAddr,
+ gsCwq.asStatsExecuted[i32WriteOffset].sDevPAddr,
+ gsCwq.asStatsExecuted[i32WriteOffset].eFenceOpType,
+#endif
+ gsCwq.asStatsExecuted[i32WriteOffset].uiOffset,
+ gsCwq.asStatsExecuted[i32WriteOffset].uiSize,
+ ui64ExecuteTime-ui64EnqueuedTime,
+ gsCwq.asStatsExecuted[i32WriteOffset].bUMF,
+ gsCwq.asStatsExecuted[i32WriteOffset].bIsFence,
+ psCacheOpWorkItem->pid);
+ }
+
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG)
+e0:
+#endif
+ OSLockRelease(gsCwq.hStatsExecLock);
+}
+
+static int CacheOpStatsExecLogRead(OSDI_IMPL_ENTRY *psEntry, void *pvData)
+{
+ IMG_CHAR *pszFlushype;
+ IMG_CHAR *pszCacheOpType;
+ IMG_CHAR *pszFlushSource;
+ IMG_INT32 i32ReadOffset;
+ IMG_INT32 i32WriteOffset;
+ IMG_UINT64 ui64EnqueuedTime;
+ IMG_UINT64 ui64DequeuedTime;
+ IMG_UINT64 ui64ExecuteTime;
+ IMG_CHAR szBuffer[CACHEOP_MAX_DEBUG_MESSAGE_LEN] = {0};
+ PVR_UNREFERENCED_PARAMETER(pvData);
+
+ OSLockAcquire(gsCwq.hStatsExecLock);
+
+ DIPrintf(psEntry,
+ "Primary CPU d-cache architecture: LSZ: 0x%x, URBF: %s\n",
+ gsCwq.uiLineSize,
+ gsCwq.bSupportsUMFlush ? "Yes" : "No"
+ );
+
+ DIPrintf(psEntry,
+ "Configuration: QSZ: %d, UKT: %d, KDFT: %d, KDF: %s, URBF: %s\n",
+ CACHEOP_INDICES_MAX,
+ gsCwq.pui32InfoPage[CACHEOP_INFO_UMKMTHRESHLD],
+ gsCwq.pui32InfoPage[CACHEOP_INFO_KMDFTHRESHLD],
+ gsCwq.eConfig & CACHEOP_CONFIG_KDF ? "Yes" : "No",
+ gsCwq.eConfig & CACHEOP_CONFIG_URBF ? "Yes" : "No"
+ );
+
+ DIPrintf(psEntry,
+ "Summary: OP[F][TL] (tot.avg): %d.%d/%d.%d/%d, [KM][UM][A]SYNC: %d.%d/%d/%d, RBF (um/km): %d/%d\n",
+ gsCwq.ui32TotalExecOps, gsCwq.ui32AvgExecTime, gsCwq.ui32TotalFenceOps, gsCwq.ui32AvgFenceTime, gsCwq.ui32ServerDTL,
+ gsCwq.ui32ServerSync, gsCwq.ui32ServerSyncVA, gsCwq.ui32ClientSync, gsCwq.ui32ServerASync,
+ gsCwq.ui32ClientRBF, gsCwq.ui32ServerRBF
+ );
+
+ CacheOpStatsExecLogHeader(szBuffer);
+ DIPrintf(psEntry, "%s\n", szBuffer);
+
+ i32WriteOffset = gsCwq.i32StatsExecWriteIdx;
+ for (i32ReadOffset = DECR_WRAP(i32WriteOffset);
+ i32ReadOffset != i32WriteOffset;
+ i32ReadOffset = DECR_WRAP(i32ReadOffset))
+ {
+ if (!gsCwq.asStatsExecuted[i32ReadOffset].ui32OpSeqNum &&
+ !gsCwq.asStatsExecuted[i32ReadOffset].uiCacheOp)
+ {
+ break;
+ }
+
+ {
+ /* Convert from nano-seconds to micro-seconds */
+ IMG_UINT64 ui64ExecuteTimeNs = gsCwq.asStatsExecuted[i32ReadOffset].ui64ExecuteTime;
+ IMG_UINT64 ui64EnqueuedTimeNs = gsCwq.asStatsExecuted[i32ReadOffset].ui64EnqueuedTime;
+ IMG_UINT64 ui64DequeuedTimeNs = gsCwq.asStatsExecuted[i32ReadOffset].ui64DequeuedTime;
+
+ do_div(ui64ExecuteTimeNs, 1000);
+ do_div(ui64EnqueuedTimeNs, 1000);
+ do_div(ui64DequeuedTimeNs, 1000);
+
+ ui64ExecuteTime = ui64ExecuteTimeNs;
+ ui64EnqueuedTime = ui64EnqueuedTimeNs;
+ ui64DequeuedTime = ui64DequeuedTimeNs;
+ }
+
+ if (gsCwq.asStatsExecuted[i32ReadOffset].bIsFence)
+ {
+ IMG_CHAR *pszMode = "";
+ IMG_CHAR *pszFenceType = "";
+ pszCacheOpType = "Fence";
+
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG)
+ switch (gsCwq.asStatsExecuted[i32ReadOffset].eFenceOpType)
+ {
+ case RGXFWIF_DM_GP:
+ pszFenceType = " GP ";
+ break;
+
+ case RGXFWIF_DM_TDM:
+ pszFenceType = " TDM ";
+ break;
+
+ case RGXFWIF_DM_GEOM:
+ pszFenceType = " GEOM";
+ break;
+
+ case RGXFWIF_DM_3D:
+ pszFenceType = " 3D ";
+ break;
+
+ case RGXFWIF_DM_CDM:
+ pszFenceType = " CDM ";
+ break;
+
+ default:
+ pszFenceType = " DM? ";
+ CACHEOP_PVR_ASSERT(0);
+ break;
+ }
+#endif
+
+ DIPrintf(psEntry,
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG)
+ CACHEOP_RI_PRINTF,
+#else
+ CACHEOP_PRINTF,
+#endif
+ gsCwq.asStatsExecuted[i32ReadOffset].ui32DeviceID,
+ gsCwq.asStatsExecuted[i32ReadOffset].pid,
+ pszCacheOpType,
+ pszFenceType,
+ pszMode,
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG)
+ 0ull,
+ 0ull,
+#endif
+ gsCwq.asStatsExecuted[i32ReadOffset].uiOffset,
+ gsCwq.asStatsExecuted[i32ReadOffset].uiSize,
+ ui64ExecuteTime - ui64EnqueuedTime,
+ ui64DequeuedTime ? ui64DequeuedTime - ui64EnqueuedTime : 0, /* CacheOp might not have a valid DequeuedTime */
+ gsCwq.asStatsExecuted[i32ReadOffset].ui32OpSeqNum);
+ }
+ else
+ {
+ IMG_DEVMEM_SIZE_T ui64NumOfPages;
+
+ ui64NumOfPages = gsCwq.asStatsExecuted[i32ReadOffset].uiSize >> gsCwq.uiPageShift;
+ if (ui64NumOfPages <= PMR_MAX_TRANSLATION_STACK_ALLOC)
+ {
+ pszFlushype = "RBF.Fast";
+ }
+ else
+ {
+ pszFlushype = "RBF.Slow";
+ }
+
+ if (gsCwq.asStatsExecuted[i32ReadOffset].bUMF)
+ {
+ pszFlushSource = " UM";
+ }
+ else
+ {
+ /*
+ - Request originates directly from a KM thread or in KM (KM<), or
+ - Request originates from a UM thread and is KM deferred (KM+), or
+ */
+ pszFlushSource =
+ gsCwq.asStatsExecuted[i32ReadOffset].bKMReq ? " KM<" :
+ gsCwq.asStatsExecuted[i32ReadOffset].bDeferred && gsCwq.asStatsExecuted[i32ReadOffset].ui64ExecuteTime ? " KM+" :
+ !gsCwq.asStatsExecuted[i32ReadOffset].ui64ExecuteTime ? " KM-" : " KM";
+ }
+
+ switch (gsCwq.asStatsExecuted[i32ReadOffset].uiCacheOp)
+ {
+ case PVRSRV_CACHE_OP_NONE:
+ pszCacheOpType = "None";
+ break;
+ case PVRSRV_CACHE_OP_CLEAN:
+ pszCacheOpType = "Clean";
+ break;
+ case PVRSRV_CACHE_OP_INVALIDATE:
+ pszCacheOpType = "Invalidate";
+ break;
+ case PVRSRV_CACHE_OP_FLUSH:
+ pszCacheOpType = "Flush";
+ break;
+ case PVRSRV_CACHE_OP_TIMELINE:
+ pszCacheOpType = "Timeline";
+ pszFlushype = " ";
+ break;
+ default:
+ pszCacheOpType = "Unknown";
+ gsCwq.asStatsExecuted[i32ReadOffset].ui32OpSeqNum =
+ (IMG_UINT32) gsCwq.asStatsExecuted[i32ReadOffset].uiCacheOp;
+ break;
+ }
+
+ DIPrintf(psEntry,
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG)
+ CACHEOP_RI_PRINTF,
+#else
+ CACHEOP_PRINTF,
+#endif
+ gsCwq.asStatsExecuted[i32ReadOffset].ui32DeviceID,
+ gsCwq.asStatsExecuted[i32ReadOffset].pid,
+ pszCacheOpType,
+ pszFlushype,
+ pszFlushSource,
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG)
+ gsCwq.asStatsExecuted[i32ReadOffset].sDevVAddr.uiAddr,
+ gsCwq.asStatsExecuted[i32ReadOffset].sDevPAddr.uiAddr,
+#endif
+ gsCwq.asStatsExecuted[i32ReadOffset].uiOffset,
+ gsCwq.asStatsExecuted[i32ReadOffset].uiSize,
+ ui64ExecuteTime - ui64EnqueuedTime,
+ ui64DequeuedTime ? ui64DequeuedTime - ui64EnqueuedTime : 0, /* CacheOp might not have a valid DequeuedTime */
+ gsCwq.asStatsExecuted[i32ReadOffset].ui32OpSeqNum);
+ }
+ }
+
+ OSLockRelease(gsCwq.hStatsExecLock);
+
+ return 0;
+}
+#endif /* defined(CACHEOP_DEBUG) */
+
+static INLINE void CacheOpStatsReset(void)
+{
+#if defined(CACHEOP_DEBUG)
+ gsCwq.ui32TotalExecOps = 0;
+ gsCwq.ui32TotalFenceOps = 0;
+ gsCwq.ui32AvgExecTime = 0;
+ gsCwq.ui32AvgExecTimeRemainder = 0;
+ gsCwq.ui32AvgFenceTime = 0;
+ gsCwq.ui32AvgFenceTimeRemainder = 0;
+ gsCwq.ui32ClientRBF = 0;
+ gsCwq.ui32ClientSync = 0;
+ gsCwq.ui32ServerRBF = 0;
+ gsCwq.ui32ServerASync = 0;
+ gsCwq.ui32ServerSyncVA = 0;
+ gsCwq.ui32ServerSync = 0;
+ gsCwq.ui32ServerDTL = 0;
+ gsCwq.i32StatsExecWriteIdx = 0;
+ OSCachedMemSet(gsCwq.asStatsExecuted, 0, sizeof(gsCwq.asStatsExecuted));
+#endif
+}
+
+static void CacheOpConfigUpdate(IMG_UINT32 ui32Config)
+{
+ OSLockAcquire(gsCwq.hConfigLock);
+
+ /* Step 0, set the gsCwq.eConfig bits */
+ if (!(ui32Config & (CACHEOP_CONFIG_LAST - 1)))
+ {
+ gsCwq.eConfig = CACHEOP_CONFIG_KDF;
+ if (gsCwq.bSupportsUMFlush)
+ {
+ gsCwq.eConfig |= CACHEOP_CONFIG_URBF;
+ }
+ }
+ else
+ {
+ if (ui32Config & CACHEOP_CONFIG_KDF)
+ {
+ gsCwq.eConfig |= CACHEOP_CONFIG_KDF;
+ }
+ else
+ {
+ gsCwq.eConfig &= ~CACHEOP_CONFIG_KDF;
+ }
+
+ if (gsCwq.bSupportsUMFlush && (ui32Config & CACHEOP_CONFIG_URBF))
+ {
+ gsCwq.eConfig |= CACHEOP_CONFIG_URBF;
+ }
+ else
+ {
+ gsCwq.eConfig &= ~CACHEOP_CONFIG_URBF;
+ }
+ }
+
+ if (ui32Config & CACHEOP_CONFIG_KLOG)
+ {
+ /* Suppress logs from KM caller */
+ gsCwq.eConfig |= CACHEOP_CONFIG_KLOG;
+ }
+ else
+ {
+ gsCwq.eConfig &= ~CACHEOP_CONFIG_KLOG;
+ }
+
+ /* Step 1, set gsCwq.ui32Config based on gsCwq.eConfig */
+ ui32Config = 0;
+
+ if (gsCwq.eConfig & CACHEOP_CONFIG_KDF)
+ {
+ ui32Config |= CACHEOP_CONFIG_KDF;
+ }
+ if (gsCwq.eConfig & CACHEOP_CONFIG_URBF)
+ {
+ ui32Config |= CACHEOP_CONFIG_URBF;
+ }
+ if (gsCwq.eConfig & CACHEOP_CONFIG_KLOG)
+ {
+ ui32Config |= CACHEOP_CONFIG_KLOG;
+ }
+ gsCwq.ui32Config = ui32Config;
+
+
+ /* Step 3, in certain cases where a CacheOp/VA is provided, this threshold determines at what point
+ the optimisation due to the presence of said VA (i.e. us not having to remap the PMR pages in KM)
+ is clawed-back because of the overhead of maintaining such large request which might stalls the
+ user thread; so to hide this latency have these CacheOps executed on deferred CacheOp thread */
+ gsCwq.pui32InfoPage[CACHEOP_INFO_KMDFTHRESHLD] = (IMG_UINT32)(PVR_DIRTY_BYTES_FLUSH_THRESHOLD >> 2);
+
+ /* Step 4, if no UM support, all requests are done in KM so zero these forcing all client requests
+ to come down into the KM for maintenance */
+ gsCwq.pui32InfoPage[CACHEOP_INFO_UMKMTHRESHLD] = 0;
+
+ if (gsCwq.bSupportsUMFlush)
+ {
+ /* With URBF enabled we never go to the kernel */
+ if (gsCwq.eConfig & CACHEOP_CONFIG_URBF)
+ {
+ gsCwq.pui32InfoPage[CACHEOP_INFO_UMKMTHRESHLD] = (IMG_UINT32)~0;
+ }
+ }
+
+ /* Step 5, reset stats. */
+ CacheOpStatsReset();
+
+ OSLockRelease(gsCwq.hConfigLock);
+}
+
+static int CacheOpConfigRead(OSDI_IMPL_ENTRY *psEntry, void *pvData)
+{
+ PVR_UNREFERENCED_PARAMETER(pvData);
+ DIPrintf(psEntry,
+ "KDF: %s, URBF: %s\n",
+ gsCwq.eConfig & CACHEOP_CONFIG_KDF ? "Yes" : "No",
+ gsCwq.eConfig & CACHEOP_CONFIG_URBF ? "Yes" : "No"
+ );
+ return 0;
+}
+
+static INLINE PVRSRV_ERROR CacheOpConfigQuery(const PVRSRV_DEVICE_NODE *psDevNode,
+ const void *psPrivate,
+ IMG_UINT32 *pui32Value)
+{
+ IMG_UINT32 ui32ID = (IMG_UINT32)(uintptr_t) psPrivate;
+ PVR_UNREFERENCED_PARAMETER(psDevNode);
+
+ switch (ui32ID)
+ {
+ case APPHINT_ID_CacheOpConfig:
+ *pui32Value = gsCwq.ui32Config;
+ break;
+
+ case APPHINT_ID_CacheOpUMKMThresholdSize:
+ *pui32Value = gsCwq.pui32InfoPage[CACHEOP_INFO_UMKMTHRESHLD];
+ break;
+
+ default:
+ break;
+ }
+
+ return PVRSRV_OK;
+}
+
+static INLINE PVRSRV_ERROR CacheOpConfigSet(const PVRSRV_DEVICE_NODE *psDevNode,
+ const void *psPrivate,
+ IMG_UINT32 ui32Value)
+{
+ IMG_UINT32 ui32ID = (IMG_UINT32)(uintptr_t) psPrivate;
+ PVR_UNREFERENCED_PARAMETER(psDevNode);
+
+ switch (ui32ID)
+ {
+ case APPHINT_ID_CacheOpConfig:
+ CacheOpConfigUpdate(ui32Value & CACHEOP_CONFIG_ALL);
+ break;
+
+
+ case APPHINT_ID_CacheOpUMKMThresholdSize:
+ {
+ if (!ui32Value || !gsCwq.bSupportsUMFlush)
+ {
+ /* CPU ISA does not support UM flush, therefore every request goes down into
+ the KM, silently ignore request to adjust threshold */
+ PVR_ASSERT(! gsCwq.pui32InfoPage[CACHEOP_INFO_UMKMTHRESHLD]);
+ break;
+ }
+ else if (ui32Value < gsCwq.uiPageSize)
+ {
+ /* Silently round-up to OS page size */
+ ui32Value = gsCwq.uiPageSize;
+ }
+
+ /* Align to OS page size */
+ ui32Value &= ~(gsCwq.uiPageSize - 1);
+
+ gsCwq.pui32InfoPage[CACHEOP_INFO_UMKMTHRESHLD] = ui32Value;
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return PVRSRV_OK;
+}
+
+static INLINE IMG_UINT32 CacheOpGetNextCommonSeqNum(void)
+{
+ IMG_UINT32 ui32SeqNum = OSAtomicIncrement(&gsCwq.hCommonSeqNum);
+ if (! ui32SeqNum)
+ {
+ ui32SeqNum = OSAtomicIncrement(&gsCwq.hCommonSeqNum);
+ }
+ return ui32SeqNum;
+}
+
+static INLINE IMG_BOOL CacheOpFenceCheck(IMG_UINT32 ui32CompletedSeqNum,
+ IMG_UINT32 ui32FenceSeqNum)
+{
+ IMG_UINT32 ui32RebasedCompletedNum;
+ IMG_UINT32 ui32RebasedFenceNum;
+ IMG_UINT32 ui32Rebase;
+
+ if (ui32FenceSeqNum == 0)
+ {
+ return IMG_TRUE;
+ }
+
+ /*
+ The problem statement is how to compare two values on
+ a numerical sequentially incrementing timeline in the
+ presence of wrap around arithmetic semantics using a
+ single ui32 counter & atomic (increment) operations.
+
+ The rationale for the solution here is to rebase the
+ incoming values to the sequence midpoint and perform
+ comparisons there; this allows us to handle overflow
+ or underflow wrap-round using only a single integer.
+
+ NOTE: Here we assume that the absolute value of the
+ difference between the two incoming values in _not_
+ greater than CACHEOP_SEQ_MIDPOINT. This assumption
+ holds as it implies that it is very _unlikely_ that 2
+ billion CacheOp requests could have been made between
+ a single client's CacheOp request & the corresponding
+ fence check. This code sequence is hopefully a _more_
+ hand optimised (branchless) version of this:
+
+ x = ui32CompletedOpSeqNum
+ y = ui32FenceOpSeqNum
+
+ if (|x - y| < CACHEOP_SEQ_MIDPOINT)
+ return (x - y) >= 0 ? true : false
+ else
+ return (y - x) >= 0 ? true : false
+ */
+ ui32Rebase = CACHEOP_SEQ_MIDPOINT - ui32CompletedSeqNum;
+
+ /* ui32Rebase could be either positive/negative, in
+ any case we still perform operation using unsigned
+ semantics as 2's complement notation always means
+ we end up with the correct result */
+ ui32RebasedCompletedNum = ui32Rebase + ui32CompletedSeqNum;
+ ui32RebasedFenceNum = ui32Rebase + ui32FenceSeqNum;
+
+ return (ui32RebasedCompletedNum >= ui32RebasedFenceNum);
+}
+
+static INLINE PVRSRV_ERROR CacheOpTimelineBind(PVRSRV_DEVICE_NODE *psDevNode,
+ CACHEOP_WORK_ITEM *psCacheOpWorkItem,
+ PVRSRV_TIMELINE iTimeline)
+{
+ PVRSRV_ERROR eError;
+
+ /* Always default the incoming CacheOp work-item to safe values */
+ SyncClearTimelineObj(&psCacheOpWorkItem->sSWTimelineObj);
+ psCacheOpWorkItem->iTimeline = PVRSRV_NO_TIMELINE;
+ psCacheOpWorkItem->psDevNode = psDevNode;
+ if (iTimeline == PVRSRV_NO_TIMELINE)
+ {
+ return PVRSRV_OK;
+ }
+
+ psCacheOpWorkItem->iTimeline = iTimeline;
+ eError = SyncSWGetTimelineObj(iTimeline, &psCacheOpWorkItem->sSWTimelineObj);
+ PVR_LOG_IF_ERROR(eError, "SyncSWGetTimelineObj");
+
+ return eError;
+}
+
+static INLINE PVRSRV_ERROR CacheOpTimelineExec(CACHEOP_WORK_ITEM *psCacheOpWorkItem)
+{
+ PVRSRV_ERROR eError;
+
+ if (psCacheOpWorkItem->iTimeline == PVRSRV_NO_TIMELINE)
+ {
+ return PVRSRV_OK;
+ }
+ CACHEOP_PVR_ASSERT(psCacheOpWorkItem->sSWTimelineObj.pvTlObj);
+
+ eError = SyncSWTimelineAdvanceKM(psCacheOpWorkItem->psDevNode,
+ &psCacheOpWorkItem->sSWTimelineObj);
+ (void) SyncSWTimelineReleaseKM(&psCacheOpWorkItem->sSWTimelineObj);
+
+ return eError;
+}
+
+static INLINE void CacheOpExecRangeBased(PVRSRV_DEVICE_NODE *psDevNode,
+ PVRSRV_CACHE_OP uiCacheOp,
+ IMG_BYTE *pbCpuVirtAddr,
+ IMG_CPU_PHYADDR sCpuPhyAddr,
+ IMG_DEVMEM_OFFSET_T uiPgAlignedOffset,
+ IMG_DEVMEM_OFFSET_T uiCLAlignedStartOffset,
+ IMG_DEVMEM_OFFSET_T uiCLAlignedEndOffset)
+{
+ IMG_BYTE *pbCpuVirtAddrEnd;
+ IMG_BYTE *pbCpuVirtAddrStart;
+ IMG_CPU_PHYADDR sCpuPhyAddrEnd;
+ IMG_CPU_PHYADDR sCpuPhyAddrStart;
+ IMG_DEVMEM_SIZE_T uiRelFlushSize;
+ IMG_DEVMEM_OFFSET_T uiRelFlushOffset;
+ IMG_DEVMEM_SIZE_T uiNextPgAlignedOffset;
+
+ /* These quantities allows us to perform cache operations
+ at cache-line granularity thereby ensuring we do not
+ perform more than is necessary */
+ CACHEOP_PVR_ASSERT(uiPgAlignedOffset < uiCLAlignedEndOffset);
+ uiRelFlushSize = (IMG_DEVMEM_SIZE_T)gsCwq.uiPageSize;
+ uiRelFlushOffset = 0;
+
+ if (uiCLAlignedStartOffset > uiPgAlignedOffset)
+ {
+ /* Zero unless initially starting at an in-page offset */
+ uiRelFlushOffset = uiCLAlignedStartOffset - uiPgAlignedOffset;
+ uiRelFlushSize -= uiRelFlushOffset;
+ }
+
+ /* uiRelFlushSize is gsCwq.uiPageSize unless current outstanding CacheOp
+ size is smaller. The 1st case handles in-page CacheOp range and
+ the 2nd case handles multiple-page CacheOp range with a last
+ CacheOp size that is less than gsCwq.uiPageSize */
+ uiNextPgAlignedOffset = uiPgAlignedOffset + (IMG_DEVMEM_SIZE_T)gsCwq.uiPageSize;
+ if (uiNextPgAlignedOffset < uiPgAlignedOffset)
+ {
+ /* uiNextPgAlignedOffset is greater than uiCLAlignedEndOffset
+ by implication of this wrap-round; this only happens when
+ uiPgAlignedOffset is the last page aligned offset */
+ uiRelFlushSize = uiRelFlushOffset ?
+ uiCLAlignedEndOffset - uiCLAlignedStartOffset :
+ uiCLAlignedEndOffset - uiPgAlignedOffset;
+ }
+ else
+ {
+ if (uiNextPgAlignedOffset > uiCLAlignedEndOffset)
+ {
+ uiRelFlushSize = uiRelFlushOffset ?
+ uiCLAlignedEndOffset - uiCLAlignedStartOffset :
+ uiCLAlignedEndOffset - uiPgAlignedOffset;
+ }
+ }
+
+ /* More efficient to request cache maintenance operation for full
+ relative range as opposed to multiple cache-aligned ranges */
+ sCpuPhyAddrStart.uiAddr = sCpuPhyAddr.uiAddr + uiRelFlushOffset;
+ sCpuPhyAddrEnd.uiAddr = sCpuPhyAddrStart.uiAddr + uiRelFlushSize;
+ if (pbCpuVirtAddr)
+ {
+ pbCpuVirtAddrStart = pbCpuVirtAddr + uiRelFlushOffset;
+ pbCpuVirtAddrEnd = pbCpuVirtAddrStart + uiRelFlushSize;
+ }
+ else
+ {
+ /* Some OS/Env layer support functions expect NULL(s) */
+ pbCpuVirtAddrStart = NULL;
+ pbCpuVirtAddrEnd = NULL;
+ }
+
+ /* Perform requested CacheOp on the CPU data cache for successive cache
+ line worth of bytes up to page or in-page cache-line boundary */
+ switch (uiCacheOp)
+ {
+ case PVRSRV_CACHE_OP_CLEAN:
+ OSCPUCacheCleanRangeKM(psDevNode, pbCpuVirtAddrStart, pbCpuVirtAddrEnd,
+ sCpuPhyAddrStart, sCpuPhyAddrEnd);
+ break;
+ case PVRSRV_CACHE_OP_INVALIDATE:
+ OSCPUCacheInvalidateRangeKM(psDevNode, pbCpuVirtAddrStart, pbCpuVirtAddrEnd,
+ sCpuPhyAddrStart, sCpuPhyAddrEnd);
+ break;
+ case PVRSRV_CACHE_OP_FLUSH:
+ OSCPUCacheFlushRangeKM(psDevNode, pbCpuVirtAddrStart, pbCpuVirtAddrEnd,
+ sCpuPhyAddrStart, sCpuPhyAddrEnd);
+ break;
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid cache operation type %d",
+ __func__, uiCacheOp));
+ break;
+ }
+
+#if defined(CACHEOP_DEBUG)
+ /* Tracks the number of kernel-mode cacheline maintenance instructions */
+ gsCwq.ui32ServerRBF += (uiRelFlushSize & ((IMG_DEVMEM_SIZE_T)~(gsCwq.uiLineSize - 1))) >> gsCwq.uiLineShift;
+#endif
+}
+
+static INLINE void CacheOpExecRangeBasedVA(PVRSRV_DEVICE_NODE *psDevNode,
+ IMG_CPU_VIRTADDR pvAddress,
+ IMG_DEVMEM_SIZE_T uiSize,
+ PVRSRV_CACHE_OP uiCacheOp)
+{
+ IMG_CPU_PHYADDR sCpuPhyAddrUnused =
+ { IMG_CAST_TO_CPUPHYADDR_UINT(0xCAFEF00DDEADBEEFULL) };
+ IMG_BYTE *pbEnd = (IMG_BYTE*)((uintptr_t)pvAddress + (uintptr_t)uiSize);
+ IMG_BYTE *pbStart = (IMG_BYTE*)((uintptr_t)pvAddress & ~((uintptr_t)gsCwq.uiLineSize-1));
+
+ /*
+ If the start/end address isn't aligned to cache line size, round it up to the
+ nearest multiple; this ensures that we flush all the cache lines affected by
+ unaligned start/end addresses.
+ */
+ pbEnd = (IMG_BYTE *) PVR_ALIGN((uintptr_t)pbEnd, (uintptr_t)gsCwq.uiLineSize);
+ switch (uiCacheOp)
+ {
+ case PVRSRV_CACHE_OP_CLEAN:
+ OSCPUCacheCleanRangeKM(psDevNode, pbStart, pbEnd, sCpuPhyAddrUnused, sCpuPhyAddrUnused);
+ break;
+ case PVRSRV_CACHE_OP_INVALIDATE:
+ OSCPUCacheInvalidateRangeKM(psDevNode, pbStart, pbEnd, sCpuPhyAddrUnused, sCpuPhyAddrUnused);
+ break;
+ case PVRSRV_CACHE_OP_FLUSH:
+ OSCPUCacheFlushRangeKM(psDevNode, pbStart, pbEnd, sCpuPhyAddrUnused, sCpuPhyAddrUnused);
+ break;
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid cache operation type %d",
+ __func__, uiCacheOp));
+ break;
+ }
+
+#if defined(CACHEOP_DEBUG)
+ /* Tracks the number of kernel-mode cacheline maintenance instructions */
+ gsCwq.ui32ServerRBF += (uiSize & ((IMG_DEVMEM_SIZE_T)~(gsCwq.uiLineSize - 1))) >> gsCwq.uiLineShift;
+#endif
+}
+
+static INLINE PVRSRV_ERROR CacheOpValidateUMVA(PMR *psPMR,
+ IMG_CPU_VIRTADDR pvAddress,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_DEVMEM_SIZE_T uiSize,
+ PVRSRV_CACHE_OP uiCacheOp,
+ void **ppvOutAddress)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+#if defined(__linux__) && !defined(CACHEFLUSH_NO_KMRBF_USING_UMVA)
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+#endif
+ void __user *pvAddr;
+
+ IMG_BOOL bReadOnlyInvalidate =
+ (uiCacheOp == PVRSRV_CACHE_OP_INVALIDATE) &&
+ !PVRSRV_CHECK_CPU_WRITEABLE(PMR_Flags(psPMR));
+
+ if (!pvAddress || bReadOnlyInvalidate)
+ {
+ /* As pvAddress is optional, NULL is expected from UM/KM requests */
+ /* Also don't allow invalidates for UMVA of read-only memory */
+ pvAddr = NULL;
+ goto e0;
+ }
+
+
+
+#if !defined(__linux__) || defined(CACHEFLUSH_NO_KMRBF_USING_UMVA)
+ pvAddr = NULL;
+#else
+ /* Validate VA, assume most basic address limit access_ok() check */
+ pvAddr = (void __user *)(uintptr_t)((uintptr_t)pvAddress + uiOffset);
+ if (!access_ok(pvAddr, uiSize))
+ {
+ pvAddr = NULL;
+ if (! mm)
+ {
+ /* Bad KM request, don't silently ignore */
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_CPU_ADDR, e0);
+ }
+ }
+ else if (mm)
+ {
+ mmap_read_lock(mm);
+ vma = find_vma(mm, (unsigned long)(uintptr_t)pvAddr);
+
+ if (!vma ||
+ vma->vm_start > (unsigned long)(uintptr_t)pvAddr ||
+ vma->vm_end < (unsigned long)(uintptr_t)pvAddr + uiSize ||
+ vma->vm_private_data != psPMR)
+ {
+ /*
+ * Request range is not fully mapped or is not matching the PMR
+ * Ignore request's VA.
+ */
+ pvAddr = NULL;
+ }
+ mmap_read_unlock(mm);
+ }
+#endif
+
+e0:
+ *ppvOutAddress = (IMG_CPU_VIRTADDR __force) pvAddr;
+ return eError;
+}
+
+static PVRSRV_ERROR CacheOpPMRExec (PMR *psPMR,
+ IMG_CPU_VIRTADDR pvAddress,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_DEVMEM_SIZE_T uiSize,
+ PVRSRV_CACHE_OP uiCacheOp,
+ IMG_BOOL bIsRequestValidated)
+
+{
+ IMG_HANDLE hPrivOut = NULL;
+ IMG_BOOL bPMRIsSparse;
+ IMG_UINT32 ui32PageIndex;
+ IMG_UINT32 ui32NumOfPages;
+ size_t uiOutSize; /* Effectively unused */
+ PVRSRV_DEVICE_NODE *psDevNode;
+ IMG_DEVMEM_SIZE_T uiPgAlignedSize;
+ IMG_DEVMEM_OFFSET_T uiPgAlignedOffset;
+ IMG_DEVMEM_OFFSET_T uiCLAlignedEndOffset;
+ IMG_DEVMEM_OFFSET_T uiPgAlignedEndOffset;
+ IMG_DEVMEM_OFFSET_T uiCLAlignedStartOffset;
+ IMG_DEVMEM_OFFSET_T uiPgAlignedStartOffset;
+ IMG_BOOL abValid[PMR_MAX_TRANSLATION_STACK_ALLOC];
+ IMG_CPU_PHYADDR asCpuPhyAddr[PMR_MAX_TRANSLATION_STACK_ALLOC];
+ IMG_CPU_PHYADDR *psCpuPhyAddr = asCpuPhyAddr;
+ IMG_BOOL bIsPMRInfoValid = IMG_FALSE;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ IMG_BYTE *pbCpuVirtAddr = NULL;
+ IMG_BOOL *pbValid = abValid;
+
+ if (uiCacheOp == PVRSRV_CACHE_OP_NONE || uiCacheOp == PVRSRV_CACHE_OP_TIMELINE)
+ {
+ return PVRSRV_OK;
+ }
+
+ if (! bIsRequestValidated)
+ {
+ IMG_DEVMEM_SIZE_T uiLPhysicalSize;
+
+ /* Need to validate parameters before proceeding */
+ eError = PMR_PhysicalSize(psPMR, &uiLPhysicalSize);
+ PVR_LOG_RETURN_IF_ERROR(eError, "uiLPhysicalSize");
+
+ PVR_LOG_RETURN_IF_FALSE(((uiOffset+uiSize) <= uiLPhysicalSize), CACHEOP_DEVMEM_OOR_ERROR_STRING, PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE);
+
+ eError = PMRLockSysPhysAddresses(psPMR);
+ PVR_LOG_RETURN_IF_ERROR(eError, "PMRLockSysPhysAddresses");
+ }
+
+ /* Fast track the request if a CPU VA is provided and CPU ISA supports VA only maintenance */
+ eError = CacheOpValidateUMVA(psPMR, pvAddress, uiOffset, uiSize, uiCacheOp, (void**)&pbCpuVirtAddr);
+ if (eError == PVRSRV_OK)
+ {
+ pvAddress = pbCpuVirtAddr;
+
+ if (pvAddress && gsCwq.uiCacheOpAddrType == OS_CACHE_OP_ADDR_TYPE_VIRTUAL)
+ {
+ CacheOpExecRangeBasedVA(PMR_DeviceNode(psPMR), pvAddress, uiSize, uiCacheOp);
+
+ if (!bIsRequestValidated)
+ {
+ eError = PMRUnlockSysPhysAddresses(psPMR);
+ PVR_LOG_IF_ERROR(eError, "PMRUnlockSysPhysAddresses");
+ }
+#if defined(CACHEOP_DEBUG)
+ gsCwq.ui32ServerSyncVA += 1;
+#endif
+ return PVRSRV_OK;
+ }
+ else if (pvAddress)
+ {
+ /* Round down the incoming VA (if any) down to the nearest page aligned VA */
+ pvAddress = (void*)((uintptr_t)pvAddress & ~((uintptr_t)gsCwq.uiPageSize-1));
+#if defined(CACHEOP_DEBUG)
+ gsCwq.ui32ServerSyncVA += 1;
+#endif
+ }
+ }
+ else
+ {
+ /*
+ * This validation pathway has been added to accommodate any/all requests that might
+ * cause the kernel to Oops; essentially, KM requests should prevalidate cache maint.
+ * parameters but if this fails then we would rather fail gracefully than cause the
+ * kernel to Oops so instead we log the fact that an invalid KM virtual address was
+ * supplied and what action was taken to mitigate against kernel Oops(ing) if any.
+ */
+ CACHEOP_PVR_ASSERT(pbCpuVirtAddr == NULL);
+
+ if (gsCwq.uiCacheOpAddrType == OS_CACHE_OP_ADDR_TYPE_PHYSICAL)
+ {
+ PVR_DPF((PVR_DBG_WARNING,
+ "%s: Invalid vaddress 0x%p in CPU d-cache maint. op, using paddress",
+ __func__,
+ pvAddress));
+
+ /* We can still proceed as kernel/cpu uses CPU PA for d-cache maintenance */
+ pvAddress = NULL;
+ }
+ else
+ {
+ /*
+ * The approach here is to attempt a reacquisition of the PMR kernel VA and see if
+ * said VA corresponds to the parameter VA, if so fail requested cache maint. op.
+ * cause this indicates some kind of internal, memory and/or meta-data corruption
+ * else we reissue the request using this (re)acquired alias PMR kernel VA.
+ */
+ if (PMR_IsSparse(psPMR))
+ {
+ eError = PMRAcquireSparseKernelMappingData(psPMR,
+ 0,
+ gsCwq.uiPageSize,
+ (void **)&pbCpuVirtAddr,
+ &uiOutSize,
+ &hPrivOut);
+ PVR_LOG_GOTO_IF_ERROR(eError, "PMRAcquireSparseKernelMappingData", e0);
+ }
+ else
+ {
+ eError = PMRAcquireKernelMappingData(psPMR,
+ 0,
+ gsCwq.uiPageSize,
+ (void **)&pbCpuVirtAddr,
+ &uiOutSize,
+ &hPrivOut);
+ PVR_LOG_GOTO_IF_ERROR(eError, "PMRAcquireKernelMappingData", e0);
+ }
+
+ /* Here, we only compare these CPU virtual addresses at granularity of the OS page size */
+ if ((uintptr_t)pbCpuVirtAddr == ((uintptr_t)pvAddress & ~((uintptr_t)gsCwq.uiPageSize-1)))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Invalid vaddress 0x%p in CPU d-cache maint. op, no alt. so failing request",
+ __func__,
+ pvAddress));
+
+ eError = PMRReleaseKernelMappingData(psPMR, hPrivOut);
+ PVR_LOG_GOTO_WITH_ERROR("PMRReleaseKernelMappingData", eError, PVRSRV_ERROR_INVALID_CPU_ADDR, e0);
+ }
+ else if (gsCwq.uiCacheOpAddrType == OS_CACHE_OP_ADDR_TYPE_VIRTUAL)
+ {
+ PVR_DPF((PVR_DBG_WARNING,
+ "%s: Bad vaddress 0x%p in CPU d-cache maint. op, using reacquired vaddress 0x%p",
+ __func__,
+ pvAddress,
+ pbCpuVirtAddr));
+
+ /* Note that this might still fail if there is kernel memory/meta-data corruption;
+ there is not much we can do here but at the least we will be informed of this
+ before the kernel Oops(ing) */
+ CacheOpExecRangeBasedVA(PMR_DeviceNode(psPMR), pbCpuVirtAddr, uiSize, uiCacheOp);
+
+ eError = PMRReleaseKernelMappingData(psPMR, hPrivOut);
+ PVR_LOG_IF_ERROR(eError, "PMRReleaseKernelMappingData");
+
+ eError = PVRSRV_OK;
+ goto e0;
+ }
+ else
+ {
+ /* At this junction, we have exhausted every possible work-around possible but we do
+ know that VA reacquisition returned another/alias page-aligned VA; so with this
+ future expectation of PMRAcquireKernelMappingData(), we proceed */
+ PVR_DPF((PVR_DBG_WARNING,
+ "%s: Bad vaddress %p in CPU d-cache maint. op, will use reacquired vaddress",
+ __func__,
+ pvAddress));
+
+ eError = PMRReleaseKernelMappingData(psPMR, hPrivOut);
+ PVR_LOG_IF_ERROR(eError, "PMRReleaseKernelMappingData");
+
+ /* NULL this to force per-page reacquisition down-stream */
+ pvAddress = NULL;
+ }
+ }
+ }
+
+ /* NULL clobbered var., OK to proceed */
+ pbCpuVirtAddr = NULL;
+ eError = PVRSRV_OK;
+
+ /* Need this for kernel mapping */
+ bPMRIsSparse = PMR_IsSparse(psPMR);
+ psDevNode = PMR_DeviceNode(psPMR);
+
+ /* Round the incoming offset down to the nearest cache-line / page aligned-address */
+ uiCLAlignedEndOffset = uiOffset + uiSize;
+ uiCLAlignedEndOffset = PVR_ALIGN(uiCLAlignedEndOffset, (IMG_DEVMEM_SIZE_T)gsCwq.uiLineSize);
+ uiCLAlignedStartOffset = (uiOffset & ~((IMG_DEVMEM_OFFSET_T)gsCwq.uiLineSize-1));
+
+ uiPgAlignedEndOffset = uiCLAlignedEndOffset;
+ uiPgAlignedEndOffset = PVR_ALIGN(uiPgAlignedEndOffset, (IMG_DEVMEM_SIZE_T)gsCwq.uiPageSize);
+ uiPgAlignedStartOffset = (uiOffset & ~((IMG_DEVMEM_OFFSET_T)gsCwq.uiPageSize-1));
+ uiPgAlignedSize = uiPgAlignedEndOffset - uiPgAlignedStartOffset;
+
+#if defined(CACHEOP_NO_CACHE_LINE_ALIGNED_ROUNDING)
+ /* For internal debug if cache-line optimised
+ flushing is suspected of causing data corruption */
+ uiCLAlignedStartOffset = uiPgAlignedStartOffset;
+ uiCLAlignedEndOffset = uiPgAlignedEndOffset;
+#endif
+
+ /* Type of allocation backing the PMR data */
+ ui32NumOfPages = uiPgAlignedSize >> gsCwq.uiPageShift;
+ if (ui32NumOfPages > PMR_MAX_TRANSLATION_STACK_ALLOC)
+ {
+ /* The pbValid array is allocated first as it is needed in
+ both physical/virtual cache maintenance methods */
+ pbValid = OSAllocZMem(ui32NumOfPages * sizeof(IMG_BOOL));
+ if (! pbValid)
+ {
+ pbValid = abValid;
+ }
+ else if (gsCwq.uiCacheOpAddrType != OS_CACHE_OP_ADDR_TYPE_VIRTUAL)
+ {
+ psCpuPhyAddr = OSAllocZMem(ui32NumOfPages * sizeof(IMG_CPU_PHYADDR));
+ if (! psCpuPhyAddr)
+ {
+ psCpuPhyAddr = asCpuPhyAddr;
+ OSFreeMem(pbValid);
+ pbValid = abValid;
+ }
+ }
+ }
+
+ /* We always retrieve PMR data in bulk, up-front if number of pages is within
+ PMR_MAX_TRANSLATION_STACK_ALLOC limits else we check to ensure that a
+ dynamic buffer has been allocated to satisfy requests outside limits */
+ if (ui32NumOfPages <= PMR_MAX_TRANSLATION_STACK_ALLOC || pbValid != abValid)
+ {
+ if (gsCwq.uiCacheOpAddrType != OS_CACHE_OP_ADDR_TYPE_VIRTUAL)
+ {
+ /* Look-up PMR CpuPhyAddr once, if possible */
+ eError = PMR_CpuPhysAddr(psPMR,
+ gsCwq.uiPageShift,
+ ui32NumOfPages,
+ uiPgAlignedStartOffset,
+ psCpuPhyAddr,
+ pbValid);
+ if (eError == PVRSRV_OK)
+ {
+ bIsPMRInfoValid = IMG_TRUE;
+ }
+ }
+ else
+ {
+ /* Look-up PMR per-page validity once, if possible */
+ eError = PMR_IsOffsetValid(psPMR,
+ gsCwq.uiPageShift,
+ ui32NumOfPages,
+ uiPgAlignedStartOffset,
+ pbValid);
+ bIsPMRInfoValid = (eError == PVRSRV_OK) ? IMG_TRUE : IMG_FALSE;
+ }
+ }
+
+ /* For each (possibly non-contiguous) PMR page(s), carry out the requested cache maint. op. */
+ for (uiPgAlignedOffset = uiPgAlignedStartOffset, ui32PageIndex = 0;
+ uiPgAlignedOffset < uiPgAlignedEndOffset;
+ uiPgAlignedOffset += (IMG_DEVMEM_OFFSET_T) gsCwq.uiPageSize, ui32PageIndex += 1)
+ {
+
+ if (! bIsPMRInfoValid)
+ {
+ /* Never cross page boundary without looking up corresponding PMR page physical
+ address and/or page validity if these were not looked-up, in bulk, up-front */
+ ui32PageIndex = 0;
+ if (gsCwq.uiCacheOpAddrType != OS_CACHE_OP_ADDR_TYPE_VIRTUAL)
+ {
+ eError = PMR_CpuPhysAddr(psPMR,
+ gsCwq.uiPageShift,
+ 1,
+ uiPgAlignedOffset,
+ psCpuPhyAddr,
+ pbValid);
+ PVR_LOG_GOTO_IF_ERROR(eError, "PMR_CpuPhysAddr", e0);
+ }
+ else
+ {
+ eError = PMR_IsOffsetValid(psPMR,
+ gsCwq.uiPageShift,
+ 1,
+ uiPgAlignedOffset,
+ pbValid);
+ PVR_LOG_GOTO_IF_ERROR(eError, "PMR_IsOffsetValid", e0);
+ }
+ }
+
+ /* Skip invalid PMR pages (i.e. sparse) */
+ if (pbValid[ui32PageIndex] == IMG_FALSE)
+ {
+ CACHEOP_PVR_ASSERT(bPMRIsSparse);
+ continue;
+ }
+
+ if (pvAddress)
+ {
+ /* The caller has supplied either a KM/UM CpuVA, so use it unconditionally */
+ pbCpuVirtAddr =
+ (void *)(uintptr_t)((uintptr_t)pvAddress + (uintptr_t)(uiPgAlignedOffset-uiPgAlignedStartOffset));
+ }
+ /* Skip CpuVA acquire if CacheOp can be maintained entirely using CpuPA */
+ else if (gsCwq.uiCacheOpAddrType != OS_CACHE_OP_ADDR_TYPE_PHYSICAL)
+ {
+ if (bPMRIsSparse)
+ {
+ eError =
+ PMRAcquireSparseKernelMappingData(psPMR,
+ uiPgAlignedOffset,
+ gsCwq.uiPageSize,
+ (void **)&pbCpuVirtAddr,
+ &uiOutSize,
+ &hPrivOut);
+ PVR_LOG_GOTO_IF_ERROR(eError, "PMRAcquireSparseKernelMappingData", e0);
+ }
+ else
+ {
+ eError =
+ PMRAcquireKernelMappingData(psPMR,
+ uiPgAlignedOffset,
+ gsCwq.uiPageSize,
+ (void **)&pbCpuVirtAddr,
+ &uiOutSize,
+ &hPrivOut);
+ PVR_LOG_GOTO_IF_ERROR(eError, "PMRAcquireKernelMappingData", e0);
+ }
+ }
+
+ /* Issue actual cache maintenance for PMR */
+ CacheOpExecRangeBased(psDevNode,
+ uiCacheOp,
+ pbCpuVirtAddr,
+ (gsCwq.uiCacheOpAddrType != OS_CACHE_OP_ADDR_TYPE_VIRTUAL) ?
+ psCpuPhyAddr[ui32PageIndex] : psCpuPhyAddr[0],
+ uiPgAlignedOffset,
+ uiCLAlignedStartOffset,
+ uiCLAlignedEndOffset);
+
+ if (! pvAddress)
+ {
+ /* The caller has not supplied either a KM/UM CpuVA, release mapping */
+ if (gsCwq.uiCacheOpAddrType != OS_CACHE_OP_ADDR_TYPE_PHYSICAL)
+ {
+ eError = PMRReleaseKernelMappingData(psPMR, hPrivOut);
+ PVR_LOG_IF_ERROR(eError, "PMRReleaseKernelMappingData");
+ }
+ }
+ }
+
+e0:
+ if (psCpuPhyAddr != asCpuPhyAddr)
+ {
+ OSFreeMem(psCpuPhyAddr);
+ }
+
+ if (pbValid != abValid)
+ {
+ OSFreeMem(pbValid);
+ }
+
+ if (! bIsRequestValidated)
+ {
+ eError = PMRUnlockSysPhysAddresses(psPMR);
+ PVR_LOG_IF_ERROR(eError, "PMRUnlockSysPhysAddresses");
+ }
+
+ return eError;
+}
+
+static PVRSRV_ERROR CacheOpQListExecRangeBased(void)
+{
+ IMG_UINT32 ui32NumOfEntries;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ CACHEOP_WORK_ITEM *psCacheOpWorkItem = NULL;
+
+ /* Take a snapshot of the current count of deferred entries at this junction */
+ ui32NumOfEntries = CacheOpIdxSpan(&gsCwq.hWriteCounter, &gsCwq.hReadCounter);
+ if (! ui32NumOfEntries)
+ {
+ return PVRSRV_OK;
+ }
+#if defined(CACHEOP_DEBUG)
+ CACHEOP_PVR_ASSERT(ui32NumOfEntries < CACHEOP_INDICES_MAX);
+#endif
+
+ while (ui32NumOfEntries)
+ {
+ if (! OSAtomicRead(&gsCwq.hReadCounter))
+ {
+ /* Normally, the read-counter will trail the write counter until the write
+ counter wraps-round to zero. Under this condition we (re)calculate as the
+ read-counter too is wrapping around at this point */
+ ui32NumOfEntries = CacheOpIdxSpan(&gsCwq.hWriteCounter, &gsCwq.hReadCounter);
+ }
+#if defined(CACHEOP_DEBUG)
+ /* Something's gone horribly wrong if these 2 counters are identical at this point */
+ CACHEOP_PVR_ASSERT(OSAtomicRead(&gsCwq.hWriteCounter) != OSAtomicRead(&gsCwq.hReadCounter));
+#endif
+
+ /* Select the next pending deferred work-item for RBF cache maintenance */
+ psCacheOpWorkItem = &gsCwq.asWorkItems[CacheOpIdxNext(&gsCwq.hReadCounter)];
+
+#if defined(CACHEOP_DEBUG)
+ /* The time waiting in the queue to be serviced */
+ psCacheOpWorkItem->ui64DequeuedTime = OSClockns64();
+#endif
+
+ eError = CacheOpPMRExec(psCacheOpWorkItem->psPMR,
+ NULL, /* No UM virtual address */
+ psCacheOpWorkItem->uiOffset,
+ psCacheOpWorkItem->uiSize,
+ psCacheOpWorkItem->uiCacheOp,
+ IMG_TRUE /* PMR is pre-validated */
+ );
+ if (eError != PVRSRV_OK)
+ {
+#if defined(CACHEOP_DEBUG)
+#define PID_FMTSPEC " PID:%u"
+#define CACHE_OP_WORK_PID psCacheOpWorkItem->pid
+#else
+#define PID_FMTSPEC "%s"
+#define CACHE_OP_WORK_PID ""
+#endif
+
+ PVR_LOG(("Deferred CacheOpPMRExec failed:"
+ PID_FMTSPEC
+ " PMR:%p"
+ " Offset:%" IMG_UINT64_FMTSPECX
+ " Size:%" IMG_UINT64_FMTSPECX
+ " CacheOp:%d,"
+ " error: %d",
+ CACHE_OP_WORK_PID,
+ psCacheOpWorkItem->psPMR,
+ psCacheOpWorkItem->uiOffset,
+ psCacheOpWorkItem->uiSize,
+ psCacheOpWorkItem->uiCacheOp,
+ eError));
+
+#undef PID_FMTSPEC
+#undef CACHE_OP_WORK_PID
+ }
+
+#if defined(CACHEOP_DEBUG)
+ psCacheOpWorkItem->ui64ExecuteTime = OSClockns64();
+ CacheOpStatsExecLogWrite(psCacheOpWorkItem);
+#endif
+
+ /* The currently executed CacheOp item updates gsCwq.hCompletedSeqNum.
+ NOTE: This CacheOp item might be a discard item, if so its seqNum
+ still updates the gsCwq.hCompletedSeqNum */
+ OSAtomicWrite(&gsCwq.hCompletedSeqNum, psCacheOpWorkItem->ui32OpSeqNum);
+
+ /* If CacheOp is timeline(d), notify timeline waiters */
+ eError = CacheOpTimelineExec(psCacheOpWorkItem);
+ PVR_LOG_IF_ERROR(eError, "CacheOpTimelineExec");
+
+ eError = PMRUnlockSysPhysAddresses(psCacheOpWorkItem->psPMR);
+ PVR_LOG_IF_ERROR(eError, "PMRUnlockSysPhysAddresses");
+
+ (void) CacheOpIdxIncrement(&gsCwq.hReadCounter);
+ ui32NumOfEntries = ui32NumOfEntries - 1;
+ }
+
+ return eError;
+}
+
+static INLINE PVRSRV_ERROR CacheOpQListExec(void)
+{
+ PVRSRV_ERROR eError;
+
+ eError = CacheOpQListExecRangeBased();
+ PVR_LOG_IF_ERROR(eError, "CacheOpQListExecRangeBased");
+
+ /* Signal any waiting threads blocked on CacheOp fence checks update
+ completed sequence number to last queue work item */
+ eError = OSEventObjectSignal(gsCwq.hClientWakeUpEvtObj);
+ PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+
+ return eError;
+}
+
+static void CacheOpThread(void *pvData)
+{
+ PVRSRV_DATA *psPVRSRVData = pvData;
+ IMG_HANDLE hOSEvent;
+ PVRSRV_ERROR eError;
+
+ /* Open CacheOp thread event object, abort driver if event object open fails */
+ eError = OSEventObjectOpen(gsCwq.hThreadWakeUpEvtObj, &hOSEvent);
+ PVR_LOG_IF_ERROR(eError, "OSEventObjectOpen");
+
+ /* While driver is in good state & loaded, perform pending cache maintenance */
+ while ((psPVRSRVData->eServicesState == PVRSRV_SERVICES_STATE_OK) && gsCwq.bInit)
+ {
+ /* Sleep-wait here until when signalled for new queued CacheOp work items;
+ when woken-up, drain deferred queue completely before next event-wait */
+ (void) OSEventObjectWaitKernel(hOSEvent, CACHEOP_THREAD_WAIT_TIMEOUT);
+ while (CacheOpIdxSpan(&gsCwq.hWriteCounter, &gsCwq.hReadCounter))
+ {
+ eError = CacheOpQListExec();
+ PVR_LOG_IF_ERROR(eError, "CacheOpQListExec");
+ }
+ }
+
+ eError = CacheOpQListExec();
+ PVR_LOG_IF_ERROR(eError, "CacheOpQListExec");
+
+ eError = OSEventObjectClose(hOSEvent);
+ PVR_LOG_IF_ERROR(eError, "OSEventObjectClose");
+}
+
+static PVRSRV_ERROR CacheOpBatchExecTimeline(PVRSRV_DEVICE_NODE *psDevNode,
+ PVRSRV_TIMELINE iTimeline,
+ IMG_UINT32 ui32CurrentFenceSeqNum,
+ IMG_UINT32 *pui32NextFenceSeqNum)
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32NextIdx;
+ CACHEOP_WORK_ITEM sCacheOpWorkItem = {NULL};
+ CACHEOP_WORK_ITEM *psCacheOpWorkItem = NULL;
+
+ eError = CacheOpTimelineBind(psDevNode, &sCacheOpWorkItem, iTimeline);
+ PVR_LOG_RETURN_IF_ERROR(eError, "CacheOpTimelineBind");
+
+ OSLockAcquire(gsCwq.hDeferredLock);
+
+ /*
+ Check if there is any deferred queueing space available and that nothing is
+ currently queued. This second check is required as Android where timelines
+ are used sets a timeline signalling deadline of 1000ms to signal timelines
+ else complains. So seeing we cannot be sure how long the CacheOp presently
+ in the queue would take we should not send this timeline down the queue as
+ well.
+ */
+ ui32NextIdx = CacheOpIdxNext(&gsCwq.hWriteCounter);
+ if (!CacheOpIdxSpan(&gsCwq.hWriteCounter, &gsCwq.hReadCounter) &&
+ CacheOpIdxRead(&gsCwq.hReadCounter) != ui32NextIdx)
+ {
+ psCacheOpWorkItem = &gsCwq.asWorkItems[ui32NextIdx];
+
+ psCacheOpWorkItem->sSWTimelineObj = sCacheOpWorkItem.sSWTimelineObj;
+ psCacheOpWorkItem->iTimeline = sCacheOpWorkItem.iTimeline;
+ psCacheOpWorkItem->psDevNode = sCacheOpWorkItem.psDevNode;
+ psCacheOpWorkItem->ui32OpSeqNum = CacheOpGetNextCommonSeqNum();
+ psCacheOpWorkItem->uiCacheOp = PVRSRV_CACHE_OP_TIMELINE;
+ psCacheOpWorkItem->uiOffset = (IMG_DEVMEM_OFFSET_T)0;
+ psCacheOpWorkItem->uiSize = (IMG_DEVMEM_SIZE_T)0;
+ /* Defer timeline using information page PMR */
+ psCacheOpWorkItem->psPMR = gsCwq.psInfoPagePMR;
+
+ eError = PMRLockSysPhysAddresses(psCacheOpWorkItem->psPMR);
+ PVR_LOG_GOTO_IF_ERROR(eError, "PMRLockSysPhysAddresses", e0);
+
+#if defined(CACHEOP_DEBUG)
+ psCacheOpWorkItem->pid = OSGetCurrentClientProcessIDKM();
+ psCacheOpWorkItem->ui64EnqueuedTime = OSClockns64();
+ gsCwq.ui32ServerASync += 1;
+ gsCwq.ui32ServerDTL += 1;
+#endif
+
+ /* Mark index ready for cache maintenance */
+ (void) CacheOpIdxIncrement(&gsCwq.hWriteCounter);
+
+ eError = OSEventObjectSignal(gsCwq.hThreadWakeUpEvtObj);
+ PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+ }
+ else
+ {
+ /* signal timeline.
+ * All ops with timelines and partial batches were executed synchronously. */
+ eError = CacheOpTimelineExec(&sCacheOpWorkItem);
+ PVR_LOG_IF_ERROR(eError, "CacheOpTimelineExec");
+ }
+
+e0:
+ OSLockRelease(gsCwq.hDeferredLock);
+ return eError;
+}
+
+static PVRSRV_ERROR CacheOpBatchExecRangeBased(PVRSRV_DEVICE_NODE *psDevNode,
+ PMR **ppsPMR,
+ IMG_CPU_VIRTADDR *pvAddress,
+ IMG_DEVMEM_OFFSET_T *puiOffset,
+ IMG_DEVMEM_SIZE_T *puiSize,
+ PVRSRV_CACHE_OP *puiCacheOp,
+ IMG_UINT32 ui32NumCacheOps,
+ PVRSRV_TIMELINE uiTimeline,
+ IMG_UINT32 uiCurrentFenceSeqNum,
+ IMG_UINT32 *pui32NextFenceSeqNum)
+{
+ IMG_UINT32 ui32Idx;
+ IMG_UINT32 ui32NextIdx;
+ IMG_BOOL bBatchHasTimeline;
+ IMG_BOOL bCacheOpConfigKDF;
+ IMG_DEVMEM_SIZE_T uiLogicalSize;
+ IMG_BOOL bBatchForceSynchronous = IMG_FALSE;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ CACHEOP_WORK_ITEM *psCacheOpWorkItem = NULL;
+#if defined(CACHEOP_DEBUG)
+ CACHEOP_WORK_ITEM sCacheOpWorkItem = {0};
+ IMG_UINT32 ui32OpSeqNum = CacheOpGetNextCommonSeqNum();
+ sCacheOpWorkItem.pid = OSGetCurrentClientProcessIDKM();
+#endif
+
+ /* Check if batch has an associated timeline update */
+ bBatchHasTimeline = puiCacheOp[ui32NumCacheOps-1] & PVRSRV_CACHE_OP_TIMELINE;
+ puiCacheOp[ui32NumCacheOps-1] &= ~(PVRSRV_CACHE_OP_TIMELINE);
+
+ /* Check if batch is forcing synchronous execution */
+ bBatchForceSynchronous = puiCacheOp[ui32NumCacheOps-1] & PVRSRV_CACHE_OP_FORCE_SYNCHRONOUS;
+ puiCacheOp[ui32NumCacheOps-1] &= ~(PVRSRV_CACHE_OP_FORCE_SYNCHRONOUS);
+
+ /* Check if config. supports kernel deferring of cacheops */
+ bCacheOpConfigKDF = CacheOpConfigSupports(CACHEOP_CONFIG_KDF);
+
+ /*
+ Client expects the next fence seqNum to be zero unless the server has deferred
+ at least one CacheOp in the submitted queue in which case the server informs
+ the client of the last CacheOp seqNum deferred in this batch.
+ */
+ for (*pui32NextFenceSeqNum = 0, ui32Idx = 0; ui32Idx < ui32NumCacheOps; ui32Idx++)
+ {
+ /* Fail UM request, don't silently ignore */
+ PVR_GOTO_IF_INVALID_PARAM(puiSize[ui32Idx], eError, e0);
+
+ if (bCacheOpConfigKDF)
+ {
+ /* Check if there is deferred queueing space available */
+ ui32NextIdx = CacheOpIdxNext(&gsCwq.hWriteCounter);
+ if (ui32NextIdx != CacheOpIdxRead(&gsCwq.hReadCounter))
+ {
+ psCacheOpWorkItem = &gsCwq.asWorkItems[ui32NextIdx];
+ }
+ }
+
+ /*
+ Normally, we would like to defer client CacheOp(s) but we may not always be in a
+ position or is necessary to do so based on the following reasons:
+ 0 - There is currently no queueing space left to enqueue this CacheOp, this might
+ imply the system is queueing more requests than can be consumed by the CacheOp
+ thread in time.
+ 1 - Batch has timeline, action this now due to Android timeline signaling deadlines.
+ 2 - Batch is forced synchronous. Necessary on Android for batches scheduled in the
+ middle of add operation. Those cannot have timelines that client plans to add
+ during actual batch execution and thus make synchronization on Android tricky.
+ 3 - Configuration does not support deferring of cache maintenance operations so we
+ execute the batch synchronously/immediately.
+ 4 - CacheOp has an INVALIDATE, as this is used to transfer device memory buffer
+ ownership back to the processor, we cannot defer it so action it immediately.
+ 5 - CacheOp size too small (single OS page size) to warrant overhead of deferment,
+ 6 - CacheOp size OK for deferment, but a client virtual address is supplied so we
+ might has well just take advantage of said VA & flush immediately in UM context.
+ 7 - Prevent DoS attack if a malicious client queues something very large, say 1GiB.
+ Here we upper bound this threshold to PVR_DIRTY_BYTES_FLUSH_THRESHOLD.
+ */
+ if (!psCacheOpWorkItem ||
+ bBatchHasTimeline ||
+ bBatchForceSynchronous ||
+ !bCacheOpConfigKDF ||
+ puiCacheOp[ui32Idx] & PVRSRV_CACHE_OP_INVALIDATE ||
+ (puiSize[ui32Idx] <= (IMG_DEVMEM_SIZE_T)gsCwq.uiPageSize) ||
+ (pvAddress[ui32Idx] && puiSize[ui32Idx] < (IMG_DEVMEM_SIZE_T)gsCwq.pui32InfoPage[CACHEOP_INFO_KMDFTHRESHLD]) ||
+ (puiSize[ui32Idx] >= (IMG_DEVMEM_SIZE_T)(gsCwq.pui32InfoPage[CACHEOP_INFO_KMDFTHRESHLD] << 2)))
+ {
+ /* When the CacheOp thread not keeping up, trash d-cache */
+#if defined(CACHEOP_DEBUG)
+ sCacheOpWorkItem.ui64EnqueuedTime = OSClockns64();
+ gsCwq.ui32ServerSync += 1;
+#endif
+ psCacheOpWorkItem = NULL;
+
+ eError = CacheOpPMRExec(ppsPMR[ui32Idx],
+ pvAddress[ui32Idx],
+ puiOffset[ui32Idx],
+ puiSize[ui32Idx],
+ puiCacheOp[ui32Idx],
+ IMG_FALSE);
+ PVR_LOG_GOTO_IF_ERROR(eError, "CacheOpExecPMR", e0);
+
+#if defined(CACHEOP_DEBUG)
+ sCacheOpWorkItem.psDevNode = psDevNode;
+ sCacheOpWorkItem.ui64ExecuteTime = OSClockns64();
+ sCacheOpWorkItem.ui32OpSeqNum = ui32OpSeqNum;
+ sCacheOpWorkItem.psPMR = ppsPMR[ui32Idx];
+ sCacheOpWorkItem.uiSize = puiSize[ui32Idx];
+ sCacheOpWorkItem.uiOffset = puiOffset[ui32Idx];
+ sCacheOpWorkItem.uiCacheOp = puiCacheOp[ui32Idx];
+ CacheOpStatsExecLogWrite(&sCacheOpWorkItem);
+#endif
+
+ continue;
+ }
+
+ /* Need to validate request parameters here before enqueing */
+ eError = PMR_LogicalSize(ppsPMR[ui32Idx], &uiLogicalSize);
+ PVR_LOG_GOTO_IF_ERROR(eError, "PMR_LogicalSize", e0);
+ eError = PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE;
+ PVR_LOG_GOTO_IF_FALSE(((puiOffset[ui32Idx]+puiSize[ui32Idx]) <= uiLogicalSize), CACHEOP_DEVMEM_OOR_ERROR_STRING, e0);
+ eError = PVRSRV_OK;
+
+ /* For safety, take reference here in user context */
+ eError = PMRLockSysPhysAddresses(ppsPMR[ui32Idx]);
+ PVR_LOG_GOTO_IF_ERROR(eError, "PMRLockSysPhysAddresses", e0);
+
+ OSLockAcquire(gsCwq.hDeferredLock);
+ /* Select next item off the queue to defer with */
+ ui32NextIdx = CacheOpIdxNext(&gsCwq.hWriteCounter);
+ if (ui32NextIdx != CacheOpIdxRead(&gsCwq.hReadCounter))
+ {
+ psCacheOpWorkItem = &gsCwq.asWorkItems[ui32NextIdx];
+ }
+ else
+ {
+ /* Retry, disable KDF for this batch */
+ OSLockRelease(gsCwq.hDeferredLock);
+ bCacheOpConfigKDF = IMG_FALSE;
+ psCacheOpWorkItem = NULL;
+ eError = PMRUnlockSysPhysAddresses(ppsPMR[ui32Idx]);
+ PVR_LOG_GOTO_IF_ERROR(eError, "PMRUnlockSysPhysAddresses", e0);
+ ui32Idx = ui32Idx - 1;
+ continue;
+ }
+
+ psCacheOpWorkItem->psPMR = ppsPMR[ui32Idx];
+ psCacheOpWorkItem->uiCacheOp = puiCacheOp[ui32Idx];
+ psCacheOpWorkItem->uiOffset = puiOffset[ui32Idx];
+ psCacheOpWorkItem->uiSize = puiSize[ui32Idx];
+
+ /* Timeline need to be looked-up (i.e. bind) in the user context
+ before deferring into the CacheOp thread kernel context */
+ eError = CacheOpTimelineBind(psDevNode, psCacheOpWorkItem, PVRSRV_NO_TIMELINE);
+ PVR_LOG_GOTO_IF_ERROR(eError, "CacheOpTimelineBind", e1);
+
+ /* Prepare & enqueue next deferred work item for CacheOp thread */
+ psCacheOpWorkItem->ui32OpSeqNum = CacheOpGetNextCommonSeqNum();
+ *pui32NextFenceSeqNum = psCacheOpWorkItem->ui32OpSeqNum;
+
+#if defined(CACHEOP_DEBUG)
+ psCacheOpWorkItem->ui64EnqueuedTime = OSClockns64();
+ psCacheOpWorkItem->pid = sCacheOpWorkItem.pid;
+ psCacheOpWorkItem->bDeferred = IMG_TRUE;
+ psCacheOpWorkItem->bKMReq = IMG_FALSE;
+ psCacheOpWorkItem->bUMF = IMG_FALSE;
+ gsCwq.ui32ServerASync += 1;
+#endif
+
+ /* Increment deferred size & mark index ready for cache maintenance */
+ (void) CacheOpIdxIncrement(&gsCwq.hWriteCounter);
+
+ OSLockRelease(gsCwq.hDeferredLock);
+ psCacheOpWorkItem = NULL;
+ }
+
+ /* Signal the CacheOp thread to ensure these items get processed */
+ eError = OSEventObjectSignal(gsCwq.hThreadWakeUpEvtObj);
+ PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+
+e1:
+ if (psCacheOpWorkItem)
+ {
+ eError = PMRUnlockSysPhysAddresses(psCacheOpWorkItem->psPMR);
+ PVR_LOG_IF_ERROR(eError, "PMRUnlockSysPhysAddresses");
+ }
+ OSLockRelease(gsCwq.hDeferredLock);
+
+e0:
+ if (bBatchHasTimeline)
+ {
+ PVRSRV_ERROR eError2;
+ eError2 = CacheOpBatchExecTimeline(psDevNode, uiTimeline,
+ uiCurrentFenceSeqNum, pui32NextFenceSeqNum);
+ eError = (eError2 == PVRSRV_ERROR_RETRY) ? eError2 : eError;
+ }
+
+ return eError;
+}
+
+
+PVRSRV_ERROR CacheOpExec (PPVRSRV_DEVICE_NODE psDevNode,
+ void *pvVirtStart,
+ void *pvVirtEnd,
+ IMG_CPU_PHYADDR sCPUPhysStart,
+ IMG_CPU_PHYADDR sCPUPhysEnd,
+ PVRSRV_CACHE_OP uiCacheOp)
+{
+#if defined(CACHEOP_DEBUG)
+ IMG_UINT64 ui64EnqueueTime = OSClockns64();
+#endif
+
+ switch (uiCacheOp)
+ {
+ case PVRSRV_CACHE_OP_CLEAN:
+ OSCPUCacheCleanRangeKM(psDevNode, pvVirtStart, pvVirtEnd, sCPUPhysStart, sCPUPhysEnd);
+ break;
+ case PVRSRV_CACHE_OP_INVALIDATE:
+ OSCPUCacheInvalidateRangeKM(psDevNode, pvVirtStart, pvVirtEnd, sCPUPhysStart, sCPUPhysEnd);
+ break;
+ case PVRSRV_CACHE_OP_FLUSH:
+ OSCPUCacheFlushRangeKM(psDevNode, pvVirtStart, pvVirtEnd, sCPUPhysStart, sCPUPhysEnd);
+ break;
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid cache operation type %d",
+ __func__, uiCacheOp));
+ break;
+ }
+
+#if defined(CACHEOP_DEBUG)
+ if (CacheOpConfigSupports(CACHEOP_CONFIG_KLOG))
+ {
+ CACHEOP_WORK_ITEM sCacheOpWorkItem = {0};
+
+ gsCwq.ui32ServerSync += 1;
+ gsCwq.ui32ServerRBF +=
+ ((sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr) & ((IMG_DEVMEM_SIZE_T)~(gsCwq.uiLineSize - 1))) >> gsCwq.uiLineShift;
+
+ sCacheOpWorkItem.uiOffset = 0;
+ sCacheOpWorkItem.bKMReq = IMG_TRUE;
+ sCacheOpWorkItem.uiCacheOp = uiCacheOp;
+ /* Use information page PMR for logging KM request */
+ sCacheOpWorkItem.psPMR = gsCwq.psInfoPagePMR;
+ sCacheOpWorkItem.psDevNode = psDevNode;
+ sCacheOpWorkItem.ui64EnqueuedTime = ui64EnqueueTime;
+ sCacheOpWorkItem.ui64ExecuteTime = OSClockns64();
+ sCacheOpWorkItem.pid = OSGetCurrentClientProcessIDKM();
+ sCacheOpWorkItem.ui32OpSeqNum = CacheOpGetNextCommonSeqNum();
+ sCacheOpWorkItem.uiSize = (sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr);
+
+ CacheOpStatsExecLogWrite(&sCacheOpWorkItem);
+ }
+#endif
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR CacheOpValExec(PMR *psPMR,
+ IMG_UINT64 uiAddress,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_DEVMEM_SIZE_T uiSize,
+ PVRSRV_CACHE_OP uiCacheOp)
+{
+ PVRSRV_ERROR eError;
+ IMG_CPU_VIRTADDR pvAddress = (IMG_CPU_VIRTADDR)(uintptr_t)uiAddress;
+#if defined(CACHEOP_DEBUG)
+ CACHEOP_WORK_ITEM sCacheOpWorkItem = {0};
+ gsCwq.ui32ServerSync += 1;
+ sCacheOpWorkItem.psDevNode = PMR_DeviceNode(psPMR);
+ sCacheOpWorkItem.psPMR = psPMR;
+ sCacheOpWorkItem.uiSize = uiSize;
+ sCacheOpWorkItem.uiOffset = uiOffset;
+ sCacheOpWorkItem.uiCacheOp = uiCacheOp;
+ sCacheOpWorkItem.pid = OSGetCurrentClientProcessIDKM();
+ sCacheOpWorkItem.ui32OpSeqNum = CacheOpGetNextCommonSeqNum();
+ sCacheOpWorkItem.ui64EnqueuedTime = OSClockns64();
+#endif
+
+ eError = CacheOpPMRExec(psPMR,
+ pvAddress,
+ uiOffset,
+ uiSize,
+ uiCacheOp,
+ IMG_FALSE);
+ PVR_LOG_GOTO_IF_ERROR(eError, "CacheOpPMRExec", e0);
+
+#if defined(CACHEOP_DEBUG)
+ sCacheOpWorkItem.ui64ExecuteTime = OSClockns64();
+ CacheOpStatsExecLogWrite(&sCacheOpWorkItem);
+#endif
+
+e0:
+ return eError;
+}
+
+PVRSRV_ERROR CacheOpQueue (CONNECTION_DATA *psConnection,
+ PVRSRV_DEVICE_NODE *psDevNode,
+ IMG_UINT32 ui32NumCacheOps,
+ PMR **ppsPMR,
+ IMG_UINT64 *puiAddress,
+ IMG_DEVMEM_OFFSET_T *puiOffset,
+ IMG_DEVMEM_SIZE_T *puiSize,
+ PVRSRV_CACHE_OP *puiCacheOp,
+ IMG_UINT32 ui32OpTimeline,
+ IMG_UINT32 uiCurrentFenceSeqNum,
+ IMG_UINT32 *pui32NextFenceSeqNum)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_TIMELINE uiTimeline = (PVRSRV_TIMELINE)ui32OpTimeline;
+ IMG_CPU_VIRTADDR *pvAddress = (IMG_CPU_VIRTADDR*)(uintptr_t)puiAddress;
+
+ PVR_UNREFERENCED_PARAMETER(psConnection);
+
+ if (!gsCwq.bInit)
+ {
+ PVR_LOG(("CacheOp framework not initialised, failing request"));
+ return PVRSRV_ERROR_NOT_INITIALISED;
+ }
+ else if (! ui32NumCacheOps)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+ /* Ensure any single timeline CacheOp request is processed immediately */
+ else if (ui32NumCacheOps == 1 && puiCacheOp[0] == PVRSRV_CACHE_OP_TIMELINE)
+ {
+ eError = CacheOpBatchExecTimeline(psDevNode, uiTimeline, uiCurrentFenceSeqNum, pui32NextFenceSeqNum);
+ }
+ /* This is the default entry for all client requests */
+ else
+ {
+ if (!(gsCwq.eConfig & (CACHEOP_CONFIG_LAST-1)))
+ {
+ /* default the configuration before execution */
+ CacheOpConfigUpdate(CACHEOP_CONFIG_DEFAULT);
+ }
+
+ eError =
+ CacheOpBatchExecRangeBased(psDevNode,
+ ppsPMR,
+ pvAddress,
+ puiOffset,
+ puiSize,
+ puiCacheOp,
+ ui32NumCacheOps,
+ uiTimeline,
+ uiCurrentFenceSeqNum,
+ pui32NextFenceSeqNum);
+ }
+
+ return eError;
+}
+
+PVRSRV_ERROR CacheOpFence (PPVRSRV_DEVICE_NODE psDevNode,
+ RGXFWIF_DM eFenceOpType,
+ IMG_UINT32 ui32FenceOpSeqNum)
+{
+ IMG_HANDLE hOSEvent;
+ PVRSRV_ERROR eError2;
+ IMG_UINT32 ui32RetryAbort;
+ IMG_UINT32 ui32CompletedOpSeqNum;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+#if defined(CACHEOP_DEBUG)
+ IMG_UINT64 uiTimeNow;
+ CACHEOP_WORK_ITEM sCacheOpWorkItem = {0};
+ sCacheOpWorkItem.psDevNode = psDevNode;
+ sCacheOpWorkItem.pid = OSGetCurrentClientProcessIDKM();
+ sCacheOpWorkItem.ui32OpSeqNum = ui32FenceOpSeqNum;
+ sCacheOpWorkItem.ui64EnqueuedTime = OSClockns64();
+ uiTimeNow = sCacheOpWorkItem.ui64EnqueuedTime;
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) && defined(DEBUG)
+ sCacheOpWorkItem.eFenceOpType = eFenceOpType;
+#endif
+ sCacheOpWorkItem.uiSize = (uintptr_t) OSAtomicRead(&gsCwq.hCompletedSeqNum);
+ sCacheOpWorkItem.uiOffset = 0;
+#endif
+ PVR_UNREFERENCED_PARAMETER(eFenceOpType);
+
+ /* If initial fence check fails, then wait-and-retry in loop */
+ ui32CompletedOpSeqNum = OSAtomicRead(&gsCwq.hCompletedSeqNum);
+ if (CacheOpFenceCheck(ui32CompletedOpSeqNum, ui32FenceOpSeqNum))
+ {
+#if defined(CACHEOP_DEBUG)
+ sCacheOpWorkItem.uiSize = (uintptr_t) ui32CompletedOpSeqNum;
+#endif
+ goto e0;
+ }
+
+ /* Open CacheOp update event object, if event open fails return error */
+ eError2 = OSEventObjectOpen(gsCwq.hClientWakeUpEvtObj, &hOSEvent);
+ PVR_LOG_GOTO_IF_ERROR(eError2, "OSEventObjectOpen", e0);
+
+ /* Linear (i.e. use exponential?) back-off, upper bounds user wait */
+ for (ui32RetryAbort = gsCwq.ui32FenceRetryAbort; ;--ui32RetryAbort)
+ {
+ /* (Re)read completed CacheOp sequence number before waiting */
+ ui32CompletedOpSeqNum = OSAtomicRead(&gsCwq.hCompletedSeqNum);
+ if (CacheOpFenceCheck(ui32CompletedOpSeqNum, ui32FenceOpSeqNum))
+ {
+#if defined(CACHEOP_DEBUG)
+ sCacheOpWorkItem.uiSize = (uintptr_t) ui32CompletedOpSeqNum;
+#endif
+ break;
+ }
+
+ (void) OSEventObjectWaitTimeout(hOSEvent, gsCwq.ui32FenceWaitTimeUs);
+
+ if (! ui32RetryAbort)
+ {
+#if defined(CACHEOP_DEBUG)
+ sCacheOpWorkItem.uiSize = (uintptr_t) OSAtomicRead(&gsCwq.hCompletedSeqNum);
+ sCacheOpWorkItem.uiOffset = 0;
+ uiTimeNow = OSClockns64();
+#endif
+ PVR_LOG(("CacheOpFence() event: "CACHEOP_ABORT_FENCE_ERROR_STRING));
+ eError = PVRSRV_ERROR_RETRY;
+ break;
+ }
+ else
+ {
+#if defined(CACHEOP_DEBUG)
+ uiTimeNow = OSClockns64();
+#endif
+ }
+ }
+
+ eError2 = OSEventObjectClose(hOSEvent);
+ PVR_LOG_IF_ERROR(eError2, "OSEventObjectOpen");
+
+e0:
+#if defined(CACHEOP_DEBUG)
+ sCacheOpWorkItem.ui64ExecuteTime = uiTimeNow;
+ if (ui32FenceOpSeqNum)
+ {
+ IMG_UINT64 ui64TimeTakenNs = sCacheOpWorkItem.ui64EnqueuedTime - sCacheOpWorkItem.ui64ExecuteTime;
+ IMG_UINT32 ui32Time;
+ IMG_INT32 i32Div;
+
+ do_div(ui64TimeTakenNs, 1000);
+ ui32Time = ui64TimeTakenNs;
+
+ /* Only fences pending on CacheOps contribute towards statistics,
+ * Calculate the approximate cumulative moving average fence time.
+ * This calculation is based on standard equation:
+ *
+ * CMAnext = (new + count * CMAprev) / (count + 1)
+ *
+ * but in simplified form:
+ *
+ * CMAnext = CMAprev + (new - CMAprev) / (count + 1)
+ *
+ * this gets rid of multiplication and prevents overflow.
+ *
+ * Also to increase accuracy that we lose with integer division,
+ * we hold the moving remainder of the division and add it.
+ *
+ * CMAnext = CMAprev + (new - CMAprev + CMRprev) / (count + 1)
+ *
+ * Multiple tests proved it to be the best solution for approximating
+ * CMA using integers.
+ *
+ */
+
+ i32Div = (IMG_INT32)ui32Time - (IMG_INT32)gsCwq.ui32AvgFenceTime + (IMG_INT32)gsCwq.ui32AvgFenceTimeRemainder;
+
+
+ gsCwq.ui32AvgFenceTime += i32Div / (IMG_INT32)(gsCwq.ui32TotalFenceOps + 1);
+ gsCwq.ui32AvgFenceTimeRemainder = i32Div % (IMG_INT32)(gsCwq.ui32TotalFenceOps + 1);
+
+
+ gsCwq.ui32TotalFenceOps++;
+
+ }
+ CacheOpStatsExecLogWrite(&sCacheOpWorkItem);
+#endif
+
+ return eError;
+}
+
+PVRSRV_ERROR CacheOpLog (PMR *psPMR,
+ IMG_UINT64 puiAddress,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_UINT64 ui64EnqueuedTimeUs,
+ IMG_UINT64 ui64ExecuteTimeUs,
+ IMG_UINT32 ui32NumRBF,
+ PVRSRV_CACHE_OP uiCacheOp)
+{
+#if defined(CACHEOP_DEBUG)
+ CACHEOP_WORK_ITEM sCacheOpWorkItem = {0};
+ PVR_UNREFERENCED_PARAMETER(puiAddress);
+
+ sCacheOpWorkItem.psDevNode = PMR_DeviceNode(psPMR);
+ sCacheOpWorkItem.psPMR = psPMR;
+ sCacheOpWorkItem.uiSize = uiSize;
+ sCacheOpWorkItem.uiOffset = uiOffset;
+ sCacheOpWorkItem.uiCacheOp = uiCacheOp;
+ sCacheOpWorkItem.pid = OSGetCurrentClientProcessIDKM();
+ sCacheOpWorkItem.ui32OpSeqNum = CacheOpGetNextCommonSeqNum();
+
+ sCacheOpWorkItem.ui64EnqueuedTime = ui64EnqueuedTimeUs;
+ sCacheOpWorkItem.ui64ExecuteTime = ui64ExecuteTimeUs;
+ sCacheOpWorkItem.bUMF = IMG_TRUE;
+ gsCwq.ui32ClientRBF += ui32NumRBF;
+ gsCwq.ui32ClientSync += 1;
+
+ CacheOpStatsExecLogWrite(&sCacheOpWorkItem);
+#else
+ PVR_UNREFERENCED_PARAMETER(psPMR);
+ PVR_UNREFERENCED_PARAMETER(uiSize);
+ PVR_UNREFERENCED_PARAMETER(uiOffset);
+ PVR_UNREFERENCED_PARAMETER(uiCacheOp);
+ PVR_UNREFERENCED_PARAMETER(ui32NumRBF);
+ PVR_UNREFERENCED_PARAMETER(puiAddress);
+ PVR_UNREFERENCED_PARAMETER(ui64ExecuteTimeUs);
+ PVR_UNREFERENCED_PARAMETER(ui64EnqueuedTimeUs);
+#endif
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR CacheOpInit2 (void)
+{
+ void *pvAppHintState = NULL;
+ IMG_UINT32 ui32AppHintDefault = PVRSRV_APPHINT_CACHEOPTHREADPRIORITY;
+ IMG_UINT32 ui32AppHintCacheOpThreadPriority;
+
+ PVRSRV_ERROR eError;
+ PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+ /* Create an event object for pending CacheOp work items */
+ eError = OSEventObjectCreate("PVRSRV_CACHEOP_EVENTOBJECT", &gsCwq.hThreadWakeUpEvtObj);
+ PVR_LOG_GOTO_IF_ERROR(eError, "OSEventObjectCreate", e0);
+
+ /* Create an event object for updating pending fence checks on CacheOp */
+ eError = OSEventObjectCreate("PVRSRV_CACHEOP_EVENTOBJECT", &gsCwq.hClientWakeUpEvtObj);
+ PVR_LOG_GOTO_IF_ERROR(eError, "OSEventObjectCreate", e0);
+
+ /* Appending work-items is not concurrent, lock protects against this */
+ eError = OSLockCreate((POS_LOCK*)&gsCwq.hDeferredLock);
+ PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", e0);
+
+ /* Apphint read/write is not concurrent, so lock protects against this */
+ eError = OSLockCreate((POS_LOCK*)&gsCwq.hConfigLock);
+ PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", e0);
+
+ gsCwq.ui32FenceWaitTimeUs = CACHEOP_FENCE_WAIT_TIMEOUT;
+ gsCwq.ui32FenceRetryAbort = CACHEOP_FENCE_RETRY_ABORT;
+
+#if defined(CACHEFLUSH_ISA_SUPPORTS_UM_FLUSH)
+ gsCwq.bSupportsUMFlush = IMG_TRUE;
+#else
+ gsCwq.bSupportsUMFlush = IMG_FALSE;
+#endif
+
+ gsCwq.pui32InfoPage = psPVRSRVData->pui32InfoPage;
+ gsCwq.psInfoPagePMR = psPVRSRVData->psInfoPagePMR;
+
+ /* Normally, platforms should use their default configurations, put exceptions here */
+#if defined(__i386__) || defined(__x86_64__)
+#if !defined(TC_MEMORY_CONFIG)
+ CacheOpConfigUpdate(CACHEOP_CONFIG_URBF | CACHEOP_CONFIG_KDF);
+#else
+ CacheOpConfigUpdate(CACHEOP_CONFIG_KDF);
+#endif
+#else /* defined(__x86__) */
+ CacheOpConfigUpdate(CACHEOP_CONFIG_DEFAULT);
+#endif
+
+ /* Initialise the remaining occupants of the CacheOp information page */
+ gsCwq.pui32InfoPage[CACHEOP_INFO_PGSIZE] = (IMG_UINT32)gsCwq.uiPageSize;
+ gsCwq.pui32InfoPage[CACHEOP_INFO_LINESIZE] = (IMG_UINT32)gsCwq.uiLineSize;
+
+ /* Set before spawning thread */
+ gsCwq.bInit = IMG_TRUE;
+
+ OSCreateKMAppHintState(&pvAppHintState);
+ OSGetKMAppHintUINT32(APPHINT_NO_DEVICE, pvAppHintState, CacheOpThreadPriority,
+ &ui32AppHintDefault, &ui32AppHintCacheOpThreadPriority);
+ OSFreeKMAppHintState(pvAppHintState);
+
+ /* Create a thread which is used to execute the deferred CacheOp(s),
+ these are CacheOp(s) executed by the server on behalf of clients
+ asynchronously. All clients synchronise with the server before
+ submitting any HW operation (i.e. device kicks) to ensure that
+ client device work-load memory is coherent */
+ eError = OSThreadCreatePriority(&gsCwq.hWorkerThread,
+ "pvr_cacheop",
+ CacheOpThread,
+ CacheOpThreadDumpInfo,
+ IMG_TRUE,
+ psPVRSRVData,
+ ui32AppHintCacheOpThreadPriority);
+ PVR_LOG_GOTO_IF_ERROR(eError, "OSThreadCreatePriority", e0);
+ {
+ DI_ITERATOR_CB sIterator = {.pfnShow = CacheOpConfigRead};
+ /* Writing the unsigned integer binary encoding of CACHEOP_CONFIG
+ into this file cycles through avail. configuration(s) */
+ eError = DICreateEntry("cacheop_config", NULL, &sIterator, NULL,
+ DI_ENTRY_TYPE_GENERIC, &gsCwq.psConfigTune);
+ PVR_LOG_GOTO_IF_FALSE(gsCwq.psConfigTune, "DICreateEntry", e0);
+ }
+
+ /* Register the CacheOp framework (re)configuration handlers */
+ PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_CacheOpConfig,
+ CacheOpConfigQuery,
+ CacheOpConfigSet,
+ APPHINT_OF_DRIVER_NO_DEVICE,
+ (void *) APPHINT_ID_CacheOpConfig);
+
+ PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_CacheOpUMKMThresholdSize,
+ CacheOpConfigQuery,
+ CacheOpConfigSet,
+ APPHINT_OF_DRIVER_NO_DEVICE,
+ (void *) APPHINT_ID_CacheOpUMKMThresholdSize);
+
+ return PVRSRV_OK;
+e0:
+ CacheOpDeInit2();
+ return eError;
+}
+
+void CacheOpDeInit2 (void)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ gsCwq.bInit = IMG_FALSE;
+
+ if (gsCwq.hThreadWakeUpEvtObj)
+ {
+ eError = OSEventObjectSignal(gsCwq.hThreadWakeUpEvtObj);
+ PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+ }
+
+ if (gsCwq.hClientWakeUpEvtObj)
+ {
+ eError = OSEventObjectSignal(gsCwq.hClientWakeUpEvtObj);
+ PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+ }
+
+ if (gsCwq.hWorkerThread)
+ {
+ LOOP_UNTIL_TIMEOUT(OS_THREAD_DESTROY_TIMEOUT_US)
+ {
+ eError = OSThreadDestroy(gsCwq.hWorkerThread);
+ if (PVRSRV_OK == eError)
+ {
+ gsCwq.hWorkerThread = NULL;
+ break;
+ }
+ OSWaitus(OS_THREAD_DESTROY_TIMEOUT_US/OS_THREAD_DESTROY_RETRY_COUNT);
+ } END_LOOP_UNTIL_TIMEOUT();
+ PVR_LOG_IF_ERROR(eError, "OSThreadDestroy");
+ gsCwq.hWorkerThread = NULL;
+ }
+
+ if (gsCwq.hClientWakeUpEvtObj)
+ {
+ eError = OSEventObjectDestroy(gsCwq.hClientWakeUpEvtObj);
+ PVR_LOG_IF_ERROR(eError, "OSEventObjectDestroy");
+ gsCwq.hClientWakeUpEvtObj = NULL;
+ }
+
+ if (gsCwq.hThreadWakeUpEvtObj)
+ {
+ eError = OSEventObjectDestroy(gsCwq.hThreadWakeUpEvtObj);
+ PVR_LOG_IF_ERROR(eError, "OSEventObjectDestroy");
+ gsCwq.hThreadWakeUpEvtObj = NULL;
+ }
+
+ if (gsCwq.hConfigLock)
+ {
+ eError = OSLockDestroy(gsCwq.hConfigLock);
+ PVR_LOG_IF_ERROR(eError, "OSLockDestroy");
+ gsCwq.hConfigLock = NULL;
+ }
+
+ if (gsCwq.hDeferredLock)
+ {
+ eError = OSLockDestroy(gsCwq.hDeferredLock);
+ PVR_LOG_IF_ERROR(eError, "OSLockDestroy");
+ gsCwq.hDeferredLock = NULL;
+ }
+
+ if (gsCwq.psConfigTune)
+ {
+ DIDestroyEntry(gsCwq.psConfigTune);
+ gsCwq.psConfigTune = NULL;
+ }
+
+ gsCwq.pui32InfoPage = NULL;
+ gsCwq.psInfoPagePMR = NULL;
+}
+
+PVRSRV_ERROR CacheOpInit (void)
+{
+ IMG_UINT32 idx;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ /* DDK initialisation is anticipated to be performed on the boot
+ processor (little core in big/little systems) though this may
+ not always be the case. If so, the value cached here is the
+ system wide safe (i.e. smallest) L1 d-cache line size value
+ on any/such platforms with mismatched d-cache line sizes */
+ gsCwq.uiPageSize = OSGetPageSize();
+ gsCwq.uiPageShift = OSGetPageShift();
+ gsCwq.uiLineSize = OSCPUCacheAttributeSize(OS_CPU_CACHE_ATTRIBUTE_LINE_SIZE);
+ gsCwq.uiLineShift = ExactLog2(gsCwq.uiLineSize);
+ PVR_LOG_RETURN_IF_FALSE((gsCwq.uiLineSize && gsCwq.uiPageSize && gsCwq.uiPageShift), "", PVRSRV_ERROR_INIT_FAILURE);
+ gsCwq.uiCacheOpAddrType = OSCPUCacheOpAddressType();
+
+ /* More information regarding these atomic counters can be found
+ in the CACHEOP_WORK_QUEUE type definition at top of file */
+ OSAtomicWrite(&gsCwq.hCompletedSeqNum, 0);
+ OSAtomicWrite(&gsCwq.hCommonSeqNum, 0);
+ OSAtomicWrite(&gsCwq.hWriteCounter, 0);
+ OSAtomicWrite(&gsCwq.hReadCounter, 0);
+
+ for (idx = 0; idx < CACHEOP_INDICES_MAX; idx++)
+ {
+ gsCwq.asWorkItems[idx].iTimeline = PVRSRV_NO_TIMELINE;
+ gsCwq.asWorkItems[idx].psPMR = (void *)(uintptr_t)~0;
+ gsCwq.asWorkItems[idx].ui32OpSeqNum = (IMG_UINT32)~0;
+ }
+
+
+#if defined(CACHEOP_DEBUG)
+ /* debugfs file read-out is not concurrent, so lock protects against this */
+ eError = OSLockCreate((POS_LOCK*)&gsCwq.hStatsExecLock);
+ PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", e0);
+
+ gsCwq.i32StatsExecWriteIdx = 0;
+ OSCachedMemSet(gsCwq.asStatsExecuted, 0, sizeof(gsCwq.asStatsExecuted));
+
+ {
+ DI_ITERATOR_CB sIterator = {.pfnShow = CacheOpStatsExecLogRead};
+ /* File captures the most recent subset of CacheOp(s) executed */
+ eError = DICreateEntry("cacheop_history", NULL, &sIterator, NULL,
+ DI_ENTRY_TYPE_GENERIC, &gsCwq.psDIEntry);
+ PVR_LOG_GOTO_IF_ERROR(eError, "DICreateEntry", e0);
+ }
+e0:
+#endif
+ return eError;
+}
+
+void CacheOpDeInit (void)
+{
+#if defined(CACHEOP_DEBUG)
+ if (gsCwq.hStatsExecLock)
+ {
+ (void) OSLockDestroy(gsCwq.hStatsExecLock);
+ gsCwq.hStatsExecLock = NULL;
+ }
+
+ if (gsCwq.psDIEntry)
+ {
+ DIDestroyEntry(gsCwq.psDIEntry);
+ gsCwq.psDIEntry = NULL;
+ }
+#endif
+}
diff --git a/drivers/gpu/drm/img-rogue/cache_km.h b/drivers/gpu/drm/img-rogue/cache_km.h
new file mode 100644
index 000000000..df4041f7b
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/cache_km.h
@@ -0,0 +1,166 @@
+/*************************************************************************/ /*!
+@File cache_km.h
+@Title CPU cache management header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef CACHE_KM_H
+#define CACHE_KM_H
+
+#if defined(__linux__)
+#include
+#else
+#define KERNEL_VERSION
+#endif
+
+#include "pvrsrv_error.h"
+#include "os_cpu_cache.h"
+#include "img_types.h"
+#include "cache_ops.h"
+#include "device.h"
+#include "pmr.h"
+
+typedef IMG_UINT32 PVRSRV_CACHE_OP_ADDR_TYPE; /*!< Represents CPU address type required for CPU d-cache maintenance */
+#define PVRSRV_CACHE_OP_ADDR_TYPE_VIRTUAL 0x1 /*!< Operation requires CPU virtual address only */
+#define PVRSRV_CACHE_OP_ADDR_TYPE_PHYSICAL 0x2 /*!< Operation requires CPU physical address only */
+#define PVRSRV_CACHE_OP_ADDR_TYPE_BOTH 0x3 /*!< Operation requires both CPU virtual & physical addresses */
+
+#include "connection_server.h"
+
+/*
+ * CacheOpInit() & CacheOpDeInit()
+ *
+ * This must be called to initialise the KM cache maintenance framework.
+ * This is called early during the driver/module (un)loading phase.
+ */
+PVRSRV_ERROR CacheOpInit(void);
+void CacheOpDeInit(void);
+
+/*
+ * CacheOpInit2() & CacheOpDeInit2()
+ *
+ * This must be called to initialise the UM cache maintenance framework.
+ * This is called when the driver is loaded/unloaded from the kernel.
+ */
+PVRSRV_ERROR CacheOpInit2(void);
+void CacheOpDeInit2(void);
+
+/*
+ * CacheOpExec()
+ *
+ * This is the primary CPU data-cache maintenance interface and it is
+ * always guaranteed to be synchronous; the arguments supplied must be
+ * pre-validated for performance reasons else the d-cache maintenance
+ * operation might cause the underlying OS kernel to fault.
+ */
+PVRSRV_ERROR CacheOpExec(PPVRSRV_DEVICE_NODE psDevNode,
+ void *pvVirtStart,
+ void *pvVirtEnd,
+ IMG_CPU_PHYADDR sCPUPhysStart,
+ IMG_CPU_PHYADDR sCPUPhysEnd,
+ PVRSRV_CACHE_OP uiCacheOp);
+
+/*
+ * CacheOpValExec()
+ *
+ * Same as CacheOpExec(), except arguments are _Validated_ before being
+ * presented to the underlying OS kernel for CPU data-cache maintenance.
+ * The uiAddress is the start CPU virtual address for the to-be d-cache
+ * maintained PMR, it can be NULL in which case a remap will be performed
+ * internally, if required for cache maintenance. This is primarily used
+ * as the services client bridge call handler for synchronous user-mode
+ * cache maintenance requests.
+ */
+PVRSRV_ERROR CacheOpValExec(PMR *psPMR,
+ IMG_UINT64 uiAddress,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_DEVMEM_SIZE_T uiSize,
+ PVRSRV_CACHE_OP uiCacheOp);
+
+/*
+ * CacheOpQueue()
+ *
+ * This is the secondary cache maintenance interface and it is not
+ * guaranteed to be synchronous in that requests could be deferred
+ * and executed asynchronously. This interface is primarily meant
+ * as services client bridge call handler. Both uiInfoPgGFSeqNum
+ * and ui32[Current,Next]FenceSeqNum implements an internal client
+ * server queueing protocol so making use of this interface outside
+ * of services client is not recommended and should not be done.
+ */
+PVRSRV_ERROR CacheOpQueue(CONNECTION_DATA *psConnection,
+ PPVRSRV_DEVICE_NODE psDevNode,
+ IMG_UINT32 ui32OpCount,
+ PMR **ppsPMR,
+ IMG_UINT64 *puiAddress,
+ IMG_DEVMEM_OFFSET_T *puiOffset,
+ IMG_DEVMEM_SIZE_T *puiSize,
+ PVRSRV_CACHE_OP *puiCacheOp,
+ IMG_UINT32 ui32OpTimeline,
+ IMG_UINT32 uiCurrentFenceSeqNum,
+ IMG_UINT32 *puiNextFenceSeqNum);
+
+/*
+ * CacheOpFence()
+ *
+ * This is used for fencing for any client in-flight cache maintenance
+ * operations that might have been deferred by the use of CacheOpQueue().
+ * This should be called before any subsequent HW device kicks to ensure
+ * device memory is coherent with the HW before the kick.
+ */
+PVRSRV_ERROR CacheOpFence(PPVRSRV_DEVICE_NODE psDevNode,
+ RGXFWIF_DM eOpType,
+ IMG_UINT32 ui32OpSeqNum);
+
+/*
+ * CacheOpLog()
+ *
+ * This is used for logging client cache maintenance operations that
+ * was executed in user-space.
+ */
+PVRSRV_ERROR CacheOpLog(PMR *psPMR,
+ IMG_UINT64 uiAddress,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_UINT64 ui64QueuedTimeMs,
+ IMG_UINT64 ui64ExecuteTimeMs,
+ IMG_UINT32 ui32NumRBF,
+ PVRSRV_CACHE_OP uiCacheOp);
+
+#endif /* CACHE_KM_H */
diff --git a/drivers/gpu/drm/img-rogue/cache_ops.h b/drivers/gpu/drm/img-rogue/cache_ops.h
new file mode 100644
index 000000000..a1d714519
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/cache_ops.h
@@ -0,0 +1,61 @@
+/*************************************************************************/ /*!
+@File
+@Title Services cache management header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Defines for cache management which are visible internally
+ and externally
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef CACHE_OPS_H
+#define CACHE_OPS_H
+#include "img_types.h"
+/*!
+* @Defgroup CPUCacheAPIs
+* @{
+*/
+#define CACHE_BATCH_MAX (8U)
+#define MAX_DMA_OPS (34)
+typedef IMG_UINT32 PVRSRV_CACHE_OP; /*!< Type represents cache maintenance operation */
+#define PVRSRV_CACHE_OP_NONE 0x0U /*!< No operation */
+#define PVRSRV_CACHE_OP_CLEAN 0x1U /*!< Flush w/o invalidate */
+#define PVRSRV_CACHE_OP_INVALIDATE 0x2U /*!< Invalidate w/o flush */
+#define PVRSRV_CACHE_OP_FLUSH 0x3U /*!< Flush w/ invalidate */
+/*! @} End of Defgroup CPUCacheAPIs */
+
+#endif /* CACHE_OPS_H */
diff --git a/drivers/gpu/drm/img-rogue/client_cache_bridge.h b/drivers/gpu/drm/img-rogue/client_cache_bridge.h
new file mode 100644
index 000000000..5952ae758
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/client_cache_bridge.h
@@ -0,0 +1,83 @@
+/*******************************************************************************
+@File
+@Title Client bridge header for cache
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Exports the client bridge functions for cache
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef CLIENT_CACHE_BRIDGE_H
+#define CLIENT_CACHE_BRIDGE_H
+
+#include "img_defs.h"
+#include "pvrsrv_error.h"
+
+#if defined(PVR_INDIRECT_BRIDGE_CLIENTS)
+#include "pvr_bridge_client.h"
+#include "pvr_bridge.h"
+#endif
+
+#include "common_cache_bridge.h"
+
+IMG_INTERNAL PVRSRV_ERROR BridgeCacheOpQueue(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32NumCacheOps,
+ IMG_HANDLE * phPMR,
+ IMG_UINT64 * pui64Address,
+ IMG_DEVMEM_OFFSET_T * puiOffset,
+ IMG_DEVMEM_SIZE_T * puiSize,
+ PVRSRV_CACHE_OP * piuCacheOp,
+ IMG_UINT32 ui32OpTimeline,
+ IMG_UINT32 ui32CurrentFenceSeqNum,
+ IMG_UINT32 * pui32NextFenceSeqNum);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeCacheOpExec(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMR,
+ IMG_UINT64 ui64Address,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_DEVMEM_SIZE_T uiSize, PVRSRV_CACHE_OP iuCacheOp);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeCacheOpLog(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMR,
+ IMG_UINT64 ui64Address,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_INT64 i64QueuedTimeUs,
+ IMG_INT64 i64ExecuteTimeUs,
+ IMG_INT32 i32NumRBF, PVRSRV_CACHE_OP iuCacheOp);
+
+#endif /* CLIENT_CACHE_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/client_cache_direct_bridge.c b/drivers/gpu/drm/img-rogue/client_cache_direct_bridge.c
new file mode 100644
index 000000000..9f7634cc2
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/client_cache_direct_bridge.c
@@ -0,0 +1,120 @@
+/*******************************************************************************
+@File
+@Title Direct client bridge for cache
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Implements the client side of the bridge for cache
+ which is used in calls from Server context.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#include "client_cache_bridge.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+
+/* Module specific includes */
+#include "cache_ops.h"
+
+#include "cache_km.h"
+
+IMG_INTERNAL PVRSRV_ERROR BridgeCacheOpQueue(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32NumCacheOps,
+ IMG_HANDLE * phPMR,
+ IMG_UINT64 * pui64Address,
+ IMG_DEVMEM_OFFSET_T * puiOffset,
+ IMG_DEVMEM_SIZE_T * puiSize,
+ PVRSRV_CACHE_OP * piuCacheOp,
+ IMG_UINT32 ui32OpTimeline,
+ IMG_UINT32 ui32CurrentFenceSeqNum,
+ IMG_UINT32 * pui32NextFenceSeqNum)
+{
+ PVRSRV_ERROR eError;
+ PMR **psPMRInt;
+
+ psPMRInt = (PMR **) phPMR;
+
+ eError =
+ CacheOpQueue(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge),
+ ui32NumCacheOps,
+ psPMRInt,
+ pui64Address,
+ puiOffset,
+ puiSize,
+ piuCacheOp, ui32OpTimeline, ui32CurrentFenceSeqNum, pui32NextFenceSeqNum);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeCacheOpExec(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMR,
+ IMG_UINT64 ui64Address,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_DEVMEM_SIZE_T uiSize, PVRSRV_CACHE_OP iuCacheOp)
+{
+ PVRSRV_ERROR eError;
+ PMR *psPMRInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psPMRInt = (PMR *) hPMR;
+
+ eError = CacheOpValExec(psPMRInt, ui64Address, uiOffset, uiSize, iuCacheOp);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeCacheOpLog(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMR,
+ IMG_UINT64 ui64Address,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_INT64 i64QueuedTimeUs,
+ IMG_INT64 i64ExecuteTimeUs,
+ IMG_INT32 i32NumRBF, PVRSRV_CACHE_OP iuCacheOp)
+{
+ PVRSRV_ERROR eError;
+ PMR *psPMRInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psPMRInt = (PMR *) hPMR;
+
+ eError =
+ CacheOpLog(psPMRInt,
+ ui64Address,
+ uiOffset, uiSize, i64QueuedTimeUs, i64ExecuteTimeUs, i32NumRBF, iuCacheOp);
+
+ return eError;
+}
diff --git a/drivers/gpu/drm/img-rogue/client_devicememhistory_bridge.h b/drivers/gpu/drm/img-rogue/client_devicememhistory_bridge.h
new file mode 100644
index 000000000..bfa6bfb9c
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/client_devicememhistory_bridge.h
@@ -0,0 +1,111 @@
+/*******************************************************************************
+@File
+@Title Client bridge header for devicememhistory
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Exports the client bridge functions for devicememhistory
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef CLIENT_DEVICEMEMHISTORY_BRIDGE_H
+#define CLIENT_DEVICEMEMHISTORY_BRIDGE_H
+
+#include "img_defs.h"
+#include "pvrsrv_error.h"
+
+#if defined(PVR_INDIRECT_BRIDGE_CLIENTS)
+#include "pvr_bridge_client.h"
+#include "pvr_bridge.h"
+#endif
+
+#include "common_devicememhistory_bridge.h"
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistoryMap(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMR,
+ IMG_DEVMEM_SIZE_T uiOffset,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ const IMG_CHAR * puiText,
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 * pui32AllocationIndexOut);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistoryUnmap(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMR,
+ IMG_DEVMEM_SIZE_T uiOffset,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ const IMG_CHAR * puiText,
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 * pui32AllocationIndexOut);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistoryMapVRange(IMG_HANDLE hBridge,
+ IMG_DEV_VIRTADDR sBaseDevVAddr,
+ IMG_UINT32 ui32ui32StartPage,
+ IMG_UINT32 ui32NumPages,
+ IMG_DEVMEM_SIZE_T uiAllocSize,
+ const IMG_CHAR * puiText,
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 * pui32AllocationIndexOut);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistoryUnmapVRange(IMG_HANDLE hBridge,
+ IMG_DEV_VIRTADDR sBaseDevVAddr,
+ IMG_UINT32 ui32ui32StartPage,
+ IMG_UINT32 ui32NumPages,
+ IMG_DEVMEM_SIZE_T uiAllocSize,
+ const IMG_CHAR * puiText,
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 * pui32AllocationIndexOut);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistorySparseChange(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMR,
+ IMG_DEVMEM_SIZE_T uiOffset,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ const IMG_CHAR * puiText,
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_UINT32 ui32AllocPageCount,
+ IMG_UINT32 * pui32AllocPageIndices,
+ IMG_UINT32 ui32FreePageCount,
+ IMG_UINT32 * pui32FreePageIndices,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 * pui32AllocationIndexOut);
+
+#endif /* CLIENT_DEVICEMEMHISTORY_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/client_devicememhistory_direct_bridge.c b/drivers/gpu/drm/img-rogue/client_devicememhistory_direct_bridge.c
new file mode 100644
index 000000000..acbb46475
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/client_devicememhistory_direct_bridge.c
@@ -0,0 +1,194 @@
+/*******************************************************************************
+@File
+@Title Direct client bridge for devicememhistory
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Implements the client side of the bridge for devicememhistory
+ which is used in calls from Server context.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#include "client_devicememhistory_bridge.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+
+/* Module specific includes */
+#include "img_types.h"
+#include "img_defs.h"
+#include "devicemem_typedefs.h"
+
+#include "devicemem_history_server.h"
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistoryMap(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMR,
+ IMG_DEVMEM_SIZE_T uiOffset,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ const IMG_CHAR * puiText,
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 * pui32AllocationIndexOut)
+{
+ PVRSRV_ERROR eError;
+ PMR *psPMRInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psPMRInt = (PMR *) hPMR;
+
+ eError =
+ DevicememHistoryMapKM(psPMRInt,
+ uiOffset,
+ sDevVAddr,
+ uiSize,
+ puiText,
+ ui32Log2PageSize, ui32AllocationIndex, pui32AllocationIndexOut);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistoryUnmap(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMR,
+ IMG_DEVMEM_SIZE_T uiOffset,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ const IMG_CHAR * puiText,
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 * pui32AllocationIndexOut)
+{
+ PVRSRV_ERROR eError;
+ PMR *psPMRInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psPMRInt = (PMR *) hPMR;
+
+ eError =
+ DevicememHistoryUnmapKM(psPMRInt,
+ uiOffset,
+ sDevVAddr,
+ uiSize,
+ puiText,
+ ui32Log2PageSize, ui32AllocationIndex, pui32AllocationIndexOut);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistoryMapVRange(IMG_HANDLE hBridge,
+ IMG_DEV_VIRTADDR sBaseDevVAddr,
+ IMG_UINT32 ui32ui32StartPage,
+ IMG_UINT32 ui32NumPages,
+ IMG_DEVMEM_SIZE_T uiAllocSize,
+ const IMG_CHAR * puiText,
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 * pui32AllocationIndexOut)
+{
+ PVRSRV_ERROR eError;
+
+ eError =
+ DevicememHistoryMapVRangeKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge),
+ sBaseDevVAddr,
+ ui32ui32StartPage,
+ ui32NumPages,
+ uiAllocSize,
+ puiText,
+ ui32Log2PageSize,
+ ui32AllocationIndex, pui32AllocationIndexOut);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistoryUnmapVRange(IMG_HANDLE hBridge,
+ IMG_DEV_VIRTADDR sBaseDevVAddr,
+ IMG_UINT32 ui32ui32StartPage,
+ IMG_UINT32 ui32NumPages,
+ IMG_DEVMEM_SIZE_T uiAllocSize,
+ const IMG_CHAR * puiText,
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 * pui32AllocationIndexOut)
+{
+ PVRSRV_ERROR eError;
+
+ eError =
+ DevicememHistoryUnmapVRangeKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge),
+ sBaseDevVAddr,
+ ui32ui32StartPage,
+ ui32NumPages,
+ uiAllocSize,
+ puiText,
+ ui32Log2PageSize,
+ ui32AllocationIndex, pui32AllocationIndexOut);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevicememHistorySparseChange(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMR,
+ IMG_DEVMEM_SIZE_T uiOffset,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ const IMG_CHAR * puiText,
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_UINT32 ui32AllocPageCount,
+ IMG_UINT32 * pui32AllocPageIndices,
+ IMG_UINT32 ui32FreePageCount,
+ IMG_UINT32 * pui32FreePageIndices,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 * pui32AllocationIndexOut)
+{
+ PVRSRV_ERROR eError;
+ PMR *psPMRInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psPMRInt = (PMR *) hPMR;
+
+ eError =
+ DevicememHistorySparseChangeKM(psPMRInt,
+ uiOffset,
+ sDevVAddr,
+ uiSize,
+ puiText,
+ ui32Log2PageSize,
+ ui32AllocPageCount,
+ pui32AllocPageIndices,
+ ui32FreePageCount,
+ pui32FreePageIndices,
+ ui32AllocationIndex, pui32AllocationIndexOut);
+
+ return eError;
+}
diff --git a/drivers/gpu/drm/img-rogue/client_htbuffer_bridge.h b/drivers/gpu/drm/img-rogue/client_htbuffer_bridge.h
new file mode 100644
index 000000000..b3514eaba
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/client_htbuffer_bridge.h
@@ -0,0 +1,71 @@
+/*******************************************************************************
+@File
+@Title Client bridge header for htbuffer
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Exports the client bridge functions for htbuffer
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef CLIENT_HTBUFFER_BRIDGE_H
+#define CLIENT_HTBUFFER_BRIDGE_H
+
+#include "img_defs.h"
+#include "pvrsrv_error.h"
+
+#if defined(PVR_INDIRECT_BRIDGE_CLIENTS)
+#include "pvr_bridge_client.h"
+#include "pvr_bridge.h"
+#endif
+
+#include "common_htbuffer_bridge.h"
+
+IMG_INTERNAL PVRSRV_ERROR BridgeHTBControl(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32NumGroups,
+ IMG_UINT32 * pui32GroupEnable,
+ IMG_UINT32 ui32LogLevel,
+ IMG_UINT32 ui32EnablePID,
+ IMG_UINT32 ui32LogMode, IMG_UINT32 ui32OpMode);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeHTBLog(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32PID,
+ IMG_UINT32 ui32TID,
+ IMG_UINT64 ui64TimeStamp,
+ IMG_UINT32 ui32SF,
+ IMG_UINT32 ui32NumArgs, IMG_UINT32 * pui32Args);
+
+#endif /* CLIENT_HTBUFFER_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/client_htbuffer_direct_bridge.c b/drivers/gpu/drm/img-rogue/client_htbuffer_direct_bridge.c
new file mode 100644
index 000000000..9c5833116
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/client_htbuffer_direct_bridge.c
@@ -0,0 +1,85 @@
+/*******************************************************************************
+@File
+@Title Direct client bridge for htbuffer
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Implements the client side of the bridge for htbuffer
+ which is used in calls from Server context.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#include "client_htbuffer_bridge.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+
+/* Module specific includes */
+#include "devicemem_typedefs.h"
+#include "htbuffer_types.h"
+
+#include "htbserver.h"
+
+IMG_INTERNAL PVRSRV_ERROR BridgeHTBControl(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32NumGroups,
+ IMG_UINT32 * pui32GroupEnable,
+ IMG_UINT32 ui32LogLevel,
+ IMG_UINT32 ui32EnablePID,
+ IMG_UINT32 ui32LogMode, IMG_UINT32 ui32OpMode)
+{
+ PVRSRV_ERROR eError;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ eError =
+ HTBControlKM(ui32NumGroups,
+ pui32GroupEnable, ui32LogLevel, ui32EnablePID, ui32LogMode, ui32OpMode);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeHTBLog(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32PID,
+ IMG_UINT32 ui32TID,
+ IMG_UINT64 ui64TimeStamp,
+ IMG_UINT32 ui32SF,
+ IMG_UINT32 ui32NumArgs, IMG_UINT32 * pui32Args)
+{
+ PVRSRV_ERROR eError;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ eError = HTBLogKM(ui32PID, ui32TID, ui64TimeStamp, ui32SF, ui32NumArgs, pui32Args);
+
+ return eError;
+}
diff --git a/drivers/gpu/drm/img-rogue/client_mm_bridge.h b/drivers/gpu/drm/img-rogue/client_mm_bridge.h
new file mode 100644
index 000000000..9be507ced
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/client_mm_bridge.h
@@ -0,0 +1,254 @@
+/*******************************************************************************
+@File
+@Title Client bridge header for mm
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Exports the client bridge functions for mm
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef CLIENT_MM_BRIDGE_H
+#define CLIENT_MM_BRIDGE_H
+
+#include "img_defs.h"
+#include "pvrsrv_error.h"
+
+#if defined(PVR_INDIRECT_BRIDGE_CLIENTS)
+#include "pvr_bridge_client.h"
+#include "pvr_bridge.h"
+#endif
+
+#include "common_mm_bridge.h"
+
+IMG_INTERNAL PVRSRV_ERROR BridgePMRExportPMR(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMR,
+ IMG_HANDLE * phPMRExport,
+ IMG_UINT64 * pui64Size,
+ IMG_UINT32 * pui32Log2Contig,
+ IMG_UINT64 * pui64Password);
+
+IMG_INTERNAL PVRSRV_ERROR BridgePMRUnexportPMR(IMG_HANDLE hBridge, IMG_HANDLE hPMRExport);
+
+IMG_INTERNAL PVRSRV_ERROR BridgePMRGetUID(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMR, IMG_UINT64 * pui64UID);
+
+IMG_INTERNAL PVRSRV_ERROR BridgePMRMakeLocalImportHandle(IMG_HANDLE hBridge,
+ IMG_HANDLE hBuffer, IMG_HANDLE * phExtMem);
+
+IMG_INTERNAL PVRSRV_ERROR BridgePMRUnmakeLocalImportHandle(IMG_HANDLE hBridge, IMG_HANDLE hExtMem);
+
+IMG_INTERNAL PVRSRV_ERROR BridgePMRImportPMR(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMRExport,
+ IMG_UINT64 ui64uiPassword,
+ IMG_UINT64 ui64uiSize,
+ IMG_UINT32 ui32uiLog2Contig, IMG_HANDLE * phPMR);
+
+IMG_INTERNAL PVRSRV_ERROR BridgePMRLocalImportPMR(IMG_HANDLE hBridge,
+ IMG_HANDLE hExtHandle,
+ IMG_HANDLE * phPMR,
+ IMG_DEVMEM_SIZE_T * puiSize,
+ IMG_DEVMEM_ALIGN_T * puiAlign);
+
+IMG_INTERNAL PVRSRV_ERROR BridgePMRUnrefPMR(IMG_HANDLE hBridge, IMG_HANDLE hPMR);
+
+IMG_INTERNAL PVRSRV_ERROR BridgePMRUnrefUnlockPMR(IMG_HANDLE hBridge, IMG_HANDLE hPMR);
+
+IMG_INTERNAL PVRSRV_ERROR BridgePhysmemNewRamBackedPMR(IMG_HANDLE hBridge,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_DEVMEM_SIZE_T uiChunkSize,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 * pui32MappingTable,
+ IMG_UINT32 ui32Log2PageSize,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ IMG_UINT32 ui32AnnotationLength,
+ const IMG_CHAR * puiAnnotation,
+ IMG_PID ui32PID,
+ IMG_HANDLE * phPMRPtr,
+ IMG_UINT32 ui32PDumpFlags,
+ PVRSRV_MEMALLOCFLAGS_T * puiOutFlags);
+
+IMG_INTERNAL PVRSRV_ERROR BridgePhysmemNewRamBackedLockedPMR(IMG_HANDLE hBridge,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_DEVMEM_SIZE_T uiChunkSize,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 * pui32MappingTable,
+ IMG_UINT32 ui32Log2PageSize,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ IMG_UINT32 ui32AnnotationLength,
+ const IMG_CHAR * puiAnnotation,
+ IMG_PID ui32PID,
+ IMG_HANDLE * phPMRPtr,
+ IMG_UINT32 ui32PDumpFlags,
+ PVRSRV_MEMALLOCFLAGS_T * puiOutFlags);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntPin(IMG_HANDLE hBridge, IMG_HANDLE hPMR);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnpin(IMG_HANDLE hBridge, IMG_HANDLE hPMR);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntPinValidate(IMG_HANDLE hBridge,
+ IMG_HANDLE hMapping, IMG_HANDLE hPMR);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnpinInvalidate(IMG_HANDLE hBridge,
+ IMG_HANDLE hMapping, IMG_HANDLE hPMR);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntCtxCreate(IMG_HANDLE hBridge,
+ IMG_BOOL bbKernelMemoryCtx,
+ IMG_HANDLE * phDevMemServerContext,
+ IMG_HANDLE * phPrivData,
+ IMG_UINT32 * pui32CPUCacheLineSize);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntCtxDestroy(IMG_HANDLE hBridge,
+ IMG_HANDLE hDevmemServerContext);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntHeapCreate(IMG_HANDLE hBridge,
+ IMG_HANDLE hDevmemCtx,
+ IMG_DEV_VIRTADDR sHeapBaseAddr,
+ IMG_DEVMEM_SIZE_T uiHeapLength,
+ IMG_UINT32 ui32Log2DataPageSize,
+ IMG_HANDLE * phDevmemHeapPtr);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntHeapDestroy(IMG_HANDLE hBridge, IMG_HANDLE hDevmemHeap);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntMapPMR(IMG_HANDLE hBridge,
+ IMG_HANDLE hDevmemServerHeap,
+ IMG_HANDLE hReservation,
+ IMG_HANDLE hPMR,
+ PVRSRV_MEMALLOCFLAGS_T uiMapFlags,
+ IMG_HANDLE * phMapping);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnmapPMR(IMG_HANDLE hBridge, IMG_HANDLE hMapping);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntReserveRange(IMG_HANDLE hBridge,
+ IMG_HANDLE hDevmemServerHeap,
+ IMG_DEV_VIRTADDR sAddress,
+ IMG_DEVMEM_SIZE_T uiLength,
+ IMG_HANDLE * phReservation);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnreserveRange(IMG_HANDLE hBridge,
+ IMG_HANDLE hReservation);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeChangeSparseMem(IMG_HANDLE hBridge,
+ IMG_HANDLE hSrvDevMemHeap,
+ IMG_HANDLE hPMR,
+ IMG_UINT32 ui32AllocPageCount,
+ IMG_UINT32 * pui32AllocPageIndices,
+ IMG_UINT32 ui32FreePageCount,
+ IMG_UINT32 * pui32FreePageIndices,
+ IMG_UINT32 ui32SparseFlags,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_UINT64 ui64CPUVAddr);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntMapPages(IMG_HANDLE hBridge,
+ IMG_HANDLE hReservation,
+ IMG_HANDLE hPMR,
+ IMG_UINT32 ui32PageCount,
+ IMG_UINT32 ui32PhysicalPgOffset,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ IMG_DEV_VIRTADDR sDevVAddr);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnmapPages(IMG_HANDLE hBridge,
+ IMG_HANDLE hReservation,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_UINT32 ui32PageCount);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIsVDevAddrValid(IMG_HANDLE hBridge,
+ IMG_HANDLE hDevmemCtx,
+ IMG_DEV_VIRTADDR sAddress);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemFlushDevSLCRange(IMG_HANDLE hBridge,
+ IMG_HANDLE hDevmemCtx,
+ IMG_DEV_VIRTADDR sAddress,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_BOOL bInvalidate);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemInvalidateFBSCTable(IMG_HANDLE hBridge,
+ IMG_HANDLE hDevmemCtx,
+ IMG_UINT64 ui64FBSCEntries);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeHeapCfgHeapConfigCount(IMG_HANDLE hBridge,
+ IMG_UINT32 * pui32NumHeapConfigs);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeHeapCfgHeapCount(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32HeapConfigIndex,
+ IMG_UINT32 * pui32NumHeaps);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeHeapCfgHeapConfigName(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32HeapConfigIndex,
+ IMG_UINT32 ui32HeapConfigNameBufSz,
+ IMG_CHAR * puiHeapConfigName);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeHeapCfgHeapDetails(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32HeapConfigIndex,
+ IMG_UINT32 ui32HeapIndex,
+ IMG_UINT32 ui32HeapNameBufSz,
+ IMG_CHAR * puiHeapNameOut,
+ IMG_DEV_VIRTADDR * psDevVAddrBase,
+ IMG_DEVMEM_SIZE_T * puiHeapLength,
+ IMG_DEVMEM_SIZE_T * puiReservedRegionLength,
+ IMG_UINT32 * pui32Log2DataPageSizeOut,
+ IMG_UINT32 * pui32Log2ImportAlignmentOut);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntRegisterPFNotifyKM(IMG_HANDLE hBridge,
+ IMG_HANDLE hDevm,
+ IMG_UINT32 ui32PID, IMG_BOOL bRegister);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeGetMaxPhysHeapCount(IMG_HANDLE hBridge,
+ IMG_UINT32 * pui32PhysHeapCount);
+
+IMG_INTERNAL PVRSRV_ERROR BridgePhysHeapGetMemInfo(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32PhysHeapCount,
+ PVRSRV_PHYS_HEAP * peaPhysHeapID,
+ PHYS_HEAP_MEM_STATS * pasapPhysHeapMemStats);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeGetDefaultPhysicalHeap(IMG_HANDLE hBridge,
+ PVRSRV_PHYS_HEAP * peHeap);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeGetHeapPhysMemUsage(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32PhysHeapCount,
+ PHYS_HEAP_MEM_STATS * pasapPhysHeapMemStats);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemGetFaultAddress(IMG_HANDLE hBridge,
+ IMG_HANDLE hDevmemCtx,
+ IMG_DEV_VIRTADDR * psFaultAddress);
+
+IMG_INTERNAL PVRSRV_ERROR BridgePVRSRVUpdateOOMStats(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32ui32StatType, IMG_PID ui32pid);
+
+#endif /* CLIENT_MM_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/client_mm_direct_bridge.c b/drivers/gpu/drm/img-rogue/client_mm_direct_bridge.c
new file mode 100644
index 000000000..df0a6f661
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/client_mm_direct_bridge.c
@@ -0,0 +1,775 @@
+/*******************************************************************************
+@File
+@Title Direct client bridge for mm
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Implements the client side of the bridge for mm
+ which is used in calls from Server context.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#include "client_mm_bridge.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+
+/* Module specific includes */
+#include "pvrsrv_memallocflags.h"
+#include "pvrsrv_memalloc_physheap.h"
+#include "devicemem_typedefs.h"
+
+#include "pvrsrv_memalloc_physheap.h"
+#include "devicemem.h"
+#include "devicemem_server.h"
+#include "pmr.h"
+#include "devicemem_heapcfg.h"
+#include "physmem.h"
+#include "devicemem_utils.h"
+#include "process_stats.h"
+
+IMG_INTERNAL PVRSRV_ERROR BridgePMRExportPMR(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMR,
+ IMG_HANDLE * phPMRExport,
+ IMG_UINT64 * pui64Size,
+ IMG_UINT32 * pui32Log2Contig,
+ IMG_UINT64 * pui64Password)
+{
+ PVRSRV_ERROR eError;
+ PMR *psPMRInt;
+ PMR_EXPORT *psPMRExportInt = NULL;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psPMRInt = (PMR *) hPMR;
+
+ eError = PMRExportPMR(psPMRInt, &psPMRExportInt, pui64Size, pui32Log2Contig, pui64Password);
+
+ *phPMRExport = psPMRExportInt;
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgePMRUnexportPMR(IMG_HANDLE hBridge, IMG_HANDLE hPMRExport)
+{
+ PVRSRV_ERROR eError;
+ PMR_EXPORT *psPMRExportInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psPMRExportInt = (PMR_EXPORT *) hPMRExport;
+
+ eError = PMRUnexportPMR(psPMRExportInt);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgePMRGetUID(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMR, IMG_UINT64 * pui64UID)
+{
+ PVRSRV_ERROR eError;
+ PMR *psPMRInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psPMRInt = (PMR *) hPMR;
+
+ eError = PMRGetUID(psPMRInt, pui64UID);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgePMRMakeLocalImportHandle(IMG_HANDLE hBridge,
+ IMG_HANDLE hBuffer, IMG_HANDLE * phExtMem)
+{
+ PVRSRV_ERROR eError;
+ PMR *psBufferInt;
+ PMR *psExtMemInt = NULL;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psBufferInt = (PMR *) hBuffer;
+
+ eError = PMRMakeLocalImportHandle(psBufferInt, &psExtMemInt);
+
+ *phExtMem = psExtMemInt;
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgePMRUnmakeLocalImportHandle(IMG_HANDLE hBridge, IMG_HANDLE hExtMem)
+{
+ PVRSRV_ERROR eError;
+ PMR *psExtMemInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psExtMemInt = (PMR *) hExtMem;
+
+ eError = PMRUnmakeLocalImportHandle(psExtMemInt);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgePMRImportPMR(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMRExport,
+ IMG_UINT64 ui64uiPassword,
+ IMG_UINT64 ui64uiSize,
+ IMG_UINT32 ui32uiLog2Contig, IMG_HANDLE * phPMR)
+{
+ PVRSRV_ERROR eError;
+ PMR_EXPORT *psPMRExportInt;
+ PMR *psPMRInt = NULL;
+
+ psPMRExportInt = (PMR_EXPORT *) hPMRExport;
+
+ eError =
+ PhysmemImportPMR(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge),
+ psPMRExportInt,
+ ui64uiPassword, ui64uiSize, ui32uiLog2Contig, &psPMRInt);
+
+ *phPMR = psPMRInt;
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgePMRLocalImportPMR(IMG_HANDLE hBridge,
+ IMG_HANDLE hExtHandle,
+ IMG_HANDLE * phPMR,
+ IMG_DEVMEM_SIZE_T * puiSize,
+ IMG_DEVMEM_ALIGN_T * puiAlign)
+{
+ PVRSRV_ERROR eError;
+ PMR *psExtHandleInt;
+ PMR *psPMRInt = NULL;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psExtHandleInt = (PMR *) hExtHandle;
+
+ eError = PMRLocalImportPMR(psExtHandleInt, &psPMRInt, puiSize, puiAlign);
+
+ *phPMR = psPMRInt;
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgePMRUnrefPMR(IMG_HANDLE hBridge, IMG_HANDLE hPMR)
+{
+ PVRSRV_ERROR eError;
+ PMR *psPMRInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psPMRInt = (PMR *) hPMR;
+
+ eError = PMRUnrefPMR(psPMRInt);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgePMRUnrefUnlockPMR(IMG_HANDLE hBridge, IMG_HANDLE hPMR)
+{
+ PVRSRV_ERROR eError;
+ PMR *psPMRInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psPMRInt = (PMR *) hPMR;
+
+ eError = PMRUnrefUnlockPMR(psPMRInt);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgePhysmemNewRamBackedPMR(IMG_HANDLE hBridge,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_DEVMEM_SIZE_T uiChunkSize,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 * pui32MappingTable,
+ IMG_UINT32 ui32Log2PageSize,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ IMG_UINT32 ui32AnnotationLength,
+ const IMG_CHAR * puiAnnotation,
+ IMG_PID ui32PID,
+ IMG_HANDLE * phPMRPtr,
+ IMG_UINT32 ui32PDumpFlags,
+ PVRSRV_MEMALLOCFLAGS_T * puiOutFlags)
+{
+ PVRSRV_ERROR eError;
+ PMR *psPMRPtrInt = NULL;
+
+ eError =
+ PhysmemNewRamBackedPMR_direct(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge),
+ uiSize,
+ uiChunkSize,
+ ui32NumPhysChunks,
+ ui32NumVirtChunks,
+ pui32MappingTable,
+ ui32Log2PageSize,
+ uiFlags,
+ ui32AnnotationLength,
+ puiAnnotation,
+ ui32PID, &psPMRPtrInt, ui32PDumpFlags, puiOutFlags);
+
+ *phPMRPtr = psPMRPtrInt;
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgePhysmemNewRamBackedLockedPMR(IMG_HANDLE hBridge,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_DEVMEM_SIZE_T uiChunkSize,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 * pui32MappingTable,
+ IMG_UINT32 ui32Log2PageSize,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ IMG_UINT32 ui32AnnotationLength,
+ const IMG_CHAR * puiAnnotation,
+ IMG_PID ui32PID,
+ IMG_HANDLE * phPMRPtr,
+ IMG_UINT32 ui32PDumpFlags,
+ PVRSRV_MEMALLOCFLAGS_T * puiOutFlags)
+{
+ PVRSRV_ERROR eError;
+ PMR *psPMRPtrInt = NULL;
+
+ eError =
+ PhysmemNewRamBackedLockedPMR(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge),
+ uiSize,
+ uiChunkSize,
+ ui32NumPhysChunks,
+ ui32NumVirtChunks,
+ pui32MappingTable,
+ ui32Log2PageSize,
+ uiFlags,
+ ui32AnnotationLength,
+ puiAnnotation,
+ ui32PID, &psPMRPtrInt, ui32PDumpFlags, puiOutFlags);
+
+ *phPMRPtr = psPMRPtrInt;
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntPin(IMG_HANDLE hBridge, IMG_HANDLE hPMR)
+{
+ PVRSRV_ERROR eError;
+ PMR *psPMRInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psPMRInt = (PMR *) hPMR;
+
+ eError = DevmemIntPin(psPMRInt);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnpin(IMG_HANDLE hBridge, IMG_HANDLE hPMR)
+{
+ PVRSRV_ERROR eError;
+ PMR *psPMRInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psPMRInt = (PMR *) hPMR;
+
+ eError = DevmemIntUnpin(psPMRInt);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntPinValidate(IMG_HANDLE hBridge,
+ IMG_HANDLE hMapping, IMG_HANDLE hPMR)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_MAPPING *psMappingInt;
+ PMR *psPMRInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psMappingInt = (DEVMEMINT_MAPPING *) hMapping;
+ psPMRInt = (PMR *) hPMR;
+
+ eError = DevmemIntPinValidate(psMappingInt, psPMRInt);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnpinInvalidate(IMG_HANDLE hBridge,
+ IMG_HANDLE hMapping, IMG_HANDLE hPMR)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_MAPPING *psMappingInt;
+ PMR *psPMRInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psMappingInt = (DEVMEMINT_MAPPING *) hMapping;
+ psPMRInt = (PMR *) hPMR;
+
+ eError = DevmemIntUnpinInvalidate(psMappingInt, psPMRInt);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntCtxCreate(IMG_HANDLE hBridge,
+ IMG_BOOL bbKernelMemoryCtx,
+ IMG_HANDLE * phDevMemServerContext,
+ IMG_HANDLE * phPrivData,
+ IMG_UINT32 * pui32CPUCacheLineSize)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_CTX *psDevMemServerContextInt = NULL;
+ IMG_HANDLE hPrivDataInt = NULL;
+
+ eError =
+ DevmemIntCtxCreate(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge),
+ bbKernelMemoryCtx,
+ &psDevMemServerContextInt, &hPrivDataInt, pui32CPUCacheLineSize);
+
+ *phDevMemServerContext = psDevMemServerContextInt;
+ *phPrivData = hPrivDataInt;
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntCtxDestroy(IMG_HANDLE hBridge,
+ IMG_HANDLE hDevmemServerContext)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_CTX *psDevmemServerContextInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psDevmemServerContextInt = (DEVMEMINT_CTX *) hDevmemServerContext;
+
+ eError = DevmemIntCtxDestroy(psDevmemServerContextInt);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntHeapCreate(IMG_HANDLE hBridge,
+ IMG_HANDLE hDevmemCtx,
+ IMG_DEV_VIRTADDR sHeapBaseAddr,
+ IMG_DEVMEM_SIZE_T uiHeapLength,
+ IMG_UINT32 ui32Log2DataPageSize,
+ IMG_HANDLE * phDevmemHeapPtr)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_CTX *psDevmemCtxInt;
+ DEVMEMINT_HEAP *psDevmemHeapPtrInt = NULL;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psDevmemCtxInt = (DEVMEMINT_CTX *) hDevmemCtx;
+
+ eError =
+ DevmemIntHeapCreate(psDevmemCtxInt,
+ sHeapBaseAddr,
+ uiHeapLength, ui32Log2DataPageSize, &psDevmemHeapPtrInt);
+
+ *phDevmemHeapPtr = psDevmemHeapPtrInt;
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntHeapDestroy(IMG_HANDLE hBridge, IMG_HANDLE hDevmemHeap)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_HEAP *psDevmemHeapInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psDevmemHeapInt = (DEVMEMINT_HEAP *) hDevmemHeap;
+
+ eError = DevmemIntHeapDestroy(psDevmemHeapInt);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntMapPMR(IMG_HANDLE hBridge,
+ IMG_HANDLE hDevmemServerHeap,
+ IMG_HANDLE hReservation,
+ IMG_HANDLE hPMR,
+ PVRSRV_MEMALLOCFLAGS_T uiMapFlags,
+ IMG_HANDLE * phMapping)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_HEAP *psDevmemServerHeapInt;
+ DEVMEMINT_RESERVATION *psReservationInt;
+ PMR *psPMRInt;
+ DEVMEMINT_MAPPING *psMappingInt = NULL;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psDevmemServerHeapInt = (DEVMEMINT_HEAP *) hDevmemServerHeap;
+ psReservationInt = (DEVMEMINT_RESERVATION *) hReservation;
+ psPMRInt = (PMR *) hPMR;
+
+ eError =
+ DevmemIntMapPMR(psDevmemServerHeapInt,
+ psReservationInt, psPMRInt, uiMapFlags, &psMappingInt);
+
+ *phMapping = psMappingInt;
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnmapPMR(IMG_HANDLE hBridge, IMG_HANDLE hMapping)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_MAPPING *psMappingInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psMappingInt = (DEVMEMINT_MAPPING *) hMapping;
+
+ eError = DevmemIntUnmapPMR(psMappingInt);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntReserveRange(IMG_HANDLE hBridge,
+ IMG_HANDLE hDevmemServerHeap,
+ IMG_DEV_VIRTADDR sAddress,
+ IMG_DEVMEM_SIZE_T uiLength,
+ IMG_HANDLE * phReservation)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_HEAP *psDevmemServerHeapInt;
+ DEVMEMINT_RESERVATION *psReservationInt = NULL;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psDevmemServerHeapInt = (DEVMEMINT_HEAP *) hDevmemServerHeap;
+
+ eError =
+ DevmemIntReserveRange(psDevmemServerHeapInt, sAddress, uiLength, &psReservationInt);
+
+ *phReservation = psReservationInt;
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnreserveRange(IMG_HANDLE hBridge, IMG_HANDLE hReservation)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_RESERVATION *psReservationInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psReservationInt = (DEVMEMINT_RESERVATION *) hReservation;
+
+ eError = DevmemIntUnreserveRange(psReservationInt);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeChangeSparseMem(IMG_HANDLE hBridge,
+ IMG_HANDLE hSrvDevMemHeap,
+ IMG_HANDLE hPMR,
+ IMG_UINT32 ui32AllocPageCount,
+ IMG_UINT32 * pui32AllocPageIndices,
+ IMG_UINT32 ui32FreePageCount,
+ IMG_UINT32 * pui32FreePageIndices,
+ IMG_UINT32 ui32SparseFlags,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ IMG_DEV_VIRTADDR sDevVAddr, IMG_UINT64 ui64CPUVAddr)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_HEAP *psSrvDevMemHeapInt;
+ PMR *psPMRInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psSrvDevMemHeapInt = (DEVMEMINT_HEAP *) hSrvDevMemHeap;
+ psPMRInt = (PMR *) hPMR;
+
+ eError =
+ DevmemIntChangeSparse(psSrvDevMemHeapInt,
+ psPMRInt,
+ ui32AllocPageCount,
+ pui32AllocPageIndices,
+ ui32FreePageCount,
+ pui32FreePageIndices,
+ ui32SparseFlags, uiFlags, sDevVAddr, ui64CPUVAddr);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntMapPages(IMG_HANDLE hBridge,
+ IMG_HANDLE hReservation,
+ IMG_HANDLE hPMR,
+ IMG_UINT32 ui32PageCount,
+ IMG_UINT32 ui32PhysicalPgOffset,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ IMG_DEV_VIRTADDR sDevVAddr)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_RESERVATION *psReservationInt;
+ PMR *psPMRInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psReservationInt = (DEVMEMINT_RESERVATION *) hReservation;
+ psPMRInt = (PMR *) hPMR;
+
+ eError =
+ DevmemIntMapPages(psReservationInt,
+ psPMRInt, ui32PageCount, ui32PhysicalPgOffset, uiFlags, sDevVAddr);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntUnmapPages(IMG_HANDLE hBridge,
+ IMG_HANDLE hReservation,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_UINT32 ui32PageCount)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_RESERVATION *psReservationInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psReservationInt = (DEVMEMINT_RESERVATION *) hReservation;
+
+ eError = DevmemIntUnmapPages(psReservationInt, sDevVAddr, ui32PageCount);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIsVDevAddrValid(IMG_HANDLE hBridge,
+ IMG_HANDLE hDevmemCtx,
+ IMG_DEV_VIRTADDR sAddress)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_CTX *psDevmemCtxInt;
+
+ psDevmemCtxInt = (DEVMEMINT_CTX *) hDevmemCtx;
+
+ eError =
+ DevmemIntIsVDevAddrValid(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge),
+ psDevmemCtxInt, sAddress);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemFlushDevSLCRange(IMG_HANDLE hBridge,
+ IMG_HANDLE hDevmemCtx,
+ IMG_DEV_VIRTADDR sAddress,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_BOOL bInvalidate)
+{
+#if defined(RGX_SRV_SLC_RANGEBASED_CFI_SUPPORTED)
+ PVRSRV_ERROR eError;
+ DEVMEMINT_CTX *psDevmemCtxInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psDevmemCtxInt = (DEVMEMINT_CTX *) hDevmemCtx;
+
+ eError = DevmemIntFlushDevSLCRange(psDevmemCtxInt, sAddress, uiSize, bInvalidate);
+
+ return eError;
+#else
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+ PVR_UNREFERENCED_PARAMETER(hDevmemCtx);
+ PVR_UNREFERENCED_PARAMETER(sAddress);
+ PVR_UNREFERENCED_PARAMETER(uiSize);
+ PVR_UNREFERENCED_PARAMETER(bInvalidate);
+
+ return PVRSRV_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemInvalidateFBSCTable(IMG_HANDLE hBridge,
+ IMG_HANDLE hDevmemCtx,
+ IMG_UINT64 ui64FBSCEntries)
+{
+#if defined(RGX_FEATURE_FBCDC)
+ PVRSRV_ERROR eError;
+ DEVMEMINT_CTX *psDevmemCtxInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psDevmemCtxInt = (DEVMEMINT_CTX *) hDevmemCtx;
+
+ eError = DevmemIntInvalidateFBSCTable(psDevmemCtxInt, ui64FBSCEntries);
+
+ return eError;
+#else
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+ PVR_UNREFERENCED_PARAMETER(hDevmemCtx);
+ PVR_UNREFERENCED_PARAMETER(ui64FBSCEntries);
+
+ return PVRSRV_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeHeapCfgHeapConfigCount(IMG_HANDLE hBridge,
+ IMG_UINT32 * pui32NumHeapConfigs)
+{
+ PVRSRV_ERROR eError;
+
+ eError =
+ HeapCfgHeapConfigCount(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge),
+ pui32NumHeapConfigs);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeHeapCfgHeapCount(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32HeapConfigIndex,
+ IMG_UINT32 * pui32NumHeaps)
+{
+ PVRSRV_ERROR eError;
+
+ eError =
+ HeapCfgHeapCount(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge),
+ ui32HeapConfigIndex, pui32NumHeaps);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeHeapCfgHeapConfigName(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32HeapConfigIndex,
+ IMG_UINT32 ui32HeapConfigNameBufSz,
+ IMG_CHAR * puiHeapConfigName)
+{
+ PVRSRV_ERROR eError;
+
+ eError =
+ HeapCfgHeapConfigName(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge),
+ ui32HeapConfigIndex, ui32HeapConfigNameBufSz, puiHeapConfigName);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeHeapCfgHeapDetails(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32HeapConfigIndex,
+ IMG_UINT32 ui32HeapIndex,
+ IMG_UINT32 ui32HeapNameBufSz,
+ IMG_CHAR * puiHeapNameOut,
+ IMG_DEV_VIRTADDR * psDevVAddrBase,
+ IMG_DEVMEM_SIZE_T * puiHeapLength,
+ IMG_DEVMEM_SIZE_T * puiReservedRegionLength,
+ IMG_UINT32 * pui32Log2DataPageSizeOut,
+ IMG_UINT32 * pui32Log2ImportAlignmentOut)
+{
+ PVRSRV_ERROR eError;
+
+ eError =
+ HeapCfgHeapDetails(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge),
+ ui32HeapConfigIndex,
+ ui32HeapIndex,
+ ui32HeapNameBufSz,
+ puiHeapNameOut,
+ psDevVAddrBase,
+ puiHeapLength,
+ puiReservedRegionLength,
+ pui32Log2DataPageSizeOut, pui32Log2ImportAlignmentOut);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemIntRegisterPFNotifyKM(IMG_HANDLE hBridge,
+ IMG_HANDLE hDevm,
+ IMG_UINT32 ui32PID, IMG_BOOL bRegister)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_CTX *psDevmInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psDevmInt = (DEVMEMINT_CTX *) hDevm;
+
+ eError = DevmemIntRegisterPFNotifyKM(psDevmInt, ui32PID, bRegister);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeGetMaxPhysHeapCount(IMG_HANDLE hBridge,
+ IMG_UINT32 * pui32PhysHeapCount)
+{
+ PVRSRV_ERROR eError;
+
+ eError =
+ PVRSRVGetMaxPhysHeapCountKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge),
+ pui32PhysHeapCount);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgePhysHeapGetMemInfo(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32PhysHeapCount,
+ PVRSRV_PHYS_HEAP * peaPhysHeapID,
+ PHYS_HEAP_MEM_STATS * pasapPhysHeapMemStats)
+{
+ PVRSRV_ERROR eError;
+
+ eError =
+ PVRSRVPhysHeapGetMemInfoKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge),
+ ui32PhysHeapCount, peaPhysHeapID, pasapPhysHeapMemStats);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeGetDefaultPhysicalHeap(IMG_HANDLE hBridge,
+ PVRSRV_PHYS_HEAP * peHeap)
+{
+ PVRSRV_ERROR eError;
+
+ eError =
+ PVRSRVGetDefaultPhysicalHeapKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), peHeap);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeGetHeapPhysMemUsage(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32PhysHeapCount,
+ PHYS_HEAP_MEM_STATS * pasapPhysHeapMemStats)
+{
+ PVRSRV_ERROR eError;
+
+ eError =
+ PVRSRVGetHeapPhysMemUsageKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge),
+ ui32PhysHeapCount, pasapPhysHeapMemStats);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeDevmemGetFaultAddress(IMG_HANDLE hBridge,
+ IMG_HANDLE hDevmemCtx,
+ IMG_DEV_VIRTADDR * psFaultAddress)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_CTX *psDevmemCtxInt;
+
+ psDevmemCtxInt = (DEVMEMINT_CTX *) hDevmemCtx;
+
+ eError =
+ DevmemIntGetFaultAddress(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge),
+ psDevmemCtxInt, psFaultAddress);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgePVRSRVUpdateOOMStats(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32ui32StatType, IMG_PID ui32pid)
+{
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+ PVRSRV_ERROR eError;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ eError = PVRSRVServerUpdateOOMStats(ui32ui32StatType, ui32pid);
+
+ return eError;
+#else
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+ PVR_UNREFERENCED_PARAMETER(ui32ui32StatType);
+ PVR_UNREFERENCED_PARAMETER(ui32pid);
+
+ return PVRSRV_ERROR_NOT_IMPLEMENTED;
+#endif
+}
diff --git a/drivers/gpu/drm/img-rogue/client_pvrtl_bridge.h b/drivers/gpu/drm/img-rogue/client_pvrtl_bridge.h
new file mode 100644
index 000000000..2cfafd5a8
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/client_pvrtl_bridge.h
@@ -0,0 +1,93 @@
+/*******************************************************************************
+@File
+@Title Client bridge header for pvrtl
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Exports the client bridge functions for pvrtl
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef CLIENT_PVRTL_BRIDGE_H
+#define CLIENT_PVRTL_BRIDGE_H
+
+#include "img_defs.h"
+#include "pvrsrv_error.h"
+
+#if defined(PVR_INDIRECT_BRIDGE_CLIENTS)
+#include "pvr_bridge_client.h"
+#include "pvr_bridge.h"
+#endif
+
+#include "common_pvrtl_bridge.h"
+
+IMG_INTERNAL PVRSRV_ERROR BridgeTLOpenStream(IMG_HANDLE hBridge,
+ const IMG_CHAR * puiName,
+ IMG_UINT32 ui32Mode,
+ IMG_HANDLE * phSD, IMG_HANDLE * phTLPMR);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeTLCloseStream(IMG_HANDLE hBridge, IMG_HANDLE hSD);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeTLAcquireData(IMG_HANDLE hBridge,
+ IMG_HANDLE hSD,
+ IMG_UINT32 * pui32ReadOffset,
+ IMG_UINT32 * pui32ReadLen);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeTLReleaseData(IMG_HANDLE hBridge,
+ IMG_HANDLE hSD,
+ IMG_UINT32 ui32ReadOffset, IMG_UINT32 ui32ReadLen);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeTLDiscoverStreams(IMG_HANDLE hBridge,
+ const IMG_CHAR * puiNamePattern,
+ IMG_UINT32 ui32Size,
+ IMG_CHAR * puiStreams,
+ IMG_UINT32 * pui32NumFound);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeTLReserveStream(IMG_HANDLE hBridge,
+ IMG_HANDLE hSD,
+ IMG_UINT32 * pui32BufferOffset,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32SizeMin,
+ IMG_UINT32 * pui32Available);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeTLCommitStream(IMG_HANDLE hBridge,
+ IMG_HANDLE hSD, IMG_UINT32 ui32ReqSize);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeTLWriteData(IMG_HANDLE hBridge,
+ IMG_HANDLE hSD,
+ IMG_UINT32 ui32Size, IMG_BYTE * pui8Data);
+
+#endif /* CLIENT_PVRTL_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/client_pvrtl_direct_bridge.c b/drivers/gpu/drm/img-rogue/client_pvrtl_direct_bridge.c
new file mode 100644
index 000000000..fa2fbed95
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/client_pvrtl_direct_bridge.c
@@ -0,0 +1,175 @@
+/*******************************************************************************
+@File
+@Title Direct client bridge for pvrtl
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Implements the client side of the bridge for pvrtl
+ which is used in calls from Server context.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#include "client_pvrtl_bridge.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+
+/* Module specific includes */
+#include "devicemem_typedefs.h"
+#include "pvrsrv_tlcommon.h"
+
+#include "tlserver.h"
+
+IMG_INTERNAL PVRSRV_ERROR BridgeTLOpenStream(IMG_HANDLE hBridge,
+ const IMG_CHAR * puiName,
+ IMG_UINT32 ui32Mode,
+ IMG_HANDLE * phSD, IMG_HANDLE * phTLPMR)
+{
+ PVRSRV_ERROR eError;
+ TL_STREAM_DESC *psSDInt = NULL;
+ PMR *psTLPMRInt = NULL;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ eError = TLServerOpenStreamKM(puiName, ui32Mode, &psSDInt, &psTLPMRInt);
+
+ *phSD = psSDInt;
+ *phTLPMR = psTLPMRInt;
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeTLCloseStream(IMG_HANDLE hBridge, IMG_HANDLE hSD)
+{
+ PVRSRV_ERROR eError;
+ TL_STREAM_DESC *psSDInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psSDInt = (TL_STREAM_DESC *) hSD;
+
+ eError = TLServerCloseStreamKM(psSDInt);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeTLAcquireData(IMG_HANDLE hBridge,
+ IMG_HANDLE hSD,
+ IMG_UINT32 * pui32ReadOffset,
+ IMG_UINT32 * pui32ReadLen)
+{
+ PVRSRV_ERROR eError;
+ TL_STREAM_DESC *psSDInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psSDInt = (TL_STREAM_DESC *) hSD;
+
+ eError = TLServerAcquireDataKM(psSDInt, pui32ReadOffset, pui32ReadLen);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeTLReleaseData(IMG_HANDLE hBridge,
+ IMG_HANDLE hSD,
+ IMG_UINT32 ui32ReadOffset, IMG_UINT32 ui32ReadLen)
+{
+ PVRSRV_ERROR eError;
+ TL_STREAM_DESC *psSDInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psSDInt = (TL_STREAM_DESC *) hSD;
+
+ eError = TLServerReleaseDataKM(psSDInt, ui32ReadOffset, ui32ReadLen);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeTLDiscoverStreams(IMG_HANDLE hBridge,
+ const IMG_CHAR * puiNamePattern,
+ IMG_UINT32 ui32Size,
+ IMG_CHAR * puiStreams, IMG_UINT32 * pui32NumFound)
+{
+ PVRSRV_ERROR eError;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ eError = TLServerDiscoverStreamsKM(puiNamePattern, ui32Size, puiStreams, pui32NumFound);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeTLReserveStream(IMG_HANDLE hBridge,
+ IMG_HANDLE hSD,
+ IMG_UINT32 * pui32BufferOffset,
+ IMG_UINT32 ui32Size,
+ IMG_UINT32 ui32SizeMin, IMG_UINT32 * pui32Available)
+{
+ PVRSRV_ERROR eError;
+ TL_STREAM_DESC *psSDInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psSDInt = (TL_STREAM_DESC *) hSD;
+
+ eError =
+ TLServerReserveStreamKM(psSDInt,
+ pui32BufferOffset, ui32Size, ui32SizeMin, pui32Available);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeTLCommitStream(IMG_HANDLE hBridge,
+ IMG_HANDLE hSD, IMG_UINT32 ui32ReqSize)
+{
+ PVRSRV_ERROR eError;
+ TL_STREAM_DESC *psSDInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psSDInt = (TL_STREAM_DESC *) hSD;
+
+ eError = TLServerCommitStreamKM(psSDInt, ui32ReqSize);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeTLWriteData(IMG_HANDLE hBridge,
+ IMG_HANDLE hSD,
+ IMG_UINT32 ui32Size, IMG_BYTE * pui8Data)
+{
+ PVRSRV_ERROR eError;
+ TL_STREAM_DESC *psSDInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psSDInt = (TL_STREAM_DESC *) hSD;
+
+ eError = TLServerWriteDataKM(psSDInt, ui32Size, pui8Data);
+
+ return eError;
+}
diff --git a/drivers/gpu/drm/img-rogue/client_ri_bridge.h b/drivers/gpu/drm/img-rogue/client_ri_bridge.h
new file mode 100644
index 000000000..b3c42e6f4
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/client_ri_bridge.h
@@ -0,0 +1,89 @@
+/*******************************************************************************
+@File
+@Title Client bridge header for ri
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Exports the client bridge functions for ri
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef CLIENT_RI_BRIDGE_H
+#define CLIENT_RI_BRIDGE_H
+
+#include "img_defs.h"
+#include "pvrsrv_error.h"
+
+#if defined(PVR_INDIRECT_BRIDGE_CLIENTS)
+#include "pvr_bridge_client.h"
+#include "pvr_bridge.h"
+#endif
+
+#include "common_ri_bridge.h"
+
+IMG_INTERNAL PVRSRV_ERROR BridgeRIWritePMREntry(IMG_HANDLE hBridge, IMG_HANDLE hPMRHandle);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeRIWriteMEMDESCEntry(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMRHandle,
+ IMG_UINT32 ui32TextBSize,
+ const IMG_CHAR * puiTextB,
+ IMG_UINT64 ui64Offset,
+ IMG_UINT64 ui64Size,
+ IMG_BOOL bIsImport,
+ IMG_BOOL bIsSuballoc, IMG_HANDLE * phRIHandle);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeRIWriteProcListEntry(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32TextBSize,
+ const IMG_CHAR * puiTextB,
+ IMG_UINT64 ui64Size,
+ IMG_UINT64 ui64DevVAddr,
+ IMG_HANDLE * phRIHandle);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeRIUpdateMEMDESCAddr(IMG_HANDLE hBridge,
+ IMG_HANDLE hRIHandle, IMG_DEV_VIRTADDR sAddr);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeRIDeleteMEMDESCEntry(IMG_HANDLE hBridge, IMG_HANDLE hRIHandle);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeRIDumpList(IMG_HANDLE hBridge, IMG_HANDLE hPMRHandle);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeRIDumpAll(IMG_HANDLE hBridge);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeRIDumpProcess(IMG_HANDLE hBridge, IMG_PID ui32Pid);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeRIWritePMREntryWithOwner(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMRHandle, IMG_PID ui32Owner);
+
+#endif /* CLIENT_RI_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/client_ri_direct_bridge.c b/drivers/gpu/drm/img-rogue/client_ri_direct_bridge.c
new file mode 100644
index 000000000..2a9934cc4
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/client_ri_direct_bridge.c
@@ -0,0 +1,182 @@
+/*******************************************************************************
+@File
+@Title Direct client bridge for ri
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Implements the client side of the bridge for ri
+ which is used in calls from Server context.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#include "client_ri_bridge.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+
+/* Module specific includes */
+#include "ri_typedefs.h"
+
+#include "ri_server.h"
+
+IMG_INTERNAL PVRSRV_ERROR BridgeRIWritePMREntry(IMG_HANDLE hBridge, IMG_HANDLE hPMRHandle)
+{
+ PVRSRV_ERROR eError;
+ PMR *psPMRHandleInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psPMRHandleInt = (PMR *) hPMRHandle;
+
+ eError = RIWritePMREntryKM(psPMRHandleInt);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeRIWriteMEMDESCEntry(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMRHandle,
+ IMG_UINT32 ui32TextBSize,
+ const IMG_CHAR * puiTextB,
+ IMG_UINT64 ui64Offset,
+ IMG_UINT64 ui64Size,
+ IMG_BOOL bIsImport,
+ IMG_BOOL bIsSuballoc, IMG_HANDLE * phRIHandle)
+{
+ PVRSRV_ERROR eError;
+ PMR *psPMRHandleInt;
+ RI_HANDLE psRIHandleInt = NULL;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psPMRHandleInt = (PMR *) hPMRHandle;
+
+ eError =
+ RIWriteMEMDESCEntryKM(psPMRHandleInt,
+ ui32TextBSize,
+ puiTextB,
+ ui64Offset, ui64Size, bIsImport, bIsSuballoc, &psRIHandleInt);
+
+ *phRIHandle = psRIHandleInt;
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeRIWriteProcListEntry(IMG_HANDLE hBridge,
+ IMG_UINT32 ui32TextBSize,
+ const IMG_CHAR * puiTextB,
+ IMG_UINT64 ui64Size,
+ IMG_UINT64 ui64DevVAddr,
+ IMG_HANDLE * phRIHandle)
+{
+ PVRSRV_ERROR eError;
+ RI_HANDLE psRIHandleInt = NULL;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ eError =
+ RIWriteProcListEntryKM(ui32TextBSize, puiTextB, ui64Size, ui64DevVAddr, &psRIHandleInt);
+
+ *phRIHandle = psRIHandleInt;
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeRIUpdateMEMDESCAddr(IMG_HANDLE hBridge,
+ IMG_HANDLE hRIHandle, IMG_DEV_VIRTADDR sAddr)
+{
+ PVRSRV_ERROR eError;
+ RI_HANDLE psRIHandleInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psRIHandleInt = (RI_HANDLE) hRIHandle;
+
+ eError = RIUpdateMEMDESCAddrKM(psRIHandleInt, sAddr);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeRIDeleteMEMDESCEntry(IMG_HANDLE hBridge, IMG_HANDLE hRIHandle)
+{
+ PVRSRV_ERROR eError;
+ RI_HANDLE psRIHandleInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psRIHandleInt = (RI_HANDLE) hRIHandle;
+
+ eError = RIDeleteMEMDESCEntryKM(psRIHandleInt);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeRIDumpList(IMG_HANDLE hBridge, IMG_HANDLE hPMRHandle)
+{
+ PVRSRV_ERROR eError;
+ PMR *psPMRHandleInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psPMRHandleInt = (PMR *) hPMRHandle;
+
+ eError = RIDumpListKM(psPMRHandleInt);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeRIDumpAll(IMG_HANDLE hBridge)
+{
+ PVRSRV_ERROR eError;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ eError = RIDumpAllKM();
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeRIDumpProcess(IMG_HANDLE hBridge, IMG_PID ui32Pid)
+{
+ PVRSRV_ERROR eError;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ eError = RIDumpProcessKM(ui32Pid);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeRIWritePMREntryWithOwner(IMG_HANDLE hBridge,
+ IMG_HANDLE hPMRHandle, IMG_PID ui32Owner)
+{
+ PVRSRV_ERROR eError;
+ PMR *psPMRHandleInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psPMRHandleInt = (PMR *) hPMRHandle;
+
+ eError = RIWritePMREntryWithOwnerKM(psPMRHandleInt, ui32Owner);
+
+ return eError;
+}
diff --git a/drivers/gpu/drm/img-rogue/client_sync_bridge.h b/drivers/gpu/drm/img-rogue/client_sync_bridge.h
new file mode 100644
index 000000000..19f1b0ece
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/client_sync_bridge.h
@@ -0,0 +1,102 @@
+/*******************************************************************************
+@File
+@Title Client bridge header for sync
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Exports the client bridge functions for sync
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef CLIENT_SYNC_BRIDGE_H
+#define CLIENT_SYNC_BRIDGE_H
+
+#include "img_defs.h"
+#include "pvrsrv_error.h"
+
+#if defined(PVR_INDIRECT_BRIDGE_CLIENTS)
+#include "pvr_bridge_client.h"
+#include "pvr_bridge.h"
+#endif
+
+#include "common_sync_bridge.h"
+
+IMG_INTERNAL PVRSRV_ERROR BridgeAllocSyncPrimitiveBlock(IMG_HANDLE hBridge,
+ IMG_HANDLE * phSyncHandle,
+ IMG_UINT32 * pui32SyncPrimVAddr,
+ IMG_UINT32 * pui32SyncPrimBlockSize,
+ IMG_HANDLE * phhSyncPMR);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeFreeSyncPrimitiveBlock(IMG_HANDLE hBridge, IMG_HANDLE hSyncHandle);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimSet(IMG_HANDLE hBridge,
+ IMG_HANDLE hSyncHandle,
+ IMG_UINT32 ui32Index, IMG_UINT32 ui32Value);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimPDump(IMG_HANDLE hBridge,
+ IMG_HANDLE hSyncHandle, IMG_UINT32 ui32Offset);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimPDumpValue(IMG_HANDLE hBridge,
+ IMG_HANDLE hSyncHandle,
+ IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimPDumpPol(IMG_HANDLE hBridge,
+ IMG_HANDLE hSyncHandle,
+ IMG_UINT32 ui32Offset,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ PDUMP_POLL_OPERATOR eOperator,
+ PDUMP_FLAGS_T uiPDumpFlags);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimPDumpCBP(IMG_HANDLE hBridge,
+ IMG_HANDLE hSyncHandle,
+ IMG_UINT32 ui32Offset,
+ IMG_DEVMEM_OFFSET_T uiWriteOffset,
+ IMG_DEVMEM_SIZE_T uiPacketSize,
+ IMG_DEVMEM_SIZE_T uiBufferSize);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncAllocEvent(IMG_HANDLE hBridge,
+ IMG_BOOL bServerSync,
+ IMG_UINT32 ui32FWAddr,
+ IMG_UINT32 ui32ClassNameSize,
+ const IMG_CHAR * puiClassName);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncFreeEvent(IMG_HANDLE hBridge, IMG_UINT32 ui32FWAddr);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncCheckpointSignalledPDumpPol(IMG_HANDLE hBridge,
+ PVRSRV_FENCE hFence);
+
+#endif /* CLIENT_SYNC_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/client_sync_direct_bridge.c b/drivers/gpu/drm/img-rogue/client_sync_direct_bridge.c
new file mode 100644
index 000000000..d631aea42
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/client_sync_direct_bridge.c
@@ -0,0 +1,262 @@
+/*******************************************************************************
+@File
+@Title Direct client bridge for sync
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Implements the client side of the bridge for sync
+ which is used in calls from Server context.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#include "client_sync_bridge.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+
+/* Module specific includes */
+#include "pdump.h"
+#include "pdumpdefs.h"
+#include "devicemem_typedefs.h"
+#include "pvrsrv_sync_km.h"
+#include
+
+#include "sync.h"
+#include "sync_server.h"
+#include "pdump.h"
+#include "pvrsrv_sync_km.h"
+#include "sync_fallback_server.h"
+#include "sync_checkpoint.h"
+
+IMG_INTERNAL PVRSRV_ERROR BridgeAllocSyncPrimitiveBlock(IMG_HANDLE hBridge,
+ IMG_HANDLE * phSyncHandle,
+ IMG_UINT32 * pui32SyncPrimVAddr,
+ IMG_UINT32 * pui32SyncPrimBlockSize,
+ IMG_HANDLE * phhSyncPMR)
+{
+ PVRSRV_ERROR eError;
+ SYNC_PRIMITIVE_BLOCK *psSyncHandleInt = NULL;
+ PMR *pshSyncPMRInt = NULL;
+
+ eError =
+ PVRSRVAllocSyncPrimitiveBlockKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge),
+ &psSyncHandleInt,
+ pui32SyncPrimVAddr,
+ pui32SyncPrimBlockSize, &pshSyncPMRInt);
+
+ *phSyncHandle = psSyncHandleInt;
+ *phhSyncPMR = pshSyncPMRInt;
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeFreeSyncPrimitiveBlock(IMG_HANDLE hBridge, IMG_HANDLE hSyncHandle)
+{
+ PVRSRV_ERROR eError;
+ SYNC_PRIMITIVE_BLOCK *psSyncHandleInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psSyncHandleInt = (SYNC_PRIMITIVE_BLOCK *) hSyncHandle;
+
+ eError = PVRSRVFreeSyncPrimitiveBlockKM(psSyncHandleInt);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimSet(IMG_HANDLE hBridge,
+ IMG_HANDLE hSyncHandle,
+ IMG_UINT32 ui32Index, IMG_UINT32 ui32Value)
+{
+ PVRSRV_ERROR eError;
+ SYNC_PRIMITIVE_BLOCK *psSyncHandleInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psSyncHandleInt = (SYNC_PRIMITIVE_BLOCK *) hSyncHandle;
+
+ eError = PVRSRVSyncPrimSetKM(psSyncHandleInt, ui32Index, ui32Value);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimPDump(IMG_HANDLE hBridge,
+ IMG_HANDLE hSyncHandle, IMG_UINT32 ui32Offset)
+{
+#if defined(PDUMP)
+ PVRSRV_ERROR eError;
+ SYNC_PRIMITIVE_BLOCK *psSyncHandleInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psSyncHandleInt = (SYNC_PRIMITIVE_BLOCK *) hSyncHandle;
+
+ eError = PVRSRVSyncPrimPDumpKM(psSyncHandleInt, ui32Offset);
+
+ return eError;
+#else
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+ PVR_UNREFERENCED_PARAMETER(hSyncHandle);
+ PVR_UNREFERENCED_PARAMETER(ui32Offset);
+
+ return PVRSRV_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimPDumpValue(IMG_HANDLE hBridge,
+ IMG_HANDLE hSyncHandle,
+ IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
+{
+#if defined(PDUMP)
+ PVRSRV_ERROR eError;
+ SYNC_PRIMITIVE_BLOCK *psSyncHandleInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psSyncHandleInt = (SYNC_PRIMITIVE_BLOCK *) hSyncHandle;
+
+ eError = PVRSRVSyncPrimPDumpValueKM(psSyncHandleInt, ui32Offset, ui32Value);
+
+ return eError;
+#else
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+ PVR_UNREFERENCED_PARAMETER(hSyncHandle);
+ PVR_UNREFERENCED_PARAMETER(ui32Offset);
+ PVR_UNREFERENCED_PARAMETER(ui32Value);
+
+ return PVRSRV_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimPDumpPol(IMG_HANDLE hBridge,
+ IMG_HANDLE hSyncHandle,
+ IMG_UINT32 ui32Offset,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ PDUMP_POLL_OPERATOR eOperator,
+ PDUMP_FLAGS_T uiPDumpFlags)
+{
+#if defined(PDUMP)
+ PVRSRV_ERROR eError;
+ SYNC_PRIMITIVE_BLOCK *psSyncHandleInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psSyncHandleInt = (SYNC_PRIMITIVE_BLOCK *) hSyncHandle;
+
+ eError =
+ PVRSRVSyncPrimPDumpPolKM(psSyncHandleInt,
+ ui32Offset, ui32Value, ui32Mask, eOperator, uiPDumpFlags);
+
+ return eError;
+#else
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+ PVR_UNREFERENCED_PARAMETER(hSyncHandle);
+ PVR_UNREFERENCED_PARAMETER(ui32Offset);
+ PVR_UNREFERENCED_PARAMETER(ui32Value);
+ PVR_UNREFERENCED_PARAMETER(ui32Mask);
+ PVR_UNREFERENCED_PARAMETER(eOperator);
+ PVR_UNREFERENCED_PARAMETER(uiPDumpFlags);
+
+ return PVRSRV_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncPrimPDumpCBP(IMG_HANDLE hBridge,
+ IMG_HANDLE hSyncHandle,
+ IMG_UINT32 ui32Offset,
+ IMG_DEVMEM_OFFSET_T uiWriteOffset,
+ IMG_DEVMEM_SIZE_T uiPacketSize,
+ IMG_DEVMEM_SIZE_T uiBufferSize)
+{
+#if defined(PDUMP)
+ PVRSRV_ERROR eError;
+ SYNC_PRIMITIVE_BLOCK *psSyncHandleInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ psSyncHandleInt = (SYNC_PRIMITIVE_BLOCK *) hSyncHandle;
+
+ eError =
+ PVRSRVSyncPrimPDumpCBPKM(psSyncHandleInt,
+ ui32Offset, uiWriteOffset, uiPacketSize, uiBufferSize);
+
+ return eError;
+#else
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+ PVR_UNREFERENCED_PARAMETER(hSyncHandle);
+ PVR_UNREFERENCED_PARAMETER(ui32Offset);
+ PVR_UNREFERENCED_PARAMETER(uiWriteOffset);
+ PVR_UNREFERENCED_PARAMETER(uiPacketSize);
+ PVR_UNREFERENCED_PARAMETER(uiBufferSize);
+
+ return PVRSRV_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncAllocEvent(IMG_HANDLE hBridge,
+ IMG_BOOL bServerSync,
+ IMG_UINT32 ui32FWAddr,
+ IMG_UINT32 ui32ClassNameSize,
+ const IMG_CHAR * puiClassName)
+{
+ PVRSRV_ERROR eError;
+
+ eError =
+ PVRSRVSyncAllocEventKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge),
+ bServerSync, ui32FWAddr, ui32ClassNameSize, puiClassName);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncFreeEvent(IMG_HANDLE hBridge, IMG_UINT32 ui32FWAddr)
+{
+ PVRSRV_ERROR eError;
+
+ eError = PVRSRVSyncFreeEventKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge), ui32FWAddr);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncCheckpointSignalledPDumpPol(IMG_HANDLE hBridge,
+ PVRSRV_FENCE hFence)
+{
+#if defined(PDUMP)
+ PVRSRV_ERROR eError;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ eError = PVRSRVSyncCheckpointSignalledPDumpPolKM(hFence);
+
+ return eError;
+#else
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+ PVR_UNREFERENCED_PARAMETER(hFence);
+
+ return PVRSRV_ERROR_NOT_IMPLEMENTED;
+#endif
+}
diff --git a/drivers/gpu/drm/img-rogue/client_synctracking_bridge.h b/drivers/gpu/drm/img-rogue/client_synctracking_bridge.h
new file mode 100644
index 000000000..544efd962
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/client_synctracking_bridge.h
@@ -0,0 +1,68 @@
+/*******************************************************************************
+@File
+@Title Client bridge header for synctracking
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Exports the client bridge functions for synctracking
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef CLIENT_SYNCTRACKING_BRIDGE_H
+#define CLIENT_SYNCTRACKING_BRIDGE_H
+
+#include "img_defs.h"
+#include "pvrsrv_error.h"
+
+#if defined(PVR_INDIRECT_BRIDGE_CLIENTS)
+#include "pvr_bridge_client.h"
+#include "pvr_bridge.h"
+#endif
+
+#include "common_synctracking_bridge.h"
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncRecordRemoveByHandle(IMG_HANDLE hBridge, IMG_HANDLE hhRecord);
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncRecordAdd(IMG_HANDLE hBridge,
+ IMG_HANDLE * phhRecord,
+ IMG_HANDLE hhServerSyncPrimBlock,
+ IMG_UINT32 ui32ui32FwBlockAddr,
+ IMG_UINT32 ui32ui32SyncOffset,
+ IMG_BOOL bbServerSync,
+ IMG_UINT32 ui32ClassNameSize,
+ const IMG_CHAR * puiClassName);
+
+#endif /* CLIENT_SYNCTRACKING_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/client_synctracking_direct_bridge.c b/drivers/gpu/drm/img-rogue/client_synctracking_direct_bridge.c
new file mode 100644
index 000000000..baeb89a6a
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/client_synctracking_direct_bridge.c
@@ -0,0 +1,92 @@
+/*******************************************************************************
+@File
+@Title Direct client bridge for synctracking
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Implements the client side of the bridge for synctracking
+ which is used in calls from Server context.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#include "client_synctracking_bridge.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+
+/* Module specific includes */
+
+#include "sync.h"
+#include "sync_server.h"
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncRecordRemoveByHandle(IMG_HANDLE hBridge, IMG_HANDLE hhRecord)
+{
+ PVRSRV_ERROR eError;
+ SYNC_RECORD_HANDLE pshRecordInt;
+ PVR_UNREFERENCED_PARAMETER(hBridge);
+
+ pshRecordInt = (SYNC_RECORD_HANDLE) hhRecord;
+
+ eError = PVRSRVSyncRecordRemoveByHandleKM(pshRecordInt);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR BridgeSyncRecordAdd(IMG_HANDLE hBridge,
+ IMG_HANDLE * phhRecord,
+ IMG_HANDLE hhServerSyncPrimBlock,
+ IMG_UINT32 ui32ui32FwBlockAddr,
+ IMG_UINT32 ui32ui32SyncOffset,
+ IMG_BOOL bbServerSync,
+ IMG_UINT32 ui32ClassNameSize,
+ const IMG_CHAR * puiClassName)
+{
+ PVRSRV_ERROR eError;
+ SYNC_RECORD_HANDLE pshRecordInt = NULL;
+ SYNC_PRIMITIVE_BLOCK *pshServerSyncPrimBlockInt;
+
+ pshServerSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK *) hhServerSyncPrimBlock;
+
+ eError =
+ PVRSRVSyncRecordAddKM(NULL, (PVRSRV_DEVICE_NODE *) ((void *)hBridge),
+ &pshRecordInt,
+ pshServerSyncPrimBlockInt,
+ ui32ui32FwBlockAddr,
+ ui32ui32SyncOffset,
+ bbServerSync, ui32ClassNameSize, puiClassName);
+
+ *phhRecord = pshRecordInt;
+ return eError;
+}
diff --git a/drivers/gpu/drm/img-rogue/common_cache_bridge.h b/drivers/gpu/drm/img-rogue/common_cache_bridge.h
new file mode 100644
index 000000000..e8532f635
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_cache_bridge.h
@@ -0,0 +1,129 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for cache
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for cache
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_CACHE_BRIDGE_H
+#define COMMON_CACHE_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "cache_ops.h"
+
+#define PVRSRV_BRIDGE_CACHE_CMD_FIRST 0
+#define PVRSRV_BRIDGE_CACHE_CACHEOPQUEUE PVRSRV_BRIDGE_CACHE_CMD_FIRST+0
+#define PVRSRV_BRIDGE_CACHE_CACHEOPEXEC PVRSRV_BRIDGE_CACHE_CMD_FIRST+1
+#define PVRSRV_BRIDGE_CACHE_CACHEOPLOG PVRSRV_BRIDGE_CACHE_CMD_FIRST+2
+#define PVRSRV_BRIDGE_CACHE_CMD_LAST (PVRSRV_BRIDGE_CACHE_CMD_FIRST+2)
+
+/*******************************************
+ CacheOpQueue
+ *******************************************/
+
+/* Bridge in structure for CacheOpQueue */
+typedef struct PVRSRV_BRIDGE_IN_CACHEOPQUEUE_TAG
+{
+ PVRSRV_CACHE_OP *piuCacheOp;
+ IMG_UINT64 *pui64Address;
+ IMG_DEVMEM_OFFSET_T *puiOffset;
+ IMG_DEVMEM_SIZE_T *puiSize;
+ IMG_HANDLE *phPMR;
+ IMG_UINT32 ui32CurrentFenceSeqNum;
+ IMG_UINT32 ui32NumCacheOps;
+ IMG_UINT32 ui32OpTimeline;
+} __packed PVRSRV_BRIDGE_IN_CACHEOPQUEUE;
+
+/* Bridge out structure for CacheOpQueue */
+typedef struct PVRSRV_BRIDGE_OUT_CACHEOPQUEUE_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32NextFenceSeqNum;
+} __packed PVRSRV_BRIDGE_OUT_CACHEOPQUEUE;
+
+/*******************************************
+ CacheOpExec
+ *******************************************/
+
+/* Bridge in structure for CacheOpExec */
+typedef struct PVRSRV_BRIDGE_IN_CACHEOPEXEC_TAG
+{
+ IMG_UINT64 ui64Address;
+ IMG_DEVMEM_OFFSET_T uiOffset;
+ IMG_DEVMEM_SIZE_T uiSize;
+ IMG_HANDLE hPMR;
+ PVRSRV_CACHE_OP iuCacheOp;
+} __packed PVRSRV_BRIDGE_IN_CACHEOPEXEC;
+
+/* Bridge out structure for CacheOpExec */
+typedef struct PVRSRV_BRIDGE_OUT_CACHEOPEXEC_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_CACHEOPEXEC;
+
+/*******************************************
+ CacheOpLog
+ *******************************************/
+
+/* Bridge in structure for CacheOpLog */
+typedef struct PVRSRV_BRIDGE_IN_CACHEOPLOG_TAG
+{
+ IMG_INT64 i64ExecuteTimeUs;
+ IMG_INT64 i64QueuedTimeUs;
+ IMG_UINT64 ui64Address;
+ IMG_DEVMEM_OFFSET_T uiOffset;
+ IMG_DEVMEM_SIZE_T uiSize;
+ IMG_HANDLE hPMR;
+ IMG_INT32 i32NumRBF;
+ PVRSRV_CACHE_OP iuCacheOp;
+} __packed PVRSRV_BRIDGE_IN_CACHEOPLOG;
+
+/* Bridge out structure for CacheOpLog */
+typedef struct PVRSRV_BRIDGE_OUT_CACHEOPLOG_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_CACHEOPLOG;
+
+#endif /* COMMON_CACHE_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_cmm_bridge.h b/drivers/gpu/drm/img-rogue/common_cmm_bridge.h
new file mode 100644
index 000000000..da48de359
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_cmm_bridge.h
@@ -0,0 +1,114 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for cmm
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for cmm
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_CMM_BRIDGE_H
+#define COMMON_CMM_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "devicemem_typedefs.h"
+
+#define PVRSRV_BRIDGE_CMM_CMD_FIRST 0
+#define PVRSRV_BRIDGE_CMM_DEVMEMINTEXPORTCTX PVRSRV_BRIDGE_CMM_CMD_FIRST+0
+#define PVRSRV_BRIDGE_CMM_DEVMEMINTUNEXPORTCTX PVRSRV_BRIDGE_CMM_CMD_FIRST+1
+#define PVRSRV_BRIDGE_CMM_DEVMEMINTACQUIREREMOTECTX PVRSRV_BRIDGE_CMM_CMD_FIRST+2
+#define PVRSRV_BRIDGE_CMM_CMD_LAST (PVRSRV_BRIDGE_CMM_CMD_FIRST+2)
+
+/*******************************************
+ DevmemIntExportCtx
+ *******************************************/
+
+/* Bridge in structure for DevmemIntExportCtx */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTEXPORTCTX_TAG
+{
+ IMG_HANDLE hContext;
+ IMG_HANDLE hPMR;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMINTEXPORTCTX;
+
+/* Bridge out structure for DevmemIntExportCtx */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTEXPORTCTX_TAG
+{
+ IMG_HANDLE hContextExport;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTEXPORTCTX;
+
+/*******************************************
+ DevmemIntUnexportCtx
+ *******************************************/
+
+/* Bridge in structure for DevmemIntUnexportCtx */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTUNEXPORTCTX_TAG
+{
+ IMG_HANDLE hContextExport;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMINTUNEXPORTCTX;
+
+/* Bridge out structure for DevmemIntUnexportCtx */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTUNEXPORTCTX_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTUNEXPORTCTX;
+
+/*******************************************
+ DevmemIntAcquireRemoteCtx
+ *******************************************/
+
+/* Bridge in structure for DevmemIntAcquireRemoteCtx */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTACQUIREREMOTECTX_TAG
+{
+ IMG_HANDLE hPMR;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMINTACQUIREREMOTECTX;
+
+/* Bridge out structure for DevmemIntAcquireRemoteCtx */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTACQUIREREMOTECTX_TAG
+{
+ IMG_HANDLE hContext;
+ IMG_HANDLE hPrivData;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTACQUIREREMOTECTX;
+
+#endif /* COMMON_CMM_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_devicememhistory_bridge.h b/drivers/gpu/drm/img-rogue/common_devicememhistory_bridge.h
new file mode 100644
index 000000000..800f98dd2
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_devicememhistory_bridge.h
@@ -0,0 +1,185 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for devicememhistory
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for devicememhistory
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_DEVICEMEMHISTORY_BRIDGE_H
+#define COMMON_DEVICEMEMHISTORY_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "img_types.h"
+#include "img_defs.h"
+#include "devicemem_typedefs.h"
+
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST 0
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAP PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+0
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAP PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+1
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAPVRANGE PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+2
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAPVRANGE PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+3
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYSPARSECHANGE PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+4
+#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_LAST (PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+4)
+
+/*******************************************
+ DevicememHistoryMap
+ *******************************************/
+
+/* Bridge in structure for DevicememHistoryMap */
+typedef struct PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAP_TAG
+{
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_DEVMEM_SIZE_T uiOffset;
+ IMG_DEVMEM_SIZE_T uiSize;
+ IMG_HANDLE hPMR;
+ const IMG_CHAR *puiText;
+ IMG_UINT32 ui32AllocationIndex;
+ IMG_UINT32 ui32Log2PageSize;
+} __packed PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAP;
+
+/* Bridge out structure for DevicememHistoryMap */
+typedef struct PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAP_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32AllocationIndexOut;
+} __packed PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAP;
+
+/*******************************************
+ DevicememHistoryUnmap
+ *******************************************/
+
+/* Bridge in structure for DevicememHistoryUnmap */
+typedef struct PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAP_TAG
+{
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_DEVMEM_SIZE_T uiOffset;
+ IMG_DEVMEM_SIZE_T uiSize;
+ IMG_HANDLE hPMR;
+ const IMG_CHAR *puiText;
+ IMG_UINT32 ui32AllocationIndex;
+ IMG_UINT32 ui32Log2PageSize;
+} __packed PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAP;
+
+/* Bridge out structure for DevicememHistoryUnmap */
+typedef struct PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAP_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32AllocationIndexOut;
+} __packed PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAP;
+
+/*******************************************
+ DevicememHistoryMapVRange
+ *******************************************/
+
+/* Bridge in structure for DevicememHistoryMapVRange */
+typedef struct PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAPVRANGE_TAG
+{
+ IMG_DEV_VIRTADDR sBaseDevVAddr;
+ IMG_DEVMEM_SIZE_T uiAllocSize;
+ const IMG_CHAR *puiText;
+ IMG_UINT32 ui32AllocationIndex;
+ IMG_UINT32 ui32Log2PageSize;
+ IMG_UINT32 ui32NumPages;
+ IMG_UINT32 ui32ui32StartPage;
+} __packed PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAPVRANGE;
+
+/* Bridge out structure for DevicememHistoryMapVRange */
+typedef struct PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAPVRANGE_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32AllocationIndexOut;
+} __packed PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAPVRANGE;
+
+/*******************************************
+ DevicememHistoryUnmapVRange
+ *******************************************/
+
+/* Bridge in structure for DevicememHistoryUnmapVRange */
+typedef struct PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAPVRANGE_TAG
+{
+ IMG_DEV_VIRTADDR sBaseDevVAddr;
+ IMG_DEVMEM_SIZE_T uiAllocSize;
+ const IMG_CHAR *puiText;
+ IMG_UINT32 ui32AllocationIndex;
+ IMG_UINT32 ui32Log2PageSize;
+ IMG_UINT32 ui32NumPages;
+ IMG_UINT32 ui32ui32StartPage;
+} __packed PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAPVRANGE;
+
+/* Bridge out structure for DevicememHistoryUnmapVRange */
+typedef struct PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAPVRANGE_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32AllocationIndexOut;
+} __packed PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAPVRANGE;
+
+/*******************************************
+ DevicememHistorySparseChange
+ *******************************************/
+
+/* Bridge in structure for DevicememHistorySparseChange */
+typedef struct PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYSPARSECHANGE_TAG
+{
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_DEVMEM_SIZE_T uiOffset;
+ IMG_DEVMEM_SIZE_T uiSize;
+ IMG_HANDLE hPMR;
+ IMG_UINT32 *pui32AllocPageIndices;
+ IMG_UINT32 *pui32FreePageIndices;
+ const IMG_CHAR *puiText;
+ IMG_UINT32 ui32AllocPageCount;
+ IMG_UINT32 ui32AllocationIndex;
+ IMG_UINT32 ui32FreePageCount;
+ IMG_UINT32 ui32Log2PageSize;
+} __packed PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYSPARSECHANGE;
+
+/* Bridge out structure for DevicememHistorySparseChange */
+typedef struct PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYSPARSECHANGE_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32AllocationIndexOut;
+} __packed PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYSPARSECHANGE;
+
+#endif /* COMMON_DEVICEMEMHISTORY_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_di_bridge.h b/drivers/gpu/drm/img-rogue/common_di_bridge.h
new file mode 100644
index 000000000..859100614
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_di_bridge.h
@@ -0,0 +1,153 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for di
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for di
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_DI_BRIDGE_H
+#define COMMON_DI_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "pvrsrv_tlcommon.h"
+#include "pvr_dicommon.h"
+
+#define PVRSRV_BRIDGE_DI_CMD_FIRST 0
+#define PVRSRV_BRIDGE_DI_DICREATECONTEXT PVRSRV_BRIDGE_DI_CMD_FIRST+0
+#define PVRSRV_BRIDGE_DI_DIDESTROYCONTEXT PVRSRV_BRIDGE_DI_CMD_FIRST+1
+#define PVRSRV_BRIDGE_DI_DIREADENTRY PVRSRV_BRIDGE_DI_CMD_FIRST+2
+#define PVRSRV_BRIDGE_DI_DIWRITEENTRY PVRSRV_BRIDGE_DI_CMD_FIRST+3
+#define PVRSRV_BRIDGE_DI_DILISTALLENTRIES PVRSRV_BRIDGE_DI_CMD_FIRST+4
+#define PVRSRV_BRIDGE_DI_CMD_LAST (PVRSRV_BRIDGE_DI_CMD_FIRST+4)
+
+/*******************************************
+ DICreateContext
+ *******************************************/
+
+/* Bridge in structure for DICreateContext */
+typedef struct PVRSRV_BRIDGE_IN_DICREATECONTEXT_TAG
+{
+ IMG_CHAR *puiStreamName;
+} __packed PVRSRV_BRIDGE_IN_DICREATECONTEXT;
+
+/* Bridge out structure for DICreateContext */
+typedef struct PVRSRV_BRIDGE_OUT_DICREATECONTEXT_TAG
+{
+ IMG_HANDLE hContext;
+ IMG_CHAR *puiStreamName;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DICREATECONTEXT;
+
+/*******************************************
+ DIDestroyContext
+ *******************************************/
+
+/* Bridge in structure for DIDestroyContext */
+typedef struct PVRSRV_BRIDGE_IN_DIDESTROYCONTEXT_TAG
+{
+ IMG_HANDLE hContext;
+} __packed PVRSRV_BRIDGE_IN_DIDESTROYCONTEXT;
+
+/* Bridge out structure for DIDestroyContext */
+typedef struct PVRSRV_BRIDGE_OUT_DIDESTROYCONTEXT_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DIDESTROYCONTEXT;
+
+/*******************************************
+ DIReadEntry
+ *******************************************/
+
+/* Bridge in structure for DIReadEntry */
+typedef struct PVRSRV_BRIDGE_IN_DIREADENTRY_TAG
+{
+ IMG_UINT64 ui64Offset;
+ IMG_UINT64 ui64Size;
+ IMG_HANDLE hContext;
+ const IMG_CHAR *puiEntryPath;
+} __packed PVRSRV_BRIDGE_IN_DIREADENTRY;
+
+/* Bridge out structure for DIReadEntry */
+typedef struct PVRSRV_BRIDGE_OUT_DIREADENTRY_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DIREADENTRY;
+
+/*******************************************
+ DIWriteEntry
+ *******************************************/
+
+/* Bridge in structure for DIWriteEntry */
+typedef struct PVRSRV_BRIDGE_IN_DIWRITEENTRY_TAG
+{
+ IMG_HANDLE hContext;
+ const IMG_CHAR *puiEntryPath;
+ const IMG_CHAR *puiValue;
+ IMG_UINT32 ui32ValueSize;
+} __packed PVRSRV_BRIDGE_IN_DIWRITEENTRY;
+
+/* Bridge out structure for DIWriteEntry */
+typedef struct PVRSRV_BRIDGE_OUT_DIWRITEENTRY_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DIWRITEENTRY;
+
+/*******************************************
+ DIListAllEntries
+ *******************************************/
+
+/* Bridge in structure for DIListAllEntries */
+typedef struct PVRSRV_BRIDGE_IN_DILISTALLENTRIES_TAG
+{
+ IMG_HANDLE hContext;
+} __packed PVRSRV_BRIDGE_IN_DILISTALLENTRIES;
+
+/* Bridge out structure for DIListAllEntries */
+typedef struct PVRSRV_BRIDGE_OUT_DILISTALLENTRIES_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DILISTALLENTRIES;
+
+#endif /* COMMON_DI_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_dmabuf_bridge.h b/drivers/gpu/drm/img-rogue/common_dmabuf_bridge.h
new file mode 100644
index 000000000..2a1456c05
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_dmabuf_bridge.h
@@ -0,0 +1,150 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for dmabuf
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for dmabuf
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_DMABUF_BRIDGE_H
+#define COMMON_DMABUF_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "pvrsrv_memallocflags.h"
+
+#define PVRSRV_BRIDGE_DMABUF_CMD_FIRST 0
+#define PVRSRV_BRIDGE_DMABUF_PHYSMEMIMPORTDMABUF PVRSRV_BRIDGE_DMABUF_CMD_FIRST+0
+#define PVRSRV_BRIDGE_DMABUF_PHYSMEMEXPORTDMABUF PVRSRV_BRIDGE_DMABUF_CMD_FIRST+1
+#define PVRSRV_BRIDGE_DMABUF_PHYSMEMIMPORTSPARSEDMABUF PVRSRV_BRIDGE_DMABUF_CMD_FIRST+2
+#define PVRSRV_BRIDGE_DMABUF_PHYSMEMIMPORTDMABUFLOCKED PVRSRV_BRIDGE_DMABUF_CMD_FIRST+3
+#define PVRSRV_BRIDGE_DMABUF_CMD_LAST (PVRSRV_BRIDGE_DMABUF_CMD_FIRST+3)
+
+/*******************************************
+ PhysmemImportDmaBuf
+ *******************************************/
+
+/* Bridge in structure for PhysmemImportDmaBuf */
+typedef struct PVRSRV_BRIDGE_IN_PHYSMEMIMPORTDMABUF_TAG
+{
+ const IMG_CHAR *puiName;
+ IMG_INT ifd;
+ IMG_UINT32 ui32NameSize;
+ PVRSRV_MEMALLOCFLAGS_T uiFlags;
+} __packed PVRSRV_BRIDGE_IN_PHYSMEMIMPORTDMABUF;
+
+/* Bridge out structure for PhysmemImportDmaBuf */
+typedef struct PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTDMABUF_TAG
+{
+ IMG_DEVMEM_ALIGN_T uiAlign;
+ IMG_DEVMEM_SIZE_T uiSize;
+ IMG_HANDLE hPMRPtr;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTDMABUF;
+
+/*******************************************
+ PhysmemExportDmaBuf
+ *******************************************/
+
+/* Bridge in structure for PhysmemExportDmaBuf */
+typedef struct PVRSRV_BRIDGE_IN_PHYSMEMEXPORTDMABUF_TAG
+{
+ IMG_HANDLE hPMR;
+} __packed PVRSRV_BRIDGE_IN_PHYSMEMEXPORTDMABUF;
+
+/* Bridge out structure for PhysmemExportDmaBuf */
+typedef struct PVRSRV_BRIDGE_OUT_PHYSMEMEXPORTDMABUF_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_INT iFd;
+} __packed PVRSRV_BRIDGE_OUT_PHYSMEMEXPORTDMABUF;
+
+/*******************************************
+ PhysmemImportSparseDmaBuf
+ *******************************************/
+
+/* Bridge in structure for PhysmemImportSparseDmaBuf */
+typedef struct PVRSRV_BRIDGE_IN_PHYSMEMIMPORTSPARSEDMABUF_TAG
+{
+ IMG_DEVMEM_SIZE_T uiChunkSize;
+ IMG_UINT32 *pui32MappingTable;
+ const IMG_CHAR *puiName;
+ IMG_INT ifd;
+ IMG_UINT32 ui32NameSize;
+ IMG_UINT32 ui32NumPhysChunks;
+ IMG_UINT32 ui32NumVirtChunks;
+ PVRSRV_MEMALLOCFLAGS_T uiFlags;
+} __packed PVRSRV_BRIDGE_IN_PHYSMEMIMPORTSPARSEDMABUF;
+
+/* Bridge out structure for PhysmemImportSparseDmaBuf */
+typedef struct PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTSPARSEDMABUF_TAG
+{
+ IMG_DEVMEM_ALIGN_T uiAlign;
+ IMG_DEVMEM_SIZE_T uiSize;
+ IMG_HANDLE hPMRPtr;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTSPARSEDMABUF;
+
+/*******************************************
+ PhysmemImportDmaBufLocked
+ *******************************************/
+
+/* Bridge in structure for PhysmemImportDmaBufLocked */
+typedef struct PVRSRV_BRIDGE_IN_PHYSMEMIMPORTDMABUFLOCKED_TAG
+{
+ const IMG_CHAR *puiName;
+ IMG_INT ifd;
+ IMG_UINT32 ui32NameSize;
+ PVRSRV_MEMALLOCFLAGS_T uiFlags;
+} __packed PVRSRV_BRIDGE_IN_PHYSMEMIMPORTDMABUFLOCKED;
+
+/* Bridge out structure for PhysmemImportDmaBufLocked */
+typedef struct PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTDMABUFLOCKED_TAG
+{
+ IMG_DEVMEM_ALIGN_T uiAlign;
+ IMG_DEVMEM_SIZE_T uiSize;
+ IMG_HANDLE hPMRPtr;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_PHYSMEMIMPORTDMABUFLOCKED;
+
+#endif /* COMMON_DMABUF_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_htbuffer_bridge.h b/drivers/gpu/drm/img-rogue/common_htbuffer_bridge.h
new file mode 100644
index 000000000..69a406b25
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_htbuffer_bridge.h
@@ -0,0 +1,104 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for htbuffer
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for htbuffer
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_HTBUFFER_BRIDGE_H
+#define COMMON_HTBUFFER_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "devicemem_typedefs.h"
+#include "htbuffer_types.h"
+
+#define PVRSRV_BRIDGE_HTBUFFER_CMD_FIRST 0
+#define PVRSRV_BRIDGE_HTBUFFER_HTBCONTROL PVRSRV_BRIDGE_HTBUFFER_CMD_FIRST+0
+#define PVRSRV_BRIDGE_HTBUFFER_HTBLOG PVRSRV_BRIDGE_HTBUFFER_CMD_FIRST+1
+#define PVRSRV_BRIDGE_HTBUFFER_CMD_LAST (PVRSRV_BRIDGE_HTBUFFER_CMD_FIRST+1)
+
+/*******************************************
+ HTBControl
+ *******************************************/
+
+/* Bridge in structure for HTBControl */
+typedef struct PVRSRV_BRIDGE_IN_HTBCONTROL_TAG
+{
+ IMG_UINT32 *pui32GroupEnable;
+ IMG_UINT32 ui32EnablePID;
+ IMG_UINT32 ui32LogLevel;
+ IMG_UINT32 ui32LogMode;
+ IMG_UINT32 ui32NumGroups;
+ IMG_UINT32 ui32OpMode;
+} __packed PVRSRV_BRIDGE_IN_HTBCONTROL;
+
+/* Bridge out structure for HTBControl */
+typedef struct PVRSRV_BRIDGE_OUT_HTBCONTROL_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_HTBCONTROL;
+
+/*******************************************
+ HTBLog
+ *******************************************/
+
+/* Bridge in structure for HTBLog */
+typedef struct PVRSRV_BRIDGE_IN_HTBLOG_TAG
+{
+ IMG_UINT64 ui64TimeStamp;
+ IMG_UINT32 *pui32Args;
+ IMG_UINT32 ui32NumArgs;
+ IMG_UINT32 ui32PID;
+ IMG_UINT32 ui32SF;
+ IMG_UINT32 ui32TID;
+} __packed PVRSRV_BRIDGE_IN_HTBLOG;
+
+/* Bridge out structure for HTBLog */
+typedef struct PVRSRV_BRIDGE_OUT_HTBLOG_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_HTBLOG;
+
+#endif /* COMMON_HTBUFFER_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_mm_bridge.h b/drivers/gpu/drm/img-rogue/common_mm_bridge.h
new file mode 100644
index 000000000..21a893c0a
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_mm_bridge.h
@@ -0,0 +1,840 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for mm
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for mm
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_MM_BRIDGE_H
+#define COMMON_MM_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "pvrsrv_memallocflags.h"
+#include "pvrsrv_memalloc_physheap.h"
+#include "devicemem_typedefs.h"
+
+#define PVRSRV_BRIDGE_MM_CMD_FIRST 0
+#define PVRSRV_BRIDGE_MM_PMREXPORTPMR PVRSRV_BRIDGE_MM_CMD_FIRST+0
+#define PVRSRV_BRIDGE_MM_PMRUNEXPORTPMR PVRSRV_BRIDGE_MM_CMD_FIRST+1
+#define PVRSRV_BRIDGE_MM_PMRGETUID PVRSRV_BRIDGE_MM_CMD_FIRST+2
+#define PVRSRV_BRIDGE_MM_PMRMAKELOCALIMPORTHANDLE PVRSRV_BRIDGE_MM_CMD_FIRST+3
+#define PVRSRV_BRIDGE_MM_PMRUNMAKELOCALIMPORTHANDLE PVRSRV_BRIDGE_MM_CMD_FIRST+4
+#define PVRSRV_BRIDGE_MM_PMRIMPORTPMR PVRSRV_BRIDGE_MM_CMD_FIRST+5
+#define PVRSRV_BRIDGE_MM_PMRLOCALIMPORTPMR PVRSRV_BRIDGE_MM_CMD_FIRST+6
+#define PVRSRV_BRIDGE_MM_PMRUNREFPMR PVRSRV_BRIDGE_MM_CMD_FIRST+7
+#define PVRSRV_BRIDGE_MM_PMRUNREFUNLOCKPMR PVRSRV_BRIDGE_MM_CMD_FIRST+8
+#define PVRSRV_BRIDGE_MM_PHYSMEMNEWRAMBACKEDPMR PVRSRV_BRIDGE_MM_CMD_FIRST+9
+#define PVRSRV_BRIDGE_MM_PHYSMEMNEWRAMBACKEDLOCKEDPMR PVRSRV_BRIDGE_MM_CMD_FIRST+10
+#define PVRSRV_BRIDGE_MM_DEVMEMINTPIN PVRSRV_BRIDGE_MM_CMD_FIRST+11
+#define PVRSRV_BRIDGE_MM_DEVMEMINTUNPIN PVRSRV_BRIDGE_MM_CMD_FIRST+12
+#define PVRSRV_BRIDGE_MM_DEVMEMINTPINVALIDATE PVRSRV_BRIDGE_MM_CMD_FIRST+13
+#define PVRSRV_BRIDGE_MM_DEVMEMINTUNPININVALIDATE PVRSRV_BRIDGE_MM_CMD_FIRST+14
+#define PVRSRV_BRIDGE_MM_DEVMEMINTCTXCREATE PVRSRV_BRIDGE_MM_CMD_FIRST+15
+#define PVRSRV_BRIDGE_MM_DEVMEMINTCTXDESTROY PVRSRV_BRIDGE_MM_CMD_FIRST+16
+#define PVRSRV_BRIDGE_MM_DEVMEMINTHEAPCREATE PVRSRV_BRIDGE_MM_CMD_FIRST+17
+#define PVRSRV_BRIDGE_MM_DEVMEMINTHEAPDESTROY PVRSRV_BRIDGE_MM_CMD_FIRST+18
+#define PVRSRV_BRIDGE_MM_DEVMEMINTMAPPMR PVRSRV_BRIDGE_MM_CMD_FIRST+19
+#define PVRSRV_BRIDGE_MM_DEVMEMINTUNMAPPMR PVRSRV_BRIDGE_MM_CMD_FIRST+20
+#define PVRSRV_BRIDGE_MM_DEVMEMINTRESERVERANGE PVRSRV_BRIDGE_MM_CMD_FIRST+21
+#define PVRSRV_BRIDGE_MM_DEVMEMINTUNRESERVERANGE PVRSRV_BRIDGE_MM_CMD_FIRST+22
+#define PVRSRV_BRIDGE_MM_CHANGESPARSEMEM PVRSRV_BRIDGE_MM_CMD_FIRST+23
+#define PVRSRV_BRIDGE_MM_DEVMEMINTMAPPAGES PVRSRV_BRIDGE_MM_CMD_FIRST+24
+#define PVRSRV_BRIDGE_MM_DEVMEMINTUNMAPPAGES PVRSRV_BRIDGE_MM_CMD_FIRST+25
+#define PVRSRV_BRIDGE_MM_DEVMEMISVDEVADDRVALID PVRSRV_BRIDGE_MM_CMD_FIRST+26
+#define PVRSRV_BRIDGE_MM_DEVMEMFLUSHDEVSLCRANGE PVRSRV_BRIDGE_MM_CMD_FIRST+27
+#define PVRSRV_BRIDGE_MM_DEVMEMINVALIDATEFBSCTABLE PVRSRV_BRIDGE_MM_CMD_FIRST+28
+#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPCONFIGCOUNT PVRSRV_BRIDGE_MM_CMD_FIRST+29
+#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPCOUNT PVRSRV_BRIDGE_MM_CMD_FIRST+30
+#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPCONFIGNAME PVRSRV_BRIDGE_MM_CMD_FIRST+31
+#define PVRSRV_BRIDGE_MM_HEAPCFGHEAPDETAILS PVRSRV_BRIDGE_MM_CMD_FIRST+32
+#define PVRSRV_BRIDGE_MM_DEVMEMINTREGISTERPFNOTIFYKM PVRSRV_BRIDGE_MM_CMD_FIRST+33
+#define PVRSRV_BRIDGE_MM_GETMAXPHYSHEAPCOUNT PVRSRV_BRIDGE_MM_CMD_FIRST+34
+#define PVRSRV_BRIDGE_MM_PHYSHEAPGETMEMINFO PVRSRV_BRIDGE_MM_CMD_FIRST+35
+#define PVRSRV_BRIDGE_MM_GETDEFAULTPHYSICALHEAP PVRSRV_BRIDGE_MM_CMD_FIRST+36
+#define PVRSRV_BRIDGE_MM_GETHEAPPHYSMEMUSAGE PVRSRV_BRIDGE_MM_CMD_FIRST+37
+#define PVRSRV_BRIDGE_MM_DEVMEMGETFAULTADDRESS PVRSRV_BRIDGE_MM_CMD_FIRST+38
+#define PVRSRV_BRIDGE_MM_PVRSRVUPDATEOOMSTATS PVRSRV_BRIDGE_MM_CMD_FIRST+39
+#define PVRSRV_BRIDGE_MM_CMD_LAST (PVRSRV_BRIDGE_MM_CMD_FIRST+39)
+
+/*******************************************
+ PMRExportPMR
+ *******************************************/
+
+/* Bridge in structure for PMRExportPMR */
+typedef struct PVRSRV_BRIDGE_IN_PMREXPORTPMR_TAG
+{
+ IMG_HANDLE hPMR;
+} __packed PVRSRV_BRIDGE_IN_PMREXPORTPMR;
+
+/* Bridge out structure for PMRExportPMR */
+typedef struct PVRSRV_BRIDGE_OUT_PMREXPORTPMR_TAG
+{
+ IMG_UINT64 ui64Password;
+ IMG_UINT64 ui64Size;
+ IMG_HANDLE hPMRExport;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32Log2Contig;
+} __packed PVRSRV_BRIDGE_OUT_PMREXPORTPMR;
+
+/*******************************************
+ PMRUnexportPMR
+ *******************************************/
+
+/* Bridge in structure for PMRUnexportPMR */
+typedef struct PVRSRV_BRIDGE_IN_PMRUNEXPORTPMR_TAG
+{
+ IMG_HANDLE hPMRExport;
+} __packed PVRSRV_BRIDGE_IN_PMRUNEXPORTPMR;
+
+/* Bridge out structure for PMRUnexportPMR */
+typedef struct PVRSRV_BRIDGE_OUT_PMRUNEXPORTPMR_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_PMRUNEXPORTPMR;
+
+/*******************************************
+ PMRGetUID
+ *******************************************/
+
+/* Bridge in structure for PMRGetUID */
+typedef struct PVRSRV_BRIDGE_IN_PMRGETUID_TAG
+{
+ IMG_HANDLE hPMR;
+} __packed PVRSRV_BRIDGE_IN_PMRGETUID;
+
+/* Bridge out structure for PMRGetUID */
+typedef struct PVRSRV_BRIDGE_OUT_PMRGETUID_TAG
+{
+ IMG_UINT64 ui64UID;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_PMRGETUID;
+
+/*******************************************
+ PMRMakeLocalImportHandle
+ *******************************************/
+
+/* Bridge in structure for PMRMakeLocalImportHandle */
+typedef struct PVRSRV_BRIDGE_IN_PMRMAKELOCALIMPORTHANDLE_TAG
+{
+ IMG_HANDLE hBuffer;
+} __packed PVRSRV_BRIDGE_IN_PMRMAKELOCALIMPORTHANDLE;
+
+/* Bridge out structure for PMRMakeLocalImportHandle */
+typedef struct PVRSRV_BRIDGE_OUT_PMRMAKELOCALIMPORTHANDLE_TAG
+{
+ IMG_HANDLE hExtMem;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_PMRMAKELOCALIMPORTHANDLE;
+
+/*******************************************
+ PMRUnmakeLocalImportHandle
+ *******************************************/
+
+/* Bridge in structure for PMRUnmakeLocalImportHandle */
+typedef struct PVRSRV_BRIDGE_IN_PMRUNMAKELOCALIMPORTHANDLE_TAG
+{
+ IMG_HANDLE hExtMem;
+} __packed PVRSRV_BRIDGE_IN_PMRUNMAKELOCALIMPORTHANDLE;
+
+/* Bridge out structure for PMRUnmakeLocalImportHandle */
+typedef struct PVRSRV_BRIDGE_OUT_PMRUNMAKELOCALIMPORTHANDLE_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_PMRUNMAKELOCALIMPORTHANDLE;
+
+/*******************************************
+ PMRImportPMR
+ *******************************************/
+
+/* Bridge in structure for PMRImportPMR */
+typedef struct PVRSRV_BRIDGE_IN_PMRIMPORTPMR_TAG
+{
+ IMG_UINT64 ui64uiPassword;
+ IMG_UINT64 ui64uiSize;
+ IMG_HANDLE hPMRExport;
+ IMG_UINT32 ui32uiLog2Contig;
+} __packed PVRSRV_BRIDGE_IN_PMRIMPORTPMR;
+
+/* Bridge out structure for PMRImportPMR */
+typedef struct PVRSRV_BRIDGE_OUT_PMRIMPORTPMR_TAG
+{
+ IMG_HANDLE hPMR;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_PMRIMPORTPMR;
+
+/*******************************************
+ PMRLocalImportPMR
+ *******************************************/
+
+/* Bridge in structure for PMRLocalImportPMR */
+typedef struct PVRSRV_BRIDGE_IN_PMRLOCALIMPORTPMR_TAG
+{
+ IMG_HANDLE hExtHandle;
+} __packed PVRSRV_BRIDGE_IN_PMRLOCALIMPORTPMR;
+
+/* Bridge out structure for PMRLocalImportPMR */
+typedef struct PVRSRV_BRIDGE_OUT_PMRLOCALIMPORTPMR_TAG
+{
+ IMG_DEVMEM_ALIGN_T uiAlign;
+ IMG_DEVMEM_SIZE_T uiSize;
+ IMG_HANDLE hPMR;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_PMRLOCALIMPORTPMR;
+
+/*******************************************
+ PMRUnrefPMR
+ *******************************************/
+
+/* Bridge in structure for PMRUnrefPMR */
+typedef struct PVRSRV_BRIDGE_IN_PMRUNREFPMR_TAG
+{
+ IMG_HANDLE hPMR;
+} __packed PVRSRV_BRIDGE_IN_PMRUNREFPMR;
+
+/* Bridge out structure for PMRUnrefPMR */
+typedef struct PVRSRV_BRIDGE_OUT_PMRUNREFPMR_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_PMRUNREFPMR;
+
+/*******************************************
+ PMRUnrefUnlockPMR
+ *******************************************/
+
+/* Bridge in structure for PMRUnrefUnlockPMR */
+typedef struct PVRSRV_BRIDGE_IN_PMRUNREFUNLOCKPMR_TAG
+{
+ IMG_HANDLE hPMR;
+} __packed PVRSRV_BRIDGE_IN_PMRUNREFUNLOCKPMR;
+
+/* Bridge out structure for PMRUnrefUnlockPMR */
+typedef struct PVRSRV_BRIDGE_OUT_PMRUNREFUNLOCKPMR_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_PMRUNREFUNLOCKPMR;
+
+/*******************************************
+ PhysmemNewRamBackedPMR
+ *******************************************/
+
+/* Bridge in structure for PhysmemNewRamBackedPMR */
+typedef struct PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDPMR_TAG
+{
+ IMG_DEVMEM_SIZE_T uiChunkSize;
+ IMG_DEVMEM_SIZE_T uiSize;
+ IMG_UINT32 *pui32MappingTable;
+ const IMG_CHAR *puiAnnotation;
+ IMG_UINT32 ui32AnnotationLength;
+ IMG_UINT32 ui32Log2PageSize;
+ IMG_UINT32 ui32NumPhysChunks;
+ IMG_UINT32 ui32NumVirtChunks;
+ IMG_UINT32 ui32PDumpFlags;
+ IMG_PID ui32PID;
+ PVRSRV_MEMALLOCFLAGS_T uiFlags;
+} __packed PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDPMR;
+
+/* Bridge out structure for PhysmemNewRamBackedPMR */
+typedef struct PVRSRV_BRIDGE_OUT_PHYSMEMNEWRAMBACKEDPMR_TAG
+{
+ IMG_HANDLE hPMRPtr;
+ PVRSRV_ERROR eError;
+ PVRSRV_MEMALLOCFLAGS_T uiOutFlags;
+} __packed PVRSRV_BRIDGE_OUT_PHYSMEMNEWRAMBACKEDPMR;
+
+/*******************************************
+ PhysmemNewRamBackedLockedPMR
+ *******************************************/
+
+/* Bridge in structure for PhysmemNewRamBackedLockedPMR */
+typedef struct PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDLOCKEDPMR_TAG
+{
+ IMG_DEVMEM_SIZE_T uiChunkSize;
+ IMG_DEVMEM_SIZE_T uiSize;
+ IMG_UINT32 *pui32MappingTable;
+ const IMG_CHAR *puiAnnotation;
+ IMG_UINT32 ui32AnnotationLength;
+ IMG_UINT32 ui32Log2PageSize;
+ IMG_UINT32 ui32NumPhysChunks;
+ IMG_UINT32 ui32NumVirtChunks;
+ IMG_UINT32 ui32PDumpFlags;
+ IMG_PID ui32PID;
+ PVRSRV_MEMALLOCFLAGS_T uiFlags;
+} __packed PVRSRV_BRIDGE_IN_PHYSMEMNEWRAMBACKEDLOCKEDPMR;
+
+/* Bridge out structure for PhysmemNewRamBackedLockedPMR */
+typedef struct PVRSRV_BRIDGE_OUT_PHYSMEMNEWRAMBACKEDLOCKEDPMR_TAG
+{
+ IMG_HANDLE hPMRPtr;
+ PVRSRV_ERROR eError;
+ PVRSRV_MEMALLOCFLAGS_T uiOutFlags;
+} __packed PVRSRV_BRIDGE_OUT_PHYSMEMNEWRAMBACKEDLOCKEDPMR;
+
+/*******************************************
+ DevmemIntPin
+ *******************************************/
+
+/* Bridge in structure for DevmemIntPin */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTPIN_TAG
+{
+ IMG_HANDLE hPMR;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMINTPIN;
+
+/* Bridge out structure for DevmemIntPin */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTPIN_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTPIN;
+
+/*******************************************
+ DevmemIntUnpin
+ *******************************************/
+
+/* Bridge in structure for DevmemIntUnpin */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTUNPIN_TAG
+{
+ IMG_HANDLE hPMR;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMINTUNPIN;
+
+/* Bridge out structure for DevmemIntUnpin */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTUNPIN_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTUNPIN;
+
+/*******************************************
+ DevmemIntPinValidate
+ *******************************************/
+
+/* Bridge in structure for DevmemIntPinValidate */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTPINVALIDATE_TAG
+{
+ IMG_HANDLE hMapping;
+ IMG_HANDLE hPMR;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMINTPINVALIDATE;
+
+/* Bridge out structure for DevmemIntPinValidate */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTPINVALIDATE_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTPINVALIDATE;
+
+/*******************************************
+ DevmemIntUnpinInvalidate
+ *******************************************/
+
+/* Bridge in structure for DevmemIntUnpinInvalidate */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTUNPININVALIDATE_TAG
+{
+ IMG_HANDLE hMapping;
+ IMG_HANDLE hPMR;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMINTUNPININVALIDATE;
+
+/* Bridge out structure for DevmemIntUnpinInvalidate */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTUNPININVALIDATE_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTUNPININVALIDATE;
+
+/*******************************************
+ DevmemIntCtxCreate
+ *******************************************/
+
+/* Bridge in structure for DevmemIntCtxCreate */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTCTXCREATE_TAG
+{
+ IMG_BOOL bbKernelMemoryCtx;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMINTCTXCREATE;
+
+/* Bridge out structure for DevmemIntCtxCreate */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTCTXCREATE_TAG
+{
+ IMG_HANDLE hDevMemServerContext;
+ IMG_HANDLE hPrivData;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32CPUCacheLineSize;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTCTXCREATE;
+
+/*******************************************
+ DevmemIntCtxDestroy
+ *******************************************/
+
+/* Bridge in structure for DevmemIntCtxDestroy */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTCTXDESTROY_TAG
+{
+ IMG_HANDLE hDevmemServerContext;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMINTCTXDESTROY;
+
+/* Bridge out structure for DevmemIntCtxDestroy */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTCTXDESTROY_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTCTXDESTROY;
+
+/*******************************************
+ DevmemIntHeapCreate
+ *******************************************/
+
+/* Bridge in structure for DevmemIntHeapCreate */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTHEAPCREATE_TAG
+{
+ IMG_DEV_VIRTADDR sHeapBaseAddr;
+ IMG_DEVMEM_SIZE_T uiHeapLength;
+ IMG_HANDLE hDevmemCtx;
+ IMG_UINT32 ui32Log2DataPageSize;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMINTHEAPCREATE;
+
+/* Bridge out structure for DevmemIntHeapCreate */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPCREATE_TAG
+{
+ IMG_HANDLE hDevmemHeapPtr;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPCREATE;
+
+/*******************************************
+ DevmemIntHeapDestroy
+ *******************************************/
+
+/* Bridge in structure for DevmemIntHeapDestroy */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTHEAPDESTROY_TAG
+{
+ IMG_HANDLE hDevmemHeap;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMINTHEAPDESTROY;
+
+/* Bridge out structure for DevmemIntHeapDestroy */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPDESTROY_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTHEAPDESTROY;
+
+/*******************************************
+ DevmemIntMapPMR
+ *******************************************/
+
+/* Bridge in structure for DevmemIntMapPMR */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTMAPPMR_TAG
+{
+ IMG_HANDLE hDevmemServerHeap;
+ IMG_HANDLE hPMR;
+ IMG_HANDLE hReservation;
+ PVRSRV_MEMALLOCFLAGS_T uiMapFlags;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMINTMAPPMR;
+
+/* Bridge out structure for DevmemIntMapPMR */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPMR_TAG
+{
+ IMG_HANDLE hMapping;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPMR;
+
+/*******************************************
+ DevmemIntUnmapPMR
+ *******************************************/
+
+/* Bridge in structure for DevmemIntUnmapPMR */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPMR_TAG
+{
+ IMG_HANDLE hMapping;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPMR;
+
+/* Bridge out structure for DevmemIntUnmapPMR */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPMR_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPMR;
+
+/*******************************************
+ DevmemIntReserveRange
+ *******************************************/
+
+/* Bridge in structure for DevmemIntReserveRange */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTRESERVERANGE_TAG
+{
+ IMG_DEV_VIRTADDR sAddress;
+ IMG_DEVMEM_SIZE_T uiLength;
+ IMG_HANDLE hDevmemServerHeap;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMINTRESERVERANGE;
+
+/* Bridge out structure for DevmemIntReserveRange */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTRESERVERANGE_TAG
+{
+ IMG_HANDLE hReservation;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTRESERVERANGE;
+
+/*******************************************
+ DevmemIntUnreserveRange
+ *******************************************/
+
+/* Bridge in structure for DevmemIntUnreserveRange */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTUNRESERVERANGE_TAG
+{
+ IMG_HANDLE hReservation;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMINTUNRESERVERANGE;
+
+/* Bridge out structure for DevmemIntUnreserveRange */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTUNRESERVERANGE_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTUNRESERVERANGE;
+
+/*******************************************
+ ChangeSparseMem
+ *******************************************/
+
+/* Bridge in structure for ChangeSparseMem */
+typedef struct PVRSRV_BRIDGE_IN_CHANGESPARSEMEM_TAG
+{
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_UINT64 ui64CPUVAddr;
+ IMG_HANDLE hPMR;
+ IMG_HANDLE hSrvDevMemHeap;
+ IMG_UINT32 *pui32AllocPageIndices;
+ IMG_UINT32 *pui32FreePageIndices;
+ IMG_UINT32 ui32AllocPageCount;
+ IMG_UINT32 ui32FreePageCount;
+ IMG_UINT32 ui32SparseFlags;
+ PVRSRV_MEMALLOCFLAGS_T uiFlags;
+} __packed PVRSRV_BRIDGE_IN_CHANGESPARSEMEM;
+
+/* Bridge out structure for ChangeSparseMem */
+typedef struct PVRSRV_BRIDGE_OUT_CHANGESPARSEMEM_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_CHANGESPARSEMEM;
+
+/*******************************************
+ DevmemIntMapPages
+ *******************************************/
+
+/* Bridge in structure for DevmemIntMapPages */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTMAPPAGES_TAG
+{
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_HANDLE hPMR;
+ IMG_HANDLE hReservation;
+ IMG_UINT32 ui32PageCount;
+ IMG_UINT32 ui32PhysicalPgOffset;
+ PVRSRV_MEMALLOCFLAGS_T uiFlags;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMINTMAPPAGES;
+
+/* Bridge out structure for DevmemIntMapPages */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPAGES_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTMAPPAGES;
+
+/*******************************************
+ DevmemIntUnmapPages
+ *******************************************/
+
+/* Bridge in structure for DevmemIntUnmapPages */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPAGES_TAG
+{
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_HANDLE hReservation;
+ IMG_UINT32 ui32PageCount;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMINTUNMAPPAGES;
+
+/* Bridge out structure for DevmemIntUnmapPages */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPAGES_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTUNMAPPAGES;
+
+/*******************************************
+ DevmemIsVDevAddrValid
+ *******************************************/
+
+/* Bridge in structure for DevmemIsVDevAddrValid */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMISVDEVADDRVALID_TAG
+{
+ IMG_DEV_VIRTADDR sAddress;
+ IMG_HANDLE hDevmemCtx;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMISVDEVADDRVALID;
+
+/* Bridge out structure for DevmemIsVDevAddrValid */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMISVDEVADDRVALID_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMISVDEVADDRVALID;
+
+/*******************************************
+ DevmemFlushDevSLCRange
+ *******************************************/
+
+/* Bridge in structure for DevmemFlushDevSLCRange */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMFLUSHDEVSLCRANGE_TAG
+{
+ IMG_DEV_VIRTADDR sAddress;
+ IMG_DEVMEM_SIZE_T uiSize;
+ IMG_HANDLE hDevmemCtx;
+ IMG_BOOL bInvalidate;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMFLUSHDEVSLCRANGE;
+
+/* Bridge out structure for DevmemFlushDevSLCRange */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMFLUSHDEVSLCRANGE_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMFLUSHDEVSLCRANGE;
+
+/*******************************************
+ DevmemInvalidateFBSCTable
+ *******************************************/
+
+/* Bridge in structure for DevmemInvalidateFBSCTable */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINVALIDATEFBSCTABLE_TAG
+{
+ IMG_UINT64 ui64FBSCEntries;
+ IMG_HANDLE hDevmemCtx;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMINVALIDATEFBSCTABLE;
+
+/* Bridge out structure for DevmemInvalidateFBSCTable */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINVALIDATEFBSCTABLE_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMINVALIDATEFBSCTABLE;
+
+/*******************************************
+ HeapCfgHeapConfigCount
+ *******************************************/
+
+/* Bridge in structure for HeapCfgHeapConfigCount */
+typedef struct PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGCOUNT_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGCOUNT;
+
+/* Bridge out structure for HeapCfgHeapConfigCount */
+typedef struct PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGCOUNT_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32NumHeapConfigs;
+} __packed PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGCOUNT;
+
+/*******************************************
+ HeapCfgHeapCount
+ *******************************************/
+
+/* Bridge in structure for HeapCfgHeapCount */
+typedef struct PVRSRV_BRIDGE_IN_HEAPCFGHEAPCOUNT_TAG
+{
+ IMG_UINT32 ui32HeapConfigIndex;
+} __packed PVRSRV_BRIDGE_IN_HEAPCFGHEAPCOUNT;
+
+/* Bridge out structure for HeapCfgHeapCount */
+typedef struct PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCOUNT_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32NumHeaps;
+} __packed PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCOUNT;
+
+/*******************************************
+ HeapCfgHeapConfigName
+ *******************************************/
+
+/* Bridge in structure for HeapCfgHeapConfigName */
+typedef struct PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGNAME_TAG
+{
+ IMG_CHAR *puiHeapConfigName;
+ IMG_UINT32 ui32HeapConfigIndex;
+ IMG_UINT32 ui32HeapConfigNameBufSz;
+} __packed PVRSRV_BRIDGE_IN_HEAPCFGHEAPCONFIGNAME;
+
+/* Bridge out structure for HeapCfgHeapConfigName */
+typedef struct PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGNAME_TAG
+{
+ IMG_CHAR *puiHeapConfigName;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_HEAPCFGHEAPCONFIGNAME;
+
+/*******************************************
+ HeapCfgHeapDetails
+ *******************************************/
+
+/* Bridge in structure for HeapCfgHeapDetails */
+typedef struct PVRSRV_BRIDGE_IN_HEAPCFGHEAPDETAILS_TAG
+{
+ IMG_CHAR *puiHeapNameOut;
+ IMG_UINT32 ui32HeapConfigIndex;
+ IMG_UINT32 ui32HeapIndex;
+ IMG_UINT32 ui32HeapNameBufSz;
+} __packed PVRSRV_BRIDGE_IN_HEAPCFGHEAPDETAILS;
+
+/* Bridge out structure for HeapCfgHeapDetails */
+typedef struct PVRSRV_BRIDGE_OUT_HEAPCFGHEAPDETAILS_TAG
+{
+ IMG_DEV_VIRTADDR sDevVAddrBase;
+ IMG_DEVMEM_SIZE_T uiHeapLength;
+ IMG_DEVMEM_SIZE_T uiReservedRegionLength;
+ IMG_CHAR *puiHeapNameOut;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32Log2DataPageSizeOut;
+ IMG_UINT32 ui32Log2ImportAlignmentOut;
+} __packed PVRSRV_BRIDGE_OUT_HEAPCFGHEAPDETAILS;
+
+/*******************************************
+ DevmemIntRegisterPFNotifyKM
+ *******************************************/
+
+/* Bridge in structure for DevmemIntRegisterPFNotifyKM */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMINTREGISTERPFNOTIFYKM_TAG
+{
+ IMG_HANDLE hDevm;
+ IMG_BOOL bRegister;
+ IMG_UINT32 ui32PID;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMINTREGISTERPFNOTIFYKM;
+
+/* Bridge out structure for DevmemIntRegisterPFNotifyKM */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMINTREGISTERPFNOTIFYKM_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMINTREGISTERPFNOTIFYKM;
+
+/*******************************************
+ GetMaxPhysHeapCount
+ *******************************************/
+
+/* Bridge in structure for GetMaxPhysHeapCount */
+typedef struct PVRSRV_BRIDGE_IN_GETMAXPHYSHEAPCOUNT_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_GETMAXPHYSHEAPCOUNT;
+
+/* Bridge out structure for GetMaxPhysHeapCount */
+typedef struct PVRSRV_BRIDGE_OUT_GETMAXPHYSHEAPCOUNT_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32PhysHeapCount;
+} __packed PVRSRV_BRIDGE_OUT_GETMAXPHYSHEAPCOUNT;
+
+/*******************************************
+ PhysHeapGetMemInfo
+ *******************************************/
+
+/* Bridge in structure for PhysHeapGetMemInfo */
+typedef struct PVRSRV_BRIDGE_IN_PHYSHEAPGETMEMINFO_TAG
+{
+ PHYS_HEAP_MEM_STATS *pasapPhysHeapMemStats;
+ PVRSRV_PHYS_HEAP *peaPhysHeapID;
+ IMG_UINT32 ui32PhysHeapCount;
+} __packed PVRSRV_BRIDGE_IN_PHYSHEAPGETMEMINFO;
+
+/* Bridge out structure for PhysHeapGetMemInfo */
+typedef struct PVRSRV_BRIDGE_OUT_PHYSHEAPGETMEMINFO_TAG
+{
+ PHYS_HEAP_MEM_STATS *pasapPhysHeapMemStats;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_PHYSHEAPGETMEMINFO;
+
+/*******************************************
+ GetDefaultPhysicalHeap
+ *******************************************/
+
+/* Bridge in structure for GetDefaultPhysicalHeap */
+typedef struct PVRSRV_BRIDGE_IN_GETDEFAULTPHYSICALHEAP_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_GETDEFAULTPHYSICALHEAP;
+
+/* Bridge out structure for GetDefaultPhysicalHeap */
+typedef struct PVRSRV_BRIDGE_OUT_GETDEFAULTPHYSICALHEAP_TAG
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_PHYS_HEAP eHeap;
+} __packed PVRSRV_BRIDGE_OUT_GETDEFAULTPHYSICALHEAP;
+
+/*******************************************
+ GetHeapPhysMemUsage
+ *******************************************/
+
+/* Bridge in structure for GetHeapPhysMemUsage */
+typedef struct PVRSRV_BRIDGE_IN_GETHEAPPHYSMEMUSAGE_TAG
+{
+ PHYS_HEAP_MEM_STATS *pasapPhysHeapMemStats;
+ IMG_UINT32 ui32PhysHeapCount;
+} __packed PVRSRV_BRIDGE_IN_GETHEAPPHYSMEMUSAGE;
+
+/* Bridge out structure for GetHeapPhysMemUsage */
+typedef struct PVRSRV_BRIDGE_OUT_GETHEAPPHYSMEMUSAGE_TAG
+{
+ PHYS_HEAP_MEM_STATS *pasapPhysHeapMemStats;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_GETHEAPPHYSMEMUSAGE;
+
+/*******************************************
+ DevmemGetFaultAddress
+ *******************************************/
+
+/* Bridge in structure for DevmemGetFaultAddress */
+typedef struct PVRSRV_BRIDGE_IN_DEVMEMGETFAULTADDRESS_TAG
+{
+ IMG_HANDLE hDevmemCtx;
+} __packed PVRSRV_BRIDGE_IN_DEVMEMGETFAULTADDRESS;
+
+/* Bridge out structure for DevmemGetFaultAddress */
+typedef struct PVRSRV_BRIDGE_OUT_DEVMEMGETFAULTADDRESS_TAG
+{
+ IMG_DEV_VIRTADDR sFaultAddress;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DEVMEMGETFAULTADDRESS;
+
+/*******************************************
+ PVRSRVUpdateOOMStats
+ *******************************************/
+
+/* Bridge in structure for PVRSRVUpdateOOMStats */
+typedef struct PVRSRV_BRIDGE_IN_PVRSRVUPDATEOOMSTATS_TAG
+{
+ IMG_PID ui32pid;
+ IMG_UINT32 ui32ui32StatType;
+} __packed PVRSRV_BRIDGE_IN_PVRSRVUPDATEOOMSTATS;
+
+/* Bridge out structure for PVRSRVUpdateOOMStats */
+typedef struct PVRSRV_BRIDGE_OUT_PVRSRVUPDATEOOMSTATS_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_PVRSRVUPDATEOOMSTATS;
+
+#endif /* COMMON_MM_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_pvrtl_bridge.h b/drivers/gpu/drm/img-rogue/common_pvrtl_bridge.h
new file mode 100644
index 000000000..edc822375
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_pvrtl_bridge.h
@@ -0,0 +1,214 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for pvrtl
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for pvrtl
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_PVRTL_BRIDGE_H
+#define COMMON_PVRTL_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "devicemem_typedefs.h"
+#include "pvrsrv_tlcommon.h"
+
+#define PVRSRV_BRIDGE_PVRTL_CMD_FIRST 0
+#define PVRSRV_BRIDGE_PVRTL_TLOPENSTREAM PVRSRV_BRIDGE_PVRTL_CMD_FIRST+0
+#define PVRSRV_BRIDGE_PVRTL_TLCLOSESTREAM PVRSRV_BRIDGE_PVRTL_CMD_FIRST+1
+#define PVRSRV_BRIDGE_PVRTL_TLACQUIREDATA PVRSRV_BRIDGE_PVRTL_CMD_FIRST+2
+#define PVRSRV_BRIDGE_PVRTL_TLRELEASEDATA PVRSRV_BRIDGE_PVRTL_CMD_FIRST+3
+#define PVRSRV_BRIDGE_PVRTL_TLDISCOVERSTREAMS PVRSRV_BRIDGE_PVRTL_CMD_FIRST+4
+#define PVRSRV_BRIDGE_PVRTL_TLRESERVESTREAM PVRSRV_BRIDGE_PVRTL_CMD_FIRST+5
+#define PVRSRV_BRIDGE_PVRTL_TLCOMMITSTREAM PVRSRV_BRIDGE_PVRTL_CMD_FIRST+6
+#define PVRSRV_BRIDGE_PVRTL_TLWRITEDATA PVRSRV_BRIDGE_PVRTL_CMD_FIRST+7
+#define PVRSRV_BRIDGE_PVRTL_CMD_LAST (PVRSRV_BRIDGE_PVRTL_CMD_FIRST+7)
+
+/*******************************************
+ TLOpenStream
+ *******************************************/
+
+/* Bridge in structure for TLOpenStream */
+typedef struct PVRSRV_BRIDGE_IN_TLOPENSTREAM_TAG
+{
+ const IMG_CHAR *puiName;
+ IMG_UINT32 ui32Mode;
+} __packed PVRSRV_BRIDGE_IN_TLOPENSTREAM;
+
+/* Bridge out structure for TLOpenStream */
+typedef struct PVRSRV_BRIDGE_OUT_TLOPENSTREAM_TAG
+{
+ IMG_HANDLE hSD;
+ IMG_HANDLE hTLPMR;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_TLOPENSTREAM;
+
+/*******************************************
+ TLCloseStream
+ *******************************************/
+
+/* Bridge in structure for TLCloseStream */
+typedef struct PVRSRV_BRIDGE_IN_TLCLOSESTREAM_TAG
+{
+ IMG_HANDLE hSD;
+} __packed PVRSRV_BRIDGE_IN_TLCLOSESTREAM;
+
+/* Bridge out structure for TLCloseStream */
+typedef struct PVRSRV_BRIDGE_OUT_TLCLOSESTREAM_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_TLCLOSESTREAM;
+
+/*******************************************
+ TLAcquireData
+ *******************************************/
+
+/* Bridge in structure for TLAcquireData */
+typedef struct PVRSRV_BRIDGE_IN_TLACQUIREDATA_TAG
+{
+ IMG_HANDLE hSD;
+} __packed PVRSRV_BRIDGE_IN_TLACQUIREDATA;
+
+/* Bridge out structure for TLAcquireData */
+typedef struct PVRSRV_BRIDGE_OUT_TLACQUIREDATA_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32ReadLen;
+ IMG_UINT32 ui32ReadOffset;
+} __packed PVRSRV_BRIDGE_OUT_TLACQUIREDATA;
+
+/*******************************************
+ TLReleaseData
+ *******************************************/
+
+/* Bridge in structure for TLReleaseData */
+typedef struct PVRSRV_BRIDGE_IN_TLRELEASEDATA_TAG
+{
+ IMG_HANDLE hSD;
+ IMG_UINT32 ui32ReadLen;
+ IMG_UINT32 ui32ReadOffset;
+} __packed PVRSRV_BRIDGE_IN_TLRELEASEDATA;
+
+/* Bridge out structure for TLReleaseData */
+typedef struct PVRSRV_BRIDGE_OUT_TLRELEASEDATA_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_TLRELEASEDATA;
+
+/*******************************************
+ TLDiscoverStreams
+ *******************************************/
+
+/* Bridge in structure for TLDiscoverStreams */
+typedef struct PVRSRV_BRIDGE_IN_TLDISCOVERSTREAMS_TAG
+{
+ const IMG_CHAR *puiNamePattern;
+ IMG_CHAR *puiStreams;
+ IMG_UINT32 ui32Size;
+} __packed PVRSRV_BRIDGE_IN_TLDISCOVERSTREAMS;
+
+/* Bridge out structure for TLDiscoverStreams */
+typedef struct PVRSRV_BRIDGE_OUT_TLDISCOVERSTREAMS_TAG
+{
+ IMG_CHAR *puiStreams;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32NumFound;
+} __packed PVRSRV_BRIDGE_OUT_TLDISCOVERSTREAMS;
+
+/*******************************************
+ TLReserveStream
+ *******************************************/
+
+/* Bridge in structure for TLReserveStream */
+typedef struct PVRSRV_BRIDGE_IN_TLRESERVESTREAM_TAG
+{
+ IMG_HANDLE hSD;
+ IMG_UINT32 ui32Size;
+ IMG_UINT32 ui32SizeMin;
+} __packed PVRSRV_BRIDGE_IN_TLRESERVESTREAM;
+
+/* Bridge out structure for TLReserveStream */
+typedef struct PVRSRV_BRIDGE_OUT_TLRESERVESTREAM_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32Available;
+ IMG_UINT32 ui32BufferOffset;
+} __packed PVRSRV_BRIDGE_OUT_TLRESERVESTREAM;
+
+/*******************************************
+ TLCommitStream
+ *******************************************/
+
+/* Bridge in structure for TLCommitStream */
+typedef struct PVRSRV_BRIDGE_IN_TLCOMMITSTREAM_TAG
+{
+ IMG_HANDLE hSD;
+ IMG_UINT32 ui32ReqSize;
+} __packed PVRSRV_BRIDGE_IN_TLCOMMITSTREAM;
+
+/* Bridge out structure for TLCommitStream */
+typedef struct PVRSRV_BRIDGE_OUT_TLCOMMITSTREAM_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_TLCOMMITSTREAM;
+
+/*******************************************
+ TLWriteData
+ *******************************************/
+
+/* Bridge in structure for TLWriteData */
+typedef struct PVRSRV_BRIDGE_IN_TLWRITEDATA_TAG
+{
+ IMG_HANDLE hSD;
+ IMG_BYTE *pui8Data;
+ IMG_UINT32 ui32Size;
+} __packed PVRSRV_BRIDGE_IN_TLWRITEDATA;
+
+/* Bridge out structure for TLWriteData */
+typedef struct PVRSRV_BRIDGE_OUT_TLWRITEDATA_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_TLWRITEDATA;
+
+#endif /* COMMON_PVRTL_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_rgxbreakpoint_bridge.h b/drivers/gpu/drm/img-rogue/common_rgxbreakpoint_bridge.h
new file mode 100644
index 000000000..7b83d9abc
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_rgxbreakpoint_bridge.h
@@ -0,0 +1,149 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for rgxbreakpoint
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for rgxbreakpoint
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_RGXBREAKPOINT_BRIDGE_H
+#define COMMON_RGXBREAKPOINT_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+
+#define PVRSRV_BRIDGE_RGXBREAKPOINT_CMD_FIRST 0
+#define PVRSRV_BRIDGE_RGXBREAKPOINT_RGXSETBREAKPOINT PVRSRV_BRIDGE_RGXBREAKPOINT_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RGXBREAKPOINT_RGXCLEARBREAKPOINT PVRSRV_BRIDGE_RGXBREAKPOINT_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RGXBREAKPOINT_RGXENABLEBREAKPOINT PVRSRV_BRIDGE_RGXBREAKPOINT_CMD_FIRST+2
+#define PVRSRV_BRIDGE_RGXBREAKPOINT_RGXDISABLEBREAKPOINT PVRSRV_BRIDGE_RGXBREAKPOINT_CMD_FIRST+3
+#define PVRSRV_BRIDGE_RGXBREAKPOINT_RGXOVERALLOCATEBPREGISTERS PVRSRV_BRIDGE_RGXBREAKPOINT_CMD_FIRST+4
+#define PVRSRV_BRIDGE_RGXBREAKPOINT_CMD_LAST (PVRSRV_BRIDGE_RGXBREAKPOINT_CMD_FIRST+4)
+
+/*******************************************
+ RGXSetBreakpoint
+ *******************************************/
+
+/* Bridge in structure for RGXSetBreakpoint */
+typedef struct PVRSRV_BRIDGE_IN_RGXSETBREAKPOINT_TAG
+{
+ IMG_HANDLE hPrivData;
+ IMG_UINT32 eFWDataMaster;
+ IMG_UINT32 ui32BreakpointAddr;
+ IMG_UINT32 ui32DM;
+ IMG_UINT32 ui32HandlerAddr;
+} __packed PVRSRV_BRIDGE_IN_RGXSETBREAKPOINT;
+
+/* Bridge out structure for RGXSetBreakpoint */
+typedef struct PVRSRV_BRIDGE_OUT_RGXSETBREAKPOINT_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXSETBREAKPOINT;
+
+/*******************************************
+ RGXClearBreakpoint
+ *******************************************/
+
+/* Bridge in structure for RGXClearBreakpoint */
+typedef struct PVRSRV_BRIDGE_IN_RGXCLEARBREAKPOINT_TAG
+{
+ IMG_HANDLE hPrivData;
+} __packed PVRSRV_BRIDGE_IN_RGXCLEARBREAKPOINT;
+
+/* Bridge out structure for RGXClearBreakpoint */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCLEARBREAKPOINT_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXCLEARBREAKPOINT;
+
+/*******************************************
+ RGXEnableBreakpoint
+ *******************************************/
+
+/* Bridge in structure for RGXEnableBreakpoint */
+typedef struct PVRSRV_BRIDGE_IN_RGXENABLEBREAKPOINT_TAG
+{
+ IMG_HANDLE hPrivData;
+} __packed PVRSRV_BRIDGE_IN_RGXENABLEBREAKPOINT;
+
+/* Bridge out structure for RGXEnableBreakpoint */
+typedef struct PVRSRV_BRIDGE_OUT_RGXENABLEBREAKPOINT_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXENABLEBREAKPOINT;
+
+/*******************************************
+ RGXDisableBreakpoint
+ *******************************************/
+
+/* Bridge in structure for RGXDisableBreakpoint */
+typedef struct PVRSRV_BRIDGE_IN_RGXDISABLEBREAKPOINT_TAG
+{
+ IMG_HANDLE hPrivData;
+} __packed PVRSRV_BRIDGE_IN_RGXDISABLEBREAKPOINT;
+
+/* Bridge out structure for RGXDisableBreakpoint */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDISABLEBREAKPOINT_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXDISABLEBREAKPOINT;
+
+/*******************************************
+ RGXOverallocateBPRegisters
+ *******************************************/
+
+/* Bridge in structure for RGXOverallocateBPRegisters */
+typedef struct PVRSRV_BRIDGE_IN_RGXOVERALLOCATEBPREGISTERS_TAG
+{
+ IMG_UINT32 ui32SharedRegs;
+ IMG_UINT32 ui32TempRegs;
+} __packed PVRSRV_BRIDGE_IN_RGXOVERALLOCATEBPREGISTERS;
+
+/* Bridge out structure for RGXOverallocateBPRegisters */
+typedef struct PVRSRV_BRIDGE_OUT_RGXOVERALLOCATEBPREGISTERS_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXOVERALLOCATEBPREGISTERS;
+
+#endif /* COMMON_RGXBREAKPOINT_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_rgxcmp_bridge.h b/drivers/gpu/drm/img-rogue/common_rgxcmp_bridge.h
new file mode 100644
index 000000000..dc6ed7d06
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_rgxcmp_bridge.h
@@ -0,0 +1,230 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for rgxcmp
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for rgxcmp
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_RGXCMP_BRIDGE_H
+#define COMMON_RGXCMP_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+#include "pvrsrv_sync_km.h"
+
+#define PVRSRV_BRIDGE_RGXCMP_CMD_FIRST 0
+#define PVRSRV_BRIDGE_RGXCMP_RGXCREATECOMPUTECONTEXT PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RGXCMP_RGXDESTROYCOMPUTECONTEXT PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RGXCMP_RGXFLUSHCOMPUTEDATA PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+2
+#define PVRSRV_BRIDGE_RGXCMP_RGXSETCOMPUTECONTEXTPRIORITY PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+3
+#define PVRSRV_BRIDGE_RGXCMP_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+4
+#define PVRSRV_BRIDGE_RGXCMP_RGXKICKCDM2 PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+5
+#define PVRSRV_BRIDGE_RGXCMP_RGXSETCOMPUTECONTEXTPROPERTY PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+6
+#define PVRSRV_BRIDGE_RGXCMP_RGXGETLASTDEVICEERROR PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+7
+#define PVRSRV_BRIDGE_RGXCMP_CMD_LAST (PVRSRV_BRIDGE_RGXCMP_CMD_FIRST+7)
+
+/*******************************************
+ RGXCreateComputeContext
+ *******************************************/
+
+/* Bridge in structure for RGXCreateComputeContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXCREATECOMPUTECONTEXT_TAG
+{
+ IMG_UINT64 ui64RobustnessAddress;
+ IMG_HANDLE hPrivData;
+ IMG_BYTE *pui8FrameworkCmd;
+ IMG_BYTE *pui8StaticComputeContextState;
+ IMG_UINT32 ui32ContextFlags;
+ IMG_UINT32 ui32FrameworkCmdize;
+ IMG_UINT32 ui32MaxDeadlineMS;
+ IMG_UINT32 ui32PackedCCBSizeU88;
+ IMG_UINT32 ui32Priority;
+ IMG_UINT32 ui32StaticComputeContextStateSize;
+} __packed PVRSRV_BRIDGE_IN_RGXCREATECOMPUTECONTEXT;
+
+/* Bridge out structure for RGXCreateComputeContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCREATECOMPUTECONTEXT_TAG
+{
+ IMG_HANDLE hComputeContext;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXCREATECOMPUTECONTEXT;
+
+/*******************************************
+ RGXDestroyComputeContext
+ *******************************************/
+
+/* Bridge in structure for RGXDestroyComputeContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYCOMPUTECONTEXT_TAG
+{
+ IMG_HANDLE hComputeContext;
+} __packed PVRSRV_BRIDGE_IN_RGXDESTROYCOMPUTECONTEXT;
+
+/* Bridge out structure for RGXDestroyComputeContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYCOMPUTECONTEXT_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXDESTROYCOMPUTECONTEXT;
+
+/*******************************************
+ RGXFlushComputeData
+ *******************************************/
+
+/* Bridge in structure for RGXFlushComputeData */
+typedef struct PVRSRV_BRIDGE_IN_RGXFLUSHCOMPUTEDATA_TAG
+{
+ IMG_HANDLE hComputeContext;
+} __packed PVRSRV_BRIDGE_IN_RGXFLUSHCOMPUTEDATA;
+
+/* Bridge out structure for RGXFlushComputeData */
+typedef struct PVRSRV_BRIDGE_OUT_RGXFLUSHCOMPUTEDATA_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXFLUSHCOMPUTEDATA;
+
+/*******************************************
+ RGXSetComputeContextPriority
+ *******************************************/
+
+/* Bridge in structure for RGXSetComputeContextPriority */
+typedef struct PVRSRV_BRIDGE_IN_RGXSETCOMPUTECONTEXTPRIORITY_TAG
+{
+ IMG_HANDLE hComputeContext;
+ IMG_UINT32 ui32Priority;
+} __packed PVRSRV_BRIDGE_IN_RGXSETCOMPUTECONTEXTPRIORITY;
+
+/* Bridge out structure for RGXSetComputeContextPriority */
+typedef struct PVRSRV_BRIDGE_OUT_RGXSETCOMPUTECONTEXTPRIORITY_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXSETCOMPUTECONTEXTPRIORITY;
+
+/*******************************************
+ RGXNotifyComputeWriteOffsetUpdate
+ *******************************************/
+
+/* Bridge in structure for RGXNotifyComputeWriteOffsetUpdate */
+typedef struct PVRSRV_BRIDGE_IN_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE_TAG
+{
+ IMG_HANDLE hComputeContext;
+} __packed PVRSRV_BRIDGE_IN_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE;
+
+/* Bridge out structure for RGXNotifyComputeWriteOffsetUpdate */
+typedef struct PVRSRV_BRIDGE_OUT_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXNOTIFYCOMPUTEWRITEOFFSETUPDATE;
+
+/*******************************************
+ RGXKickCDM2
+ *******************************************/
+
+/* Bridge in structure for RGXKickCDM2 */
+typedef struct PVRSRV_BRIDGE_IN_RGXKICKCDM2_TAG
+{
+ IMG_UINT64 ui64DeadlineInus;
+ IMG_HANDLE hComputeContext;
+ IMG_UINT32 *pui32ClientUpdateOffset;
+ IMG_UINT32 *pui32ClientUpdateValue;
+ IMG_UINT32 *pui32SyncPMRFlags;
+ IMG_BYTE *pui8DMCmd;
+ IMG_CHAR *puiUpdateFenceName;
+ IMG_HANDLE *phClientUpdateUFOSyncPrimBlock;
+ IMG_HANDLE *phSyncPMRs;
+ PVRSRV_FENCE hCheckFenceFd;
+ PVRSRV_TIMELINE hUpdateTimeline;
+ IMG_UINT32 ui32ClientCacheOpSeqNum;
+ IMG_UINT32 ui32ClientUpdateCount;
+ IMG_UINT32 ui32CmdSize;
+ IMG_UINT32 ui32ExtJobRef;
+ IMG_UINT32 ui32NumOfWorkgroups;
+ IMG_UINT32 ui32NumOfWorkitems;
+ IMG_UINT32 ui32PDumpFlags;
+ IMG_UINT32 ui32SyncPMRCount;
+} __packed PVRSRV_BRIDGE_IN_RGXKICKCDM2;
+
+/* Bridge out structure for RGXKickCDM2 */
+typedef struct PVRSRV_BRIDGE_OUT_RGXKICKCDM2_TAG
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_FENCE hUpdateFence;
+} __packed PVRSRV_BRIDGE_OUT_RGXKICKCDM2;
+
+/*******************************************
+ RGXSetComputeContextProperty
+ *******************************************/
+
+/* Bridge in structure for RGXSetComputeContextProperty */
+typedef struct PVRSRV_BRIDGE_IN_RGXSETCOMPUTECONTEXTPROPERTY_TAG
+{
+ IMG_UINT64 ui64Input;
+ IMG_HANDLE hComputeContext;
+ IMG_UINT32 ui32Property;
+} __packed PVRSRV_BRIDGE_IN_RGXSETCOMPUTECONTEXTPROPERTY;
+
+/* Bridge out structure for RGXSetComputeContextProperty */
+typedef struct PVRSRV_BRIDGE_OUT_RGXSETCOMPUTECONTEXTPROPERTY_TAG
+{
+ IMG_UINT64 ui64Output;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXSETCOMPUTECONTEXTPROPERTY;
+
+/*******************************************
+ RGXGetLastDeviceError
+ *******************************************/
+
+/* Bridge in structure for RGXGetLastDeviceError */
+typedef struct PVRSRV_BRIDGE_IN_RGXGETLASTDEVICEERROR_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_RGXGETLASTDEVICEERROR;
+
+/* Bridge out structure for RGXGetLastDeviceError */
+typedef struct PVRSRV_BRIDGE_OUT_RGXGETLASTDEVICEERROR_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32Error;
+} __packed PVRSRV_BRIDGE_OUT_RGXGETLASTDEVICEERROR;
+
+#endif /* COMMON_RGXCMP_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_rgxfwdbg_bridge.h b/drivers/gpu/drm/img-rogue/common_rgxfwdbg_bridge.h
new file mode 100644
index 000000000..68c79e573
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_rgxfwdbg_bridge.h
@@ -0,0 +1,200 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for rgxfwdbg
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for rgxfwdbg
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_RGXFWDBG_BRIDGE_H
+#define COMMON_RGXFWDBG_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "devicemem_typedefs.h"
+#include "rgx_bridge.h"
+#include "pvrsrv_memallocflags.h"
+
+#define PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST 0
+#define PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGSETFWLOG PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGDUMPFREELISTPAGELIST PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGSETHCSDEADLINE PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST+2
+#define PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGSETOSIDPRIORITY PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST+3
+#define PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGSETOSNEWONLINESTATE PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST+4
+#define PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGPHRCONFIGURE PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST+5
+#define PVRSRV_BRIDGE_RGXFWDBG_RGXFWDEBUGWDGCONFIGURE PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST+6
+#define PVRSRV_BRIDGE_RGXFWDBG_RGXCURRENTTIME PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST+7
+#define PVRSRV_BRIDGE_RGXFWDBG_CMD_LAST (PVRSRV_BRIDGE_RGXFWDBG_CMD_FIRST+7)
+
+/*******************************************
+ RGXFWDebugSetFWLog
+ *******************************************/
+
+/* Bridge in structure for RGXFWDebugSetFWLog */
+typedef struct PVRSRV_BRIDGE_IN_RGXFWDEBUGSETFWLOG_TAG
+{
+ IMG_UINT32 ui32RGXFWLogType;
+} __packed PVRSRV_BRIDGE_IN_RGXFWDEBUGSETFWLOG;
+
+/* Bridge out structure for RGXFWDebugSetFWLog */
+typedef struct PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETFWLOG_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETFWLOG;
+
+/*******************************************
+ RGXFWDebugDumpFreelistPageList
+ *******************************************/
+
+/* Bridge in structure for RGXFWDebugDumpFreelistPageList */
+typedef struct PVRSRV_BRIDGE_IN_RGXFWDEBUGDUMPFREELISTPAGELIST_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_RGXFWDEBUGDUMPFREELISTPAGELIST;
+
+/* Bridge out structure for RGXFWDebugDumpFreelistPageList */
+typedef struct PVRSRV_BRIDGE_OUT_RGXFWDEBUGDUMPFREELISTPAGELIST_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXFWDEBUGDUMPFREELISTPAGELIST;
+
+/*******************************************
+ RGXFWDebugSetHCSDeadline
+ *******************************************/
+
+/* Bridge in structure for RGXFWDebugSetHCSDeadline */
+typedef struct PVRSRV_BRIDGE_IN_RGXFWDEBUGSETHCSDEADLINE_TAG
+{
+ IMG_UINT32 ui32RGXHCSDeadline;
+} __packed PVRSRV_BRIDGE_IN_RGXFWDEBUGSETHCSDEADLINE;
+
+/* Bridge out structure for RGXFWDebugSetHCSDeadline */
+typedef struct PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETHCSDEADLINE_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETHCSDEADLINE;
+
+/*******************************************
+ RGXFWDebugSetOSidPriority
+ *******************************************/
+
+/* Bridge in structure for RGXFWDebugSetOSidPriority */
+typedef struct PVRSRV_BRIDGE_IN_RGXFWDEBUGSETOSIDPRIORITY_TAG
+{
+ IMG_UINT32 ui32OSid;
+ IMG_UINT32 ui32Priority;
+} __packed PVRSRV_BRIDGE_IN_RGXFWDEBUGSETOSIDPRIORITY;
+
+/* Bridge out structure for RGXFWDebugSetOSidPriority */
+typedef struct PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETOSIDPRIORITY_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETOSIDPRIORITY;
+
+/*******************************************
+ RGXFWDebugSetOSNewOnlineState
+ *******************************************/
+
+/* Bridge in structure for RGXFWDebugSetOSNewOnlineState */
+typedef struct PVRSRV_BRIDGE_IN_RGXFWDEBUGSETOSNEWONLINESTATE_TAG
+{
+ IMG_UINT32 ui32OSNewState;
+ IMG_UINT32 ui32OSid;
+} __packed PVRSRV_BRIDGE_IN_RGXFWDEBUGSETOSNEWONLINESTATE;
+
+/* Bridge out structure for RGXFWDebugSetOSNewOnlineState */
+typedef struct PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETOSNEWONLINESTATE_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXFWDEBUGSETOSNEWONLINESTATE;
+
+/*******************************************
+ RGXFWDebugPHRConfigure
+ *******************************************/
+
+/* Bridge in structure for RGXFWDebugPHRConfigure */
+typedef struct PVRSRV_BRIDGE_IN_RGXFWDEBUGPHRCONFIGURE_TAG
+{
+ IMG_UINT32 ui32ui32PHRMode;
+} __packed PVRSRV_BRIDGE_IN_RGXFWDEBUGPHRCONFIGURE;
+
+/* Bridge out structure for RGXFWDebugPHRConfigure */
+typedef struct PVRSRV_BRIDGE_OUT_RGXFWDEBUGPHRCONFIGURE_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXFWDEBUGPHRCONFIGURE;
+
+/*******************************************
+ RGXFWDebugWdgConfigure
+ *******************************************/
+
+/* Bridge in structure for RGXFWDebugWdgConfigure */
+typedef struct PVRSRV_BRIDGE_IN_RGXFWDEBUGWDGCONFIGURE_TAG
+{
+ IMG_UINT32 ui32ui32WdgPeriodUs;
+} __packed PVRSRV_BRIDGE_IN_RGXFWDEBUGWDGCONFIGURE;
+
+/* Bridge out structure for RGXFWDebugWdgConfigure */
+typedef struct PVRSRV_BRIDGE_OUT_RGXFWDEBUGWDGCONFIGURE_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXFWDEBUGWDGCONFIGURE;
+
+/*******************************************
+ RGXCurrentTime
+ *******************************************/
+
+/* Bridge in structure for RGXCurrentTime */
+typedef struct PVRSRV_BRIDGE_IN_RGXCURRENTTIME_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_RGXCURRENTTIME;
+
+/* Bridge out structure for RGXCurrentTime */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCURRENTTIME_TAG
+{
+ IMG_UINT64 ui64Time;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXCURRENTTIME;
+
+#endif /* COMMON_RGXFWDBG_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_rgxhwperf_bridge.h b/drivers/gpu/drm/img-rogue/common_rgxhwperf_bridge.h
new file mode 100644
index 000000000..08e80bb46
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_rgxhwperf_bridge.h
@@ -0,0 +1,172 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for rgxhwperf
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for rgxhwperf
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_RGXHWPERF_BRIDGE_H
+#define COMMON_RGXHWPERF_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+#include "rgx_hwperf.h"
+
+#define PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST 0
+#define PVRSRV_BRIDGE_RGXHWPERF_RGXCTRLHWPERF PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RGXHWPERF_RGXGETHWPERFBVNCFEATUREFLAGS PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RGXHWPERF_RGXCONFIGMUXHWPERFCOUNTERS PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST+2
+#define PVRSRV_BRIDGE_RGXHWPERF_RGXCONTROLHWPERFBLOCKS PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST+3
+#define PVRSRV_BRIDGE_RGXHWPERF_RGXCONFIGCUSTOMCOUNTERS PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST+4
+#define PVRSRV_BRIDGE_RGXHWPERF_RGXCONFIGUREHWPERFBLOCKS PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST+5
+#define PVRSRV_BRIDGE_RGXHWPERF_CMD_LAST (PVRSRV_BRIDGE_RGXHWPERF_CMD_FIRST+5)
+
+/*******************************************
+ RGXCtrlHWPerf
+ *******************************************/
+
+/* Bridge in structure for RGXCtrlHWPerf */
+typedef struct PVRSRV_BRIDGE_IN_RGXCTRLHWPERF_TAG
+{
+ IMG_UINT64 ui64Mask;
+ IMG_BOOL bToggle;
+ IMG_UINT32 ui32StreamId;
+} __packed PVRSRV_BRIDGE_IN_RGXCTRLHWPERF;
+
+/* Bridge out structure for RGXCtrlHWPerf */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCTRLHWPERF_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXCTRLHWPERF;
+
+/*******************************************
+ RGXGetHWPerfBvncFeatureFlags
+ *******************************************/
+
+/* Bridge in structure for RGXGetHWPerfBvncFeatureFlags */
+typedef struct PVRSRV_BRIDGE_IN_RGXGETHWPERFBVNCFEATUREFLAGS_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_RGXGETHWPERFBVNCFEATUREFLAGS;
+
+/* Bridge out structure for RGXGetHWPerfBvncFeatureFlags */
+typedef struct PVRSRV_BRIDGE_OUT_RGXGETHWPERFBVNCFEATUREFLAGS_TAG
+{
+ RGX_HWPERF_BVNC sBVNC;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXGETHWPERFBVNCFEATUREFLAGS;
+
+/*******************************************
+ RGXConfigMuxHWPerfCounters
+ *******************************************/
+
+/* Bridge in structure for RGXConfigMuxHWPerfCounters */
+typedef struct PVRSRV_BRIDGE_IN_RGXCONFIGMUXHWPERFCOUNTERS_TAG
+{
+ RGX_HWPERF_CONFIG_MUX_CNTBLK *psBlockConfigs;
+ IMG_UINT32 ui32ArrayLen;
+} __packed PVRSRV_BRIDGE_IN_RGXCONFIGMUXHWPERFCOUNTERS;
+
+/* Bridge out structure for RGXConfigMuxHWPerfCounters */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCONFIGMUXHWPERFCOUNTERS_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXCONFIGMUXHWPERFCOUNTERS;
+
+/*******************************************
+ RGXControlHWPerfBlocks
+ *******************************************/
+
+/* Bridge in structure for RGXControlHWPerfBlocks */
+typedef struct PVRSRV_BRIDGE_IN_RGXCONTROLHWPERFBLOCKS_TAG
+{
+ IMG_UINT16 *pui16BlockIDs;
+ IMG_BOOL bEnable;
+ IMG_UINT32 ui32ArrayLen;
+} __packed PVRSRV_BRIDGE_IN_RGXCONTROLHWPERFBLOCKS;
+
+/* Bridge out structure for RGXControlHWPerfBlocks */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCONTROLHWPERFBLOCKS_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXCONTROLHWPERFBLOCKS;
+
+/*******************************************
+ RGXConfigCustomCounters
+ *******************************************/
+
+/* Bridge in structure for RGXConfigCustomCounters */
+typedef struct PVRSRV_BRIDGE_IN_RGXCONFIGCUSTOMCOUNTERS_TAG
+{
+ IMG_UINT32 *pui32CustomCounterIDs;
+ IMG_UINT16 ui16CustomBlockID;
+ IMG_UINT16 ui16NumCustomCounters;
+} __packed PVRSRV_BRIDGE_IN_RGXCONFIGCUSTOMCOUNTERS;
+
+/* Bridge out structure for RGXConfigCustomCounters */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCONFIGCUSTOMCOUNTERS_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXCONFIGCUSTOMCOUNTERS;
+
+/*******************************************
+ RGXConfigureHWPerfBlocks
+ *******************************************/
+
+/* Bridge in structure for RGXConfigureHWPerfBlocks */
+typedef struct PVRSRV_BRIDGE_IN_RGXCONFIGUREHWPERFBLOCKS_TAG
+{
+ RGX_HWPERF_CONFIG_CNTBLK *psBlockConfigs;
+ IMG_UINT32 ui32ArrayLen;
+ IMG_UINT32 ui32CtrlWord;
+} __packed PVRSRV_BRIDGE_IN_RGXCONFIGUREHWPERFBLOCKS;
+
+/* Bridge out structure for RGXConfigureHWPerfBlocks */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCONFIGUREHWPERFBLOCKS_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXCONFIGUREHWPERFBLOCKS;
+
+#endif /* COMMON_RGXHWPERF_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_rgxkicksync_bridge.h b/drivers/gpu/drm/img-rogue/common_rgxkicksync_bridge.h
new file mode 100644
index 000000000..d0c1df3b6
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_rgxkicksync_bridge.h
@@ -0,0 +1,144 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for rgxkicksync
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for rgxkicksync
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_RGXKICKSYNC_BRIDGE_H
+#define COMMON_RGXKICKSYNC_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+#include "pvrsrv_sync_km.h"
+
+#define PVRSRV_BRIDGE_RGXKICKSYNC_CMD_FIRST 0
+#define PVRSRV_BRIDGE_RGXKICKSYNC_RGXCREATEKICKSYNCCONTEXT PVRSRV_BRIDGE_RGXKICKSYNC_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RGXKICKSYNC_RGXDESTROYKICKSYNCCONTEXT PVRSRV_BRIDGE_RGXKICKSYNC_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RGXKICKSYNC_RGXKICKSYNC2 PVRSRV_BRIDGE_RGXKICKSYNC_CMD_FIRST+2
+#define PVRSRV_BRIDGE_RGXKICKSYNC_RGXSETKICKSYNCCONTEXTPROPERTY PVRSRV_BRIDGE_RGXKICKSYNC_CMD_FIRST+3
+#define PVRSRV_BRIDGE_RGXKICKSYNC_CMD_LAST (PVRSRV_BRIDGE_RGXKICKSYNC_CMD_FIRST+3)
+
+/*******************************************
+ RGXCreateKickSyncContext
+ *******************************************/
+
+/* Bridge in structure for RGXCreateKickSyncContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXCREATEKICKSYNCCONTEXT_TAG
+{
+ IMG_HANDLE hPrivData;
+ IMG_UINT32 ui32ContextFlags;
+ IMG_UINT32 ui32PackedCCBSizeU88;
+} __packed PVRSRV_BRIDGE_IN_RGXCREATEKICKSYNCCONTEXT;
+
+/* Bridge out structure for RGXCreateKickSyncContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCREATEKICKSYNCCONTEXT_TAG
+{
+ IMG_HANDLE hKickSyncContext;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXCREATEKICKSYNCCONTEXT;
+
+/*******************************************
+ RGXDestroyKickSyncContext
+ *******************************************/
+
+/* Bridge in structure for RGXDestroyKickSyncContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYKICKSYNCCONTEXT_TAG
+{
+ IMG_HANDLE hKickSyncContext;
+} __packed PVRSRV_BRIDGE_IN_RGXDESTROYKICKSYNCCONTEXT;
+
+/* Bridge out structure for RGXDestroyKickSyncContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYKICKSYNCCONTEXT_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXDESTROYKICKSYNCCONTEXT;
+
+/*******************************************
+ RGXKickSync2
+ *******************************************/
+
+/* Bridge in structure for RGXKickSync2 */
+typedef struct PVRSRV_BRIDGE_IN_RGXKICKSYNC2_TAG
+{
+ IMG_HANDLE hKickSyncContext;
+ IMG_UINT32 *pui32UpdateDevVarOffset;
+ IMG_UINT32 *pui32UpdateValue;
+ IMG_CHAR *puiUpdateFenceName;
+ IMG_HANDLE *phUpdateUFODevVarBlock;
+ PVRSRV_FENCE hCheckFenceFD;
+ PVRSRV_TIMELINE hTimelineFenceFD;
+ IMG_UINT32 ui32ClientCacheOpSeqNum;
+ IMG_UINT32 ui32ClientUpdateCount;
+ IMG_UINT32 ui32ExtJobRef;
+} __packed PVRSRV_BRIDGE_IN_RGXKICKSYNC2;
+
+/* Bridge out structure for RGXKickSync2 */
+typedef struct PVRSRV_BRIDGE_OUT_RGXKICKSYNC2_TAG
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_FENCE hUpdateFenceFD;
+} __packed PVRSRV_BRIDGE_OUT_RGXKICKSYNC2;
+
+/*******************************************
+ RGXSetKickSyncContextProperty
+ *******************************************/
+
+/* Bridge in structure for RGXSetKickSyncContextProperty */
+typedef struct PVRSRV_BRIDGE_IN_RGXSETKICKSYNCCONTEXTPROPERTY_TAG
+{
+ IMG_UINT64 ui64Input;
+ IMG_HANDLE hKickSyncContext;
+ IMG_UINT32 ui32Property;
+} __packed PVRSRV_BRIDGE_IN_RGXSETKICKSYNCCONTEXTPROPERTY;
+
+/* Bridge out structure for RGXSetKickSyncContextProperty */
+typedef struct PVRSRV_BRIDGE_OUT_RGXSETKICKSYNCCONTEXTPROPERTY_TAG
+{
+ IMG_UINT64 ui64Output;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXSETKICKSYNCCONTEXTPROPERTY;
+
+#endif /* COMMON_RGXKICKSYNC_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_rgxregconfig_bridge.h b/drivers/gpu/drm/img-rogue/common_rgxregconfig_bridge.h
new file mode 100644
index 000000000..942b7e4b0
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_rgxregconfig_bridge.h
@@ -0,0 +1,146 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for rgxregconfig
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for rgxregconfig
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_RGXREGCONFIG_BRIDGE_H
+#define COMMON_RGXREGCONFIG_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+
+#define PVRSRV_BRIDGE_RGXREGCONFIG_CMD_FIRST 0
+#define PVRSRV_BRIDGE_RGXREGCONFIG_RGXSETREGCONFIGTYPE PVRSRV_BRIDGE_RGXREGCONFIG_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RGXREGCONFIG_RGXADDREGCONFIG PVRSRV_BRIDGE_RGXREGCONFIG_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RGXREGCONFIG_RGXCLEARREGCONFIG PVRSRV_BRIDGE_RGXREGCONFIG_CMD_FIRST+2
+#define PVRSRV_BRIDGE_RGXREGCONFIG_RGXENABLEREGCONFIG PVRSRV_BRIDGE_RGXREGCONFIG_CMD_FIRST+3
+#define PVRSRV_BRIDGE_RGXREGCONFIG_RGXDISABLEREGCONFIG PVRSRV_BRIDGE_RGXREGCONFIG_CMD_FIRST+4
+#define PVRSRV_BRIDGE_RGXREGCONFIG_CMD_LAST (PVRSRV_BRIDGE_RGXREGCONFIG_CMD_FIRST+4)
+
+/*******************************************
+ RGXSetRegConfigType
+ *******************************************/
+
+/* Bridge in structure for RGXSetRegConfigType */
+typedef struct PVRSRV_BRIDGE_IN_RGXSETREGCONFIGTYPE_TAG
+{
+ IMG_UINT8 ui8RegPowerIsland;
+} __packed PVRSRV_BRIDGE_IN_RGXSETREGCONFIGTYPE;
+
+/* Bridge out structure for RGXSetRegConfigType */
+typedef struct PVRSRV_BRIDGE_OUT_RGXSETREGCONFIGTYPE_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXSETREGCONFIGTYPE;
+
+/*******************************************
+ RGXAddRegconfig
+ *******************************************/
+
+/* Bridge in structure for RGXAddRegconfig */
+typedef struct PVRSRV_BRIDGE_IN_RGXADDREGCONFIG_TAG
+{
+ IMG_UINT64 ui64RegMask;
+ IMG_UINT64 ui64RegValue;
+ IMG_UINT32 ui32RegAddr;
+} __packed PVRSRV_BRIDGE_IN_RGXADDREGCONFIG;
+
+/* Bridge out structure for RGXAddRegconfig */
+typedef struct PVRSRV_BRIDGE_OUT_RGXADDREGCONFIG_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXADDREGCONFIG;
+
+/*******************************************
+ RGXClearRegConfig
+ *******************************************/
+
+/* Bridge in structure for RGXClearRegConfig */
+typedef struct PVRSRV_BRIDGE_IN_RGXCLEARREGCONFIG_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_RGXCLEARREGCONFIG;
+
+/* Bridge out structure for RGXClearRegConfig */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCLEARREGCONFIG_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXCLEARREGCONFIG;
+
+/*******************************************
+ RGXEnableRegConfig
+ *******************************************/
+
+/* Bridge in structure for RGXEnableRegConfig */
+typedef struct PVRSRV_BRIDGE_IN_RGXENABLEREGCONFIG_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_RGXENABLEREGCONFIG;
+
+/* Bridge out structure for RGXEnableRegConfig */
+typedef struct PVRSRV_BRIDGE_OUT_RGXENABLEREGCONFIG_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXENABLEREGCONFIG;
+
+/*******************************************
+ RGXDisableRegConfig
+ *******************************************/
+
+/* Bridge in structure for RGXDisableRegConfig */
+typedef struct PVRSRV_BRIDGE_IN_RGXDISABLEREGCONFIG_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_RGXDISABLEREGCONFIG;
+
+/* Bridge out structure for RGXDisableRegConfig */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDISABLEREGCONFIG_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXDISABLEREGCONFIG;
+
+#endif /* COMMON_RGXREGCONFIG_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_rgxta3d_bridge.h b/drivers/gpu/drm/img-rogue/common_rgxta3d_bridge.h
new file mode 100644
index 000000000..65b001bca
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_rgxta3d_bridge.h
@@ -0,0 +1,404 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for rgxta3d
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for rgxta3d
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_RGXTA3D_BRIDGE_H
+#define COMMON_RGXTA3D_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+#include "rgx_fwif_shared.h"
+#include "devicemem_typedefs.h"
+#include "pvrsrv_sync_km.h"
+
+#define PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST 0
+#define PVRSRV_BRIDGE_RGXTA3D_RGXCREATEHWRTDATASET PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYHWRTDATASET PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RGXTA3D_RGXCREATEZSBUFFER PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+2
+#define PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYZSBUFFER PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+3
+#define PVRSRV_BRIDGE_RGXTA3D_RGXPOPULATEZSBUFFER PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+4
+#define PVRSRV_BRIDGE_RGXTA3D_RGXUNPOPULATEZSBUFFER PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+5
+#define PVRSRV_BRIDGE_RGXTA3D_RGXCREATEFREELIST PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+6
+#define PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYFREELIST PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+7
+#define PVRSRV_BRIDGE_RGXTA3D_RGXCREATERENDERCONTEXT PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+8
+#define PVRSRV_BRIDGE_RGXTA3D_RGXDESTROYRENDERCONTEXT PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+9
+#define PVRSRV_BRIDGE_RGXTA3D_RGXSETRENDERCONTEXTPRIORITY PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+10
+#define PVRSRV_BRIDGE_RGXTA3D_RGXRENDERCONTEXTSTALLED PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+11
+#define PVRSRV_BRIDGE_RGXTA3D_RGXKICKTA3D2 PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+12
+#define PVRSRV_BRIDGE_RGXTA3D_RGXSETRENDERCONTEXTPROPERTY PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+13
+#define PVRSRV_BRIDGE_RGXTA3D_CMD_LAST (PVRSRV_BRIDGE_RGXTA3D_CMD_FIRST+13)
+
+/*******************************************
+ RGXCreateHWRTDataSet
+ *******************************************/
+
+/* Bridge in structure for RGXCreateHWRTDataSet */
+typedef struct PVRSRV_BRIDGE_IN_RGXCREATEHWRTDATASET_TAG
+{
+ IMG_DEV_VIRTADDR sTailPtrsDevVAddr;
+ IMG_DEV_VIRTADDR ssRTCDevVAddr;
+ IMG_DEV_VIRTADDR ssVHeapTableDevVAddr;
+ IMG_UINT64 ui64FlippedMultiSampleCtl;
+ IMG_UINT64 ui64MultiSampleCtl;
+ IMG_DEV_VIRTADDR *psMacrotileArrayDevVAddr;
+ IMG_DEV_VIRTADDR *psPMMlistDevVAddr;
+ IMG_DEV_VIRTADDR *psRgnHeaderDevVAddr;
+ IMG_HANDLE *phKmHwRTDataSet;
+ IMG_HANDLE *phapsFreeLists;
+ IMG_UINT32 ui32MTileStride;
+ IMG_UINT32 ui32PPPScreen;
+ IMG_UINT32 ui32TEAA;
+ IMG_UINT32 ui32TEMTILE1;
+ IMG_UINT32 ui32TEMTILE2;
+ IMG_UINT32 ui32TEScreen;
+ IMG_UINT32 ui32TPCSize;
+ IMG_UINT32 ui32TPCStride;
+ IMG_UINT32 ui32ui32ISPMergeLowerX;
+ IMG_UINT32 ui32ui32ISPMergeLowerY;
+ IMG_UINT32 ui32ui32ISPMergeScaleX;
+ IMG_UINT32 ui32ui32ISPMergeScaleY;
+ IMG_UINT32 ui32ui32ISPMergeUpperX;
+ IMG_UINT32 ui32ui32ISPMergeUpperY;
+ IMG_UINT32 ui32ui32ISPMtileSize;
+ IMG_UINT32 ui32uiRgnHeaderSize;
+ IMG_UINT16 ui16MaxRTs;
+} __packed PVRSRV_BRIDGE_IN_RGXCREATEHWRTDATASET;
+
+/* Bridge out structure for RGXCreateHWRTDataSet */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCREATEHWRTDATASET_TAG
+{
+ IMG_HANDLE *phKmHwRTDataSet;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXCREATEHWRTDATASET;
+
+/*******************************************
+ RGXDestroyHWRTDataSet
+ *******************************************/
+
+/* Bridge in structure for RGXDestroyHWRTDataSet */
+typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYHWRTDATASET_TAG
+{
+ IMG_HANDLE hKmHwRTDataSet;
+} __packed PVRSRV_BRIDGE_IN_RGXDESTROYHWRTDATASET;
+
+/* Bridge out structure for RGXDestroyHWRTDataSet */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYHWRTDATASET_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXDESTROYHWRTDATASET;
+
+/*******************************************
+ RGXCreateZSBuffer
+ *******************************************/
+
+/* Bridge in structure for RGXCreateZSBuffer */
+typedef struct PVRSRV_BRIDGE_IN_RGXCREATEZSBUFFER_TAG
+{
+ IMG_HANDLE hPMR;
+ IMG_HANDLE hReservation;
+ PVRSRV_MEMALLOCFLAGS_T uiMapFlags;
+} __packed PVRSRV_BRIDGE_IN_RGXCREATEZSBUFFER;
+
+/* Bridge out structure for RGXCreateZSBuffer */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCREATEZSBUFFER_TAG
+{
+ IMG_HANDLE hsZSBufferKM;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXCREATEZSBUFFER;
+
+/*******************************************
+ RGXDestroyZSBuffer
+ *******************************************/
+
+/* Bridge in structure for RGXDestroyZSBuffer */
+typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYZSBUFFER_TAG
+{
+ IMG_HANDLE hsZSBufferMemDesc;
+} __packed PVRSRV_BRIDGE_IN_RGXDESTROYZSBUFFER;
+
+/* Bridge out structure for RGXDestroyZSBuffer */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYZSBUFFER_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXDESTROYZSBUFFER;
+
+/*******************************************
+ RGXPopulateZSBuffer
+ *******************************************/
+
+/* Bridge in structure for RGXPopulateZSBuffer */
+typedef struct PVRSRV_BRIDGE_IN_RGXPOPULATEZSBUFFER_TAG
+{
+ IMG_HANDLE hsZSBufferKM;
+} __packed PVRSRV_BRIDGE_IN_RGXPOPULATEZSBUFFER;
+
+/* Bridge out structure for RGXPopulateZSBuffer */
+typedef struct PVRSRV_BRIDGE_OUT_RGXPOPULATEZSBUFFER_TAG
+{
+ IMG_HANDLE hsPopulation;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXPOPULATEZSBUFFER;
+
+/*******************************************
+ RGXUnpopulateZSBuffer
+ *******************************************/
+
+/* Bridge in structure for RGXUnpopulateZSBuffer */
+typedef struct PVRSRV_BRIDGE_IN_RGXUNPOPULATEZSBUFFER_TAG
+{
+ IMG_HANDLE hsPopulation;
+} __packed PVRSRV_BRIDGE_IN_RGXUNPOPULATEZSBUFFER;
+
+/* Bridge out structure for RGXUnpopulateZSBuffer */
+typedef struct PVRSRV_BRIDGE_OUT_RGXUNPOPULATEZSBUFFER_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXUNPOPULATEZSBUFFER;
+
+/*******************************************
+ RGXCreateFreeList
+ *******************************************/
+
+/* Bridge in structure for RGXCreateFreeList */
+typedef struct PVRSRV_BRIDGE_IN_RGXCREATEFREELIST_TAG
+{
+ IMG_DEV_VIRTADDR spsFreeListDevVAddr;
+ IMG_DEVMEM_OFFSET_T uiPMROffset;
+ IMG_HANDLE hMemCtxPrivData;
+ IMG_HANDLE hsFreeListPMR;
+ IMG_HANDLE hsGlobalFreeList;
+ IMG_BOOL bbFreeListCheck;
+ IMG_UINT32 ui32GrowFLPages;
+ IMG_UINT32 ui32GrowParamThreshold;
+ IMG_UINT32 ui32InitFLPages;
+ IMG_UINT32 ui32MaxFLPages;
+} __packed PVRSRV_BRIDGE_IN_RGXCREATEFREELIST;
+
+/* Bridge out structure for RGXCreateFreeList */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCREATEFREELIST_TAG
+{
+ IMG_HANDLE hCleanupCookie;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXCREATEFREELIST;
+
+/*******************************************
+ RGXDestroyFreeList
+ *******************************************/
+
+/* Bridge in structure for RGXDestroyFreeList */
+typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYFREELIST_TAG
+{
+ IMG_HANDLE hCleanupCookie;
+} __packed PVRSRV_BRIDGE_IN_RGXDESTROYFREELIST;
+
+/* Bridge out structure for RGXDestroyFreeList */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYFREELIST_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXDESTROYFREELIST;
+
+/*******************************************
+ RGXCreateRenderContext
+ *******************************************/
+
+/* Bridge in structure for RGXCreateRenderContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXCREATERENDERCONTEXT_TAG
+{
+ IMG_DEV_VIRTADDR sVDMCallStackAddr;
+ IMG_UINT64 ui64RobustnessAddress;
+ IMG_HANDLE hPrivData;
+ IMG_BYTE *pui8FrameworkCmd;
+ IMG_BYTE *pui8StaticRenderContextState;
+ IMG_UINT32 ui32ContextFlags;
+ IMG_UINT32 ui32FrameworkCmdSize;
+ IMG_UINT32 ui32Max3DDeadlineMS;
+ IMG_UINT32 ui32MaxTADeadlineMS;
+ IMG_UINT32 ui32PackedCCBSizeU8888;
+ IMG_UINT32 ui32Priority;
+ IMG_UINT32 ui32StaticRenderContextStateSize;
+} __packed PVRSRV_BRIDGE_IN_RGXCREATERENDERCONTEXT;
+
+/* Bridge out structure for RGXCreateRenderContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCREATERENDERCONTEXT_TAG
+{
+ IMG_HANDLE hRenderContext;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXCREATERENDERCONTEXT;
+
+/*******************************************
+ RGXDestroyRenderContext
+ *******************************************/
+
+/* Bridge in structure for RGXDestroyRenderContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYRENDERCONTEXT_TAG
+{
+ IMG_HANDLE hCleanupCookie;
+} __packed PVRSRV_BRIDGE_IN_RGXDESTROYRENDERCONTEXT;
+
+/* Bridge out structure for RGXDestroyRenderContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYRENDERCONTEXT_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXDESTROYRENDERCONTEXT;
+
+/*******************************************
+ RGXSetRenderContextPriority
+ *******************************************/
+
+/* Bridge in structure for RGXSetRenderContextPriority */
+typedef struct PVRSRV_BRIDGE_IN_RGXSETRENDERCONTEXTPRIORITY_TAG
+{
+ IMG_HANDLE hRenderContext;
+ IMG_UINT32 ui32Priority;
+} __packed PVRSRV_BRIDGE_IN_RGXSETRENDERCONTEXTPRIORITY;
+
+/* Bridge out structure for RGXSetRenderContextPriority */
+typedef struct PVRSRV_BRIDGE_OUT_RGXSETRENDERCONTEXTPRIORITY_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXSETRENDERCONTEXTPRIORITY;
+
+/*******************************************
+ RGXRenderContextStalled
+ *******************************************/
+
+/* Bridge in structure for RGXRenderContextStalled */
+typedef struct PVRSRV_BRIDGE_IN_RGXRENDERCONTEXTSTALLED_TAG
+{
+ IMG_HANDLE hRenderContext;
+} __packed PVRSRV_BRIDGE_IN_RGXRENDERCONTEXTSTALLED;
+
+/* Bridge out structure for RGXRenderContextStalled */
+typedef struct PVRSRV_BRIDGE_OUT_RGXRENDERCONTEXTSTALLED_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXRENDERCONTEXTSTALLED;
+
+/*******************************************
+ RGXKickTA3D2
+ *******************************************/
+
+/* Bridge in structure for RGXKickTA3D2 */
+typedef struct PVRSRV_BRIDGE_IN_RGXKICKTA3D2_TAG
+{
+ IMG_UINT64 ui64Deadline;
+ IMG_HANDLE hKMHWRTDataSet;
+ IMG_HANDLE hMSAAScratchBuffer;
+ IMG_HANDLE hPRFenceUFOSyncPrimBlock;
+ IMG_HANDLE hRenderContext;
+ IMG_HANDLE hZSBuffer;
+ IMG_UINT32 *pui32Client3DUpdateSyncOffset;
+ IMG_UINT32 *pui32Client3DUpdateValue;
+ IMG_UINT32 *pui32ClientTAFenceSyncOffset;
+ IMG_UINT32 *pui32ClientTAFenceValue;
+ IMG_UINT32 *pui32ClientTAUpdateSyncOffset;
+ IMG_UINT32 *pui32ClientTAUpdateValue;
+ IMG_UINT32 *pui32SyncPMRFlags;
+ IMG_BYTE *pui83DCmd;
+ IMG_BYTE *pui83DPRCmd;
+ IMG_BYTE *pui8TACmd;
+ IMG_CHAR *puiUpdateFenceName;
+ IMG_CHAR *puiUpdateFenceName3D;
+ IMG_HANDLE *phClient3DUpdateSyncPrimBlock;
+ IMG_HANDLE *phClientTAFenceSyncPrimBlock;
+ IMG_HANDLE *phClientTAUpdateSyncPrimBlock;
+ IMG_HANDLE *phSyncPMRs;
+ IMG_BOOL bbAbort;
+ IMG_BOOL bbKick3D;
+ IMG_BOOL bbKickPR;
+ IMG_BOOL bbKickTA;
+ PVRSRV_FENCE hCheckFence;
+ PVRSRV_FENCE hCheckFence3D;
+ PVRSRV_TIMELINE hUpdateTimeline;
+ PVRSRV_TIMELINE hUpdateTimeline3D;
+ IMG_UINT32 ui323DCmdSize;
+ IMG_UINT32 ui323DPRCmdSize;
+ IMG_UINT32 ui32Client3DUpdateCount;
+ IMG_UINT32 ui32ClientCacheOpSeqNum;
+ IMG_UINT32 ui32ClientTAFenceCount;
+ IMG_UINT32 ui32ClientTAUpdateCount;
+ IMG_UINT32 ui32ExtJobRef;
+ IMG_UINT32 ui32FRFenceUFOSyncOffset;
+ IMG_UINT32 ui32FRFenceValue;
+ IMG_UINT32 ui32NumberOfDrawCalls;
+ IMG_UINT32 ui32NumberOfIndices;
+ IMG_UINT32 ui32NumberOfMRTs;
+ IMG_UINT32 ui32PDumpFlags;
+ IMG_UINT32 ui32RenderTargetSize;
+ IMG_UINT32 ui32SyncPMRCount;
+ IMG_UINT32 ui32TACmdSize;
+} __packed PVRSRV_BRIDGE_IN_RGXKICKTA3D2;
+
+/* Bridge out structure for RGXKickTA3D2 */
+typedef struct PVRSRV_BRIDGE_OUT_RGXKICKTA3D2_TAG
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_FENCE hUpdateFence;
+ PVRSRV_FENCE hUpdateFence3D;
+} __packed PVRSRV_BRIDGE_OUT_RGXKICKTA3D2;
+
+/*******************************************
+ RGXSetRenderContextProperty
+ *******************************************/
+
+/* Bridge in structure for RGXSetRenderContextProperty */
+typedef struct PVRSRV_BRIDGE_IN_RGXSETRENDERCONTEXTPROPERTY_TAG
+{
+ IMG_UINT64 ui64Input;
+ IMG_HANDLE hRenderContext;
+ IMG_UINT32 ui32Property;
+} __packed PVRSRV_BRIDGE_IN_RGXSETRENDERCONTEXTPROPERTY;
+
+/* Bridge out structure for RGXSetRenderContextProperty */
+typedef struct PVRSRV_BRIDGE_OUT_RGXSETRENDERCONTEXTPROPERTY_TAG
+{
+ IMG_UINT64 ui64Output;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXSETRENDERCONTEXTPROPERTY;
+
+#endif /* COMMON_RGXTA3D_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_rgxtimerquery_bridge.h b/drivers/gpu/drm/img-rogue/common_rgxtimerquery_bridge.h
new file mode 100644
index 000000000..34d7c2c56
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_rgxtimerquery_bridge.h
@@ -0,0 +1,112 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for rgxtimerquery
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for rgxtimerquery
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_RGXTIMERQUERY_BRIDGE_H
+#define COMMON_RGXTIMERQUERY_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+
+#define PVRSRV_BRIDGE_RGXTIMERQUERY_CMD_FIRST 0
+#define PVRSRV_BRIDGE_RGXTIMERQUERY_RGXBEGINTIMERQUERY PVRSRV_BRIDGE_RGXTIMERQUERY_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RGXTIMERQUERY_RGXENDTIMERQUERY PVRSRV_BRIDGE_RGXTIMERQUERY_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RGXTIMERQUERY_RGXQUERYTIMER PVRSRV_BRIDGE_RGXTIMERQUERY_CMD_FIRST+2
+#define PVRSRV_BRIDGE_RGXTIMERQUERY_CMD_LAST (PVRSRV_BRIDGE_RGXTIMERQUERY_CMD_FIRST+2)
+
+/*******************************************
+ RGXBeginTimerQuery
+ *******************************************/
+
+/* Bridge in structure for RGXBeginTimerQuery */
+typedef struct PVRSRV_BRIDGE_IN_RGXBEGINTIMERQUERY_TAG
+{
+ IMG_UINT32 ui32QueryId;
+} __packed PVRSRV_BRIDGE_IN_RGXBEGINTIMERQUERY;
+
+/* Bridge out structure for RGXBeginTimerQuery */
+typedef struct PVRSRV_BRIDGE_OUT_RGXBEGINTIMERQUERY_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXBEGINTIMERQUERY;
+
+/*******************************************
+ RGXEndTimerQuery
+ *******************************************/
+
+/* Bridge in structure for RGXEndTimerQuery */
+typedef struct PVRSRV_BRIDGE_IN_RGXENDTIMERQUERY_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_RGXENDTIMERQUERY;
+
+/* Bridge out structure for RGXEndTimerQuery */
+typedef struct PVRSRV_BRIDGE_OUT_RGXENDTIMERQUERY_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXENDTIMERQUERY;
+
+/*******************************************
+ RGXQueryTimer
+ *******************************************/
+
+/* Bridge in structure for RGXQueryTimer */
+typedef struct PVRSRV_BRIDGE_IN_RGXQUERYTIMER_TAG
+{
+ IMG_UINT32 ui32QueryId;
+} __packed PVRSRV_BRIDGE_IN_RGXQUERYTIMER;
+
+/* Bridge out structure for RGXQueryTimer */
+typedef struct PVRSRV_BRIDGE_OUT_RGXQUERYTIMER_TAG
+{
+ IMG_UINT64 ui64EndTime;
+ IMG_UINT64 ui64StartTime;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXQUERYTIMER;
+
+#endif /* COMMON_RGXTIMERQUERY_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_rgxtq2_bridge.h b/drivers/gpu/drm/img-rogue/common_rgxtq2_bridge.h
new file mode 100644
index 000000000..c76562780
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_rgxtq2_bridge.h
@@ -0,0 +1,228 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for rgxtq2
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for rgxtq2
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_RGXTQ2_BRIDGE_H
+#define COMMON_RGXTQ2_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+#include "pvrsrv_sync_km.h"
+
+#define PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST 0
+#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMCREATETRANSFERCONTEXT PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMDESTROYTRANSFERCONTEXT PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMSETTRANSFERCONTEXTPRIORITY PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+2
+#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMNOTIFYWRITEOFFSETUPDATE PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+3
+#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMSUBMITTRANSFER2 PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+4
+#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMGETSHAREDMEMORY PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+5
+#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMRELEASESHAREDMEMORY PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+6
+#define PVRSRV_BRIDGE_RGXTQ2_RGXTDMSETTRANSFERCONTEXTPROPERTY PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+7
+#define PVRSRV_BRIDGE_RGXTQ2_CMD_LAST (PVRSRV_BRIDGE_RGXTQ2_CMD_FIRST+7)
+
+/*******************************************
+ RGXTDMCreateTransferContext
+ *******************************************/
+
+/* Bridge in structure for RGXTDMCreateTransferContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXTDMCREATETRANSFERCONTEXT_TAG
+{
+ IMG_HANDLE hPrivData;
+ IMG_BYTE *pui8FrameworkCmd;
+ IMG_UINT32 ui32ContextFlags;
+ IMG_UINT32 ui32FrameworkCmdize;
+ IMG_UINT32 ui32PackedCCBSizeU88;
+ IMG_UINT32 ui32Priority;
+} __packed PVRSRV_BRIDGE_IN_RGXTDMCREATETRANSFERCONTEXT;
+
+/* Bridge out structure for RGXTDMCreateTransferContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXTDMCREATETRANSFERCONTEXT_TAG
+{
+ IMG_HANDLE hTransferContext;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXTDMCREATETRANSFERCONTEXT;
+
+/*******************************************
+ RGXTDMDestroyTransferContext
+ *******************************************/
+
+/* Bridge in structure for RGXTDMDestroyTransferContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXTDMDESTROYTRANSFERCONTEXT_TAG
+{
+ IMG_HANDLE hTransferContext;
+} __packed PVRSRV_BRIDGE_IN_RGXTDMDESTROYTRANSFERCONTEXT;
+
+/* Bridge out structure for RGXTDMDestroyTransferContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXTDMDESTROYTRANSFERCONTEXT_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXTDMDESTROYTRANSFERCONTEXT;
+
+/*******************************************
+ RGXTDMSetTransferContextPriority
+ *******************************************/
+
+/* Bridge in structure for RGXTDMSetTransferContextPriority */
+typedef struct PVRSRV_BRIDGE_IN_RGXTDMSETTRANSFERCONTEXTPRIORITY_TAG
+{
+ IMG_HANDLE hTransferContext;
+ IMG_UINT32 ui32Priority;
+} __packed PVRSRV_BRIDGE_IN_RGXTDMSETTRANSFERCONTEXTPRIORITY;
+
+/* Bridge out structure for RGXTDMSetTransferContextPriority */
+typedef struct PVRSRV_BRIDGE_OUT_RGXTDMSETTRANSFERCONTEXTPRIORITY_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXTDMSETTRANSFERCONTEXTPRIORITY;
+
+/*******************************************
+ RGXTDMNotifyWriteOffsetUpdate
+ *******************************************/
+
+/* Bridge in structure for RGXTDMNotifyWriteOffsetUpdate */
+typedef struct PVRSRV_BRIDGE_IN_RGXTDMNOTIFYWRITEOFFSETUPDATE_TAG
+{
+ IMG_HANDLE hTransferContext;
+ IMG_UINT32 ui32PDumpFlags;
+} __packed PVRSRV_BRIDGE_IN_RGXTDMNOTIFYWRITEOFFSETUPDATE;
+
+/* Bridge out structure for RGXTDMNotifyWriteOffsetUpdate */
+typedef struct PVRSRV_BRIDGE_OUT_RGXTDMNOTIFYWRITEOFFSETUPDATE_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXTDMNOTIFYWRITEOFFSETUPDATE;
+
+/*******************************************
+ RGXTDMSubmitTransfer2
+ *******************************************/
+
+/* Bridge in structure for RGXTDMSubmitTransfer2 */
+typedef struct PVRSRV_BRIDGE_IN_RGXTDMSUBMITTRANSFER2_TAG
+{
+ IMG_UINT64 ui64DeadlineInus;
+ IMG_HANDLE hTransferContext;
+ IMG_UINT32 *pui32SyncPMRFlags;
+ IMG_UINT32 *pui32UpdateSyncOffset;
+ IMG_UINT32 *pui32UpdateValue;
+ IMG_UINT8 *pui8FWCommand;
+ IMG_CHAR *puiUpdateFenceName;
+ IMG_HANDLE *phSyncPMRs;
+ IMG_HANDLE *phUpdateUFOSyncPrimBlock;
+ PVRSRV_FENCE hCheckFenceFD;
+ PVRSRV_TIMELINE hUpdateTimeline;
+ IMG_UINT32 ui32Characteristic1;
+ IMG_UINT32 ui32Characteristic2;
+ IMG_UINT32 ui32ClientCacheOpSeqNum;
+ IMG_UINT32 ui32ClientUpdateCount;
+ IMG_UINT32 ui32CommandSize;
+ IMG_UINT32 ui32ExternalJobReference;
+ IMG_UINT32 ui32PDumpFlags;
+ IMG_UINT32 ui32SyncPMRCount;
+} __packed PVRSRV_BRIDGE_IN_RGXTDMSUBMITTRANSFER2;
+
+/* Bridge out structure for RGXTDMSubmitTransfer2 */
+typedef struct PVRSRV_BRIDGE_OUT_RGXTDMSUBMITTRANSFER2_TAG
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_FENCE hUpdateFence;
+} __packed PVRSRV_BRIDGE_OUT_RGXTDMSUBMITTRANSFER2;
+
+/*******************************************
+ RGXTDMGetSharedMemory
+ *******************************************/
+
+/* Bridge in structure for RGXTDMGetSharedMemory */
+typedef struct PVRSRV_BRIDGE_IN_RGXTDMGETSHAREDMEMORY_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_RGXTDMGETSHAREDMEMORY;
+
+/* Bridge out structure for RGXTDMGetSharedMemory */
+typedef struct PVRSRV_BRIDGE_OUT_RGXTDMGETSHAREDMEMORY_TAG
+{
+ IMG_HANDLE hCLIPMRMem;
+ IMG_HANDLE hUSCPMRMem;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXTDMGETSHAREDMEMORY;
+
+/*******************************************
+ RGXTDMReleaseSharedMemory
+ *******************************************/
+
+/* Bridge in structure for RGXTDMReleaseSharedMemory */
+typedef struct PVRSRV_BRIDGE_IN_RGXTDMRELEASESHAREDMEMORY_TAG
+{
+ IMG_HANDLE hPMRMem;
+} __packed PVRSRV_BRIDGE_IN_RGXTDMRELEASESHAREDMEMORY;
+
+/* Bridge out structure for RGXTDMReleaseSharedMemory */
+typedef struct PVRSRV_BRIDGE_OUT_RGXTDMRELEASESHAREDMEMORY_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXTDMRELEASESHAREDMEMORY;
+
+/*******************************************
+ RGXTDMSetTransferContextProperty
+ *******************************************/
+
+/* Bridge in structure for RGXTDMSetTransferContextProperty */
+typedef struct PVRSRV_BRIDGE_IN_RGXTDMSETTRANSFERCONTEXTPROPERTY_TAG
+{
+ IMG_UINT64 ui64Input;
+ IMG_HANDLE hTransferContext;
+ IMG_UINT32 ui32Property;
+} __packed PVRSRV_BRIDGE_IN_RGXTDMSETTRANSFERCONTEXTPROPERTY;
+
+/* Bridge out structure for RGXTDMSetTransferContextProperty */
+typedef struct PVRSRV_BRIDGE_OUT_RGXTDMSETTRANSFERCONTEXTPROPERTY_TAG
+{
+ IMG_UINT64 ui64Output;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXTDMSETTRANSFERCONTEXTPROPERTY;
+
+#endif /* COMMON_RGXTQ2_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_rgxtq_bridge.h b/drivers/gpu/drm/img-rogue/common_rgxtq_bridge.h
new file mode 100644
index 000000000..ce320bb4c
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_rgxtq_bridge.h
@@ -0,0 +1,176 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for rgxtq
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for rgxtq
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_RGXTQ_BRIDGE_H
+#define COMMON_RGXTQ_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "rgx_bridge.h"
+#include "pvrsrv_sync_km.h"
+
+#define PVRSRV_BRIDGE_RGXTQ_CMD_FIRST 0
+#define PVRSRV_BRIDGE_RGXTQ_RGXCREATETRANSFERCONTEXT PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RGXTQ_RGXDESTROYTRANSFERCONTEXT PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RGXTQ_RGXSETTRANSFERCONTEXTPRIORITY PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+2
+#define PVRSRV_BRIDGE_RGXTQ_RGXSUBMITTRANSFER2 PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+3
+#define PVRSRV_BRIDGE_RGXTQ_RGXSETTRANSFERCONTEXTPROPERTY PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+4
+#define PVRSRV_BRIDGE_RGXTQ_CMD_LAST (PVRSRV_BRIDGE_RGXTQ_CMD_FIRST+4)
+
+/*******************************************
+ RGXCreateTransferContext
+ *******************************************/
+
+/* Bridge in structure for RGXCreateTransferContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXCREATETRANSFERCONTEXT_TAG
+{
+ IMG_HANDLE hPrivData;
+ IMG_BYTE *pui8FrameworkCmd;
+ IMG_UINT32 ui32ContextFlags;
+ IMG_UINT32 ui32FrameworkCmdize;
+ IMG_UINT32 ui32PackedCCBSizeU8888;
+ IMG_UINT32 ui32Priority;
+} __packed PVRSRV_BRIDGE_IN_RGXCREATETRANSFERCONTEXT;
+
+/* Bridge out structure for RGXCreateTransferContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXCREATETRANSFERCONTEXT_TAG
+{
+ IMG_HANDLE hCLIPMRMem;
+ IMG_HANDLE hTransferContext;
+ IMG_HANDLE hUSCPMRMem;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXCREATETRANSFERCONTEXT;
+
+/*******************************************
+ RGXDestroyTransferContext
+ *******************************************/
+
+/* Bridge in structure for RGXDestroyTransferContext */
+typedef struct PVRSRV_BRIDGE_IN_RGXDESTROYTRANSFERCONTEXT_TAG
+{
+ IMG_HANDLE hTransferContext;
+} __packed PVRSRV_BRIDGE_IN_RGXDESTROYTRANSFERCONTEXT;
+
+/* Bridge out structure for RGXDestroyTransferContext */
+typedef struct PVRSRV_BRIDGE_OUT_RGXDESTROYTRANSFERCONTEXT_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXDESTROYTRANSFERCONTEXT;
+
+/*******************************************
+ RGXSetTransferContextPriority
+ *******************************************/
+
+/* Bridge in structure for RGXSetTransferContextPriority */
+typedef struct PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPRIORITY_TAG
+{
+ IMG_HANDLE hTransferContext;
+ IMG_UINT32 ui32Priority;
+} __packed PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPRIORITY;
+
+/* Bridge out structure for RGXSetTransferContextPriority */
+typedef struct PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPRIORITY_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPRIORITY;
+
+/*******************************************
+ RGXSubmitTransfer2
+ *******************************************/
+
+/* Bridge in structure for RGXSubmitTransfer2 */
+typedef struct PVRSRV_BRIDGE_IN_RGXSUBMITTRANSFER2_TAG
+{
+ IMG_HANDLE hTransferContext;
+ IMG_UINT32 *pui32ClientUpdateCount;
+ IMG_UINT32 *pui32CommandSize;
+ IMG_UINT32 *pui32SyncPMRFlags;
+ IMG_UINT32 *pui32TQPrepareFlags;
+ IMG_UINT32 **pui32UpdateSyncOffset;
+ IMG_UINT32 **pui32UpdateValue;
+ IMG_UINT8 **pui8FWCommand;
+ IMG_CHAR *puiUpdateFenceName;
+ IMG_HANDLE *phSyncPMRs;
+ IMG_HANDLE **phUpdateUFOSyncPrimBlock;
+ PVRSRV_TIMELINE h2DUpdateTimeline;
+ PVRSRV_TIMELINE h3DUpdateTimeline;
+ PVRSRV_FENCE hCheckFenceFD;
+ IMG_UINT32 ui32ClientCacheOpSeqNum;
+ IMG_UINT32 ui32ExtJobRef;
+ IMG_UINT32 ui32PrepareCount;
+ IMG_UINT32 ui32SyncPMRCount;
+} __packed PVRSRV_BRIDGE_IN_RGXSUBMITTRANSFER2;
+
+/* Bridge out structure for RGXSubmitTransfer2 */
+typedef struct PVRSRV_BRIDGE_OUT_RGXSUBMITTRANSFER2_TAG
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_FENCE h2DUpdateFence;
+ PVRSRV_FENCE h3DUpdateFence;
+} __packed PVRSRV_BRIDGE_OUT_RGXSUBMITTRANSFER2;
+
+/*******************************************
+ RGXSetTransferContextProperty
+ *******************************************/
+
+/* Bridge in structure for RGXSetTransferContextProperty */
+typedef struct PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPROPERTY_TAG
+{
+ IMG_UINT64 ui64Input;
+ IMG_HANDLE hTransferContext;
+ IMG_UINT32 ui32Property;
+} __packed PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPROPERTY;
+
+/* Bridge out structure for RGXSetTransferContextProperty */
+typedef struct PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPROPERTY_TAG
+{
+ IMG_UINT64 ui64Output;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPROPERTY;
+
+#endif /* COMMON_RGXTQ_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_ri_bridge.h b/drivers/gpu/drm/img-rogue/common_ri_bridge.h
new file mode 100644
index 000000000..ca9b68751
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_ri_bridge.h
@@ -0,0 +1,225 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for ri
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for ri
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_RI_BRIDGE_H
+#define COMMON_RI_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "ri_typedefs.h"
+
+#define PVRSRV_BRIDGE_RI_CMD_FIRST 0
+#define PVRSRV_BRIDGE_RI_RIWRITEPMRENTRY PVRSRV_BRIDGE_RI_CMD_FIRST+0
+#define PVRSRV_BRIDGE_RI_RIWRITEMEMDESCENTRY PVRSRV_BRIDGE_RI_CMD_FIRST+1
+#define PVRSRV_BRIDGE_RI_RIWRITEPROCLISTENTRY PVRSRV_BRIDGE_RI_CMD_FIRST+2
+#define PVRSRV_BRIDGE_RI_RIUPDATEMEMDESCADDR PVRSRV_BRIDGE_RI_CMD_FIRST+3
+#define PVRSRV_BRIDGE_RI_RIDELETEMEMDESCENTRY PVRSRV_BRIDGE_RI_CMD_FIRST+4
+#define PVRSRV_BRIDGE_RI_RIDUMPLIST PVRSRV_BRIDGE_RI_CMD_FIRST+5
+#define PVRSRV_BRIDGE_RI_RIDUMPALL PVRSRV_BRIDGE_RI_CMD_FIRST+6
+#define PVRSRV_BRIDGE_RI_RIDUMPPROCESS PVRSRV_BRIDGE_RI_CMD_FIRST+7
+#define PVRSRV_BRIDGE_RI_RIWRITEPMRENTRYWITHOWNER PVRSRV_BRIDGE_RI_CMD_FIRST+8
+#define PVRSRV_BRIDGE_RI_CMD_LAST (PVRSRV_BRIDGE_RI_CMD_FIRST+8)
+
+/*******************************************
+ RIWritePMREntry
+ *******************************************/
+
+/* Bridge in structure for RIWritePMREntry */
+typedef struct PVRSRV_BRIDGE_IN_RIWRITEPMRENTRY_TAG
+{
+ IMG_HANDLE hPMRHandle;
+} __packed PVRSRV_BRIDGE_IN_RIWRITEPMRENTRY;
+
+/* Bridge out structure for RIWritePMREntry */
+typedef struct PVRSRV_BRIDGE_OUT_RIWRITEPMRENTRY_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RIWRITEPMRENTRY;
+
+/*******************************************
+ RIWriteMEMDESCEntry
+ *******************************************/
+
+/* Bridge in structure for RIWriteMEMDESCEntry */
+typedef struct PVRSRV_BRIDGE_IN_RIWRITEMEMDESCENTRY_TAG
+{
+ IMG_UINT64 ui64Offset;
+ IMG_UINT64 ui64Size;
+ IMG_HANDLE hPMRHandle;
+ const IMG_CHAR *puiTextB;
+ IMG_BOOL bIsImport;
+ IMG_BOOL bIsSuballoc;
+ IMG_UINT32 ui32TextBSize;
+} __packed PVRSRV_BRIDGE_IN_RIWRITEMEMDESCENTRY;
+
+/* Bridge out structure for RIWriteMEMDESCEntry */
+typedef struct PVRSRV_BRIDGE_OUT_RIWRITEMEMDESCENTRY_TAG
+{
+ IMG_HANDLE hRIHandle;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RIWRITEMEMDESCENTRY;
+
+/*******************************************
+ RIWriteProcListEntry
+ *******************************************/
+
+/* Bridge in structure for RIWriteProcListEntry */
+typedef struct PVRSRV_BRIDGE_IN_RIWRITEPROCLISTENTRY_TAG
+{
+ IMG_UINT64 ui64DevVAddr;
+ IMG_UINT64 ui64Size;
+ const IMG_CHAR *puiTextB;
+ IMG_UINT32 ui32TextBSize;
+} __packed PVRSRV_BRIDGE_IN_RIWRITEPROCLISTENTRY;
+
+/* Bridge out structure for RIWriteProcListEntry */
+typedef struct PVRSRV_BRIDGE_OUT_RIWRITEPROCLISTENTRY_TAG
+{
+ IMG_HANDLE hRIHandle;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RIWRITEPROCLISTENTRY;
+
+/*******************************************
+ RIUpdateMEMDESCAddr
+ *******************************************/
+
+/* Bridge in structure for RIUpdateMEMDESCAddr */
+typedef struct PVRSRV_BRIDGE_IN_RIUPDATEMEMDESCADDR_TAG
+{
+ IMG_DEV_VIRTADDR sAddr;
+ IMG_HANDLE hRIHandle;
+} __packed PVRSRV_BRIDGE_IN_RIUPDATEMEMDESCADDR;
+
+/* Bridge out structure for RIUpdateMEMDESCAddr */
+typedef struct PVRSRV_BRIDGE_OUT_RIUPDATEMEMDESCADDR_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RIUPDATEMEMDESCADDR;
+
+/*******************************************
+ RIDeleteMEMDESCEntry
+ *******************************************/
+
+/* Bridge in structure for RIDeleteMEMDESCEntry */
+typedef struct PVRSRV_BRIDGE_IN_RIDELETEMEMDESCENTRY_TAG
+{
+ IMG_HANDLE hRIHandle;
+} __packed PVRSRV_BRIDGE_IN_RIDELETEMEMDESCENTRY;
+
+/* Bridge out structure for RIDeleteMEMDESCEntry */
+typedef struct PVRSRV_BRIDGE_OUT_RIDELETEMEMDESCENTRY_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RIDELETEMEMDESCENTRY;
+
+/*******************************************
+ RIDumpList
+ *******************************************/
+
+/* Bridge in structure for RIDumpList */
+typedef struct PVRSRV_BRIDGE_IN_RIDUMPLIST_TAG
+{
+ IMG_HANDLE hPMRHandle;
+} __packed PVRSRV_BRIDGE_IN_RIDUMPLIST;
+
+/* Bridge out structure for RIDumpList */
+typedef struct PVRSRV_BRIDGE_OUT_RIDUMPLIST_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RIDUMPLIST;
+
+/*******************************************
+ RIDumpAll
+ *******************************************/
+
+/* Bridge in structure for RIDumpAll */
+typedef struct PVRSRV_BRIDGE_IN_RIDUMPALL_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_RIDUMPALL;
+
+/* Bridge out structure for RIDumpAll */
+typedef struct PVRSRV_BRIDGE_OUT_RIDUMPALL_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RIDUMPALL;
+
+/*******************************************
+ RIDumpProcess
+ *******************************************/
+
+/* Bridge in structure for RIDumpProcess */
+typedef struct PVRSRV_BRIDGE_IN_RIDUMPPROCESS_TAG
+{
+ IMG_PID ui32Pid;
+} __packed PVRSRV_BRIDGE_IN_RIDUMPPROCESS;
+
+/* Bridge out structure for RIDumpProcess */
+typedef struct PVRSRV_BRIDGE_OUT_RIDUMPPROCESS_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RIDUMPPROCESS;
+
+/*******************************************
+ RIWritePMREntryWithOwner
+ *******************************************/
+
+/* Bridge in structure for RIWritePMREntryWithOwner */
+typedef struct PVRSRV_BRIDGE_IN_RIWRITEPMRENTRYWITHOWNER_TAG
+{
+ IMG_HANDLE hPMRHandle;
+ IMG_PID ui32Owner;
+} __packed PVRSRV_BRIDGE_IN_RIWRITEPMRENTRYWITHOWNER;
+
+/* Bridge out structure for RIWritePMREntryWithOwner */
+typedef struct PVRSRV_BRIDGE_OUT_RIWRITEPMRENTRYWITHOWNER_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RIWRITEPMRENTRYWITHOWNER;
+
+#endif /* COMMON_RI_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_srvcore_bridge.h b/drivers/gpu/drm/img-rogue/common_srvcore_bridge.h
new file mode 100644
index 000000000..7e9ac6eed
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_srvcore_bridge.h
@@ -0,0 +1,369 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for srvcore
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for srvcore
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_SRVCORE_BRIDGE_H
+#define COMMON_SRVCORE_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "pvrsrv_device_types.h"
+#include "cache_ops.h"
+
+#define PVRSRV_BRIDGE_SRVCORE_CMD_FIRST 0
+#define PVRSRV_BRIDGE_SRVCORE_CONNECT PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+0
+#define PVRSRV_BRIDGE_SRVCORE_DISCONNECT PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+1
+#define PVRSRV_BRIDGE_SRVCORE_ACQUIREGLOBALEVENTOBJECT PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+2
+#define PVRSRV_BRIDGE_SRVCORE_RELEASEGLOBALEVENTOBJECT PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+3
+#define PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTOPEN PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+4
+#define PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTWAIT PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+5
+#define PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTCLOSE PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+6
+#define PVRSRV_BRIDGE_SRVCORE_DUMPDEBUGINFO PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+7
+#define PVRSRV_BRIDGE_SRVCORE_GETDEVCLOCKSPEED PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+8
+#define PVRSRV_BRIDGE_SRVCORE_HWOPTIMEOUT PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+9
+#define PVRSRV_BRIDGE_SRVCORE_ALIGNMENTCHECK PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+10
+#define PVRSRV_BRIDGE_SRVCORE_GETDEVICESTATUS PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+11
+#define PVRSRV_BRIDGE_SRVCORE_GETMULTICOREINFO PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+12
+#define PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTWAITTIMEOUT PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+13
+#define PVRSRV_BRIDGE_SRVCORE_FINDPROCESSMEMSTATS PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+14
+#define PVRSRV_BRIDGE_SRVCORE_ACQUIREINFOPAGE PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+15
+#define PVRSRV_BRIDGE_SRVCORE_RELEASEINFOPAGE PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+16
+#define PVRSRV_BRIDGE_SRVCORE_CMD_LAST (PVRSRV_BRIDGE_SRVCORE_CMD_FIRST+16)
+
+/*******************************************
+ Connect
+ *******************************************/
+
+/* Bridge in structure for Connect */
+typedef struct PVRSRV_BRIDGE_IN_CONNECT_TAG
+{
+ IMG_UINT32 ui32ClientBuildOptions;
+ IMG_UINT32 ui32ClientDDKBuild;
+ IMG_UINT32 ui32ClientDDKVersion;
+ IMG_UINT32 ui32Flags;
+} __packed PVRSRV_BRIDGE_IN_CONNECT;
+
+/* Bridge out structure for Connect */
+typedef struct PVRSRV_BRIDGE_OUT_CONNECT_TAG
+{
+ IMG_UINT64 ui64PackedBvnc;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32CapabilityFlags;
+ IMG_UINT8 ui8KernelArch;
+} __packed PVRSRV_BRIDGE_OUT_CONNECT;
+
+/*******************************************
+ Disconnect
+ *******************************************/
+
+/* Bridge in structure for Disconnect */
+typedef struct PVRSRV_BRIDGE_IN_DISCONNECT_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_DISCONNECT;
+
+/* Bridge out structure for Disconnect */
+typedef struct PVRSRV_BRIDGE_OUT_DISCONNECT_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DISCONNECT;
+
+/*******************************************
+ AcquireGlobalEventObject
+ *******************************************/
+
+/* Bridge in structure for AcquireGlobalEventObject */
+typedef struct PVRSRV_BRIDGE_IN_ACQUIREGLOBALEVENTOBJECT_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_ACQUIREGLOBALEVENTOBJECT;
+
+/* Bridge out structure for AcquireGlobalEventObject */
+typedef struct PVRSRV_BRIDGE_OUT_ACQUIREGLOBALEVENTOBJECT_TAG
+{
+ IMG_HANDLE hGlobalEventObject;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_ACQUIREGLOBALEVENTOBJECT;
+
+/*******************************************
+ ReleaseGlobalEventObject
+ *******************************************/
+
+/* Bridge in structure for ReleaseGlobalEventObject */
+typedef struct PVRSRV_BRIDGE_IN_RELEASEGLOBALEVENTOBJECT_TAG
+{
+ IMG_HANDLE hGlobalEventObject;
+} __packed PVRSRV_BRIDGE_IN_RELEASEGLOBALEVENTOBJECT;
+
+/* Bridge out structure for ReleaseGlobalEventObject */
+typedef struct PVRSRV_BRIDGE_OUT_RELEASEGLOBALEVENTOBJECT_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RELEASEGLOBALEVENTOBJECT;
+
+/*******************************************
+ EventObjectOpen
+ *******************************************/
+
+/* Bridge in structure for EventObjectOpen */
+typedef struct PVRSRV_BRIDGE_IN_EVENTOBJECTOPEN_TAG
+{
+ IMG_HANDLE hEventObject;
+} __packed PVRSRV_BRIDGE_IN_EVENTOBJECTOPEN;
+
+/* Bridge out structure for EventObjectOpen */
+typedef struct PVRSRV_BRIDGE_OUT_EVENTOBJECTOPEN_TAG
+{
+ IMG_HANDLE hOSEvent;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_EVENTOBJECTOPEN;
+
+/*******************************************
+ EventObjectWait
+ *******************************************/
+
+/* Bridge in structure for EventObjectWait */
+typedef struct PVRSRV_BRIDGE_IN_EVENTOBJECTWAIT_TAG
+{
+ IMG_HANDLE hOSEventKM;
+} __packed PVRSRV_BRIDGE_IN_EVENTOBJECTWAIT;
+
+/* Bridge out structure for EventObjectWait */
+typedef struct PVRSRV_BRIDGE_OUT_EVENTOBJECTWAIT_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_EVENTOBJECTWAIT;
+
+/*******************************************
+ EventObjectClose
+ *******************************************/
+
+/* Bridge in structure for EventObjectClose */
+typedef struct PVRSRV_BRIDGE_IN_EVENTOBJECTCLOSE_TAG
+{
+ IMG_HANDLE hOSEventKM;
+} __packed PVRSRV_BRIDGE_IN_EVENTOBJECTCLOSE;
+
+/* Bridge out structure for EventObjectClose */
+typedef struct PVRSRV_BRIDGE_OUT_EVENTOBJECTCLOSE_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_EVENTOBJECTCLOSE;
+
+/*******************************************
+ DumpDebugInfo
+ *******************************************/
+
+/* Bridge in structure for DumpDebugInfo */
+typedef struct PVRSRV_BRIDGE_IN_DUMPDEBUGINFO_TAG
+{
+ IMG_UINT32 ui32VerbLevel;
+} __packed PVRSRV_BRIDGE_IN_DUMPDEBUGINFO;
+
+/* Bridge out structure for DumpDebugInfo */
+typedef struct PVRSRV_BRIDGE_OUT_DUMPDEBUGINFO_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_DUMPDEBUGINFO;
+
+/*******************************************
+ GetDevClockSpeed
+ *******************************************/
+
+/* Bridge in structure for GetDevClockSpeed */
+typedef struct PVRSRV_BRIDGE_IN_GETDEVCLOCKSPEED_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_GETDEVCLOCKSPEED;
+
+/* Bridge out structure for GetDevClockSpeed */
+typedef struct PVRSRV_BRIDGE_OUT_GETDEVCLOCKSPEED_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32ClockSpeed;
+} __packed PVRSRV_BRIDGE_OUT_GETDEVCLOCKSPEED;
+
+/*******************************************
+ HWOpTimeout
+ *******************************************/
+
+/* Bridge in structure for HWOpTimeout */
+typedef struct PVRSRV_BRIDGE_IN_HWOPTIMEOUT_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_HWOPTIMEOUT;
+
+/* Bridge out structure for HWOpTimeout */
+typedef struct PVRSRV_BRIDGE_OUT_HWOPTIMEOUT_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_HWOPTIMEOUT;
+
+/*******************************************
+ AlignmentCheck
+ *******************************************/
+
+/* Bridge in structure for AlignmentCheck */
+typedef struct PVRSRV_BRIDGE_IN_ALIGNMENTCHECK_TAG
+{
+ IMG_UINT32 *pui32AlignChecks;
+ IMG_UINT32 ui32AlignChecksSize;
+} __packed PVRSRV_BRIDGE_IN_ALIGNMENTCHECK;
+
+/* Bridge out structure for AlignmentCheck */
+typedef struct PVRSRV_BRIDGE_OUT_ALIGNMENTCHECK_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_ALIGNMENTCHECK;
+
+/*******************************************
+ GetDeviceStatus
+ *******************************************/
+
+/* Bridge in structure for GetDeviceStatus */
+typedef struct PVRSRV_BRIDGE_IN_GETDEVICESTATUS_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_GETDEVICESTATUS;
+
+/* Bridge out structure for GetDeviceStatus */
+typedef struct PVRSRV_BRIDGE_OUT_GETDEVICESTATUS_TAG
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32DeviceSatus;
+} __packed PVRSRV_BRIDGE_OUT_GETDEVICESTATUS;
+
+/*******************************************
+ GetMultiCoreInfo
+ *******************************************/
+
+/* Bridge in structure for GetMultiCoreInfo */
+typedef struct PVRSRV_BRIDGE_IN_GETMULTICOREINFO_TAG
+{
+ IMG_UINT64 *pui64Caps;
+ IMG_UINT32 ui32CapsSize;
+} __packed PVRSRV_BRIDGE_IN_GETMULTICOREINFO;
+
+/* Bridge out structure for GetMultiCoreInfo */
+typedef struct PVRSRV_BRIDGE_OUT_GETMULTICOREINFO_TAG
+{
+ IMG_UINT64 *pui64Caps;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32NumCores;
+} __packed PVRSRV_BRIDGE_OUT_GETMULTICOREINFO;
+
+/*******************************************
+ EventObjectWaitTimeout
+ *******************************************/
+
+/* Bridge in structure for EventObjectWaitTimeout */
+typedef struct PVRSRV_BRIDGE_IN_EVENTOBJECTWAITTIMEOUT_TAG
+{
+ IMG_UINT64 ui64uiTimeoutus;
+ IMG_HANDLE hOSEventKM;
+} __packed PVRSRV_BRIDGE_IN_EVENTOBJECTWAITTIMEOUT;
+
+/* Bridge out structure for EventObjectWaitTimeout */
+typedef struct PVRSRV_BRIDGE_OUT_EVENTOBJECTWAITTIMEOUT_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_EVENTOBJECTWAITTIMEOUT;
+
+/*******************************************
+ FindProcessMemStats
+ *******************************************/
+
+/* Bridge in structure for FindProcessMemStats */
+typedef struct PVRSRV_BRIDGE_IN_FINDPROCESSMEMSTATS_TAG
+{
+ IMG_UINT32 *pui32MemStatsArray;
+ IMG_BOOL bbAllProcessStats;
+ IMG_UINT32 ui32ArrSize;
+ IMG_UINT32 ui32PID;
+} __packed PVRSRV_BRIDGE_IN_FINDPROCESSMEMSTATS;
+
+/* Bridge out structure for FindProcessMemStats */
+typedef struct PVRSRV_BRIDGE_OUT_FINDPROCESSMEMSTATS_TAG
+{
+ IMG_UINT32 *pui32MemStatsArray;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_FINDPROCESSMEMSTATS;
+
+/*******************************************
+ AcquireInfoPage
+ *******************************************/
+
+/* Bridge in structure for AcquireInfoPage */
+typedef struct PVRSRV_BRIDGE_IN_ACQUIREINFOPAGE_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_ACQUIREINFOPAGE;
+
+/* Bridge out structure for AcquireInfoPage */
+typedef struct PVRSRV_BRIDGE_OUT_ACQUIREINFOPAGE_TAG
+{
+ IMG_HANDLE hPMR;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_ACQUIREINFOPAGE;
+
+/*******************************************
+ ReleaseInfoPage
+ *******************************************/
+
+/* Bridge in structure for ReleaseInfoPage */
+typedef struct PVRSRV_BRIDGE_IN_RELEASEINFOPAGE_TAG
+{
+ IMG_HANDLE hPMR;
+} __packed PVRSRV_BRIDGE_IN_RELEASEINFOPAGE;
+
+/* Bridge out structure for ReleaseInfoPage */
+typedef struct PVRSRV_BRIDGE_OUT_RELEASEINFOPAGE_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_RELEASEINFOPAGE;
+
+#endif /* COMMON_SRVCORE_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_sync_bridge.h b/drivers/gpu/drm/img-rogue/common_sync_bridge.h
new file mode 100644
index 000000000..db48d2e90
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_sync_bridge.h
@@ -0,0 +1,254 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for sync
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for sync
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_SYNC_BRIDGE_H
+#define COMMON_SYNC_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#include "pdump.h"
+#include "pdumpdefs.h"
+#include "devicemem_typedefs.h"
+#include "pvrsrv_sync_km.h"
+#include
+
+#define PVRSRV_BRIDGE_SYNC_CMD_FIRST 0
+#define PVRSRV_BRIDGE_SYNC_ALLOCSYNCPRIMITIVEBLOCK PVRSRV_BRIDGE_SYNC_CMD_FIRST+0
+#define PVRSRV_BRIDGE_SYNC_FREESYNCPRIMITIVEBLOCK PVRSRV_BRIDGE_SYNC_CMD_FIRST+1
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMSET PVRSRV_BRIDGE_SYNC_CMD_FIRST+2
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMP PVRSRV_BRIDGE_SYNC_CMD_FIRST+3
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPVALUE PVRSRV_BRIDGE_SYNC_CMD_FIRST+4
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPPOL PVRSRV_BRIDGE_SYNC_CMD_FIRST+5
+#define PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMPCBP PVRSRV_BRIDGE_SYNC_CMD_FIRST+6
+#define PVRSRV_BRIDGE_SYNC_SYNCALLOCEVENT PVRSRV_BRIDGE_SYNC_CMD_FIRST+7
+#define PVRSRV_BRIDGE_SYNC_SYNCFREEEVENT PVRSRV_BRIDGE_SYNC_CMD_FIRST+8
+#define PVRSRV_BRIDGE_SYNC_SYNCCHECKPOINTSIGNALLEDPDUMPPOL PVRSRV_BRIDGE_SYNC_CMD_FIRST+9
+#define PVRSRV_BRIDGE_SYNC_CMD_LAST (PVRSRV_BRIDGE_SYNC_CMD_FIRST+9)
+
+/*******************************************
+ AllocSyncPrimitiveBlock
+ *******************************************/
+
+/* Bridge in structure for AllocSyncPrimitiveBlock */
+typedef struct PVRSRV_BRIDGE_IN_ALLOCSYNCPRIMITIVEBLOCK_TAG
+{
+ IMG_UINT32 ui32EmptyStructPlaceholder;
+} __packed PVRSRV_BRIDGE_IN_ALLOCSYNCPRIMITIVEBLOCK;
+
+/* Bridge out structure for AllocSyncPrimitiveBlock */
+typedef struct PVRSRV_BRIDGE_OUT_ALLOCSYNCPRIMITIVEBLOCK_TAG
+{
+ IMG_HANDLE hSyncHandle;
+ IMG_HANDLE hhSyncPMR;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32SyncPrimBlockSize;
+ IMG_UINT32 ui32SyncPrimVAddr;
+} __packed PVRSRV_BRIDGE_OUT_ALLOCSYNCPRIMITIVEBLOCK;
+
+/*******************************************
+ FreeSyncPrimitiveBlock
+ *******************************************/
+
+/* Bridge in structure for FreeSyncPrimitiveBlock */
+typedef struct PVRSRV_BRIDGE_IN_FREESYNCPRIMITIVEBLOCK_TAG
+{
+ IMG_HANDLE hSyncHandle;
+} __packed PVRSRV_BRIDGE_IN_FREESYNCPRIMITIVEBLOCK;
+
+/* Bridge out structure for FreeSyncPrimitiveBlock */
+typedef struct PVRSRV_BRIDGE_OUT_FREESYNCPRIMITIVEBLOCK_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_FREESYNCPRIMITIVEBLOCK;
+
+/*******************************************
+ SyncPrimSet
+ *******************************************/
+
+/* Bridge in structure for SyncPrimSet */
+typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMSET_TAG
+{
+ IMG_HANDLE hSyncHandle;
+ IMG_UINT32 ui32Index;
+ IMG_UINT32 ui32Value;
+} __packed PVRSRV_BRIDGE_IN_SYNCPRIMSET;
+
+/* Bridge out structure for SyncPrimSet */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMSET_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_SYNCPRIMSET;
+
+/*******************************************
+ SyncPrimPDump
+ *******************************************/
+
+/* Bridge in structure for SyncPrimPDump */
+typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMPDUMP_TAG
+{
+ IMG_HANDLE hSyncHandle;
+ IMG_UINT32 ui32Offset;
+} __packed PVRSRV_BRIDGE_IN_SYNCPRIMPDUMP;
+
+/* Bridge out structure for SyncPrimPDump */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMP_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMP;
+
+/*******************************************
+ SyncPrimPDumpValue
+ *******************************************/
+
+/* Bridge in structure for SyncPrimPDumpValue */
+typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPVALUE_TAG
+{
+ IMG_HANDLE hSyncHandle;
+ IMG_UINT32 ui32Offset;
+ IMG_UINT32 ui32Value;
+} __packed PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPVALUE;
+
+/* Bridge out structure for SyncPrimPDumpValue */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPVALUE_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPVALUE;
+
+/*******************************************
+ SyncPrimPDumpPol
+ *******************************************/
+
+/* Bridge in structure for SyncPrimPDumpPol */
+typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPPOL_TAG
+{
+ IMG_HANDLE hSyncHandle;
+ PDUMP_POLL_OPERATOR eOperator;
+ IMG_UINT32 ui32Mask;
+ IMG_UINT32 ui32Offset;
+ IMG_UINT32 ui32Value;
+ PDUMP_FLAGS_T uiPDumpFlags;
+} __packed PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPPOL;
+
+/* Bridge out structure for SyncPrimPDumpPol */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPPOL_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPPOL;
+
+/*******************************************
+ SyncPrimPDumpCBP
+ *******************************************/
+
+/* Bridge in structure for SyncPrimPDumpCBP */
+typedef struct PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPCBP_TAG
+{
+ IMG_DEVMEM_SIZE_T uiBufferSize;
+ IMG_DEVMEM_SIZE_T uiPacketSize;
+ IMG_DEVMEM_OFFSET_T uiWriteOffset;
+ IMG_HANDLE hSyncHandle;
+ IMG_UINT32 ui32Offset;
+} __packed PVRSRV_BRIDGE_IN_SYNCPRIMPDUMPCBP;
+
+/* Bridge out structure for SyncPrimPDumpCBP */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPCBP_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMPCBP;
+
+/*******************************************
+ SyncAllocEvent
+ *******************************************/
+
+/* Bridge in structure for SyncAllocEvent */
+typedef struct PVRSRV_BRIDGE_IN_SYNCALLOCEVENT_TAG
+{
+ const IMG_CHAR *puiClassName;
+ IMG_BOOL bServerSync;
+ IMG_UINT32 ui32ClassNameSize;
+ IMG_UINT32 ui32FWAddr;
+} __packed PVRSRV_BRIDGE_IN_SYNCALLOCEVENT;
+
+/* Bridge out structure for SyncAllocEvent */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCALLOCEVENT_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_SYNCALLOCEVENT;
+
+/*******************************************
+ SyncFreeEvent
+ *******************************************/
+
+/* Bridge in structure for SyncFreeEvent */
+typedef struct PVRSRV_BRIDGE_IN_SYNCFREEEVENT_TAG
+{
+ IMG_UINT32 ui32FWAddr;
+} __packed PVRSRV_BRIDGE_IN_SYNCFREEEVENT;
+
+/* Bridge out structure for SyncFreeEvent */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCFREEEVENT_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_SYNCFREEEVENT;
+
+/*******************************************
+ SyncCheckpointSignalledPDumpPol
+ *******************************************/
+
+/* Bridge in structure for SyncCheckpointSignalledPDumpPol */
+typedef struct PVRSRV_BRIDGE_IN_SYNCCHECKPOINTSIGNALLEDPDUMPPOL_TAG
+{
+ PVRSRV_FENCE hFence;
+} __packed PVRSRV_BRIDGE_IN_SYNCCHECKPOINTSIGNALLEDPDUMPPOL;
+
+/* Bridge out structure for SyncCheckpointSignalledPDumpPol */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCCHECKPOINTSIGNALLEDPDUMPPOL_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_SYNCCHECKPOINTSIGNALLEDPDUMPPOL;
+
+#endif /* COMMON_SYNC_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/common_synctracking_bridge.h b/drivers/gpu/drm/img-rogue/common_synctracking_bridge.h
new file mode 100644
index 000000000..036c7dce6
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/common_synctracking_bridge.h
@@ -0,0 +1,97 @@
+/*******************************************************************************
+@File
+@Title Common bridge header for synctracking
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Declares common defines and structures used by both the client
+ and server side of the bridge for synctracking
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*******************************************************************************/
+
+#ifndef COMMON_SYNCTRACKING_BRIDGE_H
+#define COMMON_SYNCTRACKING_BRIDGE_H
+
+#include
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#define PVRSRV_BRIDGE_SYNCTRACKING_CMD_FIRST 0
+#define PVRSRV_BRIDGE_SYNCTRACKING_SYNCRECORDREMOVEBYHANDLE PVRSRV_BRIDGE_SYNCTRACKING_CMD_FIRST+0
+#define PVRSRV_BRIDGE_SYNCTRACKING_SYNCRECORDADD PVRSRV_BRIDGE_SYNCTRACKING_CMD_FIRST+1
+#define PVRSRV_BRIDGE_SYNCTRACKING_CMD_LAST (PVRSRV_BRIDGE_SYNCTRACKING_CMD_FIRST+1)
+
+/*******************************************
+ SyncRecordRemoveByHandle
+ *******************************************/
+
+/* Bridge in structure for SyncRecordRemoveByHandle */
+typedef struct PVRSRV_BRIDGE_IN_SYNCRECORDREMOVEBYHANDLE_TAG
+{
+ IMG_HANDLE hhRecord;
+} __packed PVRSRV_BRIDGE_IN_SYNCRECORDREMOVEBYHANDLE;
+
+/* Bridge out structure for SyncRecordRemoveByHandle */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCRECORDREMOVEBYHANDLE_TAG
+{
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_SYNCRECORDREMOVEBYHANDLE;
+
+/*******************************************
+ SyncRecordAdd
+ *******************************************/
+
+/* Bridge in structure for SyncRecordAdd */
+typedef struct PVRSRV_BRIDGE_IN_SYNCRECORDADD_TAG
+{
+ IMG_HANDLE hhServerSyncPrimBlock;
+ const IMG_CHAR *puiClassName;
+ IMG_BOOL bbServerSync;
+ IMG_UINT32 ui32ClassNameSize;
+ IMG_UINT32 ui32ui32FwBlockAddr;
+ IMG_UINT32 ui32ui32SyncOffset;
+} __packed PVRSRV_BRIDGE_IN_SYNCRECORDADD;
+
+/* Bridge out structure for SyncRecordAdd */
+typedef struct PVRSRV_BRIDGE_OUT_SYNCRECORDADD_TAG
+{
+ IMG_HANDLE hhRecord;
+ PVRSRV_ERROR eError;
+} __packed PVRSRV_BRIDGE_OUT_SYNCRECORDADD;
+
+#endif /* COMMON_SYNCTRACKING_BRIDGE_H */
diff --git a/drivers/gpu/drm/img-rogue/config_kernel.h b/drivers/gpu/drm/img-rogue/config_kernel.h
new file mode 100644
index 000000000..4a3869d62
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/config_kernel.h
@@ -0,0 +1,150 @@
+#define PVRSRV_APPHINT_FIRMWARE_HEAP_POLICY 5
+#define PVRSRV_ENABLE_CCCB_GROW
+#define RGX_FW_FILENAME "rgx.fw"
+#define RGX_SH_FILENAME "rgx.sh"
+#define PVR_BUILD_DIR "thead_linux"
+#define PVR_BUILD_TYPE "release"
+#define PVRSRV_MODNAME "pvrsrvkm"
+#define PVRSYNC_MODNAME "pvr_sync"
+#define SUPPORT_RGX 1
+#define DISPLAY_CONTROLLER drm_nulldisp
+#define RELEASE
+#define RGX_BVNC_CORE_KM_HEADER "cores/rgxcore_km_36.52.104.182.h"
+#define RGX_BNC_CONFIG_KM_HEADER "configs/rgxconfig_km_36.V.104.182.h"
+#define PVRSRV_NEED_PVR_DPF
+#define SUPPORT_PHYSMEM_TEST
+#define SUPPORT_RGXTQ_BRIDGE
+#define PVRSRV_POISON_ON_ALLOC_VALUE 0xd9
+#define PVRSRV_POISON_ON_FREE_VALUE 0x63
+#define RGX_NUM_OS_SUPPORTED 1
+#define RGX_OSID_0_DEFAULT_PRIORITY (1 - 0)
+#define RGX_OSID_1_DEFAULT_PRIORITY (1 - 1)
+#define RGX_OSID_2_DEFAULT_PRIORITY (1 - 2)
+#define RGX_OSID_3_DEFAULT_PRIORITY (1 - 3)
+#define RGX_OSID_4_DEFAULT_PRIORITY (1 - 4)
+#define RGX_OSID_5_DEFAULT_PRIORITY (1 - 5)
+#define RGX_OSID_6_DEFAULT_PRIORITY (1 - 6)
+#define RGX_OSID_7_DEFAULT_PRIORITY (1 - 7)
+#define RGX_HCS_DEFAULT_DEADLINE_MS 0xFFFFFFFFU
+#define PVRSRV_APPHINT_DRIVERMODE 0x7FFFFFFF
+#define RGX_FW_HEAP_SHIFT 25
+#define SUPPORT_POWMON_COMPONENT
+#define PVR_POWER_ACTOR_MEASUREMENT_PERIOD_MS 10U
+#define PVR_POWER_MONITOR_HWPERF
+#define PVR_LDM_PLATFORM_PRE_REGISTERED
+#define PVR_LDM_DRIVER_REGISTRATION_NAME "pvrsrvkm"
+#define PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN 256
+#define ION_DEFAULT_HEAP_NAME "ion_system_heap"
+#define ION_DEFAULT_HEAP_ID_MASK (1 << ION_HEAP_TYPE_SYSTEM)
+#define PVRSRV_APPHINT_HWRDEBUGDUMPLIMIT APPHNT_BLDVAR_DBGDUMPLIMIT
+#define PVRSRV_APPHINT_ENABLETRUSTEDDEVICEACECONFIG IMG_FALSE
+#define PVRSRV_APPHINT_GENERALNON4KHEAPPAGESIZE 0x4000
+#define PVRSRV_APPHINT_HWPERFCLIENTBUFFERSIZE 786432
+#define PVRSRV_APPHINT_ENABLESIGNATURECHECKS APPHNT_BLDVAR_ENABLESIGNATURECHECKS
+#define PVRSRV_APPHINT_SIGNATURECHECKSBUFSIZE RGXFW_SIG_BUFFER_SIZE_MIN
+#define PVRSRV_APPHINT_ENABLEFULLSYNCTRACKING IMG_FALSE
+#define PVRSRV_APPHINT_ENABLEPAGEFAULTDEBUG APPHNT_BLDVAR_ENABLEPAGEFAULTDEBUG
+#define PVRSRV_APPHINT_VALIDATEIRQ 0
+#define PVRSRV_APPHINT_DISABLECLOCKGATING 0
+#define PVRSRV_APPHINT_DISABLEDMOVERLAP 0
+#define PVRSRV_APPHINT_ENABLECDMKILLINGRANDMODE 0
+#define PVRSRV_APPHINT_ENABLERANDOMCONTEXTSWITCH 0
+#define PVRSRV_APPHINT_ENABLESOFTRESETCNTEXTSWITCH 0
+#define PVRSRV_APPHINT_ENABLEFWCONTEXTSWITCH RGXFWIF_INICFG_OS_CTXSWITCH_DM_ALL
+#define PVRSRV_APPHINT_VDMCONTEXTSWITCHMODE RGXFWIF_INICFG_VDM_CTX_STORE_MODE_INDEX
+#define PVRSRV_APPHINT_ENABLERDPOWERISLAND RGX_RD_POWER_ISLAND_DEFAULT
+#define PVRSRV_APPHINT_FIRMWAREPERF FW_PERF_CONF_NONE
+#define PVRSRV_APPHINT_FWCONTEXTSWITCHPROFILE RGXFWIF_CTXSWITCH_PROFILE_MEDIUM_EN
+#define PVRSRV_APPHINT_HWPERFDISABLECUSTOMCOUNTERFILTER 0
+#define PVRSRV_APPHINT_HWPERFFWBUFSIZEINKB 2048
+#define PVRSRV_APPHINT_HWPERFHOSTBUFSIZEINKB 2048
+#define PVRSRV_APPHINT_HWPERFHOSTTHREADTIMEOUTINMS 50
+#define PVRSRV_APPHINT_TFBCCOMPRESSIONCONTROLGROUP 0
+#define PVRSRV_APPHINT_TFBCCOMPRESSIONCONTROLSCHEME 0
+#define PVRSRV_APPHINT_JONESDISABLEMASK 0
+#define PVRSRV_APPHINT_NEWFILTERINGMODE 1
+#define PVRSRV_APPHINT_TRUNCATEMODE 0
+#define PVRSRV_APPHINT_EMUMAXFREQ 0
+#define PVRSRV_APPHINT_GPIOVALIDATIONMODE 0
+#define PVRSRV_APPHINT_RGXBVNC ""
+#define PVRSRV_APPHINT_CLEANUPTHREADPRIORITY 5
+#define PVRSRV_APPHINT_WATCHDOGTHREADPRIORITY 0
+#define PVRSRV_APPHINT_CACHEOPTHREADPRIORITY 1
+#define PVRSRV_APPHINT_ASSERTONHWRTRIGGER IMG_FALSE
+#define PVRSRV_APPHINT_ASSERTOUTOFMEMORY IMG_FALSE
+#define PVRSRV_APPHINT_CHECKMLIST APPHNT_BLDVAR_DEBUG
+#define PVRSRV_APPHINT_DISABLEFEDLOGGING IMG_FALSE
+#define PVRSRV_APPHINT_KCCB_SIZE_LOG2 7
+#define PVRSRV_APPHINT_ENABLEAPM RGX_ACTIVEPM_DEFAULT
+#define PVRSRV_APPHINT_ENABLEHTBLOGGROUP 0
+#define PVRSRV_APPHINT_ENABLELOGGROUP RGXFWIF_LOG_TYPE_NONE
+#define PVRSRV_APPHINT_FIRMWARELOGTYPE 0
+#define PVRSRV_APPHINT_FWTRACEBUFSIZEINDWORDS RGXFW_TRACE_BUF_DEFAULT_SIZE_IN_DWORDS
+#define PVRSRV_APPHINT_FBCDCVERSIONOVERRIDE 0
+#define PVRSRV_APPHINT_HTBOPERATIONMODE HTB_OPMODE_DROPOLDEST
+#define PVRSRV_APPHINT_HTBUFFERSIZE 64
+#define PVRSRV_APPHINT_ENABLEFTRACEGPU IMG_FALSE
+#define PVRSRV_APPHINT_HWPERFFWFILTER 0
+#define PVRSRV_APPHINT_HWPERFHOSTFILTER 0
+#define PVRSRV_APPHINT_HWPERFCLIENTFILTER_SERVICES 0
+#define PVRSRV_APPHINT_HWPERFCLIENTFILTER_EGL 0
+#define PVRSRV_APPHINT_HWPERFCLIENTFILTER_OPENGLES 0
+#define PVRSRV_APPHINT_HWPERFCLIENTFILTER_OPENCL 0
+#define PVRSRV_APPHINT_HWPERFCLIENTFILTER_VULKAN 0
+#define PVRSRV_APPHINT_HWPERFCLIENTFILTER_OPENGL 0
+#define PVRSRV_APPHINT_TIMECORRCLOCK 0
+#define PVRSRV_APPHINT_ENABLEFWPOISONONFREE IMG_FALSE
+#define PVRSRV_APPHINT_FWPOISONONFREEVALUE 0xBD
+#define PVRSRV_APPHINT_ZEROFREELIST IMG_FALSE
+#define PVRSRV_APPHINT_GPUUNITSPOWERCHANGE IMG_FALSE
+#define PVRSRV_APPHINT_DISABLEPDUMPPANIC IMG_FALSE
+#define PVRSRV_APPHINT_CACHEOPCONFIG 0
+#define PVRSRV_APPHINT_CACHEOPUMKMHRESHOLDSIZE 0
+#define PVRSRV_APPHINT_IGNOREHWREPORTEDBVNC IMG_FALSE
+#define PVRSRV_APPHINT_PHYSMEMTESTPASSES APPHNT_PHYSMEMTEST_ENABLE
+#define PVRSRV_APPHINT_TESTSLRINTERVAL 0
+#define PVRSRV_APPHINT_RISCVDMITEST 0
+#define SOC_TIMER_FREQ 20
+#define PDVFS_COM_HOST 1
+#define PDVFS_COM_AP 2
+#define PDVFS_COM_PMC 3
+#define PDVFS_COM_IMG_CLKDIV 4
+#define PDVFS_COM PDVFS_COM_HOST
+#define PVR_GPIO_MODE_GENERAL 1
+#define PVR_GPIO_MODE_POWMON_PIN 2
+#define PVR_GPIO_MODE PVR_GPIO_MODE_GENERAL
+#define PVRSRV_ENABLE_PROCESS_STATS
+#define SUPPORT_USC_BREAKPOINT
+#define RGXFW_SAFETY_WATCHDOG_PERIOD_IN_US 1000000
+#define PVR_ANNOTATION_MAX_LEN 63
+#define SUPPORT_DI_BRG_IMPL
+#define PVR_LINUX_PHYSMEM_MAX_POOL_PAGES 10240
+#define PVR_LINUX_PHYSMEM_MAX_EXCESS_POOL_PAGES 20480
+#define PVR_DIRTY_BYTES_FLUSH_THRESHOLD 524288
+#define PVR_LINUX_HIGHORDER_ALLOCATION_THRESHOLD 256
+#define PVR_LINUX_PHYSMEM_MAX_ALLOC_ORDER_NUM 2
+#define PVR_LINUX_KMALLOC_ALLOCATION_THRESHOLD 16384
+#define SUPPORT_NATIVE_FENCE_SYNC
+#define PVRSRV_STALLED_CCB_ACTION
+#define UPDATE_FENCE_CHECKPOINT_COUNT 1
+#define PVR_DRM_NAME "pvr"
+#define DEVICE_MEMSETCPY_ALIGN_IN_BYTES 16
+#define DISABLE_GPU_FREQUENCY_CALIBRATION
+#define RGX_INITIAL_SLR_HOLDOFF_PERIOD_MS 0
+#define PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_TQ3D 14
+#define PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_TQ2D 14
+#define PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_CDM 13
+#define PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_TA 15
+#define PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_3D 16
+#define PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_KICKSYNC 13
+#define PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_TDM 14
+#define PVRSRV_RGX_LOG2_CLIENT_CCB_SIZE_RDM 13
+#define PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_TQ3D 17
+#define PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_TQ2D 17
+#define PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_CDM 15
+#define PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_TA 16
+#define PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_3D 17
+#define PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_KICKSYNC 13
+#define PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_TDM 17
+#define PVRSRV_RGX_LOG2_CLIENT_CCB_MAX_SIZE_RDM 15
+#define SUPPORT_BUFFER_SYNC 1
diff --git a/drivers/gpu/drm/img-rogue/config_kernel.mk b/drivers/gpu/drm/img-rogue/config_kernel.mk
new file mode 100644
index 000000000..42219560a
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/config_kernel.mk
@@ -0,0 +1,51 @@
+override HOST_PRIMARY_ARCH := host_x86_64
+override HOST_32BIT_ARCH := host_i386
+override HOST_FORCE_32BIT := -m32
+override HOST_ALL_ARCH := host_x86_64 host_i386
+override TARGET_PRIMARY_ARCH := target_riscv64
+override TARGET_SECONDARY_ARCH :=
+override TARGET_ALL_ARCH := target_riscv64
+override TARGET_FORCE_32BIT :=
+override PVR_ARCH := rogue
+override METAG_VERSION_NEEDED := 2.8.1.0.3
+override MIPS_VERSION_NEEDED := 2014.07-1
+override RISCV_VERSION_NEEDED := 1.0.1
+override KERNEL_COMPONENTS := srvkm drm_nulldisp
+override WINDOW_SYSTEM := wayland
+override PVRSRV_MODNAME := pvrsrvkm
+override PVR_BUILD_DIR := thead_linux
+override SUPPORT_RGX := 1
+override DISPLAY_CONTROLLER := drm_nulldisp
+override PVR_SYSTEM := rgx_thead
+override PVR_LOADER :=
+override SORT_BRIDGE_STRUCTS := 1
+override DEBUGLINK := 1
+override SUPPORT_PHYSMEM_TEST := 1
+override RGX_NUM_OS_SUPPORTED := 1
+override VMM_TYPE := stub
+override SUPPORT_POWMON_COMPONENT := 1
+override RGX_TIMECORR_CLOCK := mono
+override PDVFS_COM_HOST := 1
+override PDVFS_COM_AP := 2
+override PDVFS_COM_PMC := 3
+override PDVFS_COM_IMG_CLKDIV := 4
+override PDVFS_COM := PDVFS_COM_HOST
+override PVR_GPIO_MODE_GENERAL := 1
+override PVR_GPIO_MODE_POWMON_PIN := 2
+override PVR_GPIO_MODE := PVR_GPIO_MODE_GENERAL
+override PVR_HANDLE_BACKEND := idr
+override SUPPORT_DMABUF_BRIDGE := 1
+override SUPPORT_USC_BREAKPOINT := 1
+override SUPPORT_DI_BRG_IMPL := 1
+override SUPPORT_NATIVE_FENCE_SYNC := 1
+override SUPPORT_DMA_FENCE := 1
+override SUPPORT_BUFFER_SYNC := 1
+ifeq ($(CONFIG_DRM_POWERVR_ROGUE_DEBUG),y)
+override BUILD := debug
+override PVRSRV_ENABLE_GPU_MEMORY_INFO := 1
+override PVR_BUILD_TYPE := debug
+else
+override BUILD := release
+override PVR_BUILD_TYPE := release
+endif
+
diff --git a/drivers/gpu/drm/img-rogue/configs/rgxconfig_km_1.V.4.5.h b/drivers/gpu/drm/img-rogue/configs/rgxconfig_km_1.V.4.5.h
new file mode 100644
index 000000000..44be042e7
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/configs/rgxconfig_km_1.V.4.5.h
@@ -0,0 +1,78 @@
+/*************************************************************************/ /*!
+@Title RGX Configuration for BVNC 1.V.4.5 (kernel defines)
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef RGXCONFIG_KM_1_V_4_5_H
+#define RGXCONFIG_KM_1_V_4_5_H
+
+/***** Automatically generated file. Do not edit manually ********************/
+
+/******************************************************************************
+ * B.V.N.C Validation defines
+ *****************************************************************************/
+#define RGX_BNC_KM_B 1
+#define RGX_BNC_KM_N 4
+#define RGX_BNC_KM_C 5
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_CDM_CONTROL_STREAM_FORMAT (1U)
+#define RGX_FEATURE_COMPUTE
+#define RGX_FEATURE_COMPUTE_OVERLAP
+#define RGX_FEATURE_FBCDC_ALGORITHM (1U)
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (1U)
+#define RGX_FEATURE_GS_RTA_SUPPORT
+#define RGX_FEATURE_LAYOUT_MARS (0U)
+#define RGX_FEATURE_META (MTP218)
+#define RGX_FEATURE_META_COREMEM_SIZE (0U)
+#define RGX_FEATURE_NUM_CLUSTERS (4U)
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (3U)
+#define RGX_FEATURE_NUM_RASTER_PIPES (1U)
+#define RGX_FEATURE_PERFBUS
+#define RGX_FEATURE_PHYS_BUS_WIDTH (40U)
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512U)
+#define RGX_FEATURE_SLC_SIZE_IN_KILOBYTES (128U)
+#define RGX_FEATURE_TILE_SIZE_X (32U)
+#define RGX_FEATURE_TILE_SIZE_Y (32U)
+#define RGX_FEATURE_TLA
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40U)
+
+#endif /* RGXCONFIG_KM_1_V_4_5_H */
diff --git a/drivers/gpu/drm/img-rogue/configs/rgxconfig_km_36.V.104.182.h b/drivers/gpu/drm/img-rogue/configs/rgxconfig_km_36.V.104.182.h
new file mode 100644
index 000000000..cb251a8c7
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/configs/rgxconfig_km_36.V.104.182.h
@@ -0,0 +1,101 @@
+/*************************************************************************/ /*!
+@Title RGX Configuration for BVNC 36.V.104.182 (kernel defines)
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef RGXCONFIG_KM_36_V_104_182_H
+#define RGXCONFIG_KM_36_V_104_182_H
+
+/***** Automatically generated file. Do not edit manually ********************/
+
+/******************************************************************************
+ * B.V.N.C Validation defines
+ *****************************************************************************/
+#define RGX_BNC_KM_B 36
+#define RGX_BNC_KM_N 104
+#define RGX_BNC_KM_C 182
+
+/******************************************************************************
+ * DDK Defines
+ *****************************************************************************/
+#define RGX_FEATURE_AXI_ACELITE
+#define RGX_FEATURE_CDM_CONTROL_STREAM_FORMAT (1U)
+#define RGX_FEATURE_COMPUTE
+#define RGX_FEATURE_COMPUTE_OVERLAP
+#define RGX_FEATURE_COREID_PER_OS
+#define RGX_FEATURE_FBCDC (50U)
+#define RGX_FEATURE_FBCDC_ALGORITHM (50U)
+#define RGX_FEATURE_FBCDC_ARCHITECTURE (7U)
+#define RGX_FEATURE_GPU_MULTICORE_SUPPORT
+#define RGX_FEATURE_GPU_VIRTUALISATION
+#define RGX_FEATURE_GS_RTA_SUPPORT
+#define RGX_FEATURE_IRQ_PER_OS
+#define RGX_FEATURE_LAYOUT_MARS (1U)
+#define RGX_FEATURE_MIPS
+#define RGX_FEATURE_NUM_CLUSTERS (1U)
+#define RGX_FEATURE_NUM_ISP_IPP_PIPES (6U)
+#define RGX_FEATURE_NUM_OSIDS (8U)
+#define RGX_FEATURE_NUM_RASTER_PIPES (1U)
+#define RGX_FEATURE_PBE2_IN_XE
+#define RGX_FEATURE_PBVNC_COREID_REG
+#define RGX_FEATURE_PERFBUS
+#define RGX_FEATURE_PHYS_BUS_WIDTH (36U)
+#define RGX_FEATURE_ROGUEXE
+#define RGX_FEATURE_SIMPLE_INTERNAL_PARAMETER_FORMAT
+#define RGX_FEATURE_SIMPLE_INTERNAL_PARAMETER_FORMAT_V2
+#define RGX_FEATURE_SIMPLE_PARAMETER_FORMAT_VERSION (2U)
+#define RGX_FEATURE_SLC_BANKS (1U)
+#define RGX_FEATURE_SLC_CACHE_LINE_SIZE_BITS (512U)
+#define RGX_FEATURE_SLC_SIZE_CONFIGURABLE /* Specifies the SLC is */
+ /* customer-configurable. True SLC */
+ /* size must be sourced from */
+ /* register. */
+#define RGX_FEATURE_SLC_SIZE_IN_KILOBYTES (16U)
+#define RGX_FEATURE_SYS_BUS_SECURE_RESET
+#define RGX_FEATURE_TILE_SIZE_X (16U)
+#define RGX_FEATURE_TILE_SIZE_Y (16U)
+#define RGX_FEATURE_TPU_CEM_DATAMASTER_GLOBAL_REGISTERS
+#define RGX_FEATURE_TPU_DM_GLOBAL_REGISTERS
+#define RGX_FEATURE_VIRTUAL_ADDRESS_SPACE_BITS (40U)
+#define RGX_FEATURE_XE_MEMORY_HIERARCHY
+#define RGX_FEATURE_XPU_MAX_REGBANKS_ADDR_WIDTH (19U)
+#define RGX_FEATURE_XPU_MAX_SLAVES (3U)
+#define RGX_FEATURE_XPU_REGISTER_BROADCAST (1U)
+
+#endif /* RGXCONFIG_KM_36_V_104_182_H */
diff --git a/drivers/gpu/drm/img-rogue/connection_server.c b/drivers/gpu/drm/img-rogue/connection_server.c
new file mode 100644
index 000000000..3c6ab13cb
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/connection_server.c
@@ -0,0 +1,540 @@
+/*************************************************************************/ /*!
+@File
+@Title Server side connection management
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Handles connections coming from the client and the management
+ connection based information
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "handle.h"
+#include "pvrsrv.h"
+#include "connection_server.h"
+#include "osconnection_server.h"
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "sync_server.h"
+#include "process_stats.h"
+#include "pdump_km.h"
+#include "osfunc.h"
+#include "tlstream.h"
+
+/* PID associated with Connection currently being purged by Cleanup thread */
+static IMG_PID gCurrentPurgeConnectionPid;
+
+static PVRSRV_ERROR ConnectionDataDestroy(CONNECTION_DATA *psConnection)
+{
+ PVRSRV_ERROR eError;
+ PROCESS_HANDLE_BASE *psProcessHandleBase;
+ IMG_UINT64 ui64MaxBridgeTime;
+ PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+ if (psPVRSRVData->bUnload)
+ {
+ /* driver is unloading so do not allow the bridge lock to be released */
+ ui64MaxBridgeTime = 0;
+ }
+ else
+ {
+ ui64MaxBridgeTime = CONNECTION_DEFERRED_CLEANUP_TIMESLICE_NS;
+ }
+
+ PVR_ASSERT(psConnection != NULL);
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psConnection, "psConnection");
+
+ /* Close HWPerfClient stream here even though we created it in
+ * PVRSRVConnectKM(). */
+ if (psConnection->hClientTLStream)
+ {
+ TLStreamClose(psConnection->hClientTLStream);
+ psConnection->hClientTLStream = NULL;
+ PVR_DPF((PVR_DBG_MESSAGE, "Destroyed private stream."));
+ }
+
+ /* Get process handle base to decrement the refcount */
+ psProcessHandleBase = psConnection->psProcessHandleBase;
+
+ if (psProcessHandleBase != NULL)
+ {
+ /* acquire the lock now to ensure unref and removal from the
+ * hash table is atomic.
+ * if the refcount becomes zero then the lock needs to be held
+ * until the entry is removed from the hash table.
+ */
+ OSLockAcquire(psPVRSRVData->hProcessHandleBase_Lock);
+
+ /* In case the refcount becomes 0 we can remove the process handle base */
+ if (OSAtomicDecrement(&psProcessHandleBase->iRefCount) == 0)
+ {
+ uintptr_t uiHashValue;
+
+ uiHashValue = HASH_Remove(psPVRSRVData->psProcessHandleBase_Table, psConnection->pid);
+ OSLockRelease(psPVRSRVData->hProcessHandleBase_Lock);
+
+ if (!uiHashValue)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Failed to remove handle base from hash table.",
+ __func__));
+ return PVRSRV_ERROR_UNABLE_TO_REMOVE_HASH_VALUE;
+ }
+
+ eError = PVRSRVFreeKernelHandles(psProcessHandleBase->psHandleBase);
+ PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVFreeKernelHandles");
+
+ eError = PVRSRVFreeHandleBase(psProcessHandleBase->psHandleBase, ui64MaxBridgeTime);
+ PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVFreeHandleBase:1");
+
+ OSFreeMem(psProcessHandleBase);
+ }
+ else
+ {
+ OSLockRelease(psPVRSRVData->hProcessHandleBase_Lock);
+ }
+
+ psConnection->psProcessHandleBase = NULL;
+ }
+
+ /* Free handle base for this connection */
+ if (psConnection->psHandleBase != NULL)
+ {
+ eError = PVRSRVFreeHandleBase(psConnection->psHandleBase, ui64MaxBridgeTime);
+ /*
+ * If we get PVRSRV_ERROR_RETRY we need to pass this back to the caller
+ * who will schedule a retry.
+ * Do not log this as it is an expected exception.
+ * This can occur if the Firmware is still processing a workload from
+ * the client when a tear-down request is received.
+ * Retrying will allow the in-flight work to be completed and the
+ * tear-down request can be completed when the FW is no longer busy.
+ */
+ if (PVRSRV_ERROR_RETRY == eError)
+ {
+ return eError;
+ }
+ else
+ {
+ PVR_LOG_RETURN_IF_ERROR(eError, "PVRSRVFreeHandleBase:2");
+ }
+
+ psConnection->psHandleBase = NULL;
+ }
+
+ if (psConnection->psSyncConnectionData != NULL)
+ {
+ SyncUnregisterConnection(psConnection->psSyncConnectionData);
+ psConnection->psSyncConnectionData = NULL;
+ }
+
+ if (psConnection->psPDumpConnectionData != NULL)
+ {
+ PDumpUnregisterConnection(psConnection->psPDumpConnectionData);
+ psConnection->psPDumpConnectionData = NULL;
+ }
+
+ /* Call environment specific connection data deinit function */
+ if (psConnection->hOsPrivateData != NULL)
+ {
+ eError = OSConnectionPrivateDataDeInit(psConnection->hOsPrivateData);
+ PVR_LOG_RETURN_IF_ERROR(eError, "OSConnectionPrivateDataDeInit");
+
+ psConnection->hOsPrivateData = NULL;
+ }
+
+ /* Close the PID stats entry as late as possible to catch all frees */
+#if defined(PVRSRV_ENABLE_PROCESS_STATS) && !defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS)
+ if (psConnection->hProcessStats != NULL)
+ {
+ PVRSRVStatsDeregisterProcess(psConnection->hProcessStats);
+ psConnection->hProcessStats = NULL;
+ }
+#endif
+
+ OSFreeMemNoStats(psConnection);
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PVRSRVCommonConnectionConnect(void **ppvPrivData, void *pvOSData)
+{
+ CONNECTION_DATA *psConnection;
+ PVRSRV_ERROR eError;
+ PROCESS_HANDLE_BASE *psProcessHandleBase;
+ PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+ /* Allocate connection data area, no stats since process not registered yet */
+ psConnection = OSAllocZMemNoStats(sizeof(*psConnection));
+ PVR_LOG_RETURN_IF_NOMEM(psConnection, "psConnection");
+
+ /* Allocate process statistics as early as possible to catch all allocs */
+#if defined(PVRSRV_ENABLE_PROCESS_STATS) && !defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS)
+ eError = PVRSRVStatsRegisterProcess(&psConnection->hProcessStats);
+ PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVStatsRegisterProcess", failure);
+#endif
+
+ /* Call environment specific connection data init function */
+ eError = OSConnectionPrivateDataInit(&psConnection->hOsPrivateData, pvOSData);
+ PVR_LOG_GOTO_IF_ERROR(eError, "OSConnectionPrivateDataInit", failure);
+
+ psConnection->pid = OSGetCurrentClientProcessIDKM();
+ psConnection->vpid = OSGetCurrentVirtualProcessID();
+ psConnection->tid = (IMG_UINT32)OSGetCurrentClientThreadIDKM();
+ OSStringLCopy(psConnection->pszProcName, OSGetCurrentClientProcessNameKM(), PVRSRV_CONNECTION_PROCESS_NAME_LEN);
+
+#if defined(SUPPORT_DMA_TRANSFER)
+ OSLockCreate(&psConnection->hDmaReqLock);
+
+ eError = OSEventObjectCreate("Dma transfer cleanup event object",
+ &psConnection->hDmaEventObject);
+ PVR_LOG_GOTO_IF_ERROR(eError, "OSEventObjectCreate", failure);
+
+ OSAtomicWrite(&psConnection->ui32NumDmaTransfersInFlight, 0);
+ psConnection->bAcceptDmaRequests = IMG_TRUE;
+#endif
+
+ /* Register this connection with the sync core */
+ eError = SyncRegisterConnection(&psConnection->psSyncConnectionData);
+ PVR_LOG_GOTO_IF_ERROR(eError, "SyncRegisterConnection", failure);
+
+ /*
+ * Register this connection and Sync PDump callback with
+ * the pdump core. Pass in the Sync connection data.
+ */
+ eError = PDumpRegisterConnection(psConnection->psSyncConnectionData,
+ SyncConnectionPDumpSyncBlocks,
+ &psConnection->psPDumpConnectionData);
+ PVR_LOG_GOTO_IF_ERROR(eError, "PDumpRegisterConnection", failure);
+
+ /* Allocate handle base for this connection */
+ eError = PVRSRVAllocHandleBase(&psConnection->psHandleBase,
+ PVRSRV_HANDLE_BASE_TYPE_CONNECTION);
+ PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVAllocHandleBase", failure);
+
+ /* Try to get process handle base if it already exists */
+ OSLockAcquire(psPVRSRVData->hProcessHandleBase_Lock);
+ psProcessHandleBase = (PROCESS_HANDLE_BASE*) HASH_Retrieve(PVRSRVGetPVRSRVData()->psProcessHandleBase_Table,
+ psConnection->pid);
+
+ /* In case there is none we are going to allocate one */
+ if (psProcessHandleBase == NULL)
+ {
+ psProcessHandleBase = OSAllocZMem(sizeof(PROCESS_HANDLE_BASE));
+ PVR_LOG_GOTO_IF_NOMEM(psProcessHandleBase, eError, failureLock);
+
+ OSAtomicWrite(&psProcessHandleBase->iRefCount, 0);
+
+ /* Allocate handle base for this process */
+ eError = PVRSRVAllocHandleBase(&psProcessHandleBase->psHandleBase,
+ PVRSRV_HANDLE_BASE_TYPE_PROCESS);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_LOG_ERROR(eError, "PVRSRVAllocHandleBase");
+ OSFreeMem(psProcessHandleBase);
+ goto failureLock;
+ }
+
+ /* Insert the handle base into the global hash table */
+ if (!HASH_Insert(PVRSRVGetPVRSRVData()->psProcessHandleBase_Table,
+ psConnection->pid,
+ (uintptr_t) psProcessHandleBase))
+ {
+ PVRSRVFreeHandleBase(psProcessHandleBase->psHandleBase, 0);
+
+ OSFreeMem(psProcessHandleBase);
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_UNABLE_TO_INSERT_HASH_VALUE, failureLock);
+ }
+ }
+ OSAtomicIncrement(&psProcessHandleBase->iRefCount);
+
+ OSLockRelease(psPVRSRVData->hProcessHandleBase_Lock);
+
+ /* hConnectionsLock now resides in PVRSRV_DEVICE_NODE */
+ {
+ PVRSRV_DEVICE_NODE *psDevNode = OSGetDevNode(psConnection);
+
+ OSLockAcquire(psDevNode->hConnectionsLock);
+ dllist_add_to_tail(&psDevNode->sConnections, &psConnection->sConnectionListNode);
+#if defined(DEBUG) || defined(PDUMP)
+ PVR_LOG(("%s connected - (devID = %u)", psConnection->pszProcName,
+ psDevNode->sDevId.ui32InternalID));
+#endif
+ OSLockRelease(psDevNode->hConnectionsLock);
+ }
+
+ psConnection->psProcessHandleBase = psProcessHandleBase;
+
+ *ppvPrivData = psConnection;
+
+ return PVRSRV_OK;
+
+failureLock:
+ OSLockRelease(psPVRSRVData->hProcessHandleBase_Lock);
+failure:
+ ConnectionDataDestroy(psConnection);
+
+ return eError;
+}
+
+static PVRSRV_ERROR _CleanupThreadPurgeConnectionData(void *pvConnectionData)
+{
+ PVRSRV_ERROR eErrorConnection, eErrorKernel;
+ CONNECTION_DATA *psConnectionData = pvConnectionData;
+
+ gCurrentPurgeConnectionPid = psConnectionData->pid;
+
+ eErrorConnection = ConnectionDataDestroy(psConnectionData);
+ if (eErrorConnection != PVRSRV_OK)
+ {
+ if (eErrorConnection == PVRSRV_ERROR_RETRY)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "%s: Failed to purge connection data %p "
+ "(deferring destruction)",
+ __func__,
+ psConnectionData));
+ }
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "%s: Connection data %p deferred destruction finished",
+ __func__,
+ psConnectionData));
+ }
+
+ /* Check if possible resize the global handle base */
+ eErrorKernel = PVRSRVPurgeHandles(KERNEL_HANDLE_BASE);
+ PVR_LOG_IF_ERROR(eErrorKernel, "PVRSRVPurgeHandles");
+
+ gCurrentPurgeConnectionPid = 0;
+
+ return eErrorConnection;
+}
+
+#if defined(SUPPORT_DMA_TRANSFER)
+static void WaitForOutstandingDma(CONNECTION_DATA *psConnectionData)
+{
+
+ PVRSRV_ERROR eError;
+ IMG_HANDLE hEvent;
+ IMG_UINT32 ui32Tries = 100;
+
+#if defined(DMA_VERBOSE)
+ PVR_DPF((PVR_DBG_ERROR,
+ "Waiting on %d DMA transfers in flight...", OSAtomicRead(&psConnectionData->ui32NumDmaTransfersInFlight)));
+#endif
+
+ eError = OSEventObjectOpen(psConnectionData->hDmaEventObject, &hEvent);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to open event object", __func__));
+ return;
+ }
+
+ while (OSAtomicRead(&psConnectionData->ui32NumDmaTransfersInFlight) != 0)
+ {
+ /*
+ #define DMA_TRANSFER_TIMEOUT_US (5000000ULL)
+
+ This currently doesn't work properly. Wait time is not as requested.
+ Using OSSleepms instead
+
+ OSEventObjectWaitKernel(hEvent, DMA_TRANSFER_TIMEOUT_US);
+ */
+ OSSleepms(50);
+ if (!ui32Tries)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Timeout while waiting on outstanding DMA transfers!", __func__));
+ break;
+ }
+
+ ui32Tries--;
+ }
+
+ OSEventObjectClose(hEvent);
+}
+#endif
+
+void PVRSRVCommonConnectionDisconnect(void *pvDataPtr)
+{
+ CONNECTION_DATA *psConnectionData = pvDataPtr;
+ PVRSRV_DEVICE_NODE *psDevNode = OSGetDevNode(psConnectionData);
+
+ OSLockAcquire(psDevNode->hConnectionsLock);
+ dllist_remove_node(&psConnectionData->sConnectionListNode);
+ OSLockRelease(psDevNode->hConnectionsLock);
+
+ /* Notify the PDump core if the pdump control client is disconnecting */
+ if (psConnectionData->ui32ClientFlags & SRV_FLAGS_PDUMPCTRL)
+ {
+ PDumpDisconnectionNotify(psDevNode);
+ }
+#if defined(SUPPORT_DMA_TRANSFER)
+ OSLockAcquire(psConnectionData->hDmaReqLock);
+
+ psConnectionData->bAcceptDmaRequests = IMG_FALSE;
+
+ OSLockRelease(psConnectionData->hDmaReqLock);
+
+ WaitForOutstandingDma(psConnectionData);
+
+ OSEventObjectDestroy(psConnectionData->hDmaEventObject);
+ OSLockDestroy(psConnectionData->hDmaReqLock);
+#endif
+
+#if defined(DEBUG) || defined(PDUMP)
+ PVR_LOG(("%s disconnected - (devID = %u)", psConnectionData->pszProcName,
+ psDevNode->sDevId.ui32InternalID));
+#endif
+
+#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE)
+ if (PVRSRVGetPVRSRVData()->eServicesState == PVRSRV_SERVICES_STATE_OK)
+#endif
+ {
+ /* Defer the release of the connection data */
+ psConnectionData->sCleanupThreadFn.pfnFree = _CleanupThreadPurgeConnectionData;
+ psConnectionData->sCleanupThreadFn.pvData = psConnectionData;
+ psConnectionData->sCleanupThreadFn.bDependsOnHW = IMG_FALSE;
+ CLEANUP_THREAD_SET_RETRY_COUNT(&psConnectionData->sCleanupThreadFn,
+ CLEANUP_THREAD_RETRY_COUNT_DEFAULT);
+ PVRSRVCleanupThreadAddWork(&psConnectionData->sCleanupThreadFn);
+ }
+}
+
+IMG_PID PVRSRVGetPurgeConnectionPid(void)
+{
+ return gCurrentPurgeConnectionPid;
+}
+
+/* Prefix for debug messages about Active Connections */
+#define DEBUG_DUMP_CONNECTION_FORMAT_STR " P%d-V%d-T%d-%s,"
+#define CONNECTIONS_PREFIX "Connections Device ID:%u(%d)"
+#define MAX_CONNECTIONS_PREFIX (29)
+#define MAX_DEBUG_DUMP_CONNECTION_STR_LEN (1+10+10+10+7+PVRSRV_CONNECTION_PROCESS_NAME_LEN)
+#define MAX_DEBUG_DUMP_STRING_LEN (1+MAX_CONNECTIONS_PREFIX+(3*MAX_DEBUG_DUMP_CONNECTION_STR_LEN))
+
+void PVRSRVConnectionDebugNotify(PVRSRV_DEVICE_NODE *psDevNode,
+ DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+ void *pvDumpDebugFile)
+{
+ PDLLIST_NODE pNext, pNode;
+
+ /* We must check for an initialised device before accessing its mutex.
+ * The mutex is initialised as part of DeviceInitialize() which occurs
+ * on first access to the device node.
+ */
+ if (psDevNode->eDevState != PVRSRV_DEVICE_STATE_ACTIVE)
+ {
+ PVR_DUMPDEBUG_LOG("Connections: No Devices: No active connections");
+ }
+ else
+ {
+ OSLockAcquire(psDevNode->hConnectionsLock);
+ if (dllist_is_empty(&psDevNode->sConnections))
+ {
+ PVR_DUMPDEBUG_LOG(CONNECTIONS_PREFIX " No active connections",
+ (unsigned char)psDevNode->sDevId.ui32InternalID,
+ (unsigned char)psDevNode->sDevId.i32OsDeviceID);
+ }
+ else
+ {
+ IMG_CHAR sActiveConnections[MAX_DEBUG_DUMP_STRING_LEN];
+ IMG_UINT16 i, uiPos = 0;
+ IMG_BOOL bPrinted = IMG_FALSE;
+ size_t uiSize = sizeof(sActiveConnections);
+
+ IMG_CHAR szTmpConBuff[MAX_CONNECTIONS_PREFIX + 1];
+ i = OSSNPrintf(szTmpConBuff,
+ MAX_CONNECTIONS_PREFIX,
+ CONNECTIONS_PREFIX,
+ (unsigned char)psDevNode->sDevId.ui32InternalID,
+ (unsigned char)psDevNode->sDevId.i32OsDeviceID);
+ OSStringLCopy(sActiveConnections+uiPos, szTmpConBuff, uiSize);
+
+ /* Move the write offset to the end of the current string */
+ uiPos += i;
+ /* Update the amount of remaining space available to copy into */
+ uiSize -= i;
+
+ dllist_foreach_node(&psDevNode->sConnections, pNode, pNext)
+ {
+ CONNECTION_DATA *sData = IMG_CONTAINER_OF(pNode, CONNECTION_DATA, sConnectionListNode);
+
+ IMG_CHAR sTmpBuff[MAX_DEBUG_DUMP_CONNECTION_STR_LEN];
+ i = OSSNPrintf(sTmpBuff, MAX_DEBUG_DUMP_CONNECTION_STR_LEN,
+ DEBUG_DUMP_CONNECTION_FORMAT_STR, sData->pid, sData->vpid, sData->tid, sData->pszProcName);
+ i = MIN(MAX_DEBUG_DUMP_CONNECTION_STR_LEN, i);
+ bPrinted = IMG_FALSE;
+
+ OSStringLCopy(sActiveConnections+uiPos, sTmpBuff, uiSize);
+
+ /* Move the write offset to the end of the current string */
+ uiPos += i;
+ /* Update the amount of remaining space available to copy into */
+ uiSize -= i;
+
+ /* If there is not enough space to add another connection to this line, output the line */
+ if (uiSize <= MAX_DEBUG_DUMP_CONNECTION_STR_LEN)
+ {
+ PVR_DUMPDEBUG_LOG("%s", sActiveConnections);
+
+ /*
+ * Remove the "Connections:" prefix from the buffer.
+ * Leave the subsequent buffer contents indented by the same
+ * amount to aid in interpreting the debug output.
+ */
+ uiPos = sizeof(CONNECTIONS_PREFIX) - 1;
+ /* Reset the amount of space available to copy into */
+ uiSize = MAX_DEBUG_DUMP_STRING_LEN - uiPos;
+ bPrinted = IMG_TRUE;
+ }
+ }
+
+ /* Only print the current line if it hasn't already been printed */
+ if (!bPrinted)
+ {
+ // Strip of the final comma
+ sActiveConnections[OSStringNLength(sActiveConnections, MAX_DEBUG_DUMP_STRING_LEN) - 1] = '\0';
+ PVR_DUMPDEBUG_LOG("%s", sActiveConnections);
+ }
+#undef MAX_DEBUG_DUMP_STRING_LEN
+#undef MAX_DEBUG_DUMP_CONNECTIONS_PER_LINE
+ }
+ OSLockRelease(psDevNode->hConnectionsLock);
+ }
+}
diff --git a/drivers/gpu/drm/img-rogue/connection_server.h b/drivers/gpu/drm/img-rogue/connection_server.h
new file mode 100644
index 000000000..27b2d1aad
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/connection_server.h
@@ -0,0 +1,135 @@
+/*************************************************************************/ /*!
+@File
+@Title Server side connection management
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description API for server side connection management
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(CONNECTION_SERVER_H)
+#define CONNECTION_SERVER_H
+
+
+#include "img_types.h"
+#include "img_defs.h"
+#include "handle.h"
+#include "pvrsrv_cleanup.h"
+
+/* Variable used to hold in memory the timeout for the current time slice*/
+extern IMG_UINT64 gui64TimesliceLimit;
+/* Counter number of handle data freed during the current time slice */
+extern IMG_UINT32 gui32HandleDataFreeCounter;
+/* Set the maximum time the freeing of the resources can keep the lock */
+#define CONNECTION_DEFERRED_CLEANUP_TIMESLICE_NS (3000 * 1000) /* 3ms */
+
+typedef struct _CONNECTION_DATA_
+{
+ PVRSRV_HANDLE_BASE *psHandleBase;
+ PROCESS_HANDLE_BASE *psProcessHandleBase;
+ struct _SYNC_CONNECTION_DATA_ *psSyncConnectionData;
+ struct _PDUMP_CONNECTION_DATA_ *psPDumpConnectionData;
+
+ /* Holds the client flags supplied at connection time */
+ IMG_UINT32 ui32ClientFlags;
+
+ /*
+ * OS specific data can be stored via this handle.
+ * See osconnection_server.h for a generic mechanism
+ * for initialising this field.
+ */
+ IMG_HANDLE hOsPrivateData;
+
+#define PVRSRV_CONNECTION_PROCESS_NAME_LEN (16)
+ IMG_PID pid;
+ IMG_PID vpid;
+ IMG_UINT32 tid;
+ IMG_CHAR pszProcName[PVRSRV_CONNECTION_PROCESS_NAME_LEN];
+
+ IMG_HANDLE hProcessStats;
+
+ IMG_HANDLE hClientTLStream;
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+ /*
+ * Connection-based values per application which can be modified by the
+ * AppHint settings 'OSid, OSidReg, bOSidAxiProtReg' for each application.
+ * These control where the connection's memory allocation is sourced from.
+ * ui32OSid, ui32OSidReg range from 0..(GPUVIRT_VALIDATION_NUM_OS - 1).
+ */
+ IMG_UINT32 ui32OSid;
+ IMG_UINT32 ui32OSidReg;
+ IMG_BOOL bOSidAxiProtReg;
+#endif /* defined(SUPPORT_GPUVIRT_VALIDATION) */
+
+#if defined(SUPPORT_DMA_TRANSFER)
+ IMG_BOOL bAcceptDmaRequests;
+ ATOMIC_T ui32NumDmaTransfersInFlight;
+ POS_LOCK hDmaReqLock;
+ IMG_HANDLE hDmaEventObject;
+#endif
+ /* Structure which is hooked into the cleanup thread work list */
+ PVRSRV_CLEANUP_THREAD_WORK sCleanupThreadFn;
+
+ DLLIST_NODE sConnectionListNode;
+
+ /* List navigation for deferred freeing of connection data */
+ struct _CONNECTION_DATA_ **ppsThis;
+ struct _CONNECTION_DATA_ *psNext;
+} CONNECTION_DATA;
+
+#include "osconnection_server.h"
+
+PVRSRV_ERROR PVRSRVCommonConnectionConnect(void **ppvPrivData, void *pvOSData);
+void PVRSRVCommonConnectionDisconnect(void *pvPrivData);
+
+IMG_PID PVRSRVGetPurgeConnectionPid(void);
+
+void PVRSRVConnectionDebugNotify(PVRSRV_DEVICE_NODE *psDevNode,
+ DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+ void *pvDumpDebugFile);
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVConnectionPrivateData)
+#endif
+static INLINE
+IMG_HANDLE PVRSRVConnectionPrivateData(CONNECTION_DATA *psConnection)
+{
+ return (psConnection != NULL) ? psConnection->hOsPrivateData : NULL;
+}
+
+#endif /* !defined(CONNECTION_SERVER_H) */
diff --git a/drivers/gpu/drm/img-rogue/cores/rgxcore_km_1.82.4.5.h b/drivers/gpu/drm/img-rogue/cores/rgxcore_km_1.82.4.5.h
new file mode 100644
index 000000000..da5f543d9
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/cores/rgxcore_km_1.82.4.5.h
@@ -0,0 +1,69 @@
+/*************************************************************************/ /*!
+@Title RGX Core BVNC 1.82.4.5
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef RGXCORE_KM_1_82_4_5_H
+#define RGXCORE_KM_1_82_4_5_H
+
+/* Automatically generated file (29/06/2021 09:01:16): Do not edit manually */
+/* CS: @2503111 */
+
+/******************************************************************************
+ * BVNC = 1.82.4.5
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 1
+#define RGX_BVNC_KM_V 82
+#define RGX_BVNC_KM_N 4
+#define RGX_BVNC_KM_C 5
+
+/******************************************************************************
+ * Errata
+ *****************************************************************************/
+
+
+
+
+/******************************************************************************
+ * Enhancements
+ *****************************************************************************/
+
+
+
+#endif /* RGXCORE_KM_1_82_4_5_H */
diff --git a/drivers/gpu/drm/img-rogue/cores/rgxcore_km_36.52.104.182.h b/drivers/gpu/drm/img-rogue/cores/rgxcore_km_36.52.104.182.h
new file mode 100644
index 000000000..6657f5410
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/cores/rgxcore_km_36.52.104.182.h
@@ -0,0 +1,74 @@
+/*************************************************************************/ /*!
+@Title RGX Core BVNC 36.52.104.182
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef RGXCORE_KM_36_52_104_182_H
+#define RGXCORE_KM_36_52_104_182_H
+
+/* Automatically generated file (29/06/2021 09:01:17): Do not edit manually */
+/* CS: @5849605 */
+
+/******************************************************************************
+ * BVNC = 36.52.104.182
+ *****************************************************************************/
+#define RGX_BVNC_KM_B 36
+#define RGX_BVNC_KM_V 52
+#define RGX_BVNC_KM_N 104
+#define RGX_BVNC_KM_C 182
+
+/******************************************************************************
+ * Errata
+ *****************************************************************************/
+
+#define FIX_HW_BRN_63553
+
+
+
+/******************************************************************************
+ * Enhancements
+ *****************************************************************************/
+#define HW_ERN_42290
+#define HW_ERN_42606
+#define HW_ERN_47025
+#define HW_ERN_57596
+
+
+
+#endif /* RGXCORE_KM_36_52_104_182_H */
diff --git a/drivers/gpu/drm/img-rogue/debug_common.c b/drivers/gpu/drm/img-rogue/debug_common.c
new file mode 100644
index 000000000..9b0e4ead8
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/debug_common.c
@@ -0,0 +1,1476 @@
+/*************************************************************************/ /*!
+@File
+@Title Debug Functionality
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Creates common debug info entries.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__linux__)
+#include
+#endif /* #if !defined(__linux__) */
+
+#include "debug_common.h"
+#include "pvrsrv.h"
+#include "di_server.h"
+#include "lists.h"
+#include "pvrversion.h"
+#include "rgx_options.h"
+#include "allocmem.h"
+#include "rgxfwutils.h"
+
+#ifdef SUPPORT_RGX
+#include "rgxdevice.h"
+#include "rgxdebug.h"
+#include "rgxinit.h"
+static IMG_HANDLE ghGpuUtilUserDebugFS;
+#endif
+
+static DI_ENTRY *gpsVersionDIEntry;
+static DI_ENTRY *gpsStatusDIEntry;
+
+#ifdef SUPPORT_RGX
+#ifdef SUPPORT_FIRMWARE_GCOV
+static DI_ENTRY *gpsFirmwareGcovDIEntry;
+#endif /* SUPPORT_FIRMWARE_GCOV */
+#endif /* SUPPORT_RGX */
+#ifdef SUPPORT_VALIDATION
+static DI_ENTRY *gpsTestMemLeakDIEntry;
+#endif /* SUPPORT_VALIDATION */
+#if defined(DEBUG) || defined(PVR_DPF_ADHOC_DEBUG_ON)
+static DI_ENTRY *gpsDebugLevelDIEntry;
+#endif /* defined(DEBUG) || defined(PVR_DPF_ADHOC_DEBUG_ON) */
+
+static void _DumpDebugDIPrintfWrapper(void *pvDumpDebugFile, const IMG_CHAR *pszFormat, ...)
+{
+ IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN];
+ va_list ArgList;
+
+ OSSNPrintf(szBuffer, PVR_MAX_DEBUG_MESSAGE_LEN, "%s\n", pszFormat);
+
+ va_start(ArgList, pszFormat);
+ DIVPrintf(pvDumpDebugFile, szBuffer, ArgList);
+ va_end(ArgList);
+}
+
+/*************************************************************************/ /*!
+ Version DebugFS entry
+*/ /**************************************************************************/
+
+static void *_DebugVersionCompare_AnyVaCb(PVRSRV_DEVICE_NODE *psDevNode,
+ va_list va)
+{
+ IMG_UINT64 *pui64CurrentPosition = va_arg(va, IMG_UINT64 *);
+ IMG_UINT64 ui64Position = va_arg(va, IMG_UINT64);
+ IMG_UINT64 ui64CurrentPosition = *pui64CurrentPosition;
+
+ (*pui64CurrentPosition)++;
+
+ return (ui64CurrentPosition == ui64Position) ? psDevNode : NULL;
+}
+
+static void *_VersionDIStart(OSDI_IMPL_ENTRY *psEntry, IMG_UINT64 *pui64Pos)
+{
+ PVRSRV_DATA *psPVRSRVData = DIGetPrivData(psEntry);
+ IMG_UINT64 uiCurrentPosition = 1;
+
+ PVR_UNREFERENCED_PARAMETER(psEntry);
+
+ if (psPVRSRVData == NULL) {
+ PVR_DPF((PVR_DBG_ERROR, "psPVRSRVData = NULL"));
+ return NULL;
+ }
+
+ if (*pui64Pos == 0)
+ {
+ return DI_START_TOKEN;
+ }
+
+ return List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList,
+ _DebugVersionCompare_AnyVaCb,
+ &uiCurrentPosition,
+ *pui64Pos);
+}
+
+static void _VersionDIStop(OSDI_IMPL_ENTRY *psEntry, void *pvPriv)
+{
+ PVR_UNREFERENCED_PARAMETER(psEntry);
+ PVR_UNREFERENCED_PARAMETER(pvPriv);
+}
+
+static void *_VersionDINext(OSDI_IMPL_ENTRY *psEntry,void *pvPriv,
+ IMG_UINT64 *pui64Pos)
+{
+ PVRSRV_DATA *psPVRSRVData = DIGetPrivData(psEntry);
+ IMG_UINT64 uiCurrentPosition = 1;
+
+ (*pui64Pos)++;
+
+ return List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList,
+ _DebugVersionCompare_AnyVaCb,
+ &uiCurrentPosition,
+ *pui64Pos);
+}
+
+#define DI_PRINT_VERSION_FMTSPEC \
+ "%s Version: %u.%u @ %u (%s) build options: 0x%08x %s\n"
+#define STR_DEBUG "debug"
+#define STR_RELEASE "release"
+
+#if defined(DEBUG) || defined(SUPPORT_VALIDATION)
+#define BUILD_OPT_LEN 80
+
+static inline void _AppendOptionStr(IMG_CHAR pszBuildOptions[], const IMG_CHAR* str, OSDI_IMPL_ENTRY *psEntry, IMG_UINT32* pui32BuildOptionLen)
+{
+ IMG_UINT32 ui32BuildOptionLen = *pui32BuildOptionLen;
+ const IMG_UINT32 strLen = OSStringLength(str);
+ const IMG_UINT32 optStrLen = sizeof(IMG_CHAR) * (BUILD_OPT_LEN-1);
+
+ if ((ui32BuildOptionLen + strLen) > optStrLen)
+ {
+ pszBuildOptions[ui32BuildOptionLen] = '\0';
+ DIPrintf(psEntry, "%s\n", pszBuildOptions);
+ ui32BuildOptionLen = 0;
+ }
+ if (strLen < optStrLen)
+ {
+ OSStringLCopy(pszBuildOptions+ui32BuildOptionLen, str, strLen);
+ ui32BuildOptionLen += strLen - 1;
+ }
+ *pui32BuildOptionLen = ui32BuildOptionLen;
+}
+#endif /* DEBUG || SUPPORT_VALIDATION */
+
+static int _VersionDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvPriv)
+{
+ PVRSRV_DATA *psPVRSRVData = DIGetPrivData(psEntry);
+
+ if (pvPriv == DI_START_TOKEN)
+ {
+ if (psPVRSRVData->sDriverInfo.bIsNoMatch)
+ {
+ const BUILD_INFO *psBuildInfo;
+
+ psBuildInfo = &psPVRSRVData->sDriverInfo.sUMBuildInfo;
+ DIPrintf(psEntry, DI_PRINT_VERSION_FMTSPEC,
+ "UM Driver",
+ PVRVERSION_UNPACK_MAJ(psBuildInfo->ui32BuildVersion),
+ PVRVERSION_UNPACK_MIN(psBuildInfo->ui32BuildVersion),
+ psBuildInfo->ui32BuildRevision,
+ (psBuildInfo->ui32BuildType == BUILD_TYPE_DEBUG) ?
+ STR_DEBUG : STR_RELEASE,
+ psBuildInfo->ui32BuildOptions,
+ PVR_BUILD_DIR);
+
+ psBuildInfo = &psPVRSRVData->sDriverInfo.sKMBuildInfo;
+ DIPrintf(psEntry, DI_PRINT_VERSION_FMTSPEC,
+ "KM Driver (" PVR_ARCH_NAME ")",
+ PVRVERSION_UNPACK_MAJ(psBuildInfo->ui32BuildVersion),
+ PVRVERSION_UNPACK_MIN(psBuildInfo->ui32BuildVersion),
+ psBuildInfo->ui32BuildRevision,
+ (psBuildInfo->ui32BuildType == BUILD_TYPE_DEBUG) ?
+ STR_DEBUG : STR_RELEASE,
+ psBuildInfo->ui32BuildOptions,
+ PVR_BUILD_DIR);
+ }
+ else
+ {
+ /* bIsNoMatch is `false` in one of the following cases:
+ * - UM & KM version parameters actually match.
+ * - A comparison between UM & KM has not been made yet, because no
+ * client ever connected.
+ *
+ * In both cases, available (KM) version info is the best output we
+ * can provide.
+ */
+ DIPrintf(psEntry, "Driver Version: %s (%s) (%s) build options: "
+ "0x%08lx %s\n", PVRVERSION_STRING, PVR_ARCH_NAME,
+ PVR_BUILD_TYPE, RGX_BUILD_OPTIONS_KM, PVR_BUILD_DIR);
+ }
+ }
+ else if (pvPriv != NULL)
+ {
+ PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *) pvPriv;
+ PVRSRV_DEVICE_CONFIG *psDevConfig = psDevNode->psDevConfig;
+#ifdef SUPPORT_RGX
+ PVRSRV_RGXDEV_INFO *psDevInfo = psDevNode->pvDevice;
+#if defined(DEBUG) || defined(SUPPORT_VALIDATION)
+ IMG_CHAR pszBuildOptions[BUILD_OPT_LEN];
+ IMG_UINT32 ui32BuildOptionLen = 0;
+ static const char* aszOptions[] = RGX_BUILD_OPTIONS_LIST;
+ int i = 0;
+#endif
+#endif /* SUPPORT_RGX */
+ IMG_BOOL bFwVersionInfoPrinted = IMG_FALSE;
+
+ DIPrintf(psEntry, "\nDevice Name: %s\n", psDevConfig->pszName);
+ DIPrintf(psEntry, "Device ID: %u:%d\n", psDevNode->sDevId.ui32InternalID,
+ psDevNode->sDevId.i32OsDeviceID);
+
+ if (psDevConfig->pszVersion)
+ {
+ DIPrintf(psEntry, "Device Version: %s\n",
+ psDevConfig->pszVersion);
+ }
+
+ if (psDevNode->pfnDeviceVersionString)
+ {
+ IMG_CHAR *pszVerStr;
+
+ if (psDevNode->pfnDeviceVersionString(psDevNode,
+ &pszVerStr) == PVRSRV_OK)
+ {
+ DIPrintf(psEntry, "%s\n", pszVerStr);
+
+ OSFreeMem(pszVerStr);
+ }
+ }
+
+#ifdef SUPPORT_RGX
+ /* print device's firmware version info */
+ if (psDevInfo->psRGXFWIfOsInitMemDesc != NULL)
+ {
+ /* psDevInfo->psRGXFWIfOsInitMemDesc should be permanently mapped */
+ if (psDevInfo->psRGXFWIfOsInit != NULL)
+ {
+ if (psDevInfo->psRGXFWIfOsInit->sRGXCompChecks.bUpdated)
+ {
+ const RGXFWIF_COMPCHECKS *psRGXCompChecks =
+ &psDevInfo->psRGXFWIfOsInit->sRGXCompChecks;
+ IMG_UINT32 ui32DDKVer = psRGXCompChecks->ui32DDKVersion;
+
+ DIPrintf(psEntry, DI_PRINT_VERSION_FMTSPEC,
+ "Firmware",
+ PVRVERSION_UNPACK_MAJ(ui32DDKVer),
+ PVRVERSION_UNPACK_MIN(ui32DDKVer),
+ psRGXCompChecks->ui32DDKBuild,
+ ((psRGXCompChecks->ui32BuildOptions &
+ OPTIONS_DEBUG_MASK) ? STR_DEBUG : STR_RELEASE),
+ psRGXCompChecks->ui32BuildOptions,
+ PVR_BUILD_DIR);
+ bFwVersionInfoPrinted = IMG_TRUE;
+
+#if defined(DEBUG) || defined(SUPPORT_VALIDATION)
+ DIPrintf(psEntry, "Firmware Build Options:\n");
+
+ for (i = 0; i < ARRAY_SIZE(aszOptions); i++)
+ {
+ if ((psRGXCompChecks->ui32BuildOptions & 1<pvDevice,
+ RGXFWIF_DM_GP,
+ &sCounterDumpCmd,
+ 0,
+ PDUMP_FLAGS_CONTINUOUS,
+ pui32kCCBCommandSlot);
+ PVR_LOG_IF_ERROR(eError, "RGXScheduleCommandAndGetKCCBSlot");
+
+ return eError;
+}
+
+static int _DebugPowerDataDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode = DIGetPrivData(psEntry);
+ PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ IMG_UINT32 ui32kCCBCommandSlot;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ PVR_UNREFERENCED_PARAMETER(pvData);
+
+ if (psDeviceNode->eDevState != PVRSRV_DEVICE_STATE_ACTIVE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Device not initialised when "
+ "power counter data was requested!"));
+ return -EIO;
+ }
+
+ OSLockAcquire(psDevInfo->hCounterDumpingLock);
+
+ eError = SendPowerCounterCommand(psDeviceNode,
+ RGXFWIF_PWR_COUNTER_DUMP_SAMPLE,
+ &ui32kCCBCommandSlot);
+
+ if (eError != PVRSRV_OK)
+ {
+ OSLockRelease(psDevInfo->hCounterDumpingLock);
+ return -EIO;
+ }
+
+ /* Wait for FW complete completion */
+ eError = RGXWaitForKCCBSlotUpdate(psDevInfo,
+ ui32kCCBCommandSlot,
+ PDUMP_FLAGS_CONTINUOUS);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_LOG_ERROR(eError, "RGXWaitForKCCBSlotUpdate");
+ OSLockRelease(psDevInfo->hCounterDumpingLock);
+ return -EIO;
+ }
+
+ /* Read back the buffer */
+ {
+ IMG_UINT32* pui32PowerBuffer;
+ IMG_UINT32 ui32NumOfRegs, ui32SamplePeriod;
+ IMG_UINT32 i, j;
+
+ eError = DevmemAcquireCpuVirtAddr(psDevInfo->psCounterBufferMemDesc,
+ (void**)&pui32PowerBuffer);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_LOG_ERROR(eError, "DevmemAcquireCpuVirtAddr");
+ OSLockRelease(psDevInfo->hCounterDumpingLock);
+ return -EIO;
+ }
+
+ ui32NumOfRegs = *pui32PowerBuffer++;
+ ui32SamplePeriod = *pui32PowerBuffer++;
+
+ if (ui32NumOfRegs)
+ {
+ DIPrintf(psEntry, "Power counter data for device\n");
+ DIPrintf(psEntry, "Sample period: 0x%08x\n", ui32SamplePeriod);
+
+ for (i = 0; i < ui32NumOfRegs; i++)
+ {
+ IMG_UINT32 ui32High, ui32Low;
+ IMG_UINT32 ui32RegOffset = *pui32PowerBuffer++;
+ IMG_UINT32 ui32NumOfInstances = *pui32PowerBuffer++;
+
+ PVR_ASSERT(ui32NumOfInstances);
+
+ DIPrintf(psEntry, "0x%08x:", ui32RegOffset);
+
+ for (j = 0; j < ui32NumOfInstances; j++)
+ {
+ ui32Low = *pui32PowerBuffer++;
+ ui32High = *pui32PowerBuffer++;
+
+ DIPrintf(psEntry, " 0x%016llx",
+ (IMG_UINT64) ui32Low | (IMG_UINT64) ui32High << 32);
+ }
+
+ DIPrintf(psEntry, "\n");
+ }
+ }
+
+ DevmemReleaseCpuVirtAddr(psDevInfo->psCounterBufferMemDesc);
+ }
+
+ OSLockRelease(psDevInfo->hCounterDumpingLock);
+
+ return eError;
+}
+
+static IMG_INT64 PowerDataSet(const IMG_CHAR __user *pcBuffer,
+ IMG_UINT64 ui64Count, IMG_UINT64 *pui64Pos,
+ void *pvData)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE*)pvData;
+ PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ RGXFWIF_COUNTER_DUMP_REQUEST eRequest;
+ IMG_UINT32 ui32kCCBCommandSlot;
+
+ PVR_RETURN_IF_FALSE(pcBuffer != NULL, -EIO);
+ PVR_RETURN_IF_FALSE(pui64Pos != NULL && *pui64Pos == 0, -EIO);
+ PVR_RETURN_IF_FALSE(ui64Count >= 1, -EINVAL);
+ PVR_RETURN_IF_FALSE(pcBuffer[ui64Count - 1] == '\0', -EINVAL);
+
+ if (psDeviceNode->eDevState != PVRSRV_DEVICE_STATE_ACTIVE)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Device not initialised when "
+ "power counter data was requested!"));
+ return -EIO;
+ }
+
+ if (pcBuffer[0] == '1')
+ {
+ eRequest = RGXFWIF_PWR_COUNTER_DUMP_START;
+ }
+ else if (pcBuffer[0] == '0')
+ {
+ eRequest = RGXFWIF_PWR_COUNTER_DUMP_STOP;
+ }
+ else
+ {
+ return -EINVAL;
+ }
+
+ OSLockAcquire(psDevInfo->hCounterDumpingLock);
+
+ SendPowerCounterCommand(psDeviceNode,
+ eRequest,
+ &ui32kCCBCommandSlot);
+
+ OSLockRelease(psDevInfo->hCounterDumpingLock);
+
+ *pui64Pos += ui64Count;
+ return ui64Count;
+}
+
+#endif /* defined(SUPPORT_RGX) && defined(SUPPORT_POWER_SAMPLING_VIA_DEBUGFS) */
+
+/*************************************************************************/ /*!
+ Status DebugFS entry
+*/ /**************************************************************************/
+
+static void *_DebugStatusCompare_AnyVaCb(PVRSRV_DEVICE_NODE *psDevNode,
+ va_list va)
+{
+ IMG_UINT64 *pui64CurrentPosition = va_arg(va, IMG_UINT64 *);
+ IMG_UINT64 ui64Position = va_arg(va, IMG_UINT64);
+ IMG_UINT64 ui64CurrentPosition = *pui64CurrentPosition;
+
+ (*pui64CurrentPosition)++;
+
+ return (ui64CurrentPosition == ui64Position) ? psDevNode : NULL;
+}
+
+static void *_DebugStatusDIStart(OSDI_IMPL_ENTRY *psEntry, IMG_UINT64 *pui64Pos)
+{
+ PVRSRV_DATA *psPVRSRVData = DIGetPrivData(psEntry);
+ IMG_UINT64 uiCurrentPosition = 1;
+
+ if (*pui64Pos == 0)
+ {
+ return DI_START_TOKEN;
+ }
+
+ return List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList,
+ _DebugStatusCompare_AnyVaCb,
+ &uiCurrentPosition,
+ *pui64Pos);
+}
+
+static void _DebugStatusDIStop(OSDI_IMPL_ENTRY *psEntry, void *pvData)
+{
+ PVR_UNREFERENCED_PARAMETER(psEntry);
+ PVR_UNREFERENCED_PARAMETER(pvData);
+}
+
+static void *_DebugStatusDINext(OSDI_IMPL_ENTRY *psEntry,
+ void *pvData,
+ IMG_UINT64 *pui64Pos)
+{
+ PVRSRV_DATA *psPVRSRVData = DIGetPrivData(psEntry);
+ IMG_UINT64 uiCurrentPosition = 1;
+
+ PVR_UNREFERENCED_PARAMETER(pvData);
+
+ (*pui64Pos)++;
+
+ return List_PVRSRV_DEVICE_NODE_Any_va(psPVRSRVData->psDeviceNodeList,
+ _DebugStatusCompare_AnyVaCb,
+ &uiCurrentPosition,
+ *pui64Pos);
+}
+
+static int _DebugStatusDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData)
+{
+ if (pvData == DI_START_TOKEN)
+ {
+ PVRSRV_DATA *psPVRSRVData = DIGetPrivData(psEntry);
+
+ if (psPVRSRVData != NULL)
+ {
+ switch (psPVRSRVData->eServicesState)
+ {
+ case PVRSRV_SERVICES_STATE_OK:
+ DIPrintf(psEntry, "Driver Status: OK\n");
+ break;
+ case PVRSRV_SERVICES_STATE_BAD:
+ DIPrintf(psEntry, "Driver Status: BAD\n");
+ break;
+ case PVRSRV_SERVICES_STATE_UNDEFINED:
+ DIPrintf(psEntry, "Driver Status: UNDEFINED\n");
+ break;
+ default:
+ DIPrintf(psEntry, "Driver Status: UNKNOWN (%d)\n",
+ psPVRSRVData->eServicesState);
+ break;
+ }
+ }
+ }
+ else if (pvData != NULL)
+ {
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;
+ IMG_CHAR *pszStatus = "";
+ IMG_CHAR *pszReason = "";
+ PVRSRV_DEVICE_HEALTH_STATUS eHealthStatus;
+ PVRSRV_DEVICE_HEALTH_REASON eHealthReason;
+
+ DIPrintf(psEntry, "\nDevice ID: %u:%d\n", psDeviceNode->sDevId.ui32InternalID,
+ psDeviceNode->sDevId.i32OsDeviceID);
+
+ /* Update the health status now if possible... */
+ if (psDeviceNode->pfnUpdateHealthStatus)
+ {
+ psDeviceNode->pfnUpdateHealthStatus(psDeviceNode, IMG_FALSE);
+ }
+ eHealthStatus = OSAtomicRead(&psDeviceNode->eHealthStatus);
+ eHealthReason = OSAtomicRead(&psDeviceNode->eHealthReason);
+
+ switch (eHealthStatus)
+ {
+ case PVRSRV_DEVICE_HEALTH_STATUS_OK: pszStatus = "OK"; break;
+ case PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING: pszStatus = "NOT RESPONDING"; break;
+ case PVRSRV_DEVICE_HEALTH_STATUS_DEAD: pszStatus = "DEAD"; break;
+ case PVRSRV_DEVICE_HEALTH_STATUS_FAULT: pszStatus = "FAULT"; break;
+ case PVRSRV_DEVICE_HEALTH_STATUS_UNDEFINED: pszStatus = "UNDEFINED"; break;
+ default: pszStatus = "UNKNOWN"; break;
+ }
+
+ switch (eHealthReason)
+ {
+ case PVRSRV_DEVICE_HEALTH_REASON_NONE: pszReason = ""; break;
+ case PVRSRV_DEVICE_HEALTH_REASON_ASSERTED: pszReason = " (Asserted)"; break;
+ case PVRSRV_DEVICE_HEALTH_REASON_POLL_FAILING: pszReason = " (Poll failing)"; break;
+ case PVRSRV_DEVICE_HEALTH_REASON_TIMEOUTS: pszReason = " (Global Event Object timeouts rising)"; break;
+ case PVRSRV_DEVICE_HEALTH_REASON_QUEUE_CORRUPT: pszReason = " (KCCB offset invalid)"; break;
+ case PVRSRV_DEVICE_HEALTH_REASON_QUEUE_STALLED: pszReason = " (KCCB stalled)"; break;
+ case PVRSRV_DEVICE_HEALTH_REASON_IDLING: pszReason = " (Idling)"; break;
+ case PVRSRV_DEVICE_HEALTH_REASON_RESTARTING: pszReason = " (Restarting)"; break;
+ case PVRSRV_DEVICE_HEALTH_REASON_MISSING_INTERRUPTS: pszReason = " (Missing interrupts)"; break;
+ default: pszReason = " (Unknown reason)"; break;
+ }
+
+ DIPrintf(psEntry, "Firmware Status: %s%s\n", pszStatus, pszReason);
+ if (PVRSRV_ERROR_LIMIT_REACHED)
+ {
+ DIPrintf(psEntry, "Server Errors: %d+\n", IMG_UINT32_MAX);
+ }
+ else
+ {
+ DIPrintf(psEntry, "Server Errors: %d\n", PVRSRV_KM_ERRORS);
+ }
+
+
+ /* Write other useful stats to aid the test cycle... */
+ if (psDeviceNode->pvDevice != NULL)
+ {
+#ifdef SUPPORT_RGX
+ PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ const RGXFWIF_HWRINFOBUF *psHWRInfoBuf = psDevInfo->psRGXFWIfHWRInfoBufCtl;
+ const RGXFWIF_SYSDATA *psFwSysData = psDevInfo->psRGXFWIfFwSysData;
+
+#ifdef PVRSRV_DEBUG_LISR_EXECUTION
+ /* Show the detected #LISR, #MISR scheduled calls */
+ DIPrintf(psEntry, "RGX #LISR: %llu\n", psDeviceNode->ui64nLISR);
+ DIPrintf(psEntry, "RGX #MISR: %llu\n", psDeviceNode->ui64nMISR);
+#endif /* PVRSRV_DEBUG_LISR_EXECUTION */
+
+ /* Calculate the number of HWR events in total across all the DMs... */
+ if (psHWRInfoBuf != NULL)
+ {
+ IMG_UINT32 ui32HWREventCount = 0;
+ IMG_UINT32 ui32CRREventCount = 0;
+ IMG_UINT32 ui32DMIndex;
+
+ for (ui32DMIndex = 0; ui32DMIndex < RGXFWIF_DM_MAX; ui32DMIndex++)
+ {
+ ui32HWREventCount += psHWRInfoBuf->aui32HwrDmLockedUpCount[ui32DMIndex];
+ ui32CRREventCount += psHWRInfoBuf->aui32HwrDmOverranCount[ui32DMIndex];
+ }
+
+ DIPrintf(psEntry, "HWR Event Count: %d\n", ui32HWREventCount);
+ DIPrintf(psEntry, "CRR Event Count: %d\n", ui32CRREventCount);
+#ifdef PVRSRV_STALLED_CCB_ACTION
+ /* Write the number of Sync Lockup Recovery (SLR) events... */
+ DIPrintf(psEntry, "SLR Event Count: %d\n", psDevInfo->psRGXFWIfFwOsData->ui32ForcedUpdatesRequested);
+#endif /* PVRSRV_STALLED_CCB_ACTION */
+ }
+
+ /* Show error counts */
+ DIPrintf(psEntry, "WGP Error Count: %d\n", psDevInfo->sErrorCounts.ui32WGPErrorCount);
+ DIPrintf(psEntry, "TRP Error Count: %d\n", psDevInfo->sErrorCounts.ui32TRPErrorCount);
+
+ /*
+ * Guest drivers do not support the following functionality:
+ * - Perform actual on-chip fw tracing.
+ * - Collect actual on-chip GPU utilization stats.
+ * - Perform actual on-chip GPU power/dvfs management.
+ * - As a result no more information can be provided.
+ */
+ if (!PVRSRV_VZ_MODE_IS(GUEST))
+ {
+ if (psFwSysData != NULL)
+ {
+ DIPrintf(psEntry, "FWF Event Count: %d\n", psFwSysData->ui32FWFaults);
+ }
+
+ /* Write the number of APM events... */
+ DIPrintf(psEntry, "APM Event Count: %d\n", psDevInfo->ui32ActivePMReqTotal);
+
+ /* Write the current GPU Utilisation values... */
+ if (psDevInfo->pfnGetGpuUtilStats &&
+ eHealthStatus == PVRSRV_DEVICE_HEALTH_STATUS_OK)
+ {
+ RGXFWIF_GPU_UTIL_STATS sGpuUtilStats;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ eError = psDevInfo->pfnGetGpuUtilStats(psDeviceNode,
+ ghGpuUtilUserDebugFS,
+ &sGpuUtilStats);
+
+ if ((eError == PVRSRV_OK) &&
+ ((IMG_UINT32)sGpuUtilStats.ui64GpuStatCumulative))
+ {
+ IMG_UINT64 util;
+ IMG_UINT32 rem;
+
+ util = 100 * sGpuUtilStats.ui64GpuStatActive;
+ util = OSDivide64(util, (IMG_UINT32)sGpuUtilStats.ui64GpuStatCumulative, &rem);
+
+ DIPrintf(psEntry, "GPU Utilisation: %u%%\n", (IMG_UINT32)util);
+ }
+ else
+ {
+ DIPrintf(psEntry, "GPU Utilisation: -\n");
+ }
+ }
+ }
+#endif /* SUPPORT_RGX */
+ }
+ }
+
+ return 0;
+}
+
+static IMG_INT64 DebugStatusSet(const IMG_CHAR *pcBuffer, IMG_UINT64 ui64Count,
+ IMG_UINT64 *pui64Pos, void *pvData)
+{
+ PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+ PVR_RETURN_IF_FALSE(pcBuffer != NULL, -EIO);
+ PVR_RETURN_IF_FALSE(pui64Pos != NULL && *pui64Pos == 0, -EIO);
+ PVR_RETURN_IF_FALSE(ui64Count >= 1, -EINVAL);
+ PVR_RETURN_IF_FALSE(pcBuffer[0] == 'k' || pcBuffer[0] == 'K', -EINVAL);
+ PVR_RETURN_IF_FALSE(pcBuffer[ui64Count - 1] == '\0', -EINVAL);
+
+ psPVRSRVData->eServicesState = PVRSRV_SERVICES_STATE_BAD;
+
+ *pui64Pos += ui64Count;
+ return ui64Count;
+}
+
+/*************************************************************************/ /*!
+ Dump Debug DebugFS entry
+*/ /**************************************************************************/
+
+static int _DebugDumpDebugDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode = DIGetPrivData(psEntry);
+
+ PVR_UNREFERENCED_PARAMETER(pvData);
+
+ if (psDeviceNode->pvDevice != NULL)
+ {
+ PVRSRVDebugRequest(psDeviceNode, DEBUG_REQUEST_VERBOSITY_MAX,
+ _DumpDebugDIPrintfWrapper, psEntry);
+ }
+
+ return 0;
+}
+
+#ifdef SUPPORT_RGX
+
+/*************************************************************************/ /*!
+ Firmware Trace DebugFS entry
+*/ /**************************************************************************/
+
+static int _DebugFWTraceDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode = DIGetPrivData(psEntry);
+ PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+
+ if (psDevInfo != NULL)
+ {
+ RGXDumpFirmwareTrace(_DumpDebugDIPrintfWrapper, psEntry, psDevInfo);
+ }
+
+ return 0;
+}
+
+#ifdef SUPPORT_FIRMWARE_GCOV
+
+static PVRSRV_RGXDEV_INFO *getPsDevInfo(OSDI_IMPL_ENTRY *psEntry)
+{
+ PVRSRV_DATA *psPVRSRVData = DIGetPrivData(psEntry);
+
+ if (psPVRSRVData != NULL)
+ {
+ if (psPVRSRVData->psDeviceNodeList != NULL)
+ {
+ PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO*)psPVRSRVData->psDeviceNodeList->pvDevice;
+ return psDevInfo;
+ }
+ }
+ return NULL;
+}
+
+static void *_FirmwareGcovDIStart(OSDI_IMPL_ENTRY *psEntry, IMG_UINT64 *pui64Pos)
+{
+ PVRSRV_RGXDEV_INFO *psDevInfo = getPsDevInfo(psEntry);
+
+ if (psDevInfo != NULL)
+ {
+ if (psDevInfo->psFirmwareGcovBufferMemDesc != NULL)
+ {
+ void *pvCpuVirtAddr;
+ DevmemAcquireCpuVirtAddr(psDevInfo->psFirmwareGcovBufferMemDesc, &pvCpuVirtAddr);
+ return *pui64Pos ? NULL : pvCpuVirtAddr;
+ }
+ }
+
+ return NULL;
+}
+
+static void _FirmwareGcovDIStop(OSDI_IMPL_ENTRY *psEntry, void *pvData)
+{
+ PVRSRV_RGXDEV_INFO *psDevInfo = getPsDevInfo(psEntry);
+
+ PVR_UNREFERENCED_PARAMETER(pvData);
+
+ if (psDevInfo != NULL)
+ {
+ if (psDevInfo->psFirmwareGcovBufferMemDesc != NULL)
+ {
+ DevmemReleaseCpuVirtAddr(psDevInfo->psFirmwareGcovBufferMemDesc);
+ }
+ }
+}
+
+static void *_FirmwareGcovDINext(OSDI_IMPL_ENTRY *psEntry,
+ void *pvData,
+ IMG_UINT64 *pui64Pos)
+{
+ PVR_UNREFERENCED_PARAMETER(psEntry);
+ PVR_UNREFERENCED_PARAMETER(pvData);
+ PVR_UNREFERENCED_PARAMETER(pui64Pos);
+ return NULL;
+}
+
+static int _FirmwareGcovDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData)
+{
+ PVRSRV_RGXDEV_INFO *psDevInfo = getPsDevInfo(psEntry);
+
+ if (psDevInfo != NULL)
+ {
+ DIWrite(psEntry, pvData, psDevInfo->ui32FirmwareGcovSize);
+ }
+ return 0;
+}
+
+#endif /* SUPPORT_FIRMWARE_GCOV */
+
+#ifdef SUPPORT_POWER_VALIDATION_VIA_DEBUGFS
+
+/*************************************************************************/ /*!
+ Power monitoring DebugFS entry
+*/ /**************************************************************************/
+
+static int _PowMonTraceDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode = DIGetPrivData(psEntry);
+ PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+
+ PVR_UNREFERENCED_PARAMETER(pvData);
+
+ if (psDevInfo != NULL)
+ {
+ RGXDumpPowerMonitoring(_DumpDebugDIPrintfWrapper, psEntry, psDevInfo);
+ }
+
+ return 0;
+}
+
+#endif /* SUPPORT_POWER_VALIDATION_VIA_DEBUGFS */
+
+#ifdef SUPPORT_VALIDATION
+
+#ifndef SYS_RGX_DEV_UNMAPPED_FW_REG
+#define SYS_RGX_DEV_UNMAPPED_FW_REG 0XFFFFFFFF
+#endif
+#define DI_RGXREGS_TIMEOUT_MS 1000
+
+/*************************************************************************/ /*!
+ RGX Registers Dump DebugFS entry
+*/ /**************************************************************************/
+
+static IMG_INT64 _RgxRegsSeek(IMG_UINT64 ui64Offset, void *pvData)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE*)pvData;
+ PVRSRV_RGXDEV_INFO *psDevInfo;
+
+ PVR_LOG_RETURN_IF_FALSE(psDeviceNode != NULL, "psDeviceNode is NULL", -1);
+
+ psDevInfo = psDeviceNode->pvDevice;
+
+ PVR_LOG_RETURN_IF_FALSE(ui64Offset <= (psDevInfo->ui32RegSize - 4),
+ "register offset is too big", -1);
+
+ return ui64Offset;
+}
+
+static IMG_INT64 _RgxRegsRead(IMG_CHAR *pcBuffer, IMG_UINT64 ui64Count,
+ IMG_UINT64 *pui64Pos, void *pvData)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE*)pvData;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ IMG_UINT64 ui64RegVal = 0;
+ PVRSRV_RGXDEV_INFO *psDevInfo;
+ IMG_UINT64 ui64CompRes;
+
+ PVR_LOG_RETURN_IF_FALSE(psDeviceNode != NULL, "psDeviceNode is NULL", -ENXIO);
+ PVR_LOG_RETURN_IF_FALSE(ui64Count == 4 || ui64Count == 8,
+ "wrong RGX register size", -EIO);
+ PVR_LOG_RETURN_IF_FALSE(!(*pui64Pos & (ui64Count - 1)),
+ "register read offset isn't aligned", -EINVAL);
+
+ psDevInfo = psDeviceNode->pvDevice;
+
+ if (*pui64Pos >= SYS_RGX_DEV_UNMAPPED_FW_REG)
+ {
+ if (!psDevInfo->bFirmwareInitialised)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "RGX Register offset is above PCI mapped range but "
+ "Firmware isn't yet initialised\n"));
+ return -EIO;
+ }
+
+ reinit_completion(&psDevInfo->sFwRegs.sRegComp);
+
+ eError = RGXScheduleRgxRegCommand(psDevInfo,
+ 0x00,
+ ui64Count,
+ (IMG_UINT32) *pui64Pos,
+ IMG_FALSE);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_LOG_ERROR(eError, "RGXScheduleRgxRegCommand");
+ return -EIO;
+ }
+
+ ui64CompRes = wait_for_completion_timeout(&psDevInfo->sFwRegs.sRegComp,
+ msecs_to_jiffies(DI_RGXREGS_TIMEOUT_MS));
+ if (!ui64CompRes)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "FW RGX Register access timeout %#x\n",
+ (IMG_UINT32) *pui64Pos));
+ return -EIO;
+ }
+
+ OSCachedMemCopy(pcBuffer, &psDevInfo->sFwRegs.ui64RegVal, ui64Count);
+ }
+ else
+ {
+ ui64RegVal = ui64Count == 4 ?
+ OSReadHWReg32(psDevInfo->pvRegsBaseKM, *pui64Pos) :
+ OSReadHWReg64(psDevInfo->pvRegsBaseKM, *pui64Pos);
+ OSCachedMemCopy(pcBuffer, &ui64RegVal, ui64Count);
+ }
+
+ return ui64Count;
+}
+
+static IMG_INT64 _RgxRegsWrite(const IMG_CHAR *pcBuffer, IMG_UINT64 ui64Count,
+ IMG_UINT64 *pui64Pos, void *pvData)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE*)pvData;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ IMG_UINT64 ui64RegVal = 0;
+ PVRSRV_RGXDEV_INFO *psDevInfo;
+
+ /* ignore the '\0' character */
+ ui64Count -= 1;
+
+ PVR_LOG_RETURN_IF_FALSE(psDeviceNode != NULL, "psDeviceNode is NULL", -ENXIO);
+ PVR_LOG_RETURN_IF_FALSE(ui64Count == 4 || ui64Count == 8,
+ "wrong RGX register size", -EIO);
+ PVR_LOG_RETURN_IF_FALSE(!(*pui64Pos & (ui64Count - 1)),
+ "register read offset isn't aligned", -EINVAL);
+
+ psDevInfo = psDeviceNode->pvDevice;
+
+ if (*pui64Pos >= SYS_RGX_DEV_UNMAPPED_FW_REG)
+ {
+ if (!psDevInfo->bFirmwareInitialised)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "RGX Register offset is above PCI mapped range but "
+ "Firmware isn't yet initialised\n"));
+ return -EIO;
+ }
+
+ if (ui64Count == 4)
+ ui64RegVal = (IMG_UINT64) *((IMG_UINT32 *) pcBuffer);
+ else
+ ui64RegVal = *((IMG_UINT64 *) pcBuffer);
+
+ eError = RGXScheduleRgxRegCommand(psDevInfo,
+ ui64RegVal,
+ ui64Count,
+ (IMG_UINT32) *pui64Pos,
+ IMG_TRUE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_LOG_ERROR(eError, "RGXScheduleRgxRegCommand");
+ return -EIO;
+ }
+
+ }
+ else
+ {
+ if (ui64Count == 4)
+ {
+ OSWriteHWReg32(psDevInfo->pvRegsBaseKM, *pui64Pos,
+ *((IMG_UINT32 *) (void *) pcBuffer));
+ }
+ else
+ {
+ OSWriteHWReg64(psDevInfo->pvRegsBaseKM, *pui64Pos,
+ *((IMG_UINT64 *) (void *) pcBuffer));
+ }
+ }
+
+ return ui64Count;
+}
+
+#endif /* SUPPORT_VALIDATION */
+
+#if defined(SUPPORT_VALIDATION) || defined(SUPPORT_RISCV_GDB)
+#define RISCV_DMI_SIZE (8U)
+
+static IMG_INT64 _RiscvDmiRead(IMG_CHAR *pcBuffer, IMG_UINT64 ui64Count,
+ IMG_UINT64 *pui64Pos, void *pvData)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;
+ PVRSRV_DEVICE_DEBUG_INFO *psDebugInfo = &psDeviceNode->sDebugInfo;
+
+ ui64Count = MIN(RISCV_DMI_SIZE, ui64Count);
+ memcpy(pcBuffer, &psDebugInfo->ui64RiscvDmi, ui64Count);
+
+ return ui64Count;
+}
+
+static IMG_INT64 _RiscvDmiWrite(const IMG_CHAR *pcBuffer, IMG_UINT64 ui64Count,
+ IMG_UINT64 *pui64Pos, void *pvData)
+{
+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData;
+ PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
+ PVRSRV_DEVICE_DEBUG_INFO *psDebugInfo = &psDeviceNode->sDebugInfo;
+
+ if (psDevInfo == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: devinfo is NULL", __func__));
+ return 0;
+ }
+
+ ui64Count -= 1; /* Drop `\0` */
+ ui64Count = MIN(RISCV_DMI_SIZE, ui64Count);
+
+ memcpy(&psDebugInfo->ui64RiscvDmi, pcBuffer, ui64Count);
+
+ RGXRiscvDmiOp(psDevInfo, &psDebugInfo->ui64RiscvDmi);
+
+ return ui64Count;
+}
+#endif
+
+#endif /* SUPPORT_RGX */
+
+#ifdef SUPPORT_VALIDATION
+
+static int TestMemLeakDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData)
+{
+ PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+ PVR_UNREFERENCED_PARAMETER(pvData);
+
+ PVR_RETURN_IF_FALSE(pvData != NULL, -EINVAL);
+
+ DIPrintf(psEntry, "os: %s, %u\ngpu: %s, %u\nmmu: %s, %u\n",
+ psPVRSRVData->sMemLeakIntervals.ui32OSAlloc ? "enabled" : "disabled",
+ psPVRSRVData->sMemLeakIntervals.ui32OSAlloc,
+ psPVRSRVData->sMemLeakIntervals.ui32GPU ? "enabled" : "disabled",
+ psPVRSRVData->sMemLeakIntervals.ui32GPU,
+ psPVRSRVData->sMemLeakIntervals.ui32MMU ? "enabled" : "disabled",
+ psPVRSRVData->sMemLeakIntervals.ui32MMU);
+
+ return 0;
+}
+
+static IMG_INT64 TestMemLeakDISet(const IMG_CHAR *pcBuffer, IMG_UINT64 ui64Count,
+ IMG_UINT64 *pui64Pos, void *pvData)
+{
+ PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+ IMG_CHAR *pcTemp;
+ unsigned long ui32MemLeakInterval;
+
+ PVR_UNREFERENCED_PARAMETER(pvData);
+
+ PVR_RETURN_IF_FALSE(pcBuffer != NULL, -EIO);
+ PVR_RETURN_IF_FALSE(pui64Pos != NULL && *pui64Pos == 0, -EIO);
+ PVR_RETURN_IF_FALSE(ui64Count <= 16, -EINVAL);
+ PVR_RETURN_IF_FALSE(pcBuffer[ui64Count - 1] == '\0', -EINVAL);
+
+ pcTemp = strchr(pcBuffer, ',');
+
+ if (kstrtoul(pcTemp+1, 0, &ui32MemLeakInterval) != 0)
+ {
+ return -EINVAL;
+ }
+
+ if (strncmp(pcBuffer, "os", pcTemp-pcBuffer) == 0)
+ {
+ psPVRSRVData->sMemLeakIntervals.ui32OSAlloc = ui32MemLeakInterval;
+ }
+ else if (strncmp(pcBuffer, "gpu", pcTemp-pcBuffer) == 0)
+ {
+ psPVRSRVData->sMemLeakIntervals.ui32GPU = ui32MemLeakInterval;
+ }
+ else if (strncmp(pcBuffer, "mmu", pcTemp-pcBuffer) == 0)
+ {
+ psPVRSRVData->sMemLeakIntervals.ui32MMU = ui32MemLeakInterval;
+ }
+ else
+ {
+ return -EINVAL;
+ }
+
+ *pui64Pos += ui64Count;
+ return ui64Count;
+}
+
+#endif /* SUPPORT_VALIDATION */
+
+#if defined(DEBUG) || defined(PVR_DPF_ADHOC_DEBUG_ON)
+
+/*************************************************************************/ /*!
+ Debug level DebugFS entry
+*/ /**************************************************************************/
+
+static int DebugLevelDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData)
+{
+ DIPrintf(psEntry, "%u\n", OSDebugLevel());
+
+ return 0;
+}
+
+#ifndef __GNUC__
+static int __builtin_ffsl(long int x)
+{
+ for (size_t i = 0; i < sizeof(x) * 8; i++)
+ {
+ if (x & (1 << i))
+ {
+ return i + 1;
+ }
+ }
+ return 0;
+}
+#endif /* __GNUC__ */
+
+static IMG_INT64 DebugLevelSet(const IMG_CHAR *pcBuffer, IMG_UINT64 ui64Count,
+ IMG_UINT64 *pui64Pos, void *pvData)
+{
+ const IMG_UINT uiMaxBufferSize = 6;
+ IMG_UINT32 ui32Level;
+
+ PVR_RETURN_IF_FALSE(pcBuffer != NULL, -EIO);
+ PVR_RETURN_IF_FALSE(pui64Pos != NULL && *pui64Pos == 0, -EIO);
+ PVR_RETURN_IF_FALSE(ui64Count > 0 && ui64Count < uiMaxBufferSize, -EINVAL);
+ PVR_RETURN_IF_FALSE(pcBuffer[ui64Count - 1] == '\0', -EINVAL);
+
+ if (sscanf(pcBuffer, "%u", &ui32Level) == 0)
+ {
+ return -EINVAL;
+ }
+
+ OSSetDebugLevel(ui32Level & ((1 << __builtin_ffsl(DBGPRIV_LAST)) - 1));
+
+ *pui64Pos += ui64Count;
+ return ui64Count;
+}
+#endif /* defined(DEBUG) || defined(PVR_DPF_ADHOC_DEBUG_ON) */
+
+PVRSRV_ERROR DebugCommonInitDriver(void)
+{
+ PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(psPVRSRVData != NULL);
+
+ /*
+ * The DebugFS entries are designed to work in a single device system but
+ * this function will be called multiple times in a multi-device system.
+ * Return an error in this case.
+ */
+ if (gpsVersionDIEntry)
+ {
+ return -EEXIST;
+ }
+
+#if defined(SUPPORT_RGX) && !defined(NO_HARDWARE)
+ if (SORgxGpuUtilStatsRegister(&ghGpuUtilUserDebugFS) != PVRSRV_OK)
+ {
+ return -ENOMEM;
+ }
+#endif /* defined(SUPPORT_RGX) && !defined(NO_HARDWARE) */
+
+ {
+ DI_ITERATOR_CB sIterator = {
+ .pfnStart = _VersionDIStart,
+ .pfnStop = _VersionDIStop,
+ .pfnNext = _VersionDINext,
+ .pfnShow = _VersionDIShow
+ };
+
+ eError = DICreateEntry("version", NULL, &sIterator, psPVRSRVData,
+ DI_ENTRY_TYPE_GENERIC, &gpsVersionDIEntry);
+ PVR_GOTO_IF_ERROR(eError, return_error_);
+ }
+
+ {
+ DI_ITERATOR_CB sIterator = {
+ .pfnStart = _DebugStatusDIStart,
+ .pfnStop = _DebugStatusDIStop,
+ .pfnNext = _DebugStatusDINext,
+ .pfnShow = _DebugStatusDIShow,
+ .pfnWrite = DebugStatusSet
+ };
+ eError = DICreateEntry("status", NULL, &sIterator, psPVRSRVData,
+ DI_ENTRY_TYPE_GENERIC, &gpsStatusDIEntry);
+ PVR_GOTO_IF_ERROR(eError, return_error_);
+ }
+
+#ifdef SUPPORT_RGX
+#ifdef SUPPORT_FIRMWARE_GCOV
+ {
+ DI_ITERATOR_CB sIterator = {
+ .pfnStart = _FirmwareGcovDIStart,
+ .pfnStop = _FirmwareGcovDIStop,
+ .pfnNext = _FirmwareGcovDINext,
+ .pfnShow = _FirmwareGcovDIShow
+ };
+
+ eError = DICreateEntry("firmware_gcov", NULL, &sIterator, psPVRSRVData,
+ DI_ENTRY_TYPE_GENERIC, &gpsFirmwareGcovDIEntry);
+ PVR_GOTO_IF_ERROR(eError, return_error_);
+ }
+#endif /* SUPPORT_FIRMWARE_GCOV */
+#endif /* SUPPORT_RGX */
+
+#ifdef SUPPORT_VALIDATION
+ {
+ DI_ITERATOR_CB sIterator = {
+ .pfnShow = TestMemLeakDIShow,
+ .pfnWrite = TestMemLeakDISet
+ };
+ eError = DICreateEntry("test_memleak", NULL, &sIterator, psPVRSRVData,
+ DI_ENTRY_TYPE_GENERIC, &gpsTestMemLeakDIEntry);
+ PVR_GOTO_IF_ERROR(eError, return_error_);
+ }
+#endif /* SUPPORT_VALIDATION */
+
+#if defined(DEBUG) || defined(PVR_DPF_ADHOC_DEBUG_ON)
+ {
+ DI_ITERATOR_CB sIterator = {
+ .pfnShow = DebugLevelDIShow,
+ .pfnWrite = DebugLevelSet
+ };
+ eError = DICreateEntry("debug_level", NULL, &sIterator, NULL,
+ DI_ENTRY_TYPE_GENERIC, &gpsDebugLevelDIEntry);
+ PVR_GOTO_IF_ERROR(eError, return_error_);
+ }
+#endif /* defined(DEBUG) || defined(PVR_DPF_ADHOC_DEBUG_ON) */
+
+ return PVRSRV_OK;
+
+return_error_:
+ DebugCommonDeInitDriver();
+
+ return eError;
+}
+
+void DebugCommonDeInitDriver(void)
+{
+#if defined(DEBUG) || defined(PVR_DPF_ADHOC_DEBUG_ON)
+ if (gpsDebugLevelDIEntry != NULL)
+ {
+ DIDestroyEntry(gpsDebugLevelDIEntry);
+ }
+#endif /* defined(DEBUG) || defined(PVR_DPF_ADHOC_DEBUG_ON) */
+
+#if defined(SUPPORT_RGX) && !defined(NO_HARDWARE)
+ if (ghGpuUtilUserDebugFS != NULL)
+ {
+ SORgxGpuUtilStatsUnregister(ghGpuUtilUserDebugFS);
+ ghGpuUtilUserDebugFS = NULL;
+ }
+#endif /* defined(SUPPORT_RGX) && !defined(NO_HARDWARE) */
+
+#ifdef SUPPORT_RGX
+#ifdef SUPPORT_FIRMWARE_GCOV
+ if (gpsFirmwareGcovDIEntry != NULL)
+ {
+ DIDestroyEntry(gpsFirmwareGcovDIEntry);
+ }
+#endif /* SUPPORT_FIRMWARE_GCOV */
+#endif /* SUPPORT_RGX */
+
+#ifdef SUPPORT_VALIDATION
+ if (gpsTestMemLeakDIEntry != NULL)
+ {
+ DIDestroyEntry(gpsTestMemLeakDIEntry);
+ }
+#endif /* SUPPORT_VALIDATION */
+
+ if (gpsStatusDIEntry != NULL)
+ {
+ DIDestroyEntry(gpsStatusDIEntry);
+ }
+
+ if (gpsVersionDIEntry != NULL)
+ {
+ DIDestroyEntry(gpsVersionDIEntry);
+ }
+}
+
+PVRSRV_ERROR DebugCommonInitDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVRSRV_DEVICE_DEBUG_INFO *psDebugInfo = &psDeviceNode->sDebugInfo;
+ PVRSRV_ERROR eError;
+
+ {
+ IMG_CHAR pszDeviceId[sizeof("gpu4294967296")];
+
+ OSSNPrintf(pszDeviceId, sizeof(pszDeviceId), "gpu%02d",
+ psDeviceNode->sDevId.ui32InternalID);
+
+ eError = DICreateGroup(pszDeviceId, NULL, &psDebugInfo->psGroup);
+ PVR_GOTO_IF_ERROR(eError, return_error_);
+ }
+
+ {
+ DI_ITERATOR_CB sIterator = {.pfnShow = _DebugDumpDebugDIShow};
+ eError = DICreateEntry("debug_dump", psDebugInfo->psGroup, &sIterator,
+ psDeviceNode, DI_ENTRY_TYPE_GENERIC,
+ &psDebugInfo->psDumpDebugEntry);
+ PVR_GOTO_IF_ERROR(eError, return_error_);
+ }
+
+#ifdef SUPPORT_RGX
+ if (! PVRSRV_VZ_MODE_IS(GUEST))
+ {
+ {
+ DI_ITERATOR_CB sIterator = {.pfnShow = _DebugFWTraceDIShow};
+ eError = DICreateEntry("firmware_trace", psDebugInfo->psGroup, &sIterator,
+ psDeviceNode, DI_ENTRY_TYPE_GENERIC,
+ &psDebugInfo->psFWTraceEntry);
+ PVR_GOTO_IF_ERROR(eError, return_error_);
+ }
+
+#if defined(SUPPORT_VALIDATION) || defined(SUPPORT_RISCV_GDB)
+ {
+ DI_ITERATOR_CB sIterator = {
+ .pfnRead = _RiscvDmiRead,
+ .pfnWrite = _RiscvDmiWrite
+ };
+ eError = DICreateEntry("riscv_dmi", psDebugInfo->psGroup, &sIterator, psDeviceNode,
+ DI_ENTRY_TYPE_RANDOM_ACCESS, &psDebugInfo->psRiscvDmiDIEntry);
+ PVR_GOTO_IF_ERROR(eError, return_error_);
+ psDebugInfo->ui64RiscvDmi = 0ULL;
+ }
+#endif /* SUPPORT_VALIDATION || SUPPORT_RISCV_GDB */
+ }
+#ifdef SUPPORT_VALIDATION
+ {
+ DI_ITERATOR_CB sIterator = {
+ .pfnSeek = _RgxRegsSeek,
+ .pfnRead = _RgxRegsRead,
+ .pfnWrite = _RgxRegsWrite
+ };
+ eError = DICreateEntry("rgxregs", psDebugInfo->psGroup, &sIterator, psDeviceNode,
+ DI_ENTRY_TYPE_RANDOM_ACCESS, &psDebugInfo->psRGXRegsEntry);
+
+ PVR_GOTO_IF_ERROR(eError, return_error_);
+ }
+#endif /* SUPPORT_VALIDATION */
+
+#ifdef SUPPORT_POWER_VALIDATION_VIA_DEBUGFS
+ if (! PVRSRV_VZ_MODE_IS(GUEST))
+ {
+ DI_ITERATOR_CB sIterator = {
+ .pfnShow = _PowMonTraceDIShow
+ };
+ eError = DICreateEntry("power_mon", psDebugInfo->psGroup, &sIterator, psDeviceNode,
+ DI_ENTRY_TYPE_GENERIC, &psDebugInfo->psPowMonEntry);
+ PVR_GOTO_IF_ERROR(eError, return_error_);
+ }
+#endif /* SUPPORT_POWER_VALIDATION_VIA_DEBUGFS */
+#ifdef SUPPORT_POWER_SAMPLING_VIA_DEBUGFS
+ {
+ DI_ITERATOR_CB sIterator = {
+ .pfnShow = _DebugPowerDataDIShow,
+ .pfnWrite = PowerDataSet
+ };
+ eError = DICreateEntry("power_data", psDebugInfo->psGroup, &sIterator, psDeviceNode,
+ DI_ENTRY_TYPE_GENERIC, &psDebugInfo->psPowerDataEntry);
+ PVR_GOTO_IF_ERROR(eError, return_error_);
+ }
+#endif /* SUPPORT_POWER_SAMPLING_VIA_DEBUGFS */
+#endif /* SUPPORT_RGX */
+
+ return PVRSRV_OK;
+
+return_error_:
+ DebugCommonDeInitDevice(psDeviceNode);
+
+ return eError;
+}
+
+void DebugCommonDeInitDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ PVRSRV_DEVICE_DEBUG_INFO *psDebugInfo = &psDeviceNode->sDebugInfo;
+
+#ifdef SUPPORT_POWER_SAMPLING_VIA_DEBUGFS
+ if (psDebugInfo->psPowerDataEntry != NULL)
+ {
+ DIDestroyEntry(psDebugInfo->psPowerDataEntry);
+ psDebugInfo->psPowerDataEntry = NULL;
+ }
+#endif /* SUPPORT_POWER_SAMPLING_VIA_DEBUGFS */
+
+#ifdef SUPPORT_POWER_VALIDATION_VIA_DEBUGFS
+ if (psDebugInfo->psPowMonEntry != NULL)
+ {
+ DIDestroyEntry(psDebugInfo->psPowMonEntry);
+ psDebugInfo->psPowMonEntry = NULL;
+ }
+#endif /* SUPPORT_POWER_VALIDATION_VIA_DEBUGFS */
+
+#ifdef SUPPORT_VALIDATION
+ if (psDebugInfo->psRGXRegsEntry != NULL)
+ {
+ DIDestroyEntry(psDebugInfo->psRGXRegsEntry);
+ psDebugInfo->psRGXRegsEntry = NULL;
+ }
+#endif /* SUPPORT_VALIDATION */
+
+#ifdef SUPPORT_RGX
+ if (psDebugInfo->psFWTraceEntry != NULL)
+ {
+ DIDestroyEntry(psDebugInfo->psFWTraceEntry);
+ psDebugInfo->psFWTraceEntry = NULL;
+ }
+
+#if defined(SUPPORT_VALIDATION) || defined(SUPPORT_RISCV_GDB)
+ if (psDebugInfo->psRiscvDmiDIEntry != NULL)
+ {
+ DIDestroyEntry(psDebugInfo->psRiscvDmiDIEntry);
+ psDebugInfo->psRiscvDmiDIEntry = NULL;
+ }
+#endif
+#endif /* SUPPORT_RGX */
+
+ if (psDebugInfo->psDumpDebugEntry != NULL)
+ {
+ DIDestroyEntry(psDebugInfo->psDumpDebugEntry);
+ psDebugInfo->psDumpDebugEntry = NULL;
+ }
+
+ if (psDebugInfo->psGroup != NULL)
+ {
+ DIDestroyGroup(psDebugInfo->psGroup);
+ psDebugInfo->psGroup = NULL;
+ }
+}
diff --git a/drivers/gpu/drm/img-rogue/debug_common.h b/drivers/gpu/drm/img-rogue/debug_common.h
new file mode 100644
index 000000000..e8b902f47
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/debug_common.h
@@ -0,0 +1,55 @@
+/*************************************************************************/ /*!
+@File
+@Title Common debug definitions and functions.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef DEBUG_COMMON_H
+#define DEBUG_COMMON_H
+
+#include "pvrsrv_error.h"
+#include "device.h"
+
+PVRSRV_ERROR DebugCommonInitDriver(void);
+void DebugCommonDeInitDriver(void);
+
+PVRSRV_ERROR DebugCommonInitDevice(PVRSRV_DEVICE_NODE *psDeviceNode);
+void DebugCommonDeInitDevice(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+#endif /* DEBUG_COMMON_H */
diff --git a/drivers/gpu/drm/img-rogue/device.h b/drivers/gpu/drm/img-rogue/device.h
new file mode 100644
index 000000000..29ee8cb1c
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/device.h
@@ -0,0 +1,590 @@
+/**************************************************************************/ /*!
+@File
+@Title Common Device header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Device related function templates and defines
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#ifndef DEVICE_H
+#define DEVICE_H
+
+#include "devicemem_heapcfg.h"
+#include "mmu_common.h"
+#include "ra.h" /* RA_ARENA */
+#include "pvrsrv_device.h"
+#include "sync_checkpoint.h"
+#include "srvkm.h"
+#include "physheap.h"
+#include "sync_internal.h"
+#include "sysinfo.h"
+#include "dllist.h"
+
+#include "rgx_bvnc_defs_km.h"
+
+#include "lock.h"
+
+#include "power.h"
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+#include "virt_validation_defs.h"
+#endif
+
+typedef struct _PVRSRV_POWER_DEV_TAG_ *PPVRSRV_POWER_DEV;
+
+struct SYNC_RECORD;
+
+struct _CONNECTION_DATA_;
+
+/*************************************************************************/ /*!
+ @Function AllocUFOBlockCallback
+ @Description Device specific callback for allocation of a UFO block
+
+ @Input psDeviceNode Pointer to device node to allocate
+ the UFO for.
+ @Output ppsMemDesc Pointer to pointer for the memdesc of
+ the allocation
+ @Output pui32SyncAddr FW Base address of the UFO block
+ @Output puiSyncPrimBlockSize Size of the UFO block
+
+ @Return PVRSRV_OK if allocation was successful
+*/ /**************************************************************************/
+typedef PVRSRV_ERROR (*AllocUFOBlockCallback)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+ DEVMEM_MEMDESC **ppsMemDesc,
+ IMG_UINT32 *pui32SyncAddr,
+ IMG_UINT32 *puiSyncPrimBlockSize);
+
+/*************************************************************************/ /*!
+ @Function FreeUFOBlockCallback
+ @Description Device specific callback for freeing of a UFO
+
+ @Input psDeviceNode Pointer to device node that the UFO block was
+ allocated from.
+ @Input psMemDesc Pointer to pointer for the memdesc of the UFO
+ block to free.
+*/ /**************************************************************************/
+typedef void (*FreeUFOBlockCallback)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+ DEVMEM_MEMDESC *psMemDesc);
+
+typedef struct _PVRSRV_DEVICE_IDENTIFIER_
+{
+ /* Pdump memory and register bank names */
+ IMG_CHAR *pszPDumpDevName;
+ IMG_CHAR *pszPDumpRegName;
+
+ /* Under Linux, this is the minor number of RenderNode corresponding to this Device */
+ IMG_INT32 i32OsDeviceID;
+ /* Services layer enumeration of the device used in pvrdebug */
+ IMG_UINT32 ui32InternalID;
+} PVRSRV_DEVICE_IDENTIFIER;
+
+typedef struct _DEVICE_MEMORY_INFO_
+{
+ /* Heap count. Doesn't include additional heaps from PVRSRVCreateDeviceMemHeap */
+ IMG_UINT32 ui32HeapCount;
+
+ /* Blueprints for creating new device memory contexts */
+ IMG_UINT32 uiNumHeapConfigs;
+ DEVMEM_HEAP_CONFIG *psDeviceMemoryHeapConfigArray;
+ DEVMEM_HEAP_BLUEPRINT *psDeviceMemoryHeap;
+} DEVICE_MEMORY_INFO;
+
+
+typedef struct _PG_HANDLE_
+{
+ union
+ {
+ void *pvHandle;
+ IMG_UINT64 ui64Handle;
+ }u;
+ /* The allocation order is log2 value of the number of pages to allocate.
+ * As such this is a correspondingly small value. E.g, for order 4 we
+ * are talking 2^4 * PAGE_SIZE contiguous allocation.
+ * DevPxAlloc API does not need to support orders higher than 4.
+ */
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+ IMG_BYTE uiOrder; /* Order of the corresponding allocation */
+ IMG_BYTE uiOSid; /* OSid to use for allocation arena.
+ * Connection-specific. */
+ IMG_BYTE uiPad1,
+ uiPad2; /* Spare */
+#else
+ IMG_BYTE uiOrder; /* Order of the corresponding allocation */
+ IMG_BYTE uiPad1,
+ uiPad2,
+ uiPad3; /* Spare */
+#endif
+} PG_HANDLE;
+
+#define MMU_BAD_PHYS_ADDR (0xbadbad00badULL)
+#define DUMMY_PAGE ("DUMMY_PAGE")
+#define DEV_ZERO_PAGE ("DEV_ZERO_PAGE")
+#define PVR_DUMMY_PAGE_INIT_VALUE (0x0)
+#define PVR_ZERO_PAGE_INIT_VALUE (0x0)
+
+typedef struct __DEFAULT_PAGE__
+{
+ /*Page handle for the page allocated (UMA/LMA)*/
+ PG_HANDLE sPageHandle;
+ POS_LOCK psPgLock;
+ ATOMIC_T atRefCounter;
+ /*Default page size in terms of log2 */
+ IMG_UINT32 ui32Log2PgSize;
+ IMG_UINT64 ui64PgPhysAddr;
+#if defined(PDUMP)
+ IMG_HANDLE hPdumpPg;
+#endif
+} PVRSRV_DEF_PAGE;
+
+typedef enum _PVRSRV_DEVICE_STATE_
+{
+ PVRSRV_DEVICE_STATE_UNDEFINED = 0,
+ PVRSRV_DEVICE_STATE_INIT,
+ PVRSRV_DEVICE_STATE_ACTIVE,
+ PVRSRV_DEVICE_STATE_DEINIT,
+ PVRSRV_DEVICE_STATE_BAD,
+} PVRSRV_DEVICE_STATE;
+
+typedef enum _PVRSRV_DEVICE_HEALTH_STATUS_
+{
+ PVRSRV_DEVICE_HEALTH_STATUS_UNDEFINED = 0,
+ PVRSRV_DEVICE_HEALTH_STATUS_OK,
+ PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING,
+ PVRSRV_DEVICE_HEALTH_STATUS_DEAD,
+ PVRSRV_DEVICE_HEALTH_STATUS_FAULT
+} PVRSRV_DEVICE_HEALTH_STATUS;
+
+typedef enum _PVRSRV_DEVICE_HEALTH_REASON_
+{
+ PVRSRV_DEVICE_HEALTH_REASON_NONE = 0,
+ PVRSRV_DEVICE_HEALTH_REASON_ASSERTED,
+ PVRSRV_DEVICE_HEALTH_REASON_POLL_FAILING,
+ PVRSRV_DEVICE_HEALTH_REASON_TIMEOUTS,
+ PVRSRV_DEVICE_HEALTH_REASON_QUEUE_CORRUPT,
+ PVRSRV_DEVICE_HEALTH_REASON_QUEUE_STALLED,
+ PVRSRV_DEVICE_HEALTH_REASON_IDLING,
+ PVRSRV_DEVICE_HEALTH_REASON_RESTARTING,
+ PVRSRV_DEVICE_HEALTH_REASON_MISSING_INTERRUPTS
+} PVRSRV_DEVICE_HEALTH_REASON;
+
+typedef enum _PVRSRV_DEVICE_DEBUG_DUMP_STATUS_
+{
+ PVRSRV_DEVICE_DEBUG_DUMP_NONE = 0,
+ PVRSRV_DEVICE_DEBUG_DUMP_CAPTURE
+} PVRSRV_DEVICE_DEBUG_DUMP_STATUS;
+
+typedef struct _MMU_PX_SETUP_
+{
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+ PVRSRV_ERROR (*pfnDevPxAllocGPV)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, size_t uiSize,
+ PG_HANDLE *psMemHandle, IMG_DEV_PHYADDR *psDevPAddr,
+ IMG_UINT32 ui32OSid, IMG_PID uiPid);
+#endif
+ PVRSRV_ERROR (*pfnDevPxAlloc)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, size_t uiSize,
+ PG_HANDLE *psMemHandle, IMG_DEV_PHYADDR *psDevPAddr,
+ IMG_PID uiPid);
+
+ void (*pfnDevPxFree)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, PG_HANDLE *psMemHandle);
+
+ PVRSRV_ERROR (*pfnDevPxMap)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, PG_HANDLE *pshMemHandle,
+ size_t uiSize, IMG_DEV_PHYADDR *psDevPAddr,
+ void **pvPtr);
+
+ void (*pfnDevPxUnMap)(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
+ PG_HANDLE *psMemHandle, void *pvPtr);
+
+ PVRSRV_ERROR (*pfnDevPxClean)(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
+ PG_HANDLE *pshMemHandle,
+ IMG_UINT32 uiOffset,
+ IMG_UINT32 uiLength);
+
+ IMG_UINT32 uiMMUPxLog2AllocGran;
+
+ RA_ARENA *psPxRA;
+} MMU_PX_SETUP;
+
+#ifndef DI_GROUP_DEFINED
+#define DI_GROUP_DEFINED
+typedef struct DI_GROUP DI_GROUP;
+#endif
+#ifndef DI_ENTRY_DEFINED
+#define DI_ENTRY_DEFINED
+typedef struct DI_ENTRY DI_ENTRY;
+#endif
+
+typedef struct _PVRSRV_DEVICE_DEBUG_INFO_
+{
+ DI_GROUP *psGroup;
+ DI_ENTRY *psDumpDebugEntry;
+#ifdef SUPPORT_RGX
+ DI_ENTRY *psFWTraceEntry;
+#if defined(SUPPORT_VALIDATION) || defined(SUPPORT_RISCV_GDB)
+ DI_ENTRY *psRiscvDmiDIEntry;
+ IMG_UINT64 ui64RiscvDmi;
+#endif
+#endif /* SUPPORT_RGX */
+#ifdef SUPPORT_VALIDATION
+ DI_ENTRY *psRGXRegsEntry;
+#endif /* SUPPORT_VALIDATION */
+#ifdef SUPPORT_POWER_VALIDATION_VIA_DEBUGFS
+ DI_ENTRY *psPowMonEntry;
+#endif
+#ifdef SUPPORT_POWER_SAMPLING_VIA_DEBUGFS
+ DI_ENTRY *psPowerDataEntry;
+#endif
+} PVRSRV_DEVICE_DEBUG_INFO;
+
+#if defined(PVRSRV_DEBUG_LISR_EXECUTION)
+#define RGX_LISR_INIT (0U)
+#define RGX_LISR_DEVICE_NOT_POWERED (1U)
+#define RGX_LISR_NOT_TRIGGERED_BY_HW (2U)
+#define RGX_LISR_FW_IRQ_COUNTER_NOT_UPDATED (3U)
+#define RGX_LISR_PROCESSED (4U)
+
+typedef IMG_UINT32 LISR_STATUS;
+
+typedef struct _LISR_EXECUTION_INFO_
+{
+ /* status of last LISR invocation */
+ LISR_STATUS ui32Status;
+
+ /* snapshot from the last LISR invocation */
+#if defined(RGX_FW_IRQ_OS_COUNTERS)
+ IMG_UINT32 aui32InterruptCountSnapshot[RGX_NUM_OS_SUPPORTED];
+#else
+ IMG_UINT32 aui32InterruptCountSnapshot[RGXFW_THREAD_NUM];
+#endif
+
+ /* time of the last LISR invocation */
+ IMG_UINT64 ui64Clockns;
+} LISR_EXECUTION_INFO;
+
+#define UPDATE_LISR_DBG_STATUS(status) psDeviceNode->sLISRExecutionInfo.ui32Status = (status)
+#define UPDATE_LISR_DBG_SNAPSHOT(idx, val) psDeviceNode->sLISRExecutionInfo.aui32InterruptCountSnapshot[idx] = (val)
+#define UPDATE_LISR_DBG_TIMESTAMP() psDeviceNode->sLISRExecutionInfo.ui64Clockns = OSClockns64()
+#define UPDATE_LISR_DBG_COUNTER() psDeviceNode->ui64nLISR++
+#define UPDATE_MISR_DBG_COUNTER() psDeviceNode->ui64nMISR++
+#else
+#define UPDATE_LISR_DBG_STATUS(status)
+#define UPDATE_LISR_DBG_SNAPSHOT(idx, val)
+#define UPDATE_LISR_DBG_TIMESTAMP()
+#define UPDATE_LISR_DBG_COUNTER()
+#define UPDATE_MISR_DBG_COUNTER()
+#endif /* defined(PVRSRV_DEBUG_LISR_EXECUTION) */
+
+typedef struct _PVRSRV_DEVICE_NODE_
+{
+ PVRSRV_DEVICE_IDENTIFIER sDevId;
+
+ PVRSRV_DEVICE_STATE eDevState;
+ PVRSRV_DEVICE_FABRIC_TYPE eDevFabricType;
+
+ ATOMIC_T eHealthStatus; /* Holds values from PVRSRV_DEVICE_HEALTH_STATUS */
+ ATOMIC_T eHealthReason; /* Holds values from PVRSRV_DEVICE_HEALTH_REASON */
+ ATOMIC_T eDebugDumpRequested; /* Holds values from PVRSRV_DEVICE_DEBUG_DUMP_STATUS */
+
+ IMG_HANDLE *hDebugTable;
+
+ /* device specific MMU attributes */
+ MMU_DEVICEATTRIBS *psMMUDevAttrs;
+ /* Device specific MMU firmware attributes, used only in some devices */
+ MMU_DEVICEATTRIBS *psFirmwareMMUDevAttrs;
+
+ MMU_PX_SETUP sDevMMUPxSetup;
+
+ /* lock for power state transitions */
+ POS_LOCK hPowerLock;
+ IMG_PID uiPwrLockOwnerPID; /* Only valid between lock and corresponding unlock
+ operations of hPowerLock */
+
+ /* current system device power state */
+ PVRSRV_SYS_POWER_STATE eCurrentSysPowerState;
+ PPVRSRV_POWER_DEV psPowerDev;
+
+ /* multicore configuration information */
+ IMG_UINT32 ui32MultiCoreNumCores; /* total cores primary + secondaries. 0 for non-multi core */
+ IMG_UINT32 ui32MultiCorePrimaryId; /* primary core id for this device */
+ IMG_UINT64 *pui64MultiCoreCapabilities; /* capabilities for each core */
+
+ /*
+ callbacks the device must support:
+ */
+
+ PVRSRV_ERROR (*pfnDevSLCFlushRange)(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
+ MMU_CONTEXT *psMMUContext,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_BOOL bInvalidate);
+
+ PVRSRV_ERROR (*pfnInvalFBSCTable)(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
+ MMU_CONTEXT *psMMUContext,
+ IMG_UINT64 ui64FBSCEntries);
+
+ PVRSRV_ERROR (*pfnValidateOrTweakPhysAddrs)(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
+ MMU_DEVICEATTRIBS *psDevAttrs,
+ IMG_UINT64 *pui64Addr);
+
+ void (*pfnMMUCacheInvalidate)(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
+ MMU_CONTEXT *psMMUContext,
+ MMU_LEVEL eLevel,
+ IMG_BOOL bUnmap);
+
+ PVRSRV_ERROR (*pfnMMUCacheInvalidateKick)(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
+ IMG_UINT32 *pui32NextMMUInvalidateUpdate);
+
+ IMG_UINT32 (*pfnMMUCacheGetInvalidateCounter)(struct _PVRSRV_DEVICE_NODE_ *psDevNode);
+
+
+ void (*pfnDumpDebugInfo)(struct _PVRSRV_DEVICE_NODE_ *psDevNode);
+
+ PVRSRV_ERROR (*pfnUpdateHealthStatus)(struct _PVRSRV_DEVICE_NODE_ *psDevNode,
+ IMG_BOOL bIsTimerPoll);
+
+#if defined(SUPPORT_AUTOVZ)
+ void (*pfnUpdateAutoVzWatchdog)(struct _PVRSRV_DEVICE_NODE_ *psDevNode);
+#endif
+
+ PVRSRV_ERROR (*pfnValidationGPUUnitsPowerChange)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT32 ui32NewState);
+
+ PVRSRV_ERROR (*pfnResetHWRLogs)(struct _PVRSRV_DEVICE_NODE_ *psDevNode);
+
+ PVRSRV_ERROR (*pfnVerifyBVNC)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT64 ui64GivenBVNC, IMG_UINT64 ui64CoreIdMask);
+
+ /* Method to drain device HWPerf packets from firmware buffer to host buffer */
+ PVRSRV_ERROR (*pfnServiceHWPerf)(struct _PVRSRV_DEVICE_NODE_ *psDevNode);
+
+ PVRSRV_ERROR (*pfnDeviceVersionString)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_CHAR **ppszVersionString);
+
+ PVRSRV_ERROR (*pfnDeviceClockSpeed)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_PUINT32 pui32RGXClockSpeed);
+
+ PVRSRV_ERROR (*pfnSoftReset)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT64 ui64ResetValue1, IMG_UINT64 ui64ResetValue2);
+
+ PVRSRV_ERROR (*pfnAlignmentCheck)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT32 ui32FWAlignChecksSize, IMG_UINT32 aui32FWAlignChecks[]);
+ IMG_BOOL (*pfnCheckDeviceFeature)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT64 ui64FeatureMask);
+
+ IMG_INT32 (*pfnGetDeviceFeatureValue)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, enum _RGX_FEATURE_WITH_VALUE_INDEX_ eFeatureIndex);
+
+ PVRSRV_ERROR (*pfnGetMultiCoreInfo)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT32 ui32CapsSize,
+ IMG_UINT32 *pui32NumCores, IMG_UINT64 *pui64Caps);
+
+ IMG_BOOL (*pfnHasFBCDCVersion31)(struct _PVRSRV_DEVICE_NODE_ *psDevNode);
+
+ MMU_DEVICEATTRIBS* (*pfnGetMMUDeviceAttributes)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_BOOL bKernelMemoryCtx);
+
+ PVRSRV_DEVICE_CONFIG *psDevConfig;
+
+ /* device post-finalise compatibility check */
+ PVRSRV_ERROR (*pfnInitDeviceCompatCheck) (struct _PVRSRV_DEVICE_NODE_*);
+
+ /* initialise device-specific physheaps */
+ PVRSRV_ERROR (*pfnPhysMemDeviceHeapsInit) (struct _PVRSRV_DEVICE_NODE_ *);
+
+ /* initialise fw mmu, if FW not using GPU mmu, NULL otherwise. */
+ PVRSRV_ERROR (*pfnFwMMUInit) (struct _PVRSRV_DEVICE_NODE_ *);
+
+ /* information about the device's address space and heaps */
+ DEVICE_MEMORY_INFO sDevMemoryInfo;
+
+ /* device's shared-virtual-memory heap max virtual address */
+ IMG_UINT64 ui64GeneralSVMHeapTopVA;
+
+ ATOMIC_T iNumClockSpeedChanges;
+
+ /* private device information */
+ void *pvDevice;
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+ RA_ARENA *psOSSharedArena;
+ RA_ARENA *psOSidSubArena[GPUVIRT_VALIDATION_NUM_OS];
+ /* Number of supported OSid for this device node given available memory */
+ IMG_UINT32 ui32NumOSId;
+#endif
+
+ /* FW_MAIN, FW_CONFIG and FW_GUEST heaps. Should be part of registered heaps? */
+ PHYS_HEAP *psFWMainPhysHeap;
+ PHYS_HEAP *psFWCfgPhysHeap;
+ PHYS_HEAP *apsFWPremapPhysHeap[RGX_NUM_OS_SUPPORTED];
+
+ IMG_UINT32 ui32RegisteredPhysHeaps;
+ PHYS_HEAP **papsRegisteredPhysHeaps;
+
+ /* PHYS_HEAP Mapping table to the platform's physical memory heap(s)
+ * used by this device. The physical heaps are created based on
+ * the PHYS_HEAP_CONFIG data from the platform's system layer at device
+ * creation time.
+ *
+ * Contains PVRSRV_PHYS_HEAP_LAST entries for all the possible physical heaps allowed in the design.
+ * It allows the system layer PhysHeaps for the device to be identified for use in creating new PMRs.
+ * See PhysHeapCreatePMR()
+ */
+ PHYS_HEAP *apsPhysHeap[PVRSRV_PHYS_HEAP_LAST];
+ IMG_UINT32 ui32UserAllocHeapCount;
+
+ /* RA reserved for storing the MMU mappings of firmware.
+ * The memory backing up this RA must persist between driver or OS reboots */
+ RA_ARENA *psFwMMUReservedMemArena;
+
+ /* Flag indicating if the firmware has been initialised during the
+ * 1st boot of the Host driver according to the AutoVz life-cycle. */
+ IMG_BOOL bAutoVzFwIsUp;
+
+ struct _PVRSRV_DEVICE_NODE_ *psNext;
+ struct _PVRSRV_DEVICE_NODE_ **ppsThis;
+
+ /* Functions for notification about memory contexts */
+ PVRSRV_ERROR (*pfnRegisterMemoryContext)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+ MMU_CONTEXT *psMMUContext,
+ IMG_HANDLE *hPrivData);
+ void (*pfnUnregisterMemoryContext)(IMG_HANDLE hPrivData);
+
+ /* Functions for allocation/freeing of UFOs */
+ AllocUFOBlockCallback pfnAllocUFOBlock; /*!< Callback for allocation of a block of UFO memory */
+ FreeUFOBlockCallback pfnFreeUFOBlock; /*!< Callback for freeing of a block of UFO memory */
+
+ IMG_HANDLE hSyncServerRecordNotify;
+ POS_LOCK hSyncServerRecordLock;
+ IMG_UINT32 ui32SyncServerRecordCount;
+ IMG_UINT32 ui32SyncServerRecordCountHighWatermark;
+ DLLIST_NODE sSyncServerRecordList;
+ struct SYNC_RECORD *apsSyncServerRecordsFreed[PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN];
+ IMG_UINT32 uiSyncServerRecordFreeIdx;
+
+ IMG_HANDLE hSyncCheckpointRecordNotify;
+ POS_LOCK hSyncCheckpointRecordLock;
+ IMG_UINT32 ui32SyncCheckpointRecordCount;
+ IMG_UINT32 ui32SyncCheckpointRecordCountHighWatermark;
+ DLLIST_NODE sSyncCheckpointRecordList;
+ struct SYNC_CHECKPOINT_RECORD *apsSyncCheckpointRecordsFreed[PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN];
+ IMG_UINT32 uiSyncCheckpointRecordFreeIdx;
+
+ IMG_HANDLE hSyncCheckpointNotify;
+ POS_SPINLOCK hSyncCheckpointListLock; /*!< Protects sSyncCheckpointSyncsList */
+ DLLIST_NODE sSyncCheckpointSyncsList;
+
+ PSYNC_CHECKPOINT_CONTEXT hSyncCheckpointContext;
+ PSYNC_PRIM_CONTEXT hSyncPrimContext;
+
+ /* With this sync-prim we make sure the MMU cache is flushed
+ * before we free the page table memory */
+ PVRSRV_CLIENT_SYNC_PRIM *psMMUCacheSyncPrim;
+ IMG_UINT32 ui32NextMMUInvalidateUpdate;
+
+ IMG_HANDLE hCmdCompNotify;
+ IMG_HANDLE hDbgReqNotify;
+ IMG_HANDLE hAppHintDbgReqNotify;
+
+ PVRSRV_DEF_PAGE sDummyPage;
+ PVRSRV_DEF_PAGE sDevZeroPage;
+
+ POSWR_LOCK hMemoryContextPageFaultNotifyListLock;
+ DLLIST_NODE sMemoryContextPageFaultNotifyListHead;
+
+ /* System DMA capability */
+ IMG_BOOL bHasSystemDMA;
+ IMG_HANDLE hDmaTxChan;
+ IMG_HANDLE hDmaRxChan;
+
+#if defined(PDUMP)
+ /*
+ * FBC clear color register default value to use.
+ */
+ IMG_UINT64 ui64FBCClearColour;
+
+ /* Device-level callback which is called when pdump.exe starts.
+ * Should be implemented in device-specific init code, e.g. rgxinit.c
+ */
+ PVRSRV_ERROR (*pfnPDumpInitDevice)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
+ /* device-level callback to return pdump ID associated to a memory context */
+ IMG_UINT32 (*pfnMMUGetContextID)(IMG_HANDLE hDevMemContext);
+
+ IMG_UINT8 *pui8DeferredSyncCPSignal; /*! Deferred fence events buffer */
+
+ IMG_UINT16 ui16SyncCPReadIdx; /*! Read index in the above deferred fence events buffer */
+
+ IMG_UINT16 ui16SyncCPWriteIdx; /*! Write index in the above deferred fence events buffer */
+
+ POS_LOCK hSyncCheckpointSignalLock; /*! Guards data shared between an sleepable-contexts */
+
+ void *pvSyncCPMISR; /*! MISR to emit pending/deferred fence signals */
+
+ void *hTransition; /*!< SyncCheckpoint PdumpTransition Cookie */
+
+ DLLIST_NODE sSyncCheckpointContextListHead; /*!< List head for the sync chkpt contexts */
+
+ POS_LOCK hSyncCheckpointContextListLock; /*! lock for accessing sync chkpt contexts list */
+
+#endif
+
+#if defined(SUPPORT_VALIDATION)
+ POS_LOCK hValidationLock;
+#endif
+
+ POS_LOCK hConnectionsLock; /*!< Lock protecting sConnections */
+ DLLIST_NODE sConnections; /*!< The list of currently active connection objects for this device node */
+#if defined(PVRSRV_DEBUG_LISR_EXECUTION)
+ LISR_EXECUTION_INFO sLISRExecutionInfo; /*!< Information about the last execution of the LISR */
+ IMG_UINT64 ui64nLISR; /*!< Number of LISR calls seen */
+ IMG_UINT64 ui64nMISR; /*!< Number of MISR calls made */
+#endif
+
+ PVRSRV_DEVICE_DEBUG_INFO sDebugInfo;
+} PVRSRV_DEVICE_NODE;
+
+/*
+ * Macros to be used instead of calling directly the pfns since these macros
+ * will expand the feature passed as argument into the bitmask/index to work
+ * with the macros defined in rgx_bvnc_defs_km.h
+ */
+#define PVRSRV_IS_FEATURE_SUPPORTED(psDevNode, Feature) \
+ psDevNode->pfnCheckDeviceFeature(psDevNode, RGX_FEATURE_##Feature##_BIT_MASK)
+#define PVRSRV_GET_DEVICE_FEATURE_VALUE(psDevNode, Feature) \
+ psDevNode->pfnGetDeviceFeatureValue(psDevNode, RGX_FEATURE_##Feature##_IDX)
+
+PVRSRV_ERROR PVRSRVDeviceFinalise(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_BOOL bInitSuccessful);
+
+PVRSRV_ERROR PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+PVRSRV_ERROR RGXClientConnectCompatCheck_ClientAgainstFW(PVRSRV_DEVICE_NODE * psDeviceNode, IMG_UINT32 ui32ClientBuildOptions);
+
+
+#endif /* DEVICE_H */
+
+/******************************************************************************
+ End of file (device.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/device_connection.h b/drivers/gpu/drm/img-rogue/device_connection.h
new file mode 100644
index 000000000..24917745f
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/device_connection.h
@@ -0,0 +1,123 @@
+/*************************************************************************/ /*!
+@File device_connection.h
+@Title
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(DEVICE_CONNECTION_H)
+#define DEVICE_CONNECTION_H
+
+#include "img_types.h"
+#include "img_defs.h"
+
+#if defined(__KERNEL__)
+typedef struct _PVRSRV_DEVICE_NODE_ *SHARED_DEV_CONNECTION;
+#else
+#include "connection.h"
+typedef const struct PVRSRV_DEV_CONNECTION_TAG *SHARED_DEV_CONNECTION;
+#endif
+
+/******************************************************************************
+ * Device capability flags and masks
+ *
+ * Following bitmask shows allocated ranges and values for our device
+ * capability settings:
+ *
+ * 31 27 23 19 15 11 7 3 0
+ * |...|...|...|...|...|...|...|...
+ * ** CACHE_COHERENT [0x1..0x2]
+ * x PVRSRV_CACHE_COHERENT_DEVICE_FLAG
+ * x. PVRSRV_CACHE_COHERENT_CPU_FLAG
+ * *... NONMAPPABLE_MEMORY [0x8]
+ * x... PVRSRV_NONMAPPABLE_MEMORY_PRESENT_FLAG
+ * *.... PDUMP_IS_RECORDING [0x10]
+ * x.... PVRSRV_PDUMP_IS_RECORDING
+ * ***........ DEVMEM_SVM_ALLOC [0x100..0x400]
+ * x........ PVRSRV_DEVMEM_SVM_ALLOC_UNSUPPORTED
+ * x......... PVRSRV_DEVMEM_SVM_ALLOC_SUPPORTED
+ * x.......... PVRSRV_DEVMEM_SVM_ALLOC_CANFAIL
+ * *........... FBCDC_V3_1 [0x800]
+ * x........... FBCDC_V3_1_USED
+ * *............ PVRSRV_SYSTEM_DMA
+ * x............ PVRSRV_SYSTEM_DMA_USED
+ * |...|...|...|...|...|...|...|...
+ *****************************************************************************/
+
+/* Flag to be passed over the bridge during connection stating whether CPU cache coherent is available*/
+#define PVRSRV_CACHE_COHERENT_SHIFT (0)
+#define PVRSRV_CACHE_COHERENT_DEVICE_FLAG (1U << PVRSRV_CACHE_COHERENT_SHIFT)
+#define PVRSRV_CACHE_COHERENT_CPU_FLAG (2U << PVRSRV_CACHE_COHERENT_SHIFT)
+#define PVRSRV_CACHE_COHERENT_EMULATE_FLAG (4U << PVRSRV_CACHE_COHERENT_SHIFT)
+#define PVRSRV_CACHE_COHERENT_MASK (7U << PVRSRV_CACHE_COHERENT_SHIFT)
+
+/* Flag to be passed over the bridge during connection stating whether CPU non-mappable memory is present */
+#define PVRSRV_NONMAPPABLE_MEMORY_PRESENT_SHIFT (7)
+#define PVRSRV_NONMAPPABLE_MEMORY_PRESENT_FLAG (1U << PVRSRV_NONMAPPABLE_MEMORY_PRESENT_SHIFT)
+
+/* Flag to be passed over the bridge to indicate PDump activity */
+#define PVRSRV_PDUMP_IS_RECORDING_SHIFT (4)
+#define PVRSRV_PDUMP_IS_RECORDING (1U << PVRSRV_PDUMP_IS_RECORDING_SHIFT)
+
+/* Flag to be passed over the bridge during connection stating SVM allocation availability */
+#define PVRSRV_DEVMEM_SVM_ALLOC_SHIFT (8)
+#define PVRSRV_DEVMEM_SVM_ALLOC_UNSUPPORTED (1U << PVRSRV_DEVMEM_SVM_ALLOC_SHIFT)
+#define PVRSRV_DEVMEM_SVM_ALLOC_SUPPORTED (2U << PVRSRV_DEVMEM_SVM_ALLOC_SHIFT)
+#define PVRSRV_DEVMEM_SVM_ALLOC_CANFAIL (4U << PVRSRV_DEVMEM_SVM_ALLOC_SHIFT)
+
+/* Flag to be passed over the bridge during connection stating whether GPU uses FBCDC v3.1 */
+#define PVRSRV_FBCDC_V3_1_USED_SHIFT (11)
+#define PVRSRV_FBCDC_V3_1_USED (1U << PVRSRV_FBCDC_V3_1_USED_SHIFT)
+
+/* Flag to be passed over the bridge during connection stating whether System has
+ DMA transfer capability to and from device memory */
+#define PVRSRV_SYSTEM_DMA_SHIFT (12)
+#define PVRSRV_SYSTEM_DMA_USED (1U << PVRSRV_SYSTEM_DMA_SHIFT)
+
+static INLINE IMG_HANDLE GetBridgeHandle(SHARED_DEV_CONNECTION hDevConnection)
+{
+#if defined(__KERNEL__)
+ return hDevConnection;
+#else
+ return hDevConnection->hServices;
+#endif
+}
+
+
+#endif /* !defined(DEVICE_CONNECTION_H) */
diff --git a/drivers/gpu/drm/img-rogue/devicemem.c b/drivers/gpu/drm/img-rogue/devicemem.c
new file mode 100644
index 000000000..029f80f2b
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/devicemem.c
@@ -0,0 +1,2991 @@
+/*************************************************************************/ /*!
+@File
+@Title Device Memory Management
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Front End (nominally Client side part, but now invokable
+ from server too) of device memory management
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */ /**************************************************************************/
+
+#include "devicemem.h"
+#include "img_types.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+#include "allocmem.h"
+#include "ra.h"
+#include "osfunc.h"
+#include "osmmap.h"
+#include "devicemem_utils.h"
+#include "client_mm_bridge.h"
+#include "client_cache_bridge.h"
+#include "services_km.h"
+#include "pvrsrv_memallocflags_internal.h"
+
+#if defined(PDUMP)
+#if defined(__KERNEL__)
+#include "pdump_km.h"
+#else
+#include "pdump_um.h"
+#endif
+#include "devicemem_pdump.h"
+#endif
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO)
+#include "client_ri_bridge.h"
+#endif
+#include "client_devicememhistory_bridge.h"
+#include "info_page_client.h"
+
+#include "rgx_heaps.h"
+#if defined(__KERNEL__)
+#include "pvrsrv.h"
+#include "rgxdefs_km.h"
+#include "rgx_bvnc_defs_km.h"
+#include "device.h"
+#include "rgxdevice.h"
+#include "pvr_ricommon.h"
+#include "pvrsrv_apphint.h"
+#include "oskm_apphint.h"
+#if defined(__linux__)
+#include "linux/kernel.h"
+#endif
+#else
+#include "rgxdefs.h"
+#endif
+
+#if defined(__KERNEL__) && defined(PVRSRV_ENABLE_GPU_MEMORY_INFO)
+extern PVRSRV_ERROR RIDumpAllKM(void);
+#endif
+
+#if defined(__KERNEL__)
+#define GET_ERROR_STRING(eError) PVRSRVGetErrorString(eError)
+#else
+#define GET_ERROR_STRING(eError) PVRSRVGetErrorString(eError)
+#endif
+
+#if defined(__KERNEL__)
+/* Derive the virtual from the hPMR */
+static
+IMG_UINT64 _GetPremappedVA(PMR *psPMR, PVRSRV_DEVICE_NODE *psDevNode)
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT64 ui64OptionalMapAddress = DEVICEMEM_UTILS_NO_ADDRESS;
+
+ IMG_DEV_PHYADDR sDevAddr;
+ IMG_BOOL bValid;
+ PVRSRV_PHYS_HEAP eFirstHeap = (PVRSRV_VZ_MODE_IS(GUEST) ? PVRSRV_PHYS_HEAP_FW_CONFIG : PVRSRV_PHYS_HEAP_FW_MAIN);
+ PHYS_HEAP *psPhysHeap = psDevNode->apsPhysHeap[eFirstHeap];
+ IMG_DEV_PHYADDR sHeapAddr;
+
+ eError = PhysHeapGetDevPAddr(psPhysHeap, &sHeapAddr);
+ PVR_LOG_GOTO_IF_ERROR(eError, "PhysHeapGetDevPAddr", fail);
+
+#if defined(PVR_PMR_TRANSLATE_UMA_ADDRESSES)
+{
+ if (PhysHeapGetType(psPhysHeap) == PHYS_HEAP_TYPE_UMA ||
+ PhysHeapGetType(psPhysHeap) == PHYS_HEAP_TYPE_DMA)
+ {
+ IMG_DEV_PHYADDR sDevPAddrCorrected;
+
+ PhysHeapCpuPAddrToDevPAddr(psPhysHeap, 1, &sDevPAddrCorrected, (IMG_CPU_PHYADDR *)&sHeapAddr);
+ sHeapAddr.uiAddr = sDevPAddrCorrected.uiAddr;
+ }
+}
+#endif
+
+ eError = PMRLockSysPhysAddresses(psPMR);
+ PVR_LOG_GOTO_IF_ERROR(eError, "PMRLockSysPhysAddr", fail);
+
+ eError = PMR_DevPhysAddr(psPMR, OSGetPageShift(), 1, 0, &sDevAddr, &bValid);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_LOG_IF_ERROR(eError, "PMR_DevPhysAddr");
+ eError = PMRUnlockSysPhysAddresses(psPMR);
+ PVR_LOG_IF_ERROR(eError, "PMRUnlockSysPhysAddr");
+ goto fail;
+ }
+
+ eError = PMRUnlockSysPhysAddresses(psPMR);
+ PVR_LOG_IF_ERROR(eError, "PMRUnlockSysPhysAddr");
+
+ ui64OptionalMapAddress = RGX_FIRMWARE_RAW_HEAP_BASE | (sDevAddr.uiAddr - sHeapAddr.uiAddr);
+
+ PVR_DPF((PVR_DBG_ALLOC, "%s: sDevAddr.uiAddr = 0x%"IMG_UINT64_FMTSPECx" sHeapAddr.uiAddr = 0x%"IMG_UINT64_FMTSPECx" => ui64OptionalMapAddress = 0x%"IMG_UINT64_FMTSPECx,
+ __func__, sDevAddr.uiAddr, sHeapAddr.uiAddr, ui64OptionalMapAddress));
+fail:
+ return ui64OptionalMapAddress;
+}
+#endif
+
+/*****************************************************************************
+ * Sub allocation internals *
+ *****************************************************************************/
+static INLINE PVRSRV_MEMALLOCFLAGS_T
+DevmemOverrideFlagsOrPassThrough(SHARED_DEV_CONNECTION hDevConnection, PVRSRV_MEMALLOCFLAGS_T uiFlags)
+{
+#if defined(__KERNEL__) && defined(RGX_FEATURE_GPU_CPU_COHERENCY)
+ /*
+ * Override the requested memory flags of FW allocations only,
+ * non-FW allocations pass-through unmodified.
+ *
+ * On fully coherent platforms:
+ * - We upgrade uncached, CPU-only cached or GPU-only cached to
+ * full coherency. This gives caching improvements for free.
+ *
+ * On ace-lite platforms:
+ * - If the allocation is not CPU cached, then there is nothing
+ * for the GPU to snoop regardless of the GPU cache setting.
+ * - If the allocation is not GPU cached, then the SLC will not
+ * be used and will not snoop the CPU even if it is CPU cached.
+ * - Therefore only the GPU setting can be upgraded to coherent
+ * if it is already GPU cached incoherent and the CPU is cached.
+ *
+ * All other platforms:
+ * - Do not modify the allocation flags.
+ */
+ if (PVRSRV_CHECK_FW_MAIN(uiFlags))
+ {
+ PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *)hDevConnection;
+
+ if (PVRSRVSystemSnoopingOfDeviceCache(psDevNode->psDevConfig) &&
+ PVRSRVSystemSnoopingOfCPUCache(psDevNode->psDevConfig))
+ {
+ /* Clear existing flags, mark the allocation as fully coherent. */
+ uiFlags &= ~(PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK | PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK);
+ uiFlags |= PVRSRV_MEMALLOCFLAG_CACHE_COHERENT;
+ }
+ else if ((PVRSRV_CHECK_CPU_CACHE_COHERENT(uiFlags) || PVRSRV_CHECK_CPU_CACHE_INCOHERENT(uiFlags)) &&
+ (PVRSRV_CHECK_GPU_CACHE_INCOHERENT(uiFlags)) &&
+ PVRSRVSystemSnoopingOfCPUCache(psDevNode->psDevConfig) &&
+ psDevNode->eDevFabricType == PVRSRV_DEVICE_FABRIC_ACELITE)
+ {
+ /* Upgrade the allocation from GPU cached incoherent to GPU cached coherent. */
+ uiFlags &= ~PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK;
+ uiFlags |= PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT;
+ }
+ }
+#else
+ PVR_UNREFERENCED_PARAMETER(hDevConnection);
+#endif
+
+ return uiFlags;
+}
+
+static INLINE void
+CheckAnnotationLength(const IMG_CHAR *pszAnnotation)
+{
+ IMG_UINT32 length = OSStringLength(pszAnnotation);
+
+ if (length >= DEVMEM_ANNOTATION_MAX_LEN)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: Annotation \"%s\" has been truncated to %d characters from %d characters",
+ __func__, pszAnnotation, DEVMEM_ANNOTATION_MAX_LEN - 1, length));
+ }
+}
+
+static PVRSRV_ERROR
+AllocateDeviceMemory(SHARED_DEV_CONNECTION hDevConnection,
+ IMG_UINT32 uiLog2Quantum,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_DEVMEM_SIZE_T uiChunkSize,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 *pui32MappingTable,
+ IMG_DEVMEM_ALIGN_T uiAlign,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ IMG_BOOL bExportable,
+ const IMG_CHAR *pszAnnotation,
+ DEVMEM_IMPORT **ppsImport)
+{
+ DEVMEM_IMPORT *psImport;
+ PVRSRV_MEMALLOCFLAGS_T uiOutFlags;
+ IMG_HANDLE hPMR;
+ PVRSRV_ERROR eError;
+
+ eError = DevmemImportStructAlloc(hDevConnection,
+ &psImport);
+ PVR_GOTO_IF_ERROR(eError, failAlloc);
+
+ /* check if shift value is not too big (sizeof(1ULL)) */
+ PVR_ASSERT(uiLog2Quantum < sizeof(unsigned long long) * 8);
+ /* Check the size is a multiple of the quantum */
+ PVR_ASSERT((uiSize & ((1ULL<psImport;
+ SHARED_DEV_CONNECTION hDevConnection;
+ IMG_HANDLE hPMR;
+ IMG_HANDLE hSrvDevMemHeap;
+ POS_LOCK hLock;
+ IMG_DEV_VIRTADDR sDevVAddr;
+ IMG_CPU_VIRTADDR pvCpuVAddr;
+ DEVMEM_PROPERTIES_T uiProperties;
+
+ if (NULL == psImport)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid Sparse memory import", __func__));
+ goto e0;
+ }
+
+ hDevConnection = psImport->hDevConnection;
+ hPMR = psImport->hPMR;
+ hLock = psImport->hLock;
+ sDevVAddr = psImport->sDeviceImport.sDevVAddr;
+ pvCpuVAddr = psImport->sCPUImport.pvCPUVAddr;
+
+ if (NULL == hDevConnection)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid Bridge handle", __func__));
+ goto e0;
+ }
+
+ if (NULL == hPMR)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid PMR handle", __func__));
+ goto e0;
+ }
+
+ if ((uiSparseFlags & SPARSE_RESIZE_BOTH) && (0 == sDevVAddr.uiAddr))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid Device Virtual Map", __func__));
+ goto e0;
+ }
+
+ if ((uiSparseFlags & SPARSE_MAP_CPU_ADDR) && (NULL == pvCpuVAddr))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid CPU Virtual Map", __func__));
+ goto e0;
+ }
+
+ uiProperties = GetImportProperties(psMemDesc->psImport);
+
+ if (uiProperties & DEVMEM_PROPERTIES_SECURE)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Secure buffers currently do not support sparse changes",
+ __func__));
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ goto e0;
+ }
+
+ if (uiProperties & DEVMEM_PROPERTIES_NO_LAYOUT_CHANGE)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: This memory descriptor doesn't support sparse changes",
+ __func__));
+ eError = PVRSRV_ERROR_INVALID_REQUEST;
+ goto e0;
+ }
+
+#ifdef PVRSRV_UNMAP_ON_SPARSE_CHANGE
+ if (psMemDesc->sCPUMemDesc.ui32RefCount > 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: This memory descriptor is mapped more than once (refcnt: %u)into "
+ "CPU Address space.\nRelease all CPU maps of this object and retry...",
+ __func__, psMemDesc->sCPUMemDesc.ui32RefCount));
+ eError = PVRSRV_ERROR_OBJECT_STILL_REFERENCED;
+ goto e0;
+ }
+#endif
+
+ hSrvDevMemHeap = psImport->sDeviceImport.psHeap->hDevMemServerHeap;
+
+ OSLockAcquire(hLock);
+
+ eError = BridgeChangeSparseMem(GetBridgeHandle(hDevConnection),
+ hSrvDevMemHeap,
+ hPMR,
+ ui32AllocPageCount,
+ paui32AllocPageIndices,
+ ui32FreePageCount,
+ pauiFreePageIndices,
+ uiSparseFlags,
+ psImport->uiFlags,
+ sDevVAddr,
+ (IMG_UINT64)((uintptr_t)pvCpuVAddr));
+
+ OSLockRelease(hLock);
+
+ if (eError != PVRSRV_OK)
+ {
+ goto e0;
+ }
+
+ if (GetInfoPageDebugFlags(psMemDesc->psImport->hDevConnection) & DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED)
+ {
+ BridgeDevicememHistorySparseChange(GetBridgeHandle(psMemDesc->psImport->hDevConnection),
+ psMemDesc->psImport->hPMR,
+ psMemDesc->uiOffset,
+ psMemDesc->sDeviceMemDesc.sDevVAddr,
+ psMemDesc->uiAllocSize,
+ psMemDesc->szText,
+ DevmemGetHeapLog2PageSize(psImport->sDeviceImport.psHeap),
+ ui32AllocPageCount,
+ paui32AllocPageIndices,
+ ui32FreePageCount,
+ pauiFreePageIndices,
+ psMemDesc->ui32AllocationIndex,
+ &psMemDesc->ui32AllocationIndex);
+ }
+
+e0:
+ return eError;
+}
+
+static void
+FreeDeviceMemory(DEVMEM_IMPORT *psImport)
+{
+ DevmemImportStructRelease(psImport);
+}
+
+static PVRSRV_ERROR
+SubAllocImportAlloc(RA_PERARENA_HANDLE hArena,
+ RA_LENGTH_T uiSize,
+ RA_FLAGS_T _flags,
+ const IMG_CHAR *pszAnnotation,
+ /* returned data */
+ RA_BASE_T *puiBase,
+ RA_LENGTH_T *puiActualSize,
+ RA_PERISPAN_HANDLE *phImport)
+{
+ /* When suballocations need a new lump of memory, the RA calls
+ back here. Later, in the kernel, we must construct a new PMR
+ and a pairing between the new lump of virtual memory and the
+ PMR (whether or not such PMR is backed by physical memory) */
+ DEVMEM_HEAP *psHeap;
+ DEVMEM_IMPORT *psImport;
+ IMG_DEVMEM_ALIGN_T uiAlign;
+ PVRSRV_ERROR eError;
+ IMG_UINT32 ui32MappingTable = 0;
+ PVRSRV_MEMALLOCFLAGS_T uiFlags = (PVRSRV_MEMALLOCFLAGS_T) _flags;
+ IMG_UINT64 ui64OptionalMapAddress = DEVICEMEM_UTILS_NO_ADDRESS;
+
+ /* Per-arena private handle is, for us, the heap */
+ psHeap = hArena;
+
+ /* align to the l.s.b. of the size... e.g. 96kiB aligned to
+ 32kiB. NB: There is an argument to say that the RA should never
+ ask us for Non-power-of-2 size anyway, but I don't want to make
+ that restriction arbitrarily now */
+ uiAlign = uiSize & ~(uiSize-1);
+
+ /* Technically this is only required for guest drivers due to
+ fw heaps being pre-allocated and pre-mapped resulting in
+ a 1:1 (i.e. virtual : physical) offset correlation but we
+ force this behaviour for all drivers to maintain consistency
+ (i.e. heap->VA uiAlign <= heap->PA uiLog2Quantum) */
+ if (uiAlign > (IMG_DEVMEM_ALIGN_T)(1ULL << psHeap->uiLog2Quantum))
+ {
+ uiAlign = (IMG_DEVMEM_ALIGN_T)(1ULL << psHeap->uiLog2Quantum);
+ }
+
+ /* The RA should not have invoked us with a size that is not a
+ multiple of the quantum anyway */
+ PVR_ASSERT((uiSize & ((1ULL<uiLog2Quantum)-1)) == 0);
+
+ eError = AllocateDeviceMemory(psHeap->psCtx->hDevConnection,
+ psHeap->uiLog2Quantum,
+ uiSize,
+ uiSize,
+ 1,
+ 1,
+ &ui32MappingTable,
+ uiAlign,
+ uiFlags,
+ IMG_FALSE,
+ "PMR sub-allocated",
+ &psImport);
+ PVR_GOTO_IF_ERROR(eError, failAlloc);
+
+#if defined(PDUMP) && defined(DEBUG)
+#if defined(__KERNEL__)
+ PDUMPCOMMENTWITHFLAGS(PMR_DeviceNode((PMR*)psImport->hPMR), PDUMP_CONT,
+ "Created PMR for sub-allocations with handle ID: 0x%p Annotation: \"%s\" (PID %u)",
+ psImport->hPMR, pszAnnotation, OSGetCurrentProcessID());
+#else
+ PDUMPCOMMENTF(psHeap->psCtx->hDevConnection, PDUMP_FLAGS_CONTINUOUS,
+ "Created PMR for sub-allocations with handle ID: %p Annotation: \"%s\" (PID %u)",
+ psImport->hPMR, pszAnnotation, OSGetCurrentProcessID());
+#endif
+#else
+ PVR_UNREFERENCED_PARAMETER(pszAnnotation);
+#endif
+
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO)
+ if (PVRSRVIsBridgeEnabled(GetBridgeHandle(psImport->hDevConnection), PVRSRV_BRIDGE_RI))
+ {
+#if defined(__KERNEL__)
+ PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *)psHeap->psCtx->hDevConnection;
+ PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *)psDevNode->pvDevice;
+
+ PVR_ASSERT(PVRSRV_CHECK_FW_MAIN(uiFlags));
+
+ /* If allocation is made by the Kernel from the firmware heap, account for it
+ * under the PVR_SYS_ALLOC_PID.
+ */
+ if ((psHeap == psDevInfo->psFirmwareMainHeap) || (psHeap == psDevInfo->psFirmwareConfigHeap))
+ {
+ eError = BridgeRIWritePMREntryWithOwner (GetBridgeHandle(psImport->hDevConnection),
+ psImport->hPMR,
+ PVR_SYS_ALLOC_PID);
+ PVR_LOG_IF_ERROR(eError, "BridgeRIWritePMREntryWithOwner");
+ }
+ else
+#endif
+ {
+ eError = BridgeRIWritePMREntry (GetBridgeHandle(psImport->hDevConnection),
+ psImport->hPMR);
+ PVR_LOG_IF_ERROR(eError, "BridgeRIWritePMREntry");
+ }
+ }
+#endif
+
+#if defined(__KERNEL__)
+ if (psHeap->bPremapped)
+ {
+ ui64OptionalMapAddress = _GetPremappedVA(psImport->hPMR, psHeap->psCtx->hDevConnection);
+ }
+#endif
+
+ /*
+ Suballocations always get mapped into the device was we need to
+ key the RA off something and as we can't export suballocations
+ there is no valid reason to request an allocation an not map it
+ */
+ eError = DevmemImportStructDevMap(psHeap,
+ IMG_TRUE,
+ psImport,
+ ui64OptionalMapAddress);
+ PVR_GOTO_IF_ERROR(eError, failMap);
+
+ OSLockAcquire(psImport->hLock);
+ /* Mark this import struct as zeroed so we can save some PDump LDBs
+ * and do not have to CPU map + mem set()*/
+ if (uiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC)
+ {
+ psImport->uiProperties |= DEVMEM_PROPERTIES_IMPORT_IS_ZEROED;
+ }
+ else if (uiFlags & PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC)
+ {
+ psImport->uiProperties |= DEVMEM_PROPERTIES_IMPORT_IS_POISONED;
+ }
+ psImport->uiProperties |= DEVMEM_PROPERTIES_IMPORT_IS_CLEAN;
+ OSLockRelease(psImport->hLock);
+
+ *puiBase = psImport->sDeviceImport.sDevVAddr.uiAddr;
+ *puiActualSize = uiSize;
+ *phImport = psImport;
+
+ return PVRSRV_OK;
+
+ /* error exit paths follow */
+
+failMap:
+ FreeDeviceMemory(psImport);
+failAlloc:
+
+ return eError;
+}
+
+static void
+SubAllocImportFree(RA_PERARENA_HANDLE hArena,
+ RA_BASE_T uiBase,
+ RA_PERISPAN_HANDLE hImport)
+{
+ DEVMEM_IMPORT *psImport = hImport;
+#if !defined(PVRSRV_NEED_PVR_ASSERT)
+ PVR_UNREFERENCED_PARAMETER(hArena);
+ PVR_UNREFERENCED_PARAMETER(uiBase);
+#endif
+
+ PVR_ASSERT(psImport != NULL);
+ PVR_ASSERT(hArena == psImport->sDeviceImport.psHeap);
+ PVR_ASSERT(uiBase == psImport->sDeviceImport.sDevVAddr.uiAddr);
+
+ (void) DevmemImportStructDevUnmap(psImport);
+ (void) DevmemImportStructRelease(psImport);
+}
+
+/*****************************************************************************
+ * Devmem context internals *
+ *****************************************************************************/
+
+static PVRSRV_ERROR
+PopulateContextFromBlueprint(struct DEVMEM_CONTEXT_TAG *psCtx,
+ DEVMEM_HEAPCFGID uiHeapBlueprintID)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_ERROR eError2;
+ struct DEVMEM_HEAP_TAG **ppsHeapArray;
+ IMG_UINT32 uiNumHeaps;
+ IMG_UINT32 uiHeapsToUnwindOnError;
+ IMG_UINT32 uiHeapIndex;
+ IMG_DEV_VIRTADDR sDevVAddrBase;
+ IMG_CHAR aszHeapName[DEVMEM_HEAPNAME_MAXLENGTH];
+ IMG_DEVMEM_SIZE_T uiHeapLength;
+ IMG_DEVMEM_SIZE_T uiReservedRegionLength;
+ IMG_DEVMEM_LOG2ALIGN_T uiLog2DataPageSize;
+ IMG_DEVMEM_LOG2ALIGN_T uiLog2ImportAlignment;
+
+ eError = DevmemHeapCount(psCtx->hDevConnection,
+ uiHeapBlueprintID,
+ &uiNumHeaps);
+ PVR_GOTO_IF_ERROR(eError, e0);
+
+ if (uiNumHeaps == 0)
+ {
+ ppsHeapArray = NULL;
+ }
+ else
+ {
+ ppsHeapArray = OSAllocMem(sizeof(*ppsHeapArray) * uiNumHeaps);
+ PVR_GOTO_IF_NOMEM(ppsHeapArray, eError, e0);
+ }
+
+ uiHeapsToUnwindOnError = 0;
+
+ for (uiHeapIndex = 0; uiHeapIndex < uiNumHeaps; uiHeapIndex++)
+ {
+ eError = DevmemHeapDetails(psCtx->hDevConnection,
+ uiHeapBlueprintID,
+ uiHeapIndex,
+ &aszHeapName[0],
+ sizeof(aszHeapName),
+ &sDevVAddrBase,
+ &uiHeapLength,
+ &uiReservedRegionLength,
+ &uiLog2DataPageSize,
+ &uiLog2ImportAlignment);
+ PVR_GOTO_IF_ERROR(eError, e1);
+
+ eError = DevmemCreateHeap(psCtx,
+ sDevVAddrBase,
+ uiHeapLength,
+ uiReservedRegionLength,
+ uiLog2DataPageSize,
+ uiLog2ImportAlignment,
+ aszHeapName,
+ uiHeapBlueprintID,
+ &ppsHeapArray[uiHeapIndex]);
+ PVR_GOTO_IF_ERROR(eError, e1);
+
+ uiHeapsToUnwindOnError = uiHeapIndex + 1;
+ }
+
+ psCtx->uiAutoHeapCount = uiNumHeaps;
+ psCtx->ppsAutoHeapArray = ppsHeapArray;
+
+ PVR_ASSERT(psCtx->uiNumHeaps >= psCtx->uiAutoHeapCount);
+ PVR_ASSERT(psCtx->uiAutoHeapCount == uiNumHeaps);
+
+ return PVRSRV_OK;
+
+ /* error exit paths */
+e1:
+ for (uiHeapIndex = 0; uiHeapIndex < uiHeapsToUnwindOnError; uiHeapIndex++)
+ {
+ eError2 = DevmemDestroyHeap(ppsHeapArray[uiHeapIndex]);
+ PVR_ASSERT(eError2 == PVRSRV_OK);
+ }
+
+ if (uiNumHeaps != 0)
+ {
+ OSFreeMem(ppsHeapArray);
+ }
+
+e0:
+ PVR_ASSERT(eError != PVRSRV_OK);
+ return eError;
+}
+
+static PVRSRV_ERROR
+UnpopulateContextFromBlueprint(struct DEVMEM_CONTEXT_TAG *psCtx)
+{
+ PVRSRV_ERROR eReturn = PVRSRV_OK;
+ PVRSRV_ERROR eError2;
+ IMG_UINT32 uiHeapIndex;
+ IMG_BOOL bDoCheck = IMG_TRUE;
+#if defined(__KERNEL__)
+ PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+ if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
+ {
+ bDoCheck = IMG_FALSE;
+ }
+#endif
+
+ for (uiHeapIndex = 0; uiHeapIndex < psCtx->uiAutoHeapCount; uiHeapIndex++)
+ {
+ if (!psCtx->ppsAutoHeapArray[uiHeapIndex])
+ {
+ continue;
+ }
+
+ eError2 = DevmemDestroyHeap(psCtx->ppsAutoHeapArray[uiHeapIndex]);
+ if (eError2 != PVRSRV_OK)
+ {
+ eReturn = eError2;
+ }
+ else
+ {
+ psCtx->ppsAutoHeapArray[uiHeapIndex] = NULL;
+ }
+ }
+
+ if ((!bDoCheck || (eReturn == PVRSRV_OK)) && psCtx->ppsAutoHeapArray)
+ {
+ OSFreeMem(psCtx->ppsAutoHeapArray);
+ psCtx->ppsAutoHeapArray = NULL;
+ psCtx->uiAutoHeapCount = 0;
+ }
+
+ return eReturn;
+}
+
+/*****************************************************************************
+ * Devmem context functions *
+ *****************************************************************************/
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemCreateContext(SHARED_DEV_CONNECTION hDevConnection,
+ DEVMEM_HEAPCFGID uiHeapBlueprintID,
+ DEVMEM_CONTEXT **ppsCtxPtr)
+{
+ PVRSRV_ERROR eError;
+ DEVMEM_CONTEXT *psCtx;
+ /* handle to the server-side counterpart of the device memory
+ context (specifically, for handling mapping to device MMU) */
+ IMG_HANDLE hDevMemServerContext;
+ IMG_HANDLE hPrivData;
+ IMG_BOOL bHeapCfgMetaId = (uiHeapBlueprintID == DEVMEM_HEAPCFG_META);
+
+ PVR_GOTO_IF_NOMEM(ppsCtxPtr, eError, e0);
+
+ psCtx = OSAllocMem(sizeof(*psCtx));
+ PVR_GOTO_IF_NOMEM(psCtx, eError, e0);
+
+ psCtx->uiNumHeaps = 0;
+
+ psCtx->hDevConnection = hDevConnection;
+
+ /* Create (server-side) Device Memory context */
+ eError = BridgeDevmemIntCtxCreate(GetBridgeHandle(psCtx->hDevConnection),
+ bHeapCfgMetaId,
+ &hDevMemServerContext,
+ &hPrivData,
+ &psCtx->ui32CPUCacheLineSize);
+ PVR_GOTO_IF_ERROR(eError, e1);
+
+ psCtx->hDevMemServerContext = hDevMemServerContext;
+ psCtx->hPrivData = hPrivData;
+
+ /* automagic heap creation */
+ psCtx->uiAutoHeapCount = 0;
+
+ eError = PopulateContextFromBlueprint(psCtx, uiHeapBlueprintID);
+ PVR_GOTO_IF_ERROR(eError, e2);
+
+ *ppsCtxPtr = psCtx;
+
+ PVR_ASSERT(psCtx->uiNumHeaps == psCtx->uiAutoHeapCount);
+ return PVRSRV_OK;
+
+ /* error exit paths follow */
+
+e2:
+ PVR_ASSERT(psCtx->uiAutoHeapCount == 0);
+ PVR_ASSERT(psCtx->uiNumHeaps == 0);
+ BridgeDevmemIntCtxDestroy(GetBridgeHandle(psCtx->hDevConnection), hDevMemServerContext);
+
+e1:
+ OSFreeMem(psCtx);
+
+e0:
+ PVR_ASSERT(eError != PVRSRV_OK);
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemAcquireDevPrivData(DEVMEM_CONTEXT *psCtx,
+ IMG_HANDLE *hPrivData)
+{
+ PVRSRV_ERROR eError;
+
+ PVR_GOTO_IF_INVALID_PARAM(psCtx, eError, e0);
+ PVR_GOTO_IF_INVALID_PARAM(hPrivData, eError, e0);
+
+ *hPrivData = psCtx->hPrivData;
+ return PVRSRV_OK;
+
+e0:
+ PVR_ASSERT(eError != PVRSRV_OK);
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemReleaseDevPrivData(DEVMEM_CONTEXT *psCtx)
+{
+ PVRSRV_ERROR eError;
+
+ PVR_GOTO_IF_INVALID_PARAM(psCtx, eError, e0);
+ return PVRSRV_OK;
+
+e0:
+ PVR_ASSERT(eError != PVRSRV_OK);
+ return eError;
+}
+
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemFindHeapByName(const struct DEVMEM_CONTEXT_TAG *psCtx,
+ const IMG_CHAR *pszHeapName,
+ struct DEVMEM_HEAP_TAG **ppsHeapRet)
+{
+ IMG_UINT32 uiHeapIndex;
+
+ /* N.B. This func is only useful for finding "automagic" heaps by name */
+ for (uiHeapIndex = 0;
+ uiHeapIndex < psCtx->uiAutoHeapCount;
+ uiHeapIndex++)
+ {
+ if (!OSStringNCompare(psCtx->ppsAutoHeapArray[uiHeapIndex]->pszName, pszHeapName, OSStringLength(psCtx->ppsAutoHeapArray[uiHeapIndex]->pszName) + 1))
+ {
+ *ppsHeapRet = psCtx->ppsAutoHeapArray[uiHeapIndex];
+ return PVRSRV_OK;
+ }
+ }
+
+ return PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_INDEX;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemDestroyContext(DEVMEM_CONTEXT *psCtx)
+{
+ PVRSRV_ERROR eError;
+ IMG_BOOL bDoCheck = IMG_TRUE;
+
+#if defined(__KERNEL__)
+ PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+ if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
+ {
+ bDoCheck = IMG_FALSE;
+ }
+#endif
+
+ PVR_RETURN_IF_INVALID_PARAM(psCtx);
+
+ eError = UnpopulateContextFromBlueprint(psCtx);
+ if (bDoCheck && eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: UnpopulateContextFromBlueprint failed (%d) leaving %d heaps",
+ __func__, eError, psCtx->uiNumHeaps));
+ goto e1;
+ }
+
+ eError = BridgeDevmemIntCtxDestroy(GetBridgeHandle(psCtx->hDevConnection),
+ psCtx->hDevMemServerContext);
+ if (bDoCheck)
+ {
+ PVR_LOG_GOTO_IF_ERROR(eError, "BridgeDevMemIntCtxDestroy", e1);
+
+ /* should be no more heaps left */
+ if (psCtx->uiNumHeaps)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Additional heaps remain in DEVMEM_CONTEXT",
+ __func__));
+ eError = PVRSRV_ERROR_DEVICEMEM_ADDITIONAL_HEAPS_IN_CONTEXT;
+ goto e1;
+ }
+ }
+
+ OSCachedMemSet(psCtx, 0, sizeof(*psCtx));
+ OSFreeMem(psCtx);
+
+e1:
+ return eError;
+}
+
+/*****************************************************************************
+ * Devmem heap query functions *
+ *****************************************************************************/
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemHeapConfigCount(SHARED_DEV_CONNECTION hDevConnection,
+ IMG_UINT32 *puiNumHeapConfigsOut)
+{
+ PVRSRV_ERROR eError;
+ eError = BridgeHeapCfgHeapConfigCount(GetBridgeHandle(hDevConnection),
+ puiNumHeapConfigsOut);
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemHeapCount(SHARED_DEV_CONNECTION hDevConnection,
+ IMG_UINT32 uiHeapConfigIndex,
+ IMG_UINT32 *puiNumHeapsOut)
+{
+ PVRSRV_ERROR eError;
+ eError = BridgeHeapCfgHeapCount(GetBridgeHandle(hDevConnection),
+ uiHeapConfigIndex,
+ puiNumHeapsOut);
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemHeapConfigName(SHARED_DEV_CONNECTION hDevConnection,
+ IMG_UINT32 uiHeapConfigIndex,
+ IMG_CHAR *pszConfigNameOut,
+ IMG_UINT32 uiConfigNameBufSz)
+{
+ PVRSRV_ERROR eError;
+ eError = BridgeHeapCfgHeapConfigName(GetBridgeHandle(hDevConnection),
+ uiHeapConfigIndex,
+ uiConfigNameBufSz,
+ pszConfigNameOut);
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemHeapDetails(SHARED_DEV_CONNECTION hDevConnection,
+ IMG_UINT32 uiHeapConfigIndex,
+ IMG_UINT32 uiHeapIndex,
+ IMG_CHAR *pszHeapNameOut,
+ IMG_UINT32 uiHeapNameBufSz,
+ IMG_DEV_VIRTADDR *psDevVAddrBaseOut,
+ IMG_DEVMEM_SIZE_T *puiHeapLengthOut,
+ IMG_DEVMEM_SIZE_T *puiReservedRegionLengthOut,
+ IMG_UINT32 *puiLog2DataPageSizeOut,
+ IMG_UINT32 *puiLog2ImportAlignmentOut)
+{
+ PVRSRV_ERROR eError;
+
+ eError = BridgeHeapCfgHeapDetails(GetBridgeHandle(hDevConnection),
+ uiHeapConfigIndex,
+ uiHeapIndex,
+ uiHeapNameBufSz,
+ pszHeapNameOut,
+ psDevVAddrBaseOut,
+ puiHeapLengthOut,
+ puiReservedRegionLengthOut,
+ puiLog2DataPageSizeOut,
+ puiLog2ImportAlignmentOut);
+
+ VG_MARK_INITIALIZED(pszHeapNameOut, uiHeapNameBufSz);
+
+ return eError;
+}
+
+/*****************************************************************************
+ * Devmem heap functions *
+ *****************************************************************************/
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetHeapInt(DEVMEM_HEAP *psHeap,
+ IMG_HANDLE *phDevmemHeap)
+{
+ PVR_RETURN_IF_INVALID_PARAM(psHeap);
+ *phDevmemHeap = psHeap->hDevMemServerHeap;
+ return PVRSRV_OK;
+}
+
+/* See devicemem.h for important notes regarding the arguments
+ to this function */
+IMG_INTERNAL PVRSRV_ERROR
+DevmemCreateHeap(DEVMEM_CONTEXT *psCtx,
+ IMG_DEV_VIRTADDR sBaseAddress,
+ IMG_DEVMEM_SIZE_T uiLength,
+ IMG_DEVMEM_SIZE_T uiReservedRegionLength,
+ IMG_UINT32 ui32Log2Quantum,
+ IMG_UINT32 ui32Log2ImportAlignment,
+ const IMG_CHAR *pszName,
+ DEVMEM_HEAPCFGID uiHeapBlueprintID,
+ DEVMEM_HEAP **ppsHeapPtr)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ PVRSRV_ERROR eError2;
+ DEVMEM_HEAP *psHeap;
+ /* handle to the server-side counterpart of the device memory heap
+ (specifically, for handling mapping to device MMU) */
+ IMG_HANDLE hDevMemServerHeap;
+ IMG_UINT32 ui32Policy = RA_POLICY_DEFAULT, ui32PolicyVMRA;
+
+ IMG_CHAR aszBuf[100];
+ IMG_CHAR *pszStr;
+ IMG_UINT32 ui32pszStrSize;
+
+ if (ppsHeapPtr == NULL ||
+ uiReservedRegionLength % DEVMEM_HEAP_RESERVED_SIZE_GRANULARITY)
+ {
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, e0);
+ }
+
+ ui32PolicyVMRA = RA_POLICY_DEFAULT;
+
+ PVR_ASSERT(uiReservedRegionLength + DEVMEM_HEAP_MINIMUM_SIZE <= uiLength);
+
+ psHeap = OSAllocMem(sizeof(*psHeap));
+ PVR_GOTO_IF_NOMEM(psHeap, eError, e0);
+
+ /* Need to keep local copy of heap name, so caller may free theirs */
+ ui32pszStrSize = OSStringLength(pszName) + 1;
+ pszStr = OSAllocMem(ui32pszStrSize);
+ PVR_GOTO_IF_NOMEM(pszStr, eError, e1);
+ OSStringLCopy(pszStr, pszName, ui32pszStrSize);
+ psHeap->pszName = pszStr;
+
+ psHeap->uiSize = uiLength;
+ psHeap->uiReservedRegionSize = uiReservedRegionLength;
+ psHeap->sBaseAddress = sBaseAddress;
+ psHeap->bPremapped = IMG_FALSE;
+ OSAtomicWrite(&psHeap->hImportCount, 0);
+
+ OSSNPrintf(aszBuf, sizeof(aszBuf),
+ "NDM heap '%s' (suballocs) ctx:%p",
+ pszName, psCtx);
+ ui32pszStrSize = OSStringLength(aszBuf) + 1;
+ pszStr = OSAllocMem(ui32pszStrSize);
+ PVR_GOTO_IF_NOMEM(pszStr, eError, e2);
+ OSStringLCopy(pszStr, aszBuf, ui32pszStrSize);
+ psHeap->pszSubAllocRAName = pszStr;
+
+#if defined(__KERNEL__)
+ if (uiHeapBlueprintID == DEVMEM_HEAPCFG_META)
+ {
+ void *pvAppHintState = NULL;
+ IMG_UINT32 ui32FirmwarePolicydefault = 0, ui32FirmwarePolicy=0;
+ OSCreateKMAppHintState(&pvAppHintState);
+ OSGetKMAppHintUINT32(APPHINT_NO_DEVICE, pvAppHintState, DevMemFWHeapPolicy,
+ &ui32FirmwarePolicydefault, &ui32FirmwarePolicy);
+ ui32PolicyVMRA = ui32Policy = ui32FirmwarePolicy;
+ OSFreeKMAppHintState(pvAppHintState);
+ }
+#endif
+
+#if defined(PDUMP)
+ /* The META heap is shared globally so a single physical memory import
+ * may be used to satisfy allocations of different processes.
+ * This is problematic when PDumping because the physical memory
+ * import used to satisfy a new allocation may actually have been
+ * imported (and thus the PDump MALLOC generated) before the PDump
+ * client was started, leading to the MALLOC being missing.
+ *
+ * This is solved by disabling splitting of imports for the META physmem
+ * RA, meaning that every firmware allocation gets its own import, thus
+ * ensuring the MALLOC is present for every allocation made within the
+ * pdump capture range
+ */
+ if (uiHeapBlueprintID == DEVMEM_HEAPCFG_META)
+ {
+ ui32Policy |= RA_POLICY_NO_SPLIT;
+ }
+#else
+ PVR_UNREFERENCED_PARAMETER(uiHeapBlueprintID);
+#endif
+
+ psHeap->psSubAllocRA = RA_Create(psHeap->pszSubAllocRAName,
+ /* Subsequent imports: */
+ ui32Log2Quantum,
+ RA_LOCKCLASS_2,
+ SubAllocImportAlloc,
+ SubAllocImportFree,
+ (RA_PERARENA_HANDLE) psHeap,
+ ui32Policy);
+ if (psHeap->psSubAllocRA == NULL)
+ {
+ eError = PVRSRV_ERROR_DEVICEMEM_UNABLE_TO_CREATE_ARENA;
+ goto e3;
+ }
+
+ psHeap->uiLog2ImportAlignment = ui32Log2ImportAlignment;
+ psHeap->uiLog2Quantum = ui32Log2Quantum;
+
+ if (!OSStringNCompare(pszName, RGX_GENERAL_SVM_HEAP_IDENT, sizeof(RGX_GENERAL_SVM_HEAP_IDENT)))
+ {
+ /* The SVM heap normally starts out as this type though
+ it may transition to DEVMEM_HEAP_MANAGER_USER
+ on platforms with more processor virtual address
+ bits than device virtual address bits */
+ psHeap->ui32HeapManagerFlags = DEVMEM_HEAP_MANAGER_KERNEL;
+ }
+ else if (uiReservedRegionLength != 0)
+ {
+ /* Heaps which specify reserved VA space range are dual managed:
+ * - sBaseAddress to (sBaseAddress+uiReservedRegionLength-1): User managed
+ * - (sBaseAddress+uiReservedRegionLength) to uiLength: RA managed
+ */
+ psHeap->ui32HeapManagerFlags = DEVMEM_HEAP_MANAGER_DUAL_USER_RA;
+ }
+ else
+ {
+ /* Otherwise, heap manager is decided (USER or RA) at first map */
+ psHeap->ui32HeapManagerFlags = DEVMEM_HEAP_MANAGER_UNKNOWN;
+ }
+
+ /* Mark the heap to be managed by RA */
+ if (!OSStringNCompare(pszName, RGX_VK_CAPT_REPLAY_HEAP_IDENT,
+ sizeof(RGX_VK_CAPT_REPLAY_HEAP_IDENT)))
+ {
+ psHeap->ui32HeapManagerFlags |= DEVMEM_HEAP_MANAGER_RA;
+ }
+
+ OSSNPrintf(aszBuf, sizeof(aszBuf),
+ "NDM heap '%s' (QVM) ctx:%p",
+ pszName, psCtx);
+ ui32pszStrSize = OSStringLength(aszBuf) + 1;
+ pszStr = OSAllocMem(ui32pszStrSize);
+ if (pszStr == NULL)
+ {
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto e4;
+ }
+ OSStringLCopy(pszStr, aszBuf, ui32pszStrSize);
+ psHeap->pszQuantizedVMRAName = pszStr;
+
+ psHeap->psQuantizedVMRA = RA_Create(psHeap->pszQuantizedVMRAName,
+ /* Subsequent import: */
+ 0, RA_LOCKCLASS_1, NULL, NULL,
+ (RA_PERARENA_HANDLE) psHeap,
+ ui32PolicyVMRA);
+ if (psHeap->psQuantizedVMRA == NULL)
+ {
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_UNABLE_TO_CREATE_ARENA, e5);
+ }
+
+ if (!RA_Add(psHeap->psQuantizedVMRA,
+ /* Make sure the VMRA doesn't allocate from reserved VAs */
+ (RA_BASE_T)sBaseAddress.uiAddr + uiReservedRegionLength,
+ (RA_LENGTH_T)uiLength,
+ (RA_FLAGS_T)0, /* This RA doesn't use or need flags */
+ NULL /* per ispan handle */))
+ {
+ RA_Delete(psHeap->psQuantizedVMRA);
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_UNABLE_TO_CREATE_ARENA, e5);
+ }
+
+ psHeap->psCtx = psCtx;
+
+
+ /* Create server-side counterpart of Device Memory heap */
+ eError = BridgeDevmemIntHeapCreate(GetBridgeHandle(psCtx->hDevConnection),
+ psCtx->hDevMemServerContext,
+ sBaseAddress,
+ uiLength,
+ ui32Log2Quantum,
+ &hDevMemServerHeap);
+ PVR_GOTO_IF_ERROR(eError, e6);
+
+ psHeap->hDevMemServerHeap = hDevMemServerHeap;
+
+ eError = OSLockCreate(&psHeap->hLock);
+ PVR_GOTO_IF_ERROR(eError, e7);
+
+ psHeap->psCtx->uiNumHeaps++;
+ *ppsHeapPtr = psHeap;
+
+#if defined(PVRSRV_NEWDEVMEM_SUPPORT_MEM_TRACKING)
+ psHeap->psMemDescList = NULL;
+#endif /* PVRSRV_NEWDEVMEM_SUPPORT_MEM_TRACKING */
+
+ return PVRSRV_OK;
+
+ /* error exit paths */
+e7:
+ eError2 = BridgeDevmemIntHeapDestroy(GetBridgeHandle(psCtx->hDevConnection),
+ psHeap->hDevMemServerHeap);
+ PVR_ASSERT (eError2 == PVRSRV_OK);
+e6:
+ if (psHeap->psQuantizedVMRA)
+ RA_Delete(psHeap->psQuantizedVMRA);
+e5:
+ if (psHeap->pszQuantizedVMRAName)
+ OSFreeMem(psHeap->pszQuantizedVMRAName);
+e4:
+ RA_Delete(psHeap->psSubAllocRA);
+e3:
+ OSFreeMem(psHeap->pszSubAllocRAName);
+e2:
+ OSFreeMem(psHeap->pszName);
+e1:
+ OSFreeMem(psHeap);
+e0:
+ PVR_ASSERT(eError != PVRSRV_OK);
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetHeapBaseDevVAddr(struct DEVMEM_HEAP_TAG *psHeap,
+ IMG_DEV_VIRTADDR *pDevVAddr)
+{
+ PVR_RETURN_IF_INVALID_PARAM(psHeap);
+
+ *pDevVAddr = psHeap->sBaseAddress;
+
+ return PVRSRV_OK;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemExportalignAdjustSizeAndAlign(IMG_UINT32 uiLog2Quantum,
+ IMG_DEVMEM_SIZE_T *puiSize,
+ IMG_DEVMEM_ALIGN_T *puiAlign)
+{
+ IMG_DEVMEM_SIZE_T uiSize = *puiSize;
+ IMG_DEVMEM_ALIGN_T uiAlign = *puiAlign;
+
+ /* Just in case someone changes definition of IMG_DEVMEM_ALIGN_T. */
+ static_assert(sizeof(unsigned long long) == sizeof(uiAlign),
+ "invalid uiAlign size");
+ /* This value is used for shifting so it cannot be greater than number
+ * of bits in unsigned long long (sizeof(1ULL)). Using greater value is
+ * undefined behaviour. */
+ if (uiLog2Quantum >= sizeof(unsigned long long) * 8)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if ((1ULL << uiLog2Quantum) > uiAlign)
+ {
+ uiAlign = 1ULL << uiLog2Quantum;
+ }
+ uiSize = (uiSize + uiAlign - 1) & ~(uiAlign - 1);
+
+ *puiSize = uiSize;
+ *puiAlign = uiAlign;
+
+ return PVRSRV_OK;
+}
+
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemDestroyHeap(DEVMEM_HEAP *psHeap)
+{
+ PVRSRV_ERROR eError;
+ IMG_INT uiImportCount;
+#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE)
+ IMG_BOOL bDoCheck = IMG_TRUE;
+#if defined(__KERNEL__)
+ if (PVRSRVGetPVRSRVData()->eServicesState != PVRSRV_SERVICES_STATE_OK)
+ {
+ bDoCheck = IMG_FALSE;
+ }
+#endif
+#endif
+
+ PVR_RETURN_IF_INVALID_PARAM(psHeap);
+
+ uiImportCount = OSAtomicRead(&psHeap->hImportCount);
+ if (uiImportCount > 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%d(%s) leaks remain", uiImportCount, psHeap->pszName));
+#if defined(__KERNEL__)
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO)
+ PVR_DPF((PVR_DBG_ERROR, "Details of remaining allocated device memory (for all processes):"));
+ RIDumpAllKM();
+#else
+ PVR_DPF((PVR_DBG_ERROR, "Compile with PVRSRV_ENABLE_GPU_MEMORY_INFO=1 to get a full "
+ "list of all driver allocations."));
+#endif
+#endif
+#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE)
+ if (bDoCheck)
+#endif
+ {
+ return PVRSRV_ERROR_DEVICEMEM_ALLOCATIONS_REMAIN_IN_HEAP;
+ }
+ }
+
+ eError = BridgeDevmemIntHeapDestroy(GetBridgeHandle(psHeap->psCtx->hDevConnection),
+ psHeap->hDevMemServerHeap);
+#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE)
+ if (bDoCheck)
+#endif
+ {
+ PVR_LOG_RETURN_IF_ERROR(eError, "BridgeDevmemIntHeapDestroy");
+ }
+
+ PVR_ASSERT(psHeap->psCtx->uiNumHeaps > 0);
+ psHeap->psCtx->uiNumHeaps--;
+
+ OSLockDestroy(psHeap->hLock);
+
+ if (psHeap->psQuantizedVMRA)
+ {
+ RA_Delete(psHeap->psQuantizedVMRA);
+ }
+ if (psHeap->pszQuantizedVMRAName)
+ {
+ OSFreeMem(psHeap->pszQuantizedVMRAName);
+ }
+
+ RA_Delete(psHeap->psSubAllocRA);
+ OSFreeMem(psHeap->pszSubAllocRAName);
+
+ OSFreeMem(psHeap->pszName);
+
+ OSCachedMemSet(psHeap, 0, sizeof(*psHeap));
+ OSFreeMem(psHeap);
+
+ return PVRSRV_OK;
+}
+
+/*****************************************************************************
+ * Devmem allocation/free functions *
+ *****************************************************************************/
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemSubAllocateAndMap(IMG_UINT8 uiPreAllocMultiplier,
+ DEVMEM_HEAP *psHeap,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_DEVMEM_ALIGN_T uiAlign,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ const IMG_CHAR *pszText,
+ DEVMEM_MEMDESC **ppsMemDescPtr,
+ IMG_DEV_VIRTADDR *psDevVirtAddr)
+{
+ PVRSRV_ERROR eError;
+ eError = DevmemSubAllocate(uiPreAllocMultiplier,
+ psHeap,
+ uiSize,
+ uiAlign,
+ uiFlags,
+ pszText,
+ ppsMemDescPtr);
+ PVR_GOTO_IF_ERROR(eError, fail_alloc);
+
+ eError = DevmemMapToDevice(*ppsMemDescPtr,
+ psHeap,
+ psDevVirtAddr);
+ PVR_GOTO_IF_ERROR(eError, fail_map);
+
+ return PVRSRV_OK;
+
+fail_map:
+ DevmemFree(*ppsMemDescPtr);
+fail_alloc:
+ ppsMemDescPtr = NULL;
+ return eError;
+
+}
+
+static INLINE void _MemSet(void *pvMem,
+ IMG_UINT8 uiPattern,
+ IMG_DEVMEM_SIZE_T uiSize,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags)
+{
+ if (PVRSRV_CHECK_CPU_UNCACHED(uiFlags))
+ {
+ OSDeviceMemSet(pvMem, uiPattern, uiSize);
+ }
+ else
+ {
+ /* it's safe to use OSCachedMemSet() for cached and wc memory */
+ OSCachedMemSet(pvMem, uiPattern, uiSize);
+ }
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemSubAllocate(IMG_UINT8 uiPreAllocMultiplier,
+ DEVMEM_HEAP *psHeap,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_DEVMEM_ALIGN_T uiAlign,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ const IMG_CHAR *pszText,
+ DEVMEM_MEMDESC **ppsMemDescPtr)
+{
+ RA_BASE_T uiAllocatedAddr = 0;
+ RA_LENGTH_T uiAllocatedSize;
+ RA_PERISPAN_HANDLE hImport; /* the "import" from which this sub-allocation came */
+ PVRSRV_ERROR eError;
+ DEVMEM_MEMDESC *psMemDesc = NULL;
+ IMG_DEVMEM_OFFSET_T uiOffset = 0;
+ DEVMEM_IMPORT *psImport;
+ IMG_UINT32 ui32CPUCacheLineSize;
+ void *pvAddr = NULL;
+
+ IMG_BOOL bImportClean;
+ IMG_BOOL bCPUCleanFlag = PVRSRV_CHECK_CPU_CACHE_CLEAN(uiFlags);
+ IMG_BOOL bZero = PVRSRV_CHECK_ZERO_ON_ALLOC(uiFlags);
+ IMG_BOOL bPoisonOnAlloc = PVRSRV_CHECK_POISON_ON_ALLOC(uiFlags);
+ IMG_BOOL bCPUCached = (PVRSRV_CHECK_CPU_CACHE_COHERENT(uiFlags) ||
+ PVRSRV_CHECK_CPU_CACHE_INCOHERENT(uiFlags));
+ IMG_BOOL bGPUCached = (PVRSRV_CHECK_GPU_CACHE_COHERENT(uiFlags) ||
+ PVRSRV_CHECK_GPU_CACHE_INCOHERENT(uiFlags));
+ IMG_BOOL bAlign = ! (PVRSRV_CHECK_NO_CACHE_LINE_ALIGN(uiFlags));
+ PVRSRV_CACHE_OP eOp = PVRSRV_CACHE_OP_INVALIDATE;
+ IMG_UINT32 ui32CacheLineSize = 0;
+ DEVMEM_PROPERTIES_T uiProperties;
+
+ if (uiFlags & PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC)
+ {
+ /* Deferred Allocation not supported on SubAllocs*/
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, failParams);
+ }
+
+ PVR_GOTO_IF_INVALID_PARAM(psHeap, eError, failParams);
+ PVR_GOTO_IF_INVALID_PARAM(psHeap->psCtx, eError, failParams);
+ PVR_GOTO_IF_INVALID_PARAM(ppsMemDescPtr, eError, failParams);
+
+ uiFlags = DevmemOverrideFlagsOrPassThrough(psHeap->psCtx->hDevConnection, uiFlags);
+
+#if defined(__KERNEL__)
+ {
+ /* The hDevConnection holds two different types of pointers depending on the
+ * address space in which it is used.
+ * In this instance the variable points to the device node in server */
+ PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE *)psHeap->psCtx->hDevConnection;
+ ui32CacheLineSize = GET_ROGUE_CACHE_LINE_SIZE(PVRSRV_GET_DEVICE_FEATURE_VALUE(psDevNode, SLC_CACHE_LINE_SIZE_BITS));
+ }
+#else
+ ui32CacheLineSize = ROGUE_CACHE_LINE_SIZE;
+#endif
+
+ /* The following logic makes sure that any cached memory is aligned to both the CPU and GPU.
+ * To be aligned on both you have to take the Lowest Common Multiple (LCM) of the cache line sizes of each.
+ * As the possibilities are all powers of 2 then simply the largest number can be picked as the LCM.
+ * Therefore this algorithm just picks the highest from the CPU, GPU and given alignments.
+ */
+ ui32CPUCacheLineSize = psHeap->psCtx->ui32CPUCacheLineSize;
+ /* If the CPU cache line size is larger than the alignment given then it is the lowest common multiple
+ * Also checking if the allocation is going to be cached on the CPU
+ * Currently there is no check for the validity of the cache coherent option.
+ * In this case, the alignment could be applied but the mode could still fall back to uncached.
+ */
+ if (bAlign && ui32CPUCacheLineSize > uiAlign && bCPUCached)
+ {
+ uiAlign = ui32CPUCacheLineSize;
+ }
+
+ /* If the GPU cache line size is larger than the alignment given then it is the lowest common multiple
+ * Also checking if the allocation is going to be cached on the GPU via checking for any of the cached options.
+ * Currently there is no check for the validity of the cache coherent option.
+ * In this case, the alignment could be applied but the mode could still fall back to uncached.
+ */
+ if (bAlign && ui32CacheLineSize > uiAlign && bGPUCached)
+ {
+ uiAlign = ui32CacheLineSize;
+ }
+
+ eError = DevmemValidateParams(uiSize,
+ uiAlign,
+ &uiFlags);
+ PVR_GOTO_IF_ERROR(eError, failParams);
+
+ eError = DevmemMemDescAlloc(&psMemDesc);
+ PVR_GOTO_IF_ERROR(eError, failMemDescAlloc);
+
+ /* No request for exportable memory so use the RA */
+ eError = RA_Alloc(psHeap->psSubAllocRA,
+ uiSize,
+ uiPreAllocMultiplier,
+ uiFlags,
+ uiAlign,
+ pszText,
+ &uiAllocatedAddr,
+ &uiAllocatedSize,
+ &hImport);
+ PVR_GOTO_IF_ERROR(eError, failDeviceMemAlloc);
+
+ psImport = hImport;
+
+ /* This assignment is assuming the RA returns an hImport where suballocations
+ * can be made from if uiSize is NOT a page multiple of the passed heap.
+ *
+ * So we check if uiSize is a page multiple and mark it as exportable
+ * if it is not.
+ * */
+ OSLockAcquire(psImport->hLock);
+ if (!(uiSize & ((1ULL << psHeap->uiLog2Quantum) - 1)) &&
+ (uiPreAllocMultiplier == RA_NO_IMPORT_MULTIPLIER))
+ {
+ psImport->uiProperties |= DEVMEM_PROPERTIES_EXPORTABLE;
+ }
+ psImport->uiProperties |= DEVMEM_PROPERTIES_SUBALLOCATABLE;
+ uiProperties = psImport->uiProperties;
+ OSLockRelease(psImport->hLock);
+
+ uiOffset = uiAllocatedAddr - psImport->sDeviceImport.sDevVAddr.uiAddr;
+
+#if defined(PDUMP) && defined(DEBUG)
+#if defined(__KERNEL__)
+ PDUMPCOMMENTWITHFLAGS(PMR_DeviceNode((PMR*)psImport->hPMR), PDUMP_CONT,
+ "Suballocated %u Byte for \"%s\" from PMR with handle ID: 0x%p (PID %u)",
+ (IMG_UINT32) uiSize, pszText, psImport->hPMR, OSGetCurrentProcessID());
+#else
+ PDUMPCOMMENTF(psHeap->psCtx->hDevConnection, PDUMP_FLAGS_CONTINUOUS,
+ "Suballocated %u Byte for \"%s\" from PMR with handle ID: %p (PID %u)",
+ (IMG_UINT32) uiSize,
+ pszText,
+ psImport->hPMR,
+ OSGetCurrentProcessID());
+#endif
+#endif
+
+ DevmemMemDescInit(psMemDesc,
+ uiOffset,
+ psImport,
+ uiSize);
+
+ bImportClean = ((uiProperties & DEVMEM_PROPERTIES_IMPORT_IS_CLEAN) != 0);
+
+ /* Zero the memory */
+ if (bZero)
+ {
+ /* Has the import been zeroed on allocation and were no suballocations returned to it so far? */
+ bImportClean = bImportClean && ((uiProperties & DEVMEM_PROPERTIES_IMPORT_IS_ZEROED) != 0);
+
+ if (!bImportClean)
+ {
+ eOp = PVRSRV_CACHE_OP_FLUSH;
+
+ eError = DevmemAcquireCpuVirtAddr(psMemDesc, &pvAddr);
+ PVR_GOTO_IF_ERROR(eError, failMaintenance);
+
+ /* uiSize is a 64-bit quantity whereas the 3rd argument
+ * to OSDeviceMemSet is a 32-bit quantity on 32-bit systems
+ * hence a compiler warning of implicit cast and loss of data.
+ * Added explicit cast and assert to remove warning.
+ */
+ PVR_ASSERT(uiSize < IMG_UINT32_MAX);
+
+ _MemSet(pvAddr, 0, uiSize, uiFlags);
+
+#if defined(PDUMP)
+ DevmemPDumpLoadZeroMem(psMemDesc, 0, uiSize, PDUMP_FLAGS_CONTINUOUS);
+#endif
+ }
+ }
+ else if (bPoisonOnAlloc)
+ {
+ /* Has the import been poisoned on allocation and were no suballocations returned to it so far? */
+ bPoisonOnAlloc = (uiProperties & DEVMEM_PROPERTIES_IMPORT_IS_POISONED) != 0;
+
+ if (!bPoisonOnAlloc)
+ {
+ eOp = PVRSRV_CACHE_OP_FLUSH;
+
+ eError = DevmemAcquireCpuVirtAddr(psMemDesc, &pvAddr);
+ PVR_GOTO_IF_ERROR(eError, failMaintenance);
+
+ _MemSet(pvAddr, PVRSRV_POISON_ON_ALLOC_VALUE, uiSize, uiFlags);
+
+ bPoisonOnAlloc = IMG_TRUE;
+ }
+ }
+
+ /* Flush or invalidate */
+ if (bCPUCached && !bImportClean && (bZero || bCPUCleanFlag || bPoisonOnAlloc))
+ {
+ /* BridgeCacheOpQueue _may_ be deferred so use BridgeCacheOpExec
+ to ensure this cache maintenance is actioned immediately */
+ eError = BridgeCacheOpExec (GetBridgeHandle(psMemDesc->psImport->hDevConnection),
+ psMemDesc->psImport->hPMR,
+ (IMG_UINT64)(uintptr_t)
+ pvAddr - psMemDesc->uiOffset,
+ psMemDesc->uiOffset,
+ psMemDesc->uiAllocSize,
+ eOp);
+ PVR_GOTO_IF_ERROR(eError, failMaintenance);
+ }
+
+ if (pvAddr)
+ {
+ DevmemReleaseCpuVirtAddr(psMemDesc);
+ pvAddr = NULL;
+ }
+
+ /* copy the allocation descriptive name and size so it can be passed to DevicememHistory when
+ * the allocation gets mapped/unmapped
+ */
+ CheckAnnotationLength(pszText);
+ OSStringLCopy(psMemDesc->szText, pszText, DEVMEM_ANNOTATION_MAX_LEN);
+
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO)
+ if (PVRSRVIsBridgeEnabled(GetBridgeHandle(psMemDesc->psImport->hDevConnection), PVRSRV_BRIDGE_RI))
+ {
+ /* Attach RI information */
+ eError = BridgeRIWriteMEMDESCEntry (GetBridgeHandle(psMemDesc->psImport->hDevConnection),
+ psMemDesc->psImport->hPMR,
+ OSStringNLength(psMemDesc->szText, DEVMEM_ANNOTATION_MAX_LEN),
+ psMemDesc->szText,
+ psMemDesc->uiOffset,
+ uiAllocatedSize,
+ IMG_FALSE,
+ IMG_TRUE,
+ &(psMemDesc->hRIHandle));
+ PVR_LOG_IF_ERROR(eError, "BridgeRIWriteMEMDESCEntry");
+ }
+#else /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */
+ PVR_UNREFERENCED_PARAMETER (pszText);
+#endif /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */
+
+ *ppsMemDescPtr = psMemDesc;
+
+ return PVRSRV_OK;
+
+ /* error exit paths follow */
+
+failMaintenance:
+ if (pvAddr)
+ {
+ DevmemReleaseCpuVirtAddr(psMemDesc);
+ pvAddr = NULL;
+ }
+ DevmemMemDescRelease(psMemDesc);
+ psMemDesc = NULL; /* Make sure we don't do a discard after the release */
+failDeviceMemAlloc:
+ if (psMemDesc)
+ {
+ DevmemMemDescDiscard(psMemDesc);
+ }
+failMemDescAlloc:
+failParams:
+ PVR_ASSERT(eError != PVRSRV_OK);
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Failed! Error is %s. Allocation size: " IMG_DEVMEM_SIZE_FMTSPEC,
+ __func__,
+ PVRSRVGETERRORSTRING(eError),
+ uiSize));
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemAllocateExportable(SHARED_DEV_CONNECTION hDevConnection,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_DEVMEM_ALIGN_T uiAlign,
+ IMG_UINT32 uiLog2HeapPageSize,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ const IMG_CHAR *pszText,
+ DEVMEM_MEMDESC **ppsMemDescPtr)
+{
+ PVRSRV_ERROR eError;
+ DEVMEM_MEMDESC *psMemDesc = NULL;
+ DEVMEM_IMPORT *psImport;
+ IMG_UINT32 ui32MappingTable = 0;
+
+ eError = DevmemExportalignAdjustSizeAndAlign(uiLog2HeapPageSize,
+ &uiSize,
+ &uiAlign);
+ PVR_GOTO_IF_ERROR(eError, failParams);
+
+ uiFlags = DevmemOverrideFlagsOrPassThrough(hDevConnection, uiFlags);
+
+ eError = DevmemValidateParams(uiSize,
+ uiAlign,
+ &uiFlags);
+ PVR_GOTO_IF_ERROR(eError, failParams);
+
+ eError = DevmemMemDescAlloc(&psMemDesc);
+ PVR_GOTO_IF_ERROR(eError, failMemDescAlloc);
+
+ eError = AllocateDeviceMemory(hDevConnection,
+ uiLog2HeapPageSize,
+ uiSize,
+ uiSize,
+ 1,
+ 1,
+ &ui32MappingTable,
+ uiAlign,
+ uiFlags,
+ IMG_TRUE,
+ pszText,
+ &psImport);
+ PVR_GOTO_IF_ERROR(eError, failDeviceMemAlloc);
+
+ DevmemMemDescInit(psMemDesc,
+ 0,
+ psImport,
+ uiSize);
+
+ *ppsMemDescPtr = psMemDesc;
+
+ /* copy the allocation descriptive name and size so it can be passed to DevicememHistory when
+ * the allocation gets mapped/unmapped
+ */
+ CheckAnnotationLength(pszText);
+ OSStringLCopy(psMemDesc->szText, pszText, DEVMEM_ANNOTATION_MAX_LEN);
+
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO)
+ if (PVRSRVIsBridgeEnabled(GetBridgeHandle(psImport->hDevConnection), PVRSRV_BRIDGE_RI))
+ {
+ eError = BridgeRIWritePMREntry (GetBridgeHandle(psImport->hDevConnection),
+ psImport->hPMR);
+ PVR_LOG_IF_ERROR(eError, "BridgeRIWritePMREntry");
+
+ /* Attach RI information */
+ eError = BridgeRIWriteMEMDESCEntry (GetBridgeHandle(psImport->hDevConnection),
+ psImport->hPMR,
+ sizeof("^"),
+ "^",
+ psMemDesc->uiOffset,
+ uiSize,
+ IMG_FALSE,
+ IMG_FALSE,
+ &psMemDesc->hRIHandle);
+ PVR_LOG_IF_ERROR(eError, "BridgeRIWriteMEMDESCEntry");
+ }
+#else /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */
+ PVR_UNREFERENCED_PARAMETER (pszText);
+#endif /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */
+
+ return PVRSRV_OK;
+
+ /* error exit paths follow */
+
+failDeviceMemAlloc:
+ DevmemMemDescDiscard(psMemDesc);
+
+failMemDescAlloc:
+failParams:
+ PVR_ASSERT(eError != PVRSRV_OK);
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Failed! Error is %s. Allocation size: " IMG_DEVMEM_SIZE_FMTSPEC,
+ __func__,
+ PVRSRVGETERRORSTRING(eError),
+ uiSize));
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemAllocateSparse(SHARED_DEV_CONNECTION hDevConnection,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_DEVMEM_SIZE_T uiChunkSize,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 *pui32MappingTable,
+ IMG_DEVMEM_ALIGN_T uiAlign,
+ IMG_UINT32 uiLog2HeapPageSize,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ const IMG_CHAR *pszText,
+ DEVMEM_MEMDESC **ppsMemDescPtr)
+{
+ PVRSRV_ERROR eError;
+ DEVMEM_MEMDESC *psMemDesc = NULL;
+ DEVMEM_IMPORT *psImport;
+
+ eError = DevmemExportalignAdjustSizeAndAlign(uiLog2HeapPageSize,
+ &uiSize,
+ &uiAlign);
+ PVR_GOTO_IF_ERROR(eError, failParams);
+
+ uiFlags = DevmemOverrideFlagsOrPassThrough(hDevConnection, uiFlags);
+
+ eError = DevmemValidateParams(uiSize,
+ uiAlign,
+ &uiFlags);
+ PVR_GOTO_IF_ERROR(eError, failParams);
+
+ eError = DevmemMemDescAlloc(&psMemDesc);
+ PVR_GOTO_IF_ERROR(eError, failMemDescAlloc);
+
+ eError = AllocateDeviceMemory(hDevConnection,
+ uiLog2HeapPageSize,
+ uiSize,
+ uiChunkSize,
+ ui32NumPhysChunks,
+ ui32NumVirtChunks,
+ pui32MappingTable,
+ uiAlign,
+ uiFlags,
+ IMG_TRUE,
+ pszText,
+ &psImport);
+ PVR_GOTO_IF_ERROR(eError, failDeviceMemAlloc);
+
+ DevmemMemDescInit(psMemDesc,
+ 0,
+ psImport,
+ uiSize);
+
+ /* copy the allocation descriptive name and size so it can be passed to DevicememHistory when
+ * the allocation gets mapped/unmapped
+ */
+ CheckAnnotationLength(pszText);
+ OSStringLCopy(psMemDesc->szText, pszText, DEVMEM_ANNOTATION_MAX_LEN);
+
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO)
+ if (PVRSRVIsBridgeEnabled(GetBridgeHandle(psImport->hDevConnection), PVRSRV_BRIDGE_RI))
+ {
+ eError = BridgeRIWritePMREntry (GetBridgeHandle(psImport->hDevConnection),
+ psImport->hPMR);
+ PVR_LOG_IF_ERROR(eError, "BridgeRIWritePMREntry");
+
+ /* Attach RI information */
+ eError = BridgeRIWriteMEMDESCEntry (GetBridgeHandle(psMemDesc->psImport->hDevConnection),
+ psMemDesc->psImport->hPMR,
+ sizeof("^"),
+ "^",
+ psMemDesc->uiOffset,
+ uiSize,
+ IMG_FALSE,
+ IMG_FALSE,
+ &psMemDesc->hRIHandle);
+ PVR_LOG_IF_ERROR(eError, "BridgeRIWriteMEMDESCEntry");
+ }
+#else /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */
+ PVR_UNREFERENCED_PARAMETER (pszText);
+#endif /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */
+
+ *ppsMemDescPtr = psMemDesc;
+
+ return PVRSRV_OK;
+
+ /* error exit paths follow */
+
+failDeviceMemAlloc:
+ DevmemMemDescDiscard(psMemDesc);
+
+failMemDescAlloc:
+failParams:
+ PVR_ASSERT(eError != PVRSRV_OK);
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Failed! Error is %s. Allocation size: " IMG_DEVMEM_SIZE_FMTSPEC,
+ __func__,
+ PVRSRVGETERRORSTRING(eError),
+ uiSize));
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemMakeLocalImportHandle(SHARED_DEV_CONNECTION hDevConnection,
+ IMG_HANDLE hServerHandle,
+ IMG_HANDLE *hLocalImportHandle)
+{
+ return BridgePMRMakeLocalImportHandle(GetBridgeHandle(hDevConnection),
+ hServerHandle,
+ hLocalImportHandle);
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemUnmakeLocalImportHandle(SHARED_DEV_CONNECTION hDevConnection,
+ IMG_HANDLE hLocalImportHandle)
+{
+ return BridgePMRUnmakeLocalImportHandle(GetBridgeHandle(hDevConnection), hLocalImportHandle);
+}
+
+/*****************************************************************************
+ * Devmem unsecure export functions *
+ *****************************************************************************/
+
+#if defined(SUPPORT_INSECURE_EXPORT)
+
+static PVRSRV_ERROR
+_Mapping_Export(DEVMEM_IMPORT *psImport,
+ DEVMEM_EXPORTHANDLE *phPMRExportHandlePtr,
+ DEVMEM_EXPORTKEY *puiExportKeyPtr,
+ DEVMEM_SIZE_T *puiSize,
+ DEVMEM_LOG2ALIGN_T *puiLog2Contig)
+{
+ /* Gets an export handle and key for the PMR used for this mapping */
+ /* Can only be done if there are no suballocations for this mapping */
+
+ PVRSRV_ERROR eError;
+ DEVMEM_EXPORTHANDLE hPMRExportHandle;
+ DEVMEM_EXPORTKEY uiExportKey;
+ IMG_DEVMEM_SIZE_T uiSize;
+ IMG_DEVMEM_LOG2ALIGN_T uiLog2Contig;
+
+ PVR_GOTO_IF_INVALID_PARAM(psImport, eError, failParams);
+
+ if ((GetImportProperties(psImport) & DEVMEM_PROPERTIES_EXPORTABLE) == 0)
+ {
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_CANT_EXPORT_SUBALLOCATION, failParams);
+ }
+
+ eError = BridgePMRExportPMR(GetBridgeHandle(psImport->hDevConnection),
+ psImport->hPMR,
+ &hPMRExportHandle,
+ &uiSize,
+ &uiLog2Contig,
+ &uiExportKey);
+ PVR_GOTO_IF_ERROR(eError, failExport);
+
+ PVR_ASSERT(uiSize == psImport->uiSize);
+
+ *phPMRExportHandlePtr = hPMRExportHandle;
+ *puiExportKeyPtr = uiExportKey;
+ *puiSize = uiSize;
+ *puiLog2Contig = uiLog2Contig;
+
+ return PVRSRV_OK;
+
+ /* error exit paths follow */
+
+failExport:
+failParams:
+
+ PVR_ASSERT(eError != PVRSRV_OK);
+ return eError;
+
+}
+
+static void
+_Mapping_Unexport(DEVMEM_IMPORT *psImport,
+ DEVMEM_EXPORTHANDLE hPMRExportHandle)
+{
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT (psImport != NULL);
+
+ eError = BridgePMRUnexportPMR(GetBridgeHandle(psImport->hDevConnection),
+ hPMRExportHandle);
+ PVR_ASSERT(eError == PVRSRV_OK);
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemExport(DEVMEM_MEMDESC *psMemDesc,
+ DEVMEM_EXPORTCOOKIE *psExportCookie)
+{
+ /* Caller to provide storage for export cookie struct */
+ PVRSRV_ERROR eError;
+ IMG_HANDLE hPMRExportHandle = 0;
+ IMG_UINT64 uiPMRExportPassword = 0;
+ IMG_DEVMEM_SIZE_T uiSize = 0;
+ IMG_DEVMEM_LOG2ALIGN_T uiLog2Contig = 0;
+
+ PVR_GOTO_IF_INVALID_PARAM(psMemDesc, eError, e0);
+ PVR_GOTO_IF_INVALID_PARAM(psExportCookie, eError, e0);
+
+ if (DEVMEM_PROPERTIES_EXPORTABLE !=
+ (GetImportProperties(psMemDesc->psImport) & DEVMEM_PROPERTIES_EXPORTABLE))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: This Memory (0x%p) cannot be exported!...",
+ __func__, psMemDesc));
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_REQUEST, e0);
+ }
+
+ eError = _Mapping_Export(psMemDesc->psImport,
+ &hPMRExportHandle,
+ &uiPMRExportPassword,
+ &uiSize,
+ &uiLog2Contig);
+ if (eError != PVRSRV_OK)
+ {
+ psExportCookie->uiSize = 0;
+ goto e0;
+ }
+
+ psExportCookie->hPMRExportHandle = hPMRExportHandle;
+ psExportCookie->uiPMRExportPassword = uiPMRExportPassword;
+ psExportCookie->uiSize = uiSize;
+ psExportCookie->uiLog2ContiguityGuarantee = uiLog2Contig;
+
+ return PVRSRV_OK;
+
+ /* error exit paths follow */
+
+e0:
+ PVR_ASSERT(eError != PVRSRV_OK);
+ return eError;
+}
+
+IMG_INTERNAL void
+DevmemUnexport(DEVMEM_MEMDESC *psMemDesc,
+ DEVMEM_EXPORTCOOKIE *psExportCookie)
+{
+ _Mapping_Unexport(psMemDesc->psImport,
+ psExportCookie->hPMRExportHandle);
+
+ psExportCookie->uiSize = 0;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemImport(SHARED_DEV_CONNECTION hDevConnection,
+ DEVMEM_EXPORTCOOKIE *psCookie,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ DEVMEM_MEMDESC **ppsMemDescPtr)
+{
+ DEVMEM_MEMDESC *psMemDesc = NULL;
+ DEVMEM_IMPORT *psImport;
+ IMG_HANDLE hPMR;
+ PVRSRV_ERROR eError;
+
+ PVR_GOTO_IF_INVALID_PARAM(ppsMemDescPtr, eError, failParams);
+
+ eError = DevmemMemDescAlloc(&psMemDesc);
+ PVR_GOTO_IF_ERROR(eError, failMemDescAlloc);
+
+ eError = DevmemImportStructAlloc(hDevConnection,
+ &psImport);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_OUT_OF_MEMORY, failImportAlloc);
+ }
+
+ /* Get a handle to the PMR (inc refcount) */
+ eError = BridgePMRImportPMR(GetBridgeHandle(hDevConnection),
+ psCookie->hPMRExportHandle,
+ psCookie->uiPMRExportPassword,
+ psCookie->uiSize, /* not trusted - just for validation */
+ psCookie->uiLog2ContiguityGuarantee, /* not trusted - just for validation */
+ &hPMR);
+ PVR_GOTO_IF_ERROR(eError, failImport);
+
+ DevmemImportStructInit(psImport,
+ psCookie->uiSize,
+ 1ULL << psCookie->uiLog2ContiguityGuarantee,
+ uiFlags,
+ hPMR,
+ DEVMEM_PROPERTIES_IMPORTED |
+ DEVMEM_PROPERTIES_EXPORTABLE);
+
+ DevmemMemDescInit(psMemDesc,
+ 0,
+ psImport,
+ psImport->uiSize);
+
+ *ppsMemDescPtr = psMemDesc;
+
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO)
+ if (PVRSRVIsBridgeEnabled(GetBridgeHandle(psMemDesc->psImport->hDevConnection), PVRSRV_BRIDGE_RI))
+ {
+ /* Attach RI information */
+ eError = BridgeRIWriteMEMDESCEntry (GetBridgeHandle(psMemDesc->psImport->hDevConnection),
+ psMemDesc->psImport->hPMR,
+ sizeof("^"),
+ "^",
+ psMemDesc->uiOffset,
+ psMemDesc->psImport->uiSize,
+ IMG_TRUE,
+ IMG_TRUE,
+ &psMemDesc->hRIHandle);
+ PVR_LOG_IF_ERROR(eError, "BridgeRIWriteMEMDESCEntry");
+ }
+#endif /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */
+
+ return PVRSRV_OK;
+
+ /* error exit paths follow */
+
+failImport:
+ DevmemImportDiscard(psImport);
+failImportAlloc:
+ DevmemMemDescDiscard(psMemDesc);
+failMemDescAlloc:
+failParams:
+ PVR_ASSERT(eError != PVRSRV_OK);
+
+ return eError;
+}
+
+#endif /* SUPPORT_INSECURE_EXPORT */
+
+/*****************************************************************************
+ * Common MemDesc functions *
+ *****************************************************************************/
+IMG_INTERNAL PVRSRV_ERROR
+DevmemUnpin(DEVMEM_MEMDESC *psMemDesc)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ DEVMEM_IMPORT *psImport = psMemDesc->psImport;
+ DEVMEM_PROPERTIES_T uiProperties = GetImportProperties(psImport);
+
+ if (uiProperties & DEVMEM_PROPERTIES_NO_LAYOUT_CHANGE)
+ {
+ eError = PVRSRV_ERROR_INVALID_REQUEST;
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: The passed allocation is not valid to unpin",
+ __func__));
+
+ goto e_exit;
+ }
+
+ /* Stop if the allocation might have suballocations. */
+ if (!(uiProperties & DEVMEM_PROPERTIES_EXPORTABLE))
+ {
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: The passed allocation is not valid to unpin because "
+ "there might be suballocations on it. Make sure you allocate a page multiple "
+ "of the heap when using PVRSRVAllocDeviceMem()",
+ __func__));
+
+ goto e_exit;
+ }
+
+ /* Stop if the Import is still mapped to CPU */
+ if (psImport->sCPUImport.ui32RefCount)
+ {
+ eError = PVRSRV_ERROR_STILL_MAPPED;
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: There are still %u references on the CPU mapping. "
+ "Please remove all CPU mappings before unpinning.",
+ __func__,
+ psImport->sCPUImport.ui32RefCount));
+
+ goto e_exit;
+ }
+
+ /* Only unpin if it is not already unpinned
+ * Return PVRSRV_OK */
+ if (uiProperties & DEVMEM_PROPERTIES_UNPINNED)
+ {
+ goto e_exit;
+ }
+
+ /* Unpin it and invalidate mapping */
+ if (psImport->sDeviceImport.bMapped)
+ {
+ eError = BridgeDevmemIntUnpinInvalidate(GetBridgeHandle(psImport->hDevConnection),
+ psImport->sDeviceImport.hMapping,
+ psImport->hPMR);
+ }
+ else
+ {
+ /* Or just unpin it */
+ eError = BridgeDevmemIntUnpin(GetBridgeHandle(psImport->hDevConnection),
+ psImport->hPMR);
+ }
+
+ /* Update flags and RI when call was successful */
+ if (eError == PVRSRV_OK)
+ {
+ OSLockAcquire(psImport->hLock);
+ psImport->uiProperties |= DEVMEM_PROPERTIES_UNPINNED;
+ OSLockRelease(psImport->hLock);
+ }
+ else
+ {
+ /* Or just show what went wrong */
+ PVR_DPF((PVR_DBG_ERROR, "%s: Unpin aborted because of error %d",
+ __func__,
+ eError));
+ }
+
+e_exit:
+ return eError;
+}
+
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemPin(DEVMEM_MEMDESC *psMemDesc)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ DEVMEM_IMPORT *psImport = psMemDesc->psImport;
+ DEVMEM_PROPERTIES_T uiProperties = GetImportProperties(psImport);
+
+ if (uiProperties & DEVMEM_PROPERTIES_NO_LAYOUT_CHANGE)
+ {
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_REQUEST, e_exit);
+ }
+
+ /* Only pin if it is unpinned */
+ if ((uiProperties & DEVMEM_PROPERTIES_UNPINNED) == 0)
+ {
+ goto e_exit;
+ }
+
+ /* Pin it and make mapping valid */
+ if (psImport->sDeviceImport.bMapped)
+ {
+ eError = BridgeDevmemIntPinValidate(GetBridgeHandle(psImport->hDevConnection),
+ psImport->sDeviceImport.hMapping,
+ psImport->hPMR);
+ }
+ else
+ {
+ /* Or just pin it */
+ eError = BridgeDevmemIntPin(GetBridgeHandle(psImport->hDevConnection),
+ psImport->hPMR);
+ }
+
+ if ((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_PMR_NEW_MEMORY))
+ {
+ OSLockAcquire(psImport->hLock);
+ psImport->uiProperties &= ~DEVMEM_PROPERTIES_UNPINNED;
+ OSLockRelease(psImport->hLock);
+ }
+ else
+ {
+ /* Or just show what went wrong */
+ PVR_DPF((PVR_DBG_ERROR, "%s: Pin aborted because of error %d",
+ __func__,
+ eError));
+ }
+
+e_exit:
+ return eError;
+}
+
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetSize(DEVMEM_MEMDESC *psMemDesc, IMG_DEVMEM_SIZE_T* puiSize)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ *puiSize = psMemDesc->uiAllocSize;
+
+ return eError;
+}
+
+IMG_INTERNAL void
+DevmemGetAnnotation(DEVMEM_MEMDESC *psMemDesc, IMG_CHAR **pszAnnotation)
+{
+ /*
+ * It is expected that psMemDesc->szText is a valid NUL-terminated string,
+ * since DevmemMemDescAlloc uses OSAllocZMem to create the memdesc.
+ */
+ *pszAnnotation = psMemDesc->szText;
+}
+
+/*
+ This function is called for freeing any class of memory
+ */
+IMG_INTERNAL IMG_BOOL
+DevmemFree(DEVMEM_MEMDESC *psMemDesc)
+{
+ if (GetImportProperties(psMemDesc->psImport) & DEVMEM_PROPERTIES_SECURE)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Please use methods dedicated to secure buffers.",
+ __func__));
+ return IMG_FALSE;
+ }
+
+ return DevmemMemDescRelease(psMemDesc);
+}
+
+IMG_INTERNAL IMG_BOOL
+DevmemReleaseDevAddrAndFree(DEVMEM_MEMDESC *psMemDesc)
+{
+ DevmemReleaseDevVirtAddr(psMemDesc);
+ return DevmemFree(psMemDesc);
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemMapToDevice(DEVMEM_MEMDESC *psMemDesc,
+ DEVMEM_HEAP *psHeap,
+ IMG_DEV_VIRTADDR *psDevVirtAddr)
+{
+ DEVMEM_IMPORT *psImport;
+ IMG_DEV_VIRTADDR sDevVAddr;
+ PVRSRV_ERROR eError;
+ IMG_BOOL bMap = IMG_TRUE;
+ IMG_BOOL bDestroyed = IMG_FALSE;
+ IMG_UINT64 ui64OptionalMapAddress = DEVICEMEM_UTILS_NO_ADDRESS;
+ DEVMEM_PROPERTIES_T uiProperties = GetImportProperties(psMemDesc->psImport);
+
+ /* Do not try to map unpinned memory */
+ if (uiProperties & DEVMEM_PROPERTIES_UNPINNED)
+ {
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_MAP_REQUEST, failFlags);
+ }
+
+ OSLockAcquire(psMemDesc->sDeviceMemDesc.hLock);
+ PVR_GOTO_IF_INVALID_PARAM(psHeap, eError, failParams);
+
+ if (psMemDesc->sDeviceMemDesc.ui32RefCount != 0)
+ {
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_ALREADY_MAPPED, failCheck);
+ }
+
+ /* Don't map memory for deferred allocations */
+ if (psMemDesc->psImport->uiFlags & PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC)
+ {
+ PVR_ASSERT(uiProperties & DEVMEM_PROPERTIES_EXPORTABLE);
+ bMap = IMG_FALSE;
+ }
+
+ DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+ __func__,
+ psMemDesc,
+ psMemDesc->sDeviceMemDesc.ui32RefCount,
+ psMemDesc->sDeviceMemDesc.ui32RefCount+1);
+
+ psImport = psMemDesc->psImport;
+ DevmemMemDescAcquire(psMemDesc);
+
+#if defined(__KERNEL__)
+ if (psHeap->bPremapped)
+ {
+ ui64OptionalMapAddress = _GetPremappedVA(psImport->hPMR, psHeap->psCtx->hDevConnection);
+ }
+#endif
+
+ eError = DevmemImportStructDevMap(psHeap,
+ bMap,
+ psImport,
+ ui64OptionalMapAddress);
+ PVR_GOTO_IF_ERROR(eError, failMap);
+
+ sDevVAddr.uiAddr = psImport->sDeviceImport.sDevVAddr.uiAddr;
+ sDevVAddr.uiAddr += psMemDesc->uiOffset;
+ psMemDesc->sDeviceMemDesc.sDevVAddr = sDevVAddr;
+ psMemDesc->sDeviceMemDesc.ui32RefCount++;
+
+ *psDevVirtAddr = psMemDesc->sDeviceMemDesc.sDevVAddr;
+
+ OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
+
+ if (GetInfoPageDebugFlags(psMemDesc->psImport->hDevConnection) & DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED)
+ {
+ BridgeDevicememHistoryMap(GetBridgeHandle(psMemDesc->psImport->hDevConnection),
+ psMemDesc->psImport->hPMR,
+ psMemDesc->uiOffset,
+ psMemDesc->sDeviceMemDesc.sDevVAddr,
+ psMemDesc->uiAllocSize,
+ psMemDesc->szText,
+ DevmemGetHeapLog2PageSize(psHeap),
+ psMemDesc->ui32AllocationIndex,
+ &psMemDesc->ui32AllocationIndex);
+ }
+
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO)
+ if (PVRSRVIsBridgeEnabled(GetBridgeHandle(psImport->hDevConnection), PVRSRV_BRIDGE_RI))
+ {
+ if (psMemDesc->hRIHandle)
+ {
+ eError = BridgeRIUpdateMEMDESCAddr(GetBridgeHandle(psImport->hDevConnection),
+ psMemDesc->hRIHandle,
+ psImport->sDeviceImport.sDevVAddr);
+ PVR_LOG_IF_ERROR(eError, "BridgeRIUpdateMEMDESCAddr");
+ }
+ }
+#endif
+
+ return PVRSRV_OK;
+
+failMap:
+ bDestroyed = DevmemMemDescRelease(psMemDesc);
+failCheck:
+failParams:
+ if (!bDestroyed)
+ {
+ OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
+ }
+ PVR_ASSERT(eError != PVRSRV_OK);
+failFlags:
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemMapToDeviceAddress(DEVMEM_MEMDESC *psMemDesc,
+ DEVMEM_HEAP *psHeap,
+ IMG_DEV_VIRTADDR sDevVirtAddr)
+{
+ DEVMEM_IMPORT *psImport;
+ IMG_DEV_VIRTADDR sDevVAddr;
+ PVRSRV_ERROR eError;
+ IMG_BOOL bMap = IMG_TRUE;
+ IMG_BOOL bDestroyed = IMG_FALSE;
+ DEVMEM_PROPERTIES_T uiProperties = GetImportProperties(psMemDesc->psImport);
+
+ /* Do not try to map unpinned memory */
+ if (uiProperties & DEVMEM_PROPERTIES_UNPINNED)
+ {
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_MAP_REQUEST, failFlags);
+ }
+
+ OSLockAcquire(psMemDesc->sDeviceMemDesc.hLock);
+ PVR_GOTO_IF_INVALID_PARAM(psHeap, eError, failParams);
+
+ if (psMemDesc->sDeviceMemDesc.ui32RefCount != 0)
+ {
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_ALREADY_MAPPED, failCheck);
+ }
+
+ /* Don't map memory for deferred allocations */
+ if (psMemDesc->psImport->uiFlags & PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC)
+ {
+ PVR_ASSERT(uiProperties & DEVMEM_PROPERTIES_EXPORTABLE);
+ bMap = IMG_FALSE;
+ }
+
+ DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+ __func__,
+ psMemDesc,
+ psMemDesc->sDeviceMemDesc.ui32RefCount,
+ psMemDesc->sDeviceMemDesc.ui32RefCount+1);
+
+ psImport = psMemDesc->psImport;
+ DevmemMemDescAcquire(psMemDesc);
+
+ eError = DevmemImportStructDevMap(psHeap,
+ bMap,
+ psImport,
+ sDevVirtAddr.uiAddr);
+ PVR_GOTO_IF_ERROR(eError, failMap);
+
+ sDevVAddr.uiAddr = psImport->sDeviceImport.sDevVAddr.uiAddr;
+ sDevVAddr.uiAddr += psMemDesc->uiOffset;
+ psMemDesc->sDeviceMemDesc.sDevVAddr = sDevVAddr;
+ psMemDesc->sDeviceMemDesc.ui32RefCount++;
+
+ OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
+
+ if (GetInfoPageDebugFlags(psMemDesc->psImport->hDevConnection) & DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED)
+ {
+ BridgeDevicememHistoryMap(GetBridgeHandle(psMemDesc->psImport->hDevConnection),
+ psMemDesc->psImport->hPMR,
+ psMemDesc->uiOffset,
+ psMemDesc->sDeviceMemDesc.sDevVAddr,
+ psMemDesc->uiAllocSize,
+ psMemDesc->szText,
+ DevmemGetHeapLog2PageSize(psHeap),
+ psMemDesc->ui32AllocationIndex,
+ &psMemDesc->ui32AllocationIndex);
+ }
+
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO)
+ if (PVRSRVIsBridgeEnabled(GetBridgeHandle(psImport->hDevConnection), PVRSRV_BRIDGE_RI))
+ {
+ if (psMemDesc->hRIHandle)
+ {
+ eError = BridgeRIUpdateMEMDESCAddr(GetBridgeHandle(psImport->hDevConnection),
+ psMemDesc->hRIHandle,
+ psImport->sDeviceImport.sDevVAddr);
+ PVR_LOG_IF_ERROR(eError, "BridgeRIUpdateMEMDESCAddr");
+ }
+ }
+#endif
+
+ return PVRSRV_OK;
+
+failMap:
+ bDestroyed = DevmemMemDescRelease(psMemDesc);
+failCheck:
+failParams:
+ if (!bDestroyed)
+ {
+ OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
+ }
+ PVR_ASSERT(eError != PVRSRV_OK);
+failFlags:
+ return eError;
+}
+
+IMG_INTERNAL IMG_DEV_VIRTADDR
+DevmemGetDevVirtAddr(DEVMEM_MEMDESC *psMemDesc)
+{
+ if (psMemDesc->sDeviceMemDesc.ui32RefCount == 0)
+ {
+ PVR_LOG_ERROR(PVRSRV_ERROR_DEVICEMEM_NO_MAPPING, "DevmemGetDevVirtAddr");
+ }
+
+ PVR_ASSERT(psMemDesc->sDeviceMemDesc.sDevVAddr.uiAddr !=0 );
+
+ return psMemDesc->sDeviceMemDesc.sDevVAddr;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemAcquireDevVirtAddr(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEV_VIRTADDR *psDevVirtAddr)
+{
+ PVRSRV_ERROR eError;
+
+ /* Do not try to map unpinned memory */
+ if (GetImportProperties(psMemDesc->psImport) & DEVMEM_PROPERTIES_UNPINNED)
+ {
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_MAP_REQUEST, failCheck);
+ }
+
+ OSLockAcquire(psMemDesc->sDeviceMemDesc.hLock);
+ DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+ __func__,
+ psMemDesc,
+ psMemDesc->sDeviceMemDesc.ui32RefCount,
+ psMemDesc->sDeviceMemDesc.ui32RefCount+1);
+
+ if (psMemDesc->sDeviceMemDesc.ui32RefCount == 0)
+ {
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_NO_MAPPING, failRelease);
+ }
+ psMemDesc->sDeviceMemDesc.ui32RefCount++;
+
+ *psDevVirtAddr = psMemDesc->sDeviceMemDesc.sDevVAddr;
+ OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
+
+ return PVRSRV_OK;
+
+failRelease:
+ OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
+ PVR_ASSERT(eError != PVRSRV_OK);
+failCheck:
+ return eError;
+}
+
+IMG_INTERNAL void
+DevmemReleaseDevVirtAddr(DEVMEM_MEMDESC *psMemDesc)
+{
+ PVR_ASSERT(psMemDesc != NULL);
+
+ OSLockAcquire(psMemDesc->sDeviceMemDesc.hLock);
+ DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+ __func__,
+ psMemDesc,
+ psMemDesc->sDeviceMemDesc.ui32RefCount,
+ psMemDesc->sDeviceMemDesc.ui32RefCount-1);
+
+ PVR_ASSERT(psMemDesc->sDeviceMemDesc.ui32RefCount != 0);
+
+ if (--psMemDesc->sDeviceMemDesc.ui32RefCount == 0)
+ {
+ if (GetInfoPageDebugFlags(psMemDesc->psImport->hDevConnection) & DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED)
+ {
+ BridgeDevicememHistoryUnmap(GetBridgeHandle(psMemDesc->psImport->hDevConnection),
+ psMemDesc->psImport->hPMR,
+ psMemDesc->uiOffset,
+ psMemDesc->sDeviceMemDesc.sDevVAddr,
+ psMemDesc->uiAllocSize,
+ psMemDesc->szText,
+ DevmemGetHeapLog2PageSize(psMemDesc->psImport->sDeviceImport.psHeap),
+ psMemDesc->ui32AllocationIndex,
+ &psMemDesc->ui32AllocationIndex);
+ }
+
+ /* When device mapping destroyed, zero Dev VA so DevmemGetDevVirtAddr()
+ * returns 0 */
+ if (DevmemImportStructDevUnmap(psMemDesc->psImport) == IMG_TRUE)
+ {
+ psMemDesc->sDeviceMemDesc.sDevVAddr.uiAddr = 0;
+ }
+ OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
+
+ DevmemMemDescRelease(psMemDesc);
+ }
+ else
+ {
+ OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
+ }
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemAcquireCpuVirtAddr(DEVMEM_MEMDESC *psMemDesc,
+ void **ppvCpuVirtAddr)
+{
+ PVRSRV_ERROR eError;
+ DEVMEM_PROPERTIES_T uiProperties;
+
+ PVR_ASSERT(psMemDesc != NULL);
+ PVR_ASSERT(ppvCpuVirtAddr != NULL);
+
+ uiProperties = GetImportProperties(psMemDesc->psImport);
+
+ if (uiProperties &
+ (DEVMEM_PROPERTIES_UNPINNED | DEVMEM_PROPERTIES_SECURE))
+ {
+#if defined(SUPPORT_SECURITY_VALIDATION)
+ if (uiProperties & DEVMEM_PROPERTIES_SECURE)
+ {
+ PVR_DPF((PVR_DBG_WARNING,
+ "%s: Allocation is a secure buffer. "
+ "It should not be possible to map to CPU, but for security "
+ "validation this will be allowed for testing purposes, "
+ "as long as the buffer is pinned.",
+ __func__));
+ }
+
+ if (uiProperties & DEVMEM_PROPERTIES_UNPINNED)
+#endif
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Allocation is currently unpinned or a secure buffer. "
+ "Not possible to map to CPU!",
+ __func__));
+ return PVRSRV_ERROR_INVALID_MAP_REQUEST;
+ }
+ }
+
+ if (uiProperties & DEVMEM_PROPERTIES_NO_CPU_MAPPING)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: CPU Mapping is not possible on this allocation!",
+ __func__));
+ return PVRSRV_ERROR_INVALID_MAP_REQUEST;
+ }
+
+ OSLockAcquire(psMemDesc->sCPUMemDesc.hLock);
+ DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+ __func__,
+ psMemDesc,
+ psMemDesc->sCPUMemDesc.ui32RefCount,
+ psMemDesc->sCPUMemDesc.ui32RefCount+1);
+
+ if (psMemDesc->sCPUMemDesc.ui32RefCount++ == 0)
+ {
+ DEVMEM_IMPORT *psImport = psMemDesc->psImport;
+ IMG_UINT8 *pui8CPUVAddr;
+
+ DevmemMemDescAcquire(psMemDesc);
+ eError = DevmemImportStructCPUMap(psImport);
+ PVR_GOTO_IF_ERROR(eError, failMap);
+
+ pui8CPUVAddr = psImport->sCPUImport.pvCPUVAddr;
+ pui8CPUVAddr += psMemDesc->uiOffset;
+ psMemDesc->sCPUMemDesc.pvCPUVAddr = pui8CPUVAddr;
+ }
+ *ppvCpuVirtAddr = psMemDesc->sCPUMemDesc.pvCPUVAddr;
+
+ VG_MARK_INITIALIZED(*ppvCpuVirtAddr, psMemDesc->psImport->uiSize);
+
+ OSLockRelease(psMemDesc->sCPUMemDesc.hLock);
+
+ return PVRSRV_OK;
+
+failMap:
+ PVR_ASSERT(eError != PVRSRV_OK);
+ psMemDesc->sCPUMemDesc.ui32RefCount--;
+
+ if (!DevmemMemDescRelease(psMemDesc))
+ {
+ OSLockRelease(psMemDesc->sCPUMemDesc.hLock);
+ }
+ return eError;
+}
+
+IMG_INTERNAL void
+DevmemReacquireCpuVirtAddr(DEVMEM_MEMDESC *psMemDesc,
+ void **ppvCpuVirtAddr)
+{
+ PVR_ASSERT(psMemDesc != NULL);
+ PVR_ASSERT(ppvCpuVirtAddr != NULL);
+
+ if (GetImportProperties(psMemDesc->psImport) & DEVMEM_PROPERTIES_NO_CPU_MAPPING)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: CPU UnMapping is not possible on this allocation!",
+ __func__));
+ return;
+ }
+
+ OSLockAcquire(psMemDesc->sCPUMemDesc.hLock);
+ DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+ __func__,
+ psMemDesc,
+ psMemDesc->sCPUMemDesc.ui32RefCount,
+ psMemDesc->sCPUMemDesc.ui32RefCount+1);
+
+ *ppvCpuVirtAddr = NULL;
+ if (psMemDesc->sCPUMemDesc.ui32RefCount)
+ {
+ *ppvCpuVirtAddr = psMemDesc->sCPUMemDesc.pvCPUVAddr;
+ psMemDesc->sCPUMemDesc.ui32RefCount += 1;
+ }
+
+ VG_MARK_INITIALIZED(*ppvCpuVirtAddr, psMemDesc->psImport->uiSize);
+ OSLockRelease(psMemDesc->sCPUMemDesc.hLock);
+}
+
+IMG_INTERNAL void
+DevmemReleaseCpuVirtAddr(DEVMEM_MEMDESC *psMemDesc)
+{
+ PVR_ASSERT(psMemDesc != NULL);
+
+ if (GetImportProperties(psMemDesc->psImport) & DEVMEM_PROPERTIES_NO_CPU_MAPPING)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: CPU UnMapping is not possible on this allocation!",
+ __func__));
+ return;
+ }
+
+ OSLockAcquire(psMemDesc->sCPUMemDesc.hLock);
+ DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+ __func__,
+ psMemDesc,
+ psMemDesc->sCPUMemDesc.ui32RefCount,
+ psMemDesc->sCPUMemDesc.ui32RefCount-1);
+
+ PVR_ASSERT(psMemDesc->sCPUMemDesc.ui32RefCount != 0);
+
+ if (--psMemDesc->sCPUMemDesc.ui32RefCount == 0)
+ {
+ OSLockRelease(psMemDesc->sCPUMemDesc.hLock);
+ DevmemImportStructCPUUnmap(psMemDesc->psImport);
+ DevmemMemDescRelease(psMemDesc);
+ }
+ else
+ {
+ OSLockRelease(psMemDesc->sCPUMemDesc.hLock);
+ }
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemLocalGetImportHandle(DEVMEM_MEMDESC *psMemDesc,
+ IMG_HANDLE *phImport)
+{
+ if ((GetImportProperties(psMemDesc->psImport) & DEVMEM_PROPERTIES_EXPORTABLE) == 0)
+ {
+ return PVRSRV_ERROR_DEVICEMEM_CANT_EXPORT_SUBALLOCATION;
+ }
+
+ *phImport = psMemDesc->psImport->hPMR;
+
+ return PVRSRV_OK;
+}
+
+#if !defined(__KERNEL__)
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetImportUID(DEVMEM_MEMDESC *psMemDesc,
+ IMG_UINT64 *pui64UID)
+{
+ DEVMEM_IMPORT *psImport = psMemDesc->psImport;
+ PVRSRV_ERROR eError;
+
+ if (!(GetImportProperties(psImport) & (DEVMEM_PROPERTIES_IMPORTED |
+ DEVMEM_PROPERTIES_EXPORTABLE)))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: This Memory (0x%p) doesn't support the functionality requested...",
+ __func__, psMemDesc));
+ return PVRSRV_ERROR_INVALID_REQUEST;
+ }
+
+ eError = BridgePMRGetUID(GetBridgeHandle(psImport->hDevConnection),
+ psImport->hPMR,
+ pui64UID);
+
+ return eError;
+}
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetReservation(DEVMEM_MEMDESC *psMemDesc,
+ IMG_HANDLE *hReservation)
+{
+ DEVMEM_IMPORT *psImport;
+
+ PVR_ASSERT(psMemDesc);
+ psImport = psMemDesc->psImport;
+
+ PVR_ASSERT(psImport);
+ *hReservation = psImport->sDeviceImport.hReservation;
+
+ return PVRSRV_OK;
+}
+
+#endif /* !__KERNEL__ */
+
+/* Kernel usage of this function will only work with
+ * memdescs of buffers allocated in the FW memory context
+ * that is created in the Server
+ */
+PVRSRV_ERROR
+DevmemGetPMRData(DEVMEM_MEMDESC *psMemDesc,
+ IMG_HANDLE *phPMR,
+ IMG_DEVMEM_OFFSET_T *puiPMROffset)
+{
+ DEVMEM_IMPORT *psImport;
+
+ PVR_ASSERT(psMemDesc);
+ *puiPMROffset = psMemDesc->uiOffset;
+ psImport = psMemDesc->psImport;
+
+ PVR_ASSERT(psImport);
+ *phPMR = psImport->hPMR;
+
+ return PVRSRV_OK;
+}
+
+#if defined(__KERNEL__)
+IMG_INTERNAL void
+DevmemGetFlags(DEVMEM_MEMDESC *psMemDesc,
+ PVRSRV_MEMALLOCFLAGS_T *puiFlags)
+{
+ DEVMEM_IMPORT *psImport;
+
+ PVR_ASSERT(psMemDesc);
+ psImport = psMemDesc->psImport;
+
+ PVR_ASSERT(psImport);
+ *puiFlags = psImport->uiFlags;
+}
+
+IMG_INTERNAL SHARED_DEV_CONNECTION
+DevmemGetConnection(DEVMEM_MEMDESC *psMemDesc)
+{
+ return psMemDesc->psImport->hDevConnection;
+}
+#endif /* __KERNEL__ */
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemLocalImport(SHARED_DEV_CONNECTION hDevConnection,
+ IMG_HANDLE hExtHandle,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ DEVMEM_MEMDESC **ppsMemDescPtr,
+ IMG_DEVMEM_SIZE_T *puiSizePtr,
+ const IMG_CHAR *pszAnnotation)
+{
+ DEVMEM_MEMDESC *psMemDesc = NULL;
+ DEVMEM_IMPORT *psImport;
+ IMG_DEVMEM_SIZE_T uiSize;
+ IMG_DEVMEM_ALIGN_T uiAlign;
+ IMG_HANDLE hPMR;
+ PVRSRV_ERROR eError;
+
+ PVR_GOTO_IF_INVALID_PARAM(ppsMemDescPtr, eError, failParams);
+
+ eError = DevmemMemDescAlloc(&psMemDesc);
+ PVR_GOTO_IF_ERROR(eError, failMemDescAlloc);
+
+ eError = DevmemImportStructAlloc(hDevConnection,
+ &psImport);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_OUT_OF_MEMORY, failImportAlloc);
+ }
+
+ /* Get the PMR handle and its size from the server */
+ eError = BridgePMRLocalImportPMR(GetBridgeHandle(hDevConnection),
+ hExtHandle,
+ &hPMR,
+ &uiSize,
+ &uiAlign);
+ PVR_GOTO_IF_ERROR(eError, failImport);
+
+ DevmemImportStructInit(psImport,
+ uiSize,
+ uiAlign,
+ uiFlags,
+ hPMR,
+ DEVMEM_PROPERTIES_IMPORTED |
+ DEVMEM_PROPERTIES_EXPORTABLE);
+
+ DevmemMemDescInit(psMemDesc,
+ 0,
+ psImport,
+ uiSize);
+
+ *ppsMemDescPtr = psMemDesc;
+ if (puiSizePtr)
+ *puiSizePtr = uiSize;
+
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO)
+ if (PVRSRVIsBridgeEnabled(GetBridgeHandle(psMemDesc->psImport->hDevConnection), PVRSRV_BRIDGE_RI))
+ {
+ /* Attach RI information.
+ * Set backed size to 0 since this allocation has been allocated
+ * by the same process and has been accounted for. */
+ eError = BridgeRIWriteMEMDESCEntry (GetBridgeHandle(psMemDesc->psImport->hDevConnection),
+ psMemDesc->psImport->hPMR,
+ sizeof("^"),
+ "^",
+ psMemDesc->uiOffset,
+ psMemDesc->psImport->uiSize,
+ IMG_TRUE,
+ IMG_FALSE,
+ &(psMemDesc->hRIHandle));
+ PVR_LOG_IF_ERROR(eError, "BridgeRIWriteMEMDESCEntry");
+ }
+#endif /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */
+
+
+ /* Copy the allocation descriptive name and size so it can be passed
+ * to DevicememHistory when the allocation gets mapped/unmapped
+ */
+ CheckAnnotationLength(pszAnnotation);
+ OSStringLCopy(psMemDesc->szText, pszAnnotation, DEVMEM_ANNOTATION_MAX_LEN);
+
+ return PVRSRV_OK;
+
+failImport:
+ DevmemImportDiscard(psImport);
+failImportAlloc:
+ DevmemMemDescDiscard(psMemDesc);
+failMemDescAlloc:
+failParams:
+ PVR_ASSERT(eError != PVRSRV_OK);
+
+ return eError;
+}
+
+#if !defined(__KERNEL__)
+IMG_INTERNAL PVRSRV_ERROR
+DevmemIsDevVirtAddrValid(DEVMEM_CONTEXT *psContext,
+ IMG_DEV_VIRTADDR sDevVAddr)
+{
+ return BridgeDevmemIsVDevAddrValid(GetBridgeHandle(psContext->hDevConnection),
+ psContext->hDevMemServerContext,
+ sDevVAddr);
+}
+
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetFaultAddress(DEVMEM_CONTEXT *psContext,
+ IMG_DEV_VIRTADDR *psFaultAddress)
+{
+ return BridgeDevmemGetFaultAddress(GetBridgeHandle(psContext->hDevConnection),
+ psContext->hDevMemServerContext,
+ psFaultAddress);
+}
+IMG_INTERNAL PVRSRV_ERROR
+DevmemFlushDeviceSLCRange(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_BOOL bInvalidate)
+{
+ DEVMEM_IMPORT *psImport = psMemDesc->psImport;
+ return BridgeDevmemFlushDevSLCRange(GetBridgeHandle(psImport->hDevConnection),
+ psImport->sDeviceImport.psHeap->psCtx->hDevMemServerContext,
+ sDevVAddr,
+ uiSize,
+ bInvalidate);
+}
+
+#if defined(RGX_FEATURE_FBCDC)
+IMG_INTERNAL PVRSRV_ERROR
+DevmemInvalidateFBSCTable(DEVMEM_CONTEXT *psContext,
+ IMG_UINT64 ui64FBSCEntries)
+{
+ return BridgeDevmemInvalidateFBSCTable(GetBridgeHandle(psContext->hDevConnection),
+ psContext->hDevMemServerContext,
+ ui64FBSCEntries);
+}
+#endif
+
+#endif /* !__KERNEL__ */
+
+IMG_INTERNAL IMG_UINT32
+DevmemGetHeapLog2PageSize(DEVMEM_HEAP *psHeap)
+{
+ return psHeap->uiLog2Quantum;
+}
+
+IMG_INTERNAL PVRSRV_MEMALLOCFLAGS_T
+DevmemGetMemAllocFlags(DEVMEM_MEMDESC *psMemDesc)
+{
+ return psMemDesc->psImport->uiFlags;
+}
+
+IMG_INTERNAL IMG_DEVMEM_SIZE_T
+DevmemGetHeapReservedSize(DEVMEM_HEAP *psHeap)
+{
+ return psHeap->uiReservedRegionSize;
+}
+
+#if !defined(__KERNEL__)
+/**************************************************************************/ /*!
+@Function RegisterDevMemPFNotify
+@Description Registers that the application wants to be signaled when a page
+ fault occurs.
+
+@Input psContext Memory context the process that would like to
+ be notified about.
+@Input ui32PID The PID of the calling process.
+@Input bRegister If true, register. If false, de-register.
+@Return PVRSRV_ERROR: PVRSRV_OK on success. Otherwise, a PVRSRV_
+ error code
+ */ /***************************************************************************/
+IMG_INTERNAL PVRSRV_ERROR
+RegisterDevmemPFNotify(DEVMEM_CONTEXT *psContext,
+ IMG_UINT32 ui32PID,
+ IMG_BOOL bRegister)
+{
+ PVRSRV_ERROR eError;
+
+ eError = BridgeDevmemIntRegisterPFNotifyKM(GetBridgeHandle(psContext->hDevConnection),
+ psContext->hDevMemServerContext,
+ ui32PID,
+ bRegister);
+ if (eError == PVRSRV_ERROR_BRIDGE_CALL_FAILED)
+ {
+ PVR_LOG_ERROR(eError, "BridgeDevmemIntRegisterPFNotifyKM");
+ }
+
+ return eError;
+}
+#endif /* !__KERNEL__ */
+
+IMG_INTERNAL void
+DevmemHeapSetPremapStatus(DEVMEM_HEAP *psHeap, IMG_BOOL IsPremapped)
+{
+ psHeap->bPremapped = IsPremapped;
+}
diff --git a/drivers/gpu/drm/img-rogue/devicemem.h b/drivers/gpu/drm/img-rogue/devicemem.h
new file mode 100644
index 000000000..430169a1b
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/devicemem.h
@@ -0,0 +1,730 @@
+/*************************************************************************/ /*!
+@File
+@Title Device Memory Management core internal
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Services internal interface to core device memory management
+ functions that are shared between client and server code.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef SRVCLIENT_DEVICEMEM_H
+#define SRVCLIENT_DEVICEMEM_H
+
+/******************************************************************************
+ * *
+ * +------------+ +------------+ +--------------+ +--------------+ *
+ * | a sub- | | a sub- | | an | | allocation | *
+ * | allocation | | allocation | | allocation | | also mapped | *
+ * | | | | | in proc 1 | | into proc 2 | *
+ * +------------+ +------------+ +--------------+ +--------------+ *
+ * | | | | *
+ * +--------------+ +--------------+ +--------------+ *
+ * | page gran- | | page gran- | | page gran- | *
+ * | ular mapping | | ular mapping | | ular mapping | *
+ * +--------------+ +--------------+ +--------------+ *
+ * | | | *
+ * | | | *
+ * | | | *
+ * +--------------+ +--------------+ *
+ * | | | | *
+ * | A "P.M.R." | | A "P.M.R." | *
+ * | | | | *
+ * +--------------+ +--------------+ *
+ * *
+ ******************************************************************************/
+
+/*
+ All device memory allocations are ultimately a view upon (not
+ necessarily the whole of) a "PMR".
+
+ A PMR is a "Physical Memory Resource", which may be a
+ "pre-faulted" lump of physical memory, or it may be a
+ representation of some physical memory that will be instantiated
+ at some future time.
+
+ PMRs always represent multiple of some power-of-2 "contiguity"
+ promised by the PMR, which will allow them to be mapped in whole
+ pages into the device MMU. As memory allocations may be smaller
+ than a page, these mappings may be suballocated and thus shared
+ between multiple allocations in one process. A PMR may also be
+ mapped simultaneously into multiple device memory contexts
+ (cross-process scenario), however, for security reasons, it is not
+ legal to share a PMR "both ways" at once, that is, mapped into
+ multiple processes and divided up amongst several suballocations.
+
+ This PMR terminology is introduced here for background
+ information, but is generally of little concern to the caller of
+ this API. This API handles suballocations and mappings, and the
+ caller thus deals primarily with MEMORY DESCRIPTORS representing
+ an allocation or suballocation, HEAPS representing ranges of
+ virtual addresses in a CONTEXT.
+*/
+
+/*
+ |<---------------------------context------------------------------>|
+ |<-------heap------->| |<-------heap------->|<-------heap------->|
+ |<-alloc->| | |<-alloc->|<-alloc->|| |<-alloc->| |
+*/
+
+#include "img_types.h"
+#include "img_defs.h"
+#include "devicemem_typedefs.h"
+#include "pdumpdefs.h"
+#include "pvrsrv_error.h"
+#include "pvrsrv_memallocflags.h"
+
+#include "pdump.h"
+
+#include "device_connection.h"
+
+
+typedef IMG_UINT32 DEVMEM_HEAPCFGID;
+#define DEVMEM_HEAPCFG_FORCLIENTS 0
+#define DEVMEM_HEAPCFG_META 1
+
+
+/*
+ In order to call the server side functions, we need a bridge handle.
+ We abstract that here, as we may wish to change its form.
+ */
+
+typedef IMG_HANDLE DEVMEM_BRIDGE_HANDLE;
+
+/*************************************************************************/ /*!
+@Function DevmemUnpin
+@Description This is the counterpart to DevmemPin(). It is meant to be
+ called before repinning an allocation.
+
+ For a detailed description see client API documentation.
+
+@Input phMemDesc The MemDesc that is going to be unpinned.
+
+@Return PVRSRV_ERROR: PVRSRV_OK on success and the memory is
+ registered to be reclaimed. Error otherwise.
+*/ /**************************************************************************/
+IMG_INTERNAL PVRSRV_ERROR
+DevmemUnpin(DEVMEM_MEMDESC *psMemDesc);
+
+/*************************************************************************/ /*!
+@Function DevmemPin
+@Description This is the counterpart to DevmemUnpin(). It is meant to be
+ called after unpinning an allocation.
+
+ For a detailed description see client API documentation.
+
+@Input phMemDesc The MemDesc that is going to be pinned.
+
+@Return PVRSRV_ERROR: PVRSRV_OK on success and the allocation content
+ was successfully restored.
+
+ PVRSRV_ERROR_PMR_NEW_MEMORY when the content
+ could not be restored and new physical memory
+ was allocated.
+
+ A different error otherwise.
+*/ /**************************************************************************/
+IMG_INTERNAL PVRSRV_ERROR
+DevmemPin(DEVMEM_MEMDESC *psMemDesc);
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetHeapInt(DEVMEM_HEAP *psHeap,
+ IMG_HANDLE *phDevmemHeap);
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetSize(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_SIZE_T* puiSize);
+
+IMG_INTERNAL void
+DevmemGetAnnotation(DEVMEM_MEMDESC *psMemDesc,
+ IMG_CHAR **pszAnnotation);
+
+/*
+ * DevmemCreateContext()
+ *
+ * Create a device memory context
+ *
+ * This must be called before any heap is created in this context
+ *
+ * Caller to provide bridge handle which will be recorded internally and used
+ * for all future operations on items from this memory context. Caller also
+ * to provide devicenode handle, as this is used for MMU configuration and
+ * also to determine the heap configuration for the auto-instantiated heaps.
+ *
+ * Note that when compiled in services/server, the hBridge is not used and
+ * is thrown away by the "fake" direct bridge. (This may change. It is
+ * recommended that NULL be passed for the handle for now.)
+ *
+ * hDeviceNode and uiHeapBlueprintID shall together dictate which heap-config
+ * to use.
+ *
+ * This will cause the server side counterpart to be created also.
+ *
+ * If you call DevmemCreateContext() (and the call succeeds) you are promising
+ * that you will later call Devmem_ContextDestroy(), except for abnormal
+ * process termination in which case it is expected it will be destroyed as
+ * part of handle clean up.
+ *
+ * Caller to provide storage for the pointer to the newly created
+ * NEWDEVMEM_CONTEXT object.
+ */
+PVRSRV_ERROR
+DevmemCreateContext(SHARED_DEV_CONNECTION hDevConnection,
+ DEVMEM_HEAPCFGID uiHeapBlueprintID,
+ DEVMEM_CONTEXT **ppsCtxPtr);
+
+/*
+ * DevmemAcquireDevPrivData()
+ *
+ * Acquire the device private data for this memory context
+ */
+PVRSRV_ERROR
+DevmemAcquireDevPrivData(DEVMEM_CONTEXT *psCtx,
+ IMG_HANDLE *hPrivData);
+
+/*
+ * DevmemReleaseDevPrivData()
+ *
+ * Release the device private data for this memory context
+ */
+PVRSRV_ERROR
+DevmemReleaseDevPrivData(DEVMEM_CONTEXT *psCtx);
+
+/*
+ * DevmemDestroyContext()
+ *
+ * Undoes that done by DevmemCreateContext()
+ */
+PVRSRV_ERROR
+DevmemDestroyContext(DEVMEM_CONTEXT *psCtx);
+
+/*
+ * DevmemCreateHeap()
+ *
+ * Create a heap in the given context.
+ *
+ * N.B. Not intended to be called directly, though it can be.
+ * Normally, heaps are instantiated at context creation time according
+ * to the specified blueprint. See DevmemCreateContext() for details.
+ *
+ * This will cause MMU code to set up data structures for the heap,
+ * but may not cause page tables to be modified until allocations are
+ * made from the heap.
+ *
+ * uiReservedRegionLength Reserved address space for static VAs shared
+ * between clients and firmware
+ *
+ * The "Quantum" is both the device MMU page size to be configured for
+ * this heap, and the unit multiples of which "quantized" allocations
+ * are made (allocations smaller than this, known as "suballocations"
+ * will be made from a "sub alloc RA" and will "import" chunks
+ * according to this quantum)
+ *
+ * Where imported PMRs (or, for example, PMRs created by device class
+ * buffers) are mapped into this heap, it is important that the
+ * physical contiguity guarantee offered by the PMR is greater than or
+ * equal to the quantum size specified here, otherwise the attempt to
+ * map it will fail. "Normal" allocations via Devmem_Allocate
+ * shall automatically meet this requirement, as each "import" will
+ * trigger the creation of a PMR with the desired contiguity. The
+ * supported quantum sizes in that case shall be dictated by the OS
+ * specific implementation of PhysmemNewOSRamBackedPMR() (see)
+ */
+PVRSRV_ERROR
+DevmemCreateHeap(DEVMEM_CONTEXT *psCtxPtr,
+ /* base and length of heap */
+ IMG_DEV_VIRTADDR sBaseAddress,
+ IMG_DEVMEM_SIZE_T uiLength,
+ IMG_DEVMEM_SIZE_T uiReservedRegionLength,
+ /* log2 of allocation quantum, i.e. "page" size.
+ All allocations (that go to server side) are
+ multiples of this. We use a client-side RA to
+ make sub-allocations from this */
+ IMG_UINT32 ui32Log2Quantum,
+ /* The minimum import alignment for this heap */
+ IMG_UINT32 ui32Log2ImportAlignment,
+ /* Name of heap for debug */
+ /* N.B. Okay to exist on caller's stack - this
+ func takes a copy if it needs it. */
+ const IMG_CHAR *pszName,
+ DEVMEM_HEAPCFGID uiHeapBlueprintID,
+ DEVMEM_HEAP **ppsHeapPtr);
+/*
+ * DevmemDestroyHeap()
+ *
+ * Reverses DevmemCreateHeap()
+ *
+ * N.B. All allocations must have been freed and all mappings must
+ * have been unmapped before invoking this call
+ */
+PVRSRV_ERROR
+DevmemDestroyHeap(DEVMEM_HEAP *psHeap);
+
+/*
+ * DevmemExportalignAdjustSizeAndAlign()
+ * Compute the Size and Align passed to avoid suballocations
+ * (used when allocation with PVRSRV_MEMALLOCFLAG_EXPORTALIGN).
+ *
+ * Returns PVRSRV_ERROR_INVALID_PARAMS if uiLog2Quantum has invalid value.
+ */
+IMG_INTERNAL PVRSRV_ERROR
+DevmemExportalignAdjustSizeAndAlign(IMG_UINT32 uiLog2Quantum,
+ IMG_DEVMEM_SIZE_T *puiSize,
+ IMG_DEVMEM_ALIGN_T *puiAlign);
+
+/*
+ * DevmemSubAllocate()
+ *
+ * Makes an allocation (possibly a "suballocation", as described
+ * below) of device virtual memory from this heap.
+ *
+ * The size and alignment of the allocation will be honoured by the RA
+ * that allocates the "suballocation". The resulting allocation will
+ * be mapped into GPU virtual memory and the physical memory to back
+ * it will exist, by the time this call successfully completes.
+ *
+ * The size must be a positive integer multiple of the alignment.
+ * (i.e. the alignment specifies the alignment of both the start and
+ * the end of the resulting allocation.)
+ *
+ * Allocations made via this API are routed through a "suballocation
+ * RA" which is responsible for ensuring that small allocations can be
+ * made without wasting physical memory in the server. Furthermore,
+ * such suballocations can be made entirely client side without
+ * needing to go to the server unless the allocation spills into a new
+ * page.
+ *
+ * Such suballocations cause many allocations to share the same "PMR".
+ * This happens only when the flags match exactly.
+ *
+ */
+
+PVRSRV_ERROR
+DevmemSubAllocate(IMG_UINT8 uiPreAllocMultiplier,
+ DEVMEM_HEAP *psHeap,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_DEVMEM_ALIGN_T uiAlign,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ const IMG_CHAR *pszText,
+ DEVMEM_MEMDESC **ppsMemDescPtr);
+
+#define DevmemAllocate(...) \
+ DevmemSubAllocate(DEVMEM_NO_PRE_ALLOCATE_MULTIPLIER, __VA_ARGS__)
+
+PVRSRV_ERROR
+DevmemAllocateExportable(SHARED_DEV_CONNECTION hDevConnection,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_DEVMEM_ALIGN_T uiAlign,
+ IMG_UINT32 uiLog2HeapPageSize,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ const IMG_CHAR *pszText,
+ DEVMEM_MEMDESC **ppsMemDescPtr);
+
+PVRSRV_ERROR
+DeviceMemChangeSparse(DEVMEM_MEMDESC *psMemDesc,
+ IMG_UINT32 ui32AllocPageCount,
+ IMG_UINT32 *paui32AllocPageIndices,
+ IMG_UINT32 ui32FreePageCount,
+ IMG_UINT32 *pauiFreePageIndices,
+ SPARSE_MEM_RESIZE_FLAGS uiFlags);
+
+PVRSRV_ERROR
+DevmemAllocateSparse(SHARED_DEV_CONNECTION hDevConnection,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_DEVMEM_SIZE_T uiChunkSize,
+ IMG_UINT32 ui32NumPhysChunks,
+ IMG_UINT32 ui32NumVirtChunks,
+ IMG_UINT32 *pui32MappingTable,
+ IMG_DEVMEM_ALIGN_T uiAlign,
+ IMG_UINT32 uiLog2HeapPageSize,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ const IMG_CHAR *pszText,
+ DEVMEM_MEMDESC **ppsMemDescPtr);
+
+PVRSRV_ERROR
+DevmemSubAllocateAndMap(IMG_UINT8 uiPreAllocMultiplier,
+ DEVMEM_HEAP *psHeap,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_DEVMEM_ALIGN_T uiAlign,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ const IMG_CHAR *pszText,
+ DEVMEM_MEMDESC **ppsMemDescPtr,
+ IMG_DEV_VIRTADDR *psDevVirtAddr);
+
+#define DevmemAllocateAndMap(...) \
+ DevmemSubAllocateAndMap(DEVMEM_NO_PRE_ALLOCATE_MULTIPLIER, __VA_ARGS__)
+
+/*
+ * DevmemFree()
+ *
+ * Reverses that done by DevmemSubAllocate() N.B. The underlying
+ * mapping and server side allocation _may_ not be torn down, for
+ * example, if the allocation has been exported, or if multiple
+ * allocations were suballocated from the same mapping, but this is
+ * properly refcounted, so the caller does not have to care.
+ */
+
+IMG_BOOL
+DevmemFree(DEVMEM_MEMDESC *psMemDesc);
+
+IMG_BOOL
+DevmemReleaseDevAddrAndFree(DEVMEM_MEMDESC *psMemDesc);
+
+/*
+ DevmemMapToDevice:
+
+ Map an allocation to the device it was allocated from.
+ This function _must_ be called before any call to
+ DevmemAcquireDevVirtAddr is made as it binds the allocation
+ to the heap.
+ DevmemReleaseDevVirtAddr is used to release the reference
+ to the device mapping this function created, but it doesn't
+ mean that the memory will actually be unmapped from the
+ device as other references to the mapping obtained via
+ DevmemAcquireDevVirtAddr could still be active.
+*/
+PVRSRV_ERROR DevmemMapToDevice(DEVMEM_MEMDESC *psMemDesc,
+ DEVMEM_HEAP *psHeap,
+ IMG_DEV_VIRTADDR *psDevVirtAddr);
+
+/*
+ DevmemMapToDeviceAddress:
+
+ Same as DevmemMapToDevice but the caller chooses the address
+ to map to.
+*/
+IMG_INTERNAL PVRSRV_ERROR
+DevmemMapToDeviceAddress(DEVMEM_MEMDESC *psMemDesc,
+ DEVMEM_HEAP *psHeap,
+ IMG_DEV_VIRTADDR sDevVirtAddr);
+
+/*
+ DevmemGetDevVirtAddr
+
+ Obtain the MemDesc's device virtual address.
+ This function _must_ be called after DevmemMapToDevice(Address)
+ and is expected to be used be functions which didn't allocate
+ the MemDesc but need to know it's address.
+ It will PVR_ASSERT if no device mapping exists and 0 is returned.
+ */
+IMG_DEV_VIRTADDR
+DevmemGetDevVirtAddr(DEVMEM_MEMDESC *psMemDesc);
+
+/*
+ DevmemAcquireDevVirtAddr
+
+ Acquire the MemDesc's device virtual address.
+ This function _must_ be called after DevmemMapToDevice
+ and is expected to be used be functions which didn't allocate
+ the MemDesc but need to know it's address
+ */
+PVRSRV_ERROR DevmemAcquireDevVirtAddr(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEV_VIRTADDR *psDevVirtAddrRet);
+
+/*
+ * DevmemReleaseDevVirtAddr()
+ *
+ * give up the licence to use the device virtual address that was
+ * acquired by "Acquire" or "MapToDevice"
+ */
+void
+DevmemReleaseDevVirtAddr(DEVMEM_MEMDESC *psMemDesc);
+
+/*
+ * DevmemAcquireCpuVirtAddr()
+ *
+ * Acquires a license to use the cpu virtual address of this mapping.
+ * Note that the memory may not have been mapped into cpu virtual
+ * memory prior to this call. On first "acquire" the memory will be
+ * mapped in (if it wasn't statically mapped in) and on last put it
+ * _may_ become unmapped. Later calling "Acquire" again, _may_ cause
+ * the memory to be mapped at a different address.
+ */
+PVRSRV_ERROR DevmemAcquireCpuVirtAddr(DEVMEM_MEMDESC *psMemDesc,
+ void **ppvCpuVirtAddr);
+
+/*
+ * DevmemReacquireCpuVirtAddr()
+ *
+ * (Re)acquires license to use the cpu virtual address of this mapping
+ * if (and only if) there is already a pre-existing license to use the
+ * cpu virtual address for the mapping, returns NULL otherwise.
+ */
+void DevmemReacquireCpuVirtAddr(DEVMEM_MEMDESC *psMemDesc,
+ void **ppvCpuVirtAddr);
+
+/*
+ * DevmemReleaseDevVirtAddr()
+ *
+ * give up the licence to use the cpu virtual address that was granted
+ * with the "Get" call.
+ */
+void
+DevmemReleaseCpuVirtAddr(DEVMEM_MEMDESC *psMemDesc);
+
+#if defined(SUPPORT_INSECURE_EXPORT)
+/*
+ * DevmemExport()
+ *
+ * Given a memory allocation allocated with DevmemAllocateExportable()
+ * create a "cookie" that can be passed intact by the caller's own choice
+ * of secure IPC to another process and used as the argument to "map"
+ * to map this memory into a heap in the target processes. N.B. This can
+ * also be used to map into multiple heaps in one process, though that's not
+ * the intention.
+ *
+ * Note, the caller must later call Unexport before freeing the
+ * memory.
+ */
+PVRSRV_ERROR DevmemExport(DEVMEM_MEMDESC *psMemDesc,
+ DEVMEM_EXPORTCOOKIE *psExportCookie);
+
+
+void DevmemUnexport(DEVMEM_MEMDESC *psMemDesc,
+ DEVMEM_EXPORTCOOKIE *psExportCookie);
+
+PVRSRV_ERROR
+DevmemImport(SHARED_DEV_CONNECTION hDevConnection,
+ DEVMEM_EXPORTCOOKIE *psCookie,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ DEVMEM_MEMDESC **ppsMemDescPtr);
+#endif /* SUPPORT_INSECURE_EXPORT */
+
+/*
+ * DevmemMakeLocalImportHandle()
+ *
+ * This is a "special case" function for making a server export cookie
+ * which went through the direct bridge into an export cookie that can
+ * be passed through the client bridge.
+ */
+PVRSRV_ERROR
+DevmemMakeLocalImportHandle(SHARED_DEV_CONNECTION hDevConnection,
+ IMG_HANDLE hServerExport,
+ IMG_HANDLE *hClientExport);
+
+/*
+ * DevmemUnmakeLocalImportHandle()
+ *
+ * Free any resource associated with the Make operation
+ */
+PVRSRV_ERROR
+DevmemUnmakeLocalImportHandle(SHARED_DEV_CONNECTION hDevConnection,
+ IMG_HANDLE hClientExport);
+
+/*
+ *
+ * The following set of functions is specific to the heap "blueprint"
+ * stuff, for automatic creation of heaps when a context is created
+ *
+ */
+
+
+/* Devmem_HeapConfigCount: returns the number of heap configs that
+ this device has. Note that there is no acquire/release semantics
+ required, as this data is guaranteed to be constant for the
+ lifetime of the device node */
+PVRSRV_ERROR
+DevmemHeapConfigCount(SHARED_DEV_CONNECTION hDevConnection,
+ IMG_UINT32 *puiNumHeapConfigsOut);
+
+/* Devmem_HeapCount: returns the number of heaps that a given heap
+ config on this device has. Note that there is no acquire/release
+ semantics required, as this data is guaranteed to be constant for
+ the lifetime of the device node */
+PVRSRV_ERROR
+DevmemHeapCount(SHARED_DEV_CONNECTION hDevConnection,
+ IMG_UINT32 uiHeapConfigIndex,
+ IMG_UINT32 *puiNumHeapsOut);
+/* Devmem_HeapConfigName: return the name of the given heap config.
+ The caller is to provide the storage for the returned string and
+ indicate the number of bytes (including null terminator) for such
+ string in the BufSz arg. Note that there is no acquire/release
+ semantics required, as this data is guaranteed to be constant for
+ the lifetime of the device node.
+ */
+PVRSRV_ERROR
+DevmemHeapConfigName(SHARED_DEV_CONNECTION hsDevConnection,
+ IMG_UINT32 uiHeapConfigIndex,
+ IMG_CHAR *pszConfigNameOut,
+ IMG_UINT32 uiConfigNameBufSz);
+
+/* Devmem_HeapDetails: fetches all the metadata that is recorded in
+ this heap "blueprint". Namely: heap name (caller to provide
+ storage, and indicate buffer size (including null terminator) in
+ BufSz arg), device virtual address and length, log2 of data page
+ size (will be one of 12, 14, 16, 18, 20, 21, at time of writing).
+ Note that there is no acquire/release semantics required, as this
+ data is guaranteed to be constant for the lifetime of the device
+ node. */
+PVRSRV_ERROR
+DevmemHeapDetails(SHARED_DEV_CONNECTION hDevConnection,
+ IMG_UINT32 uiHeapConfigIndex,
+ IMG_UINT32 uiHeapIndex,
+ IMG_CHAR *pszHeapNameOut,
+ IMG_UINT32 uiHeapNameBufSz,
+ IMG_DEV_VIRTADDR *psDevVAddrBaseOut,
+ IMG_DEVMEM_SIZE_T *puiHeapLengthOut,
+ IMG_DEVMEM_SIZE_T *puiReservedRegionLengthOut,
+ IMG_UINT32 *puiLog2DataPageSize,
+ IMG_UINT32 *puiLog2ImportAlignmentOut);
+
+/*
+ * Devmem_FindHeapByName()
+ *
+ * returns the heap handle for the named _automagic_ heap in this
+ * context. "automagic" heaps are those that are born with the
+ * context from a blueprint
+ */
+PVRSRV_ERROR
+DevmemFindHeapByName(const DEVMEM_CONTEXT *psCtx,
+ const IMG_CHAR *pszHeapName,
+ DEVMEM_HEAP **ppsHeapRet);
+
+/*
+ * DevmemGetHeapBaseDevVAddr()
+ *
+ * returns the device virtual address of the base of the heap.
+ */
+
+PVRSRV_ERROR
+DevmemGetHeapBaseDevVAddr(DEVMEM_HEAP *psHeap,
+ IMG_DEV_VIRTADDR *pDevVAddr);
+
+PVRSRV_ERROR
+DevmemLocalGetImportHandle(DEVMEM_MEMDESC *psMemDesc,
+ IMG_HANDLE *phImport);
+
+PVRSRV_ERROR
+DevmemGetImportUID(DEVMEM_MEMDESC *psMemDesc,
+ IMG_UINT64 *pui64UID);
+
+PVRSRV_ERROR
+DevmemGetReservation(DEVMEM_MEMDESC *psMemDesc,
+ IMG_HANDLE *hReservation);
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetPMRData(DEVMEM_MEMDESC *psMemDesc,
+ IMG_HANDLE *hPMR,
+ IMG_DEVMEM_OFFSET_T *puiPMROffset);
+
+IMG_INTERNAL void
+DevmemGetFlags(DEVMEM_MEMDESC *psMemDesc,
+ PVRSRV_MEMALLOCFLAGS_T *puiFlags);
+
+IMG_INTERNAL SHARED_DEV_CONNECTION
+DevmemGetConnection(DEVMEM_MEMDESC *psMemDesc);
+
+PVRSRV_ERROR
+DevmemLocalImport(SHARED_DEV_CONNECTION hDevConnection,
+ IMG_HANDLE hExtHandle,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ DEVMEM_MEMDESC **ppsMemDescPtr,
+ IMG_DEVMEM_SIZE_T *puiSizePtr,
+ const IMG_CHAR *pszAnnotation);
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemIsDevVirtAddrValid(DEVMEM_CONTEXT *psContext,
+ IMG_DEV_VIRTADDR sDevVAddr);
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemGetFaultAddress(DEVMEM_CONTEXT *psContext,
+ IMG_DEV_VIRTADDR *psFaultAddress);
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemFlushDeviceSLCRange(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_BOOL bInvalidate);
+
+IMG_INTERNAL PVRSRV_ERROR
+DevmemInvalidateFBSCTable(DEVMEM_CONTEXT *psContext,
+ IMG_UINT64 ui64FBSCEntries);
+
+/* DevmemGetHeapLog2PageSize()
+ *
+ * Get the page size used for a certain heap.
+ */
+IMG_UINT32
+DevmemGetHeapLog2PageSize(DEVMEM_HEAP *psHeap);
+
+/* DevmemGetMemFlags()
+ *
+ * Get the memalloc flags for a certain memdesc.
+ */
+PVRSRV_MEMALLOCFLAGS_T
+DevmemGetMemAllocFlags(DEVMEM_MEMDESC *psMemDesc);
+
+/* DevmemGetHeapReservedSize()
+ *
+ * Get the reserved size used for a certain heap.
+ */
+IMG_DEVMEM_SIZE_T
+DevmemGetHeapReservedSize(DEVMEM_HEAP *psHeap);
+
+/*************************************************************************/ /*!
+@Function RegisterDevMemPFNotify
+@Description Registers that the application wants to be signaled when a page
+ fault occurs.
+
+@Input psContext Memory context the process that would like to
+ be notified about.
+@Input ui32PID The PID of the calling process.
+@Input bRegister If true, register. If false, de-register.
+@Return PVRSRV_ERROR: PVRSRV_OK on success. Otherwise, a PVRSRV_
+ error code
+*/ /**************************************************************************/
+IMG_INTERNAL PVRSRV_ERROR
+RegisterDevmemPFNotify(DEVMEM_CONTEXT *psContext,
+ IMG_UINT32 ui32PID,
+ IMG_BOOL bRegister);
+
+/*************************************************************************/ /*!
+@Function DevmemHeapSetPremapStatus
+@Description In some special cases like virtualisation, a device memory heap
+ must be entirely backed by physical memory and mapped into the
+ device's virtual address space. This is done at context creation.
+ When objects are allocated from such a heap, the mapping part
+ must be skipped. The 'bPremapped' flag dictates if allocations
+ are to be mapped or not.
+
+@Input psHeap Device memory heap to be updated
+@Input IsPremapped The premapping status to be set
+*/ /**************************************************************************/
+IMG_INTERNAL void
+DevmemHeapSetPremapStatus(DEVMEM_HEAP *psHeap, IMG_BOOL IsPremapped);
+
+#endif /* #ifndef SRVCLIENT_DEVICEMEM_H */
diff --git a/drivers/gpu/drm/img-rogue/devicemem_heapcfg.c b/drivers/gpu/drm/img-rogue/devicemem_heapcfg.c
new file mode 100644
index 000000000..f38a612cd
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/devicemem_heapcfg.c
@@ -0,0 +1,184 @@
+/*************************************************************************/ /*!
+@File devicemem_heapcfg.c
+@Title Device Heap Configuration Helper Functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Device memory management
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+/* our exported API */
+#include "devicemem_heapcfg.h"
+#include "devicemem_utils.h"
+
+#include "device.h"
+#include "img_types.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+#include "osfunc.h"
+
+#include "connection_server.h"
+
+static INLINE void _CheckBlueprintHeapAlignment(DEVMEM_HEAP_BLUEPRINT *psHeapBlueprint)
+{
+ IMG_UINT32 ui32OSPageSize = OSGetPageShift();
+
+ /* Any heap length should at least match OS page size at the minimum or
+ * a multiple of OS page size */
+ if ((psHeapBlueprint->uiHeapLength < DEVMEM_HEAP_MINIMUM_SIZE) ||
+ (psHeapBlueprint->uiHeapLength & (ui32OSPageSize - 1)))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Invalid Heap \"%s\" Size: "
+ "%"IMG_UINT64_FMTSPEC
+ "("IMG_DEVMEM_SIZE_FMTSPEC")",
+ __func__,
+ psHeapBlueprint->pszName,
+ psHeapBlueprint->uiHeapLength,
+ psHeapBlueprint->uiHeapLength));
+ PVR_DPF((PVR_DBG_ERROR,
+ "Heap Size should always be a non-zero value and a "
+ "multiple of OS Page Size:%u(0x%x)",
+ ui32OSPageSize, ui32OSPageSize));
+ PVR_ASSERT(psHeapBlueprint->uiHeapLength >= ui32OSPageSize);
+ }
+
+
+ PVR_ASSERT(psHeapBlueprint->uiReservedRegionLength % DEVMEM_HEAP_RESERVED_SIZE_GRANULARITY == 0);
+}
+
+void HeapCfgBlueprintInit(const IMG_CHAR *pszName,
+ IMG_UINT64 ui64HeapBaseAddr,
+ IMG_DEVMEM_SIZE_T uiHeapLength,
+ IMG_DEVMEM_SIZE_T uiReservedRegionLength,
+ IMG_UINT32 ui32Log2DataPageSize,
+ IMG_UINT32 uiLog2ImportAlignment,
+ DEVMEM_HEAP_BLUEPRINT *psHeapBlueprint)
+{
+ psHeapBlueprint->pszName = pszName;
+ psHeapBlueprint->sHeapBaseAddr.uiAddr = ui64HeapBaseAddr;
+ psHeapBlueprint->uiHeapLength = uiHeapLength;
+ psHeapBlueprint->uiReservedRegionLength = uiReservedRegionLength;
+ psHeapBlueprint->uiLog2DataPageSize = ui32Log2DataPageSize;
+ psHeapBlueprint->uiLog2ImportAlignment = uiLog2ImportAlignment;
+
+ _CheckBlueprintHeapAlignment(psHeapBlueprint);
+}
+
+PVRSRV_ERROR
+HeapCfgHeapConfigCount(CONNECTION_DATA * psConnection,
+ const PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 *puiNumHeapConfigsOut)
+{
+
+ PVR_UNREFERENCED_PARAMETER(psConnection);
+
+ *puiNumHeapConfigsOut = psDeviceNode->sDevMemoryInfo.uiNumHeapConfigs;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+HeapCfgHeapCount(CONNECTION_DATA * psConnection,
+ const PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 uiHeapConfigIndex,
+ IMG_UINT32 *puiNumHeapsOut)
+{
+ if (uiHeapConfigIndex >= psDeviceNode->sDevMemoryInfo.uiNumHeapConfigs)
+ {
+ return PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_CONFIG_INDEX;
+ }
+
+ *puiNumHeapsOut = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeapConfigArray[uiHeapConfigIndex].uiNumHeaps;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+HeapCfgHeapConfigName(CONNECTION_DATA * psConnection,
+ const PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 uiHeapConfigIndex,
+ IMG_UINT32 uiHeapConfigNameBufSz,
+ IMG_CHAR *pszHeapConfigNameOut)
+{
+ if (uiHeapConfigIndex >= psDeviceNode->sDevMemoryInfo.uiNumHeapConfigs)
+ {
+ return PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_CONFIG_INDEX;
+ }
+
+ OSSNPrintf(pszHeapConfigNameOut, uiHeapConfigNameBufSz, "%s", psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeapConfigArray[uiHeapConfigIndex].pszName);
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+HeapCfgHeapDetails(CONNECTION_DATA * psConnection,
+ const PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 uiHeapConfigIndex,
+ IMG_UINT32 uiHeapIndex,
+ IMG_UINT32 uiHeapNameBufSz,
+ IMG_CHAR *pszHeapNameOut,
+ IMG_DEV_VIRTADDR *psDevVAddrBaseOut,
+ IMG_DEVMEM_SIZE_T *puiHeapLengthOut,
+ IMG_DEVMEM_SIZE_T *puiReservedRegionLengthOut,
+ IMG_UINT32 *puiLog2DataPageSizeOut,
+ IMG_UINT32 *puiLog2ImportAlignmentOut)
+{
+ DEVMEM_HEAP_BLUEPRINT *psHeapBlueprint;
+
+ if (uiHeapConfigIndex >= psDeviceNode->sDevMemoryInfo.uiNumHeapConfigs)
+ {
+ return PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_CONFIG_INDEX;
+ }
+
+ if (uiHeapIndex >= psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeapConfigArray[uiHeapConfigIndex].uiNumHeaps)
+ {
+ return PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_INDEX;
+ }
+
+ psHeapBlueprint = &psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeapConfigArray[uiHeapConfigIndex].psHeapBlueprintArray[uiHeapIndex];
+
+ OSSNPrintf(pszHeapNameOut, uiHeapNameBufSz, "%s", psHeapBlueprint->pszName);
+ *psDevVAddrBaseOut = psHeapBlueprint->sHeapBaseAddr;
+ *puiHeapLengthOut = psHeapBlueprint->uiHeapLength;
+ *puiReservedRegionLengthOut = psHeapBlueprint->uiReservedRegionLength;
+ *puiLog2DataPageSizeOut = psHeapBlueprint->uiLog2DataPageSize;
+ *puiLog2ImportAlignmentOut = psHeapBlueprint->uiLog2ImportAlignment;
+
+ return PVRSRV_OK;
+}
diff --git a/drivers/gpu/drm/img-rogue/devicemem_heapcfg.h b/drivers/gpu/drm/img-rogue/devicemem_heapcfg.h
new file mode 100644
index 000000000..3b032ae60
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/devicemem_heapcfg.h
@@ -0,0 +1,184 @@
+/**************************************************************************/ /*!
+@File
+@Title Device Heap Configuration Helper Functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Device memory management
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#ifndef DEVICEMEMHEAPCFG_H
+#define DEVICEMEMHEAPCFG_H
+
+#include
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+/*
+ * Supported log2 page size values for RGX_GENERAL_NON_4K_HEAP_ID
+ */
+#define RGX_HEAP_4KB_PAGE_SHIFT (12U)
+#define RGX_HEAP_16KB_PAGE_SHIFT (14U)
+#define RGX_HEAP_64KB_PAGE_SHIFT (16U)
+#define RGX_HEAP_256KB_PAGE_SHIFT (18U)
+#define RGX_HEAP_1MB_PAGE_SHIFT (20U)
+#define RGX_HEAP_2MB_PAGE_SHIFT (21U)
+
+struct _PVRSRV_DEVICE_NODE_;
+struct _CONNECTION_DATA_;
+
+
+/*
+ A "heap config" is a blueprint to be used for initial setting up of heaps
+ when a device memory context is created.
+
+ We define a data structure to define this, but it's really down to the
+ caller to populate it. This is all expected to be in-kernel. We provide an
+ API that client code can use to enquire about the blueprint, such that it may
+ do the heap set-up during the context creation call on behalf of the user.
+*/
+
+/* Blueprint for a single heap */
+typedef struct _DEVMEM_HEAP_BLUEPRINT_
+{
+ /* Name of this heap - for debug purposes, and perhaps for lookup
+ by name */
+ const IMG_CHAR *pszName;
+
+ /* Virtual address of the beginning of the heap. This _must_ be a
+ multiple of the data page size for the heap. It is
+ _recommended_ that it be coarser than that - especially, it
+ should begin on a boundary appropriate to the MMU for the
+ device. For Rogue, this is a Page Directory boundary, or 1GB
+ (virtual address a multiple of 0x0040000000). */
+ IMG_DEV_VIRTADDR sHeapBaseAddr;
+
+ /* Length of the heap. Given that the END address of the heap has
+ a similar restriction to that of the _beginning_ of the heap.
+ That is the heap length _must_ be a whole number of data pages.
+ Again, the recommendation is that it ends on a 1GB boundary.
+ Again, this is not essential, but we do know that (at the time
+ of writing) the current implementation of mmu_common.c is such
+ that no two heaps may share a page directory, thus the
+ remaining virtual space would be wasted if the length were not
+ a multiple of 1GB */
+ IMG_DEVMEM_SIZE_T uiHeapLength;
+
+ /* VA space starting sHeapBaseAddr to uiReservedRegionLength-1 are reserved
+ for statically defined addresses (shared/known between clients and FW).
+ Services never maps allocations into this reserved address space _unless_
+ explicitly requested via PVRSRVMapToDeviceAddress by passing sDevVirtAddr
+ which falls within this reserved range. Since this range is completely for
+ clients to manage (where allocations are page granular), it _must_ again be
+ a whole number of data pages. Additionally, another constraint enforces this
+ to be a multiple of DEVMEM_HEAP_RESERVED_SIZE_GRANULARITY (which evaluates to
+ max page size supported) to support varied pages sizes */
+ IMG_DEVMEM_SIZE_T uiReservedRegionLength;
+
+ /* Data page size. This is the page size that is going to get
+ programmed into the MMU, so it needs to be a valid one for the
+ device. Importantly, the start address and length _must_ be
+ multiples of this page size. Note that the page size is
+ specified as the log 2 relative to 1 byte (e.g. 12 indicates
+ 4kB) */
+ IMG_UINT32 uiLog2DataPageSize;
+
+ /* Import alignment. Force imports to this heap to be
+ aligned to at least this value */
+ IMG_UINT32 uiLog2ImportAlignment;
+
+} DEVMEM_HEAP_BLUEPRINT;
+
+void HeapCfgBlueprintInit(const IMG_CHAR *pszName,
+ IMG_UINT64 ui64HeapBaseAddr,
+ IMG_DEVMEM_SIZE_T uiHeapLength,
+ IMG_DEVMEM_SIZE_T uiReservedRegionLength,
+ IMG_UINT32 ui32Log2DataPageSize,
+ IMG_UINT32 uiLog2ImportAlignment,
+ DEVMEM_HEAP_BLUEPRINT *psHeapBlueprint);
+
+/* Entire named heap config */
+typedef struct _DEVMEM_HEAP_CONFIG_
+{
+ /* Name of this heap config - for debug and maybe lookup */
+ const IMG_CHAR *pszName;
+
+ /* Number of heaps in this config */
+ IMG_UINT32 uiNumHeaps;
+
+ /* Array of individual heap blueprints as defined above */
+ DEVMEM_HEAP_BLUEPRINT *psHeapBlueprintArray;
+} DEVMEM_HEAP_CONFIG;
+
+
+PVRSRV_ERROR
+HeapCfgHeapConfigCount(struct _CONNECTION_DATA_ *psConnection,
+ const struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+ IMG_UINT32 *puiNumHeapConfigsOut
+);
+
+PVRSRV_ERROR
+HeapCfgHeapCount(struct _CONNECTION_DATA_ *psConnection,
+ const struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+ IMG_UINT32 uiHeapConfigIndex,
+ IMG_UINT32 *puiNumHeapsOut
+);
+
+PVRSRV_ERROR
+HeapCfgHeapConfigName(struct _CONNECTION_DATA_ *psConnection,
+ const struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+ IMG_UINT32 uiHeapConfigIndex,
+ IMG_UINT32 uiHeapConfigNameBufSz,
+ IMG_CHAR *pszHeapConfigNameOut
+);
+
+PVRSRV_ERROR
+HeapCfgHeapDetails(struct _CONNECTION_DATA_ *psConnection,
+ const struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
+ IMG_UINT32 uiHeapConfigIndex,
+ IMG_UINT32 uiHeapIndex,
+ IMG_UINT32 uiHeapNameBufSz,
+ IMG_CHAR *pszHeapNameOut,
+ IMG_DEV_VIRTADDR *psDevVAddrBaseOut,
+ IMG_DEVMEM_SIZE_T *puiHeapLengthOut,
+ IMG_DEVMEM_SIZE_T *puiReservedRegionLengthOut,
+ IMG_UINT32 *puiLog2DataPageSizeOut,
+ IMG_UINT32 *puiLog2ImportAlignmentOut
+);
+
+#endif
diff --git a/drivers/gpu/drm/img-rogue/devicemem_history_server.c b/drivers/gpu/drm/img-rogue/devicemem_history_server.c
new file mode 100644
index 000000000..412a51b32
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/devicemem_history_server.c
@@ -0,0 +1,1962 @@
+/*************************************************************************/ /*!
+@File
+@Title Devicemem history functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Devicemem history functions
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "allocmem.h"
+#include "img_defs.h"
+#include "pmr.h"
+#include "pvrsrv.h"
+#include "pvrsrv_device.h"
+#include "pvr_debug.h"
+#include "devicemem_server.h"
+#include "lock.h"
+#include "devicemem_history_server.h"
+#include "pdump_km.h"
+#include "di_server.h"
+
+#define ALLOCATION_LIST_NUM_ENTRIES 10000
+
+/* data type to hold an allocation index.
+ * we make it 16 bits wide if possible
+ */
+#if ALLOCATION_LIST_NUM_ENTRIES <= 0xFFFF
+typedef uint16_t ALLOC_INDEX_T;
+#else
+typedef uint32_t ALLOC_INDEX_T;
+#endif
+
+/* a record describing a single allocation known to DeviceMemHistory.
+ * this is an element in a doubly linked list of allocations
+ */
+typedef struct _RECORD_ALLOCATION_
+{
+ /* time when this RECORD_ALLOCATION was created/initialised */
+ IMG_UINT64 ui64CreationTime;
+ /* serial number of the PMR relating to this allocation */
+ IMG_UINT64 ui64Serial;
+ /* base DevVAddr of this allocation */
+ IMG_DEV_VIRTADDR sDevVAddr;
+ /* size in bytes of this allocation */
+ IMG_DEVMEM_SIZE_T uiSize;
+ /* Log2 page size of this allocation's GPU pages */
+ IMG_UINT32 ui32Log2PageSize;
+ /* Process ID (PID) this allocation belongs to */
+ IMG_PID uiPID;
+ /* index of previous allocation in the list */
+ ALLOC_INDEX_T ui32Prev;
+ /* index of next allocation in the list */
+ ALLOC_INDEX_T ui32Next;
+ /* annotation/name of this allocation */
+ IMG_CHAR szName[DEVMEM_ANNOTATION_MAX_LEN];
+} RECORD_ALLOCATION;
+
+/* each command in the circular buffer is prefixed with an 8-bit value
+ * denoting the command type
+ */
+typedef enum _COMMAND_TYPE_
+{
+ COMMAND_TYPE_NONE,
+ COMMAND_TYPE_TIMESTAMP,
+ COMMAND_TYPE_MAP_ALL,
+ COMMAND_TYPE_UNMAP_ALL,
+ COMMAND_TYPE_MAP_RANGE,
+ COMMAND_TYPE_UNMAP_RANGE,
+ /* sentinel value */
+ COMMAND_TYPE_COUNT,
+} COMMAND_TYPE;
+
+/* Timestamp command:
+ * This command is inserted into the circular buffer to provide an updated
+ * timestamp.
+ * The nanosecond-accuracy timestamp is packed into a 56-bit integer, in order
+ * for the whole command to fit into 8 bytes.
+ */
+typedef struct _COMMAND_TIMESTAMP_
+{
+ IMG_UINT8 aui8TimeNs[7];
+} COMMAND_TIMESTAMP;
+
+/* MAP_ALL command:
+ * This command denotes the allocation at the given index was wholly mapped
+ * in to the GPU MMU
+ */
+typedef struct _COMMAND_MAP_ALL_
+{
+ ALLOC_INDEX_T uiAllocIndex;
+} COMMAND_MAP_ALL;
+
+/* UNMAP_ALL command:
+ * This command denotes the allocation at the given index was wholly unmapped
+ * from the GPU MMU
+ * Note: COMMAND_MAP_ALL and COMMAND_UNMAP_ALL commands have the same layout.
+ */
+typedef COMMAND_MAP_ALL COMMAND_UNMAP_ALL;
+
+/* packing attributes for the MAP_RANGE command */
+#define MAP_RANGE_MAX_START ((1 << 18) - 1)
+#define MAP_RANGE_MAX_RANGE ((1 << 12) - 1)
+
+/* MAP_RANGE command:
+ * Denotes a range of pages within the given allocation being mapped.
+ * The range is expressed as [Page Index] + [Page Count]
+ * This information is packed into a 40-bit integer, in order to make
+ * the command size 8 bytes.
+ */
+
+typedef struct _COMMAND_MAP_RANGE_
+{
+ IMG_UINT8 aui8Data[5];
+ ALLOC_INDEX_T uiAllocIndex;
+} COMMAND_MAP_RANGE;
+
+/* UNMAP_RANGE command:
+ * Denotes a range of pages within the given allocation being mapped.
+ * The range is expressed as [Page Index] + [Page Count]
+ * This information is packed into a 40-bit integer, in order to make
+ * the command size 8 bytes.
+ * Note: COMMAND_MAP_RANGE and COMMAND_UNMAP_RANGE commands have the same layout.
+ */
+typedef COMMAND_MAP_RANGE COMMAND_UNMAP_RANGE;
+
+/* wrapper structure for a command */
+typedef struct _COMMAND_WRAPPER_
+{
+ IMG_UINT8 ui8Type;
+ union {
+ COMMAND_TIMESTAMP sTimeStamp;
+ COMMAND_MAP_ALL sMapAll;
+ COMMAND_UNMAP_ALL sUnmapAll;
+ COMMAND_MAP_RANGE sMapRange;
+ COMMAND_UNMAP_RANGE sUnmapRange;
+ } u;
+} COMMAND_WRAPPER;
+
+/* target size for the circular buffer of commands */
+#define CIRCULAR_BUFFER_SIZE_KB 2048
+/* turn the circular buffer target size into a number of commands */
+#define CIRCULAR_BUFFER_NUM_COMMANDS ((CIRCULAR_BUFFER_SIZE_KB * 1024) / sizeof(COMMAND_WRAPPER))
+
+/* index value denoting the end of a list */
+#define END_OF_LIST 0xFFFFFFFF
+#define ALLOC_INDEX_TO_PTR(idx) (&(gsDevicememHistoryData.sRecords.pasAllocations[idx]))
+#define CHECK_ALLOC_INDEX(idx) (idx < ALLOCATION_LIST_NUM_ENTRIES)
+
+/* wrapper structure for the allocation records and the commands circular buffer */
+typedef struct _RECORDS_
+{
+ RECORD_ALLOCATION *pasAllocations;
+ IMG_UINT32 ui32AllocationsListHead;
+
+ IMG_UINT32 ui32Head;
+ IMG_UINT32 ui32Tail;
+ COMMAND_WRAPPER *pasCircularBuffer;
+} RECORDS;
+
+typedef struct _DEVICEMEM_HISTORY_DATA_
+{
+ /* DI entry */
+ DI_ENTRY *psDIEntry;
+
+ RECORDS sRecords;
+ POS_LOCK hLock;
+} DEVICEMEM_HISTORY_DATA;
+
+static DEVICEMEM_HISTORY_DATA gsDevicememHistoryData;
+
+/* gsDevicememHistoryData is static, hLock is NULL unless
+ * EnablePageFaultDebug is set and DevicememHistoryInitKM()
+ * was called.
+ */
+static void DevicememHistoryLock(void)
+{
+ if (gsDevicememHistoryData.hLock)
+ {
+ OSLockAcquire(gsDevicememHistoryData.hLock);
+ }
+}
+
+static void DevicememHistoryUnlock(void)
+{
+ if (gsDevicememHistoryData.hLock)
+ {
+ OSLockRelease(gsDevicememHistoryData.hLock);
+ }
+}
+
+/* given a time stamp, calculate the age in nanoseconds */
+static IMG_UINT64 _CalculateAge(IMG_UINT64 ui64Now,
+ IMG_UINT64 ui64Then,
+ IMG_UINT64 ui64Max)
+{
+ if (ui64Now >= ui64Then)
+ {
+ /* no clock wrap */
+ return ui64Now - ui64Then;
+ }
+ else
+ {
+ /* clock has wrapped */
+ return (ui64Max - ui64Then) + ui64Now + 1;
+ }
+}
+
+/* AcquireCBSlot:
+ * Acquire the next slot in the circular buffer and
+ * move the circular buffer head along by one
+ * Returns a pointer to the acquired slot.
+ */
+static COMMAND_WRAPPER *AcquireCBSlot(void)
+{
+ COMMAND_WRAPPER *psSlot;
+
+ psSlot = &gsDevicememHistoryData.sRecords.pasCircularBuffer[gsDevicememHistoryData.sRecords.ui32Head];
+
+ gsDevicememHistoryData.sRecords.ui32Head =
+ (gsDevicememHistoryData.sRecords.ui32Head + 1)
+ % CIRCULAR_BUFFER_NUM_COMMANDS;
+
+ return psSlot;
+}
+
+/* TimeStampPack:
+ * Packs the given timestamp value into the COMMAND_TIMESTAMP structure.
+ * This takes a 64-bit nanosecond timestamp and packs it in to a 56-bit
+ * integer in the COMMAND_TIMESTAMP command.
+ */
+static void TimeStampPack(COMMAND_TIMESTAMP *psTimeStamp, IMG_UINT64 ui64Now)
+{
+ IMG_UINT32 i;
+
+ for (i = 0; i < ARRAY_SIZE(psTimeStamp->aui8TimeNs); i++)
+ {
+ psTimeStamp->aui8TimeNs[i] = ui64Now & 0xFF;
+ ui64Now >>= 8;
+ }
+}
+
+/* packing a 64-bit nanosecond into a 7-byte integer loses the
+ * top 8 bits of data. This must be taken into account when
+ * comparing a full timestamp against an unpacked timestamp
+ */
+#define TIME_STAMP_MASK ((1LLU << 56) - 1)
+#define DO_TIME_STAMP_MASK(ns64) (ns64 & TIME_STAMP_MASK)
+
+/* TimeStampUnpack:
+ * Unpack the timestamp value from the given COMMAND_TIMESTAMP command
+ */
+static IMG_UINT64 TimeStampUnpack(COMMAND_TIMESTAMP *psTimeStamp)
+{
+ IMG_UINT64 ui64TimeNs = 0;
+ IMG_UINT32 i;
+
+ for (i = ARRAY_SIZE(psTimeStamp->aui8TimeNs); i > 0; i--)
+ {
+ ui64TimeNs <<= 8;
+ ui64TimeNs |= (IMG_UINT64) psTimeStamp->aui8TimeNs[i - 1];
+ }
+
+ return ui64TimeNs;
+}
+
+#if defined(PDUMP)
+
+static void EmitPDumpAllocation(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 ui32AllocationIndex,
+ RECORD_ALLOCATION *psAlloc)
+{
+ PDUMPCOMMENT(psDeviceNode,
+ "[SrvPFD] Allocation: %u"
+ " Addr: " IMG_DEV_VIRTADDR_FMTSPEC
+ " Size: " IMG_DEVMEM_SIZE_FMTSPEC
+ " Page size: %u"
+ " PID: %u"
+ " Process: %s"
+ " Name: %s",
+ ui32AllocationIndex,
+ psAlloc->sDevVAddr.uiAddr,
+ psAlloc->uiSize,
+ 1U << psAlloc->ui32Log2PageSize,
+ psAlloc->uiPID,
+ OSGetCurrentClientProcessNameKM(),
+ psAlloc->szName);
+}
+
+static void EmitPDumpMapUnmapAll(PVRSRV_DEVICE_NODE *psDeviceNode,
+ COMMAND_TYPE eType,
+ IMG_UINT32 ui32AllocationIndex)
+{
+ const IMG_CHAR *pszOpName;
+
+ switch (eType)
+ {
+ case COMMAND_TYPE_MAP_ALL:
+ pszOpName = "MAP_ALL";
+ break;
+ case COMMAND_TYPE_UNMAP_ALL:
+ pszOpName = "UNMAP_ALL";
+ break;
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "EmitPDumpMapUnmapAll: Invalid type: %u",
+ eType));
+ return;
+
+ }
+
+ PDUMPCOMMENT(psDeviceNode,
+ "[SrvPFD] Op: %s Allocation: %u",
+ pszOpName,
+ ui32AllocationIndex);
+}
+
+static void EmitPDumpMapUnmapRange(PVRSRV_DEVICE_NODE *psDeviceNode,
+ COMMAND_TYPE eType,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 ui32StartPage,
+ IMG_UINT32 ui32Count)
+{
+ const IMG_CHAR *pszOpName;
+
+ switch (eType)
+ {
+ case COMMAND_TYPE_MAP_RANGE:
+ pszOpName = "MAP_RANGE";
+ break;
+ case COMMAND_TYPE_UNMAP_RANGE:
+ pszOpName = "UNMAP_RANGE";
+ break;
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "EmitPDumpMapUnmapRange: Invalid type: %u",
+ eType));
+ return;
+ }
+
+ PDUMPCOMMENT(psDeviceNode,
+ "[SrvPFD] Op: %s Allocation: %u Start Page: %u Count: %u",
+ pszOpName,
+ ui32AllocationIndex,
+ ui32StartPage,
+ ui32Count);
+}
+
+#endif
+
+/* InsertTimeStampCommand:
+ * Insert a timestamp command into the circular buffer.
+ */
+static void InsertTimeStampCommand(IMG_UINT64 ui64Now)
+{
+ COMMAND_WRAPPER *psCommand;
+
+ psCommand = AcquireCBSlot();
+
+ psCommand->ui8Type = COMMAND_TYPE_TIMESTAMP;
+
+ TimeStampPack(&psCommand->u.sTimeStamp, ui64Now);
+}
+
+/* InsertMapAllCommand:
+ * Insert a "MAP_ALL" command for the given allocation into the circular buffer
+ */
+static void InsertMapAllCommand(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 ui32AllocIndex)
+{
+ COMMAND_WRAPPER *psCommand;
+
+ psCommand = AcquireCBSlot();
+
+ psCommand->ui8Type = COMMAND_TYPE_MAP_ALL;
+ psCommand->u.sMapAll.uiAllocIndex = ui32AllocIndex;
+
+#if defined(PDUMP)
+ EmitPDumpMapUnmapAll(psDeviceNode, COMMAND_TYPE_MAP_ALL, ui32AllocIndex);
+#else
+ PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+#endif
+}
+
+/* InsertUnmapAllCommand:
+ * Insert a "UNMAP_ALL" command for the given allocation into the circular buffer
+ */
+static void InsertUnmapAllCommand(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 ui32AllocIndex)
+{
+ COMMAND_WRAPPER *psCommand;
+
+ psCommand = AcquireCBSlot();
+
+ psCommand->ui8Type = COMMAND_TYPE_UNMAP_ALL;
+ psCommand->u.sUnmapAll.uiAllocIndex = ui32AllocIndex;
+
+#if defined(PDUMP)
+ EmitPDumpMapUnmapAll(psDeviceNode, COMMAND_TYPE_UNMAP_ALL, ui32AllocIndex);
+#else
+ PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+#endif
+}
+
+/* MapRangePack:
+ * Pack the given StartPage and Count values into the 40-bit representation
+ * in the MAP_RANGE command.
+ */
+static void MapRangePack(COMMAND_MAP_RANGE *psMapRange,
+ IMG_UINT32 ui32StartPage,
+ IMG_UINT32 ui32Count)
+{
+ IMG_UINT64 ui64Data;
+ IMG_UINT32 i;
+
+ /* we must encode the data into 40 bits:
+ * 18 bits for the start page index
+ * 12 bits for the range
+ */
+ PVR_ASSERT(ui32StartPage <= MAP_RANGE_MAX_START);
+ PVR_ASSERT(ui32Count <= MAP_RANGE_MAX_RANGE);
+
+ ui64Data = (((IMG_UINT64) ui32StartPage) << 12) | ui32Count;
+
+ for (i = 0; i < ARRAY_SIZE(psMapRange->aui8Data); i++)
+ {
+ psMapRange->aui8Data[i] = ui64Data & 0xFF;
+ ui64Data >>= 8;
+ }
+}
+
+/* MapRangePack:
+ * Unpack the StartPage and Count values from the 40-bit representation
+ * in the MAP_RANGE command.
+ */
+static void MapRangeUnpack(COMMAND_MAP_RANGE *psMapRange,
+ IMG_UINT32 *pui32StartPage,
+ IMG_UINT32 *pui32Count)
+{
+ IMG_UINT64 ui64Data = 0;
+ IMG_UINT32 i;
+
+ for (i = ARRAY_SIZE(psMapRange->aui8Data); i > 0; i--)
+ {
+ ui64Data <<= 8;
+ ui64Data |= (IMG_UINT64) psMapRange->aui8Data[i - 1];
+ }
+
+ *pui32StartPage = (ui64Data >> 12);
+ *pui32Count = ui64Data & ((1 << 12) - 1);
+}
+
+/* InsertMapRangeCommand:
+ * Insert a MAP_RANGE command into the circular buffer with the given
+ * StartPage and Count values.
+ */
+static void InsertMapRangeCommand(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 ui32AllocIndex,
+ IMG_UINT32 ui32StartPage,
+ IMG_UINT32 ui32Count)
+{
+ COMMAND_WRAPPER *psCommand;
+
+ psCommand = AcquireCBSlot();
+
+ psCommand->ui8Type = COMMAND_TYPE_MAP_RANGE;
+ psCommand->u.sMapRange.uiAllocIndex = ui32AllocIndex;
+
+ MapRangePack(&psCommand->u.sMapRange, ui32StartPage, ui32Count);
+
+#if defined(PDUMP)
+ EmitPDumpMapUnmapRange(psDeviceNode,
+ COMMAND_TYPE_MAP_RANGE,
+ ui32AllocIndex,
+ ui32StartPage,
+ ui32Count);
+#else
+ PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+#endif
+}
+
+/* InsertUnmapRangeCommand:
+ * Insert a UNMAP_RANGE command into the circular buffer with the given
+ * StartPage and Count values.
+ */
+static void InsertUnmapRangeCommand(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 ui32AllocIndex,
+ IMG_UINT32 ui32StartPage,
+ IMG_UINT32 ui32Count)
+{
+ COMMAND_WRAPPER *psCommand;
+
+ psCommand = AcquireCBSlot();
+
+ psCommand->ui8Type = COMMAND_TYPE_UNMAP_RANGE;
+ psCommand->u.sMapRange.uiAllocIndex = ui32AllocIndex;
+
+ MapRangePack(&psCommand->u.sMapRange, ui32StartPage, ui32Count);
+
+#if defined(PDUMP)
+ EmitPDumpMapUnmapRange(psDeviceNode,
+ COMMAND_TYPE_UNMAP_RANGE,
+ ui32AllocIndex,
+ ui32StartPage,
+ ui32Count);
+#else
+ PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+#endif
+}
+
+/* InsertAllocationToList:
+ * Helper function for the allocation list.
+ * Inserts the given allocation at the head of the list, whose current head is
+ * pointed to by pui32ListHead
+ */
+static void InsertAllocationToList(IMG_UINT32 *pui32ListHead, IMG_UINT32 ui32Alloc)
+{
+ RECORD_ALLOCATION *psAlloc;
+
+ psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc);
+
+ if (*pui32ListHead == END_OF_LIST)
+ {
+ /* list is currently empty, so just replace it */
+ *pui32ListHead = ui32Alloc;
+ psAlloc->ui32Next = psAlloc->ui32Prev = *pui32ListHead;
+ }
+ else
+ {
+ RECORD_ALLOCATION *psHeadAlloc;
+ RECORD_ALLOCATION *psTailAlloc;
+
+ psHeadAlloc = ALLOC_INDEX_TO_PTR(*pui32ListHead);
+ psTailAlloc = ALLOC_INDEX_TO_PTR(psHeadAlloc->ui32Prev);
+
+ /* make the new alloc point forwards to the previous head */
+ psAlloc->ui32Next = *pui32ListHead;
+ /* make the new alloc point backwards to the previous tail */
+ psAlloc->ui32Prev = psHeadAlloc->ui32Prev;
+
+ /* the head is now our new alloc */
+ *pui32ListHead = ui32Alloc;
+
+ /* the old head now points back to the new head */
+ psHeadAlloc->ui32Prev = *pui32ListHead;
+
+ /* the tail now points forward to the new head */
+ psTailAlloc->ui32Next = ui32Alloc;
+ }
+}
+
+static void InsertAllocationToBusyList(IMG_UINT32 ui32Alloc)
+{
+ InsertAllocationToList(&gsDevicememHistoryData.sRecords.ui32AllocationsListHead, ui32Alloc);
+}
+
+/* RemoveAllocationFromList:
+ * Helper function for the allocation list.
+ * Removes the given allocation from the list, whose head is
+ * pointed to by pui32ListHead
+ */
+static void RemoveAllocationFromList(IMG_UINT32 *pui32ListHead, IMG_UINT32 ui32Alloc)
+{
+ RECORD_ALLOCATION *psAlloc;
+
+ psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc);
+
+ /* if this is the only element in the list then just make the list empty */
+ if ((*pui32ListHead == ui32Alloc) && (psAlloc->ui32Next == ui32Alloc))
+ {
+ *pui32ListHead = END_OF_LIST;
+ }
+ else
+ {
+ RECORD_ALLOCATION *psPrev, *psNext;
+
+ psPrev = ALLOC_INDEX_TO_PTR(psAlloc->ui32Prev);
+ psNext = ALLOC_INDEX_TO_PTR(psAlloc->ui32Next);
+
+ /* remove the allocation from the list */
+ psPrev->ui32Next = psAlloc->ui32Next;
+ psNext->ui32Prev = psAlloc->ui32Prev;
+
+ /* if this allocation is the head then update the head */
+ if (*pui32ListHead == ui32Alloc)
+ {
+ *pui32ListHead = psAlloc->ui32Prev;
+ }
+ }
+}
+
+static void RemoveAllocationFromBusyList(IMG_UINT32 ui32Alloc)
+{
+ RemoveAllocationFromList(&gsDevicememHistoryData.sRecords.ui32AllocationsListHead, ui32Alloc);
+}
+
+/* TouchBusyAllocation:
+ * Move the given allocation to the head of the list
+ */
+static void TouchBusyAllocation(IMG_UINT32 ui32Alloc)
+{
+ RemoveAllocationFromBusyList(ui32Alloc);
+ InsertAllocationToBusyList(ui32Alloc);
+}
+
+/* GetOldestBusyAllocation:
+ * Returns the index of the oldest allocation in the MRU list
+ */
+static IMG_UINT32 GetOldestBusyAllocation(void)
+{
+ IMG_UINT32 ui32Alloc;
+ RECORD_ALLOCATION *psAlloc;
+
+ ui32Alloc = gsDevicememHistoryData.sRecords.ui32AllocationsListHead;
+
+ if (ui32Alloc == END_OF_LIST)
+ {
+ return END_OF_LIST;
+ }
+
+ psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc);
+
+ return psAlloc->ui32Prev;
+}
+
+static IMG_UINT32 GetFreeAllocation(void)
+{
+ IMG_UINT32 ui32Alloc;
+
+ ui32Alloc = GetOldestBusyAllocation();
+
+ return ui32Alloc;
+}
+
+
+/* InitialiseAllocation:
+ * Initialise the given allocation structure with the given properties
+ */
+static void InitialiseAllocation(RECORD_ALLOCATION *psAlloc,
+ const IMG_CHAR *pszName,
+ IMG_UINT64 ui64Serial,
+ IMG_PID uiPID,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_UINT32 ui32Log2PageSize)
+{
+ OSStringLCopy(psAlloc->szName, pszName, sizeof(psAlloc->szName));
+ psAlloc->ui64Serial = ui64Serial;
+ psAlloc->uiPID = uiPID;
+ psAlloc->sDevVAddr = sDevVAddr;
+ psAlloc->uiSize = uiSize;
+ psAlloc->ui32Log2PageSize = ui32Log2PageSize;
+ psAlloc->ui64CreationTime = OSClockns64();
+}
+
+/* CreateAllocation:
+ * Creates a new allocation with the given properties then outputs the
+ * index of the allocation
+ */
+static PVRSRV_ERROR CreateAllocation(PVRSRV_DEVICE_NODE *psDeviceNode,
+ const IMG_CHAR *pszName,
+ IMG_UINT64 ui64Serial,
+ IMG_PID uiPID,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_BOOL bAutoPurge,
+ IMG_UINT32 *puiAllocationIndex)
+{
+ IMG_UINT32 ui32Alloc;
+ RECORD_ALLOCATION *psAlloc;
+
+ ui32Alloc = GetFreeAllocation();
+
+ psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc);
+
+ InitialiseAllocation(ALLOC_INDEX_TO_PTR(ui32Alloc),
+ pszName,
+ ui64Serial,
+ uiPID,
+ sDevVAddr,
+ uiSize,
+ ui32Log2PageSize);
+
+ /* put the newly initialised allocation at the front of the MRU list */
+ TouchBusyAllocation(ui32Alloc);
+
+ *puiAllocationIndex = ui32Alloc;
+
+#if defined(PDUMP)
+ EmitPDumpAllocation(psDeviceNode, ui32Alloc, psAlloc);
+#else
+ PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+#endif
+
+ return PVRSRV_OK;
+}
+
+/* MatchAllocation:
+ * Tests if the allocation at the given index matches the supplied properties.
+ * Returns IMG_TRUE if it is a match, otherwise IMG_FALSE.
+ */
+static IMG_BOOL MatchAllocation(IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT64 ui64Serial,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ const IMG_CHAR *pszName,
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_PID uiPID)
+{
+ RECORD_ALLOCATION *psAlloc;
+
+ psAlloc = ALLOC_INDEX_TO_PTR(ui32AllocationIndex);
+
+ return (psAlloc->ui64Serial == ui64Serial) &&
+ (psAlloc->sDevVAddr.uiAddr == sDevVAddr.uiAddr) &&
+ (psAlloc->uiSize == uiSize) &&
+ (psAlloc->ui32Log2PageSize == ui32Log2PageSize) &&
+ (OSStringNCompare(psAlloc->szName, pszName, DEVMEM_ANNOTATION_MAX_LEN) == 0);
+}
+
+/* FindOrCreateAllocation:
+ * Convenience function.
+ * Given a set of allocation properties (serial, DevVAddr, size, name, etc),
+ * this function will look for an existing record of this allocation and
+ * create the allocation if there is no existing record
+ */
+static PVRSRV_ERROR FindOrCreateAllocation(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 ui32AllocationIndexHint,
+ IMG_UINT64 ui64Serial,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ const char *pszName,
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_PID uiPID,
+ IMG_BOOL bSparse,
+ IMG_UINT32 *pui32AllocationIndexOut,
+ IMG_BOOL *pbCreated)
+{
+ IMG_UINT32 ui32AllocationIndex;
+ PVRSRV_ERROR eError;
+
+ if (ui32AllocationIndexHint != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE)
+ {
+ IMG_BOOL bHaveAllocation;
+
+ /* first, try to match against the index given by the client.
+ * if the caller provided a hint but the allocation record is no longer
+ * there, it must have been purged, so go ahead and create a new allocation
+ */
+ bHaveAllocation = MatchAllocation(ui32AllocationIndexHint,
+ ui64Serial,
+ sDevVAddr,
+ uiSize,
+ pszName,
+ ui32Log2PageSize,
+ uiPID);
+ if (bHaveAllocation)
+ {
+ *pbCreated = IMG_FALSE;
+ *pui32AllocationIndexOut = ui32AllocationIndexHint;
+ return PVRSRV_OK;
+ }
+ }
+
+ /* if there is no record of the allocation then we
+ * create it now
+ */
+ eError = CreateAllocation(psDeviceNode,
+ pszName,
+ ui64Serial,
+ uiPID,
+ sDevVAddr,
+ uiSize,
+ ui32Log2PageSize,
+ IMG_TRUE,
+ &ui32AllocationIndex);
+
+ if (eError == PVRSRV_OK)
+ {
+ *pui32AllocationIndexOut = ui32AllocationIndex;
+ *pbCreated = IMG_TRUE;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Failed to create record for allocation %s",
+ __func__,
+ pszName));
+ }
+
+ return eError;
+}
+
+/* GenerateMapUnmapCommandsForSparsePMR:
+ * Generate the MAP_RANGE or UNMAP_RANGE commands for the sparse PMR, using the PMR's
+ * current mapping table
+ *
+ * PMR: The PMR whose mapping table to read.
+ * ui32AllocIndex: The allocation to attribute the MAP_RANGE/UNMAP range commands to.
+ * bMap: Set to TRUE for mapping or IMG_FALSE for unmapping
+ *
+ * This function goes through every page in the PMR's mapping table and looks for
+ * virtually contiguous ranges to record as being mapped or unmapped.
+ */
+static void GenerateMapUnmapCommandsForSparsePMR(PMR *psPMR,
+ IMG_UINT32 ui32AllocIndex,
+ IMG_BOOL bMap)
+{
+ PMR_MAPPING_TABLE *psMappingTable;
+ IMG_UINT32 ui32DonePages = 0;
+ IMG_UINT32 ui32NumPages;
+ IMG_UINT32 i;
+ IMG_BOOL bInARun = IMG_FALSE;
+ IMG_UINT32 ui32CurrentStart = 0;
+ IMG_UINT32 ui32RunCount = 0;
+
+ psMappingTable = PMR_GetMappingTable(psPMR);
+ ui32NumPages = psMappingTable->ui32NumPhysChunks;
+
+ if (ui32NumPages == 0)
+ {
+ /* nothing to do */
+ return;
+ }
+
+ for (i = 0; i < psMappingTable->ui32NumVirtChunks; i++)
+ {
+ if (psMappingTable->aui32Translation[i] != TRANSLATION_INVALID)
+ {
+ if (!bInARun)
+ {
+ bInARun = IMG_TRUE;
+ ui32CurrentStart = i;
+ ui32RunCount = 1;
+ }
+ else
+ {
+ ui32RunCount++;
+ }
+ }
+
+ if (bInARun)
+ {
+ /* test if we need to end this current run and generate the command,
+ * either because the next page is not virtually contiguous
+ * to the current page, we have reached the maximum range,
+ * or this is the last page in the mapping table
+ */
+ if ((psMappingTable->aui32Translation[i] == TRANSLATION_INVALID) ||
+ (ui32RunCount == MAP_RANGE_MAX_RANGE) ||
+ (i == (psMappingTable->ui32NumVirtChunks - 1)))
+ {
+ if (bMap)
+ {
+ InsertMapRangeCommand(PMR_DeviceNode(psPMR),
+ ui32AllocIndex,
+ ui32CurrentStart,
+ ui32RunCount);
+ }
+ else
+ {
+ InsertUnmapRangeCommand(PMR_DeviceNode(psPMR),
+ ui32AllocIndex,
+ ui32CurrentStart,
+ ui32RunCount);
+ }
+
+ ui32DonePages += ui32RunCount;
+
+ if (ui32DonePages == ui32NumPages)
+ {
+ break;
+ }
+
+ bInARun = IMG_FALSE;
+ }
+ }
+ }
+
+}
+
+/* GenerateMapUnmapCommandsForChangeList:
+ * Generate the MAP_RANGE or UNMAP_RANGE commands for the sparse PMR, using the
+ * list of page change (page map or page unmap) indices given.
+ *
+ * ui32NumPages: Number of pages which have changed.
+ * pui32PageList: List of indices of the pages which have changed.
+ * ui32AllocIndex: The allocation to attribute the MAP_RANGE/UNMAP range commands to.
+ * bMap: Set to TRUE for mapping or IMG_FALSE for unmapping
+ *
+ * This function goes through every page in the list and looks for
+ * virtually contiguous ranges to record as being mapped or unmapped.
+ */
+static void GenerateMapUnmapCommandsForChangeList(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_UINT32 ui32NumPages,
+ IMG_UINT32 *pui32PageList,
+ IMG_UINT32 ui32AllocIndex,
+ IMG_BOOL bMap)
+{
+ IMG_UINT32 i;
+ IMG_BOOL bInARun = IMG_FALSE;
+ IMG_UINT32 ui32CurrentStart = 0;
+ IMG_UINT32 ui32RunCount = 0;
+
+ for (i = 0; i < ui32NumPages; i++)
+ {
+ if (!bInARun)
+ {
+ bInARun = IMG_TRUE;
+ ui32CurrentStart = pui32PageList[i];
+ }
+
+ ui32RunCount++;
+
+ /* we flush if:
+ * - the next page in the list is not one greater than the current page
+ * - this is the last page in the list
+ * - we have reached the maximum range size
+ */
+ if ((i == (ui32NumPages - 1)) ||
+ ((pui32PageList[i] + 1) != pui32PageList[i + 1]) ||
+ (ui32RunCount == MAP_RANGE_MAX_RANGE))
+ {
+ if (bMap)
+ {
+ InsertMapRangeCommand(psDeviceNode,
+ ui32AllocIndex,
+ ui32CurrentStart,
+ ui32RunCount);
+ }
+ else
+ {
+ InsertUnmapRangeCommand(psDeviceNode,
+ ui32AllocIndex,
+ ui32CurrentStart,
+ ui32RunCount);
+ }
+
+ bInARun = IMG_FALSE;
+ ui32RunCount = 0;
+ }
+ }
+}
+
+/* DevicememHistoryMapKM:
+ * Entry point for when an allocation is mapped into the MMU GPU
+ *
+ * psPMR: The PMR to which the allocation belongs.
+ * ui32Offset: The offset within the PMR at which the allocation begins.
+ * sDevVAddr: The DevVAddr at which the allocation begins.
+ * szName: Annotation/name for the allocation.
+ * ui32Log2PageSize: Page size of the allocation, expressed in log2 form.
+ * ui32AllocationIndex: Allocation index as provided by the client.
+ * We will use this as a short-cut to find the allocation
+ * in our records.
+ * pui32AllocationIndexOut: An updated allocation index for the client.
+ * This may be a new value if we just created the
+ * allocation record.
+ */
+PVRSRV_ERROR DevicememHistoryMapKM(PMR *psPMR,
+ IMG_UINT32 ui32Offset,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ const char szName[DEVMEM_ANNOTATION_MAX_LEN],
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 *pui32AllocationIndexOut)
+{
+ IMG_BOOL bSparse = PMR_IsSparse(psPMR);
+ IMG_UINT64 ui64Serial;
+ IMG_PID uiPID = OSGetCurrentClientProcessIDKM();
+ PVRSRV_ERROR eError;
+ IMG_BOOL bCreated;
+
+ if ((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) &&
+ !CHECK_ALLOC_INDEX(ui32AllocationIndex))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u",
+ __func__,
+ ui32AllocationIndex));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ PMRGetUID(psPMR, &ui64Serial);
+
+ DevicememHistoryLock();
+
+ eError = FindOrCreateAllocation(PMR_DeviceNode(psPMR),
+ ui32AllocationIndex,
+ ui64Serial,
+ sDevVAddr,
+ uiSize,
+ szName,
+ ui32Log2PageSize,
+ uiPID,
+ bSparse,
+ &ui32AllocationIndex,
+ &bCreated);
+
+ if ((eError == PVRSRV_OK) && !bCreated)
+ {
+ /* touch the allocation so it goes to the head of our MRU list */
+ TouchBusyAllocation(ui32AllocationIndex);
+ }
+ else if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)",
+ __func__,
+ szName,
+ PVRSRVGETERRORSTRING(eError)));
+ goto out_unlock;
+ }
+
+ if (!bSparse)
+ {
+ InsertMapAllCommand(PMR_DeviceNode(psPMR), ui32AllocationIndex);
+ }
+ else
+ {
+ GenerateMapUnmapCommandsForSparsePMR(psPMR,
+ ui32AllocationIndex,
+ IMG_TRUE);
+ }
+
+ InsertTimeStampCommand(OSClockns64());
+
+ *pui32AllocationIndexOut = ui32AllocationIndex;
+
+out_unlock:
+ DevicememHistoryUnlock();
+
+ return eError;
+}
+
+static void VRangeInsertMapUnmapCommands(PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_BOOL bMap,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_DEV_VIRTADDR sBaseDevVAddr,
+ IMG_UINT32 ui32StartPage,
+ IMG_UINT32 ui32NumPages,
+ const IMG_CHAR *pszName)
+{
+ while (ui32NumPages > 0)
+ {
+ IMG_UINT32 ui32PagesToAdd;
+
+ ui32PagesToAdd = MIN(ui32NumPages, MAP_RANGE_MAX_RANGE);
+
+ if (ui32StartPage > MAP_RANGE_MAX_START)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "Cannot record %s range beginning at page "
+ "%u on allocation %s",
+ bMap ? "map" : "unmap",
+ ui32StartPage,
+ pszName));
+ return;
+ }
+
+ if (bMap)
+ {
+ InsertMapRangeCommand(psDeviceNode,
+ ui32AllocationIndex,
+ ui32StartPage,
+ ui32PagesToAdd);
+ }
+ else
+ {
+ InsertUnmapRangeCommand(psDeviceNode,
+ ui32AllocationIndex,
+ ui32StartPage,
+ ui32PagesToAdd);
+ }
+
+ ui32StartPage += ui32PagesToAdd;
+ ui32NumPages -= ui32PagesToAdd;
+ }
+}
+
+PVRSRV_ERROR DevicememHistoryMapVRangeKM(CONNECTION_DATA *psConnection,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_DEV_VIRTADDR sBaseDevVAddr,
+ IMG_UINT32 ui32StartPage,
+ IMG_UINT32 ui32NumPages,
+ IMG_DEVMEM_SIZE_T uiAllocSize,
+ const IMG_CHAR szName[DEVMEM_ANNOTATION_MAX_LEN],
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 *pui32AllocationIndexOut)
+{
+ IMG_PID uiPID = OSGetCurrentClientProcessIDKM();
+ PVRSRV_ERROR eError;
+ IMG_BOOL bCreated;
+
+ PVR_UNREFERENCED_PARAMETER(psConnection);
+
+ if ((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) &&
+ !CHECK_ALLOC_INDEX(ui32AllocationIndex))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u",
+ __func__,
+ ui32AllocationIndex));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ DevicememHistoryLock();
+
+ eError = FindOrCreateAllocation(psDeviceNode,
+ ui32AllocationIndex,
+ 0,
+ sBaseDevVAddr,
+ uiAllocSize,
+ szName,
+ ui32Log2PageSize,
+ uiPID,
+ IMG_FALSE,
+ &ui32AllocationIndex,
+ &bCreated);
+
+ if ((eError == PVRSRV_OK) && !bCreated)
+ {
+ /* touch the allocation so it goes to the head of our MRU list */
+ TouchBusyAllocation(ui32AllocationIndex);
+ }
+ else if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)",
+ __func__,
+ szName,
+ PVRSRVGETERRORSTRING(eError)));
+ goto out_unlock;
+ }
+
+ VRangeInsertMapUnmapCommands(psDeviceNode,
+ IMG_TRUE,
+ ui32AllocationIndex,
+ sBaseDevVAddr,
+ ui32StartPage,
+ ui32NumPages,
+ szName);
+
+ *pui32AllocationIndexOut = ui32AllocationIndex;
+
+out_unlock:
+ DevicememHistoryUnlock();
+
+ return eError;
+
+}
+
+PVRSRV_ERROR DevicememHistoryUnmapVRangeKM(CONNECTION_DATA *psConnection,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_DEV_VIRTADDR sBaseDevVAddr,
+ IMG_UINT32 ui32StartPage,
+ IMG_UINT32 ui32NumPages,
+ IMG_DEVMEM_SIZE_T uiAllocSize,
+ const IMG_CHAR szName[DEVMEM_ANNOTATION_MAX_LEN],
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 *pui32AllocationIndexOut)
+{
+ IMG_PID uiPID = OSGetCurrentClientProcessIDKM();
+ PVRSRV_ERROR eError;
+ IMG_BOOL bCreated;
+
+ PVR_UNREFERENCED_PARAMETER(psConnection);
+
+ if ((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) &&
+ !CHECK_ALLOC_INDEX(ui32AllocationIndex))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u",
+ __func__,
+ ui32AllocationIndex));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ DevicememHistoryLock();
+
+ eError = FindOrCreateAllocation(psDeviceNode,
+ ui32AllocationIndex,
+ 0,
+ sBaseDevVAddr,
+ uiAllocSize,
+ szName,
+ ui32Log2PageSize,
+ uiPID,
+ IMG_FALSE,
+ &ui32AllocationIndex,
+ &bCreated);
+
+ if ((eError == PVRSRV_OK) && !bCreated)
+ {
+ /* touch the allocation so it goes to the head of our MRU list */
+ TouchBusyAllocation(ui32AllocationIndex);
+ }
+ else if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)",
+ __func__,
+ szName,
+ PVRSRVGETERRORSTRING(eError)));
+ goto out_unlock;
+ }
+
+ VRangeInsertMapUnmapCommands(psDeviceNode,
+ IMG_FALSE,
+ ui32AllocationIndex,
+ sBaseDevVAddr,
+ ui32StartPage,
+ ui32NumPages,
+ szName);
+
+ *pui32AllocationIndexOut = ui32AllocationIndex;
+
+out_unlock:
+ DevicememHistoryUnlock();
+
+ return eError;
+}
+
+
+
+/* DevicememHistoryUnmapKM:
+ * Entry point for when an allocation is unmapped from the MMU GPU
+ *
+ * psPMR: The PMR to which the allocation belongs.
+ * ui32Offset: The offset within the PMR at which the allocation begins.
+ * sDevVAddr: The DevVAddr at which the allocation begins.
+ * szName: Annotation/name for the allocation.
+ * ui32Log2PageSize: Page size of the allocation, expressed in log2 form.
+ * ui32AllocationIndex: Allocation index as provided by the client.
+ * We will use this as a short-cut to find the allocation
+ * in our records.
+ * pui32AllocationIndexOut: An updated allocation index for the client.
+ * This may be a new value if we just created the
+ * allocation record.
+ */
+PVRSRV_ERROR DevicememHistoryUnmapKM(PMR *psPMR,
+ IMG_UINT32 ui32Offset,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ const char szName[DEVMEM_ANNOTATION_MAX_LEN],
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 *pui32AllocationIndexOut)
+{
+ IMG_BOOL bSparse = PMR_IsSparse(psPMR);
+ IMG_UINT64 ui64Serial;
+ IMG_PID uiPID = OSGetCurrentClientProcessIDKM();
+ PVRSRV_ERROR eError;
+ IMG_BOOL bCreated;
+
+ if ((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) &&
+ !CHECK_ALLOC_INDEX(ui32AllocationIndex))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u",
+ __func__,
+ ui32AllocationIndex));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ PMRGetUID(psPMR, &ui64Serial);
+
+ DevicememHistoryLock();
+
+ eError = FindOrCreateAllocation(PMR_DeviceNode(psPMR),
+ ui32AllocationIndex,
+ ui64Serial,
+ sDevVAddr,
+ uiSize,
+ szName,
+ ui32Log2PageSize,
+ uiPID,
+ bSparse,
+ &ui32AllocationIndex,
+ &bCreated);
+
+ if ((eError == PVRSRV_OK) && !bCreated)
+ {
+ /* touch the allocation so it goes to the head of our MRU list */
+ TouchBusyAllocation(ui32AllocationIndex);
+ }
+ else if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)",
+ __func__,
+ szName,
+ PVRSRVGETERRORSTRING(eError)));
+ goto out_unlock;
+ }
+
+ if (!bSparse)
+ {
+ InsertUnmapAllCommand(PMR_DeviceNode(psPMR), ui32AllocationIndex);
+ }
+ else
+ {
+ GenerateMapUnmapCommandsForSparsePMR(psPMR,
+ ui32AllocationIndex,
+ IMG_FALSE);
+ }
+
+ InsertTimeStampCommand(OSClockns64());
+
+ *pui32AllocationIndexOut = ui32AllocationIndex;
+
+out_unlock:
+ DevicememHistoryUnlock();
+
+ return eError;
+}
+
+/* DevicememHistorySparseChangeKM:
+ * Entry point for when a sparse allocation is changed, such that some of the
+ * pages within the sparse allocation are mapped or unmapped.
+ *
+ * psPMR: The PMR to which the allocation belongs.
+ * ui32Offset: The offset within the PMR at which the allocation begins.
+ * sDevVAddr: The DevVAddr at which the allocation begins.
+ * szName: Annotation/name for the allocation.
+ * ui32Log2PageSize: Page size of the allocation, expressed in log2 form.
+ * ui32AllocPageCount: Number of pages which have been mapped.
+ * paui32AllocPageIndices: Indices of pages which have been mapped.
+ * ui32FreePageCount: Number of pages which have been unmapped.
+ * paui32FreePageIndices: Indices of pages which have been unmapped.
+ * ui32AllocationIndex: Allocation index as provided by the client.
+ * We will use this as a short-cut to find the allocation
+ * in our records.
+ * pui32AllocationIndexOut: An updated allocation index for the client.
+ * This may be a new value if we just created the
+ * allocation record.
+ */
+PVRSRV_ERROR DevicememHistorySparseChangeKM(PMR *psPMR,
+ IMG_UINT32 ui32Offset,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ const char szName[DEVMEM_ANNOTATION_MAX_LEN],
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_UINT32 ui32AllocPageCount,
+ IMG_UINT32 *paui32AllocPageIndices,
+ IMG_UINT32 ui32FreePageCount,
+ IMG_UINT32 *paui32FreePageIndices,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 *pui32AllocationIndexOut)
+{
+ IMG_UINT64 ui64Serial;
+ IMG_PID uiPID = OSGetCurrentClientProcessIDKM();
+ PVRSRV_ERROR eError;
+ IMG_BOOL bCreated;
+
+ if ((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) &&
+ !CHECK_ALLOC_INDEX(ui32AllocationIndex))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u",
+ __func__,
+ ui32AllocationIndex));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ PMRGetUID(psPMR, &ui64Serial);
+
+ DevicememHistoryLock();
+
+ eError = FindOrCreateAllocation(PMR_DeviceNode(psPMR),
+ ui32AllocationIndex,
+ ui64Serial,
+ sDevVAddr,
+ uiSize,
+ szName,
+ ui32Log2PageSize,
+ uiPID,
+ IMG_TRUE /* bSparse */,
+ &ui32AllocationIndex,
+ &bCreated);
+
+ if ((eError == PVRSRV_OK) && !bCreated)
+ {
+ /* touch the allocation so it goes to the head of our MRU list */
+ TouchBusyAllocation(ui32AllocationIndex);
+ }
+ else if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)",
+ __func__,
+ szName,
+ PVRSRVGETERRORSTRING(eError)));
+ goto out_unlock;
+ }
+
+ GenerateMapUnmapCommandsForChangeList(PMR_DeviceNode(psPMR),
+ ui32AllocPageCount,
+ paui32AllocPageIndices,
+ ui32AllocationIndex,
+ IMG_TRUE);
+
+ GenerateMapUnmapCommandsForChangeList(PMR_DeviceNode(psPMR),
+ ui32FreePageCount,
+ paui32FreePageIndices,
+ ui32AllocationIndex,
+ IMG_FALSE);
+
+ InsertTimeStampCommand(OSClockns64());
+
+ *pui32AllocationIndexOut = ui32AllocationIndex;
+
+out_unlock:
+ DevicememHistoryUnlock();
+
+ return eError;
+
+}
+
+/* CircularBufferIterateStart:
+ * Initialise local state for iterating over the circular buffer
+ */
+static void CircularBufferIterateStart(IMG_UINT32 *pui32Head, IMG_UINT32 *pui32Iter)
+{
+ *pui32Head = gsDevicememHistoryData.sRecords.ui32Head;
+
+ if (*pui32Head != 0)
+ {
+ *pui32Iter = *pui32Head - 1;
+ }
+ else
+ {
+ *pui32Iter = CIRCULAR_BUFFER_NUM_COMMANDS - 1;
+ }
+}
+
+/* CircularBufferIteratePrevious:
+ * Iterate to the previous item in the circular buffer.
+ * This is called repeatedly to iterate over the whole circular buffer.
+ */
+static COMMAND_WRAPPER *CircularBufferIteratePrevious(IMG_UINT32 ui32Head,
+ IMG_UINT32 *pui32Iter,
+ COMMAND_TYPE *peType,
+ IMG_BOOL *pbLast)
+{
+ IMG_UINT8 *pui8Header;
+ COMMAND_WRAPPER *psOut = NULL;
+
+ psOut = gsDevicememHistoryData.sRecords.pasCircularBuffer + *pui32Iter;
+
+ pui8Header = (void *) psOut;
+
+ /* Check the command looks valid.
+ * this condition should never happen, but check for it anyway
+ * and try to handle it
+ */
+ if (*pui8Header >= COMMAND_TYPE_COUNT)
+ {
+ /* invalid header detected. Circular buffer corrupted? */
+ PVR_DPF((PVR_DBG_ERROR, "CircularBufferIteratePrevious: "
+ "Invalid header: %u",
+ *pui8Header));
+ *pbLast = IMG_TRUE;
+ return NULL;
+ }
+
+ *peType = *pui8Header;
+
+ if (*pui32Iter != 0)
+ {
+ (*pui32Iter)--;
+ }
+ else
+ {
+ *pui32Iter = CIRCULAR_BUFFER_NUM_COMMANDS - 1;
+ }
+
+
+ /* inform the caller this is the last command if either we have reached
+ * the head (where we started) or if we have reached an empty command,
+ * which means we have covered all populated entries
+ */
+ if ((*pui32Iter == ui32Head) || (*peType == COMMAND_TYPE_NONE))
+ {
+ /* this is the final iteration */
+ *pbLast = IMG_TRUE;
+ }
+
+ return psOut;
+}
+
+/* MapUnmapCommandGetInfo:
+ * Helper function to get the address and mapping information from a MAP_ALL, UNMAP_ALL,
+ * MAP_RANGE or UNMAP_RANGE command
+ */
+static void MapUnmapCommandGetInfo(COMMAND_WRAPPER *psCommand,
+ COMMAND_TYPE eType,
+ IMG_DEV_VIRTADDR *psDevVAddrStart,
+ IMG_DEV_VIRTADDR *psDevVAddrEnd,
+ IMG_BOOL *pbMap,
+ IMG_UINT32 *pui32AllocIndex)
+{
+ if ((eType == COMMAND_TYPE_MAP_ALL) || ((eType == COMMAND_TYPE_UNMAP_ALL)))
+ {
+ COMMAND_MAP_ALL *psMapAll = &psCommand->u.sMapAll;
+ RECORD_ALLOCATION *psAlloc;
+
+ *pbMap = (eType == COMMAND_TYPE_MAP_ALL);
+ *pui32AllocIndex = psMapAll->uiAllocIndex;
+
+ psAlloc = ALLOC_INDEX_TO_PTR(psMapAll->uiAllocIndex);
+
+ *psDevVAddrStart = psAlloc->sDevVAddr;
+ psDevVAddrEnd->uiAddr = psDevVAddrStart->uiAddr + psAlloc->uiSize - 1;
+ }
+ else if ((eType == COMMAND_TYPE_MAP_RANGE) || ((eType == COMMAND_TYPE_UNMAP_RANGE)))
+ {
+ COMMAND_MAP_RANGE *psMapRange = &psCommand->u.sMapRange;
+ RECORD_ALLOCATION *psAlloc;
+ IMG_UINT32 ui32StartPage, ui32Count;
+
+ *pbMap = (eType == COMMAND_TYPE_MAP_RANGE);
+ *pui32AllocIndex = psMapRange->uiAllocIndex;
+
+ psAlloc = ALLOC_INDEX_TO_PTR(psMapRange->uiAllocIndex);
+
+ MapRangeUnpack(psMapRange, &ui32StartPage, &ui32Count);
+
+ psDevVAddrStart->uiAddr = psAlloc->sDevVAddr.uiAddr +
+ ((1ULL << psAlloc->ui32Log2PageSize) * ui32StartPage);
+
+ psDevVAddrEnd->uiAddr = psDevVAddrStart->uiAddr +
+ ((1ULL << psAlloc->ui32Log2PageSize) * ui32Count) - 1;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid command type: %u",
+ __func__,
+ eType));
+ }
+}
+
+/* DevicememHistoryQuery:
+ * Entry point for rgxdebug to look up addresses relating to a page fault
+ */
+IMG_BOOL DevicememHistoryQuery(DEVICEMEM_HISTORY_QUERY_IN *psQueryIn,
+ DEVICEMEM_HISTORY_QUERY_OUT *psQueryOut,
+ IMG_UINT32 ui32PageSizeBytes,
+ IMG_BOOL bMatchAnyAllocInPage)
+{
+ IMG_UINT32 ui32Head, ui32Iter;
+ COMMAND_TYPE eType = COMMAND_TYPE_NONE;
+ COMMAND_WRAPPER *psCommand = NULL;
+ IMG_BOOL bLast = IMG_FALSE;
+ IMG_UINT64 ui64StartTime = OSClockns64();
+ IMG_UINT64 ui64TimeNs = 0;
+
+ /* initialise the results count for the caller */
+ psQueryOut->ui32NumResults = 0;
+
+ DevicememHistoryLock();
+
+ /* if the search is constrained to a particular PID then we
+ * first search the list of allocations to see if this
+ * PID is known to us
+ */
+ if (psQueryIn->uiPID != DEVICEMEM_HISTORY_PID_ANY)
+ {
+ IMG_UINT32 ui32Alloc;
+ ui32Alloc = gsDevicememHistoryData.sRecords.ui32AllocationsListHead;
+
+ while (ui32Alloc != END_OF_LIST)
+ {
+ RECORD_ALLOCATION *psAlloc;
+
+ psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc);
+
+ if (psAlloc->uiPID == psQueryIn->uiPID)
+ {
+ goto found_pid;
+ }
+
+ if (ui32Alloc == gsDevicememHistoryData.sRecords.ui32AllocationsListHead)
+ {
+ /* gone through whole list */
+ break;
+ }
+ }
+
+ /* PID not found, so we do not have any suitable data for this
+ * page fault
+ */
+ goto out_unlock;
+ }
+
+found_pid:
+
+ CircularBufferIterateStart(&ui32Head, &ui32Iter);
+
+ while (!bLast)
+ {
+ psCommand = CircularBufferIteratePrevious(ui32Head, &ui32Iter, &eType, &bLast);
+
+ if (eType == COMMAND_TYPE_TIMESTAMP)
+ {
+ ui64TimeNs = TimeStampUnpack(&psCommand->u.sTimeStamp);
+ continue;
+ }
+
+ if ((eType == COMMAND_TYPE_MAP_ALL) ||
+ (eType == COMMAND_TYPE_UNMAP_ALL) ||
+ (eType == COMMAND_TYPE_MAP_RANGE) ||
+ (eType == COMMAND_TYPE_UNMAP_RANGE))
+ {
+ RECORD_ALLOCATION *psAlloc;
+ IMG_DEV_VIRTADDR sAllocStartAddrOrig, sAllocEndAddrOrig;
+ IMG_DEV_VIRTADDR sAllocStartAddr, sAllocEndAddr;
+ IMG_BOOL bMap;
+ IMG_UINT32 ui32AllocIndex;
+
+ MapUnmapCommandGetInfo(psCommand,
+ eType,
+ &sAllocStartAddrOrig,
+ &sAllocEndAddrOrig,
+ &bMap,
+ &ui32AllocIndex);
+
+ sAllocStartAddr = sAllocStartAddrOrig;
+ sAllocEndAddr = sAllocEndAddrOrig;
+
+ psAlloc = ALLOC_INDEX_TO_PTR(ui32AllocIndex);
+
+ /* skip this command if we need to search within
+ * a particular PID, and this allocation is not from
+ * that PID
+ */
+ if ((psQueryIn->uiPID != DEVICEMEM_HISTORY_PID_ANY) &&
+ (psAlloc->uiPID != psQueryIn->uiPID))
+ {
+ continue;
+ }
+
+ /* if the allocation was created after this event, then this
+ * event must be for an old/removed allocation, so skip it
+ */
+ if (DO_TIME_STAMP_MASK(psAlloc->ui64CreationTime) > ui64TimeNs)
+ {
+ continue;
+ }
+
+ /* if the caller wants us to match any allocation in the
+ * same page as the allocation then tweak the real start/end
+ * addresses of the allocation here
+ */
+ if (bMatchAnyAllocInPage)
+ {
+ sAllocStartAddr.uiAddr = sAllocStartAddr.uiAddr & ~(IMG_UINT64) (ui32PageSizeBytes - 1);
+ sAllocEndAddr.uiAddr = (sAllocEndAddr.uiAddr + ui32PageSizeBytes - 1) & ~(IMG_UINT64) (ui32PageSizeBytes - 1);
+ }
+
+ if ((psQueryIn->sDevVAddr.uiAddr >= sAllocStartAddr.uiAddr) &&
+ (psQueryIn->sDevVAddr.uiAddr < sAllocEndAddr.uiAddr))
+ {
+ DEVICEMEM_HISTORY_QUERY_OUT_RESULT *psResult = &psQueryOut->sResults[psQueryOut->ui32NumResults];
+
+ OSStringLCopy(psResult->szString, psAlloc->szName, sizeof(psResult->szString));
+ psResult->sBaseDevVAddr = psAlloc->sDevVAddr;
+ psResult->uiSize = psAlloc->uiSize;
+ psResult->bMap = bMap;
+ psResult->ui64Age = _CalculateAge(ui64StartTime, ui64TimeNs, TIME_STAMP_MASK);
+ psResult->ui64When = ui64TimeNs;
+ /* write the responsible PID in the placeholder */
+ psResult->sProcessInfo.uiPID = psAlloc->uiPID;
+
+ if ((eType == COMMAND_TYPE_MAP_ALL) || (eType == COMMAND_TYPE_UNMAP_ALL))
+ {
+ psResult->bRange = IMG_FALSE;
+ psResult->bAll = IMG_TRUE;
+ }
+ else
+ {
+ psResult->bRange = IMG_TRUE;
+ MapRangeUnpack(&psCommand->u.sMapRange,
+ &psResult->ui32StartPage,
+ &psResult->ui32PageCount);
+ psResult->bAll = (psResult->ui32PageCount * (1U << psAlloc->ui32Log2PageSize))
+ == psAlloc->uiSize;
+ psResult->sMapStartAddr = sAllocStartAddrOrig;
+ psResult->sMapEndAddr = sAllocEndAddrOrig;
+ }
+
+ psQueryOut->ui32NumResults++;
+
+ if (psQueryOut->ui32NumResults == DEVICEMEM_HISTORY_QUERY_OUT_MAX_RESULTS)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+out_unlock:
+ DevicememHistoryUnlock();
+
+ return psQueryOut->ui32NumResults > 0;
+}
+
+static void DeviceMemHistoryFmt(IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN],
+ IMG_PID uiPID,
+ const IMG_CHAR *pszName,
+ const IMG_CHAR *pszAction,
+ IMG_DEV_VIRTADDR sDevVAddrStart,
+ IMG_DEV_VIRTADDR sDevVAddrEnd,
+ IMG_UINT64 ui64TimeNs)
+{
+
+ OSSNPrintf(szBuffer, PVR_MAX_DEBUG_MESSAGE_LEN,
+ /* PID NAME MAP/UNMAP MIN-MAX SIZE AbsUS AgeUS*/
+ "%04u %-40s %-10s "
+ IMG_DEV_VIRTADDR_FMTSPEC "-" IMG_DEV_VIRTADDR_FMTSPEC " "
+ "0x%08" IMG_UINT64_FMTSPECX " "
+ "%013" IMG_UINT64_FMTSPEC, /* 13 digits is over 2 hours of ns */
+ uiPID,
+ pszName,
+ pszAction,
+ sDevVAddrStart.uiAddr,
+ sDevVAddrEnd.uiAddr,
+ sDevVAddrEnd.uiAddr - sDevVAddrStart.uiAddr + 1,
+ ui64TimeNs);
+}
+
+static void DeviceMemHistoryFmtHeader(IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN])
+{
+ OSSNPrintf(szBuffer, PVR_MAX_DEBUG_MESSAGE_LEN,
+ "%-4s %-40s %-6s %10s %10s %8s %13s",
+ "PID",
+ "NAME",
+ "ACTION",
+ "ADDR MIN",
+ "ADDR MAX",
+ "SIZE",
+ "ABS NS");
+}
+
+static const char *CommandTypeToString(COMMAND_TYPE eType)
+{
+ switch (eType)
+ {
+ case COMMAND_TYPE_MAP_ALL:
+ return "MapAll";
+ case COMMAND_TYPE_UNMAP_ALL:
+ return "UnmapAll";
+ case COMMAND_TYPE_MAP_RANGE:
+ return "MapRange";
+ case COMMAND_TYPE_UNMAP_RANGE:
+ return "UnmapRange";
+ case COMMAND_TYPE_TIMESTAMP:
+ return "TimeStamp";
+ default:
+ return "???";
+ }
+}
+
+static void DevicememHistoryPrintAll(OSDI_IMPL_ENTRY *psEntry)
+{
+ IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN];
+ IMG_UINT32 ui32Iter;
+ IMG_UINT32 ui32Head;
+ IMG_BOOL bLast = IMG_FALSE;
+ IMG_UINT64 ui64TimeNs = 0;
+ IMG_UINT64 ui64StartTime = OSClockns64();
+
+ DeviceMemHistoryFmtHeader(szBuffer);
+ DIPrintf(psEntry, "%s\n", szBuffer);
+
+ CircularBufferIterateStart(&ui32Head, &ui32Iter);
+
+ while (!bLast)
+ {
+ COMMAND_WRAPPER *psCommand;
+ COMMAND_TYPE eType = COMMAND_TYPE_NONE;
+
+ psCommand = CircularBufferIteratePrevious(ui32Head, &ui32Iter, &eType,
+ &bLast);
+
+ if (eType == COMMAND_TYPE_TIMESTAMP)
+ {
+ ui64TimeNs = TimeStampUnpack(&psCommand->u.sTimeStamp);
+ continue;
+ }
+
+
+ if ((eType == COMMAND_TYPE_MAP_ALL) ||
+ (eType == COMMAND_TYPE_UNMAP_ALL) ||
+ (eType == COMMAND_TYPE_MAP_RANGE) ||
+ (eType == COMMAND_TYPE_UNMAP_RANGE))
+ {
+ RECORD_ALLOCATION *psAlloc;
+ IMG_DEV_VIRTADDR sDevVAddrStart, sDevVAddrEnd;
+ IMG_BOOL bMap;
+ IMG_UINT32 ui32AllocIndex;
+
+ MapUnmapCommandGetInfo(psCommand,
+ eType,
+ &sDevVAddrStart,
+ &sDevVAddrEnd,
+ &bMap,
+ &ui32AllocIndex);
+
+ psAlloc = ALLOC_INDEX_TO_PTR(ui32AllocIndex);
+
+ if (DO_TIME_STAMP_MASK(psAlloc->ui64CreationTime) > ui64TimeNs)
+ {
+ /* if this event relates to an allocation we
+ * are no longer tracking then do not print it
+ */
+ continue;
+ }
+
+ DeviceMemHistoryFmt(szBuffer,
+ psAlloc->uiPID,
+ psAlloc->szName,
+ CommandTypeToString(eType),
+ sDevVAddrStart,
+ sDevVAddrEnd,
+ ui64TimeNs);
+
+ DIPrintf(psEntry, "%s\n", szBuffer);
+ }
+ }
+
+ DIPrintf(psEntry, "\nTimestamp reference: %013" IMG_UINT64_FMTSPEC "\n",
+ ui64StartTime);
+}
+
+static int DevicememHistoryPrintAllWrapper(OSDI_IMPL_ENTRY *psEntry,
+ void *pvData)
+{
+ PVR_UNREFERENCED_PARAMETER(pvData);
+
+ DevicememHistoryLock();
+ DevicememHistoryPrintAll(psEntry);
+ DevicememHistoryUnlock();
+
+ return 0;
+}
+
+static PVRSRV_ERROR CreateRecords(void)
+{
+ gsDevicememHistoryData.sRecords.pasAllocations =
+ OSAllocMem(sizeof(RECORD_ALLOCATION) * ALLOCATION_LIST_NUM_ENTRIES);
+
+ PVR_RETURN_IF_NOMEM(gsDevicememHistoryData.sRecords.pasAllocations);
+
+ /* Allocated and initialise the circular buffer with zeros so every
+ * command is initialised as a command of type COMMAND_TYPE_NONE. */
+ gsDevicememHistoryData.sRecords.pasCircularBuffer =
+ OSAllocZMem(sizeof(COMMAND_WRAPPER) * CIRCULAR_BUFFER_NUM_COMMANDS);
+
+ if (gsDevicememHistoryData.sRecords.pasCircularBuffer == NULL)
+ {
+ OSFreeMem(gsDevicememHistoryData.sRecords.pasAllocations);
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ return PVRSRV_OK;
+}
+
+static void DestroyRecords(void)
+{
+ OSFreeMem(gsDevicememHistoryData.sRecords.pasCircularBuffer);
+ OSFreeMem(gsDevicememHistoryData.sRecords.pasAllocations);
+}
+
+static void InitialiseRecords(void)
+{
+ IMG_UINT32 i;
+
+ /* initialise the allocations list */
+
+ gsDevicememHistoryData.sRecords.pasAllocations[0].ui32Prev = ALLOCATION_LIST_NUM_ENTRIES - 1;
+ gsDevicememHistoryData.sRecords.pasAllocations[0].ui32Next = 1;
+
+ for (i = 1; i < ALLOCATION_LIST_NUM_ENTRIES; i++)
+ {
+ gsDevicememHistoryData.sRecords.pasAllocations[i].ui32Prev = i - 1;
+ gsDevicememHistoryData.sRecords.pasAllocations[i].ui32Next = i + 1;
+ }
+
+ gsDevicememHistoryData.sRecords.pasAllocations[ALLOCATION_LIST_NUM_ENTRIES - 1].ui32Next = 0;
+
+ gsDevicememHistoryData.sRecords.ui32AllocationsListHead = 0;
+}
+
+PVRSRV_ERROR DevicememHistoryInitKM(void)
+{
+ PVRSRV_ERROR eError;
+ DI_ITERATOR_CB sIterator = {.pfnShow = DevicememHistoryPrintAllWrapper};
+
+ eError = OSLockCreate(&gsDevicememHistoryData.hLock);
+ PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", err_lock);
+
+ eError = CreateRecords();
+ PVR_LOG_GOTO_IF_ERROR(eError, "CreateRecords", err_allocations);
+
+ InitialiseRecords();
+
+ eError = DICreateEntry("devicemem_history", NULL, &sIterator, NULL,
+ DI_ENTRY_TYPE_GENERIC,
+ &gsDevicememHistoryData.psDIEntry);
+ PVR_LOG_GOTO_IF_ERROR(eError, "DICreateEntry", err_di_creation);
+
+ return PVRSRV_OK;
+
+err_di_creation:
+ DestroyRecords();
+err_allocations:
+ OSLockDestroy(gsDevicememHistoryData.hLock);
+ gsDevicememHistoryData.hLock = NULL;
+err_lock:
+ return eError;
+}
+
+void DevicememHistoryDeInitKM(void)
+{
+ if (gsDevicememHistoryData.psDIEntry != NULL)
+ {
+ DIDestroyEntry(gsDevicememHistoryData.psDIEntry);
+ }
+
+ DestroyRecords();
+
+ if (gsDevicememHistoryData.hLock != NULL)
+ {
+ OSLockDestroy(gsDevicememHistoryData.hLock);
+ gsDevicememHistoryData.hLock = NULL;
+ }
+}
diff --git a/drivers/gpu/drm/img-rogue/devicemem_history_server.h b/drivers/gpu/drm/img-rogue/devicemem_history_server.h
new file mode 100644
index 000000000..8e7ca59a6
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/devicemem_history_server.h
@@ -0,0 +1,157 @@
+/*************************************************************************/ /*!
+@File devicemem_history_server.h
+@Title Resource Information abstraction
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Devicemem History functions
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef DEVICEMEM_HISTORY_SERVER_H
+#define DEVICEMEM_HISTORY_SERVER_H
+
+#include "img_defs.h"
+#include "pvrsrv_error.h"
+#include "rgxmem.h"
+#include "devicemem_utils.h"
+#include "connection_server.h"
+
+PVRSRV_ERROR DevicememHistoryInitKM(void);
+
+void DevicememHistoryDeInitKM(void);
+
+PVRSRV_ERROR DevicememHistoryMapKM(PMR *psPMR,
+ IMG_UINT32 ui32Offset,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ const char szName[DEVMEM_ANNOTATION_MAX_LEN],
+ IMG_UINT32 ui32PageSize,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 *pui32AllocationIndexOut);
+
+PVRSRV_ERROR DevicememHistoryUnmapKM(PMR *psPMR,
+ IMG_UINT32 ui32Offset,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ const char szName[DEVMEM_ANNOTATION_MAX_LEN],
+ IMG_UINT32 ui32PageSize,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 *pui32AllocationIndexOut);
+
+PVRSRV_ERROR DevicememHistoryMapVRangeKM(CONNECTION_DATA *psConnection,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_DEV_VIRTADDR sBaseDevVAddr,
+ IMG_UINT32 ui32StartPage,
+ IMG_UINT32 ui32NumPages,
+ IMG_DEVMEM_SIZE_T uiAllocSize,
+ const IMG_CHAR szName[DEVMEM_ANNOTATION_MAX_LEN],
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 *ui32AllocationIndexOut);
+
+PVRSRV_ERROR DevicememHistoryUnmapVRangeKM(CONNECTION_DATA *psConnection,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_DEV_VIRTADDR sBaseDevVAddr,
+ IMG_UINT32 ui32StartPage,
+ IMG_UINT32 ui32NumPages,
+ IMG_DEVMEM_SIZE_T uiAllocSize,
+ const IMG_CHAR szName[DEVMEM_ANNOTATION_MAX_LEN],
+ IMG_UINT32 ui32Log2PageSize,
+ IMG_UINT32 ui32AllocationIndex,
+ IMG_UINT32 *ui32AllocationIndexOut);
+
+PVRSRV_ERROR DevicememHistorySparseChangeKM(PMR *psPMR,
+ IMG_UINT32 ui32Offset,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ const char szName[DEVMEM_ANNOTATION_MAX_LEN],
+ IMG_UINT32 ui32PageSize,
+ IMG_UINT32 ui32AllocPageCount,
+ IMG_UINT32 *paui32AllocPageIndices,
+ IMG_UINT32 ui32FreePageCount,
+ IMG_UINT32 *pauiFreePageIndices,
+ IMG_UINT32 AllocationIndex,
+ IMG_UINT32 *pui32AllocationIndexOut);
+
+/* used when the PID does not matter */
+#define DEVICEMEM_HISTORY_PID_ANY 0xFFFFFFFE
+
+typedef struct _DEVICEMEM_HISTORY_QUERY_IN_
+{
+ IMG_PID uiPID;
+ IMG_DEV_VIRTADDR sDevVAddr;
+} DEVICEMEM_HISTORY_QUERY_IN;
+
+/* Store up to 4 results for a lookup. In the case of the faulting page being
+ * re-mapped between the page fault occurring on HW and the page fault analysis
+ * being done, the second result entry will show the allocation being unmapped.
+ * A further 2 entries are added to cater for multiple buffers in the same page.
+ */
+#define DEVICEMEM_HISTORY_QUERY_OUT_MAX_RESULTS 4
+
+typedef struct _DEVICEMEM_HISTORY_QUERY_OUT_RESULT_
+{
+ IMG_CHAR szString[DEVMEM_ANNOTATION_MAX_LEN];
+ IMG_DEV_VIRTADDR sBaseDevVAddr;
+ IMG_DEVMEM_SIZE_T uiSize;
+ IMG_BOOL bMap;
+ IMG_BOOL bRange;
+ IMG_BOOL bAll;
+ IMG_UINT64 ui64When;
+ IMG_UINT64 ui64Age;
+ /* info for sparse map/unmap operations (i.e. bRange=IMG_TRUE) */
+ IMG_UINT32 ui32StartPage;
+ IMG_UINT32 ui32PageCount;
+ IMG_DEV_VIRTADDR sMapStartAddr;
+ IMG_DEV_VIRTADDR sMapEndAddr;
+ RGXMEM_PROCESS_INFO sProcessInfo;
+} DEVICEMEM_HISTORY_QUERY_OUT_RESULT;
+
+typedef struct _DEVICEMEM_HISTORY_QUERY_OUT_
+{
+ IMG_UINT32 ui32NumResults;
+ /* result 0 is the newest */
+ DEVICEMEM_HISTORY_QUERY_OUT_RESULT sResults[DEVICEMEM_HISTORY_QUERY_OUT_MAX_RESULTS];
+} DEVICEMEM_HISTORY_QUERY_OUT;
+
+IMG_BOOL
+DevicememHistoryQuery(DEVICEMEM_HISTORY_QUERY_IN *psQueryIn,
+ DEVICEMEM_HISTORY_QUERY_OUT *psQueryOut,
+ IMG_UINT32 ui32PageSizeBytes,
+ IMG_BOOL bMatchAnyAllocInPage);
+
+#endif
diff --git a/drivers/gpu/drm/img-rogue/devicemem_pdump.h b/drivers/gpu/drm/img-rogue/devicemem_pdump.h
new file mode 100644
index 000000000..09b28afe7
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/devicemem_pdump.h
@@ -0,0 +1,363 @@
+/*************************************************************************/ /*!
+@File
+@Title Device Memory Management PDump internal
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Services internal interface to PDump device memory management
+ functions that are shared between client and server code.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef DEVICEMEM_PDUMP_H
+#define DEVICEMEM_PDUMP_H
+
+#include "devicemem.h"
+#include "pdumpdefs.h"
+#include "pdump.h"
+
+#if defined(PDUMP)
+/*
+ * DevmemPDumpLoadMem()
+ *
+ * takes a memory descriptor, offset, and size, and takes the current contents
+ * of the memory at that location and writes it to the prm pdump file, and
+ * emits a pdump LDB to load the data from that file. The intention here is
+ * that the contents of the simulated buffer upon pdump playback will be made
+ * to be the same as they are when this command is run, enabling pdump of
+ * cases where the memory has been modified externally, i.e. by the host cpu
+ * or by a third party.
+ */
+void
+DevmemPDumpLoadMem(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_DEVMEM_SIZE_T uiSize,
+ PDUMP_FLAGS_T uiPDumpFlags);
+
+/*
+ * DevmemPDumpLoadZeroMem()
+ *
+ * As DevmemPDumpLoadMem() but the PDump allocation will be populated with
+ * zeros from the zero page in the parameter stream
+ */
+void
+DevmemPDumpLoadZeroMem(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_DEVMEM_SIZE_T uiSize,
+ PDUMP_FLAGS_T uiPDumpFlags);
+
+/*
+ * DevmemPDumpLoadMemValue32()
+ *
+ * As above but dumps the value at a dword-aligned address in plain text to
+ * the pdump script2 file. Useful for patching a buffer at pdump playback by
+ * simply editing the script output file.
+ *
+ * (The same functionality can be achieved by the above function but the
+ * binary PARAM file must be patched in that case.)
+ */
+IMG_INTERNAL void
+DevmemPDumpLoadMemValue32(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_UINT32 ui32Value,
+ PDUMP_FLAGS_T uiPDumpFlags);
+
+/*
+ * DevmemPDumpMemValue64()
+ *
+ * As above but dumps the 64bit-value at a dword-aligned address in plain text
+ * to the pdump script2 file. Useful for patching a buffer at pdump playback by
+ * simply editing the script output file.
+ *
+ * (The same functionality can be achieved by the above function but the
+ * binary PARAM file must be patched in that case.)
+ */
+IMG_INTERNAL void
+DevmemPDumpLoadMemValue64(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_UINT64 ui64Value,
+ PDUMP_FLAGS_T uiPDumpFlags);
+
+/*
+ * DevmemPDumpPageCatBaseToSAddr()
+ *
+ * Returns the symbolic address of a piece of memory represented by an offset
+ * into the mem descriptor.
+ */
+PVRSRV_ERROR
+DevmemPDumpPageCatBaseToSAddr(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T *puiMemOffset,
+ IMG_CHAR *pszName,
+ IMG_UINT32 ui32Size);
+
+/*
+ * DevmemPDumpSaveToFile()
+ *
+ * Emits a pdump SAB to cause the current contents of the memory to be written
+ * to the given file during playback
+ */
+void
+DevmemPDumpSaveToFile(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_DEVMEM_SIZE_T uiSize,
+ const IMG_CHAR *pszFilename,
+ IMG_UINT32 uiFileOffset);
+
+/*
+ * DevmemPDumpSaveToFileVirtual()
+ *
+ * Emits a pdump SAB, just like DevmemPDumpSaveToFile(), but uses the virtual
+ * address and device MMU context to cause the pdump player to traverse the
+ * MMU page tables itself.
+ */
+void
+DevmemPDumpSaveToFileVirtual(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_DEVMEM_SIZE_T uiSize,
+ const IMG_CHAR *pszFilename,
+ IMG_UINT32 ui32FileOffset,
+ IMG_UINT32 ui32PdumpFlags);
+
+/*
+ * DevmemPDumpDataDescriptor()
+ *
+ * Emits a pdump CMD:OutputData, using the virtual address and device MMU
+ * context. Provides more flexibility than a pdump SAB because metadata can
+ * be passed to an external pdump player library via the command header.
+ */
+void
+DevmemPDumpDataDescriptor(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_DEVMEM_SIZE_T uiSize,
+ const IMG_CHAR *pszFilename,
+ IMG_UINT32 ui32HeaderType,
+ IMG_UINT32 ui32ElementType,
+ IMG_UINT32 ui32ElementCount,
+ IMG_UINT32 ui32PdumpFlags);
+
+
+/*
+ *
+ * DevmemPDumpDevmemPol32()
+ *
+ * Writes a PDump 'POL' command to wait for a masked 32-bit memory location to
+ * become the specified value.
+ */
+PVRSRV_ERROR
+DevmemPDumpDevmemPol32(const DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ PDUMP_POLL_OPERATOR eOperator,
+ PDUMP_FLAGS_T ui32PDumpFlags);
+
+#if defined(__KERNEL__)
+/*
+ *
+ * DevmemPDumpDevmemCheck32()
+ *
+ * Writes a PDump 'POL' command to run a single-shot check for a masked
+ * 32-bit memory location to match the specified value.
+ */
+PVRSRV_ERROR
+DevmemPDumpDevmemCheck32(const DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ PDUMP_POLL_OPERATOR eOperator,
+ PDUMP_FLAGS_T ui32PDumpFlags);
+#endif
+
+/*
+ * DevmemPDumpCBP()
+ *
+ * Polls for space in circular buffer. Reads the read offset from memory and
+ * waits until there is enough space to write the packet.
+ *
+ * psMemDesc - MemDesc which contains the read offset
+ * uiReadOffset - Offset into MemDesc to the read offset
+ * uiWriteOffset - Current write offset
+ * uiPacketSize - Size of packet to write
+ * uiBufferSize - Size of circular buffer
+ */
+PVRSRV_ERROR
+DevmemPDumpCBP(const DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T uiReadOffset,
+ IMG_DEVMEM_OFFSET_T uiWriteOffset,
+ IMG_DEVMEM_SIZE_T uiPacketSize,
+ IMG_DEVMEM_SIZE_T uiBufferSize);
+
+#else /* PDUMP */
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemPDumpLoadMem)
+#endif
+static INLINE void
+DevmemPDumpLoadMem(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_DEVMEM_SIZE_T uiSize,
+ PDUMP_FLAGS_T uiPDumpFlags)
+{
+ PVR_UNREFERENCED_PARAMETER(psMemDesc);
+ PVR_UNREFERENCED_PARAMETER(uiOffset);
+ PVR_UNREFERENCED_PARAMETER(uiSize);
+ PVR_UNREFERENCED_PARAMETER(uiPDumpFlags);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemPDumpLoadMemValue32)
+#endif
+static INLINE void
+DevmemPDumpLoadMemValue32(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_UINT32 ui32Value,
+ PDUMP_FLAGS_T uiPDumpFlags)
+{
+ PVR_UNREFERENCED_PARAMETER(psMemDesc);
+ PVR_UNREFERENCED_PARAMETER(uiOffset);
+ PVR_UNREFERENCED_PARAMETER(ui32Value);
+ PVR_UNREFERENCED_PARAMETER(uiPDumpFlags);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemPDumpLoadMemValue64)
+#endif
+static INLINE void
+DevmemPDumpLoadMemValue64(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_UINT64 ui64Value,
+ PDUMP_FLAGS_T uiPDumpFlags)
+{
+ PVR_UNREFERENCED_PARAMETER(psMemDesc);
+ PVR_UNREFERENCED_PARAMETER(uiOffset);
+ PVR_UNREFERENCED_PARAMETER(ui64Value);
+ PVR_UNREFERENCED_PARAMETER(uiPDumpFlags);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemPDumpPageCatBaseToSAddr)
+#endif
+static INLINE PVRSRV_ERROR
+DevmemPDumpPageCatBaseToSAddr(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T *puiMemOffset,
+ IMG_CHAR *pszName,
+ IMG_UINT32 ui32Size)
+{
+ PVR_UNREFERENCED_PARAMETER(psMemDesc);
+ PVR_UNREFERENCED_PARAMETER(puiMemOffset);
+ PVR_UNREFERENCED_PARAMETER(pszName);
+ PVR_UNREFERENCED_PARAMETER(ui32Size);
+
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemPDumpSaveToFile)
+#endif
+static INLINE void
+DevmemPDumpSaveToFile(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_DEVMEM_SIZE_T uiSize,
+ const IMG_CHAR *pszFilename,
+ IMG_UINT32 uiFileOffset)
+{
+ PVR_UNREFERENCED_PARAMETER(psMemDesc);
+ PVR_UNREFERENCED_PARAMETER(uiOffset);
+ PVR_UNREFERENCED_PARAMETER(uiSize);
+ PVR_UNREFERENCED_PARAMETER(pszFilename);
+ PVR_UNREFERENCED_PARAMETER(uiFileOffset);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemPDumpSaveToFileVirtual)
+#endif
+static INLINE void
+DevmemPDumpSaveToFileVirtual(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_DEVMEM_SIZE_T uiSize,
+ const IMG_CHAR *pszFilename,
+ IMG_UINT32 ui32FileOffset,
+ IMG_UINT32 ui32PdumpFlags)
+{
+ PVR_UNREFERENCED_PARAMETER(psMemDesc);
+ PVR_UNREFERENCED_PARAMETER(uiOffset);
+ PVR_UNREFERENCED_PARAMETER(uiSize);
+ PVR_UNREFERENCED_PARAMETER(pszFilename);
+ PVR_UNREFERENCED_PARAMETER(ui32FileOffset);
+ PVR_UNREFERENCED_PARAMETER(ui32PdumpFlags);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemPDumpDevmemPol32)
+#endif
+static INLINE PVRSRV_ERROR
+DevmemPDumpDevmemPol32(const DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ PDUMP_POLL_OPERATOR eOperator,
+ PDUMP_FLAGS_T ui32PDumpFlags)
+{
+ PVR_UNREFERENCED_PARAMETER(psMemDesc);
+ PVR_UNREFERENCED_PARAMETER(uiOffset);
+ PVR_UNREFERENCED_PARAMETER(ui32Value);
+ PVR_UNREFERENCED_PARAMETER(ui32Mask);
+ PVR_UNREFERENCED_PARAMETER(eOperator);
+ PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
+
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemPDumpCBP)
+#endif
+static INLINE PVRSRV_ERROR
+DevmemPDumpCBP(const DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T uiReadOffset,
+ IMG_DEVMEM_OFFSET_T uiWriteOffset,
+ IMG_DEVMEM_SIZE_T uiPacketSize,
+ IMG_DEVMEM_SIZE_T uiBufferSize)
+{
+ PVR_UNREFERENCED_PARAMETER(psMemDesc);
+ PVR_UNREFERENCED_PARAMETER(uiReadOffset);
+ PVR_UNREFERENCED_PARAMETER(uiWriteOffset);
+ PVR_UNREFERENCED_PARAMETER(uiPacketSize);
+ PVR_UNREFERENCED_PARAMETER(uiBufferSize);
+
+ return PVRSRV_OK;
+}
+#endif /* PDUMP */
+#endif /* DEVICEMEM_PDUMP_H */
diff --git a/drivers/gpu/drm/img-rogue/devicemem_server.c b/drivers/gpu/drm/img-rogue/devicemem_server.c
new file mode 100644
index 000000000..65762fd3a
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/devicemem_server.c
@@ -0,0 +1,1815 @@
+/*************************************************************************/ /*!
+@File
+@Title Device Memory Management
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Server-side component of the Device Memory Management.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+/* our exported API */
+#include "devicemem_server.h"
+#include "devicemem_utils.h"
+#include "devicemem.h"
+
+#include "device.h" /* For device node */
+#include "img_types.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+
+#include "mmu_common.h"
+#include "pdump_km.h"
+#include "pmr.h"
+#include "physmem.h"
+#include "pdumpdesc.h"
+
+#include "allocmem.h"
+#include "osfunc.h"
+#include "lock.h"
+
+#include "pvrsrv.h" /* for PVRSRVGetPVRSRVData() */
+
+#define DEVMEMCTX_FLAGS_FAULT_ADDRESS_AVAILABLE (1 << 0)
+
+struct _DEVMEMINT_CTX_
+{
+ PVRSRV_DEVICE_NODE *psDevNode;
+
+ /* MMU common code needs to have a context. There's a one-to-one
+ correspondence between device memory context and MMU context,
+ but we have the abstraction here so that we don't need to care
+ what the MMU does with its context, and the MMU code need not
+ know about us at all. */
+ MMU_CONTEXT *psMMUContext;
+
+ ATOMIC_T hRefCount;
+
+ /* This handle is for devices that require notification when a new
+ memory context is created and they need to store private data that
+ is associated with the context. */
+ IMG_HANDLE hPrivData;
+
+ /* Protects access to sProcessNotifyListHead */
+ POSWR_LOCK hListLock;
+
+ /* The following tracks UM applications that need to be notified of a
+ * page fault */
+ DLLIST_NODE sProcessNotifyListHead;
+ /* The following is a node for the list of registered devmem contexts */
+ DLLIST_NODE sPageFaultNotifyListElem;
+
+ /* Device virtual address of a page fault on this context */
+ IMG_DEV_VIRTADDR sFaultAddress;
+
+ /* General purpose flags */
+ IMG_UINT32 ui32Flags;
+};
+
+struct _DEVMEMINT_CTX_EXPORT_
+{
+ DEVMEMINT_CTX *psDevmemCtx;
+ PMR *psPMR;
+ ATOMIC_T hRefCount;
+ DLLIST_NODE sNode;
+};
+
+struct _DEVMEMINT_HEAP_
+{
+ struct _DEVMEMINT_CTX_ *psDevmemCtx;
+ IMG_UINT32 uiLog2PageSize;
+ ATOMIC_T hRefCount;
+};
+
+struct _DEVMEMINT_RESERVATION_
+{
+ struct _DEVMEMINT_HEAP_ *psDevmemHeap;
+ IMG_DEV_VIRTADDR sBase;
+ IMG_DEVMEM_SIZE_T uiLength;
+};
+
+struct _DEVMEMINT_MAPPING_
+{
+ struct _DEVMEMINT_RESERVATION_ *psReservation;
+ PMR *psPMR;
+ IMG_UINT32 uiNumPages;
+};
+
+struct _DEVMEMINT_PF_NOTIFY_
+{
+ IMG_UINT32 ui32PID;
+ DLLIST_NODE sProcessNotifyListElem;
+};
+
+/*************************************************************************/ /*!
+@Function DevmemIntCtxAcquire
+@Description Acquire a reference to the provided device memory context.
+@Return None
+*/ /**************************************************************************/
+static INLINE void DevmemIntCtxAcquire(DEVMEMINT_CTX *psDevmemCtx)
+{
+ OSAtomicIncrement(&psDevmemCtx->hRefCount);
+}
+
+/*************************************************************************/ /*!
+@Function DevmemIntCtxRelease
+@Description Release the reference to the provided device memory context.
+ If this is the last reference which was taken then the
+ memory context will be freed.
+@Return None
+*/ /**************************************************************************/
+static INLINE void DevmemIntCtxRelease(DEVMEMINT_CTX *psDevmemCtx)
+{
+ if (OSAtomicDecrement(&psDevmemCtx->hRefCount) == 0)
+ {
+ /* The last reference has gone, destroy the context */
+ PVRSRV_DEVICE_NODE *psDevNode = psDevmemCtx->psDevNode;
+ DLLIST_NODE *psNode, *psNodeNext;
+
+ /* If there are any PIDs registered for page fault notification.
+ * Loop through the registered PIDs and free each one */
+ dllist_foreach_node(&(psDevmemCtx->sProcessNotifyListHead), psNode, psNodeNext)
+ {
+ DEVMEMINT_PF_NOTIFY *psNotifyNode =
+ IMG_CONTAINER_OF(psNode, DEVMEMINT_PF_NOTIFY, sProcessNotifyListElem);
+ dllist_remove_node(psNode);
+ OSFreeMem(psNotifyNode);
+ }
+
+ /* If this context is in the list registered for a debugger, remove
+ * from that list */
+ if (dllist_node_is_in_list(&psDevmemCtx->sPageFaultNotifyListElem))
+ {
+ dllist_remove_node(&psDevmemCtx->sPageFaultNotifyListElem);
+ }
+
+ if (psDevNode->pfnUnregisterMemoryContext)
+ {
+ psDevNode->pfnUnregisterMemoryContext(psDevmemCtx->hPrivData);
+ }
+ MMU_ContextDestroy(psDevmemCtx->psMMUContext);
+
+ OSWRLockDestroy(psDevmemCtx->hListLock);
+
+ PVR_DPF((PVR_DBG_MESSAGE, "%s: Freed memory context %p",
+ __func__, psDevmemCtx));
+ OSFreeMem(psDevmemCtx);
+ }
+}
+
+/*************************************************************************/ /*!
+@Function DevmemIntHeapAcquire
+@Description Acquire a reference to the provided device memory heap.
+@Return None
+*/ /**************************************************************************/
+static INLINE void DevmemIntHeapAcquire(DEVMEMINT_HEAP *psDevmemHeap)
+{
+ OSAtomicIncrement(&psDevmemHeap->hRefCount);
+}
+
+/*************************************************************************/ /*!
+@Function DevmemIntHeapRelease
+@Description Release the reference to the provided device memory heap.
+ If this is the last reference which was taken then the
+ memory context will be freed.
+@Return None
+*/ /**************************************************************************/
+static INLINE void DevmemIntHeapRelease(DEVMEMINT_HEAP *psDevmemHeap)
+{
+ OSAtomicDecrement(&psDevmemHeap->hRefCount);
+}
+
+PVRSRV_ERROR
+DevmemIntUnpin(PMR *psPMR)
+{
+ PVRSRV_ERROR eError;
+
+ /* Unpin */
+ eError = PMRUnpinPMR(psPMR, IMG_FALSE);
+
+ return eError;
+}
+
+PVRSRV_ERROR
+DevmemIntUnpinInvalidate(DEVMEMINT_MAPPING *psDevmemMapping, PMR *psPMR)
+{
+ PVRSRV_ERROR eError;
+
+ eError = PMRUnpinPMR(psPMR, IMG_TRUE);
+ PVR_GOTO_IF_ERROR(eError, e_exit);
+
+ /* Invalidate mapping */
+ eError = MMU_ChangeValidity(psDevmemMapping->psReservation->psDevmemHeap->psDevmemCtx->psMMUContext,
+ psDevmemMapping->psReservation->sBase,
+ psDevmemMapping->uiNumPages,
+ psDevmemMapping->psReservation->psDevmemHeap->uiLog2PageSize,
+ IMG_FALSE, /* !< Choose to invalidate PT entries */
+ psPMR);
+
+e_exit:
+ return eError;
+}
+
+PVRSRV_ERROR
+DevmemIntPin(PMR *psPMR)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ /* Start the pinning */
+ eError = PMRPinPMR(psPMR);
+
+ return eError;
+}
+
+PVRSRV_ERROR
+DevmemIntPinValidate(DEVMEMINT_MAPPING *psDevmemMapping, PMR *psPMR)
+{
+ PVRSRV_ERROR eError;
+ PVRSRV_ERROR eErrorMMU = PVRSRV_OK;
+ IMG_UINT32 uiLog2PageSize = psDevmemMapping->psReservation->psDevmemHeap->uiLog2PageSize;
+
+ /* Start the pinning */
+ eError = PMRPinPMR(psPMR);
+
+ if (eError == PVRSRV_OK)
+ {
+ /* Make mapping valid again */
+ eErrorMMU = MMU_ChangeValidity(psDevmemMapping->psReservation->psDevmemHeap->psDevmemCtx->psMMUContext,
+ psDevmemMapping->psReservation->sBase,
+ psDevmemMapping->uiNumPages,
+ uiLog2PageSize,
+ IMG_TRUE, /* !< Choose to make PT entries valid again */
+ psPMR);
+ }
+ else if (eError == PVRSRV_ERROR_PMR_NEW_MEMORY)
+ {
+ /* If we lost the physical backing we have to map it again because
+ * the old physical addresses are not valid anymore. */
+ PMR_FLAGS_T uiFlags;
+ uiFlags = PMR_Flags(psPMR);
+
+ eErrorMMU = MMU_MapPages(psDevmemMapping->psReservation->psDevmemHeap->psDevmemCtx->psMMUContext,
+ uiFlags,
+ psDevmemMapping->psReservation->sBase,
+ psPMR,
+ 0,
+ psDevmemMapping->uiNumPages,
+ NULL,
+ uiLog2PageSize);
+ }
+
+ /* Just overwrite eError if the mappings failed.
+ * PMR_NEW_MEMORY has to be propagated to the user. */
+ if (eErrorMMU != PVRSRV_OK)
+ {
+ eError = eErrorMMU;
+ }
+
+ return eError;
+}
+
+/*************************************************************************/ /*!
+@Function DevmemServerGetImportHandle
+@Description For given exportable memory descriptor returns PMR handle.
+@Return Memory is exportable - Success
+ PVRSRV_ERROR failure code
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemServerGetImportHandle(DEVMEM_MEMDESC *psMemDesc,
+ IMG_HANDLE *phImport)
+{
+ PVRSRV_ERROR eError;
+
+ if ((GetImportProperties(psMemDesc->psImport) & DEVMEM_PROPERTIES_EXPORTABLE) == 0)
+ {
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_CANT_EXPORT_SUBALLOCATION, e0);
+ }
+
+ /* A new handle means a new import tracking the PMR.
+ * Hence the source PMR memory layout should be marked fixed
+ * to make sure the importer view of the memory is the same as
+ * the exporter throughout its lifetime */
+ PMR_SetLayoutFixed((PMR *)psMemDesc->psImport->hPMR, IMG_TRUE);
+
+ *phImport = psMemDesc->psImport->hPMR;
+ return PVRSRV_OK;
+
+e0:
+ return eError;
+}
+
+/*************************************************************************/ /*!
+@Function DevmemServerGetHeapHandle
+@Description For given reservation returns the Heap handle.
+@Return PVRSRV_ERROR failure code
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemServerGetHeapHandle(DEVMEMINT_RESERVATION *psReservation,
+ IMG_HANDLE *phHeap)
+{
+ if (psReservation == NULL || phHeap == NULL)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ *phHeap = psReservation->psDevmemHeap;
+
+ return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
+@Function DevmemServerGetContext
+@Description For given heap returns the context.
+@Return PVRSRV_ERROR failure code
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemServerGetContext(DEVMEMINT_HEAP *psDevmemHeap,
+ DEVMEMINT_CTX **ppsDevmemCtxPtr)
+{
+ if (psDevmemHeap == NULL || ppsDevmemCtxPtr == NULL)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ *ppsDevmemCtxPtr = psDevmemHeap->psDevmemCtx;
+
+ return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
+@Function DevmemServerGetPrivData
+@Description For given context returns the private data handle.
+@Return PVRSRV_ERROR failure code
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemServerGetPrivData(DEVMEMINT_CTX *psDevmemCtx,
+ IMG_HANDLE *phPrivData)
+{
+ if (psDevmemCtx == NULL || phPrivData == NULL)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ *phPrivData = psDevmemCtx->hPrivData;
+
+ return PVRSRV_OK;
+}
+
+/*************************************************************************/ /*!
+@Function DevmemIntCtxCreate
+@Description Creates and initialises a device memory context.
+@Return valid Device Memory context handle - Success
+ PVRSRV_ERROR failure code
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemIntCtxCreate(CONNECTION_DATA *psConnection,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_BOOL bKernelMemoryCtx,
+ DEVMEMINT_CTX **ppsDevmemCtxPtr,
+ IMG_HANDLE *hPrivData,
+ IMG_UINT32 *pui32CPUCacheLineSize)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_CTX *psDevmemCtx;
+ IMG_HANDLE hPrivDataInt = NULL;
+ MMU_DEVICEATTRIBS *psMMUDevAttrs = psDeviceNode->pfnGetMMUDeviceAttributes(psDeviceNode,
+ bKernelMemoryCtx);
+
+ PVR_DPF((PVR_DBG_MESSAGE, "%s", __func__));
+
+ /*
+ * Ensure that we are safe to perform unaligned accesses on memory
+ * we mark write-combine, as the compiler might generate
+ * instructions operating on this memory which require this
+ * assumption to be true.
+ */
+ PVR_ASSERT(OSIsWriteCombineUnalignedSafe());
+
+ /* allocate a Devmem context */
+ psDevmemCtx = OSAllocMem(sizeof(*psDevmemCtx));
+ PVR_LOG_GOTO_IF_NOMEM(psDevmemCtx, eError, fail_alloc);
+
+ OSAtomicWrite(&psDevmemCtx->hRefCount, 1);
+ psDevmemCtx->psDevNode = psDeviceNode;
+
+ /* Call down to MMU context creation */
+
+ eError = MMU_ContextCreate(psConnection,
+ psDeviceNode,
+ &psDevmemCtx->psMMUContext,
+ psMMUDevAttrs);
+ PVR_LOG_GOTO_IF_ERROR(eError, "MMU_ContextCreate", fail_mmucontext);
+
+ if (psDeviceNode->pfnRegisterMemoryContext)
+ {
+ eError = psDeviceNode->pfnRegisterMemoryContext(psDeviceNode, psDevmemCtx->psMMUContext, &hPrivDataInt);
+ PVR_LOG_GOTO_IF_ERROR(eError, "pfnRegisterMemoryContext", fail_register);
+ }
+
+ /* Store the private data as it is required to unregister the memory context */
+ psDevmemCtx->hPrivData = hPrivDataInt;
+ *hPrivData = hPrivDataInt;
+ *ppsDevmemCtxPtr = psDevmemCtx;
+
+ /* Pass the CPU cache line size through the bridge to the user mode as it can't be queried in user mode.*/
+ *pui32CPUCacheLineSize = OSCPUCacheAttributeSize(OS_CPU_CACHE_ATTRIBUTE_LINE_SIZE);
+
+ /* Initialise the PID notify list */
+ OSWRLockCreate(&psDevmemCtx->hListLock);
+ dllist_init(&(psDevmemCtx->sProcessNotifyListHead));
+ psDevmemCtx->sPageFaultNotifyListElem.psNextNode = NULL;
+ psDevmemCtx->sPageFaultNotifyListElem.psPrevNode = NULL;
+
+ /* Initialise page fault address */
+ psDevmemCtx->sFaultAddress.uiAddr = 0ULL;
+
+ /* Initialise flags */
+ psDevmemCtx->ui32Flags = 0;
+
+ return PVRSRV_OK;
+
+fail_register:
+ MMU_ContextDestroy(psDevmemCtx->psMMUContext);
+fail_mmucontext:
+ OSFreeMem(psDevmemCtx);
+fail_alloc:
+ PVR_ASSERT(eError != PVRSRV_OK);
+ return eError;
+}
+
+/*************************************************************************/ /*!
+@Function DevmemIntHeapCreate
+@Description Creates and initialises a device memory heap.
+@Return valid Device Memory heap handle - Success
+ PVRSRV_ERROR failure code
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemIntHeapCreate(DEVMEMINT_CTX *psDevmemCtx,
+ IMG_DEV_VIRTADDR sHeapBaseAddr,
+ IMG_DEVMEM_SIZE_T uiHeapLength,
+ IMG_UINT32 uiLog2DataPageSize,
+ DEVMEMINT_HEAP **ppsDevmemHeapPtr)
+{
+ DEVMEMINT_HEAP *psDevmemHeap;
+
+ PVR_DPF((PVR_DBG_MESSAGE, "%s", __func__));
+
+ /* allocate a Devmem context */
+ psDevmemHeap = OSAllocMem(sizeof(*psDevmemHeap));
+ PVR_LOG_RETURN_IF_NOMEM(psDevmemHeap, "psDevmemHeap");
+
+ psDevmemHeap->psDevmemCtx = psDevmemCtx;
+
+ DevmemIntCtxAcquire(psDevmemHeap->psDevmemCtx);
+
+ OSAtomicWrite(&psDevmemHeap->hRefCount, 1);
+
+ psDevmemHeap->uiLog2PageSize = uiLog2DataPageSize;
+
+ *ppsDevmemHeapPtr = psDevmemHeap;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR DevmemIntAllocDefBackingPage(PVRSRV_DEVICE_NODE *psDevNode,
+ PVRSRV_DEF_PAGE *psDefPage,
+ IMG_INT uiInitValue,
+ IMG_CHAR *pcDefPageName,
+ IMG_BOOL bInitPage)
+{
+ IMG_UINT32 ui32RefCnt;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ OSLockAcquire(psDefPage->psPgLock);
+
+ /* We know there will not be 4G number of sparse PMR's */
+ ui32RefCnt = OSAtomicIncrement(&psDefPage->atRefCounter);
+
+ if (1 == ui32RefCnt)
+ {
+ IMG_DEV_PHYADDR sDevPhysAddr = {0};
+
+#if defined(PDUMP)
+ PDUMPCOMMENT(psDevNode, "Alloc %s page object", pcDefPageName);
+#endif
+
+ /* Allocate the dummy page required for sparse backing */
+ eError = DevPhysMemAlloc(psDevNode,
+ (1 << psDefPage->ui32Log2PgSize),
+ 0,
+ uiInitValue,
+ bInitPage,
+#if defined(PDUMP)
+ psDevNode->psMMUDevAttrs->pszMMUPxPDumpMemSpaceName,
+ pcDefPageName,
+ &psDefPage->hPdumpPg,
+#endif
+ &psDefPage->sPageHandle,
+ &sDevPhysAddr);
+ if (PVRSRV_OK != eError)
+ {
+ OSAtomicDecrement(&psDefPage->atRefCounter);
+ }
+ else
+ {
+ psDefPage->ui64PgPhysAddr = sDevPhysAddr.uiAddr;
+ }
+ }
+
+ OSLockRelease(psDefPage->psPgLock);
+
+ return eError;
+}
+
+void DevmemIntFreeDefBackingPage(PVRSRV_DEVICE_NODE *psDevNode,
+ PVRSRV_DEF_PAGE *psDefPage,
+ IMG_CHAR *pcDefPageName)
+{
+ IMG_UINT32 ui32RefCnt;
+
+ ui32RefCnt = OSAtomicRead(&psDefPage->atRefCounter);
+
+ /* For the cases where the dummy page allocation fails due to lack of memory
+ * The refcount can still be 0 even for a sparse allocation */
+ if (0 != ui32RefCnt)
+ {
+ OSLockAcquire(psDefPage->psPgLock);
+
+ /* We know there will not be 4G number of sparse PMR's */
+ ui32RefCnt = OSAtomicDecrement(&psDefPage->atRefCounter);
+
+ if (0 == ui32RefCnt)
+ {
+ PDUMPCOMMENT(psDevNode, "Free %s page object", pcDefPageName);
+
+ /* Free the dummy page when refcount reaches zero */
+ DevPhysMemFree(psDevNode,
+#if defined(PDUMP)
+ psDefPage->hPdumpPg,
+#endif
+ &psDefPage->sPageHandle);
+
+#if defined(PDUMP)
+ psDefPage->hPdumpPg = NULL;
+#endif
+ psDefPage->ui64PgPhysAddr = MMU_BAD_PHYS_ADDR;
+ }
+
+ OSLockRelease(psDefPage->psPgLock);
+ }
+
+}
+
+PVRSRV_ERROR
+DevmemIntMapPages(DEVMEMINT_RESERVATION *psReservation,
+ PMR *psPMR,
+ IMG_UINT32 ui32PageCount,
+ IMG_UINT32 ui32PhysicalPgOffset,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ IMG_DEV_VIRTADDR sDevVAddrBase)
+{
+ PVRSRV_ERROR eError;
+
+ if (psReservation->psDevmemHeap->uiLog2PageSize > PMR_GetLog2Contiguity(psPMR))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Device heap and PMR have incompatible Log2Contiguity (%u - %u). "
+ "PMR contiguity must be a multiple of the heap contiguity!",
+ __func__,
+ psReservation->psDevmemHeap->uiLog2PageSize,
+ PMR_GetLog2Contiguity(psPMR)));
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, e0);
+ }
+
+ eError = MMU_MapPages(psReservation->psDevmemHeap->psDevmemCtx->psMMUContext,
+ uiFlags,
+ sDevVAddrBase,
+ psPMR,
+ ui32PhysicalPgOffset,
+ ui32PageCount,
+ NULL,
+ psReservation->psDevmemHeap->uiLog2PageSize);
+
+e0:
+ return eError;
+}
+
+PVRSRV_ERROR
+DevmemIntUnmapPages(DEVMEMINT_RESERVATION *psReservation,
+ IMG_DEV_VIRTADDR sDevVAddrBase,
+ IMG_UINT32 ui32PageCount)
+{
+ /* Unmap the pages and mark them invalid in the MMU PTE */
+ MMU_UnmapPages(psReservation->psDevmemHeap->psDevmemCtx->psMMUContext,
+ 0,
+ sDevVAddrBase,
+ ui32PageCount,
+ NULL,
+ psReservation->psDevmemHeap->uiLog2PageSize,
+ 0);
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+DevmemIntMapPMR(DEVMEMINT_HEAP *psDevmemHeap,
+ DEVMEMINT_RESERVATION *psReservation,
+ PMR *psPMR,
+ PVRSRV_MEMALLOCFLAGS_T uiMapFlags,
+ DEVMEMINT_MAPPING **ppsMappingPtr)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_MAPPING *psMapping;
+ /* number of pages (device pages) that allocation spans */
+ IMG_UINT32 ui32NumDevPages;
+ /* device virtual address of start of allocation */
+ IMG_DEV_VIRTADDR sAllocationDevVAddr;
+ /* and its length */
+ IMG_DEVMEM_SIZE_T uiAllocationSize;
+ IMG_UINT32 uiLog2HeapContiguity = psDevmemHeap->uiLog2PageSize;
+ IMG_BOOL bIsSparse = IMG_FALSE, bNeedBacking = IMG_FALSE;
+ PVRSRV_DEVICE_NODE *psDevNode;
+ PMR_FLAGS_T uiPMRFlags;
+ PVRSRV_DEF_PAGE *psDefPage;
+ IMG_CHAR *pszPageName;
+
+ if (uiLog2HeapContiguity > PMR_GetLog2Contiguity(psPMR))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Device heap and PMR have incompatible contiguity (%u - %u). "
+ "Heap contiguity must be a multiple of the heap contiguity!",
+ __func__,
+ uiLog2HeapContiguity,
+ PMR_GetLog2Contiguity(psPMR) ));
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, e0);
+ }
+ psDevNode = psDevmemHeap->psDevmemCtx->psDevNode;
+
+ /* allocate memory to record the mapping info */
+ psMapping = OSAllocMem(sizeof(*psMapping));
+ PVR_LOG_GOTO_IF_NOMEM(psMapping, eError, e0);
+
+ uiAllocationSize = psReservation->uiLength;
+
+ ui32NumDevPages = 0xffffffffU & ( ( (uiAllocationSize - 1) >> uiLog2HeapContiguity) + 1);
+ PVR_ASSERT((IMG_DEVMEM_SIZE_T) ui32NumDevPages << uiLog2HeapContiguity == uiAllocationSize);
+
+ eError = PMRLockSysPhysAddresses(psPMR);
+ PVR_GOTO_IF_ERROR(eError, e2);
+
+ sAllocationDevVAddr = psReservation->sBase;
+
+ /*Check if the PMR that needs to be mapped is sparse */
+ bIsSparse = PMR_IsSparse(psPMR);
+ if (bIsSparse)
+ {
+ /*Get the flags*/
+ uiPMRFlags = PMR_Flags(psPMR);
+ bNeedBacking = PVRSRV_IS_SPARSE_DUMMY_BACKING_REQUIRED(uiPMRFlags);
+
+ if (bNeedBacking)
+ {
+ IMG_INT uiInitValue;
+
+ if (PVRSRV_IS_SPARSE_ZERO_BACKING_REQUIRED(uiPMRFlags))
+ {
+ psDefPage = &psDevmemHeap->psDevmemCtx->psDevNode->sDevZeroPage;
+ uiInitValue = PVR_ZERO_PAGE_INIT_VALUE;
+ pszPageName = DEV_ZERO_PAGE;
+ }
+ else
+ {
+ psDefPage = &psDevmemHeap->psDevmemCtx->psDevNode->sDummyPage;
+ uiInitValue = PVR_DUMMY_PAGE_INIT_VALUE;
+ pszPageName = DUMMY_PAGE;
+ }
+
+ /* Error is logged with in the function if any failures.
+ * As the allocation fails we need to fail the map request and
+ * return appropriate error
+ *
+ * Allocation of dummy/zero page is done after locking the pages for PMR physically
+ * By implementing this way, the best case path of dummy/zero page being most likely to be
+ * allocated after physically locking down pages, is considered.
+ * If the dummy/zero page allocation fails, we do unlock the physical address and the impact
+ * is a bit more in on demand mode of operation */
+ eError = DevmemIntAllocDefBackingPage(psDevNode,
+ psDefPage,
+ uiInitValue,
+ pszPageName,
+ IMG_TRUE);
+ PVR_GOTO_IF_ERROR(eError, e3);
+ }
+
+ /* N.B. We pass mapping permission flags to MMU_MapPages and let
+ * it reject the mapping if the permissions on the PMR are not compatible. */
+ eError = MMU_MapPages(psDevmemHeap->psDevmemCtx->psMMUContext,
+ uiMapFlags,
+ sAllocationDevVAddr,
+ psPMR,
+ 0,
+ ui32NumDevPages,
+ NULL,
+ uiLog2HeapContiguity);
+ PVR_GOTO_IF_ERROR(eError, e4);
+ }
+ else
+ {
+ eError = MMU_MapPMRFast(psDevmemHeap->psDevmemCtx->psMMUContext,
+ sAllocationDevVAddr,
+ psPMR,
+ (IMG_DEVMEM_SIZE_T) ui32NumDevPages << uiLog2HeapContiguity,
+ uiMapFlags,
+ uiLog2HeapContiguity);
+ PVR_GOTO_IF_ERROR(eError, e3);
+ }
+
+ psMapping->psReservation = psReservation;
+ psMapping->uiNumPages = ui32NumDevPages;
+ psMapping->psPMR = psPMR;
+
+ /* Don't bother with refcount on reservation, as a reservation
+ only ever holds one mapping, so we directly increment the
+ refcount on the heap instead */
+ DevmemIntHeapAcquire(psMapping->psReservation->psDevmemHeap);
+
+ *ppsMappingPtr = psMapping;
+
+ return PVRSRV_OK;
+e4:
+ if (bNeedBacking)
+ {
+ /*if the mapping failed, the allocated dummy ref count need
+ * to be handled accordingly */
+ DevmemIntFreeDefBackingPage(psDevmemHeap->psDevmemCtx->psDevNode,
+ psDefPage,
+ pszPageName);
+ }
+e3:
+ {
+ PVRSRV_ERROR eError1=PVRSRV_OK;
+ eError1 = PMRUnlockSysPhysAddresses(psPMR);
+ PVR_LOG_IF_ERROR(eError1, "PMRUnlockSysPhysAddresses");
+
+ *ppsMappingPtr = NULL;
+ }
+e2:
+ OSFreeMem(psMapping);
+
+e0:
+ PVR_ASSERT (eError != PVRSRV_OK);
+ return eError;
+}
+
+
+PVRSRV_ERROR
+DevmemIntUnmapPMR(DEVMEMINT_MAPPING *psMapping)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_HEAP *psDevmemHeap = psMapping->psReservation->psDevmemHeap;
+ /* device virtual address of start of allocation */
+ IMG_DEV_VIRTADDR sAllocationDevVAddr;
+ /* number of pages (device pages) that allocation spans */
+ IMG_UINT32 ui32NumDevPages;
+ IMG_BOOL bIsSparse = IMG_FALSE, bNeedBacking = IMG_FALSE;
+ PMR_FLAGS_T uiPMRFlags;
+
+ ui32NumDevPages = psMapping->uiNumPages;
+ sAllocationDevVAddr = psMapping->psReservation->sBase;
+
+ /*Check if the PMR that needs to be mapped is sparse */
+ bIsSparse = PMR_IsSparse(psMapping->psPMR);
+
+ if (bIsSparse)
+ {
+ /*Get the flags*/
+ uiPMRFlags = PMR_Flags(psMapping->psPMR);
+ bNeedBacking = PVRSRV_IS_SPARSE_DUMMY_BACKING_REQUIRED(uiPMRFlags);
+
+ if (bNeedBacking)
+ {
+ if (PVRSRV_IS_SPARSE_ZERO_BACKING_REQUIRED(uiPMRFlags))
+ {
+ DevmemIntFreeDefBackingPage(psDevmemHeap->psDevmemCtx->psDevNode,
+ &psDevmemHeap->psDevmemCtx->psDevNode->sDevZeroPage,
+ DEV_ZERO_PAGE);
+ }
+ else
+ {
+ DevmemIntFreeDefBackingPage(psDevmemHeap->psDevmemCtx->psDevNode,
+ &psDevmemHeap->psDevmemCtx->psDevNode->sDummyPage,
+ DUMMY_PAGE);
+ }
+ }
+
+ MMU_UnmapPages (psDevmemHeap->psDevmemCtx->psMMUContext,
+ 0,
+ sAllocationDevVAddr,
+ ui32NumDevPages,
+ NULL,
+ psMapping->psReservation->psDevmemHeap->uiLog2PageSize,
+ 0);
+ }
+ else
+ {
+ MMU_UnmapPMRFast(psDevmemHeap->psDevmemCtx->psMMUContext,
+ sAllocationDevVAddr,
+ ui32NumDevPages,
+ psMapping->psReservation->psDevmemHeap->uiLog2PageSize);
+ }
+
+
+
+ eError = PMRUnlockSysPhysAddresses(psMapping->psPMR);
+ PVR_ASSERT(eError == PVRSRV_OK);
+
+ /* Don't bother with refcount on reservation, as a reservation
+ only ever holds one mapping, so we directly decrement the
+ refcount on the heap instead */
+ DevmemIntHeapRelease(psDevmemHeap);
+
+ OSFreeMem(psMapping);
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR
+DevmemIntReserveRange(DEVMEMINT_HEAP *psDevmemHeap,
+ IMG_DEV_VIRTADDR sAllocationDevVAddr,
+ IMG_DEVMEM_SIZE_T uiAllocationSize,
+ DEVMEMINT_RESERVATION **ppsReservationPtr)
+{
+ PVRSRV_ERROR eError;
+ DEVMEMINT_RESERVATION *psReservation;
+
+ /* allocate memory to record the reservation info */
+ psReservation = OSAllocMem(sizeof(*psReservation));
+ PVR_LOG_GOTO_IF_NOMEM(psReservation, eError, e0);
+
+ psReservation->sBase = sAllocationDevVAddr;
+ psReservation->uiLength = uiAllocationSize;
+
+ eError = MMU_Alloc(psDevmemHeap->psDevmemCtx->psMMUContext,
+ uiAllocationSize,
+ &uiAllocationSize,
+ 0, /* IMG_UINT32 uiProtFlags */
+ 0, /* alignment is n/a since we supply devvaddr */
+ &sAllocationDevVAddr,
+ psDevmemHeap->uiLog2PageSize);
+ PVR_GOTO_IF_ERROR(eError, e1);
+
+ /* since we supplied the virt addr, MMU_Alloc shouldn't have
+ chosen a new one for us */
+ PVR_ASSERT(sAllocationDevVAddr.uiAddr == psReservation->sBase.uiAddr);
+
+ DevmemIntHeapAcquire(psDevmemHeap);
+
+ psReservation->psDevmemHeap = psDevmemHeap;
+ *ppsReservationPtr = psReservation;
+
+ return PVRSRV_OK;
+
+ /*
+ * error exit paths follow
+ */
+
+e1:
+ OSFreeMem(psReservation);
+
+e0:
+ PVR_ASSERT(eError != PVRSRV_OK);
+ return eError;
+}
+
+PVRSRV_ERROR
+DevmemIntUnreserveRange(DEVMEMINT_RESERVATION *psReservation)
+{
+ IMG_DEV_VIRTADDR sBase = psReservation->sBase;
+ IMG_UINT32 uiLength = psReservation->uiLength;
+ IMG_UINT32 uiLog2DataPageSize = psReservation->psDevmemHeap->uiLog2PageSize;
+
+ MMU_Free(psReservation->psDevmemHeap->psDevmemCtx->psMMUContext,
+ sBase,
+ uiLength,
+ uiLog2DataPageSize);
+
+ DevmemIntHeapRelease(psReservation->psDevmemHeap);
+ OSFreeMem(psReservation);
+
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR
+DevmemIntHeapDestroy(DEVMEMINT_HEAP *psDevmemHeap)
+{
+ if (OSAtomicRead(&psDevmemHeap->hRefCount) != 1)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "BUG! %s called but has too many references (%d) "
+ "which probably means allocations have been made from the heap and not freed",
+ __func__,
+ OSAtomicRead(&psDevmemHeap->hRefCount)));
+
+ /*
+ * Try again later when you've freed all the memory
+ *
+ * Note:
+ * We don't expect the application to retry (after all this call would
+ * succeed if the client had freed all the memory which it should have
+ * done before calling this function). However, given there should be
+ * an associated handle, when the handle base is destroyed it will free
+ * any allocations leaked by the client and then it will retry this call,
+ * which should then succeed.
+ */
+ return PVRSRV_ERROR_RETRY;
+ }
+
+ PVR_ASSERT(OSAtomicRead(&psDevmemHeap->hRefCount) == 1);
+
+ DevmemIntCtxRelease(psDevmemHeap->psDevmemCtx);
+
+ PVR_DPF((PVR_DBG_MESSAGE, "%s: Freed heap %p", __func__, psDevmemHeap));
+ OSFreeMem(psDevmemHeap);
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+DevmemIntChangeSparse(DEVMEMINT_HEAP *psDevmemHeap,
+ PMR *psPMR,
+ IMG_UINT32 ui32AllocPageCount,
+ IMG_UINT32 *pai32AllocIndices,
+ IMG_UINT32 ui32FreePageCount,
+ IMG_UINT32 *pai32FreeIndices,
+ SPARSE_MEM_RESIZE_FLAGS uiSparseFlags,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ IMG_DEV_VIRTADDR sDevVAddrBase,
+ IMG_UINT64 sCpuVAddrBase)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ IMG_UINT32 uiLog2PMRContiguity = PMR_GetLog2Contiguity(psPMR);
+ IMG_UINT32 uiLog2HeapContiguity = psDevmemHeap->uiLog2PageSize;
+ IMG_UINT32 uiOrderDiff = uiLog2PMRContiguity - uiLog2HeapContiguity;
+ IMG_UINT32 uiPagesPerOrder = 1 << uiOrderDiff;
+
+ IMG_UINT32 *pai32MapIndices = pai32AllocIndices;
+ IMG_UINT32 *pai32UnmapIndices = pai32FreeIndices;
+ IMG_UINT32 uiMapPageCount = ui32AllocPageCount;
+ IMG_UINT32 uiUnmapPageCount = ui32FreePageCount;
+
+ /* Special case:
+ * Adjust indices if we map into a heap that uses smaller page sizes
+ * than the physical allocation itself.
+ * The incoming parameters are all based on the page size of the PMR
+ * but the mapping functions expects parameters to be in terms of heap page sizes. */
+ if (uiOrderDiff != 0)
+ {
+ IMG_UINT32 uiPgIdx, uiPgOffset;
+
+ uiMapPageCount = (uiMapPageCount << uiOrderDiff);
+ uiUnmapPageCount = (uiUnmapPageCount << uiOrderDiff);
+
+ pai32MapIndices = OSAllocMem(uiMapPageCount * sizeof(*pai32MapIndices));
+ PVR_GOTO_IF_NOMEM(pai32MapIndices, eError, e0);
+
+ pai32UnmapIndices = OSAllocMem(uiUnmapPageCount * sizeof(*pai32UnmapIndices));
+ if (!pai32UnmapIndices)
+ {
+ OSFreeMem(pai32MapIndices);
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_OUT_OF_MEMORY, e0);
+ }
+
+ /* Every chunk index needs to be translated from physical indices
+ * into heap based indices. */
+ for (uiPgIdx = 0; uiPgIdx < ui32AllocPageCount; uiPgIdx++)
+ {
+ for (uiPgOffset = 0; uiPgOffset < uiPagesPerOrder; uiPgOffset++)
+ {
+ pai32MapIndices[uiPgIdx*uiPagesPerOrder + uiPgOffset] =
+ pai32AllocIndices[uiPgIdx]*uiPagesPerOrder + uiPgOffset;
+ }
+ }
+
+ for (uiPgIdx = 0; uiPgIdx < ui32FreePageCount; uiPgIdx++)
+ {
+ for (uiPgOffset = 0; uiPgOffset < uiPagesPerOrder; uiPgOffset++)
+ {
+ pai32UnmapIndices[uiPgIdx*uiPagesPerOrder + uiPgOffset] =
+ pai32FreeIndices[uiPgIdx]*uiPagesPerOrder + uiPgOffset;
+ }
+ }
+ }
+
+ /*
+ * The order of steps in which this request is done is given below. The order of
+ * operations is very important in this case:
+ *
+ * 1. The parameters are validated in function PMR_ChangeSparseMem below.
+ * A successful response indicates all the parameters are correct.
+ * In failure case we bail out from here without processing further.
+ * 2. On success, get the PMR specific operations done. this includes page alloc, page free
+ * and the corresponding PMR status changes.
+ * when this call fails, it is ensured that the state of the PMR before is
+ * not disturbed. If it succeeds, then we can go ahead with the subsequent steps.
+ * 3. Invalidate the GPU page table entries for the pages to be freed.
+ * 4. Write the GPU page table entries for the pages that got allocated.
+ * 5. Change the corresponding CPU space map.
+ *
+ * The above steps can be selectively controlled using flags.
+ */
+ if (uiSparseFlags & (SPARSE_REMAP_MEM | SPARSE_RESIZE_BOTH))
+ {
+ /* Do the PMR specific changes first */
+ eError = PMR_ChangeSparseMem(psPMR,
+ ui32AllocPageCount,
+ pai32AllocIndices,
+ ui32FreePageCount,
+ pai32FreeIndices,
+ uiSparseFlags);
+ if (PVRSRV_OK != eError)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "%s: Failed to do PMR specific changes.",
+ __func__));
+ goto e1;
+ }
+
+ /* Invalidate the page table entries for the free pages.
+ * Optimisation later would be not to touch the ones that gets re-mapped */
+ if ((0 != ui32FreePageCount) && (uiSparseFlags & SPARSE_RESIZE_FREE))
+ {
+ PMR_FLAGS_T uiPMRFlags;
+
+ /*Get the flags*/
+ uiPMRFlags = PMR_Flags(psPMR);
+
+ if (SPARSE_REMAP_MEM != (uiSparseFlags & SPARSE_REMAP_MEM))
+ {
+ /* Unmap the pages and mark them invalid in the MMU PTE */
+ MMU_UnmapPages (psDevmemHeap->psDevmemCtx->psMMUContext,
+ uiFlags,
+ sDevVAddrBase,
+ uiUnmapPageCount,
+ pai32UnmapIndices,
+ uiLog2HeapContiguity,
+ uiPMRFlags);
+ }
+ }
+
+ /* Wire the pages tables that got allocated */
+ if ((0 != ui32AllocPageCount) && (uiSparseFlags & SPARSE_RESIZE_ALLOC))
+ {
+ /* Map the pages and mark them Valid in the MMU PTE */
+ eError = MMU_MapPages (psDevmemHeap->psDevmemCtx->psMMUContext,
+ uiFlags,
+ sDevVAddrBase,
+ psPMR,
+ 0,
+ uiMapPageCount,
+ pai32MapIndices,
+ uiLog2HeapContiguity);
+ if (PVRSRV_OK != eError)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "%s: Failed to map alloc indices.",
+ __func__));
+ goto e1;
+ }
+ }
+
+ /* Currently only used for debug */
+ if (SPARSE_REMAP_MEM == (uiSparseFlags & SPARSE_REMAP_MEM))
+ {
+ eError = MMU_MapPages(psDevmemHeap->psDevmemCtx->psMMUContext,
+ uiFlags,
+ sDevVAddrBase,
+ psPMR,
+ 0,
+ uiMapPageCount,
+ pai32UnmapIndices,
+ uiLog2HeapContiguity);
+ if (PVRSRV_OK != eError)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "%s: Failed to map Free indices.",
+ __func__));
+ goto e1;
+ }
+ }
+ }
+
+#ifndef PVRSRV_UNMAP_ON_SPARSE_CHANGE
+ /* Do the changes in sparse on to the CPU virtual map accordingly */
+ if (uiSparseFlags & SPARSE_MAP_CPU_ADDR)
+ {
+ if (sCpuVAddrBase != 0)
+ {
+ eError = PMR_ChangeSparseMemCPUMap(psPMR,
+ sCpuVAddrBase,
+ ui32AllocPageCount,
+ pai32AllocIndices,
+ ui32FreePageCount,
+ pai32FreeIndices);
+ if (PVRSRV_OK != eError)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "%s: Failed to map to CPU addr space.",
+ __func__));
+ goto e0;
+ }
+ }
+ }
+#endif
+
+e1:
+ if (pai32MapIndices != pai32AllocIndices)
+ {
+ OSFreeMem(pai32MapIndices);
+ }
+ if (pai32UnmapIndices != pai32FreeIndices)
+ {
+ OSFreeMem(pai32UnmapIndices);
+ }
+e0:
+ return eError;
+}
+
+/*************************************************************************/ /*!
+@Function DevmemIntCtxDestroy
+@Description Destroy that created by DevmemIntCtxCreate
+@Input psDevmemCtx Device Memory context
+@Return cannot fail.
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemIntCtxDestroy(DEVMEMINT_CTX *psDevmemCtx)
+{
+ /*
+ We can't determine if we should be freeing the context here
+ as a refcount!=1 could be due to either the fact that heap(s)
+ remain with allocations on them, or that this memory context
+ has been exported.
+ As the client couldn't do anything useful with this information
+ anyway and the fact that the refcount will ensure we only
+ free the context when _all_ references have been released
+ don't bother checking and just return OK regardless.
+ */
+ DevmemIntCtxRelease(psDevmemCtx);
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR DevmemIntIsVDevAddrValid(CONNECTION_DATA * psConnection,
+ PVRSRV_DEVICE_NODE *psDevNode,
+ DEVMEMINT_CTX *psDevMemContext,
+ IMG_DEV_VIRTADDR sDevAddr)
+{
+ IMG_UINT32 i, j, uiLog2HeapPageSize = 0;
+ DEVICE_MEMORY_INFO *psDinfo = &psDevNode->sDevMemoryInfo;
+ DEVMEM_HEAP_CONFIG *psConfig = psDinfo->psDeviceMemoryHeapConfigArray;
+
+ IMG_BOOL bFound = IMG_FALSE;
+
+ for (i = 0;
+ i < psDinfo->uiNumHeapConfigs && !bFound;
+ i++)
+ {
+ for (j = 0;
+ j < psConfig[i].uiNumHeaps && !bFound;
+ j++)
+ {
+ IMG_DEV_VIRTADDR uiBase =
+ psConfig[i].psHeapBlueprintArray[j].sHeapBaseAddr;
+ IMG_DEVMEM_SIZE_T uiSize =
+ psConfig[i].psHeapBlueprintArray[j].uiHeapLength;
+
+ if ((sDevAddr.uiAddr >= uiBase.uiAddr) &&
+ (sDevAddr.uiAddr < (uiBase.uiAddr + uiSize)))
+ {
+ uiLog2HeapPageSize =
+ psConfig[i].psHeapBlueprintArray[j].uiLog2DataPageSize;
+ bFound = IMG_TRUE;
+ }
+ }
+ }
+
+ if (uiLog2HeapPageSize == 0)
+ {
+ return PVRSRV_ERROR_INVALID_GPU_ADDR;
+ }
+
+ return MMU_IsVDevAddrValid(psDevMemContext->psMMUContext,
+ uiLog2HeapPageSize,
+ sDevAddr) ? PVRSRV_OK : PVRSRV_ERROR_INVALID_GPU_ADDR;
+}
+
+PVRSRV_ERROR
+DevmemIntFlushDevSLCRange(DEVMEMINT_CTX *psDevMemContext,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_BOOL bInvalidate)
+{
+ PVRSRV_DEVICE_NODE *psDevNode = psDevMemContext->psDevNode;
+ MMU_CONTEXT *psMMUContext = psDevMemContext->psMMUContext;
+
+ if (psDevNode->pfnDevSLCFlushRange)
+ {
+ return psDevNode->pfnDevSLCFlushRange(psDevNode,
+ psMMUContext,
+ sDevVAddr,
+ uiSize,
+ bInvalidate);
+ }
+
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+PVRSRV_ERROR
+DevmemIntInvalidateFBSCTable(DEVMEMINT_CTX *psDevMemContext,
+ IMG_UINT64 ui64FBSCEntryMask)
+{
+ PVRSRV_DEVICE_NODE *psDevNode = psDevMemContext->psDevNode;
+ MMU_CONTEXT *psMMUContext = psDevMemContext->psMMUContext;
+
+ if (psDevNode->pfnInvalFBSCTable)
+ {
+ return psDevNode->pfnInvalFBSCTable(psDevNode,
+ psMMUContext,
+ ui64FBSCEntryMask);
+ }
+
+ return PVRSRV_ERROR_NOT_SUPPORTED;
+}
+
+PVRSRV_ERROR DevmemIntGetFaultAddress(CONNECTION_DATA *psConnection,
+ PVRSRV_DEVICE_NODE *psDevNode,
+ DEVMEMINT_CTX *psDevMemContext,
+ IMG_DEV_VIRTADDR *psFaultAddress)
+{
+ if ((psDevMemContext->ui32Flags & DEVMEMCTX_FLAGS_FAULT_ADDRESS_AVAILABLE) == 0)
+ {
+ return PVRSRV_ERROR_RESOURCE_UNAVAILABLE;
+ }
+
+ *psFaultAddress = psDevMemContext->sFaultAddress;
+ psDevMemContext->ui32Flags &= ~DEVMEMCTX_FLAGS_FAULT_ADDRESS_AVAILABLE;
+
+ return PVRSRV_OK;
+}
+
+static POSWR_LOCK g_hExportCtxListLock;
+static DLLIST_NODE g_sExportCtxList;
+
+PVRSRV_ERROR
+DevmemIntInit(void)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ dllist_init(&g_sExportCtxList);
+
+ eError = OSWRLockCreate(&g_hExportCtxListLock);
+
+ return eError;
+}
+
+PVRSRV_ERROR
+DevmemIntDeInit(void)
+{
+ PVR_ASSERT(dllist_is_empty(&g_sExportCtxList));
+
+ OSWRLockDestroy(g_hExportCtxListLock);
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+DevmemIntExportCtx(DEVMEMINT_CTX *psContext,
+ PMR *psPMR,
+ DEVMEMINT_CTX_EXPORT **ppsContextExport)
+{
+ DEVMEMINT_CTX_EXPORT *psCtxExport;
+
+ psCtxExport = OSAllocMem(sizeof(DEVMEMINT_CTX_EXPORT));
+ PVR_LOG_RETURN_IF_NOMEM(psCtxExport, "psCtxExport");
+
+ DevmemIntCtxAcquire(psContext);
+ PMRRefPMR(psPMR);
+ /* Now that the source PMR is exported, the layout
+ * can't change as there could be outstanding importers
+ * This is to make sure both exporter and importers view of
+ * the memory is same */
+ PMR_SetLayoutFixed(psPMR, IMG_TRUE);
+ psCtxExport->psDevmemCtx = psContext;
+ psCtxExport->psPMR = psPMR;
+ OSWRLockAcquireWrite(g_hExportCtxListLock);
+ dllist_add_to_tail(&g_sExportCtxList, &psCtxExport->sNode);
+ OSWRLockReleaseWrite(g_hExportCtxListLock);
+
+ *ppsContextExport = psCtxExport;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+DevmemIntUnexportCtx(DEVMEMINT_CTX_EXPORT *psContextExport)
+{
+ PMRUnrefPMR(psContextExport->psPMR);
+ DevmemIntCtxRelease(psContextExport->psDevmemCtx);
+ OSWRLockAcquireWrite(g_hExportCtxListLock);
+ dllist_remove_node(&psContextExport->sNode);
+ OSWRLockReleaseWrite(g_hExportCtxListLock);
+ OSFreeMem(psContextExport);
+
+ /* Unable to find exported context, return error */
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR
+DevmemIntAcquireRemoteCtx(PMR *psPMR,
+ DEVMEMINT_CTX **ppsContext,
+ IMG_HANDLE *phPrivData)
+{
+ PDLLIST_NODE psListNode, psListNodeNext;
+ DEVMEMINT_CTX_EXPORT *psCtxExport;
+
+ OSWRLockAcquireRead(g_hExportCtxListLock);
+ /* Find context from list using PMR as key */
+ dllist_foreach_node(&g_sExportCtxList, psListNode, psListNodeNext)
+ {
+ psCtxExport = IMG_CONTAINER_OF(psListNode, DEVMEMINT_CTX_EXPORT, sNode);
+ if (psCtxExport->psPMR == psPMR)
+ {
+ OSWRLockReleaseRead(g_hExportCtxListLock);
+ DevmemIntCtxAcquire(psCtxExport->psDevmemCtx);
+ *ppsContext = psCtxExport->psDevmemCtx;
+ *phPrivData = psCtxExport->psDevmemCtx->hPrivData;
+
+ /* PMR should have been already exported to import it
+ * If a PMR is exported, its immutable and the same is
+ * checked here */
+ PVR_ASSERT(IMG_TRUE == PMR_IsMemLayoutFixed(psPMR));
+
+ return PVRSRV_OK;
+ }
+ }
+ OSWRLockReleaseRead(g_hExportCtxListLock);
+
+ /* Unable to find exported context, return error */
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Failed to acquire remote context. Could not retrieve context with given PMR",
+ __func__));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+}
+
+/*************************************************************************/ /*!
+@Function DevmemIntRegisterPFNotify
+@Description Registers a PID to be notified when a page fault occurs on a
+ specific device memory context.
+@Input psDevmemCtx The context to be notified about.
+@Input ui32PID The PID of the process that would like to be
+ notified.
+@Input bRegister If true, register. If false, de-register.
+@Return PVRSRV_ERROR.
+*/ /**************************************************************************/
+PVRSRV_ERROR DevmemIntRegisterPFNotifyKM(DEVMEMINT_CTX *psDevmemCtx,
+ IMG_INT32 ui32PID,
+ IMG_BOOL bRegister)
+{
+ PVRSRV_DEVICE_NODE *psDevNode;
+ DLLIST_NODE *psNode, *psNodeNext;
+ DEVMEMINT_PF_NOTIFY *psNotifyNode;
+ IMG_BOOL bPresent = IMG_FALSE;
+ PVRSRV_ERROR eError;
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psDevmemCtx, "psDevmemCtx");
+
+ /* Acquire write lock for the duration, to avoid resource free
+ * while trying to read (no need to then also acquire the read lock
+ * as we have exclusive access while holding the write lock)
+ */
+ OSWRLockAcquireWrite(psDevmemCtx->hListLock);
+
+ psDevNode = psDevmemCtx->psDevNode;
+
+ if (bRegister)
+ {
+ /* If this is the first PID in the list, the device memory context
+ * needs to be registered for notification */
+ if (dllist_is_empty(&psDevmemCtx->sProcessNotifyListHead))
+ {
+ OSWRLockAcquireWrite(psDevNode->hMemoryContextPageFaultNotifyListLock);
+ dllist_add_to_tail(&psDevNode->sMemoryContextPageFaultNotifyListHead,
+ &psDevmemCtx->sPageFaultNotifyListElem);
+ OSWRLockReleaseWrite(psDevNode->hMemoryContextPageFaultNotifyListLock);
+ }
+ }
+
+ /* Loop through the registered PIDs and check whether this one is
+ * present */
+ dllist_foreach_node(&(psDevmemCtx->sProcessNotifyListHead), psNode, psNodeNext)
+ {
+ psNotifyNode = IMG_CONTAINER_OF(psNode, DEVMEMINT_PF_NOTIFY, sProcessNotifyListElem);
+
+ if (psNotifyNode->ui32PID == ui32PID)
+ {
+ bPresent = IMG_TRUE;
+ break;
+ }
+ }
+
+ if (bRegister)
+ {
+ if (bPresent)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Trying to register a PID that is already registered",
+ __func__));
+ eError = PVRSRV_ERROR_PID_ALREADY_REGISTERED;
+ goto err_already_registered;
+ }
+
+ psNotifyNode = OSAllocMem(sizeof(*psNotifyNode));
+ if (psNotifyNode == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Unable to allocate memory for the notify list",
+ __func__));
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto err_out_of_mem;
+ }
+ psNotifyNode->ui32PID = ui32PID;
+ /* Write lock is already held */
+ dllist_add_to_tail(&(psDevmemCtx->sProcessNotifyListHead), &(psNotifyNode->sProcessNotifyListElem));
+ }
+ else
+ {
+ if (!bPresent)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Trying to unregister a PID that is not registered",
+ __func__));
+ eError = PVRSRV_ERROR_PID_NOT_REGISTERED;
+ goto err_not_registered;
+ }
+ /* Write lock is already held */
+ dllist_remove_node(psNode);
+ psNotifyNode = IMG_CONTAINER_OF(psNode, DEVMEMINT_PF_NOTIFY, sProcessNotifyListElem);
+ OSFreeMem(psNotifyNode);
+
+ /* If the last process in the list is being unregistered, then also
+ * unregister the device memory context from the notify list. */
+ if (dllist_is_empty(&psDevmemCtx->sProcessNotifyListHead))
+ {
+ OSWRLockAcquireWrite(psDevNode->hMemoryContextPageFaultNotifyListLock);
+ dllist_remove_node(&psDevmemCtx->sPageFaultNotifyListElem);
+ OSWRLockReleaseWrite(psDevNode->hMemoryContextPageFaultNotifyListLock);
+ }
+ }
+ eError = PVRSRV_OK;
+
+err_already_registered:
+err_out_of_mem:
+err_not_registered:
+
+ OSWRLockReleaseWrite(psDevmemCtx->hListLock);
+ return eError;
+}
+
+/*************************************************************************/ /*!
+@Function DevmemIntPFNotify
+@Description Notifies any processes that have registered themselves to be
+ notified when a page fault happens on a specific device memory
+ context.
+@Input *psDevNode The device node.
+@Input ui64FaultedPCAddress The page catalogue address that faulted.
+@Input sFaultAddress The address that triggered the fault.
+@Return PVRSRV_ERROR
+*/ /**************************************************************************/
+PVRSRV_ERROR DevmemIntPFNotify(PVRSRV_DEVICE_NODE *psDevNode,
+ IMG_UINT64 ui64FaultedPCAddress,
+ IMG_DEV_VIRTADDR sFaultAddress)
+{
+ DLLIST_NODE *psNode, *psNodeNext;
+ DEVMEMINT_PF_NOTIFY *psNotifyNode;
+ PVRSRV_ERROR eError;
+ DEVMEMINT_CTX *psDevmemCtx = NULL;
+ IMG_BOOL bFailed = IMG_FALSE;
+
+ OSWRLockAcquireRead(psDevNode->hMemoryContextPageFaultNotifyListLock);
+ if (dllist_is_empty(&(psDevNode->sMemoryContextPageFaultNotifyListHead)))
+ {
+ OSWRLockReleaseRead(psDevNode->hMemoryContextPageFaultNotifyListLock);
+ return PVRSRV_OK;
+ }
+
+ dllist_foreach_node(&(psDevNode->sMemoryContextPageFaultNotifyListHead), psNode, psNodeNext)
+ {
+ DEVMEMINT_CTX *psThisContext =
+ IMG_CONTAINER_OF(psNode, DEVMEMINT_CTX, sPageFaultNotifyListElem);
+ IMG_DEV_PHYADDR sPCDevPAddr;
+
+ eError = MMU_AcquireBaseAddr(psThisContext->psMMUContext, &sPCDevPAddr);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_LOG_ERROR(eError, "MMU_AcquireBaseAddr");
+ OSWRLockReleaseRead(psDevNode->hMemoryContextPageFaultNotifyListLock);
+ return eError;
+ }
+
+ if (sPCDevPAddr.uiAddr == ui64FaultedPCAddress)
+ {
+ psDevmemCtx = psThisContext;
+ break;
+ }
+ }
+ OSWRLockReleaseRead(psDevNode->hMemoryContextPageFaultNotifyListLock);
+
+ if (psDevmemCtx == NULL)
+ {
+ /* Not found, just return */
+ return PVRSRV_OK;
+ }
+ OSWRLockAcquireRead(psDevmemCtx->hListLock);
+
+ /*
+ * Store the first occurrence of a page fault address,
+ * until that address is consumed by a client.
+ */
+ if ((psDevmemCtx->ui32Flags & DEVMEMCTX_FLAGS_FAULT_ADDRESS_AVAILABLE) == 0)
+ {
+ psDevmemCtx->sFaultAddress = sFaultAddress;
+ psDevmemCtx->ui32Flags |= DEVMEMCTX_FLAGS_FAULT_ADDRESS_AVAILABLE;
+ }
+
+ /* Loop through each registered PID and send a signal to the process */
+ dllist_foreach_node(&(psDevmemCtx->sProcessNotifyListHead), psNode, psNodeNext)
+ {
+ psNotifyNode = IMG_CONTAINER_OF(psNode, DEVMEMINT_PF_NOTIFY, sProcessNotifyListElem);
+
+ eError = OSDebugSignalPID(psNotifyNode->ui32PID);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Unable to signal process for PID: %u",
+ __func__,
+ psNotifyNode->ui32PID));
+
+ PVR_ASSERT(!"Unable to signal process");
+
+ bFailed = IMG_TRUE;
+ }
+ }
+ OSWRLockReleaseRead(psDevmemCtx->hListLock);
+
+ if (bFailed)
+ {
+ return PVRSRV_ERROR_SIGNAL_FAILED;
+ }
+
+ return PVRSRV_OK;
+}
+
+#if defined(PDUMP)
+IMG_UINT32 DevmemIntMMUContextID(DEVMEMINT_CTX *psDevMemContext)
+{
+ IMG_UINT32 ui32MMUContextID;
+ MMU_AcquirePDumpMMUContext(psDevMemContext->psMMUContext, &ui32MMUContextID, PDUMP_FLAGS_CONTINUOUS);
+ return ui32MMUContextID;
+}
+
+PVRSRV_ERROR
+DevmemIntPDumpSaveToFileVirtual(DEVMEMINT_CTX *psDevmemCtx,
+ IMG_DEV_VIRTADDR sDevAddrStart,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_UINT32 ui32ArraySize,
+ const IMG_CHAR *pszFilename,
+ IMG_UINT32 ui32FileOffset,
+ IMG_UINT32 ui32PDumpFlags)
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT32 uiPDumpMMUCtx;
+
+ PVR_UNREFERENCED_PARAMETER(ui32ArraySize);
+
+ /* Confirm that the device node's ui32InternalID matches the bound
+ * PDump device stored in PVRSRV_DATA.
+ */
+ if (psDevmemCtx->psDevNode->sDevId.ui32InternalID !=
+ (PVRSRVGetPVRSRVData())->ui32PDumpBoundDevice)
+ {
+ return PVRSRV_ERROR_PDUMP_CAPTURE_BOUND_TO_ANOTHER_DEVICE;
+ }
+
+ eError = MMU_AcquirePDumpMMUContext(psDevmemCtx->psMMUContext,
+ &uiPDumpMMUCtx,
+ ui32PDumpFlags);
+
+ PVR_ASSERT(eError == PVRSRV_OK);
+
+ /*
+ The following SYSMEM refers to the 'MMU Context', hence it
+ should be the MMU context, not the PMR, that says what the PDump
+ MemSpace tag is?
+ From a PDump P.O.V. it doesn't matter which name space we use as long
+ as that MemSpace is used on the 'MMU Context' we're dumping from
+ */
+ eError = PDumpMMUSAB(psDevmemCtx->psDevNode,
+ psDevmemCtx->psDevNode->sDevId.pszPDumpDevName,
+ uiPDumpMMUCtx,
+ sDevAddrStart,
+ uiSize,
+ pszFilename,
+ ui32FileOffset,
+ ui32PDumpFlags);
+ PVR_ASSERT(eError == PVRSRV_OK);
+
+ MMU_ReleasePDumpMMUContext(psDevmemCtx->psMMUContext, ui32PDumpFlags);
+ return PVRSRV_OK;
+}
+
+
+PVRSRV_ERROR
+DevmemIntPDumpBitmap(CONNECTION_DATA * psConnection,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_UINT32 ui32Width,
+ IMG_UINT32 ui32Height,
+ IMG_UINT32 ui32StrideInBytes,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+ DEVMEMINT_CTX *psDevMemContext,
+ IMG_UINT32 ui32Size,
+ PDUMP_PIXEL_FORMAT ePixelFormat,
+ IMG_UINT32 ui32AddrMode,
+ IMG_UINT32 ui32PDumpFlags)
+{
+ IMG_UINT32 ui32ContextID;
+ PVRSRV_ERROR eError;
+
+ PVR_UNREFERENCED_PARAMETER(psConnection);
+
+ eError = MMU_AcquirePDumpMMUContext(psDevMemContext->psMMUContext, &ui32ContextID, ui32PDumpFlags);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_LOG_ERROR(eError, "MMU_AcquirePDumpMMUContext");
+ return PVRSRV_ERROR_FAILED_TO_ALLOC_MMUCONTEXT_ID;
+ }
+
+ eError = PDumpBitmapKM(psDeviceNode,
+ pszFileName,
+ ui32FileOffset,
+ ui32Width,
+ ui32Height,
+ ui32StrideInBytes,
+ sDevBaseAddr,
+ ui32ContextID,
+ ui32Size,
+ ePixelFormat,
+ ui32AddrMode,
+ ui32PDumpFlags);
+
+ /* Don't care about return value */
+ MMU_ReleasePDumpMMUContext(psDevMemContext->psMMUContext, ui32PDumpFlags);
+
+ return eError;
+}
+
+PVRSRV_ERROR
+DevmemIntPDumpImageDescriptor(CONNECTION_DATA * psConnection,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ DEVMEMINT_CTX *psDevMemContext,
+ IMG_UINT32 ui32Size,
+ const IMG_CHAR *pszFileName,
+ IMG_DEV_VIRTADDR sData,
+ IMG_UINT32 ui32DataSize,
+ IMG_UINT32 ui32LogicalWidth,
+ IMG_UINT32 ui32LogicalHeight,
+ IMG_UINT32 ui32PhysicalWidth,
+ IMG_UINT32 ui32PhysicalHeight,
+ PDUMP_PIXEL_FORMAT ePixFmt,
+ IMG_MEMLAYOUT eMemLayout,
+ IMG_FB_COMPRESSION eFBCompression,
+ const IMG_UINT32 *paui32FBCClearColour,
+ PDUMP_FBC_SWIZZLE eFBCSwizzle,
+ IMG_DEV_VIRTADDR sHeader,
+ IMG_UINT32 ui32HeaderSize,
+ IMG_UINT32 ui32PDumpFlags)
+{
+ IMG_UINT32 ui32ContextID;
+ PVRSRV_ERROR eError;
+
+ PVR_UNREFERENCED_PARAMETER(psConnection);
+ PVR_UNREFERENCED_PARAMETER(ui32Size);
+
+ eError = MMU_AcquirePDumpMMUContext(psDevMemContext->psMMUContext, &ui32ContextID, ui32PDumpFlags);
+ PVR_LOG_RETURN_IF_ERROR(eError, "MMU_AcquirePDumpMMUContext");
+
+ eError = PDumpImageDescriptor(psDeviceNode,
+ ui32ContextID,
+ (IMG_CHAR *)pszFileName,
+ sData,
+ ui32DataSize,
+ ui32LogicalWidth,
+ ui32LogicalHeight,
+ ui32PhysicalWidth,
+ ui32PhysicalHeight,
+ ePixFmt,
+ eMemLayout,
+ eFBCompression,
+ paui32FBCClearColour,
+ eFBCSwizzle,
+ sHeader,
+ ui32HeaderSize,
+ ui32PDumpFlags);
+ PVR_LOG_IF_ERROR(eError, "PDumpImageDescriptor");
+
+ /* Don't care about return value */
+ (void) MMU_ReleasePDumpMMUContext(psDevMemContext->psMMUContext, ui32PDumpFlags);
+
+ return eError;
+}
+
+PVRSRV_ERROR
+DevmemIntPDumpDataDescriptor(CONNECTION_DATA * psConnection,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ DEVMEMINT_CTX *psDevMemContext,
+ IMG_UINT32 ui32Size,
+ const IMG_CHAR *pszFileName,
+ IMG_DEV_VIRTADDR sData,
+ IMG_UINT32 ui32DataSize,
+ IMG_UINT32 ui32HeaderType,
+ IMG_UINT32 ui32ElementType,
+ IMG_UINT32 ui32ElementCount,
+ IMG_UINT32 ui32PDumpFlags)
+{
+ IMG_UINT32 ui32ContextID;
+ PVRSRV_ERROR eError;
+
+ PVR_UNREFERENCED_PARAMETER(psConnection);
+ PVR_UNREFERENCED_PARAMETER(ui32Size);
+
+ if ((ui32HeaderType != IBIN_HEADER_TYPE) &&
+ (ui32HeaderType != DATA_HEADER_TYPE))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Invalid header type (%u)",
+ __func__,
+ ui32HeaderType));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ eError = MMU_AcquirePDumpMMUContext(psDevMemContext->psMMUContext, &ui32ContextID, ui32PDumpFlags);
+ PVR_LOG_RETURN_IF_ERROR(eError, "MMU_AcquirePDumpMMUContext");
+
+ eError = PDumpDataDescriptor(psDeviceNode,
+ ui32ContextID,
+ (IMG_CHAR *)pszFileName,
+ sData,
+ ui32DataSize,
+ ui32HeaderType,
+ ui32ElementType,
+ ui32ElementCount,
+ ui32PDumpFlags);
+ PVR_LOG_IF_ERROR(eError, "PDumpDataDescriptor");
+
+ /* Don't care about return value */
+ (void) MMU_ReleasePDumpMMUContext(psDevMemContext->psMMUContext, ui32PDumpFlags);
+
+ return eError;
+}
+
+#endif
diff --git a/drivers/gpu/drm/img-rogue/devicemem_server.h b/drivers/gpu/drm/img-rogue/devicemem_server.h
new file mode 100644
index 000000000..d4c7f215f
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/devicemem_server.h
@@ -0,0 +1,682 @@
+/*************************************************************************/ /*!
+@File
+@Title Device Memory Management
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Server side component for device memory management
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef DEVICEMEM_SERVER_H
+#define DEVICEMEM_SERVER_H
+
+#include "device.h" /* For device node */
+#include "img_types.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+
+#include "connection_server.h"
+#include "pmr.h"
+
+typedef struct _DEVMEMINT_CTX_ DEVMEMINT_CTX;
+typedef struct _DEVMEMINT_CTX_EXPORT_ DEVMEMINT_CTX_EXPORT;
+typedef struct _DEVMEMINT_HEAP_ DEVMEMINT_HEAP;
+
+typedef struct _DEVMEMINT_RESERVATION_ DEVMEMINT_RESERVATION;
+typedef struct _DEVMEMINT_MAPPING_ DEVMEMINT_MAPPING;
+typedef struct _DEVMEMINT_PF_NOTIFY_ DEVMEMINT_PF_NOTIFY;
+
+
+/*************************************************************************/ /*!
+@Function DevmemIntUnpin
+@Description This is the counterpart to DevmemPin(). It is meant to be
+ called when the allocation is NOT mapped in the device virtual
+ space.
+
+@Input psPMR The physical memory to unpin.
+
+@Return PVRSRV_ERROR: PVRSRV_OK on success and the memory is
+ registered to be reclaimed. Error otherwise.
+*/ /**************************************************************************/
+PVRSRV_ERROR DevmemIntUnpin(PMR *psPMR);
+
+/*************************************************************************/ /*!
+@Function DevmemIntUnpinInvalidate
+@Description This is the counterpart to DevmemIntPinValidate(). It is meant
+ to be called for allocations that ARE mapped in the device
+ virtual space and we have to invalidate the mapping.
+
+@Input psPMR The physical memory to unpin.
+
+@Return PVRSRV_ERROR: PVRSRV_OK on success and the memory is
+ registered to be reclaimed. Error otherwise.
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemIntUnpinInvalidate(DEVMEMINT_MAPPING *psDevmemMapping, PMR *psPMR);
+
+/*************************************************************************/ /*!
+@Function DevmemIntPin
+@Description This is the counterpart to DevmemIntUnpin().
+ Is meant to be called if there is NO device mapping present.
+
+@Input psPMR The physical memory to pin.
+
+@Return PVRSRV_ERROR: PVRSRV_OK on success and the allocation content
+ was successfully restored.
+
+ PVRSRV_ERROR_PMR_NEW_MEMORY when the content
+ could not be restored and new physical memory
+ was allocated.
+
+ A different error otherwise.
+*/ /**************************************************************************/
+PVRSRV_ERROR DevmemIntPin(PMR *psPMR);
+
+/*************************************************************************/ /*!
+@Function DevmemIntPinValidate
+@Description This is the counterpart to DevmemIntUnpinInvalidate().
+ Is meant to be called if there is IS a device mapping present
+ that needs to be taken care of.
+
+@Input psDevmemMapping The mapping structure used for the passed PMR.
+
+@Input psPMR The physical memory to pin.
+
+@Return PVRSRV_ERROR: PVRSRV_OK on success and the allocation content
+ was successfully restored.
+
+ PVRSRV_ERROR_PMR_NEW_MEMORY when the content
+ could not be restored and new physical memory
+ was allocated.
+
+ A different error otherwise.
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemIntPinValidate(DEVMEMINT_MAPPING *psDevmemMapping, PMR *psPMR);
+/*
+ * DevmemServerGetImportHandle()
+ *
+ * For given exportable memory descriptor returns PMR handle
+ *
+ */
+PVRSRV_ERROR
+DevmemServerGetImportHandle(DEVMEM_MEMDESC *psMemDesc,
+ IMG_HANDLE *phImport);
+
+/*
+ * DevmemServerGetHeapHandle()
+ *
+ * For given reservation returns the Heap handle
+ *
+ */
+PVRSRV_ERROR
+DevmemServerGetHeapHandle(DEVMEMINT_RESERVATION *psReservation,
+ IMG_HANDLE *phHeap);
+
+/*
+ * DevmemServerGetContext()
+ *
+ * For given heap returns the context.
+ *
+ */
+PVRSRV_ERROR
+DevmemServerGetContext(DEVMEMINT_HEAP *psDevmemHeap,
+ DEVMEMINT_CTX **ppsDevmemCtxPtr);
+
+/*
+ * DevmemServerGetPrivData()
+ *
+ * For given context returns the private data handle.
+ *
+ */
+PVRSRV_ERROR
+DevmemServerGetPrivData(DEVMEMINT_CTX *psDevmemCtx,
+ IMG_HANDLE *phPrivData);
+
+/*
+ * DevmemIntAllocDefBackingPage
+ *
+ * This function allocates default backing page and initializes it
+ * with a given default value
+ *
+ */
+PVRSRV_ERROR DevmemIntAllocDefBackingPage(PVRSRV_DEVICE_NODE *psDevNode,
+ PVRSRV_DEF_PAGE *psDefPage,
+ IMG_INT uiInitValue,
+ IMG_CHAR *pcDefPageName,
+ IMG_BOOL bInitPage);
+/*
+ * DevmemIntFreeDefBackingPage
+ *
+ * Frees a given page
+ */
+void DevmemIntFreeDefBackingPage(PVRSRV_DEVICE_NODE *psDevNode,
+ PVRSRV_DEF_PAGE *psDefPage,
+ IMG_CHAR *pcDefPageName);
+
+
+/*
+ * DevmemIntCtxCreate()
+ *
+ * Create a Server-side Device Memory Context. This is usually the counterpart
+ * of the client side memory context, and indeed is usually created at the
+ * same time.
+ *
+ * You must have one of these before creating any heaps.
+ *
+ * All heaps must have been destroyed before calling
+ * DevmemIntCtxDestroy()
+ *
+ * If you call DevmemIntCtxCreate() (and it succeeds) you are promising to
+ * later call DevmemIntCtxDestroy()
+ *
+ * Note that this call will cause the device MMU code to do some work for
+ * creating the device memory context, but it does not guarantee that a page
+ * catalogue will have been created, as this may be deferred until the first
+ * allocation.
+ *
+ * Caller to provide storage for a pointer to the DEVMEM_CTX object that will
+ * be created by this call.
+ */
+PVRSRV_ERROR
+DevmemIntCtxCreate(CONNECTION_DATA *psConnection,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ /* devnode / perproc etc */
+ IMG_BOOL bKernelMemoryCtx,
+ DEVMEMINT_CTX **ppsDevmemCtxPtr,
+ IMG_HANDLE *hPrivData,
+ IMG_UINT32 *pui32CPUCacheLineSize);
+/*
+ * DevmemIntCtxDestroy()
+ *
+ * Undoes a prior DevmemIntCtxCreate or DevmemIntCtxImport.
+ */
+PVRSRV_ERROR
+DevmemIntCtxDestroy(DEVMEMINT_CTX *psDevmemCtx);
+
+/*
+ * DevmemIntHeapCreate()
+ *
+ * Creates a new heap in this device memory context. This will cause a call
+ * into the MMU code to allocate various data structures for managing this
+ * heap. It will not necessarily cause any page tables to be set up, as this
+ * can be deferred until first allocation. (i.e. we shouldn't care - it's up
+ * to the MMU code)
+ *
+ * Note that the data page size must be specified (as log 2). The data page
+ * size as specified here will be communicated to the mmu module, and thus may
+ * determine the page size configured in page directory entries for subsequent
+ * allocations from this heap. It is essential that the page size here is less
+ * than or equal to the "minimum contiguity guarantee" of any PMR that you
+ * subsequently attempt to map to this heap.
+ *
+ * If you call DevmemIntHeapCreate() (and the call succeeds) you are promising
+ * that you shall subsequently call DevmemIntHeapDestroy()
+ *
+ * Caller to provide storage for a pointer to the DEVMEM_HEAP object that will
+ * be created by this call.
+ */
+PVRSRV_ERROR
+DevmemIntHeapCreate(DEVMEMINT_CTX *psDevmemCtx,
+ IMG_DEV_VIRTADDR sHeapBaseAddr,
+ IMG_DEVMEM_SIZE_T uiHeapLength,
+ IMG_UINT32 uiLog2DataPageSize,
+ DEVMEMINT_HEAP **ppsDevmemHeapPtr);
+/*
+ * DevmemIntHeapDestroy()
+ *
+ * Destroys a heap previously created with DevmemIntHeapCreate()
+ *
+ * All allocations from his heap must have been freed before this
+ * call.
+ */
+PVRSRV_ERROR
+DevmemIntHeapDestroy(DEVMEMINT_HEAP *psDevmemHeap);
+
+/*
+ * DevmemIntMapPMR()
+ *
+ * Maps the given PMR to the virtual range previously allocated with
+ * DevmemIntReserveRange()
+ *
+ * If appropriate, the PMR must have had its physical backing committed, as
+ * this call will call into the MMU code to set up the page tables for this
+ * allocation, which shall in turn request the physical addresses from the
+ * PMR. Alternatively, the PMR implementation can choose to do so off the
+ * the back of the "lock" callback, which it will receive as a result
+ * (indirectly) of this call.
+ *
+ * This function makes no promise w.r.t. the circumstances that it can be
+ * called, and these would be "inherited" from the implementation of the PMR.
+ * For example if the PMR "lock" callback causes pages to be pinned at that
+ * time (which may cause scheduling or disk I/O etc.) then it would not be
+ * legal to "Map" the PMR in a context where scheduling events are disallowed.
+ *
+ * If you call DevmemIntMapPMR() (and the call succeeds) then you are promising
+ * that you shall later call DevmemIntUnmapPMR()
+ */
+PVRSRV_ERROR
+DevmemIntMapPMR(DEVMEMINT_HEAP *psDevmemHeap,
+ DEVMEMINT_RESERVATION *psReservation,
+ PMR *psPMR,
+ PVRSRV_MEMALLOCFLAGS_T uiMapFlags,
+ DEVMEMINT_MAPPING **ppsMappingPtr);
+/*
+ * DevmemIntUnmapPMR()
+ *
+ * Reverses the mapping caused by DevmemIntMapPMR()
+ */
+PVRSRV_ERROR
+DevmemIntUnmapPMR(DEVMEMINT_MAPPING *psMapping);
+
+/* DevmemIntMapPages()
+ *
+ * Maps an arbitrary amount of pages from a PMR to a reserved range
+ *
+ * @input psReservation Reservation handle for the range
+ * @input psPMR PMR that is mapped
+ * @input ui32PageCount Number of consecutive pages that are
+ * mapped
+ * @input ui32PhysicalPgOffset Logical offset in the PMR
+ * @input uiFlags Mapping flags
+ * @input sDevVAddrBase Virtual address base to start the
+ * mapping from
+ */
+PVRSRV_ERROR
+DevmemIntMapPages(DEVMEMINT_RESERVATION *psReservation,
+ PMR *psPMR,
+ IMG_UINT32 ui32PageCount,
+ IMG_UINT32 ui32PhysicalPgOffset,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ IMG_DEV_VIRTADDR sDevVAddrBase);
+
+/* DevmemIntUnmapPages()
+ *
+ * Unmaps an arbitrary amount of pages from a reserved range
+ *
+ * @input psReservation Reservation handle for the range
+ * @input sDevVAddrBase Virtual address base to start from
+ * @input ui32PageCount Number of consecutive pages that are
+ * unmapped
+ */
+PVRSRV_ERROR
+DevmemIntUnmapPages(DEVMEMINT_RESERVATION *psReservation,
+ IMG_DEV_VIRTADDR sDevVAddrBase,
+ IMG_UINT32 ui32PageCount);
+
+/*
+ * DevmemIntReserveRange()
+ *
+ * Indicates that the specified range should be reserved from the given heap.
+ *
+ * In turn causes the page tables to be allocated to cover the specified range.
+ *
+ * If you call DevmemIntReserveRange() (and the call succeeds) then you are
+ * promising that you shall later call DevmemIntUnreserveRange()
+ */
+PVRSRV_ERROR
+DevmemIntReserveRange(DEVMEMINT_HEAP *psDevmemHeap,
+ IMG_DEV_VIRTADDR sAllocationDevVAddr,
+ IMG_DEVMEM_SIZE_T uiAllocationSize,
+ DEVMEMINT_RESERVATION **ppsReservationPtr);
+/*
+ * DevmemIntUnreserveRange()
+ *
+ * Undoes the state change caused by DevmemIntReserveRage()
+ */
+PVRSRV_ERROR
+DevmemIntUnreserveRange(DEVMEMINT_RESERVATION *psDevmemReservation);
+
+/*************************************************************************/ /*!
+@Function DevmemIntChangeSparse
+@Description Changes the sparse allocations of a PMR by allocating and freeing
+ pages and changing their corresponding CPU and GPU mappings.
+
+@input psDevmemHeap Pointer to the heap we map on
+@input psPMR The PMR we want to map
+@input ui32AllocPageCount Number of pages to allocate
+@input pai32AllocIndices The logical PMR indices where pages will
+ be allocated. May be NULL.
+@input ui32FreePageCount Number of pages to free
+@input pai32FreeIndices The logical PMR indices where pages will
+ be freed. May be NULL.
+@input uiSparseFlags Flags passed in to determine which kind
+ of sparse change the user wanted.
+ See devicemem_typedefs.h for details.
+@input uiFlags Memalloc flags for this virtual range.
+@input sDevVAddrBase The base address of the virtual range of
+ this sparse allocation.
+@input sCpuVAddrBase The CPU base address of this allocation.
+ May be 0 if not existing.
+@Return PVRSRV_ERROR failure code
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemIntChangeSparse(DEVMEMINT_HEAP *psDevmemHeap,
+ PMR *psPMR,
+ IMG_UINT32 ui32AllocPageCount,
+ IMG_UINT32 *pai32AllocIndices,
+ IMG_UINT32 ui32FreePageCount,
+ IMG_UINT32 *pai32FreeIndices,
+ SPARSE_MEM_RESIZE_FLAGS uiSparseFlags,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ IMG_DEV_VIRTADDR sDevVAddrBase,
+ IMG_UINT64 sCpuVAddrBase);
+
+/*
+ * DevmemIntFlushDevSLCRange()
+ *
+ * Flush specified device context's virtual address range from SLC.
+ */
+PVRSRV_ERROR
+DevmemIntFlushDevSLCRange(DEVMEMINT_CTX *psDevmemCtx,
+ IMG_DEV_VIRTADDR sDevVAddr,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_BOOL bInvalidate);
+
+/*
+ * DevmemIntRGXInvalidateFBSCTable()
+ *
+ * Invalidate selected FBSC table indices.
+ *
+ */
+PVRSRV_ERROR
+DevmemIntInvalidateFBSCTable(DEVMEMINT_CTX *psDevmemCtx,
+ IMG_UINT64 ui64FBSCEntryMask);
+
+PVRSRV_ERROR
+DevmemIntIsVDevAddrValid(CONNECTION_DATA * psConnection,
+ PVRSRV_DEVICE_NODE *psDevNode,
+ DEVMEMINT_CTX *psDevMemContext,
+ IMG_DEV_VIRTADDR sDevAddr);
+
+PVRSRV_ERROR
+DevmemIntGetFaultAddress(CONNECTION_DATA * psConnection,
+ PVRSRV_DEVICE_NODE *psDevNode,
+ DEVMEMINT_CTX *psDevMemContext,
+ IMG_DEV_VIRTADDR *psFaultAddress);
+
+/*************************************************************************/ /*!
+@Function DevmemIntRegisterPFNotifyKM
+@Description Registers a PID to be notified when a page fault occurs on a
+ specific device memory context.
+@Input psDevmemCtx The context to be notified about.
+@Input ui32PID The PID of the process that would like to be
+ notified.
+@Input bRegister If true, register. If false, de-register.
+@Return PVRSRV_ERROR
+*/ /**************************************************************************/
+PVRSRV_ERROR
+DevmemIntRegisterPFNotifyKM(DEVMEMINT_CTX *psDevmemCtx,
+ IMG_INT32 ui32PID,
+ IMG_BOOL bRegister);
+
+/*************************************************************************/ /*!
+@Function DevmemIntPFNotify
+@Description Notifies any processes that have registered themselves to be
+ notified when a page fault happens on a specific device memory
+ context.
+@Input *psDevNode The device node.
+@Input ui64FaultedPCAddress The page catalogue address that faulted.
+@Input sFaultAddress The address that triggered the fault.
+@Return PVRSRV_ERROR
+*/ /**************************************************************************/
+PVRSRV_ERROR DevmemIntPFNotify(PVRSRV_DEVICE_NODE *psDevNode,
+ IMG_UINT64 ui64FaultedPCAddress,
+ IMG_DEV_VIRTADDR sFaultAddress);
+
+#if defined(PDUMP)
+/*
+ * DevmemIntPDumpSaveToFileVirtual()
+ *
+ * Writes out PDump "SAB" commands with the data found in memory at
+ * the given virtual address.
+ */
+PVRSRV_ERROR
+DevmemIntPDumpSaveToFileVirtual(DEVMEMINT_CTX *psDevmemCtx,
+ IMG_DEV_VIRTADDR sDevAddrStart,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_UINT32 uiArraySize,
+ const IMG_CHAR *pszFilename,
+ IMG_UINT32 ui32FileOffset,
+ IMG_UINT32 ui32PDumpFlags);
+
+IMG_UINT32
+DevmemIntMMUContextID(DEVMEMINT_CTX *psDevMemContext);
+
+PVRSRV_ERROR
+DevmemIntPDumpBitmap(CONNECTION_DATA * psConnection,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_UINT32 ui32Width,
+ IMG_UINT32 ui32Height,
+ IMG_UINT32 ui32StrideInBytes,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+ DEVMEMINT_CTX *psDevMemContext,
+ IMG_UINT32 ui32Size,
+ PDUMP_PIXEL_FORMAT ePixelFormat,
+ IMG_UINT32 ui32AddrMode,
+ IMG_UINT32 ui32PDumpFlags);
+
+PVRSRV_ERROR
+DevmemIntPDumpImageDescriptor(CONNECTION_DATA * psConnection,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ DEVMEMINT_CTX *psDevMemContext,
+ IMG_UINT32 ui32Size,
+ const IMG_CHAR *pszFileName,
+ IMG_DEV_VIRTADDR sData,
+ IMG_UINT32 ui32DataSize,
+ IMG_UINT32 ui32LogicalWidth,
+ IMG_UINT32 ui32LogicalHeight,
+ IMG_UINT32 ui32PhysicalWidth,
+ IMG_UINT32 ui32PhysicalHeight,
+ PDUMP_PIXEL_FORMAT ePixFmt,
+ IMG_MEMLAYOUT eMemLayout,
+ IMG_FB_COMPRESSION eFBCompression,
+ const IMG_UINT32 *paui32FBCClearColour,
+ PDUMP_FBC_SWIZZLE eFBCSwizzle,
+ IMG_DEV_VIRTADDR sHeader,
+ IMG_UINT32 ui32HeaderSize,
+ IMG_UINT32 ui32PDumpFlags);
+
+PVRSRV_ERROR
+DevmemIntPDumpDataDescriptor(CONNECTION_DATA * psConnection,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ DEVMEMINT_CTX *psDevMemContext,
+ IMG_UINT32 ui32Size,
+ const IMG_CHAR *pszFileName,
+ IMG_DEV_VIRTADDR sData,
+ IMG_UINT32 ui32DataSize,
+ IMG_UINT32 ui32HeaderType,
+ IMG_UINT32 ui32ElementType,
+ IMG_UINT32 ui32ElementCount,
+ IMG_UINT32 ui32PDumpFlags);
+#else /* PDUMP */
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemIntPDumpSaveToFileVirtual)
+#endif
+static INLINE PVRSRV_ERROR
+DevmemIntPDumpSaveToFileVirtual(DEVMEMINT_CTX *psDevmemCtx,
+ IMG_DEV_VIRTADDR sDevAddrStart,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_UINT32 uiArraySize,
+ const IMG_CHAR *pszFilename,
+ IMG_UINT32 ui32FileOffset,
+ IMG_UINT32 ui32PDumpFlags)
+{
+ PVR_UNREFERENCED_PARAMETER(psDevmemCtx);
+ PVR_UNREFERENCED_PARAMETER(sDevAddrStart);
+ PVR_UNREFERENCED_PARAMETER(uiSize);
+ PVR_UNREFERENCED_PARAMETER(uiArraySize);
+ PVR_UNREFERENCED_PARAMETER(pszFilename);
+ PVR_UNREFERENCED_PARAMETER(ui32FileOffset);
+ PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemIntPDumpBitmap)
+#endif
+static INLINE PVRSRV_ERROR
+DevmemIntPDumpBitmap(CONNECTION_DATA * psConnection,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32FileOffset,
+ IMG_UINT32 ui32Width,
+ IMG_UINT32 ui32Height,
+ IMG_UINT32 ui32StrideInBytes,
+ IMG_DEV_VIRTADDR sDevBaseAddr,
+ DEVMEMINT_CTX *psDevMemContext,
+ IMG_UINT32 ui32Size,
+ PDUMP_PIXEL_FORMAT ePixelFormat,
+ IMG_UINT32 ui32AddrMode,
+ IMG_UINT32 ui32PDumpFlags)
+{
+ PVR_UNREFERENCED_PARAMETER(psConnection);
+ PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(ui32FileOffset);
+ PVR_UNREFERENCED_PARAMETER(ui32Width);
+ PVR_UNREFERENCED_PARAMETER(ui32Height);
+ PVR_UNREFERENCED_PARAMETER(ui32StrideInBytes);
+ PVR_UNREFERENCED_PARAMETER(sDevBaseAddr);
+ PVR_UNREFERENCED_PARAMETER(psDevMemContext);
+ PVR_UNREFERENCED_PARAMETER(ui32Size);
+ PVR_UNREFERENCED_PARAMETER(ePixelFormat);
+ PVR_UNREFERENCED_PARAMETER(ui32AddrMode);
+ PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemIntPDumpImageDescriptor)
+#endif
+static INLINE PVRSRV_ERROR
+DevmemIntPDumpImageDescriptor(CONNECTION_DATA * psConnection,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ DEVMEMINT_CTX *psDevMemContext,
+ IMG_UINT32 ui32Size,
+ const IMG_CHAR *pszFileName,
+ IMG_DEV_VIRTADDR sData,
+ IMG_UINT32 ui32DataSize,
+ IMG_UINT32 ui32LogicalWidth,
+ IMG_UINT32 ui32LogicalHeight,
+ IMG_UINT32 ui32PhysicalWidth,
+ IMG_UINT32 ui32PhysicalHeight,
+ PDUMP_PIXEL_FORMAT ePixFmt,
+ IMG_MEMLAYOUT eMemLayout,
+ IMG_FB_COMPRESSION eFBCompression,
+ const IMG_UINT32 *paui32FBCClearColour,
+ PDUMP_FBC_SWIZZLE eFBCSwizzle,
+ IMG_DEV_VIRTADDR sHeader,
+ IMG_UINT32 ui32HeaderSize,
+ IMG_UINT32 ui32PDumpFlags)
+{
+ PVR_UNREFERENCED_PARAMETER(psConnection);
+ PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+ PVR_UNREFERENCED_PARAMETER(psDevMemContext);
+ PVR_UNREFERENCED_PARAMETER(ui32Size);
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(sData);
+ PVR_UNREFERENCED_PARAMETER(ui32DataSize);
+ PVR_UNREFERENCED_PARAMETER(ui32LogicalWidth);
+ PVR_UNREFERENCED_PARAMETER(ui32LogicalHeight);
+ PVR_UNREFERENCED_PARAMETER(ui32PhysicalWidth);
+ PVR_UNREFERENCED_PARAMETER(ui32PhysicalHeight);
+ PVR_UNREFERENCED_PARAMETER(ePixFmt);
+ PVR_UNREFERENCED_PARAMETER(eMemLayout);
+ PVR_UNREFERENCED_PARAMETER(eFBCompression);
+ PVR_UNREFERENCED_PARAMETER(paui32FBCClearColour);
+ PVR_UNREFERENCED_PARAMETER(eFBCSwizzle);
+ PVR_UNREFERENCED_PARAMETER(sHeader);
+ PVR_UNREFERENCED_PARAMETER(ui32HeaderSize);
+ PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
+ return PVRSRV_OK;
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(DevmemIntPDumpDataDescriptor)
+#endif
+static INLINE PVRSRV_ERROR
+DevmemIntPDumpDataDescriptor(CONNECTION_DATA * psConnection,
+ PVRSRV_DEVICE_NODE *psDeviceNode,
+ DEVMEMINT_CTX *psDevMemContext,
+ IMG_UINT32 ui32Size,
+ const IMG_CHAR *pszFileName,
+ IMG_DEV_VIRTADDR sData,
+ IMG_UINT32 ui32DataSize,
+ IMG_UINT32 ui32ElementType,
+ IMG_UINT32 ui32ElementCount,
+ IMG_UINT32 ui32PDumpFlags)
+{
+ PVR_UNREFERENCED_PARAMETER(psConnection);
+ PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+ PVR_UNREFERENCED_PARAMETER(psDevMemContext);
+ PVR_UNREFERENCED_PARAMETER(ui32Size);
+ PVR_UNREFERENCED_PARAMETER(pszFileName);
+ PVR_UNREFERENCED_PARAMETER(sData);
+ PVR_UNREFERENCED_PARAMETER(ui32DataSize);
+ PVR_UNREFERENCED_PARAMETER(ui32ElementType);
+ PVR_UNREFERENCED_PARAMETER(ui32ElementCount);
+ PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
+ return PVRSRV_OK;
+}
+
+#endif /* PDUMP */
+
+PVRSRV_ERROR
+DevmemIntInit(void);
+
+PVRSRV_ERROR
+DevmemIntDeInit(void);
+
+PVRSRV_ERROR
+DevmemIntExportCtx(DEVMEMINT_CTX *psContext,
+ PMR *psPMR,
+ DEVMEMINT_CTX_EXPORT **ppsContextExport);
+
+PVRSRV_ERROR
+DevmemIntUnexportCtx(DEVMEMINT_CTX_EXPORT *psContextExport);
+
+PVRSRV_ERROR
+DevmemIntAcquireRemoteCtx(PMR *psPMR,
+ DEVMEMINT_CTX **ppsContext,
+ IMG_HANDLE *phPrivData);
+
+#endif /* DEVICEMEM_SERVER_H */
diff --git a/drivers/gpu/drm/img-rogue/devicemem_server_utils.h b/drivers/gpu/drm/img-rogue/devicemem_server_utils.h
new file mode 100644
index 000000000..4b54753de
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/devicemem_server_utils.h
@@ -0,0 +1,214 @@
+/**************************************************************************/ /*!
+@File
+@Title Device Memory Management
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Header file utilities that are specific to device memory functions
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "device.h"
+#include "pvrsrv_memallocflags.h"
+#include "pvrsrv.h"
+
+static INLINE PVRSRV_ERROR DevmemCPUCacheMode(PVRSRV_DEVICE_NODE *psDeviceNode,
+ PVRSRV_MEMALLOCFLAGS_T ulFlags,
+ IMG_UINT32 *pui32Ret)
+{
+ IMG_UINT32 ui32CPUCacheMode = PVRSRV_CPU_CACHE_MODE(ulFlags);
+ IMG_UINT32 ui32Ret;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ PVR_ASSERT(ui32CPUCacheMode == PVRSRV_CPU_CACHE_MODE(ulFlags));
+
+ switch (ui32CPUCacheMode)
+ {
+ case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED:
+ ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_UNCACHED;
+ break;
+
+ case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC:
+ ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC;
+ break;
+
+ case PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT:
+#if defined(SAFETY_CRITICAL_BUILD)
+ ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC;
+#else
+ ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_CACHED;
+#endif
+ break;
+
+ case PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT:
+
+ /*
+ * If system has no coherency but coherency has been requested for CPU
+ * and GPU we currently fall back to write-combine.
+ * This avoids errors on arm64 when uncached is turned into ordered device memory
+ * and suffers from problems with unaligned access.
+ */
+ if ( (PVRSRV_GPU_CACHE_MODE(ulFlags) == PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT) &&
+ !(PVRSRVSystemSnoopingOfCPUCache(psDeviceNode->psDevConfig) && PVRSRVSystemSnoopingOfDeviceCache(psDeviceNode->psDevConfig)) )
+ {
+ ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC;
+ }
+ else
+ {
+#if defined(SAFETY_CRITICAL_BUILD)
+ ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC;
+#else
+ ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_CACHED;
+#endif
+ }
+ break;
+
+ default:
+ PVR_LOG(("DevmemCPUCacheMode: Unknown CPU cache mode 0x%08x", ui32CPUCacheMode));
+ PVR_ASSERT(0);
+ /*
+ We should never get here, but if we do then setting the mode
+ to uncached is the safest thing to do.
+ */
+ ui32Ret = PVRSRV_MEMALLOCFLAG_CPU_UNCACHED;
+ eError = PVRSRV_ERROR_UNSUPPORTED_CACHE_MODE;
+ break;
+ }
+
+ *pui32Ret = ui32Ret;
+
+ return eError;
+}
+
+static INLINE PVRSRV_ERROR DevmemDeviceCacheMode(PVRSRV_DEVICE_NODE *psDeviceNode,
+ PVRSRV_MEMALLOCFLAGS_T ulFlags,
+ IMG_UINT32 *pui32Ret)
+{
+ IMG_UINT32 ui32DeviceCacheMode = PVRSRV_GPU_CACHE_MODE(ulFlags);
+ IMG_UINT32 ui32Ret;
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ PVR_ASSERT(ui32DeviceCacheMode == PVRSRV_GPU_CACHE_MODE(ulFlags));
+
+ switch (ui32DeviceCacheMode)
+ {
+ case PVRSRV_MEMALLOCFLAG_GPU_UNCACHED:
+ ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_UNCACHED;
+ break;
+
+ case PVRSRV_MEMALLOCFLAG_GPU_UNCACHED_WC:
+ ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_UNCACHED_WC;
+ break;
+
+ case PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT:
+#if defined(SAFETY_CRITICAL_BUILD)
+ ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_UNCACHED_WC;
+#else
+ ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_CACHED;
+#endif
+ break;
+
+ case PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT:
+
+ /*
+ * If system has no coherency but coherency has been requested for CPU
+ * and GPU we currently fall back to write-combine.
+ * This avoids errors on arm64 when uncached is turned into ordered device memory
+ * and suffers from problems with unaligned access.
+ */
+ if ( (PVRSRV_CPU_CACHE_MODE(ulFlags) == PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT) &&
+ !(PVRSRVSystemSnoopingOfCPUCache(psDeviceNode->psDevConfig) && PVRSRVSystemSnoopingOfDeviceCache(psDeviceNode->psDevConfig)) )
+ {
+ ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_UNCACHED_WC;
+ }
+ else
+ {
+#if defined(SAFETY_CRITICAL_BUILD)
+ ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_UNCACHED_WC;
+#else
+ ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_CACHED;
+#endif
+ }
+ break;
+
+ default:
+ PVR_LOG(("DevmemDeviceCacheMode: Unknown device cache mode 0x%08x", ui32DeviceCacheMode));
+ PVR_ASSERT(0);
+ /*
+ We should never get here, but if we do then setting the mode
+ to uncached is the safest thing to do.
+ */
+ ui32Ret = PVRSRV_MEMALLOCFLAG_GPU_UNCACHED;
+ eError = PVRSRV_ERROR_UNSUPPORTED_CACHE_MODE;
+ break;
+ }
+
+ *pui32Ret = ui32Ret;
+
+ return eError;
+}
+
+static INLINE IMG_BOOL DevmemCPUCacheCoherency(PVRSRV_DEVICE_NODE *psDeviceNode,
+ PVRSRV_MEMALLOCFLAGS_T ulFlags)
+{
+ IMG_UINT32 ui32CPUCacheMode = PVRSRV_CPU_CACHE_MODE(ulFlags);
+ IMG_BOOL bRet = IMG_FALSE;
+
+ PVR_ASSERT(ui32CPUCacheMode == PVRSRV_CPU_CACHE_MODE(ulFlags));
+
+ if (ui32CPUCacheMode == PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT)
+ {
+ bRet = PVRSRVSystemSnoopingOfDeviceCache(psDeviceNode->psDevConfig);
+ }
+ return bRet;
+}
+
+static INLINE IMG_BOOL DevmemDeviceCacheCoherency(PVRSRV_DEVICE_NODE *psDeviceNode,
+ PVRSRV_MEMALLOCFLAGS_T ulFlags)
+{
+ IMG_UINT32 ui32DeviceCacheMode = PVRSRV_GPU_CACHE_MODE(ulFlags);
+ IMG_BOOL bRet = IMG_FALSE;
+
+ PVR_ASSERT(ui32DeviceCacheMode == PVRSRV_GPU_CACHE_MODE(ulFlags));
+
+ if (ui32DeviceCacheMode == PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT)
+ {
+ bRet = PVRSRVSystemSnoopingOfCPUCache(psDeviceNode->psDevConfig);
+ }
+ return bRet;
+}
diff --git a/drivers/gpu/drm/img-rogue/devicemem_typedefs.h b/drivers/gpu/drm/img-rogue/devicemem_typedefs.h
new file mode 100644
index 000000000..98ad36c91
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/devicemem_typedefs.h
@@ -0,0 +1,142 @@
+/*************************************************************************/ /*!
+@File
+@Title Device Memory Management
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Client side part of device memory management -- this file
+ is forked from new_devmem_allocation.h as this one has to
+ reside in the top level include so that client code is able
+ to make use of the typedefs.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef DEVICEMEM_TYPEDEFS_H
+#define DEVICEMEM_TYPEDEFS_H
+
+#include
+#include "img_types.h"
+#include "pvrsrv_memallocflags.h"
+
+typedef struct DEVMEM_CONTEXT_TAG DEVMEM_CONTEXT; /*!< Convenience typedef for struct DEVMEM_CONTEXT_TAG */
+typedef struct DEVMEM_HEAP_TAG DEVMEM_HEAP; /*!< Convenience typedef for struct DEVMEM_HEAP_TAG */
+typedef struct DEVMEM_MEMDESC_TAG DEVMEM_MEMDESC; /*!< Convenience typedef for struct DEVMEM_MEMDESC_TAG */
+typedef struct DEVMEM_PAGELIST_TAG DEVMEM_PAGELIST; /*!< Convenience typedef for struct DEVMEM_PAGELIST_TAG */
+
+typedef IMG_HANDLE DEVMEM_EXPORTHANDLE; /*!< Typedef for DeviceMem Export Handle */
+typedef IMG_UINT64 DEVMEM_EXPORTKEY; /*!< Typedef for DeviceMem Export Key */
+typedef IMG_DEVMEM_SIZE_T DEVMEM_SIZE_T; /*!< Typedef for DeviceMem SIZE_T */
+typedef IMG_DEVMEM_LOG2ALIGN_T DEVMEM_LOG2ALIGN_T; /*!< Typedef for DeviceMem LOG2 Alignment */
+
+typedef struct DEVMEMX_PHYS_MEMDESC_TAG DEVMEMX_PHYSDESC; /*!< Convenience typedef for DevmemX physical */
+typedef struct DEVMEMX_VIRT_MEMDESC_TAG DEVMEMX_VIRTDESC; /*!< Convenience typedef for DevmemX virtual */
+
+/*! calling code needs all the info in this struct, to be able to pass it around */
+typedef struct
+{
+ /*! A handle to the PMR. */
+ IMG_HANDLE hPMRExportHandle;
+ /*! The "key" to prove we have authorisation to use this PMR */
+ IMG_UINT64 uiPMRExportPassword;
+ /*! Size and alignment properties for this PMR. Note, these
+ numbers are not trusted in kernel, but we need to cache them
+ client-side in order to allocate from the VM arena. The kernel
+ will know the actual alignment and size of the PMR and thus
+ would prevent client code from breaching security here. Ditto
+ for physmem granularity (aka page size) if this is different
+ from alignment */
+ IMG_DEVMEM_SIZE_T uiSize;
+ /*! We call this "contiguity guarantee" to be more precise than
+ calling it "alignment" or "page size", terms which may seem
+ similar but have different emphasis. The number reported here
+ is the minimum contiguity guarantee from the creator of the
+ PMR. Now, there is no requirement to allocate that coarsely
+ from the RA. The alignment given to the RA simply needs to be
+ at least as coarse as the device page size for the heap we
+ ultimately intend to map into. What is important is that the
+ device MMU data page size is not greater than the minimum
+ contiguity guarantee from the PMR. This value is reported to
+ the client in order that it can choose to make early checks and
+ perhaps decide which heap (in a variable page size scenario) it
+ would be safe to map this PMR into. For convenience, the
+ client may choose to use this argument as the alignment of the
+ virtual range he chooses to allocate, but this is _not_
+ necessary and in many cases would be able to get away with a
+ finer alignment, should the heap into which this PMR will be
+ mapped support it. */
+ IMG_DEVMEM_LOG2ALIGN_T uiLog2ContiguityGuarantee;
+} DEVMEM_EXPORTCOOKIE;
+
+/* Enum that describes the operation associated with changing sparse memory */
+typedef IMG_UINT32 SPARSE_MEM_RESIZE_FLAGS;
+#define SPARSE_RESIZE_NONE 0U
+
+ /* This should be set to indicate the change needs allocation */
+#define SPARSE_RESIZE_ALLOC 1U
+
+ /* This should be set to indicate the change needs free */
+#define SPARSE_RESIZE_FREE 2U
+
+#define SPARSE_RESIZE_BOTH (SPARSE_RESIZE_ALLOC | SPARSE_RESIZE_FREE)
+
+ /* This should be set to silently swap underlying physical memory
+ * without disturbing its device or cpu virtual maps.
+ * This flag is not supported in the case of PDUMP and could lead to
+ * PDUMP panic when used.
+ */
+#define SPARSE_REMAP_MEM 4U
+
+ /* Should be set to get the sparse changes appear in cpu virtual map */
+#define SPARSE_MAP_CPU_ADDR 8U
+
+
+/* To be used with all the sparse allocations that gets mapped to CPU Virtual
+ * space. The sparse allocation CPU mapping is torn down and re-mapped every
+ * time the sparse allocation layout changes.
+ */
+#define PVRSRV_UNMAP_ON_SPARSE_CHANGE 1
+
+/* To use with DevmemSubAllocate() as the default factor if no over-allocation
+ * is desired.
+ */
+#define DEVMEM_NO_PRE_ALLOCATE_MULTIPLIER (1U)
+
+/* Defines the max length for PMR, MemDesc, Device memory History and RI debug
+ * annotations stored in memory, including the null terminator.
+ */
+#define DEVMEM_ANNOTATION_MAX_LEN (PVR_ANNOTATION_MAX_LEN + 1U)
+
+#endif /* #ifndef DEVICEMEM_TYPEDEFS_H */
diff --git a/drivers/gpu/drm/img-rogue/devicemem_utils.c b/drivers/gpu/drm/img-rogue/devicemem_utils.c
new file mode 100644
index 000000000..44c9822d2
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/devicemem_utils.c
@@ -0,0 +1,1174 @@
+/*************************************************************************/ /*!
+@File
+@Title Device Memory Management internal utility functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Utility functions used internally by device memory management
+ code.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */ /**************************************************************************/
+
+#include "allocmem.h"
+#include "img_types.h"
+#include "img_defs.h"
+#include "pvrsrv_error.h"
+#include "ra.h"
+#include "devicemem_utils.h"
+#include "client_mm_bridge.h"
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO)
+#include "client_ri_bridge.h"
+#if defined(__KERNEL__)
+#include "pvrsrv.h"
+#else
+#include "pvr_bridge_client.h"
+#endif
+#endif
+
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+#include "proc_stats.h"
+#endif
+
+/*
+ SVM heap management support functions for CPU (un)mapping
+ */
+#define DEVMEM_MAP_SVM_USER_MANAGED_RETRY 2
+
+static inline PVRSRV_ERROR
+DevmemCPUMapSVMKernelManaged(DEVMEM_HEAP *psHeap,
+ DEVMEM_IMPORT *psImport,
+ IMG_UINT64 *ui64MapAddress)
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT64 ui64SvmMapAddr;
+ IMG_UINT64 ui64SvmMapAddrEnd;
+ IMG_UINT64 ui64SvmHeapAddrEnd;
+
+ /* SVM heap management always has XXX_MANAGER_KERNEL unless we
+ have triggered the fall back code-path in which case we
+ should not be calling into this code-path */
+ PVR_ASSERT(psHeap->ui32HeapManagerFlags == DEVMEM_HEAP_MANAGER_KERNEL);
+
+ /* By acquiring the CPU virtual address here, it essentially
+ means we lock-down the virtual address for the duration
+ of the life-cycle of the allocation until a de-allocation
+ request comes in. Thus the allocation is guaranteed not to
+ change its virtual address on the CPU during its life-time.
+ NOTE: Import might have already been CPU Mapped before now,
+ normally this is not a problem, see fall back */
+ eError = DevmemImportStructCPUMap(psImport);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_LOG_ERROR(eError, "DevmemImportStructCPUMap");
+ eError = PVRSRV_ERROR_DEVICEMEM_MAP_FAILED;
+ goto failSVM;
+ }
+
+ /* Supplied kernel mmap virtual address is also device virtual address;
+ calculate the heap & kernel supplied mmap virtual address limits */
+ ui64SvmMapAddr = (IMG_UINT64)(uintptr_t)psImport->sCPUImport.pvCPUVAddr;
+ ui64SvmHeapAddrEnd = psHeap->sBaseAddress.uiAddr + psHeap->uiSize;
+ ui64SvmMapAddrEnd = ui64SvmMapAddr + psImport->uiSize;
+ PVR_ASSERT(ui64SvmMapAddr != (IMG_UINT64)0);
+
+ /* SVM limit test may fail if processor has more virtual address bits than device */
+ if ((ui64SvmMapAddr >= ui64SvmHeapAddrEnd || ui64SvmMapAddrEnd > ui64SvmHeapAddrEnd) ||
+ (ui64SvmMapAddr & ~(ui64SvmHeapAddrEnd - 1)))
+ {
+ /* Unmap incompatible SVM virtual address, this
+ may not release address if it was elsewhere
+ CPU Mapped before call into this function */
+ DevmemImportStructCPUUnmap(psImport);
+
+ /* Flag incompatible SVM mapping */
+ eError = PVRSRV_ERROR_BAD_MAPPING;
+ goto failSVM;
+ }
+
+ *ui64MapAddress = ui64SvmMapAddr;
+failSVM:
+ /* either OK, MAP_FAILED or BAD_MAPPING */
+ return eError;
+}
+
+static inline void
+DevmemCPUUnmapSVMKernelManaged(DEVMEM_HEAP *psHeap, DEVMEM_IMPORT *psImport)
+{
+ PVR_UNREFERENCED_PARAMETER(psHeap);
+ DevmemImportStructCPUUnmap(psImport);
+}
+
+static inline PVRSRV_ERROR
+DevmemCPUMapSVMUserManaged(DEVMEM_HEAP *psHeap,
+ DEVMEM_IMPORT *psImport,
+ IMG_UINT uiAlign,
+ IMG_UINT64 *ui64MapAddress)
+{
+ RA_LENGTH_T uiAllocatedSize;
+ RA_BASE_T uiAllocatedAddr;
+ IMG_UINT64 ui64SvmMapAddr;
+ IMG_UINT uiRetry = 0;
+ PVRSRV_ERROR eError;
+
+ /* If SVM heap management has transitioned to XXX_MANAGER_USER,
+ this is essentially a fall back approach that ensures we
+ continue to satisfy SVM alloc. This approach is not without
+ hazards in that we may specify a virtual address that is
+ already in use by the user process */
+ PVR_ASSERT(psHeap->ui32HeapManagerFlags == DEVMEM_HEAP_MANAGER_USER);
+
+ /* Normally, for SVM heap allocations, CPUMap _must_ be done
+ before DevMap; ideally the initial CPUMap should be done by
+ SVM functions though this is not a hard requirement as long
+ as the prior elsewhere obtained CPUMap virtual address meets
+ SVM address requirements. This is a fall-back code-pathway
+ so we have to test that this assumption holds before we
+ progress any further */
+ OSLockAcquire(psImport->sCPUImport.hLock);
+
+ if (psImport->sCPUImport.ui32RefCount)
+ {
+ /* Already CPU Mapped SVM heap allocation, this prior elsewhere
+ obtained virtual address is responsible for the above
+ XXX_MANAGER_KERNEL failure. As we are not responsible for
+ this, we cannot progress any further so need to fail */
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Previously obtained CPU map address not SVM compatible"
+ , __func__));
+
+ /* Revert SVM heap to DEVMEM_HEAP_MANAGER_KERNEL */
+ psHeap->ui32HeapManagerFlags = DEVMEM_HEAP_MANAGER_KERNEL;
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "%s: Reverting SVM heap back to kernel managed",
+ __func__));
+
+ OSLockRelease(psImport->sCPUImport.hLock);
+
+ /* Do we need a more specific error code here */
+ eError = PVRSRV_ERROR_DEVICEMEM_ALREADY_MAPPED;
+ goto failSVM;
+ }
+
+ OSLockRelease(psImport->sCPUImport.hLock);
+
+ do
+ {
+ /* Next we proceed to instruct the kernel to use the RA_Alloc supplied
+ virtual address to map-in this SVM import suballocation; there is no
+ guarantee that this RA_Alloc virtual address may not collide with an
+ already in-use VMA range in the process */
+ eError = RA_Alloc(psHeap->psQuantizedVMRA,
+ psImport->uiSize,
+ RA_NO_IMPORT_MULTIPLIER,
+ 0, /* flags: this RA doesn't use flags*/
+ uiAlign,
+ "SVM_Virtual_Alloc",
+ &uiAllocatedAddr,
+ &uiAllocatedSize,
+ NULL /* don't care about per-import priv data */);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_LOG_ERROR(eError, "RA_Alloc");
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+ if (eError == PVRSRV_ERROR_RA_REQUEST_ALLOC_FAIL)
+ {
+ PVRSRV_ERROR eErr;
+ eErr = BridgePVRSRVUpdateOOMStats(GetBridgeHandle(psHeap->psCtx->hDevConnection),
+ PVRSRV_PROCESS_STAT_TYPE_OOM_VIRTMEM_COUNT,
+ OSGetCurrentProcessID());
+ PVR_LOG_IF_ERROR(eErr, "BridgePVRSRVUpdateOOMStats");
+ }
+#endif
+ goto failSVM;
+ }
+
+ /* No reason for allocated virtual size to be different from
+ the PMR's size */
+ psImport->sCPUImport.pvCPUVAddr = (void*)(uintptr_t)uiAllocatedAddr;
+ PVR_ASSERT(uiAllocatedSize == psImport->uiSize);
+
+ /* Map the import or allocation using the RA_Alloc virtual address;
+ the kernel may fail the request if the supplied virtual address
+ is already in-use in which case we re-try using another virtual
+ address obtained from the RA_Alloc */
+ eError = DevmemImportStructCPUMap(psImport);
+ if (eError != PVRSRV_OK)
+ {
+ /* For now we simply discard failed RA_Alloc() obtained virtual
+ address (i.e. plenty of virtual space), this prevents us from
+ re-using these and furthermore essentially blacklists these
+ addresses from future SVM consideration; We exit fall-back
+ attempt if retry exceeds the fall-back retry limit */
+ if (uiRetry++ > DEVMEM_MAP_SVM_USER_MANAGED_RETRY)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Cannot find SVM compatible address, bad mapping",
+ __func__));
+ eError = PVRSRV_ERROR_BAD_MAPPING;
+ goto failSVM;
+ }
+ }
+ else
+ {
+ /* Found compatible SVM virtual address, set as device virtual address */
+ ui64SvmMapAddr = (IMG_UINT64)(uintptr_t)psImport->sCPUImport.pvCPUVAddr;
+ }
+ } while (eError != PVRSRV_OK);
+
+ *ui64MapAddress = ui64SvmMapAddr;
+failSVM:
+ return eError;
+}
+
+static inline void
+DevmemCPUUnmapSVMUserManaged(DEVMEM_HEAP *psHeap, DEVMEM_IMPORT *psImport)
+{
+ RA_BASE_T uiAllocatedAddr;
+
+ /* We only free SVM compatible addresses, all addresses in
+ the blacklist are essentially excluded from future RA_Alloc */
+ uiAllocatedAddr = psImport->sDeviceImport.sDevVAddr.uiAddr;
+ RA_Free(psHeap->psQuantizedVMRA, uiAllocatedAddr);
+
+ DevmemImportStructCPUUnmap(psImport);
+}
+
+static inline PVRSRV_ERROR
+DevmemImportStructDevMapSVM(DEVMEM_HEAP *psHeap,
+ DEVMEM_IMPORT *psImport,
+ IMG_UINT uiAlign,
+ IMG_UINT64 *ui64MapAddress)
+{
+ PVRSRV_ERROR eError;
+
+ switch (psHeap->ui32HeapManagerFlags)
+ {
+ case DEVMEM_HEAP_MANAGER_KERNEL:
+ eError = DevmemCPUMapSVMKernelManaged(psHeap,
+ psImport,
+ ui64MapAddress);
+ if (eError == PVRSRV_ERROR_BAD_MAPPING)
+ {
+ /* If the SVM map address is outside of SVM heap limits,
+ change heap type to DEVMEM_HEAP_MANAGER_USER */
+ psHeap->ui32HeapManagerFlags = DEVMEM_HEAP_MANAGER_USER;
+
+ PVR_DPF((PVR_DBG_WARNING,
+ "%s: Kernel managed SVM heap is now user managed",
+ __func__));
+
+ /* Retry using user managed fall-back approach */
+ eError = DevmemCPUMapSVMUserManaged(psHeap,
+ psImport,
+ uiAlign,
+ ui64MapAddress);
+ }
+ break;
+
+ case DEVMEM_HEAP_MANAGER_USER:
+ eError = DevmemCPUMapSVMUserManaged(psHeap,
+ psImport,
+ uiAlign,
+ ui64MapAddress);
+ break;
+
+ default:
+ eError = PVRSRV_ERROR_INVALID_PARAMS;
+ break;
+ }
+
+ return eError;
+}
+
+static inline void
+DevmemImportStructDevUnmapSVM(DEVMEM_HEAP *psHeap, DEVMEM_IMPORT *psImport)
+{
+ switch (psHeap->ui32HeapManagerFlags)
+ {
+ case DEVMEM_HEAP_MANAGER_KERNEL:
+ DevmemCPUUnmapSVMKernelManaged(psHeap, psImport);
+ break;
+
+ case DEVMEM_HEAP_MANAGER_USER:
+ DevmemCPUUnmapSVMUserManaged(psHeap, psImport);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*
+ The Devmem import structure is the structure we use
+ to manage memory that is "imported" (which is page
+ granular) from the server into our process, this
+ includes allocations.
+
+ This allows memory to be imported without requiring
+ any CPU or device mapping. Memory can then be mapped
+ into the device or CPU on demand, but neither is
+ required.
+ */
+
+IMG_INTERNAL
+void DevmemImportStructAcquire(DEVMEM_IMPORT *psImport)
+{
+ IMG_INT iRefCount = OSAtomicIncrement(&psImport->hRefCount);
+ PVR_UNREFERENCED_PARAMETER(iRefCount);
+ PVR_ASSERT(iRefCount != 1);
+
+ DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+ __func__,
+ psImport,
+ iRefCount-1,
+ iRefCount);
+}
+
+IMG_INTERNAL
+IMG_BOOL DevmemImportStructRelease(DEVMEM_IMPORT *psImport)
+{
+ IMG_INT iRefCount = OSAtomicDecrement(&psImport->hRefCount);
+ PVR_ASSERT(iRefCount >= 0);
+
+ DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+ __func__,
+ psImport,
+ iRefCount+1,
+ iRefCount);
+
+ if (iRefCount == 0)
+ {
+ BridgePMRUnrefPMR(GetBridgeHandle(psImport->hDevConnection),
+ psImport->hPMR);
+ OSLockDestroy(psImport->sCPUImport.hLock);
+ OSLockDestroy(psImport->sDeviceImport.hLock);
+ OSLockDestroy(psImport->hLock);
+ OSFreeMem(psImport);
+
+ return IMG_TRUE;
+ }
+
+ return IMG_FALSE;
+}
+
+IMG_INTERNAL
+void DevmemImportDiscard(DEVMEM_IMPORT *psImport)
+{
+ PVR_ASSERT(OSAtomicRead(&psImport->hRefCount) == 0);
+ OSLockDestroy(psImport->sCPUImport.hLock);
+ OSLockDestroy(psImport->sDeviceImport.hLock);
+ OSLockDestroy(psImport->hLock);
+ OSFreeMem(psImport);
+}
+
+IMG_INTERNAL
+PVRSRV_ERROR DevmemMemDescAlloc(DEVMEM_MEMDESC **ppsMemDesc)
+{
+ DEVMEM_MEMDESC *psMemDesc;
+ PVRSRV_ERROR eError;
+
+ /* Must be zeroed in case it needs to be freed before it is initialised */
+ psMemDesc = OSAllocZMem(sizeof(DEVMEM_MEMDESC));
+ PVR_GOTO_IF_NOMEM(psMemDesc, eError, failAlloc);
+
+ eError = OSLockCreate(&psMemDesc->hLock);
+ PVR_GOTO_IF_ERROR(eError, failMDLock);
+
+ eError = OSLockCreate(&psMemDesc->sDeviceMemDesc.hLock);
+ PVR_GOTO_IF_ERROR(eError, failDMDLock);
+
+ eError = OSLockCreate(&psMemDesc->sCPUMemDesc.hLock);
+ PVR_GOTO_IF_ERROR(eError, failCMDLock);
+
+ OSAtomicWrite(&psMemDesc->hRefCount, 0);
+
+ *ppsMemDesc = psMemDesc;
+
+ return PVRSRV_OK;
+
+failCMDLock:
+ OSLockDestroy(psMemDesc->sDeviceMemDesc.hLock);
+failDMDLock:
+ OSLockDestroy(psMemDesc->hLock);
+failMDLock:
+ OSFreeMem(psMemDesc);
+failAlloc:
+ PVR_ASSERT(eError != PVRSRV_OK);
+
+ return eError;
+}
+
+/*
+ Init the MemDesc structure
+ */
+IMG_INTERNAL
+void DevmemMemDescInit(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ DEVMEM_IMPORT *psImport,
+ IMG_DEVMEM_SIZE_T uiSize)
+{
+ DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+ __func__,
+ psMemDesc,
+ 0,
+ 1);
+
+ psMemDesc->psImport = psImport;
+ psMemDesc->uiOffset = uiOffset;
+
+ psMemDesc->sDeviceMemDesc.ui32RefCount = 0;
+ psMemDesc->sCPUMemDesc.ui32RefCount = 0;
+ psMemDesc->uiAllocSize = uiSize;
+ psMemDesc->hPrivData = NULL;
+ psMemDesc->ui32AllocationIndex = DEVICEMEM_HISTORY_ALLOC_INDEX_NONE;
+
+ OSAtomicWrite(&psMemDesc->hRefCount, 1);
+}
+
+IMG_INTERNAL
+void DevmemMemDescAcquire(DEVMEM_MEMDESC *psMemDesc)
+{
+ IMG_INT iRefCount = 0;
+
+ iRefCount = OSAtomicIncrement(&psMemDesc->hRefCount);
+ DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+ __func__,
+ psMemDesc,
+ iRefCount-1,
+ iRefCount);
+
+ PVR_UNREFERENCED_PARAMETER(iRefCount);
+}
+
+IMG_INTERNAL
+IMG_BOOL DevmemMemDescRelease(DEVMEM_MEMDESC *psMemDesc)
+{
+ IMG_INT iRefCount;
+ PVR_ASSERT(psMemDesc != NULL);
+
+ iRefCount = OSAtomicDecrement(&psMemDesc->hRefCount);
+ PVR_ASSERT(iRefCount >= 0);
+
+ DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+ __func__,
+ psMemDesc,
+ iRefCount+1,
+ iRefCount);
+
+ if (iRefCount == 0)
+ {
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO)
+ if (PVRSRVIsBridgeEnabled(GetBridgeHandle(psMemDesc->psImport->hDevConnection), PVRSRV_BRIDGE_RI) &&
+ (psMemDesc->hRIHandle))
+ {
+ PVRSRV_ERROR eError;
+
+ eError = BridgeRIDeleteMEMDESCEntry(GetBridgeHandle(psMemDesc->psImport->hDevConnection),
+ psMemDesc->hRIHandle);
+ PVR_LOG_IF_ERROR(eError, "BridgeRIDeleteMEMDESCEntry");
+ }
+#endif
+
+ OSLockAcquire(psMemDesc->psImport->hLock);
+ if (psMemDesc->psImport->uiProperties & DEVMEM_PROPERTIES_SUBALLOCATABLE)
+ {
+ /* As soon as the first sub-allocation on the psImport is freed
+ * we might get dirty memory when reusing it.
+ * We have to delete the ZEROED, CLEAN & POISONED flag */
+
+ psMemDesc->psImport->uiProperties &=
+ ~(DEVMEM_PROPERTIES_IMPORT_IS_ZEROED |
+ DEVMEM_PROPERTIES_IMPORT_IS_CLEAN |
+ DEVMEM_PROPERTIES_IMPORT_IS_POISONED);
+
+ OSLockRelease(psMemDesc->psImport->hLock);
+
+ RA_Free(psMemDesc->psImport->sDeviceImport.psHeap->psSubAllocRA,
+ psMemDesc->psImport->sDeviceImport.sDevVAddr.uiAddr +
+ psMemDesc->uiOffset);
+ }
+ else
+ {
+ OSLockRelease(psMemDesc->psImport->hLock);
+ DevmemImportStructRelease(psMemDesc->psImport);
+ }
+
+ OSLockDestroy(psMemDesc->sCPUMemDesc.hLock);
+ OSLockDestroy(psMemDesc->sDeviceMemDesc.hLock);
+ OSLockDestroy(psMemDesc->hLock);
+ OSFreeMem(psMemDesc);
+
+ return IMG_TRUE;
+ }
+
+ return IMG_FALSE;
+}
+
+IMG_INTERNAL
+void DevmemMemDescDiscard(DEVMEM_MEMDESC *psMemDesc)
+{
+ PVR_ASSERT(OSAtomicRead(&psMemDesc->hRefCount) == 0);
+
+ OSLockDestroy(psMemDesc->sCPUMemDesc.hLock);
+ OSLockDestroy(psMemDesc->sDeviceMemDesc.hLock);
+ OSLockDestroy(psMemDesc->hLock);
+ OSFreeMem(psMemDesc);
+}
+
+
+IMG_INTERNAL
+PVRSRV_ERROR DevmemValidateParams(IMG_DEVMEM_SIZE_T uiSize,
+ IMG_DEVMEM_ALIGN_T uiAlign,
+ PVRSRV_MEMALLOCFLAGS_T *puiFlags)
+{
+ if ((*puiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC) &&
+ (*puiFlags & PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Zero on Alloc and Poison on Alloc are mutually exclusive.",
+ __func__));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (uiAlign & (uiAlign-1))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: The requested alignment is not a power of two.",
+ __func__));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (uiSize == 0)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Please request a non-zero size value.",
+ __func__));
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ /* If zero flag is set we have to have write access to the page. */
+ if (PVRSRV_CHECK_ZERO_ON_ALLOC(*puiFlags) || PVRSRV_CHECK_CPU_WRITEABLE(*puiFlags))
+ {
+ (*puiFlags) |= PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+ PVRSRV_MEMALLOCFLAG_CPU_READABLE;
+ }
+
+ return PVRSRV_OK;
+}
+
+/*
+ Allocate and init an import structure
+ */
+IMG_INTERNAL
+PVRSRV_ERROR DevmemImportStructAlloc(SHARED_DEV_CONNECTION hDevConnection,
+ DEVMEM_IMPORT **ppsImport)
+{
+ DEVMEM_IMPORT *psImport;
+ PVRSRV_ERROR eError;
+
+ psImport = OSAllocMem(sizeof(*psImport));
+ PVR_RETURN_IF_FALSE(psImport != NULL, PVRSRV_ERROR_OUT_OF_MEMORY);
+
+ /* Setup some known bad values for things we don't have yet */
+ psImport->sDeviceImport.hReservation = LACK_OF_RESERVATION_POISON;
+ psImport->sDeviceImport.hMapping = LACK_OF_MAPPING_POISON;
+ psImport->sDeviceImport.psHeap = NULL;
+ psImport->sDeviceImport.bMapped = IMG_FALSE;
+
+ eError = OSLockCreate(&psImport->sDeviceImport.hLock);
+ PVR_GOTO_IF_ERROR(eError, failDIOSLockCreate);
+
+ psImport->sCPUImport.hOSMMapData = NULL;
+ psImport->sCPUImport.pvCPUVAddr = NULL;
+
+ eError = OSLockCreate(&psImport->sCPUImport.hLock);
+ PVR_GOTO_IF_ERROR(eError, failCIOSLockCreate);
+
+ /* Set up common elements */
+ psImport->hDevConnection = hDevConnection;
+
+ /* Setup properties */
+ psImport->uiProperties = 0;
+
+ /* Setup refcounts */
+ psImport->sDeviceImport.ui32RefCount = 0;
+ psImport->sCPUImport.ui32RefCount = 0;
+ OSAtomicWrite(&psImport->hRefCount, 0);
+
+ /* Create the lock */
+ eError = OSLockCreate(&psImport->hLock);
+ PVR_GOTO_IF_ERROR(eError, failILockAlloc);
+
+ *ppsImport = psImport;
+
+ return PVRSRV_OK;
+
+failILockAlloc:
+ OSLockDestroy(psImport->sCPUImport.hLock);
+failCIOSLockCreate:
+ OSLockDestroy(psImport->sDeviceImport.hLock);
+failDIOSLockCreate:
+ OSFreeMem(psImport);
+ PVR_ASSERT(eError != PVRSRV_OK);
+
+ return eError;
+}
+
+/*
+ Initialise the import structure
+ */
+IMG_INTERNAL
+void DevmemImportStructInit(DEVMEM_IMPORT *psImport,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_DEVMEM_ALIGN_T uiAlign,
+ PVRSRV_MEMALLOCFLAGS_T uiFlags,
+ IMG_HANDLE hPMR,
+ DEVMEM_PROPERTIES_T uiProperties)
+{
+ DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+ __func__,
+ psImport,
+ 0,
+ 1);
+
+ psImport->uiSize = uiSize;
+ psImport->uiAlign = uiAlign;
+ psImport->uiFlags = uiFlags;
+ psImport->hPMR = hPMR;
+ psImport->uiProperties = uiProperties;
+ OSAtomicWrite(&psImport->hRefCount, 1);
+}
+
+/* Allocate the requested device virtual address region
+ * from the heap */
+static PVRSRV_ERROR DevmemReserveVARange(DEVMEM_HEAP *psHeap,
+ DEVMEM_SIZE_T uiSize,
+ IMG_UINT uiAlign,
+ RA_LENGTH_T *puiAllocatedSize,
+ IMG_UINT64 ui64OptionalMapAddress)
+{
+ PVRSRV_ERROR eError;
+
+ /* Allocate space in the VM */
+ eError = RA_Alloc_Range(psHeap->psQuantizedVMRA,
+ uiSize,
+ 0,
+ uiAlign,
+ ui64OptionalMapAddress,
+ puiAllocatedSize);
+
+ if (PVRSRV_OK != eError)
+ {
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+ if ((eError == PVRSRV_ERROR_RA_REQUEST_ALLOC_FAIL) ||
+ (eError == PVRSRV_ERROR_RA_REQUEST_VIRT_ADDR_FAIL))
+ {
+ PVRSRV_ERROR eErr;
+ eErr = BridgePVRSRVUpdateOOMStats(GetBridgeHandle(psHeap->psCtx->hDevConnection),
+ PVRSRV_PROCESS_STAT_TYPE_INVALID_VIRTMEM,
+ OSGetCurrentProcessID());
+ PVR_LOG_IF_ERROR(eErr, "BridgePVRSRVUpdateOOMStats");
+ }
+#endif
+ return eError;
+ }
+
+ /* No reason for the allocated virtual size to be different from
+ the PMR's size */
+ PVR_ASSERT(*puiAllocatedSize == uiSize);
+
+ return PVRSRV_OK;
+}
+
+/*
+ Map an import to the device
+ */
+IMG_INTERNAL
+PVRSRV_ERROR DevmemImportStructDevMap(DEVMEM_HEAP *psHeap,
+ IMG_BOOL bMap,
+ DEVMEM_IMPORT *psImport,
+ IMG_UINT64 ui64OptionalMapAddress)
+{
+ DEVMEM_DEVICE_IMPORT *psDeviceImport;
+ RA_BASE_T uiAllocatedAddr;
+ RA_LENGTH_T uiAllocatedSize;
+ IMG_DEV_VIRTADDR sBase;
+ IMG_HANDLE hReservation;
+ PVRSRV_ERROR eError;
+ IMG_UINT uiAlign;
+ IMG_BOOL bDestroyed = IMG_FALSE;
+
+ /* Round the provided import alignment to the configured heap alignment */
+ uiAlign = 1ULL << psHeap->uiLog2ImportAlignment;
+ uiAlign = (psImport->uiAlign + uiAlign - 1) & ~(uiAlign-1);
+
+ psDeviceImport = &psImport->sDeviceImport;
+
+ OSLockAcquire(psDeviceImport->hLock);
+ DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+ __func__,
+ psImport,
+ psDeviceImport->ui32RefCount,
+ psDeviceImport->ui32RefCount+1);
+
+ if (psDeviceImport->ui32RefCount++ == 0)
+ {
+ DevmemImportStructAcquire(psImport);
+
+ OSAtomicIncrement(&psHeap->hImportCount);
+
+ if (PVRSRV_CHECK_SVM_ALLOC(psImport->uiFlags))
+ {
+ /* SVM (shared virtual memory) imports or allocations always
+ need to acquire CPU virtual address first as address is
+ used to map the allocation into the device virtual address
+ space; i.e. the virtual address of the allocation for both
+ the CPU/GPU must be identical. */
+ eError = DevmemImportStructDevMapSVM(psHeap,
+ psImport,
+ uiAlign,
+ &ui64OptionalMapAddress);
+ PVR_GOTO_IF_ERROR(eError, failVMRAAlloc);
+ }
+
+ if (ui64OptionalMapAddress == 0)
+ {
+ /* If heap is _completely_ managed by USER or KERNEL, we shouldn't
+ * be here, as this is RA manager code-path */
+ if (psHeap->ui32HeapManagerFlags == DEVMEM_HEAP_MANAGER_USER ||
+ psHeap->ui32HeapManagerFlags == DEVMEM_HEAP_MANAGER_KERNEL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ psHeap->ui32HeapManagerFlags == DEVMEM_HEAP_MANAGER_USER ?
+ "%s: Heap is user managed, please use PVRSRVMapToDeviceAddress().":
+ "%s: Heap is kernel managed, use right allocation flags (e.g. SVM).",
+ __func__));
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, failVMRAAlloc);
+ }
+
+ if (psHeap->ui32HeapManagerFlags == DEVMEM_HEAP_MANAGER_UNKNOWN)
+ {
+ /* Only set the heap manager (to RA) at first map when heap manager
+ * is unknown. It might be a dual heap (both, user and RA managed),
+ * in which case heap manager is set at creation time */
+ psHeap->ui32HeapManagerFlags = DEVMEM_HEAP_MANAGER_RA;
+ }
+
+ /* Allocate space in the VM */
+ eError = RA_Alloc(psHeap->psQuantizedVMRA,
+ psImport->uiSize,
+ RA_NO_IMPORT_MULTIPLIER,
+ 0, /* flags: this RA doesn't use flags*/
+ uiAlign,
+ "Virtual_Alloc",
+ &uiAllocatedAddr,
+ &uiAllocatedSize,
+ NULL /* don't care about per-import priv data */
+ );
+ if (PVRSRV_OK != eError)
+ {
+#if defined(PVRSRV_ENABLE_PROCESS_STATS)
+ if (eError == PVRSRV_ERROR_RA_REQUEST_ALLOC_FAIL)
+ {
+ PVRSRV_ERROR eErr;
+ eErr = BridgePVRSRVUpdateOOMStats(GetBridgeHandle(psHeap->psCtx->hDevConnection),
+ PVRSRV_PROCESS_STAT_TYPE_OOM_VIRTMEM_COUNT,
+ OSGetCurrentProcessID());
+ PVR_LOG_IF_ERROR(eErr, "BridgePVRSRVUpdateOOMStats");
+ }
+#endif
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_OUT_OF_DEVICE_VM, failVMRAAlloc);
+ }
+
+ /* No reason for the allocated virtual size to be different from
+ the PMR's size */
+ PVR_ASSERT(uiAllocatedSize == psImport->uiSize);
+
+ sBase.uiAddr = uiAllocatedAddr;
+
+ }
+ else
+ {
+ IMG_UINT64 ui64ValidEndAddr;
+
+ /* Ensure supplied ui64OptionalMapAddress is within heap range */
+ ui64ValidEndAddr = psHeap->sBaseAddress.uiAddr + psHeap->uiSize;
+ if ((ui64OptionalMapAddress + psImport->uiSize > ui64ValidEndAddr) ||
+ (ui64OptionalMapAddress < psHeap->sBaseAddress.uiAddr))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: ui64OptionalMapAddress %p is outside of heap limits <%p:%p>."
+ , __func__
+ , (void*)(uintptr_t)ui64OptionalMapAddress
+ , (void*)(uintptr_t)psHeap->sBaseAddress.uiAddr
+ , (void*)(uintptr_t)ui64ValidEndAddr));
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, failVMRAAlloc);
+ }
+
+ switch (psHeap->ui32HeapManagerFlags)
+ {
+ case DEVMEM_HEAP_MANAGER_UNKNOWN:
+ /* DEVMEM_HEAP_MANAGER_USER can apply to _any_ heap and can only
+ * be determined here. This heap type transitions from
+ * DEVMEM_HEAP_MANAGER_UNKNOWN to DEVMEM_HEAP_MANAGER_USER on
+ * 1st alloc. */
+ psHeap->ui32HeapManagerFlags = DEVMEM_HEAP_MANAGER_USER;
+ break;
+
+ case DEVMEM_HEAP_MANAGER_USER:
+ case DEVMEM_HEAP_MANAGER_KERNEL:
+ if (! psHeap->uiSize)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ psHeap->ui32HeapManagerFlags == DEVMEM_HEAP_MANAGER_USER ?
+ "%s: Heap DEVMEM_HEAP_MANAGER_USER is disabled.":
+ "%s: Heap DEVMEM_HEAP_MANAGER_KERNEL is disabled."
+ , __func__));
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_HEAP, failVMRAAlloc);
+ }
+ break;
+
+ case DEVMEM_HEAP_MANAGER_DUAL_USER_RA:
+ /* When the heap is dual managed, ensure supplied ui64OptionalMapAddress
+ * and import size are within heap address space range */
+ if (ui64OptionalMapAddress + psImport->uiSize <=
+ psHeap->sBaseAddress.uiAddr + psHeap->uiReservedRegionSize)
+ {
+ break;
+ }
+ else
+ {
+ /* Allocate requested VM range */
+ eError = DevmemReserveVARange(psHeap,
+ psImport->uiSize,
+ uiAlign,
+ &uiAllocatedSize,
+ ui64OptionalMapAddress);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_VA_ALLOC_FAILED, failVMRAAlloc);
+ }
+
+ }
+ break;
+ case DEVMEM_HEAP_MANAGER_RA:
+ /* Allocate requested VM range */
+ eError = DevmemReserveVARange(psHeap,
+ psImport->uiSize,
+ uiAlign,
+ &uiAllocatedSize,
+ ui64OptionalMapAddress);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_DEVICEMEM_VA_ALLOC_FAILED, failVMRAAlloc);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (ui64OptionalMapAddress & ((1 << psHeap->uiLog2Quantum) - 1))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Invalid address to map to. Please provide an "
+ "address aligned to a page multiple of the heap."
+ , __func__));
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, failVMRAAlloc);
+ }
+
+ if (psImport->uiSize & ((1 << psHeap->uiLog2Quantum) - 1))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Invalid heap to map to. "
+ "Please choose a heap that can handle smaller page sizes."
+ , __func__));
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, failVMRAAlloc);
+ }
+
+ uiAllocatedAddr = ui64OptionalMapAddress;
+ uiAllocatedSize = psImport->uiSize;
+ sBase.uiAddr = uiAllocatedAddr;
+ }
+
+ if (psHeap->bPremapped)
+ {
+ /* no virtual address reservation and mapping are required for memory that's already mapped */
+ psDeviceImport->hReservation = LACK_OF_RESERVATION_POISON;
+ psDeviceImport->hMapping = LACK_OF_MAPPING_POISON;
+ }
+ else
+ {
+ /* Setup page tables for the allocated VM space */
+ eError = BridgeDevmemIntReserveRange(GetBridgeHandle(psHeap->psCtx->hDevConnection),
+ psHeap->hDevMemServerHeap,
+ sBase,
+ uiAllocatedSize,
+ &hReservation);
+ PVR_GOTO_IF_ERROR(eError, failReserve);
+
+ if (bMap)
+ {
+ PVRSRV_MEMALLOCFLAGS_T uiMapFlags;
+
+ uiMapFlags = psImport->uiFlags & PVRSRV_MEMALLOCFLAGS_PERMAPPINGFLAGSMASK;
+
+ /* Actually map the PMR to allocated VM space */
+ eError = BridgeDevmemIntMapPMR(GetBridgeHandle(psHeap->psCtx->hDevConnection),
+ psHeap->hDevMemServerHeap,
+ hReservation,
+ psImport->hPMR,
+ uiMapFlags,
+ &psDeviceImport->hMapping);
+ PVR_GOTO_IF_ERROR(eError, failMap);
+
+ psDeviceImport->bMapped = IMG_TRUE;
+ }
+
+ psDeviceImport->hReservation = hReservation;
+ }
+
+ /* Setup device mapping specific parts of the mapping info */
+ psDeviceImport->sDevVAddr.uiAddr = uiAllocatedAddr;
+ psDeviceImport->psHeap = psHeap;
+ }
+ else
+ {
+ /*
+ Check that we've been asked to map it into the
+ same heap 2nd time around
+ */
+ if (psHeap != psDeviceImport->psHeap)
+ {
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_HEAP, failParams);
+ }
+ }
+ OSLockRelease(psDeviceImport->hLock);
+
+ return PVRSRV_OK;
+
+failMap:
+ if (!psHeap->bPremapped)
+ {
+ BridgeDevmemIntUnreserveRange(GetBridgeHandle(psHeap->psCtx->hDevConnection),
+ hReservation);
+ }
+failReserve:
+ if (ui64OptionalMapAddress == 0)
+ {
+ RA_Free(psHeap->psQuantizedVMRA,
+ uiAllocatedAddr);
+ }
+failVMRAAlloc:
+ if ((ui64OptionalMapAddress) && PVRSRV_CHECK_SVM_ALLOC(psImport->uiFlags))
+ {
+ DevmemImportStructDevUnmapSVM(psHeap, psImport);
+ }
+ bDestroyed = DevmemImportStructRelease(psImport);
+ OSAtomicDecrement(&psHeap->hImportCount);
+failParams:
+ if (!bDestroyed)
+ {
+ psDeviceImport->ui32RefCount--;
+ OSLockRelease(psDeviceImport->hLock);
+ }
+ PVR_ASSERT(eError != PVRSRV_OK);
+ return eError;
+}
+
+/*
+ Unmap an import from the Device
+ */
+IMG_INTERNAL
+IMG_BOOL DevmemImportStructDevUnmap(DEVMEM_IMPORT *psImport)
+{
+ PVRSRV_ERROR eError;
+ DEVMEM_DEVICE_IMPORT *psDeviceImport;
+
+ psDeviceImport = &psImport->sDeviceImport;
+
+ OSLockAcquire(psDeviceImport->hLock);
+ DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+ __func__,
+ psImport,
+ psDeviceImport->ui32RefCount,
+ psDeviceImport->ui32RefCount-1);
+
+ if (--psDeviceImport->ui32RefCount == 0)
+ {
+ DEVMEM_HEAP *psHeap = psDeviceImport->psHeap;
+
+ if (!psHeap->bPremapped)
+ {
+ if (psDeviceImport->bMapped)
+ {
+ eError = BridgeDevmemIntUnmapPMR(GetBridgeHandle(psImport->hDevConnection),
+ psDeviceImport->hMapping);
+ PVR_ASSERT(eError == PVRSRV_OK);
+ }
+
+ eError = BridgeDevmemIntUnreserveRange(GetBridgeHandle(psImport->hDevConnection),
+ psDeviceImport->hReservation);
+ PVR_ASSERT(eError == PVRSRV_OK);
+ }
+
+ psDeviceImport->bMapped = IMG_FALSE;
+ psDeviceImport->hMapping = LACK_OF_MAPPING_POISON;
+ psDeviceImport->hReservation = LACK_OF_RESERVATION_POISON;
+
+ /* DEVMEM_HEAP_MANAGER_RA can also come from a dual managed heap in which case,
+ we need to check if the allocated VA falls within RA managed range */
+ if ((psHeap->ui32HeapManagerFlags & DEVMEM_HEAP_MANAGER_RA) &&
+ psDeviceImport->sDevVAddr.uiAddr >= (psHeap->sBaseAddress.uiAddr + psHeap->uiReservedRegionSize) &&
+ psDeviceImport->sDevVAddr.uiAddr < (psHeap->sBaseAddress.uiAddr + psHeap->uiSize))
+ {
+ RA_Free(psHeap->psQuantizedVMRA, psDeviceImport->sDevVAddr.uiAddr);
+ }
+
+ if (PVRSRV_CHECK_SVM_ALLOC(psImport->uiFlags))
+ {
+ DevmemImportStructDevUnmapSVM(psHeap, psImport);
+ }
+
+ OSLockRelease(psDeviceImport->hLock);
+
+ DevmemImportStructRelease(psImport);
+
+ OSAtomicDecrement(&psHeap->hImportCount);
+
+ return IMG_TRUE;
+ }
+ else
+ {
+ OSLockRelease(psDeviceImport->hLock);
+ return IMG_FALSE;
+ }
+}
+
+/*
+ Map an import into the CPU
+ */
+IMG_INTERNAL
+PVRSRV_ERROR DevmemImportStructCPUMap(DEVMEM_IMPORT *psImport)
+{
+ PVRSRV_ERROR eError;
+ DEVMEM_CPU_IMPORT *psCPUImport;
+ size_t uiMappingLength;
+
+ psCPUImport = &psImport->sCPUImport;
+
+ OSLockAcquire(psCPUImport->hLock);
+ DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+ __func__,
+ psImport,
+ psCPUImport->ui32RefCount,
+ psCPUImport->ui32RefCount+1);
+
+ if (psCPUImport->ui32RefCount++ == 0)
+ {
+ DevmemImportStructAcquire(psImport);
+
+ eError = OSMMapPMR(GetBridgeHandle(psImport->hDevConnection),
+ psImport->hPMR,
+ psImport->uiSize,
+ psImport->uiFlags,
+ &psCPUImport->hOSMMapData,
+ &psCPUImport->pvCPUVAddr,
+ &uiMappingLength);
+ PVR_GOTO_IF_ERROR(eError, failMap);
+
+ /* MappingLength might be rounded up to page size */
+ PVR_ASSERT(uiMappingLength >= psImport->uiSize);
+ }
+ OSLockRelease(psCPUImport->hLock);
+
+ return PVRSRV_OK;
+
+failMap:
+ psCPUImport->ui32RefCount--;
+ if (!DevmemImportStructRelease(psImport))
+ {
+ OSLockRelease(psCPUImport->hLock);
+ }
+ PVR_ASSERT(eError != PVRSRV_OK);
+ return eError;
+}
+
+/*
+ Unmap an import from the CPU
+ */
+IMG_INTERNAL
+void DevmemImportStructCPUUnmap(DEVMEM_IMPORT *psImport)
+{
+ DEVMEM_CPU_IMPORT *psCPUImport;
+
+ psCPUImport = &psImport->sCPUImport;
+
+ OSLockAcquire(psCPUImport->hLock);
+ DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
+ __func__,
+ psImport,
+ psCPUImport->ui32RefCount,
+ psCPUImport->ui32RefCount-1);
+
+ if (--psCPUImport->ui32RefCount == 0)
+ {
+ /* psImport->uiSize is a 64-bit quantity whereas the 5th
+ * argument to OSUnmapPMR is a 32-bit quantity on 32-bit systems
+ * hence a compiler warning of implicit cast and loss of data.
+ * Added explicit cast and assert to remove warning.
+ */
+#if defined(__linux__) && defined(__i386__)
+ PVR_ASSERT(psImport->uiSizehDevConnection),
+ psImport->hPMR,
+ psCPUImport->hOSMMapData,
+ psCPUImport->pvCPUVAddr,
+ (size_t)psImport->uiSize);
+
+ psCPUImport->hOSMMapData = NULL;
+ psCPUImport->pvCPUVAddr = NULL;
+
+ OSLockRelease(psCPUImport->hLock);
+
+ DevmemImportStructRelease(psImport);
+ }
+ else
+ {
+ OSLockRelease(psCPUImport->hLock);
+ }
+}
diff --git a/drivers/gpu/drm/img-rogue/devicemem_utils.h b/drivers/gpu/drm/img-rogue/devicemem_utils.h
new file mode 100644
index 000000000..621ca5115
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/devicemem_utils.h
@@ -0,0 +1,522 @@
+/*************************************************************************/ /*!
+@File
+@Title Device Memory Management internal utility functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Utility functions used internally by device memory management
+ code.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef DEVICEMEM_UTILS_H
+#define DEVICEMEM_UTILS_H
+
+#include "devicemem.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+#include "pvr_debug.h"
+#include "allocmem.h"
+#include "ra.h"
+#include "osfunc.h"
+#include "lock.h"
+#include "osmmap.h"
+
+#define DEVMEM_HEAPNAME_MAXLENGTH 160
+
+/*
+ * Reserved VA space of a heap must always be multiple of DEVMEM_HEAP_RESERVED_SIZE_GRANULARITY,
+ * this check is validated in the DDK. Note this is only reserving "Virtual Address" space and
+ * physical allocations (and mappings thereon) should only be done as much as required (to avoid
+ * wastage).
+ * Granularity has been chosen to support the max possible practically used OS page size.
+ */
+#define DEVMEM_HEAP_RESERVED_SIZE_GRANULARITY 0x10000 /* 64KB is MAX anticipated OS page size */
+
+/*
+ * VA heap size should be at least OS page size. This check is validated in the DDK.
+ */
+#define DEVMEM_HEAP_MINIMUM_SIZE 0x10000 /* 64KB is MAX anticipated OS page size */
+
+#if defined(DEVMEM_DEBUG) && defined(REFCOUNT_DEBUG)
+#define DEVMEM_REFCOUNT_PRINT(fmt, ...) PVRSRVDebugPrintf(PVR_DBG_ERROR, __FILE__, __LINE__, fmt, __VA_ARGS__)
+#else
+#define DEVMEM_REFCOUNT_PRINT(fmt, ...)
+#endif
+
+/* If we need a "hMapping" but we don't have a server-side mapping, we poison
+ * the entry with this value so that it's easily recognised in the debugger.
+ * Note that this is potentially a valid handle, but then so is NULL, which is
+ * no better, indeed worse, as it's not obvious in the debugger. The value
+ * doesn't matter. We _never_ use it (and because it's valid, we never assert
+ * it isn't this) but it's nice to have a value in the source code that we can
+ * grep for if things go wrong.
+ */
+#define LACK_OF_MAPPING_POISON ((IMG_HANDLE)0x6116dead)
+#define LACK_OF_RESERVATION_POISON ((IMG_HANDLE)0x7117dead)
+
+#define DEVICEMEM_HISTORY_ALLOC_INDEX_NONE 0xFFFFFFFF
+
+struct DEVMEM_CONTEXT_TAG
+{
+
+ SHARED_DEV_CONNECTION hDevConnection;
+
+ /* Number of heaps that have been created in this context
+ * (regardless of whether they have allocations)
+ */
+ IMG_UINT32 uiNumHeaps;
+
+ /* Each "DEVMEM_CONTEXT" has a counterpart in the server, which
+ * is responsible for handling the mapping into device MMU.
+ * We have a handle to that here.
+ */
+ IMG_HANDLE hDevMemServerContext;
+
+ /* Number of automagically created heaps in this context,
+ * i.e. those that are born at context creation time from the
+ * chosen "heap config" or "blueprint"
+ */
+ IMG_UINT32 uiAutoHeapCount;
+
+ /* Pointer to array of such heaps */
+ struct DEVMEM_HEAP_TAG **ppsAutoHeapArray;
+
+ /* The cache line size for use when allocating memory,
+ * as it is not queryable on the client side
+ */
+ IMG_UINT32 ui32CPUCacheLineSize;
+
+ /* Private data handle for device specific data */
+ IMG_HANDLE hPrivData;
+};
+
+/* Flags that record how a heaps virtual address space is managed. */
+#define DEVMEM_HEAP_MANAGER_UNKNOWN 0
+/* Heap VAs assigned by the client of Services APIs, heap's RA not used at all. */
+#define DEVMEM_HEAP_MANAGER_USER (1U << 0)
+/* Heap VAs managed by the OSs kernel, VA from CPU mapping call used */
+#define DEVMEM_HEAP_MANAGER_KERNEL (1U << 1)
+/* Heap VAs managed by the heap's own RA */
+#define DEVMEM_HEAP_MANAGER_RA (1U << 2)
+/* Heap VAs managed jointly by Services and the client of Services.
+ * The reserved region of the heap is managed explicitly by the client of Services
+ * The non-reserved region of the heap is managed by the heap's own RA */
+#define DEVMEM_HEAP_MANAGER_DUAL_USER_RA (DEVMEM_HEAP_MANAGER_USER | DEVMEM_HEAP_MANAGER_RA)
+
+struct DEVMEM_HEAP_TAG
+{
+ /* Name of heap - for debug and lookup purposes. */
+ IMG_CHAR *pszName;
+
+ /* Number of live imports in the heap */
+ ATOMIC_T hImportCount;
+
+ /* Base address and size of heap, required by clients due to some
+ * requesters not being full range
+ */
+ IMG_DEV_VIRTADDR sBaseAddress;
+ DEVMEM_SIZE_T uiSize;
+
+ DEVMEM_SIZE_T uiReservedRegionSize; /* uiReservedRegionLength in DEVMEM_HEAP_BLUEPRINT */
+
+ /* The heap manager, describing if the space is managed by the user, an RA,
+ * kernel or combination */
+ IMG_UINT32 ui32HeapManagerFlags;
+
+ /* This RA is for managing sub-allocations within the imports (PMRs)
+ * within the heap's virtual space. RA only used in DevmemSubAllocate()
+ * to track sub-allocated buffers.
+ *
+ * Resource Span - a PMR import added when the RA calls the
+ * imp_alloc CB (SubAllocImportAlloc) which returns the
+ * PMR import and size (span length).
+ * Resource - an allocation/buffer i.e. a MemDesc. Resource size represents
+ * the size of the sub-allocation.
+ */
+ RA_ARENA *psSubAllocRA;
+ IMG_CHAR *pszSubAllocRAName;
+
+ /* The psQuantizedVMRA is for the coarse allocation (PMRs) of virtual
+ * space from the heap.
+ *
+ * Resource Span - the heap's VM space from base to base+length,
+ * only one is added at heap creation.
+ * Resource - a PMR import associated with the heap. Dynamic number
+ * as memory is allocated/freed from or mapped/unmapped to
+ * the heap. Resource size follows PMR logical size.
+ */
+ RA_ARENA *psQuantizedVMRA;
+ IMG_CHAR *pszQuantizedVMRAName;
+
+ /* We also need to store a copy of the quantum size in order to feed
+ * this down to the server.
+ */
+ IMG_UINT32 uiLog2Quantum;
+
+ /* Store a copy of the minimum import alignment */
+ IMG_UINT32 uiLog2ImportAlignment;
+
+ /* The parent memory context for this heap */
+ struct DEVMEM_CONTEXT_TAG *psCtx;
+
+ /* Lock to protect this structure */
+ POS_LOCK hLock;
+
+ /* Each "DEVMEM_HEAP" has a counterpart in the server, which is
+ * responsible for handling the mapping into device MMU.
+ * We have a handle to that here.
+ */
+ IMG_HANDLE hDevMemServerHeap;
+
+ /* This heap is fully allocated and premapped into the device address space.
+ * Used in virtualisation for firmware heaps of Guest and optionally Host drivers. */
+ IMG_BOOL bPremapped;
+};
+
+typedef IMG_UINT32 DEVMEM_PROPERTIES_T; /*!< Typedef for Devicemem properties */
+#define DEVMEM_PROPERTIES_EXPORTABLE (1UL<<0) /*!< Is it exportable? */
+#define DEVMEM_PROPERTIES_IMPORTED (1UL<<1) /*!< Is it imported from another process? */
+#define DEVMEM_PROPERTIES_SUBALLOCATABLE (1UL<<2) /*!< Is it suballocatable? */
+#define DEVMEM_PROPERTIES_UNPINNED (1UL<<3) /*!< Is it currently pinned? */
+#define DEVMEM_PROPERTIES_IMPORT_IS_ZEROED (1UL<<4) /*!< Is the memory fully zeroed? */
+#define DEVMEM_PROPERTIES_IMPORT_IS_CLEAN (1UL<<5) /*!< Is the memory clean, i.e. not been used before? */
+#define DEVMEM_PROPERTIES_SECURE (1UL<<6) /*!< Is it a special secure buffer? No CPU maps allowed! */
+#define DEVMEM_PROPERTIES_IMPORT_IS_POISONED (1UL<<7) /*!< Is the memory fully poisoned? */
+#define DEVMEM_PROPERTIES_NO_CPU_MAPPING (1UL<<8) /* No CPU Mapping is allowed, RW attributes
+ are further derived from allocation memory flags */
+#define DEVMEM_PROPERTIES_NO_LAYOUT_CHANGE (1UL<<9) /* No sparse resizing allowed, once a memory
+ layout is chosen, no change allowed later,
+ This includes pinning and unpinning */
+
+
+typedef struct DEVMEM_DEVICE_IMPORT_TAG
+{
+ DEVMEM_HEAP *psHeap; /*!< Heap this import is bound to */
+ IMG_DEV_VIRTADDR sDevVAddr; /*!< Device virtual address of the import */
+ IMG_UINT32 ui32RefCount; /*!< Refcount of the device virtual address */
+ IMG_HANDLE hReservation; /*!< Device memory reservation handle */
+ IMG_HANDLE hMapping; /*!< Device mapping handle */
+ IMG_BOOL bMapped; /*!< This is import mapped? */
+ POS_LOCK hLock; /*!< Lock to protect the device import */
+} DEVMEM_DEVICE_IMPORT;
+
+typedef struct DEVMEM_CPU_IMPORT_TAG
+{
+ void *pvCPUVAddr; /*!< CPU virtual address of the import */
+ IMG_UINT32 ui32RefCount; /*!< Refcount of the CPU virtual address */
+ IMG_HANDLE hOSMMapData; /*!< CPU mapping handle */
+ POS_LOCK hLock; /*!< Lock to protect the CPU import */
+} DEVMEM_CPU_IMPORT;
+
+typedef struct DEVMEM_IMPORT_TAG
+{
+ SHARED_DEV_CONNECTION hDevConnection;
+ IMG_DEVMEM_ALIGN_T uiAlign; /*!< Alignment of the PMR */
+ DEVMEM_SIZE_T uiSize; /*!< Size of import */
+ ATOMIC_T hRefCount; /*!< Refcount for this import */
+ DEVMEM_PROPERTIES_T uiProperties; /*!< Stores properties of an import like if
+ it is exportable, pinned or suballocatable */
+ IMG_HANDLE hPMR; /*!< Handle to the PMR */
+ PVRSRV_MEMALLOCFLAGS_T uiFlags; /*!< Flags for this import */
+ POS_LOCK hLock; /*!< Lock to protect the import */
+
+ DEVMEM_DEVICE_IMPORT sDeviceImport; /*!< Device specifics of the import */
+ DEVMEM_CPU_IMPORT sCPUImport; /*!< CPU specifics of the import */
+} DEVMEM_IMPORT;
+
+typedef struct DEVMEM_DEVICE_MEMDESC_TAG
+{
+ IMG_DEV_VIRTADDR sDevVAddr; /*!< Device virtual address of the allocation */
+ IMG_UINT32 ui32RefCount; /*!< Refcount of the device virtual address */
+ POS_LOCK hLock; /*!< Lock to protect device memdesc */
+} DEVMEM_DEVICE_MEMDESC;
+
+typedef struct DEVMEM_CPU_MEMDESC_TAG
+{
+ void *pvCPUVAddr; /*!< CPU virtual address of the import */
+ IMG_UINT32 ui32RefCount; /*!< Refcount of the device CPU address */
+ POS_LOCK hLock; /*!< Lock to protect CPU memdesc */
+} DEVMEM_CPU_MEMDESC;
+
+struct DEVMEM_MEMDESC_TAG
+{
+ DEVMEM_IMPORT *psImport; /*!< Import this memdesc is on */
+ IMG_DEVMEM_OFFSET_T uiOffset; /*!< Offset into import where our allocation starts */
+ IMG_DEVMEM_SIZE_T uiAllocSize; /*!< Size of the allocation */
+ ATOMIC_T hRefCount; /*!< Refcount of the memdesc */
+ POS_LOCK hLock; /*!< Lock to protect memdesc */
+ IMG_HANDLE hPrivData;
+
+ DEVMEM_DEVICE_MEMDESC sDeviceMemDesc; /*!< Device specifics of the memdesc */
+ DEVMEM_CPU_MEMDESC sCPUMemDesc; /*!< CPU specifics of the memdesc */
+
+ IMG_CHAR szText[DEVMEM_ANNOTATION_MAX_LEN]; /*!< Annotation for this memdesc */
+
+ IMG_UINT32 ui32AllocationIndex;
+
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO)
+ IMG_HANDLE hRIHandle; /*!< Handle to RI information */
+#endif
+};
+
+/* The physical descriptor used to store handles and information of device
+ * physical allocations.
+ */
+struct DEVMEMX_PHYS_MEMDESC_TAG
+{
+ IMG_UINT32 uiNumPages; /*!< Number of pages that the import has*/
+ IMG_UINT32 uiLog2PageSize; /*!< Page size */
+ ATOMIC_T hRefCount; /*!< Refcount of the memdesc */
+ PVRSRV_MEMALLOCFLAGS_T uiFlags; /*!< Flags for this import */
+ IMG_HANDLE hPMR; /*!< Handle to the PMR */
+ DEVMEM_CPU_IMPORT sCPUImport; /*!< CPU specifics of the memdesc */
+ DEVMEM_BRIDGE_HANDLE hBridge; /*!< Bridge connection for the server */
+ void *pvUserData; /*!< User data */
+};
+
+/* The virtual descriptor used to store handles and information of a device
+ * virtual range and the mappings to it.
+ */
+struct DEVMEMX_VIRT_MEMDESC_TAG
+{
+ IMG_UINT32 uiNumPages; /*!< Number of pages that the import has*/
+ PVRSRV_MEMALLOCFLAGS_T uiFlags; /*!< Flags for this import */
+ DEVMEMX_PHYSDESC **apsPhysDescTable; /*!< Table to store links to physical descs */
+ DEVMEM_DEVICE_IMPORT sDeviceImport; /*!< Device specifics of the memdesc */
+
+ IMG_CHAR szText[DEVMEM_ANNOTATION_MAX_LEN]; /*!< Annotation for this virt memdesc */
+ IMG_UINT32 ui32AllocationIndex; /*!< To track mappings in this range */
+
+#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO)
+ IMG_HANDLE hRIHandle; /*!< Handle to RI information */
+#endif
+};
+
+#define DEVICEMEM_UTILS_NO_ADDRESS 0
+
+/******************************************************************************
+@Function DevmemValidateParams
+@Description Check if flags are conflicting and if align is a size multiple.
+
+@Input uiSize Size of the import.
+@Input uiAlign Alignment of the import.
+@Input puiFlags Pointer to the flags for the import.
+@return PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR DevmemValidateParams(IMG_DEVMEM_SIZE_T uiSize,
+ IMG_DEVMEM_ALIGN_T uiAlign,
+ PVRSRV_MEMALLOCFLAGS_T *puiFlags);
+
+/******************************************************************************
+@Function DevmemImportStructAlloc
+@Description Allocates memory for an import struct. Does not allocate a PMR!
+ Create locks for CPU and Devmem mappings.
+
+@Input hDevConnection Connection to use for calls from the import.
+@Input ppsImport The import to allocate.
+@return PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR DevmemImportStructAlloc(SHARED_DEV_CONNECTION hDevConnection,
+ DEVMEM_IMPORT **ppsImport);
+
+/******************************************************************************
+@Function DevmemImportStructInit
+@Description Initialises the import struct with the given parameters.
+ Set it's refcount to 1!
+
+@Input psImport The import to initialise.
+@Input uiSize Size of the import.
+@Input uiAlign Alignment of allocations in the import.
+@Input uiMapFlags
+@Input hPMR Reference to the PMR of this import struct.
+@Input uiProperties Properties of the import. Is it exportable,
+ imported, suballocatable, unpinned?
+******************************************************************************/
+void DevmemImportStructInit(DEVMEM_IMPORT *psImport,
+ IMG_DEVMEM_SIZE_T uiSize,
+ IMG_DEVMEM_ALIGN_T uiAlign,
+ PVRSRV_MEMALLOCFLAGS_T uiMapFlags,
+ IMG_HANDLE hPMR,
+ DEVMEM_PROPERTIES_T uiProperties);
+
+/******************************************************************************
+@Function DevmemImportStructDevMap
+@Description NEVER call after the last DevmemMemDescRelease()
+ Maps the PMR referenced by the import struct to the device's
+ virtual address space.
+ Does nothing but increase the cpu mapping refcount if the
+ import struct was already mapped.
+
+@Input psHeap The heap to map to.
+@Input bMap Caller can choose if the import should be really
+ mapped in the page tables or if just a virtual range
+ should be reserved and the refcounts increased.
+@Input psImport The import we want to map.
+@Input uiOptionalMapAddress An optional address to map to.
+ Pass DEVICEMEM_UTILS_NOADDRESS if not used.
+@return PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR DevmemImportStructDevMap(DEVMEM_HEAP *psHeap,
+ IMG_BOOL bMap,
+ DEVMEM_IMPORT *psImport,
+ IMG_UINT64 uiOptionalMapAddress);
+
+/******************************************************************************
+@Function DevmemImportStructDevUnmap
+@Description Unmaps the PMR referenced by the import struct from the
+ device's virtual address space.
+ If this was not the last remaining CPU mapping on the import
+ struct only the cpu mapping refcount is decreased.
+@return A boolean to signify if the import was unmapped.
+******************************************************************************/
+IMG_BOOL DevmemImportStructDevUnmap(DEVMEM_IMPORT *psImport);
+
+/******************************************************************************
+@Function DevmemImportStructCPUMap
+@Description NEVER call after the last DevmemMemDescRelease()
+ Maps the PMR referenced by the import struct to the CPU's
+ virtual address space.
+ Does nothing but increase the cpu mapping refcount if the
+ import struct was already mapped.
+@return PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR DevmemImportStructCPUMap(DEVMEM_IMPORT *psImport);
+
+/******************************************************************************
+@Function DevmemImportStructCPUUnmap
+@Description Unmaps the PMR referenced by the import struct from the CPU's
+ virtual address space.
+ If this was not the last remaining CPU mapping on the import
+ struct only the cpu mapping refcount is decreased.
+******************************************************************************/
+void DevmemImportStructCPUUnmap(DEVMEM_IMPORT *psImport);
+
+
+/******************************************************************************
+@Function DevmemImportStructAcquire
+@Description Acquire an import struct by increasing it's refcount.
+******************************************************************************/
+void DevmemImportStructAcquire(DEVMEM_IMPORT *psImport);
+
+/******************************************************************************
+@Function DevmemImportStructRelease
+@Description Reduces the refcount of the import struct.
+ Destroys the import in the case it was the last reference.
+ Destroys underlying PMR if this import was the last reference
+ to it.
+@return A boolean to signal if the import was destroyed. True = yes.
+******************************************************************************/
+IMG_BOOL DevmemImportStructRelease(DEVMEM_IMPORT *psImport);
+
+/******************************************************************************
+@Function DevmemImportDiscard
+@Description Discard a created, but unitilised import structure.
+ This must only be called before DevmemImportStructInit
+ after which DevmemImportStructRelease must be used to
+ "free" the import structure.
+******************************************************************************/
+void DevmemImportDiscard(DEVMEM_IMPORT *psImport);
+
+/******************************************************************************
+@Function DevmemMemDescAlloc
+@Description Allocates a MemDesc and create it's various locks.
+ Zero the allocated memory.
+@return PVRSRV_ERROR
+******************************************************************************/
+PVRSRV_ERROR DevmemMemDescAlloc(DEVMEM_MEMDESC **ppsMemDesc);
+
+/******************************************************************************
+@Function DevmemMemDescInit
+@Description Sets the given offset and import struct fields in the MemDesc.
+ Initialises refcount to 1 and other values to 0.
+
+@Input psMemDesc MemDesc to initialise.
+@Input uiOffset Offset in the import structure.
+@Input psImport Import the MemDesc is on.
+@Input uiAllocSize Size of the allocation
+******************************************************************************/
+void DevmemMemDescInit(DEVMEM_MEMDESC *psMemDesc,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ DEVMEM_IMPORT *psImport,
+ IMG_DEVMEM_SIZE_T uiAllocSize);
+
+/******************************************************************************
+@Function DevmemMemDescAcquire
+@Description Acquires the MemDesc by increasing it's refcount.
+******************************************************************************/
+void DevmemMemDescAcquire(DEVMEM_MEMDESC *psMemDesc);
+
+/******************************************************************************
+@Function DevmemMemDescRelease
+@Description Releases the MemDesc by reducing it's refcount.
+ Destroy the MemDesc if it's recount is 0.
+ Destroy the import struct the MemDesc is on if that was the
+ last MemDesc on the import, probably following the destruction
+ of the underlying PMR.
+@return A boolean to signal if the MemDesc was destroyed. True = yes.
+******************************************************************************/
+IMG_BOOL DevmemMemDescRelease(DEVMEM_MEMDESC *psMemDesc);
+
+/******************************************************************************
+@Function DevmemMemDescDiscard
+@Description Discard a created, but uninitialised MemDesc structure.
+ This must only be called before DevmemMemDescInit after
+ which DevmemMemDescRelease must be used to "free" the
+ MemDesc structure.
+******************************************************************************/
+void DevmemMemDescDiscard(DEVMEM_MEMDESC *psMemDesc);
+
+
+/******************************************************************************
+@Function GetImportProperties
+@Description Atomically read psImport->uiProperties
+ It's possible that another thread modifies uiProperties
+ immediately after this function returns, making its result
+ stale. So, it's recommended to use this function only to
+ check if certain non-volatile flags were set.
+******************************************************************************/
+static INLINE DEVMEM_PROPERTIES_T GetImportProperties(DEVMEM_IMPORT *psImport)
+{
+ DEVMEM_PROPERTIES_T uiProperties;
+
+ OSLockAcquire(psImport->hLock);
+ uiProperties = psImport->uiProperties;
+ OSLockRelease(psImport->hLock);
+ return uiProperties;
+}
+
+#endif /* DEVICEMEM_UTILS_H */
diff --git a/drivers/gpu/drm/img-rogue/di_common.h b/drivers/gpu/drm/img-rogue/di_common.h
new file mode 100644
index 000000000..c262495e8
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/di_common.h
@@ -0,0 +1,234 @@
+/*************************************************************************/ /*!
+@File
+@Title Common types for Debug Info framework.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef DI_COMMON_H
+#define DI_COMMON_H
+
+#include "img_types.h"
+
+/* Token that signals that a header should be printed. */
+#define DI_START_TOKEN ((void *) 1)
+
+/* This is a public handle to an entry. */
+#ifndef DI_GROUP_DEFINED
+#define DI_GROUP_DEFINED
+typedef struct DI_GROUP DI_GROUP;
+#endif
+#ifndef DI_ENTRY_DEFINED
+#define DI_ENTRY_DEFINED
+typedef struct DI_ENTRY DI_ENTRY;
+#endif
+typedef struct OSDI_IMPL_ENTRY OSDI_IMPL_ENTRY;
+
+/*! Debug Info entries types. */
+typedef enum DI_ENTRY_TYPE
+{
+ DI_ENTRY_TYPE_GENERIC, /*!< generic entry type, implements
+ start/stop/next/show iterator
+ interface */
+ DI_ENTRY_TYPE_RANDOM_ACCESS, /*!< random access entry, implements
+ seek/read iterator interface */
+} DI_ENTRY_TYPE;
+
+/*! @Function DI_PFN_START
+ *
+ * @Description
+ * Start operation returns first entry and passes it to Show operation.
+ *
+ * @Input psEntry pointer to the implementation entry
+ * @InOut pui64Pos current data position in the entry
+ *
+ * @Return pointer to data that will be passed to the other iterator
+ * functions in pvData argument
+ */
+typedef void *(*DI_PFN_START)(OSDI_IMPL_ENTRY *psEntry, IMG_UINT64 *pui64Pos);
+
+/*! @Function DI_PFN_STOP
+ *
+ * @Description
+ * Stop operations is called after iterator reaches end of data.
+ *
+ * If pvData was allocated in pfnStart it should be freed here.
+ *
+ * @Input psEntry pointer to the implementation entry
+ * @Input pvData pointer to data returned from pfnStart/pfnNext
+ */
+typedef void (*DI_PFN_STOP)(OSDI_IMPL_ENTRY *psEntry, void *pvData);
+
+/*! @Function DI_PFN_NEXT
+ *
+ * @Description
+ * Next returns next data entry and passes it to Show operation.
+ *
+ * @Input psEntry pointer to the implementation entry
+ * @Input pvData pointer to data returned from pfnStart/pfnNext
+ * @InOut pui64Pos current data position in the entry
+ */
+typedef void *(*DI_PFN_NEXT)(OSDI_IMPL_ENTRY *psEntry, void *pvData,
+ IMG_UINT64 *pui64Pos);
+
+/*! @Function DI_PFN_SHOW
+ *
+ * @Description
+ * Outputs the data element.
+ *
+ * @Input psEntry pointer to the implementation entry
+ * @Input pvData pointer to data returned from pfnStart/pfnNext
+ */
+typedef int (*DI_PFN_SHOW)(OSDI_IMPL_ENTRY *psEntry, void *pvData);
+
+/*! @Function DI_PFN_SEEK
+ *
+ * @Description
+ * Changes position of the entry data pointer
+ *
+ * @Input uiOffset new entry offset (absolute)
+ * @Input pvData private data provided during entry creation
+ */
+typedef IMG_INT64 (*DI_PFN_SEEK)(IMG_UINT64 ui64Offset, void *pvData);
+
+/*! @Function DI_PFN_READ
+ *
+ * @Description
+ * Retrieves data from the entry from position previously set by Seek.
+ *
+ * @Input pszBuffer output buffer
+ * @Input ui64Count length of the output buffer
+ * @InOut pui64Pos pointer to the current position in the entry
+ * @Input pvData private data provided during entry creation
+ */
+typedef IMG_INT64 (*DI_PFN_READ)(IMG_CHAR *pszBuffer, IMG_UINT64 ui64Count,
+ IMG_UINT64 *pui64Pos, void *pvData);
+
+/*! @Function DI_PFN_WRITE
+ *
+ * @Description
+ * Handle writes operation to the entry.
+ *
+ * @Input pszBuffer NUL-terminated buffer containing written data
+ * @Input ui64Count length of the data in pszBuffer (length of the buffer)
+ * @InOut pui64Pos pointer to the current position in the entry
+ * @Input pvData private data provided during entry creation
+ */
+typedef IMG_INT64 (*DI_PFN_WRITE)(const IMG_CHAR *pszBuffer,
+ IMG_UINT64 ui64Count, IMG_UINT64 *pui64Pos,
+ void *pvData);
+
+/*! Debug info entry iterator.
+ *
+ * This covers all entry types: GENERIC and RANDOM_ACCESS.
+ *
+ * The GENERIC entry type
+ *
+ * The GENERIC type should implement either a full set of following callbacks:
+ * pfnStart, pfnStop, pfnNext and pfnShow, or pfnShow only. If only pfnShow
+ * callback is given the framework will use default handlers in place of the
+ * other ones.
+ *
+ * e.g. for generic entry:
+ *
+ * struct sIter = {
+ * .pfnStart = StartCb, .pfnStop = StopCb, pfnNext = NextCb,
+ * .pfnShow = ShowCb
+ * };
+ *
+ * The use case for implementing pfnShow only is if the data for the given
+ * entry is short and can be printed in one go because the pfnShow callback
+ * will be called only once.
+ *
+ * e.g. for one-shot print generic entry:
+ *
+ * struct sIter = {
+ * .pfnShow = SingleShowCb
+ * };
+ *
+ * The DICreateEntry() function will return error if DI_ENTRY_TYPE_GENERIC
+ * type is used and invalid combination of callbacks is given.
+ *
+ * The RANDOM_ACCESS entry
+ *
+ * The RANDOM_ACCESS type should implement either both pfnSeek and pfnRead
+ * or pfnRead only callbacks.
+ *
+ * e.g. of seekable and readable random access entry:
+ *
+ * struct sIter = {
+ * .pfnSeek = SeekCb, .pfnRead = ReadCb
+ * };
+ *
+ * The DICreateEntry() function will return error if DI_ENTRY_TYPE_RANDOM_ACCESS
+ * type is used and invalid combination of callbacks is given.
+ *
+ * Writing to file (optional)
+ *
+ * The iterator allows also to pass a pfnWrite callback that allows implementing
+ * write operation on the entry. The write operation is entry type agnostic
+ * which means that it can be defined for both GENERIC and RANDOM_ACCESS
+ * entries.
+ *
+ * e.g. for writable one-shot print generic entry
+ *
+ * struct sIter = {
+ * .pfnShow = SingleShowCb, .pfnWrite = WriteCb
+ * };
+ */
+typedef struct DI_ITERATOR_CB
+{
+ /* Generic entry interface. */
+
+ DI_PFN_START pfnStart; /*!< Starts iteration and returns first element
+ of entry's data. */
+ DI_PFN_STOP pfnStop; /*!< Stops iteration. */
+ DI_PFN_NEXT pfnNext; /*!< Returns next element of entry's data. */
+ DI_PFN_SHOW pfnShow; /*!< Shows current data element of an entry. */
+
+ /* Optional random access entry interface. */
+
+ DI_PFN_SEEK pfnSeek; /*!< Sets data pointer in an entry. */
+ DI_PFN_READ pfnRead; /*!< Reads data from an entry. */
+
+ /* Optional writing to entry interface. */
+
+ DI_PFN_WRITE pfnWrite; /*!< Performs write operation on an entry. */
+} DI_ITERATOR_CB;
+
+#endif /* DI_COMMON_H */
diff --git a/drivers/gpu/drm/img-rogue/di_impl_brg.c b/drivers/gpu/drm/img-rogue/di_impl_brg.c
new file mode 100644
index 000000000..7188c317a
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/di_impl_brg.c
@@ -0,0 +1,882 @@
+/*************************************************************************/ /*!
+@File
+@Title OS agnostic implementation of Debug Info interface.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Implements osdi_impl.h API to provide access to driver's
+ debug data via pvrdebug.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "allocmem.h"
+#include "hash.h"
+#include "img_defs.h"
+#include "img_types.h"
+#include "lock.h"
+#include "osfunc_common.h"
+#include "osfunc.h" /* for thread */
+#include "tlstream.h"
+#include "dllist.h"
+
+#include "osdi_impl.h"
+#include "di_impl_brg.h"
+#include "di_impl_brg_intern.h"
+#include "pvr_dicommon.h"
+#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE)
+#include "pvrsrv.h"
+#endif
+
+#define ENTRIES_TABLE_INIT_SIZE 64
+#define STREAM_BUFFER_SIZE 0x4000 /* 16KB */
+#define STREAM_LINE_LENGTH 512
+
+#if defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP)
+#define WRITER_THREAD_SLEEP_TIMEOUT 0ull
+#else
+#define WRITER_THREAD_SLEEP_TIMEOUT 28800000000ull
+#endif
+#define WRITER_THREAD_DESTROY_TIMEOUT 100000ull
+#define WRITER_THREAD_DESTROY_RETRIES 10u
+
+#define WRITE_RETRY_COUNT 10 /* retry a write to a TL buffer 10 times */
+#define WRITE_RETRY_WAIT_TIME 100 /* wait 10ms between write retries */
+
+typedef enum THREAD_STATE
+{
+ THREAD_STATE_NULL,
+ THREAD_STATE_ALIVE,
+ THREAD_STATE_TERMINATED,
+} THREAD_STATE;
+
+static struct DIIB_IMPL
+{
+ HASH_TABLE *psEntriesTable; /*!< Table of entries. */
+ POS_LOCK psEntriesLock; /*!< Protects psEntriesTable. */
+ IMG_HANDLE hWriterThread;
+ IMG_HANDLE hWriterEventObject;
+ ATOMIC_T eThreadState;
+
+ DLLIST_NODE sWriterQueue;
+ POS_LOCK psWriterLock; /*!< Protects sWriterQueue. */
+} *_g_psImpl;
+
+struct DIIB_GROUP
+{
+ const IMG_CHAR *pszName;
+ struct DIIB_GROUP *psParentGroup;
+};
+
+struct DIIB_ENTRY
+{
+ struct DIIB_GROUP *psParentGroup;
+ OSDI_IMPL_ENTRY sImplEntry;
+ DI_ITERATOR_CB sIterCb;
+ DI_ENTRY_TYPE eType;
+ IMG_CHAR pszFullPath[DI_IMPL_BRG_PATH_LEN];
+ void *pvPrivData;
+
+ POS_LOCK hLock; /*!< Protects access to entry's iterator. */
+};
+
+struct DI_CONTEXT_TAG
+{
+ IMG_HANDLE hStream;
+ ATOMIC_T iRefCnt;
+ IMG_BOOL bClientConnected; /*!< Indicated that the client is or is not
+ connected to the DI. */
+};
+
+struct DIIB_WORK_ITEM
+{
+ DI_CONTEXT *psContext;
+ DIIB_ENTRY *psEntry;
+ IMG_UINT64 ui64Size;
+ IMG_UINT64 ui64Offset;
+
+ DLLIST_NODE sQueueElement;
+};
+
+/* Declaring function here to avoid dependencies that are introduced by
+ * including osfunc.h. */
+IMG_INT32 OSStringNCompare(const IMG_CHAR *pStr1, const IMG_CHAR *pStr2,
+ size_t uiSize);
+
+/* djb2 hash function is public domain */
+static IMG_UINT32 _Hash(size_t uKeySize, void *pKey, IMG_UINT32 uHashTabLen)
+{
+ IMG_CHAR *pszStr = pKey;
+ IMG_UINT32 ui32Hash = 5381, ui32Char;
+
+ PVR_UNREFERENCED_PARAMETER(uKeySize);
+ PVR_UNREFERENCED_PARAMETER(uHashTabLen);
+
+ while ((ui32Char = *pszStr++) != '\0')
+ {
+ ui32Hash = ((ui32Hash << 5) + ui32Hash) + ui32Char; /* hash * 33 + c */
+ }
+
+ return ui32Hash;
+}
+
+static IMG_BOOL _Compare(size_t uKeySize, void *pKey1, void *pKey2)
+{
+ IMG_CHAR *pszKey1 = pKey1, *pszKey2 = pKey2;
+
+ return OSStringNCompare(pszKey1, pszKey2, uKeySize) == 0;
+}
+
+/* ----- native callbacks interface ----------------------------------------- */
+
+static void _WriteWithRetires(void *pvNativeHandle, const IMG_CHAR *pszStr,
+ IMG_UINT uiLen)
+{
+ PVRSRV_ERROR eError;
+ IMG_INT iRetry = 0;
+ IMG_UINT32 ui32Flags = TL_FLAG_NO_WRITE_FAILED;
+
+ do
+ {
+ /* Try to write to the buffer but don't inject MOST_RECENT_WRITE_FAILED
+ * packet in case of failure because we're going to retry. */
+ eError = TLStreamWriteRetFlags(pvNativeHandle, (IMG_UINT8 *) pszStr,
+ uiLen, &ui32Flags);
+ if (eError == PVRSRV_ERROR_STREAM_FULL)
+ {
+ // wait to give the client a change to read
+ OSSleepms(WRITE_RETRY_WAIT_TIME);
+ }
+ }
+ while (eError == PVRSRV_ERROR_STREAM_FULL && iRetry++ < WRITE_RETRY_COUNT);
+
+ /* One last try to write to the buffer. In this case upon failure
+ * a MOST_RECENT_WRITE_FAILED packet will be inject to the buffer to
+ * indicate data loss. */
+ if (eError == PVRSRV_ERROR_STREAM_FULL)
+ {
+ eError = TLStreamWrite(pvNativeHandle, (IMG_UINT8 *) pszStr, uiLen);
+ }
+
+ PVR_LOG_IF_ERROR(eError, "TLStreamWrite");
+}
+
+__printf(2, 0)
+static void _VPrintf(void *pvNativeHandle, const IMG_CHAR *pszFmt,
+ va_list pArgs)
+{
+ IMG_CHAR pcBuffer[STREAM_LINE_LENGTH];
+ IMG_UINT uiLen = OSVSNPrintf(pcBuffer, sizeof(pcBuffer) - 1, pszFmt, pArgs);
+ pcBuffer[uiLen] = '\0';
+
+ _WriteWithRetires(pvNativeHandle, pcBuffer, uiLen + 1);
+}
+
+static void _Puts(void *pvNativeHandle, const IMG_CHAR *pszStr)
+{
+ _WriteWithRetires(pvNativeHandle, pszStr, OSStringLength(pszStr) + 1);
+}
+
+static IMG_BOOL _HasOverflowed(void *pvNativeHandle)
+{
+ PVR_UNREFERENCED_PARAMETER(pvNativeHandle);
+ return IMG_FALSE;
+}
+
+static OSDI_IMPL_ENTRY_CB _g_sEntryCallbacks = {
+ .pfnVPrintf = _VPrintf,
+ .pfnPuts = _Puts,
+ .pfnHasOverflowed = _HasOverflowed,
+};
+
+/* ----- entry operations --------------------------------------------------- */
+
+static PVRSRV_ERROR _ContextUnrefAndMaybeDestroy(DI_CONTEXT *psContext)
+{
+ if (OSAtomicDecrement(&psContext->iRefCnt) == 0)
+ {
+ TLStreamClose(psContext->hStream);
+ OSFreeMem(psContext);
+ }
+
+ return PVRSRV_OK;
+}
+
+static IMG_INT64 _ReadGeneric(const DI_CONTEXT *psContext, DIIB_ENTRY *psEntry)
+{
+ IMG_INT64 iRet = 0;
+ IMG_UINT64 ui64Pos = 0;
+ DI_ITERATOR_CB *psIter = &psEntry->sIterCb;
+ OSDI_IMPL_ENTRY *psImplEntry = &psEntry->sImplEntry;
+ PVRSRV_ERROR eError;
+
+ if (psIter->pfnStart != NULL)
+ {
+ /* this is a full sequence of the operation */
+ void *pvData = psIter->pfnStart(psImplEntry, &ui64Pos);
+
+ while (pvData != NULL && psContext->bClientConnected)
+ {
+ iRet = psIter->pfnShow(psImplEntry, pvData);
+ if (iRet < 0)
+ {
+ break;
+ }
+
+ pvData = psIter->pfnNext(psImplEntry, pvData, &ui64Pos);
+ }
+
+ psIter->pfnStop(psImplEntry, pvData);
+ }
+ else if (psIter->pfnShow != NULL)
+ {
+ /* this is a simplified sequence of the operation */
+ iRet = psIter->pfnShow(psImplEntry, NULL);
+ }
+
+ eError = TLStreamMarkEOS(psImplEntry->pvNative, IMG_FALSE);
+ PVR_LOG_GOTO_IF_ERROR(eError, "TLStreamMarkEOS", return_error_);
+
+ return iRet;
+
+return_error_:
+ return -1;
+}
+
+static IMG_INT64 _ReadRndAccess(DIIB_ENTRY *psEntry, IMG_UINT64 ui64Count,
+ IMG_UINT64 *pui64Pos, void *pvData)
+{
+ PVRSRV_ERROR eError;
+ IMG_UINT8 *pui8Buffer;
+ IMG_HANDLE hStream = psEntry->sImplEntry.pvNative;
+
+ if (psEntry->sIterCb.pfnRead == NULL)
+ {
+ return -1;
+ }
+
+ eError = TLStreamReserve(hStream, &pui8Buffer, ui64Count);
+ PVR_LOG_GOTO_IF_ERROR(eError, "TLStreamReserve", return_error_);
+
+ psEntry->sIterCb.pfnRead((IMG_CHAR *) pui8Buffer, ui64Count, pui64Pos,
+ pvData);
+
+ eError = TLStreamCommit(hStream, ui64Count);
+ PVR_LOG_GOTO_IF_ERROR(eError, "TLStreamCommit", return_error_);
+
+ eError = TLStreamMarkEOS(psEntry->sImplEntry.pvNative, IMG_FALSE);
+ PVR_LOG_GOTO_IF_ERROR(eError, "TLStreamMarkEOS", return_error_);
+
+ return 0;
+
+return_error_:
+ return -1;
+}
+
+static void _WriterThread(void *pvArg)
+{
+ PVRSRV_ERROR eError;
+ IMG_HANDLE hEvent;
+ DLLIST_NODE *psNode;
+
+ eError = OSEventObjectOpen(_g_psImpl->hWriterEventObject, &hEvent);
+ PVR_LOG_RETURN_VOID_IF_ERROR(eError, "OSEventObjectOpen");
+
+#ifdef PVRSRV_FORCE_UNLOAD_IF_BAD_STATE
+ while (PVRSRVGetPVRSRVData()->eServicesState == PVRSRV_SERVICES_STATE_OK &&
+ OSAtomicRead(&_g_psImpl->eThreadState) == THREAD_STATE_ALIVE)
+#else
+ while (OSAtomicRead(&_g_psImpl->eThreadState) == THREAD_STATE_ALIVE)
+#endif
+ {
+ struct DIIB_WORK_ITEM *psItem = NULL;
+
+ OSLockAcquire(_g_psImpl->psWriterLock);
+ /* Get element from list tail so that we always get the oldest element
+ * (elements are added to head). */
+ while ((psNode = dllist_get_prev_node(&_g_psImpl->sWriterQueue)) != NULL)
+ {
+ IMG_INT64 i64Ret;
+ DIIB_ENTRY *psEntry;
+ OSDI_IMPL_ENTRY *psImplEntry;
+
+ dllist_remove_node(psNode);
+ OSLockRelease(_g_psImpl->psWriterLock);
+
+ psItem = IMG_CONTAINER_OF(psNode, struct DIIB_WORK_ITEM,
+ sQueueElement);
+
+ psEntry = psItem->psEntry;
+ psImplEntry = &psItem->psEntry->sImplEntry;
+
+ /* if client has already disconnected we can just drop this item */
+ if (psItem->psContext->bClientConnected)
+ {
+
+ PVR_ASSERT(psItem->psContext->hStream != NULL);
+
+ psImplEntry->pvNative = psItem->psContext->hStream;
+
+ if (psEntry->eType == DI_ENTRY_TYPE_GENERIC)
+ {
+ i64Ret = _ReadGeneric(psItem->psContext, psEntry);
+ PVR_LOG_IF_FALSE(i64Ret >= 0, "generic access read operation "
+ "failed");
+ }
+ else if (psEntry->eType == DI_ENTRY_TYPE_RANDOM_ACCESS)
+ {
+ IMG_UINT64 ui64Pos = psItem->ui64Offset;
+
+ i64Ret = _ReadRndAccess(psEntry, psItem->ui64Size, &ui64Pos,
+ psEntry->pvPrivData);
+ PVR_LOG_IF_FALSE(i64Ret >= 0, "random access read operation "
+ "failed");
+ }
+ else
+ {
+ PVR_ASSERT(psEntry->eType == DI_ENTRY_TYPE_GENERIC ||
+ psEntry->eType == DI_ENTRY_TYPE_RANDOM_ACCESS);
+ }
+
+ psImplEntry->pvNative = NULL;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "client reading entry \"%s\" has "
+ "disconnected", psEntry->pszFullPath));
+ }
+
+ _ContextUnrefAndMaybeDestroy(psItem->psContext);
+ OSFreeMemNoStats(psItem);
+
+ OSLockAcquire(_g_psImpl->psWriterLock);
+ }
+ OSLockRelease(_g_psImpl->psWriterLock);
+
+ eError = OSEventObjectWaitKernel(hEvent, WRITER_THREAD_SLEEP_TIMEOUT);
+ if (eError != PVRSRV_OK && eError != PVRSRV_ERROR_TIMEOUT)
+ {
+ PVR_LOG_ERROR(eError, "OSEventObjectWaitKernel");
+ }
+ }
+
+ OSLockAcquire(_g_psImpl->psWriterLock);
+ /* clear the queue if there are any items pending */
+ while ((psNode = dllist_get_prev_node(&_g_psImpl->sWriterQueue)) != NULL)
+ {
+ struct DIIB_WORK_ITEM *psItem = IMG_CONTAINER_OF(psNode,
+ struct DIIB_WORK_ITEM,
+ sQueueElement);
+
+ dllist_remove_node(psNode);
+ _ContextUnrefAndMaybeDestroy(psItem->psContext);
+ OSFreeMem(psItem);
+ }
+ OSLockRelease(_g_psImpl->psWriterLock);
+
+ eError = OSEventObjectClose(hEvent);
+ PVR_LOG_IF_ERROR(eError, "OSEventObjectClose");
+
+ OSAtomicWrite(&_g_psImpl->eThreadState, THREAD_STATE_TERMINATED);
+}
+
+/* ----- DI internal API ---------------------------------------------------- */
+
+DIIB_ENTRY *DIImplBrgFind(const IMG_CHAR *pszPath)
+{
+ DIIB_ENTRY *psEntry;
+
+ OSLockAcquire(_g_psImpl->psEntriesLock);
+ psEntry = (void *) HASH_Retrieve_Extended(_g_psImpl->psEntriesTable,
+ (IMG_CHAR *) pszPath);
+ OSLockRelease(_g_psImpl->psEntriesLock);
+
+ return psEntry;
+}
+
+/* ----- DI bridge interface ------------------------------------------------ */
+
+static PVRSRV_ERROR _CreateStream(IMG_CHAR *pszStreamName, IMG_HANDLE *phStream)
+{
+ IMG_UINT32 iRet;
+ IMG_HANDLE hStream;
+ PVRSRV_ERROR eError;
+
+ /* for now only one stream can be created. Should we be able to create
+ * per context stream? */
+ iRet = OSSNPrintf(pszStreamName, PRVSRVTL_MAX_STREAM_NAME_SIZE,
+ "di_stream_%x", OSGetCurrentClientProcessIDKM());
+ if (iRet >= PRVSRVTL_MAX_STREAM_NAME_SIZE)
+ {
+ /* this check is superfluous because it can never happen but in case
+ * someone changes the definition of PRVSRVTL_MAX_STREAM_NAME_SIZE
+ * handle this case */
+ pszStreamName[0] = '\0';
+ return PVRSRV_ERROR_INTERNAL_ERROR;
+ }
+
+ eError = TLStreamCreate(&hStream, pszStreamName, STREAM_BUFFER_SIZE,
+ TL_OPMODE_DROP_NEWER, NULL, NULL, NULL, NULL);
+ PVR_RETURN_IF_ERROR(eError);
+
+ *phStream = hStream;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR DICreateContextKM(IMG_CHAR *pszStreamName, DI_CONTEXT **ppsContext)
+{
+ PVRSRV_ERROR eError;
+ DI_CONTEXT *psContext;
+ IMG_HANDLE hStream = NULL;
+ THREAD_STATE eTState;
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(ppsContext != NULL, "ppsContext");
+ PVR_LOG_RETURN_IF_INVALID_PARAM(pszStreamName != NULL, "pszStreamName");
+
+ psContext = OSAllocMem(sizeof(*psContext));
+ PVR_LOG_GOTO_IF_NOMEM(psContext, eError, return_);
+
+ eError = _CreateStream(pszStreamName, &hStream);
+ PVR_LOG_GOTO_IF_ERROR(eError, "_CreateStream", free_desc_);
+
+ psContext->hStream = hStream;
+ /* indicated to the write thread if the client is still connected and
+ * waiting for the data */
+ psContext->bClientConnected = IMG_TRUE;
+ OSAtomicWrite(&psContext->iRefCnt, 1);
+
+ eTState = OSAtomicCompareExchange(&_g_psImpl->eThreadState,
+ THREAD_STATE_NULL,
+ THREAD_STATE_ALIVE);
+
+ /* if the thread has not been started yet do it */
+ if (eTState == THREAD_STATE_NULL)
+ {
+ PVR_ASSERT(_g_psImpl->hWriterThread == NULL);
+
+ eError = OSThreadCreate(&_g_psImpl->hWriterThread, "di_writer",
+ _WriterThread, NULL, IMG_FALSE, NULL);
+ PVR_LOG_GOTO_IF_ERROR(eError, "OSThreadCreate", free_close_stream_);
+ }
+
+ *ppsContext = psContext;
+
+ return PVRSRV_OK;
+
+free_close_stream_:
+ TLStreamClose(psContext->hStream);
+ OSAtomicWrite(&_g_psImpl->eThreadState, THREAD_STATE_TERMINATED);
+free_desc_:
+ OSFreeMem(psContext);
+return_:
+ return eError;
+}
+
+PVRSRV_ERROR DIDestroyContextKM(DI_CONTEXT *psContext)
+{
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psContext != NULL, "psContext");
+
+ /* pass the information to the write thread that the client has
+ * disconnected */
+ psContext->bClientConnected = IMG_FALSE;
+
+ return _ContextUnrefAndMaybeDestroy(psContext);
+}
+
+PVRSRV_ERROR DIReadEntryKM(DI_CONTEXT *psContext, const IMG_CHAR *pszEntryPath,
+ IMG_UINT64 ui64Offset, IMG_UINT64 ui64Size)
+{
+ PVRSRV_ERROR eError;
+ struct DIIB_WORK_ITEM *psItem;
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psContext != NULL, "psContext");
+ PVR_LOG_RETURN_IF_INVALID_PARAM(pszEntryPath != NULL, "pszEntryPath");
+
+ /* 'no stats' to avoid acquiring the process stats locks */
+ psItem = OSAllocMemNoStats(sizeof(*psItem));
+ PVR_LOG_GOTO_IF_NOMEM(psItem, eError, return_);
+
+ psItem->psContext = psContext;
+ psItem->psEntry = DIImplBrgFind(pszEntryPath);
+ PVR_LOG_GOTO_IF_FALSE_VA(psItem->psEntry != NULL, free_item_,
+ "entry %s does not exist", pszEntryPath);
+ psItem->ui64Size = ui64Size;
+ psItem->ui64Offset = ui64Offset;
+
+ /* increment ref count on the context so that it doesn't get freed
+ * before it gets processed by the writer thread. */
+ OSAtomicIncrement(&psContext->iRefCnt);
+
+ OSLockAcquire(_g_psImpl->psWriterLock);
+ dllist_add_to_head(&_g_psImpl->sWriterQueue, &psItem->sQueueElement);
+ OSLockRelease(_g_psImpl->psWriterLock);
+
+ eError = OSEventObjectSignal(_g_psImpl->hWriterEventObject);
+ PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+
+ return PVRSRV_OK;
+
+free_item_:
+ eError = PVRSRV_ERROR_NOT_FOUND;
+ OSFreeMemNoStats(psItem);
+return_:
+ return eError;
+}
+
+PVRSRV_ERROR DIWriteEntryKM(DI_CONTEXT *psContext, const IMG_CHAR *pszEntryPath,
+ IMG_UINT32 ui32ValueSize, const IMG_CHAR *pszValue)
+{
+ DIIB_ENTRY *psEntry;
+ DI_PFN_WRITE pfnEntryPuts;
+ IMG_INT64 i64Length = 0;
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psContext != NULL, "psContext");
+ PVR_LOG_RETURN_IF_INVALID_PARAM(pszEntryPath != NULL, "pszEntryPath");
+ PVR_LOG_RETURN_IF_INVALID_PARAM(pszValue != NULL, "pszValue");
+
+ psEntry = DIImplBrgFind(pszEntryPath);
+ PVR_LOG_RETURN_IF_FALSE_VA(psEntry != NULL, PVRSRV_ERROR_NOT_FOUND,
+ "entry %s does not exist", pszEntryPath);
+
+ pfnEntryPuts = psEntry->sIterCb.pfnWrite;
+ if (pfnEntryPuts != NULL)
+ {
+ i64Length = pfnEntryPuts(pszValue, ui32ValueSize, (IMG_UINT64*)&i64Length, psEntry->pvPrivData);
+
+ /* To deal with -EINVAL being returned */
+ PVR_LOG_RETURN_IF_INVALID_PARAM(i64Length >= 0, pszValue);
+ }
+ else
+ {
+ PVR_LOG_MSG(PVR_DBG_WARNING, "Unable to write to Entry. Write callback not enabled");
+ return PVRSRV_ERROR_INVALID_REQUEST;
+ }
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR _listName(uintptr_t k,
+ uintptr_t v,
+ void* hStream)
+{
+ PVRSRV_ERROR eError;
+ DIIB_ENTRY *psEntry;
+ IMG_UINT32 ui32Size;
+ IMG_CHAR aszName[DI_IMPL_BRG_PATH_LEN];
+
+ psEntry = (DIIB_ENTRY*) v;
+ PVR_ASSERT(psEntry != NULL);
+ PVR_UNREFERENCED_PARAMETER(k);
+
+ ui32Size = OSSNPrintf(aszName, DI_IMPL_BRG_PATH_LEN, "%s\n", psEntry->pszFullPath);
+ PVR_LOG_IF_FALSE(ui32Size > 5, "ui32Size too small, Error suspected!");
+ eError = TLStreamWrite(hStream, (IMG_UINT8 *)aszName, ui32Size+1);
+
+ return eError;
+}
+
+
+PVRSRV_ERROR DIListAllEntriesKM(DI_CONTEXT *psContext)
+{
+ PVRSRV_ERROR eError;
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psContext != NULL, "psContext");
+
+ eError = HASH_Iterate(_g_psImpl->psEntriesTable, _listName, psContext->hStream);
+ PVR_LOG_IF_ERROR(eError, "HASH_Iterate_Extended");
+
+ eError = TLStreamMarkEOS(psContext->hStream, IMG_FALSE);
+ return eError;
+}
+
+/* ----- DI implementation interface ---------------------------------------- */
+
+static PVRSRV_ERROR _Init(void)
+{
+ PVRSRV_ERROR eError;
+
+ _g_psImpl = OSAllocMem(sizeof(*_g_psImpl));
+ PVR_LOG_GOTO_IF_NOMEM(_g_psImpl, eError, return_);
+
+ _g_psImpl->psEntriesTable = HASH_Create_Extended(ENTRIES_TABLE_INIT_SIZE,
+ DI_IMPL_BRG_PATH_LEN,
+ _Hash, _Compare);
+ PVR_LOG_GOTO_IF_NOMEM(_g_psImpl->psEntriesTable, eError, free_impl_);
+
+ eError = OSLockCreate(&_g_psImpl->psEntriesLock);
+ PVR_LOG_GOTO_IF_ERROR(eError, "OSCreateLock", free_table_);
+
+ eError = OSLockCreate(&_g_psImpl->psWriterLock);
+ PVR_LOG_GOTO_IF_ERROR(eError, "OSCreateLock", free_entries_lock_);
+
+ eError = OSEventObjectCreate("DI_WRITER_EO",
+ &_g_psImpl->hWriterEventObject);
+ PVR_LOG_GOTO_IF_ERROR(eError, "OSEventObjectCreate", free_writer_lock_);
+
+ _g_psImpl->hWriterThread = NULL;
+ OSAtomicWrite(&_g_psImpl->eThreadState, THREAD_STATE_NULL);
+
+ dllist_init(&_g_psImpl->sWriterQueue);
+
+ return PVRSRV_OK;
+
+free_writer_lock_:
+ OSLockDestroy(_g_psImpl->psWriterLock);
+free_entries_lock_:
+ OSLockDestroy(_g_psImpl->psEntriesLock);
+free_table_:
+ HASH_Delete_Extended(_g_psImpl->psEntriesTable, IMG_FALSE);
+free_impl_:
+ OSFreeMem(_g_psImpl);
+ _g_psImpl = NULL;
+return_:
+ return eError;
+}
+
+static void _DeInit(void)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ THREAD_STATE eTState;
+
+ eTState = OSAtomicCompareExchange(&_g_psImpl->eThreadState,
+ THREAD_STATE_ALIVE,
+ THREAD_STATE_TERMINATED);
+
+ if (eTState == THREAD_STATE_ALIVE)
+ {
+ if (_g_psImpl->hWriterEventObject != NULL)
+ {
+ eError = OSEventObjectSignal(_g_psImpl->hWriterEventObject);
+ PVR_LOG_IF_ERROR(eError, "OSEventObjectSignal");
+ }
+
+ LOOP_UNTIL_TIMEOUT(WRITER_THREAD_DESTROY_TIMEOUT)
+ {
+ eError = OSThreadDestroy(_g_psImpl->hWriterThread);
+ if (eError == PVRSRV_OK)
+ {
+ break;
+ }
+ OSWaitus(WRITER_THREAD_DESTROY_TIMEOUT/WRITER_THREAD_DESTROY_RETRIES);
+ } END_LOOP_UNTIL_TIMEOUT();
+
+ PVR_LOG_IF_ERROR(eError, "OSThreadDestroy");
+ }
+
+ if (_g_psImpl->hWriterEventObject != NULL)
+ {
+ eError = OSEventObjectDestroy(_g_psImpl->hWriterEventObject);
+ PVR_LOG_IF_ERROR(eError, "OSEventObjectDestroy");
+ }
+
+ HASH_Delete_Extended(_g_psImpl->psEntriesTable, IMG_FALSE);
+ OSLockDestroy(_g_psImpl->psWriterLock);
+ OSLockDestroy(_g_psImpl->psEntriesLock);
+ OSFreeMem(_g_psImpl);
+ _g_psImpl = NULL;
+}
+
+/* Recursively traverses the ancestors list up to the root group and
+ * appends their names preceded by "/" to the path in reverse order
+ * (root group's name first and psGroup group's name last).
+ * Returns current offset in the path (the current path length without the
+ * NUL character). If there is no more space in the path returns -1
+ * to indicate an error (the path is too long to fit into the buffer). */
+static IMG_INT _BuildGroupPath(IMG_CHAR *pszPath, const DIIB_GROUP *psGroup)
+{
+ IMG_INT iOff;
+
+ if (psGroup == NULL)
+ {
+ return 0;
+ }
+
+ PVR_ASSERT(pszPath != NULL);
+
+ iOff = _BuildGroupPath(pszPath, psGroup->psParentGroup);
+ PVR_RETURN_IF_FALSE(iOff != -1, -1);
+
+ iOff += OSStringLCopy(pszPath + iOff, "/",
+ DI_IMPL_BRG_PATH_LEN - iOff);
+ PVR_RETURN_IF_FALSE(iOff < DI_IMPL_BRG_PATH_LEN, -1);
+
+ iOff += OSStringLCopy(pszPath + iOff, psGroup->pszName,
+ DI_IMPL_BRG_PATH_LEN - iOff);
+ PVR_RETURN_IF_FALSE(iOff < DI_IMPL_BRG_PATH_LEN, -1);
+
+ return iOff;
+}
+
+static PVRSRV_ERROR _BuildEntryPath(IMG_CHAR *pszPath, const IMG_CHAR *pszName,
+ const DIIB_GROUP *psGroup)
+{
+ IMG_INT iOff = _BuildGroupPath(pszPath, psGroup);
+ PVR_RETURN_IF_FALSE(iOff != -1, PVRSRV_ERROR_INVALID_OFFSET);
+
+ iOff += OSStringLCopy(pszPath + iOff, "/", DI_IMPL_BRG_PATH_LEN - iOff);
+ PVR_RETURN_IF_FALSE(iOff < DI_IMPL_BRG_PATH_LEN,
+ PVRSRV_ERROR_INVALID_OFFSET);
+
+ iOff += OSStringLCopy(pszPath + iOff, pszName, DI_IMPL_BRG_PATH_LEN - iOff);
+ PVR_RETURN_IF_FALSE(iOff < DI_IMPL_BRG_PATH_LEN,
+ PVRSRV_ERROR_INVALID_OFFSET);
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR _CreateEntry(const IMG_CHAR *pszName,
+ DI_ENTRY_TYPE eType,
+ const DI_ITERATOR_CB *psIterCb,
+ void *pvPrivData,
+ void *pvParentGroup,
+ void **pvEntry)
+{
+ DIIB_GROUP *psParentGroup = pvParentGroup;
+ DIIB_ENTRY *psEntry;
+ PVRSRV_ERROR eError;
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(pvEntry != NULL, "pvEntry");
+ PVR_LOG_RETURN_IF_INVALID_PARAM(pvParentGroup != NULL, "pvParentGroup");
+
+ switch (eType)
+ {
+ case DI_ENTRY_TYPE_GENERIC:
+ break;
+ case DI_ENTRY_TYPE_RANDOM_ACCESS:
+ break;
+ default:
+ PVR_DPF((PVR_DBG_ERROR, "eType invalid in %s()", __func__));
+ PVR_GOTO_WITH_ERROR(eError, PVRSRV_ERROR_INVALID_PARAMS, return_);
+ }
+
+ psEntry = OSAllocMem(sizeof(*psEntry));
+ PVR_LOG_GOTO_IF_NOMEM(psEntry, eError, return_);
+
+ eError = OSLockCreate(&psEntry->hLock);
+ PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", free_entry_);
+
+ psEntry->eType = eType;
+ psEntry->sIterCb = *psIterCb;
+ psEntry->pvPrivData = pvPrivData;
+ psEntry->psParentGroup = psParentGroup;
+ psEntry->pszFullPath[0] = '\0';
+
+ psEntry->sImplEntry.pvPrivData = pvPrivData;
+ psEntry->sImplEntry.pvNative = NULL;
+ psEntry->sImplEntry.psCb = &_g_sEntryCallbacks;
+
+ eError = _BuildEntryPath(psEntry->pszFullPath, pszName,
+ psEntry->psParentGroup);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s() failed in _BuildEntryPath() for \"%s\" "
+ "entry", __func__, pszName));
+ goto destroy_lock_;
+ }
+
+ OSLockAcquire(_g_psImpl->psEntriesLock);
+ eError = HASH_Insert_Extended(_g_psImpl->psEntriesTable,
+ psEntry->pszFullPath,
+ (uintptr_t) psEntry) ?
+ PVRSRV_OK : PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE;
+ OSLockRelease(_g_psImpl->psEntriesLock);
+ PVR_LOG_GOTO_IF_ERROR(eError, "HASH_Insert_Extended failed", destroy_lock_);
+
+ *pvEntry = psEntry;
+
+ return PVRSRV_OK;
+
+destroy_lock_:
+ OSLockDestroy(psEntry->hLock);
+free_entry_:
+ OSFreeMem(psEntry);
+return_:
+ return eError;
+}
+
+static void _DestroyEntry(void *pvEntry)
+{
+ DIIB_ENTRY *psEntry = pvEntry;
+ PVR_ASSERT(psEntry != NULL);
+
+ OSLockAcquire(_g_psImpl->psEntriesLock);
+ HASH_Remove_Extended(_g_psImpl->psEntriesTable, psEntry->pszFullPath);
+ OSLockRelease(_g_psImpl->psEntriesLock);
+
+ OSLockDestroy(psEntry->hLock);
+ OSFreeMem(psEntry);
+}
+
+static PVRSRV_ERROR _CreateGroup(const IMG_CHAR *pszName,
+ void *pvParentGroup,
+ void **ppvGroup)
+{
+ DIIB_GROUP *psNewGroup;
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(pszName != NULL, "pszName");
+ PVR_LOG_RETURN_IF_INVALID_PARAM(ppvGroup != NULL, "ppvGroup");
+
+ psNewGroup = OSAllocMem(sizeof(*psNewGroup));
+ PVR_LOG_RETURN_IF_NOMEM(psNewGroup, "OSAllocMem");
+
+ psNewGroup->pszName = pszName;
+ psNewGroup->psParentGroup = pvParentGroup;
+
+ *ppvGroup = psNewGroup;
+
+ return PVRSRV_OK;
+}
+
+static void _DestroyGroup(void *pvGroup)
+{
+ DIIB_GROUP *psGroup = pvGroup;
+ PVR_ASSERT(psGroup != NULL);
+
+ OSFreeMem(psGroup);
+}
+
+PVRSRV_ERROR PVRDIImplBrgRegister(void)
+{
+ OSDI_IMPL_CB sImplCb = {
+ .pfnInit = _Init,
+ .pfnDeInit = _DeInit,
+ .pfnCreateEntry = _CreateEntry,
+ .pfnDestroyEntry = _DestroyEntry,
+ .pfnCreateGroup = _CreateGroup,
+ .pfnDestroyGroup = _DestroyGroup
+ };
+
+ return DIRegisterImplementation("impl_brg", &sImplCb);
+}
diff --git a/drivers/gpu/drm/img-rogue/di_impl_brg.h b/drivers/gpu/drm/img-rogue/di_impl_brg.h
new file mode 100644
index 000000000..7d5a6ca75
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/di_impl_brg.h
@@ -0,0 +1,92 @@
+/*************************************************************************/ /*!
+@File
+@Title OS agnostic implementation of Debug Info interface.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef PVR_IMPL_BRG_H
+#define PVR_IMPL_BRG_H
+
+#include "pvrsrv_error.h"
+
+typedef struct DI_CONTEXT_TAG DI_CONTEXT;
+typedef struct DI_ENTRY_DESC DI_ENTRY_DESC;
+
+PVRSRV_ERROR PVRDIImplBrgRegister(void);
+
+/*! @Function DICreateContextKM
+ *
+ * @Description
+ * Creates DI context which among others also creates a TL stream for reading
+ * entries.
+ *
+ * @Output pszStreamName: name of the TL stream created in this context
+ * @Output ppsContext: pointer to the new context
+ *
+ * @Return PVRSRV_ERROR error code
+ * PVRSRV_OK in case of a success
+ * PVRSRV_ERROR_INVALID_PARAMS if any of the parameters is invalid
+ * PVRSRV_ERROR_OUT_OF_MEMORY if any of the memory allocations failed
+ * error codes returned by TLStreamCreate()
+ */
+PVRSRV_ERROR DICreateContextKM(IMG_CHAR *pszStreamName,
+ DI_CONTEXT **ppsContext);
+
+/*! @Function DIDestroyContextKM
+ *
+ * @Description
+ * Destroy the DI context and all underlying dependencies.
+ *
+ * @Input psContext: pointer to the context
+ *
+ * @Return PVRSRV_ERROR error code
+ * PVRSRV_OK in case of a success
+ * PVRSRV_ERROR_INVALID_PARAMS if invalid context pointer given
+ */
+PVRSRV_ERROR DIDestroyContextKM(DI_CONTEXT *psContext);
+
+PVRSRV_ERROR DIReadEntryKM(DI_CONTEXT *psContext, const IMG_CHAR *pszEntryPath,
+ IMG_UINT64 ui64Offset, IMG_UINT64 ui64Size);
+
+PVRSRV_ERROR DIWriteEntryKM(DI_CONTEXT *psContext, const IMG_CHAR *pszEntryPath,
+ IMG_UINT32 ui32ValueSize, const IMG_CHAR *pszValue);
+
+PVRSRV_ERROR DIListAllEntriesKM(DI_CONTEXT *psContext);
+
+#endif /* PVR_IMPL_BRG_H */
diff --git a/drivers/gpu/drm/img-rogue/di_impl_brg_intern.h b/drivers/gpu/drm/img-rogue/di_impl_brg_intern.h
new file mode 100644
index 000000000..5e11cac59
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/di_impl_brg_intern.h
@@ -0,0 +1,61 @@
+/*************************************************************************/ /*!
+@File
+@Title OS agnostic implementation of Debug Info internal interface.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef PVR_IMPL_BRG_INTERN_H
+#define PVR_IMPL_BRG_INTERN_H
+
+typedef struct DIIB_GROUP DIIB_GROUP;
+typedef struct DIIB_ENTRY DIIB_ENTRY;
+
+/*! @Function DIImplBrgFind
+ *
+ * @Description
+ * Retrieves an entry based on a given path.
+ *
+ * @Input pszPath: Full entry path in form of
+ * /rootGroup/.../parentGroup/entryName.
+ *
+ * @Return Returns entry object if exists or NULL otherwise.
+ */
+DIIB_ENTRY *DIImplBrgFind(const IMG_CHAR *pszPath);
+
+#endif /* PVR_IMPL_BRG_INTERN_H */
diff --git a/drivers/gpu/drm/img-rogue/di_server.c b/drivers/gpu/drm/img-rogue/di_server.c
new file mode 100644
index 000000000..1899b431c
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/di_server.c
@@ -0,0 +1,769 @@
+/*************************************************************************/ /*!
+@File
+@Title Debug Info framework functions and types.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "di_server.h"
+#include "osdi_impl.h"
+#include "pvrsrv_error.h"
+#include "dllist.h"
+#include "lock.h"
+#include "allocmem.h"
+#include "osfunc.h"
+
+#define ROOT_GROUP_NAME PVR_DRM_NAME
+
+/*! Implementation object. */
+typedef struct DI_IMPL
+{
+ const IMG_CHAR *pszName; /*pszName = OSAllocMem(sizeof(ROOT_GROUP_NAME));
+ PVR_LOG_GOTO_IF_NOMEM(_g_psRootGroup->pszName, eError, cleanup_name_);
+ OSStringLCopy(_g_psRootGroup->pszName, ROOT_GROUP_NAME,
+ sizeof(ROOT_GROUP_NAME));
+
+ dllist_init(&_g_psRootGroup->sListNode);
+ dllist_init(&_g_psRootGroup->sGroupList);
+ dllist_init(&_g_psRootGroup->sEntryList);
+ dllist_init(&_g_psRootGroup->sNativeHandleList);
+
+ return PVRSRV_OK;
+
+cleanup_name_:
+ OSFreeMem(_g_psRootGroup);
+destroy_lock_:
+ OSLockDestroy(_g_hLock);
+return_:
+ return eError;
+}
+
+/* Destroys the whole tree of group and entries for a given group as a root. */
+static void _DeInitGroupRecursively(DI_GROUP *psGroup)
+{
+ DLLIST_NODE *psThis, *psNext;
+
+ dllist_foreach_node(&psGroup->sEntryList, psThis, psNext)
+ {
+ DI_ENTRY *psThisEntry = IMG_CONTAINER_OF(psThis, DI_ENTRY, sListNode);
+ DIDestroyEntry(psThisEntry);
+ }
+
+ dllist_foreach_node(&psGroup->sGroupList, psThis, psNext)
+ {
+ DI_GROUP *psThisGroup = IMG_CONTAINER_OF(psThis, DI_GROUP, sListNode);
+
+ _DeInitGroupRecursively(psThisGroup);
+ }
+
+ DIDestroyGroup(psGroup);
+}
+
+void DIDeInit(void)
+{
+ DLLIST_NODE *psThis, *psNext;
+
+ OSLockAcquire(_g_hLock);
+
+ if (!dllist_is_empty(&_g_psRootGroup->sGroupList) ||
+ !dllist_is_empty(&_g_psRootGroup->sEntryList))
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: entries or groups still exist during "
+ "de-initialisation process, destroying all", __func__));
+ }
+
+ _DeInitGroupRecursively(_g_psRootGroup);
+ _g_psRootGroup = NULL;
+
+ /* Remove all of the implementations. */
+ dllist_foreach_node(&_g_sImpls, psThis, psNext)
+ {
+ DI_IMPL *psDiImpl = IMG_CONTAINER_OF(psThis, DI_IMPL, sListNode);
+
+ if (psDiImpl->bInitialised)
+ {
+ psDiImpl->sCb.pfnDeInit();
+ psDiImpl->bInitialised = IMG_FALSE;
+ }
+
+ dllist_remove_node(&psDiImpl->sListNode);
+ OSFreeMem(psDiImpl);
+ }
+
+ OSLockRelease(_g_hLock);
+
+ /* all resources freed so free the lock itself too */
+
+ OSLockDestroy(_g_hLock);
+}
+
+static IMG_BOOL _ValidateIteratorCb(const DI_ITERATOR_CB *psIterCb,
+ DI_ENTRY_TYPE eType)
+{
+ IMG_UINT32 uiFlags = 0;
+
+ if (psIterCb == NULL)
+ {
+ return IMG_FALSE;
+ }
+
+ if (eType == DI_ENTRY_TYPE_GENERIC)
+ {
+ uiFlags |= psIterCb->pfnShow != NULL ? BIT(0) : 0;
+ uiFlags |= psIterCb->pfnStart != NULL ? BIT(1) : 0;
+ uiFlags |= psIterCb->pfnStop != NULL ? BIT(2) : 0;
+ uiFlags |= psIterCb->pfnNext != NULL ? BIT(3) : 0;
+
+ /* either only pfnShow or all callbacks need to be set */
+ if (uiFlags != BIT(0) && !BITMASK_HAS(uiFlags, 0x0f))
+ {
+ return IMG_FALSE;
+ }
+ }
+ else if (eType == DI_ENTRY_TYPE_RANDOM_ACCESS)
+ {
+ uiFlags |= psIterCb->pfnRead != NULL ? BIT(0) : 0;
+ uiFlags |= psIterCb->pfnSeek != NULL ? BIT(1) : 0;
+
+ /* either only pfnRead or all callbacks need to be set */
+ if (uiFlags != BIT(0) && !BITMASK_HAS(uiFlags, 0x03))
+ {
+ return IMG_FALSE;
+ }
+ }
+ else
+ {
+ return IMG_FALSE;
+ }
+
+ return IMG_TRUE;
+}
+
+static PVRSRV_ERROR _CreateNativeEntry(DI_ENTRY *psEntry,
+ const DI_NATIVE_HANDLE *psNativeParent)
+{
+ PVRSRV_ERROR eError;
+ DI_IMPL *psImpl = psNativeParent->psDiImpl;
+
+ DI_NATIVE_HANDLE *psNativeEntry = OSAllocMem(sizeof(*psNativeEntry));
+ PVR_LOG_GOTO_IF_NOMEM(psNativeEntry, eError, return_);
+
+ eError = psImpl->sCb.pfnCreateEntry(psEntry->pszName,
+ psEntry->eType,
+ &psEntry->sIterCb,
+ psEntry->pvPrivData,
+ psNativeParent->pvHandle,
+ &psNativeEntry->pvHandle);
+ PVR_LOG_GOTO_IF_ERROR(eError, "psImpl->sCb.pfnCreateGroup", free_memory_);
+
+ psNativeEntry->psDiImpl = psImpl;
+
+ dllist_add_to_head(&psEntry->sNativeHandleList, &psNativeEntry->sListNode);
+
+ return PVRSRV_OK;
+
+free_memory_:
+ OSFreeMem(psNativeEntry);
+return_:
+ return eError;
+}
+
+static void _DestroyNativeEntry(DI_NATIVE_HANDLE *psNativeEntry)
+{
+ dllist_remove_node(&psNativeEntry->sListNode);
+ OSFreeMem(psNativeEntry);
+}
+
+PVRSRV_ERROR DICreateEntry(const IMG_CHAR *pszName,
+ DI_GROUP *psGroup,
+ const DI_ITERATOR_CB *psIterCb,
+ void *pvPriv,
+ DI_ENTRY_TYPE eType,
+ DI_ENTRY **ppsEntry)
+{
+ PVRSRV_ERROR eError;
+ DLLIST_NODE *psThis, *psNext;
+ DI_ENTRY *psEntry;
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(pszName != NULL, "pszName");
+ PVR_LOG_RETURN_IF_INVALID_PARAM(_ValidateIteratorCb(psIterCb, eType),
+ "psIterCb");
+ PVR_LOG_RETURN_IF_INVALID_PARAM(ppsEntry != NULL, "psEntry");
+
+ psEntry = OSAllocMem(sizeof(*psEntry));
+ PVR_LOG_RETURN_IF_NOMEM(psEntry, "OSAllocMem");
+
+ if (psGroup == NULL)
+ {
+ psGroup = _g_psRootGroup;
+ }
+
+ psEntry->pszName = pszName;
+ psEntry->pvPrivData = pvPriv;
+ psEntry->eType = eType;
+ psEntry->sIterCb = *psIterCb;
+ dllist_init(&psEntry->sNativeHandleList);
+
+ OSLockAcquire(_g_hLock);
+
+ dllist_add_to_tail(&psGroup->sEntryList, &psEntry->sListNode);
+
+ /* Iterate over all of the native handles of parent group to create
+ * the entry for every registered implementation. */
+ dllist_foreach_node(&psGroup->sNativeHandleList, psThis, psNext)
+ {
+ DI_NATIVE_HANDLE *psNativeGroup =
+ IMG_CONTAINER_OF(psThis, DI_NATIVE_HANDLE, sListNode);
+
+ eError = _CreateNativeEntry(psEntry, psNativeGroup);
+ PVR_GOTO_IF_ERROR(eError, cleanup_);
+ }
+
+ OSLockRelease(_g_hLock);
+
+ *ppsEntry = psEntry;
+
+ return PVRSRV_OK;
+
+cleanup_:
+ OSLockRelease(_g_hLock);
+
+ /* Something went wrong so if there were any native entries created remove
+ * them from the list, free them and free the DI entry itself. */
+ dllist_foreach_node(&psEntry->sNativeHandleList, psThis, psNext)
+ {
+ DI_NATIVE_HANDLE *psNativeEntry =
+ IMG_CONTAINER_OF(psThis, DI_NATIVE_HANDLE, sListNode);
+
+ _DestroyNativeEntry(psNativeEntry);
+ }
+
+ OSFreeMem(psEntry);
+
+ return eError;
+}
+
+void DIDestroyEntry(DI_ENTRY *psEntry)
+{
+ DLLIST_NODE *psThis, *psNext;
+
+ PVR_LOG_RETURN_VOID_IF_FALSE(psEntry != NULL,
+ "psEntry invalid in DIDestroyEntry()");
+
+ /* Iterate through all of the native entries of the DI entry, remove
+ * them from the list and then destroy them. After that, destroy the
+ * DI entry itself. */
+ dllist_foreach_node(&psEntry->sNativeHandleList, psThis, psNext)
+ {
+ DI_NATIVE_HANDLE *psNative = IMG_CONTAINER_OF(psThis, DI_NATIVE_HANDLE,
+ sListNode);
+
+ /* The implementation must ensure that entry is not removed if any
+ * operations are being executed on the entry. If this is the case
+ * the implementation should block until all of them are finished
+ * and prevent any further operations.
+ * This will guarantee proper synchronisation between the DI framework
+ * and underlying implementations and prevent destruction/access
+ * races. */
+ psNative->psDiImpl->sCb.pfnDestroyEntry(psNative->pvHandle);
+ dllist_remove_node(&psNative->sListNode);
+ OSFreeMem(psNative);
+ }
+
+ dllist_remove_node(&psEntry->sListNode);
+
+ OSFreeMem(psEntry);
+}
+
+static PVRSRV_ERROR _CreateNativeGroup(DI_GROUP *psGroup,
+ const DI_NATIVE_HANDLE *psNativeParent,
+ DI_NATIVE_HANDLE **ppsNativeGroup)
+{
+ PVRSRV_ERROR eError;
+ DI_IMPL *psImpl = psNativeParent->psDiImpl;
+
+ DI_NATIVE_HANDLE *psNativeGroup = OSAllocMem(sizeof(*psNativeGroup));
+ PVR_LOG_GOTO_IF_NOMEM(psNativeGroup, eError, return_);
+
+ eError = psImpl->sCb.pfnCreateGroup(psGroup->pszName,
+ psNativeParent->pvHandle,
+ &psNativeGroup->pvHandle);
+ PVR_LOG_GOTO_IF_ERROR(eError, "psImpl->sCb.pfnCreateGroup", free_memory_);
+
+ psNativeGroup->psDiImpl = psImpl;
+
+ dllist_add_to_head(&psGroup->sNativeHandleList, &psNativeGroup->sListNode);
+
+ *ppsNativeGroup = psNativeGroup;
+
+ return PVRSRV_OK;
+
+free_memory_:
+ OSFreeMem(psNativeGroup);
+return_:
+ return eError;
+}
+
+static void _DestroyNativeGroup(DI_NATIVE_HANDLE *psNativeEntry)
+{
+ dllist_remove_node(&psNativeEntry->sListNode);
+ OSFreeMem(psNativeEntry);
+}
+
+PVRSRV_ERROR DICreateGroup(const IMG_CHAR *pszName,
+ DI_GROUP *psParent,
+ DI_GROUP **ppsGroup)
+{
+ PVRSRV_ERROR eError;
+ DLLIST_NODE *psThis, *psNext;
+ DI_GROUP *psGroup;
+ size_t uSize;
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(pszName != NULL, "pszName");
+ PVR_LOG_RETURN_IF_INVALID_PARAM(ppsGroup != NULL, "ppsDiGroup");
+
+ psGroup = OSAllocMem(sizeof(*psGroup));
+ PVR_LOG_RETURN_IF_NOMEM(psGroup, "OSAllocMem");
+
+ if (psParent == NULL)
+ {
+ psParent = _g_psRootGroup;
+ }
+
+ uSize = OSStringLength(pszName) + 1;
+ psGroup->pszName = OSAllocMem(uSize * sizeof(*psGroup->pszName));
+ PVR_LOG_GOTO_IF_NOMEM(psGroup->pszName, eError, cleanup_name_);
+ OSStringLCopy(psGroup->pszName, pszName, uSize);
+
+ psGroup->psParent = psParent;
+ dllist_init(&psGroup->sGroupList);
+ dllist_init(&psGroup->sEntryList);
+ dllist_init(&psGroup->sNativeHandleList);
+
+ OSLockAcquire(_g_hLock);
+
+ dllist_add_to_tail(&psParent->sGroupList, &psGroup->sListNode);
+
+ /* Iterate over all of the native handles of parent group to create
+ * the group for every registered implementation. */
+ dllist_foreach_node(&psParent->sNativeHandleList, psThis, psNext)
+ {
+ DI_NATIVE_HANDLE *psNativeGroup = NULL, *psNativeParent =
+ IMG_CONTAINER_OF(psThis, DI_NATIVE_HANDLE, sListNode);
+
+ eError = _CreateNativeGroup(psGroup, psNativeParent, &psNativeGroup);
+ PVR_GOTO_IF_ERROR(eError, cleanup_);
+ }
+
+ OSLockRelease(_g_hLock);
+
+ *ppsGroup = psGroup;
+
+ return PVRSRV_OK;
+
+cleanup_:
+ OSLockRelease(_g_hLock);
+
+ /* Something went wrong so if there were any native groups created remove
+ * them from the list, free them and free the DI group itself. */
+ dllist_foreach_node(&psGroup->sNativeHandleList, psThis, psNext)
+ {
+ DI_NATIVE_HANDLE *psNativeGroup =
+ IMG_CONTAINER_OF(psThis, DI_NATIVE_HANDLE, sListNode);
+
+ dllist_remove_node(&psNativeGroup->sListNode);
+ OSFreeMem(psNativeGroup);
+ }
+
+ OSFreeMem(psGroup->pszName);
+cleanup_name_:
+ OSFreeMem(psGroup);
+
+ return eError;
+}
+
+void DIDestroyGroup(DI_GROUP *psGroup)
+{
+ DLLIST_NODE *psThis, *psNext;
+
+ PVR_LOG_RETURN_VOID_IF_FALSE(psGroup != NULL,
+ "psGroup invalid in DIDestroyGroup()");
+
+ /* Iterate through all of the native groups of the DI group, remove
+ * them from the list and then destroy them. After that destroy the
+ * DI group itself. */
+ dllist_foreach_node(&psGroup->sNativeHandleList, psThis, psNext)
+ {
+ DI_NATIVE_HANDLE *psNative = IMG_CONTAINER_OF(psThis, DI_NATIVE_HANDLE,
+ sListNode);
+
+ psNative->psDiImpl->sCb.pfnDestroyGroup(psNative->pvHandle);
+ dllist_remove_node(&psNative->sListNode);
+ OSFreeMem(psNative);
+ }
+
+ dllist_remove_node(&psGroup->sListNode);
+
+ OSFreeMem(psGroup->pszName);
+ OSFreeMem(psGroup);
+}
+
+void *DIGetPrivData(const OSDI_IMPL_ENTRY *psEntry)
+{
+ PVR_ASSERT(psEntry != NULL);
+
+ return psEntry->pvPrivData;
+}
+
+void DIPrintf(const OSDI_IMPL_ENTRY *psEntry, const IMG_CHAR *pszFmt, ...)
+{
+ va_list args;
+
+ PVR_ASSERT(psEntry != NULL);
+ PVR_ASSERT(psEntry->psCb != NULL);
+ PVR_ASSERT(psEntry->psCb->pfnVPrintf != NULL);
+ PVR_ASSERT(psEntry->pvNative != NULL);
+
+ va_start(args, pszFmt);
+ psEntry->psCb->pfnVPrintf(psEntry->pvNative, pszFmt, args);
+ va_end(args);
+}
+
+void DIVPrintf(const OSDI_IMPL_ENTRY *psEntry, const IMG_CHAR *pszFmt,
+ va_list pArgs)
+{
+ PVR_ASSERT(psEntry != NULL);
+ PVR_ASSERT(psEntry->psCb != NULL);
+ PVR_ASSERT(psEntry->psCb->pfnVPrintf != NULL);
+ PVR_ASSERT(psEntry->pvNative != NULL);
+
+ psEntry->psCb->pfnVPrintf(psEntry->pvNative, pszFmt, pArgs);
+}
+
+void DIPuts(const OSDI_IMPL_ENTRY *psEntry, const IMG_CHAR *pszStr)
+{
+ PVR_ASSERT(psEntry != NULL);
+ PVR_ASSERT(psEntry->psCb != NULL);
+ PVR_ASSERT(psEntry->psCb->pfnPuts != NULL);
+ PVR_ASSERT(psEntry->pvNative != NULL);
+
+ psEntry->psCb->pfnPuts(psEntry->pvNative, pszStr);
+}
+
+IMG_BOOL DIHasOverflowed(const OSDI_IMPL_ENTRY *psEntry)
+{
+ PVR_ASSERT(psEntry != NULL);
+ PVR_ASSERT(psEntry->psCb != NULL);
+ PVR_ASSERT(psEntry->psCb->pfnHasOverflowed != NULL);
+ PVR_ASSERT(psEntry->pvNative != NULL);
+
+ return psEntry->psCb->pfnHasOverflowed(psEntry->pvNative);
+}
+
+/* ---- OS implementation API ---------------------------------------------- */
+
+static IMG_BOOL _ValidateImplCb(const OSDI_IMPL_CB *psImplCb)
+{
+ PVR_GOTO_IF_FALSE(psImplCb->pfnInit != NULL, failed_);
+ PVR_GOTO_IF_FALSE(psImplCb->pfnDeInit != NULL, failed_);
+ PVR_GOTO_IF_FALSE(psImplCb->pfnCreateGroup != NULL, failed_);
+ PVR_GOTO_IF_FALSE(psImplCb->pfnDestroyGroup != NULL, failed_);
+ PVR_GOTO_IF_FALSE(psImplCb->pfnCreateEntry != NULL, failed_);
+ PVR_GOTO_IF_FALSE(psImplCb->pfnDestroyEntry != NULL, failed_);
+
+ return IMG_TRUE;
+
+failed_:
+ return IMG_FALSE;
+}
+
+/* Walks the tree of groups and entries and create all of the native handles
+ * for the given implementation for all of the already existing groups and
+ * entries. */
+static PVRSRV_ERROR _InitNativeHandlesRecursively(DI_IMPL *psImpl,
+ DI_GROUP *psGroup,
+ DI_NATIVE_HANDLE *psNativeParent)
+{
+ PVRSRV_ERROR eError;
+ DLLIST_NODE *psThis, *psNext;
+ DI_NATIVE_HANDLE *psNativeGroup;
+
+ psNativeGroup = OSAllocMem(sizeof(*psNativeGroup));
+ PVR_LOG_RETURN_IF_NOMEM(psNativeGroup, "OSAllocMem");
+
+ eError = psImpl->sCb.pfnCreateGroup(psGroup->pszName,
+ psNativeParent ? psNativeParent->pvHandle : NULL,
+ &psNativeGroup->pvHandle);
+ PVR_LOG_GOTO_IF_ERROR(eError, "psImpl->sCb.pfnCreateGroup", free_memory_);
+
+ psNativeGroup->psDiImpl = psImpl;
+
+ dllist_add_to_head(&psGroup->sNativeHandleList,
+ &psNativeGroup->sListNode);
+
+ dllist_foreach_node(&psGroup->sGroupList, psThis, psNext)
+ {
+ DI_GROUP *psThisGroup = IMG_CONTAINER_OF(psThis, DI_GROUP, sListNode);
+
+ // and then walk the new group
+ eError = _InitNativeHandlesRecursively(psImpl, psThisGroup,
+ psNativeGroup);
+ PVR_LOG_RETURN_IF_ERROR(eError, "_InitNativeHandlesRecursively");
+ }
+
+ dllist_foreach_node(&psGroup->sEntryList, psThis, psNext)
+ {
+ DI_ENTRY *psThisEntry = IMG_CONTAINER_OF(psThis, DI_ENTRY, sListNode);
+
+ eError = _CreateNativeEntry(psThisEntry, psNativeGroup);
+ PVR_LOG_RETURN_IF_ERROR(eError, "_CreateNativeEntry");
+ }
+
+ return PVRSRV_OK;
+
+free_memory_:
+ OSFreeMem(psNativeGroup);
+
+ return eError;
+}
+
+/* Walks the tree of groups and entries and destroys all of the native handles
+ * for the given implementation. */
+static void _DeInitNativeHandlesRecursively(DI_IMPL *psImpl, DI_GROUP *psGroup)
+{
+ DLLIST_NODE *psThis, *psNext;
+
+ dllist_foreach_node(&psGroup->sEntryList, psThis, psNext)
+ {
+ DI_ENTRY *psThisEntry = IMG_CONTAINER_OF(psThis, DI_ENTRY, sListNode);
+
+ // free all of the native entries that belong to this implementation
+ dllist_foreach_node(&psThisEntry->sNativeHandleList, psThis, psNext)
+ {
+ DI_NATIVE_HANDLE *psNativeEntry =
+ IMG_CONTAINER_OF(psThis, DI_NATIVE_HANDLE, sListNode);
+
+ if (psNativeEntry->psDiImpl == psImpl)
+ {
+ _DestroyNativeEntry(psNativeEntry);
+ // there can be only one entry on the list for a given
+ // implementation
+ break;
+ }
+ }
+ }
+
+ dllist_foreach_node(&psGroup->sGroupList, psThis, psNext)
+ {
+ DI_GROUP *psThisGroup = IMG_CONTAINER_OF(psThis, DI_GROUP, sListNode);
+
+ // and then walk the new group
+ _DeInitNativeHandlesRecursively(psImpl, psThisGroup);
+ }
+
+ // free all of the native entries that belong to this implementation
+ dllist_foreach_node(&psGroup->sNativeHandleList, psThis, psNext)
+ {
+ DI_NATIVE_HANDLE *psNativeGroup =
+ IMG_CONTAINER_OF(psThis, DI_NATIVE_HANDLE, sListNode);
+
+ if (psNativeGroup->psDiImpl == psImpl)
+ {
+ _DestroyNativeGroup(psNativeGroup);
+ // there can be only one entry on the list for a given
+ // implementation
+ break;
+ }
+ }
+}
+
+static PVRSRV_ERROR _InitImpl(DI_IMPL *psImpl)
+{
+ PVRSRV_ERROR eError;
+ // DI_NATIVE_HANDLE *psNativeGroup;
+
+ eError = psImpl->sCb.pfnInit();
+ PVR_LOG_GOTO_IF_ERROR(eError, "psImpl->pfnInit()", return_);
+
+ /* if the implementation is being created after any groups or entries
+ * have been created we need to walk the current tree and create
+ * native groups and entries for all of the existing ones */
+ eError = _InitNativeHandlesRecursively(psImpl, _g_psRootGroup, NULL);
+ PVR_LOG_GOTO_IF_ERROR(eError, "_InitNativeHandlesRecursively",
+ free_native_handles_and_deinit_);
+
+ psImpl->bInitialised = IMG_TRUE;
+
+ return PVRSRV_OK;
+
+free_native_handles_and_deinit_:
+ /* something went wrong so we need to walk the tree and remove all of the
+ * native entries and groups that we've created before we can destroy
+ * the implementation */
+ _DeInitNativeHandlesRecursively(psImpl, _g_psRootGroup);
+ psImpl->sCb.pfnDeInit();
+return_:
+ return eError;
+}
+
+PVRSRV_ERROR DIRegisterImplementation(const IMG_CHAR *pszName,
+ const OSDI_IMPL_CB *psImplCb)
+{
+ DI_IMPL *psImpl;
+ PVRSRV_ERROR eError;
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(pszName != NULL, "pszName");
+ PVR_LOG_RETURN_IF_INVALID_PARAM(_ValidateImplCb(psImplCb), "psImplCb");
+ /* if root group does not exist it can mean 2 things:
+ * - DIInit() was not called so initialisation order is incorrect and needs
+ * to be fixed
+ * - DIInit() failed but if that happens we should never make it here */
+ PVR_ASSERT(_g_psRootGroup != NULL);
+
+ psImpl = OSAllocMem(sizeof(*psImpl));
+ PVR_LOG_RETURN_IF_NOMEM(psImpl, "OSAllocMem");
+
+ psImpl->pszName = pszName;
+ psImpl->sCb = *psImplCb;
+
+ OSLockAcquire(_g_hLock);
+
+ eError = _InitImpl(psImpl);
+ if (eError != PVRSRV_OK)
+ {
+ /* implementation could not be initialised so remove it from the
+ * list, free the memory and forget about it */
+
+ PVR_DPF((PVR_DBG_ERROR, "%s: could not initialise \"%s\" debug "
+ "info implementation, discarding", __func__,
+ psImpl->pszName));
+
+ goto free_impl_;
+ }
+
+ psImpl->bInitialised = IMG_TRUE;
+
+ dllist_add_to_tail(&_g_sImpls, &psImpl->sListNode);
+
+ OSLockRelease(_g_hLock);
+
+ return PVRSRV_OK;
+
+free_impl_:
+ OSLockRelease(_g_hLock);
+
+ OSFreeMem(psImpl);
+
+ return eError;
+}
diff --git a/drivers/gpu/drm/img-rogue/di_server.h b/drivers/gpu/drm/img-rogue/di_server.h
new file mode 100644
index 000000000..198efb4d8
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/di_server.h
@@ -0,0 +1,196 @@
+/*************************************************************************/ /*!
+@File
+@Title Functions for creating Debug Info groups and entries.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef DI_SERVER_H
+#define DI_SERVER_H
+
+#include
+
+#include "di_common.h"
+#include "pvrsrv_error.h"
+#include "img_defs.h"
+
+/*! @Function DIInit
+ *
+ * @Description
+ * Initialises Debug Info framework. This function will create common resources
+ * for the framework.
+ *
+ * Note: This function must be called before first call to
+ * DIRegisterImplementation() all of the implementations.
+ */
+PVRSRV_ERROR DIInit(void);
+
+/*! @Function DIDeInit
+ *
+ * @Description
+ * De-initialises Debug Info framework. This function will call pfnDeInit()
+ * on each implementation and clean up common resources.
+ *
+ * In case some of the entries and groups have not been cleaned up this function
+ * will also perform recursive sweep and remove all entries and group for
+ * all implementations.
+ */
+void DIDeInit(void);
+
+/*! @Function DICreateEntry
+ *
+ * @Description
+ * Creates debug info entry. Depending on different implementations the entry
+ * might be for example a DebugFS file or something totally different.
+ *
+ * The entry will belong to a parent group if provided or to the root group
+ * if not.
+ *
+ * @Input pszName: name of the new entry
+ * @Input psDiGroup: parent group, if NULL entry will belong to the root group
+ * @Input psIterCb: implementation of the iterator for the entry
+ * @Input psPriv: private data that will be passed to the iterator operations
+ * @Input eType: type of the entry
+ *
+ * @Output ppsEntry: handle to the newly created entry
+ *
+ * @Return PVRSRV_ERROR error code
+ */
+PVRSRV_ERROR DICreateEntry(const IMG_CHAR *pszName,
+ DI_GROUP *psGroup,
+ const DI_ITERATOR_CB *psIterCb,
+ void *psPriv,
+ DI_ENTRY_TYPE eType,
+ DI_ENTRY **ppsEntry);
+
+/*! @Function DIDestroyEntry
+ *
+ * @Description
+ * Destroys debug info entry.
+ *
+ * @Input psEntry: handle to the entry
+ */
+void DIDestroyEntry(DI_ENTRY *psEntry);
+
+/*! @Function DICreateGroup
+ *
+ * @Description
+ * Creates debug info group. Depending on different implementations the group
+ * might be for example a DebugFS directory or something totally different.
+ *
+ * The group will belong to a parent group if provided or to the root group
+ * if not.
+ *
+ * @Input pszName: name of the new entry
+ * @Input psParent: parent group, if NULL entry will belong to the root group
+ *
+ * @Output ppsGroup: handle to the newly created entry
+ *
+ * @Return PVRSRV_ERROR error code
+ */
+PVRSRV_ERROR DICreateGroup(const IMG_CHAR *pszName,
+ DI_GROUP *psParent,
+ DI_GROUP **ppsGroup);
+
+/*! @Function DIDestroyGroup
+ *
+ * @Description
+ * Destroys debug info group.
+ *
+ * @Input psGroup: handle to the group
+ */
+void DIDestroyGroup(DI_GROUP *psGroup);
+
+/*! @Function DIGetPrivData
+ *
+ * @Description
+ * Retrieves private data from psEntry. The data is either passed during
+ * entry creation via psPriv parameter of DICreateEntry() function
+ * or by explicitly setting it with DIGetPrivData() function.
+ *
+ * @Input psEntry pointer to OSDI_IMPL_ENTRY object
+ *
+ * @Returns pointer to the private data (can be NULL if private data
+ * has not been specified)
+ */
+void *DIGetPrivData(const OSDI_IMPL_ENTRY *psEntry);
+
+/*! @Function DIPrintf
+ *
+ * @Description
+ * Prints formatted string to the DI entry.
+ *
+ * @Input psEntry pointer to OSDI_IMPL_ENTRY object
+ * @Input pszFmt NUL-terminated format string
+ */
+void DIPrintf(const OSDI_IMPL_ENTRY *psEntry, const IMG_CHAR *pszFmt, ...)
+ __printf(2, 3);
+
+/*! @Function DIVPrintf
+ *
+ * @Description
+ * Prints formatted string to the DI entry. Equivalent to DIPrintf but takes
+ * va_list instead of a variable number of arguments.
+ *
+ * @Input psEntry pointer to OSDI_IMPL_ENTRY object
+ * @Input pszFmt NUL-terminated format string
+ * @Input pArgs vs_list object
+ */
+void DIVPrintf(const OSDI_IMPL_ENTRY *psEntry, const IMG_CHAR *pszFmt,
+ va_list pArgs);
+
+/*! @Function DIPrintf
+ *
+ * @Description
+ * Prints a string to the DI entry.
+ *
+ * @Input psEntry pointer to OSDI_IMPL_ENTRY object
+ * @Input pszFmt NUL-terminated string
+ */
+void DIPuts(const OSDI_IMPL_ENTRY *psEntry, const IMG_CHAR *pszStr);
+
+/*! @Function DIHasOverflowed
+ *
+ * @Description
+ * Checks if the DI buffer has overflowed.
+ *
+ * @Return IMG_TRUE if buffer overflowed
+ */
+IMG_BOOL DIHasOverflowed(const OSDI_IMPL_ENTRY *psEntry);
+
+#endif /* DI_SERVER_H */
diff --git a/drivers/gpu/drm/img-rogue/dllist.h b/drivers/gpu/drm/img-rogue/dllist.h
new file mode 100644
index 000000000..fa73dff59
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/dllist.h
@@ -0,0 +1,408 @@
+/*************************************************************************/ /*!
+@File
+@Title Double linked list header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Double linked list interface
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef DLLIST_H
+#define DLLIST_H
+
+#include "img_types.h"
+#include "img_defs.h"
+
+/*!
+ Pointer to a linked list node
+*/
+typedef struct DLLIST_NODE_ *PDLLIST_NODE;
+
+
+/*!
+ Node in a linked list
+*/
+/*
+ * Note: the following structure's size is architecture-dependent and clients
+ * may need to create a mirror of the structure definition if it needs to be
+ * used in a structure shared between host and device.
+ * Consider such clients if any changes are made to this structure.
+ */
+typedef struct DLLIST_NODE_
+{
+ struct DLLIST_NODE_ *psPrevNode;
+ struct DLLIST_NODE_ *psNextNode;
+} DLLIST_NODE;
+
+
+/*!
+ Static initialiser
+*/
+#define DECLARE_DLLIST(n) \
+DLLIST_NODE (n) = {&(n), &(n)}
+
+/*************************************************************************/ /*!
+@Function dllist_foreach_node
+
+@Description Walk through all the nodes on the list.
+ Safe against removal of (node).
+
+@Input list_head List node to start the operation
+@Input node Current list node
+@Input next Node after the current one
+
+*/
+/*****************************************************************************/
+#define dllist_foreach_node(list_head, node, next) \
+ for ((node) = (list_head)->psNextNode, (next) = (node)->psNextNode; \
+ (node) != (list_head); \
+ (node) = (next), (next) = (node)->psNextNode)
+
+#define dllist_foreach_node_backwards(list_head, node, prev) \
+ for ((node) = (list_head)->psPrevNode, (prev) = (node)->psPrevNode; \
+ (node) != (list_head); \
+ (node) = (prev), (prev) = (node)->psPrevNode)
+
+
+/*************************************************************************/ /*!
+@Function dllist_foreach
+
+@Description Simplification of dllist_foreach_node.
+ Walk through all the nodes on the list.
+ Safe against removal of currently-iterated node.
+
+ Adds utility-macro dllist_cur() to typecast the current node.
+
+@Input list_head List node to start the operation
+
+*/
+/*****************************************************************************/
+#define dllist_foreach(list_head) \
+ for (DLLIST_NODE *_DllNode = (list_head).psNextNode, *_DllNext = _DllNode->psNextNode; \
+ _DllNode != &(list_head); \
+ _DllNode = _DllNext, _DllNext = _DllNode->psNextNode)
+
+#define dllist_foreach_backwards(list_head) \
+ for (DLLIST_NODE *_DllNode = (list_head).psPrevNode, *_DllPrev = _DllNode->psPrevNode; \
+ _DllNode != &(list_head); \
+ _DllNode = _DllPrev, _DllPrev = _DllNode->psPrevNode)
+
+#define dllist_cur(type, member) IMG_CONTAINER_OF(_DllNode, type, member)
+
+/*************************************************************************/ /*!
+@Function dllist_init
+
+@Description Initialize a new double linked list
+
+@Input psListHead List head Node
+
+*/
+/*****************************************************************************/
+static INLINE
+void dllist_init(PDLLIST_NODE psListHead)
+{
+ psListHead->psPrevNode = psListHead;
+ psListHead->psNextNode = psListHead;
+}
+
+/*************************************************************************/ /*!
+@Function dllist_is_empty
+
+@Description Returns whether the list is empty
+
+@Input psListHead List head Node
+
+*/
+/*****************************************************************************/
+static INLINE
+bool dllist_is_empty(PDLLIST_NODE psListHead)
+{
+ return ((psListHead->psPrevNode == psListHead)
+ && (psListHead->psNextNode == psListHead));
+}
+
+/*************************************************************************/ /*!
+@Function dllist_add_to_head
+
+@Description Add psNewNode to head of list psListHead
+
+@Input psListHead Head Node
+@Input psNewNode New Node
+
+*/
+/*****************************************************************************/
+static INLINE
+void dllist_add_to_head(PDLLIST_NODE psListHead, PDLLIST_NODE psNewNode)
+{
+ PDLLIST_NODE psTmp;
+
+ psTmp = psListHead->psNextNode;
+
+ psListHead->psNextNode = psNewNode;
+ psNewNode->psNextNode = psTmp;
+
+ psTmp->psPrevNode = psNewNode;
+ psNewNode->psPrevNode = psListHead;
+}
+
+
+/*************************************************************************/ /*!
+@Function dllist_add_to_tail
+
+@Description Add psNewNode to tail of list psListHead
+
+@Input psListHead Head Node
+@Input psNewNode New Node
+
+*/
+/*****************************************************************************/
+static INLINE
+void dllist_add_to_tail(PDLLIST_NODE psListHead, PDLLIST_NODE psNewNode)
+{
+ PDLLIST_NODE psTmp;
+
+ psTmp = psListHead->psPrevNode;
+
+ psListHead->psPrevNode = psNewNode;
+ psNewNode->psPrevNode = psTmp;
+
+ psTmp->psNextNode = psNewNode;
+ psNewNode->psNextNode = psListHead;
+}
+
+/*************************************************************************/ /*!
+@Function dllist_node_is_in_list
+
+@Description Returns true if psNode is in a list
+
+@Input psNode List node
+
+*/
+/*****************************************************************************/
+static INLINE
+bool dllist_node_is_in_list(PDLLIST_NODE psNode)
+{
+ return (psNode->psNextNode != NULL);
+}
+
+/*************************************************************************/ /*!
+@Function dllist_get_next_node
+
+@Description Returns the list node after psListHead or NULL psListHead is
+ the only element in the list.
+
+@Input psListHead List node to start the operation
+
+*/
+/*****************************************************************************/
+static INLINE
+PDLLIST_NODE dllist_get_next_node(PDLLIST_NODE psListHead)
+{
+ if (psListHead->psNextNode == psListHead)
+ {
+ return NULL;
+ }
+ else
+ {
+ return psListHead->psNextNode;
+ }
+}
+
+/*************************************************************************/ /*!
+@Function dllist_get_prev_node
+
+@Description Returns the list node preceding psListHead or NULL if
+ psListHead is the only element in the list.
+
+@Input psListHead List node to start the operation
+
+*/
+/*****************************************************************************/
+static INLINE
+PDLLIST_NODE dllist_get_prev_node(PDLLIST_NODE psListHead)
+{
+ if (psListHead->psPrevNode == psListHead)
+ {
+ return NULL;
+ }
+ else
+ {
+ return psListHead->psPrevNode;
+ }
+}
+
+/*************************************************************************/ /*!
+@Function dllist_remove_node
+
+@Description Removes psListNode from the list where it currently belongs
+
+@Input psListNode List node to be removed
+
+*/
+/*****************************************************************************/
+static INLINE
+void dllist_remove_node(PDLLIST_NODE psListNode)
+{
+ psListNode->psNextNode->psPrevNode = psListNode->psPrevNode;
+ psListNode->psPrevNode->psNextNode = psListNode->psNextNode;
+
+ /* Clear the node to show it's not in a list */
+ psListNode->psPrevNode = NULL;
+ psListNode->psNextNode = NULL;
+}
+
+/*************************************************************************/ /*!
+@Function dllist_replace_head
+
+@Description Moves the list from psOldHead to psNewHead
+
+@Input psOldHead List node to be replaced. Will become a
+ head node of an empty list.
+@Input psNewHead List node to be inserted. Must be an
+ empty list head.
+
+*/
+/*****************************************************************************/
+static INLINE
+void dllist_replace_head(PDLLIST_NODE psOldHead, PDLLIST_NODE psNewHead)
+{
+ if (dllist_is_empty(psOldHead))
+ {
+ psNewHead->psNextNode = psNewHead;
+ psNewHead->psPrevNode = psNewHead;
+ }
+ else
+ {
+ /* Change the neighbouring nodes */
+ psOldHead->psNextNode->psPrevNode = psNewHead;
+ psOldHead->psPrevNode->psNextNode = psNewHead;
+
+ /* Copy the old data to the new node */
+ psNewHead->psNextNode = psOldHead->psNextNode;
+ psNewHead->psPrevNode = psOldHead->psPrevNode;
+
+ /* Remove links to the previous list */
+ psOldHead->psNextNode = psOldHead;
+ psOldHead->psPrevNode = psOldHead;
+ }
+}
+
+/**************************************************************************/ /*!
+@Function dllist_insert_list_at_head
+
+@Description Inserts psInHead list into the head of the psOutHead list.
+ After this operation psOutHead will contain psInHead at the
+ head of the list and the remaining elements that were
+ already in psOutHead will be places after the psInList (so
+ at a tail of the original list).
+
+@Input psOutHead List node psInHead will be inserted to.
+@Input psInHead List node to be inserted to psOutHead.
+ After this operation this becomes an empty list.
+*/ /***************************************************************************/
+static INLINE
+void dllist_insert_list_at_head(PDLLIST_NODE psOutHead, PDLLIST_NODE psInHead)
+{
+ PDLLIST_NODE psInHeadNextNode = psInHead->psNextNode;
+ PDLLIST_NODE psOutHeadNextNode = psOutHead->psNextNode;
+
+ if (!dllist_is_empty(psInHead))
+ {
+ psOutHead->psNextNode = psInHeadNextNode;
+ psInHeadNextNode->psPrevNode = psOutHead;
+
+ psInHead->psPrevNode->psNextNode = psOutHeadNextNode;
+ psOutHeadNextNode->psPrevNode = psInHead->psPrevNode;
+
+ dllist_init(psInHead);
+ }
+ }
+
+/*************************************************************************/ /*!
+@Description Pointer to a dllist comparison callback function.
+@Input psNode Pointer to a node in a dllist.
+@Input psNext Pointer to psNode's next neighbour.
+*/ /**************************************************************************/
+typedef bool (*DLLIST_CMP_CB)(const DLLIST_NODE *psNode, const DLLIST_NODE *psNext);
+
+/*************************************************************************/ /*!
+@Function dllist_sort
+
+@Description Insert-sorts the List in place
+ The cmpr function passes the current and next node,
+ From which the user writes the function responsible
+ for choosing to swap order or not.
+ The function returns true if a swap is required
+
+@Input psListHead List Head to be sorted.
+
+@Input cmpr Function pointer to use for sorting
+
+*/
+/*****************************************************************************/
+static INLINE void dllist_sort(PDLLIST_NODE psListHead,
+ DLLIST_CMP_CB cmpr)
+{
+ DLLIST_NODE *node, *next;
+ DLLIST_NODE sTempHead;
+
+ dllist_init(&sTempHead);
+
+ dllist_foreach_node(psListHead, node, next)
+ {
+ dllist_remove_node(node);
+ dllist_add_to_head(&sTempHead, node);
+ }
+
+ while (!dllist_is_empty(&sTempHead))
+ {
+ DLLIST_NODE *psSmallestNode = NULL;
+
+ dllist_foreach_node(&sTempHead, node, next)
+ {
+ if (!psSmallestNode || cmpr(psSmallestNode, node))
+ {
+ psSmallestNode = node;
+ }
+ }
+
+ dllist_remove_node(psSmallestNode);
+ dllist_add_to_tail(psListHead, psSmallestNode);
+ }
+}
+
+#endif /* DLLIST_H */
diff --git a/drivers/gpu/drm/img-rogue/dma_km.h b/drivers/gpu/drm/img-rogue/dma_km.h
new file mode 100644
index 000000000..185d4ff29
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/dma_km.h
@@ -0,0 +1,83 @@
+/*************************************************************************/ /*!
+@File dma_km.h
+@Title DMA transfer module header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef DMA_KM_H
+#define DMA_KM_H
+
+#if defined(__linux__)
+#include
+#else
+#define KERNEL_VERSION
+#endif
+
+#include "pvrsrv_error.h"
+#include "img_types.h"
+#include "cache_ops.h"
+#include "device.h"
+#include "pmr.h"
+#include "pvrsrv_sync_km.h"
+#include "connection_server.h"
+
+PVRSRV_ERROR DmaDeviceParams(CONNECTION_DATA *psConnection,
+ PVRSRV_DEVICE_NODE *psDevNode,
+ IMG_UINT32 *ui32DmaBuffAlign,
+ IMG_UINT32 *ui32DmaTransferMult);
+
+PVRSRV_ERROR DmaSparseMappingTable(PMR *psPMR,
+ IMG_DEVMEM_OFFSET_T uiOffset,
+ IMG_UINT32 ui32SizeInPages,
+ IMG_BOOL *pbTable);
+
+PVRSRV_ERROR DmaTransfer(CONNECTION_DATA *psConnection,
+ PVRSRV_DEVICE_NODE *psDevNode,
+ IMG_UINT32 uiNumDMAs,
+ PMR** ppsPMR,
+ IMG_UINT64 *puiAddress,
+ IMG_DEVMEM_OFFSET_T *puiOffset,
+ IMG_DEVMEM_SIZE_T *puiSize,
+ IMG_BOOL bMemToDev,
+ PVRSRV_TIMELINE iUpdateTimeline);
+
+PVRSRV_ERROR PVRSRVInitialiseDMA(PVRSRV_DEVICE_NODE *psDeviceNode);
+void PVRSRVDeInitialiseDMA(PVRSRV_DEVICE_NODE *psDeviceNode);
+
+#endif /* DMA_KM_H */
diff --git a/drivers/gpu/drm/img-rogue/dma_support.c b/drivers/gpu/drm/img-rogue/dma_support.c
new file mode 100644
index 000000000..f7a4f68bc
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/dma_support.c
@@ -0,0 +1,523 @@
+/*************************************************************************/ /*!
+@File dma_support.c
+@Title System DMA support
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Provides a contiguous memory allocator (i.e. DMA allocator);
+ APIs are used for allocation/ioremapping (DMA/PA <-> CPU/VA)
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "allocmem.h"
+#include "dma_support.h"
+#include "pvr_vmap.h"
+#include "kernel_compatibility.h"
+
+#define DMA_MAX_IOREMAP_ENTRIES 2
+static IMG_BOOL gbEnableDmaIoRemapping = IMG_FALSE;
+static DMA_ALLOC gsDmaIoRemapArray[DMA_MAX_IOREMAP_ENTRIES] = {{0}};
+
+static void*
+SysDmaAcquireKernelAddress(struct page *psPage, IMG_UINT64 ui64Size, DMA_ALLOC *psDmaAlloc)
+{
+ IMG_BOOL bPageByPage = IMG_TRUE;
+ IMG_UINT32 uiIdx;
+ void *pvVirtAddr = NULL;
+ IMG_UINT32 ui32PgCount = (IMG_UINT32)(ui64Size >> OSGetPageShift());
+ PVRSRV_DEVICE_NODE *psDevNode = OSAllocZMemNoStats(sizeof(*psDevNode));
+ PVRSRV_DEVICE_CONFIG *psDevConfig = OSAllocZMemNoStats(sizeof(*psDevConfig));
+ struct page **pagearray = OSAllocZMemNoStats(ui32PgCount * sizeof(struct page *));
+ void *pvOSDevice = psDmaAlloc->pvOSDevice;
+#if defined(CONFIG_ARM64)
+ pgprot_t prot = pgprot_writecombine(PAGE_KERNEL);
+#else
+ pgprot_t prot = pgprot_noncached(PAGE_KERNEL);
+#endif
+
+ /* Validate all required dynamic tmp buffer allocations */
+ if (psDevNode == NULL || psDevConfig == NULL || pagearray == NULL)
+ {
+ if (psDevNode)
+ {
+ OSFreeMem(psDevNode);
+ }
+
+ if (psDevConfig)
+ {
+ OSFreeMem(psDevConfig);
+ }
+
+ if (pagearray)
+ {
+ OSFreeMem(pagearray);
+ }
+
+ goto e0;
+ }
+
+ /* Fake psDevNode->psDevConfig->pvOSDevice */
+ psDevConfig->pvOSDevice = pvOSDevice;
+ psDevNode->psDevConfig = psDevConfig;
+
+ /* Evict any page data contents from d-cache */
+ for (uiIdx = 0; uiIdx < ui32PgCount; uiIdx++)
+ {
+ void *pvVirtStart, *pvVirtEnd;
+ IMG_CPU_PHYADDR sCPUPhysStart, sCPUPhysEnd;
+
+ /* Prepare array required for vmap */
+ pagearray[uiIdx] = &psPage[uiIdx];
+
+ if (bPageByPage)
+ {
+#if defined(CONFIG_64BIT)
+ bPageByPage = IMG_FALSE;
+
+ pvVirtStart = kmap(&psPage[uiIdx]);
+ pvVirtEnd = pvVirtStart + ui64Size;
+
+ sCPUPhysStart.uiAddr = page_to_phys(&psPage[uiIdx]);
+ sCPUPhysEnd.uiAddr = sCPUPhysStart.uiAddr + ui64Size;
+ /* all pages have a kernel linear address, flush entire range */
+#else
+ pvVirtStart = kmap(&psPage[uiIdx]);
+ pvVirtEnd = pvVirtStart + PAGE_SIZE;
+
+ sCPUPhysStart.uiAddr = page_to_phys(&psPage[uiIdx]);
+ sCPUPhysEnd.uiAddr = sCPUPhysStart.uiAddr + PAGE_SIZE;
+ /* pages might be from HIGHMEM, need to kmap/flush per page */
+#endif
+
+ /* Fallback to range-based d-cache flush */
+ OSCPUCacheInvalidateRangeKM(psDevNode,
+ pvVirtStart, pvVirtEnd,
+ sCPUPhysStart, sCPUPhysEnd);
+
+ kunmap(&psPage[uiIdx]);
+ }
+ }
+
+ /* Remap pages into VMALLOC space */
+ pvVirtAddr = pvr_vmap(pagearray, ui32PgCount, VM_READ | VM_WRITE, prot);
+ psDmaAlloc->PageProps = prot;
+
+ /* Clean-up tmp buffers */
+ OSFreeMem(psDevConfig);
+ OSFreeMem(psDevNode);
+ OSFreeMem(pagearray);
+
+e0:
+ return pvVirtAddr;
+}
+
+static void SysDmaReleaseKernelAddress(void *pvVirtAddr, IMG_UINT64 ui64Size, pgprot_t pgprot)
+{
+ pvr_vunmap(pvVirtAddr, ui64Size >> OSGetPageShift(), pgprot);
+}
+
+/*!
+******************************************************************************
+ @Function SysDmaAllocMem
+
+ @Description Allocates physically contiguous memory
+
+ @Return PVRSRV_ERROR PVRSRV_OK on success. Otherwise, a PVRSRV_
+ error code
+ ******************************************************************************/
+PVRSRV_ERROR SysDmaAllocMem(DMA_ALLOC *psDmaAlloc)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ struct device *psDev;
+ struct page *psPage;
+ size_t uiSize;
+
+ if (psDmaAlloc == NULL ||
+ psDmaAlloc->hHandle ||
+ psDmaAlloc->pvVirtAddr ||
+ psDmaAlloc->ui64Size == 0 ||
+ psDmaAlloc->sBusAddr.uiAddr ||
+ psDmaAlloc->pvOSDevice == NULL)
+ {
+ PVR_LOG_IF_FALSE((IMG_FALSE), "Invalid parameter");
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ uiSize = PVR_ALIGN(psDmaAlloc->ui64Size, PAGE_SIZE);
+ psDev = (struct device *)psDmaAlloc->pvOSDevice;
+
+ psDmaAlloc->hHandle = dma_alloc_coherent(psDev, uiSize, (dma_addr_t *)&psDmaAlloc->sBusAddr.uiAddr, GFP_KERNEL);
+
+ if (psDmaAlloc->hHandle)
+ {
+ psDmaAlloc->pvVirtAddr = psDmaAlloc->hHandle;
+
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "Allocated DMA buffer V:0x%p P:0x%llx S:0x"IMG_SIZE_FMTSPECX,
+ psDmaAlloc->pvVirtAddr,
+ psDmaAlloc->sBusAddr.uiAddr,
+ uiSize));
+ }
+ else if ((psPage = alloc_pages(GFP_KERNEL, get_order(uiSize))))
+ {
+ psDmaAlloc->sBusAddr.uiAddr = dma_map_page(psDev, psPage, 0, uiSize, DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(psDev, psDmaAlloc->sBusAddr.uiAddr))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "dma_map_page() failed, page 0x%p order %d",
+ psPage,
+ get_order(uiSize)));
+ __free_pages(psPage, get_order(uiSize));
+ goto e0;
+ }
+ psDmaAlloc->psPage = psPage;
+
+ psDmaAlloc->pvVirtAddr = SysDmaAcquireKernelAddress(psPage, uiSize, psDmaAlloc);
+ if (! psDmaAlloc->pvVirtAddr)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "SysDmaAcquireKernelAddress() failed, page 0x%p order %d",
+ psPage,
+ get_order(uiSize)));
+ dma_unmap_page(psDev, psDmaAlloc->sBusAddr.uiAddr, uiSize, DMA_BIDIRECTIONAL);
+ __free_pages(psPage, get_order(uiSize));
+ goto e0;
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "Allocated contiguous buffer V:0x%p P:0x%llx S:0x"IMG_SIZE_FMTSPECX,
+ psDmaAlloc->pvVirtAddr,
+ psDmaAlloc->sBusAddr.uiAddr,
+ uiSize));
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "Unable to allocate contiguous buffer, size: 0x"IMG_SIZE_FMTSPECX, uiSize));
+ eError = PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
+ }
+
+e0:
+ PVR_LOG_RETURN_IF_FALSE((psDmaAlloc->pvVirtAddr), "DMA/CMA allocation failed", PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES);
+ return eError;
+}
+
+/*!
+******************************************************************************
+ @Function SysDmaFreeMem
+
+ @Description Free physically contiguous memory
+
+ @Return void
+ ******************************************************************************/
+void SysDmaFreeMem(DMA_ALLOC *psDmaAlloc)
+{
+ size_t uiSize;
+ struct device *psDev;
+
+ if (psDmaAlloc == NULL ||
+ psDmaAlloc->ui64Size == 0 ||
+ psDmaAlloc->pvOSDevice == NULL ||
+ psDmaAlloc->pvVirtAddr == NULL ||
+ psDmaAlloc->sBusAddr.uiAddr == 0)
+ {
+ PVR_LOG_IF_FALSE((IMG_FALSE), "Invalid parameter");
+ return;
+ }
+
+ uiSize = PVR_ALIGN(psDmaAlloc->ui64Size, PAGE_SIZE);
+ psDev = (struct device *)psDmaAlloc->pvOSDevice;
+
+ if (psDmaAlloc->pvVirtAddr != psDmaAlloc->hHandle)
+ {
+ SysDmaReleaseKernelAddress(psDmaAlloc->pvVirtAddr, uiSize, psDmaAlloc->PageProps);
+ }
+
+ if (! psDmaAlloc->hHandle)
+ {
+ struct page *psPage;
+ dma_unmap_page(psDev, psDmaAlloc->sBusAddr.uiAddr, uiSize, DMA_BIDIRECTIONAL);
+ psPage = psDmaAlloc->psPage;
+ __free_pages(psPage, get_order(uiSize));
+ return;
+ }
+
+ dma_free_coherent(psDev, uiSize, psDmaAlloc->hHandle, (dma_addr_t )psDmaAlloc->sBusAddr.uiAddr);
+}
+
+/*!
+******************************************************************************
+ @Function SysDmaRegisterForIoRemapping
+
+ @Description Registers DMA_ALLOC for manual I/O remapping
+
+ @Return PVRSRV_ERROR PVRSRV_OK on success. Otherwise, a PVRSRV_
+ error code
+ ******************************************************************************/
+PVRSRV_ERROR SysDmaRegisterForIoRemapping(DMA_ALLOC *psDmaAlloc)
+{
+ size_t uiSize;
+ IMG_UINT32 ui32Idx;
+ IMG_BOOL bTabEntryFound = IMG_TRUE;
+ PVRSRV_ERROR eError = PVRSRV_ERROR_TOO_FEW_BUFFERS;
+
+ if (psDmaAlloc == NULL ||
+ psDmaAlloc->ui64Size == 0 ||
+ psDmaAlloc->pvOSDevice == NULL ||
+ psDmaAlloc->pvVirtAddr == NULL ||
+ psDmaAlloc->sBusAddr.uiAddr == 0)
+ {
+ PVR_LOG_IF_FALSE((IMG_FALSE), "Invalid parameter");
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ uiSize = PVR_ALIGN(psDmaAlloc->ui64Size, PAGE_SIZE);
+
+ for (ui32Idx = 0; ui32Idx < DMA_MAX_IOREMAP_ENTRIES; ++ui32Idx)
+ {
+ /* Check if an I/O remap entry exists for remapping */
+ if (gsDmaIoRemapArray[ui32Idx].pvVirtAddr == NULL)
+ {
+ PVR_ASSERT(gsDmaIoRemapArray[ui32Idx].sBusAddr.uiAddr == 0);
+ PVR_ASSERT(gsDmaIoRemapArray[ui32Idx].ui64Size == 0);
+ break;
+ }
+ }
+
+ if (ui32Idx >= DMA_MAX_IOREMAP_ENTRIES)
+ {
+ bTabEntryFound = IMG_FALSE;
+ }
+
+ if (bTabEntryFound)
+ {
+ IMG_BOOL bSameVAddr, bSamePAddr, bSameSize;
+
+ bSamePAddr = gsDmaIoRemapArray[ui32Idx].sBusAddr.uiAddr == psDmaAlloc->sBusAddr.uiAddr;
+ bSameVAddr = gsDmaIoRemapArray[ui32Idx].pvVirtAddr == psDmaAlloc->pvVirtAddr;
+ bSameSize = gsDmaIoRemapArray[ui32Idx].ui64Size == uiSize;
+
+ if (bSameVAddr)
+ {
+ if (bSamePAddr && bSameSize)
+ {
+ eError = PVRSRV_OK;
+ }
+ else
+ {
+ eError = PVRSRV_ERROR_ALREADY_EXISTS;
+ }
+ }
+ else
+ {
+ PVR_ASSERT(bSamePAddr == IMG_FALSE);
+
+ gsDmaIoRemapArray[ui32Idx].ui64Size = uiSize;
+ gsDmaIoRemapArray[ui32Idx].sBusAddr = psDmaAlloc->sBusAddr;
+ gsDmaIoRemapArray[ui32Idx].pvVirtAddr = psDmaAlloc->pvVirtAddr;
+
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "DMA: register I/O remap: "
+ "VA: 0x%p, PA: 0x%llx, Size: 0x"IMG_SIZE_FMTSPECX,
+ psDmaAlloc->pvVirtAddr,
+ psDmaAlloc->sBusAddr.uiAddr,
+ uiSize));
+
+ gbEnableDmaIoRemapping = IMG_TRUE;
+ eError = PVRSRV_OK;
+ }
+ }
+
+ return eError;
+}
+
+/*!
+******************************************************************************
+ @Function SysDmaDeregisterForIoRemapping
+
+ @Description Deregisters DMA_ALLOC from manual I/O remapping
+
+ @Return void
+ ******************************************************************************/
+void SysDmaDeregisterForIoRemapping(DMA_ALLOC *psDmaAlloc)
+{
+ size_t uiSize;
+ IMG_UINT32 ui32Idx;
+
+ if (psDmaAlloc == NULL ||
+ psDmaAlloc->ui64Size == 0 ||
+ psDmaAlloc->pvOSDevice == NULL ||
+ psDmaAlloc->pvVirtAddr == NULL ||
+ psDmaAlloc->sBusAddr.uiAddr == 0)
+ {
+ PVR_LOG_IF_FALSE((IMG_FALSE), "Invalid parameter");
+ return;
+ }
+
+ uiSize = PVR_ALIGN(psDmaAlloc->ui64Size, PAGE_SIZE);
+
+ /* Remove specified entries from list of I/O remap entries */
+ for (ui32Idx = 0; ui32Idx < DMA_MAX_IOREMAP_ENTRIES; ++ui32Idx)
+ {
+ if (gsDmaIoRemapArray[ui32Idx].pvVirtAddr == psDmaAlloc->pvVirtAddr)
+ {
+ gsDmaIoRemapArray[ui32Idx].sBusAddr.uiAddr = 0;
+ gsDmaIoRemapArray[ui32Idx].pvVirtAddr = NULL;
+ gsDmaIoRemapArray[ui32Idx].ui64Size = 0;
+
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "DMA: deregister I/O remap: "
+ "VA: 0x%p, PA: 0x%llx, Size: 0x"IMG_SIZE_FMTSPECX,
+ psDmaAlloc->pvVirtAddr,
+ psDmaAlloc->sBusAddr.uiAddr,
+ uiSize));
+
+ break;
+ }
+ }
+
+ /* Check if no other I/O remap entries exists for remapping */
+ for (ui32Idx = 0; ui32Idx < DMA_MAX_IOREMAP_ENTRIES; ++ui32Idx)
+ {
+ if (gsDmaIoRemapArray[ui32Idx].pvVirtAddr != NULL)
+ {
+ break;
+ }
+ }
+
+ if (ui32Idx == DMA_MAX_IOREMAP_ENTRIES)
+ {
+ /* No entries found so disable remapping */
+ gbEnableDmaIoRemapping = IMG_FALSE;
+ }
+}
+
+/*!
+******************************************************************************
+ @Function SysDmaDevPAddrToCpuVAddr
+
+ @Description Maps a DMA_ALLOC physical address to CPU virtual address
+
+ @Return IMG_CPU_VIRTADDR on success. Otherwise, a NULL
+ ******************************************************************************/
+IMG_CPU_VIRTADDR SysDmaDevPAddrToCpuVAddr(IMG_UINT64 uiAddr, IMG_UINT64 ui64Size)
+{
+ IMG_CPU_VIRTADDR pvDMAVirtAddr = NULL;
+ DMA_ALLOC *psHeapDmaAlloc;
+ IMG_UINT32 ui32Idx;
+
+ if (gbEnableDmaIoRemapping == IMG_FALSE)
+ {
+ return pvDMAVirtAddr;
+ }
+
+ for (ui32Idx = 0; ui32Idx < DMA_MAX_IOREMAP_ENTRIES; ++ui32Idx)
+ {
+ psHeapDmaAlloc = &gsDmaIoRemapArray[ui32Idx];
+ if (psHeapDmaAlloc->sBusAddr.uiAddr && uiAddr >= psHeapDmaAlloc->sBusAddr.uiAddr)
+ {
+ IMG_UINT64 uiSpan = psHeapDmaAlloc->ui64Size;
+ IMG_UINT64 uiOffset = uiAddr - psHeapDmaAlloc->sBusAddr.uiAddr;
+
+ if (uiOffset < uiSpan)
+ {
+ PVR_ASSERT((uiOffset+ui64Size-1) < uiSpan);
+ pvDMAVirtAddr = psHeapDmaAlloc->pvVirtAddr + uiOffset;
+
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "DMA: remap: PA: 0x%llx => VA: 0x%p",
+ uiAddr, pvDMAVirtAddr));
+
+ break;
+ }
+ }
+ }
+
+ return pvDMAVirtAddr;
+}
+
+/*!
+******************************************************************************
+ @Function SysDmaCpuVAddrToDevPAddr
+
+ @Description Maps a DMA_ALLOC CPU virtual address to physical address
+
+ @Return Non-zero value on success. Otherwise, a 0
+ ******************************************************************************/
+IMG_UINT64 SysDmaCpuVAddrToDevPAddr(IMG_CPU_VIRTADDR pvDMAVirtAddr)
+{
+ IMG_UINT64 uiAddr = 0;
+ DMA_ALLOC *psHeapDmaAlloc;
+ IMG_UINT32 ui32Idx;
+
+ if (gbEnableDmaIoRemapping == IMG_FALSE)
+ {
+ return uiAddr;
+ }
+
+ for (ui32Idx = 0; ui32Idx < DMA_MAX_IOREMAP_ENTRIES; ++ui32Idx)
+ {
+ psHeapDmaAlloc = &gsDmaIoRemapArray[ui32Idx];
+ if (psHeapDmaAlloc->pvVirtAddr && pvDMAVirtAddr >= psHeapDmaAlloc->pvVirtAddr)
+ {
+ IMG_UINT64 uiSpan = psHeapDmaAlloc->ui64Size;
+ IMG_UINT64 uiOffset = pvDMAVirtAddr - psHeapDmaAlloc->pvVirtAddr;
+
+ if (uiOffset < uiSpan)
+ {
+ uiAddr = psHeapDmaAlloc->sBusAddr.uiAddr + uiOffset;
+
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "DMA: remap: VA: 0x%p => PA: 0x%llx",
+ pvDMAVirtAddr, uiAddr));
+
+ break;
+ }
+ }
+ }
+
+ return uiAddr;
+}
+
+/******************************************************************************
+ End of file (dma_support.c)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/dma_support.h b/drivers/gpu/drm/img-rogue/dma_support.h
new file mode 100644
index 000000000..c1d22bddf
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/dma_support.h
@@ -0,0 +1,117 @@
+/*************************************************************************/ /*!
+@File dma_support.h
+@Title Device contiguous memory allocator and I/O re-mapper
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description This header provides a contiguous memory allocator API; mainly
+ used for allocating / ioremapping (DMA/PA <-> CPU/VA)
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef DMA_SUPPORT_H
+#define DMA_SUPPORT_H
+
+#include "osfunc.h"
+#include "pvrsrv.h"
+
+typedef struct _DMA_ALLOC_
+{
+ IMG_UINT64 ui64Size;
+ IMG_CPU_VIRTADDR pvVirtAddr;
+ IMG_DEV_PHYADDR sBusAddr;
+ IMG_HANDLE hHandle;
+#if defined(__linux__)
+ struct page *psPage;
+ pgprot_t PageProps;
+#endif
+ void *pvOSDevice;
+} DMA_ALLOC;
+
+/*!
+*******************************************************************************
+ @Function SysDmaAllocMem
+ @Description Allocates physically contiguous memory
+ @Return PVRSRV_OK on success. Otherwise, a PVRSRV error code
+******************************************************************************/
+PVRSRV_ERROR SysDmaAllocMem(DMA_ALLOC *psDmaAlloc);
+
+/*!
+*******************************************************************************
+ @Function SysDmaFreeMem
+ @Description Free physically contiguous memory
+ @Return void
+******************************************************************************/
+void SysDmaFreeMem(DMA_ALLOC *psCmaAlloc);
+
+/*!
+*******************************************************************************
+ @Function SysDmaRegisterForIoRemapping
+ @Description Registers DMA_ALLOC for manual I/O remapping
+ @Return PVRSRV_OK on success. Otherwise, a PVRSRV error code
+******************************************************************************/
+PVRSRV_ERROR SysDmaRegisterForIoRemapping(DMA_ALLOC *psPhysHeapDmaAlloc);
+
+/*!
+*******************************************************************************
+ @Function SysDmaDeregisterForIoRemapping
+ @Description Deregisters DMA_ALLOC from manual I/O remapping
+ @Return void
+******************************************************************************/
+void SysDmaDeregisterForIoRemapping(DMA_ALLOC *psPhysHeapDmaAlloc);
+
+/*!
+*******************************************************************************
+ @Function SysDmaDevPAddrToCpuVAddr
+ @Description Maps a DMA_ALLOC physical address to CPU virtual address
+ @Return IMG_CPU_VIRTADDR on success. Otherwise, a NULL
+******************************************************************************/
+IMG_CPU_VIRTADDR
+SysDmaDevPAddrToCpuVAddr(IMG_UINT64 uiAddr, IMG_UINT64 ui64Size);
+
+/*!
+*******************************************************************************
+ @Function SysDmaCpuVAddrToDevPAddr
+ @Description Maps a DMA_ALLOC CPU virtual address to physical address
+ @Return Non-zero value on success. Otherwise, a 0
+******************************************************************************/
+IMG_UINT64 SysDmaCpuVAddrToDevPAddr(IMG_CPU_VIRTADDR pvDMAVirtAddr);
+
+#endif /* DMA_SUPPORT_H */
+
+/******************************************************************************
+ End of file (dma_support.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/drm_netlink_gem.c b/drivers/gpu/drm/img-rogue/drm_netlink_gem.c
new file mode 100644
index 000000000..467e1f4ed
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/drm_netlink_gem.c
@@ -0,0 +1,143 @@
+/*
+ * @File
+ * @Codingstyle LinuxKernel
+ * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+ * @License Dual MIT/GPLv2
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 ("GPL") in which case the provisions
+ * of GPL are applicable instead of those above.
+ *
+ * If you wish to allow use of your version of this file only under the terms of
+ * GPL, and not to allow others to use your version of this file under the terms
+ * of the MIT license, indicate your decision by deleting the provisions above
+ * and replace them with the notice and other provisions required by GPL as set
+ * out in the file called "GPL-COPYING" included in this distribution. If you do
+ * not delete the provisions above, a recipient may use your version of this file
+ * under the terms of either the MIT license or GPL.
+ *
+ * This License is also included in this distribution in the file called
+ * "MIT-COPYING".
+ *
+ * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+ * PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0))
+#include
+#include
+#endif
+
+#include "drm_netlink_gem.h"
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
+#include
+#endif
+
+#include
+
+#include "kernel_compatibility.h"
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+static int netlink_gem_mmap_capsys(struct file *file,
+ struct vm_area_struct *vma)
+{
+ struct drm_file *file_priv = file->private_data;
+ struct drm_device *dev = file_priv->minor->dev;
+ struct drm_vma_offset_node *node;
+ struct drm_gem_object *obj = NULL;
+ int err;
+
+ drm_vma_offset_lock_lookup(dev->vma_offset_manager);
+ node = drm_vma_offset_exact_lookup_locked(dev->vma_offset_manager,
+ vma->vm_pgoff,
+ vma_pages(vma));
+ if (node) {
+ obj = container_of(node, struct drm_gem_object, vma_node);
+
+ /* Don't mmap an object that is being destroyed */
+ if (!kref_get_unless_zero(&obj->refcount))
+ obj = NULL;
+ }
+ drm_vma_offset_unlock_lookup(dev->vma_offset_manager);
+
+ if (!obj)
+ return -EINVAL;
+
+ err = drm_vma_node_allow(node, file_priv);
+ if (!err) {
+ err = drm_gem_mmap(file, vma);
+
+ drm_vma_node_revoke(node, file_priv);
+ }
+
+ drm_gem_object_put(obj);
+
+ return err;
+}
+
+int netlink_gem_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ int err;
+
+ err = drm_gem_mmap(file, vma);
+ if (!!err && capable(CAP_SYS_RAWIO))
+ err = netlink_gem_mmap_capsys(file, vma);
+
+ return err;
+}
+#else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) */
+int netlink_gem_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct drm_file *file_priv = file->private_data;
+ struct drm_device *dev = file_priv->minor->dev;
+ struct drm_vma_offset_node *node;
+ struct drm_gem_object *obj;
+ int err;
+
+ mutex_lock(&dev->struct_mutex);
+
+ node = drm_vma_offset_exact_lookup(dev->vma_offset_manager,
+ vma->vm_pgoff,
+ vma_pages(vma));
+ if (!node) {
+ err = -EINVAL;
+ goto exit_unlock;
+ }
+
+ /* Allow Netlink clients to mmap any object for reading */
+ if (!capable(CAP_SYS_RAWIO) || (vma->vm_flags & VM_WRITE)) {
+ if (!drm_vma_node_is_allowed(node, file_priv)) {
+ err = -EACCES;
+ goto exit_unlock;
+ }
+ }
+
+ obj = container_of(node, struct drm_gem_object, vma_node);
+
+ err = drm_gem_mmap_obj(obj, drm_vma_node_size(node) << PAGE_SHIFT, vma);
+
+exit_unlock:
+ mutex_unlock(&dev->struct_mutex);
+ return err;
+}
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) */
diff --git a/drivers/gpu/drm/img-rogue/drm_netlink_gem.h b/drivers/gpu/drm/img-rogue/drm_netlink_gem.h
new file mode 100644
index 000000000..3a3fcd490
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/drm_netlink_gem.h
@@ -0,0 +1,61 @@
+/*
+ * @File
+ * @Codingstyle LinuxKernel
+ * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+ * @License Dual MIT/GPLv2
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 ("GPL") in which case the provisions
+ * of GPL are applicable instead of those above.
+ *
+ * If you wish to allow use of your version of this file only under the terms of
+ * GPL, and not to allow others to use your version of this file under the terms
+ * of the MIT license, indicate your decision by deleting the provisions above
+ * and replace them with the notice and other provisions required by GPL as set
+ * out in the file called "GPL-COPYING" included in this distribution. If you do
+ * not delete the provisions above, a recipient may use your version of this file
+ * under the terms of either the MIT license or GPL.
+ *
+ * This License is also included in this distribution in the file called
+ * "MIT-COPYING".
+ *
+ * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+ * PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#if !defined(__DRM_NETLINK_GEM_H__)
+#define __DRM_NETLINK_GEM_H__
+
+#include
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0))
+struct file;
+struct vm_area_struct;
+#else
+#include
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
+#include
+#endif
+
+int netlink_gem_mmap(struct file *file, struct vm_area_struct *vma);
+
+#endif /* !defined(__DRM_NETLINK_GEM_H__) */
diff --git a/drivers/gpu/drm/img-rogue/drm_nulldisp_drv.c b/drivers/gpu/drm/img-rogue/drm_nulldisp_drv.c
new file mode 100644
index 000000000..8c722f62e
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/drm_nulldisp_drv.c
@@ -0,0 +1,2705 @@
+/*
+ * @File
+ * @Codingstyle LinuxKernel
+ * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+ * @License Dual MIT/GPLv2
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 ("GPL") in which case the provisions
+ * of GPL are applicable instead of those above.
+ *
+ * If you wish to allow use of your version of this file only under the terms of
+ * GPL, and not to allow others to use your version of this file under the terms
+ * of the MIT license, indicate your decision by deleting the provisions above
+ * and replace them with the notice and other provisions required by GPL as set
+ * out in the file called "GPL-COPYING" included in this distribution. If you do
+ * not delete the provisions above, a recipient may use your version of this file
+ * under the terms of either the MIT license or GPL.
+ *
+ * This License is also included in this distribution in the file called
+ * "MIT-COPYING".
+ *
+ * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+ * PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+#include "pvr_linux_fence.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0))
+#include
+#include
+#include
+#include
+#include
+#else
+#include
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))
+#include
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0))
+#include
+#endif
+
+#include "pvr_dma_resv.h"
+
+#include "img_drm_fourcc_internal.h"
+#include
+
+#include
+
+#include "drm_nulldisp_drv.h"
+#if defined(LMA)
+#include "tc_drv.h"
+#include "drm_pdp_gem.h"
+#include "pdp_drm.h"
+#else
+#include "drm_nulldisp_gem.h"
+#endif
+#include "nulldisp_drm.h"
+#include "drm_netlink_gem.h"
+#include "drm_nulldisp_netlink.h"
+
+#if defined(NULLDISP_USE_ATOMIC)
+#include
+#include
+#include
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0))
+#include
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) */
+#endif
+
+#include "kernel_compatibility.h"
+
+#define DRIVER_NAME "nulldisp"
+#define DRIVER_DESC "Imagination Technologies Null DRM Display Driver"
+#define DRIVER_DATE "20150612"
+
+#if defined(NULLDISP_USE_ATOMIC)
+#define NULLDISP_DRIVER_ATOMIC DRIVER_ATOMIC
+#else
+#define NULLDISP_DRIVER_ATOMIC 0
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
+#define NULLDISP_DRIVER_PRIME 0
+#else
+#define NULLDISP_DRIVER_PRIME DRIVER_PRIME
+#endif
+
+#define NULLDISP_FB_WIDTH_MIN 0
+#define NULLDISP_FB_WIDTH_MAX 8192
+#define NULLDISP_FB_HEIGHT_MIN 0
+#define NULLDISP_FB_HEIGHT_MAX 8192
+
+#define NULLDISP_DEFAULT_WIDTH 640
+#define NULLDISP_DEFAULT_HEIGHT 480
+#define NULLDISP_DEFAULT_REFRESH_RATE 60
+
+#define NULLDISP_MAX_PLANES 3
+
+#if defined(NULLDISP_USE_ATOMIC)
+#define NULLDISP_NETLINK_TIMEOUT 5
+#else
+#define NULLDISP_NETLINK_TIMEOUT 30
+#endif
+#define NULLDISP_NETLINK_TIMEOUT_MAX 300
+#define NULLDISP_NETLINK_TIMEOUT_MIN 1
+
+enum nulldisp_crtc_flip_status {
+ NULLDISP_CRTC_FLIP_STATUS_NONE = 0,
+#if !defined(NULLDISP_USE_ATOMIC)
+ NULLDISP_CRTC_FLIP_STATUS_PENDING,
+#endif
+ NULLDISP_CRTC_FLIP_STATUS_DONE,
+};
+
+struct nulldisp_flip_data {
+ struct dma_fence_cb base;
+ struct drm_crtc *crtc;
+ struct dma_fence *wait_fence;
+};
+
+struct nulldisp_crtc {
+ struct drm_crtc base;
+ struct delayed_work vb_work;
+#if defined(NULLDISP_USE_ATOMIC)
+ struct drm_framebuffer *fb;
+ struct completion flip_done;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0))
+ struct completion copy_done;
+#endif
+#else
+ struct work_struct flip_work;
+ struct delayed_work flip_to_work;
+ struct delayed_work copy_to_work;
+
+ struct completion flip_scheduled;
+ struct completion copy_done;
+#endif
+
+ /* Reuse the drm_device event_lock to protect these */
+ atomic_t flip_status;
+ struct drm_pending_vblank_event *flip_event;
+#if !defined(NULLDISP_USE_ATOMIC)
+ struct drm_framebuffer *old_fb;
+ struct nulldisp_flip_data *flip_data;
+#endif
+ bool flip_async;
+};
+
+struct nulldisp_display_device {
+ struct drm_device *dev;
+
+ struct workqueue_struct *workqueue;
+ struct nulldisp_crtc *nulldisp_crtc;
+ struct nlpvrdpy *nlpvrdpy;
+#if defined(LMA)
+ struct pdp_gem_private *pdp_gem_priv;
+#endif
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0)) || \
+ (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))
+ struct drm_connector *connector;
+#endif
+};
+
+#if !defined(NULLDISP_USE_ATOMIC)
+struct nulldisp_framebuffer {
+ struct drm_framebuffer base;
+ struct drm_gem_object *obj[NULLDISP_MAX_PLANES];
+};
+
+#define to_nulldisp_framebuffer(framebuffer) \
+ container_of(framebuffer, struct nulldisp_framebuffer, base)
+#endif
+
+struct nulldisp_module_params {
+ unsigned int hdisplay;
+ unsigned int vdisplay;
+ unsigned int vrefresh;
+ unsigned int updateto;
+};
+
+#define to_nulldisp_crtc(crtc) \
+ container_of(crtc, struct nulldisp_crtc, base)
+
+#if defined(LMA)
+#define obj_to_resv(obj) pdp_gem_get_resv(obj)
+#else
+#define obj_to_resv(obj) nulldisp_gem_get_resv(obj)
+#endif
+
+/*
+ * The order of this array helps determine the order in which EGL configs are
+ * returned to an application using eglGetConfigs. As such, RGB 8888 formats
+ * should appear first, followed by RGB 565 configs. YUV configs should appear
+ * last.
+ */
+static const uint32_t nulldisp_modeset_formats[] = {
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_ABGR2101010,
+#ifdef DRM_FORMAT_ABGR16161616F
+ DRM_FORMAT_ABGR16161616F,
+#endif
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_YUYV,
+ DRM_FORMAT_YUV444,
+ DRM_FORMAT_YUV420,
+ DRM_FORMAT_YVU420,
+};
+
+/*
+ * Note that nulldisp, being a no-hardware display controller driver,
+ * "supports" a number different decompression hardware
+ * versions (V0, V1, V2 ...). Real, hardware display controllers are
+ * likely to support only a single version.
+ */
+static const uint64_t nulldisp_primary_plane_modifiers[] = {
+ DRM_FORMAT_MOD_LINEAR,
+ DRM_FORMAT_MOD_PVR_FBCDC_8x8_V0,
+ DRM_FORMAT_MOD_PVR_FBCDC_8x8_V0_FIX,
+ DRM_FORMAT_MOD_PVR_FBCDC_8x8_V1,
+ DRM_FORMAT_MOD_PVR_FBCDC_8x8_V2,
+ DRM_FORMAT_MOD_PVR_FBCDC_8x8_V3,
+ DRM_FORMAT_MOD_PVR_FBCDC_8x8_V7,
+ DRM_FORMAT_MOD_PVR_FBCDC_8x8_V8,
+ DRM_FORMAT_MOD_PVR_FBCDC_8x8_V10,
+ DRM_FORMAT_MOD_PVR_FBCDC_8x8_V12,
+ DRM_FORMAT_MOD_PVR_FBCDC_8x8_V13,
+ DRM_FORMAT_MOD_PVR_FBCDC_LOSSY25_8x8_V13,
+ DRM_FORMAT_MOD_PVR_FBCDC_LOSSY50_8x8_V13,
+ DRM_FORMAT_MOD_PVR_FBCDC_LOSSY75_8x8_V13,
+ DRM_FORMAT_MOD_PVR_FBCDC_16x4_V0,
+ DRM_FORMAT_MOD_PVR_FBCDC_16x4_V0_FIX,
+ DRM_FORMAT_MOD_PVR_FBCDC_16x4_V1,
+ DRM_FORMAT_MOD_PVR_FBCDC_16x4_V2,
+ DRM_FORMAT_MOD_PVR_FBCDC_16x4_V3,
+ DRM_FORMAT_MOD_PVR_FBCDC_16x4_V7,
+ DRM_FORMAT_MOD_PVR_FBCDC_16x4_V8,
+ DRM_FORMAT_MOD_PVR_FBCDC_16x4_V10,
+ DRM_FORMAT_MOD_PVR_FBCDC_16x4_V12,
+ DRM_FORMAT_MOD_PVR_FBCDC_16x4_V13,
+ DRM_FORMAT_MOD_PVR_FBCDC_LOSSY25_16x4_V13,
+ DRM_FORMAT_MOD_PVR_FBCDC_LOSSY50_16x4_V13,
+ DRM_FORMAT_MOD_PVR_FBCDC_LOSSY75_16x4_V13,
+ DRM_FORMAT_MOD_PVR_FBCDC_32x2_V1,
+ DRM_FORMAT_MOD_PVR_FBCDC_32x2_V3,
+ DRM_FORMAT_MOD_PVR_FBCDC_32x2_V8,
+ DRM_FORMAT_MOD_PVR_FBCDC_32x2_V10,
+ DRM_FORMAT_MOD_PVR_FBCDC_32x2_V12,
+ DRM_FORMAT_MOD_INVALID
+};
+
+static struct nulldisp_module_params module_params = {
+ .hdisplay = NULLDISP_DEFAULT_WIDTH,
+ .vdisplay = NULLDISP_DEFAULT_HEIGHT,
+ .vrefresh = NULLDISP_DEFAULT_REFRESH_RATE,
+ .updateto = NULLDISP_NETLINK_TIMEOUT,
+};
+
+static int updateto_param_set(const char *val, const struct kernel_param *kp);
+
+static const struct kernel_param_ops updateto_ops = {
+ .set = updateto_param_set,
+ .get = param_get_uint,
+};
+
+module_param_named(width, module_params.hdisplay, uint, 0444);
+module_param_named(height, module_params.vdisplay, uint, 0444);
+module_param_named(refreshrate, module_params.vrefresh, uint, 0444);
+module_param_cb(updateto, &updateto_ops, &module_params.updateto, 0644);
+
+MODULE_PARM_DESC(width, "Preferred display width in pixels");
+MODULE_PARM_DESC(height, "Preferred display height in pixels");
+MODULE_PARM_DESC(refreshrate, "Preferred display refresh rate");
+MODULE_PARM_DESC(updateto, "Preferred remote update timeout (in seconds)");
+
+/*
+ * Please use this function to obtain the module parameters instead of
+ * accessing the global "module_params" structure directly.
+ */
+static inline const struct nulldisp_module_params *
+nulldisp_get_module_params(void)
+{
+ return &module_params;
+}
+
+static int updateto_param_set(const char *val, const struct kernel_param *kp)
+{
+ unsigned int updateto;
+ int err;
+
+ err = kstrtouint(val, 10, &updateto);
+ if (err)
+ return err;
+
+ if (updateto < NULLDISP_NETLINK_TIMEOUT_MIN ||
+ updateto > NULLDISP_NETLINK_TIMEOUT_MAX)
+ return -EINVAL;
+
+ return param_set_uint(val, kp);
+}
+
+static unsigned long nulldisp_netlink_timeout(void)
+{
+ const struct nulldisp_module_params *module_params =
+ nulldisp_get_module_params();
+ unsigned int updateto;
+
+#if !defined(CHROMIUMOS_KERNEL) && \
+ (LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0))
+ kparam_block_sysfs_write(updateto);
+#else
+ kernel_param_lock(THIS_MODULE);
+#endif
+
+ updateto = module_params->updateto;
+
+#if !defined(CHROMIUMOS_KERNEL) && \
+ (LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0))
+ kparam_unblock_sysfs_write(updateto);
+#else
+ kernel_param_unlock(THIS_MODULE);
+#endif
+
+ return msecs_to_jiffies(updateto * 1000);
+}
+
+/******************************************************************************
+ * Linux compatibility functions
+ ******************************************************************************/
+static inline void
+nulldisp_drm_fb_set_format(struct drm_framebuffer *fb,
+ u32 pixel_format)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+ fb->format = drm_format_info(pixel_format);
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
+ const struct drm_format_info *format = drm_format_info(pixel_format);
+
+ fb->pixel_format = pixel_format;
+
+ fb->depth = format->depth;
+ fb->bits_per_pixel = format->depth ? (format->cpp[0] * 8) : 0;
+#else
+ fb->pixel_format = pixel_format;
+
+ switch (pixel_format) {
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_YUV444:
+ case DRM_FORMAT_YUV420:
+ case DRM_FORMAT_YVU420:
+ /* Unused for YUV formats */
+ fb->depth = 0;
+ fb->bits_per_pixel = 0;
+ break;
+
+ default: /* RGB */
+ drm_fb_get_bpp_depth(pixel_format,
+ &fb->depth,
+ &fb->bits_per_pixel);
+ }
+#endif
+}
+
+static inline void nulldisp_drm_fb_set_modifier(struct drm_framebuffer *fb,
+ uint64_t value)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
+ fb->modifier = value;
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
+ /* FB modifier values must be the same for all planes */
+ fb->modifier[0] = value;
+ fb->modifier[1] = value;
+ fb->modifier[2] = value;
+ fb->modifier[3] = value;
+#else
+ /* Modifiers are not supported */
+#endif
+}
+
+/******************************************************************************
+ * Plane functions
+ ******************************************************************************/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
+static bool nulldisp_primary_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
+{
+ /*
+ * All 'nulldisp_modeset_formats' are supported for every modifier
+ * in the 'nulldisp_primary_plane_modifiers' array.
+ */
+ return true;
+}
+#endif
+
+#if defined(NULLDISP_USE_ATOMIC)
+static int nulldisp_plane_helper_atomic_check(struct drm_plane *plane,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 13, 0))
+ struct drm_plane_state *state)
+{
+#else
+ struct drm_atomic_state *astate)
+{
+ struct drm_plane_state *state =
+ drm_atomic_get_new_plane_state(astate, plane);
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 13, 0) */
+ struct drm_crtc_state *crtc_new_state;
+
+ if (!state->crtc)
+ return 0;
+
+ crtc_new_state = drm_atomic_get_new_crtc_state(state->state,
+ state->crtc);
+
+ return drm_atomic_helper_check_plane_state(state, crtc_new_state,
+ DRM_PLANE_HELPER_NO_SCALING,
+ DRM_PLANE_HELPER_NO_SCALING,
+ false, true);
+}
+
+static void
+nulldisp_plane_helper_atomic_update(struct drm_plane *plane,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 13, 0))
+ struct drm_plane_state *old_state)
+#else
+ struct drm_atomic_state *astate)
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 13, 0) */
+{
+ struct drm_plane_state *state = plane->state;
+
+ if (state->crtc) {
+ struct nulldisp_crtc *nulldisp_crtc =
+ to_nulldisp_crtc(state->crtc);
+
+ nulldisp_crtc->fb = state->fb;
+ }
+}
+
+static const struct drm_plane_helper_funcs nulldisp_plane_helper_funcs = {
+ .prepare_fb = drm_gem_plane_helper_prepare_fb,
+ .atomic_check = nulldisp_plane_helper_atomic_check,
+ .atomic_update = nulldisp_plane_helper_atomic_update,
+};
+
+static const struct drm_plane_funcs nulldisp_plane_funcs = {
+ .update_plane = drm_atomic_helper_update_plane,
+ .disable_plane = drm_atomic_helper_disable_plane,
+ .destroy = drm_primary_helper_destroy,
+ .reset = drm_atomic_helper_plane_reset,
+ .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+ .format_mod_supported = nulldisp_primary_format_mod_supported,
+};
+#else /* defined(NULLDISP_USE_ATOMIC) */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))
+static int nulldisp_primary_helper_update(struct drm_plane *plane,
+ struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int crtc_x, int crtc_y,
+ unsigned int crtc_w,
+ unsigned int crtc_h,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h,
+ struct drm_modeset_acquire_ctx *ctx)
+{
+ struct nulldisp_display_device *nulldisp_dev = crtc->dev->dev_private;
+ struct drm_plane_state plane_state = {
+ .plane = plane,
+ .crtc = crtc,
+ .fb = fb,
+ .crtc_x = crtc_x,
+ .crtc_y = crtc_y,
+ .crtc_w = crtc_w,
+ .crtc_h = crtc_h,
+ .src_x = src_x,
+ .src_y = src_y,
+ .src_w = src_w,
+ .src_h = src_h,
+ .alpha = DRM_BLEND_ALPHA_OPAQUE,
+ .rotation = DRM_MODE_ROTATE_0,
+ };
+ struct drm_crtc_state crtc_state = {
+ .crtc = crtc,
+ .enable = crtc->enabled,
+ .adjusted_mode = crtc->mode,
+ .mode = crtc->mode,
+ };
+ struct drm_mode_set set = {
+ .fb = fb,
+ .crtc = crtc,
+ .mode = &crtc->mode,
+ .x = src_x >> 16, /* convert from fixed point */
+ .y = src_y >> 16, /* convert from fixed point */
+ .connectors = &nulldisp_dev->connector,
+ .num_connectors = 1,
+ };
+ int err;
+
+ BUG_ON(nulldisp_dev->connector->encoder == NULL);
+ BUG_ON(nulldisp_dev->connector->encoder->crtc != crtc);
+
+ err = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
+ DRM_PLANE_HELPER_NO_SCALING,
+ DRM_PLANE_HELPER_NO_SCALING,
+ false, false);
+ if (err)
+ return err;
+
+ if (!plane_state.visible)
+ return -EINVAL;
+
+ return crtc->funcs->set_config(&set, ctx);
+}
+
+static int nulldisp_primary_helper_disable(struct drm_plane *plane,
+ struct drm_modeset_acquire_ctx *ctx)
+{
+ return -EINVAL;
+}
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) */
+
+static const struct drm_plane_funcs nulldisp_plane_funcs = {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))
+ .update_plane = nulldisp_primary_helper_update,
+ .disable_plane = nulldisp_primary_helper_disable,
+#else
+ .update_plane = drm_primary_helper_update,
+ .disable_plane = drm_primary_helper_disable,
+#endif
+ .destroy = drm_primary_helper_destroy,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
+ .format_mod_supported = nulldisp_primary_format_mod_supported,
+#endif
+};
+#endif /* defined(NULLDISP_USE_ATOMIC) */
+
+/******************************************************************************
+ * CRTC functions
+ ******************************************************************************/
+
+static bool
+nulldisp_crtc_helper_mode_fixup(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ /*
+ * Fix up mode so that it's compatible with the hardware. The results
+ * should be stored in adjusted_mode (i.e. mode should be untouched).
+ */
+ return true;
+}
+
+static void nulldisp_crtc_helper_disable(struct drm_crtc *crtc)
+{
+ struct nulldisp_crtc *nulldisp_crtc = to_nulldisp_crtc(crtc);
+
+#if !defined(NULLDISP_USE_ATOMIC)
+ if (atomic_read(&nulldisp_crtc->flip_status) ==
+ NULLDISP_CRTC_FLIP_STATUS_PENDING)
+ wait_for_completion(&nulldisp_crtc->flip_scheduled);
+
+ /*
+ * Flush any outstanding page flip related work. The order this
+ * is done is important, to ensure there are no outstanding
+ * page flips.
+ */
+ flush_work(&nulldisp_crtc->flip_work);
+ flush_delayed_work(&nulldisp_crtc->flip_to_work);
+#endif
+ flush_delayed_work(&nulldisp_crtc->vb_work);
+
+ drm_crtc_vblank_off(crtc);
+ flush_delayed_work(&nulldisp_crtc->vb_work);
+
+ /*
+ * Vblank has been disabled, so the vblank handler shouldn't be
+ * able to reschedule itself.
+ */
+ BUG_ON(cancel_delayed_work(&nulldisp_crtc->vb_work));
+
+ BUG_ON(atomic_read(&nulldisp_crtc->flip_status) !=
+ NULLDISP_CRTC_FLIP_STATUS_NONE);
+
+#if !defined(NULLDISP_USE_ATOMIC)
+ /* Flush any remaining dirty FB work */
+ flush_delayed_work(&nulldisp_crtc->copy_to_work);
+#endif
+}
+
+static void nulldisp_crtc_flip_complete(struct drm_crtc *crtc)
+{
+ struct nulldisp_crtc *nulldisp_crtc = to_nulldisp_crtc(crtc);
+ unsigned long flags;
+
+ spin_lock_irqsave(&crtc->dev->event_lock, flags);
+
+ /* The flipping process has been completed so reset the flip state */
+ atomic_set(&nulldisp_crtc->flip_status, NULLDISP_CRTC_FLIP_STATUS_NONE);
+ nulldisp_crtc->flip_async = false;
+
+#if !defined(NULLDISP_USE_ATOMIC)
+ if (nulldisp_crtc->flip_data) {
+ dma_fence_put(nulldisp_crtc->flip_data->wait_fence);
+ kfree(nulldisp_crtc->flip_data);
+ nulldisp_crtc->flip_data = NULL;
+ }
+#endif
+ if (nulldisp_crtc->flip_event) {
+ drm_crtc_send_vblank_event(crtc, nulldisp_crtc->flip_event);
+ nulldisp_crtc->flip_event = NULL;
+ }
+
+ spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+}
+
+#if defined(NULLDISP_USE_ATOMIC)
+static void nulldisp_crtc_helper_mode_set_nofb(struct drm_crtc *crtc)
+{
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0))
+static void nulldisp_crtc_helper_atomic_flush(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
+{
+#else
+static void nulldisp_crtc_helper_atomic_flush(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+{
+ struct drm_crtc_state *old_state = drm_atomic_get_new_crtc_state(state, crtc);
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) */
+ struct nulldisp_crtc *nulldisp_crtc = to_nulldisp_crtc(crtc);
+
+ if (!crtc->state->active || !old_state->active)
+ return;
+
+ if (nulldisp_crtc->fb) {
+ struct nulldisp_display_device *nulldisp_dev =
+ crtc->dev->dev_private;
+
+ reinit_completion(&nulldisp_crtc->flip_done);
+
+ if (!nlpvrdpy_send_flip(nulldisp_dev->nlpvrdpy,
+ nulldisp_crtc->fb,
+ &nulldisp_crtc->fb->obj[0])) {
+ unsigned long res;
+
+ res = wait_for_completion_timeout(
+ &nulldisp_crtc->flip_done,
+ nulldisp_netlink_timeout());
+
+ if (!res)
+ DRM_ERROR(
+ "timed out waiting for remote update\n");
+ }
+
+ nulldisp_crtc->fb = NULL;
+ }
+
+ if (crtc->state->event) {
+ unsigned long flags;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
+ nulldisp_crtc->flip_async = crtc->state->async_flip;
+#else
+ nulldisp_crtc->flip_async = !!(crtc->state->pageflip_flags
+ & DRM_MODE_PAGE_FLIP_ASYNC);
+#endif
+ if (nulldisp_crtc->flip_async)
+ WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+
+ spin_lock_irqsave(&crtc->dev->event_lock, flags);
+ nulldisp_crtc->flip_event = crtc->state->event;
+ crtc->state->event = NULL;
+
+ atomic_set(&nulldisp_crtc->flip_status,
+ NULLDISP_CRTC_FLIP_STATUS_DONE);
+ spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+
+ if (nulldisp_crtc->flip_async)
+ nulldisp_crtc_flip_complete(crtc);
+ }
+}
+
+static void nulldisp_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
+{
+ if (enable)
+ drm_crtc_vblank_on(crtc);
+ else
+ nulldisp_crtc_helper_disable(crtc);
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0))
+static void
+nulldisp_crtc_helper_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state)
+#else
+static void
+nulldisp_crtc_helper_atomic_enable(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) */
+{
+ nulldisp_crtc_set_enabled(crtc, true);
+
+ if (crtc->state->event) {
+ struct nulldisp_crtc *nulldisp_crtc = to_nulldisp_crtc(crtc);
+ unsigned long flags;
+
+ WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+
+ spin_lock_irqsave(&crtc->dev->event_lock, flags);
+ nulldisp_crtc->flip_event = crtc->state->event;
+ crtc->state->event = NULL;
+
+ atomic_set(&nulldisp_crtc->flip_status,
+ NULLDISP_CRTC_FLIP_STATUS_DONE);
+ spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+ }
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0))
+static void
+nulldisp_crtc_helper_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state)
+#else
+static void
+nulldisp_crtc_helper_atomic_disable(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) */
+{
+ struct nulldisp_crtc *nulldisp_crtc = to_nulldisp_crtc(crtc);
+
+ nulldisp_crtc_set_enabled(crtc, false);
+
+ nulldisp_crtc->fb = NULL;
+
+ if (crtc->state->event) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&crtc->dev->event_lock, flags);
+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ crtc->state->event = NULL;
+ spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+ }
+}
+#else /* defined(NULLDISP_USE_ATOMIC) */
+static void nulldisp_crtc_helper_dpms(struct drm_crtc *crtc,
+ int mode)
+{
+ /*
+ * Change the power state of the display/pipe/port/etc. If the mode
+ * passed in is unsupported, the provider must use the next lowest
+ * power level.
+ */
+}
+
+static void nulldisp_crtc_helper_prepare(struct drm_crtc *crtc)
+{
+ drm_crtc_vblank_off(crtc);
+
+ /*
+ * Prepare the display/pipe/port/etc for a mode change e.g. put them
+ * in a low power state/turn them off
+ */
+}
+
+static void nulldisp_crtc_helper_commit(struct drm_crtc *crtc)
+{
+ /* Turn the display/pipe/port/etc back on */
+
+ drm_crtc_vblank_on(crtc);
+}
+
+static int
+nulldisp_crtc_helper_mode_set_base_atomic(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int x, int y,
+ enum mode_set_atomic atomic)
+{
+ /* Set the display base address or offset from the base address */
+ return 0;
+}
+
+static int nulldisp_crtc_helper_mode_set_base(struct drm_crtc *crtc,
+ int x, int y,
+ struct drm_framebuffer *old_fb)
+{
+ return nulldisp_crtc_helper_mode_set_base_atomic(crtc,
+ crtc->primary->fb,
+ x,
+ y,
+ 0);
+}
+
+static int
+nulldisp_crtc_helper_mode_set(struct drm_crtc *crtc,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode,
+ int x, int y,
+ struct drm_framebuffer *old_fb)
+{
+ /* Setup the new mode and/or framebuffer */
+ return nulldisp_crtc_helper_mode_set_base(crtc, x, y, old_fb);
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
+static void nulldisp_crtc_helper_load_lut(struct drm_crtc *crtc)
+{
+}
+#endif
+#endif /* defined(NULLDISP_USE_ATOMIC) */
+
+static void nulldisp_crtc_destroy(struct drm_crtc *crtc)
+{
+ struct nulldisp_crtc *nulldisp_crtc = to_nulldisp_crtc(crtc);
+
+ DRM_DEBUG_DRIVER("[CRTC:%d]\n", crtc->base.id);
+
+ drm_crtc_cleanup(crtc);
+
+ BUG_ON(atomic_read(&nulldisp_crtc->flip_status) !=
+ NULLDISP_CRTC_FLIP_STATUS_NONE);
+
+ kfree(nulldisp_crtc);
+}
+
+#if !defined(NULLDISP_USE_ATOMIC)
+static void nulldisp_crtc_flip_done(struct nulldisp_crtc *nulldisp_crtc)
+{
+ struct drm_crtc *crtc = &nulldisp_crtc->base;
+
+ struct drm_framebuffer *old_fb;
+
+ WARN_ON(atomic_read(&nulldisp_crtc->flip_status) !=
+ NULLDISP_CRTC_FLIP_STATUS_PENDING);
+
+ old_fb = nulldisp_crtc->old_fb;
+ nulldisp_crtc->old_fb = NULL;
+
+ (void) nulldisp_crtc_helper_mode_set_base(crtc, crtc->x, crtc->y,
+ old_fb);
+
+ atomic_set(&nulldisp_crtc->flip_status, NULLDISP_CRTC_FLIP_STATUS_DONE);
+
+ if (nulldisp_crtc->flip_async)
+ nulldisp_crtc_flip_complete(crtc);
+}
+
+static bool nulldisp_set_flip_to(struct nulldisp_crtc *nulldisp_crtc)
+{
+ struct drm_crtc *crtc = &nulldisp_crtc->base;
+ struct nulldisp_display_device *nulldisp_dev = crtc->dev->dev_private;
+
+ /* Returns false if work already queued, else true */
+ return queue_delayed_work(nulldisp_dev->workqueue,
+ &nulldisp_crtc->flip_to_work,
+ nulldisp_netlink_timeout());
+}
+
+static bool nulldisp_set_copy_to(struct nulldisp_crtc *nulldisp_crtc)
+{
+ struct drm_crtc *crtc = &nulldisp_crtc->base;
+ struct nulldisp_display_device *nulldisp_dev = crtc->dev->dev_private;
+
+ /* Returns false if work already queued, else true */
+ return queue_delayed_work(nulldisp_dev->workqueue,
+ &nulldisp_crtc->copy_to_work,
+ nulldisp_netlink_timeout());
+}
+
+static void nulldisp_flip_to_work(struct work_struct *w)
+{
+ struct delayed_work *dw =
+ container_of(w, struct delayed_work, work);
+ struct nulldisp_crtc *nulldisp_crtc =
+ container_of(dw, struct nulldisp_crtc, flip_to_work);
+
+ if (atomic_read(&nulldisp_crtc->flip_status) ==
+ NULLDISP_CRTC_FLIP_STATUS_PENDING)
+ nulldisp_crtc_flip_done(nulldisp_crtc);
+}
+
+static void nulldisp_copy_to_work(struct work_struct *w)
+{
+ struct delayed_work *dw =
+ container_of(w, struct delayed_work, work);
+ struct nulldisp_crtc *nulldisp_crtc =
+ container_of(dw, struct nulldisp_crtc, copy_to_work);
+
+ complete(&nulldisp_crtc->copy_done);
+}
+
+static void nulldisp_flip_work(struct work_struct *w)
+{
+ struct nulldisp_crtc *nulldisp_crtc =
+ container_of(w, struct nulldisp_crtc, flip_work);
+ struct drm_crtc *crtc = &nulldisp_crtc->base;
+ struct drm_device *dev = crtc->dev;
+ struct nulldisp_display_device *nulldisp_dev = dev->dev_private;
+ struct nulldisp_framebuffer *nulldisp_fb =
+ to_nulldisp_framebuffer(crtc->primary->fb);
+
+ /*
+ * To prevent races with disconnect requests from user space,
+ * set the timeout before sending the flip request.
+ */
+ nulldisp_set_flip_to(nulldisp_crtc);
+
+ if (nlpvrdpy_send_flip(nulldisp_dev->nlpvrdpy,
+ &nulldisp_fb->base,
+ &nulldisp_fb->obj[0]))
+ goto fail_cancel;
+
+ return;
+
+fail_cancel:
+ /*
+ * We can't flush the work, as we are running on the same
+ * single threaded workqueue as the work to be flushed.
+ */
+ cancel_delayed_work(&nulldisp_crtc->flip_to_work);
+
+ nulldisp_crtc_flip_done(nulldisp_crtc);
+}
+
+static void nulldisp_crtc_flip_cb(struct dma_fence *fence,
+ struct dma_fence_cb *cb)
+{
+ struct nulldisp_flip_data *flip_data =
+ container_of(cb, struct nulldisp_flip_data, base);
+ struct drm_crtc *crtc = flip_data->crtc;
+ struct nulldisp_crtc *nulldisp_crtc = to_nulldisp_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct nulldisp_display_device *nulldisp_dev = dev->dev_private;
+
+ (void) queue_work(nulldisp_dev->workqueue,
+ &nulldisp_crtc->flip_work);
+
+ complete_all(&nulldisp_crtc->flip_scheduled);
+}
+
+static void nulldisp_crtc_flip_schedule_cb(struct dma_fence *fence,
+ struct dma_fence_cb *cb)
+{
+ struct nulldisp_flip_data *flip_data =
+ container_of(cb, struct nulldisp_flip_data, base);
+ int err = 0;
+
+ if (flip_data->wait_fence)
+ err = dma_fence_add_callback(flip_data->wait_fence,
+ &flip_data->base,
+ nulldisp_crtc_flip_cb);
+
+ if (!flip_data->wait_fence || err) {
+ if (err && err != -ENOENT)
+ DRM_ERROR("flip failed to wait on old buffer\n");
+ nulldisp_crtc_flip_cb(flip_data->wait_fence, &flip_data->base);
+ }
+}
+
+static int nulldisp_crtc_flip_schedule(struct drm_crtc *crtc,
+ struct drm_gem_object *obj,
+ struct drm_gem_object *old_obj)
+{
+ struct nulldisp_crtc *nulldisp_crtc = to_nulldisp_crtc(crtc);
+ struct dma_resv *resv = obj_to_resv(obj);
+ struct dma_resv *old_resv = obj_to_resv(old_obj);
+ struct nulldisp_flip_data *flip_data;
+ struct dma_fence *fence;
+ int err;
+
+ flip_data = kmalloc(sizeof(*flip_data), GFP_KERNEL);
+ if (!flip_data)
+ return -ENOMEM;
+
+ flip_data->crtc = crtc;
+
+ ww_mutex_lock(&old_resv->lock, NULL);
+ flip_data->wait_fence =
+ dma_fence_get(dma_resv_get_excl(old_resv));
+
+ if (old_resv != resv) {
+ ww_mutex_unlock(&old_resv->lock);
+ ww_mutex_lock(&resv->lock, NULL);
+ }
+
+ fence = dma_fence_get(dma_resv_get_excl(resv));
+ ww_mutex_unlock(&resv->lock);
+
+ nulldisp_crtc->flip_data = flip_data;
+ reinit_completion(&nulldisp_crtc->flip_scheduled);
+ atomic_set(&nulldisp_crtc->flip_status,
+ NULLDISP_CRTC_FLIP_STATUS_PENDING);
+
+ if (fence) {
+ err = dma_fence_add_callback(fence, &flip_data->base,
+ nulldisp_crtc_flip_schedule_cb);
+ dma_fence_put(fence);
+ if (err && err != -ENOENT)
+ goto err_set_flip_status_none;
+ }
+
+ if (!fence || err == -ENOENT) {
+ nulldisp_crtc_flip_schedule_cb(fence, &flip_data->base);
+ err = 0;
+ }
+
+ return err;
+
+err_set_flip_status_none:
+ atomic_set(&nulldisp_crtc->flip_status, NULLDISP_CRTC_FLIP_STATUS_NONE);
+ dma_fence_put(flip_data->wait_fence);
+ kfree(flip_data);
+ return err;
+}
+
+static int nulldisp_crtc_page_flip(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_pending_vblank_event *event,
+ uint32_t page_flip_flags
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
+ , struct drm_modeset_acquire_ctx *ctx
+#endif
+ )
+{
+ struct nulldisp_crtc *nulldisp_crtc = to_nulldisp_crtc(crtc);
+ struct nulldisp_framebuffer *nulldisp_fb = to_nulldisp_framebuffer(fb);
+ struct nulldisp_framebuffer *nulldisp_old_fb =
+ to_nulldisp_framebuffer(crtc->primary->fb);
+ enum nulldisp_crtc_flip_status status;
+ unsigned long flags;
+ int err;
+
+ spin_lock_irqsave(&crtc->dev->event_lock, flags);
+ status = atomic_read(&nulldisp_crtc->flip_status);
+ spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+
+ if (status != NULLDISP_CRTC_FLIP_STATUS_NONE)
+ return -EBUSY;
+
+ if (!(page_flip_flags & DRM_MODE_PAGE_FLIP_ASYNC)) {
+ err = drm_crtc_vblank_get(crtc);
+ if (err)
+ return err;
+ }
+
+ nulldisp_crtc->old_fb = crtc->primary->fb;
+ nulldisp_crtc->flip_event = event;
+ nulldisp_crtc->flip_async = !!(page_flip_flags &
+ DRM_MODE_PAGE_FLIP_ASYNC);
+
+ /* Set the crtc to point to the new framebuffer */
+ crtc->primary->fb = fb;
+
+ err = nulldisp_crtc_flip_schedule(crtc, nulldisp_fb->obj[0],
+ nulldisp_old_fb->obj[0]);
+ if (err) {
+ crtc->primary->fb = nulldisp_crtc->old_fb;
+ nulldisp_crtc->old_fb = NULL;
+ nulldisp_crtc->flip_event = NULL;
+ nulldisp_crtc->flip_async = false;
+
+ DRM_ERROR("failed to schedule flip (err=%d)\n", err);
+ goto err_vblank_put;
+ }
+
+ return 0;
+
+err_vblank_put:
+ if (!(page_flip_flags & DRM_MODE_PAGE_FLIP_ASYNC))
+ drm_crtc_vblank_put(crtc);
+ return err;
+}
+#endif /* !defined(NULLDISP_USE_ATOMIC) */
+
+static bool nulldisp_queue_vblank_work(struct nulldisp_crtc *nulldisp_crtc)
+{
+ struct drm_crtc *crtc = &nulldisp_crtc->base;
+ struct nulldisp_display_device *nulldisp_dev = crtc->dev->dev_private;
+ int vrefresh;
+ const int vrefresh_default = 60;
+
+ vrefresh = drm_mode_vrefresh(&crtc->hwmode);
+ if (!vrefresh) {
+ vrefresh = vrefresh_default;
+ DRM_INFO_ONCE(
+ "vertical refresh rate is zero, defaulting to %d\n",
+ vrefresh);
+ }
+
+ /* Returns false if work already queued, else true */
+ return queue_delayed_work(nulldisp_dev->workqueue,
+ &nulldisp_crtc->vb_work,
+ usecs_to_jiffies(1000000/vrefresh));
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
+static int nulldisp_enable_vblank(struct drm_crtc *crtc)
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) || \
+ (defined(CHROMIUMOS_KERNEL) && \
+ (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)))
+static int nulldisp_enable_vblank(struct drm_device *dev, unsigned int pipe)
+#else
+static int nulldisp_enable_vblank(struct drm_device *dev, int pipe)
+#endif
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
+ struct drm_device *dev = crtc->dev;
+ unsigned int pipe = drm_crtc_index(crtc);
+#endif
+
+ struct nulldisp_display_device *nulldisp_dev = dev->dev_private;
+
+ switch (pipe) {
+ case 0:
+ break;
+ default:
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+ DRM_ERROR("invalid crtc %u\n", pipe);
+#else
+ DRM_ERROR("invalid crtc %d\n", pipe);
+#endif
+ return -EINVAL;
+ }
+
+ if (!nulldisp_queue_vblank_work(nulldisp_dev->nulldisp_crtc)) {
+ DRM_ERROR("work already queued\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
+static void nulldisp_disable_vblank(struct drm_crtc *crtc)
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) || \
+ (defined(CHROMIUMOS_KERNEL) && \
+ (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)))
+static void nulldisp_disable_vblank(struct drm_device *dev, unsigned int pipe)
+#else
+static void nulldisp_disable_vblank(struct drm_device *dev, int pipe)
+#endif
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
+ struct drm_device *dev = crtc->dev;
+ unsigned int pipe = drm_crtc_index(crtc);
+#endif
+
+ struct nulldisp_display_device *nulldisp_dev = dev->dev_private;
+
+ switch (pipe) {
+ case 0:
+ break;
+ default:
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+ DRM_ERROR("invalid crtc %u\n", pipe);
+#else
+ DRM_ERROR("invalid crtc %d\n", pipe);
+#endif
+ return;
+ }
+
+ /*
+ * Vblank events may be disabled from within the vblank handler,
+ * so don't wait for the work to complete.
+ */
+ (void) cancel_delayed_work(&nulldisp_dev->nulldisp_crtc->vb_work);
+}
+
+static const struct drm_crtc_helper_funcs nulldisp_crtc_helper_funcs = {
+ .mode_fixup = nulldisp_crtc_helper_mode_fixup,
+#if defined(NULLDISP_USE_ATOMIC)
+ .mode_set_nofb = nulldisp_crtc_helper_mode_set_nofb,
+ .atomic_flush = nulldisp_crtc_helper_atomic_flush,
+ .atomic_enable = nulldisp_crtc_helper_atomic_enable,
+ .atomic_disable = nulldisp_crtc_helper_atomic_disable,
+#else
+ .dpms = nulldisp_crtc_helper_dpms,
+ .prepare = nulldisp_crtc_helper_prepare,
+ .commit = nulldisp_crtc_helper_commit,
+ .mode_set = nulldisp_crtc_helper_mode_set,
+ .mode_set_base = nulldisp_crtc_helper_mode_set_base,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
+ .load_lut = nulldisp_crtc_helper_load_lut,
+#endif
+ .mode_set_base_atomic = nulldisp_crtc_helper_mode_set_base_atomic,
+ .disable = nulldisp_crtc_helper_disable,
+#endif /* defined(NULLDISP_USE_ATOMIC) */
+};
+
+static const struct drm_crtc_funcs nulldisp_crtc_funcs = {
+ .destroy = nulldisp_crtc_destroy,
+#if defined(NULLDISP_USE_ATOMIC)
+ .reset = drm_atomic_helper_crtc_reset,
+ .set_config = drm_atomic_helper_set_config,
+ .page_flip = drm_atomic_helper_page_flip,
+ .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
+#else
+ .reset = NULL,
+ .cursor_set = NULL,
+ .cursor_move = NULL,
+ .gamma_set = NULL,
+ .set_config = drm_crtc_helper_set_config,
+ .page_flip = nulldisp_crtc_page_flip,
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
+ .enable_vblank = nulldisp_enable_vblank,
+ .disable_vblank = nulldisp_disable_vblank,
+#endif
+};
+
+static void nulldisp_handle_vblank(struct work_struct *w)
+{
+ struct delayed_work *dw =
+ container_of(w, struct delayed_work, work);
+ struct nulldisp_crtc *nulldisp_crtc =
+ container_of(dw, struct nulldisp_crtc, vb_work);
+ struct drm_crtc *crtc = &nulldisp_crtc->base;
+ struct drm_device *dev = crtc->dev;
+ enum nulldisp_crtc_flip_status status;
+
+ /*
+ * Reschedule the handler, if necessary. This is done before
+ * calling drm_crtc_vblank_put, so that the work can be cancelled
+ * if vblank events are disabled.
+ */
+ if (drm_handle_vblank(dev, 0))
+ (void) nulldisp_queue_vblank_work(nulldisp_crtc);
+
+ status = atomic_read(&nulldisp_crtc->flip_status);
+ if (status == NULLDISP_CRTC_FLIP_STATUS_DONE) {
+ if (!nulldisp_crtc->flip_async)
+ nulldisp_crtc_flip_complete(crtc);
+#if !defined(NULLDISP_USE_ATOMIC)
+ drm_crtc_vblank_put(crtc);
+#endif
+ }
+
+}
+
+static struct nulldisp_crtc *
+nulldisp_crtc_create(struct nulldisp_display_device *nulldisp_dev)
+{
+ struct nulldisp_crtc *nulldisp_crtc;
+ struct drm_crtc *crtc;
+ struct drm_plane *primary;
+
+ nulldisp_crtc = kzalloc(sizeof(*nulldisp_crtc), GFP_KERNEL);
+ if (!nulldisp_crtc)
+ goto err_return;
+
+ primary = kzalloc(sizeof(*primary), GFP_KERNEL);
+ if (!primary)
+ goto err_free_crtc;
+
+ crtc = &nulldisp_crtc->base;
+
+ atomic_set(&nulldisp_crtc->flip_status, NULLDISP_CRTC_FLIP_STATUS_NONE);
+#if defined(NULLDISP_USE_ATOMIC)
+ init_completion(&nulldisp_crtc->flip_done);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0))
+ init_completion(&nulldisp_crtc->copy_done);
+#endif
+#else
+ init_completion(&nulldisp_crtc->flip_scheduled);
+ init_completion(&nulldisp_crtc->copy_done);
+#endif
+
+ if (drm_universal_plane_init(nulldisp_dev->dev, primary, 0,
+ &nulldisp_plane_funcs,
+ nulldisp_modeset_formats,
+ ARRAY_SIZE(nulldisp_modeset_formats),
+ nulldisp_primary_plane_modifiers,
+ DRM_PLANE_TYPE_PRIMARY, NULL)) {
+ goto err_free_primary;
+ }
+
+#if defined(NULLDISP_USE_ATOMIC)
+ drm_plane_helper_add(primary, &nulldisp_plane_helper_funcs);
+#endif
+
+ if (drm_crtc_init_with_planes(nulldisp_dev->dev, crtc, primary,
+ NULL, &nulldisp_crtc_funcs, NULL)) {
+ goto err_cleanup_plane;
+ }
+
+ drm_crtc_helper_add(crtc, &nulldisp_crtc_helper_funcs);
+
+ INIT_DELAYED_WORK(&nulldisp_crtc->vb_work, nulldisp_handle_vblank);
+#if !defined(NULLDISP_USE_ATOMIC)
+ INIT_WORK(&nulldisp_crtc->flip_work, nulldisp_flip_work);
+ INIT_DELAYED_WORK(&nulldisp_crtc->copy_to_work, nulldisp_copy_to_work);
+ INIT_DELAYED_WORK(&nulldisp_crtc->flip_to_work, nulldisp_flip_to_work);
+#endif
+
+ DRM_DEBUG_DRIVER("[CRTC:%d]\n", crtc->base.id);
+
+ return nulldisp_crtc;
+
+err_cleanup_plane:
+ drm_plane_cleanup(primary);
+err_free_primary:
+ kfree(primary);
+err_free_crtc:
+ kfree(nulldisp_crtc);
+err_return:
+ return NULL;
+}
+
+
+/******************************************************************************
+ * Connector functions
+ ******************************************************************************/
+
+static int
+nulldisp_validate_module_parameters(void)
+{
+ const struct nulldisp_module_params *module_params =
+ nulldisp_get_module_params();
+
+ if (!module_params->hdisplay ||
+ !module_params->vdisplay ||
+ !module_params->vrefresh ||
+ (module_params->hdisplay > NULLDISP_FB_WIDTH_MAX) ||
+ (module_params->vdisplay > NULLDISP_FB_HEIGHT_MAX))
+ return -EINVAL;
+
+ return 0;
+}
+
+static bool
+nulldisp_set_preferred_mode(struct drm_connector *connector,
+ uint32_t hdisplay,
+ uint32_t vdisplay,
+ uint32_t vrefresh)
+{
+ struct drm_display_mode *mode;
+
+ /*
+ * Mark the first mode, matching the hdisplay, vdisplay and
+ * vrefresh, preferred.
+ */
+ list_for_each_entry(mode, &connector->probed_modes, head)
+ if (mode->hdisplay == hdisplay &&
+ mode->vdisplay == vdisplay &&
+ drm_mode_vrefresh(mode) == vrefresh) {
+ mode->type |= DRM_MODE_TYPE_PREFERRED;
+ return true;
+ }
+
+ return false;
+}
+
+static bool
+nulldisp_connector_add_preferred_mode(struct drm_connector *connector,
+ uint32_t hdisplay,
+ uint32_t vdisplay,
+ uint32_t vrefresh)
+{
+ struct drm_display_mode *preferred_mode;
+
+ preferred_mode = drm_cvt_mode(connector->dev,
+ hdisplay, vdisplay, vrefresh,
+ false, false, false);
+ if (!preferred_mode) {
+ DRM_DEBUG_DRIVER("[CONNECTOR:%s]:create mode %dx%d@%d failed\n",
+ connector->name,
+ hdisplay,
+ vdisplay,
+ vrefresh);
+
+ return false;
+ }
+
+ preferred_mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
+
+ drm_mode_probed_add(connector, preferred_mode);
+
+ return true;
+}
+
+/*
+ * Gather modes. Here we can get the EDID data from the monitor and
+ * turn it into drm_display_mode structures.
+ */
+static int
+nulldisp_connector_helper_get_modes(struct drm_connector *connector)
+{
+ int modes_count;
+ struct drm_device *dev = connector->dev;
+ const struct nulldisp_module_params *module_params =
+ nulldisp_get_module_params();
+ uint32_t hdisplay = module_params->hdisplay;
+ uint32_t vdisplay = module_params->vdisplay;
+ uint32_t vrefresh = module_params->vrefresh;
+
+ /* Add common modes */
+ modes_count = drm_add_modes_noedid(connector,
+ dev->mode_config.max_width,
+ dev->mode_config.max_height);
+
+ /*
+ * Check if any of the connector modes match the preferred mode
+ * criteria specified by the module parameters. If the mode is
+ * found - flag it as preferred. Otherwise create the preferred
+ * mode based on the module parameters criteria, and flag it as
+ * preferred.
+ */
+ if (!nulldisp_set_preferred_mode(connector,
+ hdisplay,
+ vdisplay,
+ vrefresh))
+ if (nulldisp_connector_add_preferred_mode(connector,
+ hdisplay,
+ vdisplay,
+ vrefresh))
+ modes_count++;
+
+ /* Sort the connector modes by relevance */
+ drm_mode_sort(&connector->probed_modes);
+
+ return modes_count;
+}
+
+static int
+nulldisp_connector_helper_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ /*
+ * This function is called on each gathered mode (e.g. via EDID)
+ * and gives the driver a chance to reject it if the hardware
+ * cannot support it.
+ */
+ return MODE_OK;
+}
+
+#if !defined(NULLDISP_USE_ATOMIC)
+static struct drm_encoder *
+nulldisp_connector_helper_best_encoder(struct drm_connector *connector)
+{
+ /* Pick the first encoder we find */
+ if (connector->encoder_ids[0] != 0) {
+ struct drm_encoder *encoder;
+
+ encoder = drm_encoder_find(connector->dev,
+ NULL,
+ connector->encoder_ids[0]);
+ if (encoder) {
+ DRM_DEBUG_DRIVER(
+ "[ENCODER:%d:%s] best for [CONNECTOR:%d:%s]\n",
+ encoder->base.id,
+ encoder->name,
+ connector->base.id,
+ connector->name);
+ return encoder;
+ }
+ }
+
+ return NULL;
+}
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0))
+static enum drm_connector_status
+nulldisp_connector_detect(struct drm_connector *connector,
+ bool force)
+{
+ /* Return whether or not a monitor is attached to the connector */
+ return connector_status_connected;
+}
+#endif
+
+static void nulldisp_connector_destroy(struct drm_connector *connector)
+{
+ DRM_DEBUG_DRIVER("[CONNECTOR:%d:%s]\n",
+ connector->base.id,
+ connector->name);
+
+ drm_connector_update_edid_property(connector, NULL);
+ drm_connector_cleanup(connector);
+
+ kfree(connector);
+}
+
+static void nulldisp_connector_force(struct drm_connector *connector)
+{
+}
+
+static const struct drm_connector_helper_funcs
+nulldisp_connector_helper_funcs = {
+ .get_modes = nulldisp_connector_helper_get_modes,
+ .mode_valid = nulldisp_connector_helper_mode_valid,
+ /*
+ * For atomic, don't set atomic_best_encoder or best_encoder. This will
+ * cause the DRM core to fallback to drm_atomic_helper_best_encoder().
+ * This is fine as we only have a single connector and encoder.
+ */
+#if !defined(NULLDISP_USE_ATOMIC)
+ .best_encoder = nulldisp_connector_helper_best_encoder,
+#endif
+};
+
+static const struct drm_connector_funcs nulldisp_connector_funcs = {
+#if defined(NULLDISP_USE_ATOMIC)
+ .reset = drm_atomic_helper_connector_reset,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+#else
+ .dpms = drm_helper_connector_dpms,
+ .reset = NULL,
+#endif
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0))
+ .detect = nulldisp_connector_detect,
+#endif
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = nulldisp_connector_destroy,
+ .force = nulldisp_connector_force,
+};
+
+static struct drm_connector *
+nulldisp_connector_create(struct nulldisp_display_device *nulldisp_dev,
+ int type)
+{
+ struct drm_connector *connector;
+
+ connector = kzalloc(sizeof(*connector), GFP_KERNEL);
+ if (!connector)
+ return NULL;
+
+ drm_connector_init(nulldisp_dev->dev,
+ connector,
+ &nulldisp_connector_funcs,
+ type);
+ drm_connector_helper_add(connector, &nulldisp_connector_helper_funcs);
+
+ connector->dpms = DRM_MODE_DPMS_OFF;
+ connector->interlace_allowed = false;
+ connector->doublescan_allowed = false;
+ connector->display_info.subpixel_order = SubPixelUnknown;
+
+ DRM_DEBUG_DRIVER("[CONNECTOR:%d:%s]\n",
+ connector->base.id,
+ connector->name);
+
+ return connector;
+}
+
+
+/******************************************************************************
+ * Encoder functions
+ ******************************************************************************/
+
+static void nulldisp_encoder_helper_dpms(struct drm_encoder *encoder,
+ int mode)
+{
+ /*
+ * Set the display power state or active encoder based on the mode. If
+ * the mode passed in is unsupported, the provider must use the next
+ * lowest power level.
+ */
+}
+
+static bool
+nulldisp_encoder_helper_mode_fixup(struct drm_encoder *encoder,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ /*
+ * Fix up mode so that it's compatible with the hardware. The results
+ * should be stored in adjusted_mode (i.e. mode should be untouched).
+ */
+ return true;
+}
+
+static void nulldisp_encoder_helper_prepare(struct drm_encoder *encoder)
+{
+ /*
+ * Prepare the encoder for a mode change e.g. set the active encoder
+ * accordingly/turn the encoder off
+ */
+}
+
+static void nulldisp_encoder_helper_commit(struct drm_encoder *encoder)
+{
+ /* Turn the encoder back on/set the active encoder */
+}
+
+static void
+nulldisp_encoder_helper_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ /* Setup the encoder for the new mode */
+}
+
+static void nulldisp_encoder_destroy(struct drm_encoder *encoder)
+{
+ DRM_DEBUG_DRIVER("[ENCODER:%d:%s]\n", encoder->base.id, encoder->name);
+
+ drm_encoder_cleanup(encoder);
+ kfree(encoder);
+}
+
+static const struct drm_encoder_helper_funcs nulldisp_encoder_helper_funcs = {
+ .dpms = nulldisp_encoder_helper_dpms,
+ .mode_fixup = nulldisp_encoder_helper_mode_fixup,
+ .prepare = nulldisp_encoder_helper_prepare,
+ .commit = nulldisp_encoder_helper_commit,
+ .mode_set = nulldisp_encoder_helper_mode_set,
+ .detect = NULL,
+ .disable = NULL,
+};
+
+static const struct drm_encoder_funcs nulldisp_encoder_funcs = {
+ .reset = NULL,
+ .destroy = nulldisp_encoder_destroy,
+};
+
+static struct drm_encoder *
+nulldisp_encoder_create(struct nulldisp_display_device *nulldisp_dev,
+ int type)
+{
+ struct drm_encoder *encoder;
+ int err;
+
+ encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
+ if (!encoder)
+ return ERR_PTR(-ENOMEM);
+
+ err = drm_encoder_init(nulldisp_dev->dev,
+ encoder,
+ &nulldisp_encoder_funcs,
+ type,
+ NULL);
+ if (err) {
+ DRM_ERROR("Failed to initialise encoder\n");
+ return ERR_PTR(err);
+ }
+ drm_encoder_helper_add(encoder, &nulldisp_encoder_helper_funcs);
+
+ /*
+ * This is a bit field that's used to determine which
+ * CRTCs can drive this encoder.
+ */
+ encoder->possible_crtcs = 0x1;
+
+ DRM_DEBUG_DRIVER("[ENCODER:%d:%s]\n", encoder->base.id, encoder->name);
+
+ return encoder;
+}
+
+
+/******************************************************************************
+ * Framebuffer functions
+ ******************************************************************************/
+
+#if defined(NULLDISP_USE_ATOMIC)
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0))
+static int
+nulldisp_framebuffer_dirty(struct drm_framebuffer *framebuffer,
+ struct drm_file *file_priv,
+ unsigned int flags,
+ unsigned int color,
+ struct drm_clip_rect *clips,
+ unsigned int num_clips)
+{
+ struct nulldisp_display_device *nulldisp_dev =
+ framebuffer->dev->dev_private;
+ struct nulldisp_crtc *nulldisp_crtc = nulldisp_dev->nulldisp_crtc;
+
+ reinit_completion(&nulldisp_crtc->copy_done);
+
+ if (!nlpvrdpy_send_copy(nulldisp_dev->nlpvrdpy,
+ framebuffer,
+ &framebuffer->obj[0])) {
+ unsigned long res;
+
+ res = wait_for_completion_timeout(&nulldisp_crtc->copy_done,
+ nulldisp_netlink_timeout());
+
+ if (!res)
+ DRM_ERROR("timed out waiting for remote update\n");
+ }
+
+ return 0;
+}
+
+static const struct drm_framebuffer_funcs nulldisp_framebuffer_funcs = {
+ .destroy = drm_gem_fb_destroy,
+ .create_handle = drm_gem_fb_create_handle,
+ .dirty = nulldisp_framebuffer_dirty,
+};
+
+static struct drm_framebuffer *
+nulldisp_fb_create(struct drm_device *dev, struct drm_file *file,
+ const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+ return drm_gem_fb_create_with_funcs(dev, file, mode_cmd,
+ &nulldisp_framebuffer_funcs);
+}
+#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0)) */
+#define nulldisp_fb_create drm_gem_fb_create_with_dirty
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0)) */
+#else /* defined(NULLDISP_USE_ATOMIC) */
+static void nulldisp_framebuffer_destroy(struct drm_framebuffer *framebuffer)
+{
+ struct nulldisp_framebuffer *nulldisp_framebuffer =
+ to_nulldisp_framebuffer(framebuffer);
+ int i;
+
+ DRM_DEBUG_DRIVER("[FB:%d]\n", framebuffer->base.id);
+
+ drm_framebuffer_cleanup(framebuffer);
+
+ for (i = 0; i < nulldisp_drm_fb_num_planes(framebuffer); i++)
+ drm_gem_object_put(nulldisp_framebuffer->obj[i]);
+
+ kfree(nulldisp_framebuffer);
+}
+
+static int
+nulldisp_framebuffer_create_handle(struct drm_framebuffer *framebuffer,
+ struct drm_file *file_priv,
+ unsigned int *handle)
+{
+ struct nulldisp_framebuffer *nulldisp_framebuffer =
+ to_nulldisp_framebuffer(framebuffer);
+
+ DRM_DEBUG_DRIVER("[FB:%d]\n", framebuffer->base.id);
+
+ return drm_gem_handle_create(file_priv,
+ nulldisp_framebuffer->obj[0],
+ handle);
+}
+
+static int
+nulldisp_framebuffer_dirty(struct drm_framebuffer *framebuffer,
+ struct drm_file *file_priv,
+ unsigned int flags,
+ unsigned int color,
+ struct drm_clip_rect *clips,
+ unsigned int num_clips)
+{
+ struct nulldisp_framebuffer *nulldisp_fb =
+ to_nulldisp_framebuffer(framebuffer);
+ struct nulldisp_display_device *nulldisp_dev =
+ framebuffer->dev->dev_private;
+ struct nulldisp_crtc *nulldisp_crtc = nulldisp_dev->nulldisp_crtc;
+
+ /*
+ * To prevent races with disconnect requests from user space,
+ * set the timeout before sending the copy request.
+ */
+ nulldisp_set_copy_to(nulldisp_crtc);
+
+ if (nlpvrdpy_send_copy(nulldisp_dev->nlpvrdpy,
+ &nulldisp_fb->base,
+ &nulldisp_fb->obj[0]))
+ goto fail_flush;
+
+ wait_for_completion(&nulldisp_crtc->copy_done);
+
+ return 0;
+
+fail_flush:
+ flush_delayed_work(&nulldisp_crtc->copy_to_work);
+
+ wait_for_completion(&nulldisp_crtc->copy_done);
+
+ return 0;
+
+}
+
+static const struct drm_framebuffer_funcs nulldisp_framebuffer_funcs = {
+ .destroy = nulldisp_framebuffer_destroy,
+ .create_handle = nulldisp_framebuffer_create_handle,
+ .dirty = nulldisp_framebuffer_dirty,
+};
+
+static int
+nulldisp_framebuffer_init(struct drm_device *dev,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) || \
+ (defined(CHROMIUMOS_KERNEL) && \
+ (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)))
+ const
+#endif
+ struct drm_mode_fb_cmd2 *mode_cmd,
+ struct nulldisp_framebuffer *nulldisp_framebuffer,
+ struct drm_gem_object **obj)
+{
+ struct drm_framebuffer *fb = &nulldisp_framebuffer->base;
+ int err;
+ int i;
+
+ fb->dev = dev;
+
+ nulldisp_drm_fb_set_format(fb, mode_cmd->pixel_format);
+
+ fb->width = mode_cmd->width;
+ fb->height = mode_cmd->height;
+ fb->flags = mode_cmd->flags;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
+ nulldisp_drm_fb_set_modifier(fb, mode_cmd->modifier[0]);
+#endif
+
+ for (i = 0; i < nulldisp_drm_fb_num_planes(fb); i++) {
+ fb->pitches[i] = mode_cmd->pitches[i];
+ fb->offsets[i] = mode_cmd->offsets[i];
+
+ nulldisp_framebuffer->obj[i] = obj[i];
+ }
+
+ err = drm_framebuffer_init(dev, fb, &nulldisp_framebuffer_funcs);
+ if (err) {
+ DRM_ERROR("failed to initialise framebuffer structure (%d)\n",
+ err);
+ return err;
+ }
+
+ DRM_DEBUG_DRIVER("[FB:%d]\n", fb->base.id);
+
+ return 0;
+}
+
+static struct drm_framebuffer *
+nulldisp_fb_create(struct drm_device *dev,
+ struct drm_file *file_priv,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) || \
+ (defined(CHROMIUMOS_KERNEL) && \
+ (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)))
+ const
+#endif
+ struct drm_mode_fb_cmd2 *mode_cmd)
+{
+ struct drm_gem_object *obj[NULLDISP_MAX_PLANES];
+ struct nulldisp_framebuffer *nulldisp_framebuffer;
+ int err;
+ int i;
+
+ nulldisp_framebuffer = kzalloc(sizeof(*nulldisp_framebuffer),
+ GFP_KERNEL);
+ if (!nulldisp_framebuffer) {
+ err = -ENOMEM;
+ goto fail_exit;
+ }
+
+ for (i = 0; i < drm_format_num_planes(mode_cmd->pixel_format); i++) {
+ obj[i] = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]);
+ if (!obj[i]) {
+ DRM_ERROR("failed to find buffer with handle %u\n",
+ mode_cmd->handles[i]);
+ err = -ENOENT;
+ goto fail_unreference;
+ }
+ }
+
+ err = nulldisp_framebuffer_init(dev,
+ mode_cmd,
+ nulldisp_framebuffer,
+ obj);
+ if (err)
+ goto fail_unreference;
+
+ DRM_DEBUG_DRIVER("[FB:%d]\n", nulldisp_framebuffer->base.base.id);
+
+ return &nulldisp_framebuffer->base;
+
+fail_unreference:
+ kfree(nulldisp_framebuffer);
+
+ while (i--)
+ drm_gem_object_put(obj[i]);
+
+fail_exit:
+ return ERR_PTR(err);
+}
+#endif /* defined(NULLDISP_USE_ATOMIC) */
+
+static const struct drm_mode_config_funcs nulldisp_mode_config_funcs = {
+ .fb_create = nulldisp_fb_create,
+ .output_poll_changed = NULL,
+#if defined(NULLDISP_USE_ATOMIC)
+ .atomic_check = drm_atomic_helper_check,
+ .atomic_commit = drm_atomic_helper_commit,
+#endif
+};
+
+static int nulldisp_nl_flipped_cb(void *data)
+{
+ struct nulldisp_crtc *nulldisp_crtc = data;
+
+#if defined(NULLDISP_USE_ATOMIC)
+ complete(&nulldisp_crtc->flip_done);
+#else
+ flush_delayed_work(&nulldisp_crtc->flip_to_work);
+#endif
+ flush_delayed_work(&nulldisp_crtc->vb_work);
+
+ return 0;
+}
+
+static int nulldisp_nl_copied_cb(void *data)
+{
+#if defined(NULLDISP_USE_ATOMIC)
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0))
+ struct nulldisp_crtc *nulldisp_crtc = data;
+
+ complete(&nulldisp_crtc->copy_done);
+#endif
+#else
+ struct nulldisp_crtc *nulldisp_crtc = data;
+
+ flush_delayed_work(&nulldisp_crtc->copy_to_work);
+#endif
+ return 0;
+}
+
+static void nulldisp_nl_disconnect_cb(void *data)
+{
+ struct nulldisp_crtc *nulldisp_crtc = data;
+
+#if defined(NULLDISP_USE_ATOMIC)
+ complete(&nulldisp_crtc->flip_done);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0))
+ complete(&nulldisp_crtc->copy_done);
+#endif
+#else
+ flush_delayed_work(&nulldisp_crtc->flip_to_work);
+ flush_delayed_work(&nulldisp_crtc->copy_to_work);
+#endif
+}
+
+static int nulldisp_early_load(struct drm_device *dev)
+{
+ struct nulldisp_display_device *nulldisp_dev;
+ struct drm_connector *connector;
+ struct drm_encoder *encoder;
+ int err;
+
+ platform_set_drvdata(to_platform_device(dev->dev), dev);
+
+ nulldisp_dev = kzalloc(sizeof(*nulldisp_dev), GFP_KERNEL);
+ if (!nulldisp_dev)
+ return -ENOMEM;
+
+ dev->dev_private = nulldisp_dev;
+ nulldisp_dev->dev = dev;
+
+ drm_mode_config_init(dev);
+
+ dev->mode_config.funcs = (void *)&nulldisp_mode_config_funcs;
+ dev->mode_config.min_width = NULLDISP_FB_WIDTH_MIN;
+ dev->mode_config.max_width = NULLDISP_FB_WIDTH_MAX;
+ dev->mode_config.min_height = NULLDISP_FB_HEIGHT_MIN;
+ dev->mode_config.max_height = NULLDISP_FB_HEIGHT_MAX;
+ dev->mode_config.fb_base = 0;
+ dev->mode_config.async_page_flip = true;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
+ dev->mode_config.allow_fb_modifiers = true;
+#endif
+
+ nulldisp_dev->nulldisp_crtc = nulldisp_crtc_create(nulldisp_dev);
+ if (!nulldisp_dev->nulldisp_crtc) {
+ DRM_ERROR("failed to create a CRTC.\n");
+
+ err = -ENOMEM;
+ goto err_config_cleanup;
+ }
+
+ connector = nulldisp_connector_create(nulldisp_dev,
+ DRM_MODE_CONNECTOR_Unknown);
+ if (!connector) {
+ DRM_ERROR("failed to create a connector.\n");
+
+ err = -ENOMEM;
+ goto err_config_cleanup;
+ }
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0))
+ nulldisp_dev->connector = connector;
+#endif
+ encoder = nulldisp_encoder_create(nulldisp_dev,
+ DRM_MODE_ENCODER_NONE);
+ if (IS_ERR(encoder)) {
+ DRM_ERROR("failed to create an encoder.\n");
+
+ err = PTR_ERR(encoder);
+ goto err_config_cleanup;
+ }
+
+ err = drm_connector_attach_encoder(connector, encoder);
+ if (err) {
+ DRM_ERROR("failed to attach [ENCODER:%d:%s] to [CONNECTOR:%d:%s] (err=%d)\n",
+ encoder->base.id,
+ encoder->name,
+ connector->base.id,
+ connector->name,
+ err);
+ goto err_config_cleanup;
+ }
+
+#if defined(LMA)
+ nulldisp_dev->pdp_gem_priv = pdp_gem_init(dev);
+ if (!nulldisp_dev->pdp_gem_priv) {
+ err = -ENOMEM;
+ goto err_config_cleanup;
+ }
+#endif
+ nulldisp_dev->workqueue =
+ create_singlethread_workqueue(DRIVER_NAME);
+ if (!nulldisp_dev->workqueue) {
+ DRM_ERROR("failed to create work queue\n");
+ goto err_gem_cleanup;
+ }
+
+ err = drm_vblank_init(nulldisp_dev->dev, 1);
+ if (err) {
+ DRM_ERROR("failed to complete vblank init (err=%d)\n", err);
+ goto err_workqueue_cleanup;
+ }
+
+ dev->irq_enabled = true;
+
+ nulldisp_dev->nlpvrdpy = nlpvrdpy_create(dev,
+ nulldisp_nl_disconnect_cb,
+ nulldisp_dev->nulldisp_crtc,
+ nulldisp_nl_flipped_cb,
+ nulldisp_dev->nulldisp_crtc,
+ nulldisp_nl_copied_cb,
+ nulldisp_dev->nulldisp_crtc);
+ if (!nulldisp_dev->nlpvrdpy) {
+ DRM_ERROR("Netlink initialisation failed (err=%d)\n", err);
+ goto err_vblank_cleanup;
+ }
+
+ return 0;
+
+err_vblank_cleanup:
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
+ /* Called by drm_dev_fini in Linux 4.11.0 and later */
+ drm_vblank_cleanup(dev);
+#endif
+err_workqueue_cleanup:
+ destroy_workqueue(nulldisp_dev->workqueue);
+ dev->irq_enabled = false;
+err_gem_cleanup:
+#if defined(LMA)
+ pdp_gem_cleanup(nulldisp_dev->pdp_gem_priv);
+#endif
+err_config_cleanup:
+ drm_mode_config_cleanup(dev);
+ kfree(nulldisp_dev);
+ return err;
+}
+
+static int nulldisp_late_load(struct drm_device *dev)
+{
+ drm_mode_config_reset(dev);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0))
+ {
+ struct nulldisp_display_device *nulldisp_dev = dev->dev_private;
+ int err;
+
+ err = drm_connector_register(nulldisp_dev->connector);
+ if (err) {
+ DRM_ERROR(
+ "[CONNECTOR:%d:%s] failed to register (err=%d)\n",
+ nulldisp_dev->connector->base.id,
+ nulldisp_dev->connector->name,
+ err);
+ return err;
+ }
+ }
+#endif
+ return 0;
+}
+
+static void nulldisp_early_unload(struct drm_device *dev)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0))
+ struct nulldisp_display_device *nulldisp_dev = dev->dev_private;
+
+ drm_connector_unregister(nulldisp_dev->connector);
+#endif
+}
+
+static void nulldisp_late_unload(struct drm_device *dev)
+{
+ struct nulldisp_display_device *nulldisp_dev = dev->dev_private;
+
+ nlpvrdpy_send_disconnect(nulldisp_dev->nlpvrdpy);
+ nlpvrdpy_destroy(nulldisp_dev->nlpvrdpy);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
+ /* Called by drm_dev_fini in Linux 4.11.0 and later */
+ drm_vblank_cleanup(dev);
+#endif
+ destroy_workqueue(nulldisp_dev->workqueue);
+
+ dev->irq_enabled = false;
+
+#if defined(LMA)
+ pdp_gem_cleanup(nulldisp_dev->pdp_gem_priv);
+#endif
+ drm_mode_config_cleanup(dev);
+
+ kfree(nulldisp_dev);
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0))
+static int nulldisp_load(struct drm_device *dev, unsigned long flags)
+{
+ int err;
+
+ err = nulldisp_early_load(dev);
+ if (err)
+ return err;
+
+ err = nulldisp_late_load(dev);
+ if (err) {
+ nulldisp_late_unload(dev);
+ return err;
+ }
+
+ return 0;
+}
+
+static int nulldisp_unload(struct drm_device *dev)
+{
+ nulldisp_early_unload(dev);
+ nulldisp_late_unload(dev);
+
+ return 0;
+}
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0))
+static void
+nulldisp_crtc_flip_event_cancel(struct drm_crtc *crtc, struct drm_file *file)
+{
+ struct nulldisp_crtc *nulldisp_crtc = to_nulldisp_crtc(crtc);
+ unsigned long flags;
+
+ spin_lock_irqsave(&crtc->dev->event_lock, flags);
+
+ if (nulldisp_crtc->flip_event &&
+ nulldisp_crtc->flip_event->base.file_priv == file) {
+ struct drm_pending_event *pending_event =
+ &nulldisp_crtc->flip_event->base;
+
+ pending_event->destroy(pending_event);
+ nulldisp_crtc->flip_event = NULL;
+ }
+
+ spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+}
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0))
+static void nulldisp_preclose(struct drm_device *dev, struct drm_file *file)
+{
+ struct drm_crtc *crtc;
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+ nulldisp_crtc_flip_event_cancel(crtc, file);
+}
+#endif
+
+static void nulldisp_lastclose(struct drm_device *dev)
+{
+#if defined(NULLDISP_USE_ATOMIC)
+ drm_atomic_helper_shutdown(dev);
+#else
+ struct drm_crtc *crtc;
+
+ drm_modeset_lock_all(dev);
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ if (crtc->primary->fb) {
+ struct drm_mode_set mode_set = { .crtc = crtc };
+ int err;
+
+ err = drm_mode_set_config_internal(&mode_set);
+ if (err)
+ DRM_ERROR(
+ "failed to disable crtc %p (err=%d)\n",
+ crtc, err);
+ }
+ }
+ drm_modeset_unlock_all(dev);
+#endif
+}
+
+static const struct vm_operations_struct nulldisp_gem_vm_ops = {
+#if defined(LMA)
+ .fault = pdp_gem_object_vm_fault,
+ .open = drm_gem_vm_open,
+ .close = drm_gem_vm_close,
+#else
+ .fault = nulldisp_gem_object_vm_fault,
+ .open = nulldisp_gem_vm_open,
+ .close = nulldisp_gem_vm_close,
+#endif
+};
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0))
+const struct drm_gem_object_funcs nulldisp_gem_funcs = {
+#if defined(LMA)
+ .free = pdp_gem_object_free,
+ .export = pdp_gem_prime_export,
+#else
+ .export = drm_gem_prime_export,
+ .pin = nulldisp_gem_prime_pin,
+ .unpin = nulldisp_gem_prime_unpin,
+ .get_sg_table = nulldisp_gem_prime_get_sg_table,
+ .vmap = nulldisp_gem_prime_vmap,
+ .vunmap = nulldisp_gem_prime_vunmap,
+ .free = nulldisp_gem_object_free,
+#endif /* defined(LMA) */
+ .vm_ops = &nulldisp_gem_vm_ops,
+};
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) */
+
+#if defined(LMA)
+static int pdp_gem_dumb_create(struct drm_file *file,
+ struct drm_device *dev,
+ struct drm_mode_create_dumb *args)
+{
+ struct nulldisp_display_device *nulldisp_dev = dev->dev_private;
+
+ return pdp_gem_dumb_create_priv(file,
+ dev,
+ nulldisp_dev->pdp_gem_priv,
+ args);
+}
+
+static int nulldisp_gem_object_create_ioctl(struct drm_device *dev,
+ void *data,
+ struct drm_file *file)
+{
+ struct drm_nulldisp_gem_create *args = data;
+ struct nulldisp_display_device *nulldisp_dev = dev->dev_private;
+ struct drm_pdp_gem_create pdp_args;
+ int err;
+
+ if (args->flags) {
+ DRM_ERROR("invalid flags: %#08x\n", args->flags);
+ return -EINVAL;
+ }
+
+ if (args->handle) {
+ DRM_ERROR("invalid handle (this should always be 0)\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Remapping of nulldisp create args to pdp create args.
+ *
+ * Note: even though the nulldisp and pdp args are identical
+ * in this case, they may potentially change in future.
+ */
+ pdp_args.size = args->size;
+ pdp_args.flags = args->flags;
+ pdp_args.handle = args->handle;
+
+ err = pdp_gem_object_create_ioctl_priv(dev,
+ nulldisp_dev->pdp_gem_priv,
+ &pdp_args,
+ file);
+ if (!err)
+ args->handle = pdp_args.handle;
+
+ return err;
+}
+
+static int nulldisp_gem_object_mmap_ioctl(struct drm_device *dev,
+ void *data,
+ struct drm_file *file)
+{
+ struct drm_nulldisp_gem_mmap *args = data;
+ struct drm_pdp_gem_mmap pdp_args;
+ int err;
+
+ pdp_args.handle = args->handle;
+ pdp_args.pad = args->pad;
+ pdp_args.offset = args->offset;
+
+ err = pdp_gem_object_mmap_ioctl(dev, &pdp_args, file);
+
+ if (!err)
+ args->offset = pdp_args.offset;
+
+ return err;
+}
+
+static int nulldisp_gem_object_cpu_prep_ioctl(struct drm_device *dev,
+ void *data,
+ struct drm_file *file)
+{
+ struct drm_nulldisp_gem_cpu_prep *args =
+ (struct drm_nulldisp_gem_cpu_prep *)data;
+ struct drm_pdp_gem_cpu_prep pdp_args;
+
+ pdp_args.handle = args->handle;
+ pdp_args.flags = args->flags;
+
+ return pdp_gem_object_cpu_prep_ioctl(dev, &pdp_args, file);
+}
+
+static int nulldisp_gem_object_cpu_fini_ioctl(struct drm_device *dev,
+ void *data,
+ struct drm_file *file)
+{
+ struct drm_nulldisp_gem_cpu_fini *args =
+ (struct drm_nulldisp_gem_cpu_fini *)data;
+ struct drm_pdp_gem_cpu_fini pdp_args;
+
+ pdp_args.handle = args->handle;
+ pdp_args.pad = args->pad;
+
+ return pdp_gem_object_cpu_fini_ioctl(dev, &pdp_args, file);
+}
+
+static void pdp_gem_object_free(struct drm_gem_object *obj)
+{
+ struct nulldisp_display_device *nulldisp_dev = obj->dev->dev_private;
+
+ pdp_gem_object_free_priv(nulldisp_dev->pdp_gem_priv, obj);
+}
+
+#endif
+
+static const struct drm_ioctl_desc nulldisp_ioctls[] = {
+ DRM_IOCTL_DEF_DRV(NULLDISP_GEM_CREATE,
+ nulldisp_gem_object_create_ioctl,
+ DRM_AUTH | DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(NULLDISP_GEM_MMAP,
+ nulldisp_gem_object_mmap_ioctl,
+ DRM_AUTH | DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(NULLDISP_GEM_CPU_PREP,
+ nulldisp_gem_object_cpu_prep_ioctl,
+ DRM_AUTH | DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(NULLDISP_GEM_CPU_FINI,
+ nulldisp_gem_object_cpu_fini_ioctl,
+ DRM_AUTH | DRM_UNLOCKED),
+};
+
+static int nulldisp_gem_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ int err;
+
+ err = netlink_gem_mmap(file, vma);
+#if !defined(LMA)
+ if (!err) {
+ struct drm_file *file_priv = file->private_data;
+ struct drm_device *dev = file_priv->minor->dev;
+ struct drm_gem_object *obj;
+
+ mutex_lock(&dev->struct_mutex);
+ obj = vma->vm_private_data;
+
+ if (obj->import_attach)
+ err = dma_buf_mmap(obj->dma_buf, vma, 0);
+ else
+ err = nulldisp_gem_object_get_pages(obj);
+
+ mutex_unlock(&dev->struct_mutex);
+ }
+#endif
+ return err;
+}
+
+static const struct file_operations nulldisp_driver_fops = {
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .unlocked_ioctl = drm_ioctl,
+ .mmap = nulldisp_gem_mmap,
+ .poll = drm_poll,
+ .read = drm_read,
+ .llseek = noop_llseek,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = drm_compat_ioctl,
+#endif
+};
+
+static struct drm_driver nulldisp_drm_driver = {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
+ .load = NULL,
+ .unload = NULL,
+#else
+ .load = nulldisp_load,
+ .unload = nulldisp_unload,
+#endif
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0))
+ .preclose = nulldisp_preclose,
+#endif
+ .lastclose = nulldisp_lastclose,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) && \
+ (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
+ .set_busid = drm_platform_set_busid,
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0))
+ .get_vblank_counter = drm_vblank_count,
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0))
+ .get_vblank_counter = drm_vblank_no_hw_counter,
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 7, 0))
+ .enable_vblank = nulldisp_enable_vblank,
+ .disable_vblank = nulldisp_disable_vblank,
+#endif
+
+ .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+ .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+
+#if defined(LMA)
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0))
+ .gem_free_object = pdp_gem_object_free,
+ .gem_prime_export = pdp_gem_prime_export,
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0) */
+ .gem_prime_import = pdp_gem_prime_import,
+ .gem_prime_import_sg_table = pdp_gem_prime_import_sg_table,
+
+ .dumb_create = pdp_gem_dumb_create,
+ .dumb_map_offset = pdp_gem_dumb_map_offset,
+#else
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0))
+ .gem_prime_pin = nulldisp_gem_prime_pin,
+ .gem_prime_unpin = nulldisp_gem_prime_unpin,
+ .gem_prime_get_sg_table = nulldisp_gem_prime_get_sg_table,
+ .gem_prime_vmap = nulldisp_gem_prime_vmap,
+ .gem_prime_vunmap = nulldisp_gem_prime_vunmap,
+ .gem_free_object = nulldisp_gem_object_free,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0))
+ .gem_prime_export = nulldisp_gem_prime_export,
+#else
+ .gem_prime_export = drm_gem_prime_export,
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0) */
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0) */
+ .gem_prime_import_sg_table = nulldisp_gem_prime_import_sg_table,
+ .gem_prime_mmap = nulldisp_gem_prime_mmap,
+ .gem_prime_import = drm_gem_prime_import,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0))
+ .gem_prime_res_obj = nulldisp_gem_prime_res_obj,
+#endif
+ .dumb_create = nulldisp_gem_dumb_create,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
+ .dumb_map_offset = nulldisp_gem_dumb_map_offset,
+#endif
+#endif /* defined(LMA) */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
+ .dumb_destroy = drm_gem_dumb_destroy,
+#endif
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0))
+ .gem_vm_ops = &nulldisp_gem_vm_ops,
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0) */
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = PVRVERSION_MAJ,
+ .minor = PVRVERSION_MIN,
+ .patchlevel = PVRVERSION_BUILD,
+
+ .driver_features = DRIVER_GEM |
+ DRIVER_MODESET |
+ NULLDISP_DRIVER_PRIME |
+ NULLDISP_DRIVER_ATOMIC,
+ .ioctls = nulldisp_ioctls,
+ .num_ioctls = ARRAY_SIZE(nulldisp_ioctls),
+ .fops = &nulldisp_driver_fops,
+};
+
+static int nulldisp_probe(struct platform_device *pdev)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
+ struct drm_device *ddev;
+ int ret;
+
+ ddev = drm_dev_alloc(&nulldisp_drm_driver, &pdev->dev);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0))
+ if (IS_ERR(ddev))
+ return PTR_ERR(ddev);
+#else
+ if (!ddev)
+ return -ENOMEM;
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
+ /* Needed by drm_platform_set_busid */
+ ddev->platformdev = pdev;
+#endif
+ /*
+ * The load callback, called from drm_dev_register, is deprecated,
+ * because of potential race conditions.
+ */
+ BUG_ON(nulldisp_drm_driver.load != NULL);
+
+ ret = nulldisp_early_load(ddev);
+ if (ret)
+ goto err_drm_dev_put;
+
+ ret = drm_dev_register(ddev, 0);
+ if (ret)
+ goto err_drm_dev_late_unload;
+
+ ret = nulldisp_late_load(ddev);
+ if (ret)
+ goto err_drm_dev_unregister;
+
+ drm_mode_config_reset(ddev);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0))
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
+ nulldisp_drm_driver.name,
+ nulldisp_drm_driver.major,
+ nulldisp_drm_driver.minor,
+ nulldisp_drm_driver.patchlevel,
+ nulldisp_drm_driver.date,
+ ddev->primary->index);
+#endif
+ return 0;
+
+err_drm_dev_unregister:
+ drm_dev_unregister(ddev);
+err_drm_dev_late_unload:
+ nulldisp_late_unload(ddev);
+err_drm_dev_put:
+ drm_dev_put(ddev);
+ return ret;
+#else
+ return drm_platform_init(&nulldisp_drm_driver, pdev);
+#endif
+}
+
+static int nulldisp_remove(struct platform_device *pdev)
+{
+ struct drm_device *ddev = platform_get_drvdata(pdev);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
+ /*
+ * The unload callback, called from drm_dev_unregister, is
+ * deprecated.
+ */
+ BUG_ON(nulldisp_drm_driver.unload != NULL);
+
+ nulldisp_early_unload(ddev);
+
+ drm_dev_unregister(ddev);
+
+ nulldisp_late_unload(ddev);
+
+ drm_dev_put(ddev);
+#else
+ drm_put_dev(ddev);
+#endif
+ return 0;
+}
+
+static void nulldisp_shutdown(struct platform_device *pdev)
+{
+}
+
+static struct platform_device_id nulldisp_platform_device_id_table[] = {
+#if defined(LMA)
+ { .name = APOLLO_DEVICE_NAME_PDP, .driver_data = 0 },
+ { .name = ODN_DEVICE_NAME_PDP, .driver_data = 0 },
+#else
+ { .name = "nulldisp", .driver_data = 0 },
+#endif
+ { },
+};
+
+static struct platform_driver nulldisp_platform_driver = {
+ .probe = nulldisp_probe,
+ .remove = nulldisp_remove,
+ .shutdown = nulldisp_shutdown,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRIVER_NAME,
+ },
+ .id_table = nulldisp_platform_device_id_table,
+};
+
+
+#if !defined(LMA)
+static struct platform_device_info nulldisp_device_info = {
+ .name = "nulldisp",
+ .id = -1,
+#if defined(NO_HARDWARE)
+ /*
+ * Not all cores have 40 bit physical support, but this
+ * will work unless > 32 bit address is returned on those cores.
+ * In the future this will be fixed properly.
+ */
+ .dma_mask = DMA_BIT_MASK(40),
+#else
+ .dma_mask = DMA_BIT_MASK(32),
+#endif
+};
+
+static struct platform_device *nulldisp_dev;
+#endif
+
+static int __init nulldisp_init(void)
+{
+ int err;
+
+ err = nulldisp_validate_module_parameters();
+ if (err) {
+ DRM_ERROR("invalid module parameters (err=%d)\n", err);
+ return err;
+ }
+
+ err = nlpvrdpy_register();
+ if (err) {
+ DRM_ERROR("failed to register with netlink (err=%d)\n", err);
+ return err;
+ }
+
+#if !defined(LMA)
+ nulldisp_dev = platform_device_register_full(&nulldisp_device_info);
+ if (IS_ERR(nulldisp_dev)) {
+ err = PTR_ERR(nulldisp_dev);
+ nulldisp_dev = NULL;
+ goto err_unregister_family;
+ }
+#endif
+ err = platform_driver_register(&nulldisp_platform_driver);
+ if (err)
+ goto err_unregister_family;
+
+ return 0;
+
+err_unregister_family:
+ (void) nlpvrdpy_unregister();
+ return err;
+}
+
+static void __exit nulldisp_exit(void)
+{
+ int err;
+
+ err = nlpvrdpy_unregister();
+ BUG_ON(err);
+
+#if !defined(LMA)
+ if (nulldisp_dev)
+ platform_device_unregister(nulldisp_dev);
+#endif
+ platform_driver_unregister(&nulldisp_platform_driver);
+}
+
+module_init(nulldisp_init);
+module_exit(nulldisp_exit);
+
+MODULE_AUTHOR("Imagination Technologies Ltd. ");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("Dual MIT/GPL");
diff --git a/drivers/gpu/drm/img-rogue/drm_nulldisp_drv.h b/drivers/gpu/drm/img-rogue/drm_nulldisp_drv.h
new file mode 100644
index 000000000..4dba36f8f
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/drm_nulldisp_drv.h
@@ -0,0 +1,93 @@
+/*
+ * @File
+ * @Codingstyle LinuxKernel
+ * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+ * @License Dual MIT/GPLv2
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 ("GPL") in which case the provisions
+ * of GPL are applicable instead of those above.
+ *
+ * If you wish to allow use of your version of this file only under the terms of
+ * GPL, and not to allow others to use your version of this file under the terms
+ * of the MIT license, indicate your decision by deleting the provisions above
+ * and replace them with the notice and other provisions required by GPL as set
+ * out in the file called "GPL-COPYING" included in this distribution. If you do
+ * not delete the provisions above, a recipient may use your version of this file
+ * under the terms of either the MIT license or GPL.
+ *
+ * This License is also included in this distribution in the file called
+ * "MIT-COPYING".
+ *
+ * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+ * PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __DRM_NULLDISP_DRV_H__
+#define __DRM_NULLDISP_DRV_H__
+
+#include
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+#include
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
+#define NULLDISP_USE_ATOMIC
+#endif
+
+struct drm_framebuffer;
+
+/******************************************************************************
+ * Linux compatibility functions
+ ******************************************************************************/
+static inline u32 nulldisp_drm_fb_format(struct drm_framebuffer *fb)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+ return fb->format->format;
+#else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) */
+ return fb->pixel_format;
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) */
+}
+
+static inline u64 nulldisp_drm_fb_modifier(struct drm_framebuffer *fb)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
+ return fb->modifier;
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
+ return fb->modifier[0];
+#else
+ /* 0 represents DRM_FORMAT_MOD_NONE, doesn't exist before 4.1 */
+ return 0;
+#endif
+}
+
+/******************************************************************************
+ * DRM framebuffer support functions
+ ******************************************************************************/
+static inline int nulldisp_drm_fb_num_planes(struct drm_framebuffer *fb)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+ return fb->format->num_planes;
+#else
+ return drm_format_num_planes(nulldisp_drm_fb_format(fb));
+#endif
+}
+#endif /* __DRM_NULLDISP_DRV_H__ */
diff --git a/drivers/gpu/drm/img-rogue/drm_nulldisp_gem.c b/drivers/gpu/drm/img-rogue/drm_nulldisp_gem.c
new file mode 100644
index 000000000..c47fb6519
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/drm_nulldisp_gem.c
@@ -0,0 +1,664 @@
+/*
+ * @File
+ * @Codingstyle LinuxKernel
+ * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+ * @License Dual MIT/GPLv2
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 ("GPL") in which case the provisions
+ * of GPL are applicable instead of those above.
+ *
+ * If you wish to allow use of your version of this file only under the terms of
+ * GPL, and not to allow others to use your version of this file under the terms
+ * of the MIT license, indicate your decision by deleting the provisions above
+ * and replace them with the notice and other provisions required by GPL as set
+ * out in the file called "GPL-COPYING" included in this distribution. If you do
+ * not delete the provisions above, a recipient may use your version of this file
+ * under the terms of either the MIT license or GPL.
+ *
+ * This License is also included in this distribution in the file called
+ * "MIT-COPYING".
+ *
+ * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+ * PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "pvr_dma_resv.h"
+#include "drm_nulldisp_gem.h"
+#include "nulldisp_drm.h"
+#include "kernel_compatibility.h"
+
+struct nulldisp_gem_object {
+ struct drm_gem_object base;
+
+ atomic_t pg_refcnt;
+ struct page **pages;
+ dma_addr_t *addrs; /* Will be NULL for imported buffers. */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0))
+ struct dma_resv _resv;
+#endif
+ struct dma_resv *resv;
+
+ bool cpu_prep;
+ struct sg_table *import_sgt;
+};
+
+#define to_nulldisp_obj(obj) \
+ container_of(obj, struct nulldisp_gem_object, base)
+
+int nulldisp_gem_object_get_pages(struct drm_gem_object *obj)
+{
+ struct drm_device *dev = obj->dev;
+ struct nulldisp_gem_object *nulldisp_obj = to_nulldisp_obj(obj);
+ struct page **pages;
+ int err;
+
+ if (WARN_ON(obj->import_attach))
+ return -EEXIST;
+
+ WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+
+ if (atomic_inc_return(&nulldisp_obj->pg_refcnt) == 1) {
+ unsigned int npages = obj->size >> PAGE_SHIFT;
+ dma_addr_t *addrs;
+ unsigned int i;
+
+ pages = drm_gem_get_pages(obj);
+ if (IS_ERR(pages)) {
+ err = PTR_ERR(pages);
+ goto dec_refcnt;
+ }
+
+ addrs = kmalloc_array(npages, sizeof(*addrs), GFP_KERNEL);
+ if (!addrs) {
+ err = -ENOMEM;
+ goto free_pages;
+ }
+
+ for (i = 0; i < npages; i++) {
+ addrs[i] = dma_map_page(dev->dev, pages[i],
+ 0, PAGE_SIZE,
+ DMA_BIDIRECTIONAL);
+ }
+
+ nulldisp_obj->pages = pages;
+ nulldisp_obj->addrs = addrs;
+ }
+
+ return 0;
+
+free_pages:
+ drm_gem_put_pages(obj, pages, false, false);
+dec_refcnt:
+ atomic_dec(&nulldisp_obj->pg_refcnt);
+ return err;
+}
+
+static void nulldisp_gem_object_put_pages(struct drm_gem_object *obj)
+{
+ struct drm_device *dev = obj->dev;
+ struct nulldisp_gem_object *nulldisp_obj = to_nulldisp_obj(obj);
+
+ WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+
+ if (WARN_ON(atomic_read(&nulldisp_obj->pg_refcnt) == 0))
+ return;
+
+ if (atomic_dec_and_test(&nulldisp_obj->pg_refcnt)) {
+ unsigned int npages = obj->size >> PAGE_SHIFT;
+ unsigned int i;
+
+ for (i = 0; i < npages; i++) {
+ dma_unmap_page(dev->dev, nulldisp_obj->addrs[i],
+ PAGE_SIZE, DMA_BIDIRECTIONAL);
+ }
+
+ kfree(nulldisp_obj->addrs);
+ nulldisp_obj->addrs = NULL;
+
+ drm_gem_put_pages(obj, nulldisp_obj->pages, true, true);
+ nulldisp_obj->pages = NULL;
+ }
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+vm_fault_t nulldisp_gem_object_vm_fault(struct vm_fault *vmf)
+#else
+int nulldisp_gem_object_vm_fault(struct vm_area_struct *vma,
+ struct vm_fault *vmf)
+#endif
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+ struct vm_area_struct *vma = vmf->vma;
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
+ unsigned long addr = vmf->address;
+#else
+ unsigned long addr = (unsigned long)vmf->virtual_address;
+#endif
+ struct drm_gem_object *obj = vma->vm_private_data;
+ struct nulldisp_gem_object *nulldisp_obj = to_nulldisp_obj(obj);
+ unsigned long pg_off;
+ struct page *page;
+
+ /*
+ * nulldisp_gem_object_get_pages should have been called in
+ * nulldisp_gem_mmap so there's no need to do it here.
+ */
+ if (WARN_ON(atomic_read(&nulldisp_obj->pg_refcnt) == 0))
+ return VM_FAULT_SIGBUS;
+
+ pg_off = (addr - vma->vm_start) >> PAGE_SHIFT;
+ page = nulldisp_obj->pages[pg_off];
+
+ get_page(page);
+ vmf->page = page;
+
+ return 0;
+}
+
+void nulldisp_gem_vm_open(struct vm_area_struct *vma)
+{
+ struct drm_gem_object *obj = vma->vm_private_data;
+
+ drm_gem_vm_open(vma);
+
+ if (!obj->import_attach) {
+ struct drm_device *dev = obj->dev;
+
+ mutex_lock(&dev->struct_mutex);
+ (void) nulldisp_gem_object_get_pages(obj);
+ mutex_unlock(&dev->struct_mutex);
+ }
+}
+
+void nulldisp_gem_vm_close(struct vm_area_struct *vma)
+{
+ struct drm_gem_object *obj = vma->vm_private_data;
+
+ if (!obj->import_attach) {
+ struct drm_device *dev = obj->dev;
+
+ mutex_lock(&dev->struct_mutex);
+ (void) nulldisp_gem_object_put_pages(obj);
+ mutex_unlock(&dev->struct_mutex);
+ }
+
+ drm_gem_vm_close(vma);
+}
+
+void nulldisp_gem_object_free(struct drm_gem_object *obj)
+{
+ struct nulldisp_gem_object *nulldisp_obj = to_nulldisp_obj(obj);
+
+ WARN_ON(atomic_read(&nulldisp_obj->pg_refcnt) != 0);
+
+ if (obj->import_attach) {
+ kfree(nulldisp_obj->pages);
+ drm_gem_free_mmap_offset(obj);
+ drm_prime_gem_destroy(obj, nulldisp_obj->import_sgt);
+ } else {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0))
+ dma_resv_fini(&nulldisp_obj->_resv);
+#endif
+ drm_gem_object_release(obj);
+ }
+
+ kfree(nulldisp_obj);
+}
+
+int nulldisp_gem_prime_pin(struct drm_gem_object *obj)
+{
+ struct drm_device *dev = obj->dev;
+ int err;
+
+ mutex_lock(&dev->struct_mutex);
+ err = nulldisp_gem_object_get_pages(obj);
+ mutex_unlock(&dev->struct_mutex);
+
+ return err;
+}
+
+void nulldisp_gem_prime_unpin(struct drm_gem_object *obj)
+{
+ struct drm_device *dev = obj->dev;
+
+ mutex_lock(&dev->struct_mutex);
+ nulldisp_gem_object_put_pages(obj);
+ mutex_unlock(&dev->struct_mutex);
+}
+
+struct sg_table *
+nulldisp_gem_prime_get_sg_table(struct drm_gem_object *obj)
+{
+ struct nulldisp_gem_object *nulldisp_obj = to_nulldisp_obj(obj);
+ int nr_pages = obj->size >> PAGE_SHIFT;
+
+ /*
+ * nulldisp_gem_prime_pin should have been called in which case we don't
+ * need to call nulldisp_gem_object_get_pages.
+ */
+ if (WARN_ON(atomic_read(&nulldisp_obj->pg_refcnt) == 0))
+ return NULL;
+
+ return drm_prime_pages_to_sg(obj->dev, nulldisp_obj->pages, nr_pages);
+}
+
+struct drm_gem_object *
+nulldisp_gem_prime_import_sg_table(struct drm_device *dev,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
+ struct dma_buf_attachment *attach,
+#else
+ size_t size,
+#endif
+ struct sg_table *sgt)
+{
+ struct nulldisp_gem_object *nulldisp_obj;
+ struct drm_gem_object *obj;
+ struct page **pages;
+ unsigned int npages;
+
+ nulldisp_obj = kzalloc(sizeof(*nulldisp_obj), GFP_KERNEL);
+ if (!nulldisp_obj)
+ return NULL;
+
+ nulldisp_obj->resv = attach->dmabuf->resv;
+
+ obj = &nulldisp_obj->base;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
+ obj->resv = nulldisp_obj->resv;
+#endif
+
+ drm_gem_private_object_init(dev, obj, attach->dmabuf->size);
+
+ npages = obj->size >> PAGE_SHIFT;
+
+ pages = kmalloc_array(npages, sizeof(*pages), GFP_KERNEL);
+ if (!pages)
+ goto exit_free_arrays;
+
+ if (drm_prime_sg_to_page_array(sgt, pages, npages))
+ goto exit_free_arrays;
+
+ nulldisp_obj->import_sgt = sgt;
+ nulldisp_obj->pages = pages;
+ nulldisp_obj->addrs = NULL;
+
+ return obj;
+
+exit_free_arrays:
+ kfree(pages);
+ drm_prime_gem_destroy(obj, sgt);
+ kfree(nulldisp_obj);
+ return NULL;
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0))
+struct dma_buf *nulldisp_gem_prime_export(
+ struct drm_device *dev,
+ struct drm_gem_object *obj,
+ int flags)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0))
+ /* Read/write access required */
+ flags |= O_RDWR;
+#endif
+ return drm_gem_prime_export(dev, obj, flags);
+}
+#endif
+
+static void *nulldisp_gem_vmap(struct drm_gem_object *obj)
+{
+ struct nulldisp_gem_object *nulldisp_obj = to_nulldisp_obj(obj);
+ int nr_pages = obj->size >> PAGE_SHIFT;
+
+ /*
+ * nulldisp_gem_prime_pin should have been called in which case we don't
+ * need to call nulldisp_gem_object_get_pages.
+ */
+ if (WARN_ON(atomic_read(&nulldisp_obj->pg_refcnt) == 0))
+ return NULL;
+
+
+ return vmap(nulldisp_obj->pages, nr_pages, 0, PAGE_KERNEL);
+}
+
+static void nulldisp_gem_vunmap(struct drm_gem_object *obj, void *vaddr)
+{
+ vunmap(vaddr);
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0))
+void *nulldisp_gem_prime_vmap(struct drm_gem_object *obj)
+{
+ return nulldisp_gem_vmap(obj);
+}
+
+void nulldisp_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
+{
+ nulldisp_gem_vunmap(obj, vaddr);
+}
+#else
+int nulldisp_gem_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map)
+{
+ void *vaddr = nulldisp_gem_vmap(obj);
+
+ dma_buf_map_set_vaddr(map, vaddr);
+ return (vaddr == NULL) ? -ENOMEM : 0;
+}
+
+void nulldisp_gem_prime_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map)
+{
+ nulldisp_gem_vunmap(obj, map->vaddr);
+ dma_buf_map_clear(map);
+}
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) */
+
+int nulldisp_gem_prime_mmap(struct drm_gem_object *obj,
+ struct vm_area_struct *vma)
+{
+ int err;
+
+ mutex_lock(&obj->dev->struct_mutex);
+ err = nulldisp_gem_object_get_pages(obj);
+ if (!err)
+ err = drm_gem_mmap_obj(obj, obj->size, vma);
+ mutex_unlock(&obj->dev->struct_mutex);
+
+ return err;
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0))
+struct dma_resv *
+nulldisp_gem_prime_res_obj(struct drm_gem_object *obj)
+{
+ struct nulldisp_gem_object *nulldisp_obj = to_nulldisp_obj(obj);
+
+ return nulldisp_obj->resv;
+}
+#endif
+
+int nulldisp_gem_object_mmap_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+ struct drm_nulldisp_gem_mmap *args =
+ (struct drm_nulldisp_gem_mmap *)data;
+
+ if (args->pad) {
+ DRM_ERROR("invalid pad (this should always be 0)\n");
+ return -EINVAL;
+ }
+
+ if (args->offset) {
+ DRM_ERROR("invalid offset (this should always be 0)\n");
+ return -EINVAL;
+ }
+
+ return nulldisp_gem_dumb_map_offset(file, dev, args->handle,
+ &args->offset);
+}
+
+int nulldisp_gem_object_cpu_prep_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+ struct drm_nulldisp_gem_cpu_prep *args =
+ (struct drm_nulldisp_gem_cpu_prep *)data;
+
+ struct drm_gem_object *obj;
+ struct nulldisp_gem_object *nulldisp_obj;
+ bool write = !!(args->flags & NULLDISP_GEM_CPU_PREP_WRITE);
+ bool wait = !(args->flags & NULLDISP_GEM_CPU_PREP_NOWAIT);
+ int err;
+
+ if (args->flags & ~(NULLDISP_GEM_CPU_PREP_READ |
+ NULLDISP_GEM_CPU_PREP_WRITE |
+ NULLDISP_GEM_CPU_PREP_NOWAIT)) {
+ DRM_ERROR("invalid flags: %#08x\n", args->flags);
+ return -EINVAL;
+ }
+
+ mutex_lock(&dev->struct_mutex);
+
+ obj = drm_gem_object_lookup(file, args->handle);
+ if (!obj) {
+ err = -ENOENT;
+ goto exit_unlock;
+ }
+
+ nulldisp_obj = to_nulldisp_obj(obj);
+
+ if (nulldisp_obj->cpu_prep) {
+ err = -EBUSY;
+ goto exit_unref;
+ }
+
+ if (wait) {
+ long lerr;
+
+ lerr = dma_resv_wait_timeout_rcu(nulldisp_obj->resv,
+ write,
+ true,
+ 30 * HZ);
+
+ /* Remap return value (0 indicates busy state, > 0 success) */
+ if (lerr > 0)
+ err = 0;
+ else if (!lerr)
+ err = -EBUSY;
+ else
+ err = lerr;
+ } else {
+ /*
+ * Remap return value (false indicates busy state,
+ * true success).
+ */
+ if (!dma_resv_test_signaled_rcu(nulldisp_obj->resv,
+ write))
+ err = -EBUSY;
+ else
+ err = 0;
+ }
+
+ if (!err)
+ nulldisp_obj->cpu_prep = true;
+exit_unref:
+ drm_gem_object_put(obj);
+exit_unlock:
+ mutex_unlock(&dev->struct_mutex);
+ return err;
+}
+
+int nulldisp_gem_object_cpu_fini_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+ struct drm_nulldisp_gem_cpu_fini *args =
+ (struct drm_nulldisp_gem_cpu_fini *)data;
+
+ struct drm_gem_object *obj;
+ struct nulldisp_gem_object *nulldisp_obj;
+ int err;
+
+ if (args->pad) {
+ DRM_ERROR("invalid pad (this should always be 0)\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&dev->struct_mutex);
+
+ obj = drm_gem_object_lookup(file, args->handle);
+ if (!obj) {
+ err = -ENOENT;
+ goto exit_unlock;
+ }
+
+ nulldisp_obj = to_nulldisp_obj(obj);
+
+ if (!nulldisp_obj->cpu_prep) {
+ err = -EINVAL;
+ goto exit_unref;
+ }
+
+ nulldisp_obj->cpu_prep = false;
+ err = 0;
+exit_unref:
+ drm_gem_object_put(obj);
+exit_unlock:
+ mutex_unlock(&dev->struct_mutex);
+ return err;
+}
+
+static int nulldisp_gem_object_create_priv(struct drm_file *file,
+ struct drm_device *dev,
+ u64 size,
+ u32 *handle)
+{
+ struct nulldisp_gem_object *nulldisp_obj;
+ struct drm_gem_object *obj;
+ struct address_space *mapping;
+ int err;
+
+ nulldisp_obj = kzalloc(sizeof(*nulldisp_obj), GFP_KERNEL);
+ if (!nulldisp_obj)
+ return -ENOMEM;
+
+ obj = &nulldisp_obj->base;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0))
+ obj->funcs = &nulldisp_gem_funcs;
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) */
+
+ err = drm_gem_object_init(dev, obj, size);
+ if (err) {
+ kfree(nulldisp_obj);
+ return err;
+ }
+
+ mapping = file_inode(obj->filp)->i_mapping;
+ mapping_set_gfp_mask(mapping, GFP_USER | __GFP_DMA32 | __GFP_NORETRY);
+
+ err = drm_gem_handle_create(file, obj, handle);
+ if (err)
+ goto exit;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0))
+ dma_resv_init(&nulldisp_obj->_resv);
+ nulldisp_obj->resv = &nulldisp_obj->_resv;
+#else
+ nulldisp_obj->resv = nulldisp_obj->base.resv;
+#endif
+
+exit:
+ drm_gem_object_put(obj);
+ return err;
+}
+
+int nulldisp_gem_object_create_ioctl(struct drm_device *dev,
+ void *data,
+ struct drm_file *file)
+{
+ struct drm_nulldisp_gem_create *args = data;
+ u32 handle;
+ int err;
+ u64 aligned_size;
+
+ if (args->flags) {
+ DRM_ERROR("invalid flags: %#08x\n", args->flags);
+ return -EINVAL;
+ }
+
+ if (args->handle) {
+ DRM_ERROR("invalid handle (this should always be 0)\n");
+ return -EINVAL;
+ }
+
+ aligned_size = PAGE_ALIGN(args->size);
+
+ err = nulldisp_gem_object_create_priv(file, dev, aligned_size, &handle);
+ if (!err)
+ args->handle = handle;
+
+ return err;
+}
+
+int nulldisp_gem_dumb_create(struct drm_file *file,
+ struct drm_device *dev,
+ struct drm_mode_create_dumb *args)
+{
+ u32 handle;
+ u32 pitch;
+ size_t size;
+ int err;
+
+ pitch = args->width * (ALIGN(args->bpp, 8) >> 3);
+ size = PAGE_ALIGN(pitch * args->height);
+
+ err = nulldisp_gem_object_create_priv(file, dev, size, &handle);
+ if (!err) {
+ args->handle = handle;
+ args->pitch = pitch;
+ args->size = size;
+ }
+
+ return err;
+}
+
+int nulldisp_gem_dumb_map_offset(struct drm_file *file,
+ struct drm_device *dev,
+ uint32_t handle,
+ uint64_t *offset)
+{
+ struct drm_gem_object *obj;
+ int err;
+
+ mutex_lock(&dev->struct_mutex);
+
+ obj = drm_gem_object_lookup(file, handle);
+ if (!obj) {
+ err = -ENOENT;
+ goto exit_unlock;
+ }
+
+ err = drm_gem_create_mmap_offset(obj);
+ if (err)
+ goto exit_obj_unref;
+
+ *offset = drm_vma_node_offset_addr(&obj->vma_node);
+
+exit_obj_unref:
+ drm_gem_object_put(obj);
+exit_unlock:
+ mutex_unlock(&dev->struct_mutex);
+ return err;
+}
+
+struct dma_resv *nulldisp_gem_get_resv(struct drm_gem_object *obj)
+{
+ return (to_nulldisp_obj(obj)->resv);
+}
diff --git a/drivers/gpu/drm/img-rogue/drm_nulldisp_gem.h b/drivers/gpu/drm/img-rogue/drm_nulldisp_gem.h
new file mode 100644
index 000000000..a22a1c633
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/drm_nulldisp_gem.h
@@ -0,0 +1,156 @@
+/*
+ * @File
+ * @Codingstyle LinuxKernel
+ * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+ * @License Dual MIT/GPLv2
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 ("GPL") in which case the provisions
+ * of GPL are applicable instead of those above.
+ *
+ * If you wish to allow use of your version of this file only under the terms of
+ * GPL, and not to allow others to use your version of this file under the terms
+ * of the MIT license, indicate your decision by deleting the provisions above
+ * and replace them with the notice and other provisions required by GPL as set
+ * out in the file called "GPL-COPYING" included in this distribution. If you do
+ * not delete the provisions above, a recipient may use your version of this file
+ * under the terms of either the MIT license or GPL.
+ *
+ * This License is also included in this distribution in the file called
+ * "MIT-COPYING".
+ *
+ * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+ * PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#if !defined(__DRM_NULLDISP_H__)
+#define __DRM_NULLDISP_H__
+
+#include
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0))
+#include
+#include
+#include
+#include
+
+struct dma_buf_attachment;
+struct vm_area_struct;
+struct vm_fault;
+#else
+#include
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0))
+extern const struct drm_gem_object_funcs nulldisp_gem_funcs;
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
+#include
+#endif
+
+int nulldisp_gem_object_get_pages(struct drm_gem_object *obj);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0))
+typedef int vm_fault_t;
+#endif
+vm_fault_t nulldisp_gem_object_vm_fault(struct vm_fault *vmf);
+#else
+int nulldisp_gem_object_vm_fault(struct vm_area_struct *vma,
+ struct vm_fault *vmf);
+#endif
+
+void nulldisp_gem_vm_open(struct vm_area_struct *vma);
+
+void nulldisp_gem_vm_close(struct vm_area_struct *vma);
+
+void nulldisp_gem_object_free(struct drm_gem_object *obj);
+
+int nulldisp_gem_prime_pin(struct drm_gem_object *obj);
+
+void nulldisp_gem_prime_unpin(struct drm_gem_object *obj);
+
+struct sg_table *nulldisp_gem_prime_get_sg_table(struct drm_gem_object *obj);
+
+struct drm_gem_object *
+nulldisp_gem_prime_import_sg_table(struct drm_device *dev,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
+ struct dma_buf_attachment *attach,
+#else
+ size_t size,
+#endif
+ struct sg_table *sgt);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0))
+struct dma_buf *nulldisp_gem_prime_export(struct drm_device *dev,
+ struct drm_gem_object *obj,
+ int flags);
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0))
+void *nulldisp_gem_prime_vmap(struct drm_gem_object *obj);
+#else
+int nulldisp_gem_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map);
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0))
+void nulldisp_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
+#else
+void nulldisp_gem_prime_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map);
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0) */
+
+int nulldisp_gem_prime_mmap(struct drm_gem_object *obj,
+ struct vm_area_struct *vma);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0))
+struct dma_resv *
+nulldisp_gem_prime_res_obj(struct drm_gem_object *obj);
+#endif
+
+int nulldisp_gem_dumb_create(struct drm_file *file,
+ struct drm_device *dev,
+ struct drm_mode_create_dumb *args);
+
+int nulldisp_gem_dumb_map_offset(struct drm_file *file,
+ struct drm_device *dev,
+ uint32_t handle,
+ uint64_t *offset);
+
+/* internal interfaces */
+struct dma_resv *nulldisp_gem_get_resv(struct drm_gem_object *obj);
+
+int nulldisp_gem_object_mmap_ioctl(struct drm_device *dev,
+ void *data,
+ struct drm_file *file);
+
+int nulldisp_gem_object_cpu_prep_ioctl(struct drm_device *dev,
+ void *data,
+ struct drm_file *file);
+
+int nulldisp_gem_object_cpu_fini_ioctl(struct drm_device *dev,
+ void *data,
+ struct drm_file *file);
+
+int nulldisp_gem_object_create_ioctl(struct drm_device *dev,
+ void *data,
+ struct drm_file *file);
+
+#endif /* !defined(__DRM_NULLDISP_H__) */
diff --git a/drivers/gpu/drm/img-rogue/drm_nulldisp_netlink.c b/drivers/gpu/drm/img-rogue/drm_nulldisp_netlink.c
new file mode 100644
index 000000000..a5e8a742b
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/drm_nulldisp_netlink.c
@@ -0,0 +1,698 @@
+/*
+ * @File
+ * @Codingstyle LinuxKernel
+ * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+ * @License Dual MIT/GPLv2
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 ("GPL") in which case the provisions
+ * of GPL are applicable instead of those above.
+ *
+ * If you wish to allow use of your version of this file only under the terms of
+ * GPL, and not to allow others to use your version of this file under the terms
+ * of the MIT license, indicate your decision by deleting the provisions above
+ * and replace them with the notice and other provisions required by GPL as set
+ * out in the file called "GPL-COPYING" included in this distribution. If you do
+ * not delete the provisions above, a recipient may use your version of this file
+ * under the terms of either the MIT license or GPL.
+ *
+ * This License is also included in this distribution in the file called
+ * "MIT-COPYING".
+ *
+ * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+ * PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0))
+#include
+#include
+#include
+#include
+#include
+#else
+#include
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "drm_netlink_gem.h"
+#include "drm_nulldisp_drv.h"
+#include "drm_nulldisp_netlink.h"
+#include "kernel_compatibility.h"
+
+#include "netlink.h"
+
+struct nlpvrdpy {
+ atomic_t connected;
+ struct net *net;
+ u32 dst_portid;
+ struct drm_device *dev;
+ nlpvrdpy_disconnect_cb disconnect_cb;
+ void *disconnect_cb_data;
+ nlpvrdpy_flipped_cb flipped_cb;
+ void *flipped_cb_data;
+ nlpvrdpy_copied_cb copied_cb;
+ void *copied_cb_data;
+ struct mutex mutex;
+ struct list_head nl_list;
+ bool gem_names_required;
+};
+#define NLPVRDPY_MINOR(nlpvrdpy) \
+ ((unsigned int)((nlpvrdpy)->dev->primary->index))
+
+/* Command internal flags */
+#define NLPVRDPY_CIF_NLPVRDPY_NOT_CONNECTED 0x00000001
+#define NLPVRDPY_CIF_NLPVRDPY 0x00000002
+
+static LIST_HEAD(nlpvrdpy_list);
+static DEFINE_MUTEX(nlpvrdpy_list_mutex);
+
+static inline void nlpvrdpy_lock(struct nlpvrdpy *nlpvrdpy)
+{
+ mutex_lock(&nlpvrdpy->mutex);
+}
+
+static inline void nlpvrdpy_unlock(struct nlpvrdpy *nlpvrdpy)
+{
+ mutex_unlock(&nlpvrdpy->mutex);
+}
+
+struct nlpvrdpy *nlpvrdpy_create(struct drm_device *dev,
+ nlpvrdpy_disconnect_cb disconnect_cb,
+ void *disconnect_cb_data,
+ nlpvrdpy_flipped_cb flipped_cb,
+ void *flipped_cb_data,
+ nlpvrdpy_copied_cb copied_cb,
+ void *copied_cb_data)
+{
+ struct nlpvrdpy *nlpvrdpy = kzalloc(sizeof(*nlpvrdpy), GFP_KERNEL);
+
+ if (!nlpvrdpy)
+ return NULL;
+
+ mutex_init(&nlpvrdpy->mutex);
+ INIT_LIST_HEAD(&nlpvrdpy->nl_list);
+
+ atomic_set(&nlpvrdpy->connected, 0);
+
+ nlpvrdpy->dev = dev;
+ nlpvrdpy->disconnect_cb = disconnect_cb;
+ nlpvrdpy->disconnect_cb_data = disconnect_cb_data;
+ nlpvrdpy->flipped_cb = flipped_cb;
+ nlpvrdpy->flipped_cb_data = flipped_cb_data;
+ nlpvrdpy->copied_cb = copied_cb;
+ nlpvrdpy->copied_cb_data = copied_cb_data;
+
+ mutex_lock(&nlpvrdpy_list_mutex);
+ list_add_tail(&nlpvrdpy->nl_list, &nlpvrdpy_list);
+ mutex_unlock(&nlpvrdpy_list_mutex);
+
+ return nlpvrdpy;
+}
+
+void nlpvrdpy_destroy(struct nlpvrdpy *nlpvrdpy)
+{
+ if (!nlpvrdpy)
+ return;
+
+ mutex_lock(&nlpvrdpy_list_mutex);
+ nlpvrdpy_lock(nlpvrdpy);
+ list_del(&nlpvrdpy->nl_list);
+ nlpvrdpy_unlock(nlpvrdpy);
+ mutex_unlock(&nlpvrdpy_list_mutex);
+
+ mutex_destroy(&nlpvrdpy->mutex);
+
+ kfree(nlpvrdpy);
+}
+
+static struct nlpvrdpy *nlpvrdpy_lookup(u32 minor)
+{
+ struct nlpvrdpy *nlpvrdpy = NULL;
+ struct nlpvrdpy *iter;
+
+ mutex_lock(&nlpvrdpy_list_mutex);
+ list_for_each_entry(iter, &nlpvrdpy_list, nl_list) {
+ if (NLPVRDPY_MINOR(iter) == minor) {
+ nlpvrdpy = iter;
+ nlpvrdpy_lock(nlpvrdpy);
+ break;
+ }
+ }
+ mutex_unlock(&nlpvrdpy_list_mutex);
+
+ return nlpvrdpy;
+}
+
+static int nlpvrdpy_pre_cmd(const struct genl_ops *ops,
+ struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct nlattr **attrs = info->attrs;
+ struct nlpvrdpy *nlpvrdpy = NULL;
+ int ret;
+
+ if (ops->internal_flags & NLPVRDPY_CIF_NLPVRDPY_NOT_CONNECTED) {
+ if (!(ops->flags & GENL_ADMIN_PERM))
+ return -EINVAL;
+ }
+
+ if (ops->internal_flags & (NLPVRDPY_CIF_NLPVRDPY_NOT_CONNECTED |
+ NLPVRDPY_CIF_NLPVRDPY)) {
+ u32 minor;
+
+ if (!attrs[NLPVRDPY_ATTR_MINOR])
+ return -EINVAL;
+
+ minor = nla_get_u32(attrs[NLPVRDPY_ATTR_MINOR]);
+
+ nlpvrdpy = nlpvrdpy_lookup(minor);
+ if (!nlpvrdpy)
+ return -ENODEV;
+
+ if (ops->internal_flags & NLPVRDPY_CIF_NLPVRDPY) {
+ if (!atomic_read(&nlpvrdpy->connected)) {
+ ret = -ENOTCONN;
+ goto err_unlock;
+ }
+ if ((nlpvrdpy->net != genl_info_net(info)) ||
+ (nlpvrdpy->dst_portid != info->snd_portid)) {
+ ret = -EPROTO;
+ goto err_unlock;
+ }
+ }
+
+ info->user_ptr[0] = nlpvrdpy;
+ }
+
+ ret = 0;
+
+err_unlock:
+ nlpvrdpy_unlock(nlpvrdpy);
+ return ret;
+}
+
+static void nlpvrdpy_post_cmd(const struct genl_ops *ops,
+ struct sk_buff *skb,
+ struct genl_info *info)
+{
+}
+
+static struct genl_family nlpvrdpy_family = {
+ .name = "nlpvrdpy",
+ .version = 1,
+ .maxattr = NLPVRDPY_ATTR_MAX,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
+ .policy = nlpvrdpy_policy,
+#endif
+ .pre_doit = &nlpvrdpy_pre_cmd,
+ .post_doit = &nlpvrdpy_post_cmd
+};
+
+/* Must be called with the struct nlpvrdpy mutex held */
+static int nlpvrdpy_send_msg_locked(struct nlpvrdpy *nlpvrdpy,
+ struct sk_buff *msg)
+{
+ int err;
+
+ if (atomic_read(&nlpvrdpy->connected)) {
+ err = genlmsg_unicast(nlpvrdpy->net, msg, nlpvrdpy->dst_portid);
+ if (err == -ECONNREFUSED)
+ atomic_set(&nlpvrdpy->connected, 0);
+ } else {
+ err = -ENOTCONN;
+ nlmsg_free(msg);
+ }
+
+ return err;
+}
+
+static int nlpvrdpy_send_msg(struct nlpvrdpy *nlpvrdpy, struct sk_buff *msg)
+{
+ int err;
+
+ nlpvrdpy_lock(nlpvrdpy);
+ err = nlpvrdpy_send_msg_locked(nlpvrdpy, msg);
+ nlpvrdpy_unlock(nlpvrdpy);
+
+ return err;
+}
+
+void nlpvrdpy_send_disconnect(struct nlpvrdpy *nlpvrdpy)
+{
+ struct sk_buff *msg;
+ void *hdr;
+ int err;
+
+ if (!atomic_read(&nlpvrdpy->connected))
+ return;
+
+ msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+ if (!msg)
+ return;
+
+ hdr = genlmsg_put(msg, nlpvrdpy->dst_portid, 0,
+ &nlpvrdpy_family, 0, NLPVRDPY_CMD_DISCONNECT);
+ if (!hdr)
+ goto err_msg_free;
+
+ err = nla_put_u32(msg, NLPVRDPY_ATTR_MINOR, NLPVRDPY_MINOR(nlpvrdpy));
+ if (err)
+ goto err_msg_free;
+
+ genlmsg_end(msg, hdr);
+
+ nlpvrdpy_lock(nlpvrdpy);
+
+ (void) nlpvrdpy_send_msg_locked(nlpvrdpy, msg);
+
+ atomic_set(&nlpvrdpy->connected, 0);
+ nlpvrdpy->net = NULL;
+ nlpvrdpy->dst_portid = 0;
+
+ nlpvrdpy_unlock(nlpvrdpy);
+
+ return;
+
+err_msg_free:
+ nlmsg_free(msg);
+}
+
+static int nlpvrdpy_get_offsets_and_sizes(struct drm_framebuffer *fb,
+ struct drm_gem_object **objs,
+ u64 *addr, u64 *size)
+{
+ int i;
+
+ for (i = 0; i < nulldisp_drm_fb_num_planes(fb); i++) {
+ int err;
+ struct drm_gem_object *obj = objs[i];
+
+ err = drm_gem_create_mmap_offset(obj);
+ if (err) {
+ DRM_ERROR(
+ "Failed to get mmap offset for buffer[%d] = %p\n",
+ i, obj);
+ return err;
+ }
+
+ addr[i] = drm_vma_node_offset_addr(&obj->vma_node);
+ size[i] = obj->size;
+ }
+
+ return 0;
+}
+
+static int nlpvrdpy_put_fb_attributes(struct sk_buff *msg,
+ struct drm_framebuffer *fb,
+ struct nlpvrdpy *nlpvrdpy,
+ struct drm_gem_object **objs)
+{
+ int i, err;
+ const int num_planes = nulldisp_drm_fb_num_planes(fb);
+ u64 plane_addr[NLPVRDPY_MAX_NUM_PLANES],
+ plane_size[NLPVRDPY_MAX_NUM_PLANES];
+
+ err = nlpvrdpy_get_offsets_and_sizes(fb, objs, &plane_addr[0], &plane_size[0]);
+ if (err) {
+ pr_err("%s: nlpvrdpy_get_offsets_and_sizes failed", __func__);
+ return err;
+ }
+
+ err = nla_put_u32(msg, NLPVRDPY_ATTR_MINOR, NLPVRDPY_MINOR(nlpvrdpy));
+ if (err) {
+ pr_err("%s: nla_put_u32 NLPVRDPY_ATTR_MINOR failed", __func__);
+ return err;
+ }
+
+ err = nla_put_u8(msg, NLPVRDPY_ATTR_NUM_PLANES, num_planes);
+ if (err) {
+ pr_err("%s: nla_put_u8 NLPVRDPY_ATTR_NUM_PLANES failed", __func__);
+ return err;
+ }
+
+ err = nla_put_u32(msg, NLPVRDPY_ATTR_WIDTH, fb->width);
+ if (err) {
+ pr_err("%s: nla_put_u32 NLPVRDPY_ATTR_WIDTH failed", __func__);
+ return err;
+ }
+
+ err = nla_put_u32(msg, NLPVRDPY_ATTR_HEIGHT, fb->height);
+ if (err) {
+ pr_err("%s: nla_put_u32 NLPVRDPY_ATTR_HEIGHT failed", __func__);
+ return err;
+ }
+
+ err = nla_put_u32(msg, NLPVRDPY_ATTR_PIXFMT, nulldisp_drm_fb_format(fb));
+ if (err) {
+ pr_err("%s: nla_put_u32 NLPVRDPY_ATTR_PIXFMT failed",
+ __func__);
+ return err;
+ }
+
+ err = nla_put_u64_64bit(msg, NLPVRDPY_ATTR_FB_MODIFIER,
+ nulldisp_drm_fb_modifier(fb), NLPVRDPY_ATTR_PAD);
+ if (err) {
+ pr_err("%s: nla_put_u64_64bit NLPVRDPY_ATTR_FB_MODIFIER "
+ "NLPVRDPY_ATTR_PAD failed", __func__);
+ return err;
+ }
+
+ /* IMG_COLORSPACE_BT601_CONFORMANT_RANGE */
+ err = nla_put_u8(msg, NLPVRDPY_ATTR_YUV_CSC, 1);
+ if (err) {
+ pr_err("%s: nla_put_u8 NLPVRDPY_ATTR_YUV_CSC 1 failed", __func__);
+ return err;
+ }
+
+ /* 8-bit per sample */
+ err = nla_put_u8(msg, NLPVRDPY_ATTR_YUV_BPP, 8);
+ if (err) {
+ pr_err("%s: nla_put_u8 NLPVRDPY_ATTR_YUV_BPP 8 failed", __func__);
+ return err;
+ }
+
+ for (i = 0; i < num_planes; i++) {
+ err = nla_put_u64_64bit(msg, NLPVRDPY_ATTR_PLANE(i, ADDR),
+ plane_addr[i], NLPVRDPY_ATTR_PAD);
+ if (err) {
+ pr_err("%s: nla_put_u64_64bit NLPVRDPY_ATTR_PLANE(%d, ADDR)"
+ " NLPVRDPY_ATTR_PAD failed", __func__, i);
+ return err;
+ }
+
+ err = nla_put_u64_64bit(msg, NLPVRDPY_ATTR_PLANE(i, SIZE),
+ plane_size[i], NLPVRDPY_ATTR_PAD);
+ if (err) {
+ pr_err("%s: nla_put_u64_64bit NLPVRDPY_ATTR_PLANE(%d, SIZE)"
+ " NLPVRDPY_ATTR_PAD failed", __func__, i);
+ return err;
+ }
+
+ err = nla_put_u64_64bit(msg, NLPVRDPY_ATTR_PLANE(i, OFFSET),
+ fb->offsets[i], NLPVRDPY_ATTR_PAD);
+ if (err) {
+ pr_err("%s: nla_put_u64_64bit NLPVRDPY_ATTR_PLANE(%d, OFFSET)"
+ " NLPVRDPY_ATTR_PAD failed", __func__, i);
+ return err;
+ }
+
+ err = nla_put_u64_64bit(msg, NLPVRDPY_ATTR_PLANE(i, PITCH),
+ fb->pitches[i], NLPVRDPY_ATTR_PAD);
+ if (err) {
+ pr_err("%s: nla_put_u64_64bit NLPVRDPY_ATTR_PLANE(%d, PITCH)"
+ " NLPVRDPY_ATTR_PAD failed", __func__, i);
+ return err;
+ }
+
+ err = nla_put_u32(msg, NLPVRDPY_ATTR_PLANE(i, GEM_OBJ_NAME), (u32)objs[0]->name);
+ if (err) {
+ pr_err("%s: nla_put_u32 NLPVRDPY_ATTR_PLANE(%d, GEM_OBJ_NAME)"
+ " failed", __func__, i);
+ return err;
+ }
+ }
+
+ WARN_ONCE(num_planes > NLPVRDPY_MAX_NUM_PLANES,
+ "NLPVRDPY_MAX_NUM_PLANES = [%d], num_planes = [%d]\n",
+ NLPVRDPY_MAX_NUM_PLANES, num_planes);
+
+ return 0;
+}
+
+static int nlpvrdpy_name_gem_obj(struct drm_device *dev,
+ struct drm_gem_object *obj)
+{
+ int ret;
+
+ mutex_lock(&dev->object_name_lock);
+ if (!obj->name) {
+ ret = idr_alloc(&dev->object_name_idr, obj, 1, 0, GFP_KERNEL);
+ if (ret < 0)
+ goto exit_unlock;
+
+ obj->name = ret;
+ }
+
+ ret = 0;
+
+exit_unlock:
+ mutex_unlock(&dev->object_name_lock);
+ return ret;
+}
+
+static int nlpvrdpy_name_gem_objs(struct drm_framebuffer *fb,
+ struct drm_gem_object **objs)
+{
+ int i;
+ struct drm_device *dev = fb->dev;
+
+ for (i = 0; i < nulldisp_drm_fb_num_planes(fb); i++) {
+ int err = nlpvrdpy_name_gem_obj(dev, objs[i]);
+
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+int nlpvrdpy_send_flip(struct nlpvrdpy *nlpvrdpy,
+ struct drm_framebuffer *fb,
+ struct drm_gem_object **objs)
+{
+ struct sk_buff *msg;
+ void *hdr;
+ int err;
+
+ if (!atomic_read(&nlpvrdpy->connected))
+ return -ENOTCONN;
+
+ if (nlpvrdpy->gem_names_required) {
+ err = nlpvrdpy_name_gem_objs(fb, objs);
+ if (err)
+ return err;
+ }
+
+ msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ hdr = genlmsg_put(msg, nlpvrdpy->dst_portid, 0,
+ &nlpvrdpy_family, 0, NLPVRDPY_CMD_FLIP);
+ if (!hdr) {
+ err = -ENOMEM;
+ goto err_msg_free;
+ }
+
+ err = nlpvrdpy_put_fb_attributes(msg, fb, nlpvrdpy, objs);
+ if (err)
+ goto err_msg_free;
+
+ genlmsg_end(msg, hdr);
+
+ return nlpvrdpy_send_msg(nlpvrdpy, msg);
+
+err_msg_free:
+ nlmsg_free(msg);
+ return err;
+}
+
+int nlpvrdpy_send_copy(struct nlpvrdpy *nlpvrdpy,
+ struct drm_framebuffer *fb,
+ struct drm_gem_object **objs)
+{
+ struct sk_buff *msg;
+ void *hdr;
+ int err;
+
+ if (!atomic_read(&nlpvrdpy->connected))
+ return -ENOTCONN;
+
+ if (nlpvrdpy->gem_names_required) {
+ err = nlpvrdpy_name_gem_objs(fb, objs);
+ if (err)
+ return err;
+ }
+
+ msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ hdr = genlmsg_put(msg, nlpvrdpy->dst_portid, 0,
+ &nlpvrdpy_family, 0, NLPVRDPY_CMD_COPY);
+ if (!hdr) {
+ err = -ENOMEM;
+ goto err_msg_free;
+ }
+
+ err = nlpvrdpy_put_fb_attributes(msg, fb, nlpvrdpy, objs);
+ if (err)
+ goto err_msg_free;
+
+ genlmsg_end(msg, hdr);
+
+ return nlpvrdpy_send_msg(nlpvrdpy, msg);
+
+err_msg_free:
+ nlmsg_free(msg);
+ return err;
+}
+
+static int nlpvrdpy_cmd_connect(struct sk_buff *skb, struct genl_info *info)
+{
+ struct nlpvrdpy *nlpvrdpy = info->user_ptr[0];
+ struct sk_buff *msg;
+ void *hdr;
+ int err;
+
+ if (info->attrs[NLPVRDPY_ATTR_NAMING_REQUIRED])
+ nlpvrdpy->gem_names_required = true;
+
+ msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ hdr = genlmsg_put_reply(msg, info, &nlpvrdpy_family,
+ 0, NLPVRDPY_CMD_CONNECTED);
+ if (!hdr) {
+ err = -ENOMEM;
+ goto err_msg_free;
+ }
+
+ err = nla_put_string(msg, NLPVRDPY_ATTR_NAME,
+ nlpvrdpy->dev->driver->name);
+ if (err)
+ goto err_msg_free;
+
+ genlmsg_end(msg, hdr);
+
+ err = genlmsg_reply(msg, info);
+
+ if (!err) {
+ nlpvrdpy_lock(nlpvrdpy);
+
+ nlpvrdpy->net = genl_info_net(info);
+ nlpvrdpy->dst_portid = info->snd_portid;
+ atomic_set(&nlpvrdpy->connected, 1);
+
+ nlpvrdpy_unlock(nlpvrdpy);
+ }
+
+ return err;
+
+err_msg_free:
+ nlmsg_free(msg);
+ return err;
+}
+
+static int nlpvrdpy_cmd_disconnect(struct sk_buff *skb, struct genl_info *info)
+{
+ struct nlpvrdpy *nlpvrdpy = info->user_ptr[0];
+
+ atomic_set(&nlpvrdpy->connected, 0);
+
+ if (nlpvrdpy->disconnect_cb)
+ nlpvrdpy->disconnect_cb(nlpvrdpy->disconnect_cb_data);
+
+ return 0;
+}
+
+static int nlpvrdpy_cmd_flipped(struct sk_buff *skb, struct genl_info *info)
+{
+ struct nlpvrdpy *nlpvrdpy = info->user_ptr[0];
+
+ return (nlpvrdpy->flipped_cb) ?
+ nlpvrdpy->flipped_cb(nlpvrdpy->flipped_cb_data) :
+ 0;
+}
+
+static int nlpvrdpy_cmd_copied(struct sk_buff *skb, struct genl_info *info)
+{
+ struct nlpvrdpy *nlpvrdpy = info->user_ptr[0];
+
+ return (nlpvrdpy->copied_cb) ?
+ nlpvrdpy->copied_cb(nlpvrdpy->copied_cb_data) :
+ 0;
+}
+
+static struct genl_ops nlpvrdpy_ops[] = {
+ {
+ .cmd = NLPVRDPY_CMD_CONNECT,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0))
+ .policy = nlpvrdpy_policy,
+#endif
+ .doit = nlpvrdpy_cmd_connect,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NLPVRDPY_CIF_NLPVRDPY_NOT_CONNECTED
+ },
+ {
+ .cmd = NLPVRDPY_CMD_DISCONNECT,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0))
+ .policy = nlpvrdpy_policy,
+#endif
+ .doit = nlpvrdpy_cmd_disconnect,
+ .flags = 0,
+ .internal_flags = NLPVRDPY_CIF_NLPVRDPY
+ },
+ {
+ .cmd = NLPVRDPY_CMD_FLIPPED,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0))
+ .policy = nlpvrdpy_policy,
+#endif
+ .doit = nlpvrdpy_cmd_flipped,
+ .flags = 0,
+ .internal_flags = NLPVRDPY_CIF_NLPVRDPY
+ },
+ {
+ .cmd = NLPVRDPY_CMD_COPIED,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0))
+ .policy = nlpvrdpy_policy,
+#endif
+ .doit = nlpvrdpy_cmd_copied,
+ .flags = 0,
+ .internal_flags = NLPVRDPY_CIF_NLPVRDPY
+ }
+};
+
+int nlpvrdpy_register(void)
+{
+ nlpvrdpy_family.module = THIS_MODULE;
+ nlpvrdpy_family.ops = nlpvrdpy_ops;
+ nlpvrdpy_family.n_ops = ARRAY_SIZE(nlpvrdpy_ops);
+
+ return genl_register_family(&nlpvrdpy_family);
+}
+
+int nlpvrdpy_unregister(void)
+{
+ return genl_unregister_family(&nlpvrdpy_family);
+}
diff --git a/drivers/gpu/drm/img-rogue/drm_nulldisp_netlink.h b/drivers/gpu/drm/img-rogue/drm_nulldisp_netlink.h
new file mode 100644
index 000000000..1cea24085
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/drm_nulldisp_netlink.h
@@ -0,0 +1,77 @@
+/*
+ * @File
+ * @Codingstyle LinuxKernel
+ * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+ * @License Dual MIT/GPLv2
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 ("GPL") in which case the provisions
+ * of GPL are applicable instead of those above.
+ *
+ * If you wish to allow use of your version of this file only under the terms of
+ * GPL, and not to allow others to use your version of this file under the terms
+ * of the MIT license, indicate your decision by deleting the provisions above
+ * and replace them with the notice and other provisions required by GPL as set
+ * out in the file called "GPL-COPYING" included in this distribution. If you do
+ * not delete the provisions above, a recipient may use your version of this file
+ * under the terms of either the MIT license or GPL.
+ *
+ * This License is also included in this distribution in the file called
+ * "MIT-COPYING".
+ *
+ * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+ * PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __DRM_NULLDISP_NETLINK_H__
+#define __DRM_NULLDISP_NETLINK_H__
+
+#include
+#include
+
+typedef void (*nlpvrdpy_disconnect_cb)(void *data);
+typedef int (*nlpvrdpy_flipped_cb)(void *data);
+typedef int (*nlpvrdpy_copied_cb)(void *data);
+
+struct nlpvrdpy *nlpvrdpy_create(struct drm_device *dev,
+ nlpvrdpy_disconnect_cb disconnect_cb,
+ void *disconnect_cb_data,
+ nlpvrdpy_flipped_cb flipped_cb,
+ void *flipped_cb_data,
+ nlpvrdpy_copied_cb copied_cb,
+ void *copied_cb_data);
+
+void nlpvrdpy_destroy(struct nlpvrdpy *nlpvrdpy);
+
+int nlpvrdpy_send_flip(struct nlpvrdpy *nlpvrdpy,
+ struct drm_framebuffer *fb,
+ struct drm_gem_object **objs);
+
+int nlpvrdpy_send_copy(struct nlpvrdpy *nlpvrdpy,
+ struct drm_framebuffer *fb,
+ struct drm_gem_object **objs);
+
+void nlpvrdpy_send_disconnect(struct nlpvrdpy *nlpvrdpy);
+
+int nlpvrdpy_register(void);
+
+int nlpvrdpy_unregister(void);
+
+#endif /* __DRM_NULLDISP_NETLINK_H__ */
diff --git a/drivers/gpu/drm/img-rogue/env_connection.h b/drivers/gpu/drm/img-rogue/env_connection.h
new file mode 100644
index 000000000..2a6c7d05c
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/env_connection.h
@@ -0,0 +1,92 @@
+/*************************************************************************/ /*!
+@File
+@Title Server side connection management
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Linux specific server side connection management
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(ENV_CONNECTION_H)
+#define ENV_CONNECTION_H
+
+#include
+#include
+#include
+
+#include "handle.h"
+#include "pvr_debug.h"
+#include "device.h"
+
+#if defined(SUPPORT_ION)
+#include PVR_ANDROID_ION_HEADER
+#include "ion_sys.h"
+#include "allocmem.h"
+#endif
+
+typedef struct _ENV_CONNECTION_PRIVATE_DATA_
+{
+ PVRSRV_DEVICE_NODE *psDevNode;
+} ENV_CONNECTION_PRIVATE_DATA;
+
+#if defined(SUPPORT_ION) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0))
+#define ION_CLIENT_NAME_SIZE 50
+
+typedef struct _ENV_ION_CONNECTION_DATA_
+{
+ IMG_CHAR azIonClientName[ION_CLIENT_NAME_SIZE];
+ struct ion_device *psIonDev;
+ struct ion_client *psIonClient;
+} ENV_ION_CONNECTION_DATA;
+#endif
+
+typedef struct _ENV_CONNECTION_DATA_
+{
+ pid_t owner;
+
+ PVRSRV_DEVICE_NODE *psDevNode;
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+ void *pvPvrSyncPrivateData;
+#endif
+
+#if defined(SUPPORT_ION) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0))
+ ENV_ION_CONNECTION_DATA *psIonData;
+#endif
+} ENV_CONNECTION_DATA;
+
+#endif /* !defined(ENV_CONNECTION_H) */
diff --git a/drivers/gpu/drm/img-rogue/event.c b/drivers/gpu/drm/img-rogue/event.c
new file mode 100644
index 000000000..aec0fc8a0
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/event.c
@@ -0,0 +1,514 @@
+/*************************************************************************/ /*!
+@File
+@Title Event Object
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,0)
+#include
+#endif
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "img_types.h"
+#include "img_defs.h"
+#include "pvrsrv_error.h"
+#include "allocmem.h"
+#include "event.h"
+#include "pvr_debug.h"
+#include "pvrsrv.h"
+#include "pvr_bridge_k.h"
+
+#include "osfunc.h"
+
+/* Uncomment to enable event object stats that are useful for debugging.
+ * The stats can be gotten at any time (during lifetime of event object)
+ * using OSEventObjectDumpdebugInfo API */
+// #define LINUX_EVENT_OBJECT_STATS
+
+
+typedef struct PVRSRV_LINUX_EVENT_OBJECT_LIST_TAG
+{
+ rwlock_t sLock;
+ /* Counts how many times event object was signalled i.e. how many times
+ * LinuxEventObjectSignal() was called on a given event object.
+ * Used for detecting pending signals.
+ * Note that this is in no way related to OS signals. */
+ atomic_t sEventSignalCount;
+ struct list_head sList;
+} PVRSRV_LINUX_EVENT_OBJECT_LIST;
+
+
+typedef struct PVRSRV_LINUX_EVENT_OBJECT_TAG
+{
+ IMG_UINT32 ui32EventSignalCountPrevious;
+#if defined(DEBUG)
+ IMG_UINT ui32Stats;
+#endif
+
+#ifdef LINUX_EVENT_OBJECT_STATS
+ POS_LOCK hLock;
+ IMG_UINT32 ui32ScheduleAvoided;
+ IMG_UINT32 ui32ScheduleCalled;
+ IMG_UINT32 ui32ScheduleSleptFully;
+ IMG_UINT32 ui32ScheduleSleptPartially;
+ IMG_UINT32 ui32ScheduleReturnedImmediately;
+#endif
+ wait_queue_head_t sWait;
+ struct list_head sList;
+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList;
+} PVRSRV_LINUX_EVENT_OBJECT;
+
+/*!
+******************************************************************************
+
+ @Function LinuxEventObjectListCreate
+
+ @Description
+
+ Linux wait object list creation
+
+ @Output hOSEventKM : Pointer to the event object list handle
+
+ @Return PVRSRV_ERROR : Error code
+
+******************************************************************************/
+PVRSRV_ERROR LinuxEventObjectListCreate(IMG_HANDLE *phEventObjectList)
+{
+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psEvenObjectList;
+
+ psEvenObjectList = OSAllocMem(sizeof(*psEvenObjectList));
+ if (psEvenObjectList == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectCreate: failed to allocate memory for event list"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ INIT_LIST_HEAD(&psEvenObjectList->sList);
+
+ rwlock_init(&psEvenObjectList->sLock);
+ atomic_set(&psEvenObjectList->sEventSignalCount, 0);
+
+ *phEventObjectList = (IMG_HANDLE *) psEvenObjectList;
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function LinuxEventObjectListDestroy
+
+ @Description
+
+ Linux wait object list destruction
+
+ @Input hOSEventKM : Event object list handle
+
+ @Return PVRSRV_ERROR : Error code
+
+******************************************************************************/
+PVRSRV_ERROR LinuxEventObjectListDestroy(IMG_HANDLE hEventObjectList)
+{
+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psEvenObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST *) hEventObjectList;
+
+ if (psEvenObjectList)
+ {
+ if (!list_empty(&psEvenObjectList->sList))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectListDestroy: Event List is not empty"));
+ return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT;
+ }
+ OSFreeMem(psEvenObjectList);
+ /*not nulling pointer, copy on stack*/
+ }
+ return PVRSRV_OK;
+}
+
+
+/*!
+******************************************************************************
+
+ @Function LinuxEventObjectDelete
+
+ @Description
+
+ Linux wait object removal
+
+ @Input hOSEventObject : Event object handle
+
+ @Return PVRSRV_ERROR : Error code
+
+******************************************************************************/
+PVRSRV_ERROR LinuxEventObjectDelete(IMG_HANDLE hOSEventObject)
+{
+ if (hOSEventObject)
+ {
+ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)hOSEventObject;
+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = psLinuxEventObject->psLinuxEventObjectList;
+
+ write_lock_bh(&psLinuxEventObjectList->sLock);
+ list_del(&psLinuxEventObject->sList);
+ write_unlock_bh(&psLinuxEventObjectList->sLock);
+
+#ifdef LINUX_EVENT_OBJECT_STATS
+ OSLockDestroy(psLinuxEventObject->hLock);
+#endif
+
+#if defined(DEBUG)
+// PVR_DPF((PVR_DBG_MESSAGE, "LinuxEventObjectDelete: Event object waits: %u", psLinuxEventObject->ui32Stats));
+#endif
+
+ OSFreeMem(psLinuxEventObject);
+ /*not nulling pointer, copy on stack*/
+
+ return PVRSRV_OK;
+ }
+ return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT;
+}
+
+/*!
+******************************************************************************
+
+ @Function LinuxEventObjectAdd
+
+ @Description
+
+ Linux wait object addition
+
+ @Input hOSEventObjectList : Event object list handle
+ @Output phOSEventObject : Pointer to the event object handle
+
+ @Return PVRSRV_ERROR : Error code
+
+******************************************************************************/
+PVRSRV_ERROR LinuxEventObjectAdd(IMG_HANDLE hOSEventObjectList, IMG_HANDLE *phOSEventObject)
+ {
+ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject;
+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList;
+
+ /* allocate completion variable */
+ psLinuxEventObject = OSAllocMem(sizeof(*psLinuxEventObject));
+ if (psLinuxEventObject == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: failed to allocate memory"));
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ INIT_LIST_HEAD(&psLinuxEventObject->sList);
+
+ /* Start with the timestamp at which event object was added to the list */
+ psLinuxEventObject->ui32EventSignalCountPrevious = atomic_read(&psLinuxEventObjectList->sEventSignalCount);
+
+#ifdef LINUX_EVENT_OBJECT_STATS
+ PVR_LOG_RETURN_IF_ERROR(OSLockCreate(&psLinuxEventObject->hLock), "OSLockCreate");
+ psLinuxEventObject->ui32ScheduleAvoided = 0;
+ psLinuxEventObject->ui32ScheduleCalled = 0;
+ psLinuxEventObject->ui32ScheduleSleptFully = 0;
+ psLinuxEventObject->ui32ScheduleSleptPartially = 0;
+ psLinuxEventObject->ui32ScheduleReturnedImmediately = 0;
+#endif
+
+#if defined(DEBUG)
+ psLinuxEventObject->ui32Stats = 0;
+#endif
+ init_waitqueue_head(&psLinuxEventObject->sWait);
+
+ psLinuxEventObject->psLinuxEventObjectList = psLinuxEventObjectList;
+
+ write_lock_bh(&psLinuxEventObjectList->sLock);
+ list_add(&psLinuxEventObject->sList, &psLinuxEventObjectList->sList);
+ write_unlock_bh(&psLinuxEventObjectList->sLock);
+
+ *phOSEventObject = psLinuxEventObject;
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function LinuxEventObjectSignal
+
+ @Description
+
+ Linux wait object signaling function
+
+ @Input hOSEventObjectList : Event object list handle
+
+ @Return PVRSRV_ERROR : Error code
+
+******************************************************************************/
+PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList)
+{
+ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject;
+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList;
+ struct list_head *psListEntry, *psListEntryTemp, *psList;
+ psList = &psLinuxEventObjectList->sList;
+
+ /* Move the timestamp ahead for this call, so a potential "Wait" from any
+ * EventObject/s doesn't wait for the signal to occur before returning. Early
+ * setting/incrementing of timestamp reduces the window where a concurrent
+ * "Wait" call might block while "this" Signal call is being processed */
+ atomic_inc(&psLinuxEventObjectList->sEventSignalCount);
+
+ read_lock_bh(&psLinuxEventObjectList->sLock);
+ list_for_each_safe(psListEntry, psListEntryTemp, psList)
+ {
+ psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)list_entry(psListEntry, PVRSRV_LINUX_EVENT_OBJECT, sList);
+ wake_up_interruptible(&psLinuxEventObject->sWait);
+ }
+ read_unlock_bh(&psLinuxEventObjectList->sLock);
+
+ return PVRSRV_OK;
+}
+
+static void _TryToFreeze(void)
+{
+ /* if we reach zero it means that all of the threads called try_to_freeze */
+ LinuxBridgeNumActiveKernelThreadsDecrement();
+
+ /* Returns true if the thread was frozen, should we do anything with this
+ * information? What do we return? Which one is the error case? */
+ try_to_freeze();
+
+ LinuxBridgeNumActiveKernelThreadsIncrement();
+}
+
+void LinuxEventObjectDumpDebugInfo(IMG_HANDLE hOSEventObject)
+{
+#ifdef LINUX_EVENT_OBJECT_STATS
+ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)hOSEventObject;
+
+ OSLockAcquire(psLinuxEventObject->hLock);
+ PVR_LOG(("%s: EvObj(%p) schedule: Avoided(%u) Called(%u) ReturnedImmediately(%u) SleptFully(%u) SleptPartially(%u)",
+ __func__, psLinuxEventObject, psLinuxEventObject->ui32ScheduleAvoided,
+ psLinuxEventObject->ui32ScheduleCalled, psLinuxEventObject->ui32ScheduleReturnedImmediately,
+ psLinuxEventObject->ui32ScheduleSleptFully, psLinuxEventObject->ui32ScheduleSleptPartially));
+ OSLockRelease(psLinuxEventObject->hLock);
+#else
+ PVR_LOG(("%s: LINUX_EVENT_OBJECT_STATS disabled!", __func__));
+#endif
+}
+
+/*!
+******************************************************************************
+
+ @Function LinuxEventObjectWait
+
+ @Description
+
+ Linux wait object routine
+
+ @Input hOSEventObject : Event object handle
+
+ @Input ui64Timeoutus : Time out value in usec
+
+ @Return PVRSRV_ERROR : Error code
+
+******************************************************************************/
+PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject,
+ IMG_UINT64 ui64Timeoutus,
+ IMG_BOOL bFreezable)
+{
+ IMG_UINT32 ui32EventSignalCount;
+ PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+ IMG_UINT32 ui32Remainder;
+ long timeOutJiffies;
+#ifdef LINUX_EVENT_OBJECT_STATS
+ long totalTimeoutJiffies;
+ IMG_BOOL bScheduleCalled = IMG_FALSE;
+#endif
+
+ DEFINE_WAIT(sWait);
+
+ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *) hOSEventObject;
+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = psLinuxEventObject->psLinuxEventObjectList;
+
+ /* Check if the driver is good shape */
+ if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
+ {
+ return PVRSRV_ERROR_TIMEOUT;
+ }
+
+ /* usecs_to_jiffies only takes an uint. So if our timeout is bigger than an
+ * uint use the msec version. With such a long timeout we really don't need
+ * the high resolution of usecs. */
+ if (ui64Timeoutus > 0xffffffffULL)
+ timeOutJiffies = msecs_to_jiffies(OSDivide64(ui64Timeoutus, 1000, &ui32Remainder));
+ else
+ timeOutJiffies = usecs_to_jiffies(ui64Timeoutus);
+
+#ifdef LINUX_EVENT_OBJECT_STATS
+ totalTimeoutJiffies = timeOutJiffies;
+#endif
+
+ do
+ {
+ prepare_to_wait(&psLinuxEventObject->sWait, &sWait, TASK_INTERRUPTIBLE);
+ ui32EventSignalCount = (IMG_UINT32) atomic_read(&psLinuxEventObjectList->sEventSignalCount);
+
+ if (psLinuxEventObject->ui32EventSignalCountPrevious != ui32EventSignalCount)
+ {
+ /* There is a pending event signal i.e. LinuxEventObjectSignal()
+ * was called on the event object since the last time we checked.
+ * Return without waiting. */
+ break;
+ }
+
+ if (signal_pending(current))
+ {
+ /* There is an OS signal pending so return.
+ * This allows to kill/interrupt user space processes which
+ * are waiting on this event object. */
+ break;
+ }
+
+#ifdef LINUX_EVENT_OBJECT_STATS
+ bScheduleCalled = IMG_TRUE;
+#endif
+ timeOutJiffies = schedule_timeout(timeOutJiffies);
+
+ if (bFreezable)
+ {
+ _TryToFreeze();
+ }
+
+#if defined(DEBUG)
+ psLinuxEventObject->ui32Stats++;
+#endif
+
+
+ } while (timeOutJiffies);
+
+ finish_wait(&psLinuxEventObject->sWait, &sWait);
+
+ psLinuxEventObject->ui32EventSignalCountPrevious = ui32EventSignalCount;
+
+#ifdef LINUX_EVENT_OBJECT_STATS
+ OSLockAcquire(psLinuxEventObject->hLock);
+ if (bScheduleCalled)
+ {
+ psLinuxEventObject->ui32ScheduleCalled++;
+ if (totalTimeoutJiffies == timeOutJiffies)
+ {
+ psLinuxEventObject->ui32ScheduleReturnedImmediately++;
+ }
+ else if (timeOutJiffies == 0)
+ {
+ psLinuxEventObject->ui32ScheduleSleptFully++;
+ }
+ else
+ {
+ psLinuxEventObject->ui32ScheduleSleptPartially++;
+ }
+ }
+ else
+ {
+ psLinuxEventObject->ui32ScheduleAvoided++;
+ }
+ OSLockRelease(psLinuxEventObject->hLock);
+#endif
+
+ if (signal_pending(current))
+ {
+ return PVRSRV_ERROR_INTERRUPTED;
+ }
+ else
+ {
+ return timeOutJiffies ? PVRSRV_OK : PVRSRV_ERROR_TIMEOUT;
+ }
+}
+
+#if defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP)
+
+PVRSRV_ERROR LinuxEventObjectWaitUntilSignalled(IMG_HANDLE hOSEventObject)
+{
+ PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+ DEFINE_WAIT(sWait);
+
+ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject =
+ (PVRSRV_LINUX_EVENT_OBJECT *) hOSEventObject;
+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList =
+ psLinuxEventObject->psLinuxEventObjectList;
+
+ /* Check if the driver is in good shape */
+ if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
+ {
+ return PVRSRV_ERROR_TIMEOUT;
+ }
+
+ prepare_to_wait(&psLinuxEventObject->sWait, &sWait, TASK_INTERRUPTIBLE);
+
+ if (psLinuxEventObject->ui32EventSignalCountPrevious !=
+ (IMG_UINT32) atomic_read(&psLinuxEventObjectList->sEventSignalCount))
+ {
+ /* There is a pending signal, so return without waiting */
+ goto finish;
+ }
+
+ schedule();
+
+ _TryToFreeze();
+
+finish:
+ finish_wait(&psLinuxEventObject->sWait, &sWait);
+
+ psLinuxEventObject->ui32EventSignalCountPrevious =
+ (IMG_UINT32) atomic_read(&psLinuxEventObjectList->sEventSignalCount);
+
+ return PVRSRV_OK;
+}
+
+#endif /* defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP) */
diff --git a/drivers/gpu/drm/img-rogue/event.h b/drivers/gpu/drm/img-rogue/event.h
new file mode 100644
index 000000000..bb378cb92
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/event.h
@@ -0,0 +1,54 @@
+/*************************************************************************/ /*!
+@File
+@Title Event Object
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+PVRSRV_ERROR LinuxEventObjectListCreate(IMG_HANDLE *phEventObjectList);
+PVRSRV_ERROR LinuxEventObjectListDestroy(IMG_HANDLE hEventObjectList);
+PVRSRV_ERROR LinuxEventObjectAdd(IMG_HANDLE hOSEventObjectList, IMG_HANDLE *phOSEventObject);
+PVRSRV_ERROR LinuxEventObjectDelete(IMG_HANDLE hOSEventObject);
+PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList);
+PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject,
+ IMG_UINT64 ui64Timeoutus,
+ IMG_BOOL bFreezable);
+#if defined(PVRSRV_SERVER_THREADS_INDEFINITE_SLEEP)
+PVRSRV_ERROR LinuxEventObjectWaitUntilSignalled(IMG_HANDLE hOSEventObject);
+#endif
+void LinuxEventObjectDumpDebugInfo(IMG_HANDLE hOSEventObject);
diff --git a/drivers/gpu/drm/img-rogue/fwload.c b/drivers/gpu/drm/img-rogue/fwload.c
new file mode 100644
index 000000000..35e52af56
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/fwload.c
@@ -0,0 +1,255 @@
+/*************************************************************************/ /*!
+@File
+@Title Services firmware load and access routines for Linux
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Device specific functions
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include
+#include
+#include
+#include
+
+#include "device.h"
+#include "module_common.h"
+#include "fwload.h"
+#include "pvr_debug.h"
+#include "srvkm.h"
+
+#if defined(RGX_FW_SIGNED)
+
+#include
+#include
+#include
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
+#include
+#else
+#define PKEY_ID_PKCS7 2
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) */
+
+#include "signfw.h"
+#endif /* RGX_FW_SIGNED */
+
+struct OS_FW_IMAGE_t
+{
+ const struct firmware *psFW;
+ size_t uSignatureSize;
+};
+
+#if defined(RGX_FW_SIGNED)
+
+static int OSCheckSignature(const struct FirmwareSignatureHeader *psHeader, size_t uSize)
+{
+ if (be32_to_cpu(psHeader->ui32SignatureLen) >= uSize - sizeof(*psHeader))
+ {
+ return -EBADMSG;
+ }
+
+ if (psHeader->ui8IDType != PKEY_ID_PKCS7)
+ {
+ return -ENOPKG;
+ }
+
+ if (psHeader->ui8Algo != 0 || psHeader->ui8HashAlgo != 0 ||
+ psHeader->ui8SignerLen != 0 || psHeader->ui8KeyIDLen != 0 ||
+ psHeader->__ui8Padding[0] != 0 || psHeader->__ui8Padding[1] != 0 ||
+ psHeader->__ui8Padding[2] != 0)
+ {
+ return -EBADMSG;
+ }
+
+ return 0;
+}
+
+bool OSVerifyFirmware(OS_FW_IMAGE *psFWImage)
+{
+ const struct firmware *psFW = psFWImage->psFW;
+ const u8 *pui8FWData = psFW->data;
+ size_t uFWSize = psFW->size;
+ uint32_t ui32MagicLen = sizeof(MODULE_SIG_STRING) - 1;
+ struct FirmwareSignatureHeader sHeader;
+ int err;
+
+ if (uFWSize <= ui32MagicLen)
+ {
+ return false;
+ }
+
+ /*
+ * Linux Kernel's sign-file utility is primarily intended for signing
+ * modules, and so appends the MODULE_SIG_STRING magic at the end of
+ * the signature. Only proceed with verification if this magic is found.
+ */
+ if (memcmp(pui8FWData + uFWSize - ui32MagicLen, MODULE_SIG_STRING, ui32MagicLen) != 0)
+ {
+ return false;
+ }
+
+ uFWSize -= ui32MagicLen;
+ if (uFWSize <= sizeof(sHeader))
+ {
+ return false;
+ }
+
+ /*
+ * After the magic, a header is placed which informs about the digest /
+ * crypto algorithm etc. Copy that header and ensure that it has valid
+ * contents (We only support RSA Crypto, SHA Hash, X509 certificate and
+ * PKCS#7 signature).
+ */
+ memcpy(&sHeader, pui8FWData + (uFWSize - sizeof(sHeader)), sizeof(sHeader));
+ if (OSCheckSignature(&sHeader, uFWSize) != 0)
+ {
+ return false;
+ }
+
+ /*
+ * As all information is now extracted, we can go ahead and ask PKCS
+ * module to verify the sign.
+ */
+ uFWSize -= be32_to_cpu(sHeader.ui32SignatureLen) + sizeof(sHeader);
+ err = verify_pkcs7_signature(pui8FWData, uFWSize, pui8FWData + uFWSize,
+ be32_to_cpu(sHeader.ui32SignatureLen), NULL,
+ VERIFYING_UNSPECIFIED_SIGNATURE, NULL, NULL);
+ if (err == 0)
+ {
+ psFWImage->uSignatureSize = psFW->size - uFWSize;
+ PVR_DPF((PVR_DBG_MESSAGE, "%s: Firmware Successfully Verified",
+ __func__));
+ return true;
+ }
+
+ PVR_DPF((PVR_DBG_WARNING, "%s: Firmware Verification Failed (%d)",
+ __func__, err));
+ return false;
+}
+
+#else /* defined(RGX_FW_SIGNED) */
+
+inline bool OSVerifyFirmware(OS_FW_IMAGE *psFWImage)
+{
+ return true;
+}
+
+#endif /* defined(RGX_FW_SIGNED) */
+
+PVRSRV_ERROR
+OSLoadFirmware(PVRSRV_DEVICE_NODE *psDeviceNode, const IMG_CHAR *pszBVNCString,
+ bool (*pfnVerifyFirmware)(OS_FW_IMAGE*), OS_FW_IMAGE **ppsFWImage)
+{
+ const struct firmware *psFW = NULL;
+ OS_FW_IMAGE *psFWImage;
+ IMG_INT32 res;
+ PVRSRV_ERROR eError;
+
+ res = request_firmware(&psFW, pszBVNCString, psDeviceNode->psDevConfig->pvOSDevice);
+ if (res != 0)
+ {
+ release_firmware(psFW);
+ if (res == -ENOENT)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: request_firmware('%s') not found (%d)",
+ __func__, pszBVNCString, res));
+ eError = PVRSRV_ERROR_NOT_FOUND;
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: request_firmware('%s') not ready (%d)",
+ __func__, pszBVNCString, res));
+ eError = PVRSRV_ERROR_NOT_READY;
+ }
+ goto err_exit;
+ }
+
+ psFWImage = OSAllocZMem(sizeof(*psFWImage));
+ if (psFWImage == NULL)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: OSAllocZMem('%s') failed.",
+ __func__, pszBVNCString));
+
+ release_firmware(psFW);
+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;
+ goto err_exit;
+ }
+
+ psFWImage->psFW = psFW;
+ if (pfnVerifyFirmware != NULL && !pfnVerifyFirmware(psFWImage))
+ {
+ release_firmware(psFW);
+ OSFreeMem(psFWImage);
+ eError = PVRSRV_ERROR_NOT_AUTHENTICATED;
+ goto err_exit;
+ }
+
+ *ppsFWImage = psFWImage;
+ return PVRSRV_OK;
+
+err_exit:
+ *ppsFWImage = NULL;
+ return eError;
+}
+
+void
+OSUnloadFirmware(OS_FW_IMAGE *psFWImage)
+{
+ const struct firmware *psFW = psFWImage->psFW;
+
+ release_firmware(psFW);
+ OSFreeMem(psFWImage);
+}
+
+size_t
+OSFirmwareSize(OS_FW_IMAGE *psFWImage)
+{
+ const struct firmware *psFW = psFWImage->psFW;
+ return psFW->size - psFWImage->uSignatureSize;
+}
+
+const void *
+OSFirmwareData(OS_FW_IMAGE *psFWImage)
+{
+ const struct firmware *psFW = psFWImage->psFW;
+
+ return psFW->data;
+}
+
+/******************************************************************************
+ End of file (fwload.c)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/fwload.h b/drivers/gpu/drm/img-rogue/fwload.h
new file mode 100644
index 000000000..08e7f533b
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/fwload.h
@@ -0,0 +1,158 @@
+/*************************************************************************/ /*!
+@File
+@Title Services RGX OS Interface for loading the firmware
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description This file defines the OS interface through which the RGX
+ device initialisation code in the kernel/server will obtain
+ the RGX firmware binary image. The API is used during the
+ initialisation of an RGX device via the
+ PVRSRVCommonDeviceInitialise()
+ call sequence.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef FWLOAD_H
+#define FWLOAD_H
+
+#include "img_defs.h"
+#include "device_connection.h"
+#include "device.h"
+
+/*! Opaque type handle defined and known to the OS layer implementation of this
+ * fwload.h OS API. This private data is allocated in the implementation of
+ * OSLoadFirmware() and contains whatever data and information needed to be
+ * able to acquire and return the firmware binary image to the Services
+ * kernel/server during initialisation.
+ * It is no longer required and may be freed when OSUnloadFirmware() is called.
+ */
+typedef struct OS_FW_IMAGE_t OS_FW_IMAGE;
+
+#if defined(__linux__)
+
+bool OSVerifyFirmware(OS_FW_IMAGE* psFWImage);
+
+#endif
+
+/*************************************************************************/ /*!
+@Function OSLoadFirmware
+@Description The OS implementation must load or acquire the firmware (FW)
+ image binary needed by the driver stack.
+ A handle to the common layer device node is given to identify
+ which device instance in the system is being initialised. The
+ BVNC string is also supplied so that the implementation knows
+ which FW image to retrieve since each FW image only supports one
+ GPU type/revision.
+ The calling server code supports multiple GPU types and revisions
+ and will detect the specific GPU type and revision before calling
+ this API. It will also have runtime configuration of the VZ mode,
+ hence this API must be able to retrieve different FW binary
+ images based on the pszBVNCString given. The purpose of the end
+ platform/system is key to understand which FW images must be
+ available to the kernel server.
+ On exit the implementation must return a pointer to some private
+ data it uses to hold the FW image information and data. It will
+ be passed onto later API calls by the kernel server code.
+ NULL should be returned if the FW image could not be retrieved.
+ The format of the BVNC string is as follows ([x] denotes
+ optional field):
+ "rgx.fw[.signed].B.V[p].N.C[.vz]"
+ The implementation must first try to load the FW identified
+ by the pszBVpNCString parameter. If this is not available then it
+ should drop back to retrieving the FW identified by the
+ pszBVNCString parameter. The fields in the string are:
+ B, V, N, C are all unsigned integer identifying type/revision.
+ [.signed] is present when RGX_FW_SIGNED=1 is defined in the
+ server build.
+ [p] denotes a provisional (pre-silicon) GPU configuration.
+ [.vz] is present when the kernel server is loaded on the HOST
+ of a virtualised platform. See the DriverMode server
+ AppHint for details.
+
+@Input psDeviceNode Device instance identifier.
+@Input pszBVNCString Identifier string of the FW image to
+ be loaded/acquired in production driver.
+@Input pfnVerifyFirmware Callback which checks validity of FW image.
+@Output ppsFWImage Ptr to private data on success,
+ NULL otherwise.
+@Return PVRSRV_ERROR PVRSRV_OK on success,
+ PVRSRV_ERROR_NOT_READY if filesystem is not
+ ready/initialised,
+ PVRSRV_ERROR_NOT_FOUND if no suitable FW
+ image could be found
+ PVRSRV_ERROR_OUT_OF_MEMORY if unable to alloc
+ memory for FW image
+ PVRSRV_ERROR_NOT_AUTHENTICATED if FW image
+ cannot be verified.
+*/ /**************************************************************************/
+PVRSRV_ERROR OSLoadFirmware(PVRSRV_DEVICE_NODE *psDeviceNode,
+ const IMG_CHAR *pszBVNCString,
+ bool (*pfnVerifyFirmware)(OS_FW_IMAGE*),
+ OS_FW_IMAGE **ppsFWImage);
+
+/*************************************************************************/ /*!
+@Function OSFirmwareData
+@Description This function returns a pointer to the start of the FW image
+ binary data held in memory. It must remain valid until
+ OSUnloadFirmware() is called.
+@Input psFWImage Private data opaque handle
+@Return void* Ptr to FW binary image to start on GPU.
+*/ /**************************************************************************/
+const void* OSFirmwareData(OS_FW_IMAGE *psFWImage);
+
+/*************************************************************************/ /*!
+@Function OSFirmwareSize
+@Description This function returns the size of the FW image binary data.
+@Input psFWImage Private data opaque handle
+@Return size_t Size in bytes of the firmware binary image
+*/ /**************************************************************************/
+size_t OSFirmwareSize(OS_FW_IMAGE *psFWImage);
+
+/*************************************************************************/ /*!
+@Function OSUnloadFirmware
+@Description This is called when the server has completed firmware
+ initialisation and no longer needs the private data, possibly
+ allocated by OSLoadFirmware().
+@Input psFWImage Private data opaque handle
+*/ /**************************************************************************/
+void OSUnloadFirmware(OS_FW_IMAGE *psFWImage);
+
+#endif /* FWLOAD_H */
+
+/******************************************************************************
+ End of file (fwload.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/fwtrace_string.h b/drivers/gpu/drm/img-rogue/fwtrace_string.h
new file mode 100644
index 000000000..a2ab95c3a
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/fwtrace_string.h
@@ -0,0 +1,52 @@
+/*************************************************************************/ /*!
+@File fwtrace_string.h
+@Title RGX Firmware trace strings for KM
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Platform Generic
+@Description This file defines SFs tuple.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef KM_TRACE_STRING_H
+#define KM_TRACE_STRING_H
+
+#include "rgx_fwif_sf.h"
+
+extern const RGXKM_STID_FMT SFs[];
+extern const IMG_UINT32 g_ui32SFsCount;
+
+#endif /* KM_TRACE_STRING_H */
diff --git a/drivers/gpu/drm/img-rogue/handle.c b/drivers/gpu/drm/img-rogue/handle.c
new file mode 100644
index 000000000..baa11f6fc
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/handle.c
@@ -0,0 +1,2300 @@
+/*************************************************************************/ /*!
+@File
+@Title Resource Handle Manager
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Provide resource handle management
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+/* See handle.h for a description of the handle API. */
+
+/*
+ * The implementation supports movable handle structures, allowing the address
+ * of a handle structure to change without having to fix up pointers in
+ * any of the handle structures. For example, the linked list mechanism
+ * used to link subhandles together uses handle array indices rather than
+ * pointers to the structures themselves.
+ */
+
+#if defined(__linux__)
+#include
+#else
+#include
+#endif
+
+#include "img_defs.h"
+#include "handle.h"
+#include "handle_impl.h"
+#include "allocmem.h"
+#include "pvr_debug.h"
+#include "connection_server.h"
+#include "pvrsrv.h"
+
+#define HANDLE_HASH_TAB_INIT_SIZE 32
+
+#define TEST_FLAG(v, f) BITMASK_HAS(v, f)
+#define TEST_ALLOC_FLAG(psHandleData, f) BITMASK_HAS((psHandleData)->eFlag, f)
+
+
+/* Linked list structure. Used for both the list head and list items */
+typedef struct _HANDLE_LIST_
+{
+ IMG_HANDLE hPrev;
+ IMG_HANDLE hNext;
+ IMG_HANDLE hParent;
+} HANDLE_LIST;
+
+typedef struct _HANDLE_DATA_
+{
+ /* The handle that represents this structure */
+ IMG_HANDLE hHandle;
+
+ /* Handle type */
+ PVRSRV_HANDLE_TYPE eType;
+
+ /* Flags specified when the handle was allocated */
+ PVRSRV_HANDLE_ALLOC_FLAG eFlag;
+
+ /* Pointer to the data that the handle represents */
+ void *pvData;
+
+ /*
+ * Callback specified at handle allocation time to
+ * release/destroy/free the data represented by the
+ * handle when it's reference count reaches 0. This
+ * should always be NULL for subhandles.
+ */
+ PFN_HANDLE_RELEASE pfnReleaseData;
+
+ /* List head for subhandles of this handle */
+ HANDLE_LIST sChildren;
+
+ /* List entry for sibling subhandles */
+ HANDLE_LIST sSiblings;
+
+ /* Reference count. The pfnReleaseData callback gets called when the
+ * reference count hits zero
+ */
+ IMG_UINT32 ui32RefCount;
+
+#if defined(PVRSRV_DEBUG_HANDLE_LOCK)
+ /* Store the handle base used for this handle, so we
+ * can later access the handle base lock (or check if
+ * it has been already acquired)
+ */
+ PVRSRV_HANDLE_BASE *psBase;
+#endif
+
+} HANDLE_DATA;
+
+struct _HANDLE_BASE_
+{
+ /* Pointer to a handle implementations base structure */
+ HANDLE_IMPL_BASE *psImplBase;
+
+ /*
+ * Pointer to handle hash table.
+ * The hash table is used to do reverse lookups, converting data
+ * pointers to handles.
+ */
+ HASH_TABLE *psHashTab;
+
+ /* Type specific (connection/global/process) Lock handle */
+ POS_LOCK hLock;
+
+ /* Can be connection, process, global */
+ PVRSRV_HANDLE_BASE_TYPE eType;
+};
+
+/*
+ * The key for the handle hash table is an array of three elements, the
+ * pointer to the resource, the resource type and the parent handle (or
+ * NULL if there is no parent). The eHandKey enumeration gives the
+ * array indices of the elements making up the key.
+ */
+enum eHandKey
+{
+ HAND_KEY_DATA = 0,
+ HAND_KEY_TYPE,
+ HAND_KEY_PARENT,
+ HAND_KEY_LEN /* Must be last item in list */
+};
+
+/* HAND_KEY is the type of the hash table key */
+typedef uintptr_t HAND_KEY[HAND_KEY_LEN];
+
+typedef struct FREE_HANDLE_DATA_TAG
+{
+ PVRSRV_HANDLE_BASE *psBase;
+ PVRSRV_HANDLE_TYPE eHandleFreeType;
+ /* timing data (ns) to release bridge lock upon the deadline */
+ IMG_UINT64 ui64TimeStart;
+ IMG_UINT64 ui64MaxBridgeTime;
+} FREE_HANDLE_DATA;
+
+typedef struct FREE_KERNEL_HANDLE_DATA_TAG
+{
+ PVRSRV_HANDLE_BASE *psBase;
+ HANDLE_DATA *psProcessHandleData;
+ IMG_HANDLE hKernelHandle;
+} FREE_KERNEL_HANDLE_DATA;
+
+/* Stores a pointer to the function table of the handle back-end in use */
+static HANDLE_IMPL_FUNCTAB const *gpsHandleFuncs;
+
+static POS_LOCK gKernelHandleLock;
+static IMG_BOOL gbLockInitialised = IMG_FALSE;
+
+void LockHandle(PVRSRV_HANDLE_BASE *psBase)
+{
+ OSLockAcquire(psBase->hLock);
+}
+
+void UnlockHandle(PVRSRV_HANDLE_BASE *psBase)
+{
+ OSLockRelease(psBase->hLock);
+}
+
+/*
+ * Kernel handle base structure. This is used for handles that are not
+ * allocated on behalf of a particular process.
+ */
+PVRSRV_HANDLE_BASE *gpsKernelHandleBase = NULL;
+
+/* Increase the reference count on the given handle.
+ * The handle lock must already be acquired.
+ * Returns: the reference count after the increment
+ */
+static inline IMG_UINT32 _HandleRef(HANDLE_DATA *psHandleData)
+{
+#if defined(PVRSRV_DEBUG_HANDLE_LOCK)
+ if (!OSLockIsLocked(psHandleData->psBase->hLock))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Handle lock is not locked", __func__));
+ OSDumpStack();
+ }
+#endif
+ psHandleData->ui32RefCount++;
+ return psHandleData->ui32RefCount;
+}
+
+/* Decrease the reference count on the given handle.
+ * The handle lock must already be acquired.
+ * Returns: the reference count after the decrement
+ */
+static inline IMG_UINT32 _HandleUnref(HANDLE_DATA *psHandleData)
+{
+#if defined(PVRSRV_DEBUG_HANDLE_LOCK)
+ if (!OSLockIsLocked(psHandleData->psBase->hLock))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Handle lock is not locked", __func__));
+ OSDumpStack();
+ }
+#endif
+ PVR_ASSERT(psHandleData->ui32RefCount > 0);
+ psHandleData->ui32RefCount--;
+
+ return psHandleData->ui32RefCount;
+}
+
+#if defined(PVRSRV_NEED_PVR_DPF)
+static const IMG_CHAR *HandleTypeToString(PVRSRV_HANDLE_TYPE eType)
+{
+ #define HANDLETYPE(x) \
+ case PVRSRV_HANDLE_TYPE_##x: \
+ return #x;
+ switch (eType)
+ {
+ #include "handle_types.h"
+ #undef HANDLETYPE
+
+ default:
+ return "INVALID";
+ }
+}
+
+static const IMG_CHAR *HandleBaseTypeToString(PVRSRV_HANDLE_BASE_TYPE eType)
+{
+ #define HANDLEBASETYPE(x) \
+ case PVRSRV_HANDLE_BASE_TYPE_##x: \
+ return #x;
+ switch (eType)
+ {
+ HANDLEBASETYPE(CONNECTION);
+ HANDLEBASETYPE(PROCESS);
+ HANDLEBASETYPE(GLOBAL);
+ #undef HANDLEBASETYPE
+
+ default:
+ return "INVALID";
+ }
+}
+#endif
+
+/*!
+*******************************************************************************
+ @Function GetHandleData
+ @Description Get the handle data structure for a given handle
+ @Input psBase - pointer to handle base structure
+ hHandle - handle from client
+ eType - handle type or PVRSRV_HANDLE_TYPE_NONE if the handle
+ type is not to be checked.
+ @Output ppsHandleData - pointer to a pointer to the handle data struct
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(GetHandleData)
+#endif
+static INLINE
+PVRSRV_ERROR GetHandleData(PVRSRV_HANDLE_BASE *psBase,
+ HANDLE_DATA **ppsHandleData,
+ IMG_HANDLE hHandle,
+ PVRSRV_HANDLE_TYPE eType)
+{
+ HANDLE_DATA *psHandleData;
+ PVRSRV_ERROR eError;
+
+ eError = gpsHandleFuncs->pfnGetHandleData(psBase->psImplBase,
+ hHandle,
+ (void **)&psHandleData);
+ PVR_RETURN_IF_ERROR(eError);
+
+ /*
+ * Unless PVRSRV_HANDLE_TYPE_NONE was passed in to this function,
+ * check handle is of the correct type.
+ */
+ if (unlikely(eType != PVRSRV_HANDLE_TYPE_NONE && eType != psHandleData->eType))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "GetHandleData: Type mismatch. Lookup request: Handle %p, type: %s (%u) but stored handle is type %s (%u)",
+ hHandle,
+ HandleTypeToString(eType),
+ eType,
+ HandleTypeToString(psHandleData->eType),
+ psHandleData->eType));
+ return PVRSRV_ERROR_HANDLE_TYPE_MISMATCH;
+ }
+
+ /* Return the handle structure */
+ *ppsHandleData = psHandleData;
+
+ return PVRSRV_OK;
+}
+
+/*!
+*******************************************************************************
+ @Function HandleListInit
+ @Description Initialise a linked list structure embedded in a handle
+ structure.
+ @Input hHandle - handle containing the linked list structure
+ psList - pointer to linked list structure
+ hParent - parent handle or NULL
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListInit)
+#endif
+static INLINE
+void HandleListInit(IMG_HANDLE hHandle, HANDLE_LIST *psList, IMG_HANDLE hParent)
+{
+ psList->hPrev = hHandle;
+ psList->hNext = hHandle;
+ psList->hParent = hParent;
+}
+
+/*!
+*******************************************************************************
+ @Function InitParentList
+ @Description Initialise the children list head in a handle structure.
+ The children are the subhandles of this handle.
+ @Input psHandleData - pointer to handle data structure
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(InitParentList)
+#endif
+static INLINE
+void InitParentList(HANDLE_DATA *psHandleData)
+{
+ IMG_HANDLE hParent = psHandleData->hHandle;
+
+ HandleListInit(hParent, &psHandleData->sChildren, hParent);
+}
+
+/*!
+*******************************************************************************
+
+ @Function InitChildEntry
+ @Description Initialise the child list entry in a handle structure. The list
+ entry is used to link together subhandles of a given handle.
+ @Input psHandleData - pointer to handle data structure
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(InitChildEntry)
+#endif
+static INLINE
+void InitChildEntry(HANDLE_DATA *psHandleData)
+{
+ HandleListInit(psHandleData->hHandle, &psHandleData->sSiblings, NULL);
+}
+
+/*!
+*******************************************************************************
+ @Function HandleListIsEmpty
+ @Description Determine whether a given linked list is empty.
+ @Input hHandle - handle containing the list head
+ psList - pointer to the list head
+ @Return IMG_TRUE if the list is empty, IMG_FALSE if it isn't.
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListIsEmpty)
+#endif
+static INLINE
+IMG_BOOL HandleListIsEmpty(IMG_HANDLE hHandle, HANDLE_LIST *psList) /* Instead of passing in the handle can we not just do (psList->hPrev == psList->hNext) ? IMG_TRUE : IMG_FALSE ??? */
+{
+ IMG_BOOL bIsEmpty;
+
+ bIsEmpty = (IMG_BOOL)(psList->hNext == hHandle);
+
+#ifdef DEBUG
+ {
+ IMG_BOOL bIsEmpty2;
+
+ bIsEmpty2 = (IMG_BOOL)(psList->hPrev == hHandle);
+ PVR_ASSERT(bIsEmpty == bIsEmpty2);
+ }
+#endif
+
+ return bIsEmpty;
+}
+
+#ifdef DEBUG
+/*!
+*******************************************************************************
+ @Function NoChildren
+ @Description Determine whether a handle has any subhandles
+ @Input psHandleData - pointer to handle data structure
+ @Return IMG_TRUE if the handle has no subhandles, IMG_FALSE if it does.
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(NoChildren)
+#endif
+static INLINE
+IMG_BOOL NoChildren(HANDLE_DATA *psHandleData)
+{
+ PVR_ASSERT(psHandleData->sChildren.hParent == psHandleData->hHandle);
+
+ return HandleListIsEmpty(psHandleData->hHandle, &psHandleData->sChildren);
+}
+
+/*!
+*******************************************************************************
+ @Function NoParent
+ @Description Determine whether a handle is a subhandle
+ @Input psHandleData - pointer to handle data structure
+ @Return IMG_TRUE if the handle is not a subhandle, IMG_FALSE if it is.
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(NoParent)
+#endif
+static INLINE
+IMG_BOOL NoParent(HANDLE_DATA *psHandleData)
+{
+ if (HandleListIsEmpty(psHandleData->hHandle, &psHandleData->sSiblings))
+ {
+ PVR_ASSERT(psHandleData->sSiblings.hParent == NULL);
+
+ return IMG_TRUE;
+ }
+
+ PVR_ASSERT(psHandleData->sSiblings.hParent != NULL);
+ return IMG_FALSE;
+}
+#endif /*DEBUG*/
+
+/*!
+*******************************************************************************
+ @Function ParentHandle
+ @Description Determine the parent of a handle
+ @Input psHandleData - pointer to handle data structure
+ @Return Parent handle, or NULL if the handle is not a subhandle.
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(ParentHandle)
+#endif
+static INLINE
+IMG_HANDLE ParentHandle(HANDLE_DATA *psHandleData)
+{
+ return psHandleData->sSiblings.hParent;
+}
+
+/*
+ * GetHandleListFromHandleAndOffset is used to generate either a
+ * pointer to the subhandle list head, or a pointer to the linked list
+ * structure of an item on a subhandle list.
+ * The list head is itself on the list, but is at a different offset
+ * in the handle structure to the linked list structure for items on
+ * the list. The two linked list structures are differentiated by
+ * the third parameter, containing the parent handle. The parent field
+ * in the list head structure references the handle structure that contains
+ * it. For items on the list, the parent field in the linked list structure
+ * references the parent handle, which will be different from the handle
+ * containing the linked list structure.
+ */
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(GetHandleListFromHandleAndOffset)
+#endif
+static INLINE
+HANDLE_LIST *GetHandleListFromHandleAndOffset(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE hEntry,
+ IMG_HANDLE hParent,
+ size_t uiParentOffset,
+ size_t uiEntryOffset)
+{
+ HANDLE_DATA *psHandleData = NULL;
+
+ PVR_ASSERT(psBase != NULL);
+
+ if (GetHandleData(psBase, &psHandleData, hEntry,
+ PVRSRV_HANDLE_TYPE_NONE) != PVRSRV_OK)
+ {
+ return NULL;
+ }
+
+ if (hEntry == hParent)
+ {
+ return (HANDLE_LIST *)IMG_OFFSET_ADDR(psHandleData, uiParentOffset);
+ }
+ else
+ {
+ return (HANDLE_LIST *)IMG_OFFSET_ADDR(psHandleData, uiEntryOffset);
+ }
+}
+
+/*!
+*******************************************************************************
+ @Function HandleListInsertBefore
+ @Description Insert a handle before a handle currently on the list.
+ @Input hEntry - handle to be inserted after
+ psEntry - pointer to handle structure to be inserted after
+ uiParentOffset - offset to list head struct in handle structure
+ hNewEntry - handle to be inserted
+ psNewEntry - pointer to handle structure of item to be inserted
+ uiEntryOffset - offset of list item struct in handle structure
+ hParent - parent handle of hNewEntry
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListInsertBefore)
+#endif
+static INLINE
+PVRSRV_ERROR HandleListInsertBefore(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE hEntry,
+ HANDLE_LIST *psEntry,
+ size_t uiParentOffset,
+ IMG_HANDLE hNewEntry,
+ HANDLE_LIST *psNewEntry,
+ size_t uiEntryOffset,
+ IMG_HANDLE hParent)
+{
+ HANDLE_LIST *psPrevEntry;
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psBase != NULL, "psBase");
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psEntry != NULL, "psEntry");
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psNewEntry != NULL, "psNewEntry");
+
+ psPrevEntry = GetHandleListFromHandleAndOffset(psBase,
+ psEntry->hPrev,
+ hParent,
+ uiParentOffset,
+ uiEntryOffset);
+ if (psPrevEntry == NULL)
+ {
+ return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
+ }
+
+ PVR_ASSERT(psNewEntry->hParent == NULL);
+ PVR_ASSERT(hEntry == psPrevEntry->hNext);
+
+#if defined(DEBUG)
+ {
+ HANDLE_LIST *psParentList;
+
+ psParentList = GetHandleListFromHandleAndOffset(psBase,
+ hParent,
+ hParent,
+ uiParentOffset,
+ uiParentOffset);
+ PVR_ASSERT(psParentList && psParentList->hParent == hParent);
+ }
+#endif /* defined(DEBUG) */
+
+ psNewEntry->hPrev = psEntry->hPrev;
+ psEntry->hPrev = hNewEntry;
+
+ psNewEntry->hNext = hEntry;
+ psPrevEntry->hNext = hNewEntry;
+
+ psNewEntry->hParent = hParent;
+
+ return PVRSRV_OK;
+}
+
+/*!
+*******************************************************************************
+ @Function AdoptChild
+ @Description Assign a subhandle to a handle
+ @Input psParentData - pointer to handle structure of parent handle
+ psChildData - pointer to handle structure of child subhandle
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(AdoptChild)
+#endif
+static INLINE
+PVRSRV_ERROR AdoptChild(PVRSRV_HANDLE_BASE *psBase,
+ HANDLE_DATA *psParentData,
+ HANDLE_DATA *psChildData)
+{
+ IMG_HANDLE hParent = psParentData->sChildren.hParent;
+
+ PVR_ASSERT(hParent == psParentData->hHandle);
+
+ return HandleListInsertBefore(psBase,
+ hParent,
+ &psParentData->sChildren,
+ offsetof(HANDLE_DATA, sChildren),
+ psChildData->hHandle,
+ &psChildData->sSiblings,
+ offsetof(HANDLE_DATA, sSiblings),
+ hParent);
+}
+
+/*!
+*******************************************************************************
+ @Function HandleListRemove
+ @Description Remove a handle from a list
+ @Input hEntry - handle to be removed
+ psEntry - pointer to handle structure of item to be removed
+ uiEntryOffset - offset of list item struct in handle structure
+ uiParentOffset - offset to list head struct in handle structure
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListRemove)
+#endif
+static INLINE
+PVRSRV_ERROR HandleListRemove(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE hEntry,
+ HANDLE_LIST *psEntry,
+ size_t uiEntryOffset,
+ size_t uiParentOffset)
+{
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psBase != NULL, "psBase");
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psEntry != NULL, "psEntry");
+
+ if (!HandleListIsEmpty(hEntry, psEntry))
+ {
+ HANDLE_LIST *psPrev;
+ HANDLE_LIST *psNext;
+
+ psPrev = GetHandleListFromHandleAndOffset(psBase,
+ psEntry->hPrev,
+ psEntry->hParent,
+ uiParentOffset,
+ uiEntryOffset);
+ if (psPrev == NULL)
+ {
+ return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
+ }
+
+ psNext = GetHandleListFromHandleAndOffset(psBase,
+ psEntry->hNext,
+ psEntry->hParent,
+ uiParentOffset,
+ uiEntryOffset);
+ if (psNext == NULL)
+ {
+ return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
+ }
+
+ /*
+ * The list head is on the list, and we don't want to
+ * remove it.
+ */
+ PVR_ASSERT(psEntry->hParent != NULL);
+
+ psPrev->hNext = psEntry->hNext;
+ psNext->hPrev = psEntry->hPrev;
+
+ HandleListInit(hEntry, psEntry, NULL);
+ }
+
+ return PVRSRV_OK;
+}
+
+/*!
+*******************************************************************************
+ @Function UnlinkFromParent
+ @Description Remove a subhandle from its parents list
+ @Input psHandleData - pointer to handle data structure of child
+ subhandle.
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(UnlinkFromParent)
+#endif
+static INLINE
+PVRSRV_ERROR UnlinkFromParent(PVRSRV_HANDLE_BASE *psBase,
+ HANDLE_DATA *psHandleData)
+{
+ return HandleListRemove(psBase,
+ psHandleData->hHandle,
+ &psHandleData->sSiblings,
+ offsetof(HANDLE_DATA, sSiblings),
+ offsetof(HANDLE_DATA, sChildren));
+}
+
+/*!
+*******************************************************************************
+ @Function HandleListIterate
+ @Description Iterate over the items in a list
+ @Input psHead - pointer to list head
+ uiParentOffset - offset to list head struct in handle structure
+ uiEntryOffset - offset of list item struct in handle structure
+ pfnIterFunc - function to be called for each handle in the list
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(HandleListIterate)
+#endif
+static INLINE
+PVRSRV_ERROR HandleListIterate(PVRSRV_HANDLE_BASE *psBase,
+ HANDLE_LIST *psHead,
+ size_t uiParentOffset,
+ size_t uiEntryOffset,
+ PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, IMG_HANDLE))
+{
+ IMG_HANDLE hHandle = psHead->hNext;
+ IMG_HANDLE hParent = psHead->hParent;
+ IMG_HANDLE hNext;
+
+ PVR_ASSERT(psHead->hParent != NULL);
+
+ /*
+ * Follow the next chain from the list head until we reach
+ * the list head again, which signifies the end of the list.
+ */
+ while (hHandle != hParent)
+ {
+ HANDLE_LIST *psEntry;
+ PVRSRV_ERROR eError;
+
+ psEntry = GetHandleListFromHandleAndOffset(psBase,
+ hHandle,
+ hParent,
+ uiParentOffset,
+ uiEntryOffset);
+ if (psEntry == NULL)
+ {
+ return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
+ }
+
+ PVR_ASSERT(psEntry->hParent == psHead->hParent);
+
+ /*
+ * Get the next index now, in case the list item is
+ * modified by the iteration function.
+ */
+ hNext = psEntry->hNext;
+
+ eError = (*pfnIterFunc)(psBase, hHandle);
+ PVR_RETURN_IF_ERROR(eError);
+
+ hHandle = hNext;
+ }
+
+ return PVRSRV_OK;
+}
+
+/*!
+*******************************************************************************
+ @Function IterateOverChildren
+ @Description Iterate over the subhandles of a parent handle
+ @Input psParentData - pointer to parent handle structure
+ pfnIterFunc - function to be called for each subhandle
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(IterateOverChildren)
+#endif
+static INLINE
+PVRSRV_ERROR IterateOverChildren(PVRSRV_HANDLE_BASE *psBase,
+ HANDLE_DATA *psParentData,
+ PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, IMG_HANDLE))
+{
+ return HandleListIterate(psBase,
+ &psParentData->sChildren,
+ offsetof(HANDLE_DATA, sChildren),
+ offsetof(HANDLE_DATA, sSiblings),
+ pfnIterFunc);
+}
+
+/*!
+*******************************************************************************
+ @Function ParentIfPrivate
+ @Description Return the parent handle if the handle was allocated with
+ PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE, else return NULL.
+ @Input psHandleData - pointer to handle data structure
+ @Return Parent handle or NULL
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(ParentIfPrivate)
+#endif
+static INLINE
+IMG_HANDLE ParentIfPrivate(HANDLE_DATA *psHandleData)
+{
+ return TEST_ALLOC_FLAG(psHandleData, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ?
+ ParentHandle(psHandleData) : NULL;
+}
+
+/*!
+*******************************************************************************
+ @Function InitKey
+ @Description Initialise a hash table key for the current process
+ @Input aKey - pointer to key
+ psBase - pointer to handle base structure
+ pvData - pointer to the resource the handle represents
+ eType - type of resource
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(InitKey)
+#endif
+static INLINE
+void InitKey(HAND_KEY aKey,
+ PVRSRV_HANDLE_BASE *psBase,
+ void *pvData,
+ PVRSRV_HANDLE_TYPE eType,
+ IMG_HANDLE hParent)
+{
+ PVR_UNREFERENCED_PARAMETER(psBase);
+
+ aKey[HAND_KEY_DATA] = (uintptr_t)pvData;
+ aKey[HAND_KEY_TYPE] = (uintptr_t)eType;
+ aKey[HAND_KEY_PARENT] = (uintptr_t)hParent;
+}
+
+static PVRSRV_ERROR FreeHandleWrapper(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle);
+
+/*!
+*******************************************************************************
+ @Function FreeHandle
+ @Description Free a handle data structure.
+ @Input psBase - Pointer to handle base structure
+ hHandle - Handle to be freed
+ eType - Type of the handle to be freed
+ ppvData - Location for data associated with the freed handle
+ @Output ppvData - Points to the data associated with the freed handle
+ @Return PVRSRV_OK or PVRSRV_ERROR
+******************************************************************************/
+static PVRSRV_ERROR FreeHandle(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE hHandle,
+ PVRSRV_HANDLE_TYPE eType,
+ void **ppvData)
+{
+ HANDLE_DATA *psHandleData = NULL;
+ HANDLE_DATA *psReleasedHandleData;
+ PVRSRV_ERROR eError;
+
+ eError = GetHandleData(psBase, &psHandleData, hHandle, eType);
+ PVR_LOG_RETURN_IF_ERROR(eError, "GetHandleData");
+
+ if (_HandleUnref(psHandleData) > 0)
+ {
+ /* this handle still has references so do not destroy it
+ * or the underlying object yet
+ */
+ return PVRSRV_OK;
+ }
+
+ /* Call the release data callback for each reference on the handle */
+ if (psHandleData->pfnReleaseData != NULL)
+ {
+ eError = psHandleData->pfnReleaseData(psHandleData->pvData);
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "%s: "
+ "Got retry while calling release data callback for %p (type = %d)",
+ __func__,
+ hHandle,
+ (IMG_UINT32)psHandleData->eType));
+
+ /* the caller should retry, so retain a reference on the handle */
+ _HandleRef(psHandleData);
+
+ return eError;
+ }
+ else if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+
+ if (!TEST_ALLOC_FLAG(psHandleData, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+ {
+ HAND_KEY aKey;
+ IMG_HANDLE hRemovedHandle;
+
+ InitKey(aKey, psBase, psHandleData->pvData, psHandleData->eType, ParentIfPrivate(psHandleData));
+
+ hRemovedHandle = (IMG_HANDLE)HASH_Remove_Extended(psBase->psHashTab, aKey);
+
+ PVR_ASSERT(hRemovedHandle != NULL);
+ PVR_ASSERT(hRemovedHandle == psHandleData->hHandle);
+ PVR_UNREFERENCED_PARAMETER(hRemovedHandle);
+ }
+
+ eError = UnlinkFromParent(psBase, psHandleData);
+ PVR_LOG_RETURN_IF_ERROR(eError, "UnlinkFromParent");
+
+ /* Free children */
+ eError = IterateOverChildren(psBase, psHandleData, FreeHandleWrapper);
+ PVR_LOG_RETURN_IF_ERROR(eError, "IterateOverChildren");
+
+ eError = gpsHandleFuncs->pfnReleaseHandle(psBase->psImplBase,
+ psHandleData->hHandle,
+ (void **)&psReleasedHandleData);
+ if (unlikely(eError == PVRSRV_OK))
+ {
+ PVR_ASSERT(psReleasedHandleData == psHandleData);
+ }
+
+ if (ppvData)
+ {
+ *ppvData = psHandleData->pvData;
+ }
+
+ OSFreeMem(psHandleData);
+
+ return eError;
+}
+
+static PVRSRV_ERROR FreeHandleWrapper(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle)
+{
+ return FreeHandle(psBase, hHandle, PVRSRV_HANDLE_TYPE_NONE, NULL);
+}
+
+/*!
+*******************************************************************************
+ @Function FindHandle
+ @Description Find handle corresponding to a resource pointer
+ @Input psBase - pointer to handle base structure
+ pvData - pointer to resource to be associated with the handle
+ eType - the type of resource
+ @Return The handle, or NULL if not found
+******************************************************************************/
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(FindHandle)
+#endif
+static INLINE
+IMG_HANDLE FindHandle(PVRSRV_HANDLE_BASE *psBase,
+ void *pvData,
+ PVRSRV_HANDLE_TYPE eType,
+ IMG_HANDLE hParent)
+{
+ HAND_KEY aKey;
+
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+
+ InitKey(aKey, psBase, pvData, eType, hParent);
+
+ return (IMG_HANDLE) HASH_Retrieve_Extended(psBase->psHashTab, aKey);
+}
+
+/*!
+*******************************************************************************
+ @Function AllocHandle
+ @Description Allocate a new handle
+ @Input phHandle - location for new handle
+ pvData - pointer to resource to be associated with the handle
+ eType - the type of resource
+ hParent - parent handle or NULL
+ pfnReleaseData - Function to release resource at handle release
+ time
+ @Output phHandle - points to new handle
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+static PVRSRV_ERROR AllocHandle(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE *phHandle,
+ void *pvData,
+ PVRSRV_HANDLE_TYPE eType,
+ PVRSRV_HANDLE_ALLOC_FLAG eFlag,
+ IMG_HANDLE hParent,
+ PFN_HANDLE_RELEASE pfnReleaseData)
+{
+ HANDLE_DATA *psNewHandleData;
+ IMG_HANDLE hHandle;
+ PVRSRV_ERROR eError;
+
+ /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+ PVR_ASSERT(psBase != NULL && psBase->psHashTab != NULL);
+ PVR_ASSERT(gpsHandleFuncs);
+
+ if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+ {
+ /* Handle must not already exist */
+ PVR_ASSERT(FindHandle(psBase, pvData, eType, hParent) == NULL);
+ }
+
+ psNewHandleData = OSAllocZMem(sizeof(*psNewHandleData));
+ PVR_LOG_RETURN_IF_NOMEM(psNewHandleData, "OSAllocZMem");
+
+ eError = gpsHandleFuncs->pfnAcquireHandle(psBase->psImplBase, &hHandle,
+ psNewHandleData);
+ PVR_LOG_GOTO_IF_ERROR(eError, "pfnAcquireHandle",
+ ErrorFreeHandleData);
+
+ /*
+ * If a data pointer can be associated with multiple handles, we
+ * don't put the handle in the hash table, as the data pointer
+ * may not map to a unique handle
+ */
+ if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+ {
+ HAND_KEY aKey;
+
+ /* Initialise hash key */
+ InitKey(aKey, psBase, pvData, eType, hParent);
+
+ /* Put the new handle in the hash table */
+ eError = HASH_Insert_Extended(psBase->psHashTab, aKey, (uintptr_t)hHandle) ?
+ PVRSRV_OK : PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE;
+ PVR_LOG_GOTO_IF_FALSE(eError == PVRSRV_OK, "couldn't add handle to hash table",
+ ErrorReleaseHandle);
+ }
+
+ psNewHandleData->hHandle = hHandle;
+ psNewHandleData->eType = eType;
+ psNewHandleData->eFlag = eFlag;
+ psNewHandleData->pvData = pvData;
+ psNewHandleData->pfnReleaseData = pfnReleaseData;
+ psNewHandleData->ui32RefCount = 1;
+
+ InitParentList(psNewHandleData);
+#if defined(DEBUG)
+ PVR_ASSERT(NoChildren(psNewHandleData));
+#endif
+
+ InitChildEntry(psNewHandleData);
+#if defined(DEBUG)
+ PVR_ASSERT(NoParent(psNewHandleData));
+#endif
+
+#if defined(PVRSRV_DEBUG_HANDLE_LOCK)
+ psNewHandleData->psBase = psBase;
+#endif
+
+ /* Return the new handle to the client */
+ *phHandle = psNewHandleData->hHandle;
+
+ return PVRSRV_OK;
+
+ErrorReleaseHandle:
+ (void)gpsHandleFuncs->pfnReleaseHandle(psBase->psImplBase, hHandle, NULL);
+
+ErrorFreeHandleData:
+ OSFreeMem(psNewHandleData);
+
+ return eError;
+}
+
+/*!
+*******************************************************************************
+ @Function PVRSRVAllocHandle
+ @Description Allocate a handle
+ @Input psBase - pointer to handle base structure
+ pvData - pointer to resource to be associated with the handle
+ eType - the type of resource
+ pfnReleaseData - Function to release resource at handle release
+ time
+ @Output phHandle - points to new handle
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE *phHandle,
+ void *pvData,
+ PVRSRV_HANDLE_TYPE eType,
+ PVRSRV_HANDLE_ALLOC_FLAG eFlag,
+ PFN_HANDLE_RELEASE pfnReleaseData)
+{
+ PVRSRV_ERROR eError;
+
+ LockHandle(psBase);
+ eError = PVRSRVAllocHandleUnlocked(psBase, phHandle, pvData, eType, eFlag, pfnReleaseData);
+ UnlockHandle(psBase);
+
+ return eError;
+}
+
+/*!
+*******************************************************************************
+ @Function PVRSRVAllocHandleUnlocked
+ @Description Allocate a handle without acquiring/releasing the handle lock.
+ The function assumes you hold the lock when called.
+ @Input phHandle - location for new handle
+ pvData - pointer to resource to be associated with the handle
+ eType - the type of resource
+ pfnReleaseData - Function to release resource at handle release
+ time
+ @Output phHandle - points to new handle
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+PVRSRV_ERROR PVRSRVAllocHandleUnlocked(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE *phHandle,
+ void *pvData,
+ PVRSRV_HANDLE_TYPE eType,
+ PVRSRV_HANDLE_ALLOC_FLAG eFlag,
+ PFN_HANDLE_RELEASE pfnReleaseData)
+{
+ *phHandle = NULL;
+
+ /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+ PVR_ASSERT(gpsHandleFuncs);
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psBase != NULL, "psBase");
+ PVR_LOG_RETURN_IF_INVALID_PARAM(pfnReleaseData != NULL, "pfnReleaseData");
+
+ return AllocHandle(psBase, phHandle, pvData, eType, eFlag, NULL, pfnReleaseData);
+}
+
+/*!
+*******************************************************************************
+ @Function PVRSRVAllocSubHandle
+ @Description Allocate a subhandle
+ @Input pvData - pointer to resource to be associated with the subhandle
+ eType - the type of resource
+ hParent - parent handle
+ @Output phHandle - points to new subhandle
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE *phHandle,
+ void *pvData,
+ PVRSRV_HANDLE_TYPE eType,
+ PVRSRV_HANDLE_ALLOC_FLAG eFlag,
+ IMG_HANDLE hParent)
+{
+ PVRSRV_ERROR eError;
+
+ LockHandle(psBase);
+ eError = PVRSRVAllocSubHandleUnlocked(psBase, phHandle, pvData, eType, eFlag, hParent);
+ UnlockHandle(psBase);
+
+ return eError;
+}
+
+/*!
+*******************************************************************************
+ @Function PVRSRVAllocSubHandleUnlocked
+ @Description Allocate a subhandle without acquiring/releasing the handle
+ lock. The function assumes you hold the lock when called.
+ @Input pvData - pointer to resource to be associated with the subhandle
+ eType - the type of resource
+ hParent - parent handle
+ @Output phHandle - points to new subhandle
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+PVRSRV_ERROR PVRSRVAllocSubHandleUnlocked(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE *phHandle,
+ void *pvData,
+ PVRSRV_HANDLE_TYPE eType,
+ PVRSRV_HANDLE_ALLOC_FLAG eFlag,
+ IMG_HANDLE hParent)
+{
+ HANDLE_DATA *psPHandleData = NULL;
+ HANDLE_DATA *psCHandleData = NULL;
+ IMG_HANDLE hParentKey;
+ IMG_HANDLE hHandle;
+ PVRSRV_ERROR eError;
+
+ *phHandle = NULL;
+
+ /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+ PVR_ASSERT(gpsHandleFuncs);
+
+ PVR_LOG_GOTO_IF_INVALID_PARAM(psBase, eError, Exit);
+
+ hParentKey = TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ? hParent : NULL;
+
+ /* Lookup the parent handle */
+ eError = GetHandleData(psBase, &psPHandleData, hParent, PVRSRV_HANDLE_TYPE_NONE);
+ PVR_LOG_GOTO_IF_FALSE(eError == PVRSRV_OK, "failed to get parent handle structure",
+ Exit);
+
+ eError = AllocHandle(psBase, &hHandle, pvData, eType, eFlag, hParentKey, NULL);
+ PVR_GOTO_IF_ERROR(eError, Exit);
+
+ eError = GetHandleData(psBase, &psCHandleData, hHandle, PVRSRV_HANDLE_TYPE_NONE);
+ /* If we were able to allocate the handle then there should be no reason why we
+ * can't also get it's handle structure. Otherwise something has gone badly wrong.
+ */
+ PVR_ASSERT(eError == PVRSRV_OK);
+ PVR_LOG_GOTO_IF_FALSE(eError == PVRSRV_OK, "Failed to get parent handle structure",
+ ExitFreeHandle);
+
+ /*
+ * Get the parent handle structure again, in case the handle
+ * structure has moved (depending on the implementation
+ * of AllocHandle).
+ */
+ eError = GetHandleData(psBase, &psPHandleData, hParent, PVRSRV_HANDLE_TYPE_NONE);
+ PVR_LOG_GOTO_IF_FALSE(eError == PVRSRV_OK, "failed to get parent handle structure",
+ ExitFreeHandle);
+
+ eError = AdoptChild(psBase, psPHandleData, psCHandleData);
+ PVR_LOG_GOTO_IF_FALSE(eError == PVRSRV_OK, "parent handle failed to adopt subhandle",
+ ExitFreeHandle);
+
+ *phHandle = hHandle;
+
+ return PVRSRV_OK;
+
+ExitFreeHandle:
+ (void) FreeHandle(psBase, hHandle, eType, NULL);
+Exit:
+ return eError;
+}
+
+/*!
+*******************************************************************************
+ @Function PVRSRVFindHandle
+ @Description Find handle corresponding to a resource pointer
+ @Input pvData - pointer to resource to be associated with the handle
+ eType - the type of resource
+ @Output phHandle - points to returned handle
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE *phHandle,
+ void *pvData,
+ PVRSRV_HANDLE_TYPE eType)
+{
+ PVRSRV_ERROR eError;
+
+ LockHandle(psBase);
+ eError = PVRSRVFindHandleUnlocked(psBase, phHandle, pvData, eType);
+ UnlockHandle(psBase);
+
+ return eError;
+}
+
+/*!
+*******************************************************************************
+ @Function PVRSRVFindHandleUnlocked
+ @Description Find handle corresponding to a resource pointer without
+ acquiring/releasing the handle lock. The function assumes you
+ hold the lock when called.
+ @Input pvData - pointer to resource to be associated with the handle
+ eType - the type of resource
+ @Output phHandle - points to the returned handle
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+PVRSRV_ERROR PVRSRVFindHandleUnlocked(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE *phHandle,
+ void *pvData,
+ PVRSRV_HANDLE_TYPE eType)
+{
+ IMG_HANDLE hHandle;
+
+ /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+ PVR_ASSERT(gpsHandleFuncs);
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psBase != NULL, "psBase");
+
+ /* See if there is a handle for this data pointer */
+ hHandle = FindHandle(psBase, pvData, eType, NULL);
+ if (hHandle == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Error finding handle. Type %u",
+ __func__,
+ eType));
+
+ return PVRSRV_ERROR_HANDLE_NOT_FOUND;
+ }
+
+ *phHandle = hHandle;
+
+ return PVRSRV_OK;
+}
+
+/*!
+*******************************************************************************
+ @Function PVRSRVLookupHandle
+ @Description Lookup the data pointer corresponding to a handle
+ @Input hHandle - handle from client
+ eType - handle type
+ bRef - If TRUE, a reference will be added on the handle if the
+ lookup is successful.
+ @Output ppvData - points to the return data pointer
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase,
+ void **ppvData,
+ IMG_HANDLE hHandle,
+ PVRSRV_HANDLE_TYPE eType,
+ IMG_BOOL bRef)
+{
+ PVRSRV_ERROR eError;
+
+ LockHandle(psBase);
+ eError = PVRSRVLookupHandleUnlocked(psBase, ppvData, hHandle, eType, bRef);
+ UnlockHandle(psBase);
+
+ return eError;
+}
+
+/*!
+*******************************************************************************
+ @Function PVRSRVLookupHandleUnlocked
+ @Description Lookup the data pointer corresponding to a handle without
+ acquiring/releasing the handle lock. The function assumes you
+ hold the lock when called.
+ @Input hHandle - handle from client
+ eType - handle type
+ bRef - If TRUE, a reference will be added on the handle if the
+ lookup is successful.
+ @Output ppvData - points to the returned data pointer
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+PVRSRV_ERROR PVRSRVLookupHandleUnlocked(PVRSRV_HANDLE_BASE *psBase,
+ void **ppvData,
+ IMG_HANDLE hHandle,
+ PVRSRV_HANDLE_TYPE eType,
+ IMG_BOOL bRef)
+{
+ HANDLE_DATA *psHandleData = NULL;
+ PVRSRV_ERROR eError;
+
+ /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+ PVR_ASSERT(gpsHandleFuncs);
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psBase != NULL, "psBase");
+
+ eError = GetHandleData(psBase, &psHandleData, hHandle, eType);
+ if (unlikely(eError != PVRSRV_OK))
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Error looking up handle (%s) for base %p of type %s. Handle %p, type %s",
+ __func__,
+ PVRSRVGetErrorString(eError),
+ psBase,
+ HandleBaseTypeToString(psBase->eType),
+ (void*) hHandle,
+ HandleTypeToString(eType)));
+#if defined(DEBUG) || defined(PVRSRV_NEED_PVR_DPF)
+ OSDumpStack();
+#endif
+ return eError;
+ }
+
+ if (psHandleData->ui32RefCount == 0)
+ {
+ return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
+ }
+
+ if (bRef)
+ {
+ _HandleRef(psHandleData);
+ }
+
+ *ppvData = psHandleData->pvData;
+
+ return PVRSRV_OK;
+}
+
+/*!
+*******************************************************************************
+ @Function PVRSRVLookupSubHandle
+ @Description Lookup the data pointer corresponding to a subhandle
+ @Input hHandle - handle from client
+ eType - handle type
+ hAncestor - ancestor handle
+ @Output ppvData - points to the returned data pointer
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase,
+ void **ppvData,
+ IMG_HANDLE hHandle,
+ PVRSRV_HANDLE_TYPE eType,
+ IMG_HANDLE hAncestor)
+{
+ HANDLE_DATA *psPHandleData = NULL;
+ HANDLE_DATA *psCHandleData = NULL;
+ PVRSRV_ERROR eError;
+
+ /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+ PVR_ASSERT(gpsHandleFuncs);
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psBase != NULL, "psBase");
+
+ LockHandle(psBase);
+
+ eError = GetHandleData(psBase, &psCHandleData, hHandle, eType);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Error looking up subhandle (%s). Handle %p, type %u",
+ __func__,
+ PVRSRVGetErrorString(eError),
+ (void*) hHandle,
+ eType));
+ OSDumpStack();
+ goto ExitUnlock;
+ }
+
+ /* Look for hAncestor among the handle's ancestors */
+ for (psPHandleData = psCHandleData; ParentHandle(psPHandleData) != hAncestor; )
+ {
+ eError = GetHandleData(psBase, &psPHandleData, ParentHandle(psPHandleData), PVRSRV_HANDLE_TYPE_NONE);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_LOG_ERROR(eError, "GetHandleData");
+ eError = PVRSRV_ERROR_INVALID_SUBHANDLE;
+ goto ExitUnlock;
+ }
+ }
+
+ *ppvData = psCHandleData->pvData;
+
+ eError = PVRSRV_OK;
+
+ExitUnlock:
+ UnlockHandle(psBase);
+
+ return eError;
+}
+
+
+/*!
+*******************************************************************************
+ @Function PVRSRVReleaseHandle
+ @Description Release a handle that is no longer needed
+ @Input hHandle - handle from client
+ eType - handle type
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE hHandle,
+ PVRSRV_HANDLE_TYPE eType)
+{
+ PVRSRV_ERROR eError;
+
+ LockHandle(psBase);
+ eError = PVRSRVReleaseHandleUnlocked(psBase, hHandle, eType);
+ UnlockHandle(psBase);
+
+ return eError;
+}
+
+
+/*!
+*******************************************************************************
+ @Function PVRSRVReleaseHandleUnlocked
+ @Description Release a handle that is no longer needed without
+ acquiring/releasing the handle lock. The function assumes you
+ hold the lock when called.
+ @Input hHandle - handle from client
+ eType - handle type
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+PVRSRV_ERROR PVRSRVReleaseHandleUnlocked(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE hHandle,
+ PVRSRV_HANDLE_TYPE eType)
+{
+ /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+ PVR_ASSERT(gpsHandleFuncs);
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psBase != NULL, "psBase");
+
+ return FreeHandle(psBase, hHandle, eType, NULL);
+}
+
+/*!
+*******************************************************************************
+ @Function PVRSRVPurgeHandles
+ @Description Purge handles for a given handle base
+ @Input psBase - pointer to handle base structure
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase)
+{
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(gpsHandleFuncs);
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psBase != NULL, "psBase");
+
+ LockHandle(psBase);
+ eError = gpsHandleFuncs->pfnPurgeHandles(psBase->psImplBase);
+ UnlockHandle(psBase);
+
+ return eError;
+}
+
+static PVRSRV_ERROR HandleUnrefAndMaybeMarkForFree(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE hHandle,
+ PVRSRV_HANDLE_TYPE eType);
+
+static PVRSRV_ERROR HandleUnrefAndMaybeMarkForFreeWrapper(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE hHandle)
+{
+ return HandleUnrefAndMaybeMarkForFree(psBase, hHandle, PVRSRV_HANDLE_TYPE_NONE);
+}
+
+static PVRSRV_ERROR HandleUnrefAndMaybeMarkForFree(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE hHandle,
+ PVRSRV_HANDLE_TYPE eType)
+{
+ HANDLE_DATA *psHandleData = NULL;
+ PVRSRV_ERROR eError;
+
+ eError = GetHandleData(psBase, &psHandleData, hHandle, eType);
+ PVR_RETURN_IF_ERROR(eError);
+
+ if (psHandleData->ui32RefCount == 0)
+ {
+ /* the handle is already in the destruction phase
+ * i.e. its refcount has already reached 0
+ */
+ return PVRSRV_OK;
+ }
+
+ if (_HandleUnref(psHandleData) > 0)
+ {
+ /* this handle still has references so do not destroy it
+ * or the underlying object yet
+ */
+ return PVRSRV_ERROR_OBJECT_STILL_REFERENCED;
+ }
+
+ /* Prepare children for destruction */
+ eError = IterateOverChildren(psBase, psHandleData,
+ HandleUnrefAndMaybeMarkForFreeWrapper);
+ PVR_LOG_RETURN_IF_ERROR(eError, "IterateOverChildren->HandleUnrefAndMaybeMarkForFree");
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR HandleFreePrivData(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE hHandle,
+ PVRSRV_HANDLE_TYPE eType);
+
+static PVRSRV_ERROR HandleFreePrivDataWrapper(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE hHandle)
+{
+ return HandleFreePrivData(psBase, hHandle, PVRSRV_HANDLE_TYPE_NONE);
+}
+
+static PVRSRV_ERROR HandleFreePrivData(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE hHandle,
+ PVRSRV_HANDLE_TYPE eType)
+{
+ HANDLE_DATA *psHandleData = NULL;
+ PVRSRV_ERROR eError;
+
+ eError = GetHandleData(psBase, &psHandleData, hHandle, eType);
+ PVR_RETURN_IF_ERROR(eError);
+
+ /* Call the release data callback for each reference on the handle */
+ if (psHandleData->pfnReleaseData != NULL)
+ {
+ eError = psHandleData->pfnReleaseData(psHandleData->pvData);
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "FreeHandle: "
+ "Got retry while calling release data callback for %p (type = %d)",
+ hHandle,
+ (IMG_UINT32)psHandleData->eType));
+
+ return eError;
+ }
+ else if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ /* we don't need this so make sure it's not called on
+ * the pvData for the second time
+ */
+ psHandleData->pfnReleaseData = NULL;
+ }
+
+ /* Free children's data */
+ eError = IterateOverChildren(psBase, psHandleData,
+ HandleFreePrivDataWrapper);
+ PVR_LOG_RETURN_IF_ERROR(eError, "IterateOverChildren->HandleFreePrivData");
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR HandleFreeDestroy(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE hHandle,
+ PVRSRV_HANDLE_TYPE eType);
+
+static PVRSRV_ERROR HandleFreeDestroyWrapper(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE hHandle)
+{
+ return HandleFreeDestroy(psBase, hHandle, PVRSRV_HANDLE_TYPE_NONE);
+}
+
+static PVRSRV_ERROR HandleFreeDestroy(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE hHandle,
+ PVRSRV_HANDLE_TYPE eType)
+{
+ HANDLE_DATA *psHandleData = NULL;
+ HANDLE_DATA *psReleasedHandleData;
+ PVRSRV_ERROR eError;
+
+ eError = GetHandleData(psBase, &psHandleData, hHandle, eType);
+ PVR_RETURN_IF_ERROR(eError);
+
+ eError = UnlinkFromParent(psBase, psHandleData);
+ PVR_LOG_RETURN_IF_ERROR(eError, "UnlinkFromParent");
+
+ if (!TEST_ALLOC_FLAG(psHandleData, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+ {
+ HAND_KEY aKey;
+ IMG_HANDLE hRemovedHandle;
+
+ InitKey(aKey, psBase, psHandleData->pvData, psHandleData->eType,
+ ParentIfPrivate(psHandleData));
+
+ hRemovedHandle = (IMG_HANDLE) HASH_Remove_Extended(psBase->psHashTab,
+ aKey);
+
+ PVR_ASSERT(hRemovedHandle != NULL);
+ PVR_ASSERT(hRemovedHandle == psHandleData->hHandle);
+ PVR_UNREFERENCED_PARAMETER(hRemovedHandle);
+ }
+
+ /* Free children */
+ eError = IterateOverChildren(psBase, psHandleData, HandleFreeDestroyWrapper);
+ PVR_LOG_RETURN_IF_ERROR(eError, "IterateOverChildren->HandleFreeDestroy");
+
+ eError = gpsHandleFuncs->pfnReleaseHandle(psBase->psImplBase,
+ psHandleData->hHandle,
+ (void **)&psReleasedHandleData);
+ OSFreeMem(psHandleData);
+ PVR_LOG_RETURN_IF_ERROR(eError, "pfnReleaseHandle");
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PVRSRVReleaseHandleStagedUnlock(PVRSRV_HANDLE_BASE *psBase,
+ IMG_HANDLE hHandle,
+ PVRSRV_HANDLE_TYPE eType)
+{
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE);
+ PVR_ASSERT(gpsHandleFuncs);
+
+ PVR_LOG_RETURN_IF_FALSE(psBase != NULL, "psBase invalid",
+ PVRSRV_ERROR_INVALID_PARAMS);
+
+ eError = HandleUnrefAndMaybeMarkForFree(psBase, hHandle, eType);
+ if (eError == PVRSRV_ERROR_OBJECT_STILL_REFERENCED)
+ {
+ return PVRSRV_OK;
+ }
+ else if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+
+ UnlockHandle(psBase);
+
+ eError = HandleFreePrivData(psBase, hHandle, eType);
+ if (eError != PVRSRV_OK)
+ {
+ LockHandle(psBase);
+ return eError;
+ }
+
+ LockHandle(psBase);
+
+ return HandleFreeDestroy(psBase, hHandle, eType);
+}
+
+/*!
+*******************************************************************************
+ @Function PVRSRVAllocHandleBase
+ @Description Allocate a handle base structure for a process
+ @Input eType - handle type
+ @Output ppsBase - points to handle base structure pointer
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase,
+ PVRSRV_HANDLE_BASE_TYPE eType)
+{
+ PVRSRV_HANDLE_BASE *psBase;
+ PVRSRV_ERROR eError;
+
+ PVR_LOG_RETURN_IF_FALSE(gpsHandleFuncs != NULL, "handle management not initialised",
+ PVRSRV_ERROR_NOT_READY);
+ PVR_LOG_RETURN_IF_INVALID_PARAM(ppsBase != NULL, "ppsBase");
+
+ psBase = OSAllocZMem(sizeof(*psBase));
+ PVR_LOG_RETURN_IF_NOMEM(psBase, "psBase");
+
+ eError = OSLockCreate(&psBase->hLock);
+ PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", ErrorFreeHandleBase);
+
+ psBase->eType = eType;
+
+ LockHandle(psBase);
+
+ eError = gpsHandleFuncs->pfnCreateHandleBase(&psBase->psImplBase);
+ PVR_GOTO_IF_ERROR(eError, ErrorUnlock);
+
+ psBase->psHashTab = HASH_Create_Extended(HANDLE_HASH_TAB_INIT_SIZE,
+ sizeof(HAND_KEY),
+ HASH_Func_Default,
+ HASH_Key_Comp_Default);
+ PVR_LOG_GOTO_IF_FALSE(psBase->psHashTab != NULL, "couldn't create data pointer"
+ " hash table", ErrorDestroyHandleBase);
+
+ *ppsBase = psBase;
+
+ UnlockHandle(psBase);
+
+ return PVRSRV_OK;
+
+ErrorDestroyHandleBase:
+ (void)gpsHandleFuncs->pfnDestroyHandleBase(psBase->psImplBase);
+
+ErrorUnlock:
+ UnlockHandle(psBase);
+ OSLockDestroy(psBase->hLock);
+
+ErrorFreeHandleBase:
+ OSFreeMem(psBase);
+
+ return eError;
+}
+
+#if defined(DEBUG)
+typedef struct _COUNT_HANDLE_DATA_
+{
+ PVRSRV_HANDLE_BASE *psBase;
+ IMG_UINT32 uiHandleDataCount;
+} COUNT_HANDLE_DATA;
+
+/* Used to count the number of handles that have data associated with them */
+static PVRSRV_ERROR CountHandleDataWrapper(IMG_HANDLE hHandle, void *pvData)
+{
+ COUNT_HANDLE_DATA *psData = (COUNT_HANDLE_DATA *)pvData;
+ HANDLE_DATA *psHandleData = NULL;
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(gpsHandleFuncs);
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psData != NULL, "psData");
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psData->psBase != NULL, "psData->psBase");
+
+ eError = GetHandleData(psData->psBase,
+ &psHandleData,
+ hHandle,
+ PVRSRV_HANDLE_TYPE_NONE);
+ PVR_LOG_RETURN_IF_ERROR(eError, "GetHandleData");
+
+ if (psHandleData != NULL)
+ {
+ psData->uiHandleDataCount++;
+ }
+
+ return PVRSRV_OK;
+}
+
+/* Print a handle in the handle base. Used with the iterator callback. */
+static PVRSRV_ERROR ListHandlesInBase(IMG_HANDLE hHandle, void *pvData)
+{
+ PVRSRV_HANDLE_BASE *psBase = (PVRSRV_HANDLE_BASE*) pvData;
+ HANDLE_DATA *psHandleData = NULL;
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(gpsHandleFuncs);
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psBase != NULL, "psBase");
+
+ eError = GetHandleData(psBase,
+ &psHandleData,
+ hHandle,
+ PVRSRV_HANDLE_TYPE_NONE);
+ PVR_LOG_RETURN_IF_ERROR(eError, "GetHandleData");
+
+ if (psHandleData != NULL)
+ {
+ PVR_DPF((PVR_DBG_WARNING, " Handle: %6u, Refs: %3u, Type: %s (%u), pvData<%p>",
+ (IMG_UINT32) (uintptr_t) psHandleData->hHandle,
+ psHandleData->ui32RefCount,
+ HandleTypeToString(psHandleData->eType),
+ psHandleData->eType,
+ psHandleData->pvData));
+ }
+
+ return PVRSRV_OK;
+}
+
+#endif /* defined(DEBUG) */
+
+static INLINE IMG_BOOL _CheckIfMaxTimeExpired(IMG_UINT64 ui64TimeStart, IMG_UINT64 ui64MaxBridgeTime)
+{
+ /* unsigned arithmetic is well defined so this will wrap around correctly */
+ return (OSClockns64() - ui64TimeStart) >= ui64MaxBridgeTime;
+}
+
+static PVRSRV_ERROR FreeKernelHandlesWrapperIterKernel(IMG_HANDLE hHandle, void *pvData)
+{
+ FREE_KERNEL_HANDLE_DATA *psData = (FREE_KERNEL_HANDLE_DATA *)pvData;
+ HANDLE_DATA *psKernelHandleData = NULL;
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(gpsHandleFuncs);
+
+ /* Get kernel handle data. */
+ eError = GetHandleData(KERNEL_HANDLE_BASE,
+ &psKernelHandleData,
+ hHandle,
+ PVRSRV_HANDLE_TYPE_NONE);
+ PVR_LOG_RETURN_IF_ERROR(eError, "GetHandleData");
+
+ if (psKernelHandleData->pvData == psData->psProcessHandleData->pvData)
+ {
+ /* This kernel handle belongs to our process handle. */
+ psData->hKernelHandle = hHandle;
+ }
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR FreeKernelHandlesWrapperIterProcess(IMG_HANDLE hHandle, void *pvData)
+{
+ FREE_KERNEL_HANDLE_DATA *psData = (FREE_KERNEL_HANDLE_DATA *)pvData;
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(gpsHandleFuncs);
+
+ /* Get process handle data. */
+ eError = GetHandleData(psData->psBase,
+ &psData->psProcessHandleData,
+ hHandle,
+ PVRSRV_HANDLE_TYPE_NONE);
+ PVR_LOG_RETURN_IF_ERROR(eError, "GetHandleData");
+
+ if (psData->psProcessHandleData->eFlag == PVRSRV_HANDLE_ALLOC_FLAG_MULTI
+#if defined(SUPPORT_INSECURE_EXPORT)
+ || psData->psProcessHandleData->eType == PVRSRV_HANDLE_TYPE_PVRSRV_FENCE_EXPORT
+#endif
+ )
+ {
+ /* Only multi alloc process handles might be in kernel handle base. */
+ psData->hKernelHandle = NULL;
+ /* Iterate over kernel handles. */
+ eError = gpsHandleFuncs->pfnIterateOverHandles(KERNEL_HANDLE_BASE->psImplBase,
+ &FreeKernelHandlesWrapperIterKernel,
+ (void *)psData);
+ PVR_LOG_RETURN_IF_FALSE(eError == PVRSRV_OK, "failed to iterate over kernel handles",
+ eError);
+
+ if (psData->hKernelHandle)
+ {
+ /* Release kernel handle which belongs to our process handle. */
+ eError = gpsHandleFuncs->pfnReleaseHandle(KERNEL_HANDLE_BASE->psImplBase,
+ psData->hKernelHandle,
+ NULL);
+ PVR_LOG_RETURN_IF_FALSE(eError == PVRSRV_OK, "couldn't release kernel handle",
+ eError);
+ }
+ }
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR FreeHandleDataWrapper(IMG_HANDLE hHandle, void *pvData)
+{
+ FREE_HANDLE_DATA *psData = (FREE_HANDLE_DATA *)pvData;
+ HANDLE_DATA *psHandleData = NULL;
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(gpsHandleFuncs);
+
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psData != NULL, "psData");
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psData->psBase != NULL, "psData->psBase");
+ PVR_LOG_RETURN_IF_INVALID_PARAM(psData->eHandleFreeType != PVRSRV_HANDLE_TYPE_NONE,
+ "psData->eHandleFreeType");
+
+ eError = GetHandleData(psData->psBase,
+ &psHandleData,
+ hHandle,
+ PVRSRV_HANDLE_TYPE_NONE);
+ PVR_LOG_RETURN_IF_ERROR(eError, "GetHandleData");
+
+ if (psHandleData == NULL || psHandleData->eType != psData->eHandleFreeType)
+ {
+ return PVRSRV_OK;
+ }
+
+ PVR_ASSERT(psHandleData->ui32RefCount > 0);
+
+ while (psHandleData->ui32RefCount != 0)
+ {
+ if (psHandleData->pfnReleaseData != NULL)
+ {
+ eError = psHandleData->pfnReleaseData(psHandleData->pvData);
+ if (eError == PVRSRV_ERROR_RETRY)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "%s: "
+ "Got retry while calling release data callback for %p (type = %d)",
+ __func__,
+ hHandle,
+ (IMG_UINT32)psHandleData->eType));
+
+ return eError;
+ }
+ else if (eError != PVRSRV_OK)
+ {
+ return eError;
+ }
+ }
+
+ _HandleUnref(psHandleData);
+ }
+
+ if (!TEST_ALLOC_FLAG(psHandleData, PVRSRV_HANDLE_ALLOC_FLAG_MULTI))
+ {
+ HAND_KEY aKey;
+ IMG_HANDLE hRemovedHandle;
+
+ InitKey(aKey,
+ psData->psBase,
+ psHandleData->pvData,
+ psHandleData->eType,
+ ParentIfPrivate(psHandleData));
+
+ hRemovedHandle = (IMG_HANDLE)HASH_Remove_Extended(psData->psBase->psHashTab, aKey);
+
+ PVR_ASSERT(hRemovedHandle != NULL);
+ PVR_ASSERT(hRemovedHandle == psHandleData->hHandle);
+ PVR_UNREFERENCED_PARAMETER(hRemovedHandle);
+ }
+
+ eError = gpsHandleFuncs->pfnSetHandleData(psData->psBase->psImplBase, hHandle, NULL);
+ PVR_RETURN_IF_ERROR(eError);
+
+ OSFreeMem(psHandleData);
+
+ /* If we reach the end of the time slice release we can release the global
+ * lock, invoke the scheduler and reacquire the lock */
+ if ((psData->ui64MaxBridgeTime != 0) && _CheckIfMaxTimeExpired(psData->ui64TimeStart, psData->ui64MaxBridgeTime))
+ {
+ PVR_DPF((PVR_DBG_MESSAGE,
+ "%s: Lock timeout (timeout: %" IMG_UINT64_FMTSPEC")",
+ __func__,
+ psData->ui64MaxBridgeTime));
+ /* UnlockHandle(psData->psBase); - func only run in single thread ctx */
+ /* Invoke the scheduler to check if other processes are waiting for the lock */
+ OSReleaseThreadQuanta();
+ /* LockHandle(psData->psBase); - func only run in single thread ctx */
+ /* Set again lock timeout and reset the counter */
+ psData->ui64TimeStart = OSClockns64();
+ PVR_DPF((PVR_DBG_MESSAGE, "%s: Lock acquired again", __func__));
+ }
+
+ return PVRSRV_OK;
+}
+
+/* The Ordered Array of PVRSRV_HANDLE_TYPE Enum Entries.
+ *
+ * Some handles must be destroyed prior to other handles,
+ * such relationships are established with respect to handle types.
+ * Therefore elements of this array have to maintain specific order,
+ * e.g. the PVRSRV_HANDLE_TYPE_RGX_KM_HW_RT_DATASET must be placed
+ * before PVRSRV_HANDLE_TYPE_RGX_FREELIST.
+ *
+ * If ordering is incorrect driver may fail on the ground of cleanup
+ * routines. Unfortunately, we can mainly rely on the actual definition of
+ * the array, there is no explicit information about all relationships
+ * between handle types. These relationships do not necessarily come from
+ * bridge-specified handle attributes such as 'sub handle' and 'parent
+ * handle'. They may come from internal/private ref-counters contained by
+ * objects referenced by our kernel handles.
+ *
+ * For example, at the bridge level, PVRSRV_HANDLE_TYPE_RGX_KM_HW_RT_DATASET
+ * and PVRSRV_HANDLE_TYPE_RGX_FREELIST have no explicit relationship, meaning
+ * none of them is a sub-handle for the other.
+ * However the freelist contains internal ref-count that is decremented by
+ * the destroy routine for KM_HW_RT_DATASET.
+ *
+ * BE CAREFUL when adding/deleting/moving handle types.
+ */
+static const PVRSRV_HANDLE_TYPE g_aeOrderedFreeList[] =
+{
+ PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
+ PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT,
+ PVRSRV_HANDLE_TYPE_RGX_FW_MEMDESC,
+ PVRSRV_HANDLE_TYPE_RGX_KM_HW_RT_DATASET,
+ PVRSRV_HANDLE_TYPE_RGX_FREELIST,
+ PVRSRV_HANDLE_TYPE_RGX_MEMORY_BLOCK,
+ PVRSRV_HANDLE_TYPE_RGX_POPULATION,
+ PVRSRV_HANDLE_TYPE_RGX_FWIF_ZSBUFFER,
+ PVRSRV_HANDLE_TYPE_RGX_SERVER_RENDER_CONTEXT,
+ PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT,
+ PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_TDM_CONTEXT,
+ PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT,
+ PVRSRV_HANDLE_TYPE_RGX_SERVER_RAY_CONTEXT,
+ PVRSRV_HANDLE_TYPE_RGX_SERVER_KICKSYNC_CONTEXT,
+ PVRSRV_HANDLE_TYPE_RI_HANDLE,
+ PVRSRV_HANDLE_TYPE_SYNC_RECORD_HANDLE,
+ PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
+ PVRSRV_HANDLE_TYPE_PVRSRV_TIMELINE_SERVER,
+ PVRSRV_HANDLE_TYPE_PVRSRV_FENCE_EXPORT,
+ PVRSRV_HANDLE_TYPE_PVRSRV_FENCE_SERVER,
+ PVRSRV_HANDLE_TYPE_DEVMEMINT_MAPPING,
+ PVRSRV_HANDLE_TYPE_DEVMEMINT_RESERVATION,
+ PVRSRV_HANDLE_TYPE_DEVMEMINT_HEAP,
+ PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX_EXPORT,
+ PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
+ PVRSRV_HANDLE_TYPE_DEVMEMINT_CTX,
+ PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_PAGELIST,
+ PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_SECURE_EXPORT,
+ PVRSRV_HANDLE_TYPE_PHYSMEM_PMR_EXPORT,
+ PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
+ PVRSRV_HANDLE_TYPE_DEVMEM_MEM_IMPORT,
+ PVRSRV_HANDLE_TYPE_PMR_LOCAL_EXPORT_HANDLE,
+ PVRSRV_HANDLE_TYPE_DC_PIN_HANDLE,
+ PVRSRV_HANDLE_TYPE_DC_BUFFER,
+ PVRSRV_HANDLE_TYPE_DC_DISPLAY_CONTEXT,
+ PVRSRV_HANDLE_TYPE_DC_DEVICE,
+ PVRSRV_HANDLE_TYPE_PVR_TL_SD,
+ PVRSRV_HANDLE_TYPE_DI_CONTEXT,
+ PVRSRV_HANDLE_TYPE_MM_PLAT_CLEANUP
+};
+
+/*!
+*******************************************************************************
+ @Function PVRSRVFreeKernelHandles
+ @Description Free kernel handles which belongs to process handles
+ @Input psBase - pointer to handle base structure
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+PVRSRV_ERROR PVRSRVFreeKernelHandles(PVRSRV_HANDLE_BASE *psBase)
+{
+ FREE_KERNEL_HANDLE_DATA sHandleData = {NULL};
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(gpsHandleFuncs);
+
+ LockHandle(psBase);
+
+ sHandleData.psBase = psBase;
+ /* Iterate over process handles. */
+ eError = gpsHandleFuncs->pfnIterateOverHandles(psBase->psImplBase,
+ &FreeKernelHandlesWrapperIterProcess,
+ (void *)&sHandleData);
+ PVR_LOG_GOTO_IF_ERROR(eError, "pfnIterateOverHandles", ExitUnlock);
+
+ eError = PVRSRV_OK;
+
+ExitUnlock:
+ UnlockHandle(psBase);
+
+ return eError;
+}
+
+/*!
+*******************************************************************************
+ @Function PVRSRVRetrieveProcessHandleBase
+ @Description Returns a pointer to the process handle base for the current
+ process. If the current process is the cleanup thread, then the
+ process handle base for the process currently being cleaned up
+ is returned
+ @Return Pointer to the process handle base, or NULL if not found.
+******************************************************************************/
+PVRSRV_HANDLE_BASE *PVRSRVRetrieveProcessHandleBase(void)
+{
+ PVRSRV_HANDLE_BASE *psHandleBase = NULL;
+ PROCESS_HANDLE_BASE *psProcHandleBase = NULL;
+ PVRSRV_DATA *psPvrData = PVRSRVGetPVRSRVData();
+ IMG_PID ui32PurgePid = PVRSRVGetPurgeConnectionPid();
+
+ OSLockAcquire(psPvrData->hProcessHandleBase_Lock);
+
+ /* Check to see if we're being called from the cleanup thread... */
+ if ((OSGetCurrentClientProcessIDKM() == psPvrData->cleanupThreadPid) &&
+ (ui32PurgePid > 0))
+ {
+ /* Check to see if the cleanup thread has already removed the
+ * process handle base from the HASH table.
+ */
+ psHandleBase = psPvrData->psProcessHandleBaseBeingFreed;
+ /* psHandleBase shouldn't be null, as cleanup thread
+ * should be removing this from the HASH table before
+ * we get here, so assert if not.
+ */
+ PVR_ASSERT(psHandleBase);
+ }
+ else
+ {
+ /* Not being called from the cleanup thread, so return the process
+ * handle base for the current process.
+ */
+ psProcHandleBase = (PROCESS_HANDLE_BASE*) HASH_Retrieve(psPvrData->psProcessHandleBase_Table,
+ OSGetCurrentClientProcessIDKM());
+ }
+ OSLockRelease(psPvrData->hProcessHandleBase_Lock);
+
+ if (psHandleBase == NULL && psProcHandleBase != NULL)
+ {
+ psHandleBase = psProcHandleBase->psHandleBase;
+ }
+ return psHandleBase;
+}
+
+/*!
+*******************************************************************************
+ @Function PVRSRVFreeHandleBase
+ @Description Free a handle base structure
+ @Input psBase - pointer to handle base structure
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase, IMG_UINT64 ui64MaxBridgeTime)
+{
+#if defined(DEBUG)
+ COUNT_HANDLE_DATA sCountData = {NULL};
+#endif
+ FREE_HANDLE_DATA sHandleData = {NULL};
+ IMG_UINT32 i;
+ PVRSRV_ERROR eError;
+ PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+ IMG_PID uiCleanupPid = psPVRSRVData->cleanupThreadPid;
+
+ PVR_ASSERT(gpsHandleFuncs);
+
+ /* LockHandle(psBase); - func only run in single thread ctx */
+
+ /* If this is a process handle base being freed by the cleanup
+ * thread, store this in psPVRSRVData->psProcessHandleBaseBeingFreed
+ */
+ if ((OSGetCurrentClientProcessIDKM() == uiCleanupPid) &&
+ (psBase->eType == PVRSRV_HANDLE_BASE_TYPE_PROCESS))
+ {
+ psPVRSRVData->psProcessHandleBaseBeingFreed = psBase;
+ }
+
+ sHandleData.psBase = psBase;
+ sHandleData.ui64TimeStart = OSClockns64();
+ sHandleData.ui64MaxBridgeTime = ui64MaxBridgeTime;
+
+
+#if defined(DEBUG)
+
+ sCountData.psBase = psBase;
+
+ eError = gpsHandleFuncs->pfnIterateOverHandles(psBase->psImplBase,
+ &CountHandleDataWrapper,
+ (void *)&sCountData);
+ PVR_LOG_GOTO_IF_ERROR(eError, "pfnIterateOverHandles", ExitUnlock);
+
+ if (sCountData.uiHandleDataCount != 0)
+ {
+ IMG_BOOL bList = sCountData.uiHandleDataCount < HANDLE_DEBUG_LISTING_MAX_NUM;
+
+ PVR_DPF((PVR_DBG_WARNING,
+ "%s: %u remaining handles in handle base 0x%p "
+ "(PVRSRV_HANDLE_BASE_TYPE %u).%s",
+ __func__,
+ sCountData.uiHandleDataCount,
+ psBase,
+ psBase->eType,
+ bList ? "": " Skipping details, too many items..."));
+
+ if (bList)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "-------- Listing Handles --------"));
+ (void) gpsHandleFuncs->pfnIterateOverHandles(psBase->psImplBase,
+ &ListHandlesInBase,
+ psBase);
+ PVR_DPF((PVR_DBG_WARNING, "-------- Done Listing --------"));
+ }
+ }
+
+#endif /* defined(DEBUG) */
+
+ /*
+ * As we're freeing handles based on type, make sure all
+ * handles have actually had their data freed to avoid
+ * resources being leaked
+ */
+ for (i = 0; i < ARRAY_SIZE(g_aeOrderedFreeList); i++)
+ {
+ sHandleData.eHandleFreeType = g_aeOrderedFreeList[i];
+
+ /* Make sure all handles have been freed before destroying the handle base */
+ eError = gpsHandleFuncs->pfnIterateOverHandles(psBase->psImplBase,
+ &FreeHandleDataWrapper,
+ (void *)&sHandleData);
+ PVR_GOTO_IF_ERROR(eError, ExitUnlock);
+ }
+
+
+ if (psBase->psHashTab != NULL)
+ {
+ HASH_Delete(psBase->psHashTab);
+ }
+
+ eError = gpsHandleFuncs->pfnDestroyHandleBase(psBase->psImplBase);
+ PVR_GOTO_IF_ERROR(eError, ExitUnlock);
+
+ /* UnlockHandle(psBase); - func only run in single thread ctx */
+ OSLockDestroy(psBase->hLock);
+ OSFreeMem(psBase);
+
+ return eError;
+
+ExitUnlock:
+ if (OSGetCurrentClientProcessIDKM() == uiCleanupPid)
+ {
+ psPVRSRVData->psProcessHandleBaseBeingFreed = NULL;
+ }
+ /* UnlockHandle(psBase); - func only run in single thread ctx */
+
+ return eError;
+}
+
+/*!
+*******************************************************************************
+ @Function PVRSRVHandleInit
+ @Description Initialise handle management
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+PVRSRV_ERROR PVRSRVHandleInit(void)
+{
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(gpsKernelHandleBase == NULL);
+ PVR_ASSERT(gpsHandleFuncs == NULL);
+ PVR_ASSERT(!gbLockInitialised);
+
+ eError = OSLockCreate(&gKernelHandleLock);
+ PVR_LOG_RETURN_IF_ERROR(eError, "OSLockCreate");
+
+ gbLockInitialised = IMG_TRUE;
+
+ eError = PVRSRVHandleGetFuncTable(&gpsHandleFuncs);
+ PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVHandleGetFuncTable", ErrorHandleDeinit);
+
+ eError = PVRSRVAllocHandleBase(&gpsKernelHandleBase,
+ PVRSRV_HANDLE_BASE_TYPE_GLOBAL);
+ PVR_LOG_GOTO_IF_ERROR(eError, "PVRSRVAllocHandleBase", ErrorHandleDeinit);
+
+ eError = gpsHandleFuncs->pfnEnableHandlePurging(gpsKernelHandleBase->psImplBase);
+ PVR_LOG_GOTO_IF_ERROR(eError, "pfnEnableHandlePurging",
+ ErrorHandleDeinit);
+
+ return PVRSRV_OK;
+
+ErrorHandleDeinit:
+ (void) PVRSRVHandleDeInit();
+
+ return eError;
+}
+
+/*!
+*******************************************************************************
+ @Function PVRSRVHandleDeInit
+ @Description De-initialise handle management
+ @Return Error code or PVRSRV_OK
+******************************************************************************/
+PVRSRV_ERROR PVRSRVHandleDeInit(void)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+
+ if (gpsHandleFuncs != NULL)
+ {
+ if (gpsKernelHandleBase != NULL)
+ {
+ eError = PVRSRVFreeHandleBase(gpsKernelHandleBase, 0 /* do not release bridge lock */);
+ if (eError == PVRSRV_OK)
+ {
+ gpsKernelHandleBase = NULL;
+ }
+ else
+ {
+ PVR_LOG_ERROR(eError, "PVRSRVFreeHandleBase");
+ }
+ }
+
+ if (eError == PVRSRV_OK)
+ {
+ gpsHandleFuncs = NULL;
+ }
+ }
+ else
+ {
+ /* If we don't have a handle function table we shouldn't have a handle base either */
+ PVR_ASSERT(gpsKernelHandleBase == NULL);
+ }
+
+ if (gbLockInitialised)
+ {
+ OSLockDestroy(gKernelHandleLock);
+ gbLockInitialised = IMG_FALSE;
+ }
+
+ return eError;
+}
diff --git a/drivers/gpu/drm/img-rogue/handle.h b/drivers/gpu/drm/img-rogue/handle.h
new file mode 100644
index 000000000..d9db37133
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/handle.h
@@ -0,0 +1,201 @@
+/**************************************************************************/ /*!
+@File
+@Title Handle Manager API
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Provide handle management
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#if !defined(HANDLE_API_H)
+#define HANDLE_API_H
+
+#include "lock_types.h"
+
+/*
+ * Handle API
+ * ----------
+ * The handle API is intended to provide handles for kernel resources, which
+ * can then be passed back to user space processes.
+ *
+ * The following functions comprise the API. Each function takes a pointer to
+ * a PVRSRV_HANDLE_BASE structure, one of which is allocated for each process,
+ * and stored in the per-process data area. Use KERNEL_HANDLE_BASE for handles
+ * not allocated for a particular process, or for handles that need to be
+ * allocated before the PVRSRV_HANDLE_BASE structure for the process is
+ * available.
+ *
+ * PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase,
+ * IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType,
+ * PVRSRV_HANDLE_ALLOC_FLAG eFlag);
+ *
+ * Allocate a handle phHandle, for the resource of type eType pointed to by
+ * pvData.
+ *
+ * For handles that have a definite lifetime, where the corresponding resource
+ * is explicitly created and destroyed, eFlag should be zero.
+ *
+ * If a particular resource may be referenced multiple times by a given
+ * process, setting eFlag to PVRSRV_HANDLE_ALLOC_FLAG_MULTI will allow multiple
+ * handles to be allocated for the resource. Such handles cannot be found with
+ * PVRSRVFindHandle.
+ *
+ * PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase,
+ * IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType,
+ * PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent);
+ *
+ * This function is similar to PVRSRVAllocHandle, except that the allocated
+ * handles are associated with a parent handle, hParent, that has been
+ * allocated previously. Subhandles are automatically deallocated when their
+ * parent handle is deallocated.
+ * Subhandles can be treated as ordinary handles. For example, they may have
+ * subhandles of their own, and may be explicitly deallocated using
+ * PVRSRVReleaseHandle (see below).
+ *
+ * PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase,
+ * IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType);
+ *
+ * Find the handle previously allocated for the resource pointed to by pvData,
+ * of type eType. Handles allocated with the flag
+ * PVRSRV_HANDLE_ALLOC_FLAG_MULTI cannot be found using this function.
+ *
+ * PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase,
+ * void **ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+ *
+ * Given a handle for a resource of type eType, return the pointer to the
+ * resource.
+ *
+ * PVRSRV_ERROR PVRSRVLookuSubHandle(PVRSRV_HANDLE_BASE *psBase,
+ * void **ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType,
+ * IMH_HANDLE hAncestor);
+ *
+ * Similar to PVRSRVLookupHandle, but checks the handle is a descendant
+ * of hAncestor.
+ *
+ * PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase,
+ * IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+ *
+ * Deallocate a handle of given type.
+ *
+ * Return the parent of a handle in *phParent, or NULL if the handle has
+ * no parent.
+ */
+
+#include "img_types.h"
+#include "img_defs.h"
+#include "hash.h"
+
+typedef enum
+{
+ #define HANDLETYPE(x) PVRSRV_HANDLE_TYPE_##x,
+ #include "handle_types.h"
+ #undef HANDLETYPE
+} PVRSRV_HANDLE_TYPE;
+
+static_assert(PVRSRV_HANDLE_TYPE_NONE == 0, "PVRSRV_HANDLE_TYPE_NONE must be zero");
+
+typedef enum
+{
+ PVRSRV_HANDLE_BASE_TYPE_CONNECTION,
+ PVRSRV_HANDLE_BASE_TYPE_PROCESS,
+ PVRSRV_HANDLE_BASE_TYPE_GLOBAL
+} PVRSRV_HANDLE_BASE_TYPE;
+
+
+typedef enum
+{
+ /* No flags */
+ PVRSRV_HANDLE_ALLOC_FLAG_NONE = 0,
+ /* Multiple handles can point at the given data pointer */
+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI = 0x01,
+ /* Subhandles are allocated in a private handle space */
+ PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE = 0x02
+} PVRSRV_HANDLE_ALLOC_FLAG;
+
+typedef struct _HANDLE_BASE_ PVRSRV_HANDLE_BASE;
+
+typedef struct _PROCESS_HANDLE_BASE_
+{
+ PVRSRV_HANDLE_BASE *psHandleBase;
+ ATOMIC_T iRefCount;
+
+} PROCESS_HANDLE_BASE;
+
+extern PVRSRV_HANDLE_BASE *gpsKernelHandleBase;
+#define KERNEL_HANDLE_BASE (gpsKernelHandleBase)
+
+#define HANDLE_DEBUG_LISTING_MAX_NUM 20
+
+typedef PVRSRV_ERROR (*PFN_HANDLE_RELEASE)(void *pvData);
+
+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, PFN_HANDLE_RELEASE pfnReleaseData);
+PVRSRV_ERROR PVRSRVAllocHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, PFN_HANDLE_RELEASE pfnReleaseData);
+
+PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent);
+PVRSRV_ERROR PVRSRVAllocSubHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent);
+
+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType);
+PVRSRV_ERROR PVRSRVFindHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, void *pvData, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, void **ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_BOOL bRef);
+PVRSRV_ERROR PVRSRVLookupHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, void **ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_BOOL bRef);
+
+PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, void **ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor);
+
+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+PVRSRV_ERROR PVRSRVReleaseHandleUnlocked(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+PVRSRV_ERROR PVRSRVReleaseHandleStagedUnlock(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase);
+
+PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase,
+ PVRSRV_HANDLE_BASE_TYPE eType);
+
+PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase, IMG_UINT64 ui64MaxBridgeTime);
+
+PVRSRV_ERROR PVRSRVFreeKernelHandles(PVRSRV_HANDLE_BASE *psBase);
+
+PVRSRV_ERROR PVRSRVHandleInit(void);
+
+PVRSRV_ERROR PVRSRVHandleDeInit(void);
+
+PVRSRV_HANDLE_BASE *PVRSRVRetrieveProcessHandleBase(void);
+
+void LockHandle(PVRSRV_HANDLE_BASE *psBase);
+void UnlockHandle(PVRSRV_HANDLE_BASE *psBase);
+
+#endif /* !defined(HANDLE_API_H) */
diff --git a/drivers/gpu/drm/img-rogue/handle_idr.c b/drivers/gpu/drm/img-rogue/handle_idr.c
new file mode 100644
index 000000000..c40e096bf
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/handle_idr.c
@@ -0,0 +1,440 @@
+/*************************************************************************/ /*!
+@File
+@Title Resource Handle Manager - IDR Back-end
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Provide IDR based resource handle management back-end
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#include
+#include
+#include
+#include
+#include
+
+#include "handle_impl.h"
+#include "allocmem.h"
+#include "osfunc.h"
+#include "pvr_debug.h"
+
+#define ID_VALUE_MIN 1
+#define ID_VALUE_MAX INT_MAX
+
+#define ID_TO_HANDLE(i) ((IMG_HANDLE)(uintptr_t)(i))
+#define HANDLE_TO_ID(h) ((IMG_INT)(uintptr_t)(h))
+
+struct _HANDLE_IMPL_BASE_
+{
+ struct idr sIdr;
+
+ IMG_UINT32 ui32MaxHandleValue;
+
+ IMG_UINT32 ui32TotalHandCount;
+};
+
+typedef struct _HANDLE_ITER_DATA_WRAPPER_
+{
+ PFN_HANDLE_ITER pfnHandleIter;
+ void *pvHandleIterData;
+} HANDLE_ITER_DATA_WRAPPER;
+
+
+static int HandleIterFuncWrapper(int id, void *data, void *iter_data)
+{
+ HANDLE_ITER_DATA_WRAPPER *psIterData = (HANDLE_ITER_DATA_WRAPPER *)iter_data;
+
+ PVR_UNREFERENCED_PARAMETER(data);
+
+ return (int)psIterData->pfnHandleIter(ID_TO_HANDLE(id), psIterData->pvHandleIterData);
+}
+
+/*!
+******************************************************************************
+
+ @Function AcquireHandle
+
+ @Description Acquire a new handle
+
+ @Input psBase - Pointer to handle base structure
+ phHandle - Points to a handle pointer
+ pvData - Pointer to resource to be associated with the handle
+
+ @Output phHandle - Points to a handle pointer
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+static PVRSRV_ERROR AcquireHandle(HANDLE_IMPL_BASE *psBase,
+ IMG_HANDLE *phHandle,
+ void *pvData)
+{
+ int id;
+ int result;
+
+ PVR_ASSERT(psBase != NULL);
+ PVR_ASSERT(phHandle != NULL);
+ PVR_ASSERT(pvData != NULL);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
+ idr_preload(GFP_KERNEL);
+ id = idr_alloc(&psBase->sIdr, pvData, ID_VALUE_MIN, psBase->ui32MaxHandleValue + 1, 0);
+ idr_preload_end();
+
+ result = id;
+#else
+ do
+ {
+ if (idr_pre_get(&psBase->sIdr, GFP_KERNEL) == 0)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ result = idr_get_new_above(&psBase->sIdr, pvData, ID_VALUE_MIN, &id);
+ } while (result == -EAGAIN);
+
+ if ((IMG_UINT32)id > psBase->ui32MaxHandleValue)
+ {
+ idr_remove(&psBase->sIdr, id);
+ result = -ENOSPC;
+ }
+#endif
+
+ if (result < 0)
+ {
+ if (result == -ENOSPC)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Limit of %u handles reached",
+ __func__, psBase->ui32MaxHandleValue));
+
+ return PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE;
+ }
+
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ psBase->ui32TotalHandCount++;
+
+ *phHandle = ID_TO_HANDLE(id);
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function ReleaseHandle
+
+ @Description Release a handle that is no longer needed.
+
+ @Input psBase - Pointer to handle base structure
+ hHandle - Handle to release
+ ppvData - Points to a void data pointer
+
+ @Output ppvData - Points to a void data pointer
+
+ @Return PVRSRV_OK or PVRSRV_ERROR
+
+******************************************************************************/
+static PVRSRV_ERROR ReleaseHandle(HANDLE_IMPL_BASE *psBase,
+ IMG_HANDLE hHandle,
+ void **ppvData)
+{
+ int id = HANDLE_TO_ID(hHandle);
+ void *pvData;
+
+ PVR_ASSERT(psBase);
+
+ /* Get the data associated with the handle. If we get back NULL then
+ it's an invalid handle */
+
+ pvData = idr_find(&psBase->sIdr, id);
+ if (likely(pvData))
+ {
+ idr_remove(&psBase->sIdr, id);
+ psBase->ui32TotalHandCount--;
+ }
+
+ if (unlikely(pvData == NULL))
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Handle out of range (%u > %u)",
+ __func__, id, psBase->ui32TotalHandCount));
+ return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
+ }
+
+ if (ppvData)
+ {
+ *ppvData = pvData;
+ }
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function GetHandleData
+
+ @Description Get the data associated with the given handle
+
+ @Input psBase - Pointer to handle base structure
+ hHandle - Handle from which data should be retrieved
+ ppvData - Points to a void data pointer
+
+ @Output ppvData - Points to a void data pointer
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+static PVRSRV_ERROR GetHandleData(HANDLE_IMPL_BASE *psBase,
+ IMG_HANDLE hHandle,
+ void **ppvData)
+{
+ int id = HANDLE_TO_ID(hHandle);
+ void *pvData;
+
+ PVR_ASSERT(psBase);
+ PVR_ASSERT(ppvData);
+
+ pvData = idr_find(&psBase->sIdr, id);
+ if (likely(pvData))
+ {
+ *ppvData = pvData;
+
+ return PVRSRV_OK;
+ }
+ else
+ {
+ return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
+ }
+}
+
+/*!
+******************************************************************************
+
+ @Function SetHandleData
+
+ @Description Set the data associated with the given handle
+
+ @Input psBase - Pointer to handle base structure
+ hHandle - Handle for which data should be changed
+ pvData - Pointer to new data to be associated with the handle
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+static PVRSRV_ERROR SetHandleData(HANDLE_IMPL_BASE *psBase,
+ IMG_HANDLE hHandle,
+ void *pvData)
+{
+ int id = HANDLE_TO_ID(hHandle);
+ void *pvOldData;
+
+ PVR_ASSERT(psBase);
+
+ pvOldData = idr_replace(&psBase->sIdr, pvData, id);
+ if (IS_ERR(pvOldData))
+ {
+ if (PTR_ERR(pvOldData) == -ENOENT)
+ {
+ return PVRSRV_ERROR_HANDLE_NOT_ALLOCATED;
+ }
+ else
+ {
+ return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
+ }
+ }
+
+ return PVRSRV_OK;
+}
+
+static PVRSRV_ERROR IterateOverHandles(HANDLE_IMPL_BASE *psBase, PFN_HANDLE_ITER pfnHandleIter, void *pvHandleIterData)
+{
+ HANDLE_ITER_DATA_WRAPPER sIterData;
+
+ PVR_ASSERT(psBase);
+ PVR_ASSERT(pfnHandleIter);
+
+ sIterData.pfnHandleIter = pfnHandleIter;
+ sIterData.pvHandleIterData = pvHandleIterData;
+
+ return (PVRSRV_ERROR)idr_for_each(&psBase->sIdr, HandleIterFuncWrapper, &sIterData);
+}
+
+/*!
+******************************************************************************
+
+ @Function EnableHandlePurging
+
+ @Description Enable purging for a given handle base
+
+ @Input psBase - pointer to handle base structure
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+static PVRSRV_ERROR EnableHandlePurging(HANDLE_IMPL_BASE *psBase)
+{
+ PVR_UNREFERENCED_PARAMETER(psBase);
+ PVR_ASSERT(psBase);
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function PurgeHandles
+
+ @Description Purge handles for a given handle base
+
+ @Input psBase - Pointer to handle base structure
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+static PVRSRV_ERROR PurgeHandles(HANDLE_IMPL_BASE *psBase)
+{
+ PVR_UNREFERENCED_PARAMETER(psBase);
+ PVR_ASSERT(psBase);
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function CreateHandleBase
+
+ @Description Create a handle base structure
+
+ @Input ppsBase - pointer to handle base structure pointer
+
+ @Output ppsBase - points to handle base structure pointer
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+static PVRSRV_ERROR CreateHandleBase(HANDLE_IMPL_BASE **ppsBase)
+{
+ HANDLE_IMPL_BASE *psBase;
+
+ PVR_ASSERT(ppsBase);
+
+ psBase = OSAllocZMem(sizeof(*psBase));
+ if (psBase == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Couldn't allocate generic handle base",
+ __func__));
+
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ idr_init(&psBase->sIdr);
+
+ psBase->ui32MaxHandleValue = ID_VALUE_MAX;
+ psBase->ui32TotalHandCount = 0;
+
+ *ppsBase = psBase;
+
+ return PVRSRV_OK;
+}
+
+/*!
+******************************************************************************
+
+ @Function DestroyHandleBase
+
+ @Description Destroy a handle base structure
+
+ @Input psBase - pointer to handle base structure
+
+ @Return Error code or PVRSRV_OK
+
+******************************************************************************/
+static PVRSRV_ERROR DestroyHandleBase(HANDLE_IMPL_BASE *psBase)
+{
+ PVR_ASSERT(psBase);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
+ idr_remove_all(&psBase->sIdr);
+#endif
+
+ /* Finally destroy the idr */
+ idr_destroy(&psBase->sIdr);
+
+ OSFreeMem(psBase);
+
+ return PVRSRV_OK;
+}
+
+
+static const HANDLE_IMPL_FUNCTAB g_sHandleFuncTab =
+{
+ .pfnAcquireHandle = AcquireHandle,
+ .pfnReleaseHandle = ReleaseHandle,
+ .pfnGetHandleData = GetHandleData,
+ .pfnSetHandleData = SetHandleData,
+ .pfnIterateOverHandles = IterateOverHandles,
+ .pfnEnableHandlePurging = EnableHandlePurging,
+ .pfnPurgeHandles = PurgeHandles,
+ .pfnCreateHandleBase = CreateHandleBase,
+ .pfnDestroyHandleBase = DestroyHandleBase
+};
+
+PVRSRV_ERROR PVRSRVHandleGetFuncTable(HANDLE_IMPL_FUNCTAB const **ppsFuncs)
+{
+ static IMG_BOOL bAcquired = IMG_FALSE;
+
+ if (bAcquired)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Function table already acquired",
+ __func__));
+ return PVRSRV_ERROR_RESOURCE_UNAVAILABLE;
+ }
+
+ if (ppsFuncs == NULL)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ *ppsFuncs = &g_sHandleFuncTab;
+
+ bAcquired = IMG_TRUE;
+
+ return PVRSRV_OK;
+}
diff --git a/drivers/gpu/drm/img-rogue/handle_impl.h b/drivers/gpu/drm/img-rogue/handle_impl.h
new file mode 100644
index 000000000..94305979d
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/handle_impl.h
@@ -0,0 +1,89 @@
+/**************************************************************************/ /*!
+@File
+@Title Implementation Callbacks for Handle Manager API
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Part of the handle manager API. This file is for declarations
+ and definitions that are private/internal to the handle manager
+ API but need to be shared between the generic handle manager
+ code and the various handle manager backends, i.e. the code that
+ implements the various callbacks.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+
+#if !defined(HANDLE_IMPL_H)
+#define HANDLE_IMPL_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+typedef struct _HANDLE_IMPL_BASE_ HANDLE_IMPL_BASE;
+
+typedef PVRSRV_ERROR (*PFN_HANDLE_ITER)(IMG_HANDLE hHandle, void *pvData);
+
+typedef struct _HANDLE_IMPL_FUNCTAB_
+{
+ /* Acquire a new handle which is associated with the given data */
+ PVRSRV_ERROR (*pfnAcquireHandle)(HANDLE_IMPL_BASE *psHandleBase, IMG_HANDLE *phHandle, void *pvData);
+
+ /* Release the given handle (optionally returning the data associated with it) */
+ PVRSRV_ERROR (*pfnReleaseHandle)(HANDLE_IMPL_BASE *psHandleBase, IMG_HANDLE hHandle, void **ppvData);
+
+ /* Get the data associated with the given handle */
+ PVRSRV_ERROR (*pfnGetHandleData)(HANDLE_IMPL_BASE *psHandleBase, IMG_HANDLE hHandle, void **ppvData);
+
+ /* Set the data associated with the given handle */
+ PVRSRV_ERROR (*pfnSetHandleData)(HANDLE_IMPL_BASE *psHandleBase, IMG_HANDLE hHandle, void *pvData);
+
+ PVRSRV_ERROR (*pfnIterateOverHandles)(HANDLE_IMPL_BASE *psHandleBase, PFN_HANDLE_ITER pfnHandleIter, void *pvHandleIterData);
+
+ /* Enable handle purging on the given handle base */
+ PVRSRV_ERROR (*pfnEnableHandlePurging)(HANDLE_IMPL_BASE *psHandleBase);
+
+ /* Purge handles on the given handle base */
+ PVRSRV_ERROR (*pfnPurgeHandles)(HANDLE_IMPL_BASE *psHandleBase);
+
+ /* Create handle base */
+ PVRSRV_ERROR (*pfnCreateHandleBase)(HANDLE_IMPL_BASE **psHandleBase);
+
+ /* Destroy handle base */
+ PVRSRV_ERROR (*pfnDestroyHandleBase)(HANDLE_IMPL_BASE *psHandleBase);
+} HANDLE_IMPL_FUNCTAB;
+
+PVRSRV_ERROR PVRSRVHandleGetFuncTable(HANDLE_IMPL_FUNCTAB const **ppsFuncs);
+
+#endif /* !defined(HANDLE_IMPL_H) */
diff --git a/drivers/gpu/drm/img-rogue/handle_types.h b/drivers/gpu/drm/img-rogue/handle_types.h
new file mode 100644
index 000000000..4e3a9d994
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/handle_types.h
@@ -0,0 +1,85 @@
+/**************************************************************************/ /*!
+@File
+@Title Handle Manager handle types
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Provide handle management
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /***************************************************************************/
+/* NOTE: Do not add include guards to this file */
+
+HANDLETYPE(NONE)
+HANDLETYPE(SHARED_EVENT_OBJECT)
+HANDLETYPE(EVENT_OBJECT_CONNECT)
+HANDLETYPE(PMR_LOCAL_EXPORT_HANDLE)
+HANDLETYPE(PHYSMEM_PMR)
+HANDLETYPE(PHYSMEM_PMR_EXPORT)
+HANDLETYPE(PHYSMEM_PMR_SECURE_EXPORT)
+HANDLETYPE(DEVMEMINT_CTX)
+HANDLETYPE(DEVMEMINT_CTX_EXPORT)
+HANDLETYPE(DEVMEMINT_HEAP)
+HANDLETYPE(DEVMEMINT_RESERVATION)
+HANDLETYPE(DEVMEMINT_MAPPING)
+HANDLETYPE(RGX_FW_MEMDESC)
+HANDLETYPE(RGX_FREELIST)
+HANDLETYPE(RGX_MEMORY_BLOCK)
+HANDLETYPE(RGX_SERVER_RENDER_CONTEXT)
+HANDLETYPE(RGX_SERVER_TQ_CONTEXT)
+HANDLETYPE(RGX_SERVER_TQ_TDM_CONTEXT)
+HANDLETYPE(RGX_SERVER_COMPUTE_CONTEXT)
+HANDLETYPE(RGX_SERVER_RAY_CONTEXT)
+HANDLETYPE(RGX_SERVER_KICKSYNC_CONTEXT)
+HANDLETYPE(SYNC_PRIMITIVE_BLOCK)
+HANDLETYPE(SYNC_RECORD_HANDLE)
+HANDLETYPE(PVRSRV_TIMELINE_SERVER)
+HANDLETYPE(PVRSRV_FENCE_SERVER)
+HANDLETYPE(PVRSRV_FENCE_EXPORT)
+HANDLETYPE(RGX_KM_HW_RT_DATASET)
+HANDLETYPE(RGX_FWIF_ZSBUFFER)
+HANDLETYPE(RGX_POPULATION)
+HANDLETYPE(DC_DEVICE)
+HANDLETYPE(DC_DISPLAY_CONTEXT)
+HANDLETYPE(DC_BUFFER)
+HANDLETYPE(DC_PIN_HANDLE)
+HANDLETYPE(DEVMEM_MEM_IMPORT)
+HANDLETYPE(PHYSMEM_PMR_PAGELIST)
+HANDLETYPE(PVR_TL_SD)
+HANDLETYPE(RI_HANDLE)
+HANDLETYPE(DEV_PRIV_DATA)
+HANDLETYPE(MM_PLAT_CLEANUP)
+HANDLETYPE(WORKEST_RETURN_DATA)
+HANDLETYPE(DI_CONTEXT)
diff --git a/drivers/gpu/drm/img-rogue/hash.c b/drivers/gpu/drm/img-rogue/hash.c
new file mode 100644
index 000000000..994ae5871
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/hash.c
@@ -0,0 +1,734 @@
+/*************************************************************************/ /*!
+@File
+@Title Self scaling hash tables.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description
+ Implements simple self scaling hash tables. Hash collisions are handled by
+ chaining entries together. Hash tables are increased in size when they
+ become more than (50%?) full and decreased in size when less than (25%?)
+ full. Hash tables are never decreased below their initial size.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/* include/ */
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvr_debug.h"
+#include "pvrsrv_error.h"
+
+/* services/shared/include/ */
+#include "hash.h"
+
+/* services/client/include/ or services/server/include/ */
+#include "osfunc_common.h"
+#include "allocmem.h"
+
+//#define PERF_DBG_RESIZE
+#if !defined(__KERNEL__) && defined(PERF_DBG_RESIZE)
+#include
+#endif
+
+#if defined(__KERNEL__)
+#include "pvrsrv.h"
+#endif
+
+#define KEY_TO_INDEX(pHash, key, uSize) \
+ ((pHash)->pfnHashFunc((pHash)->uKeySize, (key), (uSize)) % (uSize))
+
+#define KEY_COMPARE(pHash, pKey1, pKey2) \
+ ((pHash)->pfnKeyComp((pHash)->uKeySize, (pKey1), (pKey2)))
+
+#if defined(__linux__) && defined(__KERNEL__)
+#define _AllocMem OSAllocMemNoStats
+#define _AllocZMem OSAllocZMemNoStats
+#define _FreeMem OSFreeMemNoStats
+#else
+#define _AllocMem OSAllocMem
+#define _AllocZMem OSAllocZMem
+#define _FreeMem OSFreeMem
+#endif
+
+#define NO_SHRINK 0
+
+/* Each entry in a hash table is placed into a bucket */
+typedef struct _BUCKET_
+{
+ struct _BUCKET_ *pNext; /*!< the next bucket on the same chain */
+ uintptr_t v; /*!< entry value */
+ uintptr_t k[]; /* PRQA S 0642 */
+ /* override dynamic array declaration warning */
+} BUCKET;
+
+struct _HASH_TABLE_
+{
+ IMG_UINT32 uSize; /*!< current size of the hash table */
+ IMG_UINT32 uCount; /*!< number of entries currently in the hash table */
+ IMG_UINT32 uMinimumSize; /*!< the minimum size that the hash table should be re-sized to */
+ IMG_UINT32 uKeySize; /*!< size of key in bytes */
+ IMG_UINT32 uShrinkThreshold; /*!< The threshold at which to trigger a shrink */
+ IMG_UINT32 uGrowThreshold; /*!< The threshold at which to trigger a grow */
+ HASH_FUNC* pfnHashFunc; /*!< hash function */
+ HASH_KEY_COMP* pfnKeyComp; /*!< key comparison function */
+ BUCKET** ppBucketTable; /*!< the hash table array */
+#if defined(DEBUG)
+ const char* pszFile;
+ unsigned int ui32LineNum;
+#endif
+};
+
+/*************************************************************************/ /*!
+@Function HASH_Func_Default
+@Description Hash function intended for hashing keys composed of uintptr_t
+ arrays.
+@Input uKeySize The size of the hash key, in bytes.
+@Input pKey A pointer to the key to hash.
+@Input uHashTabLen The length of the hash table.
+@Return The hash value.
+*/ /**************************************************************************/
+IMG_INTERNAL IMG_UINT32
+HASH_Func_Default(size_t uKeySize, void *pKey, IMG_UINT32 uHashTabLen)
+{
+ uintptr_t *p = (uintptr_t *)pKey;
+ IMG_UINT32 uKeyLen = uKeySize / sizeof(uintptr_t);
+ IMG_UINT32 ui;
+ IMG_UINT32 uHashKey = 0;
+
+ PVR_UNREFERENCED_PARAMETER(uHashTabLen);
+
+ PVR_ASSERT((uKeySize % sizeof(uintptr_t)) == 0);
+
+ for (ui = 0; ui < uKeyLen; ui++)
+ {
+ IMG_UINT32 uHashPart = (IMG_UINT32)*p++;
+
+ uHashPart += (uHashPart << 12);
+ uHashPart ^= (uHashPart >> 22);
+ uHashPart += (uHashPart << 4);
+ uHashPart ^= (uHashPart >> 9);
+ uHashPart += (uHashPart << 10);
+ uHashPart ^= (uHashPart >> 2);
+ uHashPart += (uHashPart << 7);
+ uHashPart ^= (uHashPart >> 12);
+
+ uHashKey += uHashPart;
+ }
+
+ return uHashKey;
+}
+
+/*************************************************************************/ /*!
+@Function HASH_Key_Comp_Default
+@Description Compares keys composed of uintptr_t arrays.
+@Input uKeySize The size of the hash key, in bytes.
+@Input pKey1 Pointer to first hash key to compare.
+@Input pKey2 Pointer to second hash key to compare.
+@Return IMG_TRUE - The keys match.
+ IMG_FALSE - The keys don't match.
+*/ /**************************************************************************/
+IMG_INTERNAL IMG_BOOL
+HASH_Key_Comp_Default(size_t uKeySize, void *pKey1, void *pKey2)
+{
+ uintptr_t *p1 = (uintptr_t *)pKey1;
+ uintptr_t *p2 = (uintptr_t *)pKey2;
+ IMG_UINT32 uKeyLen = uKeySize / sizeof(uintptr_t);
+ IMG_UINT32 ui;
+
+ PVR_ASSERT((uKeySize % sizeof(uintptr_t)) == 0);
+
+ for (ui = 0; ui < uKeyLen; ui++)
+ {
+ if (*p1++ != *p2++)
+ return IMG_FALSE;
+ }
+
+ return IMG_TRUE;
+}
+
+/*************************************************************************/ /*!
+@Function _ChainInsert
+@Description Insert a bucket into the appropriate hash table chain.
+@Input pBucket The bucket
+@Input ppBucketTable The hash table
+@Input uSize The size of the hash table
+@Return PVRSRV_ERROR
+*/ /**************************************************************************/
+static void
+_ChainInsert(HASH_TABLE *pHash, BUCKET *pBucket, BUCKET **ppBucketTable, IMG_UINT32 uSize)
+{
+ IMG_UINT32 uIndex;
+
+ /* We assume that all parameters passed by the caller are valid. */
+ PVR_ASSERT(pBucket != NULL);
+ PVR_ASSERT(ppBucketTable != NULL);
+ PVR_ASSERT(uSize != 0);
+
+ uIndex = KEY_TO_INDEX(pHash, pBucket->k, uSize); /* PRQA S 0432,0541 */ /* ignore dynamic array warning */
+ pBucket->pNext = ppBucketTable[uIndex];
+ ppBucketTable[uIndex] = pBucket;
+}
+
+/*************************************************************************/ /*!
+@Function _Rehash
+@Description Iterate over every entry in an old hash table and rehash into
+ the new table.
+@Input ppOldTable The old hash table
+@Input uOldSize The size of the old hash table
+@Input ppNewTable The new hash table
+@Input uNewSize The size of the new hash table
+@Return None
+*/ /**************************************************************************/
+static void
+_Rehash(HASH_TABLE *pHash,
+ BUCKET **ppOldTable, IMG_UINT32 uOldSize,
+ BUCKET **ppNewTable, IMG_UINT32 uNewSize)
+{
+ IMG_UINT32 uIndex;
+ for (uIndex=0; uIndex< uOldSize; uIndex++)
+ {
+ BUCKET *pBucket;
+ pBucket = ppOldTable[uIndex];
+ while (pBucket != NULL)
+ {
+ BUCKET *pNextBucket = pBucket->pNext;
+ _ChainInsert(pHash, pBucket, ppNewTable, uNewSize);
+ pBucket = pNextBucket;
+ }
+ }
+}
+
+/*************************************************************************/ /*!
+@Function _Resize
+@Description Attempt to resize a hash table, failure to allocate a new
+ larger hash table is not considered a hard failure. We simply
+ continue and allow the table to fill up, the effect is to
+ allow hash chains to become longer.
+@Input pHash Hash table to resize.
+@Input uNewSize Required table size.
+@Return IMG_TRUE Success
+ IMG_FALSE Failed
+*/ /**************************************************************************/
+static IMG_BOOL
+_Resize(HASH_TABLE *pHash, IMG_UINT32 uNewSize)
+{
+ BUCKET **ppNewTable;
+ IMG_UINT32 uiThreshold = uNewSize >> 2;
+#if !defined(__KERNEL__) && defined(PERF_DBG_RESIZE)
+ struct timeval start, end;
+#endif
+
+ if (uNewSize == pHash->uSize)
+ {
+ return IMG_TRUE;
+ }
+
+#if !defined(__KERNEL__) && defined(PERF_DBG_RESIZE)
+ gettimeofday(&start, NULL);
+#endif
+
+ ppNewTable = _AllocZMem(sizeof(BUCKET *) * uNewSize);
+ if (ppNewTable == NULL)
+ {
+ return IMG_FALSE;
+ }
+
+ _Rehash(pHash, pHash->ppBucketTable, pHash->uSize, ppNewTable, uNewSize);
+
+ _FreeMem(pHash->ppBucketTable);
+
+#if !defined(__KERNEL__) && defined(PERF_DBG_RESIZE)
+ gettimeofday(&end, NULL);
+ if (start.tv_usec > end.tv_usec)
+ {
+ end.tv_usec = 1000000 - start.tv_usec + end.tv_usec;
+ }
+ else
+ {
+ end.tv_usec -= start.tv_usec;
+ }
+
+ PVR_DPF((PVR_DBG_ERROR, "%s: H:%p O:%d N:%d C:%d G:%d S:%d T:%06luus", __func__, pHash, pHash->uSize, uNewSize, pHash->uCount, pHash->uGrowThreshold, pHash->uShrinkThreshold, end.tv_usec));
+#endif
+
+ /*not nulling pointer, being reassigned just below*/
+ pHash->ppBucketTable = ppNewTable;
+ pHash->uSize = uNewSize;
+
+ pHash->uGrowThreshold = uiThreshold * 3;
+ pHash->uShrinkThreshold = (uNewSize <= pHash->uMinimumSize) ? NO_SHRINK : uiThreshold;
+
+ return IMG_TRUE;
+}
+
+
+/*************************************************************************/ /*!
+@Function HASH_Create_Extended
+@Description Create a self scaling hash table, using the supplied key size,
+ and the supplied hash and key comparison functions.
+@Input uInitialLen Initial and minimum length of the hash table,
+ where the length refers to the number of entries
+ in the hash table, not its size in bytes.
+@Input uKeySize The size of the key, in bytes.
+@Input pfnHashFunc Pointer to hash function.
+@Input pfnKeyComp Pointer to key comparison function.
+@Return NULL or hash table handle.
+*/ /**************************************************************************/
+IMG_INTERNAL
+HASH_TABLE * HASH_Create_Extended_Int (IMG_UINT32 uInitialLen, size_t uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp)
+{
+ HASH_TABLE *pHash;
+
+ if (uInitialLen == 0 || uKeySize == 0 || pfnHashFunc == NULL || pfnKeyComp == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: invalid input parameters", __func__));
+ return NULL;
+ }
+
+ PVR_DPF((PVR_DBG_MESSAGE, "%s: InitialSize=0x%x", __func__, uInitialLen));
+
+ pHash = _AllocMem(sizeof(HASH_TABLE));
+ if (pHash == NULL)
+ {
+ return NULL;
+ }
+
+ pHash->uCount = 0;
+ pHash->uSize = uInitialLen;
+ pHash->uMinimumSize = uInitialLen;
+ pHash->uKeySize = uKeySize;
+ pHash->uGrowThreshold = (uInitialLen >> 2) * 3;
+ pHash->uShrinkThreshold = NO_SHRINK;
+ pHash->pfnHashFunc = pfnHashFunc;
+ pHash->pfnKeyComp = pfnKeyComp;
+
+ pHash->ppBucketTable = _AllocZMem(sizeof(BUCKET *) * pHash->uSize);
+ if (pHash->ppBucketTable == NULL)
+ {
+ _FreeMem(pHash);
+ /*not nulling pointer, out of scope*/
+ return NULL;
+ }
+
+ return pHash;
+}
+
+#if defined(DEBUG)
+IMG_INTERNAL
+HASH_TABLE * HASH_Create_Extended_Debug (IMG_UINT32 uInitialLen, size_t uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp,
+ const char *file, const unsigned int line)
+{
+ HASH_TABLE *hash;
+ hash = HASH_Create_Extended_Int(uInitialLen, uKeySize,
+ pfnHashFunc, pfnKeyComp);
+ if (hash)
+ {
+ hash->pszFile = file;
+ hash->ui32LineNum = line;
+ }
+ return hash;
+}
+#endif
+
+/*************************************************************************/ /*!
+@Function HASH_Create
+@Description Create a self scaling hash table with a key consisting of a
+ single uintptr_t, and using the default hash and key
+ comparison functions.
+@Input uInitialLen Initial and minimum length of the hash table,
+ where the length refers to the number of entries
+ in the hash table, not its size in bytes.
+@Return NULL or hash table handle.
+*/ /**************************************************************************/
+IMG_INTERNAL
+HASH_TABLE * HASH_Create_Int (IMG_UINT32 uInitialLen)
+{
+ return HASH_Create_Extended_Int(uInitialLen, sizeof(uintptr_t),
+ &HASH_Func_Default, &HASH_Key_Comp_Default);
+}
+
+#if defined(DEBUG)
+IMG_INTERNAL
+HASH_TABLE * HASH_Create_Debug(IMG_UINT32 uInitialLen, const char *file, const unsigned int line)
+{
+ HASH_TABLE *hash;
+ hash = HASH_Create_Extended_Int(uInitialLen, sizeof(uintptr_t),
+ &HASH_Func_Default, &HASH_Key_Comp_Default);
+ if (hash)
+ {
+ hash->pszFile = file;
+ hash->ui32LineNum = line;
+ }
+ return hash;
+}
+#endif
+
+/*************************************************************************/ /*!
+@Function HASH_Delete_Extended
+@Description Delete a hash table created by HASH_Create_Extended or
+ HASH_Create. All entries in the table should have been removed
+ before calling this function.
+@Input pHash Hash table
+@Input bWarn Set false to suppress warnings in the case of
+ deletion with active entries.
+*/ /**************************************************************************/
+IMG_INTERNAL void
+HASH_Delete_Extended(HASH_TABLE *pHash, IMG_BOOL bWarn)
+{
+ IMG_BOOL bDoCheck = IMG_TRUE;
+#if defined(__KERNEL__) && !defined(__QNXNTO__)
+ PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
+
+ if (psPVRSRVData != NULL)
+ {
+ if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
+ {
+ bDoCheck = IMG_FALSE;
+ }
+ }
+#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE)
+ else
+ {
+ bDoCheck = IMG_FALSE;
+ }
+#endif
+#endif
+ if (pHash != NULL)
+ {
+ PVR_DPF((PVR_DBG_MESSAGE, "HASH_Delete"));
+
+ if (bDoCheck)
+ {
+ PVR_ASSERT(pHash->uCount==0);
+ }
+ if (pHash->uCount != 0)
+ {
+ IMG_UINT32 i;
+ if (bWarn)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Leak detected in hash table!", __func__));
+ PVR_DPF((PVR_DBG_ERROR, "%s: Likely Cause: client drivers not freeing allocations before destroying devmem context", __func__));
+ PVR_DPF((PVR_DBG_ERROR, "%s: Removing remaining %u hash entries.", __func__, pHash->uCount));
+#if defined(DEBUG)
+ PVR_DPF ((PVR_DBG_ERROR, "%s: Hash %p created at %s:%u.", __func__, (uintptr_t*)pHash, pHash->pszFile, pHash->ui32LineNum));
+#endif
+ }
+
+ for (i = 0; i < pHash->uSize; i++)
+ {
+ BUCKET *pBucket = pHash->ppBucketTable[i];
+ while (pBucket != NULL)
+ {
+ BUCKET *pNextBucket = pBucket->pNext;
+ _FreeMem(pBucket);
+ pBucket = pNextBucket;
+ }
+ }
+
+ }
+ _FreeMem(pHash->ppBucketTable);
+ pHash->ppBucketTable = NULL;
+ _FreeMem(pHash);
+ /*not nulling pointer, copy on stack*/
+ }
+}
+
+/*************************************************************************/ /*!
+@Function HASH_Delete
+@Description Delete a hash table created by HASH_Create_Extended or
+ HASH_Create. All entries in the table must have been removed
+ before calling this function.
+@Input pHash Hash table
+*/ /**************************************************************************/
+IMG_INTERNAL void
+HASH_Delete(HASH_TABLE *pHash)
+{
+ HASH_Delete_Extended(pHash, IMG_TRUE);
+}
+
+/*************************************************************************/ /*!
+@Function HASH_Insert_Extended
+@Description Insert a key value pair into a hash table created with
+ HASH_Create_Extended.
+@Input pHash The hash table.
+@Input pKey Pointer to the key.
+@Input v The value associated with the key.
+@Return IMG_TRUE - success.
+ IMG_FALSE - failure.
+*/ /**************************************************************************/
+IMG_INTERNAL IMG_BOOL
+HASH_Insert_Extended(HASH_TABLE *pHash, void *pKey, uintptr_t v)
+{
+ BUCKET *pBucket;
+
+ PVR_ASSERT(pHash != NULL);
+
+ if (pHash == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: invalid parameter", __func__));
+ return IMG_FALSE;
+ }
+
+ pBucket = _AllocMem(sizeof(BUCKET) + pHash->uKeySize);
+ if (pBucket == NULL)
+ {
+ return IMG_FALSE;
+ }
+
+ pBucket->v = v;
+ /* PRQA S 0432,0541 1 */ /* ignore warning about dynamic array k (linux)*/
+ OSCachedMemCopy(pBucket->k, pKey, pHash->uKeySize);
+
+ _ChainInsert(pHash, pBucket, pHash->ppBucketTable, pHash->uSize);
+
+ pHash->uCount++;
+
+ /* check if we need to think about re-balancing */
+ if (pHash->uCount > pHash->uGrowThreshold)
+ {
+ /* Ignore the return code from _Resize because the hash table is
+ still in a valid state and although not ideally sized, it is still
+ functional */
+ _Resize(pHash, pHash->uSize << 1);
+ }
+
+ return IMG_TRUE;
+}
+
+/*************************************************************************/ /*!
+@Function HASH_Insert
+@Description Insert a key value pair into a hash table created with
+ HASH_Create.
+@Input pHash The hash table.
+@Input k The key value.
+@Input v The value associated with the key.
+@Return IMG_TRUE - success.
+ IMG_FALSE - failure.
+*/ /**************************************************************************/
+IMG_INTERNAL IMG_BOOL
+HASH_Insert(HASH_TABLE *pHash, uintptr_t k, uintptr_t v)
+{
+ return HASH_Insert_Extended(pHash, &k, v);
+}
+
+/*************************************************************************/ /*!
+@Function HASH_Remove_Extended
+@Description Remove a key from a hash table created with
+ HASH_Create_Extended.
+@Input pHash The hash table.
+@Input pKey Pointer to key.
+@Return 0 if the key is missing, or the value associated with the key.
+*/ /**************************************************************************/
+IMG_INTERNAL uintptr_t
+HASH_Remove_Extended(HASH_TABLE *pHash, void *pKey)
+{
+ BUCKET **ppBucket;
+ IMG_UINT32 uIndex;
+
+ PVR_ASSERT(pHash != NULL);
+
+ if (pHash == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Null hash table", __func__));
+ return 0;
+ }
+
+ uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize);
+
+ for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != NULL; ppBucket = &((*ppBucket)->pNext))
+ {
+ /* PRQA S 0432,0541 1 */ /* ignore warning about dynamic array k */
+ if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey))
+ {
+ BUCKET *pBucket = *ppBucket;
+ uintptr_t v = pBucket->v;
+ (*ppBucket) = pBucket->pNext;
+
+ _FreeMem(pBucket);
+ /*not nulling original pointer, already overwritten*/
+
+ pHash->uCount--;
+
+ /* check if we need to think about re-balancing, when the shrink
+ * threshold is 0 we are at the minimum size, no further shrink */
+ if (pHash->uCount < pHash->uShrinkThreshold)
+ {
+ /* Ignore the return code from _Resize because the
+ hash table is still in a valid state and although
+ not ideally sized, it is still functional */
+ _Resize(pHash, MAX(pHash->uSize >> 1, pHash->uMinimumSize));
+ }
+
+ return v;
+ }
+ }
+ return 0;
+}
+
+/*************************************************************************/ /*!
+@Function HASH_Remove
+@Description Remove a key value pair from a hash table created with
+ HASH_Create.
+@Input pHash The hash table.
+@Input pKey Pointer to key.
+@Return 0 if the key is missing, or the value associated with the key.
+*/ /**************************************************************************/
+IMG_INTERNAL uintptr_t
+HASH_Remove(HASH_TABLE *pHash, uintptr_t k)
+{
+ return HASH_Remove_Extended(pHash, &k);
+}
+
+/*************************************************************************/ /*!
+@Function HASH_Retrieve_Extended
+@Description Retrieve a value from a hash table created with
+ HASH_Create_Extended.
+@Input pHash The hash table.
+@Input pKey Pointer to key.
+@Return 0 if the key is missing, or the value associated with the key.
+*/ /**************************************************************************/
+IMG_INTERNAL uintptr_t
+HASH_Retrieve_Extended(HASH_TABLE *pHash, void *pKey)
+{
+ BUCKET **ppBucket;
+ IMG_UINT32 uIndex;
+
+ PVR_ASSERT(pHash != NULL);
+
+ if (pHash == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Null hash table", __func__));
+ return 0;
+ }
+
+ uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize);
+
+ for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != NULL; ppBucket = &((*ppBucket)->pNext))
+ {
+ /* PRQA S 0432,0541 1 */ /* ignore warning about dynamic array k */
+ if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey))
+ {
+ BUCKET *pBucket = *ppBucket;
+ uintptr_t v = pBucket->v;
+
+ return v;
+ }
+ }
+ return 0;
+}
+
+/*************************************************************************/ /*!
+@Function HASH_Retrieve
+@Description Retrieve a value from a hash table created with HASH_Create.
+@Input pHash The hash table.
+@Input pKey Pointer to key.
+@Return 0 if the key is missing, or the value associated with the key.
+*/ /**************************************************************************/
+IMG_INTERNAL uintptr_t
+HASH_Retrieve(HASH_TABLE *pHash, uintptr_t k)
+{
+ return HASH_Retrieve_Extended(pHash, &k);
+}
+
+/*************************************************************************/ /*!
+@Function HASH_Iterate
+@Description Iterate over every entry in the hash table.
+@Input pHash Hash table to iterate.
+@Input pfnCallback Callback to call with the key and data for each
+. entry in the hash table
+@Return Callback error if any, otherwise PVRSRV_OK
+*/ /**************************************************************************/
+IMG_INTERNAL PVRSRV_ERROR
+HASH_Iterate(HASH_TABLE *pHash, HASH_pfnCallback pfnCallback, void* args)
+{
+ IMG_UINT32 uIndex;
+ for (uIndex=0; uIndex < pHash->uSize; uIndex++)
+ {
+ BUCKET *pBucket;
+ pBucket = pHash->ppBucketTable[uIndex];
+ while (pBucket != NULL)
+ {
+ PVRSRV_ERROR eError;
+ BUCKET *pNextBucket = pBucket->pNext;
+
+ eError = pfnCallback((uintptr_t) ((void *) *(pBucket->k)), pBucket->v, args);
+
+ /* The callback might want us to break out early */
+ if (eError != PVRSRV_OK)
+ return eError;
+
+ pBucket = pNextBucket;
+ }
+ }
+ return PVRSRV_OK;
+}
+
+#ifdef HASH_TRACE
+/*************************************************************************/ /*!
+@Function HASH_Dump
+@Description Dump out some information about a hash table.
+@Input pHash The hash table.
+*/ /**************************************************************************/
+void
+HASH_Dump(HASH_TABLE *pHash)
+{
+ IMG_UINT32 uIndex;
+ IMG_UINT32 uMaxLength=0;
+ IMG_UINT32 uEmptyCount=0;
+
+ PVR_ASSERT(pHash != NULL);
+ for (uIndex=0; uIndexuSize; uIndex++)
+ {
+ BUCKET *pBucket;
+ IMG_UINT32 uLength = 0;
+ if (pHash->ppBucketTable[uIndex] == NULL)
+ {
+ uEmptyCount++;
+ }
+ for (pBucket=pHash->ppBucketTable[uIndex];
+ pBucket != NULL;
+ pBucket = pBucket->pNext)
+ {
+ uLength++;
+ }
+ uMaxLength = MAX(uMaxLength, uLength);
+ }
+
+ PVR_TRACE(("hash table: uMinimumSize=%d size=%d count=%d",
+ pHash->uMinimumSize, pHash->uSize, pHash->uCount));
+ PVR_TRACE((" empty=%d max=%d", uEmptyCount, uMaxLength));
+}
+#endif
diff --git a/drivers/gpu/drm/img-rogue/hash.h b/drivers/gpu/drm/img-rogue/hash.h
new file mode 100644
index 000000000..92d48990a
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/hash.h
@@ -0,0 +1,247 @@
+/*************************************************************************/ /*!
+@File
+@Title Self scaling hash tables
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Implements simple self scaling hash tables.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef HASH_H
+#define HASH_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * Keys passed to the comparison function are only guaranteed to be aligned on
+ * an uintptr_t boundary.
+ */
+typedef IMG_UINT32 HASH_FUNC(size_t uKeySize, void *pKey, IMG_UINT32 uHashTabLen);
+typedef IMG_BOOL HASH_KEY_COMP(size_t uKeySize, void *pKey1, void *pKey2);
+
+typedef struct _HASH_TABLE_ HASH_TABLE;
+
+typedef PVRSRV_ERROR (*HASH_pfnCallback) (
+ uintptr_t k,
+ uintptr_t v,
+ void* pvPriv
+);
+
+#if defined(DEBUG)
+#else
+#define HASH_CREATE(LEN) HASH_Create(LEN)
+#endif
+
+/*************************************************************************/ /*!
+@Function HASH_Func_Default
+@Description Hash function intended for hashing keys composed of uintptr_t
+ arrays.
+@Input uKeySize The size of the hash key, in bytes.
+@Input pKey A pointer to the key to hash.
+@Input uHashTabLen The length of the hash table.
+@Return The hash value.
+*/ /**************************************************************************/
+IMG_UINT32 HASH_Func_Default(size_t uKeySize, void *pKey, IMG_UINT32 uHashTabLen);
+
+/*************************************************************************/ /*!
+@Function HASH_Key_Comp_Default
+@Description Compares keys composed of uintptr_t arrays.
+@Input uKeySize The size of the hash key, in bytes.
+@Input pKey1 Pointer to first hash key to compare.
+@Input pKey2 Pointer to second hash key to compare.
+@Return IMG_TRUE - The keys match.
+ IMG_FALSE - The keys don't match.
+*/ /**************************************************************************/
+IMG_BOOL HASH_Key_Comp_Default(size_t uKeySize, void *pKey1, void *pKey2);
+
+/*************************************************************************/ /*!
+@Function HASH_Create_Extended
+@Description Create a self scaling hash table, using the supplied key size,
+ and the supplied hash and key comparison functions.
+@Input uInitialLen Initial and minimum length of the hash table,
+ where the length refers to the number of entries
+ in the hash table, not its size in bytes.
+@Input uKeySize The size of the key, in bytes.
+@Input pfnHashFunc Pointer to hash function.
+@Input pfnKeyComp Pointer to key comparison function.
+@Return NULL or hash table handle.
+*/ /**************************************************************************/
+HASH_TABLE * HASH_Create_Extended_Int(IMG_UINT32 uInitialLen, size_t uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp);
+#if defined(DEBUG)
+#define HASH_Create_Extended(LEN, KS, FUN, CMP) HASH_Create_Extended_Debug(LEN, KS, FUN, CMP, __FILE__, __LINE__)
+HASH_TABLE * HASH_Create_Extended_Debug (IMG_UINT32 uInitialLen, size_t uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp,
+ const char *file, const unsigned int line);
+#else
+#define HASH_Create_Extended HASH_Create_Extended_Int
+#endif
+
+/*************************************************************************/ /*!
+@Function HASH_Create
+@Description Create a self scaling hash table with a key consisting of a
+ single uintptr_t, and using the default hash and key
+ comparison functions.
+@Input uInitialLen Initial and minimum length of the hash table,
+ where the length refers to the number of entries
+ in the hash table, not its size in bytes.
+@Return NULL or hash table handle.
+*/ /**************************************************************************/
+HASH_TABLE * HASH_Create_Int(IMG_UINT32 uInitialLen);
+#if defined(DEBUG)
+#define HASH_Create(LEN) HASH_Create_Debug(LEN, __FILE__, __LINE__)
+HASH_TABLE * HASH_Create_Debug (IMG_UINT32 uInitialLen, const char *file, const unsigned int line);
+#else
+#define HASH_Create HASH_Create_Int
+#endif
+
+/*************************************************************************/ /*!
+@Function HASH_Delete_Extended
+@Description Delete a hash table created by HASH_Create_Extended or
+ HASH_Create. All entries in the table should have been removed
+ before calling this function.
+@Input pHash Hash table
+@Input bWarn Set false to suppress warnings in the case of
+ deletion with active entries.
+@Return None
+*/ /**************************************************************************/
+void HASH_Delete_Extended(HASH_TABLE *pHash, IMG_BOOL bWarn);
+
+/*************************************************************************/ /*!
+@Function HASH_Delete
+@Description Delete a hash table created by HASH_Create_Extended or
+ HASH_Create. All entries in the table must have been removed
+ before calling this function.
+@Input pHash Hash table
+@Return None
+*/ /**************************************************************************/
+void HASH_Delete(HASH_TABLE *pHash);
+
+/*************************************************************************/ /*!
+@Function HASH_Insert_Extended
+@Description Insert a key value pair into a hash table created with
+ HASH_Create_Extended.
+@Input pHash The hash table.
+@Input pKey Pointer to the key.
+@Input v The value associated with the key.
+@Return IMG_TRUE - success.
+ IMG_FALSE - failure.
+*/ /**************************************************************************/
+IMG_BOOL HASH_Insert_Extended(HASH_TABLE *pHash, void *pKey, uintptr_t v);
+
+/*************************************************************************/ /*!
+@Function HASH_Insert
+@Description Insert a key value pair into a hash table created with
+ HASH_Create.
+@Input pHash The hash table.
+@Input k The key value.
+@Input v The value associated with the key.
+@Return IMG_TRUE - success.
+ IMG_FALSE - failure.
+*/ /**************************************************************************/
+IMG_BOOL HASH_Insert(HASH_TABLE *pHash, uintptr_t k, uintptr_t v);
+
+/*************************************************************************/ /*!
+@Function HASH_Remove_Extended
+@Description Remove a key from a hash table created with
+ HASH_Create_Extended.
+@Input pHash The hash table.
+@Input pKey Pointer to key.
+@Return 0 if the key is missing, or the value associated with the key.
+*/ /**************************************************************************/
+uintptr_t HASH_Remove_Extended(HASH_TABLE *pHash, void *pKey);
+
+/*************************************************************************/ /*!
+@Function HASH_Remove
+@Description Remove a key value pair from a hash table created with
+ HASH_Create.
+@Input pHash The hash table.
+@Input k The key value.
+@Return 0 if the key is missing, or the value associated with the key.
+*/ /**************************************************************************/
+uintptr_t HASH_Remove(HASH_TABLE *pHash, uintptr_t k);
+
+/*************************************************************************/ /*!
+@Function HASH_Retrieve_Extended
+@Description Retrieve a value from a hash table created with
+ HASH_Create_Extended.
+@Input pHash The hash table.
+@Input pKey Pointer to key.
+@Return 0 if the key is missing, or the value associated with the key.
+*/ /**************************************************************************/
+uintptr_t HASH_Retrieve_Extended(HASH_TABLE *pHash, void *pKey);
+
+/*************************************************************************/ /*!
+@Function HASH_Retrieve
+@Description Retrieve a value from a hash table created with HASH_Create.
+@Input pHash The hash table.
+@Input k The key value.
+@Return 0 if the key is missing, or the value associated with the key.
+*/ /**************************************************************************/
+uintptr_t HASH_Retrieve(HASH_TABLE *pHash, uintptr_t k);
+
+/*************************************************************************/ /*!
+@Function HASH_Iterate
+@Description Iterate over every entry in the hash table.
+@Input pHash Hash table to iterate.
+@Input pfnCallback Callback to call with the key and data for each
+. entry in the hash table
+@Return Callback error if any, otherwise PVRSRV_OK
+*/ /**************************************************************************/
+PVRSRV_ERROR HASH_Iterate(HASH_TABLE *pHash, HASH_pfnCallback pfnCallback, void* args);
+
+#ifdef HASH_TRACE
+/*************************************************************************/ /*!
+@Function HASH_Dump
+@Description Dump out some information about a hash table.
+@Input pHash The hash table.
+*/ /**************************************************************************/
+void HASH_Dump(HASH_TABLE *pHash);
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* HASH_H */
+
+/******************************************************************************
+ End of file (hash.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/htb_debug.c b/drivers/gpu/drm/img-rogue/htb_debug.c
new file mode 100644
index 000000000..f36141465
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/htb_debug.c
@@ -0,0 +1,1190 @@
+/*************************************************************************/ /*!
+@File htb_debug.c
+@Title Debug Functionality
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Provides kernel side debugFS Functionality.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#include "rgxdevice.h"
+#include "htbserver.h"
+#include "htbuffer.h"
+#include "htbuffer_types.h"
+#include "tlstream.h"
+#include "tlclient.h"
+#include "pvrsrv_tlcommon.h"
+#include "di_server.h"
+#include "img_types.h"
+#include "img_defs.h"
+#include "pvrsrv_error.h"
+#include "osfunc.h"
+#include "allocmem.h"
+#include "pvr_notifier.h"
+#include "pvrsrv.h"
+#include "htb_debug.h"
+
+// Global data handles for buffer manipulation and processing
+
+typedef struct {
+ IMG_PBYTE pBuf; /* Raw data buffer from TL stream */
+ IMG_UINT32 uiBufLen; /* Amount of data to process from 'pBuf' */
+ IMG_UINT32 uiTotal; /* Total bytes processed */
+ IMG_UINT32 uiMsgLen; /* Length of HTB message to be processed */
+ IMG_PBYTE pCurr; /* pointer to current message to be decoded */
+ IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN]; /* Output string */
+} HTB_Sentinel_t;
+
+typedef struct
+{
+ DI_ENTRY *psDumpHostDiEntry; /* debug info entry */
+ HTB_Sentinel_t sSentinel; /* private control structure for HTB DI
+ operations */
+ IMG_HANDLE hStream; /* stream handle for debugFS use */
+} HTB_DBG_INFO;
+
+static HTB_DBG_INFO g_sHTBData;
+
+// Comment out for extra debug level
+// #define HTB_CHATTY_PRINT(x) PVR_DPF(x)
+#define HTB_CHATTY_PRINT(x)
+
+typedef void (DI_PRINTF)(const OSDI_IMPL_ENTRY *, const IMG_CHAR *, ...);
+
+/******************************************************************************
+ * debugFS display routines
+ *****************************************************************************/
+static int HTBDumpBuffer(DI_PRINTF, OSDI_IMPL_ENTRY *, void *);
+
+static int _DebugHBTraceDIShow(OSDI_IMPL_ENTRY *psEntry, void *pvData)
+{
+ int retVal;
+
+ PVR_ASSERT(psEntry != NULL);
+
+ /* psEntry should never be NULL */
+ if (psEntry == NULL)
+ {
+ return -1;
+ }
+
+ /* Ensure that we have a valid address to use to dump info from. If NULL we
+ * return a failure code to terminate the DI read call. pvData is either
+ * DI_START_TOKEN (for the initial call) or an HTB buffer address for
+ * subsequent calls [returned from the NEXT function]. */
+ if (pvData == NULL)
+ {
+ return -1;
+ }
+
+ retVal = HTBDumpBuffer(DIPrintf, psEntry, pvData);
+
+ HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: Returning %d", __func__, retVal));
+
+ return retVal;
+}
+
+static IMG_UINT32 idToLogIdx(IMG_UINT32); /* Forward declaration */
+
+/*
+ * HTB_GetNextMessage
+ *
+ * Get next non-empty message block from the buffer held in pSentinel->pBuf
+ * If we exhaust the data buffer we refill it (after releasing the previous
+ * message(s) [only one non-NULL message, but PAD messages will get released
+ * as we traverse them].
+ *
+ * Input:
+ * pSentinel references the already acquired data buffer
+ *
+ * Output:
+ * pSentinel
+ * -> uiMsglen updated to the size of the non-NULL message
+ *
+ * Returns:
+ * Address of first non-NULL message in the buffer (if any)
+ * NULL if there is no further data available from the stream and the buffer
+ * contents have been drained.
+ */
+static IMG_PBYTE HTB_GetNextMessage(HTB_Sentinel_t *pSentinel)
+{
+ void *pNext, *pLast, *pStart, *pData = NULL;
+ void *pCurrent; /* Current processing point within buffer */
+ PVRSRVTL_PPACKETHDR ppHdr; /* Current packet header */
+ IMG_UINT32 uiHdrType; /* Packet header type */
+ IMG_UINT32 uiMsgSize; /* Message size of current packet (bytes) */
+ IMG_BOOL bUnrecognizedErrorPrinted = IMG_FALSE;
+ IMG_UINT32 ui32Data;
+ IMG_UINT32 ui32LogIdx;
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(pSentinel != NULL);
+
+ pLast = pSentinel->pBuf + pSentinel->uiBufLen;
+
+ pStart = pSentinel->pBuf;
+
+ pNext = pStart;
+ pSentinel->uiMsgLen = 0; // Reset count for this message
+ uiMsgSize = 0; // nothing processed so far
+ ui32LogIdx = HTB_SF_LAST; // Loop terminator condition
+
+ do
+ {
+ /*
+ * If we've drained the buffer we must RELEASE and ACQUIRE some more.
+ */
+ if (pNext >= pLast)
+ {
+ eError = TLClientReleaseData(DIRECT_BRIDGE_HANDLE, g_sHTBData.hStream);
+ PVR_ASSERT(eError == PVRSRV_OK);
+
+ eError = TLClientAcquireData(DIRECT_BRIDGE_HANDLE,
+ g_sHTBData.hStream, &pSentinel->pBuf, &pSentinel->uiBufLen);
+
+ if (PVRSRV_OK != eError)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: %s FAILED '%s'", __func__,
+ "TLClientAcquireData", PVRSRVGETERRORSTRING(eError)));
+ return NULL;
+ }
+
+ // Reset our limits - if we've returned an empty buffer we're done.
+ pLast = pSentinel->pBuf + pSentinel->uiBufLen;
+ pStart = pSentinel->pBuf;
+ pNext = pStart;
+
+ if (pStart == NULL || pLast == NULL)
+ {
+ return NULL;
+ }
+ }
+
+ /*
+ * We should have a header followed by data block(s) in the stream.
+ */
+
+ pCurrent = pNext;
+ ppHdr = GET_PACKET_HDR(pCurrent);
+
+ if (ppHdr == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Unexpected NULL packet in Host Trace buffer",
+ __func__));
+ pSentinel->uiMsgLen += uiMsgSize;
+ return NULL; // This should never happen
+ }
+
+ /*
+ * This should *NEVER* fire. If it does it means we have got some
+ * dubious packet header back from the HTB stream. In this case
+ * the sensible thing is to abort processing and return to
+ * the caller
+ */
+ uiHdrType = GET_PACKET_TYPE(ppHdr);
+
+ PVR_ASSERT(uiHdrType < PVRSRVTL_PACKETTYPE_LAST &&
+ uiHdrType > PVRSRVTL_PACKETTYPE_UNDEF);
+
+ if (uiHdrType < PVRSRVTL_PACKETTYPE_LAST &&
+ uiHdrType > PVRSRVTL_PACKETTYPE_UNDEF)
+ {
+ /*
+ * We have a (potentially) valid data header. We should see if
+ * the associated packet header matches one of our expected
+ * types.
+ */
+ pNext = GET_NEXT_PACKET_ADDR(ppHdr);
+
+ PVR_ASSERT(pNext != NULL);
+
+ uiMsgSize = (IMG_UINT32)((size_t)pNext - (size_t)ppHdr);
+
+ pSentinel->uiMsgLen += uiMsgSize;
+
+ pData = GET_PACKET_DATA_PTR(ppHdr);
+
+ /*
+ * Handle non-DATA packet types. These include PAD fields which
+ * may have data associated and other types. We simply discard
+ * these as they have no decodable information within them.
+ */
+ if (uiHdrType != PVRSRVTL_PACKETTYPE_DATA)
+ {
+ /*
+ * Now release the current non-data packet and proceed to the
+ * next entry (if any).
+ */
+ eError = TLClientReleaseDataLess(DIRECT_BRIDGE_HANDLE,
+ g_sHTBData.hStream, uiMsgSize);
+
+ HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: Packet Type %x "
+ "Length %u", __func__, uiHdrType, uiMsgSize));
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: %s FAILED - '%s' message"
+ " size %u", __func__, "TLClientReleaseDataLess",
+ PVRSRVGETERRORSTRING(eError), uiMsgSize));
+ }
+
+ eError = TLClientAcquireData(DIRECT_BRIDGE_HANDLE,
+ g_sHTBData.hStream, &pSentinel->pBuf, &pSentinel->uiBufLen);
+
+ if (PVRSRV_OK != eError)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: %s FAILED - %s Giving up",
+ __func__, "TLClientAcquireData",
+ PVRSRVGETERRORSTRING(eError)));
+
+ return NULL;
+ }
+ pSentinel->uiMsgLen = 0;
+ // Reset our limits - if we've returned an empty buffer we're done.
+ pLast = pSentinel->pBuf + pSentinel->uiBufLen;
+ pStart = pSentinel->pBuf;
+ pNext = pStart;
+
+ if (pStart == NULL || pLast == NULL)
+ {
+ return NULL;
+ }
+ continue;
+ }
+ if (pData == NULL || pData >= pLast)
+ {
+ continue;
+ }
+ ui32Data = *(IMG_UINT32 *)pData;
+ ui32LogIdx = idToLogIdx(ui32Data);
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_WARNING, "Unexpected Header @%p value %x",
+ ppHdr, uiHdrType));
+
+ return NULL;
+ }
+
+ /*
+ * Check if the unrecognized ID is valid and therefore, tracebuf
+ * needs updating.
+ */
+ if (HTB_SF_LAST == ui32LogIdx && HTB_LOG_VALIDID(ui32Data)
+ && IMG_FALSE == bUnrecognizedErrorPrinted)
+ {
+ PVR_DPF((PVR_DBG_WARNING,
+ "%s: Unrecognised LOG value '%x' GID %x Params %d ID %x @ '%p'",
+ __func__, ui32Data, HTB_SF_GID(ui32Data),
+ HTB_SF_PARAMNUM(ui32Data), ui32Data & 0xfff, pData));
+ bUnrecognizedErrorPrinted = IMG_FALSE;
+ }
+
+ } while (HTB_SF_LAST == ui32LogIdx);
+
+ HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: Returning data @ %p Log value '%x'",
+ __func__, pCurrent, ui32Data));
+
+ return pCurrent;
+}
+
+/*
+ * HTB_GetFirstMessage
+ *
+ * Called from START to obtain the buffer address of the first message within
+ * pSentinel->pBuf. Will ACQUIRE data if the buffer is empty.
+ *
+ * Input:
+ * pSentinel
+ * pui64Pos Offset within the debugFS file
+ *
+ * Output:
+ * pSentinel->pCurr Set to reference the first valid non-NULL message within
+ * the buffer. If no valid message is found set to NULL.
+ * pSentinel
+ * ->pBuf if unset on entry
+ * ->uiBufLen if pBuf unset on entry
+ *
+ * Side-effects:
+ * HTB TL stream will be updated to bypass any zero-length PAD messages before
+ * the first non-NULL message (if any).
+ */
+static void HTB_GetFirstMessage(HTB_Sentinel_t *pSentinel, IMG_UINT64 *pui64Pos)
+{
+ PVRSRV_ERROR eError;
+
+ PVR_UNREFERENCED_PARAMETER(pui64Pos);
+
+ if (pSentinel == NULL)
+ return;
+
+ if (pSentinel->pBuf == NULL)
+ {
+ /* Acquire data */
+ pSentinel->uiMsgLen = 0;
+
+ eError = TLClientAcquireData(DIRECT_BRIDGE_HANDLE,
+ g_sHTBData.hStream, &pSentinel->pBuf, &pSentinel->uiBufLen);
+
+ if (PVRSRV_OK != eError)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: %s FAILED '%s'",
+ __func__, "TLClientAcquireData", PVRSRVGETERRORSTRING(eError)));
+
+ pSentinel->pBuf = NULL;
+ pSentinel->pCurr = NULL;
+ }
+ else
+ {
+ /*
+ * If there is no data available we set pSentinel->pCurr to NULL
+ * and return. This is expected behaviour if we've drained the
+ * data and nothing else has yet been produced.
+ */
+ if (pSentinel->uiBufLen == 0 || pSentinel->pBuf == NULL)
+ {
+ HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: Empty Buffer @ %p",
+ __func__, pSentinel->pBuf));
+
+ pSentinel->pCurr = NULL;
+ return;
+ }
+ }
+ }
+
+ /* Locate next message within buffer. NULL => no more data to process */
+ pSentinel->pCurr = HTB_GetNextMessage(pSentinel);
+}
+
+/*
+ * _DebugHBTraceDIStart:
+ *
+ * Returns the address to use for subsequent 'Show', 'Next', 'Stop' file ops.
+ * Return DI_START_TOKEN for the very first call and allocate a sentinel for
+ * use by the 'Show' routine and its helpers.
+ * This is stored in the psEntry's private hook field.
+ *
+ * We obtain access to the TLstream associated with the HTB. If this doesn't
+ * exist (because no pvrdebug capture trace has been set) we simply return with
+ * a NULL value which will stop the DI traversal.
+ */
+static void *_DebugHBTraceDIStart(OSDI_IMPL_ENTRY *psEntry,
+ IMG_UINT64 *pui64Pos)
+{
+ HTB_Sentinel_t *pSentinel = DIGetPrivData(psEntry);
+ PVRSRV_ERROR eError;
+ IMG_UINT32 uiTLMode;
+ void *retVal;
+ IMG_HANDLE hStream;
+
+ /* The sentinel object should have been allocated during the creation
+ * of the DI entry. If it's not there it means that something went
+ * wrong. Return NULL in such case. */
+ if (pSentinel == NULL)
+ {
+ return NULL;
+ }
+
+ /* Check to see if the HTB stream has been configured yet. If not, there is
+ * nothing to display so we just return NULL to stop the stream access.
+ */
+ if (!HTBIsConfigured())
+ {
+ return NULL;
+ }
+
+ /* Open the stream in non-blocking mode so that we can determine if there
+ * is no data to consume. Also disable the producer callback (if any) and
+ * the open callback so that we do not generate spurious trace data when
+ * accessing the stream.
+ */
+ uiTLMode = PVRSRV_STREAM_FLAG_ACQUIRE_NONBLOCKING|
+ PVRSRV_STREAM_FLAG_DISABLE_PRODUCER_CALLBACK|
+ PVRSRV_STREAM_FLAG_IGNORE_OPEN_CALLBACK;
+
+ /* If two or more processes try to read from this file at the same time
+ * the TLClientOpenStream() function will handle this by allowing only
+ * one of them to actually open the stream. The other process will get
+ * an error stating that the stream is already open. The open function
+ * is threads safe. */
+ eError = TLClientOpenStream(DIRECT_BRIDGE_HANDLE, HTB_STREAM_NAME, uiTLMode,
+ &hStream);
+
+ if (eError == PVRSRV_ERROR_ALREADY_OPEN)
+ {
+ /* Stream allows only one reader so return error if it's already
+ * opened. */
+ HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: Stream handle %p already "
+ "exists for %s", __func__, g_sHTBData.hStream,
+ HTB_STREAM_NAME));
+ return NULL;
+ }
+ else if (eError != PVRSRV_OK)
+ {
+ /*
+ * No stream available so nothing to report
+ */
+ return NULL;
+ }
+
+ /* There is a window where hStream can be NULL but the stream is already
+ * opened. This shouldn't matter since the TLClientOpenStream() will make
+ * sure that only one stream can be opened and only one process can reach
+ * this place at a time. Also the .stop function will be always called
+ * after this function returns so there should be no risk of stream
+ * not being closed. */
+ PVR_ASSERT(g_sHTBData.hStream == NULL);
+ g_sHTBData.hStream = hStream;
+
+ /* We're starting the read operation so ensure we properly zero the
+ * sentinel object. */
+ memset(pSentinel, 0, sizeof(*pSentinel));
+
+ /*
+ * Find the first message location within pSentinel->pBuf
+ * => for DI_START_TOKEN we must issue our first ACQUIRE, also for the
+ * subsequent re-START calls (if any).
+ */
+
+ HTB_GetFirstMessage(pSentinel, pui64Pos);
+
+ retVal = *pui64Pos == 0 ? DI_START_TOKEN : pSentinel->pCurr;
+
+ HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: Returning %p, Stream %s @ %p",
+ __func__, retVal, HTB_STREAM_NAME, g_sHTBData.hStream));
+
+ return retVal;
+}
+
+/*
+ * _DebugTBTraceDIStop:
+ *
+ * Stop processing data collection and release any previously allocated private
+ * data structure if we have exhausted the previously filled data buffers.
+ */
+static void _DebugHBTraceDIStop(OSDI_IMPL_ENTRY *psEntry, void *pvData)
+{
+ HTB_Sentinel_t *pSentinel = DIGetPrivData(psEntry);
+ IMG_UINT32 uiMsgLen;
+ PVRSRV_ERROR eError;
+
+ if (pSentinel == NULL)
+ {
+ return;
+ }
+
+ uiMsgLen = pSentinel->uiMsgLen;
+
+ HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: MsgLen = %d", __func__, uiMsgLen));
+
+ /* If we get here the handle should never be NULL because
+ * _DebugHBTraceDIStart() shouldn't allow that. */
+ if (g_sHTBData.hStream == NULL)
+ {
+ return;
+ }
+
+ if (uiMsgLen != 0)
+ {
+ eError = TLClientReleaseDataLess(DIRECT_BRIDGE_HANDLE,
+ g_sHTBData.hStream, uiMsgLen);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: %s FAILED - %s, nBytes %u",
+ __func__, "TLClientReleaseDataLess",
+ PVRSRVGETERRORSTRING(eError), uiMsgLen));
+ }
+ }
+
+ eError = TLClientCloseStream(DIRECT_BRIDGE_HANDLE, g_sHTBData.hStream);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s() failed (%s) in %s()",
+ "TLClientCloseStream", PVRSRVGETERRORSTRING(eError),
+ __func__));
+ }
+
+ g_sHTBData.hStream = NULL;
+}
+
+
+/*
+ * _DebugHBTraceDINext:
+ *
+ * This is where we release any acquired data which has been processed by the
+ * DIShow routine. If we have encountered a DI entry overflow we stop
+ * processing and return NULL. Otherwise we release the message that we
+ * previously processed and simply update our position pointer to the next
+ * valid HTB message (if any)
+ */
+static void *_DebugHBTraceDINext(OSDI_IMPL_ENTRY *psEntry, void *pvPriv,
+ IMG_UINT64 *pui64Pos)
+{
+ HTB_Sentinel_t *pSentinel = DIGetPrivData(psEntry);
+ IMG_UINT64 ui64CurPos;
+ PVRSRV_ERROR eError;
+
+ PVR_UNREFERENCED_PARAMETER(pvPriv);
+
+ if (pui64Pos)
+ {
+ ui64CurPos = *pui64Pos;
+ *pui64Pos = ui64CurPos + 1;
+ }
+
+ /* Determine if we've had an overflow on the previous 'Show' call. If so
+ * we leave the previously acquired data in the queue (by releasing 0 bytes)
+ * and return NULL to end this DI entry iteration.
+ * If we have not overflowed we simply get the next HTB message and use that
+ * for our display purposes. */
+
+ if (DIHasOverflowed(psEntry))
+ {
+ (void) TLClientReleaseDataLess(DIRECT_BRIDGE_HANDLE, g_sHTBData.hStream,
+ 0);
+
+ HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: OVERFLOW - returning NULL",
+ __func__));
+
+ return NULL;
+ }
+ else
+ {
+ eError = TLClientReleaseDataLess(DIRECT_BRIDGE_HANDLE,
+ g_sHTBData.hStream,
+ pSentinel->uiMsgLen);
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: %s FAILED '%s' @ %p Length %d",
+ __func__, "TLClientReleaseDataLess",
+ PVRSRVGETERRORSTRING(eError), pSentinel->pCurr,
+ pSentinel->uiMsgLen));
+ PVR_DPF((PVR_DBG_WARNING, "%s: Buffer @ %p..%p", __func__,
+ pSentinel->pBuf,
+ (IMG_PBYTE) (pSentinel->pBuf + pSentinel->uiBufLen)));
+
+ }
+
+ eError = TLClientAcquireData(DIRECT_BRIDGE_HANDLE,
+ g_sHTBData.hStream, &pSentinel->pBuf,
+ &pSentinel->uiBufLen);
+
+ if (eError != PVRSRV_OK)
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s: %s FAILED '%s'\nPrev message len %d",
+ __func__, "TLClientAcquireData",
+ PVRSRVGETERRORSTRING(eError), pSentinel->uiMsgLen));
+ pSentinel->pBuf = NULL;
+ }
+
+ pSentinel->uiMsgLen = 0; /* We don't (yet) know the message size */
+ }
+
+ HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: Returning %p Msglen %d", __func__,
+ pSentinel->pBuf, pSentinel->uiMsgLen));
+
+ if (pSentinel->pBuf == NULL || pSentinel->uiBufLen == 0)
+ {
+ return NULL;
+ }
+
+ pSentinel->pCurr = HTB_GetNextMessage(pSentinel);
+
+ return pSentinel->pCurr;
+}
+
+/******************************************************************************
+ * HTB Dumping routines and definitions
+ *****************************************************************************/
+#define IS_VALID_FMT_STRING(FMT) (strchr(FMT, '%') != NULL)
+#define MAX_STRING_SIZE (128)
+
+typedef enum
+{
+ TRACEBUF_ARG_TYPE_INT,
+ TRACEBUF_ARG_TYPE_ERR,
+ TRACEBUF_ARG_TYPE_NONE
+} TRACEBUF_ARG_TYPE;
+
+/*
+ * Array of all Host Trace log IDs used to convert the tracebuf data
+ */
+typedef struct _HTB_TRACEBUF_LOG_ {
+ HTB_LOG_SFids eSFId;
+ IMG_CHAR *pszName;
+ IMG_CHAR *pszFmt;
+ IMG_UINT32 ui32ArgNum;
+} HTB_TRACEBUF_LOG;
+
+static const HTB_TRACEBUF_LOG aLogs[] = {
+#define X(a, b, c, d, e) {HTB_LOG_CREATESFID(a,b,e), #c, d, e},
+ HTB_LOG_SFIDLIST
+#undef X
+};
+
+static const IMG_CHAR *aGroups[] = {
+#define X(A,B) #B,
+ HTB_LOG_SFGROUPLIST
+#undef X
+};
+static const IMG_UINT32 uiMax_aGroups = ARRAY_SIZE(aGroups) - 1;
+
+static TRACEBUF_ARG_TYPE ExtractOneArgFmt(IMG_CHAR **, IMG_CHAR *);
+/*
+ * ExtractOneArgFmt
+ *
+ * Scan the input 'printf-like' string *ppszFmt and return the next
+ * value string to be displayed. If there is no '%' format field in the
+ * string we return 'TRACEBUF_ARG_TYPE_NONE' and leave the input string
+ * untouched.
+ *
+ * Input
+ * ppszFmt reference to format string to be decoded
+ * pszOneArgFmt single field format from *ppszFmt
+ *
+ * Returns
+ * TRACEBUF_ARG_TYPE_ERR unrecognised argument
+ * TRACEBUF_ARG_TYPE_INT variable is of numeric type
+ * TRACEBUF_ARG_TYPE_NONE no variable reference in *ppszFmt
+ *
+ * Side-effect
+ * *ppszFmt is updated to reference the next part of the format string
+ * to be scanned
+ */
+static TRACEBUF_ARG_TYPE ExtractOneArgFmt(
+ IMG_CHAR **ppszFmt,
+ IMG_CHAR *pszOneArgFmt)
+{
+ IMG_CHAR *pszFmt;
+ IMG_CHAR *psT;
+ IMG_UINT32 ui32Count = MAX_STRING_SIZE;
+ IMG_UINT32 ui32OneArgSize;
+ TRACEBUF_ARG_TYPE eRet = TRACEBUF_ARG_TYPE_ERR;
+
+ if (NULL == ppszFmt)
+ return TRACEBUF_ARG_TYPE_ERR;
+
+ pszFmt = *ppszFmt;
+ if (NULL == pszFmt)
+ return TRACEBUF_ARG_TYPE_ERR;
+
+ /*
+ * Find the first '%'
+ * NOTE: we can be passed a simple string to display which will have no
+ * parameters embedded within it. In this case we simply return
+ * TRACEBUF_ARG_TYPE_NONE and the string contents will be the full pszFmt
+ */
+ psT = strchr(pszFmt, '%');
+ if (psT == NULL)
+ {
+ return TRACEBUF_ARG_TYPE_NONE;
+ }
+
+ /* Find next conversion identifier after the initial '%' */
+ while ((*psT++) && (ui32Count-- > 0))
+ {
+ switch (*psT)
+ {
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ {
+ eRet = TRACEBUF_ARG_TYPE_INT;
+ goto _found_arg;
+ }
+ case 's':
+ {
+ eRet = TRACEBUF_ARG_TYPE_ERR;
+ goto _found_arg;
+ }
+ }
+ }
+
+ if ((psT == NULL) || (ui32Count == 0)) return TRACEBUF_ARG_TYPE_ERR;
+
+_found_arg:
+ ui32OneArgSize = psT - pszFmt + 1;
+ OSCachedMemCopy(pszOneArgFmt, pszFmt, ui32OneArgSize);
+ pszOneArgFmt[ui32OneArgSize] = '\0';
+
+ *ppszFmt = psT + 1;
+
+ return eRet;
+}
+
+static IMG_UINT32 idToLogIdx(IMG_UINT32 ui32CheckData)
+{
+ IMG_UINT32 i = 0;
+ for (i = 0; aLogs[i].eSFId != HTB_SF_LAST; i++)
+ {
+ if ( ui32CheckData == aLogs[i].eSFId )
+ return i;
+ }
+ /* Nothing found, return max value */
+ return HTB_SF_LAST;
+}
+
+/*
+ * DecodeHTB
+ *
+ * Decode the data buffer message located at pBuf. This should be a valid
+ * HTB message as we are provided with the start of the buffer. If empty there
+ * is no message to process. We update the uiMsgLen field with the size of the
+ * HTB message that we have processed so that it can be returned to the system
+ * on successful logging of the message to the output file.
+ *
+ * Input
+ * pSentinel reference to newly read data and pending completion data
+ * from a previous invocation [handle DI entry buffer overflow]
+ * -> pBuf reference to raw data that we are to parse
+ * -> uiBufLen total number of bytes of data available
+ * -> pCurr start of message to decode
+ *
+ * pvDumpDebugFile output file
+ * pfnDumpDebugPrintf output generating routine
+ *
+ * Output
+ * pSentinel
+ * -> uiMsgLen length of the decoded message which will be freed to
+ * the system on successful completion of the DI entry
+ * update via _DebugHBTraceDINext(),
+ * Return Value
+ * 0 successful decode
+ * -1 unsuccessful decode
+ */
+static int
+DecodeHTB(HTB_Sentinel_t *pSentinel, OSDI_IMPL_ENTRY *pvDumpDebugFile,
+ DI_PRINTF pfnDumpDebugPrintf)
+{
+ IMG_UINT32 ui32Data, ui32LogIdx, ui32ArgsCur;
+ IMG_CHAR *pszFmt = NULL;
+ IMG_CHAR aszOneArgFmt[MAX_STRING_SIZE];
+ IMG_BOOL bUnrecognizedErrorPrinted = IMG_FALSE;
+
+ size_t nPrinted;
+
+ void *pNext, *pLast, *pStart, *pData = NULL;
+ PVRSRVTL_PPACKETHDR ppHdr; /* Current packet header */
+ IMG_UINT32 uiHdrType; /* Packet header type */
+ IMG_UINT32 uiMsgSize; /* Message size of current packet (bytes) */
+ IMG_BOOL bPacketsDropped;
+
+ pLast = pSentinel->pBuf + pSentinel->uiBufLen;
+ pStart = pSentinel->pCurr;
+
+ pSentinel->uiMsgLen = 0; // Reset count for this message
+
+ HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: Buf @ %p..%p, Length = %d",
+ __func__, pStart, pLast, pSentinel->uiBufLen));
+
+ /*
+ * We should have a DATA header with the necessary information following
+ */
+ ppHdr = GET_PACKET_HDR(pStart);
+
+ if (ppHdr == NULL)
+ {
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Unexpected NULL packet in Host Trace buffer", __func__));
+ return -1;
+ }
+
+ uiHdrType = GET_PACKET_TYPE(ppHdr);
+ PVR_ASSERT(uiHdrType == PVRSRVTL_PACKETTYPE_DATA);
+
+ pNext = GET_NEXT_PACKET_ADDR(ppHdr);
+
+ PVR_ASSERT(pNext != NULL);
+
+ uiMsgSize = (IMG_UINT32)((size_t)pNext - (size_t)ppHdr);
+
+ pSentinel->uiMsgLen += uiMsgSize;
+
+ pData = GET_PACKET_DATA_PTR(ppHdr);
+
+ if (pData == NULL || pData >= pLast)
+ {
+ HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: pData = %p, pLast = %p "
+ "Returning 0", __func__, pData, pLast));
+ return 0;
+ }
+
+ ui32Data = *(IMG_UINT32 *)pData;
+ ui32LogIdx = idToLogIdx(ui32Data);
+
+ /*
+ * Check if the unrecognised ID is valid and therefore, tracebuf
+ * needs updating.
+ */
+ if (ui32LogIdx == HTB_SF_LAST)
+ {
+ if (HTB_LOG_VALIDID(ui32Data))
+ {
+ if (!bUnrecognizedErrorPrinted)
+ {
+ PVR_DPF((PVR_DBG_WARNING,
+ "%s: Unrecognised LOG value '%x' GID %x Params %d ID %x @ '%p'",
+ __func__, ui32Data, HTB_SF_GID(ui32Data),
+ HTB_SF_PARAMNUM(ui32Data), ui32Data & 0xfff, pData));
+ bUnrecognizedErrorPrinted = IMG_TRUE;
+ }
+
+ return 0;
+ }
+
+ PVR_DPF((PVR_DBG_ERROR,
+ "%s: Unrecognised and invalid LOG value detected '%x'",
+ __func__, ui32Data));
+
+ return -1;
+ }
+
+ /* The string format we are going to display */
+ /*
+ * The display will show the header (log-ID, group-ID, number of params)
+ * The maximum parameter list length = 15 (only 4bits used to encode)
+ * so we need HEADER + 15 * sizeof(UINT32) and the displayed string
+ * describing the event. We use a buffer in the per-process pSentinel
+ * structure to hold the data.
+ */
+ pszFmt = aLogs[ui32LogIdx].pszFmt;
+
+ /* add the message payload size to the running count */
+ ui32ArgsCur = HTB_SF_PARAMNUM(ui32Data);
+
+ /* Determine if we've over-filled the buffer and had to drop packets */
+ bPacketsDropped = CHECK_PACKETS_DROPPED(ppHdr);
+ if (bPacketsDropped ||
+ (uiHdrType == PVRSRVTL_PACKETTYPE_MOST_RECENT_WRITE_FAILED))
+ {
+ /* Flag this as it is useful to know ... */
+
+ PVR_DUMPDEBUG_LOG("\n<========================== *** PACKETS DROPPED *** ======================>\n");
+ }
+
+ {
+ IMG_UINT32 ui32Timestampns, ui32PID, ui32TID;
+ IMG_UINT64 ui64Timestamp, ui64TimestampSec;
+ IMG_CHAR *szBuffer = pSentinel->szBuffer; // Buffer start
+ IMG_CHAR *pszBuffer = pSentinel->szBuffer; // Current place in buf
+ size_t uBufBytesAvailable = sizeof(pSentinel->szBuffer);
+ IMG_UINT32 *pui32Data = (IMG_UINT32 *)pData;
+ IMG_UINT32 ui_aGroupIdx;
+
+ // Get PID field from data stream
+ pui32Data++;
+ ui32PID = *pui32Data;
+ // Get TID field from data stream
+ pui32Data++;
+ ui32TID = *pui32Data;
+ // Get Timestamp part 1 from data stream
+ pui32Data++;
+ ui64Timestamp = (IMG_UINT64) *pui32Data << 32;
+ // Get Timestamp part 2 from data stream
+ pui32Data++;
+ ui64Timestamp |= (IMG_UINT64) *pui32Data;
+ // Move to start of message contents data
+ pui32Data++;
+
+ /*
+ * We need to snprintf the data to a local in-kernel buffer
+ * and then PVR_DUMPDEBUG_LOG() that in one shot
+ */
+ ui_aGroupIdx = MIN(HTB_SF_GID(ui32Data), uiMax_aGroups);
+
+ /* Divide by 1B to get seconds & mod using output var (nanosecond resolution)*/
+ ui64TimestampSec = OSDivide64r64(ui64Timestamp, 1000000000, &ui32Timestampns);
+
+ nPrinted = OSSNPrintf(szBuffer, uBufBytesAvailable, "%010"IMG_UINT64_FMTSPEC".%09u:%-5u-%-5u-%s> ",
+ ui64TimestampSec, ui32Timestampns, ui32PID, ui32TID, aGroups[ui_aGroupIdx]);
+ if (nPrinted >= uBufBytesAvailable)
+ {
+ PVR_DUMPDEBUG_LOG("Buffer overrun - "IMG_SIZE_FMTSPEC" printed,"
+ " max space "IMG_SIZE_FMTSPEC"\n", nPrinted,
+ uBufBytesAvailable);
+
+ nPrinted = uBufBytesAvailable; /* Ensure we don't overflow buffer */
+ }
+
+ PVR_DUMPDEBUG_LOG("%s", pszBuffer);
+ /* Update where our next 'output' point in the buffer is */
+ pszBuffer += nPrinted;
+ uBufBytesAvailable -= nPrinted;
+
+ /*
+ * Print one argument at a time as this simplifies handling variable
+ * number of arguments. Special case handling for no arguments.
+ * This is the case for simple format strings such as
+ * HTB_SF_MAIN_KICK_UNCOUNTED.
+ */
+ if (ui32ArgsCur == 0)
+ {
+ if (pszFmt)
+ {
+ nPrinted = OSStringLCopy(pszBuffer, pszFmt, uBufBytesAvailable);
+ if (nPrinted >= uBufBytesAvailable)
+ {
+ PVR_DUMPDEBUG_LOG("Buffer overrun - "IMG_SIZE_FMTSPEC" printed,"
+ " max space "IMG_SIZE_FMTSPEC"\n", nPrinted,
+ uBufBytesAvailable);
+ nPrinted = uBufBytesAvailable; /* Ensure we don't overflow buffer */
+ }
+ PVR_DUMPDEBUG_LOG("%s", pszBuffer);
+ pszBuffer += nPrinted;
+ /* Don't update the uBufBytesAvailable as we have finished this
+ * message decode. pszBuffer - szBuffer is the total amount of
+ * data we have decoded.
+ */
+ }
+ }
+ else
+ {
+ if (HTB_SF_GID(ui32Data) == HTB_GID_CTRL && HTB_SF_ID(ui32Data) == HTB_ID_MARK_SCALE)
+ {
+ IMG_UINT32 i;
+ IMG_UINT32 ui32ArgArray[HTB_MARK_SCALE_ARG_ARRAY_SIZE];
+ IMG_UINT64 ui64OSTS = 0;
+ IMG_UINT32 ui32OSTSRem = 0;
+ IMG_UINT64 ui64CRTS = 0;
+
+ /* Retrieve 6 args to an array */
+ for (i = 0; i < ARRAY_SIZE(ui32ArgArray); i++)
+ {
+ ui32ArgArray[i] = *pui32Data;
+ pui32Data++;
+ --ui32ArgsCur;
+ }
+
+ ui64OSTS = (IMG_UINT64) ui32ArgArray[HTB_ARG_OSTS_PT1] << 32 | ui32ArgArray[HTB_ARG_OSTS_PT2];
+ ui64CRTS = (IMG_UINT64) ui32ArgArray[HTB_ARG_CRTS_PT1] << 32 | ui32ArgArray[HTB_ARG_CRTS_PT2];
+
+ /* Divide by 1B to get seconds, remainder in nano seconds*/
+ ui64OSTS = OSDivide64r64(ui64OSTS, 1000000000, &ui32OSTSRem);
+
+ nPrinted = OSSNPrintf(pszBuffer,
+ uBufBytesAvailable,
+ "HTBFWMkSync Mark=%u OSTS=%010" IMG_UINT64_FMTSPEC ".%09u CRTS=%" IMG_UINT64_FMTSPEC " CalcClkSpd=%u\n",
+ ui32ArgArray[HTB_ARG_SYNCMARK],
+ ui64OSTS,
+ ui32OSTSRem,
+ ui64CRTS,
+ ui32ArgArray[HTB_ARG_CLKSPD]);
+
+ if (nPrinted >= uBufBytesAvailable)
+ {
+ PVR_DUMPDEBUG_LOG("Buffer overrun - "IMG_SIZE_FMTSPEC" printed,"
+ " max space "IMG_SIZE_FMTSPEC"\n", nPrinted,
+ uBufBytesAvailable);
+ nPrinted = uBufBytesAvailable; /* Ensure we don't overflow buffer */
+ }
+
+ PVR_DUMPDEBUG_LOG("%s", pszBuffer);
+ pszBuffer += nPrinted;
+ uBufBytesAvailable -= nPrinted;
+ }
+ else
+ {
+ while (IS_VALID_FMT_STRING(pszFmt) && (uBufBytesAvailable > 0))
+ {
+ IMG_UINT32 ui32TmpArg = *pui32Data;
+ TRACEBUF_ARG_TYPE eArgType;
+
+ eArgType = ExtractOneArgFmt(&pszFmt, aszOneArgFmt);
+
+ pui32Data++;
+ ui32ArgsCur--;
+
+ switch (eArgType)
+ {
+ case TRACEBUF_ARG_TYPE_INT:
+ nPrinted = OSSNPrintf(pszBuffer, uBufBytesAvailable,
+ aszOneArgFmt, ui32TmpArg);
+ break;
+
+ case TRACEBUF_ARG_TYPE_NONE:
+ nPrinted = OSStringLCopy(pszBuffer, pszFmt,
+ uBufBytesAvailable);
+ break;
+
+ default:
+ nPrinted = OSSNPrintf(pszBuffer, uBufBytesAvailable,
+ "Error processing arguments, type not "
+ "recognized (fmt: %s)", aszOneArgFmt);
+ break;
+ }
+ if (nPrinted >= uBufBytesAvailable)
+ {
+ PVR_DUMPDEBUG_LOG("Buffer overrun - "IMG_SIZE_FMTSPEC" printed,"
+ " max space "IMG_SIZE_FMTSPEC"\n", nPrinted,
+ uBufBytesAvailable);
+ nPrinted = uBufBytesAvailable; /* Ensure we don't overflow buffer */
+ }
+ PVR_DUMPDEBUG_LOG("%s", pszBuffer);
+ pszBuffer += nPrinted;
+ uBufBytesAvailable -= nPrinted;
+ }
+ /* Display any remaining text in pszFmt string */
+ if (pszFmt)
+ {
+ nPrinted = OSStringLCopy(pszBuffer, pszFmt, uBufBytesAvailable);
+ if (nPrinted >= uBufBytesAvailable)
+ {
+ PVR_DUMPDEBUG_LOG("Buffer overrun - "IMG_SIZE_FMTSPEC" printed,"
+ " max space "IMG_SIZE_FMTSPEC"\n", nPrinted,
+ uBufBytesAvailable);
+ nPrinted = uBufBytesAvailable; /* Ensure we don't overflow buffer */
+ }
+ PVR_DUMPDEBUG_LOG("%s", pszBuffer);
+ pszBuffer += nPrinted;
+ /* Don't update the uBufBytesAvailable as we have finished this
+ * message decode. pszBuffer - szBuffer is the total amount of
+ * data we have decoded.
+ */
+ }
+ }
+ }
+
+ /* Update total bytes processed */
+ pSentinel->uiTotal += (pszBuffer - szBuffer);
+ }
+ return 0;
+}
+
+/*
+ * HTBDumpBuffer: Dump the Host Trace Buffer using the TLClient API
+ *
+ * This routine just parses *one* message from the buffer.
+ * The stream will be opened by the Start() routine, closed by the Stop() and
+ * updated for data consumed by this routine once we have DebugPrintf'd it.
+ * We use the new TLReleaseDataLess() routine which enables us to update the
+ * HTB contents with just the amount of data we have successfully processed.
+ * If we need to leave the data available we can call this with a 0 count.
+ * This will happen in the case of a buffer overflow so that we can reprocess
+ * any data which wasn't handled before.
+ *
+ * In case of overflow or an error we return -1 otherwise 0
+ *
+ * Input:
+ * pfnPrintf output routine to display data
+ * psEntry handle to debug frontend
+ * pvData data address to start dumping from
+ * (set by Start() / Next())
+ */
+static int HTBDumpBuffer(DI_PRINTF pfnPrintf, OSDI_IMPL_ENTRY *psEntry,
+ void *pvData)
+{
+ HTB_Sentinel_t *pSentinel = DIGetPrivData(psEntry);
+
+ PVR_ASSERT(pvData != NULL);
+
+ if (pvData == DI_START_TOKEN)
+ {
+ if (pSentinel->pCurr == NULL)
+ {
+ HTB_CHATTY_PRINT((PVR_DBG_WARNING, "%s: DI_START_TOKEN, "
+ "Empty buffer", __func__));
+ return 0;
+ }
+ PVR_ASSERT(pSentinel->pCurr != NULL);
+
+ /* Display a Header as we have data to process */
+ pfnPrintf(psEntry, "%-20s:%-5s-%-5s-%s %s\n", "Timestamp", "PID", "TID", "Group>",
+ "Log Entry");
+ }
+ else
+ {
+ if (pvData != NULL)
+ {
+ PVR_ASSERT(pSentinel->pCurr == pvData);
+ }
+ }
+
+ return DecodeHTB(pSentinel, psEntry, pfnPrintf);
+}
+
+
+/******************************************************************************
+ * External Entry Point routines ...
+ *****************************************************************************/
+/*************************************************************************/ /*!
+ @Function HTB_CreateDIEntry
+
+ @Description Create the debugFS entry-point for the host-trace-buffer
+
+ @Returns eError internal error code, PVRSRV_OK on success
+
+ */ /*************************************************************************/
+PVRSRV_ERROR HTB_CreateDIEntry(void)
+{
+ PVRSRV_ERROR eError;
+
+ DI_ITERATOR_CB sIterator = {
+ .pfnStart = _DebugHBTraceDIStart,
+ .pfnStop = _DebugHBTraceDIStop,
+ .pfnNext = _DebugHBTraceDINext,
+ .pfnShow = _DebugHBTraceDIShow,
+ };
+
+ eError = DICreateEntry("host_trace", NULL, &sIterator,
+ &g_sHTBData.sSentinel,
+ DI_ENTRY_TYPE_GENERIC,
+ &g_sHTBData.psDumpHostDiEntry);
+ PVR_LOG_RETURN_IF_ERROR(eError, "DICreateEntry");
+
+ return PVRSRV_OK;
+}
+
+
+/*************************************************************************/ /*!
+ @Function HTB_DestroyDIEntry
+
+ @Description Destroy the debugFS entry-point created by earlier
+ HTB_CreateDIEntry() call.
+*/ /**************************************************************************/
+void HTB_DestroyDIEntry(void)
+{
+ if (g_sHTBData.psDumpHostDiEntry != NULL)
+ {
+ DIDestroyEntry(g_sHTBData.psDumpHostDiEntry);
+ g_sHTBData.psDumpHostDiEntry = NULL;
+ }
+}
+
+/* EOF */
diff --git a/drivers/gpu/drm/img-rogue/htb_debug.h b/drivers/gpu/drm/img-rogue/htb_debug.h
new file mode 100644
index 000000000..04132e13c
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/htb_debug.h
@@ -0,0 +1,64 @@
+/*************************************************************************/ /*!
+@File htb_debug.h
+@Title Linux debugFS routine setup header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef HTB_DEBUG_H
+#define HTB_DEBUG_H
+
+/**************************************************************************/ /*!
+ @Function HTB_CreateDIEntry
+
+ @Description Create the debugFS entry-point for the host-trace-buffer
+
+ @Returns eError internal error code, PVRSRV_OK on success
+
+ */ /**************************************************************************/
+PVRSRV_ERROR HTB_CreateDIEntry(void);
+
+/**************************************************************************/ /*!
+ @Function HTB_DestroyFSEntry
+
+ @Description Destroy the debugFS entry-point created by earlier
+ HTB_CreateDIEntry() call.
+*/ /**************************************************************************/
+void HTB_DestroyDIEntry(void);
+
+#endif /* HTB_DEBUG_H */
diff --git a/drivers/gpu/drm/img-rogue/htbserver.c b/drivers/gpu/drm/img-rogue/htbserver.c
new file mode 100644
index 000000000..2ada5ab98
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/htbserver.c
@@ -0,0 +1,857 @@
+/*************************************************************************/ /*!
+@File htbserver.c
+@Title Host Trace Buffer server implementation.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Host Trace Buffer provides a mechanism to log Host events to a
+ buffer in a similar way to the Firmware Trace mechanism.
+ Host Trace Buffer logs data using a Transport Layer buffer.
+ The Transport Layer and pvrtld tool provides the mechanism to
+ retrieve the trace data.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "htbserver.h"
+#include "htbuffer.h"
+#include "htbuffer_types.h"
+#include "tlstream.h"
+#include "pvrsrv_tlcommon.h"
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+#include "osfunc.h"
+#include "allocmem.h"
+#include "pvr_notifier.h"
+#include "pvrsrv.h"
+#include "pvrsrv_apphint.h"
+#include "oskm_apphint.h"
+
+/* size of circular buffer controlling the maximum number of concurrent PIDs logged */
+#define HTB_MAX_NUM_PID 8
+
+/* number of times to try rewriting a log entry */
+#define HTB_LOG_RETRY_COUNT 5
+
+/*************************************************************************/ /*!
+ Host Trace Buffer control information structure
+*/ /**************************************************************************/
+typedef struct
+{
+ IMG_UINT32 ui32BufferSize; /*!< Requested buffer size in bytes
+ Once set this may not be changed */
+
+ HTB_OPMODE_CTRL eOpMode; /*!< Control what trace data is dropped if
+ the buffer is full.
+ Once set this may not be changed */
+
+/* IMG_UINT32 ui32GroupEnable; */ /*!< Flags word controlling groups to be
+ logged */
+
+ IMG_UINT32 ui32LogLevel; /*!< Log level to control messages logged */
+
+ IMG_UINT32 aui32EnablePID[HTB_MAX_NUM_PID]; /*!< PIDs to enable logging for
+ a specific set of processes */
+
+ IMG_UINT32 ui32PIDCount; /*!< Current number of PIDs being logged */
+
+ IMG_UINT32 ui32PIDHead; /*!< Head of the PID circular buffer */
+
+ HTB_LOGMODE_CTRL eLogMode; /*!< Logging mode control */
+
+ IMG_BOOL bLogDropSignalled; /*!< Flag indicating if a log message has
+ been signalled as dropped */
+
+ /* synchronisation parameters */
+ IMG_UINT64 ui64SyncOSTS;
+ IMG_UINT64 ui64SyncCRTS;
+ IMG_UINT32 ui32SyncCalcClkSpd;
+ IMG_UINT32 ui32SyncMarker;
+
+ IMG_BOOL bInitDone; /* Set by HTBInit, reset by HTBDeInit */
+
+ POS_SPINLOCK hRepeatMarkerLock; /*!< Spinlock used in HTBLogKM to protect global variables
+ (ByteCount, OSTS, CRTS ClkSpeed)
+ from becoming inconsistent due to calls from
+ both KM and UM */
+
+ IMG_UINT32 ui32ByteCount; /* Byte count used for triggering repeat sync point */
+ /* static variables containing details of previous sync point */
+ IMG_UINT64 ui64OSTS;
+ IMG_UINT64 ui64CRTS;
+ IMG_UINT32 ui32ClkSpeed;
+
+} HTB_CTRL_INFO;
+
+
+/*************************************************************************/ /*!
+*/ /**************************************************************************/
+static const IMG_UINT32 MapFlags[] =
+{
+ 0, /* HTB_OPMODE_UNDEF = 0 */
+ TL_OPMODE_DROP_NEWER, /* HTB_OPMODE_DROPLATEST */
+ TL_OPMODE_DROP_OLDEST,/* HTB_OPMODE_DROPOLDEST */
+ TL_OPMODE_BLOCK /* HTB_OPMODE_BLOCK */
+};
+
+static_assert(0 == HTB_OPMODE_UNDEF, "Unexpected value for HTB_OPMODE_UNDEF");
+static_assert(1 == HTB_OPMODE_DROPLATEST, "Unexpected value for HTB_OPMODE_DROPLATEST");
+static_assert(2 == HTB_OPMODE_DROPOLDEST, "Unexpected value for HTB_OPMODE_DROPOLDEST");
+static_assert(3 == HTB_OPMODE_BLOCK, "Unexpected value for HTB_OPMODE_BLOCK");
+
+static_assert(1 == TL_OPMODE_DROP_NEWER, "Unexpected value for TL_OPMODE_DROP_NEWER");
+static_assert(2 == TL_OPMODE_DROP_OLDEST, "Unexpected value for TL_OPMODE_DROP_OLDEST");
+static_assert(3 == TL_OPMODE_BLOCK, "Unexpected value for TL_OPMODE_BLOCK");
+
+static const IMG_UINT32 g_ui32TLBaseFlags; //TL_FLAG_NO_SIGNAL_ON_COMMIT
+
+/* Minimum TL buffer size.
+ * Large enough for around 60 worst case messages or 200 average messages
+ */
+#define HTB_TL_BUFFER_SIZE_MIN (0x10000)
+
+/* Minimum concentration of HTB packets in a TL Stream is 60%
+ * If we just put the HTB header in the TL stream (12 bytes), the TL overhead
+ * is 8 bytes for its own header, so for the smallest possible (and most
+ * inefficient) packet we have 3/5 of the buffer used for actual HTB data.
+ * This shift is used as a guaranteed estimation on when to produce a repeat
+ * packet. By shifting the size of the buffer by 1 we effectively /2 this
+ * under the 60% boundary chance we may have overwritten the marker and thus
+ * guaranteed to always have a marker in the stream */
+#define HTB_MARKER_PREDICTION_THRESHOLD(val) (val >> 1)
+
+static HTB_CTRL_INFO g_sCtrl;
+static IMG_BOOL g_bConfigured = IMG_FALSE;
+static IMG_HANDLE g_hTLStream;
+
+static IMG_HANDLE hHtbDbgReqNotify;
+
+
+/************************************************************************/ /*!
+ @Function _LookupFlags
+ @Description Convert HTBuffer Operation mode to TLStream flags
+
+ @Input eModeHTBuffer Operation Mode
+
+ @Return IMG_UINT32 TLStream FLags
+*/ /**************************************************************************/
+static IMG_UINT32
+_LookupFlags( HTB_OPMODE_CTRL eMode )
+{
+ return (eMode < ARRAY_SIZE(MapFlags)) ? MapFlags[eMode] : 0;
+}
+
+
+/************************************************************************/ /*!
+ @Function _HTBLogDebugInfo
+ @Description Debug dump handler used to dump the state of the HTB module.
+ Called for each verbosity level during a debug dump. Function
+ only prints state when called for High verbosity.
+
+ @Input hDebugRequestHandle See PFN_DBGREQ_NOTIFY
+
+ @Input ui32VerbLevel See PFN_DBGREQ_NOTIFY
+
+ @Input pfnDumpDebugPrintf See PFN_DBGREQ_NOTIFY
+
+ @Input pvDumpDebugFile See PFN_DBGREQ_NOTIFY
+
+*/ /**************************************************************************/
+static void _HTBLogDebugInfo(
+ PVRSRV_DBGREQ_HANDLE hDebugRequestHandle,
+ IMG_UINT32 ui32VerbLevel,
+ DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
+ void *pvDumpDebugFile
+)
+{
+ PVR_UNREFERENCED_PARAMETER(hDebugRequestHandle);
+
+ if (DD_VERB_LVL_ENABLED(ui32VerbLevel, DEBUG_REQUEST_VERBOSITY_HIGH))
+ {
+
+ if (g_bConfigured)
+ {
+ IMG_INT i;
+
+ PVR_DUMPDEBUG_LOG("------[ HTB Log state: On ]------");
+
+ PVR_DUMPDEBUG_LOG("HTB Log mode: %d", g_sCtrl.eLogMode);
+ PVR_DUMPDEBUG_LOG("HTB Log level: %d", g_sCtrl.ui32LogLevel);
+ PVR_DUMPDEBUG_LOG("HTB Buffer Opmode: %d", g_sCtrl.eOpMode);
+
+ for (i=0; i < HTB_FLAG_NUM_EL; i++)
+ {
+ PVR_DUMPDEBUG_LOG("HTB Log group %d: %x", i, g_auiHTBGroupEnable[i]);
+ }
+ }
+ else
+ {
+ PVR_DUMPDEBUG_LOG("------[ HTB Log state: Off ]------");
+ }
+ }
+}
+
+static IMG_UINT32 g_ui32HTBufferSize = HTB_TL_BUFFER_SIZE_MIN;
+
+/*
+ * AppHint access routine forward definitions
+ */
+static PVRSRV_ERROR _HTBSetLogGroup(const PVRSRV_DEVICE_NODE *, const void *,
+ IMG_UINT32);
+static PVRSRV_ERROR _HTBReadLogGroup(const PVRSRV_DEVICE_NODE *, const void *,
+ IMG_UINT32 *);
+
+static PVRSRV_ERROR _HTBSetOpMode(const PVRSRV_DEVICE_NODE *, const void *,
+ IMG_UINT32);
+static PVRSRV_ERROR _HTBReadOpMode(const PVRSRV_DEVICE_NODE *, const void *,
+ IMG_UINT32 *);
+
+static void _OnTLReaderOpenCallback(void *);
+
+/************************************************************************/ /*!
+ @Function HTBInit
+ @Description Allocate and initialise the Host Trace Buffer
+ The buffer size may be changed by specifying
+ HTBufferSizeInKB=xxxx
+
+ @Return eError Internal services call returned eError error
+ number
+*/ /**************************************************************************/
+PVRSRV_ERROR
+HTBInit(void)
+{
+ void *pvAppHintState = NULL;
+ IMG_UINT32 ui32AppHintDefault;
+ IMG_UINT32 ui32BufBytes;
+ PVRSRV_ERROR eError;
+
+ if (g_sCtrl.bInitDone)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "HTBInit: Driver already initialised"));
+ return PVRSRV_ERROR_ALREADY_EXISTS;
+ }
+
+ /*
+ * Buffer Size can be configured by specifying a value in the AppHint
+ * This will only take effect at module load time so there is no query
+ * or setting mechanism available.
+ */
+ PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_HTBufferSizeInKB,
+ NULL,
+ NULL,
+ APPHINT_OF_DRIVER_NO_DEVICE,
+ NULL);
+
+ PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_EnableHTBLogGroup,
+ _HTBReadLogGroup,
+ _HTBSetLogGroup,
+ APPHINT_OF_DRIVER_NO_DEVICE,
+ NULL);
+ PVRSRVAppHintRegisterHandlersUINT32(APPHINT_ID_HTBOperationMode,
+ _HTBReadOpMode,
+ _HTBSetOpMode,
+ APPHINT_OF_DRIVER_NO_DEVICE,
+ NULL);
+
+ /*
+ * Now get whatever values have been configured for our AppHints
+ */
+ OSCreateKMAppHintState(&pvAppHintState);
+ ui32AppHintDefault = HTB_TL_BUFFER_SIZE_MIN / 1024;
+ OSGetKMAppHintUINT32(APPHINT_NO_DEVICE, pvAppHintState, HTBufferSizeInKB,
+ &ui32AppHintDefault, &g_ui32HTBufferSize);
+ OSFreeKMAppHintState(pvAppHintState);
+
+ ui32BufBytes = g_ui32HTBufferSize * 1024;
+
+ /* initialise rest of state */
+ g_sCtrl.ui32BufferSize =
+ (ui32BufBytes < HTB_TL_BUFFER_SIZE_MIN)
+ ? HTB_TL_BUFFER_SIZE_MIN
+ : ui32BufBytes;
+ g_sCtrl.eOpMode = HTB_OPMODE_DROPOLDEST;
+ g_sCtrl.ui32LogLevel = 0;
+ g_sCtrl.ui32PIDCount = 0;
+ g_sCtrl.ui32PIDHead = 0;
+ g_sCtrl.eLogMode = HTB_LOGMODE_ALLPID;
+ g_sCtrl.bLogDropSignalled = IMG_FALSE;
+
+ eError = OSSpinLockCreate(&g_sCtrl.hRepeatMarkerLock);
+ PVR_LOG_RETURN_IF_ERROR(eError, "OSSpinLockCreate");
+
+ eError = PVRSRVRegisterDriverDbgRequestNotify(&hHtbDbgReqNotify,
+ _HTBLogDebugInfo, DEBUG_REQUEST_HTB, NULL);
+ PVR_LOG_IF_ERROR(eError, "PVRSRVRegisterDeviceDbgRequestNotify");
+
+ g_sCtrl.bInitDone = IMG_TRUE;
+
+ /* Log the current driver parameter setting for the HTBufferSizeInKB.
+ * We do this here as there is no other infrastructure for obtaining
+ * the value.
+ */
+ if (g_ui32HTBufferSize != ui32AppHintDefault)
+ {
+ PVR_LOG(("Increasing HTBufferSize to %uKB", g_ui32HTBufferSize));
+ }
+
+
+ return PVRSRV_OK;
+}
+
+/************************************************************************/ /*!
+ @Function HTBDeInit
+ @Description Close the Host Trace Buffer and free all resources. Must
+ perform a no-op if already de-initialised.
+
+ @Return eError Internal services call returned eError error
+ number
+*/ /**************************************************************************/
+PVRSRV_ERROR
+HTBDeInit( void )
+{
+ if (!g_sCtrl.bInitDone)
+ return PVRSRV_OK;
+
+ if (hHtbDbgReqNotify)
+ {
+ /* Not much we can do if it fails, driver unloading */
+ (void)PVRSRVUnregisterDriverDbgRequestNotify(hHtbDbgReqNotify);
+ hHtbDbgReqNotify = NULL;
+ }
+
+ if (g_hTLStream)
+ {
+ TLStreamClose( g_hTLStream );
+ g_hTLStream = NULL;
+ }
+
+ if (g_sCtrl.hRepeatMarkerLock != NULL)
+ {
+ OSSpinLockDestroy(g_sCtrl.hRepeatMarkerLock);
+ g_sCtrl.hRepeatMarkerLock = NULL;
+ }
+
+ g_sCtrl.bInitDone = IMG_FALSE;
+ return PVRSRV_OK;
+}
+
+
+/*************************************************************************/ /*!
+ AppHint interface functions
+*/ /**************************************************************************/
+static
+PVRSRV_ERROR _HTBSetLogGroup(const PVRSRV_DEVICE_NODE *psDeviceNode,
+ const void *psPrivate,
+ IMG_UINT32 ui32Value)
+{
+ PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+ PVR_UNREFERENCED_PARAMETER(psPrivate);
+
+ return HTBControlKM(1, &ui32Value, 0, 0,
+ HTB_LOGMODE_UNDEF, HTB_OPMODE_UNDEF);
+}
+
+static
+PVRSRV_ERROR _HTBReadLogGroup(const PVRSRV_DEVICE_NODE *psDeviceNode,
+ const void *psPrivate,
+ IMG_UINT32 *pui32Value)
+{
+ PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+ PVR_UNREFERENCED_PARAMETER(psPrivate);
+
+ *pui32Value = g_auiHTBGroupEnable[0];
+ return PVRSRV_OK;
+}
+
+static
+PVRSRV_ERROR _HTBSetOpMode(const PVRSRV_DEVICE_NODE *psDeviceNode,
+ const void *psPrivate,
+ IMG_UINT32 ui32Value)
+{
+ PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+ PVR_UNREFERENCED_PARAMETER(psPrivate);
+
+ return HTBControlKM(0, NULL, 0, 0, HTB_LOGMODE_UNDEF, ui32Value);
+}
+
+static
+PVRSRV_ERROR _HTBReadOpMode(const PVRSRV_DEVICE_NODE *psDeviceNode,
+ const void *psPrivate,
+ IMG_UINT32 *pui32Value)
+{
+ PVR_UNREFERENCED_PARAMETER(psDeviceNode);
+ PVR_UNREFERENCED_PARAMETER(psPrivate);
+
+ *pui32Value = (IMG_UINT32)g_sCtrl.eOpMode;
+ return PVRSRV_OK;
+}
+
+
+static void
+_OnTLReaderOpenCallback( void *pvArg )
+{
+ if ( g_hTLStream )
+ {
+ IMG_UINT64 ui64Time;
+ OSClockMonotonicns64(&ui64Time);
+ (void) HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_FWSYNC_MARK_SCALE,
+ g_sCtrl.ui32SyncMarker,
+ ((IMG_UINT32)((g_sCtrl.ui64SyncOSTS>>32)&0xffffffff)),
+ ((IMG_UINT32)(g_sCtrl.ui64SyncOSTS&0xffffffff)),
+ ((IMG_UINT32)((g_sCtrl.ui64SyncCRTS>>32)&0xffffffff)),
+ ((IMG_UINT32)(g_sCtrl.ui64SyncCRTS&0xffffffff)),
+ g_sCtrl.ui32SyncCalcClkSpd);
+ }
+
+ PVR_UNREFERENCED_PARAMETER(pvArg);
+}
+
+
+/*************************************************************************/ /*!
+ @Function HTBControlKM
+ @Description Update the configuration of the Host Trace Buffer
+
+ @Input ui32NumFlagGroups Number of group enable flags words
+
+ @Input aui32GroupEnable Flags words controlling groups to be logged
+
+ @Input ui32LogLevel Log level to record
+
+ @Input ui32EnablePID PID to enable logging for a specific process
+
+ @Input eLogMode Enable logging for all or specific processes,
+
+ @Input eOpMode Control the behaviour of the data buffer
+
+ @Return eError Internal services call returned eError error
+ number
+*/ /**************************************************************************/
+PVRSRV_ERROR
+HTBControlKM(
+ const IMG_UINT32 ui32NumFlagGroups,
+ const IMG_UINT32 * aui32GroupEnable,
+ const IMG_UINT32 ui32LogLevel,
+ const IMG_UINT32 ui32EnablePID,
+ const HTB_LOGMODE_CTRL eLogMode,
+ const HTB_OPMODE_CTRL eOpMode
+)
+{
+ PVRSRV_ERROR eError = PVRSRV_OK;
+ IMG_UINT32 ui32RetryCount = HTB_LOG_RETRY_COUNT;
+ IMG_UINT32 i;
+ IMG_UINT64 ui64Time;
+ OSClockMonotonicns64(&ui64Time);
+
+ if ( !g_bConfigured && ui32NumFlagGroups )
+ {
+ eError = TLStreamCreate(
+ &g_hTLStream,
+ HTB_STREAM_NAME,
+ g_sCtrl.ui32BufferSize,
+ _LookupFlags(HTB_OPMODE_DROPOLDEST) | g_ui32TLBaseFlags,
+ _OnTLReaderOpenCallback, NULL, NULL, NULL);
+ PVR_LOG_RETURN_IF_ERROR(eError, "TLStreamCreate");
+ g_bConfigured = IMG_TRUE;
+ }
+
+ if (HTB_OPMODE_UNDEF != eOpMode && g_sCtrl.eOpMode != eOpMode)
+ {
+ g_sCtrl.eOpMode = eOpMode;
+ eError = TLStreamReconfigure(g_hTLStream, _LookupFlags(g_sCtrl.eOpMode | g_ui32TLBaseFlags));
+ while ( PVRSRV_ERROR_NOT_READY == eError && ui32RetryCount-- )
+ {
+ OSReleaseThreadQuanta();
+ eError = TLStreamReconfigure(g_hTLStream, _LookupFlags(g_sCtrl.eOpMode | g_ui32TLBaseFlags));
+ }
+ PVR_LOG_RETURN_IF_ERROR(eError, "TLStreamReconfigure");
+ }
+
+ if ( ui32EnablePID )
+ {
+ g_sCtrl.aui32EnablePID[g_sCtrl.ui32PIDHead] = ui32EnablePID;
+ g_sCtrl.ui32PIDHead++;
+ g_sCtrl.ui32PIDHead %= HTB_MAX_NUM_PID;
+ g_sCtrl.ui32PIDCount++;
+ if ( g_sCtrl.ui32PIDCount > HTB_MAX_NUM_PID )
+ {
+ g_sCtrl.ui32PIDCount = HTB_MAX_NUM_PID;
+ }
+ }
+
+ /* HTB_LOGMODE_ALLPID overrides ui32EnablePID */
+ if ( HTB_LOGMODE_ALLPID == eLogMode )
+ {
+ OSCachedMemSet(g_sCtrl.aui32EnablePID, 0, sizeof(g_sCtrl.aui32EnablePID));
+ g_sCtrl.ui32PIDCount = 0;
+ g_sCtrl.ui32PIDHead = 0;
+ }
+ if ( HTB_LOGMODE_UNDEF != eLogMode )
+ {
+ g_sCtrl.eLogMode = eLogMode;
+ }
+
+ if ( ui32NumFlagGroups )
+ {
+ for (i = 0; i < HTB_FLAG_NUM_EL && i < ui32NumFlagGroups; i++)
+ {
+ g_auiHTBGroupEnable[i] = aui32GroupEnable[i];
+ }
+ for (; i < HTB_FLAG_NUM_EL; i++)
+ {
+ g_auiHTBGroupEnable[i] = 0;
+ }
+ }
+
+ if ( ui32LogLevel )
+ {
+ g_sCtrl.ui32LogLevel = ui32LogLevel;
+ }
+
+ /* Dump the current configuration state */
+ eError = HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_OPMODE, g_sCtrl.eOpMode);
+ PVR_LOG_IF_ERROR(eError, "HTBLog");
+ eError = HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_ENABLE_GROUP, g_auiHTBGroupEnable[0]);
+ PVR_LOG_IF_ERROR(eError, "HTBLog");
+ eError = HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_LOG_LEVEL, g_sCtrl.ui32LogLevel);
+ PVR_LOG_IF_ERROR(eError, "HTBLog");
+ eError = HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_LOGMODE, g_sCtrl.eLogMode);
+ PVR_LOG_IF_ERROR(eError, "HTBLog");
+ for (i = 0; i < g_sCtrl.ui32PIDCount; i++)
+ {
+ eError = HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_ENABLE_PID, g_sCtrl.aui32EnablePID[i]);
+ PVR_LOG_IF_ERROR(eError, "HTBLog");
+ }
+ /* Else should never be hit as we set the spd when the power state is updated */
+ if (0 != g_sCtrl.ui32SyncMarker && 0 != g_sCtrl.ui32SyncCalcClkSpd)
+ {
+ eError = HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_FWSYNC_MARK_SCALE,
+ g_sCtrl.ui32SyncMarker,
+ ((IMG_UINT32)((g_sCtrl.ui64SyncOSTS>>32)&0xffffffff)), ((IMG_UINT32)(g_sCtrl.ui64SyncOSTS&0xffffffff)),
+ ((IMG_UINT32)((g_sCtrl.ui64SyncCRTS>>32)&0xffffffff)), ((IMG_UINT32)(g_sCtrl.ui64SyncCRTS&0xffffffff)),
+ g_sCtrl.ui32SyncCalcClkSpd);
+ PVR_LOG_IF_ERROR(eError, "HTBLog");
+ }
+
+ return eError;
+}
+
+/*************************************************************************/ /*!
+*/ /**************************************************************************/
+static IMG_BOOL
+_ValidPID( IMG_UINT32 PID )
+{
+ IMG_UINT32 i;
+
+ for (i = 0; i < g_sCtrl.ui32PIDCount; i++)
+ {
+ if ( g_sCtrl.aui32EnablePID[i] == PID )
+ {
+ return IMG_TRUE;
+ }
+ }
+ return IMG_FALSE;
+}
+
+
+/*************************************************************************/ /*!
+ @Function HTBSyncPartitionMarker
+ @Description Write an HTB sync partition marker to the HTB log
+
+ @Input ui33Marker Marker value
+
+*/ /**************************************************************************/
+void
+HTBSyncPartitionMarker(
+ const IMG_UINT32 ui32Marker
+)
+{
+ g_sCtrl.ui32SyncMarker = ui32Marker;
+ if ( g_hTLStream )
+ {
+ PVRSRV_ERROR eError;
+ IMG_UINT64 ui64Time;
+ OSClockMonotonicns64(&ui64Time);
+
+ /* Else should never be hit as we set the spd when the power state is updated */
+ if (0 != g_sCtrl.ui32SyncCalcClkSpd)
+ {
+ eError = HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_FWSYNC_MARK_SCALE,
+ ui32Marker,
+ ((IMG_UINT32)((g_sCtrl.ui64SyncOSTS>>32)&0xffffffff)), ((IMG_UINT32)(g_sCtrl.ui64SyncOSTS&0xffffffff)),
+ ((IMG_UINT32)((g_sCtrl.ui64SyncCRTS>>32)&0xffffffff)), ((IMG_UINT32)(g_sCtrl.ui64SyncCRTS&0xffffffff)),
+ g_sCtrl.ui32SyncCalcClkSpd);
+ PVR_WARN_IF_ERROR(eError, "HTBLog");
+ }
+ }
+}
+
+/*************************************************************************/ /*!
+ @Function HTBSyncPartitionMarkerRepeat
+ @Description Write a HTB sync partition marker to the HTB log, given
+ the previous values to repeat.
+
+ @Input ui33Marker Marker value
+ @Input ui64SyncOSTS previous OSTS
+ @Input ui64SyncCRTS previous CRTS
+ @Input ui32ClkSpeed previous Clock speed
+
+*/ /**************************************************************************/
+void
+HTBSyncPartitionMarkerRepeat(
+ const IMG_UINT32 ui32Marker,
+ const IMG_UINT64 ui64SyncOSTS,
+ const IMG_UINT64 ui64SyncCRTS,
+ const IMG_UINT32 ui32ClkSpeed
+)
+{
+ if ( g_hTLStream )
+ {
+ PVRSRV_ERROR eError;
+ IMG_UINT64 ui64Time;
+ OSClockMonotonicns64(&ui64Time);
+
+ /* Else should never be hit as we set the spd when the power state is updated */
+ if (0 != ui32ClkSpeed)
+ {
+ eError = HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_FWSYNC_MARK_SCALE,
+ ui32Marker,
+ ((IMG_UINT32)((ui64SyncOSTS>>32)&0xffffffffU)), ((IMG_UINT32)(ui64SyncOSTS&0xffffffffU)),
+ ((IMG_UINT32)((ui64SyncCRTS>>32)&0xffffffffU)), ((IMG_UINT32)(ui64SyncCRTS&0xffffffffU)),
+ ui32ClkSpeed);
+ PVR_WARN_IF_ERROR(eError, "HTBLog");
+ }
+ }
+}
+
+/*************************************************************************/ /*!
+ @Function HTBSyncScale
+ @Description Write FW-Host synchronisation data to the HTB log when clocks
+ change or are re-calibrated
+
+ @Input bLogValues IMG_TRUE if value should be immediately written
+ out to the log
+
+ @Input ui32OSTS OS Timestamp
+
+ @Input ui32CRTS Rogue timestamp
+
+ @Input ui32CalcClkSpd Calculated clock speed
+
+*/ /**************************************************************************/
+void
+HTBSyncScale(
+ const IMG_BOOL bLogValues,
+ const IMG_UINT64 ui64OSTS,
+ const IMG_UINT64 ui64CRTS,
+ const IMG_UINT32 ui32CalcClkSpd
+)
+{
+ g_sCtrl.ui64SyncOSTS = ui64OSTS;
+ g_sCtrl.ui64SyncCRTS = ui64CRTS;
+ g_sCtrl.ui32SyncCalcClkSpd = ui32CalcClkSpd;
+ if (g_hTLStream && bLogValues)
+ {
+ PVRSRV_ERROR eError;
+ IMG_UINT64 ui64Time;
+ OSClockMonotonicns64(&ui64Time);
+ eError = HTBLog((IMG_HANDLE) NULL, 0, 0, ui64Time, HTB_SF_CTRL_FWSYNC_MARK_SCALE,
+ g_sCtrl.ui32SyncMarker,
+ ((IMG_UINT32)((ui64OSTS>>32)&0xffffffff)), ((IMG_UINT32)(ui64OSTS&0xffffffff)),
+ ((IMG_UINT32)((ui64CRTS>>32)&0xffffffff)), ((IMG_UINT32)(ui64CRTS&0xffffffff)),
+ ui32CalcClkSpd);
+ /*
+ * Don't spam the log with non-failure cases
+ */
+ PVR_WARN_IF_ERROR(eError, "HTBLog");
+ }
+}
+
+
+/*************************************************************************/ /*!
+ @Function HTBLogKM
+ @Description Record a Host Trace Buffer log event
+
+ @Input PID The PID of the process the event is associated
+ with. This is provided as an argument rather
+ than querying internally so that events associated
+ with a particular process, but performed by
+ another can be logged correctly.
+
+ @Input ui64TimeStamp The timestamp to be associated with this log event
+
+ @Input SF The log event ID
+
+ @Input ... Log parameters
+
+ @Return PVRSRV_OK Success.
+
+*/ /**************************************************************************/
+PVRSRV_ERROR
+HTBLogKM(
+ IMG_UINT32 PID,
+ IMG_UINT32 TID,
+ IMG_UINT64 ui64TimeStamp,
+ HTB_LOG_SFids SF,
+ IMG_UINT32 ui32NumArgs,
+ IMG_UINT32 * aui32Args
+)
+{
+ OS_SPINLOCK_FLAGS uiSpinLockFlags;
+ IMG_UINT32 ui32ReturnFlags = 0;
+
+ /* Local snapshot variables of global counters */
+ IMG_UINT64 ui64OSTSSnap;
+ IMG_UINT64 ui64CRTSSnap;
+ IMG_UINT32 ui32ClkSpeedSnap;
+
+ /* format of messages is: SF:PID:TID:TIMEPT1:TIMEPT2:[PARn]*
+ * Buffer is on the stack so we don't need a semaphore to guard it
+ */
+ IMG_UINT32 aui32MessageBuffer[HTB_LOG_HEADER_SIZE+HTB_LOG_MAX_PARAMS];
+
+ /* Min HTB size is HTB_TL_BUFFER_SIZE_MIN : 10000 bytes and Max message/
+ * packet size is 4*(HTB_LOG_HEADER_SIZE+HTB_LOG_MAX_PARAMS) = 80 bytes,
+ * hence with these constraints this design is unlikely to get
+ * PVRSRV_ERROR_TLPACKET_SIZE_LIMIT_EXCEEDED error
+ */
+ PVRSRV_ERROR eError = PVRSRV_ERROR_NOT_ENABLED;
+ IMG_UINT32 ui32RetryCount = HTB_LOG_RETRY_COUNT;
+ IMG_UINT32 * pui32Message = aui32MessageBuffer;
+ IMG_UINT32 ui32MessageSize = 4 * (HTB_LOG_HEADER_SIZE+ui32NumArgs);
+
+ PVR_LOG_GOTO_IF_INVALID_PARAM(aui32Args != NULL, eError, ReturnError);
+ PVR_LOG_GOTO_IF_INVALID_PARAM(ui32NumArgs == HTB_SF_PARAMNUM(SF), eError, ReturnError);
+ PVR_LOG_GOTO_IF_INVALID_PARAM(ui32NumArgs <= HTB_LOG_MAX_PARAMS, eError, ReturnError);
+
+ if ( g_hTLStream
+ && ( 0 == PID || ~0 == PID || HTB_LOGMODE_ALLPID == g_sCtrl.eLogMode || _ValidPID(PID) )
+/* && ( g_sCtrl.ui32GroupEnable & (0x1 << HTB_SF_GID(SF)) ) */
+/* && ( g_sCtrl.ui32LogLevel >= HTB_SF_LVL(SF) ) */
+ )
+ {
+ *pui32Message++ = SF;
+ *pui32Message++ = PID;
+ *pui32Message++ = TID;
+ *pui32Message++ = ((IMG_UINT32)((ui64TimeStamp>>32)&0xffffffff));
+ *pui32Message++ = ((IMG_UINT32)(ui64TimeStamp&0xffffffff));
+ while ( ui32NumArgs )
+ {
+ ui32NumArgs--;
+ pui32Message[ui32NumArgs] = aui32Args[ui32NumArgs];
+ }
+
+ eError = TLStreamWriteRetFlags( g_hTLStream, (IMG_UINT8*)aui32MessageBuffer, ui32MessageSize, &ui32ReturnFlags );
+ while ( PVRSRV_ERROR_NOT_READY == eError && ui32RetryCount-- )
+ {
+ OSReleaseThreadQuanta();
+ eError = TLStreamWriteRetFlags( g_hTLStream, (IMG_UINT8*)aui32MessageBuffer, ui32MessageSize, &ui32ReturnFlags );
+ }
+
+ if ( PVRSRV_OK == eError )
+ {
+ g_sCtrl.bLogDropSignalled = IMG_FALSE;
+ }
+ else if ( PVRSRV_ERROR_STREAM_FULL != eError || !g_sCtrl.bLogDropSignalled )
+ {
+ PVR_DPF((PVR_DBG_WARNING, "%s() failed (%s) in %s()", "TLStreamWrite", PVRSRVGETERRORSTRING(eError), __func__));
+ }
+ if ( PVRSRV_ERROR_STREAM_FULL == eError )
+ {
+ g_sCtrl.bLogDropSignalled = IMG_TRUE;
+ }
+
+ }
+
+ if (SF == HTB_SF_CTRL_FWSYNC_MARK_SCALE)
+ {
+ OSSpinLockAcquire(g_sCtrl.hRepeatMarkerLock, uiSpinLockFlags);
+
+ /* If a marker is being placed reset byte count from last marker */
+ g_sCtrl.ui32ByteCount = 0;
+ g_sCtrl.ui64OSTS = (IMG_UINT64)aui32Args[HTB_ARG_OSTS_PT1] << 32 | aui32Args[HTB_ARG_OSTS_PT2];
+ g_sCtrl.ui64CRTS = (IMG_UINT64)aui32Args[HTB_ARG_CRTS_PT1] << 32 | aui32Args[HTB_ARG_CRTS_PT2];
+ g_sCtrl.ui32ClkSpeed = aui32Args[HTB_ARG_CLKSPD];
+
+ OSSpinLockRelease(g_sCtrl.hRepeatMarkerLock, uiSpinLockFlags);
+ }
+ else
+ {
+ OSSpinLockAcquire(g_sCtrl.hRepeatMarkerLock, uiSpinLockFlags);
+ /* Increase global count */
+ g_sCtrl.ui32ByteCount += ui32MessageSize;
+
+ /* Check if packet has overwritten last marker/rpt &&
+ If the packet count is over half the size of the buffer */
+ if (ui32ReturnFlags & TL_FLAG_OVERWRITE_DETECTED &&
+ g_sCtrl.ui32ByteCount > HTB_MARKER_PREDICTION_THRESHOLD(g_sCtrl.ui32BufferSize))
+ {
+ /* Take snapshot of global variables */
+ ui64OSTSSnap = g_sCtrl.ui64OSTS;
+ ui64CRTSSnap = g_sCtrl.ui64CRTS;
+ ui32ClkSpeedSnap = g_sCtrl.ui32ClkSpeed;
+ /* Reset global variable counter */
+ g_sCtrl.ui32ByteCount = 0;
+ OSSpinLockRelease(g_sCtrl.hRepeatMarkerLock, uiSpinLockFlags);
+
+ /* Produce a repeat marker */
+ HTBSyncPartitionMarkerRepeat(g_sCtrl.ui32SyncMarker, ui64OSTSSnap, ui64CRTSSnap, ui32ClkSpeedSnap);
+ }
+ else
+ {
+ OSSpinLockRelease(g_sCtrl.hRepeatMarkerLock, uiSpinLockFlags);
+ }
+ }
+
+ReturnError:
+ return eError;
+}
+
+/*************************************************************************/ /*!
+ @Function HTBIsConfigured
+ @Description Determine if HTB stream has been configured
+
+ @Input none
+
+ @Return IMG_FALSE Stream has not been configured
+ IMG_TRUE Stream has been configured
+
+*/ /**************************************************************************/
+IMG_BOOL
+HTBIsConfigured(void)
+{
+ return g_bConfigured;
+}
+/* EOF */
diff --git a/drivers/gpu/drm/img-rogue/htbserver.h b/drivers/gpu/drm/img-rogue/htbserver.h
new file mode 100644
index 000000000..c30556c35
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/htbserver.h
@@ -0,0 +1,228 @@
+/*************************************************************************/ /*!
+@File htbserver.h
+@Title Host Trace Buffer server implementation.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+
+@Description Host Trace Buffer provides a mechanism to log Host events to a
+ buffer in a similar way to the Firmware Trace mechanism.
+ Host Trace Buffer logs data using a Transport Layer buffer.
+ The Transport Layer and pvrtld tool provides the mechanism to
+ retrieve the trace data.
+
+ A Host Trace can be merged with a corresponding Firmware Trace.
+ This is achieved by inserting synchronisation data into both
+ traces and post processing to merge them.
+
+ The FW Trace will contain a "Sync Partition Marker". This is
+ updated every time the RGX is brought out of reset (RGX clock
+ timestamps reset at this point) and is repeated when the FW
+ Trace buffer wraps to ensure there is always at least 1
+ partition marker in the Firmware Trace buffer whenever it is
+ read.
+
+ The Host Trace will contain corresponding "Sync Partition
+ Markers" - #HTBSyncPartitionMarker(). Each partition is then
+ subdivided into "Sync Scale" sections - #HTBSyncScale(). The
+ "Sync Scale" data allows the timestamps from the two traces to
+ be correlated. The "Sync Scale" data is updated as part of the
+ standard RGX time correlation code (rgxtimecorr.c) and is
+ updated periodically including on power and clock changes.
+
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef HTBSERVER_H
+#define HTBSERVER_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+#include "pvrsrv.h"
+#include "htbuffer.h"
+
+/************************************************************************/ /*!
+ @Function HTBInit
+ @Description Initialise the Host Trace Buffer and allocate all resources
+
+ @Return eError Internal services call returned eError error
+ number
+*/ /**************************************************************************/
+PVRSRV_ERROR
+HTBInit(void);
+
+/************************************************************************/ /*!
+ @Function HTBDeInit
+ @Description Close the Host Trace Buffer and free all resources
+
+ @Return eError Internal services call returned eError error
+ number
+*/ /**************************************************************************/
+PVRSRV_ERROR
+HTBDeInit(void);
+
+/*************************************************************************/ /*!
+ @Function HTBConfigureKM
+ @Description Configure or update the configuration of the Host Trace Buffer
+
+ @Input ui32NameSize Size of the pszName string
+
+ @Input pszName Name to use for the underlying data buffer
+
+ @Input ui32BufferSize Size of the underlying data buffer
+
+ @Return eError Internal services call returned eError error
+ number
+*/ /**************************************************************************/
+PVRSRV_ERROR
+HTBConfigureKM(IMG_UINT32 ui32NameSize, const IMG_CHAR * pszName,
+ const IMG_UINT32 ui32BufferSize);
+
+
+/*************************************************************************/ /*!
+ @Function HTBControlKM
+ @Description Update the configuration of the Host Trace Buffer
+
+ @Input ui32NumFlagGroups Number of group enable flags words
+
+ @Input aui32GroupEnable Flags words controlling groups to be logged
+
+ @Input ui32LogLevel Log level to record
+
+ @Input ui32EnablePID PID to enable logging for a specific process
+
+ @Input eLogMode Enable logging for all or specific processes,
+
+ @Input eOpMode Control the behaviour of the data buffer
+
+ @Return eError Internal services call returned eError error
+ number
+*/ /**************************************************************************/
+PVRSRV_ERROR
+HTBControlKM(const IMG_UINT32 ui32NumFlagGroups,
+ const IMG_UINT32 *aui32GroupEnable,
+ const IMG_UINT32 ui32LogLevel,
+ const IMG_UINT32 ui32EnablePID,
+ const HTB_LOGMODE_CTRL eLogMode,
+ const HTB_OPMODE_CTRL eOpMode);
+
+
+/*************************************************************************/ /*!
+ @Function HTBSyncPartitionMarker
+ @Description Write an HTB sync partition marker to the HTB log
+
+ @Input ui32Marker Marker value
+
+*/ /**************************************************************************/
+void
+HTBSyncPartitionMarker(const IMG_UINT32 ui32Marker);
+
+/*************************************************************************/ /*!
+ @Function HTBSyncPartitionMarkerRpt
+ @Description Write a HTB sync partition marker to the HTB log, given
+ the previous values to repeat.
+
+ @Input ui32Marker Marker value
+ @Input ui64SyncOSTS previous OSTS
+ @Input ui64SyncCRTS previous CRTS
+ @Input ui32ClkSpeed previous Clockspeed
+
+*/ /**************************************************************************/
+void
+HTBSyncPartitionMarkerRepeat(const IMG_UINT32 ui32Marker,
+ const IMG_UINT64 ui64SyncOSTS,
+ const IMG_UINT64 ui64SyncCRTS,
+ const IMG_UINT32 ui32ClkSpeed);
+
+/*************************************************************************/ /*!
+ @Function HTBSyncScale
+ @Description Write FW-Host synchronisation data to the HTB log when clocks
+ change or are re-calibrated
+
+ @Input bLogValues IMG_TRUE if value should be immediately written
+ out to the log
+
+ @Input ui64OSTS OS Timestamp
+
+ @Input ui64CRTS Rogue timestamp
+
+ @Input ui32CalcClkSpd Calculated clock speed
+
+*/ /**************************************************************************/
+void
+HTBSyncScale(const IMG_BOOL bLogValues, const IMG_UINT64 ui64OSTS,
+ const IMG_UINT64 ui64CRTS, const IMG_UINT32 ui32CalcClkSpd);
+
+/*************************************************************************/ /*!
+ @Function HTBLogKM
+ @Description Record a Host Trace Buffer log event
+
+ @Input PID The PID of the process the event is associated
+ with. This is provided as an argument rather
+ than querying internally so that events associated
+ with a particular process, but performed by
+ another can be logged correctly.
+
+ @Input TID The TID of the process the event is associated with.
+
+ @Input ui64TimeStamp The timestamp to be associated with this log event
+
+ @Input SF The log event ID
+
+ @Input ... Log parameters
+
+ @Return PVRSRV_OK Success.
+
+*/ /**************************************************************************/
+PVRSRV_ERROR
+HTBLogKM(IMG_UINT32 PID, IMG_UINT32 TID, IMG_UINT64 ui64TimeStamp, HTB_LOG_SFids SF,
+ IMG_UINT32 ui32NumArgs, IMG_UINT32 *aui32Args);
+
+/*************************************************************************/ /*!
+ @Function HTBIsConfigured
+ @Description Determine if HTB stream has been configured
+
+ @Input none
+
+ @Return IMG_FALSE Stream has not been configured
+ IMG_TRUE Stream has been configured
+
+*/ /**************************************************************************/
+IMG_BOOL
+HTBIsConfigured(void);
+#endif /* HTBSERVER_H */
+
+/* EOF */
diff --git a/drivers/gpu/drm/img-rogue/htbuffer.c b/drivers/gpu/drm/img-rogue/htbuffer.c
new file mode 100644
index 000000000..00dbe926b
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/htbuffer.c
@@ -0,0 +1,186 @@
+/*************************************************************************/ /*!
+@File htbuffer.c
+@Title Host Trace Buffer shared API.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Host Trace Buffer provides a mechanism to log Host events to a
+ buffer in a similar way to the Firmware Trace mechanism.
+ Host Trace Buffer logs data using a Transport Layer buffer.
+ The Transport Layer and pvrtld tool provides the mechanism to
+ retrieve the trace data.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include
+#include "htbuffer.h"
+#include "osfunc.h"
+#include "client_htbuffer_bridge.h"
+
+/* The group flags array of ints large enough to store all the group flags
+ * NB: This will only work while all logging is in the kernel
+ */
+IMG_INTERNAL HTB_FLAG_EL_T g_auiHTBGroupEnable[HTB_FLAG_NUM_EL] = {0};
+
+
+/*************************************************************************/ /*!
+ @Function HTBControl
+ @Description Update the configuration of the Host Trace Buffer
+ @Input hSrvHandle Server Handle
+ @Input ui32NumFlagGroups Number of group enable flags words
+ @Input aui32GroupEnable Flags words controlling groups to be logged
+ @Input ui32LogLevel Log level to record
+ @Input ui32EnablePID PID to enable logging for a specific process
+ @Input eLogPidMode Enable logging for all or specific processes,
+ @Input eOpMode Control what trace data is dropped if the TL
+ buffer is full
+ @Return eError Internal services call returned eError error
+ number
+*/ /**************************************************************************/
+IMG_INTERNAL PVRSRV_ERROR
+HTBControl(
+ IMG_HANDLE hSrvHandle,
+ IMG_UINT32 ui32NumFlagGroups,
+ IMG_UINT32 * aui32GroupEnable,
+ IMG_UINT32 ui32LogLevel,
+ IMG_UINT32 ui32EnablePID,
+ HTB_LOGMODE_CTRL eLogPidMode,
+ HTB_OPMODE_CTRL eOpMode
+)
+{
+ return BridgeHTBControl(
+ hSrvHandle,
+ ui32NumFlagGroups,
+ aui32GroupEnable,
+ ui32LogLevel,
+ ui32EnablePID,
+ eLogPidMode,
+ eOpMode
+ );
+}
+
+
+/*************************************************************************/ /*!
+*/ /**************************************************************************/
+static PVRSRV_ERROR
+_HTBLog(IMG_HANDLE hSrvHandle, IMG_UINT32 PID, IMG_UINT32 TID, IMG_UINT64 ui64TimeStampus,
+ HTB_LOG_SFids SF, va_list args)
+{
+#if defined(__KERNEL__)
+ IMG_UINT32 i;
+ IMG_UINT32 ui32NumArgs = HTB_SF_PARAMNUM(SF);
+#if defined(__KLOCWORK__)
+ IMG_UINT32 aui32Args[HTB_LOG_MAX_PARAMS + 1]; // Prevent KW False-positive
+#else
+ IMG_UINT32 aui32Args[HTB_LOG_MAX_PARAMS];
+#endif
+
+ PVR_ASSERT(ui32NumArgs <= HTB_LOG_MAX_PARAMS);
+ ui32NumArgs = (ui32NumArgs>HTB_LOG_MAX_PARAMS) ?
+ HTB_LOG_MAX_PARAMS : ui32NumArgs;
+
+ /* unpack var args before sending over bridge */
+ for (i=0; i>32)&0xffffffff))
+#define HTBLOG_PTR_BITS_LOW(p) ((IMG_UINT32)(((IMG_UINT64)((uintptr_t)p))&0xffffffff))
+
+/* macros to cast 64-bit integers into 32-bit integer components for Host Trace */
+#define HTBLOG_U64_BITS_HIGH(u) ((IMG_UINT32)((u>>32)&0xffffffff))
+#define HTBLOG_U64_BITS_LOW(u) ((IMG_UINT32)(u&0xffffffff))
+
+/*************************************************************************/ /*!
+ @Function HTBLog
+ @Description Record a Host Trace Buffer log event
+
+ @Input PID The PID of the process the event is associated
+ with. This is provided as an argument rather
+ than querying internally so that events associated
+ with a particular process, but performed by
+ another can be logged correctly.
+
+ @Input TID The TID (Thread ID) of the thread the event is
+ associated with.
+
+ @Input TimeStampus The timestamp in us for this event
+
+ @Input SF The log event ID
+
+ @Input ... Log parameters
+
+ @Return PVRSRV_OK Success.
+
+*/ /**************************************************************************/
+IMG_INTERNAL PVRSRV_ERROR
+HTBLog(IMG_HANDLE hSrvHandle, IMG_UINT32 PID, IMG_UINT32 TID, IMG_UINT64 ui64TimeStampns, IMG_UINT32 SF, ...);
+
+
+/*************************************************************************/ /*!
+ @Function HTBLogSimple
+ @Description Record a Host Trace Buffer log event with implicit PID and Timestamp
+
+ @Input SF The log event ID
+
+ @Input ... Log parameters
+
+ @Return PVRSRV_OK Success.
+
+*/ /**************************************************************************/
+IMG_INTERNAL PVRSRV_ERROR
+HTBLogSimple(IMG_HANDLE hSrvHandle, IMG_UINT32 SF, ...);
+
+
+
+/* DEBUG log group enable */
+#if !defined(HTB_DEBUG_LOG_GROUP)
+#undef HTB_LOG_TYPE_DBG /* No trace statements in this log group should be checked in */
+#define HTB_LOG_TYPE_DBG __BUILDERROR__
+#endif
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* HTBUFFER_H */
+/*****************************************************************************
+ End of file (htbuffer.h)
+*****************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/htbuffer_init.h b/drivers/gpu/drm/img-rogue/htbuffer_init.h
new file mode 100644
index 000000000..d11457996
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/htbuffer_init.h
@@ -0,0 +1,114 @@
+/*************************************************************************/ /*!
+@File htbuffer_init.h
+@Title Host Trace Buffer functions needed for Services initialisation
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef HTBUFFER_INIT_H
+#define HTBUFFER_INIT_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "img_types.h"
+#include "img_defs.h"
+
+/*************************************************************************/ /*!
+ @Function HTBConfigure
+ @Description Configure the Host Trace Buffer.
+ Once these parameters are set they may not be changed
+
+ @Input hSrvHandle Server Handle
+
+ @Input pszBufferName Name to use for the TL buffer, this will be
+ required to request trace data from the TL
+
+ @Input ui32BufferSize Requested TL buffer size in bytes
+
+ @Return eError Internal services call returned eError error
+ number
+*/ /**************************************************************************/
+IMG_INTERNAL PVRSRV_ERROR
+HTBConfigure(
+ IMG_HANDLE hSrvHandle,
+ IMG_CHAR * pszBufferName,
+ IMG_UINT32 ui32BufferSize
+);
+
+/*************************************************************************/ /*!
+ @Function HTBControl
+ @Description Update the configuration of the Host Trace Buffer
+
+ @Input hSrvHandle Server Handle
+
+ @Input ui32NumFlagGroups Number of group enable flags words
+
+ @Input aui32GroupEnable Flags words controlling groups to be logged
+
+ @Input ui32LogLevel Log level to record
+
+ @Input ui32EnablePID PID to enable logging for a specific process
+
+ @Input eLogMode Enable logging for all or specific processes,
+
+ @Input eOpMode Control what trace data is dropped if the TL
+ buffer is full
+
+ @Return eError Internal services call returned eError error
+ number
+*/ /**************************************************************************/
+IMG_INTERNAL PVRSRV_ERROR
+HTBControl(
+ IMG_HANDLE hSrvHandle,
+ IMG_UINT32 ui32NumFlagGroups,
+ IMG_UINT32 * aui32GroupEnable,
+ IMG_UINT32 ui32LogLevel,
+ IMG_UINT32 ui32EnablePID,
+ HTB_LOGMODE_CTRL eLogMode,
+ HTB_OPMODE_CTRL eOpMode
+);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* HTBUFFER_INIT_H */
+/*****************************************************************************
+ End of file (htbuffer_init.h)
+*****************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/htbuffer_sf.h b/drivers/gpu/drm/img-rogue/htbuffer_sf.h
new file mode 100644
index 000000000..9042de20c
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/htbuffer_sf.h
@@ -0,0 +1,241 @@
+/*************************************************************************/ /*!
+@File htbuffer_sf.h
+@Title Host Trace Buffer interface string format specifiers
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Header for the Host Trace Buffer logging messages. The following
+ list are the messages the host driver prints. Changing anything
+ but the first column or spelling mistakes in the strings will
+ break compatibility with log files created with older/newer
+ driver versions.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef HTBUFFER_SF_H
+#define HTBUFFER_SF_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/******************************************************************************
+ * *DO*NOT* rearrange or delete lines in SFIDLIST or SFGROUPLIST or you
+ * WILL BREAK host tracing message compatibility with previous
+ * driver versions. Only add new ones, if so required.
+ *****************************************************************************/
+
+
+/* String used in pvrdebug -h output */
+#define HTB_LOG_GROUPS_STRING_LIST "ctrl,mmu,sync,main,brg"
+
+/* Used in print statements to display log group state, one %s per group defined */
+#define HTB_LOG_ENABLED_GROUPS_LIST_PFSPEC "%s%s%s%s%s"
+
+/* Available log groups - Master template
+ *
+ * Group usage is as follows:
+ * CTRL - Internal Host Trace information and synchronisation data
+ * MMU - MMU page mapping information
+ * SYNC - Synchronisation debug
+ * MAIN - Data master kicks, etc. tying in with the MAIN group in FWTrace
+ * DBG - Temporary debugging group, logs not to be left in the driver
+ *
+ */
+#define HTB_LOG_SFGROUPLIST \
+ X( HTB_GROUP_NONE, NONE ) \
+/* gid, group flag / apphint name */ \
+ X( HTB_GROUP_CTRL, CTRL ) \
+ X( HTB_GROUP_MMU, MMU ) \
+ X( HTB_GROUP_SYNC, SYNC ) \
+ X( HTB_GROUP_MAIN, MAIN ) \
+ X( HTB_GROUP_BRG, BRG ) \
+/* Debug group HTB_GROUP_DBG must always be last */ \
+ X( HTB_GROUP_DBG, DBG )
+
+
+/* Table of String Format specifiers, the group they belong and the number of
+ * arguments each expects. Xmacro styled macros are used to generate what is
+ * needed without requiring hand editing.
+ *
+ * id : unique id within a group
+ * gid : group id as defined above
+ * sym name : symbolic name of enumerations used to identify message strings
+ * string : Actual string
+ * #args : number of arguments the string format requires
+ */
+#define HTB_LOG_SFIDLIST \
+/*id, gid, sym name, string, # arguments */ \
+X( 0, HTB_GROUP_NONE, HTB_SF_FIRST, "You should not use this string", 0) \
+\
+X( 1, HTB_GROUP_CTRL, HTB_SF_CTRL_LOGMODE, "HTB log mode set to %d (1- all PID, 2 - restricted PID)\n", 1) \
+X( 2, HTB_GROUP_CTRL, HTB_SF_CTRL_ENABLE_PID, "HTB enable logging for PID %d\n", 1) \
+X( 3, HTB_GROUP_CTRL, HTB_SF_CTRL_ENABLE_GROUP, "HTB enable logging groups 0x%08x\n", 1) \
+X( 4, HTB_GROUP_CTRL, HTB_SF_CTRL_LOG_LEVEL, "HTB log level set to %d\n", 1) \
+X( 5, HTB_GROUP_CTRL, HTB_SF_CTRL_OPMODE, "HTB operating mode set to %d (1 - droplatest, 2 - drop oldest, 3 - block)\n", 1) \
+X( 6, HTB_GROUP_CTRL, HTB_SF_CTRL_FWSYNC_SCALE, "HTBFWSync OSTS=%08x%08x CRTS=%08x%08x CalcClkSpd=%d\n", 5) \
+X( 7, HTB_GROUP_CTRL, HTB_SF_CTRL_FWSYNC_SCALE_RPT, "FW Sync scale info OSTS=%08x%08x CRTS=%08x%08x CalcClkSpd=%d\n", 5) \
+X( 8, HTB_GROUP_CTRL, HTB_SF_CTRL_FWSYNC_MARK, "FW Sync Partition marker: %d\n", 1) \
+X( 9, HTB_GROUP_CTRL, HTB_SF_CTRL_FWSYNC_MARK_RPT, "FW Sync Partition repeat: %d\n", 1) \
+X( 10, HTB_GROUP_CTRL, HTB_SF_CTRL_FWSYNC_MARK_SCALE, "Text not used", 6)\
+\
+X( 1, HTB_GROUP_MMU, HTB_SF_MMU_PAGE_OP_TABLE, "MMU page op table entry page_id=%08x%08x index=%d level=%d val=%08x%08x map=%d\n", 7) \
+X( 2, HTB_GROUP_MMU, HTB_SF_MMU_PAGE_OP_ALLOC, "MMU allocating DevVAddr from %08x%08x to %08x%08x\n", 4) \
+X( 3, HTB_GROUP_MMU, HTB_SF_MMU_PAGE_OP_FREE, "MMU freeing DevVAddr from %08x%08x to %08x%08x\n", 4) \
+X( 4, HTB_GROUP_MMU, HTB_SF_MMU_PAGE_OP_MAP, "MMU mapping DevVAddr %08x%08x to DevPAddr %08x%08x\n", 4) \
+X( 5, HTB_GROUP_MMU, HTB_SF_MMU_PAGE_OP_PMRMAP, "MMU mapping PMR DevVAddr %08x%08x to DevPAddr %08x%08x\n", 4) \
+X( 6, HTB_GROUP_MMU, HTB_SF_MMU_PAGE_OP_UNMAP, "MMU unmapping DevVAddr %08x%08x\n", 2) \
+\
+X( 1, HTB_GROUP_SYNC, HTB_SF_SYNC_SERVER_ALLOC, "Server sync allocation [%08X]\n", 1) \
+X( 2, HTB_GROUP_SYNC, HTB_SF_SYNC_SERVER_UNREF, "Server sync unreferenced [%08X]\n", 1) \
+X( 3, HTB_GROUP_SYNC, HTB_SF_SYNC_PRIM_OP_CREATE, "Sync OP create 0x%08x, block count=%d, server syncs=%d, client syncs=%d\n", 4) \
+X( 4, HTB_GROUP_SYNC, HTB_SF_SYNC_PRIM_OP_TAKE, "Sync OP take 0x%08x server syncs=%d, client syncs=%d\n", 3) \
+X( 5, HTB_GROUP_SYNC, HTB_SF_SYNC_PRIM_OP_COMPLETE, "Sync OP complete 0x%08x\n", 1) \
+X( 6, HTB_GROUP_SYNC, HTB_SF_SYNC_PRIM_OP_DESTROY, "Sync OP destroy 0x%08x\n", 1) \
+\
+X( 1, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_TA_DEPRECATED, "Kick TA: FWCtx %08X @ %d\n", 2) \
+X( 2, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_3D_DEPRECATED, "Kick 3D: FWCtx %08X @ %d\n", 2) \
+X( 3, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_CDM_DEPRECATED,"Kick CDM: FWCtx %08X @ %d\n", 2) \
+X( 4, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_RTU, "Kick RTU: FWCtx %08X @ %d\n", 2) \
+X( 5, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_SHG, "Kick SHG: FWCtx %08X @ %d\n", 2) \
+X( 6, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_2D_DEPRECATED, "Kick 2D: FWCtx %08X @ %d\n", 2) \
+X( 7, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_UNCOUNTED, "Kick (uncounted) for all DMs\n", 0) \
+X( 8, HTB_GROUP_MAIN, HTB_SF_MAIN_FWCCB_CMD, "FW CCB Cmd: %d\n", 1) \
+X( 9, HTB_GROUP_MAIN, HTB_SF_MAIN_PRE_POWER, "Pre-power duration @ phase [%d] (0-shutdown,1-startup) RGX: %llu ns SYS: %llu ns\n", 3) \
+X(10, HTB_GROUP_MAIN, HTB_SF_MAIN_POST_POWER, "Post-power duration @ phase [%d] (0-shutdown,1-startup) SYS: %llu ns RGX: %llu ns\n", 3) \
+X(11, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_TA, "Kick TA: FWCtx %08x @ %d (frame:%d, ext:0x%08x, int:0x%08x)\n", 5) \
+X(12, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_3D, "Kick 3D: FWCtx %08x @ %d (frame:%d, ext:0x%08x, int:0x%08x)\n", 5) \
+X(13, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_CDM, "Kick CDM: FWCtx %08x @ %d (frame:%d, ext:0x%08x, int:0x%08x)\n", 5) \
+X(14, HTB_GROUP_MAIN, HTB_SF_MAIN_KICK_2D, "Kick 2D: FWCtx %08x @ %d (frame:%d, ext:0x%08x, int:0x%08x)\n", 5) \
+\
+X( 1, HTB_GROUP_BRG, HTB_SF_BRG_BRIDGE_CALL, "Bridge call: start: %010u: bid %03d fid %d\n", 3) \
+X( 2, HTB_GROUP_BRG, HTB_SF_BRG_BRIDGE_CALL_ERR, "Bridge call: start: %010u: bid %03d fid %d error %d\n", 4) \
+\
+X( 1, HTB_GROUP_DBG, HTB_SF_DBG_INTPAIR, "0x%8.8x 0x%8.8x\n", 2) \
+\
+X( 65535, HTB_GROUP_NONE, HTB_SF_LAST, "You should not use this string\n", 15)
+
+
+
+/* gid - Group numbers */
+typedef enum _HTB_LOG_SFGROUPS {
+#define X(A,B) A,
+ HTB_LOG_SFGROUPLIST
+#undef X
+} HTB_LOG_SFGROUPS;
+
+
+/* Group flags are stored in an array of elements.
+ * Each of which have a certain number of bits.
+ */
+#define HTB_FLAG_EL_T IMG_UINT32
+#define HTB_FLAG_NUM_BITS_IN_EL (sizeof(HTB_FLAG_EL_T) * 8)
+
+#define HTB_LOG_GROUP_FLAG_GROUP(gid) ((gid-1) / HTB_FLAG_NUM_BITS_IN_EL)
+#define HTB_LOG_GROUP_FLAG(gid) (gid ? (0x1 << ((gid-1)%HTB_FLAG_NUM_BITS_IN_EL)) : 0)
+#define HTB_LOG_GROUP_FLAG_NAME(gid) HTB_LOG_TYPE_ ## gid
+
+/* Group enable flags */
+typedef enum _HTB_LOG_TYPE {
+#define X(a, b) HTB_LOG_GROUP_FLAG_NAME(b) = HTB_LOG_GROUP_FLAG(a),
+ HTB_LOG_SFGROUPLIST
+#undef X
+} HTB_LOG_TYPE;
+
+
+
+/* The symbolic names found in the table above are assigned an ui32 value of
+ * the following format:
+ * 31 30 28 27 20 19 16 15 12 11 0 bits
+ * - --- ---- ---- ---- ---- ---- ---- ----
+ * 0-11: id number
+ * 12-15: group id number
+ * 16-19: number of parameters
+ * 20-27: unused
+ * 28-30: active: identify SF packet, otherwise regular int32
+ * 31: reserved for signed/unsigned compatibility
+ *
+ * The following macro assigns those values to the enum generated SF ids list.
+ */
+#define HTB_LOG_IDMARKER (0x70000000)
+#define HTB_LOG_CREATESFID(a,b,e) (((a) | (b << 12) | (e << 16)) | HTB_LOG_IDMARKER)
+
+#define HTB_LOG_IDMASK (0xFFF00000)
+#define HTB_LOG_VALIDID(I) ( ((I) & HTB_LOG_IDMASK) == HTB_LOG_IDMARKER )
+
+typedef enum HTB_LOG_SFids {
+#define X(a, b, c, d, e) c = HTB_LOG_CREATESFID(a,b,e),
+ HTB_LOG_SFIDLIST
+#undef X
+} HTB_LOG_SFids;
+
+/* Return the group id that the given (enum generated) id belongs to */
+#define HTB_SF_GID(x) (((x)>>12) & 0xf)
+/* Future improvement to support log levels */
+#define HTB_SF_LVL(x) (0)
+/* Returns how many arguments the SF(string format) for the given
+ * (enum generated) id requires.
+ */
+#define HTB_SF_PARAMNUM(x) (((x)>>16) & 0xf)
+/* Returns the id of given enum */
+#define HTB_SF_ID(x) (x & 0xfff)
+
+/* Format of messages is: SF:PID:TID:TIMEPT1:TIMEPT2:[PARn]*
+ */
+#define HTB_LOG_HEADER_SIZE 5
+#define HTB_LOG_MAX_PARAMS 15
+
+#if defined(__cplusplus)
+}
+#endif
+
+/* Defines for handling MARK_SCALE special case */
+#define HTB_GID_CTRL 1
+#define HTB_ID_MARK_SCALE 10
+#define HTB_MARK_SCALE_ARG_ARRAY_SIZE 6
+
+/* Defines for extracting args from array for special case MARK_SCALE */
+#define HTB_ARG_SYNCMARK 0
+#define HTB_ARG_OSTS_PT1 1
+#define HTB_ARG_OSTS_PT2 2
+#define HTB_ARG_CRTS_PT1 3
+#define HTB_ARG_CRTS_PT2 4
+#define HTB_ARG_CLKSPD 5
+
+#endif /* HTBUFFER_SF_H */
+/*****************************************************************************
+ End of file (htbuffer_sf.h)
+*****************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/htbuffer_types.h b/drivers/gpu/drm/img-rogue/htbuffer_types.h
new file mode 100644
index 000000000..a404bf8b7
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/htbuffer_types.h
@@ -0,0 +1,118 @@
+/*************************************************************************/ /*!
+@File htbuffer_types.h
+@Title Host Trace Buffer types.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Host Trace Buffer provides a mechanism to log Host events to a
+ buffer in a similar way to the Firmware Trace mechanism.
+ Host Trace Buffer logs data using a Transport Layer buffer.
+ The Transport Layer and pvrtld tool provides the mechanism to
+ retrieve the trace data.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef HTBUFFER_TYPES_H
+#define HTBUFFER_TYPES_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "img_defs.h"
+#include "htbuffer_sf.h"
+
+/* The group flags array of ints large enough to store all the group flags */
+#define HTB_FLAG_NUM_EL (((HTB_GROUP_DBG-1) / HTB_FLAG_NUM_BITS_IN_EL) + 1)
+extern IMG_INTERNAL HTB_FLAG_EL_T g_auiHTBGroupEnable[HTB_FLAG_NUM_EL];
+
+#define HTB_GROUP_ENABLED(SF) (g_auiHTBGroupEnable[HTB_LOG_GROUP_FLAG_GROUP(HTB_SF_GID(SF))] & HTB_LOG_GROUP_FLAG(HTB_SF_GID(SF)))
+
+/*************************************************************************/ /*!
+ Host Trace Buffer operation mode
+ Care must be taken if changing this enum to ensure the MapFlags[] array
+ in htbserver.c is kept in-step.
+*/ /**************************************************************************/
+typedef enum
+{
+ /*! Undefined operation mode */
+ HTB_OPMODE_UNDEF = 0,
+
+ /*! Drop latest, intended for continuous logging to a UM daemon.
+ * If the daemon does not keep up, the most recent log data
+ * will be dropped
+ */
+ HTB_OPMODE_DROPLATEST,
+
+ /*! Drop oldest, intended for crash logging.
+ * Data will be continuously written to a circular buffer.
+ * After a crash the buffer will contain events leading up to the crash
+ */
+ HTB_OPMODE_DROPOLDEST,
+
+ /*! Block write if buffer is full */
+ HTB_OPMODE_BLOCK,
+
+ HTB_OPMODE_LAST = HTB_OPMODE_BLOCK
+} HTB_OPMODE_CTRL;
+
+
+/*************************************************************************/ /*!
+ Host Trace Buffer log mode control
+*/ /**************************************************************************/
+typedef enum
+{
+ /*! Undefined log mode, used if update is not applied */
+ HTB_LOGMODE_UNDEF = 0,
+
+ /*! Log trace messages for all PIDs. */
+ HTB_LOGMODE_ALLPID,
+
+ /*! Log trace messages for specific PIDs only. */
+ HTB_LOGMODE_RESTRICTEDPID,
+
+ HTB_LOGMODE_LAST = HTB_LOGMODE_RESTRICTEDPID
+} HTB_LOGMODE_CTRL;
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* HTBUFFER_TYPES_H */
+
+/******************************************************************************
+ End of file (htbuffer_types.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/img_3dtypes.h b/drivers/gpu/drm/img-rogue/img_3dtypes.h
new file mode 100644
index 000000000..916e3a1ee
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/img_3dtypes.h
@@ -0,0 +1,248 @@
+/*************************************************************************/ /*!
+@File
+@Title Global 3D types for use by IMG APIs
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Defines 3D types for use by IMG APIs
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef IMG_3DTYPES_H
+#define IMG_3DTYPES_H
+
+#include
+#include "img_types.h"
+#include "img_defs.h"
+
+/**
+ * Comparison functions
+ * This comparison function is defined as:
+ * A {CmpFunc} B
+ * A is a reference value, e.g., incoming depth etc.
+ * B is the sample value, e.g., value in depth buffer.
+ */
+typedef enum _IMG_COMPFUNC_
+{
+ IMG_COMPFUNC_NEVER, /**< The comparison never succeeds */
+ IMG_COMPFUNC_LESS, /**< The comparison is a less-than operation */
+ IMG_COMPFUNC_EQUAL, /**< The comparison is an equal-to operation */
+ IMG_COMPFUNC_LESS_EQUAL, /**< The comparison is a less-than or equal-to
+ operation */
+ IMG_COMPFUNC_GREATER, /**< The comparison is a greater-than operation
+ */
+ IMG_COMPFUNC_NOT_EQUAL, /**< The comparison is a no-equal-to operation
+ */
+ IMG_COMPFUNC_GREATER_EQUAL, /**< The comparison is a greater-than or
+ equal-to operation */
+ IMG_COMPFUNC_ALWAYS, /**< The comparison always succeeds */
+} IMG_COMPFUNC;
+
+/**
+ * Stencil op functions
+ */
+typedef enum _IMG_STENCILOP_
+{
+ IMG_STENCILOP_KEEP, /**< Keep original value */
+ IMG_STENCILOP_ZERO, /**< Set stencil to 0 */
+ IMG_STENCILOP_REPLACE, /**< Replace stencil entry */
+ IMG_STENCILOP_INCR_SAT, /**< Increment stencil entry, clamping to max */
+ IMG_STENCILOP_DECR_SAT, /**< Decrement stencil entry, clamping to zero */
+ IMG_STENCILOP_INVERT, /**< Invert bits in stencil entry */
+ IMG_STENCILOP_INCR, /**< Increment stencil entry,
+ wrapping if necessary */
+ IMG_STENCILOP_DECR, /**< Decrement stencil entry,
+ wrapping if necessary */
+} IMG_STENCILOP;
+
+/**
+ * Alpha blending allows colours and textures on one surface
+ * to be blended with transparency onto another surface.
+ * These definitions apply to both source and destination blending
+ * states
+ */
+typedef enum _IMG_BLEND_
+{
+ IMG_BLEND_ZERO = 0, /**< Blend factor is (0,0,0,0) */
+ IMG_BLEND_ONE, /**< Blend factor is (1,1,1,1) */
+ IMG_BLEND_SRC_COLOUR, /**< Blend factor is the source colour */
+ IMG_BLEND_INV_SRC_COLOUR, /**< Blend factor is the inverted source colour
+ (i.e. 1-src_col) */
+ IMG_BLEND_SRC_ALPHA, /**< Blend factor is the source alpha */
+ IMG_BLEND_INV_SRC_ALPHA, /**< Blend factor is the inverted source alpha
+ (i.e. 1-src_alpha) */
+ IMG_BLEND_DEST_ALPHA, /**< Blend factor is the destination alpha */
+ IMG_BLEND_INV_DEST_ALPHA, /**< Blend factor is the inverted destination
+ alpha */
+ IMG_BLEND_DEST_COLOUR, /**< Blend factor is the destination colour */
+ IMG_BLEND_INV_DEST_COLOUR, /**< Blend factor is the inverted destination
+ colour */
+ IMG_BLEND_SRC_ALPHASAT, /**< Blend factor is the alpha saturation (the
+ minimum of (Src alpha,
+ 1 - destination alpha)) */
+ IMG_BLEND_BLEND_FACTOR, /**< Blend factor is a constant */
+ IMG_BLEND_INVBLEND_FACTOR, /**< Blend factor is a constant (inverted)*/
+ IMG_BLEND_SRC1_COLOUR, /**< Blend factor is the colour outputted from
+ the pixel shader */
+ IMG_BLEND_INV_SRC1_COLOUR, /**< Blend factor is the inverted colour
+ outputted from the pixel shader */
+ IMG_BLEND_SRC1_ALPHA, /**< Blend factor is the alpha outputted from
+ the pixel shader */
+ IMG_BLEND_INV_SRC1_ALPHA /**< Blend factor is the inverted alpha
+ outputted from the pixel shader */
+} IMG_BLEND;
+
+/**
+ * The arithmetic operation to perform when blending
+ */
+typedef enum _IMG_BLENDOP_
+{
+ IMG_BLENDOP_ADD = 0, /**< Result = (Source + Destination) */
+ IMG_BLENDOP_SUBTRACT, /**< Result = (Source - Destination) */
+ IMG_BLENDOP_REV_SUBTRACT, /**< Result = (Destination - Source) */
+ IMG_BLENDOP_MIN, /**< Result = min (Source, Destination) */
+ IMG_BLENDOP_MAX /**< Result = max (Source, Destination) */
+} IMG_BLENDOP;
+
+/**
+ * Logical operation to perform when logic ops are enabled
+ */
+typedef enum _IMG_LOGICOP_
+{
+ IMG_LOGICOP_CLEAR = 0, /**< Result = 0 */
+ IMG_LOGICOP_SET, /**< Result = -1 */
+ IMG_LOGICOP_COPY, /**< Result = Source */
+ IMG_LOGICOP_COPY_INVERTED, /**< Result = ~Source */
+ IMG_LOGICOP_NOOP, /**< Result = Destination */
+ IMG_LOGICOP_INVERT, /**< Result = ~Destination */
+ IMG_LOGICOP_AND, /**< Result = Source & Destination */
+ IMG_LOGICOP_NAND, /**< Result = ~(Source & Destination) */
+ IMG_LOGICOP_OR, /**< Result = Source | Destination */
+ IMG_LOGICOP_NOR, /**< Result = ~(Source | Destination) */
+ IMG_LOGICOP_XOR, /**< Result = Source ^ Destination */
+ IMG_LOGICOP_EQUIV, /**< Result = ~(Source ^ Destination) */
+ IMG_LOGICOP_AND_REVERSE, /**< Result = Source & ~Destination */
+ IMG_LOGICOP_AND_INVERTED, /**< Result = ~Source & Destination */
+ IMG_LOGICOP_OR_REVERSE, /**< Result = Source | ~Destination */
+ IMG_LOGICOP_OR_INVERTED /**< Result = ~Source | Destination */
+} IMG_LOGICOP;
+
+/**
+ * Type of fog blending supported
+ */
+typedef enum _IMG_FOGMODE_
+{
+ IMG_FOGMODE_NONE, /**< No fog blending - fog calculations are
+ * based on the value output from the vertex phase */
+ IMG_FOGMODE_LINEAR, /**< Linear interpolation */
+ IMG_FOGMODE_EXP, /**< Exponential */
+ IMG_FOGMODE_EXP2, /**< Exponential squaring */
+} IMG_FOGMODE;
+
+/**
+ * Types of filtering
+ */
+typedef enum _IMG_FILTER_
+{
+ IMG_FILTER_DONTCARE, /**< Any filtering mode is acceptable */
+ IMG_FILTER_POINT, /**< Point filtering */
+ IMG_FILTER_LINEAR, /**< Bi-linear filtering */
+ IMG_FILTER_BICUBIC, /**< Bi-cubic filtering */
+} IMG_FILTER;
+
+/**
+ * Addressing modes for textures
+ */
+typedef enum _IMG_ADDRESSMODE_
+{
+ IMG_ADDRESSMODE_REPEAT, /**< Texture repeats continuously */
+ IMG_ADDRESSMODE_FLIP, /**< Texture flips on odd integer part */
+ IMG_ADDRESSMODE_CLAMP, /**< Texture clamped at 0 or 1 */
+ IMG_ADDRESSMODE_FLIPCLAMP, /**< Flipped once, then clamp */
+ IMG_ADDRESSMODE_CLAMPBORDER,
+ IMG_ADDRESSMODE_OGL_CLAMP,
+ IMG_ADDRESSMODE_OVG_TILEFILL,
+ IMG_ADDRESSMODE_DONTCARE,
+} IMG_ADDRESSMODE;
+
+/**
+ * Culling based on winding order of triangle.
+ */
+typedef enum _IMG_CULLMODE_
+{
+ IMG_CULLMODE_NONE, /**< Don't cull */
+ IMG_CULLMODE_FRONTFACING, /**< Front facing triangles */
+ IMG_CULLMODE_BACKFACING, /**< Back facing triangles */
+} IMG_CULLMODE;
+
+/**
+ * Colour for clearing surfaces.
+ * The four elements of the 4 x 32 bit array will map to colour
+ * R,G,B,A components, in order.
+ * For YUV colour space the order is Y,U,V.
+ * For Depth and Stencil formats D maps to R and S maps to G.
+ */
+typedef union IMG_CLEAR_COLOUR_TAG {
+ IMG_UINT32 aui32[4];
+ IMG_INT32 ai32[4];
+ IMG_FLOAT af32[4];
+} IMG_CLEAR_COLOUR;
+
+static_assert(sizeof(IMG_FLOAT) == sizeof(IMG_INT32), "Size of IMG_FLOAT is not 32 bits.");
+
+/*! ************************************************************************//**
+@brief Specifies the MSAA resolve operation.
+*/ /**************************************************************************/
+typedef enum _IMG_RESOLVE_OP_
+{
+ IMG_RESOLVE_BLEND = 0, /*!< box filter on the samples */
+ IMG_RESOLVE_MIN = 1, /*!< minimum of the samples */
+ IMG_RESOLVE_MAX = 2, /*!< maximum of the samples */
+ IMG_RESOLVE_SAMPLE0 = 3, /*!< choose sample 0 */
+ IMG_RESOLVE_SAMPLE1 = 4, /*!< choose sample 1 */
+ IMG_RESOLVE_SAMPLE2 = 5, /*!< choose sample 2 */
+ IMG_RESOLVE_SAMPLE3 = 6, /*!< choose sample 3 */
+ IMG_RESOLVE_SAMPLE4 = 7, /*!< choose sample 4 */
+ IMG_RESOLVE_SAMPLE5 = 8, /*!< choose sample 5 */
+ IMG_RESOLVE_SAMPLE6 = 9, /*!< choose sample 6 */
+ IMG_RESOLVE_SAMPLE7 = 10, /*!< choose sample 7 */
+} IMG_RESOLVE_OP;
+
+
+#endif /* IMG_3DTYPES_H */
+/******************************************************************************
+ End of file (img_3dtypes.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/img_defs.h b/drivers/gpu/drm/img-rogue/img_defs.h
new file mode 100644
index 000000000..294d05b0d
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/img_defs.h
@@ -0,0 +1,565 @@
+/*************************************************************************/ /*!
+@File
+@Title Common header containing type definitions for portability
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Contains variable and structure definitions. Any platform
+ specific types should be defined in this file.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef IMG_DEFS_H
+#define IMG_DEFS_H
+
+#if defined(__linux__) && defined(__KERNEL__)
+#include
+#else
+#include
+#endif
+#if !(defined(__linux__) && defined(__KERNEL__))
+#include
+#endif
+
+#include "img_types.h"
+
+#if defined(NO_INLINE_FUNCS)
+ #define INLINE
+ #define FORCE_INLINE
+#else
+#if defined(__cplusplus) || defined(INTEGRITY_OS)
+ #if !defined(INLINE)
+ #define INLINE inline
+ #endif
+ #define FORCE_INLINE static inline
+#else
+#if !defined(INLINE)
+ #define INLINE __inline
+#endif
+#if (defined(UNDER_WDDM) || defined(WINDOWS_WDF)) && defined(_X86_)
+ #define FORCE_INLINE __forceinline
+#else
+ #define FORCE_INLINE static __inline
+#endif
+#endif
+#endif
+
+/* True if the GCC version is at least the given version. False for older
+ * versions of GCC, or other compilers.
+ */
+#if defined(__GNUC__)
+#define GCC_VERSION_AT_LEAST(major, minor) \
+ (__GNUC__ > (major) || \
+ (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
+#else
+#define GCC_VERSION_AT_LEAST(major, minor) 0
+#endif
+
+/* Use Clang's __has_extension and __has_builtin macros if available. */
+#if defined(__has_extension)
+#define has_clang_extension(e) __has_extension(e)
+#else
+#define has_clang_extension(e) 0
+#endif
+
+#if defined(__has_builtin)
+#define has_clang_builtin(e) __has_builtin(e)
+#else
+#define has_clang_builtin(e) 0
+#endif
+
+/* Use this in any file, or use attributes under GCC - see below */
+#ifndef PVR_UNREFERENCED_PARAMETER
+#define PVR_UNREFERENCED_PARAMETER(param) ((void)(param))
+#endif
+
+/* static_assert(condition, "message to print if it fails");
+ *
+ * Assert something at compile time. If the assertion fails, try to print
+ * the message, otherwise do nothing. static_assert is available if:
+ *
+ * - It's already defined as a macro (e.g. by in C11)
+ * - We're using MSVC which exposes static_assert unconditionally
+ * - We're using a C++ compiler that supports C++11
+ * - We're using GCC 4.6 and up in C mode (in which case it's available as
+ * _Static_assert)
+ *
+ * In all other cases, fall back to an equivalent that makes an invalid
+ * declaration.
+ */
+#if !defined(static_assert) && !defined(_MSC_VER) && \
+ (!defined(__cplusplus) || __cplusplus < 201103L) || defined(__KLOCWORK__)
+ /* static_assert isn't already available */
+ #if !defined(__cplusplus) && (GCC_VERSION_AT_LEAST(4, 6) || \
+ (defined(__clang__) && has_clang_extension(c_static_assert)))
+ #define static_assert _Static_assert
+ #else
+ #define static_assert(expr, message) \
+ extern int static_assert_failed[(expr) ? 1 : -1] __attribute__((unused))
+ #endif
+#endif
+
+/*
+ * unreachable("explanation") can be used to indicate to the compiler that
+ * some parts of the code can never be reached, like the default branch
+ * of a switch that covers all real-world possibilities, even though there
+ * are other ints that exist for instance.
+ *
+ * The message will be printed as an assert() when debugging.
+ *
+ * Note: there is no need to add a 'return' or any error handling after
+ * calling unreachable(), as this call will never return.
+ */
+#if defined(__linux__) && defined(__KERNEL__)
+/* Kernel has its own unreachable(), which is a simple infinite loop */
+#elif GCC_VERSION_AT_LEAST(4, 5) || has_clang_builtin(__builtin_unreachable)
+ #define unreachable(msg) \
+ do { \
+ assert(!(msg)); \
+ __builtin_unreachable(); \
+ } while (0)
+#elif defined(_MSC_VER)
+ #define unreachable(msg) \
+ do { \
+ assert(!(msg)); \
+ __assume(0); \
+ } while (0)
+#else
+ #define unreachable(msg) \
+ do { \
+ assert(!(msg)); \
+ while (1); \
+ } while (0)
+#endif
+
+/*
+ * assume(x > 2 && x <= 7) works like an assert(), except it hints to the
+ * compiler what it can assume to optimise the code, like a limited range
+ * of parameter values.
+ */
+#if has_clang_builtin(__builtin_assume)
+ #define assume(expr) \
+ do { \
+ assert(expr); \
+ __builtin_assume(expr); \
+ } while (0)
+#elif defined(_MSC_VER)
+ #define assume(expr) \
+ do { \
+ assert(expr); \
+ __assume(expr); \
+ } while (0)
+#elif defined(__linux__) && defined(__KERNEL__)
+ #define assume(expr) ((void)(expr))
+#elif GCC_VERSION_AT_LEAST(4, 5) || has_clang_builtin(__builtin_unreachable)
+ #define assume(expr) \
+ do { \
+ if (unlikely(!(expr))) \
+ unreachable("Assumption isn't true: " # expr); \
+ } while (0)
+#else
+ #define assume(expr) assert(expr)
+#endif
+
+/*! Macro to calculate the n-byte aligned value from that supplied rounding up.
+ * n must be a power of two.
+ *
+ * Both arguments should be of a type with the same size otherwise the macro may
+ * cut off digits, e.g. imagine a 64 bit address in _x and a 32 bit value in _n.
+ */
+#define PVR_ALIGN(_x, _n) (((_x)+((_n)-1U)) & ~((_n)-1U))
+
+#if defined(_WIN32)
+
+#if defined(WINDOWS_WDF)
+
+ /*
+ * For WINDOWS_WDF drivers we don't want these defines to overwrite calling conventions propagated through the build system.
+ * This 'empty' choice helps to resolve all the calling conv issues.
+ *
+ */
+ #define IMG_CALLCONV
+ #define C_CALLCONV
+
+ #define IMG_INTERNAL
+ #define IMG_RESTRICT __restrict
+
+ /*
+ * The proper way of dll linking under MS compilers is made of two things:
+ * - decorate implementation with __declspec(dllexport)
+ * this decoration helps compiler with making the so called
+ * 'export library'
+ * - decorate forward-declaration (in a source dependent on a dll) with
+ * __declspec(dllimport), this decoration helps the compiler to make
+ * faster and smaller code in terms of calling dll-imported functions
+ *
+ * Usually these decorations are performed by having a single macro define
+ * making that expands to a proper __declspec() depending on the
+ * translation unit, dllexport inside the dll source and dllimport outside
+ * the dll source. Having IMG_EXPORT and IMG_IMPORT resolving to the same
+ * __declspec() makes no sense, but at least works.
+ */
+ #define IMG_IMPORT __declspec(dllexport)
+ #define IMG_EXPORT __declspec(dllexport)
+
+#else
+
+ #define IMG_CALLCONV __stdcall
+ #define IMG_INTERNAL
+ #define IMG_EXPORT __declspec(dllexport)
+ #define IMG_RESTRICT __restrict
+ #define C_CALLCONV __cdecl
+
+ /*
+ * IMG_IMPORT is defined as IMG_EXPORT so that headers and implementations
+ * match. Some compilers require the header to be declared IMPORT, while
+ * the implementation is declared EXPORT.
+ */
+ #define IMG_IMPORT IMG_EXPORT
+
+#endif
+
+#if defined(UNDER_WDDM)
+ #ifndef _INC_STDLIB
+ #if defined(__mips)
+ /* do nothing */
+ #elif defined(UNDER_MSBUILD)
+ /* do nothing */
+ #else
+ _CRTIMP void __cdecl abort(void);
+ #endif
+ #endif
+#endif /* UNDER_WDDM */
+#else
+ #if (defined(__linux__) || defined(__QNXNTO__)) && defined(__KERNEL__)
+ #define IMG_INTERNAL
+ #define IMG_EXPORT
+ #define IMG_CALLCONV
+ #elif defined(__linux__) || defined(__METAG) || defined(__mips) || defined(__QNXNTO__) || defined(__riscv)
+ #define IMG_CALLCONV
+ #define C_CALLCONV
+
+ #if defined(__METAG)
+ #define IMG_INTERNAL
+ #else
+ #define IMG_INTERNAL __attribute__((visibility("hidden")))
+ #endif
+
+ #define IMG_EXPORT __attribute__((visibility("default")))
+ #define IMG_RESTRICT __restrict__
+ #elif defined(INTEGRITY_OS)
+ #define IMG_CALLCONV
+ #define IMG_INTERNAL
+ #define IMG_EXPORT
+ #define IMG_RESTRICT
+ #define C_CALLCONV
+ #define __cdecl
+
+ #ifndef USE_CODE
+ #define IMG_ABORT() printf("IMG_ABORT was called.\n")
+ #endif
+ #else
+ #error("define an OS")
+ #endif
+
+#endif
+
+/* Use default definition if not overridden */
+#ifndef IMG_ABORT
+ #if defined(EXIT_ON_ABORT)
+ #define IMG_ABORT() exit(1)
+ #else
+ #define IMG_ABORT() abort()
+ #endif
+#endif
+
+/* The best way to suppress unused parameter warnings using GCC is to use a
+ * variable attribute. Place the __maybe_unused between the type and name of an
+ * unused parameter in a function parameter list e.g. 'int __maybe_unused var'.
+ * This should only be used in GCC build environments, for example, in files
+ * that compile only on Linux.
+ * Other files should use PVR_UNREFERENCED_PARAMETER
+ */
+
+/* Kernel macros for compiler attributes */
+/* Note: param positions start at 1 */
+#if defined(__linux__) && defined(__KERNEL__)
+ #include
+
+ #if !defined(__fallthrough)
+ #if GCC_VERSION_AT_LEAST(7, 0)
+ #define __fallthrough __attribute__((__fallthrough__))
+ #else
+ #define __fallthrough
+ #endif
+ #endif
+#elif defined(__GNUC__) || defined(HAS_GNUC_ATTRIBUTES)
+ #define __must_check __attribute__((warn_unused_result))
+ #define __maybe_unused __attribute__((unused))
+ #define __malloc __attribute__((malloc))
+
+ /* Bionic's might have defined these already */
+ /* See https://android.googlesource.com/platform/bionic.git/+/master/libc/include/sys/cdefs.h */
+ #if !defined(__packed)
+ #define __packed __attribute__((packed))
+ #endif
+ #if !defined(__aligned)
+ #define __aligned(n) __attribute__((aligned(n)))
+ #endif
+ #if !defined(__noreturn)
+ #define __noreturn __attribute__((noreturn))
+ #endif
+
+ /* That one compiler that supports attributes but doesn't support
+ * the printf attribute... */
+ #if defined(__GNUC__)
+ #define __printf(fmt, va) __attribute__((format(printf, (fmt), (va))))
+ #else
+ #define __printf(fmt, va)
+ #endif /* defined(__GNUC__) */
+
+ #if defined(__cplusplus) && (__cplusplus >= 201703L)
+ #define __fallthrough [[fallthrough]]
+ #elif GCC_VERSION_AT_LEAST(7, 0)
+ #define __fallthrough __attribute__((__fallthrough__))
+ #else
+ #define __fallthrough
+ #endif
+
+ #define __user
+ #define __force
+ #define __iomem
+#else
+ /* Silently ignore those attributes */
+ #define __printf(fmt, va)
+ #define __packed
+ #define __aligned(n)
+ #define __must_check
+ #define __maybe_unused
+ #define __malloc
+
+ #if defined(_MSC_VER) || defined(CC_ARM)
+ #define __noreturn __declspec(noreturn)
+ #else
+ #define __noreturn
+ #endif
+
+ /* This may already been defined, e.g. by SAL (Source Annotation Language) */
+ #if !defined(__fallthrough)
+ #define __fallthrough
+ #endif
+
+ #define __user
+ #define __force
+ #define __iomem
+#endif
+
+
+/* Other attributes, following the same style */
+#if defined(__GNUC__) || defined(HAS_GNUC_ATTRIBUTES)
+ #define __const_function __attribute__((const))
+#else
+ #define __const_function
+#endif
+
+
+/* GCC builtins */
+#if defined(__linux__) && defined(__KERNEL__)
+ #include
+#elif defined(__GNUC__) || defined(INTEGRITY_OS)
+
+/* Klocwork does not support __builtin_expect, which makes the actual condition
+ * expressions hidden during analysis, affecting it negatively. */
+#if !defined(__KLOCWORK__) && !defined(INTEGRITY_OS) && !defined(DEBUG)
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+#endif
+
+ /* Compiler memory barrier to prevent reordering */
+ #define barrier() __asm__ __volatile__("": : :"memory")
+#else
+ #define barrier() static_assert(0, "barrier() isn't supported by your compiler");
+#endif
+
+/* That one OS that defines one but not the other... */
+#ifndef likely
+ #define likely(x) (x)
+#endif
+#ifndef unlikely
+ #define unlikely(x) (x)
+#endif
+
+/* These two macros are also provided by the kernel */
+#ifndef BIT
+#define BIT(b) (1UL << (b))
+#endif
+
+#ifndef BIT_ULL
+#define BIT_ULL(b) (1ULL << (b))
+#endif
+
+#define BIT_SET(f, b) BITMASK_SET((f), BIT(b))
+#define BIT_UNSET(f, b) BITMASK_UNSET((f), BIT(b))
+#define BIT_TOGGLE(f, b) BITMASK_TOGGLE((f), BIT(b))
+#define BIT_ISSET(f, b) BITMASK_HAS((f), BIT(b))
+
+#define BITMASK_SET(f, m) do { ((f) |= (m)); } while (false)
+#define BITMASK_UNSET(f, m) do { ((f) &= ~(m)); } while (false)
+#define BITMASK_TOGGLE(f, m) do { ((f) ^= (m)); } while (false)
+#define BITMASK_HAS(f, m) (((f) & (m)) == (m)) /* the bits from the mask are all set */
+#define BITMASK_ANY(f, m) (((f) & (m)) != 0U) /* any bit from the mask is set */
+
+#ifndef MAX
+#define MAX(a ,b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef CLAMP
+#define CLAMP(min, max, n) ((n) < (min) ? (min) : ((n) > (max) ? (max) : (n)))
+#endif
+
+#define SWAP(X, Y) (X) ^= (Y); (Y) ^= (X); (X) ^= (Y);
+
+
+#if defined(__linux__) && defined(__KERNEL__)
+ #include
+ #include
+#endif
+
+/* Get a structure's address from the address of a member */
+#define IMG_CONTAINER_OF(ptr, type, member) \
+ (type *) ((uintptr_t) (ptr) - offsetof(type, member))
+
+/* Get a new pointer with an offset (in bytes) from a base address, useful
+ * when traversing byte buffers and accessing data in buffers through struct
+ * pointers.
+ * Note, this macro is not equivalent to or replacing offsetof() */
+#define IMG_OFFSET_ADDR(addr, offset_in_bytes) \
+ (void*)&(((IMG_UINT8*)(void*)(addr))[offset_in_bytes])
+
+/* Get a new pointer with an offset (in dwords) from a base address, useful
+ * when traversing byte buffers and accessing data in buffers through struct
+ * pointers.
+ * Note, this macro is not equivalent to or replacing offsetof() */
+#define IMG_OFFSET_ADDR_DW(addr, offset_in_dwords) \
+ (void*)(((IMG_UINT32*)(void*)(addr)) + (offset_in_dwords))
+
+/* The number of elements in a fixed-sized array */
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(ARR) (sizeof(ARR) / sizeof((ARR)[0]))
+#endif
+
+/* To guarantee that __func__ can be used, define it as a macro here if it
+ isn't already provided by the compiler. */
+#if defined(_MSC_VER) || (defined(__cplusplus) && __cplusplus < 201103L)
+#define __func__ __FUNCTION__
+#endif
+
+#if defined(__cplusplus)
+/* C++ Specific:
+ * Disallow use of copy and assignment operator within a class.
+ * Should be placed under private. */
+#define IMG_DISALLOW_COPY_AND_ASSIGN(C) \
+ C(const C&); \
+ void operator=(const C&)
+#endif
+
+#if defined(SUPPORT_PVR_VALGRIND) && !defined(__METAG) && !defined(__mips) && !defined(__riscv)
+ #include "/usr/include/valgrind/memcheck.h"
+
+ #define VG_MARK_INITIALIZED(pvData,ui32Size) VALGRIND_MAKE_MEM_DEFINED(pvData,ui32Size)
+ #define VG_MARK_NOACCESS(pvData,ui32Size) VALGRIND_MAKE_MEM_NOACCESS(pvData,ui32Size)
+ #define VG_MARK_ACCESS(pvData,ui32Size) VALGRIND_MAKE_MEM_UNDEFINED(pvData,ui32Size)
+#else
+ #if defined(_MSC_VER)
+ # define PVR_MSC_SUPPRESS_4127 __pragma(warning(suppress:4127))
+ #else
+ # define PVR_MSC_SUPPRESS_4127
+ #endif
+
+ #define VG_MARK_INITIALIZED(pvData,ui32Size) PVR_MSC_SUPPRESS_4127 do { } while (0)
+ #define VG_MARK_NOACCESS(pvData,ui32Size) PVR_MSC_SUPPRESS_4127 do { } while (0)
+ #define VG_MARK_ACCESS(pvData,ui32Size) PVR_MSC_SUPPRESS_4127 do { } while (0)
+#endif
+
+#define IMG_STRINGIFY_IMPL(x) # x
+#define IMG_STRINGIFY(x) IMG_STRINGIFY_IMPL(x)
+
+#if defined(INTEGRITY_OS)
+ /* Definitions not present in INTEGRITY. */
+ #define PATH_MAX 200
+#endif
+
+#if defined(__clang__) || defined(__GNUC__)
+ /* __SIZEOF_POINTER__ is defined already by these compilers */
+#elif defined(INTEGRITY_OS)
+ #if defined(__Ptr_Is_64)
+ #define __SIZEOF_POINTER__ 8
+ #else
+ #define __SIZEOF_POINTER__ 4
+ #endif
+#elif defined(_WIN32)
+ #define __SIZEOF_POINTER__ sizeof(char *)
+#else
+ #warning Unknown OS - using default method to determine whether CPU arch is 64-bit.
+ #define __SIZEOF_POINTER__ sizeof(char *)
+#endif
+
+/* RDI8567: gcc/clang/llvm load/store optimisations may cause issues with
+ * uncached device memory allocations. Some pointers are made 'volatile'
+ * to prevent those optimisations being applied to writes through those
+ * pointers.
+ */
+#if (GCC_VERSION_AT_LEAST(7, 0) || defined(__clang__)) && (defined(__arm64__) || defined(__aarch64__))
+#define NOLDSTOPT volatile
+/* after applying 'volatile' to a pointer, we may need to cast it to 'void *'
+ * to keep it compatible with its existing uses.
+ */
+#define NOLDSTOPT_VOID (void *)
+
+#define NOLDSTOPT_REQUIRED 1
+#else
+#define NOLDSTOPT
+#define NOLDSTOPT_VOID
+#endif
+
+#endif /* IMG_DEFS_H */
+/*****************************************************************************
+ End of file (img_defs.h)
+*****************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/img_elf.h b/drivers/gpu/drm/img-rogue/img_elf.h
new file mode 100644
index 000000000..8837d9592
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/img_elf.h
@@ -0,0 +1,111 @@
+/*************************************************************************/ /*!
+@File img_elf.h
+@Title IMG ELF file definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Platform RGX
+@Description Definitions for ELF file structures used in the DDK.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(IMG_ELF_H)
+#define IMG_ELF_H
+
+#include "img_types.h"
+
+/* ELF format defines */
+#define ELF_PT_LOAD (0x1U) /* Program header identifier as Load */
+#define ELF_SHT_SYMTAB (0x2U) /* Section identifier as Symbol Table */
+#define ELF_SHT_STRTAB (0x3U) /* Section identifier as String Table */
+#define MAX_STRTAB_NUM (0x8U) /* Maximum number of string table in the ELF file */
+
+/* Redefined structs of ELF format */
+typedef struct
+{
+ IMG_UINT8 ui32Eident[16];
+ IMG_UINT16 ui32Etype;
+ IMG_UINT16 ui32Emachine;
+ IMG_UINT32 ui32Eversion;
+ IMG_UINT32 ui32Eentry;
+ IMG_UINT32 ui32Ephoff;
+ IMG_UINT32 ui32Eshoff;
+ IMG_UINT32 ui32Eflags;
+ IMG_UINT16 ui32Eehsize;
+ IMG_UINT16 ui32Ephentsize;
+ IMG_UINT16 ui32Ephnum;
+ IMG_UINT16 ui32Eshentsize;
+ IMG_UINT16 ui32Eshnum;
+ IMG_UINT16 ui32Eshtrndx;
+} IMG_ELF_HDR;
+
+typedef struct
+{
+ IMG_UINT32 ui32Stname;
+ IMG_UINT32 ui32Stvalue;
+ IMG_UINT32 ui32Stsize;
+ IMG_UINT8 ui32Stinfo;
+ IMG_UINT8 ui32Stother;
+ IMG_UINT16 ui32Stshndx;
+} IMG_ELF_SYM;
+
+typedef struct
+{
+ IMG_UINT32 ui32Shname;
+ IMG_UINT32 ui32Shtype;
+ IMG_UINT32 ui32Shflags;
+ IMG_UINT32 ui32Shaddr;
+ IMG_UINT32 ui32Shoffset;
+ IMG_UINT32 ui32Shsize;
+ IMG_UINT32 ui32Shlink;
+ IMG_UINT32 ui32Shinfo;
+ IMG_UINT32 ui32Shaddralign;
+ IMG_UINT32 ui32Shentsize;
+} IMG_ELF_SHDR;
+
+typedef struct
+{
+ IMG_UINT32 ui32Ptype;
+ IMG_UINT32 ui32Poffset;
+ IMG_UINT32 ui32Pvaddr;
+ IMG_UINT32 ui32Ppaddr;
+ IMG_UINT32 ui32Pfilesz;
+ IMG_UINT32 ui32Pmemsz;
+ IMG_UINT32 ui32Pflags;
+ IMG_UINT32 ui32Palign;
+} IMG_ELF_PROGRAM_HDR;
+
+#endif /* IMG_ELF_H */
diff --git a/drivers/gpu/drm/img-rogue/img_types.h b/drivers/gpu/drm/img-rogue/img_types.h
new file mode 100644
index 000000000..826f03e9f
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/img_types.h
@@ -0,0 +1,318 @@
+/*************************************************************************/ /*!
+@File
+@Title Global types for use by IMG APIs
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Defines type aliases for use by IMG APIs.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef IMG_TYPES_H
+#define IMG_TYPES_H
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* To use C99 types and definitions, there are two special cases we need to
+ * cater for:
+ *
+ * - Visual Studio: in VS2010 or later, some standard headers are available,
+ * and MSVC has its own built-in sized types. We can define the C99 types
+ * in terms of these.
+ *
+ * - Linux kernel code: C99 sized types are defined in , but
+ * some other features (like macros for constants or printf format
+ * strings) are missing, so we need to fill in the gaps ourselves.
+ *
+ * For other cases (userspace code under Linux, Android or Neutrino, or
+ * firmware code), we can include the standard headers.
+ */
+#if defined(_MSC_VER)
+ #include /* bool */
+ #include "msvc_types.h"
+#elif defined(__linux__) && defined(__KERNEL__)
+ #include
+ #include
+ #include "kernel_types.h"
+#elif defined(__linux__) || defined(__METAG) || defined(__MINGW32__) || \
+ defined(__QNXNTO__) || defined(INTEGRITY_OS) || defined(__riscv)
+ #include /* NULL */
+ #include
+ #include /* intX_t/uintX_t, format specifiers */
+ #include /* INT_MIN, etc */
+ #include /* bool */
+#elif defined(__mips)
+ #include /* NULL */
+ #include /* intX_t/uintX_t, format specifiers */
+ #include /* bool */
+#else
+ #error C99 support not set up for this build
+#endif
+
+/*
+ * Due to a Klocwork bug, 'true'/'false' constants are not recognized to be of
+ * boolean type. This results in large number of false-positives being reported
+ * (MISRA.ETYPE.ASSIGN.2012: "An expression value of essential type 'signed char'
+ * is assigned to an object of essential type 'bool'"). Work around this by
+ * redefining those constants with cast to bool added.
+ */
+#if defined(__KLOCWORK__) && !defined(__cplusplus)
+#undef true
+#undef false
+#define true ((bool) 1)
+#define false ((bool) 0)
+#endif
+
+typedef unsigned int IMG_UINT;
+typedef int IMG_INT;
+
+typedef uint8_t IMG_UINT8, *IMG_PUINT8;
+typedef uint8_t IMG_BYTE, *IMG_PBYTE;
+typedef int8_t IMG_INT8;
+typedef char IMG_CHAR, *IMG_PCHAR;
+
+typedef uint16_t IMG_UINT16, *IMG_PUINT16;
+typedef int16_t IMG_INT16;
+typedef uint32_t IMG_UINT32, *IMG_PUINT32;
+typedef int32_t IMG_INT32, *IMG_PINT32;
+#if defined(INTEGRITY_OS)
+#if __INT_BIT >= 32U
+#define IMG_UINT32_C(n) ((IMG_UINT32)(n ## U))
+#elif __LONG_BIT >= 32U
+#define IMG_UINT32_C(n) ((IMG_UINT32)(n ## UL))
+#elif defined(__LLONG_BIT) && __LLONG_BIT >= 32U
+#define IMG_UINT32_C(n) ((IMG_UINT32)(n ## ULL))
+#endif
+#else /* defined(INTEGRITY_OS) */
+#define IMG_UINT32_C(c) ((IMG_UINT32)UINT32_C(c))
+#endif /* defined(INTEGRITY_OS) */
+
+typedef uint64_t IMG_UINT64, *IMG_PUINT64;
+typedef int64_t IMG_INT64;
+#define IMG_INT64_C(c) INT64_C(c)
+#if defined(INTEGRITY_OS)
+#if __INT_BIT >= 64U
+#define IMG_UINT64_C(n) (n ## U)
+#elif defined(__LONG_BIT) && __LONG_BIT >= 64U
+#define IMG_UINT64_C(n) (n ## UL)
+#elif defined(__LLONG_BIT) && __LLONG_BIT >= 64U
+#define IMG_UINT64_C(n) (n ## ULL)
+#endif
+#else /* defined(INTEGRITY_OS) */
+#define IMG_UINT64_C(c) UINT64_C(c)
+#endif /* defined(INTEGRITY_OS) */
+#define IMG_UINT16_C(c) UINT16_C(c)
+#define IMG_UINT64_FMTSPEC PRIu64
+#define IMG_UINT64_FMTSPECX PRIX64
+#define IMG_UINT64_FMTSPECx PRIx64
+#define IMG_UINT64_FMTSPECo PRIo64
+#define IMG_INT64_FMTSPECd PRId64
+
+#define IMG_UINT16_MAX UINT16_MAX
+#define IMG_UINT32_MAX UINT32_MAX
+#define IMG_UINT64_MAX UINT64_MAX
+
+#define IMG_INT16_MAX INT16_MAX
+#define IMG_INT32_MAX INT32_MAX
+#define IMG_INT64_MAX INT64_MAX
+
+/* Linux kernel mode does not use floating point */
+typedef float IMG_FLOAT, *IMG_PFLOAT;
+typedef double IMG_DOUBLE;
+
+typedef union
+{
+ IMG_UINT32 ui32;
+ IMG_FLOAT f;
+} IMG_UINT32_FLOAT;
+
+typedef int IMG_SECURE_TYPE;
+
+typedef enum tag_img_bool
+{
+ IMG_FALSE = 0,
+ IMG_TRUE = 1,
+ IMG_FORCE_ALIGN = 0x7FFFFFFF
+} IMG_BOOL, *IMG_PBOOL;
+
+#if defined(UNDER_WDDM) || defined(WINDOWS_WDF)
+typedef IMG_CHAR const* IMG_PCCHAR;
+#endif
+
+/* Format specifiers for 'size_t' type */
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#define IMG_SIZE_FMTSPEC "%Iu"
+#define IMG_SIZE_FMTSPECX "%Ix"
+#else
+#define IMG_SIZE_FMTSPEC "%zu"
+#define IMG_SIZE_FMTSPECX "%zx"
+#endif
+
+#if defined(__linux__) && defined(__KERNEL__)
+/* prints the function name when used with printk */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0))
+#define IMG_PFN_FMTSPEC "%ps"
+#else
+#define IMG_PFN_FMTSPEC "%pf"
+#endif
+#else
+#define IMG_PFN_FMTSPEC "%p"
+#endif
+
+typedef void *IMG_HANDLE;
+
+/* Process IDs */
+typedef IMG_UINT32 IMG_PID;
+
+/* OS connection type */
+typedef int IMG_OS_CONNECTION;
+
+
+/*
+ * Address types.
+ * All types used to refer to a block of memory are wrapped in structures
+ * to enforce some degree of type safety, i.e. a IMG_DEV_VIRTADDR cannot
+ * be assigned to a variable of type IMG_DEV_PHYADDR because they are not the
+ * same thing.
+ *
+ * There is an assumption that the system contains at most one non-cpu mmu,
+ * and a memory block is only mapped by the MMU once.
+ *
+ * Different devices could have offset views of the physical address space.
+ *
+ */
+
+
+/*
+ *
+ * +------------+ +------------+ +------------+ +------------+
+ * | CPU | | DEV | | DEV | | DEV |
+ * +------------+ +------------+ +------------+ +------------+
+ * | | | |
+ * | void * |IMG_DEV_VIRTADDR |IMG_DEV_VIRTADDR |
+ * | \-------------------/ |
+ * | | |
+ * +------------+ +------------+ |
+ * | MMU | | MMU | |
+ * +------------+ +------------+ |
+ * | | |
+ * | | |
+ * | | |
+ * +--------+ +---------+ +--------+
+ * | Offset | | (Offset)| | Offset |
+ * +--------+ +---------+ +--------+
+ * | | IMG_DEV_PHYADDR |
+ * | | |
+ * | | IMG_DEV_PHYADDR |
+ * +---------------------------------------------------------------------+
+ * | System Address bus |
+ * +---------------------------------------------------------------------+
+ *
+ */
+
+#define IMG_DEV_VIRTADDR_FMTSPEC "0x%010" IMG_UINT64_FMTSPECX
+#define IMG_DEVMEM_SIZE_FMTSPEC "0x%010" IMG_UINT64_FMTSPECX
+#define IMG_DEVMEM_ALIGN_FMTSPEC "0x%010" IMG_UINT64_FMTSPECX
+#define IMG_DEVMEM_OFFSET_FMTSPEC "0x%010" IMG_UINT64_FMTSPECX
+
+/* cpu physical address */
+typedef struct
+{
+#if defined(UNDER_WDDM) || defined(WINDOWS_WDF)
+ uintptr_t uiAddr;
+#define IMG_CAST_TO_CPUPHYADDR_UINT(var) (uintptr_t)(var)
+#elif defined(__linux__) && defined(__KERNEL__)
+ phys_addr_t uiAddr;
+#define IMG_CAST_TO_CPUPHYADDR_UINT(var) (phys_addr_t)(var)
+#else
+ IMG_UINT64 uiAddr;
+#define IMG_CAST_TO_CPUPHYADDR_UINT(var) (IMG_UINT64)(var)
+#endif
+} IMG_CPU_PHYADDR;
+
+/* device physical address */
+typedef struct
+{
+ IMG_UINT64 uiAddr;
+} IMG_DEV_PHYADDR;
+
+/* dma address */
+typedef struct
+{
+ IMG_UINT64 uiAddr;
+} IMG_DMA_ADDR;
+
+/*
+ rectangle structure
+*/
+typedef struct
+{
+ IMG_INT32 x0;
+ IMG_INT32 y0;
+ IMG_INT32 x1;
+ IMG_INT32 y1;
+} IMG_RECT;
+
+typedef struct
+{
+ IMG_INT16 x0;
+ IMG_INT16 y0;
+ IMG_INT16 x1;
+ IMG_INT16 y1;
+} IMG_RECT_16;
+
+/*
+ * box structure
+ */
+typedef struct
+{
+ IMG_INT32 x0;
+ IMG_INT32 y0;
+ IMG_INT32 z0;
+ IMG_INT32 x1;
+ IMG_INT32 y1;
+ IMG_INT32 z1;
+} IMG_BOX;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* IMG_TYPES_H */
+/******************************************************************************
+ End of file (img_types.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/img_types_check.h b/drivers/gpu/drm/img-rogue/img_types_check.h
new file mode 100644
index 000000000..4708583b6
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/img_types_check.h
@@ -0,0 +1,58 @@
+/*************************************************************************/ /*!
+@File
+@Title Global types for use by IMG APIs
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Performs size checks on some of the IMG types.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef IMG_TYPES_CHECK_H
+#define IMG_TYPES_CHECK_H
+
+#ifndef __KERNEL__
+#include
+#endif /* __KERNEL__ */
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+static_assert(sizeof(IMG_BOOL) == 4, "invalid size of IMG_BOOL");
+static_assert(sizeof(IMG_INT) == 4, "invalid size of IMG_INT");
+static_assert(sizeof(IMG_UINT) == 4, "invalid size of IMG_UINT");
+static_assert(sizeof(PVRSRV_ERROR) == 4, "invalid size of PVRSRV_ERROR");
+
+#endif /* IMG_TYPES_CHECK_H */
diff --git a/drivers/gpu/drm/img-rogue/include/cache_ops.h b/drivers/gpu/drm/img-rogue/include/cache_ops.h
new file mode 100644
index 000000000..a1d714519
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/cache_ops.h
@@ -0,0 +1,61 @@
+/*************************************************************************/ /*!
+@File
+@Title Services cache management header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Defines for cache management which are visible internally
+ and externally
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef CACHE_OPS_H
+#define CACHE_OPS_H
+#include "img_types.h"
+/*!
+* @Defgroup CPUCacheAPIs
+* @{
+*/
+#define CACHE_BATCH_MAX (8U)
+#define MAX_DMA_OPS (34)
+typedef IMG_UINT32 PVRSRV_CACHE_OP; /*!< Type represents cache maintenance operation */
+#define PVRSRV_CACHE_OP_NONE 0x0U /*!< No operation */
+#define PVRSRV_CACHE_OP_CLEAN 0x1U /*!< Flush w/o invalidate */
+#define PVRSRV_CACHE_OP_INVALIDATE 0x2U /*!< Invalidate w/o flush */
+#define PVRSRV_CACHE_OP_FLUSH 0x3U /*!< Flush w/ invalidate */
+/*! @} End of Defgroup CPUCacheAPIs */
+
+#endif /* CACHE_OPS_H */
diff --git a/drivers/gpu/drm/img-rogue/include/devicemem_typedefs.h b/drivers/gpu/drm/img-rogue/include/devicemem_typedefs.h
new file mode 100644
index 000000000..98ad36c91
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/devicemem_typedefs.h
@@ -0,0 +1,142 @@
+/*************************************************************************/ /*!
+@File
+@Title Device Memory Management
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Client side part of device memory management -- this file
+ is forked from new_devmem_allocation.h as this one has to
+ reside in the top level include so that client code is able
+ to make use of the typedefs.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef DEVICEMEM_TYPEDEFS_H
+#define DEVICEMEM_TYPEDEFS_H
+
+#include
+#include "img_types.h"
+#include "pvrsrv_memallocflags.h"
+
+typedef struct DEVMEM_CONTEXT_TAG DEVMEM_CONTEXT; /*!< Convenience typedef for struct DEVMEM_CONTEXT_TAG */
+typedef struct DEVMEM_HEAP_TAG DEVMEM_HEAP; /*!< Convenience typedef for struct DEVMEM_HEAP_TAG */
+typedef struct DEVMEM_MEMDESC_TAG DEVMEM_MEMDESC; /*!< Convenience typedef for struct DEVMEM_MEMDESC_TAG */
+typedef struct DEVMEM_PAGELIST_TAG DEVMEM_PAGELIST; /*!< Convenience typedef for struct DEVMEM_PAGELIST_TAG */
+
+typedef IMG_HANDLE DEVMEM_EXPORTHANDLE; /*!< Typedef for DeviceMem Export Handle */
+typedef IMG_UINT64 DEVMEM_EXPORTKEY; /*!< Typedef for DeviceMem Export Key */
+typedef IMG_DEVMEM_SIZE_T DEVMEM_SIZE_T; /*!< Typedef for DeviceMem SIZE_T */
+typedef IMG_DEVMEM_LOG2ALIGN_T DEVMEM_LOG2ALIGN_T; /*!< Typedef for DeviceMem LOG2 Alignment */
+
+typedef struct DEVMEMX_PHYS_MEMDESC_TAG DEVMEMX_PHYSDESC; /*!< Convenience typedef for DevmemX physical */
+typedef struct DEVMEMX_VIRT_MEMDESC_TAG DEVMEMX_VIRTDESC; /*!< Convenience typedef for DevmemX virtual */
+
+/*! calling code needs all the info in this struct, to be able to pass it around */
+typedef struct
+{
+ /*! A handle to the PMR. */
+ IMG_HANDLE hPMRExportHandle;
+ /*! The "key" to prove we have authorisation to use this PMR */
+ IMG_UINT64 uiPMRExportPassword;
+ /*! Size and alignment properties for this PMR. Note, these
+ numbers are not trusted in kernel, but we need to cache them
+ client-side in order to allocate from the VM arena. The kernel
+ will know the actual alignment and size of the PMR and thus
+ would prevent client code from breaching security here. Ditto
+ for physmem granularity (aka page size) if this is different
+ from alignment */
+ IMG_DEVMEM_SIZE_T uiSize;
+ /*! We call this "contiguity guarantee" to be more precise than
+ calling it "alignment" or "page size", terms which may seem
+ similar but have different emphasis. The number reported here
+ is the minimum contiguity guarantee from the creator of the
+ PMR. Now, there is no requirement to allocate that coarsely
+ from the RA. The alignment given to the RA simply needs to be
+ at least as coarse as the device page size for the heap we
+ ultimately intend to map into. What is important is that the
+ device MMU data page size is not greater than the minimum
+ contiguity guarantee from the PMR. This value is reported to
+ the client in order that it can choose to make early checks and
+ perhaps decide which heap (in a variable page size scenario) it
+ would be safe to map this PMR into. For convenience, the
+ client may choose to use this argument as the alignment of the
+ virtual range he chooses to allocate, but this is _not_
+ necessary and in many cases would be able to get away with a
+ finer alignment, should the heap into which this PMR will be
+ mapped support it. */
+ IMG_DEVMEM_LOG2ALIGN_T uiLog2ContiguityGuarantee;
+} DEVMEM_EXPORTCOOKIE;
+
+/* Enum that describes the operation associated with changing sparse memory */
+typedef IMG_UINT32 SPARSE_MEM_RESIZE_FLAGS;
+#define SPARSE_RESIZE_NONE 0U
+
+ /* This should be set to indicate the change needs allocation */
+#define SPARSE_RESIZE_ALLOC 1U
+
+ /* This should be set to indicate the change needs free */
+#define SPARSE_RESIZE_FREE 2U
+
+#define SPARSE_RESIZE_BOTH (SPARSE_RESIZE_ALLOC | SPARSE_RESIZE_FREE)
+
+ /* This should be set to silently swap underlying physical memory
+ * without disturbing its device or cpu virtual maps.
+ * This flag is not supported in the case of PDUMP and could lead to
+ * PDUMP panic when used.
+ */
+#define SPARSE_REMAP_MEM 4U
+
+ /* Should be set to get the sparse changes appear in cpu virtual map */
+#define SPARSE_MAP_CPU_ADDR 8U
+
+
+/* To be used with all the sparse allocations that gets mapped to CPU Virtual
+ * space. The sparse allocation CPU mapping is torn down and re-mapped every
+ * time the sparse allocation layout changes.
+ */
+#define PVRSRV_UNMAP_ON_SPARSE_CHANGE 1
+
+/* To use with DevmemSubAllocate() as the default factor if no over-allocation
+ * is desired.
+ */
+#define DEVMEM_NO_PRE_ALLOCATE_MULTIPLIER (1U)
+
+/* Defines the max length for PMR, MemDesc, Device memory History and RI debug
+ * annotations stored in memory, including the null terminator.
+ */
+#define DEVMEM_ANNOTATION_MAX_LEN (PVR_ANNOTATION_MAX_LEN + 1U)
+
+#endif /* #ifndef DEVICEMEM_TYPEDEFS_H */
diff --git a/drivers/gpu/drm/img-rogue/include/dllist.h b/drivers/gpu/drm/img-rogue/include/dllist.h
new file mode 100644
index 000000000..fa73dff59
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/dllist.h
@@ -0,0 +1,408 @@
+/*************************************************************************/ /*!
+@File
+@Title Double linked list header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Double linked list interface
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef DLLIST_H
+#define DLLIST_H
+
+#include "img_types.h"
+#include "img_defs.h"
+
+/*!
+ Pointer to a linked list node
+*/
+typedef struct DLLIST_NODE_ *PDLLIST_NODE;
+
+
+/*!
+ Node in a linked list
+*/
+/*
+ * Note: the following structure's size is architecture-dependent and clients
+ * may need to create a mirror of the structure definition if it needs to be
+ * used in a structure shared between host and device.
+ * Consider such clients if any changes are made to this structure.
+ */
+typedef struct DLLIST_NODE_
+{
+ struct DLLIST_NODE_ *psPrevNode;
+ struct DLLIST_NODE_ *psNextNode;
+} DLLIST_NODE;
+
+
+/*!
+ Static initialiser
+*/
+#define DECLARE_DLLIST(n) \
+DLLIST_NODE (n) = {&(n), &(n)}
+
+/*************************************************************************/ /*!
+@Function dllist_foreach_node
+
+@Description Walk through all the nodes on the list.
+ Safe against removal of (node).
+
+@Input list_head List node to start the operation
+@Input node Current list node
+@Input next Node after the current one
+
+*/
+/*****************************************************************************/
+#define dllist_foreach_node(list_head, node, next) \
+ for ((node) = (list_head)->psNextNode, (next) = (node)->psNextNode; \
+ (node) != (list_head); \
+ (node) = (next), (next) = (node)->psNextNode)
+
+#define dllist_foreach_node_backwards(list_head, node, prev) \
+ for ((node) = (list_head)->psPrevNode, (prev) = (node)->psPrevNode; \
+ (node) != (list_head); \
+ (node) = (prev), (prev) = (node)->psPrevNode)
+
+
+/*************************************************************************/ /*!
+@Function dllist_foreach
+
+@Description Simplification of dllist_foreach_node.
+ Walk through all the nodes on the list.
+ Safe against removal of currently-iterated node.
+
+ Adds utility-macro dllist_cur() to typecast the current node.
+
+@Input list_head List node to start the operation
+
+*/
+/*****************************************************************************/
+#define dllist_foreach(list_head) \
+ for (DLLIST_NODE *_DllNode = (list_head).psNextNode, *_DllNext = _DllNode->psNextNode; \
+ _DllNode != &(list_head); \
+ _DllNode = _DllNext, _DllNext = _DllNode->psNextNode)
+
+#define dllist_foreach_backwards(list_head) \
+ for (DLLIST_NODE *_DllNode = (list_head).psPrevNode, *_DllPrev = _DllNode->psPrevNode; \
+ _DllNode != &(list_head); \
+ _DllNode = _DllPrev, _DllPrev = _DllNode->psPrevNode)
+
+#define dllist_cur(type, member) IMG_CONTAINER_OF(_DllNode, type, member)
+
+/*************************************************************************/ /*!
+@Function dllist_init
+
+@Description Initialize a new double linked list
+
+@Input psListHead List head Node
+
+*/
+/*****************************************************************************/
+static INLINE
+void dllist_init(PDLLIST_NODE psListHead)
+{
+ psListHead->psPrevNode = psListHead;
+ psListHead->psNextNode = psListHead;
+}
+
+/*************************************************************************/ /*!
+@Function dllist_is_empty
+
+@Description Returns whether the list is empty
+
+@Input psListHead List head Node
+
+*/
+/*****************************************************************************/
+static INLINE
+bool dllist_is_empty(PDLLIST_NODE psListHead)
+{
+ return ((psListHead->psPrevNode == psListHead)
+ && (psListHead->psNextNode == psListHead));
+}
+
+/*************************************************************************/ /*!
+@Function dllist_add_to_head
+
+@Description Add psNewNode to head of list psListHead
+
+@Input psListHead Head Node
+@Input psNewNode New Node
+
+*/
+/*****************************************************************************/
+static INLINE
+void dllist_add_to_head(PDLLIST_NODE psListHead, PDLLIST_NODE psNewNode)
+{
+ PDLLIST_NODE psTmp;
+
+ psTmp = psListHead->psNextNode;
+
+ psListHead->psNextNode = psNewNode;
+ psNewNode->psNextNode = psTmp;
+
+ psTmp->psPrevNode = psNewNode;
+ psNewNode->psPrevNode = psListHead;
+}
+
+
+/*************************************************************************/ /*!
+@Function dllist_add_to_tail
+
+@Description Add psNewNode to tail of list psListHead
+
+@Input psListHead Head Node
+@Input psNewNode New Node
+
+*/
+/*****************************************************************************/
+static INLINE
+void dllist_add_to_tail(PDLLIST_NODE psListHead, PDLLIST_NODE psNewNode)
+{
+ PDLLIST_NODE psTmp;
+
+ psTmp = psListHead->psPrevNode;
+
+ psListHead->psPrevNode = psNewNode;
+ psNewNode->psPrevNode = psTmp;
+
+ psTmp->psNextNode = psNewNode;
+ psNewNode->psNextNode = psListHead;
+}
+
+/*************************************************************************/ /*!
+@Function dllist_node_is_in_list
+
+@Description Returns true if psNode is in a list
+
+@Input psNode List node
+
+*/
+/*****************************************************************************/
+static INLINE
+bool dllist_node_is_in_list(PDLLIST_NODE psNode)
+{
+ return (psNode->psNextNode != NULL);
+}
+
+/*************************************************************************/ /*!
+@Function dllist_get_next_node
+
+@Description Returns the list node after psListHead or NULL psListHead is
+ the only element in the list.
+
+@Input psListHead List node to start the operation
+
+*/
+/*****************************************************************************/
+static INLINE
+PDLLIST_NODE dllist_get_next_node(PDLLIST_NODE psListHead)
+{
+ if (psListHead->psNextNode == psListHead)
+ {
+ return NULL;
+ }
+ else
+ {
+ return psListHead->psNextNode;
+ }
+}
+
+/*************************************************************************/ /*!
+@Function dllist_get_prev_node
+
+@Description Returns the list node preceding psListHead or NULL if
+ psListHead is the only element in the list.
+
+@Input psListHead List node to start the operation
+
+*/
+/*****************************************************************************/
+static INLINE
+PDLLIST_NODE dllist_get_prev_node(PDLLIST_NODE psListHead)
+{
+ if (psListHead->psPrevNode == psListHead)
+ {
+ return NULL;
+ }
+ else
+ {
+ return psListHead->psPrevNode;
+ }
+}
+
+/*************************************************************************/ /*!
+@Function dllist_remove_node
+
+@Description Removes psListNode from the list where it currently belongs
+
+@Input psListNode List node to be removed
+
+*/
+/*****************************************************************************/
+static INLINE
+void dllist_remove_node(PDLLIST_NODE psListNode)
+{
+ psListNode->psNextNode->psPrevNode = psListNode->psPrevNode;
+ psListNode->psPrevNode->psNextNode = psListNode->psNextNode;
+
+ /* Clear the node to show it's not in a list */
+ psListNode->psPrevNode = NULL;
+ psListNode->psNextNode = NULL;
+}
+
+/*************************************************************************/ /*!
+@Function dllist_replace_head
+
+@Description Moves the list from psOldHead to psNewHead
+
+@Input psOldHead List node to be replaced. Will become a
+ head node of an empty list.
+@Input psNewHead List node to be inserted. Must be an
+ empty list head.
+
+*/
+/*****************************************************************************/
+static INLINE
+void dllist_replace_head(PDLLIST_NODE psOldHead, PDLLIST_NODE psNewHead)
+{
+ if (dllist_is_empty(psOldHead))
+ {
+ psNewHead->psNextNode = psNewHead;
+ psNewHead->psPrevNode = psNewHead;
+ }
+ else
+ {
+ /* Change the neighbouring nodes */
+ psOldHead->psNextNode->psPrevNode = psNewHead;
+ psOldHead->psPrevNode->psNextNode = psNewHead;
+
+ /* Copy the old data to the new node */
+ psNewHead->psNextNode = psOldHead->psNextNode;
+ psNewHead->psPrevNode = psOldHead->psPrevNode;
+
+ /* Remove links to the previous list */
+ psOldHead->psNextNode = psOldHead;
+ psOldHead->psPrevNode = psOldHead;
+ }
+}
+
+/**************************************************************************/ /*!
+@Function dllist_insert_list_at_head
+
+@Description Inserts psInHead list into the head of the psOutHead list.
+ After this operation psOutHead will contain psInHead at the
+ head of the list and the remaining elements that were
+ already in psOutHead will be places after the psInList (so
+ at a tail of the original list).
+
+@Input psOutHead List node psInHead will be inserted to.
+@Input psInHead List node to be inserted to psOutHead.
+ After this operation this becomes an empty list.
+*/ /***************************************************************************/
+static INLINE
+void dllist_insert_list_at_head(PDLLIST_NODE psOutHead, PDLLIST_NODE psInHead)
+{
+ PDLLIST_NODE psInHeadNextNode = psInHead->psNextNode;
+ PDLLIST_NODE psOutHeadNextNode = psOutHead->psNextNode;
+
+ if (!dllist_is_empty(psInHead))
+ {
+ psOutHead->psNextNode = psInHeadNextNode;
+ psInHeadNextNode->psPrevNode = psOutHead;
+
+ psInHead->psPrevNode->psNextNode = psOutHeadNextNode;
+ psOutHeadNextNode->psPrevNode = psInHead->psPrevNode;
+
+ dllist_init(psInHead);
+ }
+ }
+
+/*************************************************************************/ /*!
+@Description Pointer to a dllist comparison callback function.
+@Input psNode Pointer to a node in a dllist.
+@Input psNext Pointer to psNode's next neighbour.
+*/ /**************************************************************************/
+typedef bool (*DLLIST_CMP_CB)(const DLLIST_NODE *psNode, const DLLIST_NODE *psNext);
+
+/*************************************************************************/ /*!
+@Function dllist_sort
+
+@Description Insert-sorts the List in place
+ The cmpr function passes the current and next node,
+ From which the user writes the function responsible
+ for choosing to swap order or not.
+ The function returns true if a swap is required
+
+@Input psListHead List Head to be sorted.
+
+@Input cmpr Function pointer to use for sorting
+
+*/
+/*****************************************************************************/
+static INLINE void dllist_sort(PDLLIST_NODE psListHead,
+ DLLIST_CMP_CB cmpr)
+{
+ DLLIST_NODE *node, *next;
+ DLLIST_NODE sTempHead;
+
+ dllist_init(&sTempHead);
+
+ dllist_foreach_node(psListHead, node, next)
+ {
+ dllist_remove_node(node);
+ dllist_add_to_head(&sTempHead, node);
+ }
+
+ while (!dllist_is_empty(&sTempHead))
+ {
+ DLLIST_NODE *psSmallestNode = NULL;
+
+ dllist_foreach_node(&sTempHead, node, next)
+ {
+ if (!psSmallestNode || cmpr(psSmallestNode, node))
+ {
+ psSmallestNode = node;
+ }
+ }
+
+ dllist_remove_node(psSmallestNode);
+ dllist_add_to_tail(psListHead, psSmallestNode);
+ }
+}
+
+#endif /* DLLIST_H */
diff --git a/drivers/gpu/drm/img-rogue/include/drm/netlink.h b/drivers/gpu/drm/img-rogue/include/drm/netlink.h
new file mode 100644
index 000000000..7b0a71fba
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/drm/netlink.h
@@ -0,0 +1,147 @@
+/*
+ * @File
+ * @Title Nulldisp/Netlink interface definition
+ * @Codingstyle LinuxKernel
+ * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+ * @License Dual MIT/GPLv2
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 ("GPL") in which case the provisions
+ * of GPL are applicable instead of those above.
+ *
+ * If you wish to allow use of your version of this file only under the terms of
+ * GPL, and not to allow others to use your version of this file under the terms
+ * of the MIT license, indicate your decision by deleting the provisions above
+ * and replace them with the notice and other provisions required by GPL as set
+ * out in the file called "GPL-COPYING" included in this distribution. If you do
+ * not delete the provisions above, a recipient may use your version of this file
+ * under the terms of either the MIT license or GPL.
+ *
+ * This License is also included in this distribution in the file called
+ * "MIT-COPYING".
+ *
+ * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+ * PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef __NETLINK_H__
+#define __NETLINK_H__
+
+/* For multi-plane pixel formats */
+#define NLPVRDPY_MAX_NUM_PLANES 3
+
+enum nlpvrdpy_cmd {
+ __NLPVRDPY_CMD_INVALID,
+ NLPVRDPY_CMD_CONNECT,
+ NLPVRDPY_CMD_CONNECTED,
+ NLPVRDPY_CMD_DISCONNECT,
+ NLPVRDPY_CMD_FLIP,
+ NLPVRDPY_CMD_FLIPPED,
+ NLPVRDPY_CMD_COPY,
+ NLPVRDPY_CMD_COPIED,
+ __NLPVRDPY_CMD_MAX
+};
+#define NLPVRDPY_CMD_MAX (__NLPVRDPY_CMD_MAX - 1)
+
+enum nlpvrdpy_attr {
+ __NLPVRDPY_ATTR_INVALID,
+ NLPVRDPY_ATTR_NAME,
+ NLPVRDPY_ATTR_MINOR,
+ NLPVRDPY_ATTR_NUM_PLANES,
+ NLPVRDPY_ATTR_WIDTH,
+ NLPVRDPY_ATTR_HEIGHT,
+ NLPVRDPY_ATTR_PIXFMT,
+ NLPVRDPY_ATTR_YUV_CSC,
+ NLPVRDPY_ATTR_YUV_BPP,
+ NLPVRDPY_ATTR_PLANE0_ADDR,
+ NLPVRDPY_ATTR_PLANE0_SIZE,
+ NLPVRDPY_ATTR_PLANE0_OFFSET,
+ NLPVRDPY_ATTR_PLANE0_PITCH,
+ NLPVRDPY_ATTR_PLANE0_GEM_OBJ_NAME,
+ NLPVRDPY_ATTR_PLANE1_ADDR,
+ NLPVRDPY_ATTR_PLANE1_SIZE,
+ NLPVRDPY_ATTR_PLANE1_OFFSET,
+ NLPVRDPY_ATTR_PLANE1_PITCH,
+ NLPVRDPY_ATTR_PLANE1_GEM_OBJ_NAME,
+ NLPVRDPY_ATTR_PLANE2_ADDR,
+ NLPVRDPY_ATTR_PLANE2_SIZE,
+ NLPVRDPY_ATTR_PLANE2_OFFSET,
+ NLPVRDPY_ATTR_PLANE2_PITCH,
+ NLPVRDPY_ATTR_PLANE2_GEM_OBJ_NAME,
+ NLPVRDPY_ATTR_FB_MODIFIER,
+ NLPVRDPY_ATTR_NAMING_REQUIRED,
+ NLPVRDPY_ATTR_PAD,
+ __NLPVRDPY_ATTR_MAX
+};
+#define NLPVRDPY_ATTR_MAX (__NLPVRDPY_ATTR_MAX - 1)
+
+static struct nla_policy __attribute__((unused))
+nlpvrdpy_policy[NLPVRDPY_ATTR_MAX + 1] = {
+ [NLPVRDPY_ATTR_NAME] = { .type = NLA_STRING },
+ [NLPVRDPY_ATTR_MINOR] = { .type = NLA_U32 },
+ [NLPVRDPY_ATTR_NUM_PLANES] = { .type = NLA_U8 },
+ [NLPVRDPY_ATTR_WIDTH] = { .type = NLA_U32 },
+ [NLPVRDPY_ATTR_HEIGHT] = { .type = NLA_U32 },
+ [NLPVRDPY_ATTR_PIXFMT] = { .type = NLA_U32 },
+ [NLPVRDPY_ATTR_YUV_CSC] = { .type = NLA_U8 },
+ [NLPVRDPY_ATTR_YUV_BPP] = { .type = NLA_U8 },
+ [NLPVRDPY_ATTR_PLANE0_ADDR] = { .type = NLA_U64 },
+ [NLPVRDPY_ATTR_PLANE0_SIZE] = { .type = NLA_U64 },
+ [NLPVRDPY_ATTR_PLANE0_OFFSET] = { .type = NLA_U64 },
+ [NLPVRDPY_ATTR_PLANE0_PITCH] = { .type = NLA_U64 },
+ [NLPVRDPY_ATTR_PLANE0_GEM_OBJ_NAME] = { .type = NLA_U32 },
+ [NLPVRDPY_ATTR_PLANE1_ADDR] = { .type = NLA_U64 },
+ [NLPVRDPY_ATTR_PLANE1_SIZE] = { .type = NLA_U64 },
+ [NLPVRDPY_ATTR_PLANE1_OFFSET] = { .type = NLA_U64 },
+ [NLPVRDPY_ATTR_PLANE1_PITCH] = { .type = NLA_U64 },
+ [NLPVRDPY_ATTR_PLANE1_GEM_OBJ_NAME] = { .type = NLA_U32 },
+ [NLPVRDPY_ATTR_PLANE2_ADDR] = { .type = NLA_U64 },
+ [NLPVRDPY_ATTR_PLANE2_SIZE] = { .type = NLA_U64 },
+ [NLPVRDPY_ATTR_PLANE2_OFFSET] = { .type = NLA_U64 },
+ [NLPVRDPY_ATTR_PLANE2_PITCH] = { .type = NLA_U64 },
+ [NLPVRDPY_ATTR_PLANE2_GEM_OBJ_NAME] = { .type = NLA_U32 },
+ [NLPVRDPY_ATTR_FB_MODIFIER] = { .type = NLA_U64 },
+ [NLPVRDPY_ATTR_NAMING_REQUIRED] = { .type = NLA_FLAG },
+};
+
+#define NLPVRDPY_ATTR_PLANE(index, type) \
+ ({ \
+ enum nlpvrdpy_attr __retval; \
+ \
+ switch (index) { \
+ case 0: \
+ __retval = NLPVRDPY_ATTR_PLANE0_ ## type; \
+ break; \
+ case 1: \
+ __retval = NLPVRDPY_ATTR_PLANE1_ ## type; \
+ break; \
+ case 2: \
+ __retval = NLPVRDPY_ATTR_PLANE2_ ## type; \
+ break; \
+ default: \
+ __retval = __NLPVRDPY_ATTR_INVALID; \
+ break; \
+ }; \
+ \
+ __retval; \
+ })
+
+#endif /* __NETLINK_H__ */
diff --git a/drivers/gpu/drm/img-rogue/include/drm/nulldisp_drm.h b/drivers/gpu/drm/img-rogue/include/drm/nulldisp_drm.h
new file mode 100644
index 000000000..8403fb56f
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/drm/nulldisp_drm.h
@@ -0,0 +1,105 @@
+/*
+ * @File
+ * @Title Nulldisp DRM definitions shared between kernel and user space.
+ * @Codingstyle LinuxKernel
+ * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+ * @License Dual MIT/GPLv2
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 ("GPL") in which case the provisions
+ * of GPL are applicable instead of those above.
+ *
+ * If you wish to allow use of your version of this file only under the terms of
+ * GPL, and not to allow others to use your version of this file under the terms
+ * of the MIT license, indicate your decision by deleting the provisions above
+ * and replace them with the notice and other provisions required by GPL as set
+ * out in the file called "GPL-COPYING" included in this distribution. If you do
+ * not delete the provisions above, a recipient may use your version of this file
+ * under the terms of either the MIT license or GPL.
+ *
+ * This License is also included in this distribution in the file called
+ * "MIT-COPYING".
+ *
+ * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+ * PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#if !defined(__NULLDISP_DRM_H__)
+#define __NULLDISP_DRM_H__
+
+#if defined(__KERNEL__)
+#include
+#else
+#include
+#endif
+
+struct drm_nulldisp_gem_create {
+ __u64 size; /* in */
+ __u32 flags; /* in */
+ __u32 handle; /* out */
+};
+
+struct drm_nulldisp_gem_mmap {
+ __u32 handle; /* in */
+ __u32 pad;
+ __u64 offset; /* out */
+};
+
+#define NULLDISP_GEM_CPU_PREP_READ (1 << 0)
+#define NULLDISP_GEM_CPU_PREP_WRITE (1 << 1)
+#define NULLDISP_GEM_CPU_PREP_NOWAIT (1 << 2)
+
+struct drm_nulldisp_gem_cpu_prep {
+ __u32 handle; /* in */
+ __u32 flags; /* in */
+};
+
+struct drm_nulldisp_gem_cpu_fini {
+ __u32 handle; /* in */
+ __u32 pad;
+};
+
+/*
+ * DRM command numbers, relative to DRM_COMMAND_BASE.
+ * These defines must be prefixed with "DRM_".
+ */
+#define DRM_NULLDISP_GEM_CREATE 0x00
+#define DRM_NULLDISP_GEM_MMAP 0x01
+#define DRM_NULLDISP_GEM_CPU_PREP 0x02
+#define DRM_NULLDISP_GEM_CPU_FINI 0x03
+
+/* These defines must be prefixed with "DRM_IOCTL_". */
+#define DRM_IOCTL_NULLDISP_GEM_CREATE \
+ DRM_IOWR(DRM_COMMAND_BASE + DRM_NULLDISP_GEM_CREATE, \
+ struct drm_nulldisp_gem_create)
+
+#define DRM_IOCTL_NULLDISP_GEM_MMAP \
+ DRM_IOWR(DRM_COMMAND_BASE + DRM_NULLDISP_GEM_MMAP, \
+ struct drm_nulldisp_gem_mmap)
+
+#define DRM_IOCTL_NULLDISP_GEM_CPU_PREP \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_NULLDISP_GEM_CPU_PREP, \
+ struct drm_nulldisp_gem_cpu_prep)
+
+#define DRM_IOCTL_NULLDISP_GEM_CPU_FINI \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_NULLDISP_GEM_CPU_FINI, \
+ struct drm_nulldisp_gem_cpu_fini)
+
+#endif /* defined(__NULLDISP_DRM_H__) */
diff --git a/drivers/gpu/drm/img-rogue/include/drm/pdp_drm.h b/drivers/gpu/drm/img-rogue/include/drm/pdp_drm.h
new file mode 100644
index 000000000..f5d747d3a
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/drm/pdp_drm.h
@@ -0,0 +1,105 @@
+/*
+ * @File
+ * @Title PDP DRM definitions shared between kernel and user space.
+ * @Codingstyle LinuxKernel
+ * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+ * @License Dual MIT/GPLv2
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 ("GPL") in which case the provisions
+ * of GPL are applicable instead of those above.
+ *
+ * If you wish to allow use of your version of this file only under the terms of
+ * GPL, and not to allow others to use your version of this file under the terms
+ * of the MIT license, indicate your decision by deleting the provisions above
+ * and replace them with the notice and other provisions required by GPL as set
+ * out in the file called "GPL-COPYING" included in this distribution. If you do
+ * not delete the provisions above, a recipient may use your version of this file
+ * under the terms of either the MIT license or GPL.
+ *
+ * This License is also included in this distribution in the file called
+ * "MIT-COPYING".
+ *
+ * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+ * PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#if !defined(__PDP_DRM_H__)
+#define __PDP_DRM_H__
+
+#if defined(__KERNEL__)
+#include
+#else
+#include
+#endif
+
+struct drm_pdp_gem_create {
+ __u64 size; /* in */
+ __u32 flags; /* in */
+ __u32 handle; /* out */
+};
+
+struct drm_pdp_gem_mmap {
+ __u32 handle; /* in */
+ __u32 pad;
+ __u64 offset; /* out */
+};
+
+#define PDP_GEM_CPU_PREP_READ (1 << 0)
+#define PDP_GEM_CPU_PREP_WRITE (1 << 1)
+#define PDP_GEM_CPU_PREP_NOWAIT (1 << 2)
+
+struct drm_pdp_gem_cpu_prep {
+ __u32 handle; /* in */
+ __u32 flags; /* in */
+};
+
+struct drm_pdp_gem_cpu_fini {
+ __u32 handle; /* in */
+ __u32 pad;
+};
+
+/*
+ * DRM command numbers, relative to DRM_COMMAND_BASE.
+ * These defines must be prefixed with "DRM_".
+ */
+#define DRM_PDP_GEM_CREATE 0x00
+#define DRM_PDP_GEM_MMAP 0x01
+#define DRM_PDP_GEM_CPU_PREP 0x02
+#define DRM_PDP_GEM_CPU_FINI 0x03
+
+/* These defines must be prefixed with "DRM_IOCTL_". */
+#define DRM_IOCTL_PDP_GEM_CREATE \
+ DRM_IOWR(DRM_COMMAND_BASE + DRM_PDP_GEM_CREATE, \
+ struct drm_pdp_gem_create)
+
+#define DRM_IOCTL_PDP_GEM_MMAP\
+ DRM_IOWR(DRM_COMMAND_BASE + DRM_PDP_GEM_MMAP, \
+ struct drm_pdp_gem_mmap)
+
+#define DRM_IOCTL_PDP_GEM_CPU_PREP \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_PDP_GEM_CPU_PREP, \
+ struct drm_pdp_gem_cpu_prep)
+
+#define DRM_IOCTL_PDP_GEM_CPU_FINI \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_PDP_GEM_CPU_FINI, \
+ struct drm_pdp_gem_cpu_fini)
+
+#endif /* defined(__PDP_DRM_H__) */
diff --git a/drivers/gpu/drm/img-rogue/include/drm/pvr_drm.h b/drivers/gpu/drm/img-rogue/include/drm/pvr_drm.h
new file mode 100644
index 000000000..65c293be6
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/drm/pvr_drm.h
@@ -0,0 +1,128 @@
+/*
+ * @File
+ * @Title PVR DRM definitions shared between kernel and user space.
+ * @Codingstyle LinuxKernel
+ * @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+ * @License Dual MIT/GPLv2
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 ("GPL") in which case the provisions
+ * of GPL are applicable instead of those above.
+ *
+ * If you wish to allow use of your version of this file only under the terms of
+ * GPL, and not to allow others to use your version of this file under the terms
+ * of the MIT license, indicate your decision by deleting the provisions above
+ * and replace them with the notice and other provisions required by GPL as set
+ * out in the file called "GPL-COPYING" included in this distribution. If you do
+ * not delete the provisions above, a recipient may use your version of this file
+ * under the terms of either the MIT license or GPL.
+ *
+ * This License is also included in this distribution in the file called
+ * "MIT-COPYING".
+ *
+ * EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+ * PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#if !defined(__PVR_DRM_H__)
+#define __PVR_DRM_H__
+
+#include
+
+#if defined(__KERNEL__)
+#include
+#else
+#include
+#endif
+
+/*
+ * IMPORTANT:
+ * All structures below are designed to be the same size when compiled for 32
+ * and/or 64 bit architectures, i.e. there should be no compiler inserted
+ * padding. This is achieved by sticking to the following rules:
+ * 1) only use fixed width types
+ * 2) always naturally align fields by arranging them appropriately and by using
+ * padding fields when necessary
+ *
+ * These rules should _always_ be followed when modifying or adding new
+ * structures to this file.
+ */
+
+struct drm_pvr_srvkm_cmd {
+ __u32 bridge_id;
+ __u32 bridge_func_id;
+ __u64 in_data_ptr;
+ __u64 out_data_ptr;
+ __u32 in_data_size;
+ __u32 out_data_size;
+};
+
+struct pvr_sync_rename_ioctl_data {
+ char szName[32];
+};
+
+struct pvr_sw_sync_create_fence_data {
+ char name[32];
+ __s32 fence;
+ __u32 pad;
+ __u64 sync_pt_idx;
+};
+
+struct pvr_sw_timeline_advance_data {
+ __u64 sync_pt_idx;
+};
+
+/*
+ * DRM command numbers, relative to DRM_COMMAND_BASE.
+ * These defines must be prefixed with "DRM_".
+ */
+
+/* PVR Services command */
+#define DRM_PVR_SRVKM_CMD 0
+
+/* PVR Sync commands */
+#define DRM_PVR_SYNC_RENAME_CMD 1
+#define DRM_PVR_SYNC_FORCE_SW_ONLY_CMD 2
+
+/* PVR Software Sync commands */
+#define DRM_PVR_SW_SYNC_CREATE_FENCE_CMD 3
+#define DRM_PVR_SW_SYNC_INC_CMD 4
+
+/* These defines must be prefixed with "DRM_IOCTL_". */
+#define DRM_IOCTL_PVR_SRVKM_CMD \
+ DRM_IOWR(DRM_COMMAND_BASE + DRM_PVR_SRVKM_CMD, \
+ struct drm_pvr_srvkm_cmd)
+
+#define DRM_IOCTL_PVR_SYNC_RENAME_CMD \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_PVR_SYNC_RENAME_CMD, \
+ struct pvr_sync_rename_ioctl_data)
+
+#define DRM_IOCTL_PVR_SYNC_FORCE_SW_ONLY_CMD \
+ DRM_IO(DRM_COMMAND_BASE + DRM_PVR_SYNC_FORCE_SW_ONLY_CMD)
+
+#define DRM_IOCTL_PVR_SW_SYNC_CREATE_FENCE_CMD \
+ DRM_IOWR(DRM_COMMAND_BASE + DRM_PVR_SW_SYNC_CREATE_FENCE_CMD, \
+ struct pvr_sw_sync_create_fence_data)
+
+#define DRM_IOCTL_PVR_SW_SYNC_INC_CMD \
+ DRM_IOR(DRM_COMMAND_BASE + DRM_PVR_SW_SYNC_INC_CMD, \
+ struct pvr_sw_timeline_advance_data)
+
+#endif /* defined(__PVR_DRM_H__) */
diff --git a/drivers/gpu/drm/img-rogue/include/img_3dtypes.h b/drivers/gpu/drm/img-rogue/include/img_3dtypes.h
new file mode 100644
index 000000000..916e3a1ee
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/img_3dtypes.h
@@ -0,0 +1,248 @@
+/*************************************************************************/ /*!
+@File
+@Title Global 3D types for use by IMG APIs
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Defines 3D types for use by IMG APIs
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef IMG_3DTYPES_H
+#define IMG_3DTYPES_H
+
+#include
+#include "img_types.h"
+#include "img_defs.h"
+
+/**
+ * Comparison functions
+ * This comparison function is defined as:
+ * A {CmpFunc} B
+ * A is a reference value, e.g., incoming depth etc.
+ * B is the sample value, e.g., value in depth buffer.
+ */
+typedef enum _IMG_COMPFUNC_
+{
+ IMG_COMPFUNC_NEVER, /**< The comparison never succeeds */
+ IMG_COMPFUNC_LESS, /**< The comparison is a less-than operation */
+ IMG_COMPFUNC_EQUAL, /**< The comparison is an equal-to operation */
+ IMG_COMPFUNC_LESS_EQUAL, /**< The comparison is a less-than or equal-to
+ operation */
+ IMG_COMPFUNC_GREATER, /**< The comparison is a greater-than operation
+ */
+ IMG_COMPFUNC_NOT_EQUAL, /**< The comparison is a no-equal-to operation
+ */
+ IMG_COMPFUNC_GREATER_EQUAL, /**< The comparison is a greater-than or
+ equal-to operation */
+ IMG_COMPFUNC_ALWAYS, /**< The comparison always succeeds */
+} IMG_COMPFUNC;
+
+/**
+ * Stencil op functions
+ */
+typedef enum _IMG_STENCILOP_
+{
+ IMG_STENCILOP_KEEP, /**< Keep original value */
+ IMG_STENCILOP_ZERO, /**< Set stencil to 0 */
+ IMG_STENCILOP_REPLACE, /**< Replace stencil entry */
+ IMG_STENCILOP_INCR_SAT, /**< Increment stencil entry, clamping to max */
+ IMG_STENCILOP_DECR_SAT, /**< Decrement stencil entry, clamping to zero */
+ IMG_STENCILOP_INVERT, /**< Invert bits in stencil entry */
+ IMG_STENCILOP_INCR, /**< Increment stencil entry,
+ wrapping if necessary */
+ IMG_STENCILOP_DECR, /**< Decrement stencil entry,
+ wrapping if necessary */
+} IMG_STENCILOP;
+
+/**
+ * Alpha blending allows colours and textures on one surface
+ * to be blended with transparency onto another surface.
+ * These definitions apply to both source and destination blending
+ * states
+ */
+typedef enum _IMG_BLEND_
+{
+ IMG_BLEND_ZERO = 0, /**< Blend factor is (0,0,0,0) */
+ IMG_BLEND_ONE, /**< Blend factor is (1,1,1,1) */
+ IMG_BLEND_SRC_COLOUR, /**< Blend factor is the source colour */
+ IMG_BLEND_INV_SRC_COLOUR, /**< Blend factor is the inverted source colour
+ (i.e. 1-src_col) */
+ IMG_BLEND_SRC_ALPHA, /**< Blend factor is the source alpha */
+ IMG_BLEND_INV_SRC_ALPHA, /**< Blend factor is the inverted source alpha
+ (i.e. 1-src_alpha) */
+ IMG_BLEND_DEST_ALPHA, /**< Blend factor is the destination alpha */
+ IMG_BLEND_INV_DEST_ALPHA, /**< Blend factor is the inverted destination
+ alpha */
+ IMG_BLEND_DEST_COLOUR, /**< Blend factor is the destination colour */
+ IMG_BLEND_INV_DEST_COLOUR, /**< Blend factor is the inverted destination
+ colour */
+ IMG_BLEND_SRC_ALPHASAT, /**< Blend factor is the alpha saturation (the
+ minimum of (Src alpha,
+ 1 - destination alpha)) */
+ IMG_BLEND_BLEND_FACTOR, /**< Blend factor is a constant */
+ IMG_BLEND_INVBLEND_FACTOR, /**< Blend factor is a constant (inverted)*/
+ IMG_BLEND_SRC1_COLOUR, /**< Blend factor is the colour outputted from
+ the pixel shader */
+ IMG_BLEND_INV_SRC1_COLOUR, /**< Blend factor is the inverted colour
+ outputted from the pixel shader */
+ IMG_BLEND_SRC1_ALPHA, /**< Blend factor is the alpha outputted from
+ the pixel shader */
+ IMG_BLEND_INV_SRC1_ALPHA /**< Blend factor is the inverted alpha
+ outputted from the pixel shader */
+} IMG_BLEND;
+
+/**
+ * The arithmetic operation to perform when blending
+ */
+typedef enum _IMG_BLENDOP_
+{
+ IMG_BLENDOP_ADD = 0, /**< Result = (Source + Destination) */
+ IMG_BLENDOP_SUBTRACT, /**< Result = (Source - Destination) */
+ IMG_BLENDOP_REV_SUBTRACT, /**< Result = (Destination - Source) */
+ IMG_BLENDOP_MIN, /**< Result = min (Source, Destination) */
+ IMG_BLENDOP_MAX /**< Result = max (Source, Destination) */
+} IMG_BLENDOP;
+
+/**
+ * Logical operation to perform when logic ops are enabled
+ */
+typedef enum _IMG_LOGICOP_
+{
+ IMG_LOGICOP_CLEAR = 0, /**< Result = 0 */
+ IMG_LOGICOP_SET, /**< Result = -1 */
+ IMG_LOGICOP_COPY, /**< Result = Source */
+ IMG_LOGICOP_COPY_INVERTED, /**< Result = ~Source */
+ IMG_LOGICOP_NOOP, /**< Result = Destination */
+ IMG_LOGICOP_INVERT, /**< Result = ~Destination */
+ IMG_LOGICOP_AND, /**< Result = Source & Destination */
+ IMG_LOGICOP_NAND, /**< Result = ~(Source & Destination) */
+ IMG_LOGICOP_OR, /**< Result = Source | Destination */
+ IMG_LOGICOP_NOR, /**< Result = ~(Source | Destination) */
+ IMG_LOGICOP_XOR, /**< Result = Source ^ Destination */
+ IMG_LOGICOP_EQUIV, /**< Result = ~(Source ^ Destination) */
+ IMG_LOGICOP_AND_REVERSE, /**< Result = Source & ~Destination */
+ IMG_LOGICOP_AND_INVERTED, /**< Result = ~Source & Destination */
+ IMG_LOGICOP_OR_REVERSE, /**< Result = Source | ~Destination */
+ IMG_LOGICOP_OR_INVERTED /**< Result = ~Source | Destination */
+} IMG_LOGICOP;
+
+/**
+ * Type of fog blending supported
+ */
+typedef enum _IMG_FOGMODE_
+{
+ IMG_FOGMODE_NONE, /**< No fog blending - fog calculations are
+ * based on the value output from the vertex phase */
+ IMG_FOGMODE_LINEAR, /**< Linear interpolation */
+ IMG_FOGMODE_EXP, /**< Exponential */
+ IMG_FOGMODE_EXP2, /**< Exponential squaring */
+} IMG_FOGMODE;
+
+/**
+ * Types of filtering
+ */
+typedef enum _IMG_FILTER_
+{
+ IMG_FILTER_DONTCARE, /**< Any filtering mode is acceptable */
+ IMG_FILTER_POINT, /**< Point filtering */
+ IMG_FILTER_LINEAR, /**< Bi-linear filtering */
+ IMG_FILTER_BICUBIC, /**< Bi-cubic filtering */
+} IMG_FILTER;
+
+/**
+ * Addressing modes for textures
+ */
+typedef enum _IMG_ADDRESSMODE_
+{
+ IMG_ADDRESSMODE_REPEAT, /**< Texture repeats continuously */
+ IMG_ADDRESSMODE_FLIP, /**< Texture flips on odd integer part */
+ IMG_ADDRESSMODE_CLAMP, /**< Texture clamped at 0 or 1 */
+ IMG_ADDRESSMODE_FLIPCLAMP, /**< Flipped once, then clamp */
+ IMG_ADDRESSMODE_CLAMPBORDER,
+ IMG_ADDRESSMODE_OGL_CLAMP,
+ IMG_ADDRESSMODE_OVG_TILEFILL,
+ IMG_ADDRESSMODE_DONTCARE,
+} IMG_ADDRESSMODE;
+
+/**
+ * Culling based on winding order of triangle.
+ */
+typedef enum _IMG_CULLMODE_
+{
+ IMG_CULLMODE_NONE, /**< Don't cull */
+ IMG_CULLMODE_FRONTFACING, /**< Front facing triangles */
+ IMG_CULLMODE_BACKFACING, /**< Back facing triangles */
+} IMG_CULLMODE;
+
+/**
+ * Colour for clearing surfaces.
+ * The four elements of the 4 x 32 bit array will map to colour
+ * R,G,B,A components, in order.
+ * For YUV colour space the order is Y,U,V.
+ * For Depth and Stencil formats D maps to R and S maps to G.
+ */
+typedef union IMG_CLEAR_COLOUR_TAG {
+ IMG_UINT32 aui32[4];
+ IMG_INT32 ai32[4];
+ IMG_FLOAT af32[4];
+} IMG_CLEAR_COLOUR;
+
+static_assert(sizeof(IMG_FLOAT) == sizeof(IMG_INT32), "Size of IMG_FLOAT is not 32 bits.");
+
+/*! ************************************************************************//**
+@brief Specifies the MSAA resolve operation.
+*/ /**************************************************************************/
+typedef enum _IMG_RESOLVE_OP_
+{
+ IMG_RESOLVE_BLEND = 0, /*!< box filter on the samples */
+ IMG_RESOLVE_MIN = 1, /*!< minimum of the samples */
+ IMG_RESOLVE_MAX = 2, /*!< maximum of the samples */
+ IMG_RESOLVE_SAMPLE0 = 3, /*!< choose sample 0 */
+ IMG_RESOLVE_SAMPLE1 = 4, /*!< choose sample 1 */
+ IMG_RESOLVE_SAMPLE2 = 5, /*!< choose sample 2 */
+ IMG_RESOLVE_SAMPLE3 = 6, /*!< choose sample 3 */
+ IMG_RESOLVE_SAMPLE4 = 7, /*!< choose sample 4 */
+ IMG_RESOLVE_SAMPLE5 = 8, /*!< choose sample 5 */
+ IMG_RESOLVE_SAMPLE6 = 9, /*!< choose sample 6 */
+ IMG_RESOLVE_SAMPLE7 = 10, /*!< choose sample 7 */
+} IMG_RESOLVE_OP;
+
+
+#endif /* IMG_3DTYPES_H */
+/******************************************************************************
+ End of file (img_3dtypes.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/img_defs.h b/drivers/gpu/drm/img-rogue/include/img_defs.h
new file mode 100644
index 000000000..294d05b0d
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/img_defs.h
@@ -0,0 +1,565 @@
+/*************************************************************************/ /*!
+@File
+@Title Common header containing type definitions for portability
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Contains variable and structure definitions. Any platform
+ specific types should be defined in this file.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef IMG_DEFS_H
+#define IMG_DEFS_H
+
+#if defined(__linux__) && defined(__KERNEL__)
+#include
+#else
+#include
+#endif
+#if !(defined(__linux__) && defined(__KERNEL__))
+#include
+#endif
+
+#include "img_types.h"
+
+#if defined(NO_INLINE_FUNCS)
+ #define INLINE
+ #define FORCE_INLINE
+#else
+#if defined(__cplusplus) || defined(INTEGRITY_OS)
+ #if !defined(INLINE)
+ #define INLINE inline
+ #endif
+ #define FORCE_INLINE static inline
+#else
+#if !defined(INLINE)
+ #define INLINE __inline
+#endif
+#if (defined(UNDER_WDDM) || defined(WINDOWS_WDF)) && defined(_X86_)
+ #define FORCE_INLINE __forceinline
+#else
+ #define FORCE_INLINE static __inline
+#endif
+#endif
+#endif
+
+/* True if the GCC version is at least the given version. False for older
+ * versions of GCC, or other compilers.
+ */
+#if defined(__GNUC__)
+#define GCC_VERSION_AT_LEAST(major, minor) \
+ (__GNUC__ > (major) || \
+ (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
+#else
+#define GCC_VERSION_AT_LEAST(major, minor) 0
+#endif
+
+/* Use Clang's __has_extension and __has_builtin macros if available. */
+#if defined(__has_extension)
+#define has_clang_extension(e) __has_extension(e)
+#else
+#define has_clang_extension(e) 0
+#endif
+
+#if defined(__has_builtin)
+#define has_clang_builtin(e) __has_builtin(e)
+#else
+#define has_clang_builtin(e) 0
+#endif
+
+/* Use this in any file, or use attributes under GCC - see below */
+#ifndef PVR_UNREFERENCED_PARAMETER
+#define PVR_UNREFERENCED_PARAMETER(param) ((void)(param))
+#endif
+
+/* static_assert(condition, "message to print if it fails");
+ *
+ * Assert something at compile time. If the assertion fails, try to print
+ * the message, otherwise do nothing. static_assert is available if:
+ *
+ * - It's already defined as a macro (e.g. by in C11)
+ * - We're using MSVC which exposes static_assert unconditionally
+ * - We're using a C++ compiler that supports C++11
+ * - We're using GCC 4.6 and up in C mode (in which case it's available as
+ * _Static_assert)
+ *
+ * In all other cases, fall back to an equivalent that makes an invalid
+ * declaration.
+ */
+#if !defined(static_assert) && !defined(_MSC_VER) && \
+ (!defined(__cplusplus) || __cplusplus < 201103L) || defined(__KLOCWORK__)
+ /* static_assert isn't already available */
+ #if !defined(__cplusplus) && (GCC_VERSION_AT_LEAST(4, 6) || \
+ (defined(__clang__) && has_clang_extension(c_static_assert)))
+ #define static_assert _Static_assert
+ #else
+ #define static_assert(expr, message) \
+ extern int static_assert_failed[(expr) ? 1 : -1] __attribute__((unused))
+ #endif
+#endif
+
+/*
+ * unreachable("explanation") can be used to indicate to the compiler that
+ * some parts of the code can never be reached, like the default branch
+ * of a switch that covers all real-world possibilities, even though there
+ * are other ints that exist for instance.
+ *
+ * The message will be printed as an assert() when debugging.
+ *
+ * Note: there is no need to add a 'return' or any error handling after
+ * calling unreachable(), as this call will never return.
+ */
+#if defined(__linux__) && defined(__KERNEL__)
+/* Kernel has its own unreachable(), which is a simple infinite loop */
+#elif GCC_VERSION_AT_LEAST(4, 5) || has_clang_builtin(__builtin_unreachable)
+ #define unreachable(msg) \
+ do { \
+ assert(!(msg)); \
+ __builtin_unreachable(); \
+ } while (0)
+#elif defined(_MSC_VER)
+ #define unreachable(msg) \
+ do { \
+ assert(!(msg)); \
+ __assume(0); \
+ } while (0)
+#else
+ #define unreachable(msg) \
+ do { \
+ assert(!(msg)); \
+ while (1); \
+ } while (0)
+#endif
+
+/*
+ * assume(x > 2 && x <= 7) works like an assert(), except it hints to the
+ * compiler what it can assume to optimise the code, like a limited range
+ * of parameter values.
+ */
+#if has_clang_builtin(__builtin_assume)
+ #define assume(expr) \
+ do { \
+ assert(expr); \
+ __builtin_assume(expr); \
+ } while (0)
+#elif defined(_MSC_VER)
+ #define assume(expr) \
+ do { \
+ assert(expr); \
+ __assume(expr); \
+ } while (0)
+#elif defined(__linux__) && defined(__KERNEL__)
+ #define assume(expr) ((void)(expr))
+#elif GCC_VERSION_AT_LEAST(4, 5) || has_clang_builtin(__builtin_unreachable)
+ #define assume(expr) \
+ do { \
+ if (unlikely(!(expr))) \
+ unreachable("Assumption isn't true: " # expr); \
+ } while (0)
+#else
+ #define assume(expr) assert(expr)
+#endif
+
+/*! Macro to calculate the n-byte aligned value from that supplied rounding up.
+ * n must be a power of two.
+ *
+ * Both arguments should be of a type with the same size otherwise the macro may
+ * cut off digits, e.g. imagine a 64 bit address in _x and a 32 bit value in _n.
+ */
+#define PVR_ALIGN(_x, _n) (((_x)+((_n)-1U)) & ~((_n)-1U))
+
+#if defined(_WIN32)
+
+#if defined(WINDOWS_WDF)
+
+ /*
+ * For WINDOWS_WDF drivers we don't want these defines to overwrite calling conventions propagated through the build system.
+ * This 'empty' choice helps to resolve all the calling conv issues.
+ *
+ */
+ #define IMG_CALLCONV
+ #define C_CALLCONV
+
+ #define IMG_INTERNAL
+ #define IMG_RESTRICT __restrict
+
+ /*
+ * The proper way of dll linking under MS compilers is made of two things:
+ * - decorate implementation with __declspec(dllexport)
+ * this decoration helps compiler with making the so called
+ * 'export library'
+ * - decorate forward-declaration (in a source dependent on a dll) with
+ * __declspec(dllimport), this decoration helps the compiler to make
+ * faster and smaller code in terms of calling dll-imported functions
+ *
+ * Usually these decorations are performed by having a single macro define
+ * making that expands to a proper __declspec() depending on the
+ * translation unit, dllexport inside the dll source and dllimport outside
+ * the dll source. Having IMG_EXPORT and IMG_IMPORT resolving to the same
+ * __declspec() makes no sense, but at least works.
+ */
+ #define IMG_IMPORT __declspec(dllexport)
+ #define IMG_EXPORT __declspec(dllexport)
+
+#else
+
+ #define IMG_CALLCONV __stdcall
+ #define IMG_INTERNAL
+ #define IMG_EXPORT __declspec(dllexport)
+ #define IMG_RESTRICT __restrict
+ #define C_CALLCONV __cdecl
+
+ /*
+ * IMG_IMPORT is defined as IMG_EXPORT so that headers and implementations
+ * match. Some compilers require the header to be declared IMPORT, while
+ * the implementation is declared EXPORT.
+ */
+ #define IMG_IMPORT IMG_EXPORT
+
+#endif
+
+#if defined(UNDER_WDDM)
+ #ifndef _INC_STDLIB
+ #if defined(__mips)
+ /* do nothing */
+ #elif defined(UNDER_MSBUILD)
+ /* do nothing */
+ #else
+ _CRTIMP void __cdecl abort(void);
+ #endif
+ #endif
+#endif /* UNDER_WDDM */
+#else
+ #if (defined(__linux__) || defined(__QNXNTO__)) && defined(__KERNEL__)
+ #define IMG_INTERNAL
+ #define IMG_EXPORT
+ #define IMG_CALLCONV
+ #elif defined(__linux__) || defined(__METAG) || defined(__mips) || defined(__QNXNTO__) || defined(__riscv)
+ #define IMG_CALLCONV
+ #define C_CALLCONV
+
+ #if defined(__METAG)
+ #define IMG_INTERNAL
+ #else
+ #define IMG_INTERNAL __attribute__((visibility("hidden")))
+ #endif
+
+ #define IMG_EXPORT __attribute__((visibility("default")))
+ #define IMG_RESTRICT __restrict__
+ #elif defined(INTEGRITY_OS)
+ #define IMG_CALLCONV
+ #define IMG_INTERNAL
+ #define IMG_EXPORT
+ #define IMG_RESTRICT
+ #define C_CALLCONV
+ #define __cdecl
+
+ #ifndef USE_CODE
+ #define IMG_ABORT() printf("IMG_ABORT was called.\n")
+ #endif
+ #else
+ #error("define an OS")
+ #endif
+
+#endif
+
+/* Use default definition if not overridden */
+#ifndef IMG_ABORT
+ #if defined(EXIT_ON_ABORT)
+ #define IMG_ABORT() exit(1)
+ #else
+ #define IMG_ABORT() abort()
+ #endif
+#endif
+
+/* The best way to suppress unused parameter warnings using GCC is to use a
+ * variable attribute. Place the __maybe_unused between the type and name of an
+ * unused parameter in a function parameter list e.g. 'int __maybe_unused var'.
+ * This should only be used in GCC build environments, for example, in files
+ * that compile only on Linux.
+ * Other files should use PVR_UNREFERENCED_PARAMETER
+ */
+
+/* Kernel macros for compiler attributes */
+/* Note: param positions start at 1 */
+#if defined(__linux__) && defined(__KERNEL__)
+ #include
+
+ #if !defined(__fallthrough)
+ #if GCC_VERSION_AT_LEAST(7, 0)
+ #define __fallthrough __attribute__((__fallthrough__))
+ #else
+ #define __fallthrough
+ #endif
+ #endif
+#elif defined(__GNUC__) || defined(HAS_GNUC_ATTRIBUTES)
+ #define __must_check __attribute__((warn_unused_result))
+ #define __maybe_unused __attribute__((unused))
+ #define __malloc __attribute__((malloc))
+
+ /* Bionic's might have defined these already */
+ /* See https://android.googlesource.com/platform/bionic.git/+/master/libc/include/sys/cdefs.h */
+ #if !defined(__packed)
+ #define __packed __attribute__((packed))
+ #endif
+ #if !defined(__aligned)
+ #define __aligned(n) __attribute__((aligned(n)))
+ #endif
+ #if !defined(__noreturn)
+ #define __noreturn __attribute__((noreturn))
+ #endif
+
+ /* That one compiler that supports attributes but doesn't support
+ * the printf attribute... */
+ #if defined(__GNUC__)
+ #define __printf(fmt, va) __attribute__((format(printf, (fmt), (va))))
+ #else
+ #define __printf(fmt, va)
+ #endif /* defined(__GNUC__) */
+
+ #if defined(__cplusplus) && (__cplusplus >= 201703L)
+ #define __fallthrough [[fallthrough]]
+ #elif GCC_VERSION_AT_LEAST(7, 0)
+ #define __fallthrough __attribute__((__fallthrough__))
+ #else
+ #define __fallthrough
+ #endif
+
+ #define __user
+ #define __force
+ #define __iomem
+#else
+ /* Silently ignore those attributes */
+ #define __printf(fmt, va)
+ #define __packed
+ #define __aligned(n)
+ #define __must_check
+ #define __maybe_unused
+ #define __malloc
+
+ #if defined(_MSC_VER) || defined(CC_ARM)
+ #define __noreturn __declspec(noreturn)
+ #else
+ #define __noreturn
+ #endif
+
+ /* This may already been defined, e.g. by SAL (Source Annotation Language) */
+ #if !defined(__fallthrough)
+ #define __fallthrough
+ #endif
+
+ #define __user
+ #define __force
+ #define __iomem
+#endif
+
+
+/* Other attributes, following the same style */
+#if defined(__GNUC__) || defined(HAS_GNUC_ATTRIBUTES)
+ #define __const_function __attribute__((const))
+#else
+ #define __const_function
+#endif
+
+
+/* GCC builtins */
+#if defined(__linux__) && defined(__KERNEL__)
+ #include
+#elif defined(__GNUC__) || defined(INTEGRITY_OS)
+
+/* Klocwork does not support __builtin_expect, which makes the actual condition
+ * expressions hidden during analysis, affecting it negatively. */
+#if !defined(__KLOCWORK__) && !defined(INTEGRITY_OS) && !defined(DEBUG)
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+#endif
+
+ /* Compiler memory barrier to prevent reordering */
+ #define barrier() __asm__ __volatile__("": : :"memory")
+#else
+ #define barrier() static_assert(0, "barrier() isn't supported by your compiler");
+#endif
+
+/* That one OS that defines one but not the other... */
+#ifndef likely
+ #define likely(x) (x)
+#endif
+#ifndef unlikely
+ #define unlikely(x) (x)
+#endif
+
+/* These two macros are also provided by the kernel */
+#ifndef BIT
+#define BIT(b) (1UL << (b))
+#endif
+
+#ifndef BIT_ULL
+#define BIT_ULL(b) (1ULL << (b))
+#endif
+
+#define BIT_SET(f, b) BITMASK_SET((f), BIT(b))
+#define BIT_UNSET(f, b) BITMASK_UNSET((f), BIT(b))
+#define BIT_TOGGLE(f, b) BITMASK_TOGGLE((f), BIT(b))
+#define BIT_ISSET(f, b) BITMASK_HAS((f), BIT(b))
+
+#define BITMASK_SET(f, m) do { ((f) |= (m)); } while (false)
+#define BITMASK_UNSET(f, m) do { ((f) &= ~(m)); } while (false)
+#define BITMASK_TOGGLE(f, m) do { ((f) ^= (m)); } while (false)
+#define BITMASK_HAS(f, m) (((f) & (m)) == (m)) /* the bits from the mask are all set */
+#define BITMASK_ANY(f, m) (((f) & (m)) != 0U) /* any bit from the mask is set */
+
+#ifndef MAX
+#define MAX(a ,b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef CLAMP
+#define CLAMP(min, max, n) ((n) < (min) ? (min) : ((n) > (max) ? (max) : (n)))
+#endif
+
+#define SWAP(X, Y) (X) ^= (Y); (Y) ^= (X); (X) ^= (Y);
+
+
+#if defined(__linux__) && defined(__KERNEL__)
+ #include
+ #include
+#endif
+
+/* Get a structure's address from the address of a member */
+#define IMG_CONTAINER_OF(ptr, type, member) \
+ (type *) ((uintptr_t) (ptr) - offsetof(type, member))
+
+/* Get a new pointer with an offset (in bytes) from a base address, useful
+ * when traversing byte buffers and accessing data in buffers through struct
+ * pointers.
+ * Note, this macro is not equivalent to or replacing offsetof() */
+#define IMG_OFFSET_ADDR(addr, offset_in_bytes) \
+ (void*)&(((IMG_UINT8*)(void*)(addr))[offset_in_bytes])
+
+/* Get a new pointer with an offset (in dwords) from a base address, useful
+ * when traversing byte buffers and accessing data in buffers through struct
+ * pointers.
+ * Note, this macro is not equivalent to or replacing offsetof() */
+#define IMG_OFFSET_ADDR_DW(addr, offset_in_dwords) \
+ (void*)(((IMG_UINT32*)(void*)(addr)) + (offset_in_dwords))
+
+/* The number of elements in a fixed-sized array */
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(ARR) (sizeof(ARR) / sizeof((ARR)[0]))
+#endif
+
+/* To guarantee that __func__ can be used, define it as a macro here if it
+ isn't already provided by the compiler. */
+#if defined(_MSC_VER) || (defined(__cplusplus) && __cplusplus < 201103L)
+#define __func__ __FUNCTION__
+#endif
+
+#if defined(__cplusplus)
+/* C++ Specific:
+ * Disallow use of copy and assignment operator within a class.
+ * Should be placed under private. */
+#define IMG_DISALLOW_COPY_AND_ASSIGN(C) \
+ C(const C&); \
+ void operator=(const C&)
+#endif
+
+#if defined(SUPPORT_PVR_VALGRIND) && !defined(__METAG) && !defined(__mips) && !defined(__riscv)
+ #include "/usr/include/valgrind/memcheck.h"
+
+ #define VG_MARK_INITIALIZED(pvData,ui32Size) VALGRIND_MAKE_MEM_DEFINED(pvData,ui32Size)
+ #define VG_MARK_NOACCESS(pvData,ui32Size) VALGRIND_MAKE_MEM_NOACCESS(pvData,ui32Size)
+ #define VG_MARK_ACCESS(pvData,ui32Size) VALGRIND_MAKE_MEM_UNDEFINED(pvData,ui32Size)
+#else
+ #if defined(_MSC_VER)
+ # define PVR_MSC_SUPPRESS_4127 __pragma(warning(suppress:4127))
+ #else
+ # define PVR_MSC_SUPPRESS_4127
+ #endif
+
+ #define VG_MARK_INITIALIZED(pvData,ui32Size) PVR_MSC_SUPPRESS_4127 do { } while (0)
+ #define VG_MARK_NOACCESS(pvData,ui32Size) PVR_MSC_SUPPRESS_4127 do { } while (0)
+ #define VG_MARK_ACCESS(pvData,ui32Size) PVR_MSC_SUPPRESS_4127 do { } while (0)
+#endif
+
+#define IMG_STRINGIFY_IMPL(x) # x
+#define IMG_STRINGIFY(x) IMG_STRINGIFY_IMPL(x)
+
+#if defined(INTEGRITY_OS)
+ /* Definitions not present in INTEGRITY. */
+ #define PATH_MAX 200
+#endif
+
+#if defined(__clang__) || defined(__GNUC__)
+ /* __SIZEOF_POINTER__ is defined already by these compilers */
+#elif defined(INTEGRITY_OS)
+ #if defined(__Ptr_Is_64)
+ #define __SIZEOF_POINTER__ 8
+ #else
+ #define __SIZEOF_POINTER__ 4
+ #endif
+#elif defined(_WIN32)
+ #define __SIZEOF_POINTER__ sizeof(char *)
+#else
+ #warning Unknown OS - using default method to determine whether CPU arch is 64-bit.
+ #define __SIZEOF_POINTER__ sizeof(char *)
+#endif
+
+/* RDI8567: gcc/clang/llvm load/store optimisations may cause issues with
+ * uncached device memory allocations. Some pointers are made 'volatile'
+ * to prevent those optimisations being applied to writes through those
+ * pointers.
+ */
+#if (GCC_VERSION_AT_LEAST(7, 0) || defined(__clang__)) && (defined(__arm64__) || defined(__aarch64__))
+#define NOLDSTOPT volatile
+/* after applying 'volatile' to a pointer, we may need to cast it to 'void *'
+ * to keep it compatible with its existing uses.
+ */
+#define NOLDSTOPT_VOID (void *)
+
+#define NOLDSTOPT_REQUIRED 1
+#else
+#define NOLDSTOPT
+#define NOLDSTOPT_VOID
+#endif
+
+#endif /* IMG_DEFS_H */
+/*****************************************************************************
+ End of file (img_defs.h)
+*****************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/img_drm_fourcc_internal.h b/drivers/gpu/drm/img-rogue/include/img_drm_fourcc_internal.h
new file mode 100644
index 000000000..162a646af
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/img_drm_fourcc_internal.h
@@ -0,0 +1,94 @@
+/*************************************************************************/ /*!
+@File
+@Title Wrapper around drm_fourcc.h
+@Description FourCCs and the DRM framebuffer modifiers should be added here
+ unless they are used by kernel code or a known user outside of
+ the DDK. If FourCCs or DRM framebuffer modifiers are required
+ outside of the DDK, they shall be moved to the corresponding
+ public header.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef IMG_DRM_FOURCC_INTERNAL_H
+#define IMG_DRM_FOURCC_INTERNAL_H
+
+#include
+
+/*
+ * Modifier names are structured using the following convention,
+ * with underscores (_) between items:
+ * - prefix: DRM_FORMAT_MOD
+ * - identifier for our driver: PVR
+ * - category: FBCDC
+ * - compression tile dimension: 8x8, 16x4, 32x2
+ * - FBDC version: V0, V1, V2, V3, V7, V8, V10, V12
+ */
+#define DRM_FORMAT_MOD_PVR_FBCDC_8x8_V0 fourcc_mod_code(PVR, 1)
+#define DRM_FORMAT_MOD_PVR_FBCDC_8x8_V0_FIX fourcc_mod_code(PVR, 2) /* Fix for HW_BRN_37464 */
+#define DRM_FORMAT_MOD_PVR_FBCDC_8x8_V1 fourcc_mod_code(PVR, 3)
+#define DRM_FORMAT_MOD_PVR_FBCDC_8x8_V2 fourcc_mod_code(PVR, 4)
+#define DRM_FORMAT_MOD_PVR_FBCDC_8x8_V3 fourcc_mod_code(PVR, 5)
+/* DRM_FORMAT_MOD_PVR_FBCDC_8x8_V7 - moved to the public header */
+#define DRM_FORMAT_MOD_PVR_FBCDC_8x8_V8 fourcc_mod_code(PVR, 18)
+/* DRM_FORMAT_MOD_PVR_FBCDC_8x8_V10 - moved to the public header */
+/* DRM_FORMAT_MOD_PVR_FBCDC_8x8_V12 - moved to the public header */
+/* DRM_FORMAT_MOD_PVR_FBCDC_8x8_V13 - moved to the public header */
+/* DRM_FORMAT_MOD_PVR_FBCDC_8x8_LOSSY25_V13 - moved to the public header */
+/* DRM_FORMAT_MOD_PVR_FBCDC_8x8_LOSSY50_V13 - moved to the public header */
+/* DRM_FORMAT_MOD_PVR_FBCDC_8x8_LOSSY75_V13 - moved to the public header */
+#define DRM_FORMAT_MOD_PVR_FBCDC_16x4_V0 fourcc_mod_code(PVR, 7)
+#define DRM_FORMAT_MOD_PVR_FBCDC_16x4_V0_FIX fourcc_mod_code(PVR, 8) /* Fix for HW_BRN_37464 */
+#define DRM_FORMAT_MOD_PVR_FBCDC_16x4_V1 fourcc_mod_code(PVR, 9)
+#define DRM_FORMAT_MOD_PVR_FBCDC_16x4_V2 fourcc_mod_code(PVR, 10)
+#define DRM_FORMAT_MOD_PVR_FBCDC_16x4_V3 fourcc_mod_code(PVR, 11)
+/* DRM_FORMAT_MOD_PVR_FBCDC_16x4_V7 - moved to the public header */
+#define DRM_FORMAT_MOD_PVR_FBCDC_16x4_V8 fourcc_mod_code(PVR, 19)
+/* DRM_FORMAT_MOD_PVR_FBCDC_16x4_V10 - moved to the public header */
+/* DRM_FORMAT_MOD_PVR_FBCDC_16x4_V12 - moved to the public header */
+/* DRM_FORMAT_MOD_PVR_FBCDC_16x4_V13 - moved to the public header */
+/* DRM_FORMAT_MOD_PVR_FBCDC_16x4_LOSSY25_V13 - moved to the public header */
+/* DRM_FORMAT_MOD_PVR_FBCDC_16x4_LOSSY50_V13 - moved to the public header */
+/* DRM_FORMAT_MOD_PVR_FBCDC_16x4_LOSSY75_V13 - moved to the public header */
+#define DRM_FORMAT_MOD_PVR_FBCDC_32x2_V1 fourcc_mod_code(PVR, 13)
+#define DRM_FORMAT_MOD_PVR_FBCDC_32x2_V3 fourcc_mod_code(PVR, 14)
+#define DRM_FORMAT_MOD_PVR_FBCDC_32x2_V8 fourcc_mod_code(PVR, 20)
+/* DRM_FORMAT_MOD_PVR_FBCDC_32x2_V10 - moved to the public header */
+#define DRM_FORMAT_MOD_PVR_FBCDC_32x2_V12 fourcc_mod_code(PVR, 17)
+
+#endif /* IMG_DRM_FOURCC_INTERNAL_H */
diff --git a/drivers/gpu/drm/img-rogue/include/img_elf.h b/drivers/gpu/drm/img-rogue/include/img_elf.h
new file mode 100644
index 000000000..8837d9592
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/img_elf.h
@@ -0,0 +1,111 @@
+/*************************************************************************/ /*!
+@File img_elf.h
+@Title IMG ELF file definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Platform RGX
+@Description Definitions for ELF file structures used in the DDK.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(IMG_ELF_H)
+#define IMG_ELF_H
+
+#include "img_types.h"
+
+/* ELF format defines */
+#define ELF_PT_LOAD (0x1U) /* Program header identifier as Load */
+#define ELF_SHT_SYMTAB (0x2U) /* Section identifier as Symbol Table */
+#define ELF_SHT_STRTAB (0x3U) /* Section identifier as String Table */
+#define MAX_STRTAB_NUM (0x8U) /* Maximum number of string table in the ELF file */
+
+/* Redefined structs of ELF format */
+typedef struct
+{
+ IMG_UINT8 ui32Eident[16];
+ IMG_UINT16 ui32Etype;
+ IMG_UINT16 ui32Emachine;
+ IMG_UINT32 ui32Eversion;
+ IMG_UINT32 ui32Eentry;
+ IMG_UINT32 ui32Ephoff;
+ IMG_UINT32 ui32Eshoff;
+ IMG_UINT32 ui32Eflags;
+ IMG_UINT16 ui32Eehsize;
+ IMG_UINT16 ui32Ephentsize;
+ IMG_UINT16 ui32Ephnum;
+ IMG_UINT16 ui32Eshentsize;
+ IMG_UINT16 ui32Eshnum;
+ IMG_UINT16 ui32Eshtrndx;
+} IMG_ELF_HDR;
+
+typedef struct
+{
+ IMG_UINT32 ui32Stname;
+ IMG_UINT32 ui32Stvalue;
+ IMG_UINT32 ui32Stsize;
+ IMG_UINT8 ui32Stinfo;
+ IMG_UINT8 ui32Stother;
+ IMG_UINT16 ui32Stshndx;
+} IMG_ELF_SYM;
+
+typedef struct
+{
+ IMG_UINT32 ui32Shname;
+ IMG_UINT32 ui32Shtype;
+ IMG_UINT32 ui32Shflags;
+ IMG_UINT32 ui32Shaddr;
+ IMG_UINT32 ui32Shoffset;
+ IMG_UINT32 ui32Shsize;
+ IMG_UINT32 ui32Shlink;
+ IMG_UINT32 ui32Shinfo;
+ IMG_UINT32 ui32Shaddralign;
+ IMG_UINT32 ui32Shentsize;
+} IMG_ELF_SHDR;
+
+typedef struct
+{
+ IMG_UINT32 ui32Ptype;
+ IMG_UINT32 ui32Poffset;
+ IMG_UINT32 ui32Pvaddr;
+ IMG_UINT32 ui32Ppaddr;
+ IMG_UINT32 ui32Pfilesz;
+ IMG_UINT32 ui32Pmemsz;
+ IMG_UINT32 ui32Pflags;
+ IMG_UINT32 ui32Palign;
+} IMG_ELF_PROGRAM_HDR;
+
+#endif /* IMG_ELF_H */
diff --git a/drivers/gpu/drm/img-rogue/include/img_types.h b/drivers/gpu/drm/img-rogue/include/img_types.h
new file mode 100644
index 000000000..826f03e9f
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/img_types.h
@@ -0,0 +1,318 @@
+/*************************************************************************/ /*!
+@File
+@Title Global types for use by IMG APIs
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Defines type aliases for use by IMG APIs.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef IMG_TYPES_H
+#define IMG_TYPES_H
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* To use C99 types and definitions, there are two special cases we need to
+ * cater for:
+ *
+ * - Visual Studio: in VS2010 or later, some standard headers are available,
+ * and MSVC has its own built-in sized types. We can define the C99 types
+ * in terms of these.
+ *
+ * - Linux kernel code: C99 sized types are defined in , but
+ * some other features (like macros for constants or printf format
+ * strings) are missing, so we need to fill in the gaps ourselves.
+ *
+ * For other cases (userspace code under Linux, Android or Neutrino, or
+ * firmware code), we can include the standard headers.
+ */
+#if defined(_MSC_VER)
+ #include /* bool */
+ #include "msvc_types.h"
+#elif defined(__linux__) && defined(__KERNEL__)
+ #include
+ #include
+ #include "kernel_types.h"
+#elif defined(__linux__) || defined(__METAG) || defined(__MINGW32__) || \
+ defined(__QNXNTO__) || defined(INTEGRITY_OS) || defined(__riscv)
+ #include /* NULL */
+ #include
+ #include /* intX_t/uintX_t, format specifiers */
+ #include /* INT_MIN, etc */
+ #include /* bool */
+#elif defined(__mips)
+ #include /* NULL */
+ #include /* intX_t/uintX_t, format specifiers */
+ #include /* bool */
+#else
+ #error C99 support not set up for this build
+#endif
+
+/*
+ * Due to a Klocwork bug, 'true'/'false' constants are not recognized to be of
+ * boolean type. This results in large number of false-positives being reported
+ * (MISRA.ETYPE.ASSIGN.2012: "An expression value of essential type 'signed char'
+ * is assigned to an object of essential type 'bool'"). Work around this by
+ * redefining those constants with cast to bool added.
+ */
+#if defined(__KLOCWORK__) && !defined(__cplusplus)
+#undef true
+#undef false
+#define true ((bool) 1)
+#define false ((bool) 0)
+#endif
+
+typedef unsigned int IMG_UINT;
+typedef int IMG_INT;
+
+typedef uint8_t IMG_UINT8, *IMG_PUINT8;
+typedef uint8_t IMG_BYTE, *IMG_PBYTE;
+typedef int8_t IMG_INT8;
+typedef char IMG_CHAR, *IMG_PCHAR;
+
+typedef uint16_t IMG_UINT16, *IMG_PUINT16;
+typedef int16_t IMG_INT16;
+typedef uint32_t IMG_UINT32, *IMG_PUINT32;
+typedef int32_t IMG_INT32, *IMG_PINT32;
+#if defined(INTEGRITY_OS)
+#if __INT_BIT >= 32U
+#define IMG_UINT32_C(n) ((IMG_UINT32)(n ## U))
+#elif __LONG_BIT >= 32U
+#define IMG_UINT32_C(n) ((IMG_UINT32)(n ## UL))
+#elif defined(__LLONG_BIT) && __LLONG_BIT >= 32U
+#define IMG_UINT32_C(n) ((IMG_UINT32)(n ## ULL))
+#endif
+#else /* defined(INTEGRITY_OS) */
+#define IMG_UINT32_C(c) ((IMG_UINT32)UINT32_C(c))
+#endif /* defined(INTEGRITY_OS) */
+
+typedef uint64_t IMG_UINT64, *IMG_PUINT64;
+typedef int64_t IMG_INT64;
+#define IMG_INT64_C(c) INT64_C(c)
+#if defined(INTEGRITY_OS)
+#if __INT_BIT >= 64U
+#define IMG_UINT64_C(n) (n ## U)
+#elif defined(__LONG_BIT) && __LONG_BIT >= 64U
+#define IMG_UINT64_C(n) (n ## UL)
+#elif defined(__LLONG_BIT) && __LLONG_BIT >= 64U
+#define IMG_UINT64_C(n) (n ## ULL)
+#endif
+#else /* defined(INTEGRITY_OS) */
+#define IMG_UINT64_C(c) UINT64_C(c)
+#endif /* defined(INTEGRITY_OS) */
+#define IMG_UINT16_C(c) UINT16_C(c)
+#define IMG_UINT64_FMTSPEC PRIu64
+#define IMG_UINT64_FMTSPECX PRIX64
+#define IMG_UINT64_FMTSPECx PRIx64
+#define IMG_UINT64_FMTSPECo PRIo64
+#define IMG_INT64_FMTSPECd PRId64
+
+#define IMG_UINT16_MAX UINT16_MAX
+#define IMG_UINT32_MAX UINT32_MAX
+#define IMG_UINT64_MAX UINT64_MAX
+
+#define IMG_INT16_MAX INT16_MAX
+#define IMG_INT32_MAX INT32_MAX
+#define IMG_INT64_MAX INT64_MAX
+
+/* Linux kernel mode does not use floating point */
+typedef float IMG_FLOAT, *IMG_PFLOAT;
+typedef double IMG_DOUBLE;
+
+typedef union
+{
+ IMG_UINT32 ui32;
+ IMG_FLOAT f;
+} IMG_UINT32_FLOAT;
+
+typedef int IMG_SECURE_TYPE;
+
+typedef enum tag_img_bool
+{
+ IMG_FALSE = 0,
+ IMG_TRUE = 1,
+ IMG_FORCE_ALIGN = 0x7FFFFFFF
+} IMG_BOOL, *IMG_PBOOL;
+
+#if defined(UNDER_WDDM) || defined(WINDOWS_WDF)
+typedef IMG_CHAR const* IMG_PCCHAR;
+#endif
+
+/* Format specifiers for 'size_t' type */
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#define IMG_SIZE_FMTSPEC "%Iu"
+#define IMG_SIZE_FMTSPECX "%Ix"
+#else
+#define IMG_SIZE_FMTSPEC "%zu"
+#define IMG_SIZE_FMTSPECX "%zx"
+#endif
+
+#if defined(__linux__) && defined(__KERNEL__)
+/* prints the function name when used with printk */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0))
+#define IMG_PFN_FMTSPEC "%ps"
+#else
+#define IMG_PFN_FMTSPEC "%pf"
+#endif
+#else
+#define IMG_PFN_FMTSPEC "%p"
+#endif
+
+typedef void *IMG_HANDLE;
+
+/* Process IDs */
+typedef IMG_UINT32 IMG_PID;
+
+/* OS connection type */
+typedef int IMG_OS_CONNECTION;
+
+
+/*
+ * Address types.
+ * All types used to refer to a block of memory are wrapped in structures
+ * to enforce some degree of type safety, i.e. a IMG_DEV_VIRTADDR cannot
+ * be assigned to a variable of type IMG_DEV_PHYADDR because they are not the
+ * same thing.
+ *
+ * There is an assumption that the system contains at most one non-cpu mmu,
+ * and a memory block is only mapped by the MMU once.
+ *
+ * Different devices could have offset views of the physical address space.
+ *
+ */
+
+
+/*
+ *
+ * +------------+ +------------+ +------------+ +------------+
+ * | CPU | | DEV | | DEV | | DEV |
+ * +------------+ +------------+ +------------+ +------------+
+ * | | | |
+ * | void * |IMG_DEV_VIRTADDR |IMG_DEV_VIRTADDR |
+ * | \-------------------/ |
+ * | | |
+ * +------------+ +------------+ |
+ * | MMU | | MMU | |
+ * +------------+ +------------+ |
+ * | | |
+ * | | |
+ * | | |
+ * +--------+ +---------+ +--------+
+ * | Offset | | (Offset)| | Offset |
+ * +--------+ +---------+ +--------+
+ * | | IMG_DEV_PHYADDR |
+ * | | |
+ * | | IMG_DEV_PHYADDR |
+ * +---------------------------------------------------------------------+
+ * | System Address bus |
+ * +---------------------------------------------------------------------+
+ *
+ */
+
+#define IMG_DEV_VIRTADDR_FMTSPEC "0x%010" IMG_UINT64_FMTSPECX
+#define IMG_DEVMEM_SIZE_FMTSPEC "0x%010" IMG_UINT64_FMTSPECX
+#define IMG_DEVMEM_ALIGN_FMTSPEC "0x%010" IMG_UINT64_FMTSPECX
+#define IMG_DEVMEM_OFFSET_FMTSPEC "0x%010" IMG_UINT64_FMTSPECX
+
+/* cpu physical address */
+typedef struct
+{
+#if defined(UNDER_WDDM) || defined(WINDOWS_WDF)
+ uintptr_t uiAddr;
+#define IMG_CAST_TO_CPUPHYADDR_UINT(var) (uintptr_t)(var)
+#elif defined(__linux__) && defined(__KERNEL__)
+ phys_addr_t uiAddr;
+#define IMG_CAST_TO_CPUPHYADDR_UINT(var) (phys_addr_t)(var)
+#else
+ IMG_UINT64 uiAddr;
+#define IMG_CAST_TO_CPUPHYADDR_UINT(var) (IMG_UINT64)(var)
+#endif
+} IMG_CPU_PHYADDR;
+
+/* device physical address */
+typedef struct
+{
+ IMG_UINT64 uiAddr;
+} IMG_DEV_PHYADDR;
+
+/* dma address */
+typedef struct
+{
+ IMG_UINT64 uiAddr;
+} IMG_DMA_ADDR;
+
+/*
+ rectangle structure
+*/
+typedef struct
+{
+ IMG_INT32 x0;
+ IMG_INT32 y0;
+ IMG_INT32 x1;
+ IMG_INT32 y1;
+} IMG_RECT;
+
+typedef struct
+{
+ IMG_INT16 x0;
+ IMG_INT16 y0;
+ IMG_INT16 x1;
+ IMG_INT16 y1;
+} IMG_RECT_16;
+
+/*
+ * box structure
+ */
+typedef struct
+{
+ IMG_INT32 x0;
+ IMG_INT32 y0;
+ IMG_INT32 z0;
+ IMG_INT32 x1;
+ IMG_INT32 y1;
+ IMG_INT32 z1;
+} IMG_BOX;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* IMG_TYPES_H */
+/******************************************************************************
+ End of file (img_types.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/kernel_types.h b/drivers/gpu/drm/img-rogue/include/kernel_types.h
new file mode 100644
index 000000000..c3305102f
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/kernel_types.h
@@ -0,0 +1,137 @@
+/*************************************************************************/ /*!
+@Title C99-compatible types and definitions for Linux kernel code
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include
+
+/* Limits of specified-width integer types */
+
+/* S8_MIN, etc were added in kernel version 3.14. The other versions are for
+ * earlier kernels. They can be removed once older kernels don't need to be
+ * supported.
+ */
+#ifdef S8_MIN
+ #define INT8_MIN S8_MIN
+#else
+ #define INT8_MIN (-128)
+#endif
+
+#ifdef S8_MAX
+ #define INT8_MAX S8_MAX
+#else
+ #define INT8_MAX 127
+#endif
+
+#ifdef U8_MAX
+ #define UINT8_MAX U8_MAX
+#else
+ #define UINT8_MAX 0xFF
+#endif
+
+#ifdef S16_MIN
+ #define INT16_MIN S16_MIN
+#else
+ #define INT16_MIN (-32768)
+#endif
+
+#ifdef S16_MAX
+ #define INT16_MAX S16_MAX
+#else
+ #define INT16_MAX 32767
+#endif
+
+#ifdef U16_MAX
+ #define UINT16_MAX U16_MAX
+#else
+ #define UINT16_MAX 0xFFFF
+#endif
+
+#ifdef S32_MIN
+ #define INT32_MIN S32_MIN
+#else
+ #define INT32_MIN (-2147483647 - 1)
+#endif
+
+#ifdef S32_MAX
+ #define INT32_MAX S32_MAX
+#else
+ #define INT32_MAX 2147483647
+#endif
+
+#ifdef U32_MAX
+ #define UINT32_MAX U32_MAX
+#else
+ #define UINT32_MAX 0xFFFFFFFF
+#endif
+
+#ifdef S64_MIN
+ #define INT64_MIN S64_MIN
+#else
+ #define INT64_MIN (-9223372036854775807LL)
+#endif
+
+#ifdef S64_MAX
+ #define INT64_MAX S64_MAX
+#else
+ #define INT64_MAX 9223372036854775807LL
+#endif
+
+#ifdef U64_MAX
+ #define UINT64_MAX U64_MAX
+#else
+ #define UINT64_MAX 0xFFFFFFFFFFFFFFFFULL
+#endif
+
+/* Macros for integer constants */
+#define INT8_C S8_C
+#define UINT8_C U8_C
+#define INT16_C S16_C
+#define UINT16_C U16_C
+#define INT32_C S32_C
+#define UINT32_C U32_C
+#define INT64_C S64_C
+#define UINT64_C U64_C
+
+/* Format conversion of integer types */
+
+#define PRIX64 "llX"
+#define PRIx64 "llx"
+#define PRIu64 "llu"
+#define PRId64 "lld"
diff --git a/drivers/gpu/drm/img-rogue/include/linux_sw_sync.h b/drivers/gpu/drm/img-rogue/include/linux_sw_sync.h
new file mode 100644
index 000000000..c12c65029
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/linux_sw_sync.h
@@ -0,0 +1,52 @@
+/*************************************************************************/ /*!
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _UAPI_LINUX_PVR_SW_SYNC_H
+#define _UAPI_LINUX_PVR_SW_SYNC_H
+
+#if defined(SUPPORT_NATIVE_FENCE_SYNC)
+
+#include
+
+#include "pvrsrv_sync_km.h"
+#include "pvr_drm.h"
+
+#endif /* defined(SUPPORT_NATIVE_FENCE_SYNC) */
+#endif
diff --git a/drivers/gpu/drm/img-rogue/include/lock_types.h b/drivers/gpu/drm/img-rogue/include/lock_types.h
new file mode 100644
index 000000000..c9e784ef8
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/lock_types.h
@@ -0,0 +1,92 @@
+/*************************************************************************/ /*!
+@File lock_types.h
+@Title Locking types
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Locking specific enums, defines and structures
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef LOCK_TYPES_H
+#define LOCK_TYPES_H
+
+/* In Linux kernel mode we are using the kernel mutex implementation directly
+ * with macros. This allows us to use the kernel lockdep feature for lock
+ * debugging. */
+#if defined(__linux__) && defined(__KERNEL__)
+
+#include
+#include
+/* The mutex is defined as a pointer to be compatible with the other code. This
+ * isn't ideal and usually you wouldn't do that in kernel code. */
+typedef struct mutex *POS_LOCK;
+typedef struct rw_semaphore *POSWR_LOCK;
+typedef spinlock_t *POS_SPINLOCK;
+typedef atomic_t ATOMIC_T;
+
+#else /* defined(__linux__) && defined(__KERNEL__) */
+#include "img_types.h" /* needed for IMG_INT */
+typedef struct _OS_LOCK_ *POS_LOCK;
+
+#if defined(__linux__) || defined(__QNXNTO__) || defined(INTEGRITY_OS)
+typedef struct _OSWR_LOCK_ *POSWR_LOCK;
+#else /* defined(__linux__) || defined(__QNXNTO__) || defined(INTEGRITY_OS) */
+typedef struct _OSWR_LOCK_ {
+ IMG_UINT32 ui32Dummy;
+} *POSWR_LOCK;
+#endif /* defined(__linux__) || defined(__QNXNTO__) || defined(INTEGRITY_OS) */
+
+#if defined(__linux__)
+ typedef struct _OS_ATOMIC {IMG_INT32 counter;} ATOMIC_T;
+#elif defined(__QNXNTO__)
+ typedef struct _OS_ATOMIC {IMG_INT32 counter;} ATOMIC_T;
+#elif defined(_WIN32)
+ /*
+ * Dummy definition. WDDM doesn't use Services, but some headers
+ * still have to be shared. This is one such case.
+ */
+ typedef struct _OS_ATOMIC {IMG_INT32 counter;} ATOMIC_T;
+#elif defined(INTEGRITY_OS)
+ /* Only lower 32bits are used in OS ATOMIC APIs to have consistent behaviour across all OS */
+ typedef struct _OS_ATOMIC {IMG_INT64 counter;} ATOMIC_T;
+#else
+ #error "Please type-define an atomic lock for this environment"
+#endif
+
+#endif /* defined(__linux__) && defined(__KERNEL__) */
+
+#endif /* LOCK_TYPES_H */
diff --git a/drivers/gpu/drm/img-rogue/include/log2.h b/drivers/gpu/drm/img-rogue/include/log2.h
new file mode 100644
index 000000000..4cba23f9d
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/log2.h
@@ -0,0 +1,417 @@
+/*************************************************************************/ /*!
+@Title Integer log2 and related functions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef LOG2_H
+#define LOG2_H
+
+#include "img_defs.h"
+
+/*************************************************************************/ /*!
+@Description Determine if a number is a power of two.
+@Input n
+@Return True if n is a power of 2, false otherwise. True if n == 0.
+*/ /**************************************************************************/
+static INLINE IMG_BOOL __const_function IsPower2(uint32_t n)
+{
+ /* C++ needs this cast. */
+ return (IMG_BOOL)((n & (n - 1U)) == 0U);
+}
+
+/*************************************************************************/ /*!
+@Description Determine if a number is a power of two.
+@Input n
+@Return True if n is a power of 2, false otherwise. True if n == 0.
+*/ /**************************************************************************/
+static INLINE IMG_BOOL __const_function IsPower2_64(uint64_t n)
+{
+ /* C++ needs this cast. */
+ return (IMG_BOOL)((n & (n - 1U)) == 0U);
+}
+
+/* Code using GNU GCC intrinsics */
+#if (defined(__GNUC__) || defined(__GNUG__)) && !(defined(__clang__) || defined(__INTEL_COMPILER))
+
+/* CHAR_BIT is typically found in . For all the platforms where
+ * CHAR_BIT is not available, defined it here with the assumption that there
+ * are 8 bits in a byte */
+#ifndef CHAR_BIT
+#define CHAR_BIT 8U
+#endif
+
+/*************************************************************************/ /*!
+@Description Compute floor(log2(n))
+@Input n
+@Return log2(n) rounded down to the nearest integer. Returns 0 if n == 0
+*/ /**************************************************************************/
+static INLINE uint32_t __const_function FloorLog2(uint32_t n)
+{
+ if (unlikely(n == 0U))
+ {
+ return 0;
+ }
+ else
+ {
+ uint32_t uNumBits = (uint32_t)CHAR_BIT * (uint32_t)sizeof(n);
+ return uNumBits - (uint32_t)__builtin_clz(n) - 1U;
+ }
+}
+
+/*************************************************************************/ /*!
+@Description Compute floor(log2(n))
+@Input n
+@Return log2(n) rounded down to the nearest integer. Returns 0 if n == 0
+*/ /**************************************************************************/
+static INLINE uint32_t __const_function FloorLog2_64(uint64_t n)
+{
+ if (unlikely(n == 0U))
+ {
+ return 0;
+ }
+ else
+ {
+ uint32_t uNumBits = (uint32_t)CHAR_BIT * (uint32_t)sizeof(n);
+ return uNumBits - (uint32_t)__builtin_clzll(n) - 1U;
+ }
+}
+
+/*************************************************************************/ /*!
+@Description Compute ceil(log2(n))
+@Input n
+@Return log2(n) rounded up to the nearest integer. Returns 0 if n == 0
+*/ /**************************************************************************/
+static INLINE uint32_t __const_function CeilLog2(uint32_t n)
+{
+ if (unlikely(n == 0U || n == 1U))
+ {
+ return 0;
+ }
+ else
+ {
+ uint32_t uNumBits = (uint32_t)CHAR_BIT * (uint32_t)sizeof(n);
+
+ n--; /* Handle powers of 2 */
+ return uNumBits - (uint32_t)__builtin_clz(n);
+ }
+}
+
+/*************************************************************************/ /*!
+@Description Compute ceil(log2(n))
+@Input n
+@Return log2(n) rounded up to the nearest integer. Returns 0 if n == 0
+*/ /**************************************************************************/
+static INLINE uint32_t __const_function CeilLog2_64(uint64_t n)
+{
+ if (unlikely(n == 0U || n == 1U))
+ {
+ return 0;
+ }
+ else
+ {
+ uint32_t uNumBits = (uint32_t)CHAR_BIT * (uint32_t)sizeof(n);
+
+ n--; /* Handle powers of 2 */
+ return uNumBits - (uint32_t)__builtin_clzll(n);
+ }
+}
+
+/*************************************************************************/ /*!
+@Description Compute log2(n) for exact powers of two only
+@Input n Must be a power of two
+@Return log2(n)
+*/ /**************************************************************************/
+static INLINE uint32_t __const_function ExactLog2(uint32_t n)
+{
+ return (uint32_t)CHAR_BIT * (uint32_t)sizeof(n) - (uint32_t)__builtin_clz(n) - 1U;
+}
+
+/*************************************************************************/ /*!
+@Description Compute log2(n) for exact powers of two only
+@Input n Must be a power of two
+@Return log2(n)
+*/ /**************************************************************************/
+static INLINE uint32_t __const_function ExactLog2_64(uint64_t n)
+{
+ return (uint32_t)CHAR_BIT * (uint32_t)sizeof(n) - (uint32_t)__builtin_clzll(n) - 1U;
+}
+
+/*************************************************************************/ /*!
+@Description Round a non-power-of-two number up to the next power of two.
+@Input n
+@Return n rounded up to the next power of two. If n is zero or
+ already a power of two, return n unmodified.
+*/ /**************************************************************************/
+static INLINE uint32_t __const_function RoundUpToNextPowerOfTwo(uint32_t n)
+{
+ /* Cases with n greater than 2^31 needs separate handling
+ * as result of (1<<32) is undefined. */
+ if (unlikely( n == 0U || n > (uint32_t)1 << ((uint32_t)CHAR_BIT * sizeof(n) - 1U)))
+ {
+ return 0;
+ }
+
+ /* Return n if it is already a power of 2 */
+ if ((IMG_BOOL)((n & (n - 1U)) == 0U))
+ {
+ return n;
+ }
+
+ return (uint32_t)1 << ((uint32_t)CHAR_BIT * sizeof(n) - (uint32_t)__builtin_clz(n));
+}
+
+/*************************************************************************/ /*!
+@Description Round a non-power-of-two number up to the next power of two.
+@Input n
+@Return n rounded up to the next power of two. If n is zero or
+ already a power of two, return n unmodified.
+*/ /**************************************************************************/
+static INLINE uint64_t __const_function RoundUpToNextPowerOfTwo_64(uint64_t n)
+{
+ /* Cases with n greater than 2^63 needs separate handling
+ * as result of (1<<64) is undefined. */
+ if (unlikely( n == 0U || n > (uint64_t)1 << ((uint32_t)CHAR_BIT * sizeof(n) - 1U)))
+ {
+ return 0;
+ }
+
+ /* Return n if it is already a power of 2 */
+ if ((IMG_BOOL)((n & (n - 1U)) == 0U))
+ {
+ return n;
+ }
+
+ return (uint64_t)1 << ((uint64_t)CHAR_BIT * sizeof(n) - (uint64_t)__builtin_clzll(n));
+}
+
+#else /* #if (defined(__GNUC__) || defined(__GNUG__)) && !(defined(__clang__) || defined(__INTEL_COMPILER)) */
+
+/*************************************************************************/ /*!
+@Description Round a non-power-of-two number up to the next power of two.
+@Input n
+@Return n rounded up to the next power of two. If n is zero or
+ already a power of two, return n unmodified.
+*/ /**************************************************************************/
+static INLINE uint32_t __const_function RoundUpToNextPowerOfTwo(uint32_t n)
+{
+ n--;
+ n |= n >> 1; /* handle 2 bit numbers */
+ n |= n >> 2; /* handle 4 bit numbers */
+ n |= n >> 4; /* handle 8 bit numbers */
+ n |= n >> 8; /* handle 16 bit numbers */
+ n |= n >> 16; /* handle 32 bit numbers */
+ n++;
+
+ return n;
+}
+
+/*************************************************************************/ /*!
+@Description Round a non-power-of-two number up to the next power of two.
+@Input n
+@Return n rounded up to the next power of two. If n is zero or
+ already a power of two, return n unmodified.
+*/ /**************************************************************************/
+static INLINE uint64_t __const_function RoundUpToNextPowerOfTwo_64(uint64_t n)
+{
+ n--;
+ n |= n >> 1; /* handle 2 bit numbers */
+ n |= n >> 2; /* handle 4 bit numbers */
+ n |= n >> 4; /* handle 8 bit numbers */
+ n |= n >> 8; /* handle 16 bit numbers */
+ n |= n >> 16; /* handle 32 bit numbers */
+ n |= n >> 32; /* handle 64 bit numbers */
+ n++;
+
+ return n;
+}
+
+/*************************************************************************/ /*!
+@Description Compute floor(log2(n))
+@Input n
+@Return log2(n) rounded down to the nearest integer. Returns 0 if n == 0
+*/ /**************************************************************************/
+static INLINE uint32_t __const_function FloorLog2(uint32_t n)
+{
+ uint32_t ui32log2 = 0;
+
+ while (n >>= 1)
+ {
+ ui32log2++;
+ }
+
+ return ui32log2;
+}
+
+/*************************************************************************/ /*!
+@Description Compute floor(log2(n))
+@Input n
+@Return log2(n) rounded down to the nearest integer. Returns 0 if n == 0
+*/ /**************************************************************************/
+static INLINE uint32_t __const_function FloorLog2_64(uint64_t n)
+{
+ uint32_t ui32log2 = 0;
+
+ while (n >>= 1)
+ {
+ ui32log2++;
+ }
+
+ return ui32log2;
+}
+
+/*************************************************************************/ /*!
+@Description Compute ceil(log2(n))
+@Input n
+@Return log2(n) rounded up to the nearest integer. Returns 0 if n == 0
+*/ /**************************************************************************/
+static INLINE uint32_t __const_function CeilLog2(uint32_t n)
+{
+ uint32_t ui32log2 = 0;
+
+ if (n == 0U)
+ {
+ return 0;
+ }
+
+ n--; /* Handle powers of 2 */
+
+ while (n)
+ {
+ ui32log2++;
+ n >>= 1;
+ }
+
+ return ui32log2;
+}
+
+/*************************************************************************/ /*!
+@Description Compute ceil(log2(n))
+@Input n
+@Return log2(n) rounded up to the nearest integer. Returns 0 if n == 0
+*/ /**************************************************************************/
+static INLINE uint32_t __const_function CeilLog2_64(uint64_t n)
+{
+ uint32_t ui32log2 = 0;
+
+ if (n == 0U)
+ {
+ return 0;
+ }
+
+ n--; /* Handle powers of 2 */
+
+ while (n)
+ {
+ ui32log2++;
+ n >>= 1;
+ }
+
+ return ui32log2;
+}
+
+/*************************************************************************/ /*!
+@Description Compute log2(n) for exact powers of two only
+@Input n Must be a power of two
+@Return log2(n)
+*/ /**************************************************************************/
+static INLINE uint32_t __const_function ExactLog2(uint32_t n)
+{
+ static const uint32_t b[] =
+ {0xAAAAAAAAU, 0xCCCCCCCCU, 0xF0F0F0F0U, 0xFF00FF00U, 0xFFFF0000U};
+ uint32_t r = (n & b[0]) != 0U;
+
+ r |= (uint32_t) ((n & b[4]) != 0U) << 4;
+ r |= (uint32_t) ((n & b[3]) != 0U) << 3;
+ r |= (uint32_t) ((n & b[2]) != 0U) << 2;
+ r |= (uint32_t) ((n & b[1]) != 0U) << 1;
+
+ return r;
+}
+
+/*************************************************************************/ /*!
+@Description Compute log2(n) for exact powers of two only
+@Input n Must be a power of two
+@Return log2(n)
+*/ /**************************************************************************/
+static INLINE uint32_t __const_function ExactLog2_64(uint64_t n)
+{
+ static const uint64_t b[] =
+ {0xAAAAAAAAAAAAAAAAULL, 0xCCCCCCCCCCCCCCCCULL,
+ 0xF0F0F0F0F0F0F0F0ULL, 0xFF00FF00FF00FF00ULL,
+ 0xFFFF0000FFFF0000ULL, 0xFFFFFFFF00000000ULL};
+ uint32_t r = (n & b[0]) != 0U;
+
+ r |= (uint32_t) ((n & b[5]) != 0U) << 5;
+ r |= (uint32_t) ((n & b[4]) != 0U) << 4;
+ r |= (uint32_t) ((n & b[3]) != 0U) << 3;
+ r |= (uint32_t) ((n & b[2]) != 0U) << 2;
+ r |= (uint32_t) ((n & b[1]) != 0U) << 1;
+
+ return r;
+}
+
+#endif /* #if (defined(__GNUC__) || defined(__GNUG__)) && !(defined(__clang__) || defined(__INTEL_COMPILER)) */
+
+/*************************************************************************/ /*!
+@Description Compute floor(log2(size)) , where size is the max of 3 sizes
+ This is almost always the ONLY EVER valid use of FloorLog2.
+ Usually CeilLog2() should be used instead.
+ For a 5x5x1 texture, the 3 miplevels are:
+ 0: 5x5x1
+ 1: 2x2x1
+ 2: 1x1x1
+
+ For an 8x8x1 texture, the 4 miplevels are:
+ 0: 8x8x1
+ 1: 4x4x1
+ 2: 2x2x1
+ 3: 1x1x1
+
+
+@Input sizeX, sizeY, sizeZ
+@Return Count of mipmap levels for given dimensions
+*/ /**************************************************************************/
+static INLINE uint32_t __const_function NumMipLevels(uint32_t sizeX, uint32_t sizeY, uint32_t sizeZ)
+{
+
+ uint32_t maxSize = MAX(MAX(sizeX, sizeY), sizeZ);
+ return FloorLog2(maxSize) + 1U;
+}
+
+#endif /* LOG2_H */
diff --git a/drivers/gpu/drm/img-rogue/include/multicore_defs.h b/drivers/gpu/drm/img-rogue/include/multicore_defs.h
new file mode 100644
index 000000000..2ca4e064d
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/multicore_defs.h
@@ -0,0 +1,53 @@
+/**************************************************************************/ /*!
+@File
+@Title RGX Multicore Information flags
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef RGX_MULTICORE_DEFS_H
+#define RGX_MULTICORE_DEFS_H
+
+/* Capability bits returned to client in RGXGetMultiCoreInfo */
+#define RGX_MULTICORE_CAPABILITY_FRAGMENT_EN (0x00000040U)
+#define RGX_MULTICORE_CAPABILITY_GEOMETRY_EN (0x00000020U)
+#define RGX_MULTICORE_CAPABILITY_COMPUTE_EN (0x00000010U)
+#define RGX_MULTICORE_CAPABILITY_PRIMARY_EN (0x00000008U)
+#define RGX_MULTICORE_ID_CLRMSK (0xFFFFFFF8U)
+
+#endif /* RGX_MULTICORE_DEFS_H */
diff --git a/drivers/gpu/drm/img-rogue/include/osfunc_common.h b/drivers/gpu/drm/img-rogue/include/osfunc_common.h
new file mode 100644
index 000000000..f209bede8
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/osfunc_common.h
@@ -0,0 +1,266 @@
+/*************************************************************************/ /*!
+@File
+@Title OS functions header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description OS specific API definitions
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef OSFUNC_COMMON_H
+/*! @cond Doxygen_Suppress */
+#define OSFUNC_COMMON_H
+/*! @endcond */
+
+#if defined(__KERNEL__) && defined(__linux__)
+#include
+#else
+#include
+#endif
+
+#include "img_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**************************************************************************/ /*!
+@Function DeviceMemSet
+@Description Set memory, whose mapping may be uncached, to a given value.
+ Safe implementation for all architectures for uncached mapping,
+ optimised for speed where supported by tool chains.
+ In such cases, OSDeviceMemSet() is defined as a call to this
+ function.
+@Input pvDest void pointer to the memory to be set
+@Input ui8Value byte containing the value to be set
+@Input ui32Size the number of bytes to be set to the given value
+@Return None
+ */ /**************************************************************************/
+void DeviceMemSet(void *pvDest, IMG_UINT8 ui8Value, size_t ui32Size);
+
+/**************************************************************************/ /*!
+@Function DeviceMemCopy
+@Description Copy values from one area of memory. Safe implementation for
+ all architectures for uncached mapping, of either the source
+ or destination, optimised for speed where supported by tool
+ chains. In such cases, OSDeviceMemCopy() is defined as a call
+ to this function.
+@Input pvDst void pointer to the destination memory
+@Input pvSrc void pointer to the source memory
+@Input ui32Size the number of bytes to be copied
+@Return None
+ */ /**************************************************************************/
+void DeviceMemCopy(void *pvDst, const void *pvSrc, size_t ui32Size);
+
+/**************************************************************************/ /*!
+@Function DeviceMemSetBytes
+@Description Potentially very slow (but safe) memset fallback for non-GNU C
+ compilers for arm64/aarch64
+@Input pvDest void pointer to the memory to be set
+@Input ui8Value byte containing the value to be set
+@Input ui32Size the number of bytes to be set to the given value
+@Return None
+ */ /**************************************************************************/
+void DeviceMemSetBytes(void *pvDest, IMG_UINT8 ui8Value, size_t ui32Size);
+
+/**************************************************************************/ /*!
+@Function DeviceMemCopyBytes
+@Description Potentially very slow (but safe) memcpy fallback for non-GNU C
+ compilers for arm64/aarch64
+@Input pvDst void pointer to the destination memory
+@Input pvSrc void pointer to the source memory
+@Input ui32Size the number of bytes to be copied
+@Return None
+ */ /**************************************************************************/
+void DeviceMemCopyBytes(void *pvDst, const void *pvSrc, size_t ui32Size);
+
+/**************************************************************************/ /*!
+@Function StringLCopy
+@Description Copy at most uDataSize-1 bytes from pszSrc to pszDest.
+ If no null byte ('\0') is contained within the first uDataSize-1
+ characters of the source string, the destination string will be
+ truncated. If the length of the source string is less than uDataSize
+ an additional NUL byte will be copied to the destination string
+ to ensure that the string is NUL-terminated.
+@Input pszDest char pointer to the destination string
+@Input pszSrc const char pointer to the source string
+@Input uDataSize the maximum number of bytes to be copied
+@Return Size of the source string
+ */ /**************************************************************************/
+size_t StringLCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc, size_t uDataSize);
+
+#if defined(__arm64__) || defined(__aarch64__) || defined(PVRSRV_DEVMEM_TEST_SAFE_MEMSETCPY)
+#if defined(__GNUC__)
+/* Workarounds for assumptions made that memory will not be mapped uncached
+ * in kernel or user address spaces on arm64 platforms (or other testing).
+ */
+
+#define OSDeviceMemSet(a,b,c) DeviceMemSet((a), (b), (c))
+#define OSDeviceMemCopy(a,b,c) DeviceMemCopy((a), (b), (c))
+
+#else /* defined __GNUC__ */
+
+#define OSDeviceMemSet(a,b,c) DeviceMemSetBytes((a), (b), (c))
+#define OSDeviceMemCopy(a,b,c) DeviceMemCopyBytes((a), (b), (c))
+
+#endif /* defined __GNUC__ */
+
+#else /* (defined(__arm64__) || defined(__aarch64__) || defined(PVRSRV_DEVMEM_TEST_SAFE_MEMSETCPY)) */
+
+/* Everything else */
+
+/**************************************************************************/ /*!
+@Function OSDeviceMemSet
+@Description Set memory, whose mapping may be uncached, to a given value.
+ On some architectures, additional processing may be needed
+ if the mapping is uncached.
+@Input a void pointer to the memory to be set
+@Input b byte containing the value to be set
+@Input c the number of bytes to be set to the given value
+@Return Pointer to the destination memory.
+ */ /**************************************************************************/
+#define OSDeviceMemSet(a,b,c) memset((a), (b), (c))
+
+/**************************************************************************/ /*!
+@Function OSDeviceMemCopy
+@Description Copy values from one area of memory, to another, when one
+ or both mappings may be uncached.
+ On some architectures, additional processing may be needed
+ if mappings are uncached.
+@Input a void pointer to the destination memory
+@Input b void pointer to the source memory
+@Input c the number of bytes to be copied
+@Return Pointer to the destination memory.
+ */ /**************************************************************************/
+#define OSDeviceMemCopy(a,b,c) memcpy((a), (b), (c))
+
+#endif /* (defined(__arm64__) || defined(__aarch64__) || defined(PVRSRV_DEVMEM_TEST_SAFE_MEMSETCPY)) */
+
+/**************************************************************************/ /*!
+@Function OSCachedMemSet
+@Description Set memory, where the mapping is known to be cached, to a
+ given value. This function exists to allow an optimal memset
+ to be performed when memory is known to be cached.
+@Input a void pointer to the memory to be set
+@Input b byte containing the value to be set
+@Input c the number of bytes to be set to the given value
+@Return Pointer to the destination memory.
+ */ /**************************************************************************/
+#define OSCachedMemSet(a,b,c) memset((a), (b), (c))
+
+/**************************************************************************/ /*!
+@Function OSCachedMemCopy
+@Description Copy values from one area of memory, to another, when both
+ mappings are known to be cached.
+ This function exists to allow an optimal memcpy to be
+ performed when memory is known to be cached.
+@Input a void pointer to the destination memory
+@Input b void pointer to the source memory
+@Input c the number of bytes to be copied
+@Return Pointer to the destination memory.
+ */ /**************************************************************************/
+#define OSCachedMemCopy(a,b,c) memcpy((a), (b), (c))
+
+#if defined(__KERNEL__)
+
+/**************************************************************************/ /*!
+@Function OSCachedMemSetWMB
+@Description Set memory, where the mapping is known to be cached or
+ write-combine, to a given value and issue a write memory barrier
+ after. This
+ function exists to allow an optimal memset to be performed when
+ memory is known to be cached or write-combine.
+@Input a void pointer to the memory to be set
+@Input b byte containing the value to be set
+@Input c the number of bytes to be set to the given value
+@Return Pointer to the destination memory.
+ */ /**************************************************************************/
+#define OSCachedMemSetWMB(a,b,c) \
+ do { \
+ (void) memset((a), (b), (c)); \
+ OSWriteMemoryBarrier(); \
+ } while (0)
+
+/**************************************************************************/ /*!
+@Function OSCachedMemCopy
+@Description Copy values from one area of memory, to another, when both
+ mappings are known to be cached or write-combine and issue
+ a write memory barrier after.
+ This function exists to allow an optimal memcpy to be
+ performed when memory is known to be cached or write-combine.
+@Input a void pointer to the destination memory
+@Input b void pointer to the source memory
+@Input c the number of bytes to be copied
+@Return Pointer to the destination memory.
+ */ /**************************************************************************/
+#define OSCachedMemCopyWMB(a,b,c) \
+ do { \
+ (void) memcpy((a), (b), (c)); \
+ OSWriteMemoryBarrier(); \
+ } while (0)
+
+#endif /* defined(__KERNEL__) */
+
+/**************************************************************************/ /*!
+@Function OSStringLCopy
+@Description Copy at most uDataSize-1 bytes from pszSrc to pszDest.
+ If no null byte ('\0') is contained within the first uDataSize-1
+ characters of the source string, the destination string will be
+ truncated. If the length of the source string is less than uDataSize
+ an additional NUL byte will be copied to the destination string
+ to ensure that the string is NUL-terminated.
+@Input a char pointer to the destination string
+@Input b const char pointer to the source string
+@Input c the maximum number of bytes to be copied
+@Return Size of the source string
+ */ /**************************************************************************/
+#if defined(__QNXNTO__) || (defined(__linux__) && defined(__KERNEL__) && !defined(DEBUG))
+#define OSStringLCopy(a,b,c) strlcpy((a), (b), (c))
+#else /* defined(__QNXNTO__) ... */
+#define OSStringLCopy(a,b,c) StringLCopy((a), (b), (c))
+#endif /* defined(__QNXNTO__) ... */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OSFUNC_COMMON_H */
+
+/******************************************************************************
+ End of file (osfunc_common.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/pdumpdefs.h b/drivers/gpu/drm/img-rogue/include/pdumpdefs.h
new file mode 100644
index 000000000..3f8cccabc
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/pdumpdefs.h
@@ -0,0 +1,249 @@
+/*************************************************************************/ /*!
+@File
+@Title PDUMP definitions header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description PDUMP definitions header
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef PDUMPDEFS_H
+#define PDUMPDEFS_H
+
+/*! PDump Pixel Format Enumeration */
+typedef enum _PDUMP_PIXEL_FORMAT_
+{
+ PVRSRV_PDUMP_PIXEL_FORMAT_UNSUPPORTED = 0,
+ PVRSRV_PDUMP_PIXEL_FORMAT_RGB8 = 1,
+ PVRSRV_PDUMP_PIXEL_FORMAT_RGB332 = 2,
+ PVRSRV_PDUMP_PIXEL_FORMAT_KRGB555 = 3,
+ PVRSRV_PDUMP_PIXEL_FORMAT_RGB565 = 4,
+ PVRSRV_PDUMP_PIXEL_FORMAT_ARGB4444 = 5,
+ PVRSRV_PDUMP_PIXEL_FORMAT_ARGB1555 = 6,
+ PVRSRV_PDUMP_PIXEL_FORMAT_RGB888 = 7,
+ PVRSRV_PDUMP_PIXEL_FORMAT_ARGB8888 = 8,
+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV8 = 9,
+/* PVRSRV_PDUMP_PIXEL_FORMAT_AYUV4444 = 10, */
+ PVRSRV_PDUMP_PIXEL_FORMAT_VY0UY1_8888 = 11,
+ PVRSRV_PDUMP_PIXEL_FORMAT_UY0VY1_8888 = 12,
+ PVRSRV_PDUMP_PIXEL_FORMAT_Y0UY1V_8888 = 13,
+ PVRSRV_PDUMP_PIXEL_FORMAT_Y0VY1U_8888 = 14,
+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV888 = 15,
+ PVRSRV_PDUMP_PIXEL_FORMAT_UYVY10101010 = 16,
+ PVRSRV_PDUMP_PIXEL_FORMAT_VYAUYA8888 = 17,
+ PVRSRV_PDUMP_PIXEL_FORMAT_AYUV8888 = 18,
+ PVRSRV_PDUMP_PIXEL_FORMAT_AYUV2101010 = 19,
+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV101010 = 20,
+ PVRSRV_PDUMP_PIXEL_FORMAT_PL12Y8 = 21,
+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV_IMC2 = 22,
+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV_YV12 = 23,
+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV_PL8 = 24,
+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV_PL12 = 25,
+ PVRSRV_PDUMP_PIXEL_FORMAT_422PL12YUV8 = 26,
+ PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV8 = 27,
+ PVRSRV_PDUMP_PIXEL_FORMAT_PL12Y10 = 28,
+ PVRSRV_PDUMP_PIXEL_FORMAT_422PL12YUV10 = 29,
+ PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV10 = 30,
+ PVRSRV_PDUMP_PIXEL_FORMAT_ABGR8888 = 31,
+ PVRSRV_PDUMP_PIXEL_FORMAT_BGRA8888 = 32,
+ PVRSRV_PDUMP_PIXEL_FORMAT_ARGB8332 = 33,
+ PVRSRV_PDUMP_PIXEL_FORMAT_RGB555 = 34,
+ PVRSRV_PDUMP_PIXEL_FORMAT_F16 = 35,
+ PVRSRV_PDUMP_PIXEL_FORMAT_F32 = 36,
+ PVRSRV_PDUMP_PIXEL_FORMAT_L16 = 37,
+ PVRSRV_PDUMP_PIXEL_FORMAT_L32 = 38,
+ PVRSRV_PDUMP_PIXEL_FORMAT_RGBA8888 = 39,
+ PVRSRV_PDUMP_PIXEL_FORMAT_ABGR4444 = 40,
+ PVRSRV_PDUMP_PIXEL_FORMAT_RGBA4444 = 41,
+ PVRSRV_PDUMP_PIXEL_FORMAT_BGRA4444 = 42,
+ PVRSRV_PDUMP_PIXEL_FORMAT_ABGR1555 = 43,
+ PVRSRV_PDUMP_PIXEL_FORMAT_RGBA5551 = 44,
+ PVRSRV_PDUMP_PIXEL_FORMAT_BGRA5551 = 45,
+ PVRSRV_PDUMP_PIXEL_FORMAT_BGR565 = 46,
+ PVRSRV_PDUMP_PIXEL_FORMAT_A8 = 47,
+ PVRSRV_PDUMP_PIXEL_FORMAT_F16F16F16F16 = 49,
+ PVRSRV_PDUMP_PIXEL_FORMAT_A4 = 50,
+ PVRSRV_PDUMP_PIXEL_FORMAT_ARGB2101010 = 51,
+ PVRSRV_PDUMP_PIXEL_FORMAT_RSGSBS888 = 52,
+ PVRSRV_PDUMP_PIXEL_FORMAT_F32F32F32F32 = 53,
+ PVRSRV_PDUMP_PIXEL_FORMAT_F16F16 = 54,
+ PVRSRV_PDUMP_PIXEL_FORMAT_F32F32 = 55,
+ PVRSRV_PDUMP_PIXEL_FORMAT_F16F16F16 = 56,
+ PVRSRV_PDUMP_PIXEL_FORMAT_F32F32F32 = 57,
+ PVRSRV_PDUMP_PIXEL_FORMAT_U8 = 58,
+ PVRSRV_PDUMP_PIXEL_FORMAT_U8U8 = 59,
+ PVRSRV_PDUMP_PIXEL_FORMAT_U16 = 60,
+ PVRSRV_PDUMP_PIXEL_FORMAT_U16U16 = 61,
+ PVRSRV_PDUMP_PIXEL_FORMAT_U16U16U16U16 = 62,
+ PVRSRV_PDUMP_PIXEL_FORMAT_U32 = 63,
+ PVRSRV_PDUMP_PIXEL_FORMAT_U32U32 = 64,
+ PVRSRV_PDUMP_PIXEL_FORMAT_U32U32U32U32 = 65,
+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV_YV32 = 66,
+
+ PVRSRV_PDUMP_PIXEL_FORMAT_FORCE_I32 = 0x7fffffff
+
+} PDUMP_PIXEL_FORMAT;
+
+typedef enum _PDUMP_FBC_SWIZZLE_
+{
+ PVRSRV_PDUMP_FBC_SWIZZLE_ARGB = 0x0,
+ PVRSRV_PDUMP_FBC_SWIZZLE_ARBG = 0x1,
+ PVRSRV_PDUMP_FBC_SWIZZLE_AGRB = 0x2,
+ PVRSRV_PDUMP_FBC_SWIZZLE_AGBR = 0x3,
+ PVRSRV_PDUMP_FBC_SWIZZLE_ABGR = 0x4,
+ PVRSRV_PDUMP_FBC_SWIZZLE_ABRG = 0x5,
+ PVRSRV_PDUMP_FBC_SWIZZLE_RGBA = 0x8,
+ PVRSRV_PDUMP_FBC_SWIZZLE_RBGA = 0x9,
+ PVRSRV_PDUMP_FBC_SWIZZLE_GRBA = 0xA,
+ PVRSRV_PDUMP_FBC_SWIZZLE_GBRA = 0xB,
+ PVRSRV_PDUMP_FBC_SWIZZLE_BGRA = 0xC,
+ PVRSRV_PDUMP_FBC_SWIZZLE_BRGA = 0xD,
+} PDUMP_FBC_SWIZZLE;
+
+/*! PDump addrmode */
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT 0
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_MASK 0x000000FF
+
+#define PVRSRV_PDUMP_ADDRMODE_STRIDESENSE_SHIFT 8
+#define PVRSRV_PDUMP_ADDRMODE_STRIDESENSE_NEGATIVE (1U << PVRSRV_PDUMP_ADDRMODE_STRIDESENSE_SHIFT)
+
+#define PVRSRV_PDUMP_ADDRMODE_BIFTILE_MODE_SHIFT 12
+#define PVRSRV_PDUMP_ADDRMODE_BIFTILE_MODE_MASK 0x000FF000
+
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT 20
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_MASK 0x00F00000
+
+#define PVRSRV_PDUMP_ADDRMODE_FBCDECOR_SHIFT 24
+#define PVRSRV_PDUMP_ADDRMODE_FBCLOSSY_SHIFT 25
+
+#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT 28
+#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_MASK 0xF0000000
+
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_STRIDE (0U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE1 (1U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE2 (2U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE3 (3U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE4 (4U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE5 (5U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE6 (6U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_BIFTILE_STRIDE7 (7U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_TWIDDLED (9U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_PAGETILED (11U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_ZTWIDDLED (12U << PVRSRV_PDUMP_ADDRMODE_MEMFORMAT_SHIFT)
+
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_NONE (0U << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_8X8_DIRECT (1U << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_16X4_DIRECT (2U << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_32X2_DIRECT (3U << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_8X8_INDIRECT (4U << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_16X4_INDIRECT (5U << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_8X8_INDIRECT_4TILE (6U << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCMODE_16X4_INDIRECT_4TILE (7U << PVRSRV_PDUMP_ADDRMODE_FBCMODE_SHIFT)
+
+#define PVRSRV_PDUMP_ADDRMODE_FBC_DECOR (1U << PVRSRV_PDUMP_ADDRMODE_FBCDECOR_SHIFT)
+
+#define PVRSRV_PDUMP_ADDRMODE_FBC_LOSSY (1U << PVRSRV_PDUMP_ADDRMODE_FBCLOSSY_SHIFT)
+
+#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_BASE (1U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_ENHANCED (2U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_V2 (3U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_V3_SURFACE (4U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_V3_RESOURCE (5U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_V3_1_SURFACE (6U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_V3_1_RESOURCE (7U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_V4 (8U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_V4PLUS (9U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT)
+#define PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_TFBCDC (10U << PVRSRV_PDUMP_ADDRMODE_FBCCOMPAT_SHIFT)
+
+/*! PDump Poll Operator */
+typedef enum _PDUMP_POLL_OPERATOR
+{
+ PDUMP_POLL_OPERATOR_EQUAL = 0,
+ PDUMP_POLL_OPERATOR_LESS = 1,
+ PDUMP_POLL_OPERATOR_LESSEQUAL = 2,
+ PDUMP_POLL_OPERATOR_GREATER = 3,
+ PDUMP_POLL_OPERATOR_GREATEREQUAL = 4,
+ PDUMP_POLL_OPERATOR_NOTEQUAL = 5,
+} PDUMP_POLL_OPERATOR;
+
+
+#define PVRSRV_PDUMP_MAX_FILENAME_SIZE 75 /*!< Max length of a pdump log file name */
+#define PVRSRV_PDUMP_MAX_COMMENT_SIZE 350 /*!< Max length of a pdump comment */
+
+/*!
+ PDump MMU type
+ (Maps to values listed in "PowerVR Tools.Pdump2 Script Functions.doc" Sec 2.13)
+*/
+typedef enum
+{
+ PDUMP_MMU_TYPE_4KPAGE_32BIT_STDTILE = 1,
+ PDUMP_MMU_TYPE_VARPAGE_32BIT_STDTILE = 2,
+ PDUMP_MMU_TYPE_4KPAGE_36BIT_EXTTILE = 3,
+ PDUMP_MMU_TYPE_4KPAGE_32BIT_EXTTILE = 4,
+ PDUMP_MMU_TYPE_4KPAGE_36BIT_STDTILE = 5,
+ PDUMP_MMU_TYPE_VARPAGE_40BIT = 6,
+ PDUMP_MMU_TYPE_VIDEO_40BIT_STDTILE = 7,
+ PDUMP_MMU_TYPE_VIDEO_40BIT_EXTTILE = 8,
+ PDUMP_MMU_TYPE_MIPS_MICROAPTIV = 9,
+ PDUMP_MMU_TYPE_LAST
+} PDUMP_MMU_TYPE;
+
+/*!
+ PDump states
+ These values are used by the bridge call PVRSRVPDumpGetState
+*/
+#define PDUMP_STATE_CAPTURE_FRAME (1U) /*!< Flag represents the PDump being in capture range or not*/
+#define PDUMP_STATE_CONNECTED (2U) /*!< Flag represents the PDump Client App being connected on not */
+#define PDUMP_STATE_SUSPENDED (4U) /*!< Flag represents the PDump being suspended or not */
+#define PDUMP_STATE_CAPTURE_IN_INTERVAL (8U) /*!< Flag represents the PDump being in a capture range interval */
+
+/*!
+ PDump Capture modes
+ Values used with calls to PVRSRVPDumpSetDefaultCaptureParams
+*/
+#define PDUMP_CAPMODE_UNSET 0x00000000UL
+#define PDUMP_CAPMODE_FRAMED 0x00000001UL
+#define PDUMP_CAPMODE_CONTINUOUS 0x00000002UL
+#define PDUMP_CAPMODE_BLOCKED 0x00000003UL
+
+#define PDUMP_CAPMODE_MAX PDUMP_CAPMODE_BLOCKED
+
+#endif /* PDUMPDEFS_H */
+
+/*****************************************************************************
+ End of file (pdumpdefs.h)
+*****************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/pdumpdesc.h b/drivers/gpu/drm/img-rogue/include/pdumpdesc.h
new file mode 100644
index 000000000..d159bf4ee
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/pdumpdesc.h
@@ -0,0 +1,226 @@
+/*************************************************************************/ /*!
+@File pdumpdesc.h
+@Title PDump Descriptor format
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Describes PDump descriptors that may be passed to the
+ extraction routines (SAB).
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(PDUMPDESC_H)
+#define PDUMPDESC_H
+
+#include "pdumpdefs.h"
+
+/*
+ * Common fields
+ */
+#define HEADER_WORD0_TYPE_SHIFT (0)
+#define HEADER_WORD0_TYPE_CLRMSK (0xFFFFFFFFU)
+
+#define HEADER_WORD1_SIZE_SHIFT (0)
+#define HEADER_WORD1_SIZE_CLRMSK (0x0000FFFFU)
+#define HEADER_WORD1_VERSION_SHIFT (16)
+#define HEADER_WORD1_VERSION_CLRMSK (0xFFFF0000U)
+
+#define HEADER_WORD2_DATA_SIZE_SHIFT (0)
+#define HEADER_WORD2_DATA_SIZE_CLRMSK (0xFFFFFFFFU)
+
+
+/*
+ * The image type descriptor
+ */
+
+/*
+ * Header type (IMGBv2) - 'IMGB' in hex + VERSION 2
+ * Header size - 64 bytes
+ */
+#define IMAGE_HEADER_TYPE (0x42474D49)
+#define IMAGE_HEADER_SIZE (64)
+#define IMAGE_HEADER_VERSION (2)
+
+/*
+ * Image type-specific fields
+ */
+#define IMAGE_HEADER_WORD3_LOGICAL_WIDTH_SHIFT (0)
+#define IMAGE_HEADER_WORD3_LOGICAL_WIDTH_CLRMSK (0xFFFFFFFFU)
+
+#define IMAGE_HEADER_WORD4_LOGICAL_HEIGHT_SHIFT (0)
+#define IMAGE_HEADER_WORD4_LOGICAL_HEIGHT_CLRMSK (0xFFFFFFFFU)
+
+#define IMAGE_HEADER_WORD5_FORMAT_SHIFT (0)
+#define IMAGE_HEADER_WORD5_FORMAT_CLRMSK (0xFFFFFFFFU)
+
+#define IMAGE_HEADER_WORD6_PHYSICAL_WIDTH_SHIFT (0)
+#define IMAGE_HEADER_WORD6_PHYSICAL_WIDTH_CLRMSK (0xFFFFFFFFU)
+
+#define IMAGE_HEADER_WORD7_PHYSICAL_HEIGHT_SHIFT (0)
+#define IMAGE_HEADER_WORD7_PHYSICAL_HEIGHT_CLRMSK (0xFFFFFFFFU)
+
+#define IMAGE_HEADER_WORD8_TWIDDLING_SHIFT (0)
+#define IMAGE_HEADER_WORD8_TWIDDLING_CLRMSK (0x000000FFU)
+#define IMAGE_HEADER_WORD8_TWIDDLING_STRIDED (0 << IMAGE_HEADER_WORD8_TWIDDLING_SHIFT)
+#define IMAGE_HEADER_WORD8_TWIDDLING_NTWIDDLE (9 << IMAGE_HEADER_WORD8_TWIDDLING_SHIFT)
+#define IMAGE_HEADER_WORD8_TWIDDLING_ZTWIDDLE (12 << IMAGE_HEADER_WORD8_TWIDDLING_SHIFT)
+
+
+#define IMAGE_HEADER_WORD8_STRIDE_SHIFT (8)
+#define IMAGE_HEADER_WORD8_STRIDE_CLRMSK (0x0000FF00U)
+#define IMAGE_HEADER_WORD8_STRIDE_POSITIVE (0 << IMAGE_HEADER_WORD8_STRIDE_SHIFT)
+#define IMAGE_HEADER_WORD8_STRIDE_NEGATIVE (1 << IMAGE_HEADER_WORD8_STRIDE_SHIFT)
+
+#define IMAGE_HEADER_WORD8_BIFTYPE_SHIFT (16)
+#define IMAGE_HEADER_WORD8_BIFTYPE_CLRMSK (0x00FF0000U)
+#define IMAGE_HEADER_WORD8_BIFTYPE_NONE (0 << IMAGE_HEADER_WORD8_BIFTYPE_SHIFT)
+
+#define IMAGE_HEADER_WORD8_FBCTYPE_SHIFT (24)
+#define IMAGE_HEADER_WORD8_FBCTYPE_CLRMSK (0xFF000000U)
+#define IMAGE_HEADER_WORD8_FBCTYPE_8X8 (1 << IMAGE_HEADER_WORD8_FBCTYPE_SHIFT)
+#define IMAGE_HEADER_WORD8_FBCTYPE_16x4 (2 << IMAGE_HEADER_WORD8_FBCTYPE_SHIFT)
+#define IMAGE_HEADER_WORD8_FBCTYPE_32x2 (3 << IMAGE_HEADER_WORD8_FBCTYPE_SHIFT)
+
+#define IMAGE_HEADER_WORD9_FBCDECOR_SHIFT (0)
+#define IMAGE_HEADER_WORD9_FBCDECOR_CLRMSK (0x000000FFU)
+#define IMAGE_HEADER_WORD9_FBCDECOR_ENABLE (1 << IMAGE_HEADER_WORD9_FBCDECOR_SHIFT)
+
+/* Align with fbcomp_export_c.h in pdump_tools branch */
+#define IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT (8)
+#define IMAGE_HEADER_WORD9_FBCCOMPAT_CLRMSK (0x0000FF00U)
+#define IMAGE_HEADER_WORD9_FBCCOMPAT_SAME_AS_GPU (0 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT)
+#define IMAGE_HEADER_WORD9_FBCCOMPAT_BASE (1 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT)
+#define IMAGE_HEADER_WORD9_FBCCOMPAT_TWIDDLED_EN (2 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT) /* TWIDDLED_ENHANCED */
+#define IMAGE_HEADER_WORD9_FBCCOMPAT_V2 (3 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT)
+#define IMAGE_HEADER_WORD9_FBCCOMPAT_V3_0_LAYOUT1 (4 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT)
+#define IMAGE_HEADER_WORD9_FBCCOMPAT_V3_0_LAYOUT2 (5 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT) /* V30_WITH_HEADER_REMAP */
+#define IMAGE_HEADER_WORD9_FBCCOMPAT_V3_1_LAYOUT1 (6 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT)
+#define IMAGE_HEADER_WORD9_FBCCOMPAT_V3_1_LAYOUT2 (7 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT) /* V31_WITH_HEADER_REMAP */
+#define IMAGE_HEADER_WORD9_FBCCOMPAT_V4 (8 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT)
+#define IMAGE_HEADER_WORD9_FBCCOMPAT_V4_PLUS (9 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT)
+#define IMAGE_HEADER_WORD9_FBCCOMPAT_TFBC (10 << IMAGE_HEADER_WORD9_FBCCOMPAT_SHIFT)
+
+#define IMAGE_HEADER_WORD9_LOSSY_SHIFT (16)
+#define IMAGE_HEADER_WORD9_LOSSY_CLRMSK (0x00FF0000U)
+/* Non-TFBC */
+#define IMAGE_HEADER_WORD9_LOSSY_ON (1 << IMAGE_HEADER_WORD9_LOSSY_SHIFT)
+
+/* TFBC */
+#define IMAGE_HEADER_WORD9_LOSSY_75 (1 << IMAGE_HEADER_WORD9_LOSSY_SHIFT)
+#define IMAGE_HEADER_WORD9_LOSSY_37 (1 << IMAGE_HEADER_WORD9_LOSSY_SHIFT)
+#define IMAGE_HEADER_WORD9_LOSSY_50 (2 << IMAGE_HEADER_WORD9_LOSSY_SHIFT)
+#define IMAGE_HEADER_WORD9_LOSSY_25 (3 << IMAGE_HEADER_WORD9_LOSSY_SHIFT)
+#define IMAGE_HEADER_WORD9_LOSSY_OFF (0 << IMAGE_HEADER_WORD9_LOSSY_SHIFT)
+
+#define IMAGE_HEADER_WORD9_SWIZZLE_SHIFT (24)
+#define IMAGE_HEADER_WORD9_SWIZZLE_CLRMSK (0xFF000000U)
+#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_ARGB (0x0 << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT)
+#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_ARBG (0x1 << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT)
+#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_AGRB (0x2 << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT)
+#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_AGBR (0x3 << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT)
+#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_ABGR (0x4 << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT)
+#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_ABRG (0x5 << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT)
+#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_RGBA (0x8 << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT)
+#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_RBGA (0x9 << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT)
+#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_GRBA (0xA << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT)
+#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_GBRA (0xB << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT)
+#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_BGRA (0xC << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT)
+#define IMAGE_HEADER_WORD9_SWIZZLE_MODE_BRGA (0xD << IMAGE_HEADER_WORD9_SWIZZLE_SHIFT)
+
+#define IMAGE_HEADER_WORD10_FBCCLEAR_CH0_SHIFT (0)
+#define IMAGE_HEADER_WORD10_FBCCLEAR_CH0_CLRMSK (0xFFFFFFFFU)
+
+#define IMAGE_HEADER_WORD11_FBCCLEAR_CH1_SHIFT (0)
+#define IMAGE_HEADER_WORD11_FBCCLEAR_CH1_CLRMSK (0xFFFFFFFFU)
+
+#define IMAGE_HEADER_WORD12_FBCCLEAR_CH2_SHIFT (0)
+#define IMAGE_HEADER_WORD12_FBCCLEAR_CH2_CLRMSK (0xFFFFFFFFU)
+
+#define IMAGE_HEADER_WORD13_FBCCLEAR_CH3_SHIFT (0)
+#define IMAGE_HEADER_WORD13_FBCCLEAR_CH3_CLRMSK (0xFFFFFFFFU)
+
+#define IMAGE_HEADER_WORD14_TFBC_GROUP_SHIFT (0)
+#define IMAGE_HEADER_WORD14_TFBC_GROUP_CLRMSK (0x000000FFU)
+#define IMAGE_HEADER_WORD14_TFBC_GROUP_25_50_75 (0 << IMAGE_HEADER_WORD14_TFBC_GROUP_SHIFT)
+#define IMAGE_HEADER_WORD14_TFBC_GROUP_25_37_50 (1 << IMAGE_HEADER_WORD14_TFBC_GROUP_SHIFT)
+
+#define IMAGE_HEADER_WORD14_COMP_SCHEME_SHIFT (8)
+#define IMAGE_HEADER_WORD14_COMP_SCHEME_CLRMSK (0x0000FF00U)
+#define IMAGE_HEADER_WORD14_COMP_SCHEME_ALL (0 << IMAGE_HEADER_WORD14_COMP_SCHEME_SHIFT)
+#define IMAGE_HEADER_WORD14_COMP_SCHEME_D_STD_CORR (1 << IMAGE_HEADER_WORD14_COMP_SCHEME_SHIFT)
+#define IMAGE_HEADER_WORD14_COMP_SCHEME_D_STD_ONLY (2 << IMAGE_HEADER_WORD14_COMP_SCHEME_SHIFT)
+#define IMAGE_HEADER_WORD14_COMP_SCHEME_PTC_ONLY (3 << IMAGE_HEADER_WORD14_COMP_SCHEME_SHIFT)
+
+#define IMAGE_HEADER_WORD14_YUV10_OPTIMAL_FMT_8_SHIFT (16)
+#define IMAGE_HEADER_WORD14_YUV10_OPTIMAL_FMT_8_CLRMSK (0x00FF0000U)
+#define IMAGE_HEADER_WORD14_YUV10_OPTIMAL_FMT_8_EN (1 << IMAGE_HEADER_WORD14_YUV10_OPTIMAL_FMT_8_SHIFT) /* Treat YUV10 optimal formats as 8 bits */
+
+/* IMAGE_HEADER_WORD15_RESERVED2 */
+
+/*
+ * The data type descriptor
+ */
+
+/*
+ * Header type (IMGCv1) - 'IMGC' in hex + VERSION 0
+ * Header size - 20 bytes (5 x 32 bit WORDS)
+ */
+#define DATA_HEADER_TYPE (0x43474D49)
+#define DATA_HEADER_SIZE (20)
+#define DATA_HEADER_VERSION (0)
+
+/*
+ * The IBIN type descriptor
+ */
+
+/*
+ * Header type (IBIN) - 'IBIN' in hex + VERSION 0
+ * Header size - 12 bytes (3 x 32 bit WORDS)
+ */
+#define IBIN_HEADER_TYPE (0x4e494249)
+#define IBIN_HEADER_SIZE (12)
+#define IBIN_HEADER_VERSION (0)
+
+/*
+ * Data type-specific fields
+ */
+#define DATA_HEADER_WORD3_ELEMENT_TYPE_SHIFT (0)
+#define DATA_HEADER_WORD3_ELEMENT_TYPE_CLRMSK (0xFFFFFFFFU)
+
+#define DATA_HEADER_WORD4_ELEMENT_COUNT_SHIFT (0)
+#define DATA_HEADER_WORD4_ELEMENT_COUNT_CLRMSK (0xFFFFFFFFU)
+
+#endif /* PDUMPDESC_H */
diff --git a/drivers/gpu/drm/img-rogue/include/public/powervr/buffer_attribs.h b/drivers/gpu/drm/img-rogue/include/public/powervr/buffer_attribs.h
new file mode 100644
index 000000000..41eaaaecd
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/public/powervr/buffer_attribs.h
@@ -0,0 +1,193 @@
+/*************************************************************************/ /*!
+@File
+@Title 3D types for use by IMG APIs
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License MIT
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef POWERVR_BUFFER_ATTRIBS_H
+#define POWERVR_BUFFER_ATTRIBS_H
+
+/*!
+ * Memory layouts
+ * Defines how pixels are laid out within a surface.
+ */
+typedef enum
+{
+ IMG_MEMLAYOUT_STRIDED, /**< Resource is strided, one row at a time */
+ IMG_MEMLAYOUT_TWIDDLED, /**< Resource is 2D twiddled to match HW */
+ IMG_MEMLAYOUT_3DTWIDDLED, /**< Resource is 3D twiddled, classic style */
+ IMG_MEMLAYOUT_TILED, /**< Resource is tiled, tiling config specified elsewhere. */
+ IMG_MEMLAYOUT_PAGETILED, /**< Resource is pagetiled */
+ IMG_MEMLAYOUT_INVNTWIDDLED, /**< Resource is 2D twiddled !N style */
+} IMG_MEMLAYOUT;
+
+/*!
+ * Rotation types
+ */
+typedef enum
+{
+ IMG_ROTATION_0DEG = 0,
+ IMG_ROTATION_90DEG = 1,
+ IMG_ROTATION_180DEG = 2,
+ IMG_ROTATION_270DEG = 3,
+ IMG_ROTATION_FLIP_Y = 4,
+
+ IMG_ROTATION_BAD = 255,
+} IMG_ROTATION;
+
+/*!
+ * Alpha types.
+ */
+typedef enum
+{
+ IMG_COLOURSPACE_FORMAT_UNKNOWN = 0x0UL << 16,
+ IMG_COLOURSPACE_FORMAT_LINEAR = 0x1UL << 16,
+ IMG_COLOURSPACE_FORMAT_SRGB = 0x2UL << 16,
+ IMG_COLOURSPACE_FORMAT_SCRGB = 0x3UL << 16,
+ IMG_COLOURSPACE_FORMAT_SCRGB_LINEAR = 0x4UL << 16,
+ IMG_COLOURSPACE_FORMAT_DISPLAY_P3_LINEAR = 0x5UL << 16,
+ IMG_COLOURSPACE_FORMAT_DISPLAY_P3 = 0x6UL << 16,
+ IMG_COLOURSPACE_FORMAT_BT2020_PQ = 0x7UL << 16,
+ IMG_COLOURSPACE_FORMAT_BT2020_LINEAR = 0x8UL << 16,
+ IMG_COLOURSPACE_FORMAT_DISPLAY_P3_PASSTHROUGH = 0x9UL << 16,
+ IMG_COLOURSPACE_FORMAT_MASK = 0xFUL << 16,
+} IMG_COLOURSPACE_FORMAT;
+
+/*!
+ * Determines if FB Compression is Lossy
+ */
+#define IS_FBCDC_LOSSY(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_LOSSY50_8x8) ? IMG_TRUE : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY50_16x4) ? IMG_TRUE : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY50_32x2) ? IMG_TRUE : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY25_8x8) ? IMG_TRUE : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY25_16x4) ? IMG_TRUE : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY25_32x2) ? IMG_TRUE : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY37_8x8) ? IMG_TRUE : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY37_16x4) ? IMG_TRUE : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY37_32x2) ? IMG_TRUE : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY75_8x8) ? IMG_TRUE : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY75_16x4) ? IMG_TRUE : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY75_32x2) ? IMG_TRUE : IMG_FALSE)
+
+/*!
+ * Determines if FB Compression is Packed
+ */
+#define IS_FBCDC_PACKED(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_PACKED_8x8) ? IMG_TRUE : IMG_FALSE)
+
+/*!
+ * Returns type of FB Compression
+ */
+#define GET_FBCDC_BLOCK_TYPE(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_LOSSY50_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY50_16x4) ? IMG_FB_COMPRESSION_DIRECT_16x4 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY50_32x2) ? IMG_FB_COMPRESSION_DIRECT_32x2 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_PACKED_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY25_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY25_16x4) ? IMG_FB_COMPRESSION_DIRECT_16x4 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY25_32x2) ? IMG_FB_COMPRESSION_DIRECT_32x2 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY37_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY37_16x4) ? IMG_FB_COMPRESSION_DIRECT_16x4 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY37_32x2) ? IMG_FB_COMPRESSION_DIRECT_32x2 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY75_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY75_16x4) ? IMG_FB_COMPRESSION_DIRECT_16x4 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY75_32x2) ? IMG_FB_COMPRESSION_DIRECT_32x2 : mode)
+
+/*!
+ * Adds Packing compression setting to mode if viable
+ */
+#define FBCDC_MODE_ADD_PACKING(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_8x8) ? IMG_FB_COMPRESSION_DIRECT_PACKED_8x8 : mode)
+
+/*!
+ * Removes Packing compression setting from mode
+ */
+#define FBCDC_MODE_REMOVE_PACKING(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_PACKED_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : mode)
+
+/*!
+ * Adds Lossy25 compression setting to mode if viable
+ */
+#define FBCDC_MODE_ADD_LOSSY25(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_8x8) ? IMG_FB_COMPRESSION_DIRECT_LOSSY25_8x8 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_16x4) ? IMG_FB_COMPRESSION_DIRECT_LOSSY25_16x4 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_32x2) ? IMG_FB_COMPRESSION_DIRECT_LOSSY25_32x2 : mode)
+
+/*!
+ * Adds Lossy37 compression setting to mode if viable
+ */
+#define FBCDC_MODE_ADD_LOSSY37(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_8x8) ? IMG_FB_COMPRESSION_DIRECT_LOSSY37_8x8 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_16x4) ? IMG_FB_COMPRESSION_DIRECT_LOSSY37_16x4 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_32x2) ? IMG_FB_COMPRESSION_DIRECT_LOSSY37_32x2 : mode)
+
+/*!
+ * Adds Lossy50 compression setting to mode if viable
+ */
+#define FBCDC_MODE_ADD_LOSSY50(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_8x8) ? IMG_FB_COMPRESSION_DIRECT_LOSSY50_8x8 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_16x4) ? IMG_FB_COMPRESSION_DIRECT_LOSSY50_16x4 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_32x2) ? IMG_FB_COMPRESSION_DIRECT_LOSSY50_32x2 : mode)
+
+/*!
+ * Adds Lossy75 compression setting to mode if viable
+ */
+#define FBCDC_MODE_ADD_LOSSY75(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_8x8) ? IMG_FB_COMPRESSION_DIRECT_LOSSY75_8x8 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_16x4) ? IMG_FB_COMPRESSION_DIRECT_LOSSY75_16x4 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_32x2) ? IMG_FB_COMPRESSION_DIRECT_LOSSY75_32x2 : mode)
+
+/*!
+ * Removes Lossy compression setting from mode
+ */
+#define FBCDC_MODE_REMOVE_LOSSY(mode) ((mode == IMG_FB_COMPRESSION_DIRECT_LOSSY50_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY50_16x4) ? IMG_FB_COMPRESSION_DIRECT_16x4 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY50_32x2) ? IMG_FB_COMPRESSION_DIRECT_32x2 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY25_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY25_16x4) ? IMG_FB_COMPRESSION_DIRECT_16x4 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY25_32x2) ? IMG_FB_COMPRESSION_DIRECT_32x2 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY37_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY37_16x4) ? IMG_FB_COMPRESSION_DIRECT_16x4 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY37_32x2) ? IMG_FB_COMPRESSION_DIRECT_32x2 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY75_8x8) ? IMG_FB_COMPRESSION_DIRECT_8x8 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY75_16x4) ? IMG_FB_COMPRESSION_DIRECT_16x4 : \
+ (mode == IMG_FB_COMPRESSION_DIRECT_LOSSY75_32x2) ? IMG_FB_COMPRESSION_DIRECT_32x2 : mode)
+
+/*!
+ * Types of framebuffer compression
+ */
+typedef enum
+{
+ IMG_FB_COMPRESSION_NONE,
+ IMG_FB_COMPRESSION_DIRECT_8x8,
+ IMG_FB_COMPRESSION_DIRECT_16x4,
+ IMG_FB_COMPRESSION_DIRECT_32x2,
+ IMG_FB_COMPRESSION_DIRECT_LOSSY25_8x8,
+ IMG_FB_COMPRESSION_DIRECT_LOSSY25_16x4,
+ IMG_FB_COMPRESSION_DIRECT_LOSSY25_32x2,
+ IMG_FB_COMPRESSION_DIRECT_LOSSY75_8x8,
+ IMG_FB_COMPRESSION_DIRECT_LOSSY50_8x8,
+ IMG_FB_COMPRESSION_DIRECT_LOSSY50_16x4,
+ IMG_FB_COMPRESSION_DIRECT_LOSSY50_32x2,
+ IMG_FB_COMPRESSION_DIRECT_PACKED_8x8,
+ IMG_FB_COMPRESSION_DIRECT_LOSSY75_16x4,
+ IMG_FB_COMPRESSION_DIRECT_LOSSY75_32x2,
+ IMG_FB_COMPRESSION_DIRECT_LOSSY37_8x8,
+ IMG_FB_COMPRESSION_DIRECT_LOSSY37_16x4,
+ IMG_FB_COMPRESSION_DIRECT_LOSSY37_32x2,
+} IMG_FB_COMPRESSION;
+
+
+#endif /* POWERVR_BUFFER_ATTRIBS_H */
diff --git a/drivers/gpu/drm/img-rogue/include/public/powervr/img_drm_fourcc.h b/drivers/gpu/drm/img-rogue/include/public/powervr/img_drm_fourcc.h
new file mode 100644
index 000000000..4856a8d11
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/public/powervr/img_drm_fourcc.h
@@ -0,0 +1,137 @@
+/*************************************************************************/ /*!
+@File
+@Title Wrapper around drm_fourcc.h
+@Description FourCCs and DRM framebuffer modifiers that are not in the
+ Kernel's and libdrm's drm_fourcc.h can be added here.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License MIT
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef IMG_DRM_FOURCC_H
+#define IMG_DRM_FOURCC_H
+
+#if defined(__KERNEL__)
+#include
+#else
+/*
+ * Include types.h to workaround versions of libdrm older than 2.4.68
+ * not including the correct headers.
+ */
+#include
+
+#include
+#endif
+
+/*
+ * Don't get too inspired by this example :)
+ * ADF doesn't support DRM modifiers, so the memory layout had to be
+ * included in the fourcc name, but the proper way to specify information
+ * additional to pixel formats is to use DRM modifiers.
+ *
+ * See upstream drm_fourcc.h for the proper naming convention.
+ */
+#ifndef DRM_FORMAT_BGRA8888_DIRECT_16x4
+#define DRM_FORMAT_BGRA8888_DIRECT_16x4 fourcc_code('I', 'M', 'G', '0')
+#endif
+
+#if !defined(__KERNEL__)
+/*
+ * A definition for the same format was added in Linux kernel 5.2 in commit
+ * 88ab9c76d191ad8645b483f31e2b394b0f3e280e. As such, this definition has been
+ * deprecated and the DRM_FORMAT_ABGR16161616F kernel define should be used
+ * instead of this one.
+ */
+#define DRM_FORMAT_ABGR16_IMG_DEPRECATED fourcc_code('I', 'M', 'G', '1')
+#endif
+
+/*
+ * Upstream does not have a packed 10 Bits Per Channel YVU format yet,
+ * so let`s make one up.
+ * Note: at the moment this format is not intended to be used with
+ * a framebuffer, so the kernels core DRM doesn`t need to know
+ * about this format. This means that the kernel doesn`t need
+ * to be patched.
+ */
+#if !defined(__KERNEL__)
+#define DRM_FORMAT_YVU444_PACK10_IMG fourcc_code('I', 'M', 'G', '2')
+#define DRM_FORMAT_YUV422_2PLANE_PACK10_IMG fourcc_code('I', 'M', 'G', '3')
+#define DRM_FORMAT_YUV420_2PLANE_PACK10_IMG fourcc_code('I', 'M', 'G', '4')
+#endif
+
+/*
+ * Value chosen in the middle of 255 pool to minimise the chance of hitting
+ * the same value potentially defined by other vendors in the drm_fourcc.h
+ */
+#define DRM_FORMAT_MOD_VENDOR_PVR 0x92
+
+#ifndef DRM_FORMAT_MOD_VENDOR_NONE
+#define DRM_FORMAT_MOD_VENDOR_NONE 0
+#endif
+
+#ifndef DRM_FORMAT_RESERVED
+#define DRM_FORMAT_RESERVED ((1ULL << 56) - 1)
+#endif
+
+#define img_fourcc_mod_combine(uiModHi, uiModLo) \
+ ((__u64) ((__u32) (uiModHi)) << 32 | (__u64) ((__u32) (uiModLo)))
+
+#define img_fourcc_mod_hi(ui64Mod) \
+ ((__u32) ((__u64) (ui64Mod) >> 32))
+
+#define img_fourcc_mod_lo(ui64Mod) \
+ ((__u32) ((__u64) (ui64Mod)) & 0xffffffff)
+
+#ifndef fourcc_mod_code
+#define fourcc_mod_code(vendor, val) \
+ ((((__u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffULL))
+#endif
+
+#ifndef DRM_FORMAT_MOD_INVALID
+#define DRM_FORMAT_MOD_INVALID fourcc_mod_code(NONE, DRM_FORMAT_RESERVED)
+#endif
+
+#ifndef DRM_FORMAT_MOD_LINEAR
+#define DRM_FORMAT_MOD_LINEAR fourcc_mod_code(NONE, 0)
+#endif
+
+#define DRM_FORMAT_MOD_PVR_FBCDC_8x8_V7 fourcc_mod_code(PVR, 6)
+#define DRM_FORMAT_MOD_PVR_FBCDC_16x4_V7 fourcc_mod_code(PVR, 12)
+
+#define DRM_FORMAT_MOD_PVR_FBCDC_8x8_V10 fourcc_mod_code(PVR, 21)
+#define DRM_FORMAT_MOD_PVR_FBCDC_16x4_V10 fourcc_mod_code(PVR, 22)
+#define DRM_FORMAT_MOD_PVR_FBCDC_32x2_V10 fourcc_mod_code(PVR, 23)
+
+#define DRM_FORMAT_MOD_PVR_FBCDC_8x8_V12 fourcc_mod_code(PVR, 15)
+#define DRM_FORMAT_MOD_PVR_FBCDC_16x4_V12 fourcc_mod_code(PVR, 16)
+
+#define DRM_FORMAT_MOD_PVR_FBCDC_8x8_V13 fourcc_mod_code(PVR, 24)
+#define DRM_FORMAT_MOD_PVR_FBCDC_LOSSY25_8x8_V13 fourcc_mod_code(PVR, 25)
+#define DRM_FORMAT_MOD_PVR_FBCDC_LOSSY50_8x8_V13 fourcc_mod_code(PVR, 26)
+#define DRM_FORMAT_MOD_PVR_FBCDC_LOSSY75_8x8_V13 fourcc_mod_code(PVR, 27)
+
+#define DRM_FORMAT_MOD_PVR_FBCDC_16x4_V13 fourcc_mod_code(PVR, 28)
+#define DRM_FORMAT_MOD_PVR_FBCDC_LOSSY25_16x4_V13 fourcc_mod_code(PVR, 29)
+#define DRM_FORMAT_MOD_PVR_FBCDC_LOSSY50_16x4_V13 fourcc_mod_code(PVR, 30)
+#define DRM_FORMAT_MOD_PVR_FBCDC_LOSSY75_16x4_V13 fourcc_mod_code(PVR, 31)
+
+#endif /* IMG_DRM_FOURCC_H */
diff --git a/drivers/gpu/drm/img-rogue/include/public/powervr/mem_types.h b/drivers/gpu/drm/img-rogue/include/public/powervr/mem_types.h
new file mode 100644
index 000000000..a6dce8fe9
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/public/powervr/mem_types.h
@@ -0,0 +1,64 @@
+/*************************************************************************/ /*!
+@File
+@Title Public types
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License MIT
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef POWERVR_TYPES_H
+#define POWERVR_TYPES_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if defined(_MSC_VER)
+ #include "msvc_types.h"
+#elif defined(__linux__) && defined(__KERNEL__)
+ #include
+ #include
+#else
+ #include
+ #define __iomem
+#endif
+
+typedef void *IMG_CPU_VIRTADDR;
+
+/* device virtual address */
+typedef struct
+{
+ uint64_t uiAddr;
+#define IMG_CAST_TO_DEVVADDR_UINT(var) (uint64_t)(var)
+
+} IMG_DEV_VIRTADDR;
+
+typedef uint64_t IMG_DEVMEM_SIZE_T;
+typedef uint64_t IMG_DEVMEM_ALIGN_T;
+typedef uint64_t IMG_DEVMEM_OFFSET_T;
+typedef uint32_t IMG_DEVMEM_LOG2ALIGN_T;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/drivers/gpu/drm/img-rogue/include/public/powervr/pvrsrv_sync_ext.h b/drivers/gpu/drm/img-rogue/include/public/powervr/pvrsrv_sync_ext.h
new file mode 100644
index 000000000..30f797244
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/public/powervr/pvrsrv_sync_ext.h
@@ -0,0 +1,72 @@
+/*************************************************************************/ /*!
+@File
+@Title Services external synchronisation interface header
+@Description Defines synchronisation structures that are visible internally
+ and externally
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License MIT
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef POWERVR_SYNC_EXT_H
+#define POWERVR_SYNC_EXT_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ * Number of sync prims still used internally in operations
+ */
+#define PVRSRV_MAX_SYNC_PRIMS 4U
+
+/*!
+ * Maximum number of dev var updates passed in a kick call
+ */
+#define PVRSRV_MAX_DEV_VARS 13U
+
+/*!
+ * Number of UFOs in operations
+ */
+#define PVRSRV_MAX_SYNCS (PVRSRV_MAX_SYNC_PRIMS + PVRSRV_MAX_DEV_VARS)
+
+/*! Implementation independent types for passing fence/timeline to Services.
+ */
+typedef int32_t PVRSRV_FENCE;
+typedef int32_t PVRSRV_TIMELINE;
+
+/*! Maximum length for an annotation name string for fence sync model objects.
+ */
+#define PVRSRV_SYNC_NAME_LENGTH 32U
+
+/* Macros for API callers using the fence sync model
+ */
+#define PVRSRV_NO_TIMELINE ((PVRSRV_TIMELINE) -1)
+#define PVRSRV_NO_FENCE ((PVRSRV_FENCE) -1)
+#define PVRSRV_NO_FENCE_PTR NULL
+#define PVRSRV_NO_TIMELINE_PTR NULL
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/drivers/gpu/drm/img-rogue/include/pvr_buffer_sync_shared.h b/drivers/gpu/drm/img-rogue/include/pvr_buffer_sync_shared.h
new file mode 100644
index 000000000..7a110910d
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/pvr_buffer_sync_shared.h
@@ -0,0 +1,57 @@
+/*************************************************************************/ /*!
+@File
+@Title PVR buffer sync shared
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Shared definitions between client and server
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef PVR_BUFFER_SYNC_SHARED_H
+#define PVR_BUFFER_SYNC_SHARED_H
+
+#define PVR_BUFFER_FLAG_READ (1U << 0)
+#define PVR_BUFFER_FLAG_WRITE (1U << 1)
+#define PVR_BUFFER_FLAG_MASK (PVR_BUFFER_FLAG_READ | \
+ PVR_BUFFER_FLAG_WRITE)
+
+/* Maximum number of PMRs passed
+ * in a kick when using buffer sync
+ */
+#define PVRSRV_MAX_BUFFERSYNC_PMRS 32
+
+#endif /* PVR_BUFFER_SYNC_SHARED_H */
diff --git a/drivers/gpu/drm/img-rogue/include/pvr_debug.h b/drivers/gpu/drm/img-rogue/include/pvr_debug.h
new file mode 100644
index 000000000..003afd490
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/pvr_debug.h
@@ -0,0 +1,873 @@
+/*************************************************************************/ /*!
+@File
+@Title PVR Debug Declarations
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Provides debug functionality
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef PVR_DEBUG_H
+#define PVR_DEBUG_H
+
+#include "img_defs.h"
+#include "img_types.h"
+#include "pvrsrv_error.h"
+
+/*! @cond Doxygen_Suppress */
+#if defined(_MSC_VER)
+# define MSC_SUPPRESS_4127 __pragma(warning(suppress:4127))
+#else
+# define MSC_SUPPRESS_4127
+#endif
+/*! @endcond */
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define PVR_MAX_DEBUG_MESSAGE_LEN (512) /*!< Max length of a Debug Message */
+
+/* These are privately used by pvr_debug, use the PVR_DBG_ defines instead */
+#define DBGPRIV_FATAL 0x001UL /*!< Debug-Fatal. Privately used by pvr_debug. */
+#define DBGPRIV_ERROR 0x002UL /*!< Debug-Error. Privately used by pvr_debug. */
+#define DBGPRIV_WARNING 0x004UL /*!< Debug-Warning. Privately used by pvr_debug. */
+#define DBGPRIV_MESSAGE 0x008UL /*!< Debug-Message. Privately used by pvr_debug. */
+#define DBGPRIV_VERBOSE 0x010UL /*!< Debug-Verbose. Privately used by pvr_debug. */
+#define DBGPRIV_CALLTRACE 0x020UL /*!< Debug-CallTrace. Privately used by pvr_debug. */
+#define DBGPRIV_ALLOC 0x040UL /*!< Debug-Alloc. Privately used by pvr_debug. */
+#define DBGPRIV_BUFFERED 0x080UL /*!< Debug-Buffered. Privately used by pvr_debug. */
+#define DBGPRIV_DEBUG 0x100UL /*!< Debug-AdHoc-Debug. Never submitted. Privately used by pvr_debug. */
+#define DBGPRIV_LAST 0x100UL /*!< Always set to highest mask value. Privately used by pvr_debug. */
+
+/* Enable DPF logging for locally from some make targets */
+#if defined(PVRSRV_NEED_PVR_DPF_LOCAL)
+#undef PVRSRV_NEED_PVR_DPF
+#define PVRSRV_NEED_PVR_DPF
+#endif
+
+#if !defined(PVRSRV_NEED_PVR_ASSERT) && defined(DEBUG)
+#define PVRSRV_NEED_PVR_ASSERT
+#endif
+
+#if defined(PVRSRV_NEED_PVR_ASSERT) && !defined(PVRSRV_NEED_PVR_DPF)
+#define PVRSRV_NEED_PVR_DPF
+#endif
+
+#if !defined(PVRSRV_NEED_PVR_TRACE) && (defined(DEBUG) || defined(TIMING))
+#define PVRSRV_NEED_PVR_TRACE
+#endif
+
+#if !defined(DOXYGEN)
+/*************************************************************************/ /*
+PVRSRVGetErrorString
+Returns a string describing the provided PVRSRV_ERROR code
+NB No doxygen comments provided as this function does not require porting
+ for other operating systems
+*/ /**************************************************************************/
+const IMG_CHAR *PVRSRVGetErrorString(PVRSRV_ERROR eError);
+#define PVRSRVGETERRORSTRING PVRSRVGetErrorString
+#endif
+
+/* PVR_ASSERT() and PVR_DBG_BREAK handling */
+
+#if defined(__KLOCWORK__)
+/* A dummy no-return function to be used under Klocwork to mark unreachable
+ paths instead of abort() in order to avoid MISRA.STDLIB.ABORT issues. */
+__noreturn void klocwork_abort(void);
+#endif
+
+#if defined(PVRSRV_NEED_PVR_ASSERT) || defined(DOXYGEN)
+
+/* Unfortunately the Klocwork static analysis checker doesn't understand our
+ * ASSERT macros. Thus it reports lots of false positive. Defining our Assert
+ * macros in a special way when the code is analysed by Klocwork avoids
+ * them.
+ */
+#if defined(__KLOCWORK__)
+#define PVR_ASSERT(x) do { if (!(x)) {klocwork_abort();} } while (0)
+#else /* ! __KLOCWORKS__ */
+
+#if defined(_WIN32)
+#define PVR_ASSERT(expr) do \
+ { \
+ MSC_SUPPRESS_4127 \
+ if (unlikely(!(expr))) \
+ { \
+ PVRSRVDebugPrintf(DBGPRIV_FATAL, __FILE__, __LINE__,\
+ "*** Debug assertion failed!"); \
+ __debugbreak(); \
+ } \
+ MSC_SUPPRESS_4127 \
+ } while (0)
+
+#else
+
+#if defined(__linux__) && defined(__KERNEL__)
+#include
+#include
+
+/* In Linux kernel mode, use WARN_ON() directly. This produces the
+ * correct filename and line number in the warning message.
+ */
+#define PVR_ASSERT(EXPR) do \
+ { \
+ if (unlikely(!(EXPR))) \
+ { \
+ PVRSRVDebugPrintf(DBGPRIV_FATAL, __FILE__, __LINE__, \
+ "Debug assertion failed!"); \
+ WARN_ON(1); \
+ } \
+ } while (0)
+
+#else /* defined(__linux__) && defined(__KERNEL__) */
+
+/*************************************************************************/ /*!
+@Function PVRSRVDebugAssertFail
+@Description Indicate to the user that a debug assertion has failed and
+ prevent the program from continuing.
+ Invoked from the macro PVR_ASSERT().
+@Input pszFile The name of the source file where the assertion failed
+@Input ui32Line The line number of the failed assertion
+@Input pszAssertion String describing the assertion
+@Return NEVER!
+*/ /**************************************************************************/
+IMG_EXPORT void IMG_CALLCONV __noreturn
+PVRSRVDebugAssertFail(const IMG_CHAR *pszFile,
+ IMG_UINT32 ui32Line,
+ const IMG_CHAR *pszAssertion);
+
+#define PVR_ASSERT(EXPR) do \
+ { \
+ if (unlikely(!(EXPR))) \
+ { \
+ PVRSRVDebugAssertFail(__FILE__, __LINE__, #EXPR); \
+ } \
+ } while (0)
+
+#endif /* defined(__linux__) && defined(__KERNEL__) */
+#endif /* defined(_WIN32) */
+#endif /* defined(__KLOCWORK__) */
+
+#if defined(__KLOCWORK__)
+ #define PVR_DBG_BREAK do { klocwork_abort(); } while (0)
+#else
+ #if defined(WIN32)
+ #define PVR_DBG_BREAK __debugbreak() /*!< Implementation of PVR_DBG_BREAK for (non-WinCE) Win32 */
+ #else
+ #if defined(PVR_DBG_BREAK_ASSERT_FAIL)
+ /*!< Implementation of PVR_DBG_BREAK that maps onto PVRSRVDebugAssertFail */
+ #if defined(_WIN32)
+ #define PVR_DBG_BREAK DBG_BREAK
+ #else
+ #if defined(__linux__) && defined(__KERNEL__)
+ #define PVR_DBG_BREAK BUG()
+ #else
+ #define PVR_DBG_BREAK PVRSRVDebugAssertFail(__FILE__, __LINE__, "PVR_DBG_BREAK")
+ #endif
+ #endif
+ #else
+ /*!< Null Implementation of PVR_DBG_BREAK (does nothing) */
+ #define PVR_DBG_BREAK
+ #endif
+ #endif
+#endif
+
+
+#else /* defined(PVRSRV_NEED_PVR_ASSERT) */
+ /* Unfortunately the Klocwork static analysis checker doesn't understand our
+ * ASSERT macros. Thus it reports lots of false positive. Defining our Assert
+ * macros in a special way when the code is analysed by Klocwork avoids
+ * them.
+ */
+ #if defined(__KLOCWORK__)
+ #define PVR_ASSERT(EXPR) do { if (!(EXPR)) {klocwork_abort();} } while (0)
+ #else
+ #define PVR_ASSERT(EXPR) (void)(EXPR) /*!< Null Implementation of PVR_ASSERT (does nothing) */
+ #endif
+
+ #define PVR_DBG_BREAK /*!< Null Implementation of PVR_DBG_BREAK (does nothing) */
+
+#endif /* defined(PVRSRV_NEED_PVR_ASSERT) */
+
+
+/* PVR_DPF() handling */
+
+#if defined(PVRSRV_NEED_PVR_DPF) || defined(DOXYGEN)
+
+ /* New logging mechanism */
+ #define PVR_DBG_FATAL DBGPRIV_FATAL /*!< Debug level passed to PVRSRVDebugPrintf() for fatal errors. */
+ #define PVR_DBG_ERROR DBGPRIV_ERROR /*!< Debug level passed to PVRSRVDebugPrintf() for non-fatal errors. */
+ #define PVR_DBG_WARNING DBGPRIV_WARNING /*!< Debug level passed to PVRSRVDebugPrintf() for warnings. */
+ #define PVR_DBG_MESSAGE DBGPRIV_MESSAGE /*!< Debug level passed to PVRSRVDebugPrintf() for information only. */
+ #define PVR_DBG_VERBOSE DBGPRIV_VERBOSE /*!< Debug level passed to PVRSRVDebugPrintf() for very low-priority debug. */
+ #define PVR_DBG_CALLTRACE DBGPRIV_CALLTRACE /*!< Debug level passed to PVRSRVDebugPrintf() for function tracing purposes. */
+ #define PVR_DBG_ALLOC DBGPRIV_ALLOC /*!< Debug level passed to PVRSRVDebugPrintf() for tracking some of drivers memory operations. */
+ #define PVR_DBG_BUFFERED DBGPRIV_BUFFERED /*!< Debug level passed to PVRSRVDebugPrintf() when debug should be written to the debug circular buffer. */
+ #define PVR_DBG_DEBUG DBGPRIV_DEBUG /*!< Debug level passed to PVRSRVDebugPrintf() for debug messages. */
+
+ /* These levels are always on with PVRSRV_NEED_PVR_DPF */
+ /*! @cond Doxygen_Suppress */
+ #define PVR_DPF_0x001UL(...) PVRSRVDebugPrintf(DBGPRIV_FATAL, __VA_ARGS__)
+ #define PVR_DPF_0x002UL(...) PVRSRVDebugPrintf(DBGPRIV_ERROR, __VA_ARGS__)
+ #define PVR_DPF_0x080UL(...) PVRSRVDebugPrintf(DBGPRIV_BUFFERED, __VA_ARGS__)
+
+ /*
+ * The AdHoc-Debug level is only supported when enabled in the local
+ * build environment and may need to be used in both debug and release
+ * builds. An error is generated in the formal build if it is checked in.
+ */
+#if defined(PVR_DPF_ADHOC_DEBUG_ON)
+ #define PVR_DPF_0x100UL(...) PVRSRVDebugPrintf(DBGPRIV_DEBUG, __VA_ARGS__)
+#else
+ /* Use an undefined token here to stop compilation dead in the offending module */
+ #define PVR_DPF_0x100UL(...) __ERROR__PVR_DBG_DEBUG_is_in_use_but_has_not_been_enabled__Note_Debug_DPF_must_not_be_checked_in__Define_PVR_DPF_ADHOC_DEBUG_ON_for_testing
+#endif
+
+ /* Some are compiled out completely in release builds */
+#if defined(DEBUG) || defined(DOXYGEN)
+ #define PVR_DPF_0x004UL(...) PVRSRVDebugPrintf(DBGPRIV_WARNING, __VA_ARGS__)
+ #define PVR_DPF_0x008UL(...) PVRSRVDebugPrintf(DBGPRIV_MESSAGE, __VA_ARGS__)
+ #define PVR_DPF_0x010UL(...) PVRSRVDebugPrintf(DBGPRIV_VERBOSE, __VA_ARGS__)
+ #define PVR_DPF_0x020UL(...) PVRSRVDebugPrintf(DBGPRIV_CALLTRACE, __VA_ARGS__)
+ #define PVR_DPF_0x040UL(...) PVRSRVDebugPrintf(DBGPRIV_ALLOC, __VA_ARGS__)
+#else
+ #define PVR_DPF_0x004UL(...)
+ #define PVR_DPF_0x008UL(...)
+ #define PVR_DPF_0x010UL(...)
+ #define PVR_DPF_0x020UL(...)
+ #define PVR_DPF_0x040UL(...)
+#endif
+
+ /* Translate the different log levels to separate macros
+ * so they can each be compiled out.
+ */
+#if defined(DEBUG)
+ #define PVR_DPF_EX(lvl, ...) PVR_DPF_ ## lvl (__FILE__, __LINE__, __VA_ARGS__)
+#else
+ #define PVR_DPF_EX(lvl, ...) PVR_DPF_ ## lvl ("", __LINE__, __VA_ARGS__)
+#endif
+ /*! @endcond */
+
+ /* Get rid of the double bracketing */
+ #define PVR_DPF(x) PVR_DPF_EX x
+
+ #define PVR_LOG_ERROR(_rc, _call) \
+ PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__))
+
+ #define PVR_LOG_IF_ERROR(_rc, _call) do \
+ { if (unlikely(_rc != PVRSRV_OK)) { \
+ PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \
+ } \
+ MSC_SUPPRESS_4127\
+ } while (0)
+
+ #define PVR_WARN_IF_ERROR(_rc, _call) do \
+ { if (unlikely(_rc != PVRSRV_OK)) { \
+ PVR_DPF((PVR_DBG_WARNING, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \
+ } \
+ MSC_SUPPRESS_4127\
+ } while (0)
+
+ #define PVR_LOG_RETURN_IF_NOMEM(_expr, _call) do \
+ { if (unlikely(_expr == NULL)) { \
+ PVR_DPF((PVR_DBG_ERROR, "%s failed (PVRSRV_ERROR_OUT_OF_MEMORY) in %s()", _call, __func__)); \
+ return PVRSRV_ERROR_OUT_OF_MEMORY; } \
+ MSC_SUPPRESS_4127\
+ } while (0)
+
+ #define PVR_LOG_GOTO_IF_NOMEM(_expr, _err, _go) do \
+ { if (unlikely(_expr == NULL)) { \
+ PVR_DPF((PVR_DBG_ERROR, "%s failed (PVRSRV_ERROR_OUT_OF_MEMORY) in %s()", #_expr, __func__)); \
+ _err = PVRSRV_ERROR_OUT_OF_MEMORY; \
+ goto _go; } \
+ MSC_SUPPRESS_4127\
+ } while (0)
+
+ #define PVR_LOG_RETURN_IF_ERROR(_rc, _call) do \
+ { if (unlikely(_rc != PVRSRV_OK)) { \
+ PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \
+ return _rc; } \
+ MSC_SUPPRESS_4127\
+ } while (0)
+
+ #define PVR_LOG_RETURN_VOID_IF_ERROR(_rc, _call) do \
+ { if (unlikely(_rc != PVRSRV_OK)) { \
+ PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \
+ return; } \
+ MSC_SUPPRESS_4127\
+ } while (0)
+
+ #define PVR_LOG_GOTO_IF_ERROR(_rc, _call, _go) do \
+ { if (unlikely(_rc != PVRSRV_OK)) { \
+ PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \
+ goto _go; } \
+ MSC_SUPPRESS_4127\
+ } while (0)
+
+ #define PVR_LOG_GOTO_WITH_ERROR(_call, _err, _rc, _go) do \
+ { PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \
+ _err = _rc; \
+ goto _go; \
+ MSC_SUPPRESS_4127\
+ } while (0)
+
+ #define PVR_LOG_IF_FALSE(_expr, _msg) do \
+ { if (unlikely(!(_expr))) { \
+ PVR_DPF((PVR_DBG_ERROR, "%s in %s()", _msg, __func__)); \
+ } \
+ MSC_SUPPRESS_4127\
+ } while (0)
+
+ #define PVR_LOG_RETURN_IF_FALSE(_expr, _msg, _rc) do \
+ { if (unlikely(!(_expr))) { \
+ PVR_DPF((PVR_DBG_ERROR, "%s in %s()", _msg, __func__)); \
+ return _rc; } \
+ MSC_SUPPRESS_4127\
+ } while (0)
+
+ #define PVR_LOG_RETURN_VOID_IF_FALSE(_expr, _msg) do \
+ { if (unlikely(!(_expr))) { \
+ PVR_DPF((PVR_DBG_ERROR, "%s in %s()", _msg, __func__)); \
+ return; } \
+ MSC_SUPPRESS_4127\
+ } while (0)
+
+ #define PVR_LOG_GOTO_IF_FALSE(_expr, _msg, _go) do \
+ { if (unlikely(!(_expr))) { \
+ PVR_DPF((PVR_DBG_ERROR, "%s in %s()", _msg, __func__)); \
+ goto _go; } \
+ MSC_SUPPRESS_4127\
+ } while (0)
+
+ #define PVR_LOG_RETURN_IF_INVALID_PARAM(_expr, _param) do \
+ { if (unlikely(!(_expr))) { \
+ PVR_DPF((PVR_DBG_ERROR, "%s invalid in %s()", _param, __func__)); \
+ return PVRSRV_ERROR_INVALID_PARAMS; } \
+ MSC_SUPPRESS_4127\
+ } while (0)
+
+ #define PVR_LOG_GOTO_IF_INVALID_PARAM(_expr, _err, _go) do \
+ { if (unlikely(!(_expr))) { \
+ PVR_DPF((PVR_DBG_ERROR, "%s invalid in %s()", #_expr, __func__)); \
+ _err = PVRSRV_ERROR_INVALID_PARAMS; \
+ goto _go; } \
+ MSC_SUPPRESS_4127\
+ } while (0)
+
+ #define PVR_LOG_MSG(_lvl, _msg) \
+ PVR_DPF((_lvl, ("In %s() "_msg), __func__))
+
+ #define PVR_LOG_VA(_lvl, _msg, ...) \
+ PVR_DPF((_lvl, ("In %s() "_msg), __func__, __VA_ARGS__))
+
+ #define PVR_LOG_IF_ERROR_VA(_lvl, _rc, _msg, ...) do \
+ { if (unlikely(_rc != PVRSRV_OK)) { \
+ PVR_DPF((_lvl, ("In %s() "_msg), __func__, __VA_ARGS__)); \
+ } \
+ MSC_SUPPRESS_4127\
+ } while (0)
+
+ #define PVR_LOG_IF_FALSE_VA(_lvl, _expr, _msg, ...) do \
+ { if (unlikely(!(_expr))) { \
+ PVR_DPF((_lvl, ("In %s() "_msg), __func__, __VA_ARGS__)); \
+ } \
+ MSC_SUPPRESS_4127\
+ } while (0)
+
+ #define PVR_LOG_RETURN_IF_ERROR_VA(_rc, _msg, ...) do \
+ { if (unlikely(_rc != PVRSRV_OK)) { \
+ PVR_DPF((PVR_DBG_ERROR, ("In %s() "_msg), __func__, __VA_ARGS__)); \
+ return _rc; \
+ } MSC_SUPPRESS_4127\
+ } while (0)
+
+ #define PVR_LOG_GOTO_IF_ERROR_VA(_rc, _go, _msg, ...) do \
+ { if (unlikely(_rc != PVRSRV_OK)) { \
+ PVR_DPF((PVR_DBG_ERROR, ("In %s() "_msg), __func__, __VA_ARGS__)); \
+ goto _go; \
+ } MSC_SUPPRESS_4127\
+ } while (0)
+
+ #define PVR_LOG_RETURN_IF_FALSE_VA(_expr, _rc, _msg, ...) do \
+ { if (unlikely(!(_expr))) { \
+ PVR_DPF((PVR_DBG_ERROR, ("At %s: "_msg), __func__, __VA_ARGS__)); \
+ return _rc; \
+ } MSC_SUPPRESS_4127\
+ } while (0)
+
+ #define PVR_LOG_GOTO_IF_FALSE_VA(_expr, _go, _msg, ...) do \
+ { if (unlikely(!(_expr))) { \
+ PVR_DPF((PVR_DBG_ERROR, ("In %s() "_msg), __func__, __VA_ARGS__)); \
+ goto _go; \
+ } MSC_SUPPRESS_4127\
+ } while (0)
+
+#else /* defined(PVRSRV_NEED_PVR_DPF) */
+
+ #define PVR_DPF(X) /*!< Null Implementation of PowerVR Debug Printf (does nothing) */
+
+ #define PVR_LOG_MSG(_lvl, _msg)
+ #define PVR_LOG_VA(_lvl, _msg, ...)
+ #define PVR_LOG_ERROR(_rc, _call) (void)(_rc)
+ #define PVR_LOG_IF_ERROR(_rc, _call) (void)(_rc)
+ #define PVR_WARN_IF_ERROR(_rc, _call) (void)(_rc)
+
+ #define PVR_LOG_IF_ERROR_VA(_lvl, _rc, _msg, ...) (void)(_rc)
+ #define PVR_LOG_IF_FALSE_VA(_lvl, _expr, _msg, ...) (void)(_expr)
+
+ #define PVR_LOG_RETURN_IF_NOMEM(_expr, _call) do { if (unlikely(_expr == NULL)) { return PVRSRV_ERROR_OUT_OF_MEMORY; } MSC_SUPPRESS_4127 } while (0)
+ #define PVR_LOG_GOTO_IF_NOMEM(_expr, _err, _go) do { if (unlikely(_expr == NULL)) { _err = PVRSRV_ERROR_OUT_OF_MEMORY; goto _go; } MSC_SUPPRESS_4127 } while (0)
+
+ #define PVR_LOG_RETURN_IF_ERROR(_rc, _call) do { if (unlikely(_rc != PVRSRV_OK)) { return (_rc); } MSC_SUPPRESS_4127 } while (0)
+ #define PVR_LOG_RETURN_IF_ERROR_VA(_rc, _msg, ...) do { if (unlikely(_rc != PVRSRV_OK)) { return (_rc); } MSC_SUPPRESS_4127 } while (0)
+ #define PVR_LOG_RETURN_VOID_IF_ERROR(_rc, _call) do { if (unlikely(_rc != PVRSRV_OK)) { return; } MSC_SUPPRESS_4127 } while (0)
+
+ #define PVR_LOG_GOTO_IF_ERROR(_rc, _call, _go) do { if (unlikely(_rc != PVRSRV_OK)) { goto _go; } MSC_SUPPRESS_4127 } while (0)
+ #define PVR_LOG_GOTO_IF_ERROR_VA(_rc, _go, _msg, ...) do { if (unlikely(_rc != PVRSRV_OK)) { goto _go; } MSC_SUPPRESS_4127 } while (0)
+ #define PVR_LOG_GOTO_WITH_ERROR(_call, _err, _rc, _go) do { _err = _rc; goto _go; MSC_SUPPRESS_4127 } while (0)
+
+ #define PVR_LOG_IF_FALSE(_expr, _msg) (void)(_expr)
+ #define PVR_LOG_RETURN_IF_FALSE(_expr, _msg, _rc) do { if (unlikely(!(_expr))) { return (_rc); } MSC_SUPPRESS_4127 } while (0)
+ #define PVR_LOG_RETURN_IF_FALSE_VA(_expr, _rc, _msg, ...) do { if (unlikely(!(_expr))) { return (_rc); } MSC_SUPPRESS_4127 } while (0)
+
+ #define PVR_LOG_RETURN_VOID_IF_FALSE(_expr, _msg) do { if (unlikely(!(_expr))) { return; } MSC_SUPPRESS_4127 } while (0)
+ #define PVR_LOG_GOTO_IF_FALSE(_expr, _msg, _go) do { if (unlikely(!(_expr))) { goto _go; } MSC_SUPPRESS_4127 } while (0)
+ #define PVR_LOG_GOTO_IF_FALSE_VA(_expr, _go, _msg, ...) do { if (unlikely(!(_expr))) { goto _go; } MSC_SUPPRESS_4127 } while (0)
+
+ #define PVR_LOG_RETURN_IF_INVALID_PARAM(_expr, _param) do { if (unlikely(!(_expr))) { return PVRSRV_ERROR_INVALID_PARAMS; } MSC_SUPPRESS_4127 } while (0)
+ #define PVR_LOG_GOTO_IF_INVALID_PARAM(_expr, _err, _go) do { if (unlikely(!(_expr))) { _err = PVRSRV_ERROR_INVALID_PARAMS; goto _go; } MSC_SUPPRESS_4127 } while (0)
+
+ #undef PVR_DPF_FUNCTION_TRACE_ON
+
+#endif /* defined(PVRSRV_NEED_PVR_DPF) */
+
+/*************************************************************************/ /*!
+@Function PVRSRVDebugPrintf
+@Description Output a debug message to the user, using an OS-specific
+ method, to a log or console which can be read by developers
+ Invoked from the macro PVR_DPF().
+@Input ui32DebugLevel The debug level of the message. This can
+ be used to restrict the output of debug
+ messages based on their severity.
+ If this is PVR_DBG_BUFFERED, the message
+ should be written into a debug circular
+ buffer instead of being output immediately
+ (useful when performance would otherwise
+ be adversely affected).
+ The debug circular buffer shall only be
+ output when PVRSRVDebugPrintfDumpCCB() is
+ called.
+@Input pszFileName The source file containing the code that is
+ generating the message
+@Input ui32Line The line number in the source file
+@Input pszFormat The formatted message string
+@Input ... Zero or more arguments for use by the
+ formatted string
+@Return None
+*/ /**************************************************************************/
+IMG_EXPORT void IMG_CALLCONV PVRSRVDebugPrintf(IMG_UINT32 ui32DebugLevel,
+ const IMG_CHAR *pszFileName,
+ IMG_UINT32 ui32Line,
+ const IMG_CHAR *pszFormat,
+ ...) __printf(4, 5);
+
+/*************************************************************************/ /*!
+@Function PVRSRVDebugPrintfDumpCCB
+@Description When PVRSRVDebugPrintf() is called with the ui32DebugLevel
+ specified as DBGPRIV_BUFFERED, the debug shall be written to
+ the debug circular buffer instead of being output immediately.
+ (This could be used to obtain debug without incurring a
+ performance hit by printing it at that moment).
+ This function shall dump the contents of that debug circular
+ buffer to be output in an OS-specific method to a log or
+ console which can be read by developers.
+@Return None
+*/ /**************************************************************************/
+IMG_EXPORT void IMG_CALLCONV PVRSRVDebugPrintfDumpCCB(void);
+
+#define PVR_DPF_FUNC__(lvl, message, ...) PVR_DPF((lvl, "%s: " message, __func__, ##__VA_ARGS__))
+#define PVR_DPF_FUNC(x) PVR_DPF_FUNC__ x
+
+/* Note: Use only when a log message due to the error absolutely should not
+ * be printed. Otherwise use PVR_LOG_RETURN_IF_ERROR macro.
+ */
+#define PVR_RETURN_IF_ERROR(_rc) do \
+ { if (unlikely(_rc != PVRSRV_OK)) { \
+ return _rc; } \
+ MSC_SUPPRESS_4127 \
+ } while (0)
+
+/* Note: Use only when a log message due to the error absolutely should not
+ * be printed. Otherwise use PVR_LOG_RETURN_IF_FALSE macro.
+ */
+#define PVR_RETURN_IF_FALSE(_expr, _rc) do \
+ { if (unlikely(!(_expr))) { \
+ return _rc; } \
+ MSC_SUPPRESS_4127 \
+ } while (0)
+
+/* Note: Use only when a log message due to the error absolutely should not
+ * be printed. Otherwise use PVR_LOG_RETURN_IF_INVALID_PARAM macro.
+ */
+#define PVR_RETURN_IF_INVALID_PARAM(_expr) do \
+ { if (unlikely(!(_expr))) { \
+ return PVRSRV_ERROR_INVALID_PARAMS; } \
+ MSC_SUPPRESS_4127 \
+ } while (0)
+
+/* Note: Use only when a log message due to the error absolutely should not
+ * be printed. Otherwise use PVR_LOG_RETURN_IF_NOMEM macro.
+ */
+#define PVR_RETURN_IF_NOMEM(_expr) do \
+ { if (unlikely(!(_expr))) { \
+ return PVRSRV_ERROR_OUT_OF_MEMORY; } \
+ MSC_SUPPRESS_4127 \
+ } while (0)
+
+/* Note: Use only when a log message due to the error absolutely should not
+ * be printed. Otherwise use PVR_LOG_GOTO_IF_NOMEM macro.
+ */
+#define PVR_GOTO_IF_NOMEM(_expr, _err, _go) do \
+ { if (unlikely(_expr == NULL)) { \
+ _err = PVRSRV_ERROR_OUT_OF_MEMORY; \
+ goto _go; } \
+ MSC_SUPPRESS_4127 \
+ } while (0)
+
+/* Note: Use only when a log message due to the error absolutely should not
+ * be printed. Otherwise use PVR_LOG_GOTO_IF_INVALID_PARAM macro.
+ */
+#define PVR_GOTO_IF_INVALID_PARAM(_expr, _err, _go) do \
+ { if (unlikely(!(_expr))) { \
+ _err = PVRSRV_ERROR_INVALID_PARAMS; \
+ goto _go; } \
+ MSC_SUPPRESS_4127 \
+ } while (0)
+
+/* Note: Use only when a log message due to the error absolutely should not
+ * be printed. Otherwise use PVR_LOG_GOTO_IF_FALSE macro.
+ */
+#define PVR_GOTO_IF_FALSE(_expr, _go) do \
+ { if (unlikely(!(_expr))) { \
+ goto _go; } \
+ MSC_SUPPRESS_4127 \
+ } while (0)
+
+/* Note: Use only when a log message due to the error absolutely should not
+ * be printed. Otherwise use PVR_LOG_GOTO_IF_ERROR macro.
+ */
+#define PVR_GOTO_IF_ERROR(_rc, _go) do \
+ { if (unlikely(_rc != PVRSRV_OK)) { \
+ goto _go; } \
+ MSC_SUPPRESS_4127\
+ } while (0)
+
+/* Note: Use only when a log message due to the error absolutely should not
+ * be printed. Otherwise use PVR_LOG_GOTO_WITH_ERROR macro.
+ */
+#define PVR_GOTO_WITH_ERROR(_err, _rc, _go) do \
+ { _err = _rc; goto _go; \
+ MSC_SUPPRESS_4127 \
+ } while (0)
+
+/*! @cond Doxygen_Suppress */
+#if defined(PVR_DPF_FUNCTION_TRACE_ON)
+
+ #define PVR_DPF_ENTERED \
+ PVR_DPF((PVR_DBG_CALLTRACE, "|-> %s:%d entered", __func__, __LINE__))
+
+ #define PVR_DPF_ENTERED1(p1) \
+ PVR_DPF((PVR_DBG_CALLTRACE, "|-> %s:%d entered (0x%lx)", __func__, __LINE__, ((unsigned long)p1)))
+
+ #define PVR_DPF_RETURN_RC(a) \
+ do { int _r = (a); PVR_DPF((PVR_DBG_CALLTRACE, "<-| %s:%d returned %d", __func__, __LINE__, (_r))); return (_r); MSC_SUPPRESS_4127 } while (0)
+
+ #define PVR_DPF_RETURN_RC1(a,p1) \
+ do { int _r = (a); PVR_DPF((PVR_DBG_CALLTRACE, "<-| %s:%d returned %d (0x%lx)", __func__, __LINE__, (_r), ((unsigned long)p1))); return (_r); MSC_SUPPRESS_4127 } while (0)
+
+ #define PVR_DPF_RETURN_VAL(a) \
+ do { PVR_DPF((PVR_DBG_CALLTRACE, "<-| %s:%d returned with value", __func__, __LINE__)); return (a); MSC_SUPPRESS_4127 } while (0)
+
+ #define PVR_DPF_RETURN_OK \
+ do { PVR_DPF((PVR_DBG_CALLTRACE, "<-| %s:%d returned ok", __func__, __LINE__)); return PVRSRV_OK; MSC_SUPPRESS_4127 } while (0)
+
+ #define PVR_DPF_RETURN \
+ do { PVR_DPF((PVR_DBG_CALLTRACE, "<-| %s:%d returned", __func__, __LINE__)); return; MSC_SUPPRESS_4127 } while (0)
+
+ #if !defined(DEBUG)
+ #error PVR DPF Function trace enabled in release build, rectify
+ #endif
+
+#else /* defined(PVR_DPF_FUNCTION_TRACE_ON) */
+
+ #define PVR_DPF_ENTERED
+ #define PVR_DPF_ENTERED1(p1)
+ #define PVR_DPF_RETURN_RC(a) return (a)
+ #define PVR_DPF_RETURN_RC1(a,p1) return (a)
+ #define PVR_DPF_RETURN_VAL(a) return (a)
+ #define PVR_DPF_RETURN_OK return PVRSRV_OK
+ #define PVR_DPF_RETURN return
+
+#endif /* defined(PVR_DPF_FUNCTION_TRACE_ON) */
+/*! @endcond */
+
+#if defined(__KERNEL__) || defined(DOXYGEN) || defined(__QNXNTO__)
+/*Use PVR_DPF() unless message is necessary in release build */
+#define PVR_LOG(X) PVRSRVReleasePrintf X
+
+/*************************************************************************/ /*!
+@Function PVRSRVReleasePrintf
+@Description Output an important message, using an OS-specific method,
+ to the Server log or console which will always be output in
+ both release and debug builds.
+ Invoked from the macro PVR_LOG(). Used in Services Server only.
+@Input pszFormat The message format string
+@Input ... Zero or more arguments for use by the format string
+@Return None
+*/ /**************************************************************************/
+void IMG_CALLCONV PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...) __printf(1, 2);
+#endif
+
+/* PVR_TRACE() handling */
+
+#if defined(PVRSRV_NEED_PVR_TRACE) || defined(DOXYGEN)
+
+ #define PVR_TRACE(X) PVRSRVTrace X /*!< PowerVR Debug Trace Macro */
+ /* Empty string implementation that is -O0 build friendly */
+ #define PVR_TRACE_EMPTY_LINE() PVR_TRACE(("%s", ""))
+
+/*************************************************************************/ /*!
+@Function PVRTrace
+@Description Output a debug message to the user
+ Invoked from the macro PVR_TRACE().
+@Input pszFormat The message format string
+@Input ... Zero or more arguments for use by the format string
+*/ /**************************************************************************/
+IMG_EXPORT void IMG_CALLCONV PVRSRVTrace(const IMG_CHAR* pszFormat, ... )
+ __printf(1, 2);
+
+#else /* defined(PVRSRV_NEED_PVR_TRACE) */
+ /*! Null Implementation of PowerVR Debug Trace Macro (does nothing) */
+ #define PVR_TRACE(X)
+
+#endif /* defined(PVRSRV_NEED_PVR_TRACE) */
+
+
+#if defined(PVRSRV_NEED_PVR_ASSERT)
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(TRUNCATE_64BITS_TO_32BITS)
+#endif
+ INLINE static IMG_UINT32 TRUNCATE_64BITS_TO_32BITS(IMG_UINT64 uiInput)
+ {
+ IMG_UINT32 uiTruncated;
+
+ uiTruncated = (IMG_UINT32)uiInput;
+ PVR_ASSERT(uiInput == uiTruncated);
+ return uiTruncated;
+ }
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(TRUNCATE_64BITS_TO_SIZE_T)
+#endif
+ INLINE static size_t TRUNCATE_64BITS_TO_SIZE_T(IMG_UINT64 uiInput)
+ {
+ size_t uiTruncated;
+
+ uiTruncated = (size_t)uiInput;
+ PVR_ASSERT(uiInput == uiTruncated);
+ return uiTruncated;
+ }
+
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(TRUNCATE_SIZE_T_TO_32BITS)
+#endif
+ INLINE static IMG_UINT32 TRUNCATE_SIZE_T_TO_32BITS(size_t uiInput)
+ {
+ IMG_UINT32 uiTruncated;
+
+ uiTruncated = (IMG_UINT32)uiInput;
+ PVR_ASSERT(uiInput == uiTruncated);
+ return uiTruncated;
+ }
+
+
+#else /* defined(PVRSRV_NEED_PVR_ASSERT) */
+ #define TRUNCATE_64BITS_TO_32BITS(expr) ((IMG_UINT32)(expr))
+ #define TRUNCATE_64BITS_TO_SIZE_T(expr) ((size_t)(expr))
+ #define TRUNCATE_SIZE_T_TO_32BITS(expr) ((IMG_UINT32)(expr))
+#endif /* defined(PVRSRV_NEED_PVR_ASSERT) */
+
+/*! @cond Doxygen_Suppress */
+/* Macros used to trace calls */
+#if defined(DEBUG)
+ #define PVR_DBG_FILELINE , (__FILE__), (__LINE__)
+ #define PVR_DBG_FILELINE_PARAM , const IMG_CHAR *pszaFile, IMG_UINT32 ui32Line
+ #define PVR_DBG_FILELINE_ARG , pszaFile, ui32Line
+ #define PVR_DBG_FILELINE_FMT " %s:%u"
+ #define PVR_DBG_FILELINE_UNREF() do { PVR_UNREFERENCED_PARAMETER(pszaFile); \
+ PVR_UNREFERENCED_PARAMETER(ui32Line); } while (0)
+#else
+ #define PVR_DBG_FILELINE
+ #define PVR_DBG_FILELINE_PARAM
+ #define PVR_DBG_FILELINE_ARG
+ #define PVR_DBG_FILELINE_FMT
+ #define PVR_DBG_FILELINE_UNREF()
+#endif
+/*! @endcond */
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*!
+ @def PVR_ASSERT
+ @brief Aborts the program if assertion fails.
+
+ The macro will be defined only when PVRSRV_NEED_PVR_ASSERT macro is
+ enabled. It's ignored otherwise.
+
+ @def PVR_DPF
+ @brief PowerVR Debug Printf logging macro used throughout the driver.
+
+ The macro allows to print logging messages to appropriate log. The
+ destination log is based on the component (user space / kernel space) and
+ operating system (Linux, Android, etc.).
+
+ The macro also supports severity levels that allow to turn on/off messages
+ based on their importance.
+
+ This macro will print messages with severity level higher that error only
+ if PVRSRV_NEED_PVR_DPF macro is defined.
+
+ @def PVR_LOG_ERROR
+ @brief Logs error.
+
+ @def PVR_LOG_IF_ERROR
+ @brief Logs error if not PVRSRV_OK.
+
+ @def PVR_WARN_IF_ERROR
+ @brief Logs warning if not PVRSRV_OK.
+
+ @def PVR_LOG_RETURN_IF_NOMEM
+ @brief Logs error if expression is NULL and returns PVRSRV_ERROR_OUT_OF_MEMORY.
+
+ @def PVR_LOG_GOTO_IF_NOMEM
+ @brief Logs error if expression is NULL and jumps to given label.
+
+ @def PVR_LOG_RETURN_IF_ERROR
+ @brief Logs error if not PVRSRV_OK and returns the error.
+
+ @def PVR_LOG_RETURN_VOID_IF_ERROR
+ @brief Logs error if not PVRSRV_OK and returns (used in function that return void).
+
+ @def PVR_LOG_GOTO_IF_ERROR
+ @brief Logs error if not PVRSRV_OK and jumps to label.
+
+ @def PVR_LOG_GOTO_WITH_ERROR
+ @brief Logs error, goes to a label and sets the error code.
+
+ @def PVR_LOG_IF_FALSE
+ @brief Prints error message if expression is false.
+
+ @def PVR_LOG_RETURN_IF_FALSE
+ @brief Prints error message if expression is false and returns given error.
+
+ @def PVR_LOG_RETURN_VOID_IF_FALSE
+ @brief Prints error message if expression is false and returns (used in function that return void).
+
+ @def PVR_LOG_GOTO_IF_FALSE
+ @brief Prints error message if expression is false and jumps to label.
+
+ @def PVR_LOG_RETURN_IF_INVALID_PARAM
+ @brief Prints error message if expression is false and returns PVRSRV_ERROR_INVALID_PARAMS.
+
+ @def PVR_LOG_GOTO_IF_INVALID_PARAM
+ @brief Prints error message if expression is false and jumps to label.
+
+ @def PVR_RETURN_IF_ERROR
+ @brief Returns passed error code if it's different than PVRSRV_OK;
+
+ @def PVR_RETURN_IF_FALSE
+ @brief Returns passed error code if expression is false.
+
+ @def PVR_RETURN_IF_INVALID_PARAM
+ @brief Returns PVRSRV_ERROR_INVALID_PARAMS if expression is false.
+
+ @def PVR_RETURN_IF_NOMEM
+ @brief Returns PVRSRV_ERROR_OUT_OF_MEMORY if expression is NULL.
+
+ @def PVR_GOTO_IF_NOMEM
+ @brief Goes to a label if expression is NULL.
+
+ @def PVR_GOTO_IF_INVALID_PARAM
+ @brief Goes to a label if expression is false.
+
+ @def PVR_GOTO_IF_FALSE
+ @def Goes to a label if expression is false.
+
+ @def PVR_GOTO_IF_ERROR
+ @brief Goes to a label if the error code is different than PVRSRV_OK;
+
+ @def PVR_GOTO_WITH_ERROR
+ @brief Goes to a label and sets the error code.
+
+ @def PVR_LOG
+ @brief Prints message to a log unconditionally.
+
+ This macro will print messages only if PVRSRV_NEED_PVR_LOG macro is defined.
+
+ @def PVR_TRACE_EMPTY_LINE
+ @brief Prints empty line to a log (PVRSRV_NEED_PVR_LOG must be defined).
+
+ @def TRUNCATE_64BITS_TO_32BITS
+ @brief Truncates 64 bit value to 32 bit value (with possible precision loss).
+
+ @def TRUNCATE_64BITS_TO_SIZE_T
+ @brief Truncates 64 bit value to size_t value (with possible precision loss).
+
+ @def TRUNCATE_SIZE_T_TO_32BITS
+ @brief Truncates size_t value to 32 bit value (with possible precision loss).
+ */
+
+#endif /* PVR_DEBUG_H */
+
+/******************************************************************************
+ End of file (pvr_debug.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/pvr_fd_sync_kernel.h b/drivers/gpu/drm/img-rogue/include/pvr_fd_sync_kernel.h
new file mode 100644
index 000000000..3645e2907
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/pvr_fd_sync_kernel.h
@@ -0,0 +1,64 @@
+/*************************************************************************/ /*!
+@File pvr_fd_sync_kernel.h
+@Title Kernel/userspace interface definitions to use the kernel sync
+ driver
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+
+#ifndef _PVR_FD_SYNC_KERNEL_H_
+#define _PVR_FD_SYNC_KERNEL_H_
+
+#include
+#include
+
+#include "pvr_drm.h"
+
+#define PVR_SYNC_MAX_QUERY_FENCE_POINTS 14
+
+struct pvr_sync_pt_info {
+ /* Output */
+ __u32 id;
+ __u32 ui32FWAddr;
+ __u32 ui32CurrOp;
+ __u32 ui32NextOp;
+ __u32 ui32TlTaken;
+} __attribute__((packed, aligned(8)));
+
+#endif /* _PVR_FD_SYNC_KERNEL_H_ */
diff --git a/drivers/gpu/drm/img-rogue/include/pvr_intrinsics.h b/drivers/gpu/drm/img-rogue/include/pvr_intrinsics.h
new file mode 100644
index 000000000..410a2f5a5
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/pvr_intrinsics.h
@@ -0,0 +1,70 @@
+/*************************************************************************/ /*!
+@File
+@Title Intrinsics definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef PVR_INTRINSICS_H
+#define PVR_INTRINSICS_H
+
+/* PVR_CTZLL:
+ * Count the number of trailing zeroes in a long long integer
+ */
+
+#if defined(__GNUC__)
+#if defined(__x86_64__)
+
+ #define PVR_CTZLL __builtin_ctzll
+#endif
+#endif
+
+/* PVR_CLZLL:
+ * Count the number of leading zeroes in a long long integer
+ */
+
+#if defined(__GNUC__)
+#if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || \
+ defined(__arm__) || defined(__mips)
+
+#define PVR_CLZLL __builtin_clzll
+
+#endif
+#endif
+
+#endif /* PVR_INTRINSICS_H */
diff --git a/drivers/gpu/drm/img-rogue/include/pvrmodule.h b/drivers/gpu/drm/img-rogue/include/pvrmodule.h
new file mode 100644
index 000000000..267c7b687
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/pvrmodule.h
@@ -0,0 +1,48 @@
+/*************************************************************************/ /*!
+@Title Module Author and License.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef _PVRMODULE_H_
+#define _PVRMODULE_H_
+
+MODULE_AUTHOR("Imagination Technologies Ltd. ");
+MODULE_LICENSE("Dual MIT/GPL");
+
+#endif /* _PVRMODULE_H_ */
diff --git a/drivers/gpu/drm/img-rogue/include/pvrsrv_device_types.h b/drivers/gpu/drm/img-rogue/include/pvrsrv_device_types.h
new file mode 100644
index 000000000..662e3bc17
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/pvrsrv_device_types.h
@@ -0,0 +1,55 @@
+/*************************************************************************/ /*!
+@File
+@Title PowerVR device type definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(PVRSRV_DEVICE_TYPES_H)
+#define PVRSRV_DEVICE_TYPES_H
+
+#include "img_types.h"
+
+#define PVRSRV_MAX_DEVICES 16U /*!< Largest supported number of devices on the system */
+
+#if defined(__KERNEL__) && defined(__linux__) && !defined(__GENKSYMS__)
+#define __pvrsrv_defined_struct_enum__
+#include
+#endif
+
+#endif /* PVRSRV_DEVICE_TYPES_H */
diff --git a/drivers/gpu/drm/img-rogue/include/pvrsrv_devvar.h b/drivers/gpu/drm/img-rogue/include/pvrsrv_devvar.h
new file mode 100644
index 000000000..a8c64e309
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/pvrsrv_devvar.h
@@ -0,0 +1,291 @@
+/*************************************************************************/ /*!
+@File
+@Title Services Device Variable interface header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Defines the client side interface for device variables
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef PVRSRV_DEVVAR_H
+#define PVRSRV_DEVVAR_H
+
+#include "img_types.h"
+#include "img_defs.h"
+#include "pvr_debug.h"
+#include
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define DEVVAR_MAX_NAME_LEN 32
+
+typedef struct SYNC_PRIM_CONTEXT_TAG *PDEVVARCTX;
+typedef struct PVRSRV_CLIENT_SYNC_PRIM_TAG *PDEVVAR;
+
+typedef struct PVRSRV_DEV_VAR_UPDATE_TAG
+{
+ PDEVVAR psDevVar; /*!< Pointer to the dev var */
+ IMG_UINT32 ui32UpdateValue; /*!< the update value */
+} PVRSRV_DEV_VAR_UPDATE;
+
+/*************************************************************************/ /*!
+@Function PVRSRVDevVarContextCreate
+
+@Description Create a new device variable context
+
+@Input psDevConnection Device to create the device
+ variable context on
+
+@Output phDevVarContext Handle to the created device
+ variable context
+
+@Return PVRSRV_OK if the device variable context was successfully
+ created
+*/
+/*****************************************************************************/
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVDevVarContextCreate(const PVRSRV_DEV_CONNECTION *psDevConnection,
+ PDEVVARCTX *phDevVarContext);
+
+/*************************************************************************/ /*!
+@Function PVRSRVDevVarContextDestroy
+
+@Description Destroy a device variable context
+
+@Input hDevVarContext Handle to the device variable
+ context to destroy
+
+@Return None
+*/
+/*****************************************************************************/
+IMG_EXPORT void
+PVRSRVDevVarContextDestroy(PDEVVARCTX hDevVarContext);
+
+/*************************************************************************/ /*!
+@Function PVRSRVDevVarAlloc
+
+@Description Allocate a new device variable on the specified device
+ variable context. The device variable's value is initialised
+ with the value passed in ui32InitialValue.
+
+@Input hDevVarContext Handle to the device variable
+ context
+@Input ui32InitialValue Value to initially assign to the
+ new variable
+@Input pszDevVarName Name assigned to the device variable
+ (for debug purposes)
+
+@Output ppsDevVar Created device variable
+
+@Return PVRSRV_OK if the device variable was successfully created
+*/
+/*****************************************************************************/
+IMG_EXPORT PVRSRV_ERROR
+PVRSRVDevVarAllocI(PDEVVARCTX hDevVarContext,
+ PDEVVAR *ppsDevVar,
+ IMG_UINT32 ui32InitialValue,
+ const IMG_CHAR *pszDevVarName
+ PVR_DBG_FILELINE_PARAM);
+#define PVRSRVDevVarAlloc(hDevVarContext, ppsDevVar, ui32InitialValue, pszDevVarName) \
+ PVRSRVDevVarAllocI( (hDevVarContext), (ppsDevVar), (ui32InitialValue), (pszDevVarName) \
+ PVR_DBG_FILELINE )
+
+/*************************************************************************/ /*!
+@Function PVRSRVDevVarFree
+
+@Description Free a device variable
+
+@Input psDevVar The device variable to free
+
+@Return None
+*/
+/*****************************************************************************/
+IMG_EXPORT void
+PVRSRVDevVarFree(PDEVVAR psDevVar);
+
+/*************************************************************************/ /*!
+@Function PVRSRVDevVarSet
+
+@Description Set the device variable to a value
+
+@Input psDevVar The device variable to set
+
+@Input ui32Value Value to set it to
+
+@Return None
+*/
+/*****************************************************************************/
+IMG_EXPORT void
+PVRSRVDevVarSet(PDEVVAR psDevVar,
+ IMG_UINT32 ui32Value);
+
+/*************************************************************************/ /*!
+@Function PVRSRVDevVarGet
+
+@Description Get the current value of the device variable
+
+@Input psDevVar The device variable to get the
+ value of
+
+@Return Value of the variable
+*/
+/*****************************************************************************/
+IMG_EXPORT IMG_UINT32
+PVRSRVDevVarGet(PDEVVAR psDevVar);
+
+/*************************************************************************/ /*!
+@Function PVRSRVDevVarGetFirmwareAddr
+
+@Description Returns the address of the associated firmware value for a
+ specified device integer (not exposed to client)
+
+@Input psDevVar The device variable to resolve
+
+@Return The firmware address of the device variable
+*/
+/*****************************************************************************/
+IMG_EXPORT IMG_UINT32
+PVRSRVDevVarGetFirmwareAddr(PDEVVAR psDevVar);
+
+#if defined(PDUMP)
+/*************************************************************************/ /*!
+@Function PVRSRVDevVarPDump
+
+@Description PDump the current value of the device variable
+
+@Input psDevVar The device variable to PDump
+
+@Return None
+*/
+/*****************************************************************************/
+IMG_EXPORT void
+PVRSRVDevVarPDump(PDEVVAR psDevVar);
+
+/*************************************************************************/ /*!
+@Function PVRSRVDevVarPDumpPol
+
+@Description Do a PDump poll of the device variable
+
+@Input psDevVar The device variable to PDump
+
+@Input ui32Value Value to Poll for
+
+@Input ui32Mask PDump mask operator
+
+@Input ui32PDumpFlags PDump flags
+
+@Return None
+*/
+/*****************************************************************************/
+IMG_EXPORT void
+PVRSRVDevVarPDumpPol(PDEVVAR psDevVar,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ PDUMP_POLL_OPERATOR eOperator,
+ IMG_UINT32 ui32PDumpFlags);
+
+/*************************************************************************/ /*!
+@Function PVRSRVDevVarPDumpCBP
+
+@Description Do a PDump CB poll using the device variable
+
+@Input psDevVar The device variable to PDump
+
+@Input uiWriteOffset Current write offset of buffer
+
+@Input uiPacketSize Size of the packet to write into CB
+
+@Input uiBufferSize Size of the CB
+
+@Return None
+*/
+/*****************************************************************************/
+IMG_EXPORT void
+PVRSRVDevVarPDumpCBP(PDEVVAR psDevVar,
+ IMG_UINT64 uiWriteOffset,
+ IMG_UINT64 uiPacketSize,
+ IMG_UINT64 uiBufferSize);
+#else /* PDUMP */
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVDevVarPDump)
+#endif
+static INLINE void
+PVRSRVDevVarPDump(PDEVVAR psDevVar)
+{
+ PVR_UNREFERENCED_PARAMETER(psDevVar);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVDevVarPDumpPol)
+#endif
+static INLINE void
+PVRSRVDevVarPDumpPol(PDEVVAR psDevVar,
+ IMG_UINT32 ui32Value,
+ IMG_UINT32 ui32Mask,
+ PDUMP_POLL_OPERATOR eOperator,
+ IMG_UINT32 ui32PDumpFlags)
+{
+ PVR_UNREFERENCED_PARAMETER(psDevVar);
+ PVR_UNREFERENCED_PARAMETER(ui32Value);
+ PVR_UNREFERENCED_PARAMETER(ui32Mask);
+ PVR_UNREFERENCED_PARAMETER(eOperator);
+ PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags);
+}
+
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(PVRSRVDevVarPDumpCBP)
+#endif
+static INLINE void
+PVRSRVDevVarPDumpCBP(PDEVVAR psDevVar,
+ IMG_UINT64 uiWriteOffset,
+ IMG_UINT64 uiPacketSize,
+ IMG_UINT64 uiBufferSize)
+{
+ PVR_UNREFERENCED_PARAMETER(psDevVar);
+ PVR_UNREFERENCED_PARAMETER(uiWriteOffset);
+ PVR_UNREFERENCED_PARAMETER(uiPacketSize);
+ PVR_UNREFERENCED_PARAMETER(uiBufferSize);
+}
+#endif /* PDUMP */
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* PVRSRV_DEVVAR_H */
diff --git a/drivers/gpu/drm/img-rogue/include/pvrsrv_error.h b/drivers/gpu/drm/img-rogue/include/pvrsrv_error.h
new file mode 100644
index 000000000..0bbf8431b
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/pvrsrv_error.h
@@ -0,0 +1,61 @@
+/*************************************************************************/ /*!
+@File pvrsrv_error.h
+@Title services error enumerant
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Defines error codes used by any/all services modules
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(PVRSRV_ERROR_H)
+#define PVRSRV_ERROR_H
+
+/*!
+ *****************************************************************************
+ * Error values
+ *****************************************************************************/
+typedef enum PVRSRV_ERROR_TAG
+{
+ PVRSRV_OK,
+#define PVRE(x) x,
+#include "pvrsrv_errors.h"
+#undef PVRE
+ PVRSRV_ERROR_FORCE_I32 = 0x7fffffff
+
+} PVRSRV_ERROR;
+
+#endif /* !defined(PVRSRV_ERROR_H) */
diff --git a/drivers/gpu/drm/img-rogue/include/pvrsrv_errors.h b/drivers/gpu/drm/img-rogue/include/pvrsrv_errors.h
new file mode 100644
index 000000000..d571d6279
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/pvrsrv_errors.h
@@ -0,0 +1,408 @@
+/*************************************************************************/ /*!
+@File pvrsrv_errors.h
+@Title services error codes
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Defines error codes used by any/all services modules
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/* Don't add include guards to this file! */
+
+PVRE(PVRSRV_ERROR_OUT_OF_MEMORY)
+PVRE(PVRSRV_ERROR_TOO_FEW_BUFFERS)
+PVRE(PVRSRV_ERROR_INVALID_PARAMS)
+PVRE(PVRSRV_ERROR_INIT_FAILURE)
+PVRE(PVRSRV_ERROR_CANT_REGISTER_CALLBACK)
+PVRE(PVRSRV_ERROR_INVALID_DEVICE)
+PVRE(PVRSRV_ERROR_NOT_OWNER)
+PVRE(PVRSRV_ERROR_BAD_MAPPING)
+PVRE(PVRSRV_ERROR_TIMEOUT)
+PVRE(PVRSRV_ERROR_NOT_IMPLEMENTED)
+PVRE(PVRSRV_ERROR_FLIP_CHAIN_EXISTS)
+PVRE(PVRSRV_ERROR_INVALID_SWAPINTERVAL)
+PVRE(PVRSRV_ERROR_SCENE_INVALID)
+PVRE(PVRSRV_ERROR_STREAM_ERROR)
+PVRE(PVRSRV_ERROR_FAILED_DEPENDENCIES)
+PVRE(PVRSRV_ERROR_CMD_NOT_PROCESSED)
+PVRE(PVRSRV_ERROR_CMD_TOO_BIG)
+PVRE(PVRSRV_ERROR_DEVICE_REGISTER_FAILED)
+PVRE(PVRSRV_ERROR_TOOMANYBUFFERS)
+PVRE(PVRSRV_ERROR_NOT_SUPPORTED)
+PVRE(PVRSRV_ERROR_PROCESSING_BLOCKED)
+PVRE(PVRSRV_ERROR_CANNOT_FLUSH_QUEUE)
+PVRE(PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE)
+PVRE(PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS)
+PVRE(PVRSRV_ERROR_RETRY)
+PVRE(PVRSRV_ERROR_DDK_VERSION_MISMATCH)
+PVRE(PVRSRV_ERROR_DDK_BUILD_MISMATCH)
+PVRE(PVRSRV_ERROR_BUILD_OPTIONS_MISMATCH)
+PVRE(PVRSRV_ERROR_BVNC_MISMATCH)
+PVRE(PVRSRV_ERROR_FWPROCESSOR_MISMATCH)
+PVRE(PVRSRV_ERROR_UPLOAD_TOO_BIG)
+PVRE(PVRSRV_ERROR_INVALID_FLAGS)
+PVRE(PVRSRV_ERROR_FAILED_TO_REGISTER_PROCESS)
+PVRE(PVRSRV_ERROR_UNABLE_TO_LOAD_LIBRARY)
+PVRE(PVRSRV_ERROR_UNABLE_GET_FUNC_ADDR)
+PVRE(PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED)
+PVRE(PVRSRV_ERROR_BRIDGE_CALL_FAILED)
+PVRE(PVRSRV_ERROR_IOCTL_CALL_FAILED)
+PVRE(PVRSRV_ERROR_MMU_API_PROTOCOL_ERROR)
+PVRE(PVRSRV_ERROR_MMU_CONFIG_IS_WRONG)
+PVRE(PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND)
+PVRE(PVRSRV_ERROR_MMU_FAILED_TO_ALLOCATE_PAGETABLES)
+PVRE(PVRSRV_ERROR_MMU_FAILED_TO_CREATE_HEAP)
+PVRE(PVRSRV_ERROR_MMU_FAILED_TO_MAP_PAGE_TABLE)
+PVRE(PVRSRV_ERROR_MMU_FAILED_TO_UNMAP_PAGE_TABLE)
+PVRE(PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE)
+PVRE(PVRSRV_ERROR_MMU_LIVE_ALLOCATIONS_IN_HEAP)
+PVRE(PVRSRV_ERROR_MMU_RESERVATION_NOT_INSIDE_HEAP)
+PVRE(PVRSRV_ERROR_PMR_NEW_MEMORY)
+PVRE(PVRSRV_ERROR_PMR_STILL_REFERENCED)
+PVRE(PVRSRV_ERROR_PMR_CLIENT_NOT_TRUSTED)
+PVRE(PVRSRV_ERROR_PMR_FAILED_TO_ALLOC_PAGES)
+PVRE(PVRSRV_ERROR_PMR_INCOMPATIBLE_CONTIGUITY)
+PVRE(PVRSRV_ERROR_PMR_MISMATCHED_ATTRIBUTES)
+PVRE(PVRSRV_ERROR_PMR_NOT_PAGE_MULTIPLE)
+PVRE(PVRSRV_ERROR_PMR_NOT_PERMITTED)
+PVRE(PVRSRV_ERROR_PMR_ALREADY_OCCUPIED)
+PVRE(PVRSRV_ERROR_PMR_UNRECOVERABLE_ERROR)
+PVRE(PVRSRV_ERROR_PMR_WRONG_PASSWORD_OR_STALE_PMR)
+PVRE(PVRSRV_ERROR_PMR_WRONG_PMR_TYPE)
+PVRE(PVRSRV_ERROR_PMR_MAPPING_ALREADY_EXISTS)
+PVRE(PVRSRV_ERROR_PMR_BAD_MAPPINGTABLE_SIZE)
+PVRE(PVRSRV_ERROR_PMR_BAD_CHUNK_SIZE)
+PVRE(PVRSRV_ERROR_PMR_MAPPINGTABLE_MISMATCH)
+PVRE(PVRSRV_ERROR_PMR_INVALID_CHUNK)
+PVRE(PVRSRV_ERROR_PMR_NO_KERNEL_MAPPING)
+PVRE(PVRSRV_ERROR_PMR_EMPTY)
+PVRE(PVRSRV_ERROR_PMR_NO_CPU_MAP_FOUND)
+PVRE(PVRSRV_ERROR_PMR_CPU_PAGE_UNMAP_FAILED)
+PVRE(PVRSRV_ERROR_PMR_CPU_PAGE_MAP_FAILED)
+PVRE(PVRSRV_ERROR_PMR_PAGE_POISONING_FAILED)
+PVRE(PVRSRV_ERROR_PMR_INVALID_MAP_INDEX_ARRAY)
+PVRE(PVRSRV_ERROR_DEVICEMEM_ALLOCATIONS_REMAIN_IN_HEAP)
+PVRE(PVRSRV_ERROR_DEVICEMEM_BAD_IMPORT_SIZE)
+PVRE(PVRSRV_ERROR_DEVICEMEM_CANT_EXPORT_SUBALLOCATION)
+PVRE(PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_CONFIG_INDEX)
+PVRE(PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_INDEX)
+PVRE(PVRSRV_ERROR_DEVICEMEM_MAP_FAILED)
+PVRE(PVRSRV_ERROR_DEVICEMEM_NON_ZERO_USAGE_COUNT)
+PVRE(PVRSRV_ERROR_DEVICEMEM_OUT_OF_RANGE)
+PVRE(PVRSRV_ERROR_DEVICEMEM_VA_ALLOC_FAILED)
+PVRE(PVRSRV_ERROR_DEVICEMEM_UNABLE_TO_CREATE_ARENA)
+PVRE(PVRSRV_ERROR_DEVICEMEM_OUT_OF_DEVICE_VM)
+PVRE(PVRSRV_ERROR_DEVICEMEM_ALREADY_MAPPED)
+PVRE(PVRSRV_ERROR_DEVICEMEM_NO_MAPPING)
+PVRE(PVRSRV_ERROR_DEVICEMEM_INVALID_PMR_FLAGS)
+PVRE(PVRSRV_ERROR_DEVICEMEM_INVALID_LMA_HEAP)
+PVRE(PVRSRV_ERROR_INVALID_MMU_TYPE)
+PVRE(PVRSRV_ERROR_BUFFER_DEVICE_NOT_FOUND)
+PVRE(PVRSRV_ERROR_BUFFER_DEVICE_ALREADY_PRESENT)
+PVRE(PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND)
+PVRE(PVRSRV_ERROR_PCI_CALL_FAILED)
+PVRE(PVRSRV_ERROR_PCI_REGION_TOO_SMALL)
+PVRE(PVRSRV_ERROR_PCI_REGION_UNAVAILABLE)
+PVRE(PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH)
+PVRE(PVRSRV_ERROR_REGISTER_BASE_NOT_SET)
+PVRE(PVRSRV_ERROR_FAILED_TO_ALLOC_USER_MEM)
+PVRE(PVRSRV_ERROR_FAILED_TO_ALLOC_VP_MEMORY)
+PVRE(PVRSRV_ERROR_FAILED_TO_MAP_SHARED_PBDESC)
+PVRE(PVRSRV_ERROR_FAILED_TO_MAP_KERNELVIRTUAL)
+PVRE(PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR)
+PVRE(PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY)
+PVRE(PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY)
+PVRE(PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES)
+PVRE(PVRSRV_ERROR_FAILED_TO_FREE_PAGES)
+PVRE(PVRSRV_ERROR_FAILED_TO_COPY_PAGES)
+PVRE(PVRSRV_ERROR_UNABLE_TO_LOCK_PAGES)
+PVRE(PVRSRV_ERROR_UNABLE_TO_UNLOCK_PAGES)
+PVRE(PVRSRV_ERROR_STILL_MAPPED)
+PVRE(PVRSRV_ERROR_MAPPING_NOT_FOUND)
+PVRE(PVRSRV_ERROR_PHYS_ADDRESS_EXCEEDS_32BIT)
+PVRE(PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE)
+PVRE(PVRSRV_ERROR_INVALID_SEGMENT_BLOCK)
+PVRE(PVRSRV_ERROR_INVALID_GFXDEVDEVDATA)
+PVRE(PVRSRV_ERROR_INVALID_DEVINFO)
+PVRE(PVRSRV_ERROR_INVALID_MEMINFO)
+PVRE(PVRSRV_ERROR_INVALID_MISCINFO)
+PVRE(PVRSRV_ERROR_UNKNOWN_IOCTL)
+PVRE(PVRSRV_ERROR_INVALID_CONTEXT)
+PVRE(PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT)
+PVRE(PVRSRV_ERROR_INVALID_HEAP)
+PVRE(PVRSRV_ERROR_INVALID_KERNELINFO)
+PVRE(PVRSRV_ERROR_UNKNOWN_POWER_STATE)
+PVRE(PVRSRV_ERROR_INVALID_HANDLE_TYPE)
+PVRE(PVRSRV_ERROR_INVALID_WRAP_TYPE)
+PVRE(PVRSRV_ERROR_INVALID_PHYS_ADDR)
+PVRE(PVRSRV_ERROR_INVALID_CPU_ADDR)
+PVRE(PVRSRV_ERROR_INVALID_HEAPINFO)
+PVRE(PVRSRV_ERROR_INVALID_PERPROC)
+PVRE(PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO)
+PVRE(PVRSRV_ERROR_INVALID_MAP_REQUEST)
+PVRE(PVRSRV_ERROR_INVALID_UNMAP_REQUEST)
+PVRE(PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP)
+PVRE(PVRSRV_ERROR_MAPPING_STILL_IN_USE)
+PVRE(PVRSRV_ERROR_EXCEEDED_HW_LIMITS)
+PVRE(PVRSRV_ERROR_NO_STAGING_BUFFER_ALLOCATED)
+PVRE(PVRSRV_ERROR_UNABLE_TO_CREATE_PERPROC_AREA)
+PVRE(PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT)
+PVRE(PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT)
+PVRE(PVRSRV_ERROR_UNABLE_TO_REGISTER_EVENT)
+PVRE(PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT)
+PVRE(PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD)
+PVRE(PVRSRV_ERROR_UNABLE_TO_CLOSE_THREAD)
+PVRE(PVRSRV_ERROR_THREAD_READ_ERROR)
+PVRE(PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER)
+PVRE(PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR)
+PVRE(PVRSRV_ERROR_UNABLE_TO_UNINSTALL_ISR)
+PVRE(PVRSRV_ERROR_ISR_ALREADY_INSTALLED)
+PVRE(PVRSRV_ERROR_ISR_NOT_INSTALLED)
+PVRE(PVRSRV_ERROR_UNABLE_TO_INITIALISE_INTERRUPT)
+PVRE(PVRSRV_ERROR_UNABLE_TO_RETRIEVE_INFO)
+PVRE(PVRSRV_ERROR_UNABLE_TO_DO_BACKWARDS_BLIT)
+PVRE(PVRSRV_ERROR_UNABLE_TO_CLOSE_SERVICES)
+PVRE(PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT)
+PVRE(PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE)
+PVRE(PVRSRV_ERROR_INVALID_CCB_COMMAND)
+PVRE(PVRSRV_ERROR_KERNEL_CCB_FULL)
+PVRE(PVRSRV_ERROR_FLIP_FAILED)
+PVRE(PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED)
+PVRE(PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE)
+PVRE(PVRSRV_ERROR_TIMEOUT_WAITING_FOR_CLIENT_CCB)
+PVRE(PVRSRV_ERROR_CREATE_RENDER_CONTEXT_FAILED)
+PVRE(PVRSRV_ERROR_UNKNOWN_PRIMARY_FRAG)
+PVRE(PVRSRV_ERROR_UNEXPECTED_SECONDARY_FRAG)
+PVRE(PVRSRV_ERROR_UNEXPECTED_PRIMARY_FRAG)
+PVRE(PVRSRV_ERROR_UNABLE_TO_INSERT_FENCE_ID)
+PVRE(PVRSRV_ERROR_BLIT_SETUP_FAILED)
+PVRE(PVRSRV_ERROR_SUBMIT_NEEDED)
+PVRE(PVRSRV_ERROR_PDUMP_NOT_AVAILABLE)
+PVRE(PVRSRV_ERROR_PDUMP_BUFFER_FULL)
+PVRE(PVRSRV_ERROR_PDUMP_BUF_OVERFLOW)
+PVRE(PVRSRV_ERROR_PDUMP_NOT_ACTIVE)
+PVRE(PVRSRV_ERROR_INCOMPLETE_LINE_OVERLAPS_PAGES)
+PVRE(PVRSRV_ERROR_MUTEX_DESTROY_FAILED)
+PVRE(PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR)
+PVRE(PVRSRV_ERROR_INSUFFICIENT_SPACE_FOR_COMMAND)
+PVRE(PVRSRV_ERROR_PROCESS_NOT_INITIALISED)
+PVRE(PVRSRV_ERROR_PROCESS_NOT_FOUND)
+PVRE(PVRSRV_ERROR_SRV_CONNECT_FAILED)
+PVRE(PVRSRV_ERROR_SRV_DISCONNECT_FAILED)
+PVRE(PVRSRV_ERROR_DEINT_PHASE_FAILED)
+PVRE(PVRSRV_ERROR_INIT2_PHASE_FAILED)
+PVRE(PVRSRV_ERROR_UNABLE_TO_FIND_RESOURCE)
+PVRE(PVRSRV_ERROR_NO_DC_DEVICES_FOUND)
+PVRE(PVRSRV_ERROR_DC_DEVICE_INACCESSIBLE)
+PVRE(PVRSRV_ERROR_DC_INVALID_MAXDEPTH)
+PVRE(PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_UNREGISTER_DEVICE)
+PVRE(PVRSRV_ERROR_NO_DEVICEDATA_FOUND)
+PVRE(PVRSRV_ERROR_NO_DEVICENODE_FOUND)
+PVRE(PVRSRV_ERROR_NO_CLIENTNODE_FOUND)
+PVRE(PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_INIT_TASK)
+PVRE(PVRSRV_ERROR_UNABLE_TO_SCHEDULE_TASK)
+PVRE(PVRSRV_ERROR_UNABLE_TO_KILL_TASK)
+PVRE(PVRSRV_ERROR_UNABLE_TO_ENABLE_TIMER)
+PVRE(PVRSRV_ERROR_UNABLE_TO_DISABLE_TIMER)
+PVRE(PVRSRV_ERROR_UNABLE_TO_REMOVE_TIMER)
+PVRE(PVRSRV_ERROR_UNKNOWN_PIXEL_FORMAT)
+PVRE(PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE)
+PVRE(PVRSRV_ERROR_HANDLE_NOT_ALLOCATED)
+PVRE(PVRSRV_ERROR_HANDLE_TYPE_MISMATCH)
+PVRE(PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE)
+PVRE(PVRSRV_ERROR_HANDLE_NOT_SHAREABLE)
+PVRE(PVRSRV_ERROR_HANDLE_NOT_FOUND)
+PVRE(PVRSRV_ERROR_INVALID_SUBHANDLE)
+PVRE(PVRSRV_ERROR_HANDLE_BATCH_IN_USE)
+PVRE(PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_RETRIEVE_HASH_VALUE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_REMOVE_HASH_VALUE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_INSERT_HASH_VALUE)
+PVRE(PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED)
+PVRE(PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP)
+PVRE(PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE)
+PVRE(PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVAILABLE)
+PVRE(PVRSRV_ERROR_INVALID_DEVICEID)
+PVRE(PVRSRV_ERROR_DEVICEID_NOT_FOUND)
+PVRE(PVRSRV_ERROR_MEMORY_TEST_FAILED)
+PVRE(PVRSRV_ERROR_CPUPADDR_TEST_FAILED)
+PVRE(PVRSRV_ERROR_COPY_TEST_FAILED)
+PVRE(PVRSRV_ERROR_SEMAPHORE_NOT_INITIALISED)
+PVRE(PVRSRV_ERROR_UNABLE_TO_RELEASE_CLOCK)
+PVRE(PVRSRV_ERROR_CLOCK_REQUEST_FAILED)
+PVRE(PVRSRV_ERROR_DISABLE_CLOCK_FAILURE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK)
+PVRE(PVRSRV_ERROR_UNABLE_TO_GET_CLOCK)
+PVRE(PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK)
+PVRE(PVRSRV_ERROR_UNABLE_TO_GET_SYSTEM_CLOCK)
+PVRE(PVRSRV_ERROR_UNKNOWN_SGL_ERROR)
+PVRE(PVRSRV_ERROR_SYSTEM_POWER_CHANGE_FAILURE)
+PVRE(PVRSRV_ERROR_DEVICE_POWER_CHANGE_FAILURE)
+PVRE(PVRSRV_ERROR_DEVICE_POWER_CHANGE_DENIED)
+PVRE(PVRSRV_ERROR_BAD_SYNC_STATE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_SET_CACHE_MODE)
+PVRE(PVRSRV_ERROR_FAILED_TO_ALLOC_MMUCONTEXT_ID)
+PVRE(PVRSRV_ERROR_PARAMETER_BUFFER_INVALID_ALIGNMENT)
+PVRE(PVRSRV_ERROR_UNABLE_TO_ACQUIRE_CONNECTION)
+PVRE(PVRSRV_ERROR_UNABLE_TO_RELEASE_CONNECTION)
+PVRE(PVRSRV_ERROR_PHYSHEAP_ID_IN_USE)
+PVRE(PVRSRV_ERROR_PHYSHEAP_ID_INVALID)
+PVRE(PVRSRV_ERROR_PHYSHEAP_CONFIG)
+PVRE(PVRSRV_ERROR_HP_REQUEST_TOO_LONG)
+PVRE(PVRSRV_ERROR_INVALID_SYNC_PRIM)
+PVRE(PVRSRV_ERROR_INVALID_SYNC_PRIM_OP)
+PVRE(PVRSRV_ERROR_INVALID_SYNC_CONTEXT)
+PVRE(PVRSRV_ERROR_BP_NOT_SET)
+PVRE(PVRSRV_ERROR_BP_ALREADY_SET)
+PVRE(PVRSRV_ERROR_FEATURE_DISABLED)
+PVRE(PVRSRV_ERROR_REG_CONFIG_ENABLED)
+PVRE(PVRSRV_ERROR_REG_CONFIG_FULL)
+PVRE(PVRSRV_ERROR_REG_CONFIG_INVALID_TYPE)
+PVRE(PVRSRV_ERROR_MEMORY_ACCESS)
+PVRE(PVRSRV_ERROR_NO_SYSTEM_BUFFER)
+PVRE(PVRSRV_ERROR_DC_INVALID_CONFIG)
+PVRE(PVRSRV_ERROR_DC_INVALID_CROP_RECT)
+PVRE(PVRSRV_ERROR_DC_INVALID_DISPLAY_RECT)
+PVRE(PVRSRV_ERROR_DC_INVALID_BUFFER_DIMS)
+PVRE(PVRSRV_ERROR_DC_INVALID_TRANSFORM)
+PVRE(PVRSRV_ERROR_DC_INVALID_SCALE)
+PVRE(PVRSRV_ERROR_DC_INVALID_CUSTOM)
+PVRE(PVRSRV_ERROR_DC_TOO_MANY_PIPES)
+PVRE(PVRSRV_ERROR_DC_INVALID_PLANE_ALPHA)
+PVRE(PVRSRV_ERROR_NOT_READY)
+PVRE(PVRSRV_ERROR_RESOURCE_UNAVAILABLE)
+PVRE(PVRSRV_ERROR_UNSUPPORTED_PIXEL_FORMAT)
+PVRE(PVRSRV_ERROR_UNSUPPORTED_MEMORY_LAYOUT)
+PVRE(PVRSRV_ERROR_UNSUPPORTED_FB_COMPRESSION_MODE)
+PVRE(PVRSRV_ERROR_UNSUPPORTED_DIMS)
+PVRE(PVRSRV_ERROR_UNSUPPORTED_CACHE_MODE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_ADD_TIMER)
+PVRE(PVRSRV_ERROR_NOT_FOUND)
+PVRE(PVRSRV_ERROR_ALREADY_OPEN)
+PVRE(PVRSRV_ERROR_STREAM_MISUSE)
+PVRE(PVRSRV_ERROR_STREAM_FULL)
+PVRE(PVRSRV_ERROR_STREAM_READLIMIT_REACHED)
+PVRE(PVRSRV_ERROR_STREAM_NOT_ENOUGH_SPACE)
+PVRE(PVRSRV_ERROR_PHYSMEM_NOT_ALLOCATED)
+PVRE(PVRSRV_ERROR_PBSIZE_ALREADY_MAX)
+PVRE(PVRSRV_ERROR_PBSIZE_ALREADY_MIN)
+PVRE(PVRSRV_ERROR_INVALID_PB_CONFIG)
+PVRE(PVRSRV_ERROR_META_THREAD0_NOT_ENABLED)
+PVRE(PVRSRV_ERROR_NOT_AUTHENTICATED)
+PVRE(PVRSRV_ERROR_REQUEST_TDFWMEM_PAGES_FAIL)
+PVRE(PVRSRV_ERROR_INIT_TDFWMEM_PAGES_FAIL)
+PVRE(PVRSRV_ERROR_REQUEST_TDSECUREBUF_PAGES_FAIL)
+PVRE(PVRSRV_ERROR_INIT_TDSECUREBUF_PAGES_FAIL)
+PVRE(PVRSRV_ERROR_MUTEX_ALREADY_CREATED)
+PVRE(PVRSRV_ERROR_DBGTABLE_ALREADY_REGISTERED)
+PVRE(PVRSRV_ERROR_ALREADY_EXISTS)
+PVRE(PVRSRV_ERROR_UNABLE_TO_SEND_PULSE)
+PVRE(PVRSRV_ERROR_TASK_FAILED)
+PVRE(PVRSRV_ERROR_DEVICE_IDLE_REQUEST_DENIED)
+PVRE(PVRSRV_ERROR_INVALID_GPU_ADDR)
+PVRE(PVRSRV_ERROR_INVALID_OFFSET)
+PVRE(PVRSRV_ERROR_CCCB_STALLED)
+PVRE(PVRSRV_ERROR_MIPS_STATUS_UNAVAILABLE)
+PVRE(PVRSRV_ERROR_NOT_ENABLED)
+PVRE(PVRSRV_ERROR_SYSTEM_LOCAL_MEMORY_INIT_FAIL)
+PVRE(PVRSRV_ERROR_FW_IMAGE_MISMATCH)
+PVRE(PVRSRV_ERROR_PDUMP_NOT_ALLOWED)
+PVRE(PVRSRV_ERROR_BRIDGE_BUFFER_TOO_SMALL)
+PVRE(PVRSRV_ERROR_RPM_PBSIZE_ALREADY_MAX)
+PVRE(PVRSRV_ERROR_NONZERO_REFCOUNT)
+PVRE(PVRSRV_ERROR_SETAFFINITY_FAILED)
+PVRE(PVRSRV_ERROR_UNABLE_TO_COMPILE_PDS)
+PVRE(PVRSRV_ERROR_INTERNAL_ERROR)
+PVRE(PVRSRV_ERROR_BRIDGE_EFAULT)
+PVRE(PVRSRV_ERROR_BRIDGE_EINVAL)
+PVRE(PVRSRV_ERROR_BRIDGE_ENOMEM)
+PVRE(PVRSRV_ERROR_BRIDGE_ERANGE)
+PVRE(PVRSRV_ERROR_BRIDGE_EPERM)
+PVRE(PVRSRV_ERROR_BRIDGE_ENOTTY)
+PVRE(PVRSRV_ERROR_SYNC_NATIVESYNC_NOT_REGISTERED)
+PVRE(PVRSRV_ERROR_PROBE_DEFER)
+PVRE(PVRSRV_ERROR_INVALID_ALIGNMENT)
+PVRE(PVRSRV_ERROR_CLOSE_FAILED)
+PVRE(PVRSRV_ERROR_NOT_INITIALISED)
+PVRE(PVRSRV_ERROR_CONVERSION_FAILED)
+PVRE(PVRSRV_ERROR_RA_REQUEST_ALLOC_FAIL)
+PVRE(PVRSRV_ERROR_RA_REQUEST_VIRT_ADDR_FAIL)
+PVRE(PVRSRV_ERROR_RA_INSERT_RESOURCE_SPAN_FAILED)
+PVRE(PVRSRV_ERROR_RA_ATTEMPT_ALLOC_ALIGNED_FAILED)
+PVRE(PVRSRV_ERROR_OBJECT_STILL_REFERENCED)
+PVRE(PVRSRV_ERROR_BVNC_UNSUPPORTED)
+PVRE(PVRSRV_ERROR_INVALID_BVNC_PARAMS)
+PVRE(PVRSRV_ERROR_ALIGNMENT_ARRAY_NOT_AVAILABLE)
+PVRE(PVRSRV_ERROR_DEVICEMEM_ADDITIONAL_HEAPS_IN_CONTEXT)
+PVRE(PVRSRV_ERROR_PID_ALREADY_REGISTERED)
+PVRE(PVRSRV_ERROR_PID_NOT_REGISTERED)
+PVRE(PVRSRV_ERROR_SIGNAL_FAILED)
+PVRE(PVRSRV_ERROR_INVALID_NOTIF_STREAM)
+PVRE(PVRSRV_ERROR_INVALID_SPU_MASK)
+PVRE(PVRSRV_ERROR_FREELIST_RECONSTRUCTION_FAILED)
+PVRE(PVRSRV_ERROR_INVALID_PVZ_CONFIG)
+PVRE(PVRSRV_ERROR_TLPACKET_SIZE_LIMIT_EXCEEDED)
+PVRE(PVRSRV_ERROR_NOT_SW_TIMELINE)
+PVRE(PVRSRV_ERROR_SW_TIMELINE_AT_LATEST_POINT)
+PVRE(PVRSRV_ERROR_INVALID_PVZ_OSID)
+PVRE(PVRSRV_ERROR_PVZ_OSID_IS_OFFLINE)
+PVRE(PVRSRV_ERROR_BRIDGE_ARRAY_SIZE_TOO_BIG)
+PVRE(PVRSRV_ERROR_INTERRUPTED)
+PVRE(PVRSRV_ERROR_PWLOCK_RELEASED_REACQ_FAILED)
+PVRE(PVRSRV_ERROR_PDUMP_INVALID_BLOCKLEN)
+PVRE(PVRSRV_ERROR_SYSTEM_STATE_POWERED_OFF)
+PVRE(PVRSRV_ERROR_MULTIPLE_SECURITY_PDUMPS)
+PVRE(PVRSRV_ERROR_BAD_PARAM_SIZE)
+PVRE(PVRSRV_ERROR_INVALID_REQUEST)
+PVRE(PVRSRV_ERROR_FAILED_TO_ACQUIRE_PAGES)
+PVRE(PVRSRV_ERROR_TEST_FAILED)
+PVRE(PVRSRV_ERROR_SYNC_PRIM_OP_NOT_SUPPORTED)
+PVRE(PVRSRV_ERROR_FAILED_TO_GET_VIRT_ADDR)
+PVRE(PVRSRV_ERROR_UNABLE_TO_FREE_RESOURCE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_CREATE_SEMAPHORE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_REGISTER_SEMAPHORE)
+PVRE(PVRSRV_ERROR_UNABLE_TO_DESTROY_SEMAPHORE)
+PVRE(PVRSRV_ERROR_TOO_MANY_SYNCS)
+PVRE(PVRSRV_ERROR_ION_NO_CLIENT)
+PVRE(PVRSRV_ERROR_ION_FAILED_TO_ALLOC)
+PVRE(PVRSRV_ERROR_PDUMP_CAPTURE_BOUND_TO_ANOTHER_DEVICE)
diff --git a/drivers/gpu/drm/img-rogue/include/pvrsrv_memalloc_physheap.h b/drivers/gpu/drm/img-rogue/include/pvrsrv_memalloc_physheap.h
new file mode 100644
index 000000000..f002a1af3
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/pvrsrv_memalloc_physheap.h
@@ -0,0 +1,96 @@
+/*************************************************************************/ /*!
+@File pvrsrv_memalloc_physheap.h
+@Title Services Phys Heap types
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Used in creating and allocating from Physical Heaps.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef PVRSRV_MEMALLOC_PHYSHEAP_H
+#define PVRSRV_MEMALLOC_PHYSHEAP_H
+
+#include "img_defs.h"
+
+/*
+ * These IDs are replicated in the Device Memory allocation flags to allow
+ * allocations to be made in terms of their locality/use to ensure the correct
+ * physical heap is accessed for the given system/platform configuration.
+ * A system Phys Heap Config is linked to one or more Phys Heaps. When a heap
+ * is not present in the system configuration the allocation will fallback to
+ * the default GPU_LOCAL physical heap which all systems must define.
+ * See PVRSRV_MEMALLOCFLAGS_*_MAPPABLE_MASK.
+ *
+ * NOTE: Enum order important, table in physheap.c must change if order changed.
+ */
+typedef enum
+{
+ /* Services client accessible heaps */
+ PVRSRV_PHYS_HEAP_DEFAULT = 0, /* default phys heap for device memory allocations */
+ PVRSRV_PHYS_HEAP_GPU_LOCAL = 1, /* used for buffers with more GPU access than CPU */
+ PVRSRV_PHYS_HEAP_CPU_LOCAL = 2, /* used for buffers with more CPU access than GPU */
+ PVRSRV_PHYS_HEAP_GPU_PRIVATE = 3, /* used for buffers that only required GPU read/write access, not visible to the CPU. */
+
+ /* Services internal heaps */
+ PVRSRV_PHYS_HEAP_FW_MAIN = 4, /* runtime data, e.g. CCBs, sync objects */
+ PVRSRV_PHYS_HEAP_EXTERNAL = 5, /* used by some PMR import/export factories where the physical memory heap is not managed by the pvrsrv driver */
+ PVRSRV_PHYS_HEAP_GPU_COHERENT = 6, /* used for a cache coherent region */
+ PVRSRV_PHYS_HEAP_GPU_SECURE = 7, /* used by security validation */
+ PVRSRV_PHYS_HEAP_FW_CONFIG = 8, /* subheap of FW_MAIN, configuration data for FW init */
+ PVRSRV_PHYS_HEAP_FW_CODE = 9, /* used by security validation or dedicated fw */
+ PVRSRV_PHYS_HEAP_FW_PRIV_DATA = 10, /* internal FW data (like the stack, FW control data structures, etc.) */
+ PVRSRV_PHYS_HEAP_FW_PREMAP0 = 11, /* Host OS premap fw heap */
+ PVRSRV_PHYS_HEAP_FW_PREMAP1 = 12, /* Guest OS 1 premap fw heap */
+ PVRSRV_PHYS_HEAP_FW_PREMAP2 = 13, /* Guest OS 2 premap fw heap */
+ PVRSRV_PHYS_HEAP_FW_PREMAP3 = 14, /* Guest OS 3 premap fw heap */
+ PVRSRV_PHYS_HEAP_FW_PREMAP4 = 15, /* Guest OS 4 premap fw heap */
+ PVRSRV_PHYS_HEAP_FW_PREMAP5 = 16, /* Guest OS 5 premap fw heap */
+ PVRSRV_PHYS_HEAP_FW_PREMAP6 = 17, /* Guest OS 6 premap fw heap */
+ PVRSRV_PHYS_HEAP_FW_PREMAP7 = 18, /* Guest OS 7 premap fw heap */
+ PVRSRV_PHYS_HEAP_LAST
+} PVRSRV_PHYS_HEAP;
+
+
+static_assert(PVRSRV_PHYS_HEAP_LAST <= (0x1FU + 1U), "Ensure enum fits in memalloc flags bitfield.");
+
+typedef struct _PHYS_HEAP_MEM_STATS_
+{
+ IMG_UINT64 ePhysHeapID;
+ IMG_UINT64 ui64TotalSize;
+ IMG_UINT64 ui64FreeSize;
+}PHYS_HEAP_MEM_STATS, *PHYS_HEAP_MEM_STATS_PTR;
+
+#endif /* PVRSRV_MEMALLOC_PHYSHEAP_H */
diff --git a/drivers/gpu/drm/img-rogue/include/pvrsrv_memallocflags.h b/drivers/gpu/drm/img-rogue/include/pvrsrv_memallocflags.h
new file mode 100644
index 000000000..28a4c018f
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/pvrsrv_memallocflags.h
@@ -0,0 +1,923 @@
+/*************************************************************************/ /*!
+@File
+@Title Device Memory Management
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description This file defines flags used on memory allocations and mappings
+ These flags are relevant throughout the memory management
+ software stack and are specified by users of services and
+ understood by all levels of the memory management in both
+ client and server.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef PVRSRV_MEMALLOCFLAGS_H
+#define PVRSRV_MEMALLOCFLAGS_H
+
+#include "img_types.h"
+#include "pvrsrv_memalloc_physheap.h"
+
+/*!
+ Type for specifying memory allocation flags.
+ */
+
+typedef IMG_UINT64 PVRSRV_MEMALLOCFLAGS_T;
+#define PVRSRV_MEMALLOCFLAGS_FMTSPEC IMG_UINT64_FMTSPECx
+
+#if defined(__KERNEL__) || defined(SERVICES_SC)
+#include "pvrsrv_memallocflags_internal.h"
+#endif /* __KERNEL__ */
+
+/*
+ * --- MAPPING FLAGS 0..14 (15-bits) ---
+ * | 0-3 | 4-7 | 8-10 | 11-13 | 14 |
+ * | GPU-RW | CPU-RW | GPU-Caching | CPU-Caching | KM-Mappable |
+ *
+ * --- MISC FLAGS 15..23 (9-bits) ---
+ * | 15 | 17 | 18 | 19 | 20 |
+ * | Defer | SVM | Sparse-Dummy-Page | CPU-Cache-Clean | Sparse-Zero-Page |
+ *
+ * --- DEV CONTROL FLAGS 26..27 (2-bits) ---
+ * | 26-27 |
+ * | Device-Flags |
+ *
+ * --- MISC FLAGS 28..31 (4-bits) ---
+ * | 28 | 29 | 30 | 31 |
+ * | No-Cache-Align | Poison-On-Free | P.-On-Alloc | Zero-On-Alloc |
+ *
+ * --- VALIDATION FLAGS ---
+ * | 35 |
+ * | Shared-buffer |
+ *
+ * --- PHYS HEAP HINTS ---
+ * | 59-63 |
+ * | PhysHeap Hints |
+ *
+ */
+
+/*
+ * **********************************************************
+ * * *
+ * * MAPPING FLAGS *
+ * * *
+ * **********************************************************
+ */
+
+/*!
+ * This flag affects the device MMU protection flags, and specifies
+ * that the memory may be read by the GPU.
+ *
+ * Typically all device memory allocations would specify this flag.
+ *
+ * At the moment, memory allocations without this flag are not supported
+ *
+ * This flag will live with the PMR, thus subsequent mappings would
+ * honour this flag.
+ *
+ * This is a dual purpose flag. It specifies that memory is permitted
+ * to be read by the GPU, and also requests that the allocation is
+ * mapped into the GPU as a readable mapping
+ *
+ * To be clear:
+ * - When used as an argument on PMR creation; it specifies
+ * that GPU readable mappings will be _permitted_
+ * - When used as an argument to a "map" function: it specifies
+ * that a GPU readable mapping is _desired_
+ * - When used as an argument to "AllocDeviceMem": it specifies
+ * that the PMR will be created with permission to be mapped
+ * with a GPU readable mapping, _and_ that this PMR will be
+ * mapped with a GPU readable mapping.
+ * This distinction becomes important when (a) we export allocations;
+ * and (b) when we separate the creation of the PMR from the mapping.
+ */
+#define PVRSRV_MEMALLOCFLAG_GPU_READABLE (1ULL<<0)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_GPU_READABLE flag is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the flag is set, false otherwise
+ */
+#define PVRSRV_CHECK_GPU_READABLE(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_GPU_READABLE) != 0U)
+
+/*!
+ * This flag affects the device MMU protection flags, and specifies
+ * that the memory may be written by the GPU
+ *
+ * Using this flag on an allocation signifies that the allocation is
+ * intended to be written by the GPU.
+ *
+ * Omitting this flag causes a read-only mapping.
+ *
+ * This flag will live with the PMR, thus subsequent mappings would
+ * honour this flag.
+ *
+ * This is a dual purpose flag. It specifies that memory is permitted
+ * to be written by the GPU, and also requests that the allocation is
+ * mapped into the GPU as a writable mapping (see note above about
+ * permission vs. mapping mode, and why this flag causes permissions
+ * to be inferred from mapping mode on first allocation)
+ *
+ * N.B. This flag has no relevance to the CPU's MMU mapping, if any,
+ * and would therefore not enforce read-only mapping on CPU.
+ */
+#define PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE (1ULL<<1)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE flag is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the flag is set, false otherwise
+ */
+#define PVRSRV_CHECK_GPU_WRITEABLE(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE) != 0U)
+
+/*!
+ The flag indicates whether an allocation can be mapped as GPU readable in another GPU memory context.
+ */
+#define PVRSRV_MEMALLOCFLAG_GPU_READ_PERMITTED (1ULL<<2)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_GPU_READ_PERMITTED flag is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the flag is set, false otherwise
+ */
+#define PVRSRV_CHECK_GPU_READ_PERMITTED(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_GPU_READ_PERMITTED) != 0U)
+
+/*!
+ The flag indicates whether an allocation can be mapped as GPU writable in another GPU memory context.
+ */
+#define PVRSRV_MEMALLOCFLAG_GPU_WRITE_PERMITTED (1ULL<<3)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_GPU_WRITE_PERMITTED flag is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the flag is set, false otherwise
+ */
+#define PVRSRV_CHECK_GPU_WRITE_PERMITTED(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_GPU_WRITE_PERMITTED) != 0U)
+
+/*!
+ The flag indicates that an allocation is mapped as readable to the CPU.
+ */
+#define PVRSRV_MEMALLOCFLAG_CPU_READABLE (1ULL<<4)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_READABLE flag is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the flag is set, false otherwise
+ */
+#define PVRSRV_CHECK_CPU_READABLE(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_CPU_READABLE) != 0U)
+
+/*!
+ The flag indicates that an allocation is mapped as writable to the CPU.
+ */
+#define PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE (1ULL<<5)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE flag is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the flag is set, false otherwise
+ */
+#define PVRSRV_CHECK_CPU_WRITEABLE(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE) != 0U)
+
+/*!
+ The flag indicates whether an allocation can be mapped as CPU readable in another CPU memory context.
+ */
+#define PVRSRV_MEMALLOCFLAG_CPU_READ_PERMITTED (1ULL<<6)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_READ_PERMITTED flag is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the flag is set, false otherwise
+ */
+#define PVRSRV_CHECK_CPU_READ_PERMITTED(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_CPU_READ_PERMITTED) != 0U)
+
+/*!
+ The flag indicates whether an allocation can be mapped as CPU writable in another CPU memory context.
+ */
+#define PVRSRV_MEMALLOCFLAG_CPU_WRITE_PERMITTED (1ULL<<7)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_WRITE_PERMITTED flag is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the flag is set, false otherwise
+ */
+#define PVRSRV_CHECK_CPU_WRITE_PERMITTED(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_CPU_WRITE_PERMITTED) != 0U)
+
+
+/*
+ * **********************************************************
+ * * *
+ * * CACHE CONTROL FLAGS *
+ * * *
+ * **********************************************************
+ */
+
+/*
+ GPU domain
+ ==========
+
+ The following defines are used to control the GPU cache bit field.
+ The defines are mutually exclusive.
+
+ A helper macro, PVRSRV_GPU_CACHE_MODE, is provided to obtain just the GPU
+ cache bit field from the flags. This should be used whenever the GPU cache
+ mode needs to be determined.
+*/
+
+/*!
+ GPU domain. Flag indicating uncached memory. This means that any writes to memory
+ allocated with this flag are written straight to memory and thus are
+ coherent for any device in the system.
+*/
+#define PVRSRV_MEMALLOCFLAG_GPU_UNCACHED (1ULL<<8)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_GPU_UNCACHED mode is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the mode is set, false otherwise
+ */
+#define PVRSRV_CHECK_GPU_UNCACHED(uiFlags) (PVRSRV_GPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_GPU_UNCACHED)
+
+/*!
+ GPU domain. Use write combiner (if supported) to combine sequential writes
+ together to reduce memory access by doing burst writes.
+*/
+#define PVRSRV_MEMALLOCFLAG_GPU_UNCACHED_WC (0ULL<<8)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_GPU_UNCACHED_WC mode is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the mode is set, false otherwise
+ */
+#define PVRSRV_CHECK_GPU_WRITE_COMBINE(uiFlags) (PVRSRV_GPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_GPU_UNCACHED_WC)
+
+/*!
+ GPU domain. This flag affects the GPU MMU protection flags.
+ The allocation will be cached.
+ Services will try to set the coherent bit in the GPU MMU tables so the
+ GPU cache is snooping the CPU cache. If coherency is not supported the
+ caller is responsible to ensure the caches are up to date.
+*/
+#define PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT (2ULL<<8)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT mode is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the mode is set, false otherwise
+ */
+#define PVRSRV_CHECK_GPU_CACHE_COHERENT(uiFlags) (PVRSRV_GPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT)
+
+/*!
+ GPU domain. Request cached memory, but not coherent (i.e. no cache
+ snooping). Services will flush the GPU internal caches after every GPU
+ task so no cache maintenance requests from the users are necessary.
+
+ Note: We reserve 3 bits in the CPU/GPU cache mode to allow for future
+ expansion.
+*/
+#define PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT (3ULL<<8)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT mode is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the mode is set, false otherwise
+ */
+#define PVRSRV_CHECK_GPU_CACHE_INCOHERENT(uiFlags) (PVRSRV_GPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT)
+
+/*!
+ GPU domain. This flag is for internal use only and is used to indicate
+ that the underlying allocation should be cached on the GPU after all
+ the snooping and coherent checks have been done
+*/
+#define PVRSRV_MEMALLOCFLAG_GPU_CACHED (7ULL<<8)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_GPU_CACHED mode is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the mode is set, false otherwise
+ */
+#define PVRSRV_CHECK_GPU_CACHED(uiFlags) (PVRSRV_GPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_GPU_CACHED)
+
+/*!
+ GPU domain. GPU cache mode mask.
+*/
+#define PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK (7ULL<<8)
+
+/*!
+ @Description A helper macro to obtain just the GPU cache bit field from the flags.
+ This should be used whenever the GPU cache mode needs to be determined.
+ @Input uiFlags Allocation flags.
+ @Return Value of the GPU cache bit field.
+ */
+#define PVRSRV_GPU_CACHE_MODE(uiFlags) ((uiFlags) & PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK)
+
+
+/*
+ CPU domain
+ ==========
+
+ The following defines are used to control the CPU cache bit field.
+ The defines are mutually exclusive.
+
+ A helper macro, PVRSRV_CPU_CACHE_MODE, is provided to obtain just the CPU
+ cache bit field from the flags. This should be used whenever the CPU cache
+ mode needs to be determined.
+*/
+
+/*!
+ CPU domain. Use write combiner (if supported) to combine sequential writes
+ together to reduce memory access by doing burst writes.
+*/
+#define PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC (0ULL<<11)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC mode is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the mode is set, false otherwise
+ */
+#define PVRSRV_CHECK_CPU_WRITE_COMBINE(uiFlags) (PVRSRV_CPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC)
+
+/*!
+ CPU domain. This flag affects the CPU MMU protection flags.
+ The allocation will be cached.
+ Services will try to set the coherent bit in the CPU MMU tables so the
+ CPU cache is snooping the GPU cache. If coherency is not supported the
+ caller is responsible to ensure the caches are up to date.
+*/
+#define PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT (2ULL<<11)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT mode is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the mode is set, false otherwise
+ */
+#define PVRSRV_CHECK_CPU_CACHE_COHERENT(uiFlags) (PVRSRV_CPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT)
+
+/*!
+ CPU domain. Request cached memory, but not coherent (i.e. no cache
+ snooping). This means that if the allocation needs to transition from
+ one device to another services has to be informed so it can
+ flush/invalidate the appropriate caches.
+
+ Note: We reserve 3 bits in the CPU/GPU cache mode to allow for future
+ expansion.
+*/
+#define PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT (3ULL<<11)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT mode is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the mode is set, false otherwise
+ */
+#define PVRSRV_CHECK_CPU_CACHE_INCOHERENT(uiFlags) (PVRSRV_CPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT)
+
+/*!
+ CPU domain. This flag is for internal use only and is used to indicate
+ that the underlying allocation should be cached on the CPU
+ after all the snooping and coherent checks have been done
+*/
+#define PVRSRV_MEMALLOCFLAG_CPU_CACHED (7ULL<<11)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_CACHED mode is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the mode is set, false otherwise
+ */
+#define PVRSRV_CHECK_CPU_CACHED(uiFlags) (PVRSRV_CPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CPU_CACHED)
+
+/*!
+ CPU domain. CPU cache mode mask
+*/
+#define PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK (7ULL<<11)
+
+/*!
+ @Description A helper macro to obtain just the CPU cache bit field from the flags.
+ This should be used whenever the CPU cache mode needs to be determined.
+ @Input uiFlags Allocation flags.
+ @Return Value of the CPU cache bit field.
+ */
+#define PVRSRV_CPU_CACHE_MODE(uiFlags) ((uiFlags) & PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK)
+
+/* Helper flags for usual cases */
+
+/*!
+ * Memory will be write-combined on CPU and GPU
+ */
+#define PVRSRV_MEMALLOCFLAG_UNCACHED_WC (PVRSRV_MEMALLOCFLAG_GPU_UNCACHED_WC | PVRSRV_MEMALLOCFLAG_CPU_UNCACHED_WC)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_UNCACHED_WC mode is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the mode is set, false otherwise
+ */
+#define PVRSRV_CHECK_WRITE_COMBINE(uiFlags) (PVRSRV_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_UNCACHED_WC)
+
+/*!
+ * Memory will be cached.
+ * Services will try to set the correct flags in the MMU tables.
+ * In case there is no coherency support the caller has to ensure caches are up to date */
+#define PVRSRV_MEMALLOCFLAG_CACHE_COHERENT (PVRSRV_MEMALLOCFLAG_GPU_CACHE_COHERENT | PVRSRV_MEMALLOCFLAG_CPU_CACHE_COHERENT)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CACHE_COHERENT mode is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the mode is set, false otherwise
+ */
+#define PVRSRV_CHECK_CACHE_COHERENT(uiFlags) (PVRSRV_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CACHE_COHERENT)
+
+/*!
+ * Memory will be cache-incoherent on CPU and GPU
+ */
+#define PVRSRV_MEMALLOCFLAG_CACHE_INCOHERENT (PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT | PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CACHE_INCOHERENT mode is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the mode is set, false otherwise
+ */
+#define PVRSRV_CHECK_CACHE_INCOHERENT(uiFlags) (PVRSRV_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CACHE_INCOHERENT)
+
+/*!
+ Cache mode mask
+*/
+#define PVRSRV_CACHE_MODE(uiFlags) (PVRSRV_GPU_CACHE_MODE(uiFlags) | PVRSRV_CPU_CACHE_MODE(uiFlags))
+
+
+/*!
+ CPU MMU Flags mask -- intended for use internal to services only
+ */
+#define PVRSRV_MEMALLOCFLAGS_CPU_MMUFLAGSMASK (PVRSRV_MEMALLOCFLAG_CPU_READABLE | \
+ PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | \
+ PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK)
+
+/*!
+ MMU Flags mask -- intended for use internal to services only - used for
+ partitioning the flags bits and determining which flags to pass down to
+ mmu_common.c
+ */
+#define PVRSRV_MEMALLOCFLAGS_GPU_MMUFLAGSMASK (PVRSRV_MEMALLOCFLAG_GPU_READABLE | \
+ PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | \
+ PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK)
+
+/*!
+ Indicates that the PMR created due to this allocation will support
+ in-kernel CPU mappings. Only privileged processes may use this flag as
+ it may cause wastage of precious kernel virtual memory on some platforms.
+ */
+#define PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE (1ULL<<14)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE flag is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the flag is set, false otherwise
+ */
+#define PVRSRV_CHECK_KERNEL_CPU_MAPPABLE(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE) != 0U)
+
+
+
+/*
+ *
+ * **********************************************************
+ * * *
+ * * ALLOC MEMORY FLAGS *
+ * * *
+ * **********************************************************
+ *
+ * (Bits 15)
+ *
+ */
+#define PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC (1ULL<<15)
+#define PVRSRV_CHECK_ON_DEMAND(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC) != 0U)
+
+/*!
+ Indicates that the allocation will be accessed by the CPU and GPU using
+ the same virtual address, i.e. for all SVM allocs,
+ IMG_CPU_VIRTADDR == IMG_DEV_VIRTADDR
+ */
+#define PVRSRV_MEMALLOCFLAG_SVM_ALLOC (1ULL<<17)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_SVM_ALLOC flag is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the flag is set, false otherwise
+ */
+#define PVRSRV_CHECK_SVM_ALLOC(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_SVM_ALLOC) != 0U)
+
+/*!
+ Indicates the particular memory that's being allocated is sparse and the
+ sparse regions should not be backed by dummy page
+*/
+#define PVRSRV_MEMALLOCFLAG_SPARSE_NO_DUMMY_BACKING (1ULL << 18)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_SPARSE_NO_DUMMY_BACKING flag is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the flag is set, false otherwise
+ */
+#define PVRSRV_IS_SPARSE_DUMMY_BACKING_REQUIRED(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_SPARSE_NO_DUMMY_BACKING) == 0U)
+
+/*!
+ Services is going to clean the cache for the allocated memory.
+ For performance reasons avoid usage if allocation is written to by the
+ CPU anyway before the next GPU kick.
+ */
+#define PVRSRV_MEMALLOCFLAG_CPU_CACHE_CLEAN (1ULL<<19)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_CACHE_CLEAN flag is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the flag is set, false otherwise
+ */
+#define PVRSRV_CHECK_CPU_CACHE_CLEAN(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_CPU_CACHE_CLEAN) != 0U)
+
+/*! PVRSRV_MEMALLOCFLAG_SPARSE_ZERO_BACKING
+
+ Indicates the particular memory that's being allocated is sparse and the
+ sparse regions should be backed by zero page. This is different with
+ zero on alloc flag such that only physically unbacked pages are backed
+ by zero page at the time of mapping.
+ The zero backed page is always with read only attribute irrespective of its
+ original attributes.
+*/
+#define PVRSRV_MEMALLOCFLAG_SPARSE_ZERO_BACKING (1ULL << 20)
+#define PVRSRV_IS_SPARSE_ZERO_BACKING_REQUIRED(uiFlags) (((uiFlags) & \
+ PVRSRV_MEMALLOCFLAG_SPARSE_ZERO_BACKING) == PVRSRV_MEMALLOCFLAG_SPARSE_ZERO_BACKING)
+
+/*!
+ @Description Macro extracting the OS id from a variable containing memalloc flags
+ @Input uiFlags Allocation flags
+ @Return returns the value of the FW_ALLOC_OSID bitfield
+ */
+#define PVRSRV_FW_RAW_ALLOC_OSID(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_FW_ALLOC_OSID_MASK) \
+ >> PVRSRV_MEMALLOCFLAG_FW_ALLOC_OSID_SHIFT)
+
+/*!
+ @Description Macro converting an OS id value into a memalloc bitfield
+ @Input uiFlags OS id
+ @Return returns a shifted bitfield with the OS id value
+ */
+#define PVRSRV_MEMALLOCFLAG_FW_RAW_ALLOC_OSID(osid) (((osid) << PVRSRV_MEMALLOCFLAG_FW_ALLOC_OSID_SHIFT) \
+ & PVRSRV_MEMALLOCFLAG_FW_ALLOC_OSID_MASK) \
+
+/*
+ *
+ * **********************************************************
+ * * *
+ * * MEMORY ZEROING AND POISONING FLAGS *
+ * * *
+ * **********************************************************
+ *
+ * Zero / Poison, on alloc/free
+ *
+ * We think the following usecases are required:
+ *
+ * don't poison or zero on alloc or free
+ * (normal operation, also most efficient)
+ * poison on alloc
+ * (for helping to highlight bugs)
+ * poison on alloc and free
+ * (for helping to highlight bugs)
+ * zero on alloc
+ * (avoid highlighting security issues in other uses of memory)
+ * zero on alloc and poison on free
+ * (avoid highlighting security issues in other uses of memory, while
+ * helping to highlight a subset of bugs e.g. memory freed prematurely)
+ *
+ * Since there are more than 4, we can't encode this in just two bits,
+ * so we might as well have a separate flag for each of the three
+ * actions.
+ */
+
+/*!
+ Ensures that the memory allocated is initialised with zeroes.
+ */
+#define PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC (1ULL<<31)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC flag is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the flag is set, false otherwise
+ */
+#define PVRSRV_CHECK_ZERO_ON_ALLOC(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC) != 0U)
+
+/*!
+ Scribbles over the allocated memory with a poison value
+
+ Not compatible with ZERO_ON_ALLOC
+
+ Poisoning is very deliberately _not_ reflected in PDump as we want
+ a simulation to cry loudly if the initialised data propagates to a
+ result.
+ */
+#define PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC (1ULL<<30)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC flag is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the flag is set, false otherwise
+ */
+#define PVRSRV_CHECK_POISON_ON_ALLOC(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC) != 0U)
+
+/*!
+ Causes memory to be trashed when freed, as a lazy man's security measure.
+ */
+#define PVRSRV_MEMALLOCFLAG_POISON_ON_FREE (1ULL<<29)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_POISON_ON_FREE flag is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the flag is set, false otherwise
+ */
+#define PVRSRV_CHECK_POISON_ON_FREE(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_POISON_ON_FREE) != 0U)
+
+/*!
+ Avoid address alignment to a CPU or GPU cache line size.
+ */
+#define PVRSRV_MEMALLOCFLAG_NO_CACHE_LINE_ALIGN (1ULL<<28)
+
+/*!
+ @Description Macro checking whether the PVRSRV_CHECK_NO_CACHE_LINE_ALIGN flag is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the flag is set, false otherwise
+ */
+#define PVRSRV_CHECK_NO_CACHE_LINE_ALIGN(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_NO_CACHE_LINE_ALIGN) != 0U)
+
+
+/*
+ *
+ * **********************************************************
+ * * *
+ * * Device specific MMU flags *
+ * * *
+ * **********************************************************
+ *
+ * (Bits 26 to 27)
+ *
+ * Some services controlled devices have device specific control bits in
+ * their page table entries, we need to allow these flags to be passed down
+ * the memory management layers so the user can control these bits.
+ * For example, RGX device has the file rgx_memallocflags.h
+ */
+
+/*!
+ * Offset of device specific MMU flags.
+ */
+#define PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_OFFSET 26
+
+/*!
+ * Mask for retrieving device specific MMU flags.
+ */
+#define PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_MASK (0x3ULL << PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_OFFSET)
+
+/*!
+ @Description Helper macro for setting device specific MMU flags.
+ @Input n Flag index.
+ @Return Flag vector with the specified bit set.
+ */
+#define PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(n) \
+ (((PVRSRV_MEMALLOCFLAGS_T)(n) << PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_OFFSET) & \
+ PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_MASK)
+
+/*
+ *
+ * **********************************************************
+ * * *
+ * * Secure validation flags *
+ * * *
+ * **********************************************************
+ *
+ * (Bit 35)
+ *
+ */
+
+/*!
+ PVRSRV_MEMALLOCFLAG_VAL_SHARED_BUFFER
+ */
+
+#define PVRSRV_MEMALLOCFLAG_VAL_SHARED_BUFFER (1ULL<<35)
+#define PVRSRV_CHECK_SHARED_BUFFER(uiFlags) (((uiFlags) & PVRSRV_MEMALLOCFLAG_VAL_SHARED_BUFFER) != 0U)
+
+/*
+ *
+ * **********************************************************
+ * * *
+ * * Phys Heap Hints *
+ * * *
+ * **********************************************************
+ *
+ * (Bits 59 to 63)
+ *
+ */
+
+/*!
+ * Value of enum PVRSRV_PHYS_HEAP stored in memalloc flags. If not set
+ * i.e. PVRSRV_PHYS_HEAP_DEFAULT (value 0) used, the system layer defined default physical heap is used.
+ */
+#define PVRSRV_PHYS_HEAP_HINT_SHIFT (59)
+#define PVRSRV_PHYS_HEAP_HINT_MASK (0x1FULL << PVRSRV_PHYS_HEAP_HINT_SHIFT)
+
+
+/*!
+ @Description Macro extracting the Phys Heap hint from memalloc flag value.
+ @Input uiFlags Allocation flags
+ @Return returns the value of the PHYS_HEAP_HINT bitfield
+ */
+#define PVRSRV_GET_PHYS_HEAP_HINT(uiFlags) (((uiFlags) & PVRSRV_PHYS_HEAP_HINT_MASK) \
+ >> PVRSRV_PHYS_HEAP_HINT_SHIFT)
+
+/*!
+ @Description Macro converting a Phys Heap value into a memalloc bitfield
+ @Input uiFlags Device Phys Heap
+ @Return returns a shifted bitfield with the Device Phys Heap value
+ */
+#define PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(PhysHeap) ((((PVRSRV_MEMALLOCFLAGS_T)PVRSRV_PHYS_HEAP_ ## PhysHeap) << \
+ PVRSRV_PHYS_HEAP_HINT_SHIFT) \
+ & PVRSRV_PHYS_HEAP_HINT_MASK)
+/*!
+ @Description Macro to replace an existing phys heap hint value in flags.
+ @Input PhysHeap Phys Heap Macro
+ @Input uiFlags Allocation flags
+ @Return N/A
+ */
+#define PVRSRV_SET_PHYS_HEAP_HINT(PhysHeap, uiFlags) (uiFlags) = ((uiFlags) & ~PVRSRV_PHYS_HEAP_HINT_MASK) | \
+ PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(PhysHeap)
+
+/*!
+ @Description Macro to replace an existing phys heap hint value using Phys Heap value.
+ @Input PhysHeap Phys Heap Value
+ @Input uiFlags Allocation flags
+ @Return N/A
+ */
+#define PVRSRV_CHANGE_PHYS_HEAP_HINT(Physheap, uiFlags) (uiFlags) = ((uiFlags) & ~PVRSRV_PHYS_HEAP_HINT_MASK) | \
+ (((PVRSRV_MEMALLOCFLAGS_T)(Physheap) << \
+ PVRSRV_PHYS_HEAP_HINT_SHIFT) \
+ & PVRSRV_PHYS_HEAP_HINT_MASK)
+
+/*!
+ @Description Macros checking if a Phys Heap hint is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the hint is set, false otherwise
+ */
+#define PVRSRV_CHECK_PHYS_HEAP(PhysHeap, uiFlags) (PVRSRV_PHYS_HEAP_ ## PhysHeap == PVRSRV_GET_PHYS_HEAP_HINT(uiFlags))
+
+#define PVRSRV_CHECK_FW_MAIN(uiFlags) (PVRSRV_CHECK_PHYS_HEAP(FW_MAIN, uiFlags) || \
+ PVRSRV_CHECK_PHYS_HEAP(FW_CONFIG, uiFlags) || \
+ PVRSRV_CHECK_PHYS_HEAP(FW_CODE, uiFlags) || \
+ PVRSRV_CHECK_PHYS_HEAP(FW_PRIV_DATA, uiFlags) || \
+ PVRSRV_CHECK_PHYS_HEAP(FW_PREMAP0, uiFlags) || \
+ PVRSRV_CHECK_PHYS_HEAP(FW_PREMAP1, uiFlags) || \
+ PVRSRV_CHECK_PHYS_HEAP(FW_PREMAP2, uiFlags) || \
+ PVRSRV_CHECK_PHYS_HEAP(FW_PREMAP3, uiFlags) || \
+ PVRSRV_CHECK_PHYS_HEAP(FW_PREMAP4, uiFlags) || \
+ PVRSRV_CHECK_PHYS_HEAP(FW_PREMAP5, uiFlags) || \
+ PVRSRV_CHECK_PHYS_HEAP(FW_PREMAP6, uiFlags) || \
+ PVRSRV_CHECK_PHYS_HEAP(FW_PREMAP7, uiFlags))
+
+/*!
+ * Secure buffer mask -- Flags in the mask are allowed for secure buffers
+ * because they are not related to CPU mappings.
+ */
+#define PVRSRV_MEMALLOCFLAGS_SECBUFMASK ~(PVRSRV_MEMALLOCFLAG_CPU_CACHE_MODE_MASK | \
+ PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | \
+ PVRSRV_MEMALLOCFLAG_CPU_READABLE | \
+ PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | \
+ PVRSRV_MEMALLOCFLAG_CPU_CACHE_CLEAN | \
+ PVRSRV_MEMALLOCFLAG_SVM_ALLOC | \
+ PVRSRV_MEMALLOCFLAG_CPU_READ_PERMITTED | \
+ PVRSRV_MEMALLOCFLAG_CPU_WRITE_PERMITTED)
+
+/*!
+ * Trusted device mask -- Flags in the mask are allowed for trusted device
+ * because the driver cannot access the memory
+ */
+#define PVRSRV_MEMALLOCFLAGS_TDFWMASK ~(PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | \
+ PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | \
+ PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC | \
+ PVRSRV_MEMALLOCFLAG_POISON_ON_FREE | \
+ PVRSRV_MEMALLOCFLAGS_CPU_MMUFLAGSMASK | \
+ PVRSRV_MEMALLOCFLAG_SPARSE_NO_DUMMY_BACKING)
+
+
+/*!
+ PMR flags mask -- for internal services use only. This is the set of flags
+ that will be passed down and stored with the PMR, this also includes the
+ MMU flags which the PMR has to pass down to mm_common.c at PMRMap time.
+*/
+
+#define PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK (PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_MASK | \
+ PVRSRV_MEMALLOCFLAG_CPU_CACHE_CLEAN | \
+ PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE | \
+ PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | \
+ PVRSRV_MEMALLOCFLAG_SVM_ALLOC | \
+ PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC | \
+ PVRSRV_MEMALLOCFLAG_POISON_ON_FREE | \
+ PVRSRV_MEMALLOCFLAGS_GPU_MMUFLAGSMASK | \
+ PVRSRV_MEMALLOCFLAGS_CPU_MMUFLAGSMASK | \
+ PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC | \
+ PVRSRV_MEMALLOCFLAG_SPARSE_NO_DUMMY_BACKING | \
+ PVRSRV_MEMALLOCFLAG_SPARSE_ZERO_BACKING | \
+ PVRSRV_MEMALLOCFLAG_VAL_SHARED_BUFFER | \
+ PVRSRV_PHYS_HEAP_HINT_MASK)
+
+/*!
+ * CPU mappable mask -- Any flag set in the mask requires memory to be CPU mappable
+ */
+#define PVRSRV_MEMALLOCFLAGS_CPU_MAPPABLE_MASK (PVRSRV_MEMALLOCFLAG_CPU_READABLE | \
+ PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | \
+ PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | \
+ PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC | \
+ PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE)
+/*!
+ RA differentiation mask
+
+ for use internal to services
+
+ this is the set of flags bits that are able to determine whether a pair of
+ allocations are permitted to live in the same page table. Allocations
+ whose flags differ in any of these places would be allocated from separate
+ RA Imports and therefore would never coexist in the same page.
+ Special cases are zeroing and poisoning of memory. The caller is responsible
+ to set the sub-allocations to the value he wants it to be. To differentiate
+ between zeroed and poisoned RA Imports does not make sense because the
+ memory might be reused.
+
+*/
+#define PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK (PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK \
+ & \
+ ~(PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | \
+ PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC))
+
+/*!
+ Flags that affect _allocation_
+*/
+#define PVRSRV_MEMALLOCFLAGS_PERALLOCFLAGSMASK (0xFFFFFFFFU)
+
+/*!
+ Flags that affect _mapping_
+*/
+#define PVRSRV_MEMALLOCFLAGS_PERMAPPINGFLAGSMASK (PVRSRV_MEMALLOCFLAG_DEVICE_FLAGS_MASK | \
+ PVRSRV_MEMALLOCFLAGS_GPU_MMUFLAGSMASK | \
+ PVRSRV_MEMALLOCFLAGS_CPU_MMUFLAGSMASK | \
+ PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC | \
+ PVRSRV_MEMALLOCFLAG_SVM_ALLOC | \
+ PVRSRV_MEMALLOCFLAG_SPARSE_ZERO_BACKING | \
+ PVRSRV_MEMALLOCFLAG_SPARSE_NO_DUMMY_BACKING)
+
+#if ((~(PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK) & PVRSRV_MEMALLOCFLAGS_PERMAPPINGFLAGSMASK) != 0U)
+#error PVRSRV_MEMALLOCFLAGS_PERMAPPINGFLAGSMASK is not a subset of PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK
+#endif
+
+
+/*!
+ Flags that affect _physical allocations_ in the DevMemX API
+ */
+#define PVRSRV_MEMALLOCFLAGS_DEVMEMX_PHYSICAL_MASK (PVRSRV_MEMALLOCFLAGS_CPU_MMUFLAGSMASK | \
+ PVRSRV_MEMALLOCFLAG_GPU_CACHE_MODE_MASK | \
+ PVRSRV_MEMALLOCFLAG_CPU_READ_PERMITTED | \
+ PVRSRV_MEMALLOCFLAG_CPU_WRITE_PERMITTED | \
+ PVRSRV_MEMALLOCFLAG_CPU_CACHE_CLEAN | \
+ PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | \
+ PVRSRV_MEMALLOCFLAG_POISON_ON_ALLOC | \
+ PVRSRV_MEMALLOCFLAG_POISON_ON_FREE | \
+ PVRSRV_PHYS_HEAP_HINT_MASK)
+
+/*!
+ Flags that affect _virtual allocations_ in the DevMemX API
+ */
+#define PVRSRV_MEMALLOCFLAGS_DEVMEMX_VIRTUAL_MASK (PVRSRV_MEMALLOCFLAGS_GPU_MMUFLAGSMASK | \
+ PVRSRV_MEMALLOCFLAG_GPU_READ_PERMITTED | \
+ PVRSRV_MEMALLOCFLAG_GPU_WRITE_PERMITTED)
+
+#endif /* PVRSRV_MEMALLOCFLAGS_H */
diff --git a/drivers/gpu/drm/img-rogue/include/pvrsrv_memallocflags_internal.h b/drivers/gpu/drm/img-rogue/include/pvrsrv_memallocflags_internal.h
new file mode 100644
index 000000000..4fee3d49b
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/pvrsrv_memallocflags_internal.h
@@ -0,0 +1,78 @@
+/*************************************************************************/ /*!
+@File
+@Title Device Memory Management allocation flags for internal Services
+ use only
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description This file defines flags used on memory allocations and mappings
+ These flags are relevant throughout the memory management
+ software stack and are specified by users of services and
+ understood by all levels of the memory management in the server
+ and in special cases in the client.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef PVRSRV_MEMALLOCFLAGS_INTERNAL_H
+#define PVRSRV_MEMALLOCFLAGS_INTERNAL_H
+
+/*!
+ CPU domain. Request uncached memory. This means that any writes to memory
+ allocated with this flag are written straight to memory and thus are
+ coherent for any device in the system.
+*/
+#define PVRSRV_MEMALLOCFLAG_CPU_UNCACHED (1ULL<<11)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_CPU_UNCACHED mode is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the mode is set, false otherwise
+ */
+#define PVRSRV_CHECK_CPU_UNCACHED(uiFlags) (PVRSRV_CPU_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_CPU_UNCACHED)
+
+/*!
+ * Memory will be uncached on CPU and GPU
+ */
+#define PVRSRV_MEMALLOCFLAG_UNCACHED (PVRSRV_MEMALLOCFLAG_GPU_UNCACHED | PVRSRV_MEMALLOCFLAG_CPU_UNCACHED)
+
+/*!
+ @Description Macro checking whether the PVRSRV_MEMALLOCFLAG_UNCACHED mode is set.
+ @Input uiFlags Allocation flags.
+ @Return True if the mode is set, false otherwise
+ */
+#define PVRSRV_CHECK_UNCACHED(uiFlags) (PVRSRV_CACHE_MODE(uiFlags) == PVRSRV_MEMALLOCFLAG_UNCACHED)
+
+#endif /* PVRSRV_MEMALLOCFLAGS_INTERNAL_H */
diff --git a/drivers/gpu/drm/img-rogue/include/pvrsrv_sync_km.h b/drivers/gpu/drm/img-rogue/include/pvrsrv_sync_km.h
new file mode 100644
index 000000000..04611f9f7
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/pvrsrv_sync_km.h
@@ -0,0 +1,65 @@
+/*************************************************************************/ /*!
+@File
+@Title PVR synchronisation interface
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Types for server side code
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef PVRSRV_SYNC_KM_H
+#define PVRSRV_SYNC_KM_H
+
+#include
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define SYNC_FB_FILE_STRING_MAX 256
+#define SYNC_FB_MODULE_STRING_LEN_MAX (32)
+#define SYNC_FB_DESC_STRING_LEN_MAX (32)
+
+/* By default, fence-sync module emits into HWPerf (of course, if enabled) and
+ * considers a process (sleepable) context */
+#define PVRSRV_FENCE_FLAG_NONE (0U)
+#define PVRSRV_FENCE_FLAG_SUPPRESS_HWP_PKT (1U << 0)
+#define PVRSRV_FENCE_FLAG_CTX_ATOMIC (1U << 1)
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* PVRSRV_SYNC_KM_H */
diff --git a/drivers/gpu/drm/img-rogue/include/pvrsrv_tlcommon.h b/drivers/gpu/drm/img-rogue/include/pvrsrv_tlcommon.h
new file mode 100644
index 000000000..7b5761397
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/pvrsrv_tlcommon.h
@@ -0,0 +1,260 @@
+/*************************************************************************/ /*!
+@File
+@Title Services Transport Layer common types and definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Transport layer common types and definitions included into
+ both user mode and kernel mode source.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef PVR_TLCOMMON_H
+#define PVR_TLCOMMON_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "img_defs.h"
+
+
+/*! Handle type for stream descriptor objects as created by this API */
+typedef IMG_HANDLE PVRSRVTL_SD;
+
+/*! Maximum stream name length including the null byte */
+#define PRVSRVTL_MAX_STREAM_NAME_SIZE 40U
+
+/*! Maximum number of streams expected to exist */
+#define PVRSRVTL_MAX_DISCOVERABLE_STREAMS_BUFFER (32*PRVSRVTL_MAX_STREAM_NAME_SIZE)
+
+/*! Packet lengths are always rounded up to a multiple of 8 bytes */
+#define PVRSRVTL_PACKET_ALIGNMENT 8U
+#define PVRSRVTL_ALIGN(x) (((x)+PVRSRVTL_PACKET_ALIGNMENT-1U) & ~(PVRSRVTL_PACKET_ALIGNMENT-1U))
+
+
+/*! A packet is made up of a header structure followed by the data bytes.
+ * There are 3 types of packet: normal (has data), data lost and padding,
+ * see packet flags. Header kept small to reduce data overhead.
+ *
+ * if the ORDER of the structure members is changed, please UPDATE the
+ * PVRSRVTL_PACKET_FLAG_OFFSET macro.
+ *
+ * Layout of uiTypeSize member is :
+ *
+ * |<---------------------------32-bits------------------------------>|
+ * |<----8---->|<-----1----->|<----7--->|<------------16------------->|
+ * | Type | Drop-Oldest | UNUSED | Size |
+ *
+ */
+typedef struct
+{
+ IMG_UINT32 uiTypeSize; /*!< Type, Drop-Oldest flag & number of bytes following header */
+ IMG_UINT32 uiReserved; /*!< Reserve, packets and data must be 8 byte aligned */
+
+ /* First bytes of TL packet data follow header ... */
+} PVRSRVTL_PACKETHDR, *PVRSRVTL_PPACKETHDR;
+
+/* Structure must always be a size multiple of 8 as stream buffer
+ * still an array of IMG_UINT32s.
+ */
+static_assert((sizeof(PVRSRVTL_PACKETHDR) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(PVRSRVTL_PACKETHDR) must be a multiple of 8");
+
+/*! Packet header reserved word fingerprint "TLP1" */
+#define PVRSRVTL_PACKETHDR_RESERVED 0x31504C54U
+
+/*! Packet header mask used to extract the size from the uiTypeSize member.
+ * Do not use directly, see GET macros.
+ */
+#define PVRSRVTL_PACKETHDR_SIZE_MASK 0x0000FFFFU
+#define PVRSRVTL_MAX_PACKET_SIZE (PVRSRVTL_PACKETHDR_SIZE_MASK & ~0xFU)
+
+
+/*! Packet header mask used to extract the type from the uiTypeSize member.
+ * Do not use directly, see GET macros.
+ */
+#define PVRSRVTL_PACKETHDR_TYPE_MASK 0xFF000000U
+#define PVRSRVTL_PACKETHDR_TYPE_OFFSET 24U
+
+/*! Packet header mask used to check if packets before this one were dropped
+ * or not. Do not use directly, see GET macros.
+ */
+#define PVRSRVTL_PACKETHDR_OLDEST_DROPPED_MASK 0x00800000U
+#define PVRSRVTL_PACKETHDR_OLDEST_DROPPED_OFFSET 23U
+
+/*! Packet type enumeration.
+ */
+typedef IMG_UINT32 PVRSRVTL_PACKETTYPE;
+
+/*! Undefined packet */
+#define PVRSRVTL_PACKETTYPE_UNDEF 0U
+
+/*! Normal packet type. Indicates data follows the header.
+ */
+#define PVRSRVTL_PACKETTYPE_DATA 1U
+
+/*! When seen this packet type indicates that at this moment in the stream
+ * packet(s) were not able to be accepted due to space constraints and
+ * that recent data may be lost - depends on how the producer handles the
+ * error. Such packets have no data, data length is 0.
+ */
+#define PVRSRVTL_PACKETTYPE_MOST_RECENT_WRITE_FAILED 2U
+
+/*! Packets with this type set are padding packets that contain undefined
+ * data and must be ignored/skipped by the client. They are used when the
+ * circular stream buffer wraps around and there is not enough space for
+ * the data at the end of the buffer. Such packets have a length of 0 or
+ * more.
+ */
+#define PVRSRVTL_PACKETTYPE_PADDING 3U
+
+/*! This packet type conveys to the stream consumer that the stream
+ * producer has reached the end of data for that data sequence. The
+ * TLDaemon has several options for processing these packets that can
+ * be selected on a per stream basis.
+ */
+#define PVRSRVTL_PACKETTYPE_MARKER_EOS 4U
+
+/*! This is same as PVRSRVTL_PACKETTYPE_MARKER_EOS but additionally removes
+ * old data record output file before opening new/next one
+ */
+#define PVRSRVTL_PACKETTYPE_MARKER_EOS_REMOVEOLD 5U
+
+/*! Packet emitted on first stream opened by writer. Packet carries a name
+ * of the opened stream in a form of null-terminated string.
+ */
+#define PVRSRVTL_PACKETTYPE_STREAM_OPEN_FOR_WRITE 6U
+
+/*! Packet emitted on last stream closed by writer. Packet carries a name
+ * of the closed stream in a form of null-terminated string.
+ */
+#define PVRSRVTL_PACKETTYPE_STREAM_CLOSE_FOR_WRITE 7U
+
+#define PVRSRVTL_PACKETTYPE_LAST 8U
+
+/* The SET_PACKET_* macros rely on the order the PVRSRVTL_PACKETHDR members are declared:
+ * uiFlags is the upper half of a structure consisting of 2 uint16 quantities.
+ */
+#define PVRSRVTL_SET_PACKET_DATA(len) (len) | (PVRSRVTL_PACKETTYPE_DATA << PVRSRVTL_PACKETHDR_TYPE_OFFSET)
+#define PVRSRVTL_SET_PACKET_PADDING(len) (len) | (PVRSRVTL_PACKETTYPE_PADDING << PVRSRVTL_PACKETHDR_TYPE_OFFSET)
+#define PVRSRVTL_SET_PACKET_WRITE_FAILED (0) | (PVRSRVTL_PACKETTYPE_MOST_RECENT_WRITE_FAILED << PVRSRVTL_PACKETHDR_TYPE_OFFSET)
+#define PVRSRVTL_SET_PACKET_HDR(len, type) (len) | ((type) << PVRSRVTL_PACKETHDR_TYPE_OFFSET)
+
+/*! Returns the number of bytes of data in the packet.
+ * p may be any address type.
+ */
+#define GET_PACKET_DATA_LEN(p) \
+ ((IMG_UINT32) ((PVRSRVTL_PPACKETHDR) (void *) (p))->uiTypeSize & PVRSRVTL_PACKETHDR_SIZE_MASK)
+
+
+/*! Returns a IMG_BYTE* pointer to the first byte of data in the packet */
+#define GET_PACKET_DATA_PTR(p) \
+ (((IMG_UINT8 *) (void *) (p)) + sizeof(PVRSRVTL_PACKETHDR))
+
+/*! Turns the packet address p into a PVRSRVTL_PPACKETHDR pointer type.
+ */
+#define GET_PACKET_HDR(p) ((PVRSRVTL_PPACKETHDR) ((void *) (p)))
+
+/*! Given a PVRSRVTL_PPACKETHDR address, return the address of the next pack
+ * It is up to the caller to determine if the new address is within the
+ * packet buffer.
+ */
+#define GET_NEXT_PACKET_ADDR(p) \
+ GET_PACKET_HDR( \
+ GET_PACKET_DATA_PTR(p) + \
+ ( \
+ (GET_PACKET_DATA_LEN(p) + (PVRSRVTL_PACKET_ALIGNMENT-1U)) & \
+ (~(PVRSRVTL_PACKET_ALIGNMENT-1U)) \
+ ) \
+ )
+
+/*! Get the type of the packet. p is of type PVRSRVTL_PPACKETHDR.
+ */
+#define GET_PACKET_TYPE(p) (((p)->uiTypeSize & PVRSRVTL_PACKETHDR_TYPE_MASK)>>PVRSRVTL_PACKETHDR_TYPE_OFFSET)
+
+/*! Set PACKETS_DROPPED flag in packet header as a part of uiTypeSize.
+ * p is of type PVRSRVTL_PPACKETHDR.
+ */
+#define SET_PACKETS_DROPPED(p) (((p)->uiTypeSize) | (1UL << PVRSRVTL_PACKETHDR_OLDEST_DROPPED_OFFSET))
+
+/*! Check if packets were dropped before this packet.
+ * p is of type PVRSRVTL_PPACKETHDR.
+ */
+#define CHECK_PACKETS_DROPPED(p) (((p)->uiTypeSize & PVRSRVTL_PACKETHDR_OLDEST_DROPPED_MASK)>>PVRSRVTL_PACKETHDR_OLDEST_DROPPED_OFFSET)
+
+/*! Flags for use with PVRSRVTLOpenStream
+ * 0x01 - Do not block in PVRSRVTLAcquireData() when no bytes are available
+ * 0x02 - When the stream does not exist wait for a bit (2s) in
+ * PVRSRVTLOpenStream() and then exit with a timeout error if it still
+ * does not exist.
+ * 0x04 - Open stream for write only operations.
+ * If flag is not used stream is opened as read-only. This flag is
+ * required if one wants to call reserve/commit/write function on the
+ * stream descriptor. Read from on the stream descriptor opened
+ * with this flag will fail.
+ * 0x08 - Disable Producer Callback.
+ * If this flag is set and the stream becomes empty, do not call any
+ * associated producer callback to generate more data from the reader
+ * context.
+ * 0x10 - Reset stream on open.
+ * When this flag is used the stream will drop all of the stored data.
+ * 0x20 - Limit read position to the write position at time the stream
+ * was opened. Hence this flag will freeze the content read to that
+ * produced before the stream was opened for reading.
+ * 0x40 - Ignore Open Callback.
+ * When this flag is set ignore any OnReaderOpenCallback setting for
+ * the stream. This allows access to the stream to be made without
+ * generating any extra packets into the stream.
+ */
+
+#define PVRSRV_STREAM_FLAG_NONE (0U)
+#define PVRSRV_STREAM_FLAG_ACQUIRE_NONBLOCKING (1U<<0)
+#define PVRSRV_STREAM_FLAG_OPEN_WAIT (1U<<1)
+#define PVRSRV_STREAM_FLAG_OPEN_WO (1U<<2)
+#define PVRSRV_STREAM_FLAG_DISABLE_PRODUCER_CALLBACK (1U<<3)
+#define PVRSRV_STREAM_FLAG_RESET_ON_OPEN (1U<<4)
+#define PVRSRV_STREAM_FLAG_READ_LIMIT (1U<<5)
+#define PVRSRV_STREAM_FLAG_IGNORE_OPEN_CALLBACK (1U<<6)
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* PVR_TLCOMMON_H */
+/******************************************************************************
+ End of file (pvrsrv_tlcommon.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/pvrsrv_tlstreams.h b/drivers/gpu/drm/img-rogue/include/pvrsrv_tlstreams.h
new file mode 100644
index 000000000..9064075ad
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/pvrsrv_tlstreams.h
@@ -0,0 +1,61 @@
+/*************************************************************************/ /*!
+@File
+@Title Services Transport Layer stream names
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Transport layer common types and definitions included into
+ both user mode and kernel mode source.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef PVRSRV_TLSTREAMS_H
+#define PVRSRV_TLSTREAMS_H
+
+#define PVRSRV_TL_CTLR_STREAM "tlctrl"
+
+#define PVRSRV_TL_HWPERF_RGX_FW_STREAM "hwperf_fw_"
+#define PVRSRV_TL_HWPERF_HOST_SERVER_STREAM "hwperf_host_"
+
+/* Host HWPerf client stream names are of the form 'hwperf_client_' */
+#define PVRSRV_TL_HWPERF_HOST_CLIENT_STREAM "hwperf_client_"
+#define PVRSRV_TL_HWPERF_HOST_CLIENT_STREAM_FMTSPEC "hwperf_client_%u_%u"
+
+#endif /* PVRSRV_TLSTREAMS_H */
+
+/******************************************************************************
+ End of file (pvrsrv_tlstreams.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/pvrversion.h b/drivers/gpu/drm/img-rogue/include/pvrversion.h
new file mode 100644
index 000000000..53db28ba8
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/pvrversion.h
@@ -0,0 +1,68 @@
+/*************************************************************************/ /*!
+@File pvrversion.h
+@Title PowerVR version numbers and strings.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Version numbers and strings for PowerVR components.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef PVRVERSION_H
+#define PVRVERSION_H
+
+#define PVRVERSION_MAJ 1U
+#define PVRVERSION_MIN 16U
+
+#define PVRVERSION_FAMILY "rogueddk"
+#define PVRVERSION_BRANCHNAME "1.16"
+#define PVRVERSION_BUILD 6099580
+#define PVRVERSION_BSCONTROL "Rogue_DDK_Linux_WS"
+
+#define PVRVERSION_STRING "Rogue_DDK_Linux_WS rogueddk 1.16@6099580"
+#define PVRVERSION_STRING_SHORT "1.16@6099580"
+
+#define COPYRIGHT_TXT "Copyright (c) Imagination Technologies Ltd. All Rights Reserved."
+
+#define PVRVERSION_BUILD_HI 609
+#define PVRVERSION_BUILD_LO 9580
+#define PVRVERSION_STRING_NUMERIC "1.16.609.9580"
+
+#define PVRVERSION_PACK(MAJOR,MINOR) (((IMG_UINT32)((IMG_UINT32)(MAJOR) & 0xFFFFU) << 16U) | (((MINOR) & 0xFFFFU) << 0U))
+#define PVRVERSION_UNPACK_MAJ(VERSION) (((VERSION) >> 16U) & 0xFFFFU)
+#define PVRVERSION_UNPACK_MIN(VERSION) (((VERSION) >> 0U) & 0xFFFFU)
+
+#endif /* PVRVERSION_H */
diff --git a/drivers/gpu/drm/img-rogue/include/rgx_common.h b/drivers/gpu/drm/img-rogue/include/rgx_common.h
new file mode 100644
index 000000000..b20d0456e
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/rgx_common.h
@@ -0,0 +1,237 @@
+/*************************************************************************/ /*!
+@File
+@Title RGX Common Types and Defines Header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Common types and definitions for RGX software
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef RGX_COMMON_H
+#define RGX_COMMON_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "img_defs.h"
+
+/* Included to get the BVNC_KM_N defined and other feature defs */
+#include "km/rgxdefs_km.h"
+
+/*! This macro represents a mask of LSBs that must be zero on data structure
+ * sizes and offsets to ensure they are 8-byte granular on types shared between
+ * the FW and host driver */
+#define RGX_FW_ALIGNMENT_LSB (7U)
+
+/*! Macro to test structure size alignment */
+#define RGX_FW_STRUCT_SIZE_ASSERT(_a) \
+ static_assert((sizeof(_a) & RGX_FW_ALIGNMENT_LSB) == 0U, \
+ "Size of " #_a " is not properly aligned")
+
+/*! Macro to test structure member alignment */
+#define RGX_FW_STRUCT_OFFSET_ASSERT(_a, _b) \
+ static_assert((offsetof(_a, _b) & RGX_FW_ALIGNMENT_LSB) == 0U, \
+ "Offset of " #_a "." #_b " is not properly aligned")
+
+
+/* Virtualisation validation builds are meant to test the VZ-related hardware without a fully virtualised platform.
+ * As such a driver can support either the vz-validation code or real virtualisation.
+ * Note: PVRSRV_VZ_NUM_OSID is the external build option, while RGX_NUM_OS_SUPPORTED is the internal symbol used in the DDK */
+#if defined(SUPPORT_GPUVIRT_VALIDATION) && (defined(RGX_NUM_OS_SUPPORTED) && (RGX_NUM_OS_SUPPORTED > 1))
+#error "Invalid build configuration: Virtualisation support (PVRSRV_VZ_NUM_OSID > 1) and virtualisation validation code (SUPPORT_GPUVIRT_VALIDATION) are mutually exclusive."
+#endif
+
+/* The RGXFWIF_DM defines assume only one of RGX_FEATURE_TLA or
+ * RGX_FEATURE_FASTRENDER_DM is present. Ensure this with a compile-time check.
+ */
+#if defined(RGX_FEATURE_TLA) && defined(RGX_FEATURE_FASTRENDER_DM)
+#error "Both RGX_FEATURE_TLA and RGX_FEATURE_FASTRENDER_DM defined. Fix code to handle this!"
+#endif
+
+/*! The master definition for data masters known to the firmware of RGX.
+ * When a new DM is added to this list, relevant entry should be added to
+ * RGX_HWPERF_DM enum list.
+ * The DM in a V1 HWPerf packet uses this definition. */
+
+typedef IMG_UINT32 RGXFWIF_DM;
+
+#define RGXFWIF_DM_GP IMG_UINT32_C(0)
+/* Either TDM or 2D DM is present. The above build time error is present to verify this */
+#define RGXFWIF_DM_2D IMG_UINT32_C(1) /* when RGX_FEATURE_TLA defined */
+#define RGXFWIF_DM_TDM IMG_UINT32_C(1) /* when RGX_FEATURE_FASTRENDER_DM defined */
+
+#define RGXFWIF_DM_GEOM IMG_UINT32_C(2)
+#define RGXFWIF_DM_3D IMG_UINT32_C(3)
+#define RGXFWIF_DM_CDM IMG_UINT32_C(4)
+#define RGXFWIF_DM_RAY IMG_UINT32_C(5)
+#define RGXFWIF_DM_GEOM2 IMG_UINT32_C(6)
+
+#define RGXFWIF_DM_LAST RGXFWIF_DM_GEOM2
+
+typedef enum _RGX_KICK_TYPE_DM_
+{
+ RGX_KICK_TYPE_DM_GP = 0x001,
+ RGX_KICK_TYPE_DM_TDM_2D = 0x002,
+ RGX_KICK_TYPE_DM_TA = 0x004,
+ RGX_KICK_TYPE_DM_3D = 0x008,
+ RGX_KICK_TYPE_DM_CDM = 0x010,
+ RGX_KICK_TYPE_DM_RTU = 0x020,
+ RGX_KICK_TYPE_DM_SHG = 0x040,
+ RGX_KICK_TYPE_DM_TQ2D = 0x080,
+ RGX_KICK_TYPE_DM_TQ3D = 0x100,
+ RGX_KICK_TYPE_DM_RAY = 0x200,
+ RGX_KICK_TYPE_DM_LAST = 0x400
+} RGX_KICK_TYPE_DM;
+
+/* Maximum number of DM in use: GP, 2D/TDM, GEOM, 3D, CDM, RDM, GEOM2 */
+#define RGXFWIF_DM_MAX (RGXFWIF_DM_LAST + 1U)
+
+/*
+ * Data Master Tags to be appended to resources created on behalf of each RGX
+ * Context.
+ */
+#define RGX_RI_DM_TAG_KS 'K'
+#define RGX_RI_DM_TAG_CDM 'C'
+#define RGX_RI_DM_TAG_RC 'R' /* To be removed once TA/3D Timelines are split */
+#define RGX_RI_DM_TAG_TA 'V'
+#define RGX_RI_DM_TAG_GEOM 'V'
+#define RGX_RI_DM_TAG_3D 'P'
+#define RGX_RI_DM_TAG_TDM 'T'
+#define RGX_RI_DM_TAG_TQ2D '2'
+#define RGX_RI_DM_TAG_TQ3D 'Q'
+#define RGX_RI_DM_TAG_RAY 'r'
+
+/*
+ * Client API Tags to be appended to resources created on behalf of each
+ * Client API.
+ */
+#define RGX_RI_CLIENT_API_GLES1 '1'
+#define RGX_RI_CLIENT_API_GLES3 '3'
+#define RGX_RI_CLIENT_API_VULKAN 'V'
+#define RGX_RI_CLIENT_API_EGL 'E'
+#define RGX_RI_CLIENT_API_OPENCL 'C'
+#define RGX_RI_CLIENT_API_OPENGL 'G'
+#define RGX_RI_CLIENT_API_SERVICES 'S'
+#define RGX_RI_CLIENT_API_WSEGL 'W'
+#define RGX_RI_CLIENT_API_ANDROID 'A'
+#define RGX_RI_CLIENT_API_LWS 'L'
+
+/*
+ * Format a RI annotation for a given RGX Data Master context
+ */
+#define RGX_RI_FORMAT_DM_ANNOTATION(annotation, dmTag, clientAPI) do \
+ { \
+ (annotation)[0] = (dmTag); \
+ (annotation)[1] = (clientAPI); \
+ (annotation)[2] = '\0'; \
+ } while (false)
+
+/*!
+ ******************************************************************************
+ * RGXFW Compiler alignment definitions
+ *****************************************************************************/
+#if defined(__GNUC__) || defined(HAS_GNUC_ATTRIBUTES) || defined(INTEGRITY_OS)
+#define RGXFW_ALIGN __attribute__ ((aligned (8)))
+#define RGXFW_ALIGN_DCACHEL __attribute__((aligned (64)))
+#elif defined(_MSC_VER)
+#define RGXFW_ALIGN __declspec(align(8))
+#define RGXFW_ALIGN_DCACHEL __declspec(align(64))
+#pragma warning (disable : 4324)
+#else
+#error "Align MACROS need to be defined for this compiler"
+#endif
+
+/*!
+ ******************************************************************************
+ * Force 8-byte alignment for structures allocated uncached.
+ *****************************************************************************/
+#define UNCACHED_ALIGN RGXFW_ALIGN
+
+
+/*!
+ ******************************************************************************
+ * GPU Utilisation states
+ *****************************************************************************/
+#define RGXFWIF_GPU_UTIL_STATE_IDLE (0U)
+#define RGXFWIF_GPU_UTIL_STATE_ACTIVE (1U)
+#define RGXFWIF_GPU_UTIL_STATE_BLOCKED (2U)
+#define RGXFWIF_GPU_UTIL_STATE_NUM (3U)
+#define RGXFWIF_GPU_UTIL_STATE_MASK IMG_UINT64_C(0x0000000000000003)
+
+
+/*
+ * Maximum amount of register writes that can be done by the register
+ * programmer (FW or META DMA). This is not a HW limitation, it is only
+ * a protection against malformed inputs to the register programmer.
+ */
+#define RGX_MAX_NUM_REGISTER_PROGRAMMER_WRITES (128U)
+
+/* FW common context priority. */
+#define RGX_CTX_PRIORITY_REALTIME (UINT32_MAX)
+#define RGX_CTX_PRIORITY_HIGH (2U)
+#define RGX_CTX_PRIORITY_MEDIUM (1U)
+#define RGX_CTX_PRIORITY_LOW (0)
+
+/*
+ * Use of the 32-bit context property flags mask
+ * ( X = taken/in use, - = available/unused )
+ *
+ * 0
+ * |
+ * -------------------------------x
+ */
+/*
+ * Context creation flags
+ * (specify a context's properties at creation time)
+ */
+#define RGX_CONTEXT_FLAG_DISABLESLR (1UL << 0) /*!< Disable SLR */
+
+/* List of attributes that may be set for a context */
+typedef enum _RGX_CONTEXT_PROPERTY_
+{
+ RGX_CONTEXT_PROPERTY_FLAGS = 0, /*!< Context flags */
+} RGX_CONTEXT_PROPERTY;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* RGX_COMMON_H */
+
+/******************************************************************************
+ End of file
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/rgx_compat_bvnc.h b/drivers/gpu/drm/img-rogue/include/rgx_compat_bvnc.h
new file mode 100644
index 000000000..748a59113
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/rgx_compat_bvnc.h
@@ -0,0 +1,140 @@
+/*************************************************************************/ /*!
+@File rgx_compat_bvnc.h
+@Title BVNC compatibility check utilities
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Utility functions used for packing BNC and V.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(RGX_COMPAT_BVNC_H)
+#define RGX_COMPAT_BVNC_H
+
+#include "img_types.h"
+
+#if defined(RGX_FIRMWARE) /* Services firmware */
+# include "rgxfw_utils.h"
+# define PVR_COMPAT_ASSERT RGXFW_ASSERT
+#elif !defined(RGX_BUILD_BINARY) /* Services host driver code */
+# include "pvr_debug.h"
+# define PVR_COMPAT_ASSERT PVR_ASSERT
+#else /* FW user-mode tools */
+# include
+# define PVR_COMPAT_ASSERT assert
+#endif
+
+/* 64bit endian conversion macros */
+#if defined(__BIG_ENDIAN__)
+#define RGX_INT64_TO_BE(N) (N)
+#define RGX_INT64_FROM_BE(N) (N)
+#define RGX_INT32_TO_BE(N) (N)
+#define RGX_INT32_FROM_BE(N) (N)
+#else
+#define RGX_INT64_TO_BE(N) \
+ ((((N) >> 56) & 0xff) \
+ | (((N) >> 40) & 0xff00) \
+ | (((N) >> 24) & 0xff0000) \
+ | (((N) >> 8) & 0xff000000U) \
+ | ((N) << 56) \
+ | (((N) & 0xff00) << 40) \
+ | (((N) & 0xff0000) << 24) \
+ | (((N) & 0xff000000U) << 8))
+#define RGX_INT64_FROM_BE(N) RGX_INT64_TO_BE(N)
+
+#define RGX_INT32_TO_BE(N) \
+ ((((N) >> 24) & 0xff) \
+ | (((N) >> 8) & 0xff00) \
+ | ((N) << 24) \
+ | ((((N) & 0xff00) << 8)))
+#define RGX_INT32_FROM_BE(N) RGX_INT32_TO_BE(N)
+#endif
+
+/******************************************************************************
+ * RGX Version packed into 64-bit (BVNC) to be used by Compatibility Check
+ *****************************************************************************/
+
+#define RGX_BVNC_PACK_SHIFT_B 48
+#define RGX_BVNC_PACK_SHIFT_V 32
+#define RGX_BVNC_PACK_SHIFT_N 16
+#define RGX_BVNC_PACK_SHIFT_C 0
+
+#define RGX_BVNC_PACK_MASK_B (IMG_UINT64_C(0xFFFF000000000000))
+#define RGX_BVNC_PACK_MASK_V (IMG_UINT64_C(0x0000FFFF00000000))
+#define RGX_BVNC_PACK_MASK_N (IMG_UINT64_C(0x00000000FFFF0000))
+#define RGX_BVNC_PACK_MASK_C (IMG_UINT64_C(0x000000000000FFFF))
+
+#define RGX_BVNC_PACKED_EXTR_B(BVNC) ((IMG_UINT32)(((BVNC) & RGX_BVNC_PACK_MASK_B) >> RGX_BVNC_PACK_SHIFT_B))
+#define RGX_BVNC_PACKED_EXTR_V(BVNC) ((IMG_UINT32)(((BVNC) & RGX_BVNC_PACK_MASK_V) >> RGX_BVNC_PACK_SHIFT_V))
+#define RGX_BVNC_PACKED_EXTR_N(BVNC) ((IMG_UINT32)(((BVNC) & RGX_BVNC_PACK_MASK_N) >> RGX_BVNC_PACK_SHIFT_N))
+#define RGX_BVNC_PACKED_EXTR_C(BVNC) ((IMG_UINT32)(((BVNC) & RGX_BVNC_PACK_MASK_C) >> RGX_BVNC_PACK_SHIFT_C))
+
+#define RGX_BVNC_EQUAL(L,R,all,version,bvnc) do { \
+ (bvnc) = IMG_FALSE; \
+ (version) = ((L).ui32LayoutVersion == (R).ui32LayoutVersion); \
+ if (version) \
+ { \
+ (bvnc) = ((L).ui64BVNC == (R).ui64BVNC); \
+ } \
+ (all) = (version) && (bvnc); \
+ } while (0)
+
+
+/**************************************************************************//**
+ * Utility function for packing BVNC
+ *****************************************************************************/
+static inline IMG_UINT64 rgx_bvnc_pack(IMG_UINT32 ui32B, IMG_UINT32 ui32V, IMG_UINT32 ui32N, IMG_UINT32 ui32C)
+{
+ /*
+ * Test for input B, V, N and C exceeding max bit width.
+ */
+ PVR_COMPAT_ASSERT((ui32B & (~(RGX_BVNC_PACK_MASK_B >> RGX_BVNC_PACK_SHIFT_B))) == 0U);
+ PVR_COMPAT_ASSERT((ui32V & (~(RGX_BVNC_PACK_MASK_V >> RGX_BVNC_PACK_SHIFT_V))) == 0U);
+ PVR_COMPAT_ASSERT((ui32N & (~(RGX_BVNC_PACK_MASK_N >> RGX_BVNC_PACK_SHIFT_N))) == 0U);
+ PVR_COMPAT_ASSERT((ui32C & (~(RGX_BVNC_PACK_MASK_C >> RGX_BVNC_PACK_SHIFT_C))) == 0U);
+
+ return (((IMG_UINT64)ui32B << RGX_BVNC_PACK_SHIFT_B) |
+ ((IMG_UINT64)ui32V << RGX_BVNC_PACK_SHIFT_V) |
+ ((IMG_UINT64)ui32N << RGX_BVNC_PACK_SHIFT_N) |
+ ((IMG_UINT64)ui32C << RGX_BVNC_PACK_SHIFT_C));
+}
+
+
+#endif /* RGX_COMPAT_BVNC_H */
+
+/******************************************************************************
+ End of file (rgx_compat_bvnc.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/rgx_fwif_resetframework.h b/drivers/gpu/drm/img-rogue/include/rgx_fwif_resetframework.h
new file mode 100644
index 000000000..84575635f
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/rgx_fwif_resetframework.h
@@ -0,0 +1,74 @@
+/*************************************************************************/ /*!
+@File rgx_fwif_resetframework.h
+@Title Post-reset work-around framework FW interface
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(RGX_FWIF_RESETFRAMEWORK_H)
+#define RGX_FWIF_RESETFRAMEWORK_H
+
+#include "img_types.h"
+#include "rgx_fwif_shared.h"
+
+typedef struct
+{
+#if defined(RGX_FEATURE_CDM_USER_MODE_QUEUE)
+ IMG_UINT64 uCDMReg_CDM_CB_QUEUE;
+ IMG_UINT64 uCDMReg_CDM_CB_BASE;
+ IMG_UINT64 uCDMReg_CDM_CB;
+#else
+ IMG_UINT64 uCDMReg_CDM_CTRL_STREAM_BASE;
+#endif
+} RGXFWIF_RF_REGISTERS;
+
+#define RGXFWIF_RF_FLAG_ENABLE 0x00000001U /*!< enables the reset framework in the firmware */
+
+typedef struct
+{
+ IMG_UINT32 ui32Flags;
+
+ /* THIS MUST BE THE LAST MEMBER OF THE CONTAINING STRUCTURE */
+ RGXFWIF_RF_REGISTERS RGXFW_ALIGN sFWRegisters;
+
+} RGXFWIF_RF_CMD;
+
+/* to opaquely allocate and copy in the kernel */
+#define RGXFWIF_RF_CMD_SIZE sizeof(RGXFWIF_RF_CMD)
+
+#endif /* RGX_FWIF_RESETFRAMEWORK_H */
diff --git a/drivers/gpu/drm/img-rogue/include/rgx_fwif_sf.h b/drivers/gpu/drm/img-rogue/include/rgx_fwif_sf.h
new file mode 100644
index 000000000..9cb64d898
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/rgx_fwif_sf.h
@@ -0,0 +1,905 @@
+/*************************************************************************/ /*!
+@File rgx_fwif_sf.h
+@Title RGX firmware interface string format specifiers
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Header for the rgx firmware logging messages. The following
+ list are the messages the firmware prints. Changing anything
+ but the first column or spelling mistakes in the strings will
+ break compatibility with log files created with older/newer
+ firmware versions.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef RGX_FWIF_SF_H
+#define RGX_FWIF_SF_H
+
+/******************************************************************************
+ * *DO*NOT* rearrange or delete lines in SFIDLIST or SFGROUPLIST or you
+ * WILL BREAK fw tracing message compatibility with previous
+ * fw versions. Only add new ones, if so required.
+ *****************************************************************************/
+/* Available log groups */
+#define RGXFW_LOG_SFGROUPLIST \
+ X(RGXFW_GROUP_NULL,NULL) \
+ X(RGXFW_GROUP_MAIN,MAIN) \
+ X(RGXFW_GROUP_CLEANUP,CLEANUP) \
+ X(RGXFW_GROUP_CSW,CSW) \
+ X(RGXFW_GROUP_PM, PM) \
+ X(RGXFW_GROUP_RTD,RTD) \
+ X(RGXFW_GROUP_SPM,SPM) \
+ X(RGXFW_GROUP_MTS,MTS) \
+ X(RGXFW_GROUP_BIF,BIF) \
+ X(RGXFW_GROUP_MISC,MISC) \
+ X(RGXFW_GROUP_POW,POW) \
+ X(RGXFW_GROUP_HWR,HWR) \
+ X(RGXFW_GROUP_HWP,HWP) \
+ X(RGXFW_GROUP_RPM,RPM) \
+ X(RGXFW_GROUP_DMA,DMA) \
+ X(RGXFW_GROUP_DBG,DBG)
+
+enum RGXFW_LOG_SFGROUPS {
+#define X(A,B) A,
+ RGXFW_LOG_SFGROUPLIST
+#undef X
+};
+
+#define IMG_SF_STRING_MAX_SIZE 256U
+
+typedef struct {
+ IMG_UINT32 ui32Id;
+ IMG_CHAR sName[IMG_SF_STRING_MAX_SIZE];
+} RGXFW_STID_FMT; /* pair of string format id and string formats */
+
+typedef struct {
+ IMG_UINT32 ui32Id;
+ const IMG_CHAR *psName;
+} RGXKM_STID_FMT; /* pair of string format id and string formats */
+
+/* Table of String Format specifiers, the group they belong and the number of
+ * arguments each expects. Xmacro styled macros are used to generate what is
+ * needed without requiring hand editing.
+ *
+ * id : id within a group
+ * gid : group id
+ * Sym name : name of enumerations used to identify message strings
+ * String : Actual string
+ * #args : number of arguments the string format requires
+ */
+#define RGXFW_LOG_SFIDLIST \
+/*id, gid, id name, string, # arguments */ \
+X( 0, RGXFW_GROUP_NULL, RGXFW_SF_FIRST, "You should not use this string", 0) \
+\
+X( 1, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_3D_DEPRECATED, "Kick 3D: FWCtx 0x%08.8x @ %d, RTD 0x%08x. Partial render:%d, CSW resume:%d, prio:%d", 6) \
+X( 2, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_3D_FINISHED, "3D finished, HWRTData0State=%x, HWRTData1State=%x", 2) \
+X( 3, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK3D_TQ_DEPRECATED, "Kick 3D TQ: FWCtx 0x%08.8x @ %d, CSW resume:%d, prio: %d", 4) \
+X( 4, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_3D_TQ_FINISHED, "3D Transfer finished", 0) \
+X( 5, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_COMPUTE_DEPRECATED, "Kick Compute: FWCtx 0x%08.8x @ %d, prio: %d", 3) \
+X( 6, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_COMPUTE_FINISHED, "Compute finished", 0) \
+X( 7, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_TA_DEPRECATED, "Kick TA: FWCtx 0x%08.8x @ %d, RTD 0x%08x. First kick:%d, Last kick:%d, CSW resume:%d, prio:%d", 7) \
+X( 8, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TA_FINISHED, "TA finished", 0) \
+X( 9, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TA_RESTART_AFTER_PRENDER, "Restart TA after partial render", 0) \
+X( 10, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TA_RESUME_WOUT_PRENDER, "Resume TA without partial render", 0) \
+X( 11, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OOM, "Out of memory! Context 0x%08x, HWRTData 0x%x", 2) \
+X( 12, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_TLA_DEPRECATED, "Kick TLA: FWCtx 0x%08.8x @ %d, prio:%d", 3) \
+X( 13, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TLA_FINISHED, "TLA finished", 0) \
+X( 14, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_CCCB_WOFF_UPDATE, "cCCB Woff update = %d, DM = %d, FWCtx = 0x%08.8x", 3) \
+X( 16, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_CHECK_START, "UFO Checks for FWCtx 0x%08.8x @ %d", 2) \
+X( 17, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_CHECK, "UFO Check: [0x%08.8x] is 0x%08.8x requires 0x%08.8x", 3) \
+X( 18, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_CHECK_SUCCEEDED, "UFO Checks succeeded", 0) \
+X( 19, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_PR_CHECK, "UFO PR-Check: [0x%08.8x] is 0x%08.8x requires >= 0x%08.8x", 3) \
+X( 20, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_SPM_PR_CHECK_START, "UFO SPM PR-Checks for FWCtx 0x%08.8x", 1) \
+X( 21, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_SPM_PR_CHECK_DEPRECATED, "UFO SPM special PR-Check: [0x%08.8x] is 0x%08.8x requires >= ????????, [0x%08.8x] is ???????? requires 0x%08.8x", 4) \
+X( 22, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_UPDATE_START, "UFO Updates for FWCtx 0x%08.8x @ %d", 2) \
+X( 23, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_UPDATE, "UFO Update: [0x%08.8x] = 0x%08.8x", 2) \
+X( 24, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_ASSERT_FAILED, "ASSERT Failed: line %d of:", 1) \
+X( 25, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_LOCKUP_DEPRECATED, "HWR: Lockup detected on DM%d, FWCtx: 0x%08.8x", 2) \
+X( 26, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_RESET_FW_DEPRECATED, "HWR: Reset fw state for DM%d, FWCtx: 0x%08.8x, MemCtx: 0x%08.8x", 3) \
+X( 27, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_RESET_HW_DEPRECATED, "HWR: Reset HW", 0) \
+X( 28, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_TERMINATED_DEPRECATED, "HWR: Lockup recovered.", 0) \
+X( 29, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_FALSE_LOCKUP_DEPRECATED, "HWR: False lockup detected for DM%u", 1) \
+X( 30, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_ALIGN_FAILED, "Alignment check %d failed: host = 0x%x, fw = 0x%x", 3) \
+X( 31, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_GP_USC_TRIGGERED, "GP USC triggered", 0) \
+X( 32, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BREAKPOINT_OVERALLOC_REGS, "Overallocating %u temporary registers and %u shared registers for breakpoint handler", 2) \
+X( 33, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BREAKPOINT_SET_DEPRECATED, "Setting breakpoint: Addr 0x%08.8x", 1) \
+X( 34, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BREAKPOINT_STORE, "Store breakpoint state", 0) \
+X( 35, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BREAKPOINT_UNSET, "Unsetting BP Registers", 0) \
+X( 36, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_NONZERO_RT, "Active RTs expected to be zero, actually %u", 1) \
+X( 37, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_RTC_PRESENT, "RTC present, %u active render targets", 1) \
+X( 38, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_EST_POWER_DEPRECATED, "Estimated Power 0x%x", 1) \
+X( 39, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_RTA_TARGET, "RTA render target %u", 1) \
+X( 40, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_RTA_KICK_RENDER, "Kick RTA render %u of %u", 2) \
+X( 41, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_SIZES_CHECK_DEPRECATED, "HWR sizes check %d failed: addresses = %d, sizes = %d", 3) \
+X( 42, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_POW_DUSTS_ENABLE_DEPRECATED, "Pow: DUSTS_ENABLE = 0x%x", 1) \
+X( 43, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_POW_HWREQ_DEPRECATED, "Pow: On(1)/Off(0): %d, Units: 0x%08.8x", 2) \
+X( 44, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_POW_DUSTS_CHANGE_DEPRECATED, "Pow: Changing number of dusts from %d to %d", 2) \
+X( 45, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_POW_SIDEKICK_IDLE_DEPRECATED, "Pow: Sidekick ready to be powered down", 0) \
+X( 46, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_POW_DUSTS_CHANGE_REQ_DEPRECATED, "Pow: Request to change num of dusts to %d (bPowRascalDust=%d)", 2) \
+X( 47, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_PARTIALRENDER_WITHOUT_ZSBUFFER_STORE, "No ZS Buffer used for partial render (store)", 0) \
+X( 48, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_PARTIALRENDER_WITHOUT_ZSBUFFER_LOAD, "No Depth/Stencil Buffer used for partial render (load)", 0) \
+X( 49, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_SET_LOCKUP_DEPRECATED, "HWR: Lock-up DM%d FWCtx: 0x%08.8x", 2) \
+X( 50, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_MLIST_CHECKER_REG_VALUE_DEPRECATED, "MLIST%d checker: CatBase TE=0x%08x (%d Pages), VCE=0x%08x (%d Pages), ALIST=0x%08x, IsTA=%d", 7) \
+X( 51, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_MLIST_CHECKER_MLIST_VALUE, "MLIST%d checker: MList[%d] = 0x%08x", 3) \
+X( 52, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_MLIST_CHECKER_OK, "MLIST%d OK", 1) \
+X( 53, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_MLIST_CHECKER_EMPTY, "MLIST%d is empty", 1) \
+X( 54, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_MLIST_CHECKER_REG_VALUE, "MLIST%d checker: CatBase TE=0x%08x%08x, VCE=0x%08x%08x, ALIST=0x%08x%08x, IsTA=%d", 8) \
+X( 55, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_3D_40480KICK, "3D OQ flush kick", 0) \
+X( 56, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWP_UNSUPPORTED_BLOCK, "HWPerf block ID (0x%x) unsupported by device", 1) \
+X( 57, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BREAKPOINT_SET_DEPRECATED2, "Setting breakpoint: Addr 0x%08.8x DM%u", 2) \
+X( 58, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_RTU_DEPRECATED, "Kick RTU: FWCtx 0x%08.8x @ %d, prio: %d", 3) \
+X( 59, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_RTU_FINISHED_DEPRECATED, "RDM finished on context %u", 1) \
+X( 60, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_SHG_DEPRECATED, "Kick SHG: FWCtx 0x%08.8x @ %d, prio: %d", 3) \
+X( 61, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SHG_FINISHED_DEPRECATED, "SHG finished", 0) \
+X( 62, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FBA_FINISHED_DEPRECATED, "FBA finished on context %u", 1) \
+X( 63, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_CHECK_FAILED, "UFO Checks failed", 0) \
+X( 64, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KILLDM_START, "Kill DM%d start", 1) \
+X( 65, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KILLDM_COMPLETE, "Kill DM%d complete", 1) \
+X( 66, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FC_CCB_UPDATE_DEPRECATED, "FC%u cCCB Woff update = %u", 2) \
+X( 67, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_RTU_DEPRECATED2, "Kick RTU: FWCtx 0x%08.8x @ %d, prio: %d, Frame Context: %d", 4) \
+X( 68, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_GPU_INIT, "GPU init", 0) \
+X( 69, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UNITS_INIT, "GPU Units init (# mask: 0x%x)", 1) \
+X( 70, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_REGTIMES, "Register access cycles: read: %d cycles, write: %d cycles, iterations: %d", 3) \
+X( 71, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_REGCONFIG_ADD, "Register configuration added. Address: 0x%x Value: 0x%x%x", 3) \
+X( 72, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_REGCONFIG_SET, "Register configuration applied to type %d. (0:pow on, 1:Rascal/dust init, 2-5: TA,3D,CDM,TLA, 6:All)", 1) \
+X( 73, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TPC_FLUSH, "Perform TPC flush.", 0) \
+X( 74, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_HIT_LOCKUP_DEPRECATED, "GPU has locked up (see HWR logs for more info)", 0) \
+X( 75, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_HIT_OUTOFTIME, "HWR has been triggered - GPU has overrun its deadline (see HWR logs)", 0) \
+X( 76, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_HIT_POLLFAILURE, "HWR has been triggered - GPU has failed a poll (see HWR logs)", 0) \
+X( 77, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_DOPPLER_OOM_DEPRECATED, "Doppler out of memory event for FC %u", 1) \
+X( 78, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_SPM_PR_CHECK1, "UFO SPM special PR-Check: [0x%08.8x] is 0x%08.8x requires >= 0x%08.8x", 3) \
+X( 79, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_SPM_PR_CHECK2, "UFO SPM special PR-Check: [0x%08.8x] is 0x%08.8x requires 0x%08.8x", 3) \
+X( 80, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TIMESTAMP, "TIMESTAMP -> [0x%08.8x]", 1) \
+X( 81, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_RMW_UPDATE_START, "UFO RMW Updates for FWCtx 0x%08.8x @ %d", 2) \
+X( 82, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_RMW_UPDATE, "UFO Update: [0x%08.8x] = 0x%08.8x", 2) \
+X( 83, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_NULLCMD, "Kick Null cmd: FWCtx 0x%08.8x @ %d", 2) \
+X( 84, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_RPM_OOM_DEPRECATED, "RPM Out of memory! Context 0x%08x, SH requestor %d", 2) \
+X( 85, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_RTU_ABORT_DISCARD_DEPRECATED, "Discard RTU due to RPM abort: FWCtx 0x%08.8x @ %d, prio: %d, Frame Context: %d", 4) \
+X( 86, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_DEFERRED, "Deferring DM%u from running context 0x%08x @ %d (deferred DMs = 0x%08x)", 4) \
+X( 87, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_DEFERRED_WAITING_TURN_DEPRECATED, "Deferring DM%u from running context 0x%08x @ %d to let other deferred DMs run (deferred DMs = 0x%08x)", 4) \
+X( 88, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_DEFERRED_NO_LONGER, "No longer deferring DM%u from running context = 0x%08x @ %d (deferred DMs = 0x%08x)", 4) \
+X( 89, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_WAITING_FOR_FWCCB_DEPRECATED, "FWCCB for DM%u is full, we will have to wait for space! (Roff = %u, Woff = %u)", 3) \
+X( 90, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_WAITING_FOR_FWCCB, "FWCCB for OSid %u is full, we will have to wait for space! (Roff = %u, Woff = %u)", 3) \
+X( 91, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SYNC_PART, "Host Sync Partition marker: %d", 1) \
+X( 92, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SYNC_PART_RPT, "Host Sync Partition repeat: %d", 1) \
+X( 93, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_CLOCK_SPEED_CHANGE, "Core clock set to %d Hz", 1) \
+X( 94, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_COMPUTE_OFFSETS, "Compute Queue: FWCtx 0x%08.8x, prio: %d, queue: 0x%08x%08x (Roff = %u, Woff = %u, Size = %u)", 7) \
+X( 95, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SIGNAL_WAIT_FAILURE_DEPRECATED, "Signal check failed, Required Data: 0x%x, Address: 0x%08x%08x", 3) \
+X( 96, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SIGNAL_UPDATE_DEPRECATED, "Signal update, Snoop Filter: %u, MMU Ctx: %u, Signal Id: %u, Signals Base: 0x%08x%08x", 5) \
+X( 97, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FWCONTEXT_SIGNALED, "Signalled the previously waiting FWCtx: 0x%08.8x, OSId: %u, Signal Address: 0x%08x%08x", 4) \
+X( 98, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_COMPUTE_STALLED_DEPRECATED, "Compute stalled", 0) \
+X( 99, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_COMPUTE_STALLED, "Compute stalled (Roff = %u, Woff = %u, Size = %u)", 3) \
+X(100, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_COMPUTE_RESUMED_FROM_STALL, "Compute resumed (Roff = %u, Woff = %u, Size = %u)", 3) \
+X(101, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_NOTIFY_SIGNAL_UPDATE, "Signal update notification from the host, PC Physical Address: 0x%08x%08x, Signal Virtual Address: 0x%08x%08x", 4) \
+X(102, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SIGNAL_UPDATE_OSID_DM_DEPRECATED, "Signal update from DM: %u, OSId: %u, PC Physical Address: 0x%08x%08x", 4) \
+X(103, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SIGNAL_WAIT_FAILURE_DM_DEPRECATED, "DM: %u signal check failed", 1) \
+X(104, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_TDM_DEPRECATED, "Kick TDM: FWCtx 0x%08.8x @ %d, prio:%d", 3) \
+X(105, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_FINISHED, "TDM finished", 0) \
+X(106, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TE_PIPE_STATUS_DEPRECATED, "MMU_PM_CAT_BASE_TE[%d]_PIPE[%d]: 0x%08x 0x%08x)", 4) \
+X(107, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BRN_54141_HIT_DEPRECATED, "BRN 54141 HIT", 0) \
+X(108, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BRN_54141_APPLYING_DUMMY_TA_DEPRECATED, "BRN 54141 Dummy TA kicked", 0) \
+X(109, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BRN_54141_RESUME_TA_DEPRECATED, "BRN 54141 resume TA", 0) \
+X(110, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BRN_54141_DOUBLE_HIT_DEPRECATED, "BRN 54141 double hit after applying WA", 0) \
+X(111, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BRN_54141_DUMMY_TA_VDM_BASE_DEPRECATED, "BRN 54141 Dummy TA VDM base address: 0x%08x%08x", 2) \
+X(112, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SIGNAL_WAIT_FAILURE_WITH_CURRENT, "Signal check failed, Required Data: 0x%x, Current Data: 0x%x, Address: 0x%08x%08x", 4) \
+X(113, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_BUFFER_STALL_DEPRECATED, "TDM stalled (Roff = %u, Woff = %u)", 2) \
+X(114, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_NOTIFY_WRITE_OFFSET_UPDATE, "Write Offset update notification for stalled FWCtx 0x%08.8x", 1) \
+X(115, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_PRIORITY_CHANGE_DEPRECATED, "Changing OSid %d's priority from %u to %u", 3) \
+X(116, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_COMPUTE_RESUMED, "Compute resumed", 0) \
+X(117, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_TLA, "Kick TLA: FWCtx 0x%08.8x @ %d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 7) \
+X(118, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_TDM, "Kick TDM: FWCtx 0x%08.8x @ %d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 7) \
+X(119, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_TA, "Kick TA: FWCtx 0x%08.8x @ %d, RTD 0x%08x, First kick:%d, Last kick:%d, CSW resume:%d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 11) \
+X(120, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_3D, "Kick 3D: FWCtx 0x%08.8x @ %d, RTD 0x%08x, Partial render:%d, CSW resume:%d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 10) \
+X(121, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_3DTQ, "Kick 3D TQ: FWCtx 0x%08.8x @ %d, CSW resume:%d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 8) \
+X(122, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_COMPUTE, "Kick Compute: FWCtx 0x%08.8x @ %d. (PID:%d, prio:%d, ext:0x%08x, int:0x%08x)", 6) \
+X(123, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_RTU_DEPRECATED3, "Kick RTU: FWCtx 0x%08.8x @ %d, Frame Context:%d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 8) \
+X(124, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_SHG_DEPRECATED2, "Kick SHG: FWCtx 0x%08.8x @ %d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 7) \
+X(125, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_CSRM_RECONFIG, "Reconfigure CSRM: special coeff support enable %d.", 1) \
+X(127, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TA_REQ_MAX_COEFFS, "TA requires max coeff mode, deferring: %d.", 1) \
+X(128, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_3D_REQ_MAX_COEFFS, "3D requires max coeff mode, deferring: %d.", 1) \
+X(129, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KILLDM_FAILED, "Kill DM%d failed", 1) \
+X(130, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_WAITING_FOR_QUEUE, "Thread Queue is full, we will have to wait for space! (Roff = %u, Woff = %u)", 2) \
+X(131, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_WAITING_FOR_QUEUE_FENCE, "Thread Queue is fencing, we are waiting for Roff = %d (Roff = %u, Woff = %u)", 3) \
+X(132, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SET_HCS_TRIGGERED, "DM %d failed to Context Switch on time. Triggered HCS (see HWR logs).", 1) \
+X(133, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HCS_SET_DEPRECATED, "HCS changed to %d ms", 1) \
+X(134, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UPDATE_TILES_IN_FLIGHT_DEPRECATED, "Updating Tiles In Flight (Dusts=%d, PartitionMask=0x%08x, ISPCtl=0x%08x%08x)", 4) \
+X(135, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SET_TILES_IN_FLIGHT, " Phantom %d: USCTiles=%d", 2) \
+X(136, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_ISOLATION_CONF_OFF_DEPRECATED, "Isolation grouping is disabled", 0) \
+X(137, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_ISOLATION_CONF_DEPRECATED, "Isolation group configured with a priority threshold of %d", 1) \
+X(138, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_ONLINE_DEPRECATED, "OS %d has come online", 1) \
+X(139, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_OFFLINE_DEPRECATED, "OS %d has gone offline", 1) \
+X(140, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FWCONTEXT_SIGNAL_REKICK, "Signalled the previously stalled FWCtx: 0x%08.8x, OSId: %u, Signal Address: 0x%08x%08x", 4) \
+X(141, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_OFFSETS_DEPRECATED, "TDM Queue: FWCtx 0x%08.8x, prio: %d, queue: 0x%08x%08x (Roff = %u, Woff = %u, Size = %u)", 7) \
+X(142, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_OFFSET_READ_RESET, "Reset TDM Queue Read Offset: FWCtx 0x%08.8x, queue: 0x%08x%08x (Roff = %u becomes 0, Woff = %u, Size = %u)", 6) \
+X(143, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UMQ_MISMATCHED_READ_OFFSET, "User Mode Queue mismatched stream start: FWCtx 0x%08.8x, queue: 0x%08x%08x (Roff = %u, StreamStartOffset = %u)", 5) \
+X(144, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_GPU_DEINIT, "GPU deinit", 0) \
+X(145, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UNITS_DEINIT, "GPU units deinit", 0) \
+X(146, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_INIT_CONFIG, "Initialised OS %d with config flags 0x%08x", 2) \
+X(147, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_LIMIT, "UFO limit exceeded %d/%d", 2) \
+X(148, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_3D_62850KICK, "3D Dummy stencil store", 0) \
+X(149, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_INIT_CONFIG_DEPRECATED, "Initialised OS %d with config flags 0x%08x and extended config flags 0x%08x", 3) \
+X(150, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UNKNOWN_COMMAND_DEPRECATED, "Unknown Command (eCmdType=0x%08x)", 1) \
+X(151, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_FORCED_UPDATE, "UFO forced update: FWCtx 0x%08.8x @ %d [0x%08.8x] = 0x%08.8x", 4) \
+X(152, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UFO_FORCED_UPDATE_NOP, "UFO forced update NOP: FWCtx 0x%08.8x @ %d [0x%08.8x] = 0x%08.8x, reason %d", 5) \
+X(153, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_BRN66075_CHECK, "TDM context switch check: Roff %u points to 0x%08x, Match=%u", 3) \
+X(154, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_INIT_CCBS, "OSid %d CCB init status: %d (1-ok 0-fail): kCCBCtl@0x%x kCCB@0x%x fwCCBCtl@0x%x fwCCB@0x%x", 6) \
+X(155, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FWIRQ, "FW IRQ # %u @ %u", 2) \
+X(156, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BREAKPOINT_SET, "Setting breakpoint: Addr 0x%08.8x DM%u usc_breakpoint_ctrl_dm = %u", 3) \
+X(157, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_INVALID_KERNEL_CCB_DEPRECATED, "Invalid KCCB setup for OSid %u: KCCB 0x%08x, KCCB Ctrl 0x%08x", 3) \
+X(158, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_INVALID_KERNEL_CCB_CMD, "Invalid KCCB cmd (%u) for OSid %u @ KCCB 0x%08x", 3) \
+X(159, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FW_FAULT, "FW FAULT: At line %d in file 0x%08x%08x, additional data=0x%08x", 4) \
+X(160, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_BREAKPOINT_INVALID, "Invalid breakpoint: MemCtx 0x%08x Addr 0x%08.8x DM%u usc_breakpoint_ctrl_dm = %u", 4) \
+X(161, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FLUSHINVAL_CMD_INVALID_DEPRECATED, "Discarding invalid SLC flushinval command for OSid %u: DM %u, FWCtx 0x%08x", 3) \
+X(162, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_INVALID_NOTIFY_WRITE_OFFSET_UPDATE_DEPRECATED, "Invalid Write Offset update notification from OSid %u to DM %u: FWCtx 0x%08x, MemCtx 0x%08x", 4) \
+X(163, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_INVALID_KCCB_KICK_CMD_DEPRECATED, "Null FWCtx in KCCB kick cmd for OSid %u: KCCB 0x%08x, ROff %u, WOff %u", 4) \
+X(164, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FULL_CHPTCCB, "Checkpoint CCB for OSid %u is full, signalling host for full check state (Roff = %u, Woff = %u)", 3) \
+X(165, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_INIT_CCBS_DEPRECATED, "OSid %d CCB init status: %d (1-ok 0-fail): kCCBCtl@0x%x kCCB@0x%x fwCCBCtl@0x%x fwCCB@0x%x chptCCBCtl@0x%x chptCCB@0x%x", 8) \
+X(166, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_STATE_CHANGE, "OSid %d fw state transition request: from %d to %d (0-offline 1-ready 2-active 3-offloading). Status %d (1-ok 0-fail)", 4) \
+X(167, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_STALE_KCCB_CMDS, "OSid %u has %u stale commands in its KCCB", 2) \
+X(168, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TA_VCE_PAUSE, "Applying VCE pause", 0) \
+X(169, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KCCB_UPDATE_RTN_SLOT_DEPRECATED, "OSid %u KCCB slot %u value updated to %u", 3) \
+X(170, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UNKNOWN_KCCB_COMMAND, "Unknown KCCB Command: KCCBCtl=0x%08x, KCCB=0x%08x, Roff=%u, Woff=%u, Wrap=%u, Cmd=0x%08x, CmdType=0x%08x", 7) \
+X(171, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UNKNOWN_CCB_COMMAND1, "Unknown Client CCB Command processing fences: FWCtx=0x%08x, CCBCtl=0x%08x, CCB=0x%08x, Roff=%u, Doff=%u, Woff=%u, Wrap=%u, CmdHdr=0x%08x, CmdType=0x%08x, CmdSize=%u", 10) \
+X(172, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UNKNOWN_CCB_COMMAND2, "Unknown Client CCB Command executing kick: FWCtx=0x%08x, CCBCtl=0x%08x, CCB=0x%08x, Roff=%u, Doff=%u, Woff=%u, Wrap=%u, CmdHdr=0x%08x, CmdType=0x%08x, CmdSize=%u", 10) \
+X(173, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_INVALID_KCCB_KICK_CMD, "Null FWCtx in KCCB kick cmd for OSid %u with WOff %u", 2) \
+X(174, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FLUSHINVAL_CMD_INVALID, "Discarding invalid SLC flushinval command for OSid %u, FWCtx 0x%08x", 2) \
+X(175, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_INVALID_NOTIFY_WRITE_OFFSET_UPDATE, "Invalid Write Offset update notification from OSid %u: FWCtx 0x%08x, MemCtx 0x%08x", 3) \
+X(176, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FW_INIT_CONFIG, "Initialised Firmware with config flags 0x%08x and extended config flags 0x%08x", 2) \
+X(177, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_PHR_CONFIG, "Set Periodic Hardware Reset Mode: %d", 1) \
+X(179, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_PHR_TRIG, "PHR mode %d, FW state: 0x%08x, HWR flags: 0x%08x", 3) \
+X(180, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_PHR_RESET_DEPRECATED, "PHR mode %d triggered a reset", 1) \
+X(181, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SIGNAL_UPDATE, "Signal update, Snoop Filter: %u, Signal Id: %u", 2) \
+X(182, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_DEV_SERIES8_DEPRECATED, "WARNING: Skipping FW KCCB Cmd type %d which is not yet supported on Series8.", 1) \
+X(183, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_INCONSISTENT_MMU_FLAGS, "MMU context cache data NULL, but cache flags=0x%x (sync counter=%u, update value=%u) OSId=%u", 4) \
+X(184, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SLC_FLUSH, "SLC range based flush: Context=%u VAddr=0x%02x%08x, Size=0x%08x, Invalidate=%d", 5) \
+X(185, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FBSC_INVAL, "FBSC invalidate for Context [0x%08x]: Entry mask 0x%08x%08x.", 3) \
+X(186, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_BRN66284_UPDATE, "TDM context switch check: Roff %u was not valid for kick starting at %u, moving back to %u", 3) \
+X(187, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SPFILTER_UPDATES, "Signal updates: FIFO: %u, Signals: 0x%08x", 2) \
+X(188, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_INVALID_FBSC_CMD, "Invalid FBSC cmd: FWCtx 0x%08x, MemCtx 0x%08x", 2) \
+X(189, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_BRN68497_BLIT, "Insert BRN68497 WA blit after TDM Context store.", 0) \
+X(190, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_PENDING_UFO_UPDATE_START, "UFO Updates for previously finished FWCtx 0x%08.8x", 1) \
+X(191, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_RTC_RTA_PRESENT, "RTC with RTA present, %u active render targets", 1) \
+X(192, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_NULL_RTAS, "Invalid RTA Set-up. The ValidRenderTargets array in RTACtl is Null!", 0) \
+X(193, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_INVALID_COUNTER, "Block 0x%x / Counter 0x%x INVALID and ignored", 2) \
+X(194, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_ECC_FAULT_DEPRECATED, "ECC fault GPU=0x%08x FW=0x%08x", 2) \
+X(195, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_PROCESS_XPU_EVENT, "Processing XPU event on DM = %d", 1) \
+X(196, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_VZ_WDG_TRIGGER, "OSid %u failed to respond to the virtualisation watchdog in time. Timestamp of its last input = %u", 2) \
+X(197, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_HIT_LOCKUP, "GPU-%u has locked up (see HWR logs for more info)", 1) \
+X(198, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UPDATE_TILES_IN_FLIGHT, "Updating Tiles In Flight (Dusts=%d, PartitionMask=0x%08x, ISPCtl=0x%08x)", 3) \
+X(199, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_HWR_HIT_LOCKUP_DM, "GPU has locked up (see HWR logs for more info)", 0) \
+X(200, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_REPROCESS_XPU_EVENTS, "Reprocessing outstanding XPU events from cores 0x%02x", 1) \
+X(201, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SECONDARY_XPU_EVENT, "Secondary XPU event on DM=%d, CoreMask=0x%02x, Raised=0x%02x", 3) \
+X(202, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_OFFSETS, "TDM Queue: Core %u, FWCtx 0x%08.8x, prio: %d, queue: 0x%08x%08x (Roff = %u, Woff = %u, Size = %u)", 8) \
+X(203, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_BUFFER_STALL, "TDM stalled Core %u (Roff = %u, Woff = %u)", 3) \
+X(204, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_COMPUTE_CORE_OFFSETS, "Compute Queue: Core %u, FWCtx 0x%08.8x, prio: %d, queue: 0x%08x%08x (Roff = %u, Woff = %u, Size = %u)", 8) \
+X(205, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_COMPUTE_CORE_STALLED, "Compute stalled core %u (Roff = %u, Woff = %u, Size = %u)", 4) \
+X(206, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_UMQ_MISMATCHED_CORE_READ_OFFSET, "User Mode Queue mismatched stream start: Core %u, FWCtx 0x%08.8x, queue: 0x%08x%08x (Roff = %u, StreamStartOffset = %u)", 6) \
+X(207, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TDM_RESUMED_FROM_STALL, "TDM resumed core %u (Roff = %u, Woff = %u)", 3) \
+X(208, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_COMPUTE_CORE_RESUMED_FROM_STALL, "Compute resumed core %u (Roff = %u, Woff = %u, Size = %u)", 4) \
+X(209, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_MTS_PERMISSION_CHANGED, " Updated permission for OSid %u to perform MTS kicks: %u (1 = allowed, 0 = not allowed)", 2) \
+X(210, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TEST1, "Mask = 0x%X, mask2 = 0x%X", 2) \
+X(211, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_TEST2, " core %u, reg = %u, mask = 0x%X)", 3) \
+X(212, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_ECC_FAULT_SAFETY_BUS, "ECC fault received from safety bus: 0x%08x", 1) \
+X(213, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SAFETY_WDG_CONFIG, "Safety Watchdog threshold period set to 0x%x clock cycles", 1) \
+X(214, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SAFETY_WDG_TRIGGER, "MTS Safety Event trigged by the safety watchdog.", 0) \
+X(215, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_USC_TASKS_RANGE, "DM%d USC tasks range limit 0 - %d, stride %d", 3) \
+X(216, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_GPU_ECC_FAULT, "ECC fault GPU=0x%08x", 1) \
+X(217, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_GPU_SAFETY_RESET, "GPU Hardware units reset to prevent transient faults.", 0) \
+X(218, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_ABORTCMD, "Kick Abort cmd: FWCtx 0x%08.8x @ %d", 2) \
+X(219, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_KICK_RAY, "Kick Ray: FWCtx 0x%08.8x @ %d. (PID:%d, prio:%d, frame:%d, ext:0x%08x, int:0x%08x)", 7)\
+X(220, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_RAY_FINISHED, "Ray finished", 0) \
+X(221, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_FWDATA_INIT_STATUS, "State of firmware's private data at boot time: %d (0 = uninitialised, 1 = initialised); Fw State Flags = 0x%08X", 2) \
+X(222, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_CFI_TIMEOUT, "CFI Timeout detected (%d increasing to %d)", 2) \
+X(223, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_CFI_TIMEOUT_FBM, "CFI Timeout detected for FBM (%d increasing to %d)", 2) \
+X(224, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_GEOM_OOM_DISALLOWED, "Geom OOM event not allowed", 0) \
+X(225, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_OS_PRIORITY_CHANGE, "Changing OSid %d's priority from %u to %u; Isolation = %u (0 = off; 1 = on)", 4) \
+X(226, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_SKIP_ALREADY_RUN_GEOM, "Skipping already executed TA FWCtx 0x%08.8x @ %d", 2) \
+X(227, RGXFW_GROUP_MAIN, RGXFW_SF_MAIN_ATTEMPT_TO_RUN_AHEAD_GEOM, "Attempt to execute TA FWCtx 0x%08.8x @ %d ahead of time on other GEOM", 2) \
+\
+X( 1, RGXFW_GROUP_MTS, RGXFW_SF_MTS_BG_KICK_DEPRECATED, "Bg Task DM = %u, counted = %d", 2) \
+X( 2, RGXFW_GROUP_MTS, RGXFW_SF_MTS_BG_COMPLETE_DEPRECATED, "Bg Task complete DM = %u", 1) \
+X( 3, RGXFW_GROUP_MTS, RGXFW_SF_MTS_IRQ_KICK_DEPRECATED, "Irq Task DM = %u, Breq = %d, SBIrq = 0x%x", 3) \
+X( 4, RGXFW_GROUP_MTS, RGXFW_SF_MTS_IRQ_COMPLETE_DEPRECATED, "Irq Task complete DM = %u", 1) \
+X( 5, RGXFW_GROUP_MTS, RGXFW_SF_MTS_KICK_MTS_BG_ALL_DEPRECATED, "Kick MTS Bg task DM=All", 0) \
+X( 6, RGXFW_GROUP_MTS, RGXFW_SF_MTS_KICK_MTS_IRQ, "Kick MTS Irq task DM=%d", 1) \
+X( 7, RGXFW_GROUP_MTS, RGXFW_SF_MTS_READYCELLTYPE_DEPRECATED, "Ready queue debug DM = %u, celltype = %d", 2) \
+X( 8, RGXFW_GROUP_MTS, RGXFW_SF_MTS_READYTORUN_DEPRECATED, "Ready-to-run debug DM = %u, item = 0x%x", 2) \
+X( 9, RGXFW_GROUP_MTS, RGXFW_SF_MTS_CMDHEADER, "Client command header DM = %u, client CCB = 0x%x, cmd = 0x%x", 3) \
+X( 10, RGXFW_GROUP_MTS, RGXFW_SF_MTS_READYTORUN, "Ready-to-run debug OSid = %u, DM = %u, item = 0x%x", 3) \
+X( 11, RGXFW_GROUP_MTS, RGXFW_SF_MTS_READYCELLTYPE_DEPRECATED2, "Ready queue debug DM = %u, celltype = %d, OSid = %u", 3) \
+X( 12, RGXFW_GROUP_MTS, RGXFW_SF_MTS_BG_KICK_DEPRECATED2, "Bg Task DM = %u, counted = %d, OSid = %u", 3) \
+X( 13, RGXFW_GROUP_MTS, RGXFW_SF_MTS_BG_COMPLETE, "Bg Task complete DM Bitfield: %u", 1) \
+X( 14, RGXFW_GROUP_MTS, RGXFW_SF_MTS_IRQ_COMPLETE, "Irq Task complete.", 0) \
+X( 15, RGXFW_GROUP_MTS, RGXFW_SF_MTS_CMD_DISCARD, "Discarded Command Type: %d OS ID = %d PID = %d context = 0x%08x cccb ROff = 0x%x, due to USC breakpoint hit by OS ID = %d PID = %d.", 7) \
+X( 16, RGXFW_GROUP_MTS, RGXFW_SF_MTS_KCCBCMD_EXEC_DEPRECATED, "KCCB Slot %u: DM=%u, Cmd=0x%08x, OSid=%u", 4) \
+X( 17, RGXFW_GROUP_MTS, RGXFW_SF_MTS_KCCBCMD_RTN_VALUE, "KCCB Slot %u: Return value %u", 2) \
+X( 18, RGXFW_GROUP_MTS, RGXFW_SF_MTS_BG_KICK, "Bg Task OSid = %u", 1) \
+X( 19, RGXFW_GROUP_MTS, RGXFW_SF_MTS_KCCBCMD_EXEC, "KCCB Slot %u: Cmd=0x%08x, OSid=%u", 3) \
+X( 20, RGXFW_GROUP_MTS, RGXFW_SF_MTS_IRQ_KICK, "Irq Task (EVENT_STATUS=0x%08x)", 1) \
+\
+X( 1, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_FWCTX_CLEANUP, "FwCommonContext [0x%08x] cleaned", 1) \
+X( 2, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_FWCTX_BUSY, "FwCommonContext [0x%08x] is busy: ReadOffset = %d, WriteOffset = %d", 3) \
+X( 3, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRTD_CLEANUP_DEPRECATED, "HWRTData [0x%08x] for DM=%d, received cleanup request", 2) \
+X( 4, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRTD_CLEANED_FOR_DM_DEPRECATED, "HWRTData [0x%08x] HW Context cleaned for DM%u, executed commands = %d", 3) \
+X( 5, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRTD_BUSY_DEPRECATED, "HWRTData [0x%08x] HW Context for DM%u is busy", 2) \
+X( 6, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRTD_CLEANED_DEPRECATED, "HWRTData [0x%08x] HW Context %u cleaned", 2) \
+X( 7, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_FL_CLEANED, "Freelist [0x%08x] cleaned", 1) \
+X( 8, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_ZSBUFFER_CLEANED, "ZSBuffer [0x%08x] cleaned", 1) \
+X( 9, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_ZSBUFFER_BUSY, "ZSBuffer [0x%08x] is busy: submitted = %d, executed = %d", 3) \
+X( 10, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRTD_BUSY_DEPRECATED2, "HWRTData [0x%08x] HW Context for DM%u is busy: submitted = %d, executed = %d", 4) \
+X( 11, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRFD_CLEANUP_DEPRECATED, "HW Ray Frame data [0x%08x] for DM=%d, received cleanup request", 2) \
+X( 12, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRFD_CLEANED_FOR_DM_DEPRECATED, "HW Ray Frame Data [0x%08x] cleaned for DM%u, executed commands = %d", 3) \
+X( 13, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRFD_BUSY_DEPRECATED, "HW Ray Frame Data [0x%08x] for DM%u is busy: submitted = %d, executed = %d", 4) \
+X( 14, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRFD_CLEANED_DEPRECATED, "HW Ray Frame Data [0x%08x] HW Context %u cleaned", 2) \
+X( 15, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_INVALID_REQUEST, "Discarding invalid cleanup request of type 0x%x", 1) \
+X( 16, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRTD_CLEANUP, "Received cleanup request for HWRTData [0x%08x]", 1) \
+X( 17, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRTD_BUSY, "HWRTData [0x%08x] HW Context is busy: submitted = %d, executed = %d", 3) \
+X( 18, RGXFW_GROUP_CLEANUP, RGXFW_SF_CLEANUP_HWRTD_CLEANED, "HWRTData [0x%08x] HW Context %u cleaned, executed commands = %d", 3) \
+\
+X( 1, RGXFW_GROUP_CSW, RGXFW_SF_CSW_CDM_NEEDS_RESUME, "CDM FWCtx 0x%08.8x needs resume", 1) \
+X( 2, RGXFW_GROUP_CSW, RGXFW_SF_CSW_CDM_RESUME_DEPRECATED, "*** CDM FWCtx 0x%08.8x resume from snapshot buffer 0x%08x%08x", 3) \
+X( 3, RGXFW_GROUP_CSW, RGXFW_SF_CSW_CDM_SHARED, "CDM FWCtx shared alloc size load 0x%x", 1) \
+X( 4, RGXFW_GROUP_CSW, RGXFW_SF_CSW_CDM_STORE_COMPLETE, "*** CDM FWCtx store complete", 0) \
+X( 5, RGXFW_GROUP_CSW, RGXFW_SF_CSW_CDM_STORE_START, "*** CDM FWCtx store start", 0) \
+X( 6, RGXFW_GROUP_CSW, RGXFW_SF_CSW_CDM_SOFT_RESET, "CDM Soft Reset", 0) \
+X( 7, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_NEEDS_RESUME, "3D FWCtx 0x%08.8x needs resume", 1) \
+X( 8, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_RESUME, "*** 3D FWCtx 0x%08.8x resume", 1) \
+X( 9, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_STORE_COMPLETE, "*** 3D context store complete", 0) \
+X( 10, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_STORE_PIPE_STATE_DEPRECATED, "3D context store pipe state: 0x%08.8x 0x%08.8x 0x%08.8x", 3) \
+X( 11, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_STORE_START, "*** 3D context store start", 0) \
+X( 12, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_TQ_RESUME, "*** 3D TQ FWCtx 0x%08.8x resume", 1) \
+X( 13, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_NEEDS_RESUME, "TA FWCtx 0x%08.8x needs resume", 1) \
+X( 14, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_RESUME, "*** TA FWCtx 0x%08.8x resume from snapshot buffer 0x%08x%08x", 3) \
+X( 15, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_SHARED, "TA context shared alloc size store 0x%x, load 0x%x", 2) \
+X( 16, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_STORE_COMPLETE, "*** TA context store complete", 0) \
+X( 17, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_STORE_START, "*** TA context store start", 0) \
+X( 18, RGXFW_GROUP_CSW, RGXFW_SF_CSW_HIGHER_PRIORITY_SCHEDULED_DEPRECATED, "Higher priority context scheduled for DM %u, old prio:%d, new prio:%d", 3) \
+X( 19, RGXFW_GROUP_CSW, RGXFW_SF_CSW_SET_CONTEXT_PRIORITY, "Set FWCtx 0x%x priority to %u", 2) \
+X( 20, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_STORE_PIPE_STATE_DEPRECATED2, "3D context store pipe%d state: 0x%08.8x", 2) \
+X( 21, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_RESUME_PIPE_STATE_DEPRECATED, "3D context resume pipe%d state: 0x%08.8x", 2) \
+X( 22, RGXFW_GROUP_CSW, RGXFW_SF_CSW_SHG_NEEDS_RESUME_DEPRECATED, "SHG FWCtx 0x%08.8x needs resume", 1) \
+X( 23, RGXFW_GROUP_CSW, RGXFW_SF_CSW_SHG_RESUME_DEPRECATED, "*** SHG FWCtx 0x%08.8x resume from snapshot buffer 0x%08x%08x", 3) \
+X( 24, RGXFW_GROUP_CSW, RGXFW_SF_CSW_SHG_SHARED_DEPRECATED, "SHG context shared alloc size store 0x%x, load 0x%x", 2) \
+X( 25, RGXFW_GROUP_CSW, RGXFW_SF_CSW_SHG_STORE_COMPLETE_DEPRECATED, "*** SHG context store complete", 0) \
+X( 26, RGXFW_GROUP_CSW, RGXFW_SF_CSW_SHG_STORE_START_DEPRECATED, "*** SHG context store start", 0) \
+X( 27, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_PIPE_INDIRECT, "Performing TA indirection, last used pipe %d", 1) \
+X( 28, RGXFW_GROUP_CSW, RGXFW_SF_CSW_CDM_STORE_CTRL_STREAM_TERMINATE, "CDM context store hit ctrl stream terminate. Skip resume.", 0) \
+X( 29, RGXFW_GROUP_CSW, RGXFW_SF_CSW_CDM_RESUME_AB_BUFFER, "*** CDM FWCtx 0x%08.8x resume from snapshot buffer 0x%08x%08x, shader state %u", 4) \
+X( 30, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_STATE_BUFFER_FLIP, "TA PDS/USC state buffer flip (%d->%d)", 2) \
+X( 31, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_STORE_52563_HIT_DEPRECATED, "TA context store hit BRN 52563: vertex store tasks outstanding", 0) \
+X( 32, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_STORE_USC_POLL_FAILED, "TA USC poll failed (USC vertex task count: %d)", 1) \
+X( 33, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TA_STORE_DEFERRED_DEPRECATED, "TA context store deferred due to BRN 54141.", 0) \
+X( 34, RGXFW_GROUP_CSW, RGXFW_SF_CSW_HIGHER_PRIORITY_SCHEDULED_DEPRECATED2, "Higher priority context scheduled for DM %u. Prios (OSid, OSid Prio, Context Prio): Current: %u, %u, %u New: %u, %u, %u", 7) \
+X( 35, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TDM_STORE_START, "*** TDM context store start", 0) \
+X( 36, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TDM_STORE_COMPLETE, "*** TDM context store complete", 0) \
+X( 37, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TDM_STORE_NEEDS_RESUME_DEPRECATED, "TDM context needs resume, header [0x%08.8x, 0x%08.8x]", 2) \
+X( 38, RGXFW_GROUP_CSW, RGXFW_SF_CSW_HIGHER_PRIORITY_SCHEDULED, "Higher priority context scheduled for DM %u. Prios (OSid, OSid Prio, Context Prio): Current: %u, %u, %u New: %u, %u, %u. Hard Context Switching: %u", 8) \
+X( 39, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_STORE_PIPE_STATE, "3D context store pipe %2d (%2d) state: 0x%08.8x", 3) \
+X( 40, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_RESUME_PIPE_STATE, "3D context resume pipe %2d (%2d) state: 0x%08.8x", 3) \
+X( 41, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_STORE_START_VOLCANIC, "*** 3D context store start version %d (1=IPP_TILE, 2=ISP_TILE)", 1) \
+X( 42, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_STORE_PIPE_STATE_VOLCANIC, "3D context store pipe%d state: 0x%08.8x%08x", 3) \
+X( 43, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_RESUME_PIPE_STATE_VOLCANIC, "3D context resume pipe%d state: 0x%08.8x%08x", 3) \
+X( 44, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_RESUME_IPP_STATE, "3D context resume IPP state: 0x%08.8x%08x", 2) \
+X( 45, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_PIPES_EMPTY, "All 3D pipes empty after ISP tile mode store! IPP_status: 0x%08x", 1) \
+X( 46, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TDM_RESUME_PIPE_STATE_DEPRECATED, "TDM context resume pipe%d state: 0x%08.8x%08x", 3) \
+X( 47, RGXFW_GROUP_CSW, RGXFW_SF_CSW_3D_LEVEL4_STORE_START, "*** 3D context store start version 4", 0) \
+X( 48, RGXFW_GROUP_CSW, RGXFW_SF_CSW_RESUME_MULTICORE, "Multicore context resume on DM%d active core mask 0x%04.4x", 2) \
+X( 49, RGXFW_GROUP_CSW, RGXFW_SF_CSW_STORE_MULTICORE, "Multicore context store on DM%d active core mask 0x%04.4x", 2) \
+X( 50, RGXFW_GROUP_CSW, RGXFW_SF_CSW_TDM_RESUME_PIPE_STATE, "TDM context resume Core %d, pipe%d state: 0x%08.8x%08x%08x", 5) \
+X( 51, RGXFW_GROUP_CSW, RGXFW_SF_CSW_RDM_STORE_COMPLETE, "*** RDM FWCtx store complete", 0) \
+X( 52, RGXFW_GROUP_CSW, RGXFW_SF_CSW_RDM_STORE_START, "*** RDM FWCtx store start", 0) \
+X( 53, RGXFW_GROUP_CSW, RGXFW_SF_CSW_RDM_NEEDS_RESUME, "RDM FWCtx 0x%08.8x needs resume", 1) \
+X( 54, RGXFW_GROUP_CSW, RGXFW_SF_CSW_RDM_RESUME, "RDM FWCtx 0x%08.8x resume", 1) \
+\
+X( 1, RGXFW_GROUP_BIF, RGXFW_SF_BIF_ACTIVATE_BIFREQ_DEPRECATED, "Activate MemCtx=0x%08x BIFreq=%d secure=%d", 3) \
+X( 2, RGXFW_GROUP_BIF, RGXFW_SF_BIF_DEACTIVATE, "Deactivate MemCtx=0x%08x", 1) \
+X( 3, RGXFW_GROUP_BIF, RGXFW_SF_BIF_PCREG_ALLOC, "Alloc PC reg %d", 1) \
+X( 4, RGXFW_GROUP_BIF, RGXFW_SF_BIF_PCREG_GRAB, "Grab reg %d refcount now %d", 2) \
+X( 5, RGXFW_GROUP_BIF, RGXFW_SF_BIF_PCREG_UNGRAB, "Ungrab reg %d refcount now %d", 2) \
+X( 6, RGXFW_GROUP_BIF, RGXFW_SF_BIF_SETUP_REG_BIFREQ_DEPRECATED, "Setup reg=%d BIFreq=%d, expect=0x%08x%08x, actual=0x%08x%08x", 6) \
+X( 7, RGXFW_GROUP_BIF, RGXFW_SF_BIF_TRUST_DEPRECATED, "Trust enabled:%d, for BIFreq=%d", 2) \
+X( 8, RGXFW_GROUP_BIF, RGXFW_SF_BIF_TILECFG_DEPRECATED, "BIF Tiling Cfg %d base 0x%08x%08x len 0x%08x%08x enable %d stride %d --> 0x%08x%08x", 9) \
+X( 9, RGXFW_GROUP_BIF, RGXFW_SF_BIF_OSID0, "Wrote the Value %d to OSID0, Cat Base %d, Register's contents are now 0x%08x 0x%08x", 4) \
+X( 10, RGXFW_GROUP_BIF, RGXFW_SF_BIF_OSID1, "Wrote the Value %d to OSID1, Context %d, Register's contents are now 0x%04x", 3) \
+X( 11, RGXFW_GROUP_BIF, RGXFW_SF_BIF_OSIDx, "ui32OSid = %u, Catbase = %u, Reg Address = 0x%x, Reg index = %u, Bitshift index = %u, Val = 0x%08x%08x", 7) \
+X( 12, RGXFW_GROUP_BIF, RGXFW_SF_BIF_MAP_GPU_MEMORY_BIFREQ_DEPRECATED, "Map GPU memory DevVAddr 0x%x%08x, Size %u, Context ID %u, BIFREQ %u", 5) \
+X( 13, RGXFW_GROUP_BIF, RGXFW_SF_BIF_UNMAP_GPU_MEMORY, "Unmap GPU memory (event status 0x%x)", 1) \
+X( 14, RGXFW_GROUP_BIF, RGXFW_SF_BIF_ACTIVATE_DM, "Activate MemCtx=0x%08x DM=%d secure=%d", 3) \
+X( 15, RGXFW_GROUP_BIF, RGXFW_SF_BIF_SETUP_REG_DM, "Setup reg=%d DM=%d, expect=0x%08x%08x, actual=0x%08x%08x", 6) \
+X( 16, RGXFW_GROUP_BIF, RGXFW_SF_BIF_MAP_GPU_MEMORY, "Map GPU memory DevVAddr 0x%x%08x, Size %u, Context ID %u", 4) \
+X( 17, RGXFW_GROUP_BIF, RGXFW_SF_BIF_TRUST_DM, "Trust enabled:%d, for DM=%d", 2) \
+X( 18, RGXFW_GROUP_BIF, RGXFW_SF_BIF_MAP_GPU_MEMORY_DM, "Map GPU memory DevVAddr 0x%x%08x, Size %u, Context ID %u, DM %u", 5) \
+\
+X( 1, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_WRITE, "GPIO write 0x%02x", 1) \
+X( 2, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_READ, "GPIO read 0x%02x", 1) \
+X( 3, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_ENABLED, "GPIO enabled", 0) \
+X( 4, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_DISABLED, "GPIO disabled", 0) \
+X( 5, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_STATUS, "GPIO status=%d (0=OK, 1=Disabled)", 1) \
+X( 6, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_AP_READ, "GPIO_AP: Read address=0x%02x (%d byte(s))", 2) \
+X( 7, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_AP_WRITE, "GPIO_AP: Write address=0x%02x (%d byte(s))", 2) \
+X( 8, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_AP_TIMEOUT, "GPIO_AP timeout!", 0) \
+X( 9, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_AP_ERROR, "GPIO_AP error. GPIO status=%d (0=OK, 1=Disabled)", 1) \
+X( 10, RGXFW_GROUP_MISC, RGXFW_SF_MISC_GPIO_ALREADY_READ, "GPIO already read 0x%02x", 1) \
+X( 11, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_CHECK_BUFFER_AVAILABLE, "SR: Check buffer %d available returned %d", 2) \
+X( 12, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_WAITING_BUFFER_AVAILABLE, "SR: Waiting for buffer %d", 1) \
+X( 13, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_WAIT_BUFFER_TIMEOUT, "SR: Timeout waiting for buffer %d (after %d ticks)", 2) \
+X( 14, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_SKIP_FRAME_CHECK, "SR: Skip frame check for strip %d returned %d (0=No skip, 1=Skip frame)", 2) \
+X( 15, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_SKIP_REMAINING_STRIPS, "SR: Skip remaining strip %d in frame", 1) \
+X( 16, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_FRAME_SKIP_NEW_FRAME, "SR: Inform HW that strip %d is a new frame", 1) \
+X( 17, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_SKIP_FRAME_TIMEOUT, "SR: Timeout waiting for INTERRUPT_FRAME_SKIP (after %d ticks)", 1) \
+X( 18, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_STRIP_MODE, "SR: Strip mode is %d", 1) \
+X( 19, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_STRIP_INDEX, "SR: Strip Render start (strip %d)", 1) \
+X( 20, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_BUFFER_RENDERED, "SR: Strip Render complete (buffer %d)", 1) \
+X( 21, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SR_BUFFER_FAULT, "SR: Strip Render fault (buffer %d)", 1) \
+X( 22, RGXFW_GROUP_MISC, RGXFW_SF_MISC_TRP_STATE, "TRP state: %d", 1) \
+X( 23, RGXFW_GROUP_MISC, RGXFW_SF_MISC_TRP_FAILURE, "TRP failure: %d", 1) \
+X( 24, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SW_TRP_STATE, "SW TRP State: %d", 1) \
+X( 25, RGXFW_GROUP_MISC, RGXFW_SF_MISC_SW_TRP_FAILURE, "SW TRP failure: %d", 1) \
+X( 26, RGXFW_GROUP_MISC, RGXFW_SF_MISC_HW_KICK, "HW kick event (%u)", 1) \
+X( 27, RGXFW_GROUP_MISC, RGXFW_SF_MISC_WGP_CHECKSUMS, "GPU core (%u/%u): checksum 0x%08x vs. 0x%08x", 4) \
+X( 28, RGXFW_GROUP_MISC, RGXFW_SF_MISC_WGP_UNIT_CHECKSUMS, "GPU core (%u/%u), unit (%u,%u): checksum 0x%08x vs. 0x%08x", 6) \
+X( 29, RGXFW_GROUP_MISC, RGXFW_SF_MISC_HWR_CHECK_REG, "HWR: Core%u, Register=0x%08x, OldValue=0x%08x%08x, CurrValue=0x%08x%08x", 6) \
+X( 30, RGXFW_GROUP_MISC, RGXFW_SF_MISC_HWR_USC_SLOTS_CHECK, "HWR: USC Core%u, ui32TotalSlotsUsedByDM=0x%08x, psDMHWCtl->ui32USCSlotsUsedByDM=0x%08x, bHWRNeeded=%u", 4) \
+X( 31, RGXFW_GROUP_MISC, RGXFW_SF_MISC_HWR_USC_REG_CHECK, "HWR: USC Core%u, Register=0x%08x, OldValue=0x%08x%08x, CurrValue=0x%08x%08x", 6) \
+\
+X( 1, RGXFW_GROUP_PM, RGXFW_SF_PM_AMLIST, "ALIST%d SP = %u, MLIST%d SP = %u (VCE 0x%08x%08x, TE 0x%08x%08x, ALIST 0x%08x%08x)", 10) \
+X( 2, RGXFW_GROUP_PM, RGXFW_SF_PM_UFL_SHARED_DEPRECATED, "Is TA: %d, finished: %d on HW %u (HWRTData = 0x%08x, MemCtx = 0x%08x). FL different between TA/3D: global:%d, local:%d, mmu:%d", 8) \
+X( 3, RGXFW_GROUP_PM, RGXFW_SF_PM_UFL_3DBASE_DEPRECATED, "UFL-3D-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u), FL-3D-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u), MFL-3D-Base: 0x%08x%08x (SP = %u, 4PT = %u)", 14) \
+X( 4, RGXFW_GROUP_PM, RGXFW_SF_PM_UFL_TABASE_DEPRECATED, "UFL-TA-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u), FL-TA-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u), MFL-TA-Base: 0x%08x%08x (SP = %u, 4PT = %u)", 14) \
+X( 5, RGXFW_GROUP_PM, RGXFW_SF_PM_FL_GROW_COMPLETE_DEPRECATED, "Freelist grow completed [0x%08x]: added pages 0x%08x, total pages 0x%08x, new DevVirtAddr 0x%08x%08x", 5) \
+X( 6, RGXFW_GROUP_PM, RGXFW_SF_PM_FL_GROW_DENIED_DEPRECATED, "Grow for freelist ID=0x%08x denied by host", 1) \
+X( 7, RGXFW_GROUP_PM, RGXFW_SF_PM_FL_UPDATE_COMPLETE, "Freelist update completed [0x%08x]: old total pages 0x%08x, new total pages 0x%08x, new DevVirtAddr 0x%08x%08x", 5) \
+X( 8, RGXFW_GROUP_PM, RGXFW_SF_PM_FL_RECONSTRUCTION_FAILED_DEPRECATED, "Reconstruction of freelist ID=0x%08x failed", 1) \
+X( 9, RGXFW_GROUP_PM, RGXFW_SF_PM_DM_PAUSE_WARNING, "Ignored attempt to pause or unpause the DM while there is no relevant operation in progress (0-TA,1-3D): %d, operation(0-unpause, 1-pause): %d", 2) \
+X( 10, RGXFW_GROUP_PM, RGXFW_SF_PM_3D_TIMEOUT_STATUS, "Force free 3D Context memory, FWCtx: 0x%08x, status(1:success, 0:fail): %d", 2)\
+X( 11, RGXFW_GROUP_PM, RGXFW_SF_PM_DM_PAUSE_ALLOC, "PM pause TA ALLOC: PM_PAGE_MANAGEOP set to 0x%x", 1) \
+X( 12, RGXFW_GROUP_PM, RGXFW_SF_PM_DM_UNPAUSE_ALLOC, "PM unpause TA ALLOC: PM_PAGE_MANAGEOP set to 0x%x", 1) \
+X( 13, RGXFW_GROUP_PM, RGXFW_SF_PM_DM_PAUSE_DALLOC, "PM pause 3D DALLOC: PM_PAGE_MANAGEOP set to 0x%x", 1) \
+X( 14, RGXFW_GROUP_PM, RGXFW_SF_PM_DM_UNPAUSE_DALLOC, "PM unpause 3D DALLOC: PM_PAGE_MANAGEOP set to 0x%x", 1) \
+X( 15, RGXFW_GROUP_PM, RGXFW_SF_PM_DM_PAUSE_FAILED, "PM ALLOC/DALLOC change was not actioned: PM_PAGE_MANAGEOP_STATUS=0x%x", 1) \
+X( 16, RGXFW_GROUP_PM, RGXFW_SF_PM_UFL_SHARED, "Is TA: %d, finished: %d on HW %u (HWRTData = 0x%08x, MemCtx = 0x%08x). FL different between TA/3D: global:%d, local:%d", 7) \
+X( 17, RGXFW_GROUP_PM, RGXFW_SF_PM_UFL_3DBASE, "UFL-3D-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u), FL-3D-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u)", 10) \
+X( 18, RGXFW_GROUP_PM, RGXFW_SF_PM_UFL_TABASE, "UFL-TA-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u), FL-TA-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u)", 10) \
+X( 19, RGXFW_GROUP_PM, RGXFW_SF_PM_FL_UPDATE_COMPLETE_VOLCANIC, "Freelist update completed [0x%08x / FL State 0x%08x%08x]: old total pages 0x%08x, new total pages 0x%08x, new DevVirtAddr 0x%08x%08x", 7) \
+X( 20, RGXFW_GROUP_PM, RGXFW_SF_PM_FL_UPDATE_FAILED, "Freelist update failed [0x%08x / FL State 0x%08x%08x]: old total pages 0x%08x, new total pages 0x%08x, new DevVirtAddr 0x%08x%08x", 7) \
+X( 21, RGXFW_GROUP_PM, RGXFW_SF_PM_UFL_3DBASE_VOLCANIC, "UFL-3D-State-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u), FL-3D-State-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u)", 10) \
+X( 22, RGXFW_GROUP_PM, RGXFW_SF_PM_UFL_TABASE_VOLCANIC, "UFL-TA-State-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u), FL-TA-State-Base: 0x%08x%08x (SP = %u, 4PB = %u, 4PT = %u)", 10) \
+X( 23, RGXFW_GROUP_PM, RGXFW_SF_PM_CHECK_FL_BASEADDR, "Freelist 0x%08x base address from HW: 0x%02x%08x (expected value: 0x%02x%08x)", 5) \
+X( 24, RGXFW_GROUP_PM, RGXFW_SF_PM_ANALYSE_FL_GROW, "Analysis of FL grow: Pause=(%u,%u) Paused+Valid(%u,%u) PMStateBuffer=0x%x", 5) \
+X( 25, RGXFW_GROUP_PM, RGXFW_SF_PM_ATTEMPT_FL_GROW, "Attempt FL grow for FL: 0x%08x, new dev address: 0x%02x%08x, new page count: %u, new ready count: %u", 5) \
+X( 26, RGXFW_GROUP_PM, RGXFW_SF_PM_DEFER_FL_GROW, "Deferring FL grow for non-loaded FL: 0x%08x, new dev address: 0x%02x%08x, new page count: %u, new ready count: %u", 5) \
+X( 27, RGXFW_GROUP_PM, RGXFW_SF_PM_UFL_SHARED_ALBIORIX, "Is GEOM: %d, finished: %d (HWRTData = 0x%08x, MemCtx = 0x%08x)", 4) \
+X( 28, RGXFW_GROUP_PM, RGXFW_SF_PM_3D_TIMEOUT, "3D Timeout Now for FWCtx 0x%08.8x", 1) \
+X( 29, RGXFW_GROUP_PM, RGXFW_SF_PM_RECYCLE, "GEOM PM Recycle for FWCtx 0x%08.8x", 1) \
+X( 30, RGXFW_GROUP_PM, RGXFW_SF_PM_PRIMARY_CONFIG, "PM running primary config (Core %d)", 1) \
+X( 31, RGXFW_GROUP_PM, RGXFW_SF_PM_SECONDARY_CONFIG, "PM running secondary config (Core %d)", 1) \
+\
+X( 1, RGXFW_GROUP_RPM, RGXFW_SF_RPM_GLL_DYNAMIC_STATUS_DEPRECATED, "Global link list dynamic page count: vertex 0x%x, varying 0x%x, node 0x%x", 3) \
+X( 2, RGXFW_GROUP_RPM, RGXFW_SF_RPM_GLL_STATIC_STATUS_DEPRECATED, "Global link list static page count: vertex 0x%x, varying 0x%x, node 0x%x", 3) \
+X( 3, RGXFW_GROUP_RPM, RGXFW_SF_RPM_STATE_WAIT_FOR_GROW_DEPRECATED, "RPM request failed. Waiting for freelist grow.", 0) \
+X( 4, RGXFW_GROUP_RPM, RGXFW_SF_RPM_STATE_ABORT_DEPRECATED, "RPM request failed. Aborting the current frame.", 0) \
+X( 5, RGXFW_GROUP_RPM, RGXFW_SF_RPM_STATE_WAIT_FOR_PENDING_GROW_DEPRECATED, "RPM waiting for pending grow on freelist 0x%08x", 1) \
+X( 6, RGXFW_GROUP_RPM, RGXFW_SF_RPM_REQUEST_HOST_GROW_DEPRECATED, "Request freelist grow [0x%08x] current pages %d, grow size %d", 3) \
+X( 7, RGXFW_GROUP_RPM, RGXFW_SF_RPM_FREELIST_LOAD_DEPRECATED, "Freelist load: SHF = 0x%08x, SHG = 0x%08x", 2) \
+X( 8, RGXFW_GROUP_RPM, RGXFW_SF_RPM_SHF_FPL_DEPRECATED, "SHF FPL register: 0x%08x.0x%08x", 2) \
+X( 9, RGXFW_GROUP_RPM, RGXFW_SF_RPM_SHG_FPL_DEPRECATED, "SHG FPL register: 0x%08x.0x%08x", 2) \
+X( 10, RGXFW_GROUP_RPM, RGXFW_SF_RPM_GROW_FREELIST_DEPRECATED, "Kernel requested RPM grow on freelist (type %d) at 0x%08x from current size %d to new size %d, RPM restart: %d (1=Yes)", 5) \
+X( 11, RGXFW_GROUP_RPM, RGXFW_SF_RPM_GROW_RESTART_DEPRECATED, "Restarting SHG", 0) \
+X( 12, RGXFW_GROUP_RPM, RGXFW_SF_RPM_GROW_ABORTED_DEPRECATED, "Grow failed, aborting the current frame.", 0) \
+X( 13, RGXFW_GROUP_RPM, RGXFW_SF_RPM_ABORT_COMPLETE_DEPRECATED, "RPM abort complete on HWFrameData [0x%08x].", 1) \
+X( 14, RGXFW_GROUP_RPM, RGXFW_SF_RPM_CLEANUP_NEEDS_ABORT_DEPRECATED, "RPM freelist cleanup [0x%08x] requires abort to proceed.", 1) \
+X( 15, RGXFW_GROUP_RPM, RGXFW_SF_RPM_RPM_PT_DEPRECATED, "RPM page table base register: 0x%08x.0x%08x", 2) \
+X( 16, RGXFW_GROUP_RPM, RGXFW_SF_RPM_OOM_ABORT_DEPRECATED, "Issuing RPM abort.", 0) \
+X( 17, RGXFW_GROUP_RPM, RGXFW_SF_RPM_OOM_TOGGLE_CHECK_FULL_DEPRECATED, "RPM OOM received but toggle bits indicate free pages available", 0) \
+X( 18, RGXFW_GROUP_RPM, RGXFW_SF_RPM_STATE_HW_TIMEOUT_DEPRECATED, "RPM hardware timeout. Unable to process OOM event.", 0) \
+X( 19, RGXFW_GROUP_RPM, RGXFW_SF_RPM_SHF_FPL_LOAD_DEPRECATED_DEPRECATED, "SHF FL (0x%08x) load, FPL: 0x%08x.0x%08x, roff: 0x%08x, woff: 0x%08x", 5) \
+X( 20, RGXFW_GROUP_RPM, RGXFW_SF_RPM_SHG_FPL_LOAD_DEPRECATED, "SHG FL (0x%08x) load, FPL: 0x%08x.0x%08x, roff: 0x%08x, woff: 0x%08x", 5) \
+X( 21, RGXFW_GROUP_RPM, RGXFW_SF_RPM_SHF_FPL_STORE_DEPRECATED, "SHF FL (0x%08x) store, roff: 0x%08x, woff: 0x%08x", 3) \
+X( 22, RGXFW_GROUP_RPM, RGXFW_SF_RPM_SHG_FPL_STORE_DEPRECATED, "SHG FL (0x%08x) store, roff: 0x%08x, woff: 0x%08x", 3) \
+\
+X( 1, RGXFW_GROUP_RTD, RGXFW_SF_RTD_3D_RTDATA_FINISHED, "3D RTData 0x%08x finished on HW context %u", 2) \
+X( 2, RGXFW_GROUP_RTD, RGXFW_SF_RTD_3D_RTDATA_READY, "3D RTData 0x%08x ready on HW context %u", 2) \
+X( 3, RGXFW_GROUP_RTD, RGXFW_SF_RTD_PB_SET_TO_DEPRECATED, "CONTEXT_PB_BASE set to 0x%x, FL different between TA/3D: local: %d, global: %d, mmu: %d", 4) \
+X( 4, RGXFW_GROUP_RTD, RGXFW_SF_RTD_LOADVFP_3D_DEPRECATED, "Loading VFP table 0x%08x%08x for 3D", 2) \
+X( 5, RGXFW_GROUP_RTD, RGXFW_SF_RTD_LOADVFP_TA_DEPRECATED, "Loading VFP table 0x%08x%08x for TA", 2) \
+X( 6, RGXFW_GROUP_RTD, RGXFW_SF_RTD_LOAD_FL_DEPRECATED, "Load Freelist 0x%x type: %d (0:local,1:global,2:mmu) for DM%d: TotalPMPages = %d, FL-addr = 0x%08x%08x, stacktop = 0x%08x%08x, Alloc Page Count = %u, Alloc MMU Page Count = %u", 10) \
+X( 7, RGXFW_GROUP_RTD, RGXFW_SF_RTD_VHEAP_STORE, "Perform VHEAP table store", 0) \
+X( 8, RGXFW_GROUP_RTD, RGXFW_SF_RTD_RTDATA_MATCH_FOUND, "RTData 0x%08x: found match in Context=%d: Load=No, Store=No", 2) \
+X( 9, RGXFW_GROUP_RTD, RGXFW_SF_RTD_RTDATA_NULL_FOUND, "RTData 0x%08x: found NULL in Context=%d: Load=Yes, Store=No", 2) \
+X( 10, RGXFW_GROUP_RTD, RGXFW_SF_RTD_RTDATA_3D_FINISHED, "RTData 0x%08x: found state 3D finished (0x%08x) in Context=%d: Load=Yes, Store=Yes", 3) \
+X( 11, RGXFW_GROUP_RTD, RGXFW_SF_RTD_RTDATA_TA_FINISHED, "RTData 0x%08x: found state TA finished (0x%08x) in Context=%d: Load=Yes, Store=Yes", 3) \
+X( 12, RGXFW_GROUP_RTD, RGXFW_SF_RTD_LOAD_STACK_POINTERS, "Loading stack-pointers for %d (0:MidTA,1:3D) on context %d, MLIST = 0x%08x, ALIST = 0x%08x%08x", 5) \
+X( 13, RGXFW_GROUP_RTD, RGXFW_SF_RTD_STORE_PB_DEPRECATED, "Store Freelist 0x%x type: %d (0:local,1:global,2:mmu) for DM%d: TotalPMPages = %d, FL-addr = 0x%08x%08x, stacktop = 0x%08x%08x, Alloc Page Count = %u, Alloc MMU Page Count = %u", 10) \
+X( 14, RGXFW_GROUP_RTD, RGXFW_SF_RTD_TA_RTDATA_FINISHED, "TA RTData 0x%08x finished on HW context %u", 2) \
+X( 15, RGXFW_GROUP_RTD, RGXFW_SF_RTD_TA_RTDATA_LOADED, "TA RTData 0x%08x loaded on HW context %u", 2) \
+X( 16, RGXFW_GROUP_RTD, RGXFW_SF_RTD_STORE_PB_DEPRECATED2, "Store Freelist 0x%x type: %d (0:local,1:global,2:mmu) for DM%d: FL Total Pages %u (max=%u,grow size=%u), FL-addr = 0x%08x%08x, stacktop = 0x%08x%08x, Alloc Page Count = %u, Alloc MMU Page Count = %u", 12) \
+X( 17, RGXFW_GROUP_RTD, RGXFW_SF_RTD_LOAD_FL_DEPRECATED2, "Load Freelist 0x%x type: %d (0:local,1:global,2:mmu) for DM%d: FL Total Pages %u (max=%u,grow size=%u), FL-addr = 0x%08x%08x, stacktop = 0x%08x%08x, Alloc Page Count = %u, Alloc MMU Page Count = %u", 12) \
+X( 18, RGXFW_GROUP_RTD, RGXFW_SF_RTD_DEBUG_DEPRECATED, "Freelist 0x%x RESET!!!!!!!!", 1) \
+X( 19, RGXFW_GROUP_RTD, RGXFW_SF_RTD_DEBUG2_DEPRECATED, "Freelist 0x%x stacktop = 0x%08x%08x, Alloc Page Count = %u, Alloc MMU Page Count = %u", 5) \
+X( 20, RGXFW_GROUP_RTD, RGXFW_SF_RTD_FL_RECON_DEPRECATED, "Request reconstruction of Freelist 0x%x type: %d (0:local,1:global,2:mmu) on HW context %u", 3) \
+X( 21, RGXFW_GROUP_RTD, RGXFW_SF_RTD_FL_RECON_ACK_DEPRECATED, "Freelist reconstruction ACK from host (HWR state :%u)", 1) \
+X( 22, RGXFW_GROUP_RTD, RGXFW_SF_RTD_FL_RECON_ACK_DEPRECATED2, "Freelist reconstruction completed", 0) \
+X( 23, RGXFW_GROUP_RTD, RGXFW_SF_RTD_TA_RTDATA_LOADED_DEPRECATED, "TA RTData 0x%08x loaded on HW context %u HWRTDataNeedsLoading=%d", 3) \
+X( 24, RGXFW_GROUP_RTD, RGXFW_SF_RTD_TE_RGNHDR_INFO, "TE Region headers base 0x%08x%08x (RGNHDR Init: %d)", 3) \
+X( 25, RGXFW_GROUP_RTD, RGXFW_SF_RTD_TA_RTDATA_BUFFER_ADDRS_DEPRECATED, "TA Buffers: FWCtx 0x%08x, RT 0x%08x, RTData 0x%08x, VHeap 0x%08x%08x, TPC 0x%08x%08x (MemCtx 0x%08x)", 8) \
+X( 26, RGXFW_GROUP_RTD, RGXFW_SF_RTD_3D_RTDATA_LOADED_DEPRECATED, "3D RTData 0x%08x loaded on HW context %u", 2) \
+X( 27, RGXFW_GROUP_RTD, RGXFW_SF_RTD_3D_RTDATA_BUFFER_ADDRS_DEPRECATED, "3D Buffers: FWCtx 0x%08x, RT 0x%08x, RTData 0x%08x (MemCtx 0x%08x)", 4) \
+X( 28, RGXFW_GROUP_RTD, RGXFW_SF_RTD_TA_RESTART_AFTER_PR_EXECUTED, "Restarting TA after partial render, HWRTData0State=0x%x, HWRTData1State=0x%x", 2) \
+X( 29, RGXFW_GROUP_RTD, RGXFW_SF_RTD_PB_SET_TO, "CONTEXT_PB_BASE set to 0x%x, FL different between TA/3D: local: %d, global: %d", 3) \
+X( 30, RGXFW_GROUP_RTD, RGXFW_SF_RTD_STORE_FL, "Store Freelist 0x%x type: %d (0:local,1:global) for PMDM%d: FL Total Pages %u (max=%u,grow size=%u), FL-addr = 0x%08x%08x, stacktop = 0x%08x%08x, Alloc Page Count = %u, Alloc MMU Page Count = %u", 12) \
+X( 31, RGXFW_GROUP_RTD, RGXFW_SF_RTD_LOAD_FL, "Load Freelist 0x%x type: %d (0:local,1:global) for PMDM%d: FL Total Pages %u (max=%u,grow size=%u), FL-addr = 0x%08x%08x, stacktop = 0x%08x%08x, Alloc Page Count = %u, Alloc MMU Page Count = %u", 12) \
+X( 32, RGXFW_GROUP_RTD, RGXFW_SF_RTD_3D_RTDATA_BUFFER_ADDRS_DEPRECATED2, "3D Buffers: FWCtx 0x%08x, parent RT 0x%08x, RTData 0x%08x on ctx %d, (MemCtx 0x%08x)", 5) \
+X( 33, RGXFW_GROUP_RTD, RGXFW_SF_RTD_TA_RTDATA_BUFFER_ADDRS, "TA Buffers: FWCtx 0x%08x, RTData 0x%08x, VHeap 0x%08x%08x, TPC 0x%08x%08x (MemCtx 0x%08x)", 7) \
+X( 34, RGXFW_GROUP_RTD, RGXFW_SF_RTD_3D_RTDATA_BUFFER_ADDRS, "3D Buffers: FWCtx 0x%08x, RTData 0x%08x on ctx %d, (MemCtx 0x%08x)", 4) \
+X( 35, RGXFW_GROUP_RTD, RGXFW_SF_RTD_LOAD_FL_V2, "Load Freelist 0x%x type: %d (0:local,1:global) for PMDM%d: FL Total Pages %u (max=%u,grow size=%u)", 6) \
+X( 36, RGXFW_GROUP_RTD, RGXFW_SF_RTD_KILLED_TA, "TA RTData 0x%08x marked as killed.", 1) \
+X( 37, RGXFW_GROUP_RTD, RGXFW_SF_RTD_KILLED_3D, "3D RTData 0x%08x marked as killed.", 1) \
+X( 38, RGXFW_GROUP_RTD, RGXFW_SF_RTD_KILL_TA_AFTER_RESTART, "RTData 0x%08x will be killed after TA restart.", 1) \
+X( 39, RGXFW_GROUP_RTD, RGXFW_SF_RTD_RENDERSTATE_RESET, "RTData 0x%08x Render State Buffer 0x%02x%08x will be reset.", 3) \
+X( 40, RGXFW_GROUP_RTD, RGXFW_SF_RTD_GEOM_RENDERSTATE, "GEOM RTData 0x%08x using Render State Buffer 0x%02x%08x.", 3) \
+X( 41, RGXFW_GROUP_RTD, RGXFW_SF_RTD_FRAG_RENDERSTATE, "FRAG RTData 0x%08x using Render State Buffer 0x%02x%08x.", 3) \
+\
+X( 1, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZLOAD_DEPRECATED, "Force Z-Load for partial render", 0) \
+X( 2, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSTORE_DEPRECATED, "Force Z-Store for partial render", 0) \
+X( 3, RGXFW_GROUP_SPM, RGXFW_SF_SPM_3DMEMFREE_LOCAL_DEPRECATED, "3D MemFree: Local FL 0x%08x", 1) \
+X( 4, RGXFW_GROUP_SPM, RGXFW_SF_SPM_3DMEMFREE_MMU_DEPRECATED, "3D MemFree: MMU FL 0x%08x", 1) \
+X( 5, RGXFW_GROUP_SPM, RGXFW_SF_SPM_3DMEMFREE_GLOBAL_DEPRECATED, "3D MemFree: Global FL 0x%08x", 1) \
+X( 6, RGXFW_GROUP_SPM, RGXFW_SF_SPM_OOM_TACMD_DEPRECATED, "OOM TA/3D PR Check: [0x%08.8x] is 0x%08.8x requires 0x%08.8x, HardwareSync Fence [0x%08.8x] is 0x%08.8x requires 0x%08.8x", 6) \
+X( 7, RGXFW_GROUP_SPM, RGXFW_SF_SPM_OOM_TACMD_UN_FL, "OOM TA_cmd=0x%08x, U-FL 0x%08x, N-FL 0x%08x", 3) \
+X( 8, RGXFW_GROUP_SPM, RGXFW_SF_SPM_OOM_TACMD_UN_MMU_FL_DEPRECATED, "OOM TA_cmd=0x%08x, OOM MMU:%d, U-FL 0x%08x, N-FL 0x%08x, MMU-FL 0x%08x", 5) \
+X( 9, RGXFW_GROUP_SPM, RGXFW_SF_SPM_PRENDER_AVOIDED_DEPRECATED, "Partial render avoided", 0) \
+X( 10, RGXFW_GROUP_SPM, RGXFW_SF_SPM_PRENDER_DISCARDED_DEPRECATED, "Partial render discarded", 0) \
+X( 11, RGXFW_GROUP_SPM, RGXFW_SF_SPM_PRENDER_FINISHED, "Partial Render finished", 0) \
+X( 12, RGXFW_GROUP_SPM, RGXFW_SF_SPM_OWNER_3DBG_DEPRECATED, "SPM Owner = 3D-BG", 0) \
+X( 13, RGXFW_GROUP_SPM, RGXFW_SF_SPM_OWNER_3DIRQ_DEPRECATED, "SPM Owner = 3D-IRQ", 0) \
+X( 14, RGXFW_GROUP_SPM, RGXFW_SF_SPM_OWNER_NONE_DEPRECATED, "SPM Owner = NONE", 0) \
+X( 15, RGXFW_GROUP_SPM, RGXFW_SF_SPM_OWNER_TABG_DEPRECATED, "SPM Owner = TA-BG", 0) \
+X( 16, RGXFW_GROUP_SPM, RGXFW_SF_SPM_OWNER_TAIRQ_DEPRECATED, "SPM Owner = TA-IRQ", 0) \
+X( 17, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSTORE_ADDRESS, "ZStore address 0x%08x%08x", 2) \
+X( 18, RGXFW_GROUP_SPM, RGXFW_SF_SPM_SSTORE_ADDRESS, "SStore address 0x%08x%08x", 2) \
+X( 19, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZLOAD_ADDRESS, "ZLoad address 0x%08x%08x", 2) \
+X( 20, RGXFW_GROUP_SPM, RGXFW_SF_SPM_SLOAD_ADDRESS, "SLoad address 0x%08x%08x", 2) \
+X( 21, RGXFW_GROUP_SPM, RGXFW_SF_SPM_NO_DEFERRED_ZSBUFFER_DEPRECATED, "No deferred ZS Buffer provided", 0) \
+X( 22, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSBUFFER_POPULATED, "ZS Buffer successfully populated (ID=0x%08x)", 1) \
+X( 23, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSBUFFER_POP_UNNEEDED_DEPRECATED, "No need to populate ZS Buffer (ID=0x%08x)", 1) \
+X( 24, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSBUFFER_UNPOPULATED, "ZS Buffer successfully unpopulated (ID=0x%08x)", 1) \
+X( 25, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSBUFFER_UNPOP_UNNEEDED_DEPRECATED, "No need to unpopulate ZS Buffer (ID=0x%08x)", 1) \
+X( 26, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSBUFFER_BACKING_REQUEST_DEPRECATED, "Send ZS-Buffer backing request to host (ID=0x%08x)", 1) \
+X( 27, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSBUFFER_UNBACKING_REQUEST_DEPRECATED, "Send ZS-Buffer unbacking request to host (ID=0x%08x)", 1) \
+X( 28, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSBUFFER_BACKING_REQUEST_PENDING_DEPRECATED, "Don't send ZS-Buffer backing request. Previous request still pending (ID=0x%08x)", 1) \
+X( 29, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSBUFFER_UNBACKING_REQUEST_PENDING_DEPRECATED, "Don't send ZS-Buffer unbacking request. Previous request still pending (ID=0x%08x)", 1) \
+X( 30, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZBUFFER_NOT_READY_DEPRECATED, "Partial Render waiting for ZBuffer to be backed (ID=0x%08x)", 1) \
+X( 31, RGXFW_GROUP_SPM, RGXFW_SF_SPM_SBUFFER_NOT_READY_DEPRECATED, "Partial Render waiting for SBuffer to be backed (ID=0x%08x)", 1) \
+X( 32, RGXFW_GROUP_SPM, RGXFW_SF_SPM_STATE_NONE, "SPM State = none", 0) \
+X( 33, RGXFW_GROUP_SPM, RGXFW_SF_SPM_STATE_PR_BLOCKED, "SPM State = PR blocked", 0) \
+X( 34, RGXFW_GROUP_SPM, RGXFW_SF_SPM_STATE_WAIT_FOR_GROW, "SPM State = wait for grow", 0) \
+X( 35, RGXFW_GROUP_SPM, RGXFW_SF_SPM_STATE_WAIT_FOR_HW, "SPM State = wait for HW", 0) \
+X( 36, RGXFW_GROUP_SPM, RGXFW_SF_SPM_STATE_PR_RUNNING, "SPM State = PR running", 0) \
+X( 37, RGXFW_GROUP_SPM, RGXFW_SF_SPM_STATE_PR_AVOIDED, "SPM State = PR avoided", 0) \
+X( 38, RGXFW_GROUP_SPM, RGXFW_SF_SPM_STATE_PR_EXECUTED, "SPM State = PR executed", 0) \
+X( 39, RGXFW_GROUP_SPM, RGXFW_SF_SPM_FREELIST_MATCH, "3DMemFree matches freelist 0x%08x (FL type = %u)", 2) \
+X( 40, RGXFW_GROUP_SPM, RGXFW_SF_SPM_3DMEMFREE_FLAG_SET, "Raise the 3DMemFreeDedected flag", 0) \
+X( 41, RGXFW_GROUP_SPM, RGXFW_SF_SPM_STATE_WAIT_FOR_PENDING_GROW, "Wait for pending grow on Freelist 0x%08x", 1) \
+X( 42, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ZSBUFFER_BACKING_REQUEST_FAILED, "ZS Buffer failed to be populated (ID=0x%08x)", 1) \
+X( 43, RGXFW_GROUP_SPM, RGXFW_SF_SPM_FL_GROW_DEBUG, "Grow update inconsistency: FL addr: 0x%02x%08x, curr pages: %u, ready: %u, new: %u", 5) \
+X( 44, RGXFW_GROUP_SPM, RGXFW_SF_SPM_RESUMED_TA_WITH_SP, "OOM: Resumed TA with ready pages, FL addr: 0x%02x%08x, current pages: %u, SP : %u", 4) \
+X( 45, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ACK_GROW_UPDATE_DEPRECATED, "Received grow update, FL addr: 0x%02x%08x, current pages: %u, ready pages: %u, threshold: %u", 5) \
+X( 46, RGXFW_GROUP_SPM, RGXFW_SF_SPM_NO_DEFERRED_PRBUFFER, "No deferred partial render FW (Type=%d) Buffer provided", 1) \
+X( 47, RGXFW_GROUP_SPM, RGXFW_SF_SPM_BUFFER_POP_UNNEEDED, "No need to populate PR Buffer (ID=0x%08x)", 1) \
+X( 48, RGXFW_GROUP_SPM, RGXFW_SF_SPM_BUFFER_UNPOP_UNNEEDED, "No need to unpopulate PR Buffer (ID=0x%08x)", 1) \
+X( 49, RGXFW_GROUP_SPM, RGXFW_SF_SPM_BUFFER_BACKING_REQUEST, "Send PR Buffer backing request to host (ID=0x%08x)", 1) \
+X( 50, RGXFW_GROUP_SPM, RGXFW_SF_SPM_BUFFER_UNBACKING_REQUEST, "Send PR Buffer unbacking request to host (ID=0x%08x)", 1) \
+X( 51, RGXFW_GROUP_SPM, RGXFW_SF_SPM_BUFFER_BACKING_REQUEST_PENDING, "Don't send PR Buffer backing request. Previous request still pending (ID=0x%08x)", 1) \
+X( 52, RGXFW_GROUP_SPM, RGXFW_SF_SPM_BUFFER_UNBACKING_REQUEST_PENDING, "Don't send PR Buffer unbacking request. Previous request still pending (ID=0x%08x)", 1) \
+X( 53, RGXFW_GROUP_SPM, RGXFW_SF_SPM_BUFFER_NOT_READY, "Partial Render waiting for Buffer %d type to be backed (ID=0x%08x)", 2) \
+X( 54, RGXFW_GROUP_SPM, RGXFW_SF_SPM_ACK_GROW_UPDATE, "Received grow update, FL addr: 0x%02x%08x, new pages: %u, ready pages: %u", 4) \
+X( 66, RGXFW_GROUP_SPM, RGXFW_SF_SPM_OOM_TACMD, "OOM TA/3D PR Check: [0x%08.8x] is 0x%08.8x requires 0x%08.8x", 3) \
+X( 67, RGXFW_GROUP_SPM, RGXFW_SF_SPM_RESUMED_TA, "OOM: Resumed TA with ready pages, FL addr: 0x%02x%08x, current pages: %u", 3) \
+X( 68, RGXFW_GROUP_SPM, RGXFW_SF_SPM_PR_DEADLOCK_UNBLOCKED, "OOM TA/3D PR deadlock unblocked reordering DM%d runlist head from Context 0x%08x to 0x%08x", 3) \
+\
+X( 1, RGXFW_GROUP_POW, RGXFW_SF_POW_CHECK_DEPRECATED, "Check Pow state DM%d int: 0x%x, ext: 0x%x, pow flags: 0x%x", 4) \
+X( 2, RGXFW_GROUP_POW, RGXFW_SF_POW_GPU_IDLE, "GPU idle (might be powered down). Pow state int: 0x%x, ext: 0x%x, flags: 0x%x", 3) \
+X( 3, RGXFW_GROUP_POW, RGXFW_SF_POW_OSREQ_DEPRECATED, "OS requested pow off (forced = %d), DM%d, pow flags: 0x%x", 3) \
+X( 4, RGXFW_GROUP_POW, RGXFW_SF_POW_INIOFF_DEPRECATED, "Initiate powoff query. Inactive DMs: %d %d %d %d", 4) \
+X( 5, RGXFW_GROUP_POW, RGXFW_SF_POW_CHECKOFF_DEPRECATED, "Any RD-DM pending? %d, Any RD-DM Active? %d", 2) \
+X( 6, RGXFW_GROUP_POW, RGXFW_SF_POW_GPU_OFF, "GPU ready to be powered down. Pow state int: 0x%x, ext: 0x%x, flags: 0x%x", 3) \
+X( 7, RGXFW_GROUP_POW, RGXFW_SF_POW_HWREQ, "HW Request On(1)/Off(0): %d, Units: 0x%08.8x", 2) \
+X( 8, RGXFW_GROUP_POW, RGXFW_SF_POW_DUSTS_CHANGE_REQ, "Request to change num of dusts to %d (Power flags=%d)", 2) \
+X( 9, RGXFW_GROUP_POW, RGXFW_SF_POW_DUSTS_CHANGE, "Changing number of dusts from %d to %d", 2) \
+X( 11, RGXFW_GROUP_POW, RGXFW_SF_POW_SIDEKICK_INIT_DEPRECATED, "Sidekick init", 0) \
+X( 12, RGXFW_GROUP_POW, RGXFW_SF_POW_RD_INIT_DEPRECATED, "Rascal+Dusts init (# dusts mask: 0x%x)", 1) \
+X( 13, RGXFW_GROUP_POW, RGXFW_SF_POW_INIOFF_RD, "Initiate powoff query for RD-DMs.", 0) \
+X( 14, RGXFW_GROUP_POW, RGXFW_SF_POW_INIOFF_TLA, "Initiate powoff query for TLA-DM.", 0) \
+X( 15, RGXFW_GROUP_POW, RGXFW_SF_POW_REQUESTEDOFF_RD, "Any RD-DM pending? %d, Any RD-DM Active? %d", 2) \
+X( 16, RGXFW_GROUP_POW, RGXFW_SF_POW_REQUESTEDOFF_TLA, "TLA-DM pending? %d, TLA-DM Active? %d", 2) \
+X( 17, RGXFW_GROUP_POW, RGXFW_SF_POW_BRN37270_DEPRECATED, "Request power up due to BRN37270. Pow stat int: 0x%x", 1) \
+X( 18, RGXFW_GROUP_POW, RGXFW_SF_POW_REQ_CANCEL, "Cancel power off request int: 0x%x, ext: 0x%x, pow flags: 0x%x", 3) \
+X( 19, RGXFW_GROUP_POW, RGXFW_SF_POW_FORCED_IDLE, "OS requested forced IDLE, pow flags: 0x%x", 1) \
+X( 20, RGXFW_GROUP_POW, RGXFW_SF_POW_CANCEL_FORCED_IDLE, "OS cancelled forced IDLE, pow flags: 0x%x", 1) \
+X( 21, RGXFW_GROUP_POW, RGXFW_SF_POW_IDLE_TIMER, "Idle timer start. Pow state int: 0x%x, ext: 0x%x, flags: 0x%x", 3) \
+X( 22, RGXFW_GROUP_POW, RGXFW_SF_POW_CANCEL_IDLE_TIMER, "Cancel idle timer. Pow state int: 0x%x, ext: 0x%x, flags: 0x%x", 3) \
+X( 23, RGXFW_GROUP_POW, RGXFW_SF_POW_APM_LATENCY_CHANGE, "Active PM latency set to %dms. Core clock: %d Hz", 2) \
+X( 24, RGXFW_GROUP_POW, RGXFW_SF_POW_CDM_CLUSTERS, "Compute cluster mask change to 0x%x, %d dusts powered.", 2) \
+X( 25, RGXFW_GROUP_POW, RGXFW_SF_POW_NULL_CMD_INIOFF_RD, "Null command executed, repeating initiate powoff query for RD-DMs.", 0) \
+X( 26, RGXFW_GROUP_POW, RGXFW_SF_POW_POWMON_ENERGY, "Power monitor: Estimate of dynamic energy %u", 1) \
+X( 27, RGXFW_GROUP_POW, RGXFW_SF_POW_CHECK_DEPRECATED2, "Check Pow state: Int: 0x%x, Ext: 0x%x, Pow flags: 0x%x", 3) \
+X( 28, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_NEW_DEADLINE, "Proactive DVFS: New deadline, time = 0x%08x%08x", 2) \
+X( 29, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_NEW_WORKLOAD, "Proactive DVFS: New workload, cycles = 0x%08x%08x", 2) \
+X( 30, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_CALCULATE, "Proactive DVFS: Proactive frequency calculated = %u", 1) \
+X( 31, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_UTILISATION, "Proactive DVFS: Reactive utilisation = %u percent", 1) \
+X( 32, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_REACT, "Proactive DVFS: Reactive frequency calculated = %u.%u", 2) \
+X( 33, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_GPIO_SEND_DEPRECATED, "Proactive DVFS: OPP Point Sent = 0x%x", 1) \
+X( 34, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_DEADLINE_REMOVED, "Proactive DVFS: Deadline removed = 0x%08x%08x", 2) \
+X( 35, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_WORKLOAD_REMOVED, "Proactive DVFS: Workload removed = 0x%08x%08x", 2) \
+X( 36, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_THROTTLE, "Proactive DVFS: Throttle to a maximum = 0x%x", 1) \
+X( 37, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_GPIO_FAILURE, "Proactive DVFS: Failed to pass OPP point via GPIO.", 0) \
+X( 38, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_INVALID_NODE_DEPRECATED, "Proactive DVFS: Invalid node passed to function.", 0) \
+X( 39, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_GUEST_BAD_ACCESS_DEPRECATED, "Proactive DVFS: Guest OS attempted to do a privileged action. OSid = %u", 1) \
+X( 40, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_UNPROFILED_STARTED, "Proactive DVFS: Unprofiled work started. Total unprofiled work present: %u", 1) \
+X( 41, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_UNPROFILED_FINISHED, "Proactive DVFS: Unprofiled work finished. Total unprofiled work present: %u", 1) \
+X( 42, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_DISABLED, "Proactive DVFS: Disabled: Not enabled by host.", 0) \
+X( 43, RGXFW_GROUP_POW, RGXFW_SF_POW_HWREQ_RESULT, "HW Request Completed(1)/Aborted(0): %d, Ticks: %d", 2) \
+X( 44, RGXFW_GROUP_POW, RGXFW_SF_POW_DUSTS_CHANGE_FIX_59042_DEPRECATED, "Allowed number of dusts is %d due to BRN59042.", 1) \
+X( 45, RGXFW_GROUP_POW, RGXFW_SF_POW_HOST_TIMEOUT_NOTIFICATION, "Host timed out while waiting for a forced idle state. Pow state int: 0x%x, ext: 0x%x, flags: 0x%x", 3) \
+X( 46, RGXFW_GROUP_POW, RGXFW_SF_POW_CHECK, "Check Pow state: Int: 0x%x, Ext: 0x%x, Pow flags: 0x%x, Fence Counters: Check: %u - Update: %u", 5) \
+X( 47, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_GPIO_SEND, "Proactive DVFS: OPP Point Sent = 0x%x, Success = 0x%x", 2) \
+X( 48, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_TO_IDLE, "Proactive DVFS: GPU transitioned to idle", 0) \
+X( 49, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_TO_ACTIVE, "Proactive DVFS: GPU transitioned to active", 0) \
+X( 50, RGXFW_GROUP_POW, RGXFW_SF_POW_POWDUMP_BUFFER_SIZE, "Power counter dumping: Data truncated writing register %u. Buffer too small.", 1) \
+X( 51, RGXFW_GROUP_POW, RGXFW_SF_POW_POWCTRL_ABORT, "Power controller returned ABORT for last request so retrying.", 0) \
+X( 52, RGXFW_GROUP_POW, RGXFW_SF_POW_INVALID_POWER_REQUEST_DEPRECATED, "Discarding invalid power request: type 0x%x, DM %u", 2) \
+X( 53, RGXFW_GROUP_POW, RGXFW_SF_POW_CANCEL_FORCED_IDLE_NOT_IDLE, "Detected attempt to cancel forced idle while not forced idle (pow state 0x%x, pow flags 0x%x)", 2) \
+X( 54, RGXFW_GROUP_POW, RGXFW_SF_POW_FORCED_POW_OFF_NOT_IDLE, "Detected attempt to force power off while not forced idle (pow state 0x%x, pow flags 0x%x)", 2) \
+X( 55, RGXFW_GROUP_POW, RGXFW_SF_POW_NUMDUST_CHANGE_NOT_IDLE, "Detected attempt to change dust count while not forced idle (pow state 0x%x)", 1) \
+X( 56, RGXFW_GROUP_POW, RGXFW_SF_POW_POWMON_RESULT, "Power monitor: Type = %d (0 = power, 1 = energy), Estimate result = 0x%08x%08x", 3) \
+X( 57, RGXFW_GROUP_POW, RGXFW_SF_POW_MINMAX_CONFLICT, "Conflicting clock frequency range: OPP min = %u, max = %u", 2) \
+X( 58, RGXFW_GROUP_POW, RGXFW_SF_POW_PDVFS_FLOOR, "Proactive DVFS: Set floor to a minimum = 0x%x", 1) \
+X( 59, RGXFW_GROUP_POW, RGXFW_SF_POW_OSREQ, "OS requested pow off (forced = %d), pow flags: 0x%x", 2) \
+X( 60, RGXFW_GROUP_POW, RGXFW_SF_POW_INVALID_POWER_REQUEST, "Discarding invalid power request: type 0x%x", 1) \
+X( 61, RGXFW_GROUP_POW, RGXFW_SF_POW_SPU_POW_STATE_CHANGE_REQ, "Request to change SPU power state mask from 0x%x to 0x%x. Pow flags: 0x%x", 3) \
+X( 62, RGXFW_GROUP_POW, RGXFW_SF_POW_SPU_POW_STATE_CHANGE, "Changing SPU power state mask from 0x%x to 0x%x", 2) \
+X( 63, RGXFW_GROUP_POW, RGXFW_SF_POW_SPU_POW_CHANGE_NOT_IDLE, "Detected attempt to change SPU power state mask while not forced idle (pow state 0x%x)", 1) \
+X( 64, RGXFW_GROUP_POW, RGXFW_SF_POW_INVALID_SPU_POWER_MASK, "Invalid SPU power mask 0x%x! Changing to 1", 1) \
+X( 65, RGXFW_GROUP_POW, RGXFW_SF_POW_CLKDIV_UPDATE, "Proactive DVFS: Send OPP %u with clock divider value %u", 2) \
+X( 66, RGXFW_GROUP_POW, RGXFW_SF_POW_POWMON_PERF_MODE, "PPA block started in perf validation mode.", 0) \
+X( 67, RGXFW_GROUP_POW, RGXFW_SF_POW_POWMON_RESET, "Reset PPA block state %u (1=reset, 0=recalculate).", 1) \
+X( 68, RGXFW_GROUP_POW, RGXFW_SF_POW_POWCTRL_ABORT_WITH_CORE, "Power controller returned ABORT for Core-%d last request so retrying.", 1) \
+X( 69, RGXFW_GROUP_POW, RGXFW_SF_POW_HWREQ64BIT, "HW Request On(1)/Off(0): %d, Units: 0x%08x%08x", 3) \
+\
+X( 1, RGXFW_GROUP_HWR, RGXFW_SF_HWR_LOCKUP_DEPRECATED, "Lockup detected on DM%d, FWCtx: 0x%08.8x", 2) \
+X( 2, RGXFW_GROUP_HWR, RGXFW_SF_HWR_RESET_FW_DEPRECATED, "Reset fw state for DM%d, FWCtx: 0x%08.8x, MemCtx: 0x%08.8x", 3) \
+X( 3, RGXFW_GROUP_HWR, RGXFW_SF_HWR_RESET_HW_DEPRECATED, "Reset HW", 0) \
+X( 4, RGXFW_GROUP_HWR, RGXFW_SF_HWR_TERMINATED_DEPRECATED, "Lockup recovered.", 0) \
+X( 5, RGXFW_GROUP_HWR, RGXFW_SF_HWR_SET_LOCKUP_DEPRECATED, "Lock-up DM%d FWCtx: 0x%08.8x", 2) \
+X( 6, RGXFW_GROUP_HWR, RGXFW_SF_HWR_LOCKUP_DETECTED_DEPRECATED, "Lockup detected: GLB(%d->%d), PER-DM(0x%08x->0x%08x)", 4) \
+X( 7, RGXFW_GROUP_HWR, RGXFW_SF_HWR_EARLY_FAULT_DETECTION_DEPRECATED, "Early fault detection: GLB(%d->%d), PER-DM(0x%08x)", 3) \
+X( 8, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HOLD_SCHEDULING_DUE_TO_LOCKUP_DEPRECATED, "Hold scheduling due lockup: GLB(%d), PER-DM(0x%08x->0x%08x)", 3) \
+X( 9, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FALSE_LOCKUP_DEPRECATED, "False lockup detected: GLB(%d->%d), PER-DM(0x%08x->0x%08x)", 4) \
+X( 10, RGXFW_GROUP_HWR, RGXFW_SF_HWR_BRN37729_DEPRECATED, "BRN37729: GLB(%d->%d), PER-DM(0x%08x->0x%08x)", 4) \
+X( 11, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FREELISTS_RECONSTRUCTED_DEPRECATED, "Freelists reconstructed: GLB(%d->%d), PER-DM(0x%08x)", 3) \
+X( 12, RGXFW_GROUP_HWR, RGXFW_SF_HWR_RECONSTRUCTING_FREELISTS_DEPRECATED, "Reconstructing freelists: %u (0-No, 1-Yes): GLB(%d->%d), PER-DM(0x%08x)", 4) \
+X( 13, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FAILED_HW_POLL, "HW poll %u (0-Unset 1-Set) failed (reg:0x%08x val:0x%08x)", 3) \
+X( 14, RGXFW_GROUP_HWR, RGXFW_SF_HWR_DM_DISCARDED_DEPRECATED, "Discarded cmd on DM%u FWCtx=0x%08x", 2) \
+X( 15, RGXFW_GROUP_HWR, RGXFW_SF_HWR_DM_DISCARDED, "Discarded cmd on DM%u (reason=%u) HWRTData=0x%08x (st: %d), FWCtx 0x%08x @ %d", 6) \
+X( 16, RGXFW_GROUP_HWR, RGXFW_SF_HWR_PM_FENCE_DEPRECATED, "PM fence WA could not be applied, Valid TA Setup: %d, RD powered off: %d", 2) \
+X( 17, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_SNAPSHOT, "FL snapshot RTD 0x%08.8x - local (0x%08.8x): %d, global (0x%08.8x): %d", 5) \
+X( 18, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_CHECK, "FL check RTD 0x%08.8x, discard: %d - local (0x%08.8x): s%d?=c%d, global (0x%08.8x): s%d?=c%d", 8) \
+X( 19, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_RECON_DEPRECATED, "FL reconstruction 0x%08.8x c%d", 2) \
+X( 20, RGXFW_GROUP_HWR, RGXFW_SF_HWR_3D_CHECK, "3D check: missing TA FWCtx 0x%08.8x @ %d, RTD 0x%08x.", 3) \
+X( 21, RGXFW_GROUP_HWR, RGXFW_SF_HWR_RESET_HW_DEPRECATED2, "Reset HW (mmu:%d, extmem: %d)", 2) \
+X( 22, RGXFW_GROUP_HWR, RGXFW_SF_HWR_ZERO_TA_CACHES, "Zero TA caches for FWCtx: 0x%08.8x (TPC addr: 0x%08x%08x, size: %d bytes)", 4) \
+X( 23, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FREELISTS_RECONSTRUCTED_DEPRECATED2, "Recovery DM%u: Freelists reconstructed. New R-Flags=0x%08x", 2) \
+X( 24, RGXFW_GROUP_HWR, RGXFW_SF_HWR_SKIPPED_CMD, "Recovery DM%u: FWCtx 0x%08x skipped to command @ %u. PR=%u. New R-Flags=0x%08x", 5) \
+X( 25, RGXFW_GROUP_HWR, RGXFW_SF_HWR_DM_RECOVERED, "Recovery DM%u: DM fully recovered", 1) \
+X( 26, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HOLD_SCHEDULING_DUE_TO_LOCKUP, "DM%u: Hold scheduling due to R-Flag = 0x%08x", 2) \
+X( 27, RGXFW_GROUP_HWR, RGXFW_SF_HWR_NEEDS_RECONSTRUCTION, "Analysis: Need freelist reconstruction", 0) \
+X( 28, RGXFW_GROUP_HWR, RGXFW_SF_HWR_NEEDS_SKIP, "Analysis DM%u: Lockup FWCtx: 0x%08.8x. Need to skip to next command", 2) \
+X( 29, RGXFW_GROUP_HWR, RGXFW_SF_HWR_NEEDS_SKIP_OOM_TA, "Analysis DM%u: Lockup while TA is OOM FWCtx: 0x%08.8x. Need to skip to next command", 2) \
+X( 30, RGXFW_GROUP_HWR, RGXFW_SF_HWR_NEEDS_PR_CLEANUP, "Analysis DM%u: Lockup while partial render FWCtx: 0x%08.8x. Need PR cleanup", 2) \
+X( 31, RGXFW_GROUP_HWR, RGXFW_SF_HWR_SET_LOCKUP_DEPRECATED2, "GPU has locked up", 0) \
+X( 32, RGXFW_GROUP_HWR, RGXFW_SF_HWR_READY, "DM%u ready for HWR", 1) \
+X( 33, RGXFW_GROUP_HWR, RGXFW_SF_HWR_DM_UPDATE_RECOVERY, "Recovery DM%u: Updated Recovery counter. New R-Flags=0x%08x", 2) \
+X( 34, RGXFW_GROUP_HWR, RGXFW_SF_HWR_BRN37729_DEPRECATED2, "Analysis: BRN37729 detected, reset TA and re-kicked 0x%08x)", 1) \
+X( 35, RGXFW_GROUP_HWR, RGXFW_SF_HWR_DM_TIMED_OUT, "DM%u timed out", 1) \
+X( 36, RGXFW_GROUP_HWR, RGXFW_SF_HWR_EVENT_STATUS_REG, "RGX_CR_EVENT_STATUS=0x%08x", 1) \
+X( 37, RGXFW_GROUP_HWR, RGXFW_SF_HWR_DM_FALSE_LOCKUP, "DM%u lockup falsely detected, R-Flags=0x%08x", 2) \
+X( 38, RGXFW_GROUP_HWR, RGXFW_SF_HWR_SET_OUTOFTIME, "GPU has overrun its deadline", 0) \
+X( 39, RGXFW_GROUP_HWR, RGXFW_SF_HWR_SET_POLLFAILURE, "GPU has failed a poll", 0) \
+X( 40, RGXFW_GROUP_HWR, RGXFW_SF_HWR_PERF_PHASE_REG, "RGX DM%u phase count=0x%08x", 2) \
+X( 41, RGXFW_GROUP_HWR, RGXFW_SF_HWR_RESET_HW_DEPRECATED3, "Reset HW (loop:%d, poll failures: 0x%08x)", 2) \
+X( 42, RGXFW_GROUP_HWR, RGXFW_SF_HWR_MMU_FAULT_EVENT, "MMU fault event: 0x%08x", 1) \
+X( 43, RGXFW_GROUP_HWR, RGXFW_SF_HWR_BIF1_FAULT, "BIF1 page fault detected (Bank1 MMU Status: 0x%08x)", 1) \
+X( 44, RGXFW_GROUP_HWR, RGXFW_SF_HWR_CRC_CHECK_TRUE_DEPRECATED, "Fast CRC Failed. Proceeding to full register checking (DM: %u).", 1) \
+X( 45, RGXFW_GROUP_HWR, RGXFW_SF_HWR_MMU_META_FAULT, "Meta MMU page fault detected (Meta MMU Status: 0x%08x%08x)", 2) \
+X( 46, RGXFW_GROUP_HWR, RGXFW_SF_HWR_CRC_CHECK_DEPRECATED, "Fast CRC Check result for DM%u is HWRNeeded=%u", 2) \
+X( 47, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FULL_CHECK_DEPRECATED, "Full Signature Check result for DM%u is HWRNeeded=%u", 2) \
+X( 48, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FINAL_RESULT, "Final result for DM%u is HWRNeeded=%u with HWRChecksToGo=%u", 3) \
+X( 49, RGXFW_GROUP_HWR, RGXFW_SF_HWR_USC_SLOTS_CHECK_DEPRECATED, "USC Slots result for DM%u is HWRNeeded=%u USCSlotsUsedByDM=%d", 3) \
+X( 50, RGXFW_GROUP_HWR, RGXFW_SF_HWR_DEADLINE_CHECK_DEPRECATED, "Deadline counter for DM%u is HWRDeadline=%u", 2) \
+X( 51, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HOLD_SCHEDULING_DUE_TO_FREELIST_DEPRECATED, "Holding Scheduling on OSid %u due to pending freelist reconstruction", 1) \
+X( 52, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_RECON_REQUEST, "Requesting reconstruction for freelist 0x%x (ID=%d)", 2) \
+X( 53, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_RECON_PASSED, "Reconstruction of freelist ID=%d complete", 1) \
+X( 54, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_RECON_NEEDED_DEPRECATED, "Reconstruction needed for freelist 0x%x (ID=%d) type: %d (0:local,1:global,2:mmu) on HW context %u", 4) \
+X( 55, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_RECON_FAILED, "Reconstruction of freelist ID=%d failed", 1) \
+X( 56, RGXFW_GROUP_HWR, RGXFW_SF_HWR_RESTRICTING_PDS_TASKS, "Restricting PDS Tasks to help other stalling DMs (RunningMask=0x%02x, StallingMask=0x%02x, PDS_CTRL=0x%08x%08x)", 4) \
+X( 57, RGXFW_GROUP_HWR, RGXFW_SF_HWR_UNRESTRICTING_PDS_TASKS, "Unrestricting PDS Tasks again (RunningMask=0x%02x, StallingMask=0x%02x, PDS_CTRL=0x%08x%08x)", 4) \
+X( 58, RGXFW_GROUP_HWR, RGXFW_SF_HWR_USC_SLOTS_USED, "USC slots: %u used by DM%u", 2) \
+X( 59, RGXFW_GROUP_HWR, RGXFW_SF_HWR_USC_SLOTS_EMPTY, "USC slots: %u empty", 1) \
+X( 60, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HCS_FIRE, "HCS DM%d's Context Switch failed to meet deadline. Current time: 0x%08x%08x, deadline: 0x%08x%08x", 5) \
+X( 61, RGXFW_GROUP_HWR, RGXFW_SF_HWR_START_HW_RESET, "Begin hardware reset (HWR Counter=%d)", 1) \
+X( 62, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FINISH_HW_RESET, "Finished hardware reset (HWR Counter=%d)", 1) \
+X( 63, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HOLD_SCHEDULING_DUE_TO_FREELIST, "Holding Scheduling on DM %u for OSid %u due to pending freelist reconstruction", 2) \
+X( 64, RGXFW_GROUP_HWR, RGXFW_SF_HWR_RESET_UMQ_READ_OFFSET, "User Mode Queue ROff reset: FWCtx 0x%08.8x, queue: 0x%08x%08x (Roff = %u becomes StreamStartOffset = %u)", 5) \
+X( 65, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_RECON_NEEDED_DEPRECATED2, "Reconstruction needed for freelist 0x%x (ID=%d) type: %d (0:local,1:global) on HW context %u", 4) \
+X( 66, RGXFW_GROUP_HWR, RGXFW_SF_HWR_MIPS_FAULT, "Mips page fault detected (BadVAddr: 0x%08x, EntryLo0: 0x%08x, EntryLo1: 0x%08x)", 3) \
+X( 67, RGXFW_GROUP_HWR, RGXFW_SF_HWR_ANOTHER_CHANCE, "At least one other DM is running okay so DM%u will get another chance", 1) \
+X( 68, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_RECON_FW, "Reconstructing in FW, FL: 0x%x (ID=%d)", 2) \
+X( 69, RGXFW_GROUP_HWR, RGXFW_SF_HWR_ZERO_RTC, "Zero RTC for FWCtx: 0x%08.8x (RTC addr: 0x%08x%08x, size: %d bytes)", 4) \
+X( 70, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_RECON_NEEDED_DEPRECATED3, "Reconstruction needed for freelist 0x%x (ID=%d) type: %d (0:local,1:global) phase: %d (0:TA, 1:3D) on HW context %u", 5) \
+X( 71, RGXFW_GROUP_HWR, RGXFW_SF_HWR_START_LONG_HW_POLL, "Start long HW poll %u (0-Unset 1-Set) for (reg:0x%08x val:0x%08x)", 3) \
+X( 72, RGXFW_GROUP_HWR, RGXFW_SF_HWR_END_LONG_HW_POLL, "End long HW poll (result=%d)", 1) \
+X( 73, RGXFW_GROUP_HWR, RGXFW_SF_HWR_DEADLINE_CHECK, "DM%u has taken %d ticks and deadline is %d ticks", 3) \
+X( 74, RGXFW_GROUP_HWR, RGXFW_SF_HWR_WATCHDOG_CHECK_DEPRECATED, "USC Watchdog result for DM%u is HWRNeeded=%u Status=%u USCs={0x%x} with HWRChecksToGo=%u", 5) \
+X( 75, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FL_RECON_NEEDED, "Reconstruction needed for freelist 0x%x (ID=%d) OSid: %d type: %d (0:local,1:global) phase: %d (0:TA, 1:3D) on HW context %u", 6) \
+X( 76, RGXFW_GROUP_HWR, RGXFW_SF_HWR_SET_LOCKUP, "GPU-%u has locked up", 1) \
+X( 77, RGXFW_GROUP_HWR, RGXFW_SF_HWR_SET_LOCKUP_DM, "DM%u has locked up", 1) \
+X( 78, RGXFW_GROUP_HWR, RGXFW_SF_HWR_CORE_EVENT_STATUS_REG, "Core %d RGX_CR_EVENT_STATUS=0x%08x", 2) \
+X( 79, RGXFW_GROUP_HWR, RGXFW_SF_HWR_MULTICORE_EVENT_STATUS_REG, "RGX_CR_MULTICORE_EVENT_STATUS%u=0x%08x", 2) \
+X( 80, RGXFW_GROUP_HWR, RGXFW_SF_HWR_CORE_BIF0_FAULT, "BIF0 page fault detected (Core %d MMU Status: 0x%08x%08x Req Status: 0x%08x%08x)", 5) \
+X( 81, RGXFW_GROUP_HWR, RGXFW_SF_HWR_CORE_MMU_FAULT_S7, "MMU page fault detected (Core %d MMU Status: 0x%08x%08x)", 3) \
+X( 82, RGXFW_GROUP_HWR, RGXFW_SF_HWR_CORE_MMU_FAULT, "MMU page fault detected (Core %d MMU Status: 0x%08x%08x 0x%08x)", 4) \
+X( 83, RGXFW_GROUP_HWR, RGXFW_SF_HWR_RESET_HW, "Reset HW (core:%d of %d, loop:%d, poll failures: 0x%08x)", 4) \
+X( 84, RGXFW_GROUP_HWR, RGXFW_SF_HWR_CRC_CHECK, "Fast CRC Check result for Core%u, DM%u is HWRNeeded=%u", 3) \
+X( 85, RGXFW_GROUP_HWR, RGXFW_SF_HWR_FULL_CHECK, "Full Signature Check result for Core%u, DM%u is HWRNeeded=%u", 3) \
+X( 86, RGXFW_GROUP_HWR, RGXFW_SF_HWR_USC_SLOTS_CHECK, "USC Slots result for Core%u, DM%u is HWRNeeded=%u USCSlotsUsedByDM=%d", 4) \
+X( 87, RGXFW_GROUP_HWR, RGXFW_SF_HWR_WATCHDOG_CHECK, "USC Watchdog result for Core%u DM%u is HWRNeeded=%u Status=%u USCs={0x%x} with HWRChecksToGo=%u", 6) \
+X( 88, RGXFW_GROUP_HWR, RGXFW_SF_HWR_MMU_RISCV_FAULT, "RISC-V MMU page fault detected (FWCORE MMU Status 0x%08x Req Status 0x%08x%08x)", 3) \
+X( 89, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HWR_FAULT_POLL_BIF_TEXAS1_PFS_DEPRECATED, "After FW fault was raised, TEXAS1_PFS poll failed on core %d with value 0x%08x", 2) \
+X( 90, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HWR_FAULT_POLL_BIF_PFS, "After FW fault was raised, BIF_PFS poll failed on core %d with value 0x%08x", 2) \
+X( 91, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HWR_FAULT_POLL_SET_ABORT_PM_STATUS, "After FW fault was raised, MMU_ABORT_PM_STATUS set poll failed on core %d with value 0x%08x", 2) \
+X( 92, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HWR_FAULT_POLL_UNSET_ABORT_PM_STATUS, "After FW fault was raised, MMU_ABORT_PM_STATUS unset poll failed on core %d with value 0x%08x", 2) \
+X( 93, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HWR_FAULT_POLL_SLC_INVAL, "After FW fault was raised, MMU_CTRL_INVAL poll (all but fw) failed on core %d with value 0x%08x", 2) \
+X( 94, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HWR_FAULT_POLL_SLCMMU_INVAL, "After FW fault was raised, MMU_CTRL_INVAL poll (all) failed on core %d with value 0x%08x", 2) \
+X( 95, RGXFW_GROUP_HWR, RGXFW_SF_HWR_HWR_FAULT_POLL_BIF_TEXAS_PFS, "After FW fault was raised, TEXAS%d_PFS poll failed on core %d with value 0x%08x", 3) \
+X( 96, RGXFW_GROUP_HWR, RGXFW_SF_HWR_EXTRA_CHECK, "Extra Registers Check result for Core%u, DM%u is HWRNeeded=%u", 3) \
+\
+X( 1, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CFGBLK, "Block 0x%x mapped to Config Idx %u", 2) \
+X( 2, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_OMTBLK, "Block 0x%x omitted from event - not enabled in HW", 1) \
+X( 3, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_INCBLK, "Block 0x%x included in event - enabled in HW", 1) \
+X( 4, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_SELREG, "Select register state hi_0x%x lo_0x%x", 2) \
+X( 5, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CSBHDR, "Counter stream block header word 0x%x", 1) \
+X( 6, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CTROFF, "Counter register offset 0x%x", 1) \
+X( 7, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CFGSKP, "Block 0x%x config unset, skipping", 1) \
+X( 8, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_INDBLK, "Accessing Indirect block 0x%x", 1) \
+X( 9, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_DIRBLK, "Accessing Direct block 0x%x", 1) \
+X( 10, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CNTPRG, "Programmed counter select register at offset 0x%x", 1) \
+X( 11, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_BLKPRG, "Block register offset 0x%x and value 0x%x", 2) \
+X( 12, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_UBLKCG, "Reading config block from driver 0x%x", 1) \
+X( 13, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_UBLKRG, "Reading block range 0x%x to 0x%x", 2) \
+X( 14, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_BLKREC, "Recording block 0x%x config from driver", 1) \
+X( 15, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_UBLKED, "Finished reading config block from driver", 0) \
+X( 16, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CUSTOM_COUNTER, "Custom Counter offset: 0x%x value: 0x%x", 2) \
+X( 17, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_SELECT_CNTR, "Select counter n:%u ID:0x%x", 2) \
+X( 18, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_DROP_SELECT_PACK, "The counter ID 0x%x is not allowed. The package [b:%u, n:%u] will be discarded", 3) \
+X( 19, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CHANGE_FILTER_STATUS_CUSTOM, "Custom Counters filter status %d", 1) \
+X( 20, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_DROP_WRONG_BLOCK, "The Custom block %d is not allowed. Use only blocks lower than %d. The package will be discarded", 2) \
+X( 21, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_DROP_TOO_MANY_ID, "The package will be discarded because it contains %d counters IDs while the upper limit is %d", 2) \
+X( 22, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CHECK_FILTER, "Check Filter 0x%x is 0x%x ?", 2) \
+X( 23, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_RESET_CUSTOM_BLOCK, "The custom block %u is reset", 1) \
+X( 24, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_INVALID_CMD_DEPRECATED, "Encountered an invalid command (%d)", 1) \
+X( 25, RGXFW_GROUP_HWP, RGXFW_SF_HWP_WAITING_FOR_QUEUE_DEPRECATED, "HWPerf Queue is full, we will have to wait for space! (Roff = %u, Woff = %u)", 2) \
+X( 26, RGXFW_GROUP_HWP, RGXFW_SF_HWP_WAITING_FOR_QUEUE_FENCE_DEPRECATED, "HWPerf Queue is fencing, we are waiting for Roff = %d (Roff = %u, Woff = %u)", 3) \
+X( 27, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CUSTOM_BLOCK, "Custom Counter block: %d", 1) \
+X( 28, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_BLKENA, "Block 0x%x ENABLED", 1) \
+X( 29, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_BLKDIS, "Block 0x%x DISABLED", 1) \
+X( 30, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_INDBLK_INSTANCE, "Accessing Indirect block 0x%x, instance %u", 2) \
+X( 31, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CTRVAL, "Counter register 0x%x, Value 0x%x", 2) \
+X( 32, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CHANGE_FILTER_STATUS, "Counters filter status %d", 1) \
+X( 33, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CTLBLK, "Block 0x%x mapped to Ctl Idx %u", 2) \
+X( 34, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_WORKEST_EN, "Block(s) in use for workload estimation.", 0) \
+X( 35, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CYCCTR, "GPU %u Cycle counter 0x%x, Value 0x%x", 3) \
+X( 36, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_CYCMAX, "GPU Mask 0x%x Cycle counter 0x%x, Value 0x%x", 3) \
+X( 37, RGXFW_GROUP_HWP, RGXFW_SF_HWP_I_IGNORE_BLOCKS, "Blocks IGNORED for GPU %u", 1) \
+\
+X( 1, RGXFW_GROUP_DMA, RGXFW_SF_DMA_TRANSFER_REQUEST_DEPRECATED, "Transfer 0x%02x request: 0x%02x%08x -> 0x%08x, size %u", 5) \
+X( 2, RGXFW_GROUP_DMA, RGXFW_SF_DMA_TRANSFER_COMPLETE, "Transfer of type 0x%02x expected on channel %u, 0x%02x found, status %u", 4) \
+X( 3, RGXFW_GROUP_DMA, RGXFW_SF_DMA_INT_REG, "DMA Interrupt register 0x%08x", 1) \
+X( 4, RGXFW_GROUP_DMA, RGXFW_SF_DMA_WAIT, "Waiting for transfer of type 0x%02x completion...", 1) \
+X( 5, RGXFW_GROUP_DMA, RGXFW_SF_DMA_CCB_LOADING_FAILED, "Loading of cCCB data from FW common context 0x%08x (offset: %u, size: %u) failed", 3) \
+X( 6, RGXFW_GROUP_DMA, RGXFW_SF_DMA_CCB_LOAD_INVALID, "Invalid load of cCCB data from FW common context 0x%08x (offset: %u, size: %u)", 3) \
+X( 7, RGXFW_GROUP_DMA, RGXFW_SF_DMA_POLL_FAILED, "Transfer 0x%02x request poll failure", 1) \
+X( 8, RGXFW_GROUP_DMA, RGXFW_SF_DMA_BOOT_TRANSFER_FAILED, "Boot transfer(s) failed (code? %u, data? %u), used slower memcpy instead", 2) \
+X( 9, RGXFW_GROUP_DMA, RGXFW_SF_DMA_TRANSFER_REQUEST, "Transfer 0x%02x request on ch. %u: system 0x%02x%08x, coremem 0x%08x, flags 0x%x, size %u", 7) \
+\
+X( 1, RGXFW_GROUP_DBG, RGXFW_SF_DBG_INTPAIR, "0x%08x 0x%08x", 2) \
+X( 2, RGXFW_GROUP_DBG, RGXFW_SF_DBG_1HEX, "0x%08x", 1) \
+X( 3, RGXFW_GROUP_DBG, RGXFW_SF_DBG_2HEX, "0x%08x 0x%08x", 2) \
+X( 4, RGXFW_GROUP_DBG, RGXFW_SF_DBG_3HEX, "0x%08x 0x%08x 0x%08x", 3) \
+X( 5, RGXFW_GROUP_DBG, RGXFW_SF_DBG_4HEX, "0x%08x 0x%08x 0x%08x 0x%08x", 4) \
+X( 6, RGXFW_GROUP_DBG, RGXFW_SF_DBG_5HEX, "0x%08x 0x%08x 0x%08x 0x%08x 0x%08x", 5) \
+X( 7, RGXFW_GROUP_DBG, RGXFW_SF_DBG_6HEX, "0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x", 6) \
+X( 8, RGXFW_GROUP_DBG, RGXFW_SF_DBG_7HEX, "0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x", 7) \
+X( 9, RGXFW_GROUP_DBG, RGXFW_SF_DBG_8HEX, "0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x", 8) \
+X( 10, RGXFW_GROUP_DBG, RGXFW_SF_DBG_1SIGNED, "%d", 1) \
+X( 11, RGXFW_GROUP_DBG, RGXFW_SF_DBG_2SIGNED, "%d %d", 2) \
+X( 12, RGXFW_GROUP_DBG, RGXFW_SF_DBG_3SIGNED, "%d %d %d", 3) \
+X( 13, RGXFW_GROUP_DBG, RGXFW_SF_DBG_4SIGNED, "%d %d %d %d", 4) \
+X( 14, RGXFW_GROUP_DBG, RGXFW_SF_DBG_5SIGNED, "%d %d %d %d %d", 5) \
+X( 15, RGXFW_GROUP_DBG, RGXFW_SF_DBG_6SIGNED, "%d %d %d %d %d %d", 6) \
+X( 16, RGXFW_GROUP_DBG, RGXFW_SF_DBG_7SIGNED, "%d %d %d %d %d %d %d", 7) \
+X( 17, RGXFW_GROUP_DBG, RGXFW_SF_DBG_8SIGNED, "%d %d %d %d %d %d %d %d", 8) \
+X( 18, RGXFW_GROUP_DBG, RGXFW_SF_DBG_1UNSIGNED, "%u", 1) \
+X( 19, RGXFW_GROUP_DBG, RGXFW_SF_DBG_2UNSIGNED, "%u %u", 2) \
+X( 20, RGXFW_GROUP_DBG, RGXFW_SF_DBG_3UNSIGNED, "%u %u %u", 3) \
+X( 21, RGXFW_GROUP_DBG, RGXFW_SF_DBG_4UNSIGNED, "%u %u %u %u", 4) \
+X( 22, RGXFW_GROUP_DBG, RGXFW_SF_DBG_5UNSIGNED, "%u %u %u %u %u", 5) \
+X( 23, RGXFW_GROUP_DBG, RGXFW_SF_DBG_6UNSIGNED, "%u %u %u %u %u %u", 6) \
+X( 24, RGXFW_GROUP_DBG, RGXFW_SF_DBG_7UNSIGNED, "%u %u %u %u %u %u %u", 7) \
+X( 25, RGXFW_GROUP_DBG, RGXFW_SF_DBG_8UNSIGNED, "%u %u %u %u %u %u %u %u", 8) \
+\
+X(65535, RGXFW_GROUP_NULL, RGXFW_SF_LAST, "You should not use this string", 15)
+
+
+/* The symbolic names found in the table above are assigned an ui32 value of
+ * the following format:
+ * 31 30 28 27 20 19 16 15 12 11 0 bits
+ * - --- ---- ---- ---- ---- ---- ---- ----
+ * 0-11: id number
+ * 12-15: group id number
+ * 16-19: number of parameters
+ * 20-27: unused
+ * 28-30: active: identify SF packet, otherwise regular int32
+ * 31: reserved for signed/unsigned compatibility
+ *
+ * The following macro assigns those values to the enum generated SF ids list.
+ */
+#define RGXFW_LOG_IDMARKER (0x70000000U)
+#define RGXFW_LOG_CREATESFID(a,b,e) ((IMG_UINT32)(a) | ((IMG_UINT32)(b)<<12U) | ((IMG_UINT32)(e)<<16U)) | RGXFW_LOG_IDMARKER
+
+#define RGXFW_LOG_IDMASK (0xFFF00000U)
+#define RGXFW_LOG_VALIDID(I) (((I) & RGXFW_LOG_IDMASK) == RGXFW_LOG_IDMARKER)
+
+typedef enum {
+#define X(a, b, c, d, e) c = RGXFW_LOG_CREATESFID(a,b,e),
+ RGXFW_LOG_SFIDLIST
+#undef X
+} RGXFW_LOG_SFids;
+
+/* Return the group id that the given (enum generated) id belongs to */
+#define RGXFW_SF_GID(x) (((IMG_UINT32)(x)>>12) & 0xfU)
+/* Returns how many arguments the SF(string format) for the given (enum generated) id requires */
+#define RGXFW_SF_PARAMNUM(x) (((IMG_UINT32)(x)>>16) & 0xfU)
+
+#endif /* RGX_FWIF_SF_H */
diff --git a/drivers/gpu/drm/img-rogue/include/rgx_heap_firmware.h b/drivers/gpu/drm/img-rogue/include/rgx_heap_firmware.h
new file mode 100644
index 000000000..36150640d
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/rgx_heap_firmware.h
@@ -0,0 +1,126 @@
+/*************************************************************************/ /*!
+@File
+@Title RGX FW heap definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(RGX_HEAP_FIRMWARE_H)
+#define RGX_HEAP_FIRMWARE_H
+
+/* Start at 903GiB. Size of 32MB per OSID (see rgxheapconfig.h)
+ * NOTE:
+ * The firmware heaps bases and sizes are defined here to
+ * simplify #include dependencies, see rgxheapconfig.h
+ * for the full RGX virtual address space layout.
+ */
+
+/*
+ * The Config heap holds initialisation data shared between the
+ * the driver and firmware (e.g. pointers to the KCCB and FWCCB).
+ * The Main Firmware heap size is adjusted accordingly but most
+ * of the map / unmap functions must take into consideration
+ * the entire range (i.e. main and config heap).
+ */
+#define RGX_FIRMWARE_NUMBER_OF_FW_HEAPS (2)
+#define RGX_FIRMWARE_HEAP_SHIFT RGX_FW_HEAP_SHIFT
+#define RGX_FIRMWARE_RAW_HEAP_BASE (0xE1C0000000ULL)
+#define RGX_FIRMWARE_RAW_HEAP_SIZE (IMG_UINT32_C(1) << RGX_FIRMWARE_HEAP_SHIFT)
+
+/* To enable the firmware to compute the exact address of structures allocated by the KM
+ * in the Fw Config subheap, regardless of the KM's page size (and PMR granularity),
+ * objects allocated consecutively but from different PMRs (due to differing memalloc flags)
+ * are allocated with a 64kb offset. This way, all structures will be located at the same base
+ * addresses when the KM is running with a page size of 4k, 16k or 64k. */
+#define RGX_FIRMWARE_CONFIG_HEAP_ALLOC_GRANULARITY (IMG_UINT32_C(0x10000))
+
+/* Ensure the heap can hold 3 PMRs of maximum supported granularity (192KB):
+ * 1st PMR: RGXFWIF_CONNECTION_CTL
+ * 2nd PMR: RGXFWIF_OSINIT
+ * 3rd PMR: RGXFWIF_SYSINIT */
+#define RGX_FIRMWARE_CONFIG_HEAP_SIZE (3*RGX_FIRMWARE_CONFIG_HEAP_ALLOC_GRANULARITY)
+
+#define RGX_FIRMWARE_META_MAIN_HEAP_SIZE (RGX_FIRMWARE_RAW_HEAP_SIZE - RGX_FIRMWARE_CONFIG_HEAP_SIZE)
+/*
+ * MIPS FW needs space in the Main heap to map GPU memory.
+ * This space is taken from the MAIN heap, to avoid creating a new heap.
+ */
+#define RGX_FIRMWARE_MIPS_GPU_MAP_RESERVED_SIZE_NORMAL (IMG_UINT32_C(0x100000)) /* 1MB */
+#define RGX_FIRMWARE_MIPS_GPU_MAP_RESERVED_SIZE_BRN65101 (IMG_UINT32_C(0x400000)) /* 4MB */
+
+#define RGX_FIRMWARE_MIPS_MAIN_HEAP_SIZE_NORMAL (RGX_FIRMWARE_RAW_HEAP_SIZE - RGX_FIRMWARE_CONFIG_HEAP_SIZE - \
+ RGX_FIRMWARE_MIPS_GPU_MAP_RESERVED_SIZE_NORMAL)
+
+#define RGX_FIRMWARE_MIPS_MAIN_HEAP_SIZE_BRN65101 (RGX_FIRMWARE_RAW_HEAP_SIZE - RGX_FIRMWARE_CONFIG_HEAP_SIZE - \
+ RGX_FIRMWARE_MIPS_GPU_MAP_RESERVED_SIZE_BRN65101)
+
+#if !defined(__KERNEL__)
+#if defined(FIX_HW_BRN_65101)
+#define RGX_FIRMWARE_MIPS_GPU_MAP_RESERVED_SIZE RGX_FIRMWARE_MIPS_GPU_MAP_RESERVED_SIZE_BRN65101
+#define RGX_FIRMWARE_MIPS_MAIN_HEAP_SIZE RGX_FIRMWARE_MIPS_MAIN_HEAP_SIZE_BRN65101
+
+#include "img_defs.h"
+static_assert((RGX_FIRMWARE_RAW_HEAP_SIZE) >= IMG_UINT32_C(0x800000), "MIPS GPU map size cannot be increased due to BRN65101 with a small FW heap");
+
+#else
+#define RGX_FIRMWARE_MIPS_GPU_MAP_RESERVED_SIZE RGX_FIRMWARE_MIPS_GPU_MAP_RESERVED_SIZE_NORMAL
+#define RGX_FIRMWARE_MIPS_MAIN_HEAP_SIZE RGX_FIRMWARE_MIPS_MAIN_HEAP_SIZE_NORMAL
+#endif
+#endif /* !defined(__KERNEL__) */
+
+/* Host sub-heap order: MAIN + CONFIG */
+#define RGX_FIRMWARE_HOST_MAIN_HEAP_BASE RGX_FIRMWARE_RAW_HEAP_BASE
+#define RGX_FIRMWARE_HOST_CONFIG_HEAP_BASE (RGX_FIRMWARE_HOST_MAIN_HEAP_BASE + \
+ RGX_FIRMWARE_RAW_HEAP_SIZE - \
+ RGX_FIRMWARE_CONFIG_HEAP_SIZE)
+
+/* Guest sub-heap order: CONFIG + MAIN */
+#define RGX_FIRMWARE_GUEST_CONFIG_HEAP_BASE RGX_FIRMWARE_RAW_HEAP_BASE
+#define RGX_FIRMWARE_GUEST_MAIN_HEAP_BASE (RGX_FIRMWARE_GUEST_CONFIG_HEAP_BASE + \
+ RGX_FIRMWARE_CONFIG_HEAP_SIZE)
+
+/*
+ * The maximum configurable size via RGX_FW_HEAP_SHIFT is 32MiB (1<<25) and
+ * the minimum is 4MiB (1<<22); the default firmware heap size is set to
+ * maximum 32MiB.
+ */
+#if defined(RGX_FW_HEAP_SHIFT) && (RGX_FW_HEAP_SHIFT < 22 || RGX_FW_HEAP_SHIFT > 25)
+#error "RGX_FW_HEAP_SHIFT is outside valid range [22, 25]"
+#endif
+
+#endif /* RGX_HEAP_FIRMWARE_H */
diff --git a/drivers/gpu/drm/img-rogue/include/rgx_meta.h b/drivers/gpu/drm/img-rogue/include/rgx_meta.h
new file mode 100644
index 000000000..e88d21308
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/rgx_meta.h
@@ -0,0 +1,385 @@
+/*************************************************************************/ /*!
+@File
+@Title RGX META definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description RGX META helper definitions
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(RGX_META_H)
+#define RGX_META_H
+
+
+/***** The META HW register definitions in the file are updated manually *****/
+
+
+#include "img_defs.h"
+#include "km/rgxdefs_km.h"
+
+
+/******************************************************************************
+* META registers and MACROS
+******************************************************************************/
+#define META_CR_CTRLREG_BASE(T) (0x04800000U + (0x1000U*(T)))
+
+#define META_CR_TXPRIVEXT (0x048000E8)
+#define META_CR_TXPRIVEXT_MINIM_EN (IMG_UINT32_C(0x1) << 7)
+
+#define META_CR_SYSC_JTAG_THREAD (0x04830030)
+#define META_CR_SYSC_JTAG_THREAD_PRIV_EN (0x00000004)
+
+#define META_CR_PERF_COUNT0 (0x0480FFE0)
+#define META_CR_PERF_COUNT1 (0x0480FFE8)
+#define META_CR_PERF_COUNT_CTRL_SHIFT (28)
+#define META_CR_PERF_COUNT_CTRL_MASK (0xF0000000)
+#define META_CR_PERF_COUNT_CTRL_DCACHEHITS (IMG_UINT32_C(0x8) << META_CR_PERF_COUNT_CTRL_SHIFT)
+#define META_CR_PERF_COUNT_CTRL_ICACHEHITS (IMG_UINT32_C(0x9) << META_CR_PERF_COUNT_CTRL_SHIFT)
+#define META_CR_PERF_COUNT_CTRL_ICACHEMISS (IMG_UINT32_C(0xA) << META_CR_PERF_COUNT_CTRL_SHIFT)
+#define META_CR_PERF_COUNT_CTRL_ICORE (IMG_UINT32_C(0xD) << META_CR_PERF_COUNT_CTRL_SHIFT)
+#define META_CR_PERF_COUNT_THR_SHIFT (24)
+#define META_CR_PERF_COUNT_THR_MASK (0x0F000000)
+#define META_CR_PERF_COUNT_THR_0 (IMG_UINT32_C(0x1) << META_CR_PERF_COUNT_THR_SHIFT)
+#define META_CR_PERF_COUNT_THR_1 (IMG_UINT32_C(0x2) << META_CR_PERF_COUNT_THR_1)
+
+#define META_CR_TxVECINT_BHALT (0x04820500)
+#define META_CR_PERF_ICORE0 (0x0480FFD0)
+#define META_CR_PERF_ICORE1 (0x0480FFD8)
+#define META_CR_PERF_ICORE_DCACHEMISS (0x8)
+
+#define META_CR_PERF_COUNT(CTRL, THR) ((META_CR_PERF_COUNT_CTRL_##CTRL << META_CR_PERF_COUNT_CTRL_SHIFT) | \
+ (THR << META_CR_PERF_COUNT_THR_SHIFT))
+
+#define META_CR_TXUXXRXDT_OFFSET (META_CR_CTRLREG_BASE(0U) + 0x0000FFF0U)
+#define META_CR_TXUXXRXRQ_OFFSET (META_CR_CTRLREG_BASE(0U) + 0x0000FFF8U)
+
+#define META_CR_TXUXXRXRQ_DREADY_BIT (0x80000000U) /* Poll for done */
+#define META_CR_TXUXXRXRQ_RDnWR_BIT (0x00010000U) /* Set for read */
+#define META_CR_TXUXXRXRQ_TX_S (12)
+#define META_CR_TXUXXRXRQ_RX_S (4)
+#define META_CR_TXUXXRXRQ_UXX_S (0)
+
+#define META_CR_TXUIN_ID (0x0) /* Internal ctrl regs */
+#define META_CR_TXUD0_ID (0x1) /* Data unit regs */
+#define META_CR_TXUD1_ID (0x2) /* Data unit regs */
+#define META_CR_TXUA0_ID (0x3) /* Address unit regs */
+#define META_CR_TXUA1_ID (0x4) /* Address unit regs */
+#define META_CR_TXUPC_ID (0x5) /* PC registers */
+
+/* Macros to calculate register access values */
+#define META_CR_CORE_REG(Thr, RegNum, Unit) (((IMG_UINT32)(Thr) << META_CR_TXUXXRXRQ_TX_S) | \
+ ((IMG_UINT32)(RegNum) << META_CR_TXUXXRXRQ_RX_S) | \
+ ((IMG_UINT32)(Unit) << META_CR_TXUXXRXRQ_UXX_S))
+
+#define META_CR_THR0_PC META_CR_CORE_REG(0, 0, META_CR_TXUPC_ID)
+#define META_CR_THR0_PCX META_CR_CORE_REG(0, 1, META_CR_TXUPC_ID)
+#define META_CR_THR0_SP META_CR_CORE_REG(0, 0, META_CR_TXUA0_ID)
+
+#define META_CR_THR1_PC META_CR_CORE_REG(1, 0, META_CR_TXUPC_ID)
+#define META_CR_THR1_PCX META_CR_CORE_REG(1, 1, META_CR_TXUPC_ID)
+#define META_CR_THR1_SP META_CR_CORE_REG(1, 0, META_CR_TXUA0_ID)
+
+#define SP_ACCESS(Thread) META_CR_CORE_REG(Thread, 0, META_CR_TXUA0_ID)
+#define PC_ACCESS(Thread) META_CR_CORE_REG(Thread, 0, META_CR_TXUPC_ID)
+
+#define META_CR_COREREG_ENABLE (0x0000000U)
+#define META_CR_COREREG_STATUS (0x0000010U)
+#define META_CR_COREREG_DEFR (0x00000A0U)
+#define META_CR_COREREG_PRIVEXT (0x00000E8U)
+
+#define META_CR_T0ENABLE_OFFSET (META_CR_CTRLREG_BASE(0U) + META_CR_COREREG_ENABLE)
+#define META_CR_T0STATUS_OFFSET (META_CR_CTRLREG_BASE(0U) + META_CR_COREREG_STATUS)
+#define META_CR_T0DEFR_OFFSET (META_CR_CTRLREG_BASE(0U) + META_CR_COREREG_DEFR)
+#define META_CR_T0PRIVEXT_OFFSET (META_CR_CTRLREG_BASE(0U) + META_CR_COREREG_PRIVEXT)
+
+#define META_CR_T1ENABLE_OFFSET (META_CR_CTRLREG_BASE(1U) + META_CR_COREREG_ENABLE)
+#define META_CR_T1STATUS_OFFSET (META_CR_CTRLREG_BASE(1U) + META_CR_COREREG_STATUS)
+#define META_CR_T1DEFR_OFFSET (META_CR_CTRLREG_BASE(1U) + META_CR_COREREG_DEFR)
+#define META_CR_T1PRIVEXT_OFFSET (META_CR_CTRLREG_BASE(1U) + META_CR_COREREG_PRIVEXT)
+
+#define META_CR_TXENABLE_ENABLE_BIT (0x00000001U) /* Set if running */
+#define META_CR_TXSTATUS_PRIV (0x00020000U)
+#define META_CR_TXPRIVEXT_MINIM (0x00000080U)
+
+#define META_MEM_GLOBAL_RANGE_BIT (0x80000000U)
+
+#define META_CR_TXCLKCTRL (0x048000B0)
+#define META_CR_TXCLKCTRL_ALL_ON (0x55111111)
+#define META_CR_TXCLKCTRL_ALL_AUTO (0xAA222222)
+
+
+/******************************************************************************
+* META LDR Format
+******************************************************************************/
+/* Block header structure */
+typedef struct
+{
+ IMG_UINT32 ui32DevID;
+ IMG_UINT32 ui32SLCode;
+ IMG_UINT32 ui32SLData;
+ IMG_UINT16 ui16PLCtrl;
+ IMG_UINT16 ui16CRC;
+
+} RGX_META_LDR_BLOCK_HDR;
+
+/* High level data stream block structure */
+typedef struct
+{
+ IMG_UINT16 ui16Cmd;
+ IMG_UINT16 ui16Length;
+ IMG_UINT32 ui32Next;
+ IMG_UINT32 aui32CmdData[4];
+
+} RGX_META_LDR_L1_DATA_BLK;
+
+/* High level data stream block structure */
+typedef struct
+{
+ IMG_UINT16 ui16Tag;
+ IMG_UINT16 ui16Length;
+ IMG_UINT32 aui32BlockData[4];
+
+} RGX_META_LDR_L2_DATA_BLK;
+
+/* Config command structure */
+typedef struct
+{
+ IMG_UINT32 ui32Type;
+ IMG_UINT32 aui32BlockData[4];
+
+} RGX_META_LDR_CFG_BLK;
+
+/* Block type definitions */
+#define RGX_META_LDR_COMMENT_TYPE_MASK (0x0010U)
+#define RGX_META_LDR_BLK_IS_COMMENT(X) ((X & RGX_META_LDR_COMMENT_TYPE_MASK) != 0U)
+
+/* Command definitions
+ * Value Name Description
+ * 0 LoadMem Load memory with binary data.
+ * 1 LoadCore Load a set of core registers.
+ * 2 LoadMMReg Load a set of memory mapped registers.
+ * 3 StartThreads Set each thread PC and SP, then enable threads.
+ * 4 ZeroMem Zeros a memory region.
+ * 5 Config Perform a configuration command.
+ */
+#define RGX_META_LDR_CMD_MASK (0x000FU)
+
+#define RGX_META_LDR_CMD_LOADMEM (0x0000U)
+#define RGX_META_LDR_CMD_LOADCORE (0x0001U)
+#define RGX_META_LDR_CMD_LOADMMREG (0x0002U)
+#define RGX_META_LDR_CMD_START_THREADS (0x0003U)
+#define RGX_META_LDR_CMD_ZEROMEM (0x0004U)
+#define RGX_META_LDR_CMD_CONFIG (0x0005U)
+
+/* Config Command definitions
+ * Value Name Description
+ * 0 Pause Pause for x times 100 instructions
+ * 1 Read Read a value from register - No value return needed.
+ * Utilises effects of issuing reads to certain registers
+ * 2 Write Write to mem location
+ * 3 MemSet Set mem to value
+ * 4 MemCheck check mem for specific value.
+ */
+#define RGX_META_LDR_CFG_PAUSE (0x0000)
+#define RGX_META_LDR_CFG_READ (0x0001)
+#define RGX_META_LDR_CFG_WRITE (0x0002)
+#define RGX_META_LDR_CFG_MEMSET (0x0003)
+#define RGX_META_LDR_CFG_MEMCHECK (0x0004)
+
+
+/******************************************************************************
+* RGX FW segmented MMU definitions
+******************************************************************************/
+/* All threads can access the segment */
+#define RGXFW_SEGMMU_ALLTHRS (IMG_UINT32_C(0xf) << 8U)
+/* Writable */
+#define RGXFW_SEGMMU_WRITEABLE (0x1U << 1U)
+/* All threads can access and writable */
+#define RGXFW_SEGMMU_ALLTHRS_WRITEABLE (RGXFW_SEGMMU_ALLTHRS | RGXFW_SEGMMU_WRITEABLE)
+
+/* Direct map region 10 used for mapping GPU memory - max 8MB */
+#define RGXFW_SEGMMU_DMAP_GPU_ID (10U)
+#define RGXFW_SEGMMU_DMAP_GPU_ADDR_START (0x07000000U)
+#define RGXFW_SEGMMU_DMAP_GPU_MAX_SIZE (0x00800000U)
+
+/* Segment IDs */
+#define RGXFW_SEGMMU_DATA_ID (1U)
+#define RGXFW_SEGMMU_BOOTLDR_ID (2U)
+#define RGXFW_SEGMMU_TEXT_ID (RGXFW_SEGMMU_BOOTLDR_ID)
+
+/*
+ * SLC caching strategy in S7 and volcanic is emitted through the segment MMU.
+ * All the segments configured through the macro RGXFW_SEGMMU_OUTADDR_TOP are
+ * CACHED in the SLC.
+ * The interface has been kept the same to simplify the code changes.
+ * The bifdm argument is ignored (no longer relevant) in S7 and volcanic.
+ */
+#define RGXFW_SEGMMU_OUTADDR_TOP_VIVT_SLC(pers, slc_policy, mmu_ctx) ((((IMG_UINT64) ((pers) & 0x3)) << 52) | \
+ (((IMG_UINT64) ((mmu_ctx) & 0xFF)) << 44) | \
+ (((IMG_UINT64) ((slc_policy) & 0x1)) << 40))
+#define RGXFW_SEGMMU_OUTADDR_TOP_VIVT_SLC_CACHED(mmu_ctx) RGXFW_SEGMMU_OUTADDR_TOP_VIVT_SLC(0x3, 0x0, mmu_ctx)
+#define RGXFW_SEGMMU_OUTADDR_TOP_VIVT_SLC_UNCACHED(mmu_ctx) RGXFW_SEGMMU_OUTADDR_TOP_VIVT_SLC(0x0, 0x1, mmu_ctx)
+
+/* To configure the Page Catalog and BIF-DM fed into the BIF for Garten
+ * accesses through this segment
+ */
+#define RGXFW_SEGMMU_OUTADDR_TOP_SLC(pc, bifdm) (((IMG_UINT64)((IMG_UINT64)(pc) & 0xFU) << 44U) | \
+ ((IMG_UINT64)((IMG_UINT64)(bifdm) & 0xFU) << 40U))
+
+#define RGXFW_SEGMMU_META_BIFDM_ID (0x7U)
+#if !defined(__KERNEL__) && defined(RGX_FEATURE_META)
+#if defined(RGX_FEATURE_SLC_VIVT)
+#define RGXFW_SEGMMU_OUTADDR_TOP_SLC_CACHED RGXFW_SEGMMU_OUTADDR_TOP_VIVT_SLC_CACHED
+#define RGXFW_SEGMMU_OUTADDR_TOP_SLC_UNCACHED RGXFW_SEGMMU_OUTADDR_TOP_VIVT_SLC_UNCACHED
+#define RGXFW_SEGMMU_OUTADDR_TOP_META RGXFW_SEGMMU_OUTADDR_TOP_SLC_CACHED
+#else
+#define RGXFW_SEGMMU_OUTADDR_TOP_SLC_CACHED RGXFW_SEGMMU_OUTADDR_TOP_SLC
+#define RGXFW_SEGMMU_OUTADDR_TOP_SLC_UNCACHED RGXFW_SEGMMU_OUTADDR_TOP_SLC
+#define RGXFW_SEGMMU_OUTADDR_TOP_META(pc) RGXFW_SEGMMU_OUTADDR_TOP_SLC(pc, RGXFW_SEGMMU_META_BIFDM_ID)
+#endif
+#endif
+
+/* META segments have 4kB minimum size */
+#define RGXFW_SEGMMU_ALIGN (0x1000U)
+
+/* Segmented MMU registers (n = segment id) */
+#define META_CR_MMCU_SEGMENTn_BASE(n) (0x04850000U + ((n)*0x10U))
+#define META_CR_MMCU_SEGMENTn_LIMIT(n) (0x04850004U + ((n)*0x10U))
+#define META_CR_MMCU_SEGMENTn_OUTA0(n) (0x04850008U + ((n)*0x10U))
+#define META_CR_MMCU_SEGMENTn_OUTA1(n) (0x0485000CU + ((n)*0x10U))
+
+/* The following defines must be recalculated if the Meta MMU segments used
+ * to access Host-FW data are changed
+ * Current combinations are:
+ * - SLC uncached, META cached, FW base address 0x70000000
+ * - SLC uncached, META uncached, FW base address 0xF0000000
+ * - SLC cached, META cached, FW base address 0x10000000
+ * - SLC cached, META uncached, FW base address 0x90000000
+ */
+#define RGXFW_SEGMMU_DATA_BASE_ADDRESS (0x10000000U)
+#define RGXFW_SEGMMU_DATA_META_CACHED (0x0U)
+#define RGXFW_SEGMMU_DATA_META_UNCACHED (META_MEM_GLOBAL_RANGE_BIT) // 0x80000000
+#define RGXFW_SEGMMU_DATA_META_CACHE_MASK (META_MEM_GLOBAL_RANGE_BIT)
+/* For non-VIVT SLCs the cacheability of the FW data in the SLC is selected in
+ * the PTEs for the FW data, not in the Meta Segment MMU, which means these
+ * defines have no real effect in those cases
+ */
+#define RGXFW_SEGMMU_DATA_VIVT_SLC_CACHED (0x0U)
+#define RGXFW_SEGMMU_DATA_VIVT_SLC_UNCACHED (0x60000000U)
+#define RGXFW_SEGMMU_DATA_VIVT_SLC_CACHE_MASK (0x60000000U)
+
+
+#if defined(SECURE_FW_CODE_OSID) && defined(RGX_FEATURE_META)
+#error "SECURE_FW_CODE_OSID is not supported on META cores"
+#endif
+
+
+/******************************************************************************
+* RGX FW Bootloader defaults
+******************************************************************************/
+#define RGXFW_BOOTLDR_META_ADDR (0x40000000U)
+#define RGXFW_BOOTLDR_DEVV_ADDR_0 (0xC0000000U)
+#define RGXFW_BOOTLDR_DEVV_ADDR_1 (0x000000E1)
+#define RGXFW_BOOTLDR_DEVV_ADDR ((((IMG_UINT64) RGXFW_BOOTLDR_DEVV_ADDR_1) << 32) | RGXFW_BOOTLDR_DEVV_ADDR_0)
+#define RGXFW_BOOTLDR_LIMIT (0x1FFFF000)
+#define RGXFW_MAX_BOOTLDR_OFFSET (0x1000)
+
+/* Bootloader configuration offset is in dwords (512 bytes) */
+#define RGXFW_BOOTLDR_CONF_OFFSET (0x80)
+
+
+/******************************************************************************
+* RGX META Stack
+******************************************************************************/
+#define RGX_META_STACK_SIZE (0x1000U)
+
+/******************************************************************************
+ RGX META Core memory
+******************************************************************************/
+/* code and data both map to the same physical memory */
+#define RGX_META_COREMEM_CODE_ADDR (0x80000000U)
+#define RGX_META_COREMEM_DATA_ADDR (0x82000000U)
+#define RGX_META_COREMEM_OFFSET_MASK (0x01ffffffU)
+
+#if defined(__KERNEL__)
+#define RGX_META_IS_COREMEM_CODE(A, B) (((A) >= RGX_META_COREMEM_CODE_ADDR) && ((A) < (RGX_META_COREMEM_CODE_ADDR + (B))))
+#define RGX_META_IS_COREMEM_DATA(A, B) (((A) >= RGX_META_COREMEM_DATA_ADDR) && ((A) < (RGX_META_COREMEM_DATA_ADDR + (B))))
+#endif
+
+/******************************************************************************
+* 2nd thread
+******************************************************************************/
+#define RGXFW_THR1_PC (0x18930000)
+#define RGXFW_THR1_SP (0x78890000)
+
+/******************************************************************************
+* META compatibility
+******************************************************************************/
+
+#define META_CR_CORE_ID (0x04831000)
+#define META_CR_CORE_ID_VER_SHIFT (16U)
+#define META_CR_CORE_ID_VER_CLRMSK (0XFF00FFFFU)
+
+#if !defined(__KERNEL__) && defined(RGX_FEATURE_META)
+
+ #if (RGX_FEATURE_META == MTP218)
+ #define RGX_CR_META_CORE_ID_VALUE 0x19
+ #elif (RGX_FEATURE_META == MTP219)
+ #define RGX_CR_META_CORE_ID_VALUE 0x1E
+ #elif (RGX_FEATURE_META == LTP218)
+ #define RGX_CR_META_CORE_ID_VALUE 0x1C
+ #elif (RGX_FEATURE_META == LTP217)
+ #define RGX_CR_META_CORE_ID_VALUE 0x1F
+ #else
+ #error "Unknown META ID"
+ #endif
+#else
+
+ #define RGX_CR_META_MTP218_CORE_ID_VALUE 0x19
+ #define RGX_CR_META_MTP219_CORE_ID_VALUE 0x1E
+ #define RGX_CR_META_LTP218_CORE_ID_VALUE 0x1C
+ #define RGX_CR_META_LTP217_CORE_ID_VALUE 0x1F
+
+#endif
+#define RGXFW_PROCESSOR_META "META"
+
+
+#endif /* RGX_META_H */
+
+/******************************************************************************
+ End of file (rgx_meta.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/rgx_mips.h b/drivers/gpu/drm/img-rogue/include/rgx_mips.h
new file mode 100644
index 000000000..d3947127f
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/rgx_mips.h
@@ -0,0 +1,374 @@
+/*************************************************************************/ /*!
+@File rgx_mips.h
+@Title
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Platform RGX
+@Description RGX MIPS definitions, kernel/user space
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(RGX_MIPS_H)
+#define RGX_MIPS_H
+
+/*
+ * Utility defines for memory management
+ */
+#define RGXMIPSFW_LOG2_PAGE_SIZE_4K (12)
+#define RGXMIPSFW_PAGE_SIZE_4K (0x1 << RGXMIPSFW_LOG2_PAGE_SIZE_4K)
+#define RGXMIPSFW_PAGE_MASK_4K (RGXMIPSFW_PAGE_SIZE_4K - 1)
+#define RGXMIPSFW_LOG2_PAGE_SIZE_64K (16)
+#define RGXMIPSFW_PAGE_SIZE_64K (0x1 << RGXMIPSFW_LOG2_PAGE_SIZE_64K)
+#define RGXMIPSFW_PAGE_MASK_64K (RGXMIPSFW_PAGE_SIZE_64K - 1)
+#define RGXMIPSFW_LOG2_PAGE_SIZE_256K (18)
+#define RGXMIPSFW_PAGE_SIZE_256K (0x1 << RGXMIPSFW_LOG2_PAGE_SIZE_256K)
+#define RGXMIPSFW_PAGE_MASK_256K (RGXMIPSFW_PAGE_SIZE_256K - 1)
+#define RGXMIPSFW_LOG2_PAGE_SIZE_1MB (20)
+#define RGXMIPSFW_PAGE_SIZE_1MB (0x1 << RGXMIPSFW_LOG2_PAGE_SIZE_1MB)
+#define RGXMIPSFW_PAGE_MASK_1MB (RGXMIPSFW_PAGE_SIZE_1MB - 1)
+#define RGXMIPSFW_LOG2_PAGE_SIZE_4MB (22)
+#define RGXMIPSFW_PAGE_SIZE_4MB (0x1 << RGXMIPSFW_LOG2_PAGE_SIZE_4MB)
+#define RGXMIPSFW_PAGE_MASK_4MB (RGXMIPSFW_PAGE_SIZE_4MB - 1)
+#define RGXMIPSFW_LOG2_PTE_ENTRY_SIZE (2)
+/* log2 page table sizes dependent on FW heap size and page size (for each OS) */
+#define RGXMIPSFW_LOG2_PAGETABLE_SIZE_4K (RGX_FIRMWARE_HEAP_SHIFT - RGXMIPSFW_LOG2_PAGE_SIZE_4K + RGXMIPSFW_LOG2_PTE_ENTRY_SIZE)
+#define RGXMIPSFW_LOG2_PAGETABLE_SIZE_64K (RGX_FIRMWARE_HEAP_SHIFT - RGXMIPSFW_LOG2_PAGE_SIZE_64K + RGXMIPSFW_LOG2_PTE_ENTRY_SIZE)
+/* Maximum number of page table pages (both Host and MIPS pages) */
+#define RGXMIPSFW_MAX_NUM_PAGETABLE_PAGES (4)
+/* Total number of TLB entries */
+#define RGXMIPSFW_NUMBER_OF_TLB_ENTRIES (16)
+/* "Uncached" caching policy */
+#define RGXMIPSFW_UNCACHED_CACHE_POLICY (0X00000002)
+/* "Write-back write-allocate" caching policy */
+#define RGXMIPSFW_WRITEBACK_CACHE_POLICY (0X00000003)
+/* "Write-through no write-allocate" caching policy */
+#define RGXMIPSFW_WRITETHROUGH_CACHE_POLICY (0X00000001)
+/* Cached policy used by MIPS in case of physical bus on 32 bit */
+#define RGXMIPSFW_CACHED_POLICY (RGXMIPSFW_WRITEBACK_CACHE_POLICY)
+/* Cached policy used by MIPS in case of physical bus on more than 32 bit */
+#define RGXMIPSFW_CACHED_POLICY_ABOVE_32BIT (RGXMIPSFW_WRITETHROUGH_CACHE_POLICY)
+/* Total number of Remap entries */
+#define RGXMIPSFW_NUMBER_OF_REMAP_ENTRIES (2 * RGXMIPSFW_NUMBER_OF_TLB_ENTRIES)
+
+
+/*
+ * MIPS EntryLo/PTE format
+ */
+
+#define RGXMIPSFW_ENTRYLO_READ_INHIBIT_SHIFT (31U)
+#define RGXMIPSFW_ENTRYLO_READ_INHIBIT_CLRMSK (0X7FFFFFFF)
+#define RGXMIPSFW_ENTRYLO_READ_INHIBIT_EN (0X80000000)
+
+#define RGXMIPSFW_ENTRYLO_EXEC_INHIBIT_SHIFT (30U)
+#define RGXMIPSFW_ENTRYLO_EXEC_INHIBIT_CLRMSK (0XBFFFFFFF)
+#define RGXMIPSFW_ENTRYLO_EXEC_INHIBIT_EN (0X40000000)
+
+/* Page Frame Number */
+#define RGXMIPSFW_ENTRYLO_PFN_SHIFT (6)
+#define RGXMIPSFW_ENTRYLO_PFN_ALIGNSHIFT (12)
+/* Mask used for the MIPS Page Table in case of physical bus on 32 bit */
+#define RGXMIPSFW_ENTRYLO_PFN_MASK (0x03FFFFC0)
+#define RGXMIPSFW_ENTRYLO_PFN_SIZE (20)
+/* Mask used for the MIPS Page Table in case of physical bus on more than 32 bit */
+#define RGXMIPSFW_ENTRYLO_PFN_MASK_ABOVE_32BIT (0x3FFFFFC0)
+#define RGXMIPSFW_ENTRYLO_PFN_SIZE_ABOVE_32BIT (24)
+#define RGXMIPSFW_ADDR_TO_ENTRYLO_PFN_RSHIFT (RGXMIPSFW_ENTRYLO_PFN_ALIGNSHIFT - \
+ RGXMIPSFW_ENTRYLO_PFN_SHIFT)
+
+#define RGXMIPSFW_ENTRYLO_CACHE_POLICY_SHIFT (3U)
+#define RGXMIPSFW_ENTRYLO_CACHE_POLICY_CLRMSK (0XFFFFFFC7)
+
+#define RGXMIPSFW_ENTRYLO_DIRTY_SHIFT (2U)
+#define RGXMIPSFW_ENTRYLO_DIRTY_CLRMSK (0XFFFFFFFB)
+#define RGXMIPSFW_ENTRYLO_DIRTY_EN (0X00000004)
+
+#define RGXMIPSFW_ENTRYLO_VALID_SHIFT (1U)
+#define RGXMIPSFW_ENTRYLO_VALID_CLRMSK (0XFFFFFFFD)
+#define RGXMIPSFW_ENTRYLO_VALID_EN (0X00000002)
+
+#define RGXMIPSFW_ENTRYLO_GLOBAL_SHIFT (0U)
+#define RGXMIPSFW_ENTRYLO_GLOBAL_CLRMSK (0XFFFFFFFE)
+#define RGXMIPSFW_ENTRYLO_GLOBAL_EN (0X00000001)
+
+#define RGXMIPSFW_ENTRYLO_DVG (RGXMIPSFW_ENTRYLO_DIRTY_EN | \
+ RGXMIPSFW_ENTRYLO_VALID_EN | \
+ RGXMIPSFW_ENTRYLO_GLOBAL_EN)
+#define RGXMIPSFW_ENTRYLO_UNCACHED (RGXMIPSFW_UNCACHED_CACHE_POLICY << \
+ RGXMIPSFW_ENTRYLO_CACHE_POLICY_SHIFT)
+#define RGXMIPSFW_ENTRYLO_DVG_UNCACHED (RGXMIPSFW_ENTRYLO_DVG | RGXMIPSFW_ENTRYLO_UNCACHED)
+
+
+/* Remap Range Config Addr Out */
+/* These defines refer to the upper half of the Remap Range Config register */
+#define RGXMIPSFW_REMAP_RANGE_ADDR_OUT_MASK (0x0FFFFFF0)
+#define RGXMIPSFW_REMAP_RANGE_ADDR_OUT_SHIFT (4) /* wrt upper half of the register */
+#define RGXMIPSFW_REMAP_RANGE_ADDR_OUT_ALIGNSHIFT (12)
+#define RGXMIPSFW_ADDR_TO_RR_ADDR_OUT_RSHIFT (RGXMIPSFW_REMAP_RANGE_ADDR_OUT_ALIGNSHIFT - \
+ RGXMIPSFW_REMAP_RANGE_ADDR_OUT_SHIFT)
+
+#if defined(SECURE_FW_CODE_OSID) && (SECURE_FW_CODE_OSID + 1 > 2)
+#define MIPS_FW_CODE_OSID (SECURE_FW_CODE_OSID)
+#elif defined(SECURE_FW_CODE_OSID)
+#define MIPS_FW_CODE_OSID (1U)
+#endif
+
+
+/*
+ * Pages to trampoline problematic physical addresses:
+ * - RGXMIPSFW_BOOT_REMAP_PHYS_ADDR_IN : 0x1FC0_0000
+ * - RGXMIPSFW_DATA_REMAP_PHYS_ADDR_IN : 0x1FC0_1000
+ * - RGXMIPSFW_CODE_REMAP_PHYS_ADDR_IN : 0x1FC0_2000
+ * - (benign trampoline) : 0x1FC0_3000
+ * that would otherwise be erroneously remapped by the MIPS wrapper
+ * (see "Firmware virtual layout and remap configuration" section below)
+ */
+
+#define RGXMIPSFW_TRAMPOLINE_LOG2_NUMPAGES (2)
+#define RGXMIPSFW_TRAMPOLINE_NUMPAGES (1 << RGXMIPSFW_TRAMPOLINE_LOG2_NUMPAGES)
+#define RGXMIPSFW_TRAMPOLINE_SIZE (RGXMIPSFW_TRAMPOLINE_NUMPAGES << RGXMIPSFW_LOG2_PAGE_SIZE_4K)
+#define RGXMIPSFW_TRAMPOLINE_LOG2_SEGMENT_SIZE (RGXMIPSFW_TRAMPOLINE_LOG2_NUMPAGES + RGXMIPSFW_LOG2_PAGE_SIZE_4K)
+
+#define RGXMIPSFW_TRAMPOLINE_TARGET_PHYS_ADDR (RGXMIPSFW_BOOT_REMAP_PHYS_ADDR_IN)
+#define RGXMIPSFW_TRAMPOLINE_OFFSET(a) (a - RGXMIPSFW_BOOT_REMAP_PHYS_ADDR_IN)
+
+#define RGXMIPSFW_SENSITIVE_ADDR(a) (RGXMIPSFW_BOOT_REMAP_PHYS_ADDR_IN == (~((1UL << RGXMIPSFW_TRAMPOLINE_LOG2_SEGMENT_SIZE)-1) & a))
+
+/*
+ * Firmware virtual layout and remap configuration
+ */
+/*
+ * For each remap region we define:
+ * - the virtual base used by the Firmware to access code/data through that region
+ * - the microAptivAP physical address correspondent to the virtual base address,
+ * used as input address and remapped to the actual physical address
+ * - log2 of size of the region remapped by the MIPS wrapper, i.e. number of bits from
+ * the bottom of the base input address that survive onto the output address
+ * (this defines both the alignment and the maximum size of the remapped region)
+ * - one or more code/data segments within the remapped region
+ */
+
+/* Boot remap setup */
+#define RGXMIPSFW_BOOT_REMAP_VIRTUAL_BASE (0xBFC00000)
+#define RGXMIPSFW_BOOT_REMAP_PHYS_ADDR_IN (0x1FC00000)
+#define RGXMIPSFW_BOOT_REMAP_LOG2_SEGMENT_SIZE (12)
+#define RGXMIPSFW_BOOT_NMI_CODE_VIRTUAL_BASE (RGXMIPSFW_BOOT_REMAP_VIRTUAL_BASE)
+
+/* Data remap setup */
+#define RGXMIPSFW_DATA_REMAP_VIRTUAL_BASE (0xBFC01000)
+#define RGXMIPSFW_DATA_CACHED_REMAP_VIRTUAL_BASE (0x9FC01000)
+#define RGXMIPSFW_DATA_REMAP_PHYS_ADDR_IN (0x1FC01000)
+#define RGXMIPSFW_DATA_REMAP_LOG2_SEGMENT_SIZE (12)
+#define RGXMIPSFW_BOOT_NMI_DATA_VIRTUAL_BASE (RGXMIPSFW_DATA_REMAP_VIRTUAL_BASE)
+
+/* Code remap setup */
+#define RGXMIPSFW_CODE_REMAP_VIRTUAL_BASE (0x9FC02000)
+#define RGXMIPSFW_CODE_REMAP_PHYS_ADDR_IN (0x1FC02000)
+#define RGXMIPSFW_CODE_REMAP_LOG2_SEGMENT_SIZE (12)
+#define RGXMIPSFW_EXCEPTIONS_VIRTUAL_BASE (RGXMIPSFW_CODE_REMAP_VIRTUAL_BASE)
+
+/* Permanent mappings setup */
+#define RGXMIPSFW_PT_VIRTUAL_BASE (0xCF000000)
+#define RGXMIPSFW_REGISTERS_VIRTUAL_BASE (0xCF800000)
+#define RGXMIPSFW_STACK_VIRTUAL_BASE (0xCF600000)
+
+
+/*
+ * Bootloader configuration data
+ */
+/* Bootloader configuration offset (where RGXMIPSFW_BOOT_DATA lives)
+ * within the bootloader/NMI data page */
+#define RGXMIPSFW_BOOTLDR_CONF_OFFSET (0x0)
+
+
+/*
+ * NMI shared data
+ */
+/* Base address of the shared data within the bootloader/NMI data page */
+#define RGXMIPSFW_NMI_SHARED_DATA_BASE (0x100)
+/* Size used by Debug dump data */
+#define RGXMIPSFW_NMI_SHARED_SIZE (0x2B0)
+/* Offsets in the NMI shared area in 32-bit words */
+#define RGXMIPSFW_NMI_SYNC_FLAG_OFFSET (0x0)
+#define RGXMIPSFW_NMI_STATE_OFFSET (0x1)
+#define RGXMIPSFW_NMI_ERROR_STATE_SET (0x1)
+
+/*
+ * MIPS boot stage
+ */
+#define RGXMIPSFW_BOOT_STAGE_OFFSET (0x400)
+
+/*
+ * MIPS private data in the bootloader data page.
+ * Memory below this offset is used by the FW only, no interface data allowed.
+ */
+#define RGXMIPSFW_PRIVATE_DATA_OFFSET (0x800)
+
+
+/* The things that follow are excluded when compiling assembly sources */
+#if !defined(RGXMIPSFW_ASSEMBLY_CODE)
+#include "img_types.h"
+#include "km/rgxdefs_km.h"
+
+typedef struct
+{
+ IMG_UINT64 ui64StackPhyAddr;
+ IMG_UINT64 ui64RegBase;
+ IMG_UINT64 aui64PTPhyAddr[RGXMIPSFW_MAX_NUM_PAGETABLE_PAGES];
+ IMG_UINT32 ui32PTLog2PageSize;
+ IMG_UINT32 ui32PTNumPages;
+ IMG_UINT32 ui32Reserved1;
+ IMG_UINT32 ui32Reserved2;
+} RGXMIPSFW_BOOT_DATA;
+
+#define RGXMIPSFW_GET_OFFSET_IN_DWORDS(offset) (offset / sizeof(IMG_UINT32))
+#define RGXMIPSFW_GET_OFFSET_IN_QWORDS(offset) (offset / sizeof(IMG_UINT64))
+
+/* Used for compatibility checks */
+#define RGXMIPSFW_ARCHTYPE_VER_CLRMSK (0xFFFFE3FFU)
+#define RGXMIPSFW_ARCHTYPE_VER_SHIFT (10U)
+#define RGXMIPSFW_CORE_ID_VALUE (0x001U)
+#define RGXFW_PROCESSOR_MIPS "MIPS"
+
+/* microAptivAP cache line size */
+#define RGXMIPSFW_MICROAPTIVEAP_CACHELINE_SIZE (16U)
+
+/* The SOCIF transactions are identified with the top 16 bits of the physical address emitted by the MIPS */
+#define RGXMIPSFW_WRAPPER_CONFIG_REGBANK_ADDR_ALIGN (16U)
+
+/* Values to put in the MIPS selectors for performance counters */
+#define RGXMIPSFW_PERF_COUNT_CTRL_ICACHE_ACCESSES_C0 (9U) /* Icache accesses in COUNTER0 */
+#define RGXMIPSFW_PERF_COUNT_CTRL_ICACHE_MISSES_C1 (9U) /* Icache misses in COUNTER1 */
+
+#define RGXMIPSFW_PERF_COUNT_CTRL_DCACHE_ACCESSES_C0 (10U) /* Dcache accesses in COUNTER0 */
+#define RGXMIPSFW_PERF_COUNT_CTRL_DCACHE_MISSES_C1 (11U) /* Dcache misses in COUNTER1 */
+
+#define RGXMIPSFW_PERF_COUNT_CTRL_ITLB_INSTR_ACCESSES_C0 (5U) /* ITLB instruction accesses in COUNTER0 */
+#define RGXMIPSFW_PERF_COUNT_CTRL_JTLB_INSTR_MISSES_C1 (7U) /* JTLB instruction accesses misses in COUNTER1 */
+
+#define RGXMIPSFW_PERF_COUNT_CTRL_INSTR_COMPLETED_C0 (1U) /* Instructions completed in COUNTER0 */
+#define RGXMIPSFW_PERF_COUNT_CTRL_JTLB_DATA_MISSES_C1 (8U) /* JTLB data misses in COUNTER1 */
+
+#define RGXMIPSFW_PERF_COUNT_CTRL_EVENT_SHIFT (5U) /* Shift for the Event field in the MIPS perf ctrl registers */
+/* Additional flags for performance counters. See MIPS manual for further reference */
+#define RGXMIPSFW_PERF_COUNT_CTRL_COUNT_USER_MODE (8U)
+#define RGXMIPSFW_PERF_COUNT_CTRL_COUNT_KERNEL_MODE (2U)
+#define RGXMIPSFW_PERF_COUNT_CTRL_COUNT_EXL (1U)
+
+
+#define RGXMIPSFW_C0_NBHWIRQ 8
+
+/* Macros to decode C0_Cause register */
+#define RGXMIPSFW_C0_CAUSE_EXCCODE(CAUSE) (((CAUSE) & 0x7c) >> 2)
+#define RGXMIPSFW_C0_CAUSE_EXCCODE_FWERROR 9
+/* Use only when Coprocessor Unusable exception */
+#define RGXMIPSFW_C0_CAUSE_UNUSABLE_UNIT(CAUSE) (((CAUSE) >> 28) & 0x3)
+#define RGXMIPSFW_C0_CAUSE_PENDING_HWIRQ(CAUSE) (((CAUSE) & 0x3fc00) >> 10)
+#define RGXMIPSFW_C0_CAUSE_FDCIPENDING (1UL << 21)
+#define RGXMIPSFW_C0_CAUSE_IV (1UL << 23)
+#define RGXMIPSFW_C0_CAUSE_IC (1UL << 25)
+#define RGXMIPSFW_C0_CAUSE_PCIPENDING (1UL << 26)
+#define RGXMIPSFW_C0_CAUSE_TIPENDING (1UL << 30)
+#define RGXMIPSFW_C0_CAUSE_BRANCH_DELAY (1UL << 31)
+
+/* Macros to decode C0_Debug register */
+#define RGXMIPSFW_C0_DEBUG_EXCCODE(DEBUG) (((DEBUG) >> 10) & 0x1f)
+#define RGXMIPSFW_C0_DEBUG_DSS (1UL << 0)
+#define RGXMIPSFW_C0_DEBUG_DBP (1UL << 1)
+#define RGXMIPSFW_C0_DEBUG_DDBL (1UL << 2)
+#define RGXMIPSFW_C0_DEBUG_DDBS (1UL << 3)
+#define RGXMIPSFW_C0_DEBUG_DIB (1UL << 4)
+#define RGXMIPSFW_C0_DEBUG_DINT (1UL << 5)
+#define RGXMIPSFW_C0_DEBUG_DIBIMPR (1UL << 6)
+#define RGXMIPSFW_C0_DEBUG_DDBLIMPR (1UL << 18)
+#define RGXMIPSFW_C0_DEBUG_DDBSIMPR (1UL << 19)
+#define RGXMIPSFW_C0_DEBUG_IEXI (1UL << 20)
+#define RGXMIPSFW_C0_DEBUG_DBUSEP (1UL << 21)
+#define RGXMIPSFW_C0_DEBUG_CACHEEP (1UL << 22)
+#define RGXMIPSFW_C0_DEBUG_MCHECKP (1UL << 23)
+#define RGXMIPSFW_C0_DEBUG_IBUSEP (1UL << 24)
+#define RGXMIPSFW_C0_DEBUG_DM (1UL << 30)
+#define RGXMIPSFW_C0_DEBUG_DBD (1UL << 31)
+
+/* Macros to decode TLB entries */
+#define RGXMIPSFW_TLB_GET_MASK(PAGE_MASK) (((PAGE_MASK) >> 13) & 0XFFFFU)
+#define RGXMIPSFW_TLB_GET_PAGE_SIZE(PAGE_MASK) ((((PAGE_MASK) | 0x1FFF) + 1) >> 11) /* page size in KB */
+#define RGXMIPSFW_TLB_GET_PAGE_MASK(PAGE_SIZE) ((((PAGE_SIZE) << 11) - 1) & ~0x7FF) /* page size in KB */
+#define RGXMIPSFW_TLB_GET_VPN2(ENTRY_HI) ((ENTRY_HI) >> 13)
+#define RGXMIPSFW_TLB_GET_COHERENCY(ENTRY_LO) (((ENTRY_LO) >> 3) & 0x7U)
+#define RGXMIPSFW_TLB_GET_PFN(ENTRY_LO) (((ENTRY_LO) >> 6) & 0XFFFFFU)
+/* GET_PA uses a non-standard PFN mask for 36 bit addresses */
+#define RGXMIPSFW_TLB_GET_PA(ENTRY_LO) (((IMG_UINT64)(ENTRY_LO) & RGXMIPSFW_ENTRYLO_PFN_MASK_ABOVE_32BIT) << 6)
+#define RGXMIPSFW_TLB_GET_INHIBIT(ENTRY_LO) (((ENTRY_LO) >> 30) & 0x3U)
+#define RGXMIPSFW_TLB_GET_DGV(ENTRY_LO) ((ENTRY_LO) & 0x7U)
+#define RGXMIPSFW_TLB_GLOBAL (1U)
+#define RGXMIPSFW_TLB_VALID (1U << 1)
+#define RGXMIPSFW_TLB_DIRTY (1U << 2)
+#define RGXMIPSFW_TLB_XI (1U << 30)
+#define RGXMIPSFW_TLB_RI (1U << 31)
+
+typedef struct {
+ IMG_UINT32 ui32TLBPageMask;
+ IMG_UINT32 ui32TLBHi;
+ IMG_UINT32 ui32TLBLo0;
+ IMG_UINT32 ui32TLBLo1;
+} RGX_MIPS_TLB_ENTRY;
+
+typedef struct {
+ IMG_UINT32 ui32RemapAddrIn; /* always 4k aligned */
+ IMG_UINT32 ui32RemapAddrOut; /* always 4k aligned */
+ IMG_UINT32 ui32RemapRegionSize;
+} RGX_MIPS_REMAP_ENTRY;
+
+typedef struct {
+ IMG_UINT32 ui32ErrorState; /* This must come first in the structure */
+ IMG_UINT32 ui32ErrorEPC;
+ IMG_UINT32 ui32StatusRegister;
+ IMG_UINT32 ui32CauseRegister;
+ IMG_UINT32 ui32BadRegister;
+ IMG_UINT32 ui32EPC;
+ IMG_UINT32 ui32SP;
+ IMG_UINT32 ui32Debug;
+ IMG_UINT32 ui32DEPC;
+ IMG_UINT32 ui32BadInstr;
+ IMG_UINT32 ui32UnmappedAddress;
+ RGX_MIPS_TLB_ENTRY asTLB[RGXMIPSFW_NUMBER_OF_TLB_ENTRIES];
+ RGX_MIPS_REMAP_ENTRY asRemap[RGXMIPSFW_NUMBER_OF_REMAP_ENTRIES];
+} RGX_MIPS_STATE;
+
+#endif /* RGXMIPSFW_ASSEMBLY_CODE */
+
+#endif /* RGX_MIPS_H */
diff --git a/drivers/gpu/drm/img-rogue/include/rgx_riscv.h b/drivers/gpu/drm/img-rogue/include/rgx_riscv.h
new file mode 100644
index 000000000..1ce9ab569
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/rgx_riscv.h
@@ -0,0 +1,250 @@
+/*************************************************************************/ /*!
+@File rgx_riscv.h
+@Title
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Platform RGX
+@Description RGX RISCV definitions, kernel/user space
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(RGX_RISCV_H)
+#define RGX_RISCV_H
+
+#include "km/rgxdefs_km.h"
+
+
+/* Utility defines to convert regions to virtual addresses and remaps */
+#define RGXRISCVFW_GET_REGION_BASE(r) IMG_UINT32_C((r) << 28)
+#define RGXRISCVFW_GET_REGION(a) IMG_UINT32_C((a) >> 28)
+#define RGXRISCVFW_MAX_REGION_SIZE IMG_UINT32_C(1 << 28)
+#define RGXRISCVFW_GET_REMAP(r) (RGX_CR_FWCORE_ADDR_REMAP_CONFIG0 + ((r) * 8U))
+
+/* RISCV remap output is aligned to 4K */
+#define RGXRISCVFW_REMAP_CONFIG_DEVVADDR_ALIGN (0x1000U)
+
+/*
+ * FW bootloader defines
+ */
+#define RGXRISCVFW_BOOTLDR_CODE_REGION IMG_UINT32_C(0xC)
+#define RGXRISCVFW_BOOTLDR_DATA_REGION IMG_UINT32_C(0x5)
+#define RGXRISCVFW_BOOTLDR_CODE_BASE (RGXRISCVFW_GET_REGION_BASE(RGXRISCVFW_BOOTLDR_CODE_REGION))
+#define RGXRISCVFW_BOOTLDR_DATA_BASE (RGXRISCVFW_GET_REGION_BASE(RGXRISCVFW_BOOTLDR_DATA_REGION))
+#define RGXRISCVFW_BOOTLDR_CODE_REMAP (RGXRISCVFW_GET_REMAP(RGXRISCVFW_BOOTLDR_CODE_REGION))
+#define RGXRISCVFW_BOOTLDR_DATA_REMAP (RGXRISCVFW_GET_REMAP(RGXRISCVFW_BOOTLDR_DATA_REGION))
+
+/* Bootloader data offset in dwords from the beginning of the FW data allocation */
+#define RGXRISCVFW_BOOTLDR_CONF_OFFSET (0x0)
+
+/*
+ * FW coremem region defines
+ */
+#define RGXRISCVFW_COREMEM_REGION IMG_UINT32_C(0x8)
+#define RGXRISCVFW_COREMEM_MAX_SIZE IMG_UINT32_C(0x10000000) /* 256 MB */
+#define RGXRISCVFW_COREMEM_BASE (RGXRISCVFW_GET_REGION_BASE(RGXRISCVFW_COREMEM_REGION))
+#define RGXRISCVFW_COREMEM_END (RGXRISCVFW_COREMEM_BASE + RGXRISCVFW_COREMEM_MAX_SIZE - 1)
+
+
+/*
+ * Host-FW shared data defines
+ */
+#define RGXRISCVFW_SHARED_CACHED_DATA_REGION (0x6UL)
+#define RGXRISCVFW_SHARED_UNCACHED_DATA_REGION (0xDUL)
+#define RGXRISCVFW_SHARED_CACHED_DATA_BASE (RGXRISCVFW_GET_REGION_BASE(RGXRISCVFW_SHARED_CACHED_DATA_REGION))
+#define RGXRISCVFW_SHARED_UNCACHED_DATA_BASE (RGXRISCVFW_GET_REGION_BASE(RGXRISCVFW_SHARED_UNCACHED_DATA_REGION))
+#define RGXRISCVFW_SHARED_CACHED_DATA_REMAP (RGXRISCVFW_GET_REMAP(RGXRISCVFW_SHARED_CACHED_DATA_REGION))
+#define RGXRISCVFW_SHARED_UNCACHED_DATA_REMAP (RGXRISCVFW_GET_REMAP(RGXRISCVFW_SHARED_UNCACHED_DATA_REGION))
+
+
+/*
+ * GPU SOCIF access defines
+ */
+#define RGXRISCVFW_SOCIF_REGION (0x2U)
+#define RGXRISCVFW_SOCIF_BASE (RGXRISCVFW_GET_REGION_BASE(RGXRISCVFW_SOCIF_REGION))
+
+
+/* The things that follow are excluded when compiling assembly sources */
+#if !defined(RGXRISCVFW_ASSEMBLY_CODE)
+#include "img_types.h"
+
+#define RGXFW_PROCESSOR_RISCV "RISCV"
+#define RGXRISCVFW_CORE_ID_VALUE (0x00450B02U)
+#define RGXRISCVFW_MISA_ADDR (0x301U)
+#define RGXRISCVFW_MISA_VALUE (0x40001104U)
+#define RGXRISCVFW_MSCRATCH_ADDR (0x340U)
+
+typedef struct
+{
+ IMG_UINT64 ui64CorememCodeDevVAddr;
+ IMG_UINT64 ui64CorememDataDevVAddr;
+ IMG_UINT32 ui32CorememCodeFWAddr;
+ IMG_UINT32 ui32CorememDataFWAddr;
+ IMG_UINT32 ui32CorememCodeSize;
+ IMG_UINT32 ui32CorememDataSize;
+ IMG_UINT32 ui32Flags;
+ IMG_UINT32 ui32Reserved;
+} RGXRISCVFW_BOOT_DATA;
+
+/*
+ * List of registers to be printed in debug dump.
+ * First column: register names (general purpose or control/status registers)
+ * Second column: register number to be used in abstract access register command
+ * (see RISC-V debug spec v0.13)
+ */
+#define RGXRISCVFW_DEBUG_DUMP_REGISTERS \
+ X(pc, 0x7b1) /* dpc */ \
+ X(ra, 0x1001) \
+ X(sp, 0x1002) \
+ X(mepc, 0x341) \
+ X(mcause, 0x342) \
+ X(mdseac, 0xfc0) \
+ X(mstatus, 0x300) \
+ X(mie, 0x304) \
+ X(mip, 0x344) \
+ X(mscratch, 0x340) \
+ X(mbvnc0, 0xffe) \
+ X(mbvnc1, 0xfff) \
+ X(micect, 0x7f0) \
+ X(mdcect, 0x7f3) \
+ X(mdcrfct, 0x7f4) \
+
+typedef struct
+{
+#define X(name, address) \
+ IMG_UINT32 name;
+
+ RGXRISCVFW_DEBUG_DUMP_REGISTERS
+#undef X
+} RGXRISCVFW_STATE;
+
+
+#define RGXRISCVFW_MCAUSE_INTERRUPT (1U << 31)
+
+#define RGXRISCVFW_MCAUSE_TABLE \
+ X(0x00000000U, IMG_FALSE, "NMI pin assertion") /* Also reset value */ \
+ X(0x00000001U, IMG_TRUE, "Instruction access fault") \
+ X(0x00000002U, IMG_TRUE, "Illegal instruction") \
+ X(0x00000003U, IMG_TRUE, "Breakpoint") \
+ X(0x00000004U, IMG_TRUE, "Load address misaligned") \
+ X(0x00000005U, IMG_TRUE, "Load access fault") \
+ X(0x00000006U, IMG_TRUE, "Store/AMO address misaligned") \
+ X(0x00000007U, IMG_TRUE, "Store/AMO access fault") \
+ X(0x0000000BU, IMG_TRUE, "Environment call from M-mode (FW assert)") \
+ X(0x80000007U, IMG_FALSE, "Machine timer interrupt") \
+ X(0x8000000BU, IMG_FALSE, "Machine external interrupt") \
+ X(0x8000001EU, IMG_FALSE, "Machine correctable error local interrupt") \
+ X(0xF0000000U, IMG_TRUE, "Machine D-bus store error NMI") \
+ X(0xF0000001U, IMG_TRUE, "Machine D-bus non-blocking load error NMI") \
+ X(0xF0000002U, IMG_TRUE, "dCache unrecoverable NMI")
+
+
+/* Debug module HW defines */
+#define RGXRISCVFW_DMI_COMMAND_ACCESS_REGISTER (0U)
+#define RGXRISCVFW_DMI_COMMAND_ACCESS_MEMORY (2U)
+#define RGXRISCVFW_DMI_COMMAND_AAxSIZE_32BIT (2UL << 20)
+#define RGXRISCVFW_DMI_COMMAND_WRITE (1UL << 16)
+#define RGXRISCVFW_DMI_COMMAND_READ (0UL << 16)
+#define RGXRISCVFW_DMI_SBCS_SBACCESS_32BIT (2U)
+
+/* Abstract command error codes (descriptions from RISC-V debug spec v0.13) */
+typedef enum
+{
+ /* No error. */
+ RISCV_ABSTRACT_CMD_NO_ERROR = 0,
+
+ /*
+ * An abstract command was executing while command, abstractcs, or abstractauto
+ * was written, or when one of the data or progbuf registers was read or
+ * written. This status is only written if cmderr contains 0.
+ */
+ RISCV_ABSTRACT_CMD_BUSY = 1,
+
+ /*
+ * The requested command is not supported, regardless of whether
+ * the hart is running or not.
+ */
+ RISCV_ABSTRACT_CMD_NOT_SUPPORTED = 2,
+
+ /*
+ * An exception occurred while executing the command
+ * (e.g. while executing the Program Buffer).
+ */
+ RISCV_ABSTRACT_CMD_EXCEPTION = 3,
+
+ /*
+ * The abstract command couldn't execute because the hart wasn't in the required
+ * state (running/halted), or unavailable.
+ */
+ RISCV_ABSTRACT_CMD_HALT_RESUME = 4,
+
+ /*
+ * The abstract command failed due to a bus error
+ * (e.g. alignment, access size, or timeout).
+ */
+ RISCV_ABSTRACT_CMD_BUS_ERROR = 5,
+
+ /* The command failed for another reason. */
+ RISCV_ABSTRACT_CMD_OTHER_ERROR = 7
+
+} RGXRISCVFW_ABSTRACT_CMD_ERR;
+
+/* System Bus error codes (descriptions from RISC-V debug spec v0.13) */
+typedef enum
+{
+ /* There was no bus error. */
+ RISCV_SYSBUS_NO_ERROR = 0,
+
+ /* There was a timeout. */
+ RISCV_SYSBUS_TIMEOUT = 1,
+
+ /* A bad address was accessed. */
+ RISCV_SYSBUS_BAD_ADDRESS = 2,
+
+ /* There was an alignment error. */
+ RISCV_SYSBUS_BAD_ALIGNMENT = 3,
+
+ /* An access of unsupported size was requested. */
+ RISCV_SYSBUS_UNSUPPORTED_SIZE = 4,
+
+ /* Other. */
+ RISCV_SYSBUS_OTHER_ERROR = 7
+
+} RGXRISCVFW_SYSBUS_ERR;
+
+#endif /* RGXRISCVFW_ASSEMBLY_CODE */
+
+#endif /* RGX_RISCV_H */
diff --git a/drivers/gpu/drm/img-rogue/include/rgxfw_log_helper.h b/drivers/gpu/drm/img-rogue/include/rgxfw_log_helper.h
new file mode 100644
index 000000000..275b63aca
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/rgxfw_log_helper.h
@@ -0,0 +1,79 @@
+/*************************************************************************/ /*!
+@File rgxfw_log_helper.h
+@Title Firmware TBI logging helper function
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Platform Generic
+@Description This file contains some helper code to make TBI logging possible
+ Specifically, it uses the SFIDLIST xmacro to trace ids back to
+ the original strings.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef RGXFW_LOG_HELPER_H
+#define RGXFW_LOG_HELPER_H
+
+#include "rgx_fwif_sf.h"
+
+static const IMG_CHAR *const groups[]= {
+#define X(A,B) #B,
+ RGXFW_LOG_SFGROUPLIST
+#undef X
+};
+
+/* idToStringID : Search SFs tuples {id,string} for a matching id.
+ * return index to array if found or RGXFW_SF_LAST if none found.
+ * bsearch could be used as ids are in increasing order. */
+#if defined(RGX_FIRMWARE)
+static IMG_UINT32 idToStringID(IMG_UINT32 ui32CheckData, const RGXFW_STID_FMT *const psSFs)
+#else
+static IMG_UINT32 idToStringID(IMG_UINT32 ui32CheckData, const RGXKM_STID_FMT *const psSFs)
+#endif
+{
+ IMG_UINT32 i = 0, ui32Id = (IMG_UINT32)RGXFW_SF_LAST;
+
+ for ( i = 0 ; psSFs[i].ui32Id != (IMG_UINT32)RGXFW_SF_LAST ; i++)
+ {
+ if ( ui32CheckData == psSFs[i].ui32Id )
+ {
+ ui32Id = i;
+ break;
+ }
+ }
+ return ui32Id;
+}
+
+#endif /* RGXFW_LOG_HELPER_H */
diff --git a/drivers/gpu/drm/img-rogue/include/ri_typedefs.h b/drivers/gpu/drm/img-rogue/include/ri_typedefs.h
new file mode 100644
index 000000000..77be10e2a
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/ri_typedefs.h
@@ -0,0 +1,52 @@
+/*************************************************************************/ /*!
+@File
+@Title Resource Information (RI) Management
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Client side part of RI management
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef RI_TYPEDEFS_H
+#define RI_TYPEDEFS_H
+
+#include "img_types.h"
+
+typedef struct RI_SUBLIST_ENTRY RI_ENTRY;
+typedef RI_ENTRY* RI_HANDLE;
+
+#endif /* #ifndef RI_TYPEDEFS_H */
diff --git a/drivers/gpu/drm/img-rogue/include/rogue/rgx_fwif_alignchecks.h b/drivers/gpu/drm/img-rogue/include/rogue/rgx_fwif_alignchecks.h
new file mode 100644
index 000000000..4f82b2374
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/rogue/rgx_fwif_alignchecks.h
@@ -0,0 +1,192 @@
+/*************************************************************************/ /*!
+@File
+@Title RGX fw interface alignment checks
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Checks to avoid disalignment in RGX fw data structures
+ shared with the host
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(RGX_FWIF_ALIGNCHECKS_H)
+#define RGX_FWIF_ALIGNCHECKS_H
+
+/* for the offsetof macro */
+#if defined(__KERNEL__) && defined(__linux__)
+#include
+#else
+#include
+#endif
+
+/*!
+ ******************************************************************************
+ * Alignment UM/FW checks array
+ *****************************************************************************/
+
+#define RGXFW_ALIGN_CHECKS_UM_MAX 128U
+
+#define RGXFW_ALIGN_CHECKS_INIT0 \
+ sizeof(RGXFWIF_TRACEBUF), \
+ offsetof(RGXFWIF_TRACEBUF, ui32LogType), \
+ offsetof(RGXFWIF_TRACEBUF, sTraceBuf), \
+ offsetof(RGXFWIF_TRACEBUF, ui32TraceBufSizeInDWords), \
+ offsetof(RGXFWIF_TRACEBUF, ui32TracebufFlags), \
+ \
+ sizeof(RGXFWIF_SYSDATA), \
+ offsetof(RGXFWIF_SYSDATA, ePowState), \
+ offsetof(RGXFWIF_SYSDATA, ui32HWPerfDropCount), \
+ offsetof(RGXFWIF_SYSDATA, ui32LastDropOrdinal), \
+ offsetof(RGXFWIF_SYSDATA, ui32FWFaults), \
+ offsetof(RGXFWIF_SYSDATA, ui32HWRStateFlags), \
+ \
+ sizeof(RGXFWIF_OSDATA), \
+ offsetof(RGXFWIF_OSDATA, ui32HostSyncCheckMark), \
+ offsetof(RGXFWIF_OSDATA, ui32KCCBCmdsExecuted), \
+ \
+ sizeof(RGXFWIF_HWRINFOBUF), \
+ offsetof(RGXFWIF_HWRINFOBUF, aui32HwrDmLockedUpCount), \
+ offsetof(RGXFWIF_HWRINFOBUF, aui32HwrDmOverranCount), \
+ offsetof(RGXFWIF_HWRINFOBUF, aui32HwrDmRecoveredCount), \
+ offsetof(RGXFWIF_HWRINFOBUF, aui32HwrDmFalseDetectCount), \
+ \
+ /* RGXFWIF_CMDTA checks */ \
+ sizeof(RGXFWIF_CMDTA), \
+ offsetof(RGXFWIF_CMDTA, sGeomRegs), \
+ \
+ /* RGXFWIF_CMD3D checks */ \
+ sizeof(RGXFWIF_CMD3D), \
+ offsetof(RGXFWIF_CMD3D, s3DRegs), \
+ \
+ /* RGXFWIF_CMDTRANSFER checks */ \
+ sizeof(RGXFWIF_CMDTRANSFER), \
+ offsetof(RGXFWIF_CMDTRANSFER, sTransRegs), \
+ \
+ \
+ /* RGXFWIF_CMD_COMPUTE checks */ \
+ sizeof(RGXFWIF_CMD_COMPUTE), \
+ offsetof(RGXFWIF_CMD_COMPUTE, sCDMRegs), \
+ \
+ /* RGXFWIF_FREELIST checks */ \
+ sizeof(RGXFWIF_FREELIST), \
+ offsetof(RGXFWIF_FREELIST, psFreeListDevVAddr), \
+ offsetof(RGXFWIF_FREELIST, ui32MaxPages), \
+ offsetof(RGXFWIF_FREELIST, ui32CurrentPages), \
+ \
+ /* RGXFWIF_HWRTDATA checks */ \
+ sizeof(RGXFWIF_HWRTDATA), \
+ offsetof(RGXFWIF_HWRTDATA, psVHeapTableDevVAddr), \
+ offsetof(RGXFWIF_HWRTDATA, psPMMListDevVAddr), \
+ offsetof(RGXFWIF_HWRTDATA, apsFreeLists), \
+ offsetof(RGXFWIF_HWRTDATA, ui64VCECatBase), \
+ offsetof(RGXFWIF_HWRTDATA, eState), \
+ \
+ /* RGXFWIF_HWRTDATA_COMMON checks */ \
+ sizeof(RGXFWIF_HWRTDATA_COMMON), \
+ offsetof(RGXFWIF_HWRTDATA_COMMON, bTACachesNeedZeroing),\
+ \
+ /* RGXFWIF_HWPERF_CTL_BLK checks */ \
+ sizeof(RGXFWIF_HWPERF_CTL_BLK), \
+ offsetof(RGXFWIF_HWPERF_CTL_BLK, aui64CounterCfg), \
+ \
+ /* RGXFWIF_HWPERF_CTL checks */ \
+ sizeof(RGXFWIF_HWPERF_CTL), \
+ offsetof(RGXFWIF_HWPERF_CTL, SelCntr)
+
+#if defined(RGX_FEATURE_TLA)
+#define RGXFW_ALIGN_CHECKS_INIT1 \
+ RGXFW_ALIGN_CHECKS_INIT0, \
+ /* RGXFWIF_CMD2D checks */ \
+ sizeof(RGXFWIF_CMD2D), \
+ offsetof(RGXFWIF_CMD2D, s2DRegs)
+#else
+#define RGXFW_ALIGN_CHECKS_INIT1 RGXFW_ALIGN_CHECKS_INIT0
+#endif /* RGX_FEATURE_TLA */
+
+
+#if defined(RGX_FEATURE_FASTRENDER_DM)
+#define RGXFW_ALIGN_CHECKS_INIT \
+ RGXFW_ALIGN_CHECKS_INIT1, \
+ /* RGXFWIF_CMDTDM checks */ \
+ sizeof(RGXFWIF_CMDTDM), \
+ offsetof(RGXFWIF_CMDTDM, sTDMRegs)
+#else
+#define RGXFW_ALIGN_CHECKS_INIT RGXFW_ALIGN_CHECKS_INIT1
+#endif /* ! RGX_FEATURE_FASTRENDER_DM */
+
+
+
+/*!
+ ******************************************************************************
+ * Alignment KM checks array
+ *****************************************************************************/
+
+#define RGXFW_ALIGN_CHECKS_INIT_KM \
+ sizeof(RGXFWIF_SYSINIT), \
+ offsetof(RGXFWIF_SYSINIT, sFaultPhysAddr), \
+ offsetof(RGXFWIF_SYSINIT, sPDSExecBase), \
+ offsetof(RGXFWIF_SYSINIT, sUSCExecBase), \
+ offsetof(RGXFWIF_SYSINIT, asSigBufCtl), \
+ offsetof(RGXFWIF_SYSINIT, sTraceBufCtl), \
+ offsetof(RGXFWIF_SYSINIT, sFwSysData), \
+ sizeof(RGXFWIF_OSINIT), \
+ offsetof(RGXFWIF_OSINIT, psKernelCCBCtl), \
+ offsetof(RGXFWIF_OSINIT, psKernelCCB), \
+ offsetof(RGXFWIF_OSINIT, psFirmwareCCBCtl), \
+ offsetof(RGXFWIF_OSINIT, psFirmwareCCB), \
+ offsetof(RGXFWIF_OSINIT, sFwOsData), \
+ offsetof(RGXFWIF_OSINIT, sRGXCompChecks), \
+ \
+ /* RGXFWIF_FWRENDERCONTEXT checks */ \
+ sizeof(RGXFWIF_FWRENDERCONTEXT), \
+ offsetof(RGXFWIF_FWRENDERCONTEXT, sTAContext), \
+ offsetof(RGXFWIF_FWRENDERCONTEXT, s3DContext), \
+ \
+ sizeof(RGXFWIF_FWCOMMONCONTEXT), \
+ offsetof(RGXFWIF_FWCOMMONCONTEXT, psFWMemContext), \
+ offsetof(RGXFWIF_FWCOMMONCONTEXT, sRunNode), \
+ offsetof(RGXFWIF_FWCOMMONCONTEXT, psCCB), \
+ \
+ sizeof(RGXFWIF_MMUCACHEDATA), \
+ offsetof(RGXFWIF_MMUCACHEDATA, ui32CacheFlags), \
+ offsetof(RGXFWIF_MMUCACHEDATA, sMMUCacheSync), \
+ offsetof(RGXFWIF_MMUCACHEDATA, ui32MMUCacheSyncUpdateValue)
+
+#endif /* RGX_FWIF_ALIGNCHECKS_H */
+
+/******************************************************************************
+ End of file (rgx_fwif_alignchecks.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/rogue/rgx_fwif_hwperf.h b/drivers/gpu/drm/img-rogue/include/rogue/rgx_fwif_hwperf.h
new file mode 100644
index 000000000..a75a07b55
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/rogue/rgx_fwif_hwperf.h
@@ -0,0 +1,224 @@
+/*************************************************************************/ /*!
+@File rgx_fwif_hwperf.h
+@Title RGX HWPerf support
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Shared header between RGX firmware and Init process
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef RGX_FWIF_HWPERF_H
+#define RGX_FWIF_HWPERF_H
+
+#include "rgx_fwif_shared.h"
+#include "rgx_hwperf.h"
+#include "rgxdefs_km.h"
+
+
+/*****************************************************************************/
+
+/* Structure to hold a block's parameters for passing between the BG context
+ * and the IRQ context when applying a configuration request. */
+typedef struct
+{
+ IMG_BOOL bValid;
+ IMG_BOOL bEnabled;
+ IMG_UINT32 eBlockID;
+ IMG_UINT32 uiCounterMask;
+ IMG_UINT64 RGXFW_ALIGN aui64CounterCfg[RGX_CNTBLK_MUX_COUNTERS_MAX];
+} RGXFWIF_HWPERF_CTL_BLK;
+
+/* Structure used to hold the configuration of the non-mux counters blocks */
+typedef struct
+{
+ IMG_UINT32 ui32NumSelectedCounters;
+ IMG_UINT32 aui32SelectedCountersIDs[RGX_HWPERF_MAX_CUSTOM_CNTRS];
+} RGXFW_HWPERF_SELECT;
+
+/* Structure to hold the whole configuration request details for all blocks
+ * The block masks and counts are used to optimise reading of this data. */
+typedef struct
+{
+ IMG_UINT32 ui32HWPerfCtlFlags;
+
+ IMG_UINT32 ui32SelectedCountersBlockMask;
+ RGXFW_HWPERF_SELECT RGXFW_ALIGN SelCntr[RGX_HWPERF_MAX_CUSTOM_BLKS];
+
+ IMG_UINT32 ui32EnabledBlksCount;
+ RGXFWIF_HWPERF_CTL_BLK RGXFW_ALIGN sBlkCfg[RGX_HWPERF_MAX_DEFINED_BLKS];
+} UNCACHED_ALIGN RGXFWIF_HWPERF_CTL;
+
+/* NOTE: The switch statement in this function must be kept in alignment with
+ * the enumeration RGX_HWPERF_CNTBLK_ID defined in rgx_hwperf.h. ASSERTs may
+ * result if not.
+ * The function provides a hash lookup to get a handle on the global store for
+ * a block's configuration store from it's block ID.
+ */
+#ifdef INLINE_IS_PRAGMA
+#pragma inline(rgxfw_hwperf_get_block_ctl)
+#endif
+static INLINE RGXFWIF_HWPERF_CTL_BLK* rgxfw_hwperf_get_block_ctl(
+ RGX_HWPERF_CNTBLK_ID eBlockID, RGXFWIF_HWPERF_CTL *psHWPerfInitData)
+{
+ IMG_UINT32 ui32Idx;
+
+ /* Hash the block ID into a control configuration array index */
+ switch (eBlockID)
+ {
+ case RGX_CNTBLK_ID_TA:
+ case RGX_CNTBLK_ID_RASTER:
+ case RGX_CNTBLK_ID_HUB:
+ case RGX_CNTBLK_ID_TORNADO:
+ case RGX_CNTBLK_ID_JONES:
+ {
+ ui32Idx = eBlockID;
+ break;
+ }
+ case RGX_CNTBLK_ID_TPU_MCU0:
+ case RGX_CNTBLK_ID_TPU_MCU1:
+ case RGX_CNTBLK_ID_TPU_MCU2:
+ case RGX_CNTBLK_ID_TPU_MCU3:
+ case RGX_CNTBLK_ID_TPU_MCU4:
+ case RGX_CNTBLK_ID_TPU_MCU5:
+ case RGX_CNTBLK_ID_TPU_MCU6:
+ case RGX_CNTBLK_ID_TPU_MCU7:
+ {
+ ui32Idx = RGX_CNTBLK_ID_DIRECT_LAST +
+ (eBlockID & RGX_CNTBLK_ID_UNIT_MASK);
+ break;
+ }
+ case RGX_CNTBLK_ID_USC0:
+ case RGX_CNTBLK_ID_USC1:
+ case RGX_CNTBLK_ID_USC2:
+ case RGX_CNTBLK_ID_USC3:
+ case RGX_CNTBLK_ID_USC4:
+ case RGX_CNTBLK_ID_USC5:
+ case RGX_CNTBLK_ID_USC6:
+ case RGX_CNTBLK_ID_USC7:
+ case RGX_CNTBLK_ID_USC8:
+ case RGX_CNTBLK_ID_USC9:
+ case RGX_CNTBLK_ID_USC10:
+ case RGX_CNTBLK_ID_USC11:
+ case RGX_CNTBLK_ID_USC12:
+ case RGX_CNTBLK_ID_USC13:
+ case RGX_CNTBLK_ID_USC14:
+ case RGX_CNTBLK_ID_USC15:
+ {
+ ui32Idx = RGX_CNTBLK_ID_DIRECT_LAST +
+ RGX_CNTBLK_INDIRECT_COUNT(TPU_MCU, 7) +
+ (eBlockID & RGX_CNTBLK_ID_UNIT_MASK);
+ break;
+ }
+ case RGX_CNTBLK_ID_TEXAS0:
+ case RGX_CNTBLK_ID_TEXAS1:
+ case RGX_CNTBLK_ID_TEXAS2:
+ case RGX_CNTBLK_ID_TEXAS3:
+ case RGX_CNTBLK_ID_TEXAS4:
+ case RGX_CNTBLK_ID_TEXAS5:
+ case RGX_CNTBLK_ID_TEXAS6:
+ case RGX_CNTBLK_ID_TEXAS7:
+ {
+ ui32Idx = RGX_CNTBLK_ID_DIRECT_LAST +
+ RGX_CNTBLK_INDIRECT_COUNT(TPU_MCU, 7) +
+ RGX_CNTBLK_INDIRECT_COUNT(USC, 15) +
+ (eBlockID & RGX_CNTBLK_ID_UNIT_MASK);
+ break;
+ }
+ case RGX_CNTBLK_ID_RASTER0:
+ case RGX_CNTBLK_ID_RASTER1:
+ case RGX_CNTBLK_ID_RASTER2:
+ case RGX_CNTBLK_ID_RASTER3:
+ {
+ ui32Idx = RGX_CNTBLK_ID_DIRECT_LAST +
+ RGX_CNTBLK_INDIRECT_COUNT(TPU_MCU, 7) +
+ RGX_CNTBLK_INDIRECT_COUNT(USC, 15) +
+ RGX_CNTBLK_INDIRECT_COUNT(TEXAS, 7) +
+ (eBlockID & RGX_CNTBLK_ID_UNIT_MASK);
+ break;
+ }
+ case RGX_CNTBLK_ID_BLACKPEARL0:
+ case RGX_CNTBLK_ID_BLACKPEARL1:
+ case RGX_CNTBLK_ID_BLACKPEARL2:
+ case RGX_CNTBLK_ID_BLACKPEARL3:
+ {
+ ui32Idx = RGX_CNTBLK_ID_DIRECT_LAST +
+ RGX_CNTBLK_INDIRECT_COUNT(TPU_MCU, 7) +
+ RGX_CNTBLK_INDIRECT_COUNT(USC, 15) +
+ RGX_CNTBLK_INDIRECT_COUNT(TEXAS, 7) +
+ RGX_CNTBLK_INDIRECT_COUNT(RASTER, 3) +
+ (eBlockID & RGX_CNTBLK_ID_UNIT_MASK);
+ break;
+ }
+ case RGX_CNTBLK_ID_PBE0:
+ case RGX_CNTBLK_ID_PBE1:
+ case RGX_CNTBLK_ID_PBE2:
+ case RGX_CNTBLK_ID_PBE3:
+ case RGX_CNTBLK_ID_PBE4:
+ case RGX_CNTBLK_ID_PBE5:
+ case RGX_CNTBLK_ID_PBE6:
+ case RGX_CNTBLK_ID_PBE7:
+ case RGX_CNTBLK_ID_PBE8:
+ case RGX_CNTBLK_ID_PBE9:
+ case RGX_CNTBLK_ID_PBE10:
+ case RGX_CNTBLK_ID_PBE11:
+ case RGX_CNTBLK_ID_PBE12:
+ case RGX_CNTBLK_ID_PBE13:
+ case RGX_CNTBLK_ID_PBE14:
+ case RGX_CNTBLK_ID_PBE15:
+ {
+ ui32Idx = RGX_CNTBLK_ID_DIRECT_LAST +
+ RGX_CNTBLK_INDIRECT_COUNT(TPU_MCU, 7) +
+ RGX_CNTBLK_INDIRECT_COUNT(USC, 15) +
+ RGX_CNTBLK_INDIRECT_COUNT(TEXAS, 7) +
+ RGX_CNTBLK_INDIRECT_COUNT(RASTER, 3) +
+ RGX_CNTBLK_INDIRECT_COUNT(BLACKPEARL, 3) +
+ (eBlockID & RGX_CNTBLK_ID_UNIT_MASK);
+ break;
+ }
+ default:
+ {
+ ui32Idx = RGX_HWPERF_MAX_DEFINED_BLKS;
+ break;
+ }
+ }
+ if (ui32Idx >= RGX_HWPERF_MAX_DEFINED_BLKS)
+ {
+ return NULL;
+ }
+ return &psHWPerfInitData->sBlkCfg[ui32Idx];
+}
+
+#endif
diff --git a/drivers/gpu/drm/img-rogue/include/rogue/rgx_fwif_km.h b/drivers/gpu/drm/img-rogue/include/rogue/rgx_fwif_km.h
new file mode 100644
index 000000000..16f5cd489
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/rogue/rgx_fwif_km.h
@@ -0,0 +1,2319 @@
+/*************************************************************************/ /*!
+@File
+@Title RGX firmware interface structures used by pvrsrvkm
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description RGX firmware interface structures used by pvrsrvkm
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(RGX_FWIF_KM_H)
+#define RGX_FWIF_KM_H
+
+#include "img_types.h"
+#include "rgx_fwif_shared.h"
+#include "rgxdefs_km.h"
+#include "dllist.h"
+#include "rgx_hwperf.h"
+
+
+/*************************************************************************/ /*!
+ Logging type
+*/ /**************************************************************************/
+#define RGXFWIF_LOG_TYPE_NONE 0x00000000U
+#define RGXFWIF_LOG_TYPE_TRACE 0x00000001U
+#define RGXFWIF_LOG_TYPE_GROUP_MAIN 0x00000002U
+#define RGXFWIF_LOG_TYPE_GROUP_MTS 0x00000004U
+#define RGXFWIF_LOG_TYPE_GROUP_CLEANUP 0x00000008U
+#define RGXFWIF_LOG_TYPE_GROUP_CSW 0x00000010U
+#define RGXFWIF_LOG_TYPE_GROUP_BIF 0x00000020U
+#define RGXFWIF_LOG_TYPE_GROUP_PM 0x00000040U
+#define RGXFWIF_LOG_TYPE_GROUP_RTD 0x00000080U
+#define RGXFWIF_LOG_TYPE_GROUP_SPM 0x00000100U
+#define RGXFWIF_LOG_TYPE_GROUP_POW 0x00000200U
+#define RGXFWIF_LOG_TYPE_GROUP_HWR 0x00000400U
+#define RGXFWIF_LOG_TYPE_GROUP_HWP 0x00000800U
+#define RGXFWIF_LOG_TYPE_GROUP_RPM 0x00001000U
+#define RGXFWIF_LOG_TYPE_GROUP_DMA 0x00002000U
+#define RGXFWIF_LOG_TYPE_GROUP_MISC 0x00004000U
+#define RGXFWIF_LOG_TYPE_GROUP_DEBUG 0x80000000U
+#define RGXFWIF_LOG_TYPE_GROUP_MASK 0x80007FFEU
+#define RGXFWIF_LOG_TYPE_MASK 0x80007FFFU
+
+/* String used in pvrdebug -h output */
+#define RGXFWIF_LOG_GROUPS_STRING_LIST "main,mts,cleanup,csw,bif,pm,rtd,spm,pow,hwr,hwp,rpm,dma,misc,debug"
+
+/* Table entry to map log group strings to log type value */
+typedef struct {
+ const IMG_CHAR* pszLogGroupName;
+ IMG_UINT32 ui32LogGroupType;
+} RGXFWIF_LOG_GROUP_MAP_ENTRY;
+
+/*
+ Macro for use with the RGXFWIF_LOG_GROUP_MAP_ENTRY type to create a lookup
+ table where needed. Keep log group names short, no more than 20 chars.
+*/
+#define RGXFWIF_LOG_GROUP_NAME_VALUE_MAP { "none", RGXFWIF_LOG_TYPE_NONE }, \
+ { "main", RGXFWIF_LOG_TYPE_GROUP_MAIN }, \
+ { "mts", RGXFWIF_LOG_TYPE_GROUP_MTS }, \
+ { "cleanup", RGXFWIF_LOG_TYPE_GROUP_CLEANUP }, \
+ { "csw", RGXFWIF_LOG_TYPE_GROUP_CSW }, \
+ { "bif", RGXFWIF_LOG_TYPE_GROUP_BIF }, \
+ { "pm", RGXFWIF_LOG_TYPE_GROUP_PM }, \
+ { "rtd", RGXFWIF_LOG_TYPE_GROUP_RTD }, \
+ { "spm", RGXFWIF_LOG_TYPE_GROUP_SPM }, \
+ { "pow", RGXFWIF_LOG_TYPE_GROUP_POW }, \
+ { "hwr", RGXFWIF_LOG_TYPE_GROUP_HWR }, \
+ { "hwp", RGXFWIF_LOG_TYPE_GROUP_HWP }, \
+ { "rpm", RGXFWIF_LOG_TYPE_GROUP_RPM }, \
+ { "dma", RGXFWIF_LOG_TYPE_GROUP_DMA }, \
+ { "misc", RGXFWIF_LOG_TYPE_GROUP_MISC }, \
+ { "debug", RGXFWIF_LOG_TYPE_GROUP_DEBUG }
+
+
+/* Used in print statements to display log group state, one %s per group defined */
+#define RGXFWIF_LOG_ENABLED_GROUPS_LIST_PFSPEC "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
+
+/* Used in a print statement to display log group state, one per group */
+#define RGXFWIF_LOG_ENABLED_GROUPS_LIST(types) (((types) & RGXFWIF_LOG_TYPE_GROUP_MAIN) ?("main ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_MTS) ?("mts ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_CLEANUP) ?("cleanup ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_CSW) ?("csw ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_BIF) ?("bif ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_PM) ?("pm ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_RTD) ?("rtd ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_SPM) ?("spm ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_POW) ?("pow ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_HWR) ?("hwr ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_HWP) ?("hwp ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_RPM) ?("rpm ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_DMA) ?("dma ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_MISC) ?("misc ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_DEBUG) ?("debug ") :(""))
+
+
+/************************************************************************
+* RGX FW signature checks
+************************************************************************/
+#define RGXFW_SIG_BUFFER_SIZE_MIN (8192)
+
+#define RGXFWIF_TIMEDIFF_ID ((0x1UL << 28) | RGX_CR_TIMER)
+
+/*!
+ ******************************************************************************
+ * Trace Buffer
+ *****************************************************************************/
+
+/*! Default size of RGXFWIF_TRACEBUF_SPACE in DWords */
+#define RGXFW_TRACE_BUF_DEFAULT_SIZE_IN_DWORDS 12000U
+#define RGXFW_TRACE_BUFFER_ASSERT_SIZE 200U
+#if defined(RGXFW_META_SUPPORT_2ND_THREAD)
+#define RGXFW_THREAD_NUM 2U
+#else
+#define RGXFW_THREAD_NUM 1U
+#endif
+
+#define RGXFW_POLL_TYPE_SET 0x80000000U
+
+typedef struct
+{
+ IMG_CHAR szPath[RGXFW_TRACE_BUFFER_ASSERT_SIZE];
+ IMG_CHAR szInfo[RGXFW_TRACE_BUFFER_ASSERT_SIZE];
+ IMG_UINT32 ui32LineNum;
+} UNCACHED_ALIGN RGXFWIF_FILE_INFO_BUF;
+
+typedef struct
+{
+ IMG_UINT32 ui32TracePointer;
+
+#if defined(RGX_FIRMWARE)
+ IMG_UINT32 *pui32RGXFWIfTraceBuffer; /* To be used by firmware for writing into trace buffer */
+#else
+ RGXFWIF_DEV_VIRTADDR pui32RGXFWIfTraceBuffer;
+#endif
+ IMG_PUINT32 pui32TraceBuffer; /* To be used by host when reading from trace buffer */
+
+ RGXFWIF_FILE_INFO_BUF sAssertBuf;
+} UNCACHED_ALIGN RGXFWIF_TRACEBUF_SPACE;
+
+#define RGXFWIF_FWFAULTINFO_MAX (8U) /* Total number of FW fault logs stored */
+
+typedef struct
+{
+ IMG_UINT64 RGXFW_ALIGN ui64CRTimer;
+ IMG_UINT64 RGXFW_ALIGN ui64OSTimer;
+ IMG_UINT32 RGXFW_ALIGN ui32Data;
+ IMG_UINT32 ui32Reserved;
+ RGXFWIF_FILE_INFO_BUF sFaultBuf;
+} UNCACHED_ALIGN RGX_FWFAULTINFO;
+
+
+#define RGXFWIF_POW_STATES \
+ X(RGXFWIF_POW_OFF) /* idle and handshaked with the host (ready to full power down) */ \
+ X(RGXFWIF_POW_ON) /* running HW commands */ \
+ X(RGXFWIF_POW_FORCED_IDLE) /* forced idle */ \
+ X(RGXFWIF_POW_IDLE) /* idle waiting for host handshake */
+
+typedef enum
+{
+#define X(NAME) NAME,
+ RGXFWIF_POW_STATES
+#undef X
+} RGXFWIF_POW_STATE;
+
+/* Firmware HWR states */
+#define RGXFWIF_HWR_HARDWARE_OK (IMG_UINT32_C(0x1) << 0U) /*!< The HW state is ok or locked up */
+#define RGXFWIF_HWR_RESET_IN_PROGRESS (IMG_UINT32_C(0x1) << 1U) /*!< Tells if a HWR reset is in progress */
+#define RGXFWIF_HWR_GENERAL_LOCKUP (IMG_UINT32_C(0x1) << 3U) /*!< A DM unrelated lockup has been detected */
+#define RGXFWIF_HWR_DM_RUNNING_OK (IMG_UINT32_C(0x1) << 4U) /*!< At least one DM is running without being close to a lockup */
+#define RGXFWIF_HWR_DM_STALLING (IMG_UINT32_C(0x1) << 5U) /*!< At least one DM is close to lockup */
+#define RGXFWIF_HWR_FW_FAULT (IMG_UINT32_C(0x1) << 6U) /*!< The FW has faulted and needs to restart */
+#define RGXFWIF_HWR_RESTART_REQUESTED (IMG_UINT32_C(0x1) << 7U) /*!< The FW has requested the host to restart it */
+
+#define RGXFWIF_PHR_STATE_SHIFT (8U)
+#define RGXFWIF_PHR_RESTART_REQUESTED (IMG_UINT32_C(1) << RGXFWIF_PHR_STATE_SHIFT) /*!< The FW has requested the host to restart it, per PHR configuration */
+#define RGXFWIF_PHR_RESTART_FINISHED (IMG_UINT32_C(2) << RGXFWIF_PHR_STATE_SHIFT) /*!< A PHR triggered GPU reset has just finished */
+#define RGXFWIF_PHR_RESTART_MASK (RGXFWIF_PHR_RESTART_REQUESTED | RGXFWIF_PHR_RESTART_FINISHED)
+
+#define RGXFWIF_PHR_MODE_OFF (0UL)
+#define RGXFWIF_PHR_MODE_RD_RESET (1UL)
+#define RGXFWIF_PHR_MODE_FULL_RESET (2UL)
+
+typedef IMG_UINT32 RGXFWIF_HWR_STATEFLAGS;
+
+/* Firmware per-DM HWR states */
+#define RGXFWIF_DM_STATE_WORKING (0x00U) /*!< DM is working if all flags are cleared */
+#define RGXFWIF_DM_STATE_READY_FOR_HWR (IMG_UINT32_C(0x1) << 0) /*!< DM is idle and ready for HWR */
+#define RGXFWIF_DM_STATE_NEEDS_SKIP (IMG_UINT32_C(0x1) << 2) /*!< DM need to skip to next cmd before resuming processing */
+#define RGXFWIF_DM_STATE_NEEDS_PR_CLEANUP (IMG_UINT32_C(0x1) << 3) /*!< DM need partial render cleanup before resuming processing */
+#define RGXFWIF_DM_STATE_NEEDS_TRACE_CLEAR (IMG_UINT32_C(0x1) << 4) /*!< DM need to increment Recovery Count once fully recovered */
+#define RGXFWIF_DM_STATE_GUILTY_LOCKUP (IMG_UINT32_C(0x1) << 5) /*!< DM was identified as locking up and causing HWR */
+#define RGXFWIF_DM_STATE_INNOCENT_LOCKUP (IMG_UINT32_C(0x1) << 6) /*!< DM was innocently affected by another lockup which caused HWR */
+#define RGXFWIF_DM_STATE_GUILTY_OVERRUNING (IMG_UINT32_C(0x1) << 7) /*!< DM was identified as over-running and causing HWR */
+#define RGXFWIF_DM_STATE_INNOCENT_OVERRUNING (IMG_UINT32_C(0x1) << 8) /*!< DM was innocently affected by another DM over-running which caused HWR */
+#define RGXFWIF_DM_STATE_HARD_CONTEXT_SWITCH (IMG_UINT32_C(0x1) << 9) /*!< DM was forced into HWR as it delayed more important workloads */
+#define RGXFWIF_DM_STATE_GPU_ECC_HWR (IMG_UINT32_C(0x1) << 10) /*!< DM was forced into HWR due to an uncorrected GPU ECC error */
+
+/* Firmware's connection state */
+typedef enum
+{
+ RGXFW_CONNECTION_FW_OFFLINE = 0, /*!< Firmware is offline */
+ RGXFW_CONNECTION_FW_READY, /*!< Firmware is initialised */
+ RGXFW_CONNECTION_FW_ACTIVE, /*!< Firmware connection is fully established */
+ RGXFW_CONNECTION_FW_OFFLOADING, /*!< Firmware is clearing up connection data */
+ RGXFW_CONNECTION_FW_STATE_COUNT
+} RGXFWIF_CONNECTION_FW_STATE;
+
+/* OS' connection state */
+typedef enum
+{
+ RGXFW_CONNECTION_OS_OFFLINE = 0, /*!< OS is offline */
+ RGXFW_CONNECTION_OS_READY, /*!< OS's KM driver is setup and waiting */
+ RGXFW_CONNECTION_OS_ACTIVE, /*!< OS connection is fully established */
+ RGXFW_CONNECTION_OS_STATE_COUNT
+} RGXFWIF_CONNECTION_OS_STATE;
+
+typedef struct
+{
+ IMG_UINT bfOsState : 3;
+ IMG_UINT bfFLOk : 1;
+ IMG_UINT bfFLGrowPending : 1;
+ IMG_UINT bfIsolatedOS : 1;
+ IMG_UINT bfReserved : 26;
+} RGXFWIF_OS_RUNTIME_FLAGS;
+
+typedef IMG_UINT32 RGXFWIF_HWR_RECOVERYFLAGS;
+
+#if defined(PVRSRV_STALLED_CCB_ACTION)
+#define PVR_SLR_LOG_ENTRIES 10
+#define PVR_SLR_LOG_STRLEN 30 /*!< MAX_CLIENT_CCB_NAME not visible to this header */
+
+typedef struct
+{
+ IMG_UINT64 RGXFW_ALIGN ui64Timestamp;
+ IMG_UINT32 ui32FWCtxAddr;
+ IMG_UINT32 ui32NumUFOs;
+ IMG_CHAR aszCCBName[PVR_SLR_LOG_STRLEN];
+} UNCACHED_ALIGN RGXFWIF_SLR_ENTRY;
+#endif
+
+/* firmware trace control data */
+typedef struct
+{
+ IMG_UINT32 ui32LogType;
+ RGXFWIF_TRACEBUF_SPACE sTraceBuf[RGXFW_THREAD_NUM];
+ IMG_UINT32 ui32TraceBufSizeInDWords; /*!< Member initialised only when sTraceBuf is actually allocated
+ * (in RGXTraceBufferInitOnDemandResources) */
+ IMG_UINT32 ui32TracebufFlags; /*!< Compatibility and other flags */
+} UNCACHED_ALIGN RGXFWIF_TRACEBUF;
+
+/*! @Brief Firmware system data shared with the Host driver */
+typedef struct
+{
+ IMG_UINT32 ui32ConfigFlags; /*!< Configuration flags from host */
+ IMG_UINT32 ui32ConfigFlagsExt; /*!< Extended configuration flags from host */
+ volatile RGXFWIF_POW_STATE ePowState;
+ volatile IMG_UINT32 ui32HWPerfRIdx;
+ volatile IMG_UINT32 ui32HWPerfWIdx;
+ volatile IMG_UINT32 ui32HWPerfWrapCount;
+ IMG_UINT32 ui32HWPerfSize; /*!< Constant after setup, needed in FW */
+ IMG_UINT32 ui32HWPerfDropCount; /*!< The number of times the FW drops a packet due to buffer full */
+
+ /* ui32HWPerfUt, ui32FirstDropOrdinal, ui32LastDropOrdinal only valid when FW is built with
+ * RGX_HWPERF_UTILIZATION & RGX_HWPERF_DROP_TRACKING defined in rgxfw_hwperf.c */
+ IMG_UINT32 ui32HWPerfUt; /*!< Buffer utilisation, high watermark of bytes in use */
+ IMG_UINT32 ui32FirstDropOrdinal; /*!< The ordinal of the first packet the FW dropped */
+ IMG_UINT32 ui32LastDropOrdinal; /*!< The ordinal of the last packet the FW dropped */
+ RGXFWIF_OS_RUNTIME_FLAGS asOsRuntimeFlagsMirror[RGXFW_MAX_NUM_OS];/*!< State flags for each Operating System mirrored from Fw coremem */
+ RGX_FWFAULTINFO sFaultInfo[RGXFWIF_FWFAULTINFO_MAX]; /*!< Firmware fault info */
+ IMG_UINT32 ui32FWFaults; /*!< Firmware faults count */
+ IMG_UINT32 aui32CrPollAddr[RGXFW_THREAD_NUM]; /*!< Failed poll address */
+ IMG_UINT32 aui32CrPollMask[RGXFW_THREAD_NUM]; /*!< Failed poll mask */
+ IMG_UINT32 aui32CrPollCount[RGXFW_THREAD_NUM]; /*!< Failed poll count */
+ IMG_UINT64 RGXFW_ALIGN ui64StartIdleTime;
+#if defined(SUPPORT_POWMON_COMPONENT)
+#if defined(SUPPORT_POWER_VALIDATION_VIA_DEBUGFS)
+ RGXFWIF_TRACEBUF_SPACE sPowerMonBuf;
+ IMG_UINT32 ui32PowerMonBufSizeInDWords;
+#endif
+#endif
+
+#if defined(SUPPORT_RGXFW_STATS_FRAMEWORK)
+#define RGXFWIF_STATS_FRAMEWORK_LINESIZE (8)
+#define RGXFWIF_STATS_FRAMEWORK_MAX (2048*RGXFWIF_STATS_FRAMEWORK_LINESIZE)
+ IMG_UINT32 RGXFW_ALIGN aui32FWStatsBuf[RGXFWIF_STATS_FRAMEWORK_MAX];
+#endif
+ RGXFWIF_HWR_STATEFLAGS ui32HWRStateFlags; /*!< Firmware's Current HWR state */
+ RGXFWIF_HWR_RECOVERYFLAGS aui32HWRRecoveryFlags[RGXFWIF_DM_MAX]; /*!< Each DM's HWR state */
+ IMG_UINT32 ui32FwSysDataFlags; /*!< Compatibility and other flags */
+} UNCACHED_ALIGN RGXFWIF_SYSDATA;
+
+/*!
+ * @InGroup ContextSwitching
+ * @Brief Firmware per-os data and configuration
+ */
+typedef struct
+{
+ IMG_UINT32 ui32FwOsConfigFlags; /*!< Configuration flags from an OS */
+ IMG_UINT32 ui32FWSyncCheckMark; /*!< Markers to signal that the host should perform a full sync check */
+ IMG_UINT32 ui32HostSyncCheckMark; /*!< Markers to signal that the Firmware should perform a full sync check */
+#if defined(PVRSRV_STALLED_CCB_ACTION)
+ IMG_UINT32 ui32ForcedUpdatesRequested;
+ IMG_UINT8 ui8SLRLogWp;
+ RGXFWIF_SLR_ENTRY sSLRLogFirst;
+ RGXFWIF_SLR_ENTRY sSLRLog[PVR_SLR_LOG_ENTRIES];
+ IMG_UINT64 RGXFW_ALIGN ui64LastForcedUpdateTime;
+#endif
+ volatile IMG_UINT32 aui32InterruptCount[RGXFW_THREAD_NUM]; /*!< Interrupt count from Threads > */
+ IMG_UINT32 ui32KCCBCmdsExecuted; /*!< Executed Kernel CCB command count */
+ RGXFWIF_DEV_VIRTADDR sPowerSync; /*!< Sync prim used to signal the host the power off state */
+ IMG_UINT32 ui32FwOsDataFlags; /*!< Compatibility and other flags */
+} UNCACHED_ALIGN RGXFWIF_OSDATA;
+
+/* Firmware trace time-stamp field breakup */
+
+/* RGX_CR_TIMER register read (48 bits) value*/
+#define RGXFWT_TIMESTAMP_TIME_SHIFT (0U)
+#define RGXFWT_TIMESTAMP_TIME_CLRMSK (IMG_UINT64_C(0xFFFF000000000000))
+
+/* Extra debug-info (16 bits) */
+#define RGXFWT_TIMESTAMP_DEBUG_INFO_SHIFT (48U)
+#define RGXFWT_TIMESTAMP_DEBUG_INFO_CLRMSK ~RGXFWT_TIMESTAMP_TIME_CLRMSK
+
+
+/* Debug-info sub-fields */
+/* Bit 0: RGX_CR_EVENT_STATUS_MMU_PAGE_FAULT bit from RGX_CR_EVENT_STATUS register */
+#define RGXFWT_DEBUG_INFO_MMU_PAGE_FAULT_SHIFT (0U)
+#define RGXFWT_DEBUG_INFO_MMU_PAGE_FAULT_SET (1U << RGXFWT_DEBUG_INFO_MMU_PAGE_FAULT_SHIFT)
+
+/* Bit 1: RGX_CR_BIF_MMU_ENTRY_PENDING bit from RGX_CR_BIF_MMU_ENTRY register */
+#define RGXFWT_DEBUG_INFO_MMU_ENTRY_PENDING_SHIFT (1U)
+#define RGXFWT_DEBUG_INFO_MMU_ENTRY_PENDING_SET (1U << RGXFWT_DEBUG_INFO_MMU_ENTRY_PENDING_SHIFT)
+
+/* Bit 2: RGX_CR_SLAVE_EVENT register is non-zero */
+#define RGXFWT_DEBUG_INFO_SLAVE_EVENTS_SHIFT (2U)
+#define RGXFWT_DEBUG_INFO_SLAVE_EVENTS_SET (1U << RGXFWT_DEBUG_INFO_SLAVE_EVENTS_SHIFT)
+
+/* Bit 3-15: Unused bits */
+
+#define RGXFWT_DEBUG_INFO_STR_MAXLEN 64
+#define RGXFWT_DEBUG_INFO_STR_PREPEND " (debug info: "
+#define RGXFWT_DEBUG_INFO_STR_APPEND ")"
+
+/* Table of debug info sub-field's masks and corresponding message strings
+ * to be appended to firmware trace
+ *
+ * Mask : 16 bit mask to be applied to debug-info field
+ * String : debug info message string
+ */
+
+#define RGXFWT_DEBUG_INFO_MSKSTRLIST \
+/*Mask, String*/ \
+X(RGXFWT_DEBUG_INFO_MMU_PAGE_FAULT_SET, "mmu pf") \
+X(RGXFWT_DEBUG_INFO_MMU_ENTRY_PENDING_SET, "mmu pending") \
+X(RGXFWT_DEBUG_INFO_SLAVE_EVENTS_SET, "slave events")
+
+/*!
+ ******************************************************************************
+ * HWR Data
+ *****************************************************************************/
+/*!
+ * @Defgroup HWRInfo FW HWR shared data interface
+ * @Brief Types grouping data structures and defines used in realising the HWR record.
+ * @{
+ */
+/*! @Brief HWR Lockup types */
+typedef enum
+{
+ RGX_HWRTYPE_UNKNOWNFAILURE = 0, /*!< Unknown failure */
+ RGX_HWRTYPE_OVERRUN = 1, /*!< DM overrun */
+ RGX_HWRTYPE_POLLFAILURE = 2, /*!< Poll failure */
+ RGX_HWRTYPE_BIF0FAULT = 3, /*!< BIF0 fault */
+ RGX_HWRTYPE_BIF1FAULT = 4, /*!< BIF1 fault */
+ RGX_HWRTYPE_TEXASBIF0FAULT = 5, /*!< TEXASBIF0 fault */
+ RGX_HWRTYPE_MMUFAULT = 6, /*!< MMU fault */
+ RGX_HWRTYPE_MMUMETAFAULT = 7, /*!< MMU META fault */
+ RGX_HWRTYPE_MIPSTLBFAULT = 8, /*!< MIPS TLB fault */
+ RGX_HWRTYPE_ECCFAULT = 9, /*!< ECC fault */
+ RGX_HWRTYPE_MMURISCVFAULT = 10, /*!< MMU RISCV fault */
+} RGX_HWRTYPE;
+
+#define RGXFWIF_HWRTYPE_BIF_BANK_GET(eHWRType) (((eHWRType) == RGX_HWRTYPE_BIF0FAULT) ? 0 : 1)
+
+#define RGXFWIF_HWRTYPE_PAGE_FAULT_GET(eHWRType) ((((eHWRType) == RGX_HWRTYPE_BIF0FAULT) || \
+ ((eHWRType) == RGX_HWRTYPE_BIF1FAULT) || \
+ ((eHWRType) == RGX_HWRTYPE_TEXASBIF0FAULT) || \
+ ((eHWRType) == RGX_HWRTYPE_MMUFAULT) || \
+ ((eHWRType) == RGX_HWRTYPE_MMUMETAFAULT) || \
+ ((eHWRType) == RGX_HWRTYPE_MIPSTLBFAULT) || \
+ ((eHWRType) == RGX_HWRTYPE_MMURISCVFAULT)) ? true : false)
+
+typedef struct
+{
+ IMG_UINT64 RGXFW_ALIGN ui64BIFReqStatus; /*!< BIF request status */
+ IMG_UINT64 RGXFW_ALIGN ui64BIFMMUStatus; /*!< MMU status */
+ IMG_UINT64 RGXFW_ALIGN ui64PCAddress; /*!< phys address of the page catalogue */
+ IMG_UINT64 RGXFW_ALIGN ui64Reserved;
+} RGX_BIFINFO;
+
+typedef struct
+{
+ IMG_UINT32 ui32FaultGPU; /*!< ECC fault in GPU */
+} RGX_ECCINFO;
+
+typedef struct
+{
+ IMG_UINT64 RGXFW_ALIGN aui64MMUStatus[2]; /*!< MMU status */
+ IMG_UINT64 RGXFW_ALIGN ui64PCAddress; /*!< phys address of the page catalogue */
+ IMG_UINT64 RGXFW_ALIGN ui64Reserved;
+} RGX_MMUINFO;
+
+typedef struct
+{
+ IMG_UINT32 ui32ThreadNum; /*!< Thread ID performing poll operation */
+ IMG_UINT32 ui32CrPollAddr; /*!< CR Poll Address */
+ IMG_UINT32 ui32CrPollMask; /*!< CR Poll mask */
+ IMG_UINT32 ui32CrPollLastValue; /*!< CR Poll last value */
+ IMG_UINT64 RGXFW_ALIGN ui64Reserved;
+} UNCACHED_ALIGN RGX_POLLINFO;
+
+typedef struct
+{
+ IMG_UINT32 ui32BadVAddr; /*!< VA address */
+ IMG_UINT32 ui32EntryLo;
+} RGX_TLBINFO;
+
+/*! @Brief Structure to keep information specific to a lockup e.g. DM, timer, lockup type etc. */
+typedef struct
+{
+ union
+ {
+ RGX_BIFINFO sBIFInfo; /*!< BIF failure details */
+ RGX_MMUINFO sMMUInfo; /*!< MMU failure details */
+ RGX_POLLINFO sPollInfo; /*!< Poll failure details */
+ RGX_TLBINFO sTLBInfo; /*!< TLB failure details */
+ RGX_ECCINFO sECCInfo; /*!< ECC failure details */
+ } uHWRData;
+
+ IMG_UINT64 RGXFW_ALIGN ui64CRTimer; /*!< Timer value at the time of lockup */
+ IMG_UINT64 RGXFW_ALIGN ui64OSTimer; /*!< OS timer value at the time of lockup */
+ IMG_UINT32 ui32FrameNum; /*!< Frame number of the workload */
+ IMG_UINT32 ui32PID; /*!< PID belonging to the workload */
+ IMG_UINT32 ui32ActiveHWRTData; /*!< HWRT data of the workload */
+ IMG_UINT32 ui32HWRNumber; /*!< HWR number */
+ IMG_UINT32 ui32EventStatus; /*!< Core specific event status register at the time of lockup */
+ IMG_UINT32 ui32HWRRecoveryFlags; /*!< DM state flags */
+ RGX_HWRTYPE eHWRType; /*!< Type of lockup */
+ RGXFWIF_DM eDM; /*!< Recovery triggered for the DM */
+ IMG_UINT32 ui32CoreID; /*!< Core ID of the GPU */
+ IMG_UINT64 RGXFW_ALIGN ui64CRTimeOfKick; /*!< Workload kick time */
+ IMG_UINT64 RGXFW_ALIGN ui64CRTimeHWResetStart; /*!< HW reset start time */
+ IMG_UINT64 RGXFW_ALIGN ui64CRTimeHWResetFinish; /*!< HW reset stop time */
+ IMG_UINT64 RGXFW_ALIGN ui64CRTimeFreelistReady; /*!< freelist ready time on the last HWR */
+ IMG_UINT64 RGXFW_ALIGN ui64Reserved[2];
+} UNCACHED_ALIGN RGX_HWRINFO;
+
+#define RGXFWIF_HWINFO_MAX_FIRST 8U /* Number of first HWR logs recorded (never overwritten by newer logs) */
+#define RGXFWIF_HWINFO_MAX_LAST 8U /* Number of latest HWR logs (older logs are overwritten by newer logs) */
+#define RGXFWIF_HWINFO_MAX (RGXFWIF_HWINFO_MAX_FIRST + RGXFWIF_HWINFO_MAX_LAST) /* Total number of HWR logs stored in a buffer */
+#define RGXFWIF_HWINFO_LAST_INDEX (RGXFWIF_HWINFO_MAX - 1U) /* Index of the last log in the HWR log buffer */
+
+/*! @Brief Firmware HWR information structure allocated by the Services and used by the Firmware to update recovery information. */
+typedef struct
+{
+ RGX_HWRINFO sHWRInfo[RGXFWIF_HWINFO_MAX]; /*!< Max number of recovery record */
+ IMG_UINT32 ui32HwrCounter; /*!< HWR counter used in FL reconstruction */
+ IMG_UINT32 ui32WriteIndex; /*!< Index for updating recovery information in sHWRInfo */
+ IMG_UINT32 ui32DDReqCount; /*!< Count of DebugDump requested to the host after recovery */
+ IMG_UINT32 ui32HWRInfoBufFlags; /* Compatibility and other flags */
+ IMG_UINT32 aui32HwrDmLockedUpCount[RGXFWIF_DM_MAX]; /*!< Lockup count for each DM */
+ IMG_UINT32 aui32HwrDmOverranCount[RGXFWIF_DM_MAX]; /*!< Overrun count for each DM */
+ IMG_UINT32 aui32HwrDmRecoveredCount[RGXFWIF_DM_MAX]; /*!< Lockup + Overrun count for each DM */
+ IMG_UINT32 aui32HwrDmFalseDetectCount[RGXFWIF_DM_MAX]; /*!< False lockup detection count for each DM */
+} UNCACHED_ALIGN RGXFWIF_HWRINFOBUF;
+
+/*! @} End of HWRInfo */
+
+#define RGXFWIF_CTXSWITCH_PROFILE_FAST_EN (IMG_UINT32_C(0x1))
+#define RGXFWIF_CTXSWITCH_PROFILE_MEDIUM_EN (IMG_UINT32_C(0x2))
+#define RGXFWIF_CTXSWITCH_PROFILE_SLOW_EN (IMG_UINT32_C(0x3))
+#define RGXFWIF_CTXSWITCH_PROFILE_NODELAY_EN (IMG_UINT32_C(0x4))
+
+#define RGXFWIF_CDM_ARBITRATION_TASK_DEMAND_EN (IMG_UINT32_C(0x1))
+#define RGXFWIF_CDM_ARBITRATION_ROUND_ROBIN_EN (IMG_UINT32_C(0x2))
+
+#define RGXFWIF_ISP_SCHEDMODE_VER1_IPP (IMG_UINT32_C(0x1))
+#define RGXFWIF_ISP_SCHEDMODE_VER2_ISP (IMG_UINT32_C(0x2))
+/*!
+ ******************************************************************************
+ * RGX firmware Init Config Data
+ *****************************************************************************/
+
+/* Flag definitions affecting the firmware globally */
+#define RGXFWIF_INICFG_CTXSWITCH_MODE_RAND (IMG_UINT32_C(0x1) << 0)
+#define RGXFWIF_INICFG_CTXSWITCH_SRESET_EN (IMG_UINT32_C(0x1) << 1)
+#define RGXFWIF_INICFG_HWPERF_EN (IMG_UINT32_C(0x1) << 2)
+#define RGXFWIF_INICFG_DM_KILL_MODE_RAND_EN (IMG_UINT32_C(0x1) << 3)
+#define RGXFWIF_INICFG_POW_RASCALDUST (IMG_UINT32_C(0x1) << 4)
+/* 5 unused */
+#define RGXFWIF_INICFG_FBCDC_V3_1_EN (IMG_UINT32_C(0x1) << 6)
+#define RGXFWIF_INICFG_CHECK_MLIST_EN (IMG_UINT32_C(0x1) << 7)
+#define RGXFWIF_INICFG_DISABLE_CLKGATING_EN (IMG_UINT32_C(0x1) << 8)
+#define RGXFWIF_INICFG_POLL_COUNTERS_EN (IMG_UINT32_C(0x1) << 9)
+#define RGXFWIF_INICFG_VDM_CTX_STORE_MODE_SHIFT (10)
+#define RGXFWIF_INICFG_VDM_CTX_STORE_MODE_INDEX ((IMG_UINT32)RGX_CR_VDM_CONTEXT_STORE_MODE_MODE_INDEX << RGXFWIF_INICFG_VDM_CTX_STORE_MODE_SHIFT)
+#define RGXFWIF_INICFG_VDM_CTX_STORE_MODE_INSTANCE ((IMG_UINT32)RGX_CR_VDM_CONTEXT_STORE_MODE_MODE_INSTANCE << RGXFWIF_INICFG_VDM_CTX_STORE_MODE_SHIFT)
+#define RGXFWIF_INICFG_VDM_CTX_STORE_MODE_LIST ((IMG_UINT32)RGX_CR_VDM_CONTEXT_STORE_MODE_MODE_LIST << RGXFWIF_INICFG_VDM_CTX_STORE_MODE_SHIFT)
+#define RGXFWIF_INICFG_VDM_CTX_STORE_MODE_MASK (RGXFWIF_INICFG_VDM_CTX_STORE_MODE_INDEX |\
+ RGXFWIF_INICFG_VDM_CTX_STORE_MODE_INSTANCE |\
+ RGXFWIF_INICFG_VDM_CTX_STORE_MODE_LIST)
+#define RGXFWIF_INICFG_REGCONFIG_EN (IMG_UINT32_C(0x1) << 12)
+#define RGXFWIF_INICFG_ASSERT_ON_OUTOFMEMORY (IMG_UINT32_C(0x1) << 13)
+#define RGXFWIF_INICFG_HWP_DISABLE_FILTER (IMG_UINT32_C(0x1) << 14)
+#define RGXFWIF_INICFG_CUSTOM_PERF_TIMER_EN (IMG_UINT32_C(0x1) << 15)
+#define RGXFWIF_INICFG_CTXSWITCH_PROFILE_SHIFT (16)
+#define RGXFWIF_INICFG_CTXSWITCH_PROFILE_FAST (RGXFWIF_CTXSWITCH_PROFILE_FAST_EN << RGXFWIF_INICFG_CTXSWITCH_PROFILE_SHIFT)
+#define RGXFWIF_INICFG_CTXSWITCH_PROFILE_MEDIUM (RGXFWIF_CTXSWITCH_PROFILE_MEDIUM_EN << RGXFWIF_INICFG_CTXSWITCH_PROFILE_SHIFT)
+#define RGXFWIF_INICFG_CTXSWITCH_PROFILE_SLOW (RGXFWIF_CTXSWITCH_PROFILE_SLOW_EN << RGXFWIF_INICFG_CTXSWITCH_PROFILE_SHIFT)
+#define RGXFWIF_INICFG_CTXSWITCH_PROFILE_NODELAY (RGXFWIF_CTXSWITCH_PROFILE_NODELAY_EN << RGXFWIF_INICFG_CTXSWITCH_PROFILE_SHIFT)
+#define RGXFWIF_INICFG_CTXSWITCH_PROFILE_MASK (IMG_UINT32_C(0x7) << RGXFWIF_INICFG_CTXSWITCH_PROFILE_SHIFT)
+#define RGXFWIF_INICFG_DISABLE_DM_OVERLAP (IMG_UINT32_C(0x1) << 19)
+#define RGXFWIF_INICFG_ASSERT_ON_HWR_TRIGGER (IMG_UINT32_C(0x1) << 20)
+#define RGXFWIF_INICFG_FABRIC_COHERENCY_ENABLED (IMG_UINT32_C(0x1) << 21)
+#define RGXFWIF_INICFG_VALIDATE_IRQ (IMG_UINT32_C(0x1) << 22)
+#define RGXFWIF_INICFG_DISABLE_PDP_EN (IMG_UINT32_C(0x1) << 23)
+#define RGXFWIF_INICFG_SPU_POWER_STATE_MASK_CHANGE_EN (IMG_UINT32_C(0x1) << 24)
+#define RGXFWIF_INICFG_WORKEST (IMG_UINT32_C(0x1) << 25)
+#define RGXFWIF_INICFG_PDVFS (IMG_UINT32_C(0x1) << 26)
+#define RGXFWIF_INICFG_CDM_ARBITRATION_SHIFT (27)
+#define RGXFWIF_INICFG_CDM_ARBITRATION_TASK_DEMAND (RGXFWIF_CDM_ARBITRATION_TASK_DEMAND_EN << RGXFWIF_INICFG_CDM_ARBITRATION_SHIFT)
+#define RGXFWIF_INICFG_CDM_ARBITRATION_ROUND_ROBIN (RGXFWIF_CDM_ARBITRATION_ROUND_ROBIN_EN << RGXFWIF_INICFG_CDM_ARBITRATION_SHIFT)
+#define RGXFWIF_INICFG_CDM_ARBITRATION_MASK (IMG_UINT32_C(0x3) << RGXFWIF_INICFG_CDM_ARBITRATION_SHIFT)
+#define RGXFWIF_INICFG_ISPSCHEDMODE_SHIFT (29)
+#define RGXFWIF_INICFG_ISPSCHEDMODE_NONE (0)
+#define RGXFWIF_INICFG_ISPSCHEDMODE_VER1_IPP (RGXFWIF_ISP_SCHEDMODE_VER1_IPP << RGXFWIF_INICFG_ISPSCHEDMODE_SHIFT)
+#define RGXFWIF_INICFG_ISPSCHEDMODE_VER2_ISP (RGXFWIF_ISP_SCHEDMODE_VER2_ISP << RGXFWIF_INICFG_ISPSCHEDMODE_SHIFT)
+#define RGXFWIF_INICFG_ISPSCHEDMODE_MASK (RGXFWIF_INICFG_ISPSCHEDMODE_VER1_IPP |\
+ RGXFWIF_INICFG_ISPSCHEDMODE_VER2_ISP)
+#define RGXFWIF_INICFG_VALIDATE_SOCUSC_TIMER (IMG_UINT32_C(0x1) << 31)
+
+#define RGXFWIF_INICFG_ALL (0xFFFFFFFFU)
+
+/* Extended Flag definitions affecting the firmware globally */
+#define RGXFWIF_INICFG_EXT_TFBC_CONTROL_SHIFT (0)
+#define RGXFWIF_INICFG_EXT_TFBC_CONTROL_MASK (IMG_UINT32_C(0x7F)) /* RGX_CR_TFBC_COMPRESSION_CONTROL_MASKFULL */
+#define RGXFWIF_INICFG_EXT_ALL (RGXFWIF_INICFG_EXT_TFBC_CONTROL_MASK)
+
+#define RGXFWIF_INICFG_SYS_CTXSWITCH_CLRMSK ~(RGXFWIF_INICFG_CTXSWITCH_MODE_RAND | \
+ RGXFWIF_INICFG_CTXSWITCH_SRESET_EN)
+
+/* Flag definitions affecting only workloads submitted by a particular OS */
+
+/*!
+ * @AddToGroup ContextSwitching
+ * @{
+ * @Name Per-OS DM context switch configuration flags
+ * @{
+ */
+#define RGXFWIF_INICFG_OS_CTXSWITCH_TDM_EN (IMG_UINT32_C(0x1) << 0) /*!< Enables TDM context switch */
+#define RGXFWIF_INICFG_OS_CTXSWITCH_GEOM_EN (IMG_UINT32_C(0x1) << 1) /*!< Enables GEOM DM context switch */
+#define RGXFWIF_INICFG_OS_CTXSWITCH_3D_EN (IMG_UINT32_C(0x1) << 2) /*!< Enables FRAG DM context switch */
+#define RGXFWIF_INICFG_OS_CTXSWITCH_CDM_EN (IMG_UINT32_C(0x1) << 3) /*!< Enables CDM context switch */
+
+#define RGXFWIF_INICFG_OS_LOW_PRIO_CS_TDM (IMG_UINT32_C(0x1) << 4)
+#define RGXFWIF_INICFG_OS_LOW_PRIO_CS_GEOM (IMG_UINT32_C(0x1) << 5)
+#define RGXFWIF_INICFG_OS_LOW_PRIO_CS_3D (IMG_UINT32_C(0x1) << 6)
+#define RGXFWIF_INICFG_OS_LOW_PRIO_CS_CDM (IMG_UINT32_C(0x1) << 7)
+
+#define RGXFWIF_INICFG_OS_ALL (0xFF)
+
+#define RGXFWIF_INICFG_OS_CTXSWITCH_DM_ALL (RGXFWIF_INICFG_OS_CTXSWITCH_GEOM_EN | \
+ RGXFWIF_INICFG_OS_CTXSWITCH_3D_EN | \
+ RGXFWIF_INICFG_OS_CTXSWITCH_CDM_EN | \
+ RGXFWIF_INICFG_OS_CTXSWITCH_TDM_EN)
+
+#define RGXFWIF_INICFG_OS_CTXSWITCH_CLRMSK ~(RGXFWIF_INICFG_OS_CTXSWITCH_DM_ALL)
+
+/*!
+ * @} End of Per-OS Context switch configuration flags
+ * @} End of AddToGroup ContextSwitching
+ */
+
+#define RGXFWIF_FILTCFG_TRUNCATE_HALF (IMG_UINT32_C(0x1) << 3)
+#define RGXFWIF_FILTCFG_TRUNCATE_INT (IMG_UINT32_C(0x1) << 2)
+#define RGXFWIF_FILTCFG_NEW_FILTER_MODE (IMG_UINT32_C(0x1) << 1)
+
+typedef enum
+{
+ RGX_ACTIVEPM_FORCE_OFF = 0,
+ RGX_ACTIVEPM_FORCE_ON = 1,
+ RGX_ACTIVEPM_DEFAULT = 2
+} RGX_ACTIVEPM_CONF;
+
+typedef enum
+{
+ RGX_RD_POWER_ISLAND_FORCE_OFF = 0,
+ RGX_RD_POWER_ISLAND_FORCE_ON = 1,
+ RGX_RD_POWER_ISLAND_DEFAULT = 2
+} RGX_RD_POWER_ISLAND_CONF;
+
+#if defined(RGX_FW_IRQ_OS_COUNTERS)
+/* Unused registers re-purposed for storing counters of the Firmware's
+ * interrupts for each OS
+ */
+#define IRQ_COUNTER_STORAGE_REGS \
+ 0x2028U, /* RGX_CR_PM_TA_MMU_FSTACK */ \
+ 0x2050U, /* RGX_CR_PM_3D_MMU_FSTACK */ \
+ 0x2030U, /* RGX_CR_PM_START_OF_MMU_TACONTEXT*/ \
+ 0x2058U, /* RGX_CR_PM_START_OF_MMU_3DCONTEXT*/ \
+ 0x2058U, /* RGX_CR_PM_START_OF_MMU_3DCONTEXT*/ \
+ 0x2058U, /* RGX_CR_PM_START_OF_MMU_3DCONTEXT*/ \
+ 0x2058U, /* RGX_CR_PM_START_OF_MMU_3DCONTEXT*/ \
+ 0x2058U, /* RGX_CR_PM_START_OF_MMU_3DCONTEXT*/
+#endif
+
+typedef struct
+{
+ IMG_UINT16 ui16RegNum; /*!< Register number */
+ IMG_UINT16 ui16IndirectRegNum; /*!< Indirect register number (or 0 if not used) */
+ IMG_UINT16 ui16IndirectStartVal; /*!< Start value for indirect register */
+ IMG_UINT16 ui16IndirectEndVal; /*!< End value for indirect register */
+} RGXFW_REGISTER_LIST;
+
+#if defined(RGX_FIRMWARE)
+typedef DLLIST_NODE RGXFWIF_DLLIST_NODE;
+#else
+typedef struct {RGXFWIF_DEV_VIRTADDR p;
+ RGXFWIF_DEV_VIRTADDR n;} RGXFWIF_DLLIST_NODE;
+#endif
+
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_SIGBUFFER;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_TRACEBUF;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_SYSDATA;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_OSDATA;
+#if defined(SUPPORT_TBI_INTERFACE)
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_TBIBUF;
+#endif
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_HWPERFBUF;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_HWRINFOBUF;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_RUNTIME_CFG;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_GPU_UTIL_FWCB;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_REG_CFG;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_HWPERF_CTL;
+typedef RGXFWIF_DEV_VIRTADDR PRGX_HWPERF_CONFIG_MUX_CNTBLK;
+typedef RGXFWIF_DEV_VIRTADDR PRGX_HWPERF_SELECT_CUSTOM_CNTRS;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CCB_CTL;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CCB;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CCB_RTN_SLOTS;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_FWMEMCONTEXT;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_FWCOMMONCONTEXT;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_ZSBUFFER;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_COMMONCTX_STATE;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CORE_CLK_RATE;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_COUNTERBUFFER;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_FIRMWAREGCOVBUFFER;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CCCB;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CCCB_CTL;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_FREELIST;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_HWRTDATA;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_TIMESTAMP_ADDR;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_RF_CMD;
+
+/*!
+ * This number is used to represent an invalid page catalogue physical address
+ */
+#define RGXFWIF_INVALID_PC_PHYADDR 0xFFFFFFFFFFFFFFFFLLU
+
+/*!
+ * This number is used to represent unallocated page catalog base register
+ */
+#define RGXFW_BIF_INVALID_PCREG 0xFFFFFFFFU
+
+/*!
+ Firmware memory context.
+*/
+typedef struct
+{
+ IMG_DEV_PHYADDR RGXFW_ALIGN sPCDevPAddr; /*!< device physical address of context's page catalogue */
+ IMG_UINT32 uiPageCatBaseRegID; /*!< associated page catalog base register (RGXFW_BIF_INVALID_PCREG == unallocated) */
+ IMG_UINT32 uiBreakpointAddr; /*!< breakpoint address */
+ IMG_UINT32 uiBPHandlerAddr; /*!< breakpoint handler address */
+ IMG_UINT32 uiBreakpointCtl; /*!< DM and enable control for BP */
+ IMG_UINT32 ui32FwMemCtxFlags; /*!< Compatibility and other flags */
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+ IMG_UINT32 ui32OSid;
+ IMG_BOOL bOSidAxiProt;
+#endif
+
+} UNCACHED_ALIGN RGXFWIF_FWMEMCONTEXT;
+
+/*!
+ * FW context state flags
+ */
+#define RGXFWIF_CONTEXT_FLAGS_NEED_RESUME (0x00000001U)
+#define RGXFWIF_CONTEXT_FLAGS_MC_NEED_RESUME_MASKFULL (0x000000FFU)
+#define RGXFWIF_CONTEXT_FLAGS_TDM_HEADER_STALE (0x00000100U)
+
+/*!
+ * @InGroup ContextSwitching
+ * @Brief Firmware GEOM/TA context suspend state
+ */
+typedef struct
+{
+ /* FW-accessible TA state which must be written out to memory on context store */
+ IMG_UINT64 RGXFW_ALIGN uTAReg_VDM_CALL_STACK_POINTER; /*!< VDM control stream stack pointer, to store in mid-TA */
+ IMG_UINT64 RGXFW_ALIGN uTAReg_VDM_CALL_STACK_POINTER_Init; /*!< Initial value of VDM control stream stack pointer (in case is 'lost' due to a lock-up) */
+ IMG_UINT64 RGXFW_ALIGN uTAReg_VBS_SO_PRIM0;
+ IMG_UINT64 RGXFW_ALIGN uTAReg_VBS_SO_PRIM1;
+ IMG_UINT64 RGXFW_ALIGN uTAReg_VBS_SO_PRIM2;
+ IMG_UINT64 RGXFW_ALIGN uTAReg_VBS_SO_PRIM3;
+ IMG_UINT16 ui16TACurrentIdx;
+} UNCACHED_ALIGN RGXFWIF_TACTX_STATE;
+
+/*!
+ * @InGroup ContextSwitching
+ * @Brief Firmware FRAG/3D context suspend state
+ */
+typedef struct
+{
+ /* FW-accessible ISP state which must be written out to memory on context store */
+ IMG_UINT32 u3DReg_PM_DEALLOCATED_MASK_STATUS; /*!< PM deallocation status */
+ IMG_UINT32 u3DReg_PM_PDS_MTILEFREE_STATUS; /*!< Macro-tiles (MTs) finished status */
+ IMG_UINT32 ui32CtxStateFlags; /*!< Compatibility and other flags */
+ /* au3DReg_ISP_STORE should be the last element of the structure
+ * as this is an array whose size is determined at runtime
+ * after detecting the RGX core */
+ IMG_UINT32 au3DReg_ISP_STORE[]; /*!< ISP state (per-pipe) */
+} UNCACHED_ALIGN RGXFWIF_3DCTX_STATE;
+
+static_assert(sizeof(RGXFWIF_3DCTX_STATE) <= 16,
+ "Size of structure RGXFWIF_3DCTX_STATE exceeds maximum expected size.");
+
+#define RGXFWIF_CTX_USING_BUFFER_A (0)
+#define RGXFWIF_CTX_USING_BUFFER_B (1U)
+
+typedef struct
+{
+ IMG_UINT32 ui32CtxStateFlags; /*!< Target buffer and other flags */
+} RGXFWIF_COMPUTECTX_STATE;
+
+/*!
+ * @InGroup WorkloadContexts
+ * @Brief Firmware Common Context (or FWCC)
+ */
+typedef struct RGXFWIF_FWCOMMONCONTEXT_
+{
+ /* CCB details for this firmware context */
+ PRGXFWIF_CCCB_CTL psCCBCtl; /*!< CCB control */
+ PRGXFWIF_CCCB psCCB; /*!< CCB base */
+ RGXFWIF_DMA_ADDR sCCBMetaDMAAddr;
+
+ /* Context suspend state */
+ PRGXFWIF_COMMONCTX_STATE RGXFW_ALIGN psContextState; /*!< TA/3D context suspend state, read/written by FW */
+
+ /* Flags e.g. for context switching */
+ IMG_UINT32 ui32FWComCtxFlags;
+ IMG_UINT32 ui32Priority; /*!< Priority level */
+ IMG_UINT32 ui32PrioritySeqNum;
+
+ /* Framework state */
+ PRGXFWIF_RF_CMD RGXFW_ALIGN psRFCmd; /*!< Register updates for Framework */
+
+ /* Statistic updates waiting to be passed back to the host... */
+ IMG_BOOL bStatsPending; /*!< True when some stats are pending */
+ IMG_INT32 i32StatsNumStores; /*!< Number of stores on this context since last update */
+ IMG_INT32 i32StatsNumOutOfMemory; /*!< Number of OOMs on this context since last update */
+ IMG_INT32 i32StatsNumPartialRenders; /*!< Number of PRs on this context since last update */
+ RGXFWIF_DM eDM; /*!< Data Master type */
+ IMG_UINT64 RGXFW_ALIGN ui64WaitSignalAddress; /*!< Device Virtual Address of the signal the context is waiting on */
+ RGXFWIF_DLLIST_NODE RGXFW_ALIGN sWaitSignalNode; /*!< List entry for the wait-signal list */
+ RGXFWIF_DLLIST_NODE RGXFW_ALIGN sBufStalledNode; /*!< List entry for the buffer stalled list */
+ IMG_UINT64 RGXFW_ALIGN ui64CBufQueueCtrlAddr; /*!< Address of the circular buffer queue pointers */
+
+ IMG_UINT64 RGXFW_ALIGN ui64RobustnessAddress;
+ IMG_UINT32 ui32MaxDeadlineMS; /*!< Max HWR deadline limit in ms */
+ bool bReadOffsetNeedsReset; /*!< Following HWR circular buffer read-offset needs resetting */
+
+ RGXFWIF_DLLIST_NODE RGXFW_ALIGN sWaitingNode; /*!< List entry for the waiting list */
+ RGXFWIF_DLLIST_NODE RGXFW_ALIGN sRunNode; /*!< List entry for the run list */
+ RGXFWIF_UFO sLastFailedUFO; /*!< UFO that last failed (or NULL) */
+
+ PRGXFWIF_FWMEMCONTEXT psFWMemContext; /*!< Memory context */
+
+ /* References to the host side originators */
+ IMG_UINT32 ui32ServerCommonContextID; /*!< the Server Common Context */
+ IMG_UINT32 ui32PID; /*!< associated process ID */
+
+ IMG_BOOL bGeomOOMDisabled; /*!< True when Geom DM OOM is not allowed */
+
+} UNCACHED_ALIGN RGXFWIF_FWCOMMONCONTEXT;
+
+static_assert(sizeof(RGXFWIF_FWCOMMONCONTEXT) <= 256,
+ "Size of structure RGXFWIF_FWCOMMONCONTEXT exceeds maximum expected size.");
+
+typedef IMG_UINT64 RGXFWIF_TRP_CHECKSUM_TQ[RGX_TRP_MAX_NUM_CORES][1];
+typedef IMG_UINT64 RGXFWIF_TRP_CHECKSUM_2D[RGX_TRP_MAX_NUM_CORES][2];
+typedef IMG_UINT64 RGXFWIF_TRP_CHECKSUM_3D[RGX_TRP_MAX_NUM_CORES][4];
+typedef IMG_UINT64 RGXFWIF_TRP_CHECKSUM_GEOM[RGX_TRP_MAX_NUM_CORES][2];
+
+/*!
+ * @InGroup WorkloadContexts
+ * @Brief Firmware render context.
+ */
+typedef struct
+{
+ RGXFWIF_FWCOMMONCONTEXT sTAContext; /*!< Firmware context for the TA */
+ RGXFWIF_FWCOMMONCONTEXT s3DContext; /*!< Firmware context for the 3D */
+
+ RGXFWIF_STATIC_RENDERCONTEXT_STATE sStaticRenderContextState;
+
+ IMG_UINT32 ui32WorkEstCCBSubmitted; /*!< Number of commands submitted to the WorkEst FW CCB */
+
+ IMG_UINT32 ui32FwRenderCtxFlags; /*!< Compatibility and other flags */
+
+} UNCACHED_ALIGN RGXFWIF_FWRENDERCONTEXT;
+
+/*!
+ Firmware compute context.
+*/
+typedef struct
+{
+ RGXFWIF_FWCOMMONCONTEXT sCDMContext; /*!< Firmware context for the CDM */
+
+ RGXFWIF_STATIC_COMPUTECONTEXT_STATE sStaticComputeContextState;
+
+ IMG_UINT32 ui32WorkEstCCBSubmitted; /*!< Number of commands submitted to the WorkEst FW CCB */
+
+ IMG_UINT32 ui32ComputeCtxFlags; /*!< Compatibility and other flags */
+
+ IMG_UINT32 ui32WGPState;
+ IMG_UINT32 ui32WGPChecksum;
+ IMG_UINT32 ui32CoreMaskA;
+ IMG_UINT32 ui32CoreMaskB;
+} UNCACHED_ALIGN RGXFWIF_FWCOMPUTECONTEXT;
+
+/*!
+ Firmware TDM context.
+*/
+typedef struct
+{
+ RGXFWIF_FWCOMMONCONTEXT sTDMContext; /*!< Firmware context for the TDM */
+
+ IMG_UINT32 ui32WorkEstCCBSubmitted; /*!< Number of commands submitted to the WorkEst FW CCB */
+
+} UNCACHED_ALIGN RGXFWIF_FWTDMCONTEXT;
+
+/*!
+ * @InGroup WorkloadContexts
+ * @Brief Firmware transfer context.
+ */
+typedef struct
+{
+ RGXFWIF_FWCOMMONCONTEXT sTQContext; /*!< Firmware context for TQ3D */
+
+#if defined(SUPPORT_TRP)
+ IMG_UINT32 ui32TRPState;
+ RGXFWIF_TRP_CHECKSUM_TQ aui64TRPChecksumsTQ;
+#endif
+} UNCACHED_ALIGN RGXFWIF_FWTRANSFERCONTEXT;
+
+/*!
+ ******************************************************************************
+ * Defines for CMD_TYPE corruption detection and forward compatibility check
+ *****************************************************************************/
+
+/* CMD_TYPE 32bit contains:
+ * 31:16 Reserved for magic value to detect corruption (16 bits)
+ * 15 Reserved for RGX_CCB_TYPE_TASK (1 bit)
+ * 14:0 Bits available for CMD_TYPEs (15 bits) */
+
+
+/* Magic value to detect corruption */
+#define RGX_CMD_MAGIC_DWORD IMG_UINT32_C(0x2ABC)
+#define RGX_CMD_MAGIC_DWORD_MASK (0xFFFF0000U)
+#define RGX_CMD_MAGIC_DWORD_SHIFT (16U)
+#define RGX_CMD_MAGIC_DWORD_SHIFTED (RGX_CMD_MAGIC_DWORD << RGX_CMD_MAGIC_DWORD_SHIFT)
+
+/*!
+ * @InGroup KCCBTypes ClientCCBTypes
+ * @Brief Generic CCB control structure
+ */
+typedef struct
+{
+ volatile IMG_UINT32 ui32WriteOffset; /*!< write offset into array of commands (MUST be aligned to 16 bytes!) */
+ volatile IMG_UINT32 ui32ReadOffset; /*!< read offset into array of commands */
+ IMG_UINT32 ui32WrapMask; /*!< Offset wrapping mask (Total capacity of the CCB - 1) */
+ IMG_UINT32 ui32CmdSize; /*!< size of each command in bytes */
+} UNCACHED_ALIGN RGXFWIF_CCB_CTL;
+
+/*!
+ * @Defgroup KCCBTypes Kernel CCB data interface
+ * @Brief Types grouping data structures and defines used in realising the KCCB functionality
+ * @{
+ */
+
+#define RGXFWIF_MMUCACHEDATA_FLAGS_PT (0x1U) /* MMU_CTRL_INVAL_PT_EN */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_PD (0x2U) /* MMU_CTRL_INVAL_PD_EN */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_PC (0x4U) /* MMU_CTRL_INVAL_PC_EN */
+
+#if !defined(__KERNEL)
+
+#if !defined(RGX_FEATURE_SLC_VIVT)
+#define RGXFWIF_MMUCACHEDATA_FLAGS_PMTLB (0x10U) /* can't use PM_TLB0 bit from BIFPM_CTRL reg because it collides with PT bit from BIF_CTRL reg */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_TLB (RGXFWIF_MMUCACHEDATA_FLAGS_PMTLB | 0x8U) /* BIF_CTRL_INVAL_TLB1_EN */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_CTX_ALL (0x0U) /* not used */
+
+#else /* RGX_FEATURE_SLC_VIVT */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_PMTLB (0x0) /* not used */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_TLB (0x0) /* not used */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_CTX_ALL (0x800) /* MMU_CTRL_INVAL_ALL_CONTEXTS_EN */
+#endif
+
+#else
+#define RGXFWIF_MMUCACHEDATA_FLAGS_PMTLB (0x10) /* can't use PM_TLB0 bit from BIFPM_CTRL reg because it collides with PT bit from BIF_CTRL reg */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_TLB (RGXFWIF_MMUCACHEDATA_FLAGS_PMTLB | 0x8) /* BIF_CTRL_INVAL_TLB1_EN */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_CTX_ALL (0x800) /* MMU_CTRL_INVAL_ALL_CONTEXTS_EN */
+#endif
+
+#define RGXFWIF_MMUCACHEDATA_FLAGS_INTERRUPT (0x4000000U) /* indicates FW should interrupt the host */
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_MMUCACHE type command
+ */
+typedef struct
+{
+ IMG_UINT32 ui32CacheFlags;
+ RGXFWIF_DEV_VIRTADDR sMMUCacheSync;
+ IMG_UINT32 ui32MMUCacheSyncUpdateValue;
+} RGXFWIF_MMUCACHEDATA;
+
+#define RGXFWIF_BPDATA_FLAGS_ENABLE (1U << 0)
+#define RGXFWIF_BPDATA_FLAGS_WRITE (1U << 1)
+#define RGXFWIF_BPDATA_FLAGS_CTL (1U << 2)
+#define RGXFWIF_BPDATA_FLAGS_REGS (1U << 3)
+
+typedef struct
+{
+ PRGXFWIF_FWMEMCONTEXT psFWMemContext; /*!< Memory context */
+ IMG_UINT32 ui32BPAddr; /*!< Breakpoint address */
+ IMG_UINT32 ui32HandlerAddr; /*!< Breakpoint handler */
+ IMG_UINT32 ui32BPDM; /*!< Breakpoint control */
+ IMG_UINT32 ui32BPDataFlags;
+ IMG_UINT32 ui32TempRegs; /*!< Number of temporary registers to overallocate */
+ IMG_UINT32 ui32SharedRegs; /*!< Number of shared registers to overallocate */
+ RGXFWIF_DM eDM; /*!< DM associated with the breakpoint */
+} RGXFWIF_BPDATA;
+
+#define RGXFWIF_KCCB_CMD_KICK_DATA_MAX_NUM_CLEANUP_CTLS (RGXFWIF_PRBUFFER_MAXSUPPORTED + 1U) /* +1 is RTDATASET cleanup */
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_KICK type command
+ */
+typedef struct
+{
+ PRGXFWIF_FWCOMMONCONTEXT psContext; /*!< address of the firmware context */
+ IMG_UINT32 ui32CWoffUpdate; /*!< Client CCB woff update */
+ IMG_UINT32 ui32CWrapMaskUpdate; /*!< Client CCB wrap mask update after CCCB growth */
+ IMG_UINT32 ui32NumCleanupCtl; /*!< number of CleanupCtl pointers attached */
+ PRGXFWIF_CLEANUP_CTL apsCleanupCtl[RGXFWIF_KCCB_CMD_KICK_DATA_MAX_NUM_CLEANUP_CTLS]; /*!< CleanupCtl structures associated with command */
+ IMG_UINT32 ui32WorkEstCmdHeaderOffset; /*!< offset to the CmdHeader which houses the workload estimation kick data. */
+} RGXFWIF_KCCB_CMD_KICK_DATA;
+
+/*!
+ * @Brief Command data for @Ref RGXFWIF_KCCB_CMD_COMBINED_TA_3D_KICK type command
+ */
+typedef struct
+{
+ RGXFWIF_KCCB_CMD_KICK_DATA sTACmdKickData; /*!< GEOM DM kick command data */
+ RGXFWIF_KCCB_CMD_KICK_DATA s3DCmdKickData; /*!< FRAG DM kick command data */
+} RGXFWIF_KCCB_CMD_COMBINED_TA_3D_KICK_DATA;
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_FORCE_UPDATE type command
+ */
+typedef struct
+{
+ PRGXFWIF_FWCOMMONCONTEXT psContext; /*!< address of the firmware context */
+ IMG_UINT32 ui32CCBFenceOffset; /*!< Client CCB fence offset */
+} RGXFWIF_KCCB_CMD_FORCE_UPDATE_DATA;
+
+/*!
+ * @Brief Resource types supported by \ref RGXFWIF_KCCB_CMD_CLEANUP type command
+ */
+typedef enum
+{
+ RGXFWIF_CLEANUP_FWCOMMONCONTEXT, /*!< FW common context cleanup */
+ RGXFWIF_CLEANUP_HWRTDATA, /*!< FW HW RT data cleanup */
+ RGXFWIF_CLEANUP_FREELIST, /*!< FW freelist cleanup */
+ RGXFWIF_CLEANUP_ZSBUFFER, /*!< FW ZS Buffer cleanup */
+} RGXFWIF_CLEANUP_TYPE;
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_CLEANUP type command
+ */
+typedef struct
+{
+ RGXFWIF_CLEANUP_TYPE eCleanupType; /*!< Cleanup type */
+ union {
+ PRGXFWIF_FWCOMMONCONTEXT psContext; /*!< FW common context to cleanup */
+ PRGXFWIF_HWRTDATA psHWRTData; /*!< HW RT to cleanup */
+ PRGXFWIF_FREELIST psFreelist; /*!< Freelist to cleanup */
+ PRGXFWIF_ZSBUFFER psZSBuffer; /*!< ZS Buffer to cleanup */
+ } uCleanupData;
+} RGXFWIF_CLEANUP_REQUEST;
+
+/*!
+ * @Brief Type of power requests supported in \ref RGXFWIF_KCCB_CMD_POW type command
+ */
+typedef enum
+{
+ RGXFWIF_POW_OFF_REQ = 1, /*!< GPU power-off request */
+ RGXFWIF_POW_FORCED_IDLE_REQ, /*!< Force-idle related request */
+ RGXFWIF_POW_NUM_UNITS_CHANGE, /*!< Request to change default powered scalable units */
+ RGXFWIF_POW_APM_LATENCY_CHANGE /*!< Request to change the APM latency period */
+} RGXFWIF_POWER_TYPE;
+
+/*!
+ * @Brief Supported force-idle related requests with \ref RGXFWIF_POW_FORCED_IDLE_REQ type request
+ */
+typedef enum
+{
+ RGXFWIF_POWER_FORCE_IDLE = 1, /*!< Request to force-idle GPU */
+ RGXFWIF_POWER_CANCEL_FORCED_IDLE, /*!< Request to cancel a previously successful force-idle transition */
+ RGXFWIF_POWER_HOST_TIMEOUT, /*!< Notification that host timed-out waiting for force-idle state */
+} RGXFWIF_POWER_FORCE_IDLE_TYPE;
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_POW type command
+ */
+typedef struct
+{
+ RGXFWIF_POWER_TYPE ePowType; /*!< Type of power request */
+ union
+ {
+ IMG_UINT32 ui32NumOfDusts; /*!< Number of active Dusts */
+ IMG_BOOL bForced; /*!< If the operation is mandatory */
+ RGXFWIF_POWER_FORCE_IDLE_TYPE ePowRequestType; /*!< Type of Request. Consolidating Force Idle, Cancel Forced Idle, Host Timeout */
+ } uPowerReqData;
+} RGXFWIF_POWER_REQUEST;
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_SLCFLUSHINVAL type command
+ */
+typedef struct
+{
+ PRGXFWIF_FWCOMMONCONTEXT psContext; /*!< Context to fence on (only useful when bDMContext == TRUE) */
+ IMG_BOOL bInval; /*!< Invalidate the cache as well as flushing */
+ IMG_BOOL bDMContext; /*!< The data to flush/invalidate belongs to a specific DM context */
+ IMG_UINT64 RGXFW_ALIGN ui64Address; /*!< Optional address of range (only useful when bDMContext == FALSE) */
+ IMG_UINT64 RGXFW_ALIGN ui64Size; /*!< Optional size of range (only useful when bDMContext == FALSE) */
+} RGXFWIF_SLCFLUSHINVALDATA;
+
+typedef enum
+{
+ RGXFWIF_HWPERF_CTRL_TOGGLE = 0,
+ RGXFWIF_HWPERF_CTRL_SET = 1,
+ RGXFWIF_HWPERF_CTRL_EMIT_FEATURES_EV = 2
+} RGXFWIF_HWPERF_UPDATE_CONFIG;
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_HWPERF_UPDATE_CONFIG type command
+ */
+typedef struct
+{
+ RGXFWIF_HWPERF_UPDATE_CONFIG eOpCode; /*!< Control operation code */
+ IMG_UINT64 RGXFW_ALIGN ui64Mask; /*!< Mask of events to toggle */
+} RGXFWIF_HWPERF_CTRL;
+
+typedef struct
+{
+ IMG_UINT32 ui32NumBlocks; /*!< Number of RGX_HWPERF_CONFIG_MUX_CNTBLK in the array */
+ PRGX_HWPERF_CONFIG_MUX_CNTBLK sBlockConfigs; /*!< Address of the RGX_HWPERF_CONFIG_MUX_CNTBLK array */
+} RGXFWIF_HWPERF_CONFIG_ENABLE_BLKS;
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_CORECLKSPEEDCHANGE type command
+ */
+typedef struct
+{
+ IMG_UINT32 ui32NewClockSpeed; /*!< New clock speed */
+} RGXFWIF_CORECLKSPEEDCHANGE_DATA;
+
+#define RGXFWIF_HWPERF_CTRL_BLKS_MAX 16U
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_HWPERF_CTRL_BLKS type command
+ */
+typedef struct
+{
+ bool bEnable;
+ IMG_UINT32 ui32NumBlocks; /*!< Number of block IDs in the array */
+ IMG_UINT16 aeBlockIDs[RGXFWIF_HWPERF_CTRL_BLKS_MAX]; /*!< Array of RGX_HWPERF_CNTBLK_ID values */
+} RGXFWIF_HWPERF_CTRL_BLKS;
+
+
+typedef struct
+{
+ IMG_UINT16 ui16CustomBlock;
+ IMG_UINT16 ui16NumCounters;
+ PRGX_HWPERF_SELECT_CUSTOM_CNTRS sCustomCounterIDs;
+} RGXFWIF_HWPERF_SELECT_CUSTOM_CNTRS;
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_ZSBUFFER_BACKING_UPDATE & \ref RGXFWIF_KCCB_CMD_ZSBUFFER_UNBACKING_UPDATE type commands
+ */
+typedef struct
+{
+ RGXFWIF_DEV_VIRTADDR sZSBufferFWDevVAddr; /*!< ZS-Buffer FW address */
+ IMG_BOOL bDone; /*!< action backing/unbacking succeeded */
+} RGXFWIF_ZSBUFFER_BACKING_DATA;
+
+#if defined(SUPPORT_VALIDATION)
+typedef struct
+{
+ IMG_UINT32 ui32RegWidth;
+ IMG_BOOL bWriteOp;
+ IMG_UINT32 ui32RegAddr;
+ IMG_UINT64 RGXFW_ALIGN ui64RegVal;
+} RGXFWIF_RGXREG_DATA;
+#endif
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_FREELIST_GROW_UPDATE type command
+ */
+typedef struct
+{
+ RGXFWIF_DEV_VIRTADDR sFreeListFWDevVAddr; /*!< Freelist FW address */
+ IMG_UINT32 ui32DeltaPages; /*!< Amount of the Freelist change */
+ IMG_UINT32 ui32NewPages; /*!< New amount of pages on the freelist (including ready pages) */
+ IMG_UINT32 ui32ReadyPages; /*!< Number of ready pages to be held in reserve until OOM */
+} RGXFWIF_FREELIST_GS_DATA;
+
+#define RGXFWIF_MAX_FREELISTS_TO_RECONSTRUCT (MAX_HW_TA3DCONTEXTS * RGXFW_MAX_FREELISTS * 2U)
+#define RGXFWIF_FREELISTS_RECONSTRUCTION_FAILED_FLAG 0x80000000U
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_FREELISTS_RECONSTRUCTION_UPDATE type command
+ */
+typedef struct
+{
+ IMG_UINT32 ui32FreelistsCount;
+ IMG_UINT32 aui32FreelistIDs[RGXFWIF_MAX_FREELISTS_TO_RECONSTRUCT];
+} RGXFWIF_FREELISTS_RECONSTRUCTION_DATA;
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_NOTIFY_WRITE_OFFSET_UPDATE type command
+ */
+typedef struct
+{
+ PRGXFWIF_FWCOMMONCONTEXT psContext; /*!< Context to that may need to be resumed following write offset update */
+} UNCACHED_ALIGN RGXFWIF_WRITE_OFFSET_UPDATE_DATA;
+
+/*!
+ ******************************************************************************
+ * Proactive DVFS Structures
+ *****************************************************************************/
+#define NUM_OPP_VALUES 16
+
+typedef struct
+{
+ IMG_UINT32 ui32Volt; /* V */
+ IMG_UINT32 ui32Freq; /* Hz */
+} UNCACHED_ALIGN PDVFS_OPP;
+
+typedef struct
+{
+ PDVFS_OPP asOPPValues[NUM_OPP_VALUES];
+#if defined(DEBUG)
+ IMG_UINT32 ui32MinOPPPoint;
+#endif
+ IMG_UINT32 ui32MaxOPPPoint;
+} UNCACHED_ALIGN RGXFWIF_PDVFS_OPP;
+
+typedef struct
+{
+ IMG_UINT32 ui32MaxOPPPoint;
+} UNCACHED_ALIGN RGXFWIF_PDVFS_MAX_FREQ_DATA;
+
+typedef struct
+{
+ IMG_UINT32 ui32MinOPPPoint;
+} UNCACHED_ALIGN RGXFWIF_PDVFS_MIN_FREQ_DATA;
+
+/*!
+ ******************************************************************************
+ * Register configuration structures
+ *****************************************************************************/
+
+#define RGXFWIF_REG_CFG_MAX_SIZE 512
+
+typedef enum
+{
+ RGXFWIF_REGCFG_CMD_ADD = 101,
+ RGXFWIF_REGCFG_CMD_CLEAR = 102,
+ RGXFWIF_REGCFG_CMD_ENABLE = 103,
+ RGXFWIF_REGCFG_CMD_DISABLE = 104
+} RGXFWIF_REGDATA_CMD_TYPE;
+
+typedef enum
+{
+ RGXFWIF_REG_CFG_TYPE_PWR_ON=0, /* Sidekick power event */
+ RGXFWIF_REG_CFG_TYPE_DUST_CHANGE, /* Rascal / dust power event */
+ RGXFWIF_REG_CFG_TYPE_TA, /* TA kick */
+ RGXFWIF_REG_CFG_TYPE_3D, /* 3D kick */
+ RGXFWIF_REG_CFG_TYPE_CDM, /* Compute kick */
+ RGXFWIF_REG_CFG_TYPE_TLA, /* TLA kick */
+ RGXFWIF_REG_CFG_TYPE_TDM, /* TDM kick */
+ RGXFWIF_REG_CFG_TYPE_ALL /* Applies to all types. Keep as last element */
+} RGXFWIF_REG_CFG_TYPE;
+
+typedef struct
+{
+ IMG_UINT64 ui64Addr;
+ IMG_UINT64 ui64Mask;
+ IMG_UINT64 ui64Value;
+} RGXFWIF_REG_CFG_REC;
+
+typedef struct
+{
+ RGXFWIF_REGDATA_CMD_TYPE eCmdType;
+ RGXFWIF_REG_CFG_TYPE eRegConfigType;
+ RGXFWIF_REG_CFG_REC RGXFW_ALIGN sRegConfig;
+
+} RGXFWIF_REGCONFIG_DATA;
+
+typedef struct
+{
+ /**
+ * PDump WRW command write granularity is 32 bits.
+ * Add padding to ensure array size is 32 bit granular.
+ */
+ IMG_UINT8 RGXFW_ALIGN aui8NumRegsType[PVR_ALIGN((IMG_UINT32)RGXFWIF_REG_CFG_TYPE_ALL,sizeof(IMG_UINT32))];
+ RGXFWIF_REG_CFG_REC RGXFW_ALIGN asRegConfigs[RGXFWIF_REG_CFG_MAX_SIZE];
+} UNCACHED_ALIGN RGXFWIF_REG_CFG;
+
+typedef enum
+{
+ RGXFWIF_OS_ONLINE = 1,
+ RGXFWIF_OS_OFFLINE
+} RGXFWIF_OS_STATE_CHANGE;
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_OS_ONLINE_STATE_CONFIGURE type command
+ */
+typedef struct
+{
+ IMG_UINT32 ui32OSid;
+ RGXFWIF_OS_STATE_CHANGE eNewOSState;
+} UNCACHED_ALIGN RGXFWIF_OS_STATE_CHANGE_DATA;
+
+typedef enum
+{
+ RGXFWIF_PWR_COUNTER_DUMP_START = 1,
+ RGXFWIF_PWR_COUNTER_DUMP_STOP,
+ RGXFWIF_PWR_COUNTER_DUMP_SAMPLE,
+} RGXFWIF_COUNTER_DUMP_REQUEST;
+
+typedef struct
+{
+ RGXFWIF_COUNTER_DUMP_REQUEST eCounterDumpRequest;
+} RGXFW_ALIGN RGXFWIF_COUNTER_DUMP_DATA;
+
+/*!
+ * @Brief List of command types supported by the Kernel CCB
+ */
+typedef enum
+{
+ /* Common commands */
+ RGXFWIF_KCCB_CMD_KICK = 101U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< DM workload kick command */
+ RGXFWIF_KCCB_CMD_MMUCACHE = 102U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< MMU cache invalidation request */
+ RGXFWIF_KCCB_CMD_BP = 103U | RGX_CMD_MAGIC_DWORD_SHIFTED,
+ RGXFWIF_KCCB_CMD_SLCFLUSHINVAL = 105U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< SLC flush and invalidation request */
+ RGXFWIF_KCCB_CMD_CLEANUP = 106U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests cleanup of a FW resource (type specified in the command data) */
+ RGXFWIF_KCCB_CMD_POW = 107U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Power request */
+ RGXFWIF_KCCB_CMD_ZSBUFFER_BACKING_UPDATE = 108U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Backing for on-demand ZS-Buffer done */
+ RGXFWIF_KCCB_CMD_ZSBUFFER_UNBACKING_UPDATE = 109U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Unbacking for on-demand ZS-Buffer done */
+ RGXFWIF_KCCB_CMD_FREELIST_GROW_UPDATE = 110U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Freelist Grow done */
+ RGXFWIF_KCCB_CMD_FREELISTS_RECONSTRUCTION_UPDATE = 112U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Freelists Reconstruction done */
+ /* RGXFWIF_KCCB_CMD_NOTIFY_SIGNAL_UPDATE */
+ RGXFWIF_KCCB_CMD_NOTIFY_WRITE_OFFSET_UPDATE = 114U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Informs the firmware that the host has added more data to a CDM2 Circular Buffer */
+ RGXFWIF_KCCB_CMD_HEALTH_CHECK = 115U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Health check request */
+ RGXFWIF_KCCB_CMD_FORCE_UPDATE = 116U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Forcing signalling of all unmet UFOs for a given CCB offset */
+
+ RGXFWIF_KCCB_CMD_COMBINED_TA_3D_KICK = 117U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< There is a TA and a 3D command in this single kick */
+ RGXFWIF_KCCB_CMD_OS_ONLINE_STATE_CONFIGURE = 118U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Informs the FW that a Guest OS has come online / offline. */
+
+ /* Commands only permitted to the native or host OS */
+ RGXFWIF_KCCB_CMD_REGCONFIG = 200U | RGX_CMD_MAGIC_DWORD_SHIFTED,
+ RGXFWIF_KCCB_CMD_HWPERF_UPDATE_CONFIG = 201U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Configure HWPerf events (to be generated) and HWPerf buffer address (if required) */
+ /* RGXFWIF_KCCB_CMD_HWPERF_CONFIG_BLKS */
+ RGXFWIF_KCCB_CMD_HWPERF_CTRL_BLKS = 203U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Enable or disable multiple HWPerf blocks (reusing existing configuration) */
+ RGXFWIF_KCCB_CMD_CORECLKSPEEDCHANGE = 204U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Core clock speed change event */
+ /* RGXFWIF_KCCB_CMD_HWPERF_CONFIG_ENABLE_BLKS_DIRECT*/
+ RGXFWIF_KCCB_CMD_LOGTYPE_UPDATE = 206U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Ask the firmware to update its cached ui32LogType value from the (shared) tracebuf control structure */
+ RGXFWIF_KCCB_CMD_PDVFS_LIMIT_MAX_FREQ = 207U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Set a maximum frequency/OPP point */
+ RGXFWIF_KCCB_CMD_OSID_PRIORITY_CHANGE = 208U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Changes the relative scheduling priority for a particular OSid. It can only be serviced for the Host DDK */
+ RGXFWIF_KCCB_CMD_STATEFLAGS_CTRL = 209U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Set or clear firmware state flags */
+ /* RGXFWIF_KCCB_CMD_HCS_SET_DEADLINE */
+ /*RGXFWIF_KCCB_CMD_OS_ONLINE_STATE_CONFIGURE */
+ RGXFWIF_KCCB_CMD_PDVFS_LIMIT_MIN_FREQ = 212U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Set a minimum frequency/OPP point */
+ RGXFWIF_KCCB_CMD_PHR_CFG = 213U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Configure Periodic Hardware Reset behaviour */
+#if defined(SUPPORT_VALIDATION)
+ RGXFWIF_KCCB_CMD_RGXREG = 214U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Read RGX Register from FW */
+#endif
+ RGXFWIF_KCCB_CMD_WDG_CFG = 215U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Configure Safety Firmware Watchdog */
+ RGXFWIF_KCCB_CMD_COUNTER_DUMP = 216U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Controls counter dumping in the FW */
+ RGXFWIF_KCCB_CMD_HWPERF_CONFIG_ENABLE_BLKS = 217U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Configure, clear and enable multiple HWPerf blocks */
+ RGXFWIF_KCCB_CMD_HWPERF_SELECT_CUSTOM_CNTRS = 218U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Configure the custom counters for HWPerf */
+} RGXFWIF_KCCB_CMD_TYPE;
+
+#define RGXFWIF_LAST_ALLOWED_GUEST_KCCB_CMD (RGXFWIF_KCCB_CMD_REGCONFIG - 1)
+
+/*! @Brief Kernel CCB command packet */
+typedef struct
+{
+ RGXFWIF_KCCB_CMD_TYPE eCmdType; /*!< Command type */
+ IMG_UINT32 ui32KCCBFlags; /*!< Compatibility and other flags */
+
+ /* NOTE: Make sure that uCmdData is the last member of this struct
+ * This is to calculate actual command size for device mem copy.
+ * (Refer RGXGetCmdMemCopySize())
+ * */
+ union
+ {
+ RGXFWIF_KCCB_CMD_KICK_DATA sCmdKickData; /*!< Data for Kick command */
+ RGXFWIF_KCCB_CMD_COMBINED_TA_3D_KICK_DATA sCombinedTA3DCmdKickData; /*!< Data for combined TA/3D Kick command */
+ RGXFWIF_MMUCACHEDATA sMMUCacheData; /*!< Data for MMU cache command */
+ RGXFWIF_BPDATA sBPData; /*!< Data for Breakpoint Commands */
+ RGXFWIF_SLCFLUSHINVALDATA sSLCFlushInvalData; /*!< Data for SLC Flush/Inval commands */
+ RGXFWIF_CLEANUP_REQUEST sCleanupData; /*!< Data for cleanup commands */
+ RGXFWIF_POWER_REQUEST sPowData; /*!< Data for power request commands */
+ RGXFWIF_HWPERF_CTRL sHWPerfCtrl; /*!< Data for HWPerf control command */
+ RGXFWIF_HWPERF_CONFIG_ENABLE_BLKS sHWPerfCfgEnableBlks; /*!< Data for HWPerf configure, clear and enable performance counter block command */
+ RGXFWIF_HWPERF_CTRL_BLKS sHWPerfCtrlBlks; /*!< Data for HWPerf enable or disable performance counter block commands */
+ RGXFWIF_HWPERF_SELECT_CUSTOM_CNTRS sHWPerfSelectCstmCntrs; /*!< Data for HWPerf configure the custom counters to read */
+ RGXFWIF_CORECLKSPEEDCHANGE_DATA sCoreClkSpeedChangeData;/*!< Data for core clock speed change */
+ RGXFWIF_ZSBUFFER_BACKING_DATA sZSBufferBackingData; /*!< Feedback for Z/S Buffer backing/unbacking */
+ RGXFWIF_FREELIST_GS_DATA sFreeListGSData; /*!< Feedback for Freelist grow/shrink */
+ RGXFWIF_FREELISTS_RECONSTRUCTION_DATA sFreeListsReconstructionData; /*!< Feedback for Freelists reconstruction */
+ RGXFWIF_REGCONFIG_DATA sRegConfigData; /*!< Data for custom register configuration */
+ RGXFWIF_WRITE_OFFSET_UPDATE_DATA sWriteOffsetUpdateData; /*!< Data for informing the FW about the write offset update */
+ RGXFWIF_PDVFS_MAX_FREQ_DATA sPDVFSMaxFreqData; /*!< Data for setting the max frequency/OPP */
+ RGXFWIF_PDVFS_MIN_FREQ_DATA sPDVFSMinFreqData; /*!< Data for setting the min frequency/OPP */
+ RGXFWIF_OS_STATE_CHANGE_DATA sCmdOSOnlineStateData; /*!< Data for updating the Guest Online states */
+ RGXFWIF_DEV_VIRTADDR sTBIBuffer; /*!< Dev address for TBI buffer allocated on demand */
+ RGXFWIF_COUNTER_DUMP_DATA sCounterDumpConfigData; /*!< Data for dumping of register ranges */
+ RGXFWIF_KCCB_CMD_FORCE_UPDATE_DATA sForceUpdateData; /*!< Data for signalling all unmet fences for a given CCB */
+#if defined(SUPPORT_VALIDATION)
+ RGXFWIF_RGXREG_DATA sFwRgxData; /*!< Data for reading off an RGX register */
+#endif
+ } UNCACHED_ALIGN uCmdData;
+} UNCACHED_ALIGN RGXFWIF_KCCB_CMD;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGXFWIF_KCCB_CMD);
+
+/*! @} End of KCCBTypes */
+
+/*!
+ * @Defgroup FWCCBTypes Firmware CCB data interface
+ * @Brief Types grouping data structures and defines used in realising the Firmware CCB functionality
+ * @{
+ */
+
+/*!
+ ******************************************************************************
+ * @Brief Command data of the \ref RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING and the
+ * \ref RGXFWIF_FWCCB_CMD_ZSBUFFER_UNBACKING Firmware CCB commands
+ *****************************************************************************/
+typedef struct
+{
+ IMG_UINT32 ui32ZSBufferID; /*!< ZS buffer ID */
+} RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING_DATA;
+
+/*!
+ ******************************************************************************
+ * @Brief Command data of the \ref RGXFWIF_FWCCB_CMD_FREELIST_GROW Firmware CCB
+ * command
+ *****************************************************************************/
+typedef struct
+{
+ IMG_UINT32 ui32FreelistID; /*!< Freelist ID */
+} RGXFWIF_FWCCB_CMD_FREELIST_GS_DATA;
+
+/*!
+ ******************************************************************************
+ * @Brief Command data of the \ref RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION
+ * Firmware CCB command
+ *****************************************************************************/
+typedef struct
+{
+ IMG_UINT32 ui32FreelistsCount; /*!< Freelists count */
+ IMG_UINT32 ui32HwrCounter; /*!< HWR counter */
+ IMG_UINT32 aui32FreelistIDs[RGXFWIF_MAX_FREELISTS_TO_RECONSTRUCT]; /*!< Array of freelist IDs to reconstruct */
+} RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION_DATA;
+
+#define RGXFWIF_FWCCB_CMD_CONTEXT_RESET_FLAG_PF (1U<<0) /*!< 1 if a page fault happened */
+#define RGXFWIF_FWCCB_CMD_CONTEXT_RESET_FLAG_ALL_CTXS (1U<<1) /*!< 1 if applicable to all contexts */
+
+/*!
+ ******************************************************************************
+ * @Brief Command data of the \ref RGXFWIF_FWCCB_CMD_CONTEXT_RESET_NOTIFICATION
+ * Firmware CCB command
+ *****************************************************************************/
+typedef struct
+{
+ IMG_UINT32 ui32ServerCommonContextID; /*!< Context affected by the reset */
+ RGX_CONTEXT_RESET_REASON eResetReason; /*!< Reason for reset */
+ RGXFWIF_DM eDM; /*!< Data Master affected by the reset */
+ IMG_UINT32 ui32ResetJobRef; /*!< Job ref running at the time of reset */
+ IMG_UINT32 ui32Flags; /*!< RGXFWIF_FWCCB_CMD_CONTEXT_RESET_FLAG bitfield */
+ IMG_UINT64 RGXFW_ALIGN ui64PCAddress; /*!< At what page catalog address */
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sFaultAddress; /*!< Page fault address (only when applicable) */
+} RGXFWIF_FWCCB_CMD_CONTEXT_RESET_DATA;
+
+/*!
+ ******************************************************************************
+ * @Brief Command data of the \ref RGXFWIF_FWCCB_CMD_CONTEXT_FW_PF_NOTIFICATION
+ * Firmware CCB command
+ *****************************************************************************/
+typedef struct
+{
+ IMG_DEV_VIRTADDR sFWFaultAddr; /*!< Page fault address */
+} RGXFWIF_FWCCB_CMD_FW_PAGEFAULT_DATA;
+
+/*!
+ ******************************************************************************
+ * List of command types supported by the Firmware CCB
+ *****************************************************************************/
+typedef enum
+{
+ RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING = 101U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests ZSBuffer to be backed with physical pages
+ \n Command data: RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING_DATA */
+ RGXFWIF_FWCCB_CMD_ZSBUFFER_UNBACKING = 102U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests ZSBuffer to be unbacked
+ \n Command data: RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING_DATA */
+ RGXFWIF_FWCCB_CMD_FREELIST_GROW = 103U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests an on-demand freelist grow
+ \n Command data: RGXFWIF_FWCCB_CMD_FREELIST_GS_DATA */
+ RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION = 104U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests freelists reconstruction
+ \n Command data: RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION_DATA */
+ RGXFWIF_FWCCB_CMD_CONTEXT_RESET_NOTIFICATION = 105U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Notifies host of a HWR event on a context
+ \n Command data: RGXFWIF_FWCCB_CMD_CONTEXT_RESET_DATA */
+ RGXFWIF_FWCCB_CMD_DEBUG_DUMP = 106U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests an on-demand debug dump
+ \n Command data: None */
+ RGXFWIF_FWCCB_CMD_UPDATE_STATS = 107U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests an on-demand update on process stats
+ \n Command data: RGXFWIF_FWCCB_CMD_UPDATE_STATS_DATA */
+
+ RGXFWIF_FWCCB_CMD_CORE_CLK_RATE_CHANGE = 108U | RGX_CMD_MAGIC_DWORD_SHIFTED,
+ RGXFWIF_FWCCB_CMD_REQUEST_GPU_RESTART = 109U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests GPU restart
+ \n Command data: None */
+#if defined(SUPPORT_VALIDATION)
+ RGXFWIF_FWCCB_CMD_REG_READ = 110U | RGX_CMD_MAGIC_DWORD_SHIFTED,
+#if defined(SUPPORT_SOC_TIMER)
+ RGXFWIF_FWCCB_CMD_SAMPLE_TIMERS = 111U | RGX_CMD_MAGIC_DWORD_SHIFTED,
+#endif
+#endif
+ RGXFWIF_FWCCB_CMD_CONTEXT_FW_PF_NOTIFICATION = 112U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Notifies host of a FW pagefault
+ \n Command data: RGXFWIF_FWCCB_CMD_FW_PAGEFAULT_DATA */
+} RGXFWIF_FWCCB_CMD_TYPE;
+
+/*!
+ ******************************************************************************
+ * List of the various stats of the process to update/increment
+ *****************************************************************************/
+typedef enum
+{
+ RGXFWIF_FWCCB_CMD_UPDATE_NUM_PARTIAL_RENDERS=1, /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32TotalNumPartialRenders stat */
+ RGXFWIF_FWCCB_CMD_UPDATE_NUM_OUT_OF_MEMORY, /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32TotalNumOutOfMemory stat */
+ RGXFWIF_FWCCB_CMD_UPDATE_NUM_TA_STORES, /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32NumTAStores stat */
+ RGXFWIF_FWCCB_CMD_UPDATE_NUM_3D_STORES, /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32Num3DStores stat */
+ RGXFWIF_FWCCB_CMD_UPDATE_NUM_CDM_STORES, /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32NumCDMStores stat */
+ RGXFWIF_FWCCB_CMD_UPDATE_NUM_TDM_STORES /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32NumTDMStores stat */
+} RGXFWIF_FWCCB_CMD_UPDATE_STATS_TYPE;
+
+/*!
+ ******************************************************************************
+ * @Brief Command data of the \ref RGXFWIF_FWCCB_CMD_UPDATE_STATS Firmware CCB
+ * command
+ *****************************************************************************/
+typedef struct
+{
+ RGXFWIF_FWCCB_CMD_UPDATE_STATS_TYPE eElementToUpdate; /*!< Element to update */
+ IMG_PID pidOwner; /*!< The pid of the process whose stats are being updated */
+ IMG_INT32 i32AdjustmentValue; /*!< Adjustment to be made to the statistic */
+} RGXFWIF_FWCCB_CMD_UPDATE_STATS_DATA;
+
+typedef struct
+{
+ IMG_UINT32 ui32CoreClkRate;
+} UNCACHED_ALIGN RGXFWIF_FWCCB_CMD_CORE_CLK_RATE_CHANGE_DATA;
+
+#if defined(SUPPORT_VALIDATION)
+typedef struct
+{
+ IMG_UINT64 ui64RegValue;
+} RGXFWIF_FWCCB_CMD_RGXREG_READ_DATA;
+
+#if defined(SUPPORT_SOC_TIMER)
+typedef struct
+{
+ IMG_UINT64 ui64timerGray;
+ IMG_UINT64 ui64timerBinary;
+ IMG_UINT64 aui64uscTimers[RGX_FEATURE_NUM_CLUSTERS];
+} RGXFWIF_FWCCB_CMD_SAMPLE_TIMERS_DATA;
+#endif
+#endif
+
+/*!
+ ******************************************************************************
+ * @Brief Firmware CCB command structure
+ *****************************************************************************/
+typedef struct
+{
+ RGXFWIF_FWCCB_CMD_TYPE eCmdType; /*!< Command type */
+ IMG_UINT32 ui32FWCCBFlags; /*!< Compatibility and other flags */
+
+ union
+ {
+ RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING_DATA sCmdZSBufferBacking; /*!< Data for Z/S-Buffer on-demand (un)backing*/
+ RGXFWIF_FWCCB_CMD_FREELIST_GS_DATA sCmdFreeListGS; /*!< Data for on-demand freelist grow/shrink */
+ RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION_DATA sCmdFreeListsReconstruction; /*!< Data for freelists reconstruction */
+ RGXFWIF_FWCCB_CMD_CONTEXT_RESET_DATA sCmdContextResetNotification; /*!< Data for context reset notification */
+ RGXFWIF_FWCCB_CMD_UPDATE_STATS_DATA sCmdUpdateStatsData; /*!< Data for updating process stats */
+ RGXFWIF_FWCCB_CMD_CORE_CLK_RATE_CHANGE_DATA sCmdCoreClkRateChange;
+ RGXFWIF_FWCCB_CMD_FW_PAGEFAULT_DATA sCmdFWPagefault; /*!< Data for context reset notification */
+#if defined(SUPPORT_VALIDATION)
+ RGXFWIF_FWCCB_CMD_RGXREG_READ_DATA sCmdRgxRegReadData;
+#if defined(SUPPORT_SOC_TIMER)
+ RGXFWIF_FWCCB_CMD_SAMPLE_TIMERS_DATA sCmdTimers;
+#endif
+#endif
+ } RGXFW_ALIGN uCmdData;
+} RGXFW_ALIGN RGXFWIF_FWCCB_CMD;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGXFWIF_FWCCB_CMD);
+
+/*! @} End of FWCCBTypes */
+
+/*!
+ ******************************************************************************
+ * Workload estimation Firmware CCB command structure for RGX
+ *****************************************************************************/
+typedef struct
+{
+ IMG_UINT16 ui16ReturnDataIndex; /*!< Index for return data array */
+ IMG_UINT32 ui32CyclesTaken; /*!< The cycles the workload took on the hardware */
+} RGXFWIF_WORKEST_FWCCB_CMD;
+
+/*!
+ * @Defgroup ClientCCBTypes Client CCB data interface
+ * @Brief Types grouping data structures and defines used in realising Client CCB commands/functionality
+ * @{
+ */
+
+/* Required memory alignment for 64-bit variables accessible by Meta
+ (The gcc meta aligns 64-bit variables to 64-bit; therefore, memory shared
+ between the host and meta that contains 64-bit variables has to maintain
+ this alignment) */
+#define RGXFWIF_FWALLOC_ALIGN sizeof(IMG_UINT64)
+
+#define RGX_CCB_TYPE_TASK (IMG_UINT32_C(1) << 15)
+#define RGX_CCB_FWALLOC_ALIGN(size) (((size) + (RGXFWIF_FWALLOC_ALIGN-1U)) & ~(RGXFWIF_FWALLOC_ALIGN - 1U))
+
+typedef IMG_UINT32 RGXFWIF_CCB_CMD_TYPE;
+
+/*!
+ * @Name Client CCB command types
+ * @{
+ */
+#define RGXFWIF_CCB_CMD_TYPE_GEOM (201U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< TA DM command */
+#define RGXFWIF_CCB_CMD_TYPE_TQ_3D (202U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< 3D DM command for TQ operation */
+#define RGXFWIF_CCB_CMD_TYPE_3D (203U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< 3D DM command */
+#define RGXFWIF_CCB_CMD_TYPE_3D_PR (204U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< 3D DM command for Partial render */
+#define RGXFWIF_CCB_CMD_TYPE_CDM (205U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< Compute DM command */
+#define RGXFWIF_CCB_CMD_TYPE_TQ_TDM (206U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< TDM command */
+#define RGXFWIF_CCB_CMD_TYPE_FBSC_INVALIDATE (207U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK)
+#define RGXFWIF_CCB_CMD_TYPE_TQ_2D (208U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< 2D DM command for TQ operation */
+#define RGXFWIF_CCB_CMD_TYPE_PRE_TIMESTAMP (209U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK)
+#define RGXFWIF_CCB_CMD_TYPE_NULL (210U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK)
+#define RGXFWIF_CCB_CMD_TYPE_ABORT (211U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK)
+
+/* Leave a gap between CCB specific commands and generic commands */
+#define RGXFWIF_CCB_CMD_TYPE_FENCE (212U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Fence dependencies of a command */
+#define RGXFWIF_CCB_CMD_TYPE_UPDATE (213U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Fence updates of a command */
+#define RGXFWIF_CCB_CMD_TYPE_RMW_UPDATE (214U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Fence updates related to workload resources */
+#define RGXFWIF_CCB_CMD_TYPE_FENCE_PR (215U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Fence dependencies of a PR command */
+#define RGXFWIF_CCB_CMD_TYPE_PRIORITY (216U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Context priority update command */
+/* Pre and Post timestamp commands are supposed to sandwich the DM cmd. The
+ padding code with the CCB wrap upsets the FW if we don't have the task type
+ bit cleared for POST_TIMESTAMPs. That's why we have 2 different cmd types.
+*/
+#define RGXFWIF_CCB_CMD_TYPE_POST_TIMESTAMP (217U | RGX_CMD_MAGIC_DWORD_SHIFTED)
+#define RGXFWIF_CCB_CMD_TYPE_UNFENCED_UPDATE (218U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Unfenced fence updates of a command */
+#define RGXFWIF_CCB_CMD_TYPE_UNFENCED_RMW_UPDATE (219U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Unfenced fence updates related to workload resources */
+
+#if defined(SUPPORT_VALIDATION)
+#define RGXFWIF_CCB_CMD_TYPE_REG_READ (220U | RGX_CMD_MAGIC_DWORD_SHIFTED)
+#endif
+
+#define RGXFWIF_CCB_CMD_TYPE_PADDING (221U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Skip without action type command */
+/*! @} End of Client CCB command types */
+
+typedef struct
+{
+ /* Index for the KM Workload estimation return data array */
+ IMG_UINT16 RGXFW_ALIGN ui16ReturnDataIndex;
+ /* Predicted time taken to do the work in cycles */
+ IMG_UINT32 RGXFW_ALIGN ui32CyclesPrediction;
+ /* Deadline for the workload (in usecs) */
+ IMG_UINT64 RGXFW_ALIGN ui64Deadline;
+} RGXFWIF_WORKEST_KICK_DATA;
+
+/*! @Brief Command header of a command in the client CCB buffer.
+ *
+ * Followed by this header is the command-data specific to the
+ * command-type as specified in the header.
+ */
+typedef struct
+{
+ RGXFWIF_CCB_CMD_TYPE eCmdType; /*!< Command data type following this command header */
+ IMG_UINT32 ui32CmdSize; /*!< Size of the command following this header */
+ IMG_UINT32 ui32ExtJobRef; /*!< external job reference - provided by client and used in debug for tracking submitted work */
+ IMG_UINT32 ui32IntJobRef; /*!< internal job reference - generated by services and used in debug for tracking submitted work */
+ RGXFWIF_WORKEST_KICK_DATA RGXFW_ALIGN sWorkEstKickData; /*!< Workload Estimation - Workload Estimation Data */
+} RGXFWIF_CCB_CMD_HEADER;
+
+/*
+ ******************************************************************************
+ * Client CCB commands which are only required by the kernel
+ *****************************************************************************/
+
+/*! @Brief Command data for \ref RGXFWIF_CCB_CMD_TYPE_PRIORITY type client CCB command */
+typedef struct
+{
+ IMG_UINT32 ui32Priority; /*!< Priority level */
+} RGXFWIF_CMD_PRIORITY;
+
+/*! @} End of ClientCCBTypes */
+
+/*!
+ ******************************************************************************
+ * Signature and Checksums Buffer
+ *****************************************************************************/
+typedef struct
+{
+ PRGXFWIF_SIGBUFFER sBuffer; /*!< Ptr to Signature Buffer memory */
+ IMG_UINT32 ui32LeftSizeInRegs; /*!< Amount of space left for storing regs in the buffer */
+} UNCACHED_ALIGN RGXFWIF_SIGBUF_CTL;
+
+typedef struct
+{
+ PRGXFWIF_COUNTERBUFFER sBuffer; /*!< Ptr to counter dump buffer */
+ IMG_UINT32 ui32SizeInDwords; /*!< Amount of space for storing in the buffer */
+} UNCACHED_ALIGN RGXFWIF_COUNTER_DUMP_CTL;
+
+typedef struct
+{
+ PRGXFWIF_FIRMWAREGCOVBUFFER sBuffer; /*!< Ptr to firmware gcov buffer */
+ IMG_UINT32 ui32Size; /*!< Amount of space for storing in the buffer */
+} UNCACHED_ALIGN RGXFWIF_FIRMWARE_GCOV_CTL;
+
+/*!
+ *****************************************************************************
+ * RGX Compatibility checks
+ *****************************************************************************/
+
+/* WARNING: Whenever the layout of RGXFWIF_COMPCHECKS_BVNC changes, the
+ following define should be increased by 1 to indicate to the
+ compatibility logic that layout has changed. */
+#define RGXFWIF_COMPCHECKS_LAYOUT_VERSION 3
+
+typedef struct
+{
+ IMG_UINT32 ui32LayoutVersion; /* WARNING: This field must be defined as first one in this structure */
+ IMG_UINT64 RGXFW_ALIGN ui64BVNC;
+} UNCACHED_ALIGN RGXFWIF_COMPCHECKS_BVNC;
+
+typedef struct
+{
+ IMG_UINT8 ui8OsCountSupport;
+} UNCACHED_ALIGN RGXFWIF_INIT_OPTIONS;
+
+#define RGXFWIF_COMPCHECKS_BVNC_DECLARE_AND_INIT(name) \
+ RGXFWIF_COMPCHECKS_BVNC (name) = { \
+ RGXFWIF_COMPCHECKS_LAYOUT_VERSION, \
+ 0, \
+ }
+#define RGXFWIF_COMPCHECKS_BVNC_INIT(name) \
+ do { \
+ (name).ui32LayoutVersion = RGXFWIF_COMPCHECKS_LAYOUT_VERSION; \
+ (name).ui64BVNC = 0; \
+ } while (0)
+
+typedef struct
+{
+ RGXFWIF_COMPCHECKS_BVNC sHWBVNC; /*!< hardware BVNC (from the RGX registers) */
+ RGXFWIF_COMPCHECKS_BVNC sFWBVNC; /*!< firmware BVNC */
+ IMG_UINT32 ui32FWProcessorVersion; /*!< identifier of the FW processor version */
+ IMG_UINT32 ui32DDKVersion; /*!< software DDK version */
+ IMG_UINT32 ui32DDKBuild; /*!< software DDK build no. */
+ IMG_UINT32 ui32BuildOptions; /*!< build options bit-field */
+ RGXFWIF_INIT_OPTIONS sInitOptions; /*!< initialisation options bit-field */
+ IMG_BOOL bUpdated; /*!< Information is valid */
+} UNCACHED_ALIGN RGXFWIF_COMPCHECKS;
+
+/*!
+ ******************************************************************************
+ * Updated configuration post FW data init.
+ *****************************************************************************/
+typedef struct
+{
+ IMG_UINT32 ui32ActivePMLatencyms; /* APM latency in ms before signalling IDLE to the host */
+ IMG_UINT32 ui32RuntimeCfgFlags; /* Compatibility and other flags */
+ IMG_BOOL bActivePMLatencyPersistant; /* If set, APM latency does not reset to system default each GPU power transition */
+ IMG_UINT32 ui32CoreClockSpeed; /* Core clock speed, currently only used to calculate timer ticks */
+ IMG_UINT32 ui32DefaultDustsNumInit; /* Last number of dusts change requested by the host */
+ IMG_UINT32 ui32PHRMode; /* Periodic Hardware Reset configuration values */
+ IMG_UINT32 ui32HCSDeadlineMS; /* New number of milliseconds C/S is allowed to last */
+ IMG_UINT32 ui32WdgPeriodUs; /* The watchdog period in microseconds */
+ IMG_UINT32 aui32OSidPriority[RGXFW_MAX_NUM_OS]; /*!< Array of priorities per OS */
+ PRGXFWIF_HWPERFBUF sHWPerfBuf; /* On-demand allocated HWPerf buffer address, to be passed to the FW */
+} RGXFWIF_RUNTIME_CFG;
+
+/*!
+ *****************************************************************************
+ * Control data for RGX
+ *****************************************************************************/
+
+#define RGXFWIF_HWR_DEBUG_DUMP_ALL (99999U)
+
+#if defined(PDUMP)
+
+#define RGXFWIF_PID_FILTER_MAX_NUM_PIDS 32U
+
+typedef enum
+{
+ RGXFW_PID_FILTER_INCLUDE_ALL_EXCEPT,
+ RGXFW_PID_FILTER_EXCLUDE_ALL_EXCEPT
+} RGXFWIF_PID_FILTER_MODE;
+
+typedef struct
+{
+ IMG_PID uiPID;
+ IMG_UINT32 ui32OSID;
+} RGXFW_ALIGN RGXFWIF_PID_FILTER_ITEM;
+
+typedef struct
+{
+ RGXFWIF_PID_FILTER_MODE eMode;
+ /* each process in the filter list is specified by a PID and OS ID pair.
+ * each PID and OS pair is an item in the items array (asItems).
+ * if the array contains less than RGXFWIF_PID_FILTER_MAX_NUM_PIDS entries
+ * then it must be terminated by an item with pid of zero.
+ */
+ RGXFWIF_PID_FILTER_ITEM asItems[RGXFWIF_PID_FILTER_MAX_NUM_PIDS];
+} RGXFW_ALIGN RGXFWIF_PID_FILTER;
+#endif
+
+#if defined(SUPPORT_SECURITY_VALIDATION)
+#define RGXFWIF_SECURE_ACCESS_TEST_READ_WRITE_FW_DATA (0x1U << 0)
+#define RGXFWIF_SECURE_ACCESS_TEST_READ_WRITE_FW_CODE (0x1U << 1)
+#define RGXFWIF_SECURE_ACCESS_TEST_RUN_FROM_NONSECURE (0x1U << 2)
+#define RGXFWIF_SECURE_ACCESS_TEST_RUN_FROM_SECURE (0x1U << 3)
+#endif
+
+typedef enum
+{
+ RGXFWIF_TPU_DM_PDM = 0,
+ RGXFWIF_TPU_DM_VDM = 1,
+ RGXFWIF_TPU_DM_CDM = 2,
+ RGXFWIF_TPU_DM_TDM = 3,
+ RGXFWIF_TPU_DM_LAST
+} RGXFWIF_TPU_DM;
+
+typedef enum
+{
+ RGXFWIF_GPIO_VAL_OFF = 0, /*!< No GPIO validation */
+ RGXFWIF_GPIO_VAL_GENERAL = 1, /*!< Simple test case that
+ initiates by sending data via the
+ GPIO and then sends back any data
+ received over the GPIO */
+ RGXFWIF_GPIO_VAL_AP = 2, /*!< More complex test case that writes
+ and reads data across the entire
+ GPIO AP address range.*/
+#if defined(SUPPORT_STRIP_RENDERING)
+ RGXFWIF_GPIO_VAL_SR_BASIC = 3, /*!< Strip Rendering AP based basic test.*/
+ RGXFWIF_GPIO_VAL_SR_COMPLEX = 4, /*!< Strip Rendering AP based complex test.*/
+#endif
+ RGXFWIF_GPIO_VAL_TESTBENCH = 5, /*!< Validates the GPIO Testbench. */
+ RGXFWIF_GPIO_VAL_LOOPBACK = 6, /*!< Send and then receive each byte
+ in the range 0-255. */
+ RGXFWIF_GPIO_VAL_LOOPBACK_LITE = 7, /*!< Send and then receive each power-of-2
+ byte in the range 0-255. */
+ RGXFWIF_GPIO_VAL_LAST
+} RGXFWIF_GPIO_VAL_MODE;
+
+typedef enum
+{
+ FW_PERF_CONF_NONE = 0,
+ FW_PERF_CONF_ICACHE = 1,
+ FW_PERF_CONF_DCACHE = 2,
+ FW_PERF_CONF_POLLS = 3,
+ FW_PERF_CONF_CUSTOM_TIMER = 4,
+ FW_PERF_CONF_JTLB_INSTR = 5,
+ FW_PERF_CONF_INSTRUCTIONS = 6
+} FW_PERF_CONF;
+
+typedef enum
+{
+ FW_BOOT_STAGE_TLB_INIT_FAILURE = -2,
+ FW_BOOT_STAGE_NOT_AVAILABLE = -1,
+ FW_BOOT_NOT_STARTED = 0,
+ FW_BOOT_BLDR_STARTED = 1,
+ FW_BOOT_CACHE_DONE,
+ FW_BOOT_TLB_DONE,
+ FW_BOOT_MAIN_STARTED,
+ FW_BOOT_ALIGNCHECKS_DONE,
+ FW_BOOT_INIT_DONE,
+} FW_BOOT_STAGE;
+
+/*!
+ * @AddToGroup KCCBTypes
+ * @{
+ * @Name Kernel CCB return slot responses
+ * @{
+ * Usage of bit-fields instead of bare integers
+ * allows FW to possibly pack-in several responses for each single kCCB command.
+ */
+
+#define RGXFWIF_KCCB_RTN_SLOT_CMD_EXECUTED (1U << 0) /*!< Command executed (return status from FW) */
+#define RGXFWIF_KCCB_RTN_SLOT_CLEANUP_BUSY (1U << 1) /*!< A cleanup was requested but resource busy */
+#define RGXFWIF_KCCB_RTN_SLOT_POLL_FAILURE (1U << 2) /*!< Poll failed in FW for a HW operation to complete */
+
+#define RGXFWIF_KCCB_RTN_SLOT_NO_RESPONSE 0x0U /*!< Reset value of a kCCB return slot (set by host) */
+/*!
+ * @} End of Name Kernel CCB return slot responses
+ * @} End of AddToGroup KCCBTypes
+ */
+
+typedef struct
+{
+ /* Fw-Os connection states */
+ volatile RGXFWIF_CONNECTION_FW_STATE eConnectionFwState;
+ volatile RGXFWIF_CONNECTION_OS_STATE eConnectionOsState;
+ volatile IMG_UINT32 ui32AliveFwToken;
+ volatile IMG_UINT32 ui32AliveOsToken;
+} UNCACHED_ALIGN RGXFWIF_CONNECTION_CTL;
+
+/*! @Brief Firmware OS Initialization data \ref RGXFWIF_OSINIT
+ * allocated by services and used by the Firmware on boot
+ **/
+typedef struct
+{
+ /* Kernel CCB */
+ PRGXFWIF_CCB_CTL psKernelCCBCtl; /*!< Kernel CCB Control */
+ PRGXFWIF_CCB psKernelCCB; /*!< Kernel CCB */
+ PRGXFWIF_CCB_RTN_SLOTS psKernelCCBRtnSlots; /*!< Kernel CCB return slots */
+
+ /* Firmware CCB */
+ PRGXFWIF_CCB_CTL psFirmwareCCBCtl; /*!< Firmware CCB control */
+ PRGXFWIF_CCB psFirmwareCCB; /*!< Firmware CCB */
+
+ /* Workload Estimation Firmware CCB */
+ PRGXFWIF_CCB_CTL psWorkEstFirmwareCCBCtl; /*!< Workload estimation control */
+ PRGXFWIF_CCB psWorkEstFirmwareCCB; /*!< Workload estimation buffer */
+
+ PRGXFWIF_HWRINFOBUF sRGXFWIfHWRInfoBufCtl; /*!< HWRecoveryInfo control */
+
+ IMG_UINT32 ui32HWRDebugDumpLimit; /*!< Firmware debug dump maximum limit */
+
+ PRGXFWIF_OSDATA sFwOsData; /*!< Firmware per-os shared data */
+
+ RGXFWIF_COMPCHECKS sRGXCompChecks; /*!< Compatibility checks to be populated by the Firmware */
+
+} UNCACHED_ALIGN RGXFWIF_OSINIT;
+
+/*! @Brief Firmware System Initialization data \ref RGXFWIF_SYSINIT
+ * allocated by services and used by the Firmware on boot
+ **/
+typedef struct
+{
+ IMG_DEV_PHYADDR RGXFW_ALIGN sFaultPhysAddr; /*!< Fault read address */
+
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sPDSExecBase; /*!< PDS execution base */
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sUSCExecBase; /*!< USC execution base */
+
+ IMG_UINT64 RGXFW_ALIGN ui64HWPerfFilter; /*! Event filter for Firmware events */
+
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sSLC3FenceDevVAddr;
+
+ IMG_UINT32 RGXFW_ALIGN aui32TPUTrilinearFracMask[RGXFWIF_TPU_DM_LAST];
+
+ RGXFWIF_SIGBUF_CTL asSigBufCtl[RGXFWIF_DM_MAX]; /*!< Signature and Checksum Buffers for DMs */
+
+ RGXFWIF_PDVFS_OPP sPDVFSOPPInfo;
+
+ RGXFWIF_DMA_ADDR sCorememDataStore; /*!< Firmware coremem data */
+
+ RGXFWIF_COUNTER_DUMP_CTL sCounterDumpCtl;
+
+#if defined(SUPPORT_FIRMWARE_GCOV)
+ RGXFWIF_FIRMWARE_GCOV_CTL sFirmwareGcovCtl; /*!< Firmware gcov buffer control */
+#endif
+
+ IMG_UINT32 ui32FilterFlags;
+
+ PRGXFWIF_RUNTIME_CFG sRuntimeCfg; /*!< Firmware Runtime configuration */
+
+ PRGXFWIF_TRACEBUF sTraceBufCtl; /*!< Firmware Trace buffer control */
+ PRGXFWIF_SYSDATA sFwSysData; /*!< Firmware System shared data */
+#if defined(SUPPORT_TBI_INTERFACE)
+ PRGXFWIF_TBIBUF sTBIBuf; /*!< Tbi log buffer */
+#endif
+
+ PRGXFWIF_GPU_UTIL_FWCB sGpuUtilFWCbCtl; /*!< GPU utilization buffer */
+ PRGXFWIF_REG_CFG sRegCfg; /*!< Firmware register user configuration */
+ PRGXFWIF_HWPERF_CTL sHWPerfCtl; /*!< HWPerf counter block configuration.*/
+
+ RGXFWIF_DEV_VIRTADDR sAlignChecks; /*!< Array holding Server structures alignment data */
+
+ IMG_UINT32 ui32InitialCoreClockSpeed; /*!< Core clock speed at FW boot time */
+
+ IMG_UINT32 ui32InitialActivePMLatencyms; /*!< APM latency in ms before signalling IDLE to the host */
+
+ IMG_BOOL bFirmwareStarted; /*!< Flag to be set by the Firmware after successful start */
+
+ IMG_UINT32 ui32MarkerVal; /*!< Host/FW Trace synchronisation Partition Marker */
+
+ IMG_UINT32 ui32FirmwareStartedTimeStamp; /*!< Firmware initialization complete time */
+
+ IMG_UINT32 ui32JonesDisableMask;
+
+ FW_PERF_CONF eFirmwarePerf; /*!< Firmware performance counter config */
+
+ /**
+ * FW Pointer to memory containing core clock rate in Hz.
+ * Firmware (PDVFS) updates the memory when running on non primary FW thread
+ * to communicate to host driver.
+ */
+ PRGXFWIF_CORE_CLK_RATE sCoreClockRate;
+
+#if defined(PDUMP)
+ RGXFWIF_PID_FILTER sPIDFilter;
+#endif
+
+ RGXFWIF_GPIO_VAL_MODE eGPIOValidationMode;
+
+ RGX_HWPERF_BVNC sBvncKmFeatureFlags; /*!< Used in HWPerf for decoding BVNC Features*/
+
+#if defined(SUPPORT_SECURITY_VALIDATION)
+ IMG_UINT32 ui32SecurityTestFlags;
+ RGXFWIF_DEV_VIRTADDR pbSecureBuffer;
+ RGXFWIF_DEV_VIRTADDR pbNonSecureBuffer;
+#endif
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+ /*
+ * Used when validation is enabled to allow the host to check
+ * that MTS sent the correct sideband in response to a kick
+ * from a given OSes schedule register.
+ * Testing is enabled if RGXFWIF_KICK_TEST_ENABLED_BIT is set
+ *
+ * Set by the host to:
+ * (osid << RGXFWIF_KICK_TEST_OSID_SHIFT) | RGXFWIF_KICK_TEST_ENABLED_BIT
+ * reset to 0 by FW when kicked by the given OSid
+ */
+ IMG_UINT32 ui32OSKickTest;
+#endif
+
+ /* Value to write into RGX_CR_TFBC_COMPRESSION_CONTROL */
+ IMG_UINT32 ui32TFBCCompressionControl;
+
+} UNCACHED_ALIGN RGXFWIF_SYSINIT;
+
+static_assert(sizeof(RGXFWIF_SYSINIT) <= 792,
+ "Size of structure RGXFW_SYSINIT exceeds maximum expected size.");
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+#define RGXFWIF_KICK_TEST_ENABLED_BIT 0x1
+#define RGXFWIF_KICK_TEST_OSID_SHIFT 0x1
+#endif
+
+/*!
+ *****************************************************************************
+ * Timer correlation shared data and defines
+ *****************************************************************************/
+
+typedef struct
+{
+ IMG_UINT64 RGXFW_ALIGN ui64OSTimeStamp;
+ IMG_UINT64 RGXFW_ALIGN ui64OSMonoTimeStamp;
+ IMG_UINT64 RGXFW_ALIGN ui64CRTimeStamp;
+
+ /* Utility variable used to convert CR timer deltas to OS timer deltas (nS),
+ * where the deltas are relative to the timestamps above:
+ * deltaOS = (deltaCR * K) >> decimal_shift, see full explanation below */
+ IMG_UINT64 RGXFW_ALIGN ui64CRDeltaToOSDeltaKNs;
+
+ IMG_UINT32 ui32CoreClockSpeed;
+ IMG_UINT32 ui32Reserved;
+} UNCACHED_ALIGN RGXFWIF_TIME_CORR;
+
+
+/* The following macros are used to help converting FW timestamps to the Host
+ * time domain. On the FW the RGX_CR_TIMER counter is used to keep track of
+ * time; it increments by 1 every 256 GPU clock ticks, so the general
+ * formula to perform the conversion is:
+ *
+ * [ GPU clock speed in Hz, if (scale == 10^9) then deltaOS is in nS,
+ * otherwise if (scale == 10^6) then deltaOS is in uS ]
+ *
+ * deltaCR * 256 256 * scale
+ * deltaOS = --------------- * scale = deltaCR * K [ K = --------------- ]
+ * GPUclockspeed GPUclockspeed
+ *
+ * The actual K is multiplied by 2^20 (and deltaCR * K is divided by 2^20)
+ * to get some better accuracy and to avoid returning 0 in the integer
+ * division 256000000/GPUfreq if GPUfreq is greater than 256MHz.
+ * This is the same as keeping K as a decimal number.
+ *
+ * The maximum deltaOS is slightly more than 5hrs for all GPU frequencies
+ * (deltaCR * K is more or less a constant), and it's relative to the base
+ * OS timestamp sampled as a part of the timer correlation data.
+ * This base is refreshed on GPU power-on, DVFS transition and periodic
+ * frequency calibration (executed every few seconds if the FW is doing
+ * some work), so as long as the GPU is doing something and one of these
+ * events is triggered then deltaCR * K will not overflow and deltaOS will be
+ * correct.
+ */
+
+#define RGXFWIF_CRDELTA_TO_OSDELTA_ACCURACY_SHIFT (20)
+
+#define RGXFWIF_GET_DELTA_OSTIME_NS(deltaCR, K) \
+ (((deltaCR) * (K)) >> RGXFWIF_CRDELTA_TO_OSDELTA_ACCURACY_SHIFT)
+
+
+/*!
+ ******************************************************************************
+ * GPU Utilisation
+ *****************************************************************************/
+
+/* See rgx_common.h for a list of GPU states */
+#define RGXFWIF_GPU_UTIL_TIME_MASK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF) & ~RGXFWIF_GPU_UTIL_STATE_MASK)
+
+#define RGXFWIF_GPU_UTIL_GET_TIME(word) ((word) & RGXFWIF_GPU_UTIL_TIME_MASK)
+#define RGXFWIF_GPU_UTIL_GET_STATE(word) ((word) & RGXFWIF_GPU_UTIL_STATE_MASK)
+
+/* The OS timestamps computed by the FW are approximations of the real time,
+ * which means they could be slightly behind or ahead the real timer on the Host.
+ * In some cases we can perform subtractions between FW approximated
+ * timestamps and real OS timestamps, so we need a form of protection against
+ * negative results if for instance the FW one is a bit ahead of time.
+ */
+#define RGXFWIF_GPU_UTIL_GET_PERIOD(newtime,oldtime) \
+ (((newtime) > (oldtime)) ? ((newtime) - (oldtime)) : 0U)
+
+#define RGXFWIF_GPU_UTIL_MAKE_WORD(time,state) \
+ (RGXFWIF_GPU_UTIL_GET_TIME(time) | RGXFWIF_GPU_UTIL_GET_STATE(state))
+
+
+/* The timer correlation array must be big enough to ensure old entries won't be
+ * overwritten before all the HWPerf events linked to those entries are processed
+ * by the MISR. The update frequency of this array depends on how fast the system
+ * can change state (basically how small the APM latency is) and perform DVFS transitions.
+ *
+ * The minimum size is 2 (not 1) to avoid race conditions between the FW reading
+ * an entry while the Host is updating it. With 2 entries in the worst case the FW
+ * will read old data, which is still quite ok if the Host is updating the timer
+ * correlation at that time.
+ */
+#define RGXFWIF_TIME_CORR_ARRAY_SIZE 256U
+#define RGXFWIF_TIME_CORR_CURR_INDEX(seqcount) ((seqcount) % RGXFWIF_TIME_CORR_ARRAY_SIZE)
+
+/* Make sure the timer correlation array size is a power of 2 */
+static_assert((RGXFWIF_TIME_CORR_ARRAY_SIZE & (RGXFWIF_TIME_CORR_ARRAY_SIZE - 1U)) == 0U,
+ "RGXFWIF_TIME_CORR_ARRAY_SIZE must be a power of two");
+
+typedef struct
+{
+ RGXFWIF_TIME_CORR sTimeCorr[RGXFWIF_TIME_CORR_ARRAY_SIZE];
+ IMG_UINT32 ui32TimeCorrSeqCount;
+
+ /* Compatibility and other flags */
+ IMG_UINT32 ui32GpuUtilFlags;
+
+ /* Last GPU state + OS time of the last state update */
+ IMG_UINT64 RGXFW_ALIGN ui64LastWord;
+
+ /* Counters for the amount of time the GPU was active/idle/blocked */
+ IMG_UINT64 RGXFW_ALIGN aui64StatsCounters[RGXFWIF_GPU_UTIL_STATE_NUM];
+} UNCACHED_ALIGN RGXFWIF_GPU_UTIL_FWCB;
+
+typedef struct
+{
+ IMG_UINT32 ui32RenderTargetIndex; //Render number
+ IMG_UINT32 ui32CurrentRenderTarget; //index in RTA
+ IMG_UINT32 ui32ActiveRenderTargets; //total active RTs
+ IMG_UINT32 ui32CumulActiveRenderTargets; //total active RTs from the first TA kick, for OOM
+ RGXFWIF_DEV_VIRTADDR sValidRenderTargets; //Array of valid RT indices
+ RGXFWIF_DEV_VIRTADDR sRTANumPartialRenders; //Array of number of occurred partial renders per render target
+ IMG_UINT32 ui32MaxRTs; //Number of render targets in the array
+ IMG_UINT32 ui32RTACtlFlags; /* Compatibility and other flags */
+} UNCACHED_ALIGN RGXFWIF_RTA_CTL;
+
+/*! @Brief Firmware Freelist holding usage state of the Parameter Buffers */
+typedef struct
+{
+ IMG_DEV_VIRTADDR RGXFW_ALIGN psFreeListDevVAddr;
+ IMG_UINT64 RGXFW_ALIGN ui64CurrentDevVAddr;
+ IMG_UINT32 ui32CurrentStackTop;
+ IMG_UINT32 ui32MaxPages;
+ IMG_UINT32 ui32GrowPages;
+ IMG_UINT32 ui32CurrentPages; /* HW pages */
+ IMG_UINT32 ui32AllocatedPageCount;
+ IMG_UINT32 ui32AllocatedMMUPageCount;
+#if defined(SUPPORT_SHADOW_FREELISTS)
+ IMG_UINT32 ui32HWRCounter;
+ PRGXFWIF_FWMEMCONTEXT psFWMemContext;
+#endif
+ IMG_UINT32 ui32FreeListID;
+ IMG_BOOL bGrowPending;
+ IMG_UINT32 ui32ReadyPages; /* Pages that should be used only when OOM is reached */
+ IMG_UINT32 ui32FreelistFlags; /* Compatibility and other flags */
+} UNCACHED_ALIGN RGXFWIF_FREELIST;
+
+/*!
+ ******************************************************************************
+ * Parameter Management (PM) control data for RGX
+ *****************************************************************************/
+
+/* Used only by Firmware but defined here for similarity with Volcanic where it's required for SW TRP */
+
+typedef enum
+{
+ RGXFW_SPM_STATE_NONE = 0,
+ RGXFW_SPM_STATE_PR_BLOCKED,
+ RGXFW_SPM_STATE_WAIT_FOR_GROW,
+ RGXFW_SPM_STATE_WAIT_FOR_HW,
+ RGXFW_SPM_STATE_PR_RUNNING,
+ RGXFW_SPM_STATE_PR_AVOIDED,
+ RGXFW_SPM_STATE_PR_EXECUTED,
+} RGXFW_SPM_STATE;
+
+/*!
+ ******************************************************************************
+ * @Brief RGX firmware SPM Control Data:
+ * This structure holds all the internal SPM control Data of the firmware.
+ *****************************************************************************/
+typedef struct
+{
+ RGXFW_SPM_STATE eSPMState; /*!< Current state of TA OOM event */
+ RGXFWIF_UFO sPartialRenderTA3DFence; /*!< TA/3D fence object holding the value to let through the 3D partial command */
+#if defined(RGX_FIRMWARE)
+ RGXFWIF_FWCOMMONCONTEXT *ps3dContext; /*!< Pointer to the 3D Context holding the partial render */
+ RGXFWIF_PRBUFFER *apsPRBuffer[RGXFWIF_PRBUFFER_MAXSUPPORTED]; /*!< Array of pointers to PR Buffers which may be used if partial render is needed */
+#else
+ RGXFWIF_DEV_VIRTADDR ps3dContext; /*!< Pointer to the 3D Context holding the partial render */
+ RGXFWIF_DEV_VIRTADDR apsPRBuffer[RGXFWIF_PRBUFFER_MAXSUPPORTED]; /*!< Array of pointers to PR Buffers which may be used if partial render is needed */
+#endif
+ IMG_UINT32 ui32CmdOffset; /*!< CCCB offset of the command holding the partial render */
+ bool b3DMemFreeDetected; /*!< Indicates if a 3D Memory Free has been detected, which resolves OOM */
+} RGXFW_ALIGN_DCACHEL RGXFW_SPMCTL;
+
+static_assert(sizeof(RGXFW_SPMCTL) <= 64,
+ "Size of structure RGXFW_SPMCTL exceeds maximum expected size.");
+/*!
+ ******************************************************************************
+ * HWRTData
+ *****************************************************************************/
+
+/* HWRTData flags */
+/* Deprecated flags 1:0 */
+#define HWRTDATA_HAS_LAST_TA (1U << 2)
+#define HWRTDATA_PARTIAL_RENDERED (1U << 3)
+#define HWRTDATA_DISABLE_TILE_REORDERING (1U << 4)
+#define HWRTDATA_NEED_BRN65101_BLIT (1U << 5)
+#define HWRTDATA_FIRST_BRN65101_STRIP (1U << 6)
+#define HWRTDATA_NEED_BRN67182_2ND_RENDER (1U << 7)
+
+typedef enum
+{
+ RGXFWIF_RTDATA_STATE_NONE = 0,
+ RGXFWIF_RTDATA_STATE_KICKTA,
+ RGXFWIF_RTDATA_STATE_KICKTAFIRST,
+ RGXFWIF_RTDATA_STATE_TAFINISHED,
+ RGXFWIF_RTDATA_STATE_KICK3D,
+ RGXFWIF_RTDATA_STATE_3DFINISHED,
+ RGXFWIF_RTDATA_STATE_3DCONTEXTSTORED,
+ RGXFWIF_RTDATA_STATE_TAOUTOFMEM,
+ RGXFWIF_RTDATA_STATE_PARTIALRENDERFINISHED,
+ /* In case of HWR, we can't set the RTDATA state to NONE,
+ * as this will cause any TA to become a first TA.
+ * To ensure all related TA's are skipped, we use the HWR state */
+ RGXFWIF_RTDATA_STATE_HWR,
+ RGXFWIF_RTDATA_STATE_UNKNOWN = 0x7FFFFFFFU
+} RGXFWIF_RTDATA_STATE;
+
+typedef struct
+{
+ IMG_BOOL bTACachesNeedZeroing;
+
+ IMG_UINT32 ui32ScreenPixelMax;
+ IMG_UINT64 RGXFW_ALIGN ui64MultiSampleCtl;
+ IMG_UINT64 ui64FlippedMultiSampleCtl;
+ IMG_UINT32 ui32TPCStride;
+ IMG_UINT32 ui32TPCSize;
+ IMG_UINT32 ui32TEScreen;
+ IMG_UINT32 ui32MTileStride;
+ IMG_UINT32 ui32TEAA;
+ IMG_UINT32 ui32TEMTILE1;
+ IMG_UINT32 ui32TEMTILE2;
+ IMG_UINT32 ui32ISPMergeLowerX;
+ IMG_UINT32 ui32ISPMergeLowerY;
+ IMG_UINT32 ui32ISPMergeUpperX;
+ IMG_UINT32 ui32ISPMergeUpperY;
+ IMG_UINT32 ui32ISPMergeScaleX;
+ IMG_UINT32 ui32ISPMergeScaleY;
+ IMG_UINT32 uiRgnHeaderSize;
+ IMG_UINT32 ui32ISPMtileSize;
+} UNCACHED_ALIGN RGXFWIF_HWRTDATA_COMMON;
+
+/*! @Brief Firmware Render Target data i.e. HWRTDATA used to hold the PM context */
+typedef struct
+{
+ IMG_DEV_VIRTADDR RGXFW_ALIGN psPMMListDevVAddr; /*!< MList Data Store */
+
+ IMG_UINT64 RGXFW_ALIGN ui64VCECatBase[4];
+ IMG_UINT64 RGXFW_ALIGN ui64VCELastCatBase[4];
+ IMG_UINT64 RGXFW_ALIGN ui64TECatBase[4];
+ IMG_UINT64 RGXFW_ALIGN ui64TELastCatBase[4];
+ IMG_UINT64 RGXFW_ALIGN ui64AlistCatBase;
+ IMG_UINT64 RGXFW_ALIGN ui64AlistLastCatBase;
+
+ IMG_UINT64 RGXFW_ALIGN ui64PMAListStackPointer;
+ IMG_UINT32 ui32PMMListStackPointer;
+
+ RGXFWIF_DEV_VIRTADDR sHWRTDataCommonFwAddr;
+
+ IMG_UINT32 ui32HWRTDataFlags;
+ RGXFWIF_RTDATA_STATE eState;
+
+ PRGXFWIF_FREELIST RGXFW_ALIGN apsFreeLists[RGXFW_MAX_FREELISTS];
+ IMG_UINT32 aui32FreeListHWRSnapshot[RGXFW_MAX_FREELISTS];
+
+ IMG_DEV_VIRTADDR RGXFW_ALIGN psVHeapTableDevVAddr;
+
+ RGXFWIF_CLEANUP_CTL sCleanupState;
+
+ RGXFWIF_RTA_CTL sRTACtl;
+
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sTailPtrsDevVAddr;
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sMacrotileArrayDevVAddr;
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sRgnHeaderDevVAddr;
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sRTCDevVAddr;
+#if defined(RGX_FIRMWARE)
+ struct RGXFWIF_FWCOMMONCONTEXT_* RGXFW_ALIGN psOwnerGeom;
+#else
+ RGXFWIF_DEV_VIRTADDR RGXFW_ALIGN pui32OwnerGeomNotUsedByHost;
+#endif
+#if defined(SUPPORT_TRP)
+ IMG_UINT32 ui32KickFlagsCopy;
+ IMG_UINT32 ui32TRPState;
+ RGXFWIF_TRP_CHECKSUM_3D aui64TRPChecksums3D;
+ RGXFWIF_TRP_CHECKSUM_GEOM aui64TRPChecksumsGeom;
+ IMG_UINT32 ui32TEPageCopy;
+ IMG_UINT32 ui32VCEPageCopy;
+#endif
+} UNCACHED_ALIGN RGXFWIF_HWRTDATA;
+
+/* Sync_checkpoint firmware object.
+ * This is the FW-addressable structure use to hold the sync checkpoint's
+ * state and other information which needs to be accessed by the firmware.
+ */
+typedef struct
+{
+ IMG_UINT32 ui32State; /*!< Holds the current state of the sync checkpoint */
+ IMG_UINT32 ui32FwRefCount; /*!< Holds the FW reference count (num of fences/updates processed) */
+} SYNC_CHECKPOINT_FW_OBJ;
+
+/* Bit mask Firmware can use to test if a checkpoint has signalled or errored */
+#define SYNC_CHECKPOINT_SIGNALLED_MASK (0x1 << 0)
+
+#endif /* RGX_FWIF_KM_H */
+
+/******************************************************************************
+ End of file (rgx_fwif_km.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/rogue/rgx_fwif_shared.h b/drivers/gpu/drm/img-rogue/include/rogue/rgx_fwif_shared.h
new file mode 100644
index 000000000..3d47224e6
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/rogue/rgx_fwif_shared.h
@@ -0,0 +1,307 @@
+/*************************************************************************/ /*!
+@File
+@Title RGX firmware interface structures
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description RGX firmware interface structures shared by both host client
+ and host server
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(RGX_FWIF_SHARED_H)
+#define RGX_FWIF_SHARED_H
+
+#include "img_types.h"
+#include "img_defs.h"
+#include "rgx_common.h"
+#include "powervr/mem_types.h"
+
+/* Indicates the number of RTDATAs per RTDATASET */
+#define RGXMKIF_NUM_RTDATAS 2U
+
+/* Maximum number of UFOs in a CCB command.
+ * The number is based on having 32 sync prims (as originally), plus 32 sync
+ * checkpoints.
+ * Once the use of sync prims is no longer supported, we will retain
+ * the same total (64) as the number of sync checkpoints which may be
+ * supporting a fence is not visible to the client driver and has to
+ * allow for the number of different timelines involved in fence merges.
+ */
+#define RGXFWIF_CCB_CMD_MAX_UFOS (32U+32U)
+
+/*
+ * This is a generic limit imposed on any DM (TA,3D,CDM,TDM,2D,TRANSFER)
+ * command passed through the bridge.
+ * Just across the bridge in the server, any incoming kick command size is
+ * checked against this maximum limit.
+ * In case the incoming command size is larger than the specified limit,
+ * the bridge call is retired with error.
+ */
+#define RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE (1024U)
+
+typedef struct RGXFWIF_DEV_VIRTADDR_
+{
+ IMG_UINT32 ui32Addr;
+} RGXFWIF_DEV_VIRTADDR;
+
+typedef struct
+{
+ IMG_DEV_VIRTADDR RGXFW_ALIGN psDevVirtAddr;
+ RGXFWIF_DEV_VIRTADDR pbyFWAddr;
+} UNCACHED_ALIGN RGXFWIF_DMA_ADDR;
+
+typedef IMG_UINT8 RGXFWIF_CCCB;
+
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_UFO_ADDR;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CLEANUP_CTL;
+
+
+/*!
+ * @InGroup ClientCCBTypes
+ * @Brief Command data for fence & update types Client CCB commands.
+ */
+typedef struct
+{
+ PRGXFWIF_UFO_ADDR puiAddrUFO; /*!< Address to be checked/updated */
+ IMG_UINT32 ui32Value; /*!< Value to check-against/update-to */
+} RGXFWIF_UFO;
+
+typedef struct
+{
+ IMG_UINT32 ui32SubmittedCommands; /*!< Number of commands received by the FW */
+ IMG_UINT32 ui32ExecutedCommands; /*!< Number of commands executed by the FW */
+} UNCACHED_ALIGN RGXFWIF_CLEANUP_CTL;
+
+#define RGXFWIF_PRBUFFER_START IMG_UINT32_C(0)
+#define RGXFWIF_PRBUFFER_ZSBUFFER IMG_UINT32_C(0)
+#define RGXFWIF_PRBUFFER_MSAABUFFER IMG_UINT32_C(1)
+#define RGXFWIF_PRBUFFER_MAXSUPPORTED IMG_UINT32_C(2)
+
+typedef IMG_UINT32 RGXFWIF_PRBUFFER_TYPE;
+
+typedef enum
+{
+ RGXFWIF_PRBUFFER_UNBACKED = 0,
+ RGXFWIF_PRBUFFER_BACKED,
+ RGXFWIF_PRBUFFER_BACKING_PENDING,
+ RGXFWIF_PRBUFFER_UNBACKING_PENDING,
+}RGXFWIF_PRBUFFER_STATE;
+
+typedef struct
+{
+ IMG_UINT32 ui32BufferID; /*!< Buffer ID*/
+ IMG_BOOL bOnDemand; /*!< Needs On-demand Z/S/MSAA Buffer allocation */
+ RGXFWIF_PRBUFFER_STATE eState; /*!< Z/S/MSAA -Buffer state */
+ RGXFWIF_CLEANUP_CTL sCleanupState; /*!< Cleanup state */
+ IMG_UINT32 ui32PRBufferFlags; /*!< Compatibility and other flags */
+} UNCACHED_ALIGN RGXFWIF_PRBUFFER;
+
+/*
+ * Used to share frame numbers across UM-KM-FW,
+ * frame number is set in UM,
+ * frame number is required in both KM for HTB and FW for FW trace.
+ *
+ * May be used to house Kick flags in the future.
+ */
+typedef struct
+{
+ IMG_UINT32 ui32FrameNum; /*!< associated frame number */
+} CMD_COMMON;
+
+/*
+ * TA and 3D commands require set of firmware addresses that are stored in the
+ * Kernel. Client has handle(s) to Kernel containers storing these addresses,
+ * instead of raw addresses. We have to patch/write these addresses in KM to
+ * prevent UM from controlling FW addresses directly.
+ * Typedefs for TA and 3D commands are shared between Client and Firmware (both
+ * single-BVNC). Kernel is implemented in a multi-BVNC manner, so it can't use
+ * TA|3D CMD type definitions directly. Therefore we have a SHARED block that
+ * is shared between UM-KM-FW across all BVNC configurations.
+ */
+typedef struct
+{
+ CMD_COMMON sCmn; /*!< Common command attributes */
+ RGXFWIF_DEV_VIRTADDR sHWRTData; /* RTData associated with this command,
+ this is used for context selection and for storing out HW-context,
+ when TA is switched out for continuing later */
+
+ RGXFWIF_DEV_VIRTADDR asPRBuffer[RGXFWIF_PRBUFFER_MAXSUPPORTED]; /* Supported PR Buffers like Z/S/MSAA Scratch */
+
+} CMDTA3D_SHARED;
+
+/*!
+ * Client Circular Command Buffer (CCCB) control structure.
+ * This is shared between the Server and the Firmware and holds byte offsets
+ * into the CCCB as well as the wrapping mask to aid wrap around. A given
+ * snapshot of this queue with Cmd 1 running on the GPU might be:
+ *
+ * Roff Doff Woff
+ * [..........|-1----------|=2===|=3===|=4===|~5~~~~|~6~~~~|~7~~~~|..........]
+ * < runnable commands >< !ready to run >
+ *
+ * Cmd 1 : Currently executing on the GPU data master.
+ * Cmd 2,3,4: Fence dependencies met, commands runnable.
+ * Cmd 5... : Fence dependency not met yet.
+ */
+typedef struct
+{
+ IMG_UINT32 ui32WriteOffset; /*!< Host write offset into CCB. This
+ * must be aligned to 16 bytes. */
+ IMG_UINT32 ui32ReadOffset; /*!< Firmware read offset into CCB.
+ Points to the command that is
+ * runnable on GPU, if R!=W */
+ IMG_UINT32 ui32DepOffset; /*!< Firmware fence dependency offset.
+ * Points to commands not ready, i.e.
+ * fence dependencies are not met. */
+ IMG_UINT32 ui32WrapMask; /*!< Offset wrapping mask, total capacity
+ * in bytes of the CCB-1 */
+} UNCACHED_ALIGN RGXFWIF_CCCB_CTL;
+
+
+typedef IMG_UINT32 RGXFW_FREELIST_TYPE;
+
+#define RGXFW_LOCAL_FREELIST IMG_UINT32_C(0)
+#define RGXFW_GLOBAL_FREELIST IMG_UINT32_C(1)
+#define RGXFW_MAX_FREELISTS (RGXFW_GLOBAL_FREELIST + 1U)
+
+/*!
+ * @Defgroup ContextSwitching Context switching data interface
+ * @Brief Types grouping data structures and defines used in realising the Context Switching (CSW) functionality
+ * @{
+ */
+
+/*!
+ * @Brief GEOM DM or TA register controls for context switch
+ */
+typedef struct
+{
+ IMG_UINT64 uTAReg_VDM_CONTEXT_STATE_BASE_ADDR; /*!< The base address of the VDM's context state buffer */
+ IMG_UINT64 uTAReg_VDM_CONTEXT_STATE_RESUME_ADDR;
+ IMG_UINT64 uTAReg_TA_CONTEXT_STATE_BASE_ADDR; /*!< The base address of the TA's context state buffer */
+
+ struct
+ {
+ IMG_UINT64 uTAReg_VDM_CONTEXT_STORE_TASK0; /*!< VDM context store task 0 */
+ IMG_UINT64 uTAReg_VDM_CONTEXT_STORE_TASK1; /*!< VDM context store task 1 */
+ IMG_UINT64 uTAReg_VDM_CONTEXT_STORE_TASK2; /*!< VDM context store task 2 */
+
+ /* VDM resume state update controls */
+ IMG_UINT64 uTAReg_VDM_CONTEXT_RESUME_TASK0; /*!< VDM context resume task 0 */
+ IMG_UINT64 uTAReg_VDM_CONTEXT_RESUME_TASK1; /*!< VDM context resume task 1 */
+ IMG_UINT64 uTAReg_VDM_CONTEXT_RESUME_TASK2; /*!< VDM context resume task 2 */
+
+ IMG_UINT64 uTAReg_VDM_CONTEXT_STORE_TASK3;
+ IMG_UINT64 uTAReg_VDM_CONTEXT_STORE_TASK4;
+
+ IMG_UINT64 uTAReg_VDM_CONTEXT_RESUME_TASK3;
+ IMG_UINT64 uTAReg_VDM_CONTEXT_RESUME_TASK4;
+ } asTAState[2];
+
+} RGXFWIF_TAREGISTERS_CSWITCH;
+/*! @} End of Defgroup ContextSwitching */
+
+#define RGXFWIF_TAREGISTERS_CSWITCH_SIZE sizeof(RGXFWIF_TAREGISTERS_CSWITCH)
+
+typedef struct
+{
+ IMG_UINT64 uCDMReg_CDM_CONTEXT_PDS0;
+ IMG_UINT64 uCDMReg_CDM_CONTEXT_PDS1;
+ IMG_UINT64 uCDMReg_CDM_TERMINATE_PDS;
+ IMG_UINT64 uCDMReg_CDM_TERMINATE_PDS1;
+
+ /* CDM resume controls */
+ IMG_UINT64 uCDMReg_CDM_RESUME_PDS0;
+ IMG_UINT64 uCDMReg_CDM_CONTEXT_PDS0_B;
+ IMG_UINT64 uCDMReg_CDM_RESUME_PDS0_B;
+
+} RGXFWIF_CDM_REGISTERS_CSWITCH;
+
+/*!
+ * @InGroup ContextSwitching
+ * @Brief Render context static register controls for context switch
+ */
+typedef struct
+{
+ RGXFWIF_TAREGISTERS_CSWITCH RGXFW_ALIGN sCtxSwitch_Regs; /*!< Geom registers for ctx switch */
+} RGXFWIF_STATIC_RENDERCONTEXT_STATE;
+
+#define RGXFWIF_STATIC_RENDERCONTEXT_SIZE sizeof(RGXFWIF_STATIC_RENDERCONTEXT_STATE)
+
+typedef struct
+{
+ RGXFWIF_CDM_REGISTERS_CSWITCH RGXFW_ALIGN sCtxSwitch_Regs; /*!< CDM registers for ctx switch */
+} RGXFWIF_STATIC_COMPUTECONTEXT_STATE;
+
+#define RGXFWIF_STATIC_COMPUTECONTEXT_SIZE sizeof(RGXFWIF_STATIC_COMPUTECONTEXT_STATE)
+
+/*!
+ @Brief Context reset reason. Last reset reason for a reset context.
+*/
+typedef enum
+{
+ RGX_CONTEXT_RESET_REASON_NONE = 0, /*!< No reset reason recorded */
+ RGX_CONTEXT_RESET_REASON_GUILTY_LOCKUP = 1, /*!< Caused a reset due to locking up */
+ RGX_CONTEXT_RESET_REASON_INNOCENT_LOCKUP = 2, /*!< Affected by another context locking up */
+ RGX_CONTEXT_RESET_REASON_GUILTY_OVERRUNING = 3, /*!< Overran the global deadline */
+ RGX_CONTEXT_RESET_REASON_INNOCENT_OVERRUNING = 4, /*!< Affected by another context overrunning */
+ RGX_CONTEXT_RESET_REASON_HARD_CONTEXT_SWITCH = 5, /*!< Forced reset to ensure scheduling requirements */
+ RGX_CONTEXT_RESET_REASON_WGP_CHECKSUM = 6, /*!< CDM Mission/safety checksum mismatch */
+ RGX_CONTEXT_RESET_REASON_TRP_CHECKSUM = 7, /*!< TRP checksum mismatch */
+ RGX_CONTEXT_RESET_REASON_GPU_ECC_OK = 8, /*!< GPU ECC error (corrected, OK) */
+ RGX_CONTEXT_RESET_REASON_GPU_ECC_HWR = 9, /*!< GPU ECC error (uncorrected, HWR) */
+ RGX_CONTEXT_RESET_REASON_FW_ECC_OK = 10, /*!< FW ECC error (corrected, OK) */
+ RGX_CONTEXT_RESET_REASON_FW_ECC_ERR = 11, /*!< FW ECC error (uncorrected, ERR) */
+ RGX_CONTEXT_RESET_REASON_FW_WATCHDOG = 12, /*!< FW Safety watchdog triggered */
+ RGX_CONTEXT_RESET_REASON_FW_PAGEFAULT = 13, /*!< FW page fault (no HWR) */
+ RGX_CONTEXT_RESET_REASON_FW_EXEC_ERR = 14, /*!< FW execution error (GPU reset requested) */
+ RGX_CONTEXT_RESET_REASON_HOST_WDG_FW_ERR = 15, /*!< Host watchdog detected FW error */
+ RGX_CONTEXT_GEOM_OOM_DISABLED = 16, /*!< Geometry DM OOM event is not allowed */
+} RGX_CONTEXT_RESET_REASON;
+
+/*!
+ @Brief Context reset data shared with the host
+*/
+typedef struct
+{
+ RGX_CONTEXT_RESET_REASON eResetReason; /*!< Reset reason */
+ IMG_UINT32 ui32ResetExtJobRef; /*!< External Job ID */
+} RGX_CONTEXT_RESET_REASON_DATA;
+#endif /* RGX_FWIF_SHARED_H */
+
+/******************************************************************************
+ End of file (rgx_fwif_shared.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/rogue/rgx_heaps.h b/drivers/gpu/drm/img-rogue/include/rogue/rgx_heaps.h
new file mode 100644
index 000000000..4c7e53582
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/rogue/rgx_heaps.h
@@ -0,0 +1,67 @@
+/*************************************************************************/ /*!
+@File
+@Title RGX heap definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(RGX_HEAPS_H)
+#define RGX_HEAPS_H
+
+/*
+ Identify heaps by their names
+*/
+#define RGX_GENERAL_SVM_HEAP_IDENT "General SVM" /*!< RGX General SVM (shared virtual memory) Heap Identifier */
+#define RGX_GENERAL_HEAP_IDENT "General" /*!< RGX General Heap Identifier */
+#define RGX_GENERAL_NON4K_HEAP_IDENT "General NON-4K" /*!< RGX General non-4K Heap Identifier */
+#define RGX_PDSCODEDATA_HEAP_IDENT "PDS Code and Data" /*!< RGX PDS Code/Data Heap Identifier */
+#define RGX_USCCODE_HEAP_IDENT "USC Code" /*!< RGX USC Code Heap Identifier */
+#define RGX_VK_CAPT_REPLAY_HEAP_IDENT "Vulkan Capture Replay" /*!< RGX Vulkan capture replay buffer Heap Identifier */
+#define RGX_SIGNALS_HEAP_IDENT "Signals" /*!< Signals Heap Identifier */
+#define RGX_FBCDC_HEAP_IDENT "FBCDC" /*!< RGX FBCDC State Table Heap Identifier */
+#define RGX_CMP_MISSION_RMW_HEAP_IDENT "Compute Mission RMW" /*!< Compute Mission RMW Heap Identifier */
+#define RGX_CMP_SAFETY_RMW_HEAP_IDENT "Compute Safety RMW" /*!< Compute Safety RMW Heap Identifier */
+#define RGX_TEXTURE_STATE_HEAP_IDENT "Texture State" /*!< Texture State Heap Identifier */
+#define RGX_VISIBILITY_TEST_HEAP_IDENT "Visibility Test" /*!< Visibility Test Heap Identifier */
+
+/* Services client internal heap identification */
+#define RGX_RGNHDR_BRN_63142_HEAP_IDENT "RgnHdr BRN63142" /*!< RGX RgnHdr BRN63142 Heap Identifier */
+#define RGX_TQ3DPARAMETERS_HEAP_IDENT "TQ3DParameters" /*!< RGX TQ 3D Parameters Heap Identifier */
+#define RGX_MMU_INIA_BRN_65273_HEAP_IDENT "MMU INIA BRN65273" /*!< MMU BRN65273 Heap A Identifier */
+#define RGX_MMU_INIB_BRN_65273_HEAP_IDENT "MMU INIB BRN65273" /*!< MMU BRN65273 Heap B Identifier */
+#endif /* RGX_HEAPS_H */
diff --git a/drivers/gpu/drm/img-rogue/include/rogue/rgx_hwperf.h b/drivers/gpu/drm/img-rogue/include/rogue/rgx_hwperf.h
new file mode 100644
index 000000000..e8d159c15
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/rogue/rgx_hwperf.h
@@ -0,0 +1,1911 @@
+/*************************************************************************/ /*!
+@File
+@Title RGX HWPerf and Debug Types and Defines Header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Common data types definitions for hardware performance API
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef RGX_HWPERF_H_
+#define RGX_HWPERF_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* These structures are used on both GPU and CPU and must be a size that is a
+ * multiple of 64 bits, 8 bytes to allow the FW to write 8 byte quantities at
+ * 8 byte aligned addresses. RGX_FW_STRUCT_*_ASSERT() is used to check this.
+ */
+
+/******************************************************************************
+ * Includes and Defines
+ *****************************************************************************/
+
+#include "img_types.h"
+#include "img_defs.h"
+
+#include "rgx_common.h"
+#include "pvrsrv_tlcommon.h"
+#include "pvrsrv_sync_km.h"
+
+
+#if !defined(__KERNEL__)
+/* User-mode and Firmware definitions only */
+
+#if defined(RGX_BVNC_CORE_KM_HEADER) && defined(RGX_BNC_CONFIG_KM_HEADER)
+
+/* HWPerf interface assumption checks */
+static_assert(RGX_FEATURE_NUM_CLUSTERS <= 16U, "Cluster count too large for HWPerf protocol definition");
+
+/*! The number of indirectly addressable TPU_MSC blocks in the GPU */
+# define RGX_HWPERF_PHANTOM_INDIRECT_BY_DUST MAX(((IMG_UINT32)RGX_FEATURE_NUM_CLUSTERS >> 1), 1U)
+
+/*! The number of indirectly addressable USC blocks in the GPU */
+# define RGX_HWPERF_PHANTOM_INDIRECT_BY_CLUSTER (RGX_FEATURE_NUM_CLUSTERS)
+
+# if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
+
+ /*! Defines the number of performance counter blocks that are directly
+ * addressable in the RGX register map for S. */
+# define RGX_HWPERF_MAX_DIRECT_ADDR_BLKS 1 /* JONES */
+# define RGX_HWPERF_INDIRECT_BY_PHANTOM (RGX_NUM_PHANTOMS)
+# define RGX_HWPERF_PHANTOM_NONDUST_BLKS 1 /* BLACKPEARL */
+# define RGX_HWPERF_PHANTOM_DUST_BLKS 2 /* TPU, TEXAS */
+# define RGX_HWPERF_PHANTOM_DUST_CLUSTER_BLKS 2 /* USC, PBE */
+
+# elif defined(RGX_FEATURE_XT_TOP_INFRASTRUCTURE)
+
+ /*! Defines the number of performance counter blocks that are directly
+ * addressable in the RGX register map. */
+# define RGX_HWPERF_MAX_DIRECT_ADDR_BLKS 2 /* TORNADO, TA */
+
+# define RGX_HWPERF_INDIRECT_BY_PHANTOM (RGX_NUM_PHANTOMS)
+# define RGX_HWPERF_PHANTOM_NONDUST_BLKS 2 /* RASTER, TEXAS */
+# define RGX_HWPERF_PHANTOM_DUST_BLKS 1 /* TPU */
+# define RGX_HWPERF_PHANTOM_DUST_CLUSTER_BLKS 1 /* USC */
+
+# else /* !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) && !defined(RGX_FEATURE_XT_TOP_INFRASTRUCTURE) i.e. S6 */
+
+ /*! Defines the number of performance counter blocks that are
+ * addressable in the RGX register map for Series 6. */
+# define RGX_HWPERF_MAX_DIRECT_ADDR_BLKS 3 /* TA, RASTER, HUB */
+# define RGX_HWPERF_INDIRECT_BY_PHANTOM 0 /* PHANTOM is not there in Rogue1. Just using it to keep naming same as later series (RogueXT n Rogue XT+) */
+# define RGX_HWPERF_PHANTOM_NONDUST_BLKS 0
+# define RGX_HWPERF_PHANTOM_DUST_BLKS 1 /* TPU */
+# define RGX_HWPERF_PHANTOM_DUST_CLUSTER_BLKS 1 /* USC */
+
+# endif
+
+/*! The number of performance counters in each layout block defined for UM/FW code */
+#if defined(RGX_FEATURE_CLUSTER_GROUPING)
+ #define RGX_HWPERF_CNTRS_IN_BLK 6
+ #else
+ #define RGX_HWPERF_CNTRS_IN_BLK 4
+#endif
+
+#endif /* #if defined(RGX_BVNC_CORE_KM_HEADER) && defined(RGX_BNC_CONFIG_KM_HEADER) */
+#else /* defined(__KERNEL__) */
+/* Kernel/server definitions - not used, hence invalid definitions */
+
+# define RGX_HWPERF_NUM_BLOCK_UNITS_RUNTIME_CALC 0xFF
+
+# define RGX_HWPERF_PHANTOM_INDIRECT_BY_DUST RGX_HWPERF_NUM_BLOCK_UNITS_RUNTIME_CALC
+# define RGX_HWPERF_PHANTOM_INDIRECT_BY_CLUSTER RGX_HWPERF_NUM_BLOCK_UNITS_RUNTIME_CALC
+
+# define RGX_HWPERF_MAX_DIRECT_ADDR_BLKS RGX_HWPERF_NUM_BLOCK_UNITS_RUNTIME_CALC
+# define RGX_HWPERF_INDIRECT_BY_PHANTOM RGX_HWPERF_NUM_BLOCK_UNITS_RUNTIME_CALC
+# define RGX_HWPERF_PHANTOM_NONDUST_BLKS RGX_HWPERF_NUM_BLOCK_UNITS_RUNTIME_CALC
+# define RGX_HWPERF_PHANTOM_DUST_BLKS RGX_HWPERF_NUM_BLOCK_UNITS_RUNTIME_CALC
+# define RGX_HWPERF_PHANTOM_DUST_CLUSTER_BLKS RGX_HWPERF_NUM_BLOCK_UNITS_RUNTIME_CALC
+
+#endif
+
+/*! The number of custom non-mux counter blocks supported */
+#define RGX_HWPERF_MAX_CUSTOM_BLKS 5U
+
+/*! The number of counters supported in each non-mux counter block */
+#define RGX_HWPERF_MAX_CUSTOM_CNTRS 8U
+
+/*! The number of non-mux counter blocks supported */
+#if defined(SUPPORT_VALIDATION)
+#define RGX_CNTBLK_COUNTERS_MAX 64U
+#else
+#define RGX_CNTBLK_COUNTERS_MAX 12U
+#endif
+
+/******************************************************************************
+ * Packet Event Type Enumerations
+ *****************************************************************************/
+
+/*! Type used to encode the event that generated the packet.
+ * NOTE: When this type is updated the corresponding hwperfbin2json tool
+ * source needs to be updated as well. The RGX_HWPERF_EVENT_MASK_* macros will
+ * also need updating when adding new types.
+ *
+ * @par
+ * The event type values are incrementing integers for use as a shift ordinal
+ * in the event filtering process at the point events are generated.
+ * This scheme thus implies a limit of 63 event types.
+ */
+
+typedef IMG_UINT32 RGX_HWPERF_EVENT_TYPE;
+
+#define RGX_HWPERF_INVALID 0x00U /*!< Invalid. Reserved value. */
+
+/*! FW types 0x01..0x06 */
+#define RGX_HWPERF_FW_EVENT_RANGE_FIRST_TYPE 0x01U
+
+#define RGX_HWPERF_FW_BGSTART 0x01U /*!< Background task processing start */
+#define RGX_HWPERF_FW_BGEND 0x02U /*!< Background task end */
+#define RGX_HWPERF_FW_IRQSTART 0x03U /*!< IRQ task processing start */
+
+#define RGX_HWPERF_FW_IRQEND 0x04U /*!< IRQ task end */
+#define RGX_HWPERF_FW_DBGSTART 0x05U /*!< Debug event start */
+#define RGX_HWPERF_FW_DBGEND 0x06U /*!< Debug event end */
+
+#define RGX_HWPERF_FW_EVENT_RANGE_LAST_TYPE 0x06U
+
+/*! HW types 0x07..0x19 */
+#define RGX_HWPERF_HW_EVENT_RANGE0_FIRST_TYPE 0x07U
+
+#define RGX_HWPERF_HW_PMOOM_TAPAUSE 0x07U /*!< TA Pause at PM Out of Memory */
+
+#define RGX_HWPERF_HW_TAKICK 0x08U /*!< TA task started */
+#define RGX_HWPERF_HW_TAFINISHED 0x09U /*!< TA task finished */
+#define RGX_HWPERF_HW_3DTQKICK 0x0AU /*!< 3D TQ started */
+#define RGX_HWPERF_HW_3DKICK 0x0BU /*!< 3D task started */
+#define RGX_HWPERF_HW_3DFINISHED 0x0CU /*!< 3D task finished */
+#define RGX_HWPERF_HW_CDMKICK 0x0DU /*!< CDM task started */
+#define RGX_HWPERF_HW_CDMFINISHED 0x0EU /*!< CDM task finished */
+#define RGX_HWPERF_HW_TLAKICK 0x0FU /*!< TLA task started */
+#define RGX_HWPERF_HW_TLAFINISHED 0x10U /*!< TLS task finished */
+#define RGX_HWPERF_HW_3DSPMKICK 0x11U /*!< 3D SPM task started */
+#define RGX_HWPERF_HW_PERIODIC 0x12U /*!< Periodic event with updated HW counters */
+#define RGX_HWPERF_HW_RTUKICK 0x13U /*!< Reserved, future use */
+#define RGX_HWPERF_HW_RTUFINISHED 0x14U /*!< Reserved, future use */
+#define RGX_HWPERF_HW_SHGKICK 0x15U /*!< Reserved, future use */
+#define RGX_HWPERF_HW_SHGFINISHED 0x16U /*!< Reserved, future use */
+#define RGX_HWPERF_HW_3DTQFINISHED 0x17U /*!< 3D TQ finished */
+#define RGX_HWPERF_HW_3DSPMFINISHED 0x18U /*!< 3D SPM task finished */
+
+#define RGX_HWPERF_HW_PMOOM_TARESUME 0x19U /*!< TA Resume after PM Out of Memory */
+
+/*! HW_EVENT_RANGE0 used up. Use next empty range below to add new hardware events */
+#define RGX_HWPERF_HW_EVENT_RANGE0_LAST_TYPE 0x19U
+
+/*! other types 0x1A..0x1F */
+#define RGX_HWPERF_CLKS_CHG 0x1AU /*!< Clock speed change in GPU */
+#define RGX_HWPERF_GPU_STATE_CHG 0x1BU /*!< GPU work state change */
+
+/*! power types 0x20..0x27 */
+#define RGX_HWPERF_PWR_EST_RANGE_FIRST_TYPE 0x20U
+#define RGX_HWPERF_PWR_EST_REQUEST 0x20U /*!< Power estimate requested (via GPIO) */
+#define RGX_HWPERF_PWR_EST_READY 0x21U /*!< Power estimate inputs ready */
+#define RGX_HWPERF_PWR_EST_RESULT 0x22U /*!< Power estimate result calculated */
+#define RGX_HWPERF_PWR_EST_RANGE_LAST_TYPE 0x22U
+
+#define RGX_HWPERF_PWR_CHG 0x23U /*!< Power state change */
+
+/*! HW_EVENT_RANGE1 0x28..0x2F, for accommodating new hardware events */
+#define RGX_HWPERF_HW_EVENT_RANGE1_FIRST_TYPE 0x28U
+
+#define RGX_HWPERF_HW_TDMKICK 0x28U /*!< TDM task started */
+#define RGX_HWPERF_HW_TDMFINISHED 0x29U /*!< TDM task finished */
+#define RGX_HWPERF_HW_NULLKICK 0x2AU /*!< NULL event */
+
+#define RGX_HWPERF_HW_EVENT_RANGE1_LAST_TYPE 0x2AU
+
+/*! context switch types 0x30..0x31 */
+#define RGX_HWPERF_CSW_START 0x30U /*!< HW context store started */
+#define RGX_HWPERF_CSW_FINISHED 0x31U /*!< HW context store finished */
+
+/*! DVFS events */
+#define RGX_HWPERF_DVFS 0x32U /*!< Dynamic voltage/frequency scaling events */
+
+/*! firmware misc 0x38..0x39 */
+#define RGX_HWPERF_UFO 0x38U /*!< FW UFO Check / Update */
+#define RGX_HWPERF_FWACT 0x39U /*!< FW Activity notification */
+
+/*! last */
+#define RGX_HWPERF_LAST_TYPE 0x3BU
+
+/*! This enumeration must have a value that is a power of two as it is
+ * used in masks and a filter bit field (currently 64 bits long).
+ */
+#define RGX_HWPERF_MAX_TYPE 0x40U
+
+static_assert(RGX_HWPERF_LAST_TYPE < RGX_HWPERF_MAX_TYPE, "Too many HWPerf event types");
+
+/*! Macro used to check if an event type ID is present in the known set of hardware type events */
+#define HWPERF_PACKET_IS_HW_TYPE(_etype) (((_etype) >= RGX_HWPERF_HW_EVENT_RANGE0_FIRST_TYPE && (_etype) <= RGX_HWPERF_HW_EVENT_RANGE0_LAST_TYPE) || \
+ ((_etype) >= RGX_HWPERF_HW_EVENT_RANGE1_FIRST_TYPE && (_etype) <= RGX_HWPERF_HW_EVENT_RANGE1_LAST_TYPE))
+
+/*! Macro used to check if an event type ID is present in the known set of firmware type events */
+#define HWPERF_PACKET_IS_FW_TYPE(_etype) \
+ ((_etype) >= RGX_HWPERF_FW_EVENT_RANGE_FIRST_TYPE && \
+ (_etype) <= RGX_HWPERF_FW_EVENT_RANGE_LAST_TYPE)
+
+
+typedef enum {
+ RGX_HWPERF_HOST_INVALID = 0x00, /*!< Invalid, do not use. */
+ RGX_HWPERF_HOST_ENQ = 0x01, /*!< ``0x01`` Kernel driver has queued GPU work.
+ See RGX_HWPERF_HOST_ENQ_DATA */
+ RGX_HWPERF_HOST_UFO = 0x02, /*!< ``0x02`` UFO updated by the driver.
+ See RGX_HWPERF_HOST_UFO_DATA */
+ RGX_HWPERF_HOST_ALLOC = 0x03, /*!< ``0x03`` Resource allocated.
+ See RGX_HWPERF_HOST_ALLOC_DATA */
+ RGX_HWPERF_HOST_CLK_SYNC = 0x04, /*!< ``0x04`` GPU / Host clocks correlation data.
+ See RGX_HWPERF_HOST_CLK_SYNC_DATA */
+ RGX_HWPERF_HOST_FREE = 0x05, /*!< ``0x05`` Resource freed,
+ See RGX_HWPERF_HOST_FREE_DATA */
+ RGX_HWPERF_HOST_MODIFY = 0x06, /*!< ``0x06`` Resource modified / updated.
+ See RGX_HWPERF_HOST_MODIFY_DATA */
+ RGX_HWPERF_HOST_DEV_INFO = 0x07, /*!< ``0x07`` Device Health status.
+ See RGX_HWPERF_HOST_DEV_INFO_DATA */
+ RGX_HWPERF_HOST_INFO = 0x08, /*!< ``0x08`` Device memory usage information.
+ See RGX_HWPERF_HOST_INFO_DATA */
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT = 0x09, /*!< ``0x09`` Wait for sync event.
+ See RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA */
+ RGX_HWPERF_HOST_SYNC_SW_TL_ADVANCE = 0x0A, /*!< ``0x0A`` Software timeline advanced.
+ See RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA */
+
+ /*! last */
+ RGX_HWPERF_HOST_LAST_TYPE,
+
+ /*! This enumeration must have a value that is a power of two as it is
+ * used in masks and a filter bit field (currently 32 bits long).
+ */
+ RGX_HWPERF_HOST_MAX_TYPE = 0x20
+} RGX_HWPERF_HOST_EVENT_TYPE;
+
+/*!< The event type values are incrementing integers for use as a shift ordinal
+ * in the event filtering process at the point events are generated.
+ * This scheme thus implies a limit of 31 event types.
+ */
+static_assert(RGX_HWPERF_HOST_LAST_TYPE < RGX_HWPERF_HOST_MAX_TYPE, "Too many HWPerf host event types");
+
+
+/******************************************************************************
+ * Packet Header Format Version 2 Types
+ *****************************************************************************/
+
+/*! Major version number of the protocol in operation
+ */
+#define RGX_HWPERF_V2_FORMAT 2
+
+/*! Signature ASCII pattern 'HWP2' found in the first word of a HWPerfV2 packet
+ */
+#define HWPERF_PACKET_V2_SIG 0x48575032
+
+/*! Signature ASCII pattern 'HWPA' found in the first word of a HWPerfV2a packet
+ */
+#define HWPERF_PACKET_V2A_SIG 0x48575041
+
+/*! Signature ASCII pattern 'HWPB' found in the first word of a HWPerfV2b packet
+ */
+#define HWPERF_PACKET_V2B_SIG 0x48575042
+
+#define HWPERF_PACKET_ISVALID(_ptr) (((_ptr) == HWPERF_PACKET_V2_SIG) || ((_ptr) == HWPERF_PACKET_V2A_SIG)|| ((_ptr) == HWPERF_PACKET_V2B_SIG))
+/*!< Checks that the packet signature is one of the supported versions */
+
+/*! Type defines the HWPerf packet header common to all events. */
+typedef struct
+{
+ IMG_UINT32 ui32Sig; /*!< Always the value HWPERF_PACKET_SIG */
+ IMG_UINT32 ui32Size; /*!< Overall packet size in bytes */
+ IMG_UINT32 eTypeId; /*!< Event type information field */
+ IMG_UINT32 ui32Ordinal; /*!< Sequential number of the packet */
+ IMG_UINT64 ui64Timestamp; /*!< Event timestamp */
+} RGX_HWPERF_V2_PACKET_HDR, *RGX_PHWPERF_V2_PACKET_HDR;
+
+#ifndef __CHECKER__
+RGX_FW_STRUCT_OFFSET_ASSERT(RGX_HWPERF_V2_PACKET_HDR, ui64Timestamp);
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_V2_PACKET_HDR);
+#endif
+
+
+/*! Mask for use with the IMG_UINT32 ui32Size header field */
+#define RGX_HWPERF_SIZE_MASK 0xFFFFU
+
+/*! This macro defines an upper limit to which the size of the largest variable
+ * length HWPerf packet must fall within, currently 3KB. This constant may be
+ * used to allocate a buffer to hold one packet.
+ * This upper limit is policed by packet producing code.
+ */
+#define RGX_HWPERF_MAX_PACKET_SIZE 0xC00U
+
+/*! Defines an upper limit to the size of a variable length packet payload.
+ */
+#define RGX_HWPERF_MAX_PAYLOAD_SIZE ((IMG_UINT32)(RGX_HWPERF_MAX_PACKET_SIZE-\
+ sizeof(RGX_HWPERF_V2_PACKET_HDR)))
+
+/*! Macro which takes a structure name and provides the packet size for
+ * a fixed size payload packet, rounded up to 8 bytes to align packets
+ * for 64 bit architectures. */
+#define RGX_HWPERF_MAKE_SIZE_FIXED(_struct) ((IMG_UINT32)(RGX_HWPERF_SIZE_MASK&(sizeof(RGX_HWPERF_V2_PACKET_HDR)+PVR_ALIGN(sizeof(_struct), PVRSRVTL_PACKET_ALIGNMENT))))
+
+/*! Macro which takes the number of bytes written in the data payload of a
+ * packet for a variable size payload packet, rounded up to 8 bytes to
+ * align packets for 64 bit architectures. */
+#define RGX_HWPERF_MAKE_SIZE_VARIABLE(_size) ((IMG_UINT32)(RGX_HWPERF_SIZE_MASK&(sizeof(RGX_HWPERF_V2_PACKET_HDR)+PVR_ALIGN((_size), PVRSRVTL_PACKET_ALIGNMENT))))
+
+/*! Macro to obtain the size of the packet */
+#define RGX_HWPERF_GET_SIZE(_packet_addr) ((IMG_UINT16)(((_packet_addr)->ui32Size) & RGX_HWPERF_SIZE_MASK))
+
+/*! Macro to obtain the size of the packet data */
+#define RGX_HWPERF_GET_DATA_SIZE(_packet_addr) (RGX_HWPERF_GET_SIZE(_packet_addr) - sizeof(RGX_HWPERF_V2_PACKET_HDR))
+
+/*! Masks for use with the IMG_UINT32 eTypeId header field */
+#define RGX_HWPERF_TYPEID_MASK 0x0007FFFFU
+#define RGX_HWPERF_TYPEID_EVENT_MASK 0x00007FFFU
+#define RGX_HWPERF_TYPEID_THREAD_MASK 0x00008000U
+#define RGX_HWPERF_TYPEID_STREAM_MASK 0x00070000U
+#define RGX_HWPERF_TYPEID_META_DMA_MASK 0x00080000U
+#define RGX_HWPERF_TYPEID_M_CORE_MASK 0x00100000U
+#define RGX_HWPERF_TYPEID_OSID_MASK 0x07000000U
+
+/*! Meta thread macros for encoding the ID into the type field of a packet */
+#define RGX_HWPERF_META_THREAD_SHIFT 15U
+#define RGX_HWPERF_META_THREAD_ID0 0x0U /*!< Meta Thread 0 ID */
+#define RGX_HWPERF_META_THREAD_ID1 0x1U /*!< Meta Thread 1 ID */
+/*! Obsolete, kept for source compatibility */
+#define RGX_HWPERF_META_THREAD_MASK 0x1U
+/*! Stream ID macros for encoding the ID into the type field of a packet */
+#define RGX_HWPERF_STREAM_SHIFT 16U
+/*! Meta DMA macro for encoding how the packet was generated into the type field of a packet */
+#define RGX_HWPERF_META_DMA_SHIFT 19U
+/*! Bit-shift macro used for encoding multi-core data into the type field of a packet */
+#define RGX_HWPERF_M_CORE_SHIFT 20U
+/*! OSID bit-shift macro used for encoding OSID into type field of a packet */
+#define RGX_HWPERF_OSID_SHIFT 24U
+typedef enum {
+ RGX_HWPERF_STREAM_ID0_FW, /*!< Events from the Firmware/GPU */
+ RGX_HWPERF_STREAM_ID1_HOST, /*!< Events from the Server host driver component */
+ RGX_HWPERF_STREAM_ID2_CLIENT, /*!< Events from the Client host driver component */
+ RGX_HWPERF_STREAM_ID_LAST,
+} RGX_HWPERF_STREAM_ID;
+
+/* Checks if all stream IDs can fit under RGX_HWPERF_TYPEID_STREAM_MASK. */
+static_assert(((IMG_UINT32)RGX_HWPERF_STREAM_ID_LAST - 1U) < (RGX_HWPERF_TYPEID_STREAM_MASK >> RGX_HWPERF_STREAM_SHIFT),
+ "Too many HWPerf stream IDs.");
+
+/*! Compile-time value used to seed the Multi-Core (MC) bit in the typeID field.
+ * Only set by RGX_FIRMWARE builds.
+ */
+#if defined(RGX_FIRMWARE)
+# if defined(RGX_FEATURE_GPU_MULTICORE_SUPPORT)
+#define RGX_HWPERF_M_CORE_VALUE 1U /*!< 1 => Multi-core supported */
+# else
+#define RGX_HWPERF_M_CORE_VALUE 0U /*!< 0 => Multi-core not supported */
+# endif
+#else
+#define RGX_HWPERF_M_CORE_VALUE 0U /*!< 0 => Multi-core not supported */
+#endif
+
+/*! Macros used to set the packet type and encode meta thread ID (0|1),
+ * HWPerf stream ID, multi-core capability and OSID within the typeID */
+#define RGX_HWPERF_MAKE_TYPEID(_stream, _type, _thread, _metadma, _osid)\
+ ((IMG_UINT32) ((RGX_HWPERF_TYPEID_STREAM_MASK&((IMG_UINT32)(_stream) << RGX_HWPERF_STREAM_SHIFT)) | \
+ (RGX_HWPERF_TYPEID_THREAD_MASK & ((IMG_UINT32)(_thread) << RGX_HWPERF_META_THREAD_SHIFT)) | \
+ (RGX_HWPERF_TYPEID_EVENT_MASK & (IMG_UINT32)(_type)) | \
+ (RGX_HWPERF_TYPEID_META_DMA_MASK & ((IMG_UINT32)(_metadma) << RGX_HWPERF_META_DMA_SHIFT)) | \
+ (RGX_HWPERF_TYPEID_OSID_MASK & ((IMG_UINT32)(_osid) << RGX_HWPERF_OSID_SHIFT)) | \
+ (RGX_HWPERF_TYPEID_M_CORE_MASK & ((IMG_UINT32)(RGX_HWPERF_M_CORE_VALUE) << RGX_HWPERF_M_CORE_SHIFT))))
+
+/*! Obtains the event type that generated the packet */
+#define RGX_HWPERF_GET_TYPE(_packet_addr) (((_packet_addr)->eTypeId) & RGX_HWPERF_TYPEID_EVENT_MASK)
+
+/*! Obtains the META Thread number that generated the packet */
+#define RGX_HWPERF_GET_THREAD_ID(_packet_addr) (((((_packet_addr)->eTypeId) & RGX_HWPERF_TYPEID_THREAD_MASK) >> RGX_HWPERF_META_THREAD_SHIFT))
+
+/*! Determines if the packet generated contains multi-core data */
+#define RGX_HWPERF_GET_M_CORE(_packet_addr) (((_packet_addr)->eTypeId & RGX_HWPERF_TYPEID_M_CORE_MASK) >> RGX_HWPERF_M_CORE_SHIFT)
+
+/*! Obtains the guest OSID which resulted in packet generation */
+#define RGX_HWPERF_GET_OSID(_packet_addr) (((_packet_addr)->eTypeId & RGX_HWPERF_TYPEID_OSID_MASK) >> RGX_HWPERF_OSID_SHIFT)
+
+/*! Obtain stream id */
+#define RGX_HWPERF_GET_STREAM_ID(_packet_addr) (((((_packet_addr)->eTypeId) & RGX_HWPERF_TYPEID_STREAM_MASK) >> RGX_HWPERF_STREAM_SHIFT))
+
+/*! Obtain information about how the packet was generated, which might affect payload total size */
+#define RGX_HWPERF_GET_META_DMA_INFO(_packet_addr) (((((_packet_addr)->eTypeId) & RGX_HWPERF_TYPEID_META_DMA_MASK) >> RGX_HWPERF_META_DMA_SHIFT))
+
+/*! Obtains a typed pointer to a packet given a buffer address */
+#define RGX_HWPERF_GET_PACKET(_buffer_addr) ((RGX_HWPERF_V2_PACKET_HDR *)(void *) (_buffer_addr))
+/*! Obtains a typed pointer to a data structure given a packet address */
+#define RGX_HWPERF_GET_PACKET_DATA_BYTES(_packet_addr) (IMG_OFFSET_ADDR((_packet_addr), sizeof(RGX_HWPERF_V2_PACKET_HDR)))
+/*! Obtains a typed pointer to the next packet given a packet address */
+#define RGX_HWPERF_GET_NEXT_PACKET(_packet_addr) ((RGX_HWPERF_V2_PACKET_HDR *) (IMG_OFFSET_ADDR((_packet_addr), RGX_HWPERF_SIZE_MASK&((_packet_addr)->ui32Size))))
+
+/*! Obtains a typed pointer to a packet header given the packet data address */
+#define RGX_HWPERF_GET_PACKET_HEADER(_packet_addr) ((RGX_HWPERF_V2_PACKET_HDR *) (IMG_OFFSET_ADDR((_packet_addr), -(IMG_INT32)sizeof(RGX_HWPERF_V2_PACKET_HDR))))
+
+
+/******************************************************************************
+ * Other Common Defines
+ *****************************************************************************/
+
+/*! This macro is not a real array size, but indicates the array has a variable
+ * length only known at run-time but always contains at least 1 element. The
+ * final size of the array is deduced from the size field of a packet header.
+ */
+#define RGX_HWPERF_ONE_OR_MORE_ELEMENTS 1U
+
+/*! This macro is not a real array size, but indicates the array is optional
+ * and if present has a variable length only known at run-time. The final
+ * size of the array is deduced from the size field of a packet header. */
+#define RGX_HWPERF_ZERO_OR_MORE_ELEMENTS 1U
+
+
+/*! Masks for use with the IMG_UINT32 ui32BlkInfo field */
+#define RGX_HWPERF_BLKINFO_BLKCOUNT_MASK 0xFFFF0000U
+#define RGX_HWPERF_BLKINFO_BLKOFFSET_MASK 0x0000FFFFU
+
+/*! Shift for the NumBlocks and counter block offset field in ui32BlkInfo */
+#define RGX_HWPERF_BLKINFO_BLKCOUNT_SHIFT 16U
+#define RGX_HWPERF_BLKINFO_BLKOFFSET_SHIFT 0U
+
+/*! Macro used to set the block info word as a combination of two 16-bit integers */
+#define RGX_HWPERF_MAKE_BLKINFO(_numblks, _blkoffset) ((IMG_UINT32) ((RGX_HWPERF_BLKINFO_BLKCOUNT_MASK&((_numblks) << RGX_HWPERF_BLKINFO_BLKCOUNT_SHIFT)) | (RGX_HWPERF_BLKINFO_BLKOFFSET_MASK&((_blkoffset) << RGX_HWPERF_BLKINFO_BLKOFFSET_SHIFT))))
+
+/*! Macro used to obtain the number of counter blocks present in the packet */
+#define RGX_HWPERF_GET_BLKCOUNT(_blkinfo) (((_blkinfo) & RGX_HWPERF_BLKINFO_BLKCOUNT_MASK) >> RGX_HWPERF_BLKINFO_BLKCOUNT_SHIFT)
+
+/*! Obtains the offset of the counter block stream in the packet */
+#define RGX_HWPERF_GET_BLKOFFSET(_blkinfo) (((_blkinfo) & RGX_HWPERF_BLKINFO_BLKOFFSET_MASK) >> RGX_HWPERF_BLKINFO_BLKOFFSET_SHIFT)
+
+/*! This macro gets the number of blocks depending on the packet version */
+#define RGX_HWPERF_GET_NUMBLKS(_sig, _packet_data, _numblocks) \
+ do { \
+ if (HWPERF_PACKET_V2B_SIG == (_sig)) \
+ { \
+ (_numblocks) = RGX_HWPERF_GET_BLKCOUNT((_packet_data)->ui32BlkInfo);\
+ } \
+ else \
+ { \
+ IMG_UINT32 ui32VersionOffset = (((_sig) == HWPERF_PACKET_V2_SIG) ? 1 : 3);\
+ (_numblocks) = *(IMG_UINT16 *)(IMG_OFFSET_ADDR(&(_packet_data)->ui32WorkTarget, ui32VersionOffset)); \
+ } \
+ } while (0)
+
+/*! This macro gets the counter stream pointer depending on the packet version */
+#define RGX_HWPERF_GET_CNTSTRM(_sig, _hw_packet_data, _cntstream_ptr) \
+{ \
+ if (HWPERF_PACKET_V2B_SIG == (_sig)) \
+ { \
+ (_cntstream_ptr) = (IMG_UINT32 *)(IMG_OFFSET_ADDR((_hw_packet_data), RGX_HWPERF_GET_BLKOFFSET((_hw_packet_data)->ui32BlkInfo))); \
+ } \
+ else \
+ { \
+ IMG_UINT32 ui32BlkStreamOffsetInWords = (((_sig) == HWPERF_PACKET_V2_SIG) ? 6 : 8); \
+ (_cntstream_ptr) = (IMG_UINT32 *)(IMG_OFFSET_ADDR_DW((_hw_packet_data), ui32BlkStreamOffsetInWords)); \
+ } \
+}
+
+/*! Masks for use with the RGX_HWPERF_UFO_EV eEvType field */
+#define RGX_HWPERF_UFO_STREAMSIZE_MASK 0xFFFF0000U
+#define RGX_HWPERF_UFO_STREAMOFFSET_MASK 0x0000FFFFU
+
+/*! Shift for the UFO count and data stream fields */
+#define RGX_HWPERF_UFO_STREAMSIZE_SHIFT 16U
+#define RGX_HWPERF_UFO_STREAMOFFSET_SHIFT 0U
+
+/*! Macro used to set UFO stream info word as a combination of two 16-bit integers */
+#define RGX_HWPERF_MAKE_UFOPKTINFO(_ssize, _soff) \
+ ((IMG_UINT32) ((RGX_HWPERF_UFO_STREAMSIZE_MASK&((_ssize) << RGX_HWPERF_UFO_STREAMSIZE_SHIFT)) | \
+ (RGX_HWPERF_UFO_STREAMOFFSET_MASK&((_soff) << RGX_HWPERF_UFO_STREAMOFFSET_SHIFT))))
+
+/*! Macro used to obtain UFO count*/
+#define RGX_HWPERF_GET_UFO_STREAMSIZE(_streaminfo) \
+ (((_streaminfo) & RGX_HWPERF_UFO_STREAMSIZE_MASK) >> RGX_HWPERF_UFO_STREAMSIZE_SHIFT)
+
+/*! Obtains the offset of the UFO stream in the packet */
+#define RGX_HWPERF_GET_UFO_STREAMOFFSET(_streaminfo) \
+ (((_streaminfo) & RGX_HWPERF_UFO_STREAMOFFSET_MASK) >> RGX_HWPERF_UFO_STREAMOFFSET_SHIFT)
+
+
+
+/******************************************************************************
+ * Data Stream Common Types
+ *****************************************************************************/
+
+/*! All the Data Masters HWPerf is aware of. When a new DM is added to this
+ * list, it should be appended at the end to maintain backward compatibility
+ * of HWPerf data.
+ */
+typedef enum {
+
+ RGX_HWPERF_DM_GP,
+ RGX_HWPERF_DM_2D,
+ RGX_HWPERF_DM_TA,
+ RGX_HWPERF_DM_3D,
+ RGX_HWPERF_DM_CDM,
+ RGX_HWPERF_DM_RTU,
+ RGX_HWPERF_DM_SHG,
+ RGX_HWPERF_DM_TDM,
+
+ RGX_HWPERF_DM_LAST,
+
+ RGX_HWPERF_DM_INVALID = 0x1FFFFFFF
+} RGX_HWPERF_DM;
+
+/*! Enum containing bit position for 32bit feature flags used in hwperf and api */
+typedef enum {
+ RGX_HWPERF_FEATURE_PERFBUS_FLAG = 0x001,
+ RGX_HWPERF_FEATURE_S7_TOP_INFRASTRUCTURE_FLAG = 0x002,
+ RGX_HWPERF_FEATURE_XT_TOP_INFRASTRUCTURE_FLAG = 0x004,
+ RGX_HWPERF_FEATURE_PERF_COUNTER_BATCH_FLAG = 0x008,
+ RGX_HWPERF_FEATURE_ROGUEXE_FLAG = 0x010,
+ RGX_HWPERF_FEATURE_DUST_POWER_ISLAND_S7_FLAG = 0x020,
+ RGX_HWPERF_FEATURE_PBE2_IN_XE_FLAG = 0x040,
+ RGX_HWPERF_FEATURE_WORKLOAD_ESTIMATION = 0x080,
+ RGX_HWPERF_FEATURE_MULTICORE_FLAG = 0x100
+} RGX_HWPERF_FEATURE_FLAGS;
+
+/*! This structure holds the data of a firmware packet. */
+typedef struct
+{
+ RGX_HWPERF_DM eDM; /*!< DataMaster identifier, see RGX_HWPERF_DM */
+ IMG_UINT32 ui32TxtActCyc; /*!< Meta TXTACTCYC register value */
+ IMG_UINT32 ui32FWPerfCount0; /*!< Meta/MIPS PERF_COUNT0 register */
+ IMG_UINT32 ui32FWPerfCount1; /*!< Meta/MIPS PERF_COUNT1 register */
+ IMG_UINT32 ui32TimeCorrIndex; /*!< Internal field */
+ IMG_UINT32 ui32Padding; /*!< Reserved */
+} RGX_HWPERF_FW_DATA;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_FW_DATA);
+
+/*! This structure holds the data of a hardware packet, including counters. */
+typedef struct
+{
+ IMG_UINT32 ui32DMCyc; /*!< DataMaster cycle count register, 0 if none */
+ IMG_UINT32 ui32FrameNum; /*!< Frame number, undefined on some DataMasters */
+ IMG_UINT32 ui32PID; /*!< Process identifier */
+ IMG_UINT32 ui32DMContext; /*!< GPU Data Master (FW) Context */
+ IMG_UINT32 ui32WorkTarget; /*!< RenderTarget for a TA,3D; Frame context for RTU, 0x0 otherwise */
+ IMG_UINT32 ui32ExtJobRef; /*!< Client driver context job reference used for tracking/debugging */
+ IMG_UINT32 ui32IntJobRef; /*!< RGX Data master context job reference used for tracking/debugging */
+ IMG_UINT32 ui32TimeCorrIndex; /*!< Index to the time correlation at the time the packet was generated */
+ IMG_UINT32 ui32BlkInfo; /*!< <31..16> NumBlocks <15..0> Counter block stream offset */
+ IMG_UINT32 ui32WorkCtx; /*!< Work context: Render Context for TA/3D; RayTracing Context for RTU/SHG; 0x0 otherwise */
+ IMG_UINT32 ui32CtxPriority; /*!< Context priority */
+ IMG_UINT32 ui32GPUIdMask; /*!< GPU IDs active within this event */
+ IMG_UINT32 aui32CountBlksStream[RGX_HWPERF_ZERO_OR_MORE_ELEMENTS]; /*!< Counter data */
+ IMG_UINT32 ui32Padding2; /*!< Reserved. To ensure correct alignment */
+} RGX_HWPERF_HW_DATA;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_HW_DATA);
+
+typedef struct
+{
+ IMG_UINT32 ui32DMCyc; /*!< DataMaster cycle count register, 0 if none */
+ IMG_UINT32 ui32FrameNum; /*!< Frame number, undefined on some DataMasters */
+ IMG_UINT32 ui32PID; /*!< Process identifier */
+ IMG_UINT32 ui32DMContext; /*!< GPU Data Master (FW) Context */
+ IMG_UINT32 ui32WorkTarget[4]; /*!< RenderTarget for a TA,3D; Frame context for RTU, 0x0 otherwise */
+ /*!< V2A Block count / Client driver context job reference used for tracking/debugging */
+ /*!< RGX Data master context job reference used for tracking/debugging */
+ /*!< V2 Block count / Index to the time correlation at the time the packet was generated */
+} RGX_HWPERF_HW_DATA_V2;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_HW_DATA_V2);
+
+/*! Mask for use with the aui32CountBlksStream field when decoding the
+ * counter block ID and mask word. */
+#define RGX_HWPERF_CNTBLK_ID_MASK 0xFFFF0000U
+#define RGX_HWPERF_CNTBLK_ID_SHIFT 16U
+
+/*! Obtains the counter block ID word from an aui32CountBlksStream field.
+ * The word combines Control bits (15-12), GPU-Id (11-8), Group (7-4), Unit
+ * within group (3-0) */
+#define RGX_HWPERF_GET_CNTBLK_IDW(_word) ((IMG_UINT16)(((_word)&RGX_HWPERF_CNTBLK_ID_MASK)>>RGX_HWPERF_CNTBLK_ID_SHIFT))
+
+/*! Obtains the counter block ID from the supplied RGX_HWPERF_HW_DATA address
+ * and stream index. May be used in decoding the counter block stream words of
+ * a RGX_HWPERF_HW_DATA structure. */
+#define RGX_HWPERF_GET_CNTBLK_ID(_data_addr, _idx) RGX_HWPERF_GET_CNTBLK_IDW((_data_addr)->aui32CountBlksStream[(_idx)])
+
+/*! Obtains the GPU ID from the supplied RGX_HWPERF_HW_DATA CNTBLK_IDW */
+#define RGX_HWPERF_GET_CNTBLK_GPUW(_word) ((IMG_UINT16)(((_word)&RGX_CNTBLK_ID_MC_GPU_MASK)>>RGX_CNTBLK_ID_MC_GPU_SHIFT))
+
+#define RGX_HWPERF_GET_CNT_MASKW(_word) ((IMG_UINT16)((_word)&(~RGX_HWPERF_CNTBLK_ID_MASK)))
+
+/*! Obtains the counter mask from the supplied RGX_HWPERF_HW_DATA address
+ * and stream index. May be used in decoding the counter block stream words
+ * of a RGX_HWPERF_HW_DATA structure. */
+#define RGX_HWPERF_GET_CNT_MASK(_data_addr, _idx) RGX_HWPERF_GET_CNT_MASKW((_data_addr)->aui32CountBlksStream[(_idx)])
+
+/*! Context switch packet event */
+typedef struct
+{
+ RGX_HWPERF_DM eDM; /*!< DataMaster identifier, see RGX_HWPERF_DM */
+ IMG_UINT32 ui32DMContext; /*!< GPU Data Master (FW) Context */
+ IMG_UINT32 ui32FrameNum; /*!< Client Frame number (TA, 3D only) */
+ IMG_UINT32 ui32TxtActCyc; /*!< Meta TXTACTCYC register value */
+ IMG_UINT32 ui32PerfCycle; /*!< Cycle count. Used to measure HW context store latency */
+ IMG_UINT32 ui32PerfPhase; /*!< Phase. Used to determine geometry content */
+ IMG_UINT32 ui32Padding[2]; /*!< Padding to 8 DWords */
+} RGX_HWPERF_CSW_DATA;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_CSW_DATA);
+
+/*! Enumeration of clocks supporting this event */
+typedef enum
+{
+ RGX_HWPERF_CLKS_CHG_INVALID = 0,
+
+ RGX_HWPERF_CLKS_CHG_NAME_CORE = 1,
+
+ RGX_HWPERF_CLKS_CHG_LAST,
+} RGX_HWPERF_CLKS_CHG_NAME;
+
+/*! This structure holds the data of a clocks change packet. */
+typedef struct
+{
+ IMG_UINT64 ui64NewClockSpeed; /*!< New Clock Speed (in Hz) */
+ RGX_HWPERF_CLKS_CHG_NAME eClockName; /*!< Clock name */
+ IMG_UINT32 ui32CalibratedClockSpeed; /*!< Calibrated new GPU clock speed (in Hz) */
+ IMG_UINT64 ui64OSTimeStamp; /*!< OSTimeStamp sampled by the host */
+ IMG_UINT64 ui64CRTimeStamp; /*!< CRTimeStamp sampled by the host and
+ correlated to OSTimeStamp */
+} RGX_HWPERF_CLKS_CHG_DATA;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_CLKS_CHG_DATA);
+
+/*! Enumeration of GPU utilisation states supported by this event */
+typedef IMG_UINT32 RGX_HWPERF_GPU_STATE;
+
+/*! This structure holds the data of a GPU utilisation state change packet. */
+typedef struct
+{
+ RGX_HWPERF_GPU_STATE eState; /*!< New GPU utilisation state */
+ IMG_UINT32 uiUnused1; /*!< Padding */
+ IMG_UINT32 uiUnused2; /*!< Padding */
+ IMG_UINT32 uiUnused3; /*!< Padding */
+} RGX_HWPERF_GPU_STATE_CHG_DATA;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_GPU_STATE_CHG_DATA);
+
+
+/*! Signature pattern 'HPE1' found in the first word of a PWR_EST packet data */
+#define HWPERF_PWR_EST_V1_SIG 0x48504531
+
+/*! Macros to obtain a component field from a counter ID word */
+#define RGX_HWPERF_GET_PWR_EST_HIGH_FLAG(_word) (((_word)&0x80000000)>>31)
+#define RGX_HWPERF_GET_PWR_EST_GPUID(_word) (((_word)&0x70000000)>>28)
+/*!< Obtains the GPU ID from a counter ID word */
+#define RGX_HWPERF_GET_PWR_EST_UNIT(_word) (((_word)&0x0F000000)>>24)
+#define RGX_HWPERF_GET_PWR_EST_NUMBER(_word) ((_word)&0x0000FFFF)
+
+#define RGX_HWPERF_PWR_EST_HIGH_OFFSET (31)
+#define RGX_HWPERF_PWR_EST_GPUID_OFFSET (28)
+#define RGX_HWPERF_PWR_EST_GPUID_MASK (0x7U)
+#define RGX_HWPERF_PWR_EST_UNIT_OFFSET (24)
+#define RGX_HWPERF_PWR_EST_UNIT_MASK (0xFU)
+#define RGX_HWPERF_PWR_EST_VALUE_MASK (0xFFFFU)
+
+/*! This macro constructs a counter ID for a power estimate data stream from
+ * the component parts of: high word flag, unit id, GPU id, counter number */
+#define RGX_HWPERF_MAKE_PWR_EST_COUNTERID(_high, _unit, _core, _number) \
+ ((IMG_UINT32)(((IMG_UINT32)((IMG_UINT32)(_high)&0x1U)<= RGX_BVNC_STR_SIZE_MAX),
+ "Space inside HWPerf packet data for BVNC string insufficient");
+
+#define RGX_HWPERF_MAX_BVNC_BLOCK_LEN (16U)
+
+/*! BVNC Features */
+typedef struct
+{
+ /*! Counter block ID, see RGX_HWPERF_CNTBLK_ID */
+ IMG_UINT16 ui16BlockID;
+
+ /*! Number of counters in this block type */
+ IMG_UINT16 ui16NumCounters;
+
+ /*! Number of blocks of this type */
+ IMG_UINT16 ui16NumBlocks;
+
+ /*! Reserved for future use */
+ IMG_UINT16 ui16Reserved;
+} RGX_HWPERF_BVNC_BLOCK;
+
+/*! BVNC Features */
+typedef struct
+{
+ IMG_CHAR aszBvncString[RGX_HWPERF_MAX_BVNC_LEN]; /*!< BVNC string */
+ IMG_UINT32 ui32BvncKmFeatureFlags; /*!< See RGX_HWPERF_FEATURE_FLAGS */
+ IMG_UINT16 ui16BvncBlocks; /*!< Number of blocks described in aBvncBlocks */
+ IMG_UINT16 ui16BvncGPUCores; /*!< Number of GPU cores present */
+ RGX_HWPERF_BVNC_BLOCK aBvncBlocks[RGX_HWPERF_MAX_BVNC_BLOCK_LEN]; /*!< Supported Performance Blocks for BVNC. See RGX_HWPERF_BVNC_BLOCK */
+} RGX_HWPERF_BVNC;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_BVNC);
+
+/*! Sub-event's data. */
+typedef union
+{
+ struct
+ {
+ RGX_HWPERF_DM eDM; /*!< Data Master ID. */
+ RGX_HWPERF_HWR_REASON eReason; /*!< Reason of the HWR. */
+ IMG_UINT32 ui32DMContext; /*!< FW render context */
+ } sHWR; /*!< HWR sub-event data. */
+
+ RGX_HWPERF_BVNC sBVNC; /*!< BVNC Features. See RGX_HWPERF_BVNC */
+ struct
+ {
+ IMG_UINT32 ui32EvMaskLo; /*!< Low order 32 bits of Filter Mask */
+ IMG_UINT32 ui32EvMaskHi; /*!< High order 32 bits of Filter Mask */
+ } sEvMsk; /*!< HW Filter Mask */
+
+} RGX_HWPERF_FWACT_DETAIL;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_FWACT_DETAIL);
+
+/*! This structure holds the data of a FW activity event packet */
+typedef struct
+{
+ RGX_HWPERF_FWACT_EV eEvType; /*!< Event type. */
+ RGX_HWPERF_FWACT_DETAIL uFwActDetail; /*!< Data of the sub-event. */
+ IMG_UINT32 ui32Padding; /*!< Reserved. */
+} RGX_HWPERF_FWACT_DATA;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_FWACT_DATA);
+
+
+typedef enum {
+ RGX_HWPERF_UFO_EV_UPDATE, /*!< Update on the UFO objects. */
+ RGX_HWPERF_UFO_EV_CHECK_SUCCESS, /*!< Successful check on UFO objects. */
+ RGX_HWPERF_UFO_EV_PRCHECK_SUCCESS, /*!< Successful partial render check on UFO objects. */
+ RGX_HWPERF_UFO_EV_CHECK_FAIL, /*!< Unsuccessful check on UFO objects. */
+ RGX_HWPERF_UFO_EV_PRCHECK_FAIL, /*!< Unsuccessful partial render check on UFO objects. */
+ RGX_HWPERF_UFO_EV_FORCE_UPDATE, /*!< Forced erroring of the UFO objects. */
+
+ RGX_HWPERF_UFO_EV_LAST /*!< Reserved. Do not use. */
+} RGX_HWPERF_UFO_EV;
+
+/*! Data stream tuple. */
+typedef union
+{
+ struct
+ {
+ IMG_UINT32 ui32FWAddr; /*!< UFO's unique address */
+ IMG_UINT32 ui32Value; /*!< Value of the UFO object */
+ } sCheckSuccess;
+ struct
+ {
+ IMG_UINT32 ui32FWAddr; /*!< UFO's unique address */
+ IMG_UINT32 ui32Value; /*!< Value of the UFO object */
+ IMG_UINT32 ui32Required; /*!< Value of the UFO object required by the fence */
+ } sCheckFail;
+ struct
+ {
+ IMG_UINT32 ui32FWAddr; /*!< UFO's unique address */
+ IMG_UINT32 ui32OldValue; /*!< Value of UFO object before update */
+ IMG_UINT32 ui32NewValue; /*!< Value of UFO object after update */
+ } sUpdate;
+} RGX_HWPERF_UFO_DATA_ELEMENT;
+
+/*! This structure holds the packet payload data for UFO event. */
+typedef struct
+{
+ RGX_HWPERF_UFO_EV eEvType; /*!< Subtype of the event. See RGX_HWPERF_UFO_EV */
+ IMG_UINT32 ui32TimeCorrIndex; /*!< Index to the timer correlation data
+ at the time the packet was generated.
+ Used to approximate Host timestamps for
+ these events. */
+ IMG_UINT32 ui32PID; /*!< Client process identifier */
+ IMG_UINT32 ui32ExtJobRef; /*!< Reference used by callers of the RGX
+ API to track submitted work (for
+ debugging/trace purposes) */
+ IMG_UINT32 ui32IntJobRef; /*!< Internal reference used to track
+ submitted work (for debugging / trace
+ purposes) */
+ IMG_UINT32 ui32DMContext; /*!< GPU Data Master (FW) Context.
+ RenderContext for TA and 3D, Common
+ Context for other DMs */
+ IMG_UINT32 ui32StreamInfo; /*!< Encoded number of elements in the
+ stream and stream data offset in the
+ payload */
+ RGX_HWPERF_DM eDM; /*!< Data Master number, see RGX_HWPERF_DM */
+ IMG_UINT32 ui32Padding; /*!< Unused, reserved */
+ IMG_UINT32 aui32StreamData[RGX_HWPERF_ONE_OR_MORE_ELEMENTS]; /*!< Series of tuples holding UFO objects data */
+} RGX_HWPERF_UFO_DATA;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_UFO_DATA);
+
+
+/*!
+ * RGX_HWPERF_KICK_TYPE describes the type of kick for events received / sent
+ * between KICK_START / KICK_END inclusively for all event types.
+ */
+typedef enum
+{
+ RGX_HWPERF_KICK_TYPE_TA3D, /*!< Replaced by separate TA and 3D types */
+ RGX_HWPERF_KICK_TYPE_TQ2D, /*!< 2D TQ Kick */
+ RGX_HWPERF_KICK_TYPE_TQ3D, /*!< 3D TQ Kick */
+ RGX_HWPERF_KICK_TYPE_CDM, /*!< Compute Kick */
+ RGX_HWPERF_KICK_TYPE_RS, /*!< Ray Store Kick */
+ RGX_HWPERF_KICK_TYPE_VRDM, /*!< Vertex Ray Data Master Kick */
+ RGX_HWPERF_KICK_TYPE_TQTDM,/*!< 2D Data Master TQ Kick */
+ RGX_HWPERF_KICK_TYPE_SYNC, /*!< Sync Kick */
+ RGX_HWPERF_KICK_TYPE_TA, /*!< TA Kick */
+ RGX_HWPERF_KICK_TYPE_3D, /*!< 3D Kick */
+ RGX_HWPERF_KICK_TYPE_LAST,
+
+ RGX_HWPERF_KICK_TYPE_FORCE_32BIT = 0x7fffffff
+} RGX_HWPERF_KICK_TYPE;
+
+typedef struct
+{
+ RGX_HWPERF_KICK_TYPE ui32EnqType; /*!< Workload type sent to FW for
+ scheduling on GPU hardware.
+ See RGX_HWPERF_KICK_TYPE */
+ IMG_UINT32 ui32PID; /*!< Client process identifier */
+ IMG_UINT32 ui32ExtJobRef; /*!< Reference used by callers of the RGX API
+ to track submitted work (for debugging /
+ trace purposes) */
+ IMG_UINT32 ui32IntJobRef; /*!< internal reference used to track submitted
+ work (for debugging / trace purposes) */
+ IMG_UINT32 ui32DMContext; /*!< GPU Data Master (FW) Context */
+ IMG_UINT32 ui32Padding; /*!< Unused, reserved */
+ IMG_UINT64 ui64CheckFence_UID; /*!< ID of fence gating work execution on GPU */
+ IMG_UINT64 ui64UpdateFence_UID; /*!< ID of fence triggered after work completes on GPU */
+ IMG_UINT64 ui64DeadlineInus; /*!< Workload deadline in system monotonic time */
+ IMG_UINT32 ui32CycleEstimate; /*!< Estimated cycle time for the workload */
+ PVRSRV_FENCE hCheckFence; /*!< Fence this enqueue task waits for, before starting */
+ PVRSRV_FENCE hUpdateFence; /*!< Fence this enqueue task signals, on completion */
+ PVRSRV_TIMELINE hUpdateTimeline; /*!< Timeline on which the above hUpdateFence is created */
+
+ /* Align structure size to 8 bytes */
+} RGX_HWPERF_HOST_ENQ_DATA;
+
+/* Payload size must be multiple of 8 bytes to align start of next packet. */
+static_assert((sizeof(RGX_HWPERF_HOST_ENQ_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_ENQ_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+typedef struct
+{
+ RGX_HWPERF_UFO_EV eEvType; /*!< Subtype of the event */
+ IMG_UINT32 ui32StreamInfo; /*!< Encoded number of elements in the stream and
+ stream data offset in the payload */
+#ifdef __CHECKER__
+ /* Since we're not conforming to the C99 standard by not using a flexible
+ * array member need to add a special case for Smatch static code analyser. */
+ IMG_UINT32 aui32StreamData[];
+#else
+ IMG_UINT32 aui32StreamData[RGX_HWPERF_ONE_OR_MORE_ELEMENTS];
+ /*!< Series of tuples holding UFO objects data */
+
+ IMG_UINT32 ui32Padding; /*!< Reserved, align structure size to 8 bytes */
+#endif
+} RGX_HWPERF_HOST_UFO_DATA;
+
+/* Payload size must be multiple of 8 bytes to align start of next packet. */
+static_assert((sizeof(RGX_HWPERF_HOST_UFO_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_UFO_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+/*!
+ * RGX_HWPERF_HOST_RESOURCE_TYPE describes the type of resource which has been
+ * Allocated, Freed or Modified. The values are used to determine which event
+ * data structure to use to decode the data from the event stream
+ */
+typedef enum
+{
+ RGX_HWPERF_HOST_RESOURCE_TYPE_INVALID, /*!< Invalid */
+ RGX_HWPERF_HOST_RESOURCE_TYPE_SYNC, /*!< SyncPrim */
+ RGX_HWPERF_HOST_RESOURCE_TYPE_TIMELINE_DEPRECATED,
+ /*!< Timeline resource packets are
+ now emitted in client hwperf buffer */
+ RGX_HWPERF_HOST_RESOURCE_TYPE_FENCE_PVR, /*!< Fence for use on GPU (SYNC_CP backed) */
+ RGX_HWPERF_HOST_RESOURCE_TYPE_SYNC_CP, /*!< Sync Checkpoint */
+ RGX_HWPERF_HOST_RESOURCE_TYPE_FENCE_SW, /*!< Fence created on SW timeline */
+
+ RGX_HWPERF_HOST_RESOURCE_TYPE_LAST /*!< End of enumeration */
+} RGX_HWPERF_HOST_RESOURCE_TYPE;
+
+typedef union
+{
+ /*! Data for TYPE_TIMELINE (*Deprecated*). This sub-event is no longer
+ * generated in the HOST stream. Timeline data is now provided in the
+ * CLIENT stream instead.
+ */
+ struct
+ {
+ IMG_UINT32 uiPid; /*!< Identifier of owning process */
+ IMG_UINT64 ui64Timeline_UID1; /*!< Unique identifier for timeline resource */
+ IMG_CHAR acName[PVRSRV_SYNC_NAME_LENGTH];
+ /*!< Label or name given to the sync resource */
+ IMG_UINT32 ui32Padding; /*!< Reserved. Align structure size to 8 bytes */
+ } sTimelineAlloc;
+
+ /*! Data for TYPE_FENCE_PVR */
+ struct
+ {
+ IMG_PID uiPID; /*!< Identifier of owning process */
+ PVRSRV_FENCE hFence; /*!< Unique identifier for the fence resource */
+ IMG_UINT32 ui32CheckPt_FWAddr; /*!< Unique identifier of the check point
+ backing this fence on the GPU */
+ IMG_CHAR acName[PVRSRV_SYNC_NAME_LENGTH];
+ /*!< Label or name given to the sync resource */
+ } sFenceAlloc;
+
+ /*! Data for TYPE_SYNC_CP */
+ struct
+ {
+ IMG_UINT32 ui32CheckPt_FWAddr; /*!< Unique identifier for the check point resource */
+ PVRSRV_TIMELINE hTimeline; /*!< Unique identifier for the timeline resource */
+ IMG_PID uiPID; /*!< Identifier of owning process */
+ PVRSRV_FENCE hFence; /*!< Unique identifier for the fence resource */
+ IMG_CHAR acName[PVRSRV_SYNC_NAME_LENGTH];
+ /*!< Label or name given to the sync resource */
+ } sSyncCheckPointAlloc;
+
+ /*! Data for TYPE_FENCE_SW */
+ struct
+ {
+ IMG_PID uiPID; /*!< Identifier of owning process */
+ PVRSRV_FENCE hSWFence; /*!< Unique identifier for the SWFence resource */
+ PVRSRV_TIMELINE hSWTimeline; /*!< Unique identifier for the timeline resource */
+ IMG_UINT64 ui64SyncPtIndex; /*!< Sync-pt index where this SW timeline has reached */
+ IMG_CHAR acName[PVRSRV_SYNC_NAME_LENGTH];
+ /*!< Label or name given to the sync resource */
+ } sSWFenceAlloc;
+
+ /*! Data for TYPE_SYNC */
+ struct
+ {
+ IMG_UINT32 ui32FWAddr; /*!< Identifier of sync resource */
+ IMG_CHAR acName[PVRSRV_SYNC_NAME_LENGTH];
+ /*!< Label or name given to the sync resource */
+ } sSyncAlloc;
+} RGX_HWPERF_HOST_ALLOC_DETAIL;
+
+typedef struct
+{
+ RGX_HWPERF_HOST_RESOURCE_TYPE ui32AllocType;
+ /*!< This describes the type of the resource
+ allocated in the driver. See
+ RGX_HWPERF_HOST_RESOURCE_TYPE */
+ RGX_HWPERF_HOST_ALLOC_DETAIL RGXFW_ALIGN uAllocDetail;
+ /*!< Union of structures providing further
+ data regarding the resource allocated.
+ Size of data varies with union member that
+ is present, check ``ui32AllocType`` value
+ to decode */
+} RGX_HWPERF_HOST_ALLOC_DATA;
+
+/* Payload size must be multiple of 8 bytes to align start of next packet. */
+static_assert((sizeof(RGX_HWPERF_HOST_ALLOC_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_ALLOC_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+typedef union
+{
+ /*! Data for TYPE_TIMELINE (*Deprecated*) */
+ struct
+ {
+ IMG_UINT32 uiPid; /*!< Identifier of owning process */
+ IMG_UINT64 ui64Timeline_UID1; /*!< Unique identifier for the timeline resource */
+ IMG_UINT32 ui32Padding; /*!< Reserved. Align structure size to 8 bytes */
+ } sTimelineDestroy;
+
+ /*! Data for TYPE_FENCE_PVR */
+ struct
+ {
+ IMG_UINT64 ui64Fence_UID; /*!< Unique identifier for the fence resource */
+ IMG_UINT32 ui32Padding; /*!< Reserved. */
+ } sFenceDestroy;
+
+ /*! Data for TYPE_SYNC_CP */
+ struct
+ {
+ IMG_UINT32 ui32CheckPt_FWAddr; /*!< Unique identifier for the check point resource */
+ } sSyncCheckPointFree;
+
+ /*! Data for TYPE_SYNC */
+ struct
+ {
+ IMG_UINT32 ui32FWAddr; /*!< Unique identifier for the sync resource */
+ } sSyncFree;
+} RGX_HWPERF_HOST_FREE_DETAIL;
+
+typedef struct
+{
+ RGX_HWPERF_HOST_RESOURCE_TYPE ui32FreeType;
+ /*!< This describes the type of the resource
+ freed or released by the driver. See
+ RGX_HWPERF_HOST_RESOURCE_TYPE */
+ RGX_HWPERF_HOST_FREE_DETAIL uFreeDetail;
+ /*!< Union of structures providing further data
+ regarding the resource freed. Size of data
+ varies with union member that is present,
+ check ``ui32FreeType`` value to decode */
+ IMG_UINT32 ui32Padding; /*!< Reserved. Align structure size to 8 bytes */
+} RGX_HWPERF_HOST_FREE_DATA;
+
+/* Payload size must be multiple of 8 bytes to align start of next packet. */
+static_assert((sizeof(RGX_HWPERF_HOST_FREE_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_FREE_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+typedef struct
+{
+ IMG_UINT64 ui64CRTimestamp; /*!< CR timer value from the latest entry of
+ the time domains correlation table */
+ IMG_UINT64 ui64OSTimestamp; /*!< OS timestamp from the latest entry of the
+ time domains correlation table */
+ IMG_UINT32 ui32ClockSpeed; /*!< GPU clock speed from the latest entry of
+ the time domains correlation table */
+ IMG_UINT32 ui32Padding; /*!< Reserved, align structure size to 8 bytes */
+} RGX_HWPERF_HOST_CLK_SYNC_DATA;
+
+/* Payload size must be multiple of 8 bytes to align start of next packet. */
+static_assert((sizeof(RGX_HWPERF_HOST_CLK_SYNC_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_CLK_SYNC_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+typedef union
+{
+ /*! Data for TYPE_FENCE_PVR */
+ struct
+ {
+ IMG_UINT64 ui64NewFence_UID; /*!< Unique identifier for the new merged fence
+ resource that has been created */
+ IMG_UINT64 ui64InFence1_UID; /*!< Unique identifier for the fence resource */
+ IMG_UINT64 ui64InFence2_UID; /*!< Unique identifier of the check point backing
+ the fence on the GPU */
+ IMG_CHAR acName[PVRSRV_SYNC_NAME_LENGTH];
+ /*!< Label or name given to the sync resource */
+ IMG_UINT32 ui32Padding; /*!< Reserved. Align structure size to 8 bytes */
+ } sFenceMerge;
+} RGX_HWPERF_HOST_MODIFY_DETAIL;
+
+typedef struct
+{
+ RGX_HWPERF_HOST_RESOURCE_TYPE ui32ModifyType;
+ /*!< Describes the type of the resource
+ modified by the driver. See
+ RGX_HWPERF_HOST_RESOURCE_TYPE */
+
+ RGX_HWPERF_HOST_MODIFY_DETAIL uModifyDetail;
+ /*!< Union of structures providing further
+ data regarding the resource modified.
+ Size of data varies with union member that
+ is present.
+ Check ``uiModifyType`` value to decode */
+} RGX_HWPERF_HOST_MODIFY_DATA;
+
+/* Payload size must be multiple of 8 bytes to align start of next packet. */
+static_assert((sizeof(RGX_HWPERF_HOST_MODIFY_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_MODIFY_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+typedef enum
+{
+ RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_UNDEFINED = 0, /*!< Invalid */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_OK, /*!< Device OK */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_RESPONDING, /*!< Device responding to requests */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_DEAD, /*!< Device not responding */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_FAULT, /*!< Device has faulted */
+
+ RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_LAST
+} RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS;
+
+typedef enum
+{
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_UNDEFINED = 0, /*!< Invalid */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_NONE, /*!< No underlying health reason. */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_ASSERTED, /*!< Device has asserted. */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_POLL_FAILING, /*!< Device poll has failed. */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_TIMEOUTS, /*!< Device timeout has fired. */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_QUEUE_CORRUPT, /*!< Queue has become corrupt. */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_QUEUE_STALLED, /*!< Queue has stalled. */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_IDLING, /*!< Device is idling. */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_RESTARTING, /*!< Device restarting. */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_MISSING_INTERRUPTS,/*!< Interrupts have been discarded. */
+
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_LAST
+} RGX_HWPERF_HOST_DEVICE_HEALTH_REASON;
+
+/*! RGX_HWPERF_DEV_INFO_EV values */
+typedef enum
+{
+ RGX_HWPERF_DEV_INFO_EV_HEALTH, /*!< Health sub-event */
+
+ RGX_HWPERF_DEV_INFO_EV_LAST /*!< Last enumeration value */
+} RGX_HWPERF_DEV_INFO_EV;
+
+/*! RGX_HWPERF_HOST_DEV_INFO_DETAIL is a union of structures providing
+ * further data regarding the device's status
+ */
+typedef union
+{
+ /*! Data for device status event */
+ struct
+ {
+ RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS eDeviceHealthStatus;
+ /*!< Device's health status */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON eDeviceHealthReason;
+ /*!< Reason for device's health status */
+ } sDeviceStatus;
+} RGX_HWPERF_HOST_DEV_INFO_DETAIL;
+
+/*! RGX_HWPERF_HOST_DEV_INFO_DATA contains device health status information */
+typedef struct
+{
+ IMG_UINT32 ui32Padding;
+ /*!< Reserved. Align structure size to 8 bytes */
+ RGX_HWPERF_DEV_INFO_EV eEvType;
+ /*!< Type of the sub-event. See
+ RGX_HWPERF_DEV_INFO_EV */
+ RGX_HWPERF_HOST_DEV_INFO_DETAIL uDevInfoDetail;
+ /*!< Union of structures providing further data
+ regarding the device's status. Size of data
+ varies with union member that is present,
+ check ``eEvType`` value to decode */
+} RGX_HWPERF_HOST_DEV_INFO_DATA;
+
+/* Payload size must be multiple of 8 bytes to align start of next packet. */
+static_assert((sizeof(RGX_HWPERF_HOST_DEV_INFO_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_DEV_INFO_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+/*! RGX_HWPERF_INFO_EV event subtype for RGX_HWPERF_HOST_INFO_DATA events */
+typedef enum
+{
+ RGX_HWPERF_INFO_EV_MEM_USAGE, /*!< Memory usage event */
+ RGX_HWPERF_INFO_EV_LAST /*!< End of enumeration */
+} RGX_HWPERF_INFO_EV;
+
+/*! RGX_HWPERF_HOST_INFO_DETAIL contains the data payload for the
+ * RGX_HWPERF_HOST_INFO_DATA event.
+ */
+typedef union
+{
+ /*! Host Memory usage statistics */
+ struct
+ {
+ IMG_UINT32 ui32TotalMemoryUsage; /*!< Total memory usage */
+ /*! Detailed memory usage */
+ struct
+ {
+ IMG_UINT32 ui32Pid; /*!< Process ID */
+ IMG_UINT32 ui32KernelMemUsage; /*!< Kernel memory usage */
+ IMG_UINT32 ui32GraphicsMemUsage; /*!< GPU memory usage */
+ } sPerProcessUsage[RGX_HWPERF_ZERO_OR_MORE_ELEMENTS];
+ } sMemUsageStats;
+} RGX_HWPERF_HOST_INFO_DETAIL;
+
+/*! RGX_HWPERF_HOST_INFO_DATA. Host Info data event payload contains device
+ * memory usage information.
+ */
+typedef struct
+{
+ IMG_UINT32 ui32Padding; /*!< Reserved. Align structure size to 8 bytes */
+ RGX_HWPERF_INFO_EV eEvType; /*!< Type of subevent. See RGX_HWPERF_INFO_EV */
+ RGX_HWPERF_HOST_INFO_DETAIL uInfoDetail;
+ /*!< Union of structures providing further data
+ regarding memory usage. Size varies with union
+ member that is present, check ``eEvType``
+ value to decode */
+} RGX_HWPERF_HOST_INFO_DATA;
+
+/* Payload size must be multiple of 8 bytes to align start of next packet. */
+static_assert((sizeof(RGX_HWPERF_HOST_INFO_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_INFO_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+/*! FENCE_WAIT_TYPE definitions */
+typedef enum
+{
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE_BEGIN = 0, /*!< Begin */
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE_END, /*!< End */
+
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE_LAST, /*!< Do not use */
+} RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE;
+
+/*! FENCE_WAIT_RESULT definitions */
+typedef enum
+{
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT_INVALID = 0, /*!< Invalid */
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT_TIMEOUT, /*!< Timed Out */
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT_PASSED, /*!< Passed */
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT_ERROR, /*!< Errored */
+
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT_LAST, /*!< Do not use */
+} RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT;
+
+/*! FENCE_WAIT_DETAIL Event Payload */
+typedef union
+{
+/*! Data for SYNC_FENCE_WAIT_TYPE_BEGIN */
+ struct
+ {
+ IMG_UINT32 ui32TimeoutInMs; /*!< Wait timeout (ms) */
+ } sBegin;
+
+ /*! Data for SYNC_FENCE_WAIT_TYPE_END */
+ struct
+ {
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT eResult; /*!< Wait result */
+ } sEnd;
+} RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DETAIL;
+
+/*! RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA Event Payload. This data structure
+ * is received whenever the host driver handles a wait for sync event request.
+ */
+typedef struct
+{
+ IMG_PID uiPID; /*!< Identifier of the owning process */
+ PVRSRV_FENCE hFence; /*!< Unique identifier for the fence resource */
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE eType;
+ /*!< Type of the subevent, see
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE */
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DETAIL uDetail;
+ /*!< Union of structures providing further data
+ regarding device's status. Size of data varies with
+ union member that is present, check ``eType`` value
+ to decode */
+
+} RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA;
+
+static_assert((sizeof(RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+/*! RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA.
+ * Software Timeline Advanced Event Payload. This data structure is received
+ * whenever the host driver processes a Software Timeline Advanced event.
+ */
+typedef struct
+{
+ IMG_PID uiPID; /*!< Identifier of the owning process */
+ PVRSRV_TIMELINE hTimeline; /*!< Unique identifier for the timeline resource */
+ IMG_UINT64 ui64SyncPtIndex; /*!< Index of the sync point to which the
+ timeline has advanced */
+
+} RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA;
+
+static_assert((sizeof(RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+typedef enum
+{
+ RGX_HWPERF_RESOURCE_CAPTURE_TYPE_NONE,
+ RGX_HWPERF_RESOURCE_CAPTURE_TYPE_DEFAULT_FRAMEBUFFER,
+ RGX_HWPERF_RESOURCE_CAPTURE_TYPE_OFFSCREEN_FB_ATTACHMENTS,
+ RGX_HWPERF_RESOURCE_CAPTURE_TYPE_TILE_LIFETIME_DATA,
+
+ RGX_HWPERF_RESOURCE_TYPE_COUNT
+} RGX_HWPERF_RESOURCE_CAPTURE_TYPE;
+
+typedef struct
+{
+ IMG_UINT32 ui32Height;
+ IMG_UINT32 ui32Width;
+ IMG_UINT32 ui32BPP;
+ IMG_UINT32 ui32PixFormat;
+} RGX_RESOURCE_PER_SURFACE_INFO, *PRGX_RESOURCE_PER_SURFACE_INFO;
+
+typedef struct
+{
+ IMG_INT32 i32XOffset; /*!< render surface X shift */
+ IMG_INT32 i32YOffset; /*!< render surface Y shift */
+ IMG_UINT32 ui32WidthInTiles; /*!< number of TLT data points in X */
+ IMG_UINT32 ui32HeightInTiles; /*!< number of TLT data points in Y */
+} RGX_RESOURCE_PER_TLT_BUFFER_INFO, *PRGX_RESOURCE_PER_TLT_BUFFER_INFO;
+
+typedef union
+{
+ struct RGX_RESOURCE_CAPTURE_RENDER_SURFACES
+ {
+ IMG_UINT32 ui32RenderSurfaceCount;
+ RGX_RESOURCE_PER_SURFACE_INFO sSurface[RGX_HWPERF_ONE_OR_MORE_ELEMENTS];
+ } sRenderSurfaces;
+
+ struct RGX_RESOURCE_CAPTURE_TILE_LIFETIME_BUFFERS
+ {
+ RGX_RESOURCE_PER_TLT_BUFFER_INFO sTLTBufInfo[RGX_HWPERF_ONE_OR_MORE_ELEMENTS];
+ } sTLTBuffers;
+} RGX_RESOURCE_CAPTURE_DETAIL;
+
+typedef struct
+{
+ RGX_HWPERF_RESOURCE_CAPTURE_TYPE eType;
+ IMG_PID uPID;
+ IMG_UINT32 ui32ContextID;
+ IMG_UINT32 ui32FrameNum;
+ IMG_UINT32 ui32CapturedTaskJobRef; /* The job ref of the HW task that emitted the data */
+ IMG_INT32 eClientModule; /* RGX_HWPERF_CLIENT_API - ID that the capture is originating from. */
+ RGX_RESOURCE_CAPTURE_DETAIL uDetail; /* eType determines the value of the union */
+} RGX_RESOURCE_CAPTURE_INFO, *PRGX_RESOURCE_CAPTURE_INFO;
+
+#define RGX_RESOURCE_CAPTURE_INFO_BASE_SIZE() offsetof(RGX_RESOURCE_CAPTURE_INFO, uDetail)
+
+/*! Tile Lifetime Tracking header size. Only available if
+ * RGX_FEATURE_ISP_TILE_LIFETIME_TRACKING is present and enabled via
+ * SUPPORT_TLT_PERF
+ */
+#define RGX_TLT_HARDWARE_HDR_SIZE (16U)
+
+/* PVRSRVGetHWPerfResourceCaptureResult */
+typedef enum
+{
+ RGX_HWPERF_RESOURCE_CAPTURE_RESULT_NONE = 0,
+ RGX_HWPERF_RESOURCE_CAPTURE_RESULT_OK, /* We got data ok, expect more packets for this request. */
+ RGX_HWPERF_RESOURCE_CAPTURE_RESULT_NOT_READY, /* Signals a timeout on the connection - no data available yet. */
+ RGX_HWPERF_RESOURCE_CAPTURE_RESULT_COMPLETE_SUCCESS, /* The request completed successfully, signals the end of packets for the request. */
+ RGX_HWPERF_RESOURCE_CAPTURE_RESULT_COMPLETE_FAILURE /* The request failed, signals the end of packets for the request. */
+} RGX_HWPERF_RESOURCE_CAPTURE_RESULT_STATUS;
+
+typedef struct
+{
+ IMG_PID uPID; /* In case of a failed request pass the caller the PID and context ID. */
+ IMG_UINT32 ui32CtxID;
+ RGX_RESOURCE_CAPTURE_INFO *psInfo; /* Various meta-data regarding the captured resource which aid the requester when,
+ unpacking the resource data, valid if RGX_HWPERF_RESOURCE_CAPTURE_RESULT_OK is returned. */
+ IMG_BYTE *pbData; /* Buffer containing the captured resource data, valid if RGX_HWPERF_RESOURCE_CAPTURE_RESULT_OK is returned. */
+} RGX_RESOURCE_CAPTURE_RESULT;
+
+/*! This type is a union of packet payload data structures associated with
+ * various FW and Host events */
+typedef union
+{
+ RGX_HWPERF_FW_DATA sFW; /*!< Firmware event packet data,
+ events ``0x01-0x06`` */
+ RGX_HWPERF_HW_DATA sHW; /*!< Hardware event packet data,
+ events ``0x07-0x19``, ``0x28-0x29`` */
+ RGX_HWPERF_CLKS_CHG_DATA sCLKSCHG; /*!< Clock change event packet
+ data, events ``0x1A`` */
+ RGX_HWPERF_GPU_STATE_CHG_DATA sGPUSTATECHG; /*!< GPU utilisation state
+ change event packet data,
+ events ``0x1B`` */
+ RGX_HWPERF_PWR_EST_DATA sPWREST; /*!< Power estimate event
+ packet data,
+ events ``0x20-0x22`` */
+ RGX_HWPERF_PWR_CHG_DATA sPWR; /*!< Power event packet data,
+ events ``0x23`` */
+ RGX_HWPERF_CSW_DATA sCSW; /*!< Context switch packet data,
+ events ``0x30-0x31`` */
+ RGX_HWPERF_DVFS_DATA sDVFS; /*!< DVFS activity data,
+ events ``0x32`` */
+ RGX_HWPERF_UFO_DATA sUFO; /*!< UFO data, events ``0x38`` */
+ RGX_HWPERF_FWACT_DATA sFWACT; /*!< Firmware activity event
+ packet data,
+ events ``0x39`` */
+ /* */
+ RGX_HWPERF_HOST_ENQ_DATA sENQ; /*!< Host ENQ data,
+ events ``0x01`` (Host) */
+ RGX_HWPERF_HOST_UFO_DATA sHUFO; /*!< Host UFO data,
+ events ``0x02`` (Host) */
+ RGX_HWPERF_HOST_ALLOC_DATA sHALLOC; /*!< Host Alloc data,
+ events ``0x03`` (Host) */
+ RGX_HWPERF_HOST_CLK_SYNC_DATA sHCLKSYNC; /*!< Host CLK_SYNC data,
+ events ``0x04`` (Host) */
+ RGX_HWPERF_HOST_FREE_DATA sHFREE; /*!< Host Free data,
+ events ``0x05`` (Host) */
+ RGX_HWPERF_HOST_MODIFY_DATA sHMOD; /*!< Host Modify data,
+ events ``0x06`` (Host) */
+ RGX_HWPERF_HOST_DEV_INFO_DATA sHDEVINFO; /*!< Host device info data,
+ events ``0x07`` (Host) */
+ RGX_HWPERF_HOST_INFO_DATA sHINFO; /*!< Host info data,
+ events ``0x08`` (Host) */
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA sWAIT; /*!< Host fence-wait data,
+ events ``0x09`` (Host) */
+ RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA sSWTLADV; /*!< Host SW-timeline advance
+ data, events ``0x0A`` (Host) */
+} RGX_HWPERF_V2_PACKET_DATA, *RGX_PHWPERF_V2_PACKET_DATA;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_V2_PACKET_DATA);
+
+#define RGX_HWPERF_GET_PACKET_DATA(_packet_addr) ((RGX_PHWPERF_V2_PACKET_DATA) (IMG_OFFSET_ADDR((_packet_addr), sizeof(RGX_HWPERF_V2_PACKET_HDR))))
+
+#define RGX_HWPERF_GET_DVFS_EVENT_TYPE_PTR(_packet_addr) \
+ ((RGX_HWPERF_DVFS_EV*) (IMG_OFFSET_ADDR((_packet_addr), sizeof(RGX_HWPERF_V2_PACKET_HDR) + offsetof(RGX_HWPERF_DVFS_DATA,eEventType))))
+
+/******************************************************************************
+ * API Types
+ *****************************************************************************/
+
+/*! Counter block IDs for all the hardware blocks with counters.
+ * Directly addressable blocks must have a value between 0..15 [0..0xF].
+ * Indirect groups have following encoding:
+ * First hex digit (LSB) represents a unit number within the group
+ * and the second hex digit represents the group number.
+ * Group 0 is the direct group, all others are indirect groups.
+ */
+typedef IMG_UINT32 RGX_HWPERF_CNTBLK_ID;
+
+/*! Directly addressable counter blocks */
+#if defined(DOXYGEN)
+/*! _RGX_HWPERF_CNTBLK_ID */
+#endif
+#define RGX_CNTBLK_ID_TA 0x0000U
+#define RGX_CNTBLK_ID_RASTER 0x0001U /*!< Non-cluster grouping cores */
+#define RGX_CNTBLK_ID_HUB 0x0002U /*!< Non-cluster grouping cores */
+#define RGX_CNTBLK_ID_TORNADO 0x0003U /*!< XT cores */
+#define RGX_CNTBLK_ID_JONES 0x0004U /*!< S7 cores */
+#define RGX_CNTBLK_ID_DIRECT_LAST 0x0005U /*!< Indirect blocks start from here */
+
+#define RGX_CNTBLK_ID_BF_DEPRECATED 0x0005U /*!< Doppler unit (DEPRECATED) */
+#define RGX_CNTBLK_ID_BT_DEPRECATED 0x0006U /*!< Doppler unit (DEPRECATED) */
+#define RGX_CNTBLK_ID_RT_DEPRECATED 0x0007U /*!< Doppler unit (DEPRECATED) */
+#define RGX_CNTBLK_ID_SH_DEPRECATED 0x0008U /*!< Ray tracing unit (DEPRECATED) */
+
+
+/*! Indirectly addressable counter blocks. DA blocks indicate counter blocks
+ * where the counter registers are directly accessible
+ */
+#define RGX_CNTBLK_ID_TPU_MCU0 0x0010U /*!< Addressable by Dust */
+#define RGX_CNTBLK_ID_TPU_MCU0_DA 0x8010U
+#define RGX_CNTBLK_ID_TPU_MCU1 0x0011U
+#define RGX_CNTBLK_ID_TPU_MCU1_DA 0x8011U
+#define RGX_CNTBLK_ID_TPU_MCU2 0x0012U
+#define RGX_CNTBLK_ID_TPU_MCU2_DA 0x8012U
+#define RGX_CNTBLK_ID_TPU_MCU3 0x0013U
+#define RGX_CNTBLK_ID_TPU_MCU3_DA 0x8013U
+#define RGX_CNTBLK_ID_TPU_MCU4 0x0014U
+#define RGX_CNTBLK_ID_TPU_MCU4_DA 0x8014U
+#define RGX_CNTBLK_ID_TPU_MCU5 0x0015U
+#define RGX_CNTBLK_ID_TPU_MCU5_DA 0x8015U
+#define RGX_CNTBLK_ID_TPU_MCU6 0x0016U
+#define RGX_CNTBLK_ID_TPU_MCU6_DA 0x8016U
+#define RGX_CNTBLK_ID_TPU_MCU7 0x0017U
+#define RGX_CNTBLK_ID_TPU_MCU7_DA 0x8017U
+#define RGX_CNTBLK_ID_TPU_MCU_ALL 0x4010U
+#define RGX_CNTBLK_ID_TPU_MCU_ALL_DA 0xC010U
+
+#define RGX_CNTBLK_ID_USC0 0x0020U /*!< Addressable by Cluster */
+#define RGX_CNTBLK_ID_USC0_DA 0x8020U
+#define RGX_CNTBLK_ID_USC1 0x0021U
+#define RGX_CNTBLK_ID_USC1_DA 0x8021U
+#define RGX_CNTBLK_ID_USC2 0x0022U
+#define RGX_CNTBLK_ID_USC2_DA 0x8022U
+#define RGX_CNTBLK_ID_USC3 0x0023U
+#define RGX_CNTBLK_ID_USC3_DA 0x8023U
+#define RGX_CNTBLK_ID_USC4 0x0024U
+#define RGX_CNTBLK_ID_USC4_DA 0x8024U
+#define RGX_CNTBLK_ID_USC5 0x0025U
+#define RGX_CNTBLK_ID_USC5_DA 0x8025U
+#define RGX_CNTBLK_ID_USC6 0x0026U
+#define RGX_CNTBLK_ID_USC6_DA 0x8026U
+#define RGX_CNTBLK_ID_USC7 0x0027U
+#define RGX_CNTBLK_ID_USC7_DA 0x8027U
+#define RGX_CNTBLK_ID_USC8 0x0028U
+#define RGX_CNTBLK_ID_USC8_DA 0x8028U
+#define RGX_CNTBLK_ID_USC9 0x0029U
+#define RGX_CNTBLK_ID_USC9_DA 0x8029U
+#define RGX_CNTBLK_ID_USC10 0x002AU
+#define RGX_CNTBLK_ID_USC10_DA 0x802AU
+#define RGX_CNTBLK_ID_USC11 0x002BU
+#define RGX_CNTBLK_ID_USC11_DA 0x802BU
+#define RGX_CNTBLK_ID_USC12 0x002CU
+#define RGX_CNTBLK_ID_USC12_DA 0x802CU
+#define RGX_CNTBLK_ID_USC13 0x002DU
+#define RGX_CNTBLK_ID_USC13_DA 0x802DU
+#define RGX_CNTBLK_ID_USC14 0x002EU
+#define RGX_CNTBLK_ID_USC14_DA 0x802EU
+#define RGX_CNTBLK_ID_USC15 0x002FU
+#define RGX_CNTBLK_ID_USC15_DA 0x802FU
+#define RGX_CNTBLK_ID_USC_ALL 0x4020U
+#define RGX_CNTBLK_ID_USC_ALL_DA 0xC020U
+
+#define RGX_CNTBLK_ID_TEXAS0 0x0030U /*!< Addressable by Phantom in XT, Dust in S7 */
+#define RGX_CNTBLK_ID_TEXAS1 0x0031U
+#define RGX_CNTBLK_ID_TEXAS2 0x0032U
+#define RGX_CNTBLK_ID_TEXAS3 0x0033U
+#define RGX_CNTBLK_ID_TEXAS4 0x0034U
+#define RGX_CNTBLK_ID_TEXAS5 0x0035U
+#define RGX_CNTBLK_ID_TEXAS6 0x0036U
+#define RGX_CNTBLK_ID_TEXAS7 0x0037U
+#define RGX_CNTBLK_ID_TEXAS_ALL 0x4030U
+
+#define RGX_CNTBLK_ID_RASTER0 0x0040U /*!< Addressable by Phantom, XT only */
+#define RGX_CNTBLK_ID_RASTER1 0x0041U
+#define RGX_CNTBLK_ID_RASTER2 0x0042U
+#define RGX_CNTBLK_ID_RASTER3 0x0043U
+#define RGX_CNTBLK_ID_RASTER_ALL 0x4040U
+
+#define RGX_CNTBLK_ID_BLACKPEARL0 0x0050U /*!< Addressable by Phantom, S7, only */
+#define RGX_CNTBLK_ID_BLACKPEARL1 0x0051U
+#define RGX_CNTBLK_ID_BLACKPEARL2 0x0052U
+#define RGX_CNTBLK_ID_BLACKPEARL3 0x0053U
+#define RGX_CNTBLK_ID_BLACKPEARL_ALL 0x4050U
+
+#define RGX_CNTBLK_ID_PBE0 0x0060U /*!< Addressable by Cluster in S7 and PBE2_IN_XE */
+#define RGX_CNTBLK_ID_PBE1 0x0061U
+#define RGX_CNTBLK_ID_PBE2 0x0062U
+#define RGX_CNTBLK_ID_PBE3 0x0063U
+#define RGX_CNTBLK_ID_PBE4 0x0064U
+#define RGX_CNTBLK_ID_PBE5 0x0065U
+#define RGX_CNTBLK_ID_PBE6 0x0066U
+#define RGX_CNTBLK_ID_PBE7 0x0067U
+#define RGX_CNTBLK_ID_PBE8 0x0068U
+#define RGX_CNTBLK_ID_PBE9 0x0069U
+#define RGX_CNTBLK_ID_PBE10 0x006AU
+#define RGX_CNTBLK_ID_PBE11 0x006BU
+#define RGX_CNTBLK_ID_PBE12 0x006CU
+#define RGX_CNTBLK_ID_PBE13 0x006DU
+#define RGX_CNTBLK_ID_PBE14 0x006EU
+#define RGX_CNTBLK_ID_PBE15 0x006FU
+#define RGX_CNTBLK_ID_PBE_ALL 0x4060U
+
+#define RGX_CNTBLK_ID_LAST 0x0070U /*!< End of PBE block */
+
+#define RGX_CNTBLK_ID_BX_TU0_DEPRECATED 0x0070U /*!< Doppler unit, DEPRECATED */
+#define RGX_CNTBLK_ID_BX_TU1_DEPRECATED 0x0071U
+#define RGX_CNTBLK_ID_BX_TU2_DEPRECATED 0x0072U
+#define RGX_CNTBLK_ID_BX_TU3_DEPRECATED 0x0073U
+#define RGX_CNTBLK_ID_BX_TU_ALL_DEPRECATED 0x4070U
+
+#define RGX_CNTBLK_ID_CUSTOM0 0x70F0U
+#define RGX_CNTBLK_ID_CUSTOM1 0x70F1U
+#define RGX_CNTBLK_ID_CUSTOM2 0x70F2U
+#define RGX_CNTBLK_ID_CUSTOM3 0x70F3U
+#define RGX_CNTBLK_ID_CUSTOM4_FW 0x70F4U /*!< Custom block used for getting statistics held in the FW */
+#define RGX_CNTBLK_ID_CUSTOM_MASK 0x70FFU
+
+
+/* Masks for the counter block ID*/
+#define RGX_CNTBLK_ID_UNIT_MASK (0x000FU)
+#define RGX_CNTBLK_ID_GROUP_MASK (0x00F0U)
+#define RGX_CNTBLK_ID_GROUP_SHIFT (4U)
+#define RGX_CNTBLK_ID_MC_GPU_MASK (0x0F00U)
+#define RGX_CNTBLK_ID_MC_GPU_SHIFT (8U)
+#define RGX_CNTBLK_ID_UNIT_ALL_MASK (0x4000U)
+#define RGX_CNTBLK_ID_DA_MASK (0x8000U) /*!< Block with directly accessible counter registers */
+
+#define RGX_CNTBLK_INDIRECT_COUNT(_class, _n) ((IMG_UINT32)(RGX_CNTBLK_ID_ ## _class ## _n) - (IMG_UINT32)(RGX_CNTBLK_ID_ ## _class ## 0) + 1u)
+
+/*! The number of layout blocks defined with configurable multiplexed
+ * performance counters, hence excludes custom counter blocks.
+ */
+#define RGX_HWPERF_MAX_DEFINED_BLKS (\
+ (IMG_UINT32)RGX_CNTBLK_ID_DIRECT_LAST +\
+ RGX_CNTBLK_INDIRECT_COUNT(TPU_MCU, 7)+\
+ RGX_CNTBLK_INDIRECT_COUNT(USC, 15)+\
+ RGX_CNTBLK_INDIRECT_COUNT(TEXAS, 7)+\
+ RGX_CNTBLK_INDIRECT_COUNT(RASTER, 3)+\
+ RGX_CNTBLK_INDIRECT_COUNT(BLACKPEARL, 3)+\
+ RGX_CNTBLK_INDIRECT_COUNT(PBE, 15) )
+
+static_assert(
+ ((RGX_CNTBLK_ID_DIRECT_LAST + ((RGX_CNTBLK_ID_LAST & RGX_CNTBLK_ID_GROUP_MASK) >> RGX_CNTBLK_ID_GROUP_SHIFT)) <= RGX_HWPERF_MAX_BVNC_BLOCK_LEN),
+ "RGX_HWPERF_MAX_BVNC_BLOCK_LEN insufficient");
+
+#define RGX_HWPERF_EVENT_MASK_VALUE(e) (IMG_UINT64_C(1) << (e))
+
+#define RGX_CUSTOM_FW_CNTRS \
+ X(TA_LOCAL_FL_SIZE, 0x0, RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_TAKICK) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_PMOOM_TAPAUSE) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_PMOOM_TARESUME) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_TAFINISHED)) \
+ \
+ X(TA_GLOBAL_FL_SIZE, 0x1, RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_TAKICK) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_PMOOM_TAPAUSE) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_PMOOM_TARESUME) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_TAFINISHED)) \
+ \
+ X(3D_LOCAL_FL_SIZE, 0x2, RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_3DKICK) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_3DFINISHED)) \
+ \
+ X(3D_GLOBAL_FL_SIZE, 0x3, RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_3DKICK) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_3DFINISHED)) \
+ \
+ X(ISP_TILES_IN_FLIGHT, 0x4, RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_3DKICK) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_3DSPMKICK))
+
+/*! Counter IDs for the firmware held statistics */
+typedef enum
+{
+#define X(ctr, id, allow_mask) RGX_CUSTOM_FW_CNTR_##ctr = id,
+ RGX_CUSTOM_FW_CNTRS
+#undef X
+
+ /* always the last entry in the list */
+ RGX_CUSTOM_FW_CNTR_LAST
+} RGX_HWPERF_CUSTOM_FW_CNTR_ID;
+
+/*! Identifier for each counter in a performance counting module */
+typedef IMG_UINT32 RGX_HWPERF_CNTBLK_COUNTER_ID;
+
+#define RGX_CNTBLK_COUNTER0_ID 0U
+#define RGX_CNTBLK_COUNTER1_ID 1U
+#define RGX_CNTBLK_COUNTER2_ID 2U
+#define RGX_CNTBLK_COUNTER3_ID 3U
+#define RGX_CNTBLK_COUNTER4_ID 4U
+#define RGX_CNTBLK_COUNTER5_ID 5U
+ /* MAX value used in server handling of counter config arrays */
+#define RGX_CNTBLK_MUX_COUNTERS_MAX 6U
+
+
+/* sets all the bits from bit _b1 to _b2, in a IMG_UINT64 type */
+#define MASK_RANGE_IMPL(b1, b2) ((IMG_UINT64)((IMG_UINT64_C(1) << ((IMG_UINT32)(b2)-(IMG_UINT32)(b1) + 1U)) - 1U) << (IMG_UINT32)(b1))
+#define MASK_RANGE(R) MASK_RANGE_IMPL(R##_FIRST_TYPE, R##_LAST_TYPE)
+#define RGX_HWPERF_HOST_EVENT_MASK_VALUE(e) (IMG_UINT32_C(1) << (e))
+
+/*! Mask macros for use with RGXCtrlHWPerf() API.
+ */
+#define RGX_HWPERF_EVENT_MASK_NONE (IMG_UINT64_C(0x0000000000000000))
+#define RGX_HWPERF_EVENT_MASK_DEFAULT RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_FWACT) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_PWR_CHG) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_CLKS_CHG)
+#define RGX_HWPERF_EVENT_MASK_ALL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF))
+
+/*! HWPerf Firmware event masks
+ * @par
+ * All FW Start/End/Debug (SED) events. */
+#define RGX_HWPERF_EVENT_MASK_FW_SED (MASK_RANGE(RGX_HWPERF_FW_EVENT_RANGE))
+
+#define RGX_HWPERF_EVENT_MASK_FW_UFO (RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_UFO))
+#define RGX_HWPERF_EVENT_MASK_FW_CSW (RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_CSW_START) |\
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_CSW_FINISHED))
+/*! All FW events. */
+#define RGX_HWPERF_EVENT_MASK_ALL_FW (RGX_HWPERF_EVENT_MASK_FW_SED |\
+ RGX_HWPERF_EVENT_MASK_FW_UFO |\
+ RGX_HWPERF_EVENT_MASK_FW_CSW)
+
+/*! HW Periodic events (1ms interval). */
+#define RGX_HWPERF_EVENT_MASK_HW_PERIODIC (RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_PERIODIC))
+/*! All HW Kick/Finish events. */
+#define RGX_HWPERF_EVENT_MASK_HW_KICKFINISH ((MASK_RANGE(RGX_HWPERF_HW_EVENT_RANGE0) |\
+ MASK_RANGE(RGX_HWPERF_HW_EVENT_RANGE1)) &\
+ ~(RGX_HWPERF_EVENT_MASK_HW_PERIODIC))
+
+#define RGX_HWPERF_EVENT_MASK_ALL_HW (RGX_HWPERF_EVENT_MASK_HW_KICKFINISH |\
+ RGX_HWPERF_EVENT_MASK_HW_PERIODIC)
+
+#define RGX_HWPERF_EVENT_MASK_ALL_PWR_EST (MASK_RANGE(RGX_HWPERF_PWR_EST_RANGE))
+
+#define RGX_HWPERF_EVENT_MASK_ALL_PWR (RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_CLKS_CHG) |\
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_GPU_STATE_CHG) |\
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_PWR_CHG))
+
+/*! HWPerf Host event masks
+ */
+#define RGX_HWPERF_EVENT_MASK_HOST_WORK_ENQ (RGX_HWPERF_HOST_EVENT_MASK_VALUE(RGX_HWPERF_HOST_ENQ))
+#define RGX_HWPERF_EVENT_MASK_HOST_ALL_UFO (RGX_HWPERF_HOST_EVENT_MASK_VALUE(RGX_HWPERF_HOST_UFO))
+#define RGX_HWPERF_EVENT_MASK_HOST_ALL_PWR (RGX_HWPERF_HOST_EVENT_MASK_VALUE(RGX_HWPERF_HOST_CLK_SYNC))
+
+
+/*! Type used in the RGX API RGXConfigMuxHWPerfCounters() */
+typedef struct
+{
+ /*! Counter block ID, see RGX_HWPERF_CNTBLK_ID */
+ IMG_UINT16 ui16BlockID;
+
+ /*! 4 or 6 LSBs used to select counters to configure in this block. */
+ IMG_UINT8 ui8CounterSelect;
+
+ /*! 4 or 6 LSBs used as MODE bits for the counters in the group. */
+ IMG_UINT8 ui8Mode;
+
+ /*! 5 or 6 LSBs used as the GROUP_SELECT value for the counter. */
+ IMG_UINT8 aui8GroupSelect[RGX_CNTBLK_MUX_COUNTERS_MAX];
+
+ /*! 16 LSBs used as the BIT_SELECT value for the counter. */
+ IMG_UINT16 aui16BitSelect[RGX_CNTBLK_MUX_COUNTERS_MAX];
+
+ /*! 14 LSBs used as the BATCH_MAX value for the counter. */
+ IMG_UINT32 aui32BatchMax[RGX_CNTBLK_MUX_COUNTERS_MAX];
+
+ /*! 14 LSBs used as the BATCH_MIN value for the counter. */
+ IMG_UINT32 aui32BatchMin[RGX_CNTBLK_MUX_COUNTERS_MAX];
+} UNCACHED_ALIGN RGX_HWPERF_CONFIG_MUX_CNTBLK;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_CONFIG_MUX_CNTBLK);
+
+/*! Type used in the RGX API RGXConfigHWPerfCounters() */
+typedef struct
+{
+ /*! Reserved for future use */
+ IMG_UINT32 ui32Reserved;
+
+ /*! Counter block ID, see RGX_HWPERF_CNTBLK_ID */
+ IMG_UINT16 ui16BlockID;
+
+ /*! Number of configured counters within this block */
+ IMG_UINT16 ui16NumCounters;
+
+ /*! Counter register values */
+ IMG_UINT16 ui16Counters[RGX_CNTBLK_COUNTERS_MAX];
+} UNCACHED_ALIGN RGX_HWPERF_CONFIG_CNTBLK;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_CONFIG_CNTBLK);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* RGX_HWPERF_H_ */
+
+/******************************************************************************
+ End of file
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/rogue/rgx_options.h b/drivers/gpu/drm/img-rogue/include/rogue/rgx_options.h
new file mode 100644
index 000000000..91fc6522d
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/rogue/rgx_options.h
@@ -0,0 +1,304 @@
+/*************************************************************************/ /*!
+@File
+@Title RGX build options
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/* Each build option listed here is packed into a dword which provides up to
+ * log2(RGX_BUILD_OPTIONS_MASK_KM + 1) flags for KM and
+ * (32 - log2(RGX_BUILD_OPTIONS_MASK_KM + 1)) flags for UM.
+ * The corresponding bit is set if the build option was enabled at compile
+ * time.
+ *
+ * In order to extract the enabled build flags the INTERNAL_TEST switch should
+ * be enabled in a client program which includes this header. Then the client
+ * can test specific build flags by reading the bit value at
+ * ##OPTIONNAME##_SET_OFFSET
+ * in RGX_BUILD_OPTIONS_KM or RGX_BUILD_OPTIONS.
+ *
+ * IMPORTANT: add new options to unused bits or define a new dword
+ * (e.g. RGX_BUILD_OPTIONS_KM2 or RGX_BUILD_OPTIONS2) so that the bitfield
+ * remains backwards compatible.
+ */
+
+#ifndef RGX_OPTIONS_H
+#define RGX_OPTIONS_H
+
+#define RGX_BUILD_OPTIONS_MASK_KM 0x0000FFFFUL
+
+#define NO_HARDWARE_OPTION "NO_HARDWARE "
+#if defined(NO_HARDWARE) || defined(INTERNAL_TEST)
+ #define NO_HARDWARE_SET_OFFSET OPTIONS_BIT0
+ #define OPTIONS_BIT0 (0x1UL << 0)
+ #if OPTIONS_BIT0 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT0 0x0UL
+#endif /* NO_HARDWARE */
+
+#define PDUMP_OPTION "PDUMP "
+#if defined(PDUMP) || defined(INTERNAL_TEST)
+ #define PDUMP_SET_OFFSET OPTIONS_BIT1
+ #define OPTIONS_BIT1 (0x1UL << 1)
+ #if OPTIONS_BIT1 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT1 0x0UL
+#endif /* PDUMP */
+
+/* No longer used */
+#define INTERNAL_TEST_OPTION "INTERNAL_TEST "
+#if defined(INTERNAL_TEST)
+ #define UNUSED_SET_OFFSET OPTIONS_BIT2
+ #define OPTIONS_BIT2 (0x1UL << 2)
+ #if OPTIONS_BIT2 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT2 0x0UL
+#endif
+
+/* No longer used */
+#define UNUSED_OPTION " "
+#if defined(INTERNAL_TEST)
+ #define OPTIONS_BIT3 (0x1UL << 3)
+ #define INTERNAL_TEST_OPTION "INTERNAL_TEST "
+ #if OPTIONS_BIT3 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT3 0x0UL
+#endif
+
+#define SUPPORT_RGX_OPTION " "
+#if defined(SUPPORT_RGX) || defined(INTERNAL_TEST)
+ #define SUPPORT_RGX_SET_OFFSET OPTIONS_BIT4
+ #define OPTIONS_BIT4 (0x1UL << 4)
+ #if OPTIONS_BIT4 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT4 0x0UL
+#endif /* SUPPORT_RGX */
+
+#define SUPPORT_SECURE_EXPORT_OPTION "SECURE_EXPORTS "
+#if defined(SUPPORT_SECURE_EXPORT) || defined(INTERNAL_TEST)
+ #define SUPPORT_SECURE_EXPORT_SET_OFFSET OPTIONS_BIT5
+ #define OPTIONS_BIT5 (0x1UL << 5)
+ #if OPTIONS_BIT5 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT5 0x0UL
+#endif /* SUPPORT_SECURE_EXPORT */
+
+#define SUPPORT_INSECURE_EXPORT_OPTION "INSECURE_EXPORTS "
+#if defined(SUPPORT_INSECURE_EXPORT) || defined(INTERNAL_TEST)
+ #define SUPPORT_INSECURE_EXPORT_SET_OFFSET OPTIONS_BIT6
+ #define OPTIONS_BIT6 (0x1UL << 6)
+ #if OPTIONS_BIT6 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT6 0x0UL
+#endif /* SUPPORT_INSECURE_EXPORT */
+
+#define SUPPORT_VFP_OPTION "VFP "
+#if defined(SUPPORT_VFP) || defined(INTERNAL_TEST)
+ #define SUPPORT_VFP_SET_OFFSET OPTIONS_BIT7
+ #define OPTIONS_BIT7 (0x1UL << 7)
+ #if OPTIONS_BIT7 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT7 0x0UL
+#endif /* SUPPORT_VFP */
+
+#define SUPPORT_WORKLOAD_ESTIMATION_OPTION "WORKLOAD_ESTIMATION "
+#if defined(SUPPORT_WORKLOAD_ESTIMATION) || defined(INTERNAL_TEST)
+ #define SUPPORT_WORKLOAD_ESTIMATION_OFFSET OPTIONS_BIT8
+ #define OPTIONS_BIT8 (0x1UL << 8)
+ #if OPTIONS_BIT8 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT8 0x0UL
+#endif /* SUPPORT_WORKLOAD_ESTIMATION */
+#define OPTIONS_WORKLOAD_ESTIMATION_MASK (0x1UL << 8)
+
+#define SUPPORT_PDVFS_OPTION "PDVFS "
+#if defined(SUPPORT_PDVFS) || defined(INTERNAL_TEST)
+ #define SUPPORT_PDVFS_OFFSET OPTIONS_BIT9
+ #define OPTIONS_BIT9 (0x1UL << 9)
+ #if OPTIONS_BIT9 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT9 0x0UL
+#endif /* SUPPORT_PDVFS */
+#define OPTIONS_PDVFS_MASK (0x1UL << 9)
+
+#define DEBUG_OPTION "DEBUG "
+#if defined(DEBUG) || defined(INTERNAL_TEST)
+ #define DEBUG_SET_OFFSET OPTIONS_BIT10
+ #define OPTIONS_BIT10 (0x1UL << 10)
+ #if OPTIONS_BIT10 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT10 0x0UL
+#endif /* DEBUG */
+/* The bit position of this should be the same as DEBUG_SET_OFFSET option
+ * when defined.
+ */
+#define OPTIONS_DEBUG_MASK (0x1UL << 10)
+
+#define SUPPORT_BUFFER_SYNC_OPTION "BUFFER_SYNC "
+#if defined(SUPPORT_BUFFER_SYNC) || defined(INTERNAL_TEST)
+ #define SUPPORT_BUFFER_SYNC_SET_OFFSET OPTIONS_BIT11
+ #define OPTIONS_BIT11 (0x1UL << 11)
+ #if OPTIONS_BIT11 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT11 0x0UL
+#endif /* SUPPORT_BUFFER_SYNC */
+
+#define SUPPORT_AUTOVZ_OPTION "AUTOVZ "
+#if defined(SUPPORT_AUTOVZ)
+ #define SUPPORT_AUTOVZ_OFFSET OPTIONS_BIT12
+ #define OPTIONS_BIT12 (0x1UL << 12)
+ #if OPTIONS_BIT12 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT12 0x0UL
+#endif /* SUPPORT_AUTOVZ */
+
+#define SUPPORT_AUTOVZ_HW_REGS_OPTION "AUTOVZ_HW_REGS "
+#if defined(SUPPORT_AUTOVZ_HW_REGS)
+ #define SUPPORT_AUTOVZ_HW_REGS_OFFSET OPTIONS_BIT13
+ #define OPTIONS_BIT13 (0x1UL << 13)
+ #if OPTIONS_BIT13 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT13 0x0UL
+#endif /* SUPPORT_AUTOVZ_HW_REGS */
+
+#define RGX_FW_IRQ_OS_COUNTERS_OPTION "FW_IRQ_OS_COUNTERS "
+#if defined(RGX_FW_IRQ_OS_COUNTERS) || defined(INTERNAL_TEST)
+ #define SUPPORT_FW_IRQ_REG_COUNTERS OPTIONS_BIT14
+ #define OPTIONS_BIT14 (0x1UL << 14)
+ #if OPTIONS_BIT14 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT14 0x0UL
+#endif /* RGX_FW_IRQ_OS_COUNTERS */
+
+#define VALIDATION_EN_MASK (0x1UL << 15)
+#define SUPPORT_VALIDATION_OPTION "VALIDATION "
+#if defined(SUPPORT_VALIDATION)
+ #define SUPPORT_VALIDATION_OFFSET OPTIONS_BIT15
+ #define OPTIONS_BIT15 (0x1UL << 15)
+ #if OPTIONS_BIT15 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT15 0x0UL
+#endif /* SUPPORT_VALIDATION */
+
+#define RGX_BUILD_OPTIONS_KM \
+ (OPTIONS_BIT0 |\
+ OPTIONS_BIT1 |\
+ OPTIONS_BIT2 |\
+ OPTIONS_BIT3 |\
+ OPTIONS_BIT4 |\
+ OPTIONS_BIT6 |\
+ OPTIONS_BIT7 |\
+ OPTIONS_BIT8 |\
+ OPTIONS_BIT9 |\
+ OPTIONS_BIT10 |\
+ OPTIONS_BIT11 |\
+ OPTIONS_BIT12 |\
+ OPTIONS_BIT13 |\
+ OPTIONS_BIT14 |\
+ OPTIONS_BIT15)
+
+#define RGX_BUILD_OPTIONS_LIST \
+ { \
+ NO_HARDWARE_OPTION, \
+ PDUMP_OPTION, \
+ INTERNAL_TEST_OPTION, \
+ UNUSED_OPTION, \
+ SUPPORT_RGX_OPTION, \
+ SUPPORT_SECURE_EXPORT_OPTION, \
+ SUPPORT_INSECURE_EXPORT_OPTION, \
+ SUPPORT_VFP_OPTION, \
+ SUPPORT_WORKLOAD_ESTIMATION_OPTION, \
+ SUPPORT_PDVFS_OPTION, \
+ DEBUG_OPTION, \
+ SUPPORT_BUFFER_SYNC_OPTION, \
+ SUPPORT_AUTOVZ_OPTION, \
+ SUPPORT_AUTOVZ_HW_REGS_OPTION, \
+ RGX_FW_IRQ_OS_COUNTERS_OPTION, \
+ SUPPORT_VALIDATION_OPTION \
+ }
+
+#define RGX_BUILD_OPTIONS_MASK_FW \
+ (RGX_BUILD_OPTIONS_MASK_KM & \
+ ~OPTIONS_BIT11)
+
+#define OPTIONS_BIT31 (0x1UL << 31)
+#if OPTIONS_BIT31 <= RGX_BUILD_OPTIONS_MASK_KM
+#error "Bit exceeds reserved range"
+#endif
+#define SUPPORT_PERCONTEXT_FREELIST_SET_OFFSET OPTIONS_BIT31
+
+#define RGX_BUILD_OPTIONS (RGX_BUILD_OPTIONS_KM | OPTIONS_BIT31)
+
+#define OPTIONS_STRICT (RGX_BUILD_OPTIONS & \
+ ~(OPTIONS_DEBUG_MASK | \
+ OPTIONS_WORKLOAD_ESTIMATION_MASK | \
+ OPTIONS_PDVFS_MASK))
+
+#endif /* RGX_OPTIONS_H */
diff --git a/drivers/gpu/drm/img-rogue/include/rogue/rgxheapconfig.h b/drivers/gpu/drm/img-rogue/include/rogue/rgxheapconfig.h
new file mode 100644
index 000000000..2c24cad1d
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/rogue/rgxheapconfig.h
@@ -0,0 +1,285 @@
+/*************************************************************************/ /*!
+@File
+@Title RGX Device virtual memory map
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Memory heaps device specific configuration
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef RGXHEAPCONFIG_H
+#define RGXHEAPCONFIG_H
+
+#include "rgxdefs_km.h"
+
+
+#define RGX_HEAP_SIZE_4KiB IMG_UINT64_C(0x0000001000)
+#define RGX_HEAP_SIZE_64KiB IMG_UINT64_C(0x0000010000)
+#define RGX_HEAP_SIZE_256KiB IMG_UINT64_C(0x0000040000)
+
+#define RGX_HEAP_SIZE_1MiB IMG_UINT64_C(0x0000100000)
+#define RGX_HEAP_SIZE_2MiB IMG_UINT64_C(0x0000200000)
+#define RGX_HEAP_SIZE_4MiB IMG_UINT64_C(0x0000400000)
+#define RGX_HEAP_SIZE_16MiB IMG_UINT64_C(0x0001000000)
+#define RGX_HEAP_SIZE_256MiB IMG_UINT64_C(0x0010000000)
+
+#define RGX_HEAP_SIZE_1GiB IMG_UINT64_C(0x0040000000)
+#define RGX_HEAP_SIZE_2GiB IMG_UINT64_C(0x0080000000)
+#define RGX_HEAP_SIZE_4GiB IMG_UINT64_C(0x0100000000)
+#define RGX_HEAP_SIZE_16GiB IMG_UINT64_C(0x0400000000)
+#define RGX_HEAP_SIZE_32GiB IMG_UINT64_C(0x0800000000)
+#define RGX_HEAP_SIZE_64GiB IMG_UINT64_C(0x1000000000)
+#define RGX_HEAP_SIZE_128GiB IMG_UINT64_C(0x2000000000)
+#define RGX_HEAP_SIZE_256GiB IMG_UINT64_C(0x4000000000)
+#define RGX_HEAP_SIZE_512GiB IMG_UINT64_C(0x8000000000)
+
+/*
+ RGX Device Virtual Address Space Definitions
+
+ This file defines the RGX virtual address heaps that are used in
+ application memory contexts. It also shows where the Firmware memory heap
+ fits into this, but the firmware heap is only ever created in the
+ Services KM/server component.
+
+ RGX_PDSCODEDATA_HEAP_BASE and RGX_USCCODE_HEAP_BASE will be programmed,
+ on a global basis, into RGX_CR_PDS_EXEC_BASE and RGX_CR_USC_CODE_BASE_*
+ respectively. Therefore if clients use multiple configs they must still
+ be consistent with their definitions for these heaps.
+
+ Shared virtual memory (GENERAL_SVM) support requires half of the address
+ space (512 GiB) be reserved for SVM allocations to mirror application CPU
+ addresses. However, if BRN_65273 WA is active in which case the SVM heap
+ is disabled. This is reflected in the device connection capability bits
+ returned to user space.
+
+ The GENERAL non-SVM region is 512 GiB to 768 GiB and is shared between the
+ general (4KiB) heap and the general non-4K heap. The first 128 GiB is used
+ for the GENERAL_HEAP (4KiB) and the last 32 GiB is used for the
+ GENERAL_NON4K_HEAP. This heap has a default page-size of 16K.
+ AppHint PVRSRV_APPHINT_GENERALNON4KHEAPPAGESIZE can be used to forced it
+ to these values: 4K,64K,256K,1M,2M.
+
+ The heaps defined for BRN_65273 _replace_ the non-BRN equivalents below
+ when this BRN WA is active on affected cores. This is different to most
+ other BRNs and hence has been given its own header file for clarity,
+ see below. This is a special case, other BRNs that need 1 or 2 additional
+ heaps should be added to this file, like BRN_63142 below.
+ NOTE: All regular heaps below greater than 1GB require a BRN_65273 WA heap.
+
+ Base addresses have to be a multiple of 4MiB
+ Heaps must not start at 0x0000000000, as this is reserved for internal
+ use within device memory layer.
+ Range comments, those starting in column 0 below are a section heading of
+ sorts and are above the heaps in that range. Often this is the reserved
+ size of the heap within the range.
+*/
+
+/* This BRN requires a different virtual memory map from the standard one
+ * defined in this file below. Hence the alternative heap definitions for this
+ * BRN are provided in a separate file for clarity. */
+#include "rgxheapconfig_65273.h"
+
+
+/* 0x00_0000_0000 ************************************************************/
+
+/* 0x00_0000_0000 - 0x00_0040_0000 **/
+ /* 0 MiB to 4 MiB, size of 4 MiB : RESERVED **/
+
+ /* BRN_65273 TQ3DPARAMETERS base 0x0000010000 */
+ /* BRN_65273 GENERAL base 0x65C0000000 */
+ /* BRN_65273 GENERAL_NON4K base 0x73C0000000 */
+
+/* 0x00_0040_0000 - 0x7F_FFC0_0000 **/
+ /* 4 MiB to 512 GiB, size of 512 GiB less 4 MiB : GENERAL_SVM_HEAP **/
+ #define RGX_GENERAL_SVM_HEAP_BASE IMG_UINT64_C(0x0000400000)
+ #define RGX_GENERAL_SVM_HEAP_SIZE (RGX_HEAP_SIZE_512GiB - RGX_HEAP_SIZE_4MiB)
+
+
+/* 0x80_0000_0000 ************************************************************/
+
+/* 0x80_0000_0000 - 0x9F_FFFF_FFFF **/
+ /* 512 GiB to 640 GiB, size of 128 GiB : GENERAL_HEAP **/
+ #define RGX_GENERAL_HEAP_BASE IMG_UINT64_C(0x8000000000)
+ #define RGX_GENERAL_HEAP_SIZE RGX_HEAP_SIZE_128GiB
+
+ /* BRN_65273 PDSCODEDATA base 0xA800000000 */
+
+/* 0xA0_0000_0000 - 0xAF_FFFF_FFFF **/
+ /* 640 GiB to 704 GiB, size of 64 GiB : FREE **/
+
+/* B0_0000_0000 - 0xB7_FFFF_FFFF **/
+ /* 704 GiB to 736 GiB, size of 32 GiB : FREE **/
+
+ /* BRN_65273 USCCODE base 0xBA00000000 */
+
+/* 0xB8_0000_0000 - 0xBF_FFFF_FFFF **/
+ /* 736 GiB to 768 GiB, size of 32 GiB : GENERAL_NON4K_HEAP **/
+ #define RGX_GENERAL_NON4K_HEAP_BASE IMG_UINT64_C(0xB800000000)
+ #define RGX_GENERAL_NON4K_HEAP_SIZE RGX_HEAP_SIZE_32GiB
+
+
+/* 0xC0_0000_0000 ************************************************************/
+
+/* 0xC0_0000_0000 - 0xD9_FFFF_FFFF **/
+ /* 768 GiB to 872 GiB, size of 104 GiB : FREE **/
+
+/* 0xDA_0000_0000 - 0xDA_FFFF_FFFF **/
+ /* 872 GiB to 876 GiB, size of 4 GiB : PDSCODEDATA_HEAP **/
+ #define RGX_PDSCODEDATA_HEAP_BASE IMG_UINT64_C(0xDA00000000)
+ #define RGX_PDSCODEDATA_HEAP_SIZE RGX_HEAP_SIZE_4GiB
+
+/* 0xDB_0000_0000 - 0xDB_FFFF_FFFF **/
+ /* 876 GiB to 880 GiB, size of 256 MiB (reserved 4GiB) : BRN **/
+ /* HWBRN63142 workaround requires Region Header memory to be at the top
+ of a 16GiB aligned range. This is so when masked with 0x03FFFFFFFF the
+ address will avoid aliasing PB addresses. Start at 879.75GiB. Size of 256MiB. */
+ #define RGX_RGNHDR_BRN_63142_HEAP_BASE IMG_UINT64_C(0xDBF0000000)
+ #define RGX_RGNHDR_BRN_63142_HEAP_SIZE RGX_HEAP_SIZE_256MiB
+
+/* 0xDC_0000_0000 - 0xDF_FFFF_FFFF **/
+ /* 880 GiB to 896 GiB, size of 16 GiB : FREE **/
+
+/* 0xE0_0000_0000 - 0xE0_FFFF_FFFF **/
+ /* 896 GiB to 900 GiB, size of 4 GiB : USCCODE_HEAP **/
+ #define RGX_USCCODE_HEAP_BASE IMG_UINT64_C(0xE000000000)
+ #define RGX_USCCODE_HEAP_SIZE RGX_HEAP_SIZE_4GiB
+
+/* 0xE1_0000_0000 - 0xE1_BFFF_FFFF **/
+ /* 900 GiB to 903 GiB, size of 3 GiB : RESERVED **/
+
+/* 0xE1_C000_000 - 0xE1_FFFF_FFFF **/
+ /* 903 GiB to 904 GiB, reserved 1 GiB, : FIRMWARE_HEAP **/
+
+ /* Firmware heaps defined in rgx_heap_firmware.h as they are not present in
+ application memory contexts, see:
+ RGX_FIRMWARE_RAW_HEAP_BASE
+ RGX_FIRMWARE_RAW_HEAP_SIZE
+ See header for other sub-heaps details
+ */
+
+/* 0xE2_0000_0000 - 0xE3_FFFF_FFFF **/
+ /* 904 GiB to 912 GiB, size of 8 GiB : FREE **/
+
+ /* BRN_65273 VISIBILITY_TEST base 0xE400000000 */
+
+/* 0xE4_0000_0000 - 0xE7_FFFF_FFFF **/
+ /* 912 GiB to 928 GiB, size 16 GiB : TQ3DPARAMETERS_HEAP **/
+ /* Aligned to match RGX_CR_ISP_PIXEL_BASE at 16 GiB */
+ #define RGX_TQ3DPARAMETERS_HEAP_BASE IMG_UINT64_C(0xE400000000)
+ #define RGX_TQ3DPARAMETERS_HEAP_SIZE RGX_HEAP_SIZE_16GiB
+
+/* 0xE8_0000_0000 - 0xE8_FFFF_FFFF **/
+ /* 928 GiB to 932 GiB, size of 4 GiB : FREE **/
+
+/* 0xE9_0000_0000 - 0xE9_3FFF_FFFF **/
+ /* 932 GiB to 933 GiB, size of 1 GiB : VK_CAPT_REPLAY_HEAP **/
+ #define RGX_VK_CAPT_REPLAY_HEAP_BASE IMG_UINT64_C(0xE900000000)
+ #define RGX_VK_CAPT_REPLAY_HEAP_SIZE RGX_HEAP_SIZE_1GiB
+
+/* 0xE9_4000_0000 - 0xE9_FFFF_FFFF **/
+ /* 933 GiB to 936 GiB, size of 3 GiB : FREE **/
+
+/* 0xEA_0000_0000 - 0xEA_0000_0FFF **/
+ /* 936 GiB to 937 GiB, size of min heap size : SIGNALS_HEAP **/
+ /* CDM Signals heap (31 signals less one reserved for Services).
+ * Size 960B rounded up to minimum heap size */
+ #define RGX_SIGNALS_HEAP_BASE IMG_UINT64_C(0xEA00000000)
+ #define RGX_SIGNALS_HEAP_SIZE DEVMEM_HEAP_MINIMUM_SIZE
+
+/* 0xEA_4000_0000 - 0xEA_FFFF_FFFF **/
+ /* 937 GiB to 940 GiB, size of 3 GiB : FREE **/
+
+/* 0xEB_0000_0000 - 0xEB_FFFF_FFFF **/
+ /* 940 GiB to 944 GiB, size of 4 GiB : RESERVED VOLCANIC **/
+
+/* 0xEC_0000_0000 - 0xEC_001F_FFFF **/
+ /* 944 GiB to 945 GiB, size 2 MiB : FBCDC_HEAP **/
+ #define RGX_FBCDC_HEAP_BASE IMG_UINT64_C(0xEC00000000)
+ #define RGX_FBCDC_HEAP_SIZE RGX_HEAP_SIZE_2MiB
+
+/* 0xEC_0020_0000 - 0xED_FFFF_FFFF **/
+ /* 945 GiB to 952 GiB, size of 7 GiB : RESERVED VOLCANIC **/
+
+/* 0xEE_0000_0000 - 0xEE_3FFF_FFFF **/
+ /* 952 GiB to 953 GiB, size of 1 GiB : CMP_MISSION_RMW_HEAP **/
+ #define RGX_CMP_MISSION_RMW_HEAP_BASE IMG_UINT64_C(0xEE00000000)
+ #define RGX_CMP_MISSION_RMW_HEAP_SIZE RGX_HEAP_SIZE_1GiB
+
+/* 0xEE_4000_0000 - 0xEE_FFFF_FFFF **/
+ /* 953 GiB to 956 GiB, size of 3 GiB : RESERVED **/
+
+/* 0xEF_0000_0000 - 0xEF_3FFF_FFFF **/
+ /* 956 GiB to 957 GiB, size of 1 GiB : CMP_SAFETY_RMW_HEAP **/
+ #define RGX_CMP_SAFETY_RMW_HEAP_BASE IMG_UINT64_C(0xEF00000000)
+ #define RGX_CMP_SAFETY_RMW_HEAP_SIZE RGX_HEAP_SIZE_1GiB
+
+/* 0xEF_4000_0000 - 0xEF_FFFF_FFFF **/
+ /* 957 GiB to 960 GiB, size of 3 GiB : RESERVED **/
+
+/* 0xF0_0000_0000 - 0xF0_FFFF_FFFF **/
+ /* 960 GiB to 964 GiB, size of 4 GiB : TEXTURE_STATE_HEAP (36-bit aligned) */
+ #define RGX_TEXTURE_STATE_HEAP_BASE IMG_UINT64_C(0xF000000000)
+ #define RGX_TEXTURE_STATE_HEAP_SIZE RGX_HEAP_SIZE_4GiB
+
+/* 0xF1_0000_0000 - 0xF1_FFFF_FFFF **/
+ /* 964 GiB to 968 GiB, size of 4 GiB : FREE **/
+
+/* 0xF2_0000_0000 - 0xF2_001F_FFFF **/
+ /* 968 GiB to 969 GiB, size of 2 MiB : VISIBILITY_TEST_HEAP **/
+ #define RGX_VISIBILITY_TEST_HEAP_BASE IMG_UINT64_C(0xF200000000)
+ #define RGX_VISIBILITY_TEST_HEAP_SIZE RGX_HEAP_SIZE_2MiB
+
+/* 0xF2_4000_0000 - 0xF2_FFFF_FFFF **/
+ /* 969 GiB to 972 GiB, size of 3 GiB : FREE **/
+
+ /* BRN_65273 MMU_INIA base 0xF800000000 */
+ /* BRN_65273 MMU_INIB base 0xF900000000 */
+
+/* 0xF3_0000_0000 - 0xFF_FFFF_FFFF **/
+ /* 972 GiB to 1024 GiB, size of 52 GiB : FREE **/
+
+
+
+/* 0xFF_FFFF_FFFF ************************************************************/
+
+/* End of RGX Device Virtual Address Space definitions */
+
+#endif /* RGXHEAPCONFIG_H */
+
+/******************************************************************************
+ End of file (rgxheapconfig.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/rogue/rgxheapconfig_65273.h b/drivers/gpu/drm/img-rogue/include/rogue/rgxheapconfig_65273.h
new file mode 100644
index 000000000..31f90fee9
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/rogue/rgxheapconfig_65273.h
@@ -0,0 +1,124 @@
+/*************************************************************************/ /*!
+@File
+@Title RGX Device virtual memory map for BRN_65273.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Memory heaps device specific configuration
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef RGXHEAPCONFIG_65273_H
+#define RGXHEAPCONFIG_65273_H
+
+/*
+ RGX Device Virtual Address Space Definitions
+
+ This file defines the RGX virtual address replacement heaps that are used in
+ in application memory contexts for BRN_65273.
+
+ The heaps defined for BRN_65273 _replace_ the non-BRN equivalents when this
+ BRN WA is active on affected cores. This is different to most other BRNs
+ and hence has been given its own header file for clarity. The SVM_HEAP is
+ also disabled and unavailable when the WA is active. This is reflected
+ in the device connection capability bits returned to user space.
+ NOTE: All regular heaps in rgxheapconfig.h greater than 1GB require
+ a BRN_65273 WA heap.
+
+ Base addresses must have to be a multiple of 4MiB
+ Heaps must not start at 0x0000000000, as this is reserved for internal
+ use within device memory layer.
+ Range comments, those starting in column 0 below are a section heading of
+ sorts and are above the heaps in that range.
+*/
+
+
+/* 0x00_0000_0000 ************************************************************/
+
+/* 0x00_0001_0000 - 0x00_3FFF_FFFF **/
+ /* HWBRN65273 workaround requires TQ memory to start at 64 KiB and use a
+ * unique single 0.99GiB PCE entry. */
+ #define RGX_TQ3DPARAMETERS_BRN_65273_HEAP_BASE IMG_UINT64_C(0x0000010000)
+ #define RGX_TQ3DPARAMETERS_BRN_65273_HEAP_SIZE (RGX_HEAP_SIZE_1GiB - RGX_HEAP_SIZE_64KiB)
+
+/* 0x65_C000_0000 - 0x66_3FFF_FFFF **/
+ /* HWBRN65273 workaround requires General Heap to use a unique PCE entry for each GiB in range */
+ #define RGX_GENERAL_BRN_65273_HEAP_BASE IMG_UINT64_C(0x65C0000000)
+ #define RGX_GENERAL_BRN_65273_HEAP_SIZE RGX_HEAP_SIZE_2GiB
+
+/* 0x73_C000_0000 - 0x74_3FFF_FFFF **/
+ /* HWBRN65273 workaround requires Non4K memory to use a unique PCE entry for each GiB in range */
+ #define RGX_GENERAL_NON4K_BRN_65273_HEAP_BASE IMG_UINT64_C(0x73C0000000)
+ #define RGX_GENERAL_NON4K_BRN_65273_HEAP_SIZE RGX_HEAP_SIZE_2GiB
+
+
+/* 0x80_0000_0000 ************************************************************/
+
+/* 0xA8_0000_0000 - 0xA8_3FFF_FFFF **/
+ /* HWBRN65273 workaround requires PDS memory to use a unique single 1GiB PCE entry. */
+ #define RGX_PDSCODEDATA_BRN_65273_HEAP_BASE IMG_UINT64_C(0xA800000000)
+ #define RGX_PDSCODEDATA_BRN_65273_HEAP_SIZE RGX_HEAP_SIZE_1GiB
+
+/* 0xBA_0000_0000 - 0xBA_3FFF_FFFF **/
+ /* HWBRN65273 workaround requires USC memory to use a unique single 1GiB PCE entry. */
+ #define RGX_USCCODE_BRN_65273_HEAP_BASE IMG_UINT64_C(0xBA00000000)
+ #define RGX_USCCODE_BRN_65273_HEAP_SIZE RGX_HEAP_SIZE_1GiB
+
+
+/* 0xC0_0000_0000 ************************************************************/
+
+/* 0xE4_0000_0000 - 0xE4_001F_FFFF **/
+ /* HWBRN65273 workaround requires USC memory to use a unique single 1GiB PCE entry. */
+ #define RGX_VISIBILITY_TEST_BRN_65273_HEAP_BASE IMG_UINT64_C(0xE400000000)
+ #define RGX_VISIBILITY_TEST_BRN_65273_HEAP_SIZE RGX_HEAP_SIZE_2MiB
+
+/* 0xF8_0000_0000 - 0xF9_FFFF_FFFF **/
+ /* HWBRN65273 workaround requires two Region Header buffers 4GiB apart. */
+ #define RGX_MMU_INIA_BRN_65273_HEAP_BASE IMG_UINT64_C(0xF800000000)
+ #define RGX_MMU_INIA_BRN_65273_HEAP_SIZE RGX_HEAP_SIZE_1GiB
+ #define RGX_MMU_INIB_BRN_65273_HEAP_BASE IMG_UINT64_C(0xF900000000)
+ #define RGX_MMU_INIB_BRN_65273_HEAP_SIZE RGX_HEAP_SIZE_1GiB
+
+
+/* 0xFF_FFFF_FFFF ************************************************************/
+
+/* End of RGX Device Virtual Address Space definitions */
+
+#endif /* RGXHEAPCONFIG_65273_H */
+
+/******************************************************************************
+ End of file (rgxheapconfig_65273.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/rogue/system/rgx_tc/tc_clocks.h b/drivers/gpu/drm/img-rogue/include/rogue/system/rgx_tc/tc_clocks.h
new file mode 100644
index 000000000..431273de0
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/rogue/system/rgx_tc/tc_clocks.h
@@ -0,0 +1,158 @@
+/*************************************************************************/ /*!
+@File
+@Title System Description Header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description This header provides system-specific declarations and macros
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(TC_CLOCKS_H)
+#define TC_CLOCKS_H
+
+/*
+ * The core clock speed is passed through a multiplier depending on the TC
+ * version.
+ *
+ * On TC_ES1: Multiplier = x3, final speed = 270MHz
+ * On TC_ES2: Multiplier = x6, final speed = 540MHz
+ * On TCF5: Multiplier = 1x final speed = 45MHz
+ *
+ *
+ * The base (unmultiplied speed) can be adjusted using a module parameter
+ * called "sys_core_clk_speed", a number in Hz.
+ * As an example:
+ *
+ * PVR_SRVKM_PARAMS="sys_core_clk_speed=60000000" /etc/init.d/rc.pvr start
+ *
+ * would result in a core speed of 60MHz xMultiplier.
+ *
+ *
+ * The memory clock is unmultiplied and can be adjusted using a module
+ * parameter called "sys_mem_clk_speed", this should be the number in Hz for
+ * the memory clock speed.
+ * As an example:
+ *
+ * PVR_SRVKM_PARAMS="sys_mem_clk_speed=100000000" /etc/init.d/rc.pvr start
+ *
+ * would attempt to start the driver with the memory clock speed set to 100MHz.
+ *
+ *
+ * Same applies to the system interface clock speed, "sys_sysif_clk_speed".
+ * Needed for TCF5 but not for TC_ES2/ES1.
+ * As an example:
+ *
+ * PVR_SRVKM_PARAMS="sys_sysif_clk_speed=45000000" /etc/init.d/rc.pvr start
+ *
+ * would attempt to start the driver with the system clock speed set to 45MHz.
+ *
+ *
+ * All parameters can be specified at once, e.g.,
+ * PVR_SRVKM_PARAMS="sys_mem_clk_speed=MEMORY_SPEED sys_core_clk_speed=CORE_SPEED sys_sysif_clk_speed=SYSIF_SPEED" /etc/init.d/rc.pvr start
+ */
+
+#define RGX_TC_SYS_CLOCK_SPEED (25000000) /*< At the moment just used for TCF5 */
+#define RGX_TC_CLOCK_MULTIPLEX (1)
+
+#if defined(TC_APOLLO_TCF5_22_46_54_330)
+ #undef RGX_TC_SYS_CLOCK_SPEED
+ #define RGX_TC_CORE_CLOCK_SPEED (100000000)
+ #define RGX_TC_MEM_CLOCK_SPEED (45000000)
+ #define RGX_TC_SYS_CLOCK_SPEED (45000000)
+#elif defined(TC_APOLLO_TCF5_22_49_21_16) || \
+ defined(TC_APOLLO_TCF5_22_60_22_29) || \
+ defined(TC_APOLLO_TCF5_22_75_22_25)
+ #define RGX_TC_CORE_CLOCK_SPEED (20000000)
+ #define RGX_TC_MEM_CLOCK_SPEED (50000000)
+#elif defined(TC_APOLLO_TCF5_22_67_54_30)
+ #define RGX_TC_CORE_CLOCK_SPEED (100000000)
+ #define RGX_TC_MEM_CLOCK_SPEED (45000000)
+#elif defined(TC_APOLLO_TCF5_22_89_204_18)
+ #define RGX_TC_CORE_CLOCK_SPEED (50000000)
+ #define RGX_TC_MEM_CLOCK_SPEED (25000000)
+#elif defined(TC_APOLLO_TCF5_22_86_104_218)
+ #define RGX_TC_CORE_CLOCK_SPEED (30000000)
+ #define RGX_TC_MEM_CLOCK_SPEED (40000000)
+#elif defined(TC_APOLLO_TCF5_22_88_104_318)
+ #define RGX_TC_CORE_CLOCK_SPEED (28000000)
+ #define RGX_TC_MEM_CLOCK_SPEED (40000000)
+#elif defined(TC_APOLLO_TCF5_22_98_54_230)
+ #define RGX_TC_CORE_CLOCK_SPEED (100000000)
+ #define RGX_TC_MEM_CLOCK_SPEED (40000000)
+#elif defined(TC_APOLLO_TCF5_22_102_54_38)
+ #define RGX_TC_CORE_CLOCK_SPEED (80000000)
+ #define RGX_TC_MEM_CLOCK_SPEED (25000000)
+#elif defined(TC_APOLLO_TCF5_BVNC_NOT_SUPPORTED)
+ /* TC TCF5 (22.*) fallback frequencies */
+ #undef RGX_TC_SYS_CLOCK_SPEED
+ #define RGX_TC_CORE_CLOCK_SPEED (20000000)
+ #define RGX_TC_MEM_CLOCK_SPEED (50000000)
+ #define RGX_TC_SYS_CLOCK_SPEED (25000000)
+#elif defined(TC_APOLLO_TCF5_33_8_22_1)
+ #define RGX_TC_CORE_CLOCK_SPEED (25000000)
+ #define RGX_TC_MEM_CLOCK_SPEED (45000000)
+#elif defined(TC_APOLLO_TCF5_REFERENCE)
+ /* TC TCF5 (Reference bitfile) */
+ #undef RGX_TC_SYS_CLOCK_SPEED
+ #define RGX_TC_CORE_CLOCK_SPEED (50000000)
+ #define RGX_TC_MEM_CLOCK_SPEED (50000000)
+ #define RGX_TC_SYS_CLOCK_SPEED (45000000)
+#elif defined(TC_APOLLO_BONNIE)
+ /* TC Bonnie */
+ #define RGX_TC_CORE_CLOCK_SPEED (18000000)
+ #define RGX_TC_MEM_CLOCK_SPEED (65000000)
+#elif defined(TC_APOLLO_ES2)
+ /* TC ES2 */
+ #define RGX_TC_CORE_CLOCK_SPEED (90000000)
+ #define RGX_TC_MEM_CLOCK_SPEED (104000000)
+#elif defined(TC_ORION)
+ #define RGX_TC_CORE_CLOCK_SPEED (40000000)
+ #define RGX_TC_MEM_CLOCK_SPEED (100000000)
+ #define RGX_TC_SYS_CLOCK_SPEED (25000000)
+#elif defined(TC_APOLLO_TCF5_29_19_52_202)
+ #define RGX_TC_CORE_CLOCK_SPEED (25000000)
+ #define RGX_TC_MEM_CLOCK_SPEED (40000000)
+#elif defined(TC_APOLLO_TCF5_29_18_204_508)
+ #define RGX_TC_CORE_CLOCK_SPEED (15000000)
+ #define RGX_TC_MEM_CLOCK_SPEED (35000000)
+#else
+ /* TC ES1 */
+ #define RGX_TC_CORE_CLOCK_SPEED (90000000)
+ #define RGX_TC_MEM_CLOCK_SPEED (65000000)
+#endif
+
+#endif /* if !defined(TC_CLOCKS_H) */
diff --git a/drivers/gpu/drm/img-rogue/include/services_km.h b/drivers/gpu/drm/img-rogue/include/services_km.h
new file mode 100644
index 000000000..91ee3b2f0
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/services_km.h
@@ -0,0 +1,180 @@
+/*************************************************************************/ /*!
+@File
+@Title Services API Kernel mode Header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Exported services API details
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef SERVICES_KM_H
+#define SERVICES_KM_H
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+#include "virt_validation_defs.h"
+#endif
+
+/*! 4k page size definition */
+#define PVRSRV_4K_PAGE_SIZE 4096UL /*!< Size of a 4K Page */
+#define PVRSRV_4K_PAGE_SIZE_ALIGNSHIFT 12 /*!< Amount to shift an address by so that
+ it is always page-aligned */
+/*! 16k page size definition */
+#define PVRSRV_16K_PAGE_SIZE 16384UL /*!< Size of a 16K Page */
+#define PVRSRV_16K_PAGE_SIZE_ALIGNSHIFT 14 /*!< Amount to shift an address by so that
+ it is always page-aligned */
+/*! 64k page size definition */
+#define PVRSRV_64K_PAGE_SIZE 65536UL /*!< Size of a 64K Page */
+#define PVRSRV_64K_PAGE_SIZE_ALIGNSHIFT 16 /*!< Amount to shift an address by so that
+ it is always page-aligned */
+/*! 256k page size definition */
+#define PVRSRV_256K_PAGE_SIZE 262144UL /*!< Size of a 256K Page */
+#define PVRSRV_256K_PAGE_SIZE_ALIGNSHIFT 18 /*!< Amount to shift an address by so that
+ it is always page-aligned */
+/*! 1MB page size definition */
+#define PVRSRV_1M_PAGE_SIZE 1048576UL /*!< Size of a 1M Page */
+#define PVRSRV_1M_PAGE_SIZE_ALIGNSHIFT 20 /*!< Amount to shift an address by so that
+ it is always page-aligned */
+/*! 2MB page size definition */
+#define PVRSRV_2M_PAGE_SIZE 2097152UL /*!< Size of a 2M Page */
+#define PVRSRV_2M_PAGE_SIZE_ALIGNSHIFT 21 /*!< Amount to shift an address by so that
+ it is always page-aligned */
+
+/*!
+ * @AddToGroup SRVConnectInterfaces
+ * @{
+ */
+
+#ifndef PVRSRV_DEV_CONNECTION_TYPEDEF
+#define PVRSRV_DEV_CONNECTION_TYPEDEF
+/*!
+ * Forward declaration (look on connection.h)
+ */
+typedef struct PVRSRV_DEV_CONNECTION_TAG PVRSRV_DEV_CONNECTION;
+#endif
+
+/*!
+ * @Anchor SRV_FLAGS
+ * @Name SRV_FLAGS: Services connection flags
+ * Allows to define per-client policy for Services.
+ * @{
+ */
+
+/*
+ * Use of the 32-bit connection flags mask
+ * ( X = taken/in use, - = available/unused )
+ *
+ * 31 27 20 6 4 0
+ * | | | | | |
+ * X---XXXXXXXX-------------XXX----
+ */
+
+#define SRV_NO_HWPERF_CLIENT_STREAM (1UL << 4) /*!< Don't create HWPerf for this connection */
+#define SRV_FLAGS_CLIENT_64BIT_COMPAT (1UL << 5) /*!< This flags gets set if the client is 64 Bit compatible. */
+#define SRV_FLAGS_CLIENT_SLR_DISABLED (1UL << 6) /*!< This flag is set if the client does not want Sync Lockup Recovery (SLR) enabled. */
+#define SRV_FLAGS_PDUMPCTRL (1UL << 31) /*!< PDump Ctrl client flag */
+
+/*! @} SRV_FLAGS */
+
+/*! @} End of SRVConnectInterfaces */
+
+/*
+ * Bits 20 - 27 are used to pass information needed for validation
+ * of the GPU Virtualisation Validation mechanism. In particular:
+ *
+ * Bits:
+ * [20 - 22]: OSid of the memory region that will be used for allocations
+ * [23 - 25]: OSid that will be emitted by the Firmware for all memory accesses
+ * regarding that memory context.
+ * [26]: If the AXI Protection register will be set to secure for that OSid
+ * [27]: If the Emulator Wrapper Register checking for protection violation
+ * will be set to secure for that OSid
+ */
+
+#define VIRTVAL_FLAG_OSID_SHIFT (20)
+#define SRV_VIRTVAL_FLAG_OSID_MASK (7U << VIRTVAL_FLAG_OSID_SHIFT)
+
+#define VIRTVAL_FLAG_OSIDREG_SHIFT (23)
+#define SRV_VIRTVAL_FLAG_OSIDREG_MASK (7U << VIRTVAL_FLAG_OSIDREG_SHIFT)
+
+#define VIRTVAL_FLAG_AXIPREG_SHIFT (26)
+#define SRV_VIRTVAL_FLAG_AXIPREG_MASK (1U << VIRTVAL_FLAG_AXIPREG_SHIFT)
+
+#define VIRTVAL_FLAG_AXIPTD_SHIFT (27)
+#define SRV_VIRTVAL_FLAG_AXIPTD_MASK (1U << VIRTVAL_FLAG_AXIPTD_SHIFT)
+
+
+/* Size of pointer on a 64 bit machine */
+#define POINTER_SIZE_64BIT (8U)
+
+
+/*
+ Pdump flags which are accessible to Services clients
+*/
+#define PDUMP_NONE 0x00000000U /*puiAddrUFO.ui32Addr))
+
+/* Maximum number of sync checkpoints the firmware supports in one fence */
+#define MAX_SYNC_CHECKPOINTS_PER_FENCE 32U
+
+/*!
+ * Define to be used with SyncCheckpointAlloc() to indicate a checkpoint which
+ * represents a foreign sync point or collection of foreign sync points.
+ */
+#define SYNC_CHECKPOINT_FOREIGN_CHECKPOINT ((PVRSRV_TIMELINE) - 2U)
+
+#endif /* SYNC_CHECKPOINT_EXTERNAL_H */
diff --git a/drivers/gpu/drm/img-rogue/include/sync_prim_internal.h b/drivers/gpu/drm/img-rogue/include/sync_prim_internal.h
new file mode 100644
index 000000000..77164c235
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/sync_prim_internal.h
@@ -0,0 +1,84 @@
+/*************************************************************************/ /*!
+@File
+@Title Services internal synchronisation typedef header
+@Description Defines synchronisation types that are used internally
+ only
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef SYNC_INTERNAL_H
+#define SYNC_INTERNAL_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include
+
+/* These are included here as the typedefs are required
+ * internally.
+ */
+
+typedef struct SYNC_PRIM_CONTEXT_TAG *PSYNC_PRIM_CONTEXT;
+typedef struct PVRSRV_CLIENT_SYNC_PRIM_TAG
+{
+ volatile uint32_t __iomem *pui32LinAddr; /*!< User pointer to the primitive */
+} PVRSRV_CLIENT_SYNC_PRIM;
+
+/*!
+ * Bundled information for a sync prim operation
+ *
+ * Structure: #PVRSRV_CLIENT_SYNC_PRIM_OP
+ * Typedef: ::PVRSRV_CLIENT_SYNC_PRIM_OP
+ */
+typedef struct PVRSRV_CLIENT_SYNC_PRIM_OP_TAG
+{
+ #define PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK (1U << 0)
+ #define PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE (1U << 1)
+ #define PVRSRV_CLIENT_SYNC_PRIM_OP_UNFENCED_UPDATE (PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE | (1U<<2))
+ uint32_t ui32Flags; /*!< Operation flags: PVRSRV_CLIENT_SYNC_PRIM_OP_XXX */
+ PVRSRV_CLIENT_SYNC_PRIM *psSync; /*!< Pointer to the client sync primitive */
+ uint32_t ui32FenceValue; /*!< The Fence value (only used if PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK is set) */
+ uint32_t ui32UpdateValue; /*!< The Update value (only used if PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE is set) */
+} PVRSRV_CLIENT_SYNC_PRIM_OP;
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* SYNC_INTERNAL_H */
diff --git a/drivers/gpu/drm/img-rogue/include/system/rgx_tc/apollo_regs.h b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/apollo_regs.h
new file mode 100644
index 000000000..4081e2123
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/apollo_regs.h
@@ -0,0 +1,108 @@
+/*************************************************************************/ /*!
+@File
+@Title System Description Header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description This header provides system-specific declarations and macros
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(APOLLO_REGS_H)
+#define APOLLO_REGS_H
+
+#include "tc_clocks.h"
+
+/* TC TCF5 */
+#define TC5_SYS_APOLLO_REG_PCI_BASENUM (1)
+#define TC5_SYS_APOLLO_REG_PDP2_OFFSET (0x800000)
+#define TC5_SYS_APOLLO_REG_PDP2_SIZE (0x7C4)
+
+#define TC5_SYS_APOLLO_REG_PDP2_FBDC_OFFSET (0xA00000)
+#define TC5_SYS_APOLLO_REG_PDP2_FBDC_SIZE (0x14)
+
+#define TC5_SYS_APOLLO_REG_HDMI_OFFSET (0xC00000)
+#define TC5_SYS_APOLLO_REG_HDMI_SIZE (0x1C)
+
+/* TC ES2 */
+#define TCF_TEMP_SENSOR_SPI_OFFSET 0xe
+#define TCF_TEMP_SENSOR_TO_C(raw) (((raw) * 248 / 4096) - 54)
+
+/* Number of bytes that are broken */
+#define SYS_DEV_MEM_BROKEN_BYTES (1024 * 1024)
+#define SYS_DEV_MEM_REGION_SIZE (0x40000000 - SYS_DEV_MEM_BROKEN_BYTES)
+
+/* Apollo reg on base register 0 */
+#define SYS_APOLLO_REG_PCI_BASENUM (0)
+#define SYS_APOLLO_REG_REGION_SIZE (0x00010000)
+
+#define SYS_APOLLO_REG_SYS_OFFSET (0x0000)
+#define SYS_APOLLO_REG_SYS_SIZE (0x0400)
+
+#define SYS_APOLLO_REG_PLL_OFFSET (0x1000)
+#define SYS_APOLLO_REG_PLL_SIZE (0x0400)
+
+#define SYS_APOLLO_REG_HOST_OFFSET (0x4050)
+#define SYS_APOLLO_REG_HOST_SIZE (0x0014)
+
+#define SYS_APOLLO_REG_PDP1_OFFSET (0xC000)
+#define SYS_APOLLO_REG_PDP1_SIZE (0x2000)
+
+/* Offsets for flashing Apollo PROMs from base 0 */
+#define APOLLO_FLASH_STAT_OFFSET (0x4058)
+#define APOLLO_FLASH_DATA_WRITE_OFFSET (0x4050)
+#define APOLLO_FLASH_RESET_OFFSET (0x4060)
+
+#define APOLLO_FLASH_FIFO_STATUS_MASK (0xF)
+#define APOLLO_FLASH_FIFO_STATUS_SHIFT (0)
+#define APOLLO_FLASH_PROGRAM_STATUS_MASK (0xF)
+#define APOLLO_FLASH_PROGRAM_STATUS_SHIFT (16)
+
+#define APOLLO_FLASH_PROG_COMPLETE_BIT (0x1)
+#define APOLLO_FLASH_PROG_PROGRESS_BIT (0x2)
+#define APOLLO_FLASH_PROG_FAILED_BIT (0x4)
+#define APOLLO_FLASH_INV_FILETYPE_BIT (0x8)
+
+#define APOLLO_FLASH_FIFO_SIZE (8)
+
+/* RGX reg on base register 1 */
+#define SYS_RGX_REG_PCI_BASENUM (1)
+#define SYS_RGX_REG_REGION_SIZE (0x7FFFF)
+
+/* Device memory (including HP mapping) on base register 2 */
+#define SYS_DEV_MEM_PCI_BASENUM (2)
+
+#endif /* APOLLO_REGS_H */
diff --git a/drivers/gpu/drm/img-rogue/include/system/rgx_tc/bonnie_tcf.h b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/bonnie_tcf.h
new file mode 100644
index 000000000..fc87ec790
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/bonnie_tcf.h
@@ -0,0 +1,68 @@
+/*************************************************************************/ /*!
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/* bonnie_tcf.h - Bonnie TCF register definitions */
+
+/* tab size 4 */
+
+#ifndef BONNIE_TCF_DEFS_H
+#define BONNIE_TCF_DEFS_H
+
+#define BONNIE_TCF_OFFSET_BONNIETC_REGBANK 0x00000000
+#define BONNIE_TCF_OFFSET_TC_IFACE_COUNTERS 0x00004000
+#define BONNIE_TCF_OFFSET_TC_TEST_MODULE_IMGV4_RTM_TOP 0x00008000
+#define BONNIE_TCF_OFFSET_TC_TEST_MODULE_TCF_SCRATCH_PAD_SECN 0x0000C000
+#define BONNIE_TCF_OFFSET_TC_TEST_MODULE_TCF_SCRATCH_PAD_DBG 0x00010000
+#define BONNIE_TCF_OFFSET_MULTI_CLK_ALIGN 0x00014000
+#define BONNIE_TCF_OFFSET_ALIGN_DATA_TX 0x00018000
+#define BONNIE_TCF_OFFSET_SAI_RX_1 0x0001C000
+#define BONNIE_TCF_OFFSET_SAI_RX_SDR 0x00040000
+#define BONNIE_TCF_OFFSET_SAI_TX_1 0x00044000
+#define BONNIE_TCF_OFFSET_SAI_TX_SDR 0x00068000
+
+#define BONNIE_TCF_OFFSET_SAI_RX_DELTA 0x00004000
+#define BONNIE_TCF_OFFSET_SAI_TX_DELTA 0x00004000
+
+#define BONNIE_TCF_OFFSET_SAI_CLK_TAPS 0x0000000C
+#define BONNIE_TCF_OFFSET_SAI_EYES 0x00000010
+#define BONNIE_TCF_OFFSET_SAI_TRAIN_ACK 0x00000018
+
+
+#endif /* BONNIE_TCF_DEFS_H */
diff --git a/drivers/gpu/drm/img-rogue/include/system/rgx_tc/odin_defs.h b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/odin_defs.h
new file mode 100644
index 000000000..6234887a1
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/odin_defs.h
@@ -0,0 +1,326 @@
+/****************************************************************************
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Odin Memory Map - View from PCIe
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+****************************************************************************/
+
+#ifndef _ODIN_DEFS_H_
+#define _ODIN_DEFS_H_
+
+/* These defines have not been autogenerated */
+
+#define PCI_VENDOR_ID_ODIN (0x1AEE)
+#define DEVICE_ID_ODIN (0x1010)
+#define DEVICE_ID_TBA (0x1CF2)
+
+/* PCI BAR 0 contains the PDP regs and the Odin system regs */
+#define ODN_SYS_BAR 0
+#define ODN_SYS_REGION_SIZE 0x000800000 /* 8MB */
+
+#define ODN_SYS_REGS_OFFSET 0
+#define ODN_SYS_REGS_SIZE 0x000400000 /* 4MB */
+
+#define ODN_PDP_REGS_OFFSET 0x000440000
+#define ODN_PDP_REGS_SIZE 0x000040000 /* 256k */
+
+#define ODN_PDP2_REGS_OFFSET 0x000480000
+#define ODN_PDP2_REGS_SIZE 0x000040000 /* 256k */
+
+#define ODN_PDP2_PFIM_OFFSET 0x000500000
+#define ODN_PDP2_PFIM_SIZE 0x000040000 /* 256k */
+
+#define ODIN_DMA_REGS_OFFSET 0x0004C0000
+#define ODIN_DMA_REGS_SIZE 0x000040000 /* 256k */
+
+#define ODIN_DMA_CHAN_REGS_SIZE 0x000001000 /* 4k */
+
+/* PCI BAR 2 contains the Device Under Test SOCIF 64MB region */
+#define ODN_DUT_SOCIF_BAR 2
+#define ODN_DUT_SOCIF_OFFSET 0x000000000
+#define ODN_DUT_SOCIF_SIZE 0x004000000 /* 64MB */
+
+/* PCI BAR 4 contains the on-board 1GB DDR memory */
+#define ODN_DDR_BAR 4
+#define ODN_DDR_MEM_OFFSET 0x000000000
+#define ODN_DDR_MEM_SIZE 0x040000000 /* 1GB */
+
+/* Odin system register banks */
+#define ODN_REG_BANK_CORE 0x00000
+#define ODN_REG_BANK_TCF_SPI_MASTER 0x02000
+#define ODN_REG_BANK_ODN_CLK_BLK 0x0A000
+#define ODN_REG_BANK_ODN_MCU_COMMUNICATOR 0x0C000
+#define ODN_REG_BANK_DB_TYPE_ID 0x0C200
+#define ODN_REG_BANK_DB_TYPE_ID_TYPE_TCFVUOCTA 0x000000C6U
+#define ODN_REG_BANK_DB_TYPE_ID_TYPE_MASK 0x000000C0U
+#define ODN_REG_BANK_DB_TYPE_ID_TYPE_SHIFT 0x6
+#define ODN_REG_BANK_ODN_I2C 0x0E000
+#define ODN_REG_BANK_MULTI_CLK_ALIGN 0x20000
+#define ODN_REG_BANK_ALIGN_DATA_TX 0x22000
+#define ODN_REG_BANK_SAI_RX_DDR_0 0x24000
+#define ODN_REG_BANK_SAI_RX_DDR(n) (ODN_REG_BANK_SAI_RX_DDR_0 + (0x02000*n))
+#define ODN_REG_BANK_SAI_TX_DDR_0 0x3A000
+#define ODN_REG_BANK_SAI_TX_DDR(n) (ODN_REG_BANK_SAI_TX_DDR_0 + (0x02000*n))
+#define ODN_REG_BANK_SAI_TX_SDR 0x4E000
+
+/* Odin SPI regs */
+#define ODN_SPI_MST_ADDR_RDNWR 0x0000
+#define ODN_SPI_MST_WDATA 0x0004
+#define ODN_SPI_MST_RDATA 0x0008
+#define ODN_SPI_MST_STATUS 0x000C
+#define ODN_SPI_MST_GO 0x0010
+
+
+/*
+ Odin CLK regs - the odn_clk_blk module defs are not auto generated
+ */
+#define ODN_PDP_P_CLK_OUT_DIVIDER_REG1 0x620
+#define ODN_PDP_PCLK_ODIV1_LO_TIME_MASK 0x0000003FU
+#define ODN_PDP_PCLK_ODIV1_LO_TIME_SHIFT 0
+#define ODN_PDP_PCLK_ODIV1_HI_TIME_MASK 0x00000FC0U
+#define ODN_PDP_PCLK_ODIV1_HI_TIME_SHIFT 6
+
+#define ODN_PDP_P_CLK_OUT_DIVIDER_REG2 0x624
+#define ODN_PDP_PCLK_ODIV2_NOCOUNT_MASK 0x00000040U
+#define ODN_PDP_PCLK_ODIV2_NOCOUNT_SHIFT 6
+#define ODN_PDP_PCLK_ODIV2_EDGE_MASK 0x00000080U
+#define ODN_PDP_PCLK_ODIV2_EDGE_SHIFT 7
+
+#define ODN_PDP_P_CLK_OUT_DIVIDER_REG3 0x61C
+
+#define ODN_PDP_M_CLK_OUT_DIVIDER_REG1 0x628
+#define ODN_PDP_MCLK_ODIV1_LO_TIME_MASK 0x0000003FU
+#define ODN_PDP_MCLK_ODIV1_LO_TIME_SHIFT 0
+#define ODN_PDP_MCLK_ODIV1_HI_TIME_MASK 0x00000FC0U
+#define ODN_PDP_MCLK_ODIV1_HI_TIME_SHIFT 6
+
+#define ODN_PDP_M_CLK_OUT_DIVIDER_REG2 0x62C
+#define ODN_PDP_MCLK_ODIV2_NOCOUNT_MASK 0x00000040U
+#define ODN_PDP_MCLK_ODIV2_NOCOUNT_SHIFT 6
+#define ODN_PDP_MCLK_ODIV2_EDGE_MASK 0x00000080U
+#define ODN_PDP_MCLK_ODIV2_EDGE_SHIFT 7
+
+#define ODN_PDP_P_CLK_MULTIPLIER_REG1 0x650
+#define ODN_PDP_PCLK_MUL1_LO_TIME_MASK 0x0000003FU
+#define ODN_PDP_PCLK_MUL1_LO_TIME_SHIFT 0
+#define ODN_PDP_PCLK_MUL1_HI_TIME_MASK 0x00000FC0U
+#define ODN_PDP_PCLK_MUL1_HI_TIME_SHIFT 6
+
+#define ODN_PDP_P_CLK_MULTIPLIER_REG2 0x654
+#define ODN_PDP_PCLK_MUL2_NOCOUNT_MASK 0x00000040U
+#define ODN_PDP_PCLK_MUL2_NOCOUNT_SHIFT 6
+#define ODN_PDP_PCLK_MUL2_EDGE_MASK 0x00000080U
+#define ODN_PDP_PCLK_MUL2_EDGE_SHIFT 7
+
+#define ODN_PDP_P_CLK_MULTIPLIER_REG3 0x64C
+
+#define ODN_PDP_P_CLK_IN_DIVIDER_REG 0x658
+#define ODN_PDP_PCLK_IDIV_LO_TIME_MASK 0x0000003FU
+#define ODN_PDP_PCLK_IDIV_LO_TIME_SHIFT 0
+#define ODN_PDP_PCLK_IDIV_HI_TIME_MASK 0x00000FC0U
+#define ODN_PDP_PCLK_IDIV_HI_TIME_SHIFT 6
+#define ODN_PDP_PCLK_IDIV_NOCOUNT_MASK 0x00001000U
+#define ODN_PDP_PCLK_IDIV_NOCOUNT_SHIFT 12
+#define ODN_PDP_PCLK_IDIV_EDGE_MASK 0x00002000U
+#define ODN_PDP_PCLK_IDIV_EDGE_SHIFT 13
+
+/*
+ * DUT core clock input divider, multiplier and out divider.
+ */
+#define ODN_DUT_CORE_CLK_OUT_DIVIDER1 (0x0028)
+#define ODN_DUT_CORE_CLK_OUT_DIVIDER1_HI_TIME_MASK (0x00000FC0U)
+#define ODN_DUT_CORE_CLK_OUT_DIVIDER1_HI_TIME_SHIFT (6)
+#define ODN_DUT_CORE_CLK_OUT_DIVIDER1_LO_TIME_MASK (0x0000003FU)
+#define ODN_DUT_CORE_CLK_OUT_DIVIDER1_LO_TIME_SHIFT (0)
+
+#define ODN_DUT_CORE_CLK_OUT_DIVIDER2 (0x002C)
+#define ODN_DUT_CORE_CLK_OUT_DIVIDER2_EDGE_MASK (0x00000080U)
+#define ODN_DUT_CORE_CLK_OUT_DIVIDER2_EDGE_SHIFT (7)
+#define ODN_DUT_CORE_CLK_OUT_DIVIDER2_NOCOUNT_MASK (0x00000040U)
+#define ODN_DUT_CORE_CLK_OUT_DIVIDER2_NOCOUNT_SHIFT (6)
+
+#define ODN_DUT_CORE_CLK_MULTIPLIER1 (0x0050)
+#define ODN_DUT_CORE_CLK_MULTIPLIER1_HI_TIME_MASK (0x00000FC0U)
+#define ODN_DUT_CORE_CLK_MULTIPLIER1_HI_TIME_SHIFT (6)
+#define ODN_DUT_CORE_CLK_MULTIPLIER1_LO_TIME_MASK (0x0000003FU)
+#define ODN_DUT_CORE_CLK_MULTIPLIER1_LO_TIME_SHIFT (0)
+
+#define ODN_DUT_CORE_CLK_MULTIPLIER2 (0x0054)
+#define ODN_DUT_CORE_CLK_MULTIPLIER2_FRAC_MASK (0x00007000U)
+#define ODN_DUT_CORE_CLK_MULTIPLIER2_FRAC_SHIFT (12)
+#define ODN_DUT_CORE_CLK_MULTIPLIER2_FRAC_EN_MASK (0x00000800U)
+#define ODN_DUT_CORE_CLK_MULTIPLIER2_FRAC_EN_SHIFT (11)
+#define ODN_DUT_CORE_CLK_MULTIPLIER2_EDGE_MASK (0x00000080U)
+#define ODN_DUT_CORE_CLK_MULTIPLIER2_EDGE_SHIFT (7)
+#define ODN_DUT_CORE_CLK_MULTIPLIER2_NOCOUNT_MASK (0x00000040U)
+#define ODN_DUT_CORE_CLK_MULTIPLIER2_NOCOUNT_SHIFT (6)
+
+#define ODN_DUT_CORE_CLK_IN_DIVIDER1 (0x0058)
+#define ODN_DUT_CORE_CLK_IN_DIVIDER1_EDGE_MASK (0x00002000U)
+#define ODN_DUT_CORE_CLK_IN_DIVIDER1_EDGE_SHIFT (13)
+#define ODN_DUT_CORE_CLK_IN_DIVIDER1_NOCOUNT_MASK (0x00001000U)
+#define ODN_DUT_CORE_CLK_IN_DIVIDER1_NOCOUNT_SHIFT (12)
+#define ODN_DUT_CORE_CLK_IN_DIVIDER1_HI_TIME_MASK (0x00000FC0U)
+#define ODN_DUT_CORE_CLK_IN_DIVIDER1_HI_TIME_SHIFT (6)
+#define ODN_DUT_CORE_CLK_IN_DIVIDER1_LO_TIME_MASK (0x0000003FU)
+#define ODN_DUT_CORE_CLK_IN_DIVIDER1_LO_TIME_SHIFT (0)
+
+/*
+ * DUT interface clock input divider, multiplier and out divider.
+ */
+#define ODN_DUT_IFACE_CLK_OUT_DIVIDER1 (0x0220)
+#define ODN_DUT_IFACE_CLK_OUT_DIVIDER1_HI_TIME_MASK (0x00000FC0U)
+#define ODN_DUT_IFACE_CLK_OUT_DIVIDER1_HI_TIME_SHIFT (6)
+#define ODN_DUT_IFACE_CLK_OUT_DIVIDER1_LO_TIME_MASK (0x0000003FU)
+#define ODN_DUT_IFACE_CLK_OUT_DIVIDER1_LO_TIME_SHIFT (0)
+
+#define ODN_DUT_IFACE_CLK_OUT_DIVIDER2 (0x0224)
+#define ODN_DUT_IFACE_CLK_OUT_DIVIDER2_EDGE_MASK (0x00000080U)
+#define ODN_DUT_IFACE_CLK_OUT_DIVIDER2_EDGE_SHIFT (7)
+#define ODN_DUT_IFACE_CLK_OUT_DIVIDER2_NOCOUNT_MASK (0x00000040U)
+#define ODN_DUT_IFACE_CLK_OUT_DIVIDER2_NOCOUNT_SHIFT (6)
+
+#define ODN_DUT_IFACE_CLK_MULTIPLIER1 (0x0250)
+#define ODN_DUT_IFACE_CLK_MULTIPLIER1_HI_TIME_MASK (0x00000FC0U)
+#define ODN_DUT_IFACE_CLK_MULTIPLIER1_HI_TIME_SHIFT (6)
+#define ODN_DUT_IFACE_CLK_MULTIPLIER1_LO_TIME_MASK (0x0000003FU)
+#define ODN_DUT_IFACE_CLK_MULTIPLIER1_LO_TIME_SHIFT (0)
+
+#define ODN_DUT_IFACE_CLK_MULTIPLIER2 (0x0254)
+#define ODN_DUT_IFACE_CLK_MULTIPLIER2_FRAC_MASK (0x00007000U)
+#define ODN_DUT_IFACE_CLK_MULTIPLIER2_FRAC_SHIFT (12)
+#define ODN_DUT_IFACE_CLK_MULTIPLIER2_FRAC_EN_MASK (0x00000800U)
+#define ODN_DUT_IFACE_CLK_MULTIPLIER2_FRAC_EN_SHIFT (11)
+#define ODN_DUT_IFACE_CLK_MULTIPLIER2_EDGE_MASK (0x00000080U)
+#define ODN_DUT_IFACE_CLK_MULTIPLIER2_EDGE_SHIFT (7)
+#define ODN_DUT_IFACE_CLK_MULTIPLIER2_NOCOUNT_MASK (0x00000040U)
+#define ODN_DUT_IFACE_CLK_MULTIPLIER2_NOCOUNT_SHIFT (6)
+
+#define ODN_DUT_IFACE_CLK_IN_DIVIDER1 (0x0258)
+#define ODN_DUT_IFACE_CLK_IN_DIVIDER1_EDGE_MASK (0x00002000U)
+#define ODN_DUT_IFACE_CLK_IN_DIVIDER1_EDGE_SHIFT (13)
+#define ODN_DUT_IFACE_CLK_IN_DIVIDER1_NOCOUNT_MASK (0x00001000U)
+#define ODN_DUT_IFACE_CLK_IN_DIVIDER1_NOCOUNT_SHIFT (12)
+#define ODN_DUT_IFACE_CLK_IN_DIVIDER1_HI_TIME_MASK (0x00000FC0U)
+#define ODN_DUT_IFACE_CLK_IN_DIVIDER1_HI_TIME_SHIFT (6)
+#define ODN_DUT_IFACE_CLK_IN_DIVIDER1_LO_TIME_MASK (0x0000003FU)
+#define ODN_DUT_IFACE_CLK_IN_DIVIDER1_LO_TIME_SHIFT (0)
+
+
+/*
+ * Min max values from Xilinx Virtex7 data sheet DS183, for speed grade 2
+ * All in Hz
+ */
+#define ODN_INPUT_CLOCK_SPEED (100000000U)
+#define ODN_INPUT_CLOCK_SPEED_MIN (10000000U)
+#define ODN_INPUT_CLOCK_SPEED_MAX (933000000U)
+#define ODN_OUTPUT_CLOCK_SPEED_MIN (4690000U)
+#define ODN_OUTPUT_CLOCK_SPEED_MAX (933000000U)
+#define ODN_VCO_MIN (600000000U)
+#define ODN_VCO_MAX (1440000000U)
+#define ODN_PFD_MIN (10000000U)
+#define ODN_PFD_MAX (500000000U)
+
+/*
+ * Max values that can be set in DRP registers
+ */
+#define ODN_OREG_VALUE_MAX (126.875f)
+#define ODN_MREG_VALUE_MAX (126.875f)
+#define ODN_DREG_VALUE_MAX (126U)
+
+
+#define ODN_MMCM_LOCK_STATUS_DUT_CORE (0x00000001U)
+#define ODN_MMCM_LOCK_STATUS_DUT_IF (0x00000002U)
+#define ODN_MMCM_LOCK_STATUS_PDPP (0x00000008U)
+
+/*
+ Odin interrupt flags
+*/
+#define ODN_INTERRUPT_ENABLE_PDP1 (1 << ODN_INTERRUPT_ENABLE_PDP1_SHIFT)
+#define ODN_INTERRUPT_ENABLE_PDP2 (1 << ODN_INTERRUPT_ENABLE_PDP2_SHIFT)
+#define ODN_INTERRUPT_ENABLE_DUT (1 << ODN_INTERRUPT_ENABLE_DUT_SHIFT)
+#define ODN_INTERRUPT_STATUS_PDP1 (1 << ODN_INTERRUPT_STATUS_PDP1_SHIFT)
+#define ODN_INTERRUPT_STATUS_PDP2 (1 << ODN_INTERRUPT_STATUS_PDP2_SHIFT)
+#define ODN_INTERRUPT_STATUS_DUT (1 << ODN_INTERRUPT_STATUS_DUT_SHIFT)
+#define ODN_INTERRUPT_CLEAR_PDP1 (1 << ODN_INTERRUPT_CLR_PDP1_SHIFT)
+#define ODN_INTERRUPT_CLEAR_PDP2 (1 << ODN_INTERRUPT_CLR_PDP2_SHIFT)
+#define ODN_INTERRUPT_CLEAR_DUT (1 << ODN_INTERRUPT_CLR_DUT_SHIFT)
+
+#define ODN_INTERRUPT_ENABLE_CDMA (1 << ODN_INTERRUPT_ENABLE_CDMA_SHIFT)
+#define ODN_INTERRUPT_STATUS_CDMA (1 << ODN_INTERRUPT_STATUS_CDMA_SHIFT)
+#define ODN_INTERRUPT_CLEAR_CDMA (1 << ODN_INTERRUPT_CLR_CDMA_SHIFT)
+
+#define ODN_INTERRUPT_ENABLE_CDMA2 (1 << (ODN_INTERRUPT_ENABLE_CDMA_SHIFT + 1))
+#define ODN_INTERRUPT_STATUS_CDMA2 (1 << (ODN_INTERRUPT_STATUS_CDMA_SHIFT + 1))
+#define ODN_INTERRUPT_CLEAR_CDMA2 (1 << (ODN_INTERRUPT_CLR_CDMA_SHIFT + 1))
+
+/*
+ Other defines
+*/
+#define ODN_STREAM_OFF 0
+#define ODN_STREAM_ON 1
+#define ODN_SYNC_GEN_DISABLE 0
+#define ODN_SYNC_GEN_ENABLE 1
+#define ODN_INTERLACE_DISABLE 0
+#define ODN_INTERLACE_ENABLE 1
+#define ODN_PIXEL_CLOCK_INVERTED 1
+#define ODN_HSYNC_POLARITY_ACTIVE_HIGH 1
+
+#define ODN_PDP_INTCLR_ALL 0x000FFFFFU
+#define ODN_PDP_INTSTAT_ALL_OURUN_MASK 0x000FFFF0U
+
+/*
+ DMA defs
+*/
+#define ODN_CDMA_ADDR_WIDTH 35
+#define ODN_DMA_HW_DESC_HEAP_SIZE 0x100000
+#define ODN_DMA_CHAN_RX 0
+#define ODN_DMA_CHAN_TX 1
+
+#define ODIN_DMA_TX_CHAN_NAME "tx"
+#define ODIN_DMA_RX_CHAN_NAME "rx"
+
+/*
+ FBC defs
+*/
+#define ODIN_PFIM_RELNUM (005U)
+
+#endif /* _ODIN_DEFS_H_ */
+
+/*****************************************************************************
+ End of file (odn_defs.h)
+*****************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/system/rgx_tc/odin_pdp_regs.h b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/odin_pdp_regs.h
new file mode 100644
index 000000000..da47a253d
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/odin_pdp_regs.h
@@ -0,0 +1,8540 @@
+/*************************************************************************/ /*!
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/* tab size 4 */
+
+#ifndef ODN_PDP_REGS_H
+#define ODN_PDP_REGS_H
+
+/* Odin-PDP hardware register definitions */
+
+
+#define ODN_PDP_GRPH1SURF_OFFSET (0x0000)
+
+/* PDP, GRPH1SURF, GRPH1PIXFMT
+*/
+#define ODN_PDP_GRPH1SURF_GRPH1PIXFMT_MASK (0xF8000000)
+#define ODN_PDP_GRPH1SURF_GRPH1PIXFMT_LSBMASK (0x0000001F)
+#define ODN_PDP_GRPH1SURF_GRPH1PIXFMT_SHIFT (27)
+#define ODN_PDP_GRPH1SURF_GRPH1PIXFMT_LENGTH (5)
+#define ODN_PDP_GRPH1SURF_GRPH1PIXFMT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1SURF, GRPH1USEGAMMA
+*/
+#define ODN_PDP_GRPH1SURF_GRPH1USEGAMMA_MASK (0x04000000)
+#define ODN_PDP_GRPH1SURF_GRPH1USEGAMMA_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH1SURF_GRPH1USEGAMMA_SHIFT (26)
+#define ODN_PDP_GRPH1SURF_GRPH1USEGAMMA_LENGTH (1)
+#define ODN_PDP_GRPH1SURF_GRPH1USEGAMMA_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1SURF, GRPH1USECSC
+*/
+#define ODN_PDP_GRPH1SURF_GRPH1USECSC_MASK (0x02000000)
+#define ODN_PDP_GRPH1SURF_GRPH1USECSC_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH1SURF_GRPH1USECSC_SHIFT (25)
+#define ODN_PDP_GRPH1SURF_GRPH1USECSC_LENGTH (1)
+#define ODN_PDP_GRPH1SURF_GRPH1USECSC_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1SURF, GRPH1LUTRWCHOICE
+*/
+#define ODN_PDP_GRPH1SURF_GRPH1LUTRWCHOICE_MASK (0x01000000)
+#define ODN_PDP_GRPH1SURF_GRPH1LUTRWCHOICE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH1SURF_GRPH1LUTRWCHOICE_SHIFT (24)
+#define ODN_PDP_GRPH1SURF_GRPH1LUTRWCHOICE_LENGTH (1)
+#define ODN_PDP_GRPH1SURF_GRPH1LUTRWCHOICE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1SURF, GRPH1USELUT
+*/
+#define ODN_PDP_GRPH1SURF_GRPH1USELUT_MASK (0x00800000)
+#define ODN_PDP_GRPH1SURF_GRPH1USELUT_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH1SURF_GRPH1USELUT_SHIFT (23)
+#define ODN_PDP_GRPH1SURF_GRPH1USELUT_LENGTH (1)
+#define ODN_PDP_GRPH1SURF_GRPH1USELUT_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH2SURF_OFFSET (0x0004)
+
+/* PDP, GRPH2SURF, GRPH2PIXFMT
+*/
+#define ODN_PDP_GRPH2SURF_GRPH2PIXFMT_MASK (0xF8000000)
+#define ODN_PDP_GRPH2SURF_GRPH2PIXFMT_LSBMASK (0x0000001F)
+#define ODN_PDP_GRPH2SURF_GRPH2PIXFMT_SHIFT (27)
+#define ODN_PDP_GRPH2SURF_GRPH2PIXFMT_LENGTH (5)
+#define ODN_PDP_GRPH2SURF_GRPH2PIXFMT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2SURF, GRPH2USEGAMMA
+*/
+#define ODN_PDP_GRPH2SURF_GRPH2USEGAMMA_MASK (0x04000000)
+#define ODN_PDP_GRPH2SURF_GRPH2USEGAMMA_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH2SURF_GRPH2USEGAMMA_SHIFT (26)
+#define ODN_PDP_GRPH2SURF_GRPH2USEGAMMA_LENGTH (1)
+#define ODN_PDP_GRPH2SURF_GRPH2USEGAMMA_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2SURF, GRPH2USECSC
+*/
+#define ODN_PDP_GRPH2SURF_GRPH2USECSC_MASK (0x02000000)
+#define ODN_PDP_GRPH2SURF_GRPH2USECSC_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH2SURF_GRPH2USECSC_SHIFT (25)
+#define ODN_PDP_GRPH2SURF_GRPH2USECSC_LENGTH (1)
+#define ODN_PDP_GRPH2SURF_GRPH2USECSC_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2SURF, GRPH2LUTRWCHOICE
+*/
+#define ODN_PDP_GRPH2SURF_GRPH2LUTRWCHOICE_MASK (0x01000000)
+#define ODN_PDP_GRPH2SURF_GRPH2LUTRWCHOICE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH2SURF_GRPH2LUTRWCHOICE_SHIFT (24)
+#define ODN_PDP_GRPH2SURF_GRPH2LUTRWCHOICE_LENGTH (1)
+#define ODN_PDP_GRPH2SURF_GRPH2LUTRWCHOICE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2SURF, GRPH2USELUT
+*/
+#define ODN_PDP_GRPH2SURF_GRPH2USELUT_MASK (0x00800000)
+#define ODN_PDP_GRPH2SURF_GRPH2USELUT_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH2SURF_GRPH2USELUT_SHIFT (23)
+#define ODN_PDP_GRPH2SURF_GRPH2USELUT_LENGTH (1)
+#define ODN_PDP_GRPH2SURF_GRPH2USELUT_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH3SURF_OFFSET (0x0008)
+
+/* PDP, GRPH3SURF, GRPH3PIXFMT
+*/
+#define ODN_PDP_GRPH3SURF_GRPH3PIXFMT_MASK (0xF8000000)
+#define ODN_PDP_GRPH3SURF_GRPH3PIXFMT_LSBMASK (0x0000001F)
+#define ODN_PDP_GRPH3SURF_GRPH3PIXFMT_SHIFT (27)
+#define ODN_PDP_GRPH3SURF_GRPH3PIXFMT_LENGTH (5)
+#define ODN_PDP_GRPH3SURF_GRPH3PIXFMT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3SURF, GRPH3USEGAMMA
+*/
+#define ODN_PDP_GRPH3SURF_GRPH3USEGAMMA_MASK (0x04000000)
+#define ODN_PDP_GRPH3SURF_GRPH3USEGAMMA_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH3SURF_GRPH3USEGAMMA_SHIFT (26)
+#define ODN_PDP_GRPH3SURF_GRPH3USEGAMMA_LENGTH (1)
+#define ODN_PDP_GRPH3SURF_GRPH3USEGAMMA_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3SURF, GRPH3USECSC
+*/
+#define ODN_PDP_GRPH3SURF_GRPH3USECSC_MASK (0x02000000)
+#define ODN_PDP_GRPH3SURF_GRPH3USECSC_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH3SURF_GRPH3USECSC_SHIFT (25)
+#define ODN_PDP_GRPH3SURF_GRPH3USECSC_LENGTH (1)
+#define ODN_PDP_GRPH3SURF_GRPH3USECSC_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3SURF, GRPH3LUTRWCHOICE
+*/
+#define ODN_PDP_GRPH3SURF_GRPH3LUTRWCHOICE_MASK (0x01000000)
+#define ODN_PDP_GRPH3SURF_GRPH3LUTRWCHOICE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH3SURF_GRPH3LUTRWCHOICE_SHIFT (24)
+#define ODN_PDP_GRPH3SURF_GRPH3LUTRWCHOICE_LENGTH (1)
+#define ODN_PDP_GRPH3SURF_GRPH3LUTRWCHOICE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3SURF, GRPH3USELUT
+*/
+#define ODN_PDP_GRPH3SURF_GRPH3USELUT_MASK (0x00800000)
+#define ODN_PDP_GRPH3SURF_GRPH3USELUT_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH3SURF_GRPH3USELUT_SHIFT (23)
+#define ODN_PDP_GRPH3SURF_GRPH3USELUT_LENGTH (1)
+#define ODN_PDP_GRPH3SURF_GRPH3USELUT_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH4SURF_OFFSET (0x000C)
+
+/* PDP, GRPH4SURF, GRPH4PIXFMT
+*/
+#define ODN_PDP_GRPH4SURF_GRPH4PIXFMT_MASK (0xF8000000)
+#define ODN_PDP_GRPH4SURF_GRPH4PIXFMT_LSBMASK (0x0000001F)
+#define ODN_PDP_GRPH4SURF_GRPH4PIXFMT_SHIFT (27)
+#define ODN_PDP_GRPH4SURF_GRPH4PIXFMT_LENGTH (5)
+#define ODN_PDP_GRPH4SURF_GRPH4PIXFMT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4SURF, GRPH4USEGAMMA
+*/
+#define ODN_PDP_GRPH4SURF_GRPH4USEGAMMA_MASK (0x04000000)
+#define ODN_PDP_GRPH4SURF_GRPH4USEGAMMA_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH4SURF_GRPH4USEGAMMA_SHIFT (26)
+#define ODN_PDP_GRPH4SURF_GRPH4USEGAMMA_LENGTH (1)
+#define ODN_PDP_GRPH4SURF_GRPH4USEGAMMA_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4SURF, GRPH4USECSC
+*/
+#define ODN_PDP_GRPH4SURF_GRPH4USECSC_MASK (0x02000000)
+#define ODN_PDP_GRPH4SURF_GRPH4USECSC_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH4SURF_GRPH4USECSC_SHIFT (25)
+#define ODN_PDP_GRPH4SURF_GRPH4USECSC_LENGTH (1)
+#define ODN_PDP_GRPH4SURF_GRPH4USECSC_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4SURF, GRPH4LUTRWCHOICE
+*/
+#define ODN_PDP_GRPH4SURF_GRPH4LUTRWCHOICE_MASK (0x01000000)
+#define ODN_PDP_GRPH4SURF_GRPH4LUTRWCHOICE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH4SURF_GRPH4LUTRWCHOICE_SHIFT (24)
+#define ODN_PDP_GRPH4SURF_GRPH4LUTRWCHOICE_LENGTH (1)
+#define ODN_PDP_GRPH4SURF_GRPH4LUTRWCHOICE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4SURF, GRPH4USELUT
+*/
+#define ODN_PDP_GRPH4SURF_GRPH4USELUT_MASK (0x00800000)
+#define ODN_PDP_GRPH4SURF_GRPH4USELUT_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH4SURF_GRPH4USELUT_SHIFT (23)
+#define ODN_PDP_GRPH4SURF_GRPH4USELUT_LENGTH (1)
+#define ODN_PDP_GRPH4SURF_GRPH4USELUT_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1SURF_OFFSET (0x0010)
+
+/* PDP, VID1SURF, VID1PIXFMT
+*/
+#define ODN_PDP_VID1SURF_VID1PIXFMT_MASK (0xF8000000)
+#define ODN_PDP_VID1SURF_VID1PIXFMT_LSBMASK (0x0000001F)
+#define ODN_PDP_VID1SURF_VID1PIXFMT_SHIFT (27)
+#define ODN_PDP_VID1SURF_VID1PIXFMT_LENGTH (5)
+#define ODN_PDP_VID1SURF_VID1PIXFMT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1SURF, VID1USEGAMMA
+*/
+#define ODN_PDP_VID1SURF_VID1USEGAMMA_MASK (0x04000000)
+#define ODN_PDP_VID1SURF_VID1USEGAMMA_LSBMASK (0x00000001)
+#define ODN_PDP_VID1SURF_VID1USEGAMMA_SHIFT (26)
+#define ODN_PDP_VID1SURF_VID1USEGAMMA_LENGTH (1)
+#define ODN_PDP_VID1SURF_VID1USEGAMMA_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1SURF, VID1USECSC
+*/
+#define ODN_PDP_VID1SURF_VID1USECSC_MASK (0x02000000)
+#define ODN_PDP_VID1SURF_VID1USECSC_LSBMASK (0x00000001)
+#define ODN_PDP_VID1SURF_VID1USECSC_SHIFT (25)
+#define ODN_PDP_VID1SURF_VID1USECSC_LENGTH (1)
+#define ODN_PDP_VID1SURF_VID1USECSC_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1SURF, VID1USEI2P
+*/
+#define ODN_PDP_VID1SURF_VID1USEI2P_MASK (0x01000000)
+#define ODN_PDP_VID1SURF_VID1USEI2P_LSBMASK (0x00000001)
+#define ODN_PDP_VID1SURF_VID1USEI2P_SHIFT (24)
+#define ODN_PDP_VID1SURF_VID1USEI2P_LENGTH (1)
+#define ODN_PDP_VID1SURF_VID1USEI2P_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1SURF, VID1COSITED
+*/
+#define ODN_PDP_VID1SURF_VID1COSITED_MASK (0x00800000)
+#define ODN_PDP_VID1SURF_VID1COSITED_LSBMASK (0x00000001)
+#define ODN_PDP_VID1SURF_VID1COSITED_SHIFT (23)
+#define ODN_PDP_VID1SURF_VID1COSITED_LENGTH (1)
+#define ODN_PDP_VID1SURF_VID1COSITED_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1SURF, VID1USEHQCD
+*/
+#define ODN_PDP_VID1SURF_VID1USEHQCD_MASK (0x00400000)
+#define ODN_PDP_VID1SURF_VID1USEHQCD_LSBMASK (0x00000001)
+#define ODN_PDP_VID1SURF_VID1USEHQCD_SHIFT (22)
+#define ODN_PDP_VID1SURF_VID1USEHQCD_LENGTH (1)
+#define ODN_PDP_VID1SURF_VID1USEHQCD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1SURF, VID1USEINSTREAM
+*/
+#define ODN_PDP_VID1SURF_VID1USEINSTREAM_MASK (0x00200000)
+#define ODN_PDP_VID1SURF_VID1USEINSTREAM_LSBMASK (0x00000001)
+#define ODN_PDP_VID1SURF_VID1USEINSTREAM_SHIFT (21)
+#define ODN_PDP_VID1SURF_VID1USEINSTREAM_LENGTH (1)
+#define ODN_PDP_VID1SURF_VID1USEINSTREAM_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2SURF_OFFSET (0x0014)
+
+/* PDP, VID2SURF, VID2PIXFMT
+*/
+#define ODN_PDP_VID2SURF_VID2PIXFMT_MASK (0xF8000000)
+#define ODN_PDP_VID2SURF_VID2PIXFMT_LSBMASK (0x0000001F)
+#define ODN_PDP_VID2SURF_VID2PIXFMT_SHIFT (27)
+#define ODN_PDP_VID2SURF_VID2PIXFMT_LENGTH (5)
+#define ODN_PDP_VID2SURF_VID2PIXFMT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2SURF, VID2COSITED
+*/
+#define ODN_PDP_VID2SURF_VID2COSITED_MASK (0x00800000)
+#define ODN_PDP_VID2SURF_VID2COSITED_LSBMASK (0x00000001)
+#define ODN_PDP_VID2SURF_VID2COSITED_SHIFT (23)
+#define ODN_PDP_VID2SURF_VID2COSITED_LENGTH (1)
+#define ODN_PDP_VID2SURF_VID2COSITED_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2SURF, VID2USEGAMMA
+*/
+#define ODN_PDP_VID2SURF_VID2USEGAMMA_MASK (0x04000000)
+#define ODN_PDP_VID2SURF_VID2USEGAMMA_LSBMASK (0x00000001)
+#define ODN_PDP_VID2SURF_VID2USEGAMMA_SHIFT (26)
+#define ODN_PDP_VID2SURF_VID2USEGAMMA_LENGTH (1)
+#define ODN_PDP_VID2SURF_VID2USEGAMMA_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2SURF, VID2USECSC
+*/
+#define ODN_PDP_VID2SURF_VID2USECSC_MASK (0x02000000)
+#define ODN_PDP_VID2SURF_VID2USECSC_LSBMASK (0x00000001)
+#define ODN_PDP_VID2SURF_VID2USECSC_SHIFT (25)
+#define ODN_PDP_VID2SURF_VID2USECSC_LENGTH (1)
+#define ODN_PDP_VID2SURF_VID2USECSC_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3SURF_OFFSET (0x0018)
+
+/* PDP, VID3SURF, VID3PIXFMT
+*/
+#define ODN_PDP_VID3SURF_VID3PIXFMT_MASK (0xF8000000)
+#define ODN_PDP_VID3SURF_VID3PIXFMT_LSBMASK (0x0000001F)
+#define ODN_PDP_VID3SURF_VID3PIXFMT_SHIFT (27)
+#define ODN_PDP_VID3SURF_VID3PIXFMT_LENGTH (5)
+#define ODN_PDP_VID3SURF_VID3PIXFMT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3SURF, VID3COSITED
+*/
+#define ODN_PDP_VID3SURF_VID3COSITED_MASK (0x00800000)
+#define ODN_PDP_VID3SURF_VID3COSITED_LSBMASK (0x00000001)
+#define ODN_PDP_VID3SURF_VID3COSITED_SHIFT (23)
+#define ODN_PDP_VID3SURF_VID3COSITED_LENGTH (1)
+#define ODN_PDP_VID3SURF_VID3COSITED_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3SURF, VID3USEGAMMA
+*/
+#define ODN_PDP_VID3SURF_VID3USEGAMMA_MASK (0x04000000)
+#define ODN_PDP_VID3SURF_VID3USEGAMMA_LSBMASK (0x00000001)
+#define ODN_PDP_VID3SURF_VID3USEGAMMA_SHIFT (26)
+#define ODN_PDP_VID3SURF_VID3USEGAMMA_LENGTH (1)
+#define ODN_PDP_VID3SURF_VID3USEGAMMA_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3SURF, VID3USECSC
+*/
+#define ODN_PDP_VID3SURF_VID3USECSC_MASK (0x02000000)
+#define ODN_PDP_VID3SURF_VID3USECSC_LSBMASK (0x00000001)
+#define ODN_PDP_VID3SURF_VID3USECSC_SHIFT (25)
+#define ODN_PDP_VID3SURF_VID3USECSC_LENGTH (1)
+#define ODN_PDP_VID3SURF_VID3USECSC_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4SURF_OFFSET (0x001C)
+
+/* PDP, VID4SURF, VID4PIXFMT
+*/
+#define ODN_PDP_VID4SURF_VID4PIXFMT_MASK (0xF8000000)
+#define ODN_PDP_VID4SURF_VID4PIXFMT_LSBMASK (0x0000001F)
+#define ODN_PDP_VID4SURF_VID4PIXFMT_SHIFT (27)
+#define ODN_PDP_VID4SURF_VID4PIXFMT_LENGTH (5)
+#define ODN_PDP_VID4SURF_VID4PIXFMT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4SURF, VID4COSITED
+*/
+#define ODN_PDP_VID4SURF_VID4COSITED_MASK (0x00800000)
+#define ODN_PDP_VID4SURF_VID4COSITED_LSBMASK (0x00000001)
+#define ODN_PDP_VID4SURF_VID4COSITED_SHIFT (23)
+#define ODN_PDP_VID4SURF_VID4COSITED_LENGTH (1)
+#define ODN_PDP_VID4SURF_VID4COSITED_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4SURF, VID4USEGAMMA
+*/
+#define ODN_PDP_VID4SURF_VID4USEGAMMA_MASK (0x04000000)
+#define ODN_PDP_VID4SURF_VID4USEGAMMA_LSBMASK (0x00000001)
+#define ODN_PDP_VID4SURF_VID4USEGAMMA_SHIFT (26)
+#define ODN_PDP_VID4SURF_VID4USEGAMMA_LENGTH (1)
+#define ODN_PDP_VID4SURF_VID4USEGAMMA_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4SURF, VID4USECSC
+*/
+#define ODN_PDP_VID4SURF_VID4USECSC_MASK (0x02000000)
+#define ODN_PDP_VID4SURF_VID4USECSC_LSBMASK (0x00000001)
+#define ODN_PDP_VID4SURF_VID4USECSC_SHIFT (25)
+#define ODN_PDP_VID4SURF_VID4USECSC_LENGTH (1)
+#define ODN_PDP_VID4SURF_VID4USECSC_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH1CTRL_OFFSET (0x0020)
+
+/* PDP, GRPH1CTRL, GRPH1STREN
+*/
+#define ODN_PDP_GRPH1CTRL_GRPH1STREN_MASK (0x80000000)
+#define ODN_PDP_GRPH1CTRL_GRPH1STREN_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH1CTRL_GRPH1STREN_SHIFT (31)
+#define ODN_PDP_GRPH1CTRL_GRPH1STREN_LENGTH (1)
+#define ODN_PDP_GRPH1CTRL_GRPH1STREN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1CTRL, GRPH1CKEYEN
+*/
+#define ODN_PDP_GRPH1CTRL_GRPH1CKEYEN_MASK (0x40000000)
+#define ODN_PDP_GRPH1CTRL_GRPH1CKEYEN_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH1CTRL_GRPH1CKEYEN_SHIFT (30)
+#define ODN_PDP_GRPH1CTRL_GRPH1CKEYEN_LENGTH (1)
+#define ODN_PDP_GRPH1CTRL_GRPH1CKEYEN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1CTRL, GRPH1CKEYSRC
+*/
+#define ODN_PDP_GRPH1CTRL_GRPH1CKEYSRC_MASK (0x20000000)
+#define ODN_PDP_GRPH1CTRL_GRPH1CKEYSRC_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH1CTRL_GRPH1CKEYSRC_SHIFT (29)
+#define ODN_PDP_GRPH1CTRL_GRPH1CKEYSRC_LENGTH (1)
+#define ODN_PDP_GRPH1CTRL_GRPH1CKEYSRC_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1CTRL, GRPH1BLEND
+*/
+#define ODN_PDP_GRPH1CTRL_GRPH1BLEND_MASK (0x18000000)
+#define ODN_PDP_GRPH1CTRL_GRPH1BLEND_LSBMASK (0x00000003)
+#define ODN_PDP_GRPH1CTRL_GRPH1BLEND_SHIFT (27)
+#define ODN_PDP_GRPH1CTRL_GRPH1BLEND_LENGTH (2)
+#define ODN_PDP_GRPH1CTRL_GRPH1BLEND_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1CTRL, GRPH1BLENDPOS
+*/
+#define ODN_PDP_GRPH1CTRL_GRPH1BLENDPOS_MASK (0x07000000)
+#define ODN_PDP_GRPH1CTRL_GRPH1BLENDPOS_LSBMASK (0x00000007)
+#define ODN_PDP_GRPH1CTRL_GRPH1BLENDPOS_SHIFT (24)
+#define ODN_PDP_GRPH1CTRL_GRPH1BLENDPOS_LENGTH (3)
+#define ODN_PDP_GRPH1CTRL_GRPH1BLENDPOS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1CTRL, GRPH1DITHEREN
+*/
+#define ODN_PDP_GRPH1CTRL_GRPH1DITHEREN_MASK (0x00800000)
+#define ODN_PDP_GRPH1CTRL_GRPH1DITHEREN_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH1CTRL_GRPH1DITHEREN_SHIFT (23)
+#define ODN_PDP_GRPH1CTRL_GRPH1DITHEREN_LENGTH (1)
+#define ODN_PDP_GRPH1CTRL_GRPH1DITHEREN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH2CTRL_OFFSET (0x0024)
+
+/* PDP, GRPH2CTRL, GRPH2STREN
+*/
+#define ODN_PDP_GRPH2CTRL_GRPH2STREN_MASK (0x80000000)
+#define ODN_PDP_GRPH2CTRL_GRPH2STREN_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH2CTRL_GRPH2STREN_SHIFT (31)
+#define ODN_PDP_GRPH2CTRL_GRPH2STREN_LENGTH (1)
+#define ODN_PDP_GRPH2CTRL_GRPH2STREN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2CTRL, GRPH2CKEYEN
+*/
+#define ODN_PDP_GRPH2CTRL_GRPH2CKEYEN_MASK (0x40000000)
+#define ODN_PDP_GRPH2CTRL_GRPH2CKEYEN_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH2CTRL_GRPH2CKEYEN_SHIFT (30)
+#define ODN_PDP_GRPH2CTRL_GRPH2CKEYEN_LENGTH (1)
+#define ODN_PDP_GRPH2CTRL_GRPH2CKEYEN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2CTRL, GRPH2CKEYSRC
+*/
+#define ODN_PDP_GRPH2CTRL_GRPH2CKEYSRC_MASK (0x20000000)
+#define ODN_PDP_GRPH2CTRL_GRPH2CKEYSRC_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH2CTRL_GRPH2CKEYSRC_SHIFT (29)
+#define ODN_PDP_GRPH2CTRL_GRPH2CKEYSRC_LENGTH (1)
+#define ODN_PDP_GRPH2CTRL_GRPH2CKEYSRC_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2CTRL, GRPH2BLEND
+*/
+#define ODN_PDP_GRPH2CTRL_GRPH2BLEND_MASK (0x18000000)
+#define ODN_PDP_GRPH2CTRL_GRPH2BLEND_LSBMASK (0x00000003)
+#define ODN_PDP_GRPH2CTRL_GRPH2BLEND_SHIFT (27)
+#define ODN_PDP_GRPH2CTRL_GRPH2BLEND_LENGTH (2)
+#define ODN_PDP_GRPH2CTRL_GRPH2BLEND_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2CTRL, GRPH2BLENDPOS
+*/
+#define ODN_PDP_GRPH2CTRL_GRPH2BLENDPOS_MASK (0x07000000)
+#define ODN_PDP_GRPH2CTRL_GRPH2BLENDPOS_LSBMASK (0x00000007)
+#define ODN_PDP_GRPH2CTRL_GRPH2BLENDPOS_SHIFT (24)
+#define ODN_PDP_GRPH2CTRL_GRPH2BLENDPOS_LENGTH (3)
+#define ODN_PDP_GRPH2CTRL_GRPH2BLENDPOS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2CTRL, GRPH2DITHEREN
+*/
+#define ODN_PDP_GRPH2CTRL_GRPH2DITHEREN_MASK (0x00800000)
+#define ODN_PDP_GRPH2CTRL_GRPH2DITHEREN_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH2CTRL_GRPH2DITHEREN_SHIFT (23)
+#define ODN_PDP_GRPH2CTRL_GRPH2DITHEREN_LENGTH (1)
+#define ODN_PDP_GRPH2CTRL_GRPH2DITHEREN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH3CTRL_OFFSET (0x0028)
+
+/* PDP, GRPH3CTRL, GRPH3STREN
+*/
+#define ODN_PDP_GRPH3CTRL_GRPH3STREN_MASK (0x80000000)
+#define ODN_PDP_GRPH3CTRL_GRPH3STREN_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH3CTRL_GRPH3STREN_SHIFT (31)
+#define ODN_PDP_GRPH3CTRL_GRPH3STREN_LENGTH (1)
+#define ODN_PDP_GRPH3CTRL_GRPH3STREN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3CTRL, GRPH3CKEYEN
+*/
+#define ODN_PDP_GRPH3CTRL_GRPH3CKEYEN_MASK (0x40000000)
+#define ODN_PDP_GRPH3CTRL_GRPH3CKEYEN_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH3CTRL_GRPH3CKEYEN_SHIFT (30)
+#define ODN_PDP_GRPH3CTRL_GRPH3CKEYEN_LENGTH (1)
+#define ODN_PDP_GRPH3CTRL_GRPH3CKEYEN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3CTRL, GRPH3CKEYSRC
+*/
+#define ODN_PDP_GRPH3CTRL_GRPH3CKEYSRC_MASK (0x20000000)
+#define ODN_PDP_GRPH3CTRL_GRPH3CKEYSRC_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH3CTRL_GRPH3CKEYSRC_SHIFT (29)
+#define ODN_PDP_GRPH3CTRL_GRPH3CKEYSRC_LENGTH (1)
+#define ODN_PDP_GRPH3CTRL_GRPH3CKEYSRC_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3CTRL, GRPH3BLEND
+*/
+#define ODN_PDP_GRPH3CTRL_GRPH3BLEND_MASK (0x18000000)
+#define ODN_PDP_GRPH3CTRL_GRPH3BLEND_LSBMASK (0x00000003)
+#define ODN_PDP_GRPH3CTRL_GRPH3BLEND_SHIFT (27)
+#define ODN_PDP_GRPH3CTRL_GRPH3BLEND_LENGTH (2)
+#define ODN_PDP_GRPH3CTRL_GRPH3BLEND_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3CTRL, GRPH3BLENDPOS
+*/
+#define ODN_PDP_GRPH3CTRL_GRPH3BLENDPOS_MASK (0x07000000)
+#define ODN_PDP_GRPH3CTRL_GRPH3BLENDPOS_LSBMASK (0x00000007)
+#define ODN_PDP_GRPH3CTRL_GRPH3BLENDPOS_SHIFT (24)
+#define ODN_PDP_GRPH3CTRL_GRPH3BLENDPOS_LENGTH (3)
+#define ODN_PDP_GRPH3CTRL_GRPH3BLENDPOS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3CTRL, GRPH3DITHEREN
+*/
+#define ODN_PDP_GRPH3CTRL_GRPH3DITHEREN_MASK (0x00800000)
+#define ODN_PDP_GRPH3CTRL_GRPH3DITHEREN_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH3CTRL_GRPH3DITHEREN_SHIFT (23)
+#define ODN_PDP_GRPH3CTRL_GRPH3DITHEREN_LENGTH (1)
+#define ODN_PDP_GRPH3CTRL_GRPH3DITHEREN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH4CTRL_OFFSET (0x002C)
+
+/* PDP, GRPH4CTRL, GRPH4STREN
+*/
+#define ODN_PDP_GRPH4CTRL_GRPH4STREN_MASK (0x80000000)
+#define ODN_PDP_GRPH4CTRL_GRPH4STREN_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH4CTRL_GRPH4STREN_SHIFT (31)
+#define ODN_PDP_GRPH4CTRL_GRPH4STREN_LENGTH (1)
+#define ODN_PDP_GRPH4CTRL_GRPH4STREN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4CTRL, GRPH4CKEYEN
+*/
+#define ODN_PDP_GRPH4CTRL_GRPH4CKEYEN_MASK (0x40000000)
+#define ODN_PDP_GRPH4CTRL_GRPH4CKEYEN_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH4CTRL_GRPH4CKEYEN_SHIFT (30)
+#define ODN_PDP_GRPH4CTRL_GRPH4CKEYEN_LENGTH (1)
+#define ODN_PDP_GRPH4CTRL_GRPH4CKEYEN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4CTRL, GRPH4CKEYSRC
+*/
+#define ODN_PDP_GRPH4CTRL_GRPH4CKEYSRC_MASK (0x20000000)
+#define ODN_PDP_GRPH4CTRL_GRPH4CKEYSRC_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH4CTRL_GRPH4CKEYSRC_SHIFT (29)
+#define ODN_PDP_GRPH4CTRL_GRPH4CKEYSRC_LENGTH (1)
+#define ODN_PDP_GRPH4CTRL_GRPH4CKEYSRC_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4CTRL, GRPH4BLEND
+*/
+#define ODN_PDP_GRPH4CTRL_GRPH4BLEND_MASK (0x18000000)
+#define ODN_PDP_GRPH4CTRL_GRPH4BLEND_LSBMASK (0x00000003)
+#define ODN_PDP_GRPH4CTRL_GRPH4BLEND_SHIFT (27)
+#define ODN_PDP_GRPH4CTRL_GRPH4BLEND_LENGTH (2)
+#define ODN_PDP_GRPH4CTRL_GRPH4BLEND_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4CTRL, GRPH4BLENDPOS
+*/
+#define ODN_PDP_GRPH4CTRL_GRPH4BLENDPOS_MASK (0x07000000)
+#define ODN_PDP_GRPH4CTRL_GRPH4BLENDPOS_LSBMASK (0x00000007)
+#define ODN_PDP_GRPH4CTRL_GRPH4BLENDPOS_SHIFT (24)
+#define ODN_PDP_GRPH4CTRL_GRPH4BLENDPOS_LENGTH (3)
+#define ODN_PDP_GRPH4CTRL_GRPH4BLENDPOS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4CTRL, GRPH4DITHEREN
+*/
+#define ODN_PDP_GRPH4CTRL_GRPH4DITHEREN_MASK (0x00800000)
+#define ODN_PDP_GRPH4CTRL_GRPH4DITHEREN_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH4CTRL_GRPH4DITHEREN_SHIFT (23)
+#define ODN_PDP_GRPH4CTRL_GRPH4DITHEREN_LENGTH (1)
+#define ODN_PDP_GRPH4CTRL_GRPH4DITHEREN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1CTRL_OFFSET (0x0030)
+
+/* PDP, VID1CTRL, VID1STREN
+*/
+#define ODN_PDP_VID1CTRL_VID1STREN_MASK (0x80000000)
+#define ODN_PDP_VID1CTRL_VID1STREN_LSBMASK (0x00000001)
+#define ODN_PDP_VID1CTRL_VID1STREN_SHIFT (31)
+#define ODN_PDP_VID1CTRL_VID1STREN_LENGTH (1)
+#define ODN_PDP_VID1CTRL_VID1STREN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1CTRL, VID1CKEYEN
+*/
+#define ODN_PDP_VID1CTRL_VID1CKEYEN_MASK (0x40000000)
+#define ODN_PDP_VID1CTRL_VID1CKEYEN_LSBMASK (0x00000001)
+#define ODN_PDP_VID1CTRL_VID1CKEYEN_SHIFT (30)
+#define ODN_PDP_VID1CTRL_VID1CKEYEN_LENGTH (1)
+#define ODN_PDP_VID1CTRL_VID1CKEYEN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1CTRL, VID1CKEYSRC
+*/
+#define ODN_PDP_VID1CTRL_VID1CKEYSRC_MASK (0x20000000)
+#define ODN_PDP_VID1CTRL_VID1CKEYSRC_LSBMASK (0x00000001)
+#define ODN_PDP_VID1CTRL_VID1CKEYSRC_SHIFT (29)
+#define ODN_PDP_VID1CTRL_VID1CKEYSRC_LENGTH (1)
+#define ODN_PDP_VID1CTRL_VID1CKEYSRC_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1CTRL, VID1BLEND
+*/
+#define ODN_PDP_VID1CTRL_VID1BLEND_MASK (0x18000000)
+#define ODN_PDP_VID1CTRL_VID1BLEND_LSBMASK (0x00000003)
+#define ODN_PDP_VID1CTRL_VID1BLEND_SHIFT (27)
+#define ODN_PDP_VID1CTRL_VID1BLEND_LENGTH (2)
+#define ODN_PDP_VID1CTRL_VID1BLEND_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1CTRL, VID1BLENDPOS
+*/
+#define ODN_PDP_VID1CTRL_VID1BLENDPOS_MASK (0x07000000)
+#define ODN_PDP_VID1CTRL_VID1BLENDPOS_LSBMASK (0x00000007)
+#define ODN_PDP_VID1CTRL_VID1BLENDPOS_SHIFT (24)
+#define ODN_PDP_VID1CTRL_VID1BLENDPOS_LENGTH (3)
+#define ODN_PDP_VID1CTRL_VID1BLENDPOS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1CTRL, VID1DITHEREN
+*/
+#define ODN_PDP_VID1CTRL_VID1DITHEREN_MASK (0x00800000)
+#define ODN_PDP_VID1CTRL_VID1DITHEREN_LSBMASK (0x00000001)
+#define ODN_PDP_VID1CTRL_VID1DITHEREN_SHIFT (23)
+#define ODN_PDP_VID1CTRL_VID1DITHEREN_LENGTH (1)
+#define ODN_PDP_VID1CTRL_VID1DITHEREN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2CTRL_OFFSET (0x0034)
+
+/* PDP, VID2CTRL, VID2STREN
+*/
+#define ODN_PDP_VID2CTRL_VID2STREN_MASK (0x80000000)
+#define ODN_PDP_VID2CTRL_VID2STREN_LSBMASK (0x00000001)
+#define ODN_PDP_VID2CTRL_VID2STREN_SHIFT (31)
+#define ODN_PDP_VID2CTRL_VID2STREN_LENGTH (1)
+#define ODN_PDP_VID2CTRL_VID2STREN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2CTRL, VID2CKEYEN
+*/
+#define ODN_PDP_VID2CTRL_VID2CKEYEN_MASK (0x40000000)
+#define ODN_PDP_VID2CTRL_VID2CKEYEN_LSBMASK (0x00000001)
+#define ODN_PDP_VID2CTRL_VID2CKEYEN_SHIFT (30)
+#define ODN_PDP_VID2CTRL_VID2CKEYEN_LENGTH (1)
+#define ODN_PDP_VID2CTRL_VID2CKEYEN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2CTRL, VID2CKEYSRC
+*/
+#define ODN_PDP_VID2CTRL_VID2CKEYSRC_MASK (0x20000000)
+#define ODN_PDP_VID2CTRL_VID2CKEYSRC_LSBMASK (0x00000001)
+#define ODN_PDP_VID2CTRL_VID2CKEYSRC_SHIFT (29)
+#define ODN_PDP_VID2CTRL_VID2CKEYSRC_LENGTH (1)
+#define ODN_PDP_VID2CTRL_VID2CKEYSRC_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2CTRL, VID2BLEND
+*/
+#define ODN_PDP_VID2CTRL_VID2BLEND_MASK (0x18000000)
+#define ODN_PDP_VID2CTRL_VID2BLEND_LSBMASK (0x00000003)
+#define ODN_PDP_VID2CTRL_VID2BLEND_SHIFT (27)
+#define ODN_PDP_VID2CTRL_VID2BLEND_LENGTH (2)
+#define ODN_PDP_VID2CTRL_VID2BLEND_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2CTRL, VID2BLENDPOS
+*/
+#define ODN_PDP_VID2CTRL_VID2BLENDPOS_MASK (0x07000000)
+#define ODN_PDP_VID2CTRL_VID2BLENDPOS_LSBMASK (0x00000007)
+#define ODN_PDP_VID2CTRL_VID2BLENDPOS_SHIFT (24)
+#define ODN_PDP_VID2CTRL_VID2BLENDPOS_LENGTH (3)
+#define ODN_PDP_VID2CTRL_VID2BLENDPOS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2CTRL, VID2DITHEREN
+*/
+#define ODN_PDP_VID2CTRL_VID2DITHEREN_MASK (0x00800000)
+#define ODN_PDP_VID2CTRL_VID2DITHEREN_LSBMASK (0x00000001)
+#define ODN_PDP_VID2CTRL_VID2DITHEREN_SHIFT (23)
+#define ODN_PDP_VID2CTRL_VID2DITHEREN_LENGTH (1)
+#define ODN_PDP_VID2CTRL_VID2DITHEREN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3CTRL_OFFSET (0x0038)
+
+/* PDP, VID3CTRL, VID3STREN
+*/
+#define ODN_PDP_VID3CTRL_VID3STREN_MASK (0x80000000)
+#define ODN_PDP_VID3CTRL_VID3STREN_LSBMASK (0x00000001)
+#define ODN_PDP_VID3CTRL_VID3STREN_SHIFT (31)
+#define ODN_PDP_VID3CTRL_VID3STREN_LENGTH (1)
+#define ODN_PDP_VID3CTRL_VID3STREN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3CTRL, VID3CKEYEN
+*/
+#define ODN_PDP_VID3CTRL_VID3CKEYEN_MASK (0x40000000)
+#define ODN_PDP_VID3CTRL_VID3CKEYEN_LSBMASK (0x00000001)
+#define ODN_PDP_VID3CTRL_VID3CKEYEN_SHIFT (30)
+#define ODN_PDP_VID3CTRL_VID3CKEYEN_LENGTH (1)
+#define ODN_PDP_VID3CTRL_VID3CKEYEN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3CTRL, VID3CKEYSRC
+*/
+#define ODN_PDP_VID3CTRL_VID3CKEYSRC_MASK (0x20000000)
+#define ODN_PDP_VID3CTRL_VID3CKEYSRC_LSBMASK (0x00000001)
+#define ODN_PDP_VID3CTRL_VID3CKEYSRC_SHIFT (29)
+#define ODN_PDP_VID3CTRL_VID3CKEYSRC_LENGTH (1)
+#define ODN_PDP_VID3CTRL_VID3CKEYSRC_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3CTRL, VID3BLEND
+*/
+#define ODN_PDP_VID3CTRL_VID3BLEND_MASK (0x18000000)
+#define ODN_PDP_VID3CTRL_VID3BLEND_LSBMASK (0x00000003)
+#define ODN_PDP_VID3CTRL_VID3BLEND_SHIFT (27)
+#define ODN_PDP_VID3CTRL_VID3BLEND_LENGTH (2)
+#define ODN_PDP_VID3CTRL_VID3BLEND_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3CTRL, VID3BLENDPOS
+*/
+#define ODN_PDP_VID3CTRL_VID3BLENDPOS_MASK (0x07000000)
+#define ODN_PDP_VID3CTRL_VID3BLENDPOS_LSBMASK (0x00000007)
+#define ODN_PDP_VID3CTRL_VID3BLENDPOS_SHIFT (24)
+#define ODN_PDP_VID3CTRL_VID3BLENDPOS_LENGTH (3)
+#define ODN_PDP_VID3CTRL_VID3BLENDPOS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3CTRL, VID3DITHEREN
+*/
+#define ODN_PDP_VID3CTRL_VID3DITHEREN_MASK (0x00800000)
+#define ODN_PDP_VID3CTRL_VID3DITHEREN_LSBMASK (0x00000001)
+#define ODN_PDP_VID3CTRL_VID3DITHEREN_SHIFT (23)
+#define ODN_PDP_VID3CTRL_VID3DITHEREN_LENGTH (1)
+#define ODN_PDP_VID3CTRL_VID3DITHEREN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4CTRL_OFFSET (0x003C)
+
+/* PDP, VID4CTRL, VID4STREN
+*/
+#define ODN_PDP_VID4CTRL_VID4STREN_MASK (0x80000000)
+#define ODN_PDP_VID4CTRL_VID4STREN_LSBMASK (0x00000001)
+#define ODN_PDP_VID4CTRL_VID4STREN_SHIFT (31)
+#define ODN_PDP_VID4CTRL_VID4STREN_LENGTH (1)
+#define ODN_PDP_VID4CTRL_VID4STREN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4CTRL, VID4CKEYEN
+*/
+#define ODN_PDP_VID4CTRL_VID4CKEYEN_MASK (0x40000000)
+#define ODN_PDP_VID4CTRL_VID4CKEYEN_LSBMASK (0x00000001)
+#define ODN_PDP_VID4CTRL_VID4CKEYEN_SHIFT (30)
+#define ODN_PDP_VID4CTRL_VID4CKEYEN_LENGTH (1)
+#define ODN_PDP_VID4CTRL_VID4CKEYEN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4CTRL, VID4CKEYSRC
+*/
+#define ODN_PDP_VID4CTRL_VID4CKEYSRC_MASK (0x20000000)
+#define ODN_PDP_VID4CTRL_VID4CKEYSRC_LSBMASK (0x00000001)
+#define ODN_PDP_VID4CTRL_VID4CKEYSRC_SHIFT (29)
+#define ODN_PDP_VID4CTRL_VID4CKEYSRC_LENGTH (1)
+#define ODN_PDP_VID4CTRL_VID4CKEYSRC_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4CTRL, VID4BLEND
+*/
+#define ODN_PDP_VID4CTRL_VID4BLEND_MASK (0x18000000)
+#define ODN_PDP_VID4CTRL_VID4BLEND_LSBMASK (0x00000003)
+#define ODN_PDP_VID4CTRL_VID4BLEND_SHIFT (27)
+#define ODN_PDP_VID4CTRL_VID4BLEND_LENGTH (2)
+#define ODN_PDP_VID4CTRL_VID4BLEND_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4CTRL, VID4BLENDPOS
+*/
+#define ODN_PDP_VID4CTRL_VID4BLENDPOS_MASK (0x07000000)
+#define ODN_PDP_VID4CTRL_VID4BLENDPOS_LSBMASK (0x00000007)
+#define ODN_PDP_VID4CTRL_VID4BLENDPOS_SHIFT (24)
+#define ODN_PDP_VID4CTRL_VID4BLENDPOS_LENGTH (3)
+#define ODN_PDP_VID4CTRL_VID4BLENDPOS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4CTRL, VID4DITHEREN
+*/
+#define ODN_PDP_VID4CTRL_VID4DITHEREN_MASK (0x00800000)
+#define ODN_PDP_VID4CTRL_VID4DITHEREN_LSBMASK (0x00000001)
+#define ODN_PDP_VID4CTRL_VID4DITHEREN_SHIFT (23)
+#define ODN_PDP_VID4CTRL_VID4DITHEREN_LENGTH (1)
+#define ODN_PDP_VID4CTRL_VID4DITHEREN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1UCTRL_OFFSET (0x0050)
+
+/* PDP, VID1UCTRL, VID1UVHALFSTR
+*/
+#define ODN_PDP_VID1UCTRL_VID1UVHALFSTR_MASK (0xC0000000)
+#define ODN_PDP_VID1UCTRL_VID1UVHALFSTR_LSBMASK (0x00000003)
+#define ODN_PDP_VID1UCTRL_VID1UVHALFSTR_SHIFT (30)
+#define ODN_PDP_VID1UCTRL_VID1UVHALFSTR_LENGTH (2)
+#define ODN_PDP_VID1UCTRL_VID1UVHALFSTR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2UCTRL_OFFSET (0x0054)
+
+/* PDP, VID2UCTRL, VID2UVHALFSTR
+*/
+#define ODN_PDP_VID2UCTRL_VID2UVHALFSTR_MASK (0xC0000000)
+#define ODN_PDP_VID2UCTRL_VID2UVHALFSTR_LSBMASK (0x00000003)
+#define ODN_PDP_VID2UCTRL_VID2UVHALFSTR_SHIFT (30)
+#define ODN_PDP_VID2UCTRL_VID2UVHALFSTR_LENGTH (2)
+#define ODN_PDP_VID2UCTRL_VID2UVHALFSTR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3UCTRL_OFFSET (0x0058)
+
+/* PDP, VID3UCTRL, VID3UVHALFSTR
+*/
+#define ODN_PDP_VID3UCTRL_VID3UVHALFSTR_MASK (0xC0000000)
+#define ODN_PDP_VID3UCTRL_VID3UVHALFSTR_LSBMASK (0x00000003)
+#define ODN_PDP_VID3UCTRL_VID3UVHALFSTR_SHIFT (30)
+#define ODN_PDP_VID3UCTRL_VID3UVHALFSTR_LENGTH (2)
+#define ODN_PDP_VID3UCTRL_VID3UVHALFSTR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4UCTRL_OFFSET (0x005C)
+
+/* PDP, VID4UCTRL, VID4UVHALFSTR
+*/
+#define ODN_PDP_VID4UCTRL_VID4UVHALFSTR_MASK (0xC0000000)
+#define ODN_PDP_VID4UCTRL_VID4UVHALFSTR_LSBMASK (0x00000003)
+#define ODN_PDP_VID4UCTRL_VID4UVHALFSTR_SHIFT (30)
+#define ODN_PDP_VID4UCTRL_VID4UVHALFSTR_LENGTH (2)
+#define ODN_PDP_VID4UCTRL_VID4UVHALFSTR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH1STRIDE_OFFSET (0x0060)
+
+/* PDP, GRPH1STRIDE, GRPH1STRIDE
+*/
+#define ODN_PDP_GRPH1STRIDE_GRPH1STRIDE_MASK (0xFFC00000)
+#define ODN_PDP_GRPH1STRIDE_GRPH1STRIDE_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH1STRIDE_GRPH1STRIDE_SHIFT (22)
+#define ODN_PDP_GRPH1STRIDE_GRPH1STRIDE_LENGTH (10)
+#define ODN_PDP_GRPH1STRIDE_GRPH1STRIDE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH2STRIDE_OFFSET (0x0064)
+
+/* PDP, GRPH2STRIDE, GRPH2STRIDE
+*/
+#define ODN_PDP_GRPH2STRIDE_GRPH2STRIDE_MASK (0xFFC00000)
+#define ODN_PDP_GRPH2STRIDE_GRPH2STRIDE_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH2STRIDE_GRPH2STRIDE_SHIFT (22)
+#define ODN_PDP_GRPH2STRIDE_GRPH2STRIDE_LENGTH (10)
+#define ODN_PDP_GRPH2STRIDE_GRPH2STRIDE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH3STRIDE_OFFSET (0x0068)
+
+/* PDP, GRPH3STRIDE, GRPH3STRIDE
+*/
+#define ODN_PDP_GRPH3STRIDE_GRPH3STRIDE_MASK (0xFFC00000)
+#define ODN_PDP_GRPH3STRIDE_GRPH3STRIDE_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH3STRIDE_GRPH3STRIDE_SHIFT (22)
+#define ODN_PDP_GRPH3STRIDE_GRPH3STRIDE_LENGTH (10)
+#define ODN_PDP_GRPH3STRIDE_GRPH3STRIDE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH4STRIDE_OFFSET (0x006C)
+
+/* PDP, GRPH4STRIDE, GRPH4STRIDE
+*/
+#define ODN_PDP_GRPH4STRIDE_GRPH4STRIDE_MASK (0xFFC00000)
+#define ODN_PDP_GRPH4STRIDE_GRPH4STRIDE_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH4STRIDE_GRPH4STRIDE_SHIFT (22)
+#define ODN_PDP_GRPH4STRIDE_GRPH4STRIDE_LENGTH (10)
+#define ODN_PDP_GRPH4STRIDE_GRPH4STRIDE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1STRIDE_OFFSET (0x0070)
+
+/* PDP, VID1STRIDE, VID1STRIDE
+*/
+#define ODN_PDP_VID1STRIDE_VID1STRIDE_MASK (0xFFC00000)
+#define ODN_PDP_VID1STRIDE_VID1STRIDE_LSBMASK (0x000003FF)
+#define ODN_PDP_VID1STRIDE_VID1STRIDE_SHIFT (22)
+#define ODN_PDP_VID1STRIDE_VID1STRIDE_LENGTH (10)
+#define ODN_PDP_VID1STRIDE_VID1STRIDE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2STRIDE_OFFSET (0x0074)
+
+/* PDP, VID2STRIDE, VID2STRIDE
+*/
+#define ODN_PDP_VID2STRIDE_VID2STRIDE_MASK (0xFFC00000)
+#define ODN_PDP_VID2STRIDE_VID2STRIDE_LSBMASK (0x000003FF)
+#define ODN_PDP_VID2STRIDE_VID2STRIDE_SHIFT (22)
+#define ODN_PDP_VID2STRIDE_VID2STRIDE_LENGTH (10)
+#define ODN_PDP_VID2STRIDE_VID2STRIDE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3STRIDE_OFFSET (0x0078)
+
+/* PDP, VID3STRIDE, VID3STRIDE
+*/
+#define ODN_PDP_VID3STRIDE_VID3STRIDE_MASK (0xFFC00000)
+#define ODN_PDP_VID3STRIDE_VID3STRIDE_LSBMASK (0x000003FF)
+#define ODN_PDP_VID3STRIDE_VID3STRIDE_SHIFT (22)
+#define ODN_PDP_VID3STRIDE_VID3STRIDE_LENGTH (10)
+#define ODN_PDP_VID3STRIDE_VID3STRIDE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4STRIDE_OFFSET (0x007C)
+
+/* PDP, VID4STRIDE, VID4STRIDE
+*/
+#define ODN_PDP_VID4STRIDE_VID4STRIDE_MASK (0xFFC00000)
+#define ODN_PDP_VID4STRIDE_VID4STRIDE_LSBMASK (0x000003FF)
+#define ODN_PDP_VID4STRIDE_VID4STRIDE_SHIFT (22)
+#define ODN_PDP_VID4STRIDE_VID4STRIDE_LENGTH (10)
+#define ODN_PDP_VID4STRIDE_VID4STRIDE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH1SIZE_OFFSET (0x0080)
+
+/* PDP, GRPH1SIZE, GRPH1WIDTH
+*/
+#define ODN_PDP_GRPH1SIZE_GRPH1WIDTH_MASK (0x0FFF0000)
+#define ODN_PDP_GRPH1SIZE_GRPH1WIDTH_LSBMASK (0x00000FFF)
+#define ODN_PDP_GRPH1SIZE_GRPH1WIDTH_SHIFT (16)
+#define ODN_PDP_GRPH1SIZE_GRPH1WIDTH_LENGTH (12)
+#define ODN_PDP_GRPH1SIZE_GRPH1WIDTH_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1SIZE, GRPH1HEIGHT
+*/
+#define ODN_PDP_GRPH1SIZE_GRPH1HEIGHT_MASK (0x00000FFF)
+#define ODN_PDP_GRPH1SIZE_GRPH1HEIGHT_LSBMASK (0x00000FFF)
+#define ODN_PDP_GRPH1SIZE_GRPH1HEIGHT_SHIFT (0)
+#define ODN_PDP_GRPH1SIZE_GRPH1HEIGHT_LENGTH (12)
+#define ODN_PDP_GRPH1SIZE_GRPH1HEIGHT_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH2SIZE_OFFSET (0x0084)
+
+/* PDP, GRPH2SIZE, GRPH2WIDTH
+*/
+#define ODN_PDP_GRPH2SIZE_GRPH2WIDTH_MASK (0x0FFF0000)
+#define ODN_PDP_GRPH2SIZE_GRPH2WIDTH_LSBMASK (0x00000FFF)
+#define ODN_PDP_GRPH2SIZE_GRPH2WIDTH_SHIFT (16)
+#define ODN_PDP_GRPH2SIZE_GRPH2WIDTH_LENGTH (12)
+#define ODN_PDP_GRPH2SIZE_GRPH2WIDTH_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2SIZE, GRPH2HEIGHT
+*/
+#define ODN_PDP_GRPH2SIZE_GRPH2HEIGHT_MASK (0x00000FFF)
+#define ODN_PDP_GRPH2SIZE_GRPH2HEIGHT_LSBMASK (0x00000FFF)
+#define ODN_PDP_GRPH2SIZE_GRPH2HEIGHT_SHIFT (0)
+#define ODN_PDP_GRPH2SIZE_GRPH2HEIGHT_LENGTH (12)
+#define ODN_PDP_GRPH2SIZE_GRPH2HEIGHT_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH3SIZE_OFFSET (0x0088)
+
+/* PDP, GRPH3SIZE, GRPH3WIDTH
+*/
+#define ODN_PDP_GRPH3SIZE_GRPH3WIDTH_MASK (0x0FFF0000)
+#define ODN_PDP_GRPH3SIZE_GRPH3WIDTH_LSBMASK (0x00000FFF)
+#define ODN_PDP_GRPH3SIZE_GRPH3WIDTH_SHIFT (16)
+#define ODN_PDP_GRPH3SIZE_GRPH3WIDTH_LENGTH (12)
+#define ODN_PDP_GRPH3SIZE_GRPH3WIDTH_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3SIZE, GRPH3HEIGHT
+*/
+#define ODN_PDP_GRPH3SIZE_GRPH3HEIGHT_MASK (0x00000FFF)
+#define ODN_PDP_GRPH3SIZE_GRPH3HEIGHT_LSBMASK (0x00000FFF)
+#define ODN_PDP_GRPH3SIZE_GRPH3HEIGHT_SHIFT (0)
+#define ODN_PDP_GRPH3SIZE_GRPH3HEIGHT_LENGTH (12)
+#define ODN_PDP_GRPH3SIZE_GRPH3HEIGHT_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH4SIZE_OFFSET (0x008C)
+
+/* PDP, GRPH4SIZE, GRPH4WIDTH
+*/
+#define ODN_PDP_GRPH4SIZE_GRPH4WIDTH_MASK (0x0FFF0000)
+#define ODN_PDP_GRPH4SIZE_GRPH4WIDTH_LSBMASK (0x00000FFF)
+#define ODN_PDP_GRPH4SIZE_GRPH4WIDTH_SHIFT (16)
+#define ODN_PDP_GRPH4SIZE_GRPH4WIDTH_LENGTH (12)
+#define ODN_PDP_GRPH4SIZE_GRPH4WIDTH_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4SIZE, GRPH4HEIGHT
+*/
+#define ODN_PDP_GRPH4SIZE_GRPH4HEIGHT_MASK (0x00000FFF)
+#define ODN_PDP_GRPH4SIZE_GRPH4HEIGHT_LSBMASK (0x00000FFF)
+#define ODN_PDP_GRPH4SIZE_GRPH4HEIGHT_SHIFT (0)
+#define ODN_PDP_GRPH4SIZE_GRPH4HEIGHT_LENGTH (12)
+#define ODN_PDP_GRPH4SIZE_GRPH4HEIGHT_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1SIZE_OFFSET (0x0090)
+
+/* PDP, VID1SIZE, VID1WIDTH
+*/
+#define ODN_PDP_VID1SIZE_VID1WIDTH_MASK (0x0FFF0000)
+#define ODN_PDP_VID1SIZE_VID1WIDTH_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID1SIZE_VID1WIDTH_SHIFT (16)
+#define ODN_PDP_VID1SIZE_VID1WIDTH_LENGTH (12)
+#define ODN_PDP_VID1SIZE_VID1WIDTH_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1SIZE, VID1HEIGHT
+*/
+#define ODN_PDP_VID1SIZE_VID1HEIGHT_MASK (0x00000FFF)
+#define ODN_PDP_VID1SIZE_VID1HEIGHT_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID1SIZE_VID1HEIGHT_SHIFT (0)
+#define ODN_PDP_VID1SIZE_VID1HEIGHT_LENGTH (12)
+#define ODN_PDP_VID1SIZE_VID1HEIGHT_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2SIZE_OFFSET (0x0094)
+
+/* PDP, VID2SIZE, VID2WIDTH
+*/
+#define ODN_PDP_VID2SIZE_VID2WIDTH_MASK (0x0FFF0000)
+#define ODN_PDP_VID2SIZE_VID2WIDTH_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID2SIZE_VID2WIDTH_SHIFT (16)
+#define ODN_PDP_VID2SIZE_VID2WIDTH_LENGTH (12)
+#define ODN_PDP_VID2SIZE_VID2WIDTH_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2SIZE, VID2HEIGHT
+*/
+#define ODN_PDP_VID2SIZE_VID2HEIGHT_MASK (0x00000FFF)
+#define ODN_PDP_VID2SIZE_VID2HEIGHT_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID2SIZE_VID2HEIGHT_SHIFT (0)
+#define ODN_PDP_VID2SIZE_VID2HEIGHT_LENGTH (12)
+#define ODN_PDP_VID2SIZE_VID2HEIGHT_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3SIZE_OFFSET (0x0098)
+
+/* PDP, VID3SIZE, VID3WIDTH
+*/
+#define ODN_PDP_VID3SIZE_VID3WIDTH_MASK (0x0FFF0000)
+#define ODN_PDP_VID3SIZE_VID3WIDTH_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID3SIZE_VID3WIDTH_SHIFT (16)
+#define ODN_PDP_VID3SIZE_VID3WIDTH_LENGTH (12)
+#define ODN_PDP_VID3SIZE_VID3WIDTH_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3SIZE, VID3HEIGHT
+*/
+#define ODN_PDP_VID3SIZE_VID3HEIGHT_MASK (0x00000FFF)
+#define ODN_PDP_VID3SIZE_VID3HEIGHT_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID3SIZE_VID3HEIGHT_SHIFT (0)
+#define ODN_PDP_VID3SIZE_VID3HEIGHT_LENGTH (12)
+#define ODN_PDP_VID3SIZE_VID3HEIGHT_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4SIZE_OFFSET (0x009C)
+
+/* PDP, VID4SIZE, VID4WIDTH
+*/
+#define ODN_PDP_VID4SIZE_VID4WIDTH_MASK (0x0FFF0000)
+#define ODN_PDP_VID4SIZE_VID4WIDTH_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID4SIZE_VID4WIDTH_SHIFT (16)
+#define ODN_PDP_VID4SIZE_VID4WIDTH_LENGTH (12)
+#define ODN_PDP_VID4SIZE_VID4WIDTH_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4SIZE, VID4HEIGHT
+*/
+#define ODN_PDP_VID4SIZE_VID4HEIGHT_MASK (0x00000FFF)
+#define ODN_PDP_VID4SIZE_VID4HEIGHT_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID4SIZE_VID4HEIGHT_SHIFT (0)
+#define ODN_PDP_VID4SIZE_VID4HEIGHT_LENGTH (12)
+#define ODN_PDP_VID4SIZE_VID4HEIGHT_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH1POSN_OFFSET (0x00A0)
+
+/* PDP, GRPH1POSN, GRPH1XSTART
+*/
+#define ODN_PDP_GRPH1POSN_GRPH1XSTART_MASK (0x0FFF0000)
+#define ODN_PDP_GRPH1POSN_GRPH1XSTART_LSBMASK (0x00000FFF)
+#define ODN_PDP_GRPH1POSN_GRPH1XSTART_SHIFT (16)
+#define ODN_PDP_GRPH1POSN_GRPH1XSTART_LENGTH (12)
+#define ODN_PDP_GRPH1POSN_GRPH1XSTART_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1POSN, GRPH1YSTART
+*/
+#define ODN_PDP_GRPH1POSN_GRPH1YSTART_MASK (0x00000FFF)
+#define ODN_PDP_GRPH1POSN_GRPH1YSTART_LSBMASK (0x00000FFF)
+#define ODN_PDP_GRPH1POSN_GRPH1YSTART_SHIFT (0)
+#define ODN_PDP_GRPH1POSN_GRPH1YSTART_LENGTH (12)
+#define ODN_PDP_GRPH1POSN_GRPH1YSTART_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH2POSN_OFFSET (0x00A4)
+
+/* PDP, GRPH2POSN, GRPH2XSTART
+*/
+#define ODN_PDP_GRPH2POSN_GRPH2XSTART_MASK (0x0FFF0000)
+#define ODN_PDP_GRPH2POSN_GRPH2XSTART_LSBMASK (0x00000FFF)
+#define ODN_PDP_GRPH2POSN_GRPH2XSTART_SHIFT (16)
+#define ODN_PDP_GRPH2POSN_GRPH2XSTART_LENGTH (12)
+#define ODN_PDP_GRPH2POSN_GRPH2XSTART_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2POSN, GRPH2YSTART
+*/
+#define ODN_PDP_GRPH2POSN_GRPH2YSTART_MASK (0x00000FFF)
+#define ODN_PDP_GRPH2POSN_GRPH2YSTART_LSBMASK (0x00000FFF)
+#define ODN_PDP_GRPH2POSN_GRPH2YSTART_SHIFT (0)
+#define ODN_PDP_GRPH2POSN_GRPH2YSTART_LENGTH (12)
+#define ODN_PDP_GRPH2POSN_GRPH2YSTART_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH3POSN_OFFSET (0x00A8)
+
+/* PDP, GRPH3POSN, GRPH3XSTART
+*/
+#define ODN_PDP_GRPH3POSN_GRPH3XSTART_MASK (0x0FFF0000)
+#define ODN_PDP_GRPH3POSN_GRPH3XSTART_LSBMASK (0x00000FFF)
+#define ODN_PDP_GRPH3POSN_GRPH3XSTART_SHIFT (16)
+#define ODN_PDP_GRPH3POSN_GRPH3XSTART_LENGTH (12)
+#define ODN_PDP_GRPH3POSN_GRPH3XSTART_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3POSN, GRPH3YSTART
+*/
+#define ODN_PDP_GRPH3POSN_GRPH3YSTART_MASK (0x00000FFF)
+#define ODN_PDP_GRPH3POSN_GRPH3YSTART_LSBMASK (0x00000FFF)
+#define ODN_PDP_GRPH3POSN_GRPH3YSTART_SHIFT (0)
+#define ODN_PDP_GRPH3POSN_GRPH3YSTART_LENGTH (12)
+#define ODN_PDP_GRPH3POSN_GRPH3YSTART_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH4POSN_OFFSET (0x00AC)
+
+/* PDP, GRPH4POSN, GRPH4XSTART
+*/
+#define ODN_PDP_GRPH4POSN_GRPH4XSTART_MASK (0x0FFF0000)
+#define ODN_PDP_GRPH4POSN_GRPH4XSTART_LSBMASK (0x00000FFF)
+#define ODN_PDP_GRPH4POSN_GRPH4XSTART_SHIFT (16)
+#define ODN_PDP_GRPH4POSN_GRPH4XSTART_LENGTH (12)
+#define ODN_PDP_GRPH4POSN_GRPH4XSTART_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4POSN, GRPH4YSTART
+*/
+#define ODN_PDP_GRPH4POSN_GRPH4YSTART_MASK (0x00000FFF)
+#define ODN_PDP_GRPH4POSN_GRPH4YSTART_LSBMASK (0x00000FFF)
+#define ODN_PDP_GRPH4POSN_GRPH4YSTART_SHIFT (0)
+#define ODN_PDP_GRPH4POSN_GRPH4YSTART_LENGTH (12)
+#define ODN_PDP_GRPH4POSN_GRPH4YSTART_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1POSN_OFFSET (0x00B0)
+
+/* PDP, VID1POSN, VID1XSTART
+*/
+#define ODN_PDP_VID1POSN_VID1XSTART_MASK (0x0FFF0000)
+#define ODN_PDP_VID1POSN_VID1XSTART_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID1POSN_VID1XSTART_SHIFT (16)
+#define ODN_PDP_VID1POSN_VID1XSTART_LENGTH (12)
+#define ODN_PDP_VID1POSN_VID1XSTART_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1POSN, VID1YSTART
+*/
+#define ODN_PDP_VID1POSN_VID1YSTART_MASK (0x00000FFF)
+#define ODN_PDP_VID1POSN_VID1YSTART_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID1POSN_VID1YSTART_SHIFT (0)
+#define ODN_PDP_VID1POSN_VID1YSTART_LENGTH (12)
+#define ODN_PDP_VID1POSN_VID1YSTART_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2POSN_OFFSET (0x00B4)
+
+/* PDP, VID2POSN, VID2XSTART
+*/
+#define ODN_PDP_VID2POSN_VID2XSTART_MASK (0x0FFF0000)
+#define ODN_PDP_VID2POSN_VID2XSTART_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID2POSN_VID2XSTART_SHIFT (16)
+#define ODN_PDP_VID2POSN_VID2XSTART_LENGTH (12)
+#define ODN_PDP_VID2POSN_VID2XSTART_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2POSN, VID2YSTART
+*/
+#define ODN_PDP_VID2POSN_VID2YSTART_MASK (0x00000FFF)
+#define ODN_PDP_VID2POSN_VID2YSTART_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID2POSN_VID2YSTART_SHIFT (0)
+#define ODN_PDP_VID2POSN_VID2YSTART_LENGTH (12)
+#define ODN_PDP_VID2POSN_VID2YSTART_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3POSN_OFFSET (0x00B8)
+
+/* PDP, VID3POSN, VID3XSTART
+*/
+#define ODN_PDP_VID3POSN_VID3XSTART_MASK (0x0FFF0000)
+#define ODN_PDP_VID3POSN_VID3XSTART_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID3POSN_VID3XSTART_SHIFT (16)
+#define ODN_PDP_VID3POSN_VID3XSTART_LENGTH (12)
+#define ODN_PDP_VID3POSN_VID3XSTART_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3POSN, VID3YSTART
+*/
+#define ODN_PDP_VID3POSN_VID3YSTART_MASK (0x00000FFF)
+#define ODN_PDP_VID3POSN_VID3YSTART_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID3POSN_VID3YSTART_SHIFT (0)
+#define ODN_PDP_VID3POSN_VID3YSTART_LENGTH (12)
+#define ODN_PDP_VID3POSN_VID3YSTART_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4POSN_OFFSET (0x00BC)
+
+/* PDP, VID4POSN, VID4XSTART
+*/
+#define ODN_PDP_VID4POSN_VID4XSTART_MASK (0x0FFF0000)
+#define ODN_PDP_VID4POSN_VID4XSTART_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID4POSN_VID4XSTART_SHIFT (16)
+#define ODN_PDP_VID4POSN_VID4XSTART_LENGTH (12)
+#define ODN_PDP_VID4POSN_VID4XSTART_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4POSN, VID4YSTART
+*/
+#define ODN_PDP_VID4POSN_VID4YSTART_MASK (0x00000FFF)
+#define ODN_PDP_VID4POSN_VID4YSTART_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID4POSN_VID4YSTART_SHIFT (0)
+#define ODN_PDP_VID4POSN_VID4YSTART_LENGTH (12)
+#define ODN_PDP_VID4POSN_VID4YSTART_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH1GALPHA_OFFSET (0x00C0)
+
+/* PDP, GRPH1GALPHA, GRPH1GALPHA
+*/
+#define ODN_PDP_GRPH1GALPHA_GRPH1GALPHA_MASK (0x000003FF)
+#define ODN_PDP_GRPH1GALPHA_GRPH1GALPHA_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH1GALPHA_GRPH1GALPHA_SHIFT (0)
+#define ODN_PDP_GRPH1GALPHA_GRPH1GALPHA_LENGTH (10)
+#define ODN_PDP_GRPH1GALPHA_GRPH1GALPHA_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH2GALPHA_OFFSET (0x00C4)
+
+/* PDP, GRPH2GALPHA, GRPH2GALPHA
+*/
+#define ODN_PDP_GRPH2GALPHA_GRPH2GALPHA_MASK (0x000003FF)
+#define ODN_PDP_GRPH2GALPHA_GRPH2GALPHA_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH2GALPHA_GRPH2GALPHA_SHIFT (0)
+#define ODN_PDP_GRPH2GALPHA_GRPH2GALPHA_LENGTH (10)
+#define ODN_PDP_GRPH2GALPHA_GRPH2GALPHA_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH3GALPHA_OFFSET (0x00C8)
+
+/* PDP, GRPH3GALPHA, GRPH3GALPHA
+*/
+#define ODN_PDP_GRPH3GALPHA_GRPH3GALPHA_MASK (0x000003FF)
+#define ODN_PDP_GRPH3GALPHA_GRPH3GALPHA_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH3GALPHA_GRPH3GALPHA_SHIFT (0)
+#define ODN_PDP_GRPH3GALPHA_GRPH3GALPHA_LENGTH (10)
+#define ODN_PDP_GRPH3GALPHA_GRPH3GALPHA_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH4GALPHA_OFFSET (0x00CC)
+
+/* PDP, GRPH4GALPHA, GRPH4GALPHA
+*/
+#define ODN_PDP_GRPH4GALPHA_GRPH4GALPHA_MASK (0x000003FF)
+#define ODN_PDP_GRPH4GALPHA_GRPH4GALPHA_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH4GALPHA_GRPH4GALPHA_SHIFT (0)
+#define ODN_PDP_GRPH4GALPHA_GRPH4GALPHA_LENGTH (10)
+#define ODN_PDP_GRPH4GALPHA_GRPH4GALPHA_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1GALPHA_OFFSET (0x00D0)
+
+/* PDP, VID1GALPHA, VID1GALPHA
+*/
+#define ODN_PDP_VID1GALPHA_VID1GALPHA_MASK (0x000003FF)
+#define ODN_PDP_VID1GALPHA_VID1GALPHA_LSBMASK (0x000003FF)
+#define ODN_PDP_VID1GALPHA_VID1GALPHA_SHIFT (0)
+#define ODN_PDP_VID1GALPHA_VID1GALPHA_LENGTH (10)
+#define ODN_PDP_VID1GALPHA_VID1GALPHA_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2GALPHA_OFFSET (0x00D4)
+
+/* PDP, VID2GALPHA, VID2GALPHA
+*/
+#define ODN_PDP_VID2GALPHA_VID2GALPHA_MASK (0x000003FF)
+#define ODN_PDP_VID2GALPHA_VID2GALPHA_LSBMASK (0x000003FF)
+#define ODN_PDP_VID2GALPHA_VID2GALPHA_SHIFT (0)
+#define ODN_PDP_VID2GALPHA_VID2GALPHA_LENGTH (10)
+#define ODN_PDP_VID2GALPHA_VID2GALPHA_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3GALPHA_OFFSET (0x00D8)
+
+/* PDP, VID3GALPHA, VID3GALPHA
+*/
+#define ODN_PDP_VID3GALPHA_VID3GALPHA_MASK (0x000003FF)
+#define ODN_PDP_VID3GALPHA_VID3GALPHA_LSBMASK (0x000003FF)
+#define ODN_PDP_VID3GALPHA_VID3GALPHA_SHIFT (0)
+#define ODN_PDP_VID3GALPHA_VID3GALPHA_LENGTH (10)
+#define ODN_PDP_VID3GALPHA_VID3GALPHA_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4GALPHA_OFFSET (0x00DC)
+
+/* PDP, VID4GALPHA, VID4GALPHA
+*/
+#define ODN_PDP_VID4GALPHA_VID4GALPHA_MASK (0x000003FF)
+#define ODN_PDP_VID4GALPHA_VID4GALPHA_LSBMASK (0x000003FF)
+#define ODN_PDP_VID4GALPHA_VID4GALPHA_SHIFT (0)
+#define ODN_PDP_VID4GALPHA_VID4GALPHA_LENGTH (10)
+#define ODN_PDP_VID4GALPHA_VID4GALPHA_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH1CKEY_R_OFFSET (0x00E0)
+
+/* PDP, GRPH1CKEY_R, GRPH1CKEY_R
+*/
+#define ODN_PDP_GRPH1CKEY_R_GRPH1CKEY_R_MASK (0x000003FF)
+#define ODN_PDP_GRPH1CKEY_R_GRPH1CKEY_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH1CKEY_R_GRPH1CKEY_R_SHIFT (0)
+#define ODN_PDP_GRPH1CKEY_R_GRPH1CKEY_R_LENGTH (10)
+#define ODN_PDP_GRPH1CKEY_R_GRPH1CKEY_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH1CKEY_GB_OFFSET (0x00E4)
+
+/* PDP, GRPH1CKEY_GB, GRPH1CKEY_G
+*/
+#define ODN_PDP_GRPH1CKEY_GB_GRPH1CKEY_G_MASK (0x03FF0000)
+#define ODN_PDP_GRPH1CKEY_GB_GRPH1CKEY_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH1CKEY_GB_GRPH1CKEY_G_SHIFT (16)
+#define ODN_PDP_GRPH1CKEY_GB_GRPH1CKEY_G_LENGTH (10)
+#define ODN_PDP_GRPH1CKEY_GB_GRPH1CKEY_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1CKEY_GB, GRPH1CKEY_B
+*/
+#define ODN_PDP_GRPH1CKEY_GB_GRPH1CKEY_B_MASK (0x000003FF)
+#define ODN_PDP_GRPH1CKEY_GB_GRPH1CKEY_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH1CKEY_GB_GRPH1CKEY_B_SHIFT (0)
+#define ODN_PDP_GRPH1CKEY_GB_GRPH1CKEY_B_LENGTH (10)
+#define ODN_PDP_GRPH1CKEY_GB_GRPH1CKEY_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH2CKEY_R_OFFSET (0x00E8)
+
+/* PDP, GRPH2CKEY_R, GRPH2CKEY_R
+*/
+#define ODN_PDP_GRPH2CKEY_R_GRPH2CKEY_R_MASK (0x000003FF)
+#define ODN_PDP_GRPH2CKEY_R_GRPH2CKEY_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH2CKEY_R_GRPH2CKEY_R_SHIFT (0)
+#define ODN_PDP_GRPH2CKEY_R_GRPH2CKEY_R_LENGTH (10)
+#define ODN_PDP_GRPH2CKEY_R_GRPH2CKEY_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH2CKEY_GB_OFFSET (0x00EC)
+
+/* PDP, GRPH2CKEY_GB, GRPH2CKEY_G
+*/
+#define ODN_PDP_GRPH2CKEY_GB_GRPH2CKEY_G_MASK (0x03FF0000)
+#define ODN_PDP_GRPH2CKEY_GB_GRPH2CKEY_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH2CKEY_GB_GRPH2CKEY_G_SHIFT (16)
+#define ODN_PDP_GRPH2CKEY_GB_GRPH2CKEY_G_LENGTH (10)
+#define ODN_PDP_GRPH2CKEY_GB_GRPH2CKEY_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2CKEY_GB, GRPH2CKEY_B
+*/
+#define ODN_PDP_GRPH2CKEY_GB_GRPH2CKEY_B_MASK (0x000003FF)
+#define ODN_PDP_GRPH2CKEY_GB_GRPH2CKEY_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH2CKEY_GB_GRPH2CKEY_B_SHIFT (0)
+#define ODN_PDP_GRPH2CKEY_GB_GRPH2CKEY_B_LENGTH (10)
+#define ODN_PDP_GRPH2CKEY_GB_GRPH2CKEY_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH3CKEY_R_OFFSET (0x00F0)
+
+/* PDP, GRPH3CKEY_R, GRPH3CKEY_R
+*/
+#define ODN_PDP_GRPH3CKEY_R_GRPH3CKEY_R_MASK (0x000003FF)
+#define ODN_PDP_GRPH3CKEY_R_GRPH3CKEY_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH3CKEY_R_GRPH3CKEY_R_SHIFT (0)
+#define ODN_PDP_GRPH3CKEY_R_GRPH3CKEY_R_LENGTH (10)
+#define ODN_PDP_GRPH3CKEY_R_GRPH3CKEY_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH3CKEY_GB_OFFSET (0x00F4)
+
+/* PDP, GRPH3CKEY_GB, GRPH3CKEY_G
+*/
+#define ODN_PDP_GRPH3CKEY_GB_GRPH3CKEY_G_MASK (0x03FF0000)
+#define ODN_PDP_GRPH3CKEY_GB_GRPH3CKEY_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH3CKEY_GB_GRPH3CKEY_G_SHIFT (16)
+#define ODN_PDP_GRPH3CKEY_GB_GRPH3CKEY_G_LENGTH (10)
+#define ODN_PDP_GRPH3CKEY_GB_GRPH3CKEY_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3CKEY_GB, GRPH3CKEY_B
+*/
+#define ODN_PDP_GRPH3CKEY_GB_GRPH3CKEY_B_MASK (0x000003FF)
+#define ODN_PDP_GRPH3CKEY_GB_GRPH3CKEY_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH3CKEY_GB_GRPH3CKEY_B_SHIFT (0)
+#define ODN_PDP_GRPH3CKEY_GB_GRPH3CKEY_B_LENGTH (10)
+#define ODN_PDP_GRPH3CKEY_GB_GRPH3CKEY_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH4CKEY_R_OFFSET (0x00F8)
+
+/* PDP, GRPH4CKEY_R, GRPH4CKEY_R
+*/
+#define ODN_PDP_GRPH4CKEY_R_GRPH4CKEY_R_MASK (0x000003FF)
+#define ODN_PDP_GRPH4CKEY_R_GRPH4CKEY_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH4CKEY_R_GRPH4CKEY_R_SHIFT (0)
+#define ODN_PDP_GRPH4CKEY_R_GRPH4CKEY_R_LENGTH (10)
+#define ODN_PDP_GRPH4CKEY_R_GRPH4CKEY_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH4CKEY_GB_OFFSET (0x00FC)
+
+/* PDP, GRPH4CKEY_GB, GRPH4CKEY_G
+*/
+#define ODN_PDP_GRPH4CKEY_GB_GRPH4CKEY_G_MASK (0x03FF0000)
+#define ODN_PDP_GRPH4CKEY_GB_GRPH4CKEY_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH4CKEY_GB_GRPH4CKEY_G_SHIFT (16)
+#define ODN_PDP_GRPH4CKEY_GB_GRPH4CKEY_G_LENGTH (10)
+#define ODN_PDP_GRPH4CKEY_GB_GRPH4CKEY_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4CKEY_GB, GRPH4CKEY_B
+*/
+#define ODN_PDP_GRPH4CKEY_GB_GRPH4CKEY_B_MASK (0x000003FF)
+#define ODN_PDP_GRPH4CKEY_GB_GRPH4CKEY_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH4CKEY_GB_GRPH4CKEY_B_SHIFT (0)
+#define ODN_PDP_GRPH4CKEY_GB_GRPH4CKEY_B_LENGTH (10)
+#define ODN_PDP_GRPH4CKEY_GB_GRPH4CKEY_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1CKEY_R_OFFSET (0x0100)
+
+/* PDP, VID1CKEY_R, VID1CKEY_R
+*/
+#define ODN_PDP_VID1CKEY_R_VID1CKEY_R_MASK (0x000003FF)
+#define ODN_PDP_VID1CKEY_R_VID1CKEY_R_LSBMASK (0x000003FF)
+#define ODN_PDP_VID1CKEY_R_VID1CKEY_R_SHIFT (0)
+#define ODN_PDP_VID1CKEY_R_VID1CKEY_R_LENGTH (10)
+#define ODN_PDP_VID1CKEY_R_VID1CKEY_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1CKEY_GB_OFFSET (0x0104)
+
+/* PDP, VID1CKEY_GB, VID1CKEY_G
+*/
+#define ODN_PDP_VID1CKEY_GB_VID1CKEY_G_MASK (0x03FF0000)
+#define ODN_PDP_VID1CKEY_GB_VID1CKEY_G_LSBMASK (0x000003FF)
+#define ODN_PDP_VID1CKEY_GB_VID1CKEY_G_SHIFT (16)
+#define ODN_PDP_VID1CKEY_GB_VID1CKEY_G_LENGTH (10)
+#define ODN_PDP_VID1CKEY_GB_VID1CKEY_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1CKEY_GB, VID1CKEY_B
+*/
+#define ODN_PDP_VID1CKEY_GB_VID1CKEY_B_MASK (0x000003FF)
+#define ODN_PDP_VID1CKEY_GB_VID1CKEY_B_LSBMASK (0x000003FF)
+#define ODN_PDP_VID1CKEY_GB_VID1CKEY_B_SHIFT (0)
+#define ODN_PDP_VID1CKEY_GB_VID1CKEY_B_LENGTH (10)
+#define ODN_PDP_VID1CKEY_GB_VID1CKEY_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2CKEY_R_OFFSET (0x0108)
+
+/* PDP, VID2CKEY_R, VID2CKEY_R
+*/
+#define ODN_PDP_VID2CKEY_R_VID2CKEY_R_MASK (0x000003FF)
+#define ODN_PDP_VID2CKEY_R_VID2CKEY_R_LSBMASK (0x000003FF)
+#define ODN_PDP_VID2CKEY_R_VID2CKEY_R_SHIFT (0)
+#define ODN_PDP_VID2CKEY_R_VID2CKEY_R_LENGTH (10)
+#define ODN_PDP_VID2CKEY_R_VID2CKEY_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2CKEY_GB_OFFSET (0x010C)
+
+/* PDP, VID2CKEY_GB, VID2CKEY_G
+*/
+#define ODN_PDP_VID2CKEY_GB_VID2CKEY_G_MASK (0x03FF0000)
+#define ODN_PDP_VID2CKEY_GB_VID2CKEY_G_LSBMASK (0x000003FF)
+#define ODN_PDP_VID2CKEY_GB_VID2CKEY_G_SHIFT (16)
+#define ODN_PDP_VID2CKEY_GB_VID2CKEY_G_LENGTH (10)
+#define ODN_PDP_VID2CKEY_GB_VID2CKEY_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2CKEY_GB, VID2CKEY_B
+*/
+#define ODN_PDP_VID2CKEY_GB_VID2CKEY_B_MASK (0x000003FF)
+#define ODN_PDP_VID2CKEY_GB_VID2CKEY_B_LSBMASK (0x000003FF)
+#define ODN_PDP_VID2CKEY_GB_VID2CKEY_B_SHIFT (0)
+#define ODN_PDP_VID2CKEY_GB_VID2CKEY_B_LENGTH (10)
+#define ODN_PDP_VID2CKEY_GB_VID2CKEY_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3CKEY_R_OFFSET (0x0110)
+
+/* PDP, VID3CKEY_R, VID3CKEY_R
+*/
+#define ODN_PDP_VID3CKEY_R_VID3CKEY_R_MASK (0x000003FF)
+#define ODN_PDP_VID3CKEY_R_VID3CKEY_R_LSBMASK (0x000003FF)
+#define ODN_PDP_VID3CKEY_R_VID3CKEY_R_SHIFT (0)
+#define ODN_PDP_VID3CKEY_R_VID3CKEY_R_LENGTH (10)
+#define ODN_PDP_VID3CKEY_R_VID3CKEY_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3CKEY_GB_OFFSET (0x0114)
+
+/* PDP, VID3CKEY_GB, VID3CKEY_G
+*/
+#define ODN_PDP_VID3CKEY_GB_VID3CKEY_G_MASK (0x03FF0000)
+#define ODN_PDP_VID3CKEY_GB_VID3CKEY_G_LSBMASK (0x000003FF)
+#define ODN_PDP_VID3CKEY_GB_VID3CKEY_G_SHIFT (16)
+#define ODN_PDP_VID3CKEY_GB_VID3CKEY_G_LENGTH (10)
+#define ODN_PDP_VID3CKEY_GB_VID3CKEY_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3CKEY_GB, VID3CKEY_B
+*/
+#define ODN_PDP_VID3CKEY_GB_VID3CKEY_B_MASK (0x000003FF)
+#define ODN_PDP_VID3CKEY_GB_VID3CKEY_B_LSBMASK (0x000003FF)
+#define ODN_PDP_VID3CKEY_GB_VID3CKEY_B_SHIFT (0)
+#define ODN_PDP_VID3CKEY_GB_VID3CKEY_B_LENGTH (10)
+#define ODN_PDP_VID3CKEY_GB_VID3CKEY_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4CKEY_R_OFFSET (0x0118)
+
+/* PDP, VID4CKEY_R, VID4CKEY_R
+*/
+#define ODN_PDP_VID4CKEY_R_VID4CKEY_R_MASK (0x000003FF)
+#define ODN_PDP_VID4CKEY_R_VID4CKEY_R_LSBMASK (0x000003FF)
+#define ODN_PDP_VID4CKEY_R_VID4CKEY_R_SHIFT (0)
+#define ODN_PDP_VID4CKEY_R_VID4CKEY_R_LENGTH (10)
+#define ODN_PDP_VID4CKEY_R_VID4CKEY_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4CKEY_GB_OFFSET (0x011C)
+
+/* PDP, VID4CKEY_GB, VID4CKEY_G
+*/
+#define ODN_PDP_VID4CKEY_GB_VID4CKEY_G_MASK (0x03FF0000)
+#define ODN_PDP_VID4CKEY_GB_VID4CKEY_G_LSBMASK (0x000003FF)
+#define ODN_PDP_VID4CKEY_GB_VID4CKEY_G_SHIFT (16)
+#define ODN_PDP_VID4CKEY_GB_VID4CKEY_G_LENGTH (10)
+#define ODN_PDP_VID4CKEY_GB_VID4CKEY_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4CKEY_GB, VID4CKEY_B
+*/
+#define ODN_PDP_VID4CKEY_GB_VID4CKEY_B_MASK (0x000003FF)
+#define ODN_PDP_VID4CKEY_GB_VID4CKEY_B_LSBMASK (0x000003FF)
+#define ODN_PDP_VID4CKEY_GB_VID4CKEY_B_SHIFT (0)
+#define ODN_PDP_VID4CKEY_GB_VID4CKEY_B_LENGTH (10)
+#define ODN_PDP_VID4CKEY_GB_VID4CKEY_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH1BLND2_R_OFFSET (0x0120)
+
+/* PDP, GRPH1BLND2_R, GRPH1PIXDBL
+*/
+#define ODN_PDP_GRPH1BLND2_R_GRPH1PIXDBL_MASK (0x80000000)
+#define ODN_PDP_GRPH1BLND2_R_GRPH1PIXDBL_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH1BLND2_R_GRPH1PIXDBL_SHIFT (31)
+#define ODN_PDP_GRPH1BLND2_R_GRPH1PIXDBL_LENGTH (1)
+#define ODN_PDP_GRPH1BLND2_R_GRPH1PIXDBL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1BLND2_R, GRPH1LINDBL
+*/
+#define ODN_PDP_GRPH1BLND2_R_GRPH1LINDBL_MASK (0x20000000)
+#define ODN_PDP_GRPH1BLND2_R_GRPH1LINDBL_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH1BLND2_R_GRPH1LINDBL_SHIFT (29)
+#define ODN_PDP_GRPH1BLND2_R_GRPH1LINDBL_LENGTH (1)
+#define ODN_PDP_GRPH1BLND2_R_GRPH1LINDBL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1BLND2_R, GRPH1CKEYMASK_R
+*/
+#define ODN_PDP_GRPH1BLND2_R_GRPH1CKEYMASK_R_MASK (0x000003FF)
+#define ODN_PDP_GRPH1BLND2_R_GRPH1CKEYMASK_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH1BLND2_R_GRPH1CKEYMASK_R_SHIFT (0)
+#define ODN_PDP_GRPH1BLND2_R_GRPH1CKEYMASK_R_LENGTH (10)
+#define ODN_PDP_GRPH1BLND2_R_GRPH1CKEYMASK_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH1BLND2_GB_OFFSET (0x0124)
+
+/* PDP, GRPH1BLND2_GB, GRPH1CKEYMASK_G
+*/
+#define ODN_PDP_GRPH1BLND2_GB_GRPH1CKEYMASK_G_MASK (0x03FF0000)
+#define ODN_PDP_GRPH1BLND2_GB_GRPH1CKEYMASK_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH1BLND2_GB_GRPH1CKEYMASK_G_SHIFT (16)
+#define ODN_PDP_GRPH1BLND2_GB_GRPH1CKEYMASK_G_LENGTH (10)
+#define ODN_PDP_GRPH1BLND2_GB_GRPH1CKEYMASK_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1BLND2_GB, GRPH1CKEYMASK_B
+*/
+#define ODN_PDP_GRPH1BLND2_GB_GRPH1CKEYMASK_B_MASK (0x000003FF)
+#define ODN_PDP_GRPH1BLND2_GB_GRPH1CKEYMASK_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH1BLND2_GB_GRPH1CKEYMASK_B_SHIFT (0)
+#define ODN_PDP_GRPH1BLND2_GB_GRPH1CKEYMASK_B_LENGTH (10)
+#define ODN_PDP_GRPH1BLND2_GB_GRPH1CKEYMASK_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH2BLND2_R_OFFSET (0x0128)
+
+/* PDP, GRPH2BLND2_R, GRPH2PIXDBL
+*/
+#define ODN_PDP_GRPH2BLND2_R_GRPH2PIXDBL_MASK (0x80000000)
+#define ODN_PDP_GRPH2BLND2_R_GRPH2PIXDBL_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH2BLND2_R_GRPH2PIXDBL_SHIFT (31)
+#define ODN_PDP_GRPH2BLND2_R_GRPH2PIXDBL_LENGTH (1)
+#define ODN_PDP_GRPH2BLND2_R_GRPH2PIXDBL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2BLND2_R, GRPH2LINDBL
+*/
+#define ODN_PDP_GRPH2BLND2_R_GRPH2LINDBL_MASK (0x20000000)
+#define ODN_PDP_GRPH2BLND2_R_GRPH2LINDBL_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH2BLND2_R_GRPH2LINDBL_SHIFT (29)
+#define ODN_PDP_GRPH2BLND2_R_GRPH2LINDBL_LENGTH (1)
+#define ODN_PDP_GRPH2BLND2_R_GRPH2LINDBL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2BLND2_R, GRPH2CKEYMASK_R
+*/
+#define ODN_PDP_GRPH2BLND2_R_GRPH2CKEYMASK_R_MASK (0x000003FF)
+#define ODN_PDP_GRPH2BLND2_R_GRPH2CKEYMASK_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH2BLND2_R_GRPH2CKEYMASK_R_SHIFT (0)
+#define ODN_PDP_GRPH2BLND2_R_GRPH2CKEYMASK_R_LENGTH (10)
+#define ODN_PDP_GRPH2BLND2_R_GRPH2CKEYMASK_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH2BLND2_GB_OFFSET (0x012C)
+
+/* PDP, GRPH2BLND2_GB, GRPH2CKEYMASK_G
+*/
+#define ODN_PDP_GRPH2BLND2_GB_GRPH2CKEYMASK_G_MASK (0x03FF0000)
+#define ODN_PDP_GRPH2BLND2_GB_GRPH2CKEYMASK_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH2BLND2_GB_GRPH2CKEYMASK_G_SHIFT (16)
+#define ODN_PDP_GRPH2BLND2_GB_GRPH2CKEYMASK_G_LENGTH (10)
+#define ODN_PDP_GRPH2BLND2_GB_GRPH2CKEYMASK_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2BLND2_GB, GRPH2CKEYMASK_B
+*/
+#define ODN_PDP_GRPH2BLND2_GB_GRPH2CKEYMASK_B_MASK (0x000003FF)
+#define ODN_PDP_GRPH2BLND2_GB_GRPH2CKEYMASK_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH2BLND2_GB_GRPH2CKEYMASK_B_SHIFT (0)
+#define ODN_PDP_GRPH2BLND2_GB_GRPH2CKEYMASK_B_LENGTH (10)
+#define ODN_PDP_GRPH2BLND2_GB_GRPH2CKEYMASK_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH3BLND2_R_OFFSET (0x0130)
+
+/* PDP, GRPH3BLND2_R, GRPH3PIXDBL
+*/
+#define ODN_PDP_GRPH3BLND2_R_GRPH3PIXDBL_MASK (0x80000000)
+#define ODN_PDP_GRPH3BLND2_R_GRPH3PIXDBL_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH3BLND2_R_GRPH3PIXDBL_SHIFT (31)
+#define ODN_PDP_GRPH3BLND2_R_GRPH3PIXDBL_LENGTH (1)
+#define ODN_PDP_GRPH3BLND2_R_GRPH3PIXDBL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3BLND2_R, GRPH3LINDBL
+*/
+#define ODN_PDP_GRPH3BLND2_R_GRPH3LINDBL_MASK (0x20000000)
+#define ODN_PDP_GRPH3BLND2_R_GRPH3LINDBL_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH3BLND2_R_GRPH3LINDBL_SHIFT (29)
+#define ODN_PDP_GRPH3BLND2_R_GRPH3LINDBL_LENGTH (1)
+#define ODN_PDP_GRPH3BLND2_R_GRPH3LINDBL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3BLND2_R, GRPH3CKEYMASK_R
+*/
+#define ODN_PDP_GRPH3BLND2_R_GRPH3CKEYMASK_R_MASK (0x000003FF)
+#define ODN_PDP_GRPH3BLND2_R_GRPH3CKEYMASK_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH3BLND2_R_GRPH3CKEYMASK_R_SHIFT (0)
+#define ODN_PDP_GRPH3BLND2_R_GRPH3CKEYMASK_R_LENGTH (10)
+#define ODN_PDP_GRPH3BLND2_R_GRPH3CKEYMASK_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH3BLND2_GB_OFFSET (0x0134)
+
+/* PDP, GRPH3BLND2_GB, GRPH3CKEYMASK_G
+*/
+#define ODN_PDP_GRPH3BLND2_GB_GRPH3CKEYMASK_G_MASK (0x03FF0000)
+#define ODN_PDP_GRPH3BLND2_GB_GRPH3CKEYMASK_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH3BLND2_GB_GRPH3CKEYMASK_G_SHIFT (16)
+#define ODN_PDP_GRPH3BLND2_GB_GRPH3CKEYMASK_G_LENGTH (10)
+#define ODN_PDP_GRPH3BLND2_GB_GRPH3CKEYMASK_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3BLND2_GB, GRPH3CKEYMASK_B
+*/
+#define ODN_PDP_GRPH3BLND2_GB_GRPH3CKEYMASK_B_MASK (0x000003FF)
+#define ODN_PDP_GRPH3BLND2_GB_GRPH3CKEYMASK_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH3BLND2_GB_GRPH3CKEYMASK_B_SHIFT (0)
+#define ODN_PDP_GRPH3BLND2_GB_GRPH3CKEYMASK_B_LENGTH (10)
+#define ODN_PDP_GRPH3BLND2_GB_GRPH3CKEYMASK_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH4BLND2_R_OFFSET (0x0138)
+
+/* PDP, GRPH4BLND2_R, GRPH4PIXDBL
+*/
+#define ODN_PDP_GRPH4BLND2_R_GRPH4PIXDBL_MASK (0x80000000)
+#define ODN_PDP_GRPH4BLND2_R_GRPH4PIXDBL_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH4BLND2_R_GRPH4PIXDBL_SHIFT (31)
+#define ODN_PDP_GRPH4BLND2_R_GRPH4PIXDBL_LENGTH (1)
+#define ODN_PDP_GRPH4BLND2_R_GRPH4PIXDBL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4BLND2_R, GRPH4LINDBL
+*/
+#define ODN_PDP_GRPH4BLND2_R_GRPH4LINDBL_MASK (0x20000000)
+#define ODN_PDP_GRPH4BLND2_R_GRPH4LINDBL_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH4BLND2_R_GRPH4LINDBL_SHIFT (29)
+#define ODN_PDP_GRPH4BLND2_R_GRPH4LINDBL_LENGTH (1)
+#define ODN_PDP_GRPH4BLND2_R_GRPH4LINDBL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4BLND2_R, GRPH4CKEYMASK_R
+*/
+#define ODN_PDP_GRPH4BLND2_R_GRPH4CKEYMASK_R_MASK (0x000003FF)
+#define ODN_PDP_GRPH4BLND2_R_GRPH4CKEYMASK_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH4BLND2_R_GRPH4CKEYMASK_R_SHIFT (0)
+#define ODN_PDP_GRPH4BLND2_R_GRPH4CKEYMASK_R_LENGTH (10)
+#define ODN_PDP_GRPH4BLND2_R_GRPH4CKEYMASK_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH4BLND2_GB_OFFSET (0x013C)
+
+/* PDP, GRPH4BLND2_GB, GRPH4CKEYMASK_G
+*/
+#define ODN_PDP_GRPH4BLND2_GB_GRPH4CKEYMASK_G_MASK (0x03FF0000)
+#define ODN_PDP_GRPH4BLND2_GB_GRPH4CKEYMASK_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH4BLND2_GB_GRPH4CKEYMASK_G_SHIFT (16)
+#define ODN_PDP_GRPH4BLND2_GB_GRPH4CKEYMASK_G_LENGTH (10)
+#define ODN_PDP_GRPH4BLND2_GB_GRPH4CKEYMASK_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4BLND2_GB, GRPH4CKEYMASK_B
+*/
+#define ODN_PDP_GRPH4BLND2_GB_GRPH4CKEYMASK_B_MASK (0x000003FF)
+#define ODN_PDP_GRPH4BLND2_GB_GRPH4CKEYMASK_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GRPH4BLND2_GB_GRPH4CKEYMASK_B_SHIFT (0)
+#define ODN_PDP_GRPH4BLND2_GB_GRPH4CKEYMASK_B_LENGTH (10)
+#define ODN_PDP_GRPH4BLND2_GB_GRPH4CKEYMASK_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1BLND2_R_OFFSET (0x0140)
+
+/* PDP, VID1BLND2_R, VID1CKEYMASK_R
+*/
+#define ODN_PDP_VID1BLND2_R_VID1CKEYMASK_R_MASK (0x000003FF)
+#define ODN_PDP_VID1BLND2_R_VID1CKEYMASK_R_LSBMASK (0x000003FF)
+#define ODN_PDP_VID1BLND2_R_VID1CKEYMASK_R_SHIFT (0)
+#define ODN_PDP_VID1BLND2_R_VID1CKEYMASK_R_LENGTH (10)
+#define ODN_PDP_VID1BLND2_R_VID1CKEYMASK_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1BLND2_GB_OFFSET (0x0144)
+
+/* PDP, VID1BLND2_GB, VID1CKEYMASK_G
+*/
+#define ODN_PDP_VID1BLND2_GB_VID1CKEYMASK_G_MASK (0x03FF0000)
+#define ODN_PDP_VID1BLND2_GB_VID1CKEYMASK_G_LSBMASK (0x000003FF)
+#define ODN_PDP_VID1BLND2_GB_VID1CKEYMASK_G_SHIFT (16)
+#define ODN_PDP_VID1BLND2_GB_VID1CKEYMASK_G_LENGTH (10)
+#define ODN_PDP_VID1BLND2_GB_VID1CKEYMASK_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1BLND2_GB, VID1CKEYMASK_B
+*/
+#define ODN_PDP_VID1BLND2_GB_VID1CKEYMASK_B_MASK (0x000003FF)
+#define ODN_PDP_VID1BLND2_GB_VID1CKEYMASK_B_LSBMASK (0x000003FF)
+#define ODN_PDP_VID1BLND2_GB_VID1CKEYMASK_B_SHIFT (0)
+#define ODN_PDP_VID1BLND2_GB_VID1CKEYMASK_B_LENGTH (10)
+#define ODN_PDP_VID1BLND2_GB_VID1CKEYMASK_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2BLND2_R_OFFSET (0x0148)
+
+/* PDP, VID2BLND2_R, VID2CKEYMASK_R
+*/
+#define ODN_PDP_VID2BLND2_R_VID2CKEYMASK_R_MASK (0x000003FF)
+#define ODN_PDP_VID2BLND2_R_VID2CKEYMASK_R_LSBMASK (0x000003FF)
+#define ODN_PDP_VID2BLND2_R_VID2CKEYMASK_R_SHIFT (0)
+#define ODN_PDP_VID2BLND2_R_VID2CKEYMASK_R_LENGTH (10)
+#define ODN_PDP_VID2BLND2_R_VID2CKEYMASK_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2BLND2_GB_OFFSET (0x014C)
+
+/* PDP, VID2BLND2_GB, VID2CKEYMASK_G
+*/
+#define ODN_PDP_VID2BLND2_GB_VID2CKEYMASK_G_MASK (0x03FF0000)
+#define ODN_PDP_VID2BLND2_GB_VID2CKEYMASK_G_LSBMASK (0x000003FF)
+#define ODN_PDP_VID2BLND2_GB_VID2CKEYMASK_G_SHIFT (16)
+#define ODN_PDP_VID2BLND2_GB_VID2CKEYMASK_G_LENGTH (10)
+#define ODN_PDP_VID2BLND2_GB_VID2CKEYMASK_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2BLND2_GB, VID2CKEYMASK_B
+*/
+#define ODN_PDP_VID2BLND2_GB_VID2CKEYMASK_B_MASK (0x000003FF)
+#define ODN_PDP_VID2BLND2_GB_VID2CKEYMASK_B_LSBMASK (0x000003FF)
+#define ODN_PDP_VID2BLND2_GB_VID2CKEYMASK_B_SHIFT (0)
+#define ODN_PDP_VID2BLND2_GB_VID2CKEYMASK_B_LENGTH (10)
+#define ODN_PDP_VID2BLND2_GB_VID2CKEYMASK_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3BLND2_R_OFFSET (0x0150)
+
+/* PDP, VID3BLND2_R, VID3CKEYMASK_R
+*/
+#define ODN_PDP_VID3BLND2_R_VID3CKEYMASK_R_MASK (0x000003FF)
+#define ODN_PDP_VID3BLND2_R_VID3CKEYMASK_R_LSBMASK (0x000003FF)
+#define ODN_PDP_VID3BLND2_R_VID3CKEYMASK_R_SHIFT (0)
+#define ODN_PDP_VID3BLND2_R_VID3CKEYMASK_R_LENGTH (10)
+#define ODN_PDP_VID3BLND2_R_VID3CKEYMASK_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3BLND2_GB_OFFSET (0x0154)
+
+/* PDP, VID3BLND2_GB, VID3CKEYMASK_G
+*/
+#define ODN_PDP_VID3BLND2_GB_VID3CKEYMASK_G_MASK (0x03FF0000)
+#define ODN_PDP_VID3BLND2_GB_VID3CKEYMASK_G_LSBMASK (0x000003FF)
+#define ODN_PDP_VID3BLND2_GB_VID3CKEYMASK_G_SHIFT (16)
+#define ODN_PDP_VID3BLND2_GB_VID3CKEYMASK_G_LENGTH (10)
+#define ODN_PDP_VID3BLND2_GB_VID3CKEYMASK_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3BLND2_GB, VID3CKEYMASK_B
+*/
+#define ODN_PDP_VID3BLND2_GB_VID3CKEYMASK_B_MASK (0x000003FF)
+#define ODN_PDP_VID3BLND2_GB_VID3CKEYMASK_B_LSBMASK (0x000003FF)
+#define ODN_PDP_VID3BLND2_GB_VID3CKEYMASK_B_SHIFT (0)
+#define ODN_PDP_VID3BLND2_GB_VID3CKEYMASK_B_LENGTH (10)
+#define ODN_PDP_VID3BLND2_GB_VID3CKEYMASK_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4BLND2_R_OFFSET (0x0158)
+
+/* PDP, VID4BLND2_R, VID4CKEYMASK_R
+*/
+#define ODN_PDP_VID4BLND2_R_VID4CKEYMASK_R_MASK (0x000003FF)
+#define ODN_PDP_VID4BLND2_R_VID4CKEYMASK_R_LSBMASK (0x000003FF)
+#define ODN_PDP_VID4BLND2_R_VID4CKEYMASK_R_SHIFT (0)
+#define ODN_PDP_VID4BLND2_R_VID4CKEYMASK_R_LENGTH (10)
+#define ODN_PDP_VID4BLND2_R_VID4CKEYMASK_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4BLND2_GB_OFFSET (0x015C)
+
+/* PDP, VID4BLND2_GB, VID4CKEYMASK_G
+*/
+#define ODN_PDP_VID4BLND2_GB_VID4CKEYMASK_G_MASK (0x03FF0000)
+#define ODN_PDP_VID4BLND2_GB_VID4CKEYMASK_G_LSBMASK (0x000003FF)
+#define ODN_PDP_VID4BLND2_GB_VID4CKEYMASK_G_SHIFT (16)
+#define ODN_PDP_VID4BLND2_GB_VID4CKEYMASK_G_LENGTH (10)
+#define ODN_PDP_VID4BLND2_GB_VID4CKEYMASK_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4BLND2_GB, VID4CKEYMASK_B
+*/
+#define ODN_PDP_VID4BLND2_GB_VID4CKEYMASK_B_MASK (0x000003FF)
+#define ODN_PDP_VID4BLND2_GB_VID4CKEYMASK_B_LSBMASK (0x000003FF)
+#define ODN_PDP_VID4BLND2_GB_VID4CKEYMASK_B_SHIFT (0)
+#define ODN_PDP_VID4BLND2_GB_VID4CKEYMASK_B_LENGTH (10)
+#define ODN_PDP_VID4BLND2_GB_VID4CKEYMASK_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH1INTERLEAVE_CTRL_OFFSET (0x0160)
+
+/* PDP, GRPH1INTERLEAVE_CTRL, GRPH1INTFIELD
+*/
+#define ODN_PDP_GRPH1INTERLEAVE_CTRL_GRPH1INTFIELD_MASK (0x00000001)
+#define ODN_PDP_GRPH1INTERLEAVE_CTRL_GRPH1INTFIELD_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH1INTERLEAVE_CTRL_GRPH1INTFIELD_SHIFT (0)
+#define ODN_PDP_GRPH1INTERLEAVE_CTRL_GRPH1INTFIELD_LENGTH (1)
+#define ODN_PDP_GRPH1INTERLEAVE_CTRL_GRPH1INTFIELD_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH2INTERLEAVE_CTRL_OFFSET (0x0164)
+
+/* PDP, GRPH2INTERLEAVE_CTRL, GRPH2INTFIELD
+*/
+#define ODN_PDP_GRPH2INTERLEAVE_CTRL_GRPH2INTFIELD_MASK (0x00000001)
+#define ODN_PDP_GRPH2INTERLEAVE_CTRL_GRPH2INTFIELD_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH2INTERLEAVE_CTRL_GRPH2INTFIELD_SHIFT (0)
+#define ODN_PDP_GRPH2INTERLEAVE_CTRL_GRPH2INTFIELD_LENGTH (1)
+#define ODN_PDP_GRPH2INTERLEAVE_CTRL_GRPH2INTFIELD_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH3INTERLEAVE_CTRL_OFFSET (0x0168)
+
+/* PDP, GRPH3INTERLEAVE_CTRL, GRPH3INTFIELD
+*/
+#define ODN_PDP_GRPH3INTERLEAVE_CTRL_GRPH3INTFIELD_MASK (0x00000001)
+#define ODN_PDP_GRPH3INTERLEAVE_CTRL_GRPH3INTFIELD_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH3INTERLEAVE_CTRL_GRPH3INTFIELD_SHIFT (0)
+#define ODN_PDP_GRPH3INTERLEAVE_CTRL_GRPH3INTFIELD_LENGTH (1)
+#define ODN_PDP_GRPH3INTERLEAVE_CTRL_GRPH3INTFIELD_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH4INTERLEAVE_CTRL_OFFSET (0x016C)
+
+/* PDP, GRPH4INTERLEAVE_CTRL, GRPH4INTFIELD
+*/
+#define ODN_PDP_GRPH4INTERLEAVE_CTRL_GRPH4INTFIELD_MASK (0x00000001)
+#define ODN_PDP_GRPH4INTERLEAVE_CTRL_GRPH4INTFIELD_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH4INTERLEAVE_CTRL_GRPH4INTFIELD_SHIFT (0)
+#define ODN_PDP_GRPH4INTERLEAVE_CTRL_GRPH4INTFIELD_LENGTH (1)
+#define ODN_PDP_GRPH4INTERLEAVE_CTRL_GRPH4INTFIELD_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1INTERLEAVE_CTRL_OFFSET (0x0170)
+
+/* PDP, VID1INTERLEAVE_CTRL, VID1INTFIELD
+*/
+#define ODN_PDP_VID1INTERLEAVE_CTRL_VID1INTFIELD_MASK (0x00000001)
+#define ODN_PDP_VID1INTERLEAVE_CTRL_VID1INTFIELD_LSBMASK (0x00000001)
+#define ODN_PDP_VID1INTERLEAVE_CTRL_VID1INTFIELD_SHIFT (0)
+#define ODN_PDP_VID1INTERLEAVE_CTRL_VID1INTFIELD_LENGTH (1)
+#define ODN_PDP_VID1INTERLEAVE_CTRL_VID1INTFIELD_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2INTERLEAVE_CTRL_OFFSET (0x0174)
+
+/* PDP, VID2INTERLEAVE_CTRL, VID2INTFIELD
+*/
+#define ODN_PDP_VID2INTERLEAVE_CTRL_VID2INTFIELD_MASK (0x00000001)
+#define ODN_PDP_VID2INTERLEAVE_CTRL_VID2INTFIELD_LSBMASK (0x00000001)
+#define ODN_PDP_VID2INTERLEAVE_CTRL_VID2INTFIELD_SHIFT (0)
+#define ODN_PDP_VID2INTERLEAVE_CTRL_VID2INTFIELD_LENGTH (1)
+#define ODN_PDP_VID2INTERLEAVE_CTRL_VID2INTFIELD_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3INTERLEAVE_CTRL_OFFSET (0x0178)
+
+/* PDP, VID3INTERLEAVE_CTRL, VID3INTFIELD
+*/
+#define ODN_PDP_VID3INTERLEAVE_CTRL_VID3INTFIELD_MASK (0x00000001)
+#define ODN_PDP_VID3INTERLEAVE_CTRL_VID3INTFIELD_LSBMASK (0x00000001)
+#define ODN_PDP_VID3INTERLEAVE_CTRL_VID3INTFIELD_SHIFT (0)
+#define ODN_PDP_VID3INTERLEAVE_CTRL_VID3INTFIELD_LENGTH (1)
+#define ODN_PDP_VID3INTERLEAVE_CTRL_VID3INTFIELD_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4INTERLEAVE_CTRL_OFFSET (0x017C)
+
+/* PDP, VID4INTERLEAVE_CTRL, VID4INTFIELD
+*/
+#define ODN_PDP_VID4INTERLEAVE_CTRL_VID4INTFIELD_MASK (0x00000001)
+#define ODN_PDP_VID4INTERLEAVE_CTRL_VID4INTFIELD_LSBMASK (0x00000001)
+#define ODN_PDP_VID4INTERLEAVE_CTRL_VID4INTFIELD_SHIFT (0)
+#define ODN_PDP_VID4INTERLEAVE_CTRL_VID4INTFIELD_LENGTH (1)
+#define ODN_PDP_VID4INTERLEAVE_CTRL_VID4INTFIELD_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH1BASEADDR_OFFSET (0x0180)
+
+/* PDP, GRPH1BASEADDR, GRPH1BASEADDR
+*/
+#define ODN_PDP_GRPH1BASEADDR_GRPH1BASEADDR_MASK (0xFFFFFFE0)
+#define ODN_PDP_GRPH1BASEADDR_GRPH1BASEADDR_LSBMASK (0x07FFFFFF)
+#define ODN_PDP_GRPH1BASEADDR_GRPH1BASEADDR_SHIFT (5)
+#define ODN_PDP_GRPH1BASEADDR_GRPH1BASEADDR_LENGTH (27)
+#define ODN_PDP_GRPH1BASEADDR_GRPH1BASEADDR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH2BASEADDR_OFFSET (0x0184)
+
+/* PDP, GRPH2BASEADDR, GRPH2BASEADDR
+*/
+#define ODN_PDP_GRPH2BASEADDR_GRPH2BASEADDR_MASK (0xFFFFFFE0)
+#define ODN_PDP_GRPH2BASEADDR_GRPH2BASEADDR_LSBMASK (0x07FFFFFF)
+#define ODN_PDP_GRPH2BASEADDR_GRPH2BASEADDR_SHIFT (5)
+#define ODN_PDP_GRPH2BASEADDR_GRPH2BASEADDR_LENGTH (27)
+#define ODN_PDP_GRPH2BASEADDR_GRPH2BASEADDR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH3BASEADDR_OFFSET (0x0188)
+
+/* PDP, GRPH3BASEADDR, GRPH3BASEADDR
+*/
+#define ODN_PDP_GRPH3BASEADDR_GRPH3BASEADDR_MASK (0xFFFFFFE0)
+#define ODN_PDP_GRPH3BASEADDR_GRPH3BASEADDR_LSBMASK (0x07FFFFFF)
+#define ODN_PDP_GRPH3BASEADDR_GRPH3BASEADDR_SHIFT (5)
+#define ODN_PDP_GRPH3BASEADDR_GRPH3BASEADDR_LENGTH (27)
+#define ODN_PDP_GRPH3BASEADDR_GRPH3BASEADDR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH4BASEADDR_OFFSET (0x018C)
+
+/* PDP, GRPH4BASEADDR, GRPH4BASEADDR
+*/
+#define ODN_PDP_GRPH4BASEADDR_GRPH4BASEADDR_MASK (0xFFFFFFE0)
+#define ODN_PDP_GRPH4BASEADDR_GRPH4BASEADDR_LSBMASK (0x07FFFFFF)
+#define ODN_PDP_GRPH4BASEADDR_GRPH4BASEADDR_SHIFT (5)
+#define ODN_PDP_GRPH4BASEADDR_GRPH4BASEADDR_LENGTH (27)
+#define ODN_PDP_GRPH4BASEADDR_GRPH4BASEADDR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1BASEADDR_OFFSET (0x0190)
+
+/* PDP, VID1BASEADDR, VID1BASEADDR
+*/
+#define ODN_PDP_VID1BASEADDR_VID1BASEADDR_MASK (0xFFFFFFE0)
+#define ODN_PDP_VID1BASEADDR_VID1BASEADDR_LSBMASK (0x07FFFFFF)
+#define ODN_PDP_VID1BASEADDR_VID1BASEADDR_SHIFT (5)
+#define ODN_PDP_VID1BASEADDR_VID1BASEADDR_LENGTH (27)
+#define ODN_PDP_VID1BASEADDR_VID1BASEADDR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2BASEADDR_OFFSET (0x0194)
+
+/* PDP, VID2BASEADDR, VID2BASEADDR
+*/
+#define ODN_PDP_VID2BASEADDR_VID2BASEADDR_MASK (0xFFFFFFE0)
+#define ODN_PDP_VID2BASEADDR_VID2BASEADDR_LSBMASK (0x07FFFFFF)
+#define ODN_PDP_VID2BASEADDR_VID2BASEADDR_SHIFT (5)
+#define ODN_PDP_VID2BASEADDR_VID2BASEADDR_LENGTH (27)
+#define ODN_PDP_VID2BASEADDR_VID2BASEADDR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3BASEADDR_OFFSET (0x0198)
+
+/* PDP, VID3BASEADDR, VID3BASEADDR
+*/
+#define ODN_PDP_VID3BASEADDR_VID3BASEADDR_MASK (0xFFFFFFE0)
+#define ODN_PDP_VID3BASEADDR_VID3BASEADDR_LSBMASK (0x07FFFFFF)
+#define ODN_PDP_VID3BASEADDR_VID3BASEADDR_SHIFT (5)
+#define ODN_PDP_VID3BASEADDR_VID3BASEADDR_LENGTH (27)
+#define ODN_PDP_VID3BASEADDR_VID3BASEADDR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4BASEADDR_OFFSET (0x019C)
+
+/* PDP, VID4BASEADDR, VID4BASEADDR
+*/
+#define ODN_PDP_VID4BASEADDR_VID4BASEADDR_MASK (0xFFFFFFE0)
+#define ODN_PDP_VID4BASEADDR_VID4BASEADDR_LSBMASK (0x07FFFFFF)
+#define ODN_PDP_VID4BASEADDR_VID4BASEADDR_SHIFT (5)
+#define ODN_PDP_VID4BASEADDR_VID4BASEADDR_LENGTH (27)
+#define ODN_PDP_VID4BASEADDR_VID4BASEADDR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1UBASEADDR_OFFSET (0x01B0)
+
+/* PDP, VID1UBASEADDR, VID1UBASEADDR
+*/
+#define ODN_PDP_VID1UBASEADDR_VID1UBASEADDR_MASK (0xFFFFFFE0)
+#define ODN_PDP_VID1UBASEADDR_VID1UBASEADDR_LSBMASK (0x07FFFFFF)
+#define ODN_PDP_VID1UBASEADDR_VID1UBASEADDR_SHIFT (5)
+#define ODN_PDP_VID1UBASEADDR_VID1UBASEADDR_LENGTH (27)
+#define ODN_PDP_VID1UBASEADDR_VID1UBASEADDR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2UBASEADDR_OFFSET (0x01B4)
+
+/* PDP, VID2UBASEADDR, VID2UBASEADDR
+*/
+#define ODN_PDP_VID2UBASEADDR_VID2UBASEADDR_MASK (0xFFFFFFE0)
+#define ODN_PDP_VID2UBASEADDR_VID2UBASEADDR_LSBMASK (0x07FFFFFF)
+#define ODN_PDP_VID2UBASEADDR_VID2UBASEADDR_SHIFT (5)
+#define ODN_PDP_VID2UBASEADDR_VID2UBASEADDR_LENGTH (27)
+#define ODN_PDP_VID2UBASEADDR_VID2UBASEADDR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3UBASEADDR_OFFSET (0x01B8)
+
+/* PDP, VID3UBASEADDR, VID3UBASEADDR
+*/
+#define ODN_PDP_VID3UBASEADDR_VID3UBASEADDR_MASK (0xFFFFFFE0)
+#define ODN_PDP_VID3UBASEADDR_VID3UBASEADDR_LSBMASK (0x07FFFFFF)
+#define ODN_PDP_VID3UBASEADDR_VID3UBASEADDR_SHIFT (5)
+#define ODN_PDP_VID3UBASEADDR_VID3UBASEADDR_LENGTH (27)
+#define ODN_PDP_VID3UBASEADDR_VID3UBASEADDR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4UBASEADDR_OFFSET (0x01BC)
+
+/* PDP, VID4UBASEADDR, VID4UBASEADDR
+*/
+#define ODN_PDP_VID4UBASEADDR_VID4UBASEADDR_MASK (0xFFFFFFE0)
+#define ODN_PDP_VID4UBASEADDR_VID4UBASEADDR_LSBMASK (0x07FFFFFF)
+#define ODN_PDP_VID4UBASEADDR_VID4UBASEADDR_SHIFT (5)
+#define ODN_PDP_VID4UBASEADDR_VID4UBASEADDR_LENGTH (27)
+#define ODN_PDP_VID4UBASEADDR_VID4UBASEADDR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1VBASEADDR_OFFSET (0x01D0)
+
+/* PDP, VID1VBASEADDR, VID1VBASEADDR
+*/
+#define ODN_PDP_VID1VBASEADDR_VID1VBASEADDR_MASK (0xFFFFFFE0)
+#define ODN_PDP_VID1VBASEADDR_VID1VBASEADDR_LSBMASK (0x07FFFFFF)
+#define ODN_PDP_VID1VBASEADDR_VID1VBASEADDR_SHIFT (5)
+#define ODN_PDP_VID1VBASEADDR_VID1VBASEADDR_LENGTH (27)
+#define ODN_PDP_VID1VBASEADDR_VID1VBASEADDR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2VBASEADDR_OFFSET (0x01D4)
+
+/* PDP, VID2VBASEADDR, VID2VBASEADDR
+*/
+#define ODN_PDP_VID2VBASEADDR_VID2VBASEADDR_MASK (0xFFFFFFE0)
+#define ODN_PDP_VID2VBASEADDR_VID2VBASEADDR_LSBMASK (0x07FFFFFF)
+#define ODN_PDP_VID2VBASEADDR_VID2VBASEADDR_SHIFT (5)
+#define ODN_PDP_VID2VBASEADDR_VID2VBASEADDR_LENGTH (27)
+#define ODN_PDP_VID2VBASEADDR_VID2VBASEADDR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3VBASEADDR_OFFSET (0x01D8)
+
+/* PDP, VID3VBASEADDR, VID3VBASEADDR
+*/
+#define ODN_PDP_VID3VBASEADDR_VID3VBASEADDR_MASK (0xFFFFFFE0)
+#define ODN_PDP_VID3VBASEADDR_VID3VBASEADDR_LSBMASK (0x07FFFFFF)
+#define ODN_PDP_VID3VBASEADDR_VID3VBASEADDR_SHIFT (5)
+#define ODN_PDP_VID3VBASEADDR_VID3VBASEADDR_LENGTH (27)
+#define ODN_PDP_VID3VBASEADDR_VID3VBASEADDR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4VBASEADDR_OFFSET (0x01DC)
+
+/* PDP, VID4VBASEADDR, VID4VBASEADDR
+*/
+#define ODN_PDP_VID4VBASEADDR_VID4VBASEADDR_MASK (0xFFFFFFE0)
+#define ODN_PDP_VID4VBASEADDR_VID4VBASEADDR_LSBMASK (0x07FFFFFF)
+#define ODN_PDP_VID4VBASEADDR_VID4VBASEADDR_SHIFT (5)
+#define ODN_PDP_VID4VBASEADDR_VID4VBASEADDR_LENGTH (27)
+#define ODN_PDP_VID4VBASEADDR_VID4VBASEADDR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1POSTSKIPCTRL_OFFSET (0x0230)
+
+/* PDP, VID1POSTSKIPCTRL, VID1HPOSTCLIP
+*/
+#define ODN_PDP_VID1POSTSKIPCTRL_VID1HPOSTCLIP_MASK (0x007F0000)
+#define ODN_PDP_VID1POSTSKIPCTRL_VID1HPOSTCLIP_LSBMASK (0x0000007F)
+#define ODN_PDP_VID1POSTSKIPCTRL_VID1HPOSTCLIP_SHIFT (16)
+#define ODN_PDP_VID1POSTSKIPCTRL_VID1HPOSTCLIP_LENGTH (7)
+#define ODN_PDP_VID1POSTSKIPCTRL_VID1HPOSTCLIP_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1POSTSKIPCTRL, VID1VPOSTCLIP
+*/
+#define ODN_PDP_VID1POSTSKIPCTRL_VID1VPOSTCLIP_MASK (0x0000003F)
+#define ODN_PDP_VID1POSTSKIPCTRL_VID1VPOSTCLIP_LSBMASK (0x0000003F)
+#define ODN_PDP_VID1POSTSKIPCTRL_VID1VPOSTCLIP_SHIFT (0)
+#define ODN_PDP_VID1POSTSKIPCTRL_VID1VPOSTCLIP_LENGTH (6)
+#define ODN_PDP_VID1POSTSKIPCTRL_VID1VPOSTCLIP_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2POSTSKIPCTRL_OFFSET (0x0234)
+
+/* PDP, VID2POSTSKIPCTRL, VID2HPOSTCLIP
+*/
+#define ODN_PDP_VID2POSTSKIPCTRL_VID2HPOSTCLIP_MASK (0x007F0000)
+#define ODN_PDP_VID2POSTSKIPCTRL_VID2HPOSTCLIP_LSBMASK (0x0000007F)
+#define ODN_PDP_VID2POSTSKIPCTRL_VID2HPOSTCLIP_SHIFT (16)
+#define ODN_PDP_VID2POSTSKIPCTRL_VID2HPOSTCLIP_LENGTH (7)
+#define ODN_PDP_VID2POSTSKIPCTRL_VID2HPOSTCLIP_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2POSTSKIPCTRL, VID2VPOSTCLIP
+*/
+#define ODN_PDP_VID2POSTSKIPCTRL_VID2VPOSTCLIP_MASK (0x0000003F)
+#define ODN_PDP_VID2POSTSKIPCTRL_VID2VPOSTCLIP_LSBMASK (0x0000003F)
+#define ODN_PDP_VID2POSTSKIPCTRL_VID2VPOSTCLIP_SHIFT (0)
+#define ODN_PDP_VID2POSTSKIPCTRL_VID2VPOSTCLIP_LENGTH (6)
+#define ODN_PDP_VID2POSTSKIPCTRL_VID2VPOSTCLIP_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3POSTSKIPCTRL_OFFSET (0x0238)
+
+/* PDP, VID3POSTSKIPCTRL, VID3HPOSTCLIP
+*/
+#define ODN_PDP_VID3POSTSKIPCTRL_VID3HPOSTCLIP_MASK (0x007F0000)
+#define ODN_PDP_VID3POSTSKIPCTRL_VID3HPOSTCLIP_LSBMASK (0x0000007F)
+#define ODN_PDP_VID3POSTSKIPCTRL_VID3HPOSTCLIP_SHIFT (16)
+#define ODN_PDP_VID3POSTSKIPCTRL_VID3HPOSTCLIP_LENGTH (7)
+#define ODN_PDP_VID3POSTSKIPCTRL_VID3HPOSTCLIP_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3POSTSKIPCTRL, VID3VPOSTCLIP
+*/
+#define ODN_PDP_VID3POSTSKIPCTRL_VID3VPOSTCLIP_MASK (0x0000003F)
+#define ODN_PDP_VID3POSTSKIPCTRL_VID3VPOSTCLIP_LSBMASK (0x0000003F)
+#define ODN_PDP_VID3POSTSKIPCTRL_VID3VPOSTCLIP_SHIFT (0)
+#define ODN_PDP_VID3POSTSKIPCTRL_VID3VPOSTCLIP_LENGTH (6)
+#define ODN_PDP_VID3POSTSKIPCTRL_VID3VPOSTCLIP_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4POSTSKIPCTRL_OFFSET (0x023C)
+
+/* PDP, VID4POSTSKIPCTRL, VID4HPOSTCLIP
+*/
+#define ODN_PDP_VID4POSTSKIPCTRL_VID4HPOSTCLIP_MASK (0x007F0000)
+#define ODN_PDP_VID4POSTSKIPCTRL_VID4HPOSTCLIP_LSBMASK (0x0000007F)
+#define ODN_PDP_VID4POSTSKIPCTRL_VID4HPOSTCLIP_SHIFT (16)
+#define ODN_PDP_VID4POSTSKIPCTRL_VID4HPOSTCLIP_LENGTH (7)
+#define ODN_PDP_VID4POSTSKIPCTRL_VID4HPOSTCLIP_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4POSTSKIPCTRL, VID4VPOSTCLIP
+*/
+#define ODN_PDP_VID4POSTSKIPCTRL_VID4VPOSTCLIP_MASK (0x0000003F)
+#define ODN_PDP_VID4POSTSKIPCTRL_VID4VPOSTCLIP_LSBMASK (0x0000003F)
+#define ODN_PDP_VID4POSTSKIPCTRL_VID4VPOSTCLIP_SHIFT (0)
+#define ODN_PDP_VID4POSTSKIPCTRL_VID4VPOSTCLIP_LENGTH (6)
+#define ODN_PDP_VID4POSTSKIPCTRL_VID4VPOSTCLIP_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH1DECIMATE_CTRL_OFFSET (0x0240)
+
+/* PDP, GRPH1DECIMATE_CTRL, GRPH1DECIMATE_LINE_DISCARD_COUNT
+*/
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_LINE_DISCARD_COUNT_MASK (0x000000F0)
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_LINE_DISCARD_COUNT_LSBMASK (0x0000000F)
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_LINE_DISCARD_COUNT_SHIFT (4)
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_LINE_DISCARD_COUNT_LENGTH (4)
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_LINE_DISCARD_COUNT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1DECIMATE_CTRL, GRPH1DECIMATE_LINE_DISCARD_MODE
+*/
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_LINE_DISCARD_MODE_MASK (0x00000008)
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_LINE_DISCARD_MODE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_LINE_DISCARD_MODE_SHIFT (3)
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_LINE_DISCARD_MODE_LENGTH (1)
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_LINE_DISCARD_MODE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1DECIMATE_CTRL, GRPH1DECIMATE_PIXEL_HALVE
+*/
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_PIXEL_HALVE_MASK (0x00000004)
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_PIXEL_HALVE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_PIXEL_HALVE_SHIFT (2)
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_PIXEL_HALVE_LENGTH (1)
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_PIXEL_HALVE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1DECIMATE_CTRL, GRPH1DECIMATE_EN
+*/
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_EN_MASK (0x00000001)
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_EN_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_EN_SHIFT (0)
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_EN_LENGTH (1)
+#define ODN_PDP_GRPH1DECIMATE_CTRL_GRPH1DECIMATE_EN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH2DECIMATE_CTRL_OFFSET (0x0244)
+
+/* PDP, GRPH2DECIMATE_CTRL, GRPH2DECIMATE_LINE_DISCARD_COUNT
+*/
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_LINE_DISCARD_COUNT_MASK (0x000000F0)
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_LINE_DISCARD_COUNT_LSBMASK (0x0000000F)
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_LINE_DISCARD_COUNT_SHIFT (4)
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_LINE_DISCARD_COUNT_LENGTH (4)
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_LINE_DISCARD_COUNT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2DECIMATE_CTRL, GRPH2DECIMATE_LINE_DISCARD_MODE
+*/
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_LINE_DISCARD_MODE_MASK (0x00000008)
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_LINE_DISCARD_MODE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_LINE_DISCARD_MODE_SHIFT (3)
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_LINE_DISCARD_MODE_LENGTH (1)
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_LINE_DISCARD_MODE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2DECIMATE_CTRL, GRPH2DECIMATE_PIXEL_HALVE
+*/
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_PIXEL_HALVE_MASK (0x00000004)
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_PIXEL_HALVE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_PIXEL_HALVE_SHIFT (2)
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_PIXEL_HALVE_LENGTH (1)
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_PIXEL_HALVE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2DECIMATE_CTRL, GRPH2DECIMATE_EN
+*/
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_EN_MASK (0x00000001)
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_EN_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_EN_SHIFT (0)
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_EN_LENGTH (1)
+#define ODN_PDP_GRPH2DECIMATE_CTRL_GRPH2DECIMATE_EN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH3DECIMATE_CTRL_OFFSET (0x0248)
+
+/* PDP, GRPH3DECIMATE_CTRL, GRPH3DECIMATE_LINE_DISCARD_COUNT
+*/
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_LINE_DISCARD_COUNT_MASK (0x000000F0)
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_LINE_DISCARD_COUNT_LSBMASK (0x0000000F)
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_LINE_DISCARD_COUNT_SHIFT (4)
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_LINE_DISCARD_COUNT_LENGTH (4)
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_LINE_DISCARD_COUNT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3DECIMATE_CTRL, GRPH3DECIMATE_LINE_DISCARD_MODE
+*/
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_LINE_DISCARD_MODE_MASK (0x00000008)
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_LINE_DISCARD_MODE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_LINE_DISCARD_MODE_SHIFT (3)
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_LINE_DISCARD_MODE_LENGTH (1)
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_LINE_DISCARD_MODE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3DECIMATE_CTRL, GRPH3DECIMATE_PIXEL_HALVE
+*/
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_PIXEL_HALVE_MASK (0x00000004)
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_PIXEL_HALVE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_PIXEL_HALVE_SHIFT (2)
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_PIXEL_HALVE_LENGTH (1)
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_PIXEL_HALVE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3DECIMATE_CTRL, GRPH3DECIMATE_EN
+*/
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_EN_MASK (0x00000001)
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_EN_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_EN_SHIFT (0)
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_EN_LENGTH (1)
+#define ODN_PDP_GRPH3DECIMATE_CTRL_GRPH3DECIMATE_EN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH4DECIMATE_CTRL_OFFSET (0x024C)
+
+/* PDP, GRPH4DECIMATE_CTRL, GRPH4DECIMATE_LINE_DISCARD_COUNT
+*/
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_LINE_DISCARD_COUNT_MASK (0x000000F0)
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_LINE_DISCARD_COUNT_LSBMASK (0x0000000F)
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_LINE_DISCARD_COUNT_SHIFT (4)
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_LINE_DISCARD_COUNT_LENGTH (4)
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_LINE_DISCARD_COUNT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4DECIMATE_CTRL, GRPH4DECIMATE_LINE_DISCARD_MODE
+*/
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_LINE_DISCARD_MODE_MASK (0x00000008)
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_LINE_DISCARD_MODE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_LINE_DISCARD_MODE_SHIFT (3)
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_LINE_DISCARD_MODE_LENGTH (1)
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_LINE_DISCARD_MODE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4DECIMATE_CTRL, GRPH4DECIMATE_PIXEL_HALVE
+*/
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_PIXEL_HALVE_MASK (0x00000004)
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_PIXEL_HALVE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_PIXEL_HALVE_SHIFT (2)
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_PIXEL_HALVE_LENGTH (1)
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_PIXEL_HALVE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4DECIMATE_CTRL, GRPH4DECIMATE_EN
+*/
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_EN_MASK (0x00000001)
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_EN_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_EN_SHIFT (0)
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_EN_LENGTH (1)
+#define ODN_PDP_GRPH4DECIMATE_CTRL_GRPH4DECIMATE_EN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1DECIMATE_CTRL_OFFSET (0x0250)
+
+/* PDP, VID1DECIMATE_CTRL, VID1DECIMATE_LINE_DISCARD_COUNT
+*/
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_LINE_DISCARD_COUNT_MASK (0x000000F0)
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_LINE_DISCARD_COUNT_LSBMASK (0x0000000F)
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_LINE_DISCARD_COUNT_SHIFT (4)
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_LINE_DISCARD_COUNT_LENGTH (4)
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_LINE_DISCARD_COUNT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1DECIMATE_CTRL, VID1DECIMATE_LINE_DISCARD_MODE
+*/
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_LINE_DISCARD_MODE_MASK (0x00000008)
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_LINE_DISCARD_MODE_LSBMASK (0x00000001)
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_LINE_DISCARD_MODE_SHIFT (3)
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_LINE_DISCARD_MODE_LENGTH (1)
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_LINE_DISCARD_MODE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1DECIMATE_CTRL, VID1DECIMATE_PIXEL_HALVE
+*/
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_PIXEL_HALVE_MASK (0x00000004)
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_PIXEL_HALVE_LSBMASK (0x00000001)
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_PIXEL_HALVE_SHIFT (2)
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_PIXEL_HALVE_LENGTH (1)
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_PIXEL_HALVE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1DECIMATE_CTRL, VID1DECIMATE_EN
+*/
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_EN_MASK (0x00000001)
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_EN_LSBMASK (0x00000001)
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_EN_SHIFT (0)
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_EN_LENGTH (1)
+#define ODN_PDP_VID1DECIMATE_CTRL_VID1DECIMATE_EN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2DECIMATE_CTRL_OFFSET (0x0254)
+
+/* PDP, VID2DECIMATE_CTRL, VID2DECIMATE_LINE_DISCARD_COUNT
+*/
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_LINE_DISCARD_COUNT_MASK (0x000000F0)
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_LINE_DISCARD_COUNT_LSBMASK (0x0000000F)
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_LINE_DISCARD_COUNT_SHIFT (4)
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_LINE_DISCARD_COUNT_LENGTH (4)
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_LINE_DISCARD_COUNT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2DECIMATE_CTRL, VID2DECIMATE_LINE_DISCARD_MODE
+*/
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_LINE_DISCARD_MODE_MASK (0x00000008)
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_LINE_DISCARD_MODE_LSBMASK (0x00000001)
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_LINE_DISCARD_MODE_SHIFT (3)
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_LINE_DISCARD_MODE_LENGTH (1)
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_LINE_DISCARD_MODE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2DECIMATE_CTRL, VID2DECIMATE_PIXEL_HALVE
+*/
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_PIXEL_HALVE_MASK (0x00000004)
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_PIXEL_HALVE_LSBMASK (0x00000001)
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_PIXEL_HALVE_SHIFT (2)
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_PIXEL_HALVE_LENGTH (1)
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_PIXEL_HALVE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2DECIMATE_CTRL, VID2DECIMATE_EN
+*/
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_EN_MASK (0x00000001)
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_EN_LSBMASK (0x00000001)
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_EN_SHIFT (0)
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_EN_LENGTH (1)
+#define ODN_PDP_VID2DECIMATE_CTRL_VID2DECIMATE_EN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3DECIMATE_CTRL_OFFSET (0x0258)
+
+/* PDP, VID3DECIMATE_CTRL, VID3DECIMATE_LINE_DISCARD_COUNT
+*/
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_LINE_DISCARD_COUNT_MASK (0x000000F0)
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_LINE_DISCARD_COUNT_LSBMASK (0x0000000F)
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_LINE_DISCARD_COUNT_SHIFT (4)
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_LINE_DISCARD_COUNT_LENGTH (4)
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_LINE_DISCARD_COUNT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3DECIMATE_CTRL, VID3DECIMATE_LINE_DISCARD_MODE
+*/
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_LINE_DISCARD_MODE_MASK (0x00000008)
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_LINE_DISCARD_MODE_LSBMASK (0x00000001)
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_LINE_DISCARD_MODE_SHIFT (3)
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_LINE_DISCARD_MODE_LENGTH (1)
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_LINE_DISCARD_MODE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3DECIMATE_CTRL, VID3DECIMATE_PIXEL_HALVE
+*/
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_PIXEL_HALVE_MASK (0x00000004)
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_PIXEL_HALVE_LSBMASK (0x00000001)
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_PIXEL_HALVE_SHIFT (2)
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_PIXEL_HALVE_LENGTH (1)
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_PIXEL_HALVE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3DECIMATE_CTRL, VID3DECIMATE_EN
+*/
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_EN_MASK (0x00000001)
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_EN_LSBMASK (0x00000001)
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_EN_SHIFT (0)
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_EN_LENGTH (1)
+#define ODN_PDP_VID3DECIMATE_CTRL_VID3DECIMATE_EN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4DECIMATE_CTRL_OFFSET (0x025C)
+
+/* PDP, VID4DECIMATE_CTRL, VID4DECIMATE_LINE_DISCARD_COUNT
+*/
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_LINE_DISCARD_COUNT_MASK (0x000000F0)
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_LINE_DISCARD_COUNT_LSBMASK (0x0000000F)
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_LINE_DISCARD_COUNT_SHIFT (4)
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_LINE_DISCARD_COUNT_LENGTH (4)
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_LINE_DISCARD_COUNT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4DECIMATE_CTRL, VID4DECIMATE_LINE_DISCARD_MODE
+*/
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_LINE_DISCARD_MODE_MASK (0x00000008)
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_LINE_DISCARD_MODE_LSBMASK (0x00000001)
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_LINE_DISCARD_MODE_SHIFT (3)
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_LINE_DISCARD_MODE_LENGTH (1)
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_LINE_DISCARD_MODE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4DECIMATE_CTRL, VID4DECIMATE_PIXEL_HALVE
+*/
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_PIXEL_HALVE_MASK (0x00000004)
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_PIXEL_HALVE_LSBMASK (0x00000001)
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_PIXEL_HALVE_SHIFT (2)
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_PIXEL_HALVE_LENGTH (1)
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_PIXEL_HALVE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4DECIMATE_CTRL, VID4DECIMATE_EN
+*/
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_EN_MASK (0x00000001)
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_EN_LSBMASK (0x00000001)
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_EN_SHIFT (0)
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_EN_LENGTH (1)
+#define ODN_PDP_VID4DECIMATE_CTRL_VID4DECIMATE_EN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1SKIPCTRL_OFFSET (0x0270)
+
+/* PDP, VID1SKIPCTRL, VID1HSKIP
+*/
+#define ODN_PDP_VID1SKIPCTRL_VID1HSKIP_MASK (0x0FFF0000)
+#define ODN_PDP_VID1SKIPCTRL_VID1HSKIP_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID1SKIPCTRL_VID1HSKIP_SHIFT (16)
+#define ODN_PDP_VID1SKIPCTRL_VID1HSKIP_LENGTH (12)
+#define ODN_PDP_VID1SKIPCTRL_VID1HSKIP_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1SKIPCTRL, VID1VSKIP
+*/
+#define ODN_PDP_VID1SKIPCTRL_VID1VSKIP_MASK (0x00000FFF)
+#define ODN_PDP_VID1SKIPCTRL_VID1VSKIP_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID1SKIPCTRL_VID1VSKIP_SHIFT (0)
+#define ODN_PDP_VID1SKIPCTRL_VID1VSKIP_LENGTH (12)
+#define ODN_PDP_VID1SKIPCTRL_VID1VSKIP_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2SKIPCTRL_OFFSET (0x0274)
+
+/* PDP, VID2SKIPCTRL, VID2HSKIP
+*/
+#define ODN_PDP_VID2SKIPCTRL_VID2HSKIP_MASK (0x0FFF0000)
+#define ODN_PDP_VID2SKIPCTRL_VID2HSKIP_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID2SKIPCTRL_VID2HSKIP_SHIFT (16)
+#define ODN_PDP_VID2SKIPCTRL_VID2HSKIP_LENGTH (12)
+#define ODN_PDP_VID2SKIPCTRL_VID2HSKIP_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2SKIPCTRL, VID2VSKIP
+*/
+#define ODN_PDP_VID2SKIPCTRL_VID2VSKIP_MASK (0x00000FFF)
+#define ODN_PDP_VID2SKIPCTRL_VID2VSKIP_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID2SKIPCTRL_VID2VSKIP_SHIFT (0)
+#define ODN_PDP_VID2SKIPCTRL_VID2VSKIP_LENGTH (12)
+#define ODN_PDP_VID2SKIPCTRL_VID2VSKIP_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3SKIPCTRL_OFFSET (0x0278)
+
+/* PDP, VID3SKIPCTRL, VID3HSKIP
+*/
+#define ODN_PDP_VID3SKIPCTRL_VID3HSKIP_MASK (0x0FFF0000)
+#define ODN_PDP_VID3SKIPCTRL_VID3HSKIP_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID3SKIPCTRL_VID3HSKIP_SHIFT (16)
+#define ODN_PDP_VID3SKIPCTRL_VID3HSKIP_LENGTH (12)
+#define ODN_PDP_VID3SKIPCTRL_VID3HSKIP_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3SKIPCTRL, VID3VSKIP
+*/
+#define ODN_PDP_VID3SKIPCTRL_VID3VSKIP_MASK (0x00000FFF)
+#define ODN_PDP_VID3SKIPCTRL_VID3VSKIP_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID3SKIPCTRL_VID3VSKIP_SHIFT (0)
+#define ODN_PDP_VID3SKIPCTRL_VID3VSKIP_LENGTH (12)
+#define ODN_PDP_VID3SKIPCTRL_VID3VSKIP_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4SKIPCTRL_OFFSET (0x027C)
+
+/* PDP, VID4SKIPCTRL, VID4HSKIP
+*/
+#define ODN_PDP_VID4SKIPCTRL_VID4HSKIP_MASK (0x0FFF0000)
+#define ODN_PDP_VID4SKIPCTRL_VID4HSKIP_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID4SKIPCTRL_VID4HSKIP_SHIFT (16)
+#define ODN_PDP_VID4SKIPCTRL_VID4HSKIP_LENGTH (12)
+#define ODN_PDP_VID4SKIPCTRL_VID4HSKIP_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4SKIPCTRL, VID4VSKIP
+*/
+#define ODN_PDP_VID4SKIPCTRL_VID4VSKIP_MASK (0x00000FFF)
+#define ODN_PDP_VID4SKIPCTRL_VID4VSKIP_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID4SKIPCTRL_VID4VSKIP_SHIFT (0)
+#define ODN_PDP_VID4SKIPCTRL_VID4VSKIP_LENGTH (12)
+#define ODN_PDP_VID4SKIPCTRL_VID4VSKIP_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1SCALECTRL_OFFSET (0x0460)
+
+/* PDP, VID1SCALECTRL, VID1HSCALEBP
+*/
+#define ODN_PDP_VID1SCALECTRL_VID1HSCALEBP_MASK (0x80000000)
+#define ODN_PDP_VID1SCALECTRL_VID1HSCALEBP_LSBMASK (0x00000001)
+#define ODN_PDP_VID1SCALECTRL_VID1HSCALEBP_SHIFT (31)
+#define ODN_PDP_VID1SCALECTRL_VID1HSCALEBP_LENGTH (1)
+#define ODN_PDP_VID1SCALECTRL_VID1HSCALEBP_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1SCALECTRL, VID1VSCALEBP
+*/
+#define ODN_PDP_VID1SCALECTRL_VID1VSCALEBP_MASK (0x40000000)
+#define ODN_PDP_VID1SCALECTRL_VID1VSCALEBP_LSBMASK (0x00000001)
+#define ODN_PDP_VID1SCALECTRL_VID1VSCALEBP_SHIFT (30)
+#define ODN_PDP_VID1SCALECTRL_VID1VSCALEBP_LENGTH (1)
+#define ODN_PDP_VID1SCALECTRL_VID1VSCALEBP_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1SCALECTRL, VID1HSBEFOREVS
+*/
+#define ODN_PDP_VID1SCALECTRL_VID1HSBEFOREVS_MASK (0x20000000)
+#define ODN_PDP_VID1SCALECTRL_VID1HSBEFOREVS_LSBMASK (0x00000001)
+#define ODN_PDP_VID1SCALECTRL_VID1HSBEFOREVS_SHIFT (29)
+#define ODN_PDP_VID1SCALECTRL_VID1HSBEFOREVS_LENGTH (1)
+#define ODN_PDP_VID1SCALECTRL_VID1HSBEFOREVS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1SCALECTRL, VID1VSURUNCTRL
+*/
+#define ODN_PDP_VID1SCALECTRL_VID1VSURUNCTRL_MASK (0x08000000)
+#define ODN_PDP_VID1SCALECTRL_VID1VSURUNCTRL_LSBMASK (0x00000001)
+#define ODN_PDP_VID1SCALECTRL_VID1VSURUNCTRL_SHIFT (27)
+#define ODN_PDP_VID1SCALECTRL_VID1VSURUNCTRL_LENGTH (1)
+#define ODN_PDP_VID1SCALECTRL_VID1VSURUNCTRL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1SCALECTRL, VID1PAN_EN
+*/
+#define ODN_PDP_VID1SCALECTRL_VID1PAN_EN_MASK (0x00040000)
+#define ODN_PDP_VID1SCALECTRL_VID1PAN_EN_LSBMASK (0x00000001)
+#define ODN_PDP_VID1SCALECTRL_VID1PAN_EN_SHIFT (18)
+#define ODN_PDP_VID1SCALECTRL_VID1PAN_EN_LENGTH (1)
+#define ODN_PDP_VID1SCALECTRL_VID1PAN_EN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1SCALECTRL, VID1VORDER
+*/
+#define ODN_PDP_VID1SCALECTRL_VID1VORDER_MASK (0x00030000)
+#define ODN_PDP_VID1SCALECTRL_VID1VORDER_LSBMASK (0x00000003)
+#define ODN_PDP_VID1SCALECTRL_VID1VORDER_SHIFT (16)
+#define ODN_PDP_VID1SCALECTRL_VID1VORDER_LENGTH (2)
+#define ODN_PDP_VID1SCALECTRL_VID1VORDER_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1SCALECTRL, VID1VPITCH
+*/
+#define ODN_PDP_VID1SCALECTRL_VID1VPITCH_MASK (0x0000FFFF)
+#define ODN_PDP_VID1SCALECTRL_VID1VPITCH_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID1SCALECTRL_VID1VPITCH_SHIFT (0)
+#define ODN_PDP_VID1SCALECTRL_VID1VPITCH_LENGTH (16)
+#define ODN_PDP_VID1SCALECTRL_VID1VPITCH_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1VSINIT_OFFSET (0x0464)
+
+/* PDP, VID1VSINIT, VID1VINITIAL1
+*/
+#define ODN_PDP_VID1VSINIT_VID1VINITIAL1_MASK (0xFFFF0000)
+#define ODN_PDP_VID1VSINIT_VID1VINITIAL1_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID1VSINIT_VID1VINITIAL1_SHIFT (16)
+#define ODN_PDP_VID1VSINIT_VID1VINITIAL1_LENGTH (16)
+#define ODN_PDP_VID1VSINIT_VID1VINITIAL1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1VSINIT, VID1VINITIAL0
+*/
+#define ODN_PDP_VID1VSINIT_VID1VINITIAL0_MASK (0x0000FFFF)
+#define ODN_PDP_VID1VSINIT_VID1VINITIAL0_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID1VSINIT_VID1VINITIAL0_SHIFT (0)
+#define ODN_PDP_VID1VSINIT_VID1VINITIAL0_LENGTH (16)
+#define ODN_PDP_VID1VSINIT_VID1VINITIAL0_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1VCOEFF0_OFFSET (0x0468)
+
+/* PDP, VID1VCOEFF0, VID1VCOEFF0
+*/
+#define ODN_PDP_VID1VCOEFF0_VID1VCOEFF0_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1VCOEFF0_VID1VCOEFF0_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1VCOEFF0_VID1VCOEFF0_SHIFT (0)
+#define ODN_PDP_VID1VCOEFF0_VID1VCOEFF0_LENGTH (32)
+#define ODN_PDP_VID1VCOEFF0_VID1VCOEFF0_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1VCOEFF1_OFFSET (0x046C)
+
+/* PDP, VID1VCOEFF1, VID1VCOEFF1
+*/
+#define ODN_PDP_VID1VCOEFF1_VID1VCOEFF1_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1VCOEFF1_VID1VCOEFF1_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1VCOEFF1_VID1VCOEFF1_SHIFT (0)
+#define ODN_PDP_VID1VCOEFF1_VID1VCOEFF1_LENGTH (32)
+#define ODN_PDP_VID1VCOEFF1_VID1VCOEFF1_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1VCOEFF2_OFFSET (0x0470)
+
+/* PDP, VID1VCOEFF2, VID1VCOEFF2
+*/
+#define ODN_PDP_VID1VCOEFF2_VID1VCOEFF2_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1VCOEFF2_VID1VCOEFF2_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1VCOEFF2_VID1VCOEFF2_SHIFT (0)
+#define ODN_PDP_VID1VCOEFF2_VID1VCOEFF2_LENGTH (32)
+#define ODN_PDP_VID1VCOEFF2_VID1VCOEFF2_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1VCOEFF3_OFFSET (0x0474)
+
+/* PDP, VID1VCOEFF3, VID1VCOEFF3
+*/
+#define ODN_PDP_VID1VCOEFF3_VID1VCOEFF3_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1VCOEFF3_VID1VCOEFF3_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1VCOEFF3_VID1VCOEFF3_SHIFT (0)
+#define ODN_PDP_VID1VCOEFF3_VID1VCOEFF3_LENGTH (32)
+#define ODN_PDP_VID1VCOEFF3_VID1VCOEFF3_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1VCOEFF4_OFFSET (0x0478)
+
+/* PDP, VID1VCOEFF4, VID1VCOEFF4
+*/
+#define ODN_PDP_VID1VCOEFF4_VID1VCOEFF4_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1VCOEFF4_VID1VCOEFF4_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1VCOEFF4_VID1VCOEFF4_SHIFT (0)
+#define ODN_PDP_VID1VCOEFF4_VID1VCOEFF4_LENGTH (32)
+#define ODN_PDP_VID1VCOEFF4_VID1VCOEFF4_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1VCOEFF5_OFFSET (0x047C)
+
+/* PDP, VID1VCOEFF5, VID1VCOEFF5
+*/
+#define ODN_PDP_VID1VCOEFF5_VID1VCOEFF5_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1VCOEFF5_VID1VCOEFF5_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1VCOEFF5_VID1VCOEFF5_SHIFT (0)
+#define ODN_PDP_VID1VCOEFF5_VID1VCOEFF5_LENGTH (32)
+#define ODN_PDP_VID1VCOEFF5_VID1VCOEFF5_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1VCOEFF6_OFFSET (0x0480)
+
+/* PDP, VID1VCOEFF6, VID1VCOEFF6
+*/
+#define ODN_PDP_VID1VCOEFF6_VID1VCOEFF6_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1VCOEFF6_VID1VCOEFF6_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1VCOEFF6_VID1VCOEFF6_SHIFT (0)
+#define ODN_PDP_VID1VCOEFF6_VID1VCOEFF6_LENGTH (32)
+#define ODN_PDP_VID1VCOEFF6_VID1VCOEFF6_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1VCOEFF7_OFFSET (0x0484)
+
+/* PDP, VID1VCOEFF7, VID1VCOEFF7
+*/
+#define ODN_PDP_VID1VCOEFF7_VID1VCOEFF7_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1VCOEFF7_VID1VCOEFF7_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1VCOEFF7_VID1VCOEFF7_SHIFT (0)
+#define ODN_PDP_VID1VCOEFF7_VID1VCOEFF7_LENGTH (32)
+#define ODN_PDP_VID1VCOEFF7_VID1VCOEFF7_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1VCOEFF8_OFFSET (0x0488)
+
+/* PDP, VID1VCOEFF8, VID1VCOEFF8
+*/
+#define ODN_PDP_VID1VCOEFF8_VID1VCOEFF8_MASK (0x000000FF)
+#define ODN_PDP_VID1VCOEFF8_VID1VCOEFF8_LSBMASK (0x000000FF)
+#define ODN_PDP_VID1VCOEFF8_VID1VCOEFF8_SHIFT (0)
+#define ODN_PDP_VID1VCOEFF8_VID1VCOEFF8_LENGTH (8)
+#define ODN_PDP_VID1VCOEFF8_VID1VCOEFF8_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1HSINIT_OFFSET (0x048C)
+
+/* PDP, VID1HSINIT, VID1HINITIAL
+*/
+#define ODN_PDP_VID1HSINIT_VID1HINITIAL_MASK (0xFFFF0000)
+#define ODN_PDP_VID1HSINIT_VID1HINITIAL_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID1HSINIT_VID1HINITIAL_SHIFT (16)
+#define ODN_PDP_VID1HSINIT_VID1HINITIAL_LENGTH (16)
+#define ODN_PDP_VID1HSINIT_VID1HINITIAL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1HSINIT, VID1HPITCH
+*/
+#define ODN_PDP_VID1HSINIT_VID1HPITCH_MASK (0x0000FFFF)
+#define ODN_PDP_VID1HSINIT_VID1HPITCH_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID1HSINIT_VID1HPITCH_SHIFT (0)
+#define ODN_PDP_VID1HSINIT_VID1HPITCH_LENGTH (16)
+#define ODN_PDP_VID1HSINIT_VID1HPITCH_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1HCOEFF0_OFFSET (0x0490)
+
+/* PDP, VID1HCOEFF0, VID1HCOEFF0
+*/
+#define ODN_PDP_VID1HCOEFF0_VID1HCOEFF0_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF0_VID1HCOEFF0_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF0_VID1HCOEFF0_SHIFT (0)
+#define ODN_PDP_VID1HCOEFF0_VID1HCOEFF0_LENGTH (32)
+#define ODN_PDP_VID1HCOEFF0_VID1HCOEFF0_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1HCOEFF1_OFFSET (0x0494)
+
+/* PDP, VID1HCOEFF1, VID1HCOEFF1
+*/
+#define ODN_PDP_VID1HCOEFF1_VID1HCOEFF1_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF1_VID1HCOEFF1_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF1_VID1HCOEFF1_SHIFT (0)
+#define ODN_PDP_VID1HCOEFF1_VID1HCOEFF1_LENGTH (32)
+#define ODN_PDP_VID1HCOEFF1_VID1HCOEFF1_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1HCOEFF2_OFFSET (0x0498)
+
+/* PDP, VID1HCOEFF2, VID1HCOEFF2
+*/
+#define ODN_PDP_VID1HCOEFF2_VID1HCOEFF2_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF2_VID1HCOEFF2_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF2_VID1HCOEFF2_SHIFT (0)
+#define ODN_PDP_VID1HCOEFF2_VID1HCOEFF2_LENGTH (32)
+#define ODN_PDP_VID1HCOEFF2_VID1HCOEFF2_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1HCOEFF3_OFFSET (0x049C)
+
+/* PDP, VID1HCOEFF3, VID1HCOEFF3
+*/
+#define ODN_PDP_VID1HCOEFF3_VID1HCOEFF3_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF3_VID1HCOEFF3_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF3_VID1HCOEFF3_SHIFT (0)
+#define ODN_PDP_VID1HCOEFF3_VID1HCOEFF3_LENGTH (32)
+#define ODN_PDP_VID1HCOEFF3_VID1HCOEFF3_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1HCOEFF4_OFFSET (0x04A0)
+
+/* PDP, VID1HCOEFF4, VID1HCOEFF4
+*/
+#define ODN_PDP_VID1HCOEFF4_VID1HCOEFF4_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF4_VID1HCOEFF4_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF4_VID1HCOEFF4_SHIFT (0)
+#define ODN_PDP_VID1HCOEFF4_VID1HCOEFF4_LENGTH (32)
+#define ODN_PDP_VID1HCOEFF4_VID1HCOEFF4_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1HCOEFF5_OFFSET (0x04A4)
+
+/* PDP, VID1HCOEFF5, VID1HCOEFF5
+*/
+#define ODN_PDP_VID1HCOEFF5_VID1HCOEFF5_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF5_VID1HCOEFF5_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF5_VID1HCOEFF5_SHIFT (0)
+#define ODN_PDP_VID1HCOEFF5_VID1HCOEFF5_LENGTH (32)
+#define ODN_PDP_VID1HCOEFF5_VID1HCOEFF5_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1HCOEFF6_OFFSET (0x04A8)
+
+/* PDP, VID1HCOEFF6, VID1HCOEFF6
+*/
+#define ODN_PDP_VID1HCOEFF6_VID1HCOEFF6_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF6_VID1HCOEFF6_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF6_VID1HCOEFF6_SHIFT (0)
+#define ODN_PDP_VID1HCOEFF6_VID1HCOEFF6_LENGTH (32)
+#define ODN_PDP_VID1HCOEFF6_VID1HCOEFF6_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1HCOEFF7_OFFSET (0x04AC)
+
+/* PDP, VID1HCOEFF7, VID1HCOEFF7
+*/
+#define ODN_PDP_VID1HCOEFF7_VID1HCOEFF7_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF7_VID1HCOEFF7_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF7_VID1HCOEFF7_SHIFT (0)
+#define ODN_PDP_VID1HCOEFF7_VID1HCOEFF7_LENGTH (32)
+#define ODN_PDP_VID1HCOEFF7_VID1HCOEFF7_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1HCOEFF8_OFFSET (0x04B0)
+
+/* PDP, VID1HCOEFF8, VID1HCOEFF8
+*/
+#define ODN_PDP_VID1HCOEFF8_VID1HCOEFF8_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF8_VID1HCOEFF8_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF8_VID1HCOEFF8_SHIFT (0)
+#define ODN_PDP_VID1HCOEFF8_VID1HCOEFF8_LENGTH (32)
+#define ODN_PDP_VID1HCOEFF8_VID1HCOEFF8_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1HCOEFF9_OFFSET (0x04B4)
+
+/* PDP, VID1HCOEFF9, VID1HCOEFF9
+*/
+#define ODN_PDP_VID1HCOEFF9_VID1HCOEFF9_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF9_VID1HCOEFF9_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF9_VID1HCOEFF9_SHIFT (0)
+#define ODN_PDP_VID1HCOEFF9_VID1HCOEFF9_LENGTH (32)
+#define ODN_PDP_VID1HCOEFF9_VID1HCOEFF9_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1HCOEFF10_OFFSET (0x04B8)
+
+/* PDP, VID1HCOEFF10, VID1HCOEFF10
+*/
+#define ODN_PDP_VID1HCOEFF10_VID1HCOEFF10_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF10_VID1HCOEFF10_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF10_VID1HCOEFF10_SHIFT (0)
+#define ODN_PDP_VID1HCOEFF10_VID1HCOEFF10_LENGTH (32)
+#define ODN_PDP_VID1HCOEFF10_VID1HCOEFF10_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1HCOEFF11_OFFSET (0x04BC)
+
+/* PDP, VID1HCOEFF11, VID1HCOEFF11
+*/
+#define ODN_PDP_VID1HCOEFF11_VID1HCOEFF11_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF11_VID1HCOEFF11_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF11_VID1HCOEFF11_SHIFT (0)
+#define ODN_PDP_VID1HCOEFF11_VID1HCOEFF11_LENGTH (32)
+#define ODN_PDP_VID1HCOEFF11_VID1HCOEFF11_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1HCOEFF12_OFFSET (0x04C0)
+
+/* PDP, VID1HCOEFF12, VID1HCOEFF12
+*/
+#define ODN_PDP_VID1HCOEFF12_VID1HCOEFF12_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF12_VID1HCOEFF12_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF12_VID1HCOEFF12_SHIFT (0)
+#define ODN_PDP_VID1HCOEFF12_VID1HCOEFF12_LENGTH (32)
+#define ODN_PDP_VID1HCOEFF12_VID1HCOEFF12_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1HCOEFF13_OFFSET (0x04C4)
+
+/* PDP, VID1HCOEFF13, VID1HCOEFF13
+*/
+#define ODN_PDP_VID1HCOEFF13_VID1HCOEFF13_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF13_VID1HCOEFF13_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF13_VID1HCOEFF13_SHIFT (0)
+#define ODN_PDP_VID1HCOEFF13_VID1HCOEFF13_LENGTH (32)
+#define ODN_PDP_VID1HCOEFF13_VID1HCOEFF13_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1HCOEFF14_OFFSET (0x04C8)
+
+/* PDP, VID1HCOEFF14, VID1HCOEFF14
+*/
+#define ODN_PDP_VID1HCOEFF14_VID1HCOEFF14_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF14_VID1HCOEFF14_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF14_VID1HCOEFF14_SHIFT (0)
+#define ODN_PDP_VID1HCOEFF14_VID1HCOEFF14_LENGTH (32)
+#define ODN_PDP_VID1HCOEFF14_VID1HCOEFF14_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1HCOEFF15_OFFSET (0x04CC)
+
+/* PDP, VID1HCOEFF15, VID1HCOEFF15
+*/
+#define ODN_PDP_VID1HCOEFF15_VID1HCOEFF15_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF15_VID1HCOEFF15_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID1HCOEFF15_VID1HCOEFF15_SHIFT (0)
+#define ODN_PDP_VID1HCOEFF15_VID1HCOEFF15_LENGTH (32)
+#define ODN_PDP_VID1HCOEFF15_VID1HCOEFF15_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1HCOEFF16_OFFSET (0x04D0)
+
+/* PDP, VID1HCOEFF16, VID1HCOEFF16
+*/
+#define ODN_PDP_VID1HCOEFF16_VID1HCOEFF16_MASK (0x000000FF)
+#define ODN_PDP_VID1HCOEFF16_VID1HCOEFF16_LSBMASK (0x000000FF)
+#define ODN_PDP_VID1HCOEFF16_VID1HCOEFF16_SHIFT (0)
+#define ODN_PDP_VID1HCOEFF16_VID1HCOEFF16_LENGTH (8)
+#define ODN_PDP_VID1HCOEFF16_VID1HCOEFF16_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1SCALESIZE_OFFSET (0x04D4)
+
+/* PDP, VID1SCALESIZE, VID1SCALEWIDTH
+*/
+#define ODN_PDP_VID1SCALESIZE_VID1SCALEWIDTH_MASK (0x0FFF0000)
+#define ODN_PDP_VID1SCALESIZE_VID1SCALEWIDTH_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID1SCALESIZE_VID1SCALEWIDTH_SHIFT (16)
+#define ODN_PDP_VID1SCALESIZE_VID1SCALEWIDTH_LENGTH (12)
+#define ODN_PDP_VID1SCALESIZE_VID1SCALEWIDTH_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1SCALESIZE, VID1SCALEHEIGHT
+*/
+#define ODN_PDP_VID1SCALESIZE_VID1SCALEHEIGHT_MASK (0x00000FFF)
+#define ODN_PDP_VID1SCALESIZE_VID1SCALEHEIGHT_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID1SCALESIZE_VID1SCALEHEIGHT_SHIFT (0)
+#define ODN_PDP_VID1SCALESIZE_VID1SCALEHEIGHT_LENGTH (12)
+#define ODN_PDP_VID1SCALESIZE_VID1SCALEHEIGHT_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_CORE_ID_OFFSET (0x04E0)
+
+/* PDP, PVR_ODN_PDP_CORE_ID, GROUP_ID
+*/
+#define ODN_PDP_CORE_ID_GROUP_ID_MASK (0xFF000000)
+#define ODN_PDP_CORE_ID_GROUP_ID_LSBMASK (0x000000FF)
+#define ODN_PDP_CORE_ID_GROUP_ID_SHIFT (24)
+#define ODN_PDP_CORE_ID_GROUP_ID_LENGTH (8)
+#define ODN_PDP_CORE_ID_GROUP_ID_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PVR_ODN_PDP_CORE_ID, CORE_ID
+*/
+#define ODN_PDP_CORE_ID_CORE_ID_MASK (0x00FF0000)
+#define ODN_PDP_CORE_ID_CORE_ID_LSBMASK (0x000000FF)
+#define ODN_PDP_CORE_ID_CORE_ID_SHIFT (16)
+#define ODN_PDP_CORE_ID_CORE_ID_LENGTH (8)
+#define ODN_PDP_CORE_ID_CORE_ID_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PVR_ODN_PDP_CORE_ID, CONFIG_ID
+*/
+#define ODN_PDP_CORE_ID_CONFIG_ID_MASK (0x0000FFFF)
+#define ODN_PDP_CORE_ID_CONFIG_ID_LSBMASK (0x0000FFFF)
+#define ODN_PDP_CORE_ID_CONFIG_ID_SHIFT (0)
+#define ODN_PDP_CORE_ID_CONFIG_ID_LENGTH (16)
+#define ODN_PDP_CORE_ID_CONFIG_ID_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_CORE_REV_OFFSET (0x04F0)
+
+/* PDP, PVR_ODN_PDP_CORE_REV, MAJOR_REV
+*/
+#define ODN_PDP_CORE_REV_MAJOR_REV_MASK (0x00FF0000)
+#define ODN_PDP_CORE_REV_MAJOR_REV_LSBMASK (0x000000FF)
+#define ODN_PDP_CORE_REV_MAJOR_REV_SHIFT (16)
+#define ODN_PDP_CORE_REV_MAJOR_REV_LENGTH (8)
+#define ODN_PDP_CORE_REV_MAJOR_REV_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PVR_ODN_PDP_CORE_REV, MINOR_REV
+*/
+#define ODN_PDP_CORE_REV_MINOR_REV_MASK (0x0000FF00)
+#define ODN_PDP_CORE_REV_MINOR_REV_LSBMASK (0x000000FF)
+#define ODN_PDP_CORE_REV_MINOR_REV_SHIFT (8)
+#define ODN_PDP_CORE_REV_MINOR_REV_LENGTH (8)
+#define ODN_PDP_CORE_REV_MINOR_REV_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PVR_ODN_PDP_CORE_REV, MAINT_REV
+*/
+#define ODN_PDP_CORE_REV_MAINT_REV_MASK (0x000000FF)
+#define ODN_PDP_CORE_REV_MAINT_REV_LSBMASK (0x000000FF)
+#define ODN_PDP_CORE_REV_MAINT_REV_SHIFT (0)
+#define ODN_PDP_CORE_REV_MAINT_REV_LENGTH (8)
+#define ODN_PDP_CORE_REV_MAINT_REV_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2SCALECTRL_OFFSET (0x0500)
+
+/* PDP, VID2SCALECTRL, VID2HSCALEBP
+*/
+#define ODN_PDP_VID2SCALECTRL_VID2HSCALEBP_MASK (0x80000000)
+#define ODN_PDP_VID2SCALECTRL_VID2HSCALEBP_LSBMASK (0x00000001)
+#define ODN_PDP_VID2SCALECTRL_VID2HSCALEBP_SHIFT (31)
+#define ODN_PDP_VID2SCALECTRL_VID2HSCALEBP_LENGTH (1)
+#define ODN_PDP_VID2SCALECTRL_VID2HSCALEBP_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2SCALECTRL, VID2VSCALEBP
+*/
+#define ODN_PDP_VID2SCALECTRL_VID2VSCALEBP_MASK (0x40000000)
+#define ODN_PDP_VID2SCALECTRL_VID2VSCALEBP_LSBMASK (0x00000001)
+#define ODN_PDP_VID2SCALECTRL_VID2VSCALEBP_SHIFT (30)
+#define ODN_PDP_VID2SCALECTRL_VID2VSCALEBP_LENGTH (1)
+#define ODN_PDP_VID2SCALECTRL_VID2VSCALEBP_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2SCALECTRL, VID2HSBEFOREVS
+*/
+#define ODN_PDP_VID2SCALECTRL_VID2HSBEFOREVS_MASK (0x20000000)
+#define ODN_PDP_VID2SCALECTRL_VID2HSBEFOREVS_LSBMASK (0x00000001)
+#define ODN_PDP_VID2SCALECTRL_VID2HSBEFOREVS_SHIFT (29)
+#define ODN_PDP_VID2SCALECTRL_VID2HSBEFOREVS_LENGTH (1)
+#define ODN_PDP_VID2SCALECTRL_VID2HSBEFOREVS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2SCALECTRL, VID2VSURUNCTRL
+*/
+#define ODN_PDP_VID2SCALECTRL_VID2VSURUNCTRL_MASK (0x08000000)
+#define ODN_PDP_VID2SCALECTRL_VID2VSURUNCTRL_LSBMASK (0x00000001)
+#define ODN_PDP_VID2SCALECTRL_VID2VSURUNCTRL_SHIFT (27)
+#define ODN_PDP_VID2SCALECTRL_VID2VSURUNCTRL_LENGTH (1)
+#define ODN_PDP_VID2SCALECTRL_VID2VSURUNCTRL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2SCALECTRL, VID2PAN_EN
+*/
+#define ODN_PDP_VID2SCALECTRL_VID2PAN_EN_MASK (0x00040000)
+#define ODN_PDP_VID2SCALECTRL_VID2PAN_EN_LSBMASK (0x00000001)
+#define ODN_PDP_VID2SCALECTRL_VID2PAN_EN_SHIFT (18)
+#define ODN_PDP_VID2SCALECTRL_VID2PAN_EN_LENGTH (1)
+#define ODN_PDP_VID2SCALECTRL_VID2PAN_EN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2SCALECTRL, VID2VORDER
+*/
+#define ODN_PDP_VID2SCALECTRL_VID2VORDER_MASK (0x00030000)
+#define ODN_PDP_VID2SCALECTRL_VID2VORDER_LSBMASK (0x00000003)
+#define ODN_PDP_VID2SCALECTRL_VID2VORDER_SHIFT (16)
+#define ODN_PDP_VID2SCALECTRL_VID2VORDER_LENGTH (2)
+#define ODN_PDP_VID2SCALECTRL_VID2VORDER_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2SCALECTRL, VID2VPITCH
+*/
+#define ODN_PDP_VID2SCALECTRL_VID2VPITCH_MASK (0x0000FFFF)
+#define ODN_PDP_VID2SCALECTRL_VID2VPITCH_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID2SCALECTRL_VID2VPITCH_SHIFT (0)
+#define ODN_PDP_VID2SCALECTRL_VID2VPITCH_LENGTH (16)
+#define ODN_PDP_VID2SCALECTRL_VID2VPITCH_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2VSINIT_OFFSET (0x0504)
+
+/* PDP, VID2VSINIT, VID2VINITIAL1
+*/
+#define ODN_PDP_VID2VSINIT_VID2VINITIAL1_MASK (0xFFFF0000)
+#define ODN_PDP_VID2VSINIT_VID2VINITIAL1_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID2VSINIT_VID2VINITIAL1_SHIFT (16)
+#define ODN_PDP_VID2VSINIT_VID2VINITIAL1_LENGTH (16)
+#define ODN_PDP_VID2VSINIT_VID2VINITIAL1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2VSINIT, VID2VINITIAL0
+*/
+#define ODN_PDP_VID2VSINIT_VID2VINITIAL0_MASK (0x0000FFFF)
+#define ODN_PDP_VID2VSINIT_VID2VINITIAL0_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID2VSINIT_VID2VINITIAL0_SHIFT (0)
+#define ODN_PDP_VID2VSINIT_VID2VINITIAL0_LENGTH (16)
+#define ODN_PDP_VID2VSINIT_VID2VINITIAL0_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2VCOEFF0_OFFSET (0x0508)
+
+/* PDP, VID2VCOEFF0, VID2VCOEFF0
+*/
+#define ODN_PDP_VID2VCOEFF0_VID2VCOEFF0_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2VCOEFF0_VID2VCOEFF0_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2VCOEFF0_VID2VCOEFF0_SHIFT (0)
+#define ODN_PDP_VID2VCOEFF0_VID2VCOEFF0_LENGTH (32)
+#define ODN_PDP_VID2VCOEFF0_VID2VCOEFF0_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2VCOEFF1_OFFSET (0x050C)
+
+/* PDP, VID2VCOEFF1, VID2VCOEFF1
+*/
+#define ODN_PDP_VID2VCOEFF1_VID2VCOEFF1_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2VCOEFF1_VID2VCOEFF1_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2VCOEFF1_VID2VCOEFF1_SHIFT (0)
+#define ODN_PDP_VID2VCOEFF1_VID2VCOEFF1_LENGTH (32)
+#define ODN_PDP_VID2VCOEFF1_VID2VCOEFF1_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2VCOEFF2_OFFSET (0x0510)
+
+/* PDP, VID2VCOEFF2, VID2VCOEFF2
+*/
+#define ODN_PDP_VID2VCOEFF2_VID2VCOEFF2_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2VCOEFF2_VID2VCOEFF2_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2VCOEFF2_VID2VCOEFF2_SHIFT (0)
+#define ODN_PDP_VID2VCOEFF2_VID2VCOEFF2_LENGTH (32)
+#define ODN_PDP_VID2VCOEFF2_VID2VCOEFF2_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2VCOEFF3_OFFSET (0x0514)
+
+/* PDP, VID2VCOEFF3, VID2VCOEFF3
+*/
+#define ODN_PDP_VID2VCOEFF3_VID2VCOEFF3_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2VCOEFF3_VID2VCOEFF3_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2VCOEFF3_VID2VCOEFF3_SHIFT (0)
+#define ODN_PDP_VID2VCOEFF3_VID2VCOEFF3_LENGTH (32)
+#define ODN_PDP_VID2VCOEFF3_VID2VCOEFF3_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2VCOEFF4_OFFSET (0x0518)
+
+/* PDP, VID2VCOEFF4, VID2VCOEFF4
+*/
+#define ODN_PDP_VID2VCOEFF4_VID2VCOEFF4_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2VCOEFF4_VID2VCOEFF4_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2VCOEFF4_VID2VCOEFF4_SHIFT (0)
+#define ODN_PDP_VID2VCOEFF4_VID2VCOEFF4_LENGTH (32)
+#define ODN_PDP_VID2VCOEFF4_VID2VCOEFF4_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2VCOEFF5_OFFSET (0x051C)
+
+/* PDP, VID2VCOEFF5, VID2VCOEFF5
+*/
+#define ODN_PDP_VID2VCOEFF5_VID2VCOEFF5_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2VCOEFF5_VID2VCOEFF5_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2VCOEFF5_VID2VCOEFF5_SHIFT (0)
+#define ODN_PDP_VID2VCOEFF5_VID2VCOEFF5_LENGTH (32)
+#define ODN_PDP_VID2VCOEFF5_VID2VCOEFF5_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2VCOEFF6_OFFSET (0x0520)
+
+/* PDP, VID2VCOEFF6, VID2VCOEFF6
+*/
+#define ODN_PDP_VID2VCOEFF6_VID2VCOEFF6_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2VCOEFF6_VID2VCOEFF6_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2VCOEFF6_VID2VCOEFF6_SHIFT (0)
+#define ODN_PDP_VID2VCOEFF6_VID2VCOEFF6_LENGTH (32)
+#define ODN_PDP_VID2VCOEFF6_VID2VCOEFF6_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2VCOEFF7_OFFSET (0x0524)
+
+/* PDP, VID2VCOEFF7, VID2VCOEFF7
+*/
+#define ODN_PDP_VID2VCOEFF7_VID2VCOEFF7_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2VCOEFF7_VID2VCOEFF7_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2VCOEFF7_VID2VCOEFF7_SHIFT (0)
+#define ODN_PDP_VID2VCOEFF7_VID2VCOEFF7_LENGTH (32)
+#define ODN_PDP_VID2VCOEFF7_VID2VCOEFF7_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2VCOEFF8_OFFSET (0x0528)
+
+/* PDP, VID2VCOEFF8, VID2VCOEFF8
+*/
+#define ODN_PDP_VID2VCOEFF8_VID2VCOEFF8_MASK (0x000000FF)
+#define ODN_PDP_VID2VCOEFF8_VID2VCOEFF8_LSBMASK (0x000000FF)
+#define ODN_PDP_VID2VCOEFF8_VID2VCOEFF8_SHIFT (0)
+#define ODN_PDP_VID2VCOEFF8_VID2VCOEFF8_LENGTH (8)
+#define ODN_PDP_VID2VCOEFF8_VID2VCOEFF8_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2HSINIT_OFFSET (0x052C)
+
+/* PDP, VID2HSINIT, VID2HINITIAL
+*/
+#define ODN_PDP_VID2HSINIT_VID2HINITIAL_MASK (0xFFFF0000)
+#define ODN_PDP_VID2HSINIT_VID2HINITIAL_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID2HSINIT_VID2HINITIAL_SHIFT (16)
+#define ODN_PDP_VID2HSINIT_VID2HINITIAL_LENGTH (16)
+#define ODN_PDP_VID2HSINIT_VID2HINITIAL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2HSINIT, VID2HPITCH
+*/
+#define ODN_PDP_VID2HSINIT_VID2HPITCH_MASK (0x0000FFFF)
+#define ODN_PDP_VID2HSINIT_VID2HPITCH_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID2HSINIT_VID2HPITCH_SHIFT (0)
+#define ODN_PDP_VID2HSINIT_VID2HPITCH_LENGTH (16)
+#define ODN_PDP_VID2HSINIT_VID2HPITCH_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2HCOEFF0_OFFSET (0x0530)
+
+/* PDP, VID2HCOEFF0, VID2HCOEFF0
+*/
+#define ODN_PDP_VID2HCOEFF0_VID2HCOEFF0_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF0_VID2HCOEFF0_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF0_VID2HCOEFF0_SHIFT (0)
+#define ODN_PDP_VID2HCOEFF0_VID2HCOEFF0_LENGTH (32)
+#define ODN_PDP_VID2HCOEFF0_VID2HCOEFF0_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2HCOEFF1_OFFSET (0x0534)
+
+/* PDP, VID2HCOEFF1, VID2HCOEFF1
+*/
+#define ODN_PDP_VID2HCOEFF1_VID2HCOEFF1_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF1_VID2HCOEFF1_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF1_VID2HCOEFF1_SHIFT (0)
+#define ODN_PDP_VID2HCOEFF1_VID2HCOEFF1_LENGTH (32)
+#define ODN_PDP_VID2HCOEFF1_VID2HCOEFF1_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2HCOEFF2_OFFSET (0x0538)
+
+/* PDP, VID2HCOEFF2, VID2HCOEFF2
+*/
+#define ODN_PDP_VID2HCOEFF2_VID2HCOEFF2_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF2_VID2HCOEFF2_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF2_VID2HCOEFF2_SHIFT (0)
+#define ODN_PDP_VID2HCOEFF2_VID2HCOEFF2_LENGTH (32)
+#define ODN_PDP_VID2HCOEFF2_VID2HCOEFF2_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2HCOEFF3_OFFSET (0x053C)
+
+/* PDP, VID2HCOEFF3, VID2HCOEFF3
+*/
+#define ODN_PDP_VID2HCOEFF3_VID2HCOEFF3_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF3_VID2HCOEFF3_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF3_VID2HCOEFF3_SHIFT (0)
+#define ODN_PDP_VID2HCOEFF3_VID2HCOEFF3_LENGTH (32)
+#define ODN_PDP_VID2HCOEFF3_VID2HCOEFF3_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2HCOEFF4_OFFSET (0x0540)
+
+/* PDP, VID2HCOEFF4, VID2HCOEFF4
+*/
+#define ODN_PDP_VID2HCOEFF4_VID2HCOEFF4_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF4_VID2HCOEFF4_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF4_VID2HCOEFF4_SHIFT (0)
+#define ODN_PDP_VID2HCOEFF4_VID2HCOEFF4_LENGTH (32)
+#define ODN_PDP_VID2HCOEFF4_VID2HCOEFF4_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2HCOEFF5_OFFSET (0x0544)
+
+/* PDP, VID2HCOEFF5, VID2HCOEFF5
+*/
+#define ODN_PDP_VID2HCOEFF5_VID2HCOEFF5_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF5_VID2HCOEFF5_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF5_VID2HCOEFF5_SHIFT (0)
+#define ODN_PDP_VID2HCOEFF5_VID2HCOEFF5_LENGTH (32)
+#define ODN_PDP_VID2HCOEFF5_VID2HCOEFF5_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2HCOEFF6_OFFSET (0x0548)
+
+/* PDP, VID2HCOEFF6, VID2HCOEFF6
+*/
+#define ODN_PDP_VID2HCOEFF6_VID2HCOEFF6_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF6_VID2HCOEFF6_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF6_VID2HCOEFF6_SHIFT (0)
+#define ODN_PDP_VID2HCOEFF6_VID2HCOEFF6_LENGTH (32)
+#define ODN_PDP_VID2HCOEFF6_VID2HCOEFF6_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2HCOEFF7_OFFSET (0x054C)
+
+/* PDP, VID2HCOEFF7, VID2HCOEFF7
+*/
+#define ODN_PDP_VID2HCOEFF7_VID2HCOEFF7_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF7_VID2HCOEFF7_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF7_VID2HCOEFF7_SHIFT (0)
+#define ODN_PDP_VID2HCOEFF7_VID2HCOEFF7_LENGTH (32)
+#define ODN_PDP_VID2HCOEFF7_VID2HCOEFF7_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2HCOEFF8_OFFSET (0x0550)
+
+/* PDP, VID2HCOEFF8, VID2HCOEFF8
+*/
+#define ODN_PDP_VID2HCOEFF8_VID2HCOEFF8_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF8_VID2HCOEFF8_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF8_VID2HCOEFF8_SHIFT (0)
+#define ODN_PDP_VID2HCOEFF8_VID2HCOEFF8_LENGTH (32)
+#define ODN_PDP_VID2HCOEFF8_VID2HCOEFF8_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2HCOEFF9_OFFSET (0x0554)
+
+/* PDP, VID2HCOEFF9, VID2HCOEFF9
+*/
+#define ODN_PDP_VID2HCOEFF9_VID2HCOEFF9_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF9_VID2HCOEFF9_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF9_VID2HCOEFF9_SHIFT (0)
+#define ODN_PDP_VID2HCOEFF9_VID2HCOEFF9_LENGTH (32)
+#define ODN_PDP_VID2HCOEFF9_VID2HCOEFF9_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2HCOEFF10_OFFSET (0x0558)
+
+/* PDP, VID2HCOEFF10, VID2HCOEFF10
+*/
+#define ODN_PDP_VID2HCOEFF10_VID2HCOEFF10_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF10_VID2HCOEFF10_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF10_VID2HCOEFF10_SHIFT (0)
+#define ODN_PDP_VID2HCOEFF10_VID2HCOEFF10_LENGTH (32)
+#define ODN_PDP_VID2HCOEFF10_VID2HCOEFF10_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2HCOEFF11_OFFSET (0x055C)
+
+/* PDP, VID2HCOEFF11, VID2HCOEFF11
+*/
+#define ODN_PDP_VID2HCOEFF11_VID2HCOEFF11_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF11_VID2HCOEFF11_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF11_VID2HCOEFF11_SHIFT (0)
+#define ODN_PDP_VID2HCOEFF11_VID2HCOEFF11_LENGTH (32)
+#define ODN_PDP_VID2HCOEFF11_VID2HCOEFF11_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2HCOEFF12_OFFSET (0x0560)
+
+/* PDP, VID2HCOEFF12, VID2HCOEFF12
+*/
+#define ODN_PDP_VID2HCOEFF12_VID2HCOEFF12_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF12_VID2HCOEFF12_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF12_VID2HCOEFF12_SHIFT (0)
+#define ODN_PDP_VID2HCOEFF12_VID2HCOEFF12_LENGTH (32)
+#define ODN_PDP_VID2HCOEFF12_VID2HCOEFF12_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2HCOEFF13_OFFSET (0x0564)
+
+/* PDP, VID2HCOEFF13, VID2HCOEFF13
+*/
+#define ODN_PDP_VID2HCOEFF13_VID2HCOEFF13_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF13_VID2HCOEFF13_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF13_VID2HCOEFF13_SHIFT (0)
+#define ODN_PDP_VID2HCOEFF13_VID2HCOEFF13_LENGTH (32)
+#define ODN_PDP_VID2HCOEFF13_VID2HCOEFF13_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2HCOEFF14_OFFSET (0x0568)
+
+/* PDP, VID2HCOEFF14, VID2HCOEFF14
+*/
+#define ODN_PDP_VID2HCOEFF14_VID2HCOEFF14_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF14_VID2HCOEFF14_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF14_VID2HCOEFF14_SHIFT (0)
+#define ODN_PDP_VID2HCOEFF14_VID2HCOEFF14_LENGTH (32)
+#define ODN_PDP_VID2HCOEFF14_VID2HCOEFF14_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2HCOEFF15_OFFSET (0x056C)
+
+/* PDP, VID2HCOEFF15, VID2HCOEFF15
+*/
+#define ODN_PDP_VID2HCOEFF15_VID2HCOEFF15_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF15_VID2HCOEFF15_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID2HCOEFF15_VID2HCOEFF15_SHIFT (0)
+#define ODN_PDP_VID2HCOEFF15_VID2HCOEFF15_LENGTH (32)
+#define ODN_PDP_VID2HCOEFF15_VID2HCOEFF15_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2HCOEFF16_OFFSET (0x0570)
+
+/* PDP, VID2HCOEFF16, VID2HCOEFF16
+*/
+#define ODN_PDP_VID2HCOEFF16_VID2HCOEFF16_MASK (0x000000FF)
+#define ODN_PDP_VID2HCOEFF16_VID2HCOEFF16_LSBMASK (0x000000FF)
+#define ODN_PDP_VID2HCOEFF16_VID2HCOEFF16_SHIFT (0)
+#define ODN_PDP_VID2HCOEFF16_VID2HCOEFF16_LENGTH (8)
+#define ODN_PDP_VID2HCOEFF16_VID2HCOEFF16_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2SCALESIZE_OFFSET (0x0574)
+
+/* PDP, VID2SCALESIZE, VID2SCALEWIDTH
+*/
+#define ODN_PDP_VID2SCALESIZE_VID2SCALEWIDTH_MASK (0x0FFF0000)
+#define ODN_PDP_VID2SCALESIZE_VID2SCALEWIDTH_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID2SCALESIZE_VID2SCALEWIDTH_SHIFT (16)
+#define ODN_PDP_VID2SCALESIZE_VID2SCALEWIDTH_LENGTH (12)
+#define ODN_PDP_VID2SCALESIZE_VID2SCALEWIDTH_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2SCALESIZE, VID2SCALEHEIGHT
+*/
+#define ODN_PDP_VID2SCALESIZE_VID2SCALEHEIGHT_MASK (0x00000FFF)
+#define ODN_PDP_VID2SCALESIZE_VID2SCALEHEIGHT_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID2SCALESIZE_VID2SCALEHEIGHT_SHIFT (0)
+#define ODN_PDP_VID2SCALESIZE_VID2SCALEHEIGHT_LENGTH (12)
+#define ODN_PDP_VID2SCALESIZE_VID2SCALEHEIGHT_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3SCALECTRL_OFFSET (0x0578)
+
+/* PDP, VID3SCALECTRL, VID3HSCALEBP
+*/
+#define ODN_PDP_VID3SCALECTRL_VID3HSCALEBP_MASK (0x80000000)
+#define ODN_PDP_VID3SCALECTRL_VID3HSCALEBP_LSBMASK (0x00000001)
+#define ODN_PDP_VID3SCALECTRL_VID3HSCALEBP_SHIFT (31)
+#define ODN_PDP_VID3SCALECTRL_VID3HSCALEBP_LENGTH (1)
+#define ODN_PDP_VID3SCALECTRL_VID3HSCALEBP_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3SCALECTRL, VID3VSCALEBP
+*/
+#define ODN_PDP_VID3SCALECTRL_VID3VSCALEBP_MASK (0x40000000)
+#define ODN_PDP_VID3SCALECTRL_VID3VSCALEBP_LSBMASK (0x00000001)
+#define ODN_PDP_VID3SCALECTRL_VID3VSCALEBP_SHIFT (30)
+#define ODN_PDP_VID3SCALECTRL_VID3VSCALEBP_LENGTH (1)
+#define ODN_PDP_VID3SCALECTRL_VID3VSCALEBP_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3SCALECTRL, VID3HSBEFOREVS
+*/
+#define ODN_PDP_VID3SCALECTRL_VID3HSBEFOREVS_MASK (0x20000000)
+#define ODN_PDP_VID3SCALECTRL_VID3HSBEFOREVS_LSBMASK (0x00000001)
+#define ODN_PDP_VID3SCALECTRL_VID3HSBEFOREVS_SHIFT (29)
+#define ODN_PDP_VID3SCALECTRL_VID3HSBEFOREVS_LENGTH (1)
+#define ODN_PDP_VID3SCALECTRL_VID3HSBEFOREVS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3SCALECTRL, VID3VSURUNCTRL
+*/
+#define ODN_PDP_VID3SCALECTRL_VID3VSURUNCTRL_MASK (0x08000000)
+#define ODN_PDP_VID3SCALECTRL_VID3VSURUNCTRL_LSBMASK (0x00000001)
+#define ODN_PDP_VID3SCALECTRL_VID3VSURUNCTRL_SHIFT (27)
+#define ODN_PDP_VID3SCALECTRL_VID3VSURUNCTRL_LENGTH (1)
+#define ODN_PDP_VID3SCALECTRL_VID3VSURUNCTRL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3SCALECTRL, VID3PAN_EN
+*/
+#define ODN_PDP_VID3SCALECTRL_VID3PAN_EN_MASK (0x00040000)
+#define ODN_PDP_VID3SCALECTRL_VID3PAN_EN_LSBMASK (0x00000001)
+#define ODN_PDP_VID3SCALECTRL_VID3PAN_EN_SHIFT (18)
+#define ODN_PDP_VID3SCALECTRL_VID3PAN_EN_LENGTH (1)
+#define ODN_PDP_VID3SCALECTRL_VID3PAN_EN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3SCALECTRL, VID3VORDER
+*/
+#define ODN_PDP_VID3SCALECTRL_VID3VORDER_MASK (0x00030000)
+#define ODN_PDP_VID3SCALECTRL_VID3VORDER_LSBMASK (0x00000003)
+#define ODN_PDP_VID3SCALECTRL_VID3VORDER_SHIFT (16)
+#define ODN_PDP_VID3SCALECTRL_VID3VORDER_LENGTH (2)
+#define ODN_PDP_VID3SCALECTRL_VID3VORDER_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3SCALECTRL, VID3VPITCH
+*/
+#define ODN_PDP_VID3SCALECTRL_VID3VPITCH_MASK (0x0000FFFF)
+#define ODN_PDP_VID3SCALECTRL_VID3VPITCH_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID3SCALECTRL_VID3VPITCH_SHIFT (0)
+#define ODN_PDP_VID3SCALECTRL_VID3VPITCH_LENGTH (16)
+#define ODN_PDP_VID3SCALECTRL_VID3VPITCH_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3VSINIT_OFFSET (0x057C)
+
+/* PDP, VID3VSINIT, VID3VINITIAL1
+*/
+#define ODN_PDP_VID3VSINIT_VID3VINITIAL1_MASK (0xFFFF0000)
+#define ODN_PDP_VID3VSINIT_VID3VINITIAL1_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID3VSINIT_VID3VINITIAL1_SHIFT (16)
+#define ODN_PDP_VID3VSINIT_VID3VINITIAL1_LENGTH (16)
+#define ODN_PDP_VID3VSINIT_VID3VINITIAL1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3VSINIT, VID3VINITIAL0
+*/
+#define ODN_PDP_VID3VSINIT_VID3VINITIAL0_MASK (0x0000FFFF)
+#define ODN_PDP_VID3VSINIT_VID3VINITIAL0_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID3VSINIT_VID3VINITIAL0_SHIFT (0)
+#define ODN_PDP_VID3VSINIT_VID3VINITIAL0_LENGTH (16)
+#define ODN_PDP_VID3VSINIT_VID3VINITIAL0_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3VCOEFF0_OFFSET (0x0580)
+
+/* PDP, VID3VCOEFF0, VID3VCOEFF0
+*/
+#define ODN_PDP_VID3VCOEFF0_VID3VCOEFF0_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3VCOEFF0_VID3VCOEFF0_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3VCOEFF0_VID3VCOEFF0_SHIFT (0)
+#define ODN_PDP_VID3VCOEFF0_VID3VCOEFF0_LENGTH (32)
+#define ODN_PDP_VID3VCOEFF0_VID3VCOEFF0_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3VCOEFF1_OFFSET (0x0584)
+
+/* PDP, VID3VCOEFF1, VID3VCOEFF1
+*/
+#define ODN_PDP_VID3VCOEFF1_VID3VCOEFF1_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3VCOEFF1_VID3VCOEFF1_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3VCOEFF1_VID3VCOEFF1_SHIFT (0)
+#define ODN_PDP_VID3VCOEFF1_VID3VCOEFF1_LENGTH (32)
+#define ODN_PDP_VID3VCOEFF1_VID3VCOEFF1_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3VCOEFF2_OFFSET (0x0588)
+
+/* PDP, VID3VCOEFF2, VID3VCOEFF2
+*/
+#define ODN_PDP_VID3VCOEFF2_VID3VCOEFF2_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3VCOEFF2_VID3VCOEFF2_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3VCOEFF2_VID3VCOEFF2_SHIFT (0)
+#define ODN_PDP_VID3VCOEFF2_VID3VCOEFF2_LENGTH (32)
+#define ODN_PDP_VID3VCOEFF2_VID3VCOEFF2_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3VCOEFF3_OFFSET (0x058C)
+
+/* PDP, VID3VCOEFF3, VID3VCOEFF3
+*/
+#define ODN_PDP_VID3VCOEFF3_VID3VCOEFF3_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3VCOEFF3_VID3VCOEFF3_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3VCOEFF3_VID3VCOEFF3_SHIFT (0)
+#define ODN_PDP_VID3VCOEFF3_VID3VCOEFF3_LENGTH (32)
+#define ODN_PDP_VID3VCOEFF3_VID3VCOEFF3_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3VCOEFF4_OFFSET (0x0590)
+
+/* PDP, VID3VCOEFF4, VID3VCOEFF4
+*/
+#define ODN_PDP_VID3VCOEFF4_VID3VCOEFF4_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3VCOEFF4_VID3VCOEFF4_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3VCOEFF4_VID3VCOEFF4_SHIFT (0)
+#define ODN_PDP_VID3VCOEFF4_VID3VCOEFF4_LENGTH (32)
+#define ODN_PDP_VID3VCOEFF4_VID3VCOEFF4_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3VCOEFF5_OFFSET (0x0594)
+
+/* PDP, VID3VCOEFF5, VID3VCOEFF5
+*/
+#define ODN_PDP_VID3VCOEFF5_VID3VCOEFF5_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3VCOEFF5_VID3VCOEFF5_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3VCOEFF5_VID3VCOEFF5_SHIFT (0)
+#define ODN_PDP_VID3VCOEFF5_VID3VCOEFF5_LENGTH (32)
+#define ODN_PDP_VID3VCOEFF5_VID3VCOEFF5_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3VCOEFF6_OFFSET (0x0598)
+
+/* PDP, VID3VCOEFF6, VID3VCOEFF6
+*/
+#define ODN_PDP_VID3VCOEFF6_VID3VCOEFF6_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3VCOEFF6_VID3VCOEFF6_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3VCOEFF6_VID3VCOEFF6_SHIFT (0)
+#define ODN_PDP_VID3VCOEFF6_VID3VCOEFF6_LENGTH (32)
+#define ODN_PDP_VID3VCOEFF6_VID3VCOEFF6_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3VCOEFF7_OFFSET (0x059C)
+
+/* PDP, VID3VCOEFF7, VID3VCOEFF7
+*/
+#define ODN_PDP_VID3VCOEFF7_VID3VCOEFF7_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3VCOEFF7_VID3VCOEFF7_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3VCOEFF7_VID3VCOEFF7_SHIFT (0)
+#define ODN_PDP_VID3VCOEFF7_VID3VCOEFF7_LENGTH (32)
+#define ODN_PDP_VID3VCOEFF7_VID3VCOEFF7_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3VCOEFF8_OFFSET (0x05A0)
+
+/* PDP, VID3VCOEFF8, VID3VCOEFF8
+*/
+#define ODN_PDP_VID3VCOEFF8_VID3VCOEFF8_MASK (0x000000FF)
+#define ODN_PDP_VID3VCOEFF8_VID3VCOEFF8_LSBMASK (0x000000FF)
+#define ODN_PDP_VID3VCOEFF8_VID3VCOEFF8_SHIFT (0)
+#define ODN_PDP_VID3VCOEFF8_VID3VCOEFF8_LENGTH (8)
+#define ODN_PDP_VID3VCOEFF8_VID3VCOEFF8_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3HSINIT_OFFSET (0x05A4)
+
+/* PDP, VID3HSINIT, VID3HINITIAL
+*/
+#define ODN_PDP_VID3HSINIT_VID3HINITIAL_MASK (0xFFFF0000)
+#define ODN_PDP_VID3HSINIT_VID3HINITIAL_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID3HSINIT_VID3HINITIAL_SHIFT (16)
+#define ODN_PDP_VID3HSINIT_VID3HINITIAL_LENGTH (16)
+#define ODN_PDP_VID3HSINIT_VID3HINITIAL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3HSINIT, VID3HPITCH
+*/
+#define ODN_PDP_VID3HSINIT_VID3HPITCH_MASK (0x0000FFFF)
+#define ODN_PDP_VID3HSINIT_VID3HPITCH_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID3HSINIT_VID3HPITCH_SHIFT (0)
+#define ODN_PDP_VID3HSINIT_VID3HPITCH_LENGTH (16)
+#define ODN_PDP_VID3HSINIT_VID3HPITCH_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3HCOEFF0_OFFSET (0x05A8)
+
+/* PDP, VID3HCOEFF0, VID3HCOEFF0
+*/
+#define ODN_PDP_VID3HCOEFF0_VID3HCOEFF0_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF0_VID3HCOEFF0_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF0_VID3HCOEFF0_SHIFT (0)
+#define ODN_PDP_VID3HCOEFF0_VID3HCOEFF0_LENGTH (32)
+#define ODN_PDP_VID3HCOEFF0_VID3HCOEFF0_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3HCOEFF1_OFFSET (0x05AC)
+
+/* PDP, VID3HCOEFF1, VID3HCOEFF1
+*/
+#define ODN_PDP_VID3HCOEFF1_VID3HCOEFF1_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF1_VID3HCOEFF1_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF1_VID3HCOEFF1_SHIFT (0)
+#define ODN_PDP_VID3HCOEFF1_VID3HCOEFF1_LENGTH (32)
+#define ODN_PDP_VID3HCOEFF1_VID3HCOEFF1_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3HCOEFF2_OFFSET (0x05B0)
+
+/* PDP, VID3HCOEFF2, VID3HCOEFF2
+*/
+#define ODN_PDP_VID3HCOEFF2_VID3HCOEFF2_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF2_VID3HCOEFF2_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF2_VID3HCOEFF2_SHIFT (0)
+#define ODN_PDP_VID3HCOEFF2_VID3HCOEFF2_LENGTH (32)
+#define ODN_PDP_VID3HCOEFF2_VID3HCOEFF2_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3HCOEFF3_OFFSET (0x05B4)
+
+/* PDP, VID3HCOEFF3, VID3HCOEFF3
+*/
+#define ODN_PDP_VID3HCOEFF3_VID3HCOEFF3_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF3_VID3HCOEFF3_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF3_VID3HCOEFF3_SHIFT (0)
+#define ODN_PDP_VID3HCOEFF3_VID3HCOEFF3_LENGTH (32)
+#define ODN_PDP_VID3HCOEFF3_VID3HCOEFF3_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3HCOEFF4_OFFSET (0x05B8)
+
+/* PDP, VID3HCOEFF4, VID3HCOEFF4
+*/
+#define ODN_PDP_VID3HCOEFF4_VID3HCOEFF4_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF4_VID3HCOEFF4_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF4_VID3HCOEFF4_SHIFT (0)
+#define ODN_PDP_VID3HCOEFF4_VID3HCOEFF4_LENGTH (32)
+#define ODN_PDP_VID3HCOEFF4_VID3HCOEFF4_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3HCOEFF5_OFFSET (0x05BC)
+
+/* PDP, VID3HCOEFF5, VID3HCOEFF5
+*/
+#define ODN_PDP_VID3HCOEFF5_VID3HCOEFF5_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF5_VID3HCOEFF5_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF5_VID3HCOEFF5_SHIFT (0)
+#define ODN_PDP_VID3HCOEFF5_VID3HCOEFF5_LENGTH (32)
+#define ODN_PDP_VID3HCOEFF5_VID3HCOEFF5_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3HCOEFF6_OFFSET (0x05C0)
+
+/* PDP, VID3HCOEFF6, VID3HCOEFF6
+*/
+#define ODN_PDP_VID3HCOEFF6_VID3HCOEFF6_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF6_VID3HCOEFF6_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF6_VID3HCOEFF6_SHIFT (0)
+#define ODN_PDP_VID3HCOEFF6_VID3HCOEFF6_LENGTH (32)
+#define ODN_PDP_VID3HCOEFF6_VID3HCOEFF6_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3HCOEFF7_OFFSET (0x05C4)
+
+/* PDP, VID3HCOEFF7, VID3HCOEFF7
+*/
+#define ODN_PDP_VID3HCOEFF7_VID3HCOEFF7_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF7_VID3HCOEFF7_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF7_VID3HCOEFF7_SHIFT (0)
+#define ODN_PDP_VID3HCOEFF7_VID3HCOEFF7_LENGTH (32)
+#define ODN_PDP_VID3HCOEFF7_VID3HCOEFF7_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3HCOEFF8_OFFSET (0x05C8)
+
+/* PDP, VID3HCOEFF8, VID3HCOEFF8
+*/
+#define ODN_PDP_VID3HCOEFF8_VID3HCOEFF8_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF8_VID3HCOEFF8_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF8_VID3HCOEFF8_SHIFT (0)
+#define ODN_PDP_VID3HCOEFF8_VID3HCOEFF8_LENGTH (32)
+#define ODN_PDP_VID3HCOEFF8_VID3HCOEFF8_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3HCOEFF9_OFFSET (0x05CC)
+
+/* PDP, VID3HCOEFF9, VID3HCOEFF9
+*/
+#define ODN_PDP_VID3HCOEFF9_VID3HCOEFF9_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF9_VID3HCOEFF9_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF9_VID3HCOEFF9_SHIFT (0)
+#define ODN_PDP_VID3HCOEFF9_VID3HCOEFF9_LENGTH (32)
+#define ODN_PDP_VID3HCOEFF9_VID3HCOEFF9_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3HCOEFF10_OFFSET (0x05D0)
+
+/* PDP, VID3HCOEFF10, VID3HCOEFF10
+*/
+#define ODN_PDP_VID3HCOEFF10_VID3HCOEFF10_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF10_VID3HCOEFF10_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF10_VID3HCOEFF10_SHIFT (0)
+#define ODN_PDP_VID3HCOEFF10_VID3HCOEFF10_LENGTH (32)
+#define ODN_PDP_VID3HCOEFF10_VID3HCOEFF10_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3HCOEFF11_OFFSET (0x05D4)
+
+/* PDP, VID3HCOEFF11, VID3HCOEFF11
+*/
+#define ODN_PDP_VID3HCOEFF11_VID3HCOEFF11_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF11_VID3HCOEFF11_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF11_VID3HCOEFF11_SHIFT (0)
+#define ODN_PDP_VID3HCOEFF11_VID3HCOEFF11_LENGTH (32)
+#define ODN_PDP_VID3HCOEFF11_VID3HCOEFF11_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3HCOEFF12_OFFSET (0x05D8)
+
+/* PDP, VID3HCOEFF12, VID3HCOEFF12
+*/
+#define ODN_PDP_VID3HCOEFF12_VID3HCOEFF12_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF12_VID3HCOEFF12_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF12_VID3HCOEFF12_SHIFT (0)
+#define ODN_PDP_VID3HCOEFF12_VID3HCOEFF12_LENGTH (32)
+#define ODN_PDP_VID3HCOEFF12_VID3HCOEFF12_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3HCOEFF13_OFFSET (0x05DC)
+
+/* PDP, VID3HCOEFF13, VID3HCOEFF13
+*/
+#define ODN_PDP_VID3HCOEFF13_VID3HCOEFF13_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF13_VID3HCOEFF13_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF13_VID3HCOEFF13_SHIFT (0)
+#define ODN_PDP_VID3HCOEFF13_VID3HCOEFF13_LENGTH (32)
+#define ODN_PDP_VID3HCOEFF13_VID3HCOEFF13_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3HCOEFF14_OFFSET (0x05E0)
+
+/* PDP, VID3HCOEFF14, VID3HCOEFF14
+*/
+#define ODN_PDP_VID3HCOEFF14_VID3HCOEFF14_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF14_VID3HCOEFF14_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF14_VID3HCOEFF14_SHIFT (0)
+#define ODN_PDP_VID3HCOEFF14_VID3HCOEFF14_LENGTH (32)
+#define ODN_PDP_VID3HCOEFF14_VID3HCOEFF14_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3HCOEFF15_OFFSET (0x05E4)
+
+/* PDP, VID3HCOEFF15, VID3HCOEFF15
+*/
+#define ODN_PDP_VID3HCOEFF15_VID3HCOEFF15_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF15_VID3HCOEFF15_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID3HCOEFF15_VID3HCOEFF15_SHIFT (0)
+#define ODN_PDP_VID3HCOEFF15_VID3HCOEFF15_LENGTH (32)
+#define ODN_PDP_VID3HCOEFF15_VID3HCOEFF15_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3HCOEFF16_OFFSET (0x05E8)
+
+/* PDP, VID3HCOEFF16, VID3HCOEFF16
+*/
+#define ODN_PDP_VID3HCOEFF16_VID3HCOEFF16_MASK (0x000000FF)
+#define ODN_PDP_VID3HCOEFF16_VID3HCOEFF16_LSBMASK (0x000000FF)
+#define ODN_PDP_VID3HCOEFF16_VID3HCOEFF16_SHIFT (0)
+#define ODN_PDP_VID3HCOEFF16_VID3HCOEFF16_LENGTH (8)
+#define ODN_PDP_VID3HCOEFF16_VID3HCOEFF16_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3SCALESIZE_OFFSET (0x05EC)
+
+/* PDP, VID3SCALESIZE, VID3SCALEWIDTH
+*/
+#define ODN_PDP_VID3SCALESIZE_VID3SCALEWIDTH_MASK (0x0FFF0000)
+#define ODN_PDP_VID3SCALESIZE_VID3SCALEWIDTH_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID3SCALESIZE_VID3SCALEWIDTH_SHIFT (16)
+#define ODN_PDP_VID3SCALESIZE_VID3SCALEWIDTH_LENGTH (12)
+#define ODN_PDP_VID3SCALESIZE_VID3SCALEWIDTH_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3SCALESIZE, VID3SCALEHEIGHT
+*/
+#define ODN_PDP_VID3SCALESIZE_VID3SCALEHEIGHT_MASK (0x00000FFF)
+#define ODN_PDP_VID3SCALESIZE_VID3SCALEHEIGHT_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID3SCALESIZE_VID3SCALEHEIGHT_SHIFT (0)
+#define ODN_PDP_VID3SCALESIZE_VID3SCALEHEIGHT_LENGTH (12)
+#define ODN_PDP_VID3SCALESIZE_VID3SCALEHEIGHT_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4SCALECTRL_OFFSET (0x05F0)
+
+/* PDP, VID4SCALECTRL, VID4HSCALEBP
+*/
+#define ODN_PDP_VID4SCALECTRL_VID4HSCALEBP_MASK (0x80000000)
+#define ODN_PDP_VID4SCALECTRL_VID4HSCALEBP_LSBMASK (0x00000001)
+#define ODN_PDP_VID4SCALECTRL_VID4HSCALEBP_SHIFT (31)
+#define ODN_PDP_VID4SCALECTRL_VID4HSCALEBP_LENGTH (1)
+#define ODN_PDP_VID4SCALECTRL_VID4HSCALEBP_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4SCALECTRL, VID4VSCALEBP
+*/
+#define ODN_PDP_VID4SCALECTRL_VID4VSCALEBP_MASK (0x40000000)
+#define ODN_PDP_VID4SCALECTRL_VID4VSCALEBP_LSBMASK (0x00000001)
+#define ODN_PDP_VID4SCALECTRL_VID4VSCALEBP_SHIFT (30)
+#define ODN_PDP_VID4SCALECTRL_VID4VSCALEBP_LENGTH (1)
+#define ODN_PDP_VID4SCALECTRL_VID4VSCALEBP_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4SCALECTRL, VID4HSBEFOREVS
+*/
+#define ODN_PDP_VID4SCALECTRL_VID4HSBEFOREVS_MASK (0x20000000)
+#define ODN_PDP_VID4SCALECTRL_VID4HSBEFOREVS_LSBMASK (0x00000001)
+#define ODN_PDP_VID4SCALECTRL_VID4HSBEFOREVS_SHIFT (29)
+#define ODN_PDP_VID4SCALECTRL_VID4HSBEFOREVS_LENGTH (1)
+#define ODN_PDP_VID4SCALECTRL_VID4HSBEFOREVS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4SCALECTRL, VID4VSURUNCTRL
+*/
+#define ODN_PDP_VID4SCALECTRL_VID4VSURUNCTRL_MASK (0x08000000)
+#define ODN_PDP_VID4SCALECTRL_VID4VSURUNCTRL_LSBMASK (0x00000001)
+#define ODN_PDP_VID4SCALECTRL_VID4VSURUNCTRL_SHIFT (27)
+#define ODN_PDP_VID4SCALECTRL_VID4VSURUNCTRL_LENGTH (1)
+#define ODN_PDP_VID4SCALECTRL_VID4VSURUNCTRL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4SCALECTRL, VID4PAN_EN
+*/
+#define ODN_PDP_VID4SCALECTRL_VID4PAN_EN_MASK (0x00040000)
+#define ODN_PDP_VID4SCALECTRL_VID4PAN_EN_LSBMASK (0x00000001)
+#define ODN_PDP_VID4SCALECTRL_VID4PAN_EN_SHIFT (18)
+#define ODN_PDP_VID4SCALECTRL_VID4PAN_EN_LENGTH (1)
+#define ODN_PDP_VID4SCALECTRL_VID4PAN_EN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4SCALECTRL, VID4VORDER
+*/
+#define ODN_PDP_VID4SCALECTRL_VID4VORDER_MASK (0x00030000)
+#define ODN_PDP_VID4SCALECTRL_VID4VORDER_LSBMASK (0x00000003)
+#define ODN_PDP_VID4SCALECTRL_VID4VORDER_SHIFT (16)
+#define ODN_PDP_VID4SCALECTRL_VID4VORDER_LENGTH (2)
+#define ODN_PDP_VID4SCALECTRL_VID4VORDER_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4SCALECTRL, VID4VPITCH
+*/
+#define ODN_PDP_VID4SCALECTRL_VID4VPITCH_MASK (0x0000FFFF)
+#define ODN_PDP_VID4SCALECTRL_VID4VPITCH_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID4SCALECTRL_VID4VPITCH_SHIFT (0)
+#define ODN_PDP_VID4SCALECTRL_VID4VPITCH_LENGTH (16)
+#define ODN_PDP_VID4SCALECTRL_VID4VPITCH_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4VSINIT_OFFSET (0x05F4)
+
+/* PDP, VID4VSINIT, VID4VINITIAL1
+*/
+#define ODN_PDP_VID4VSINIT_VID4VINITIAL1_MASK (0xFFFF0000)
+#define ODN_PDP_VID4VSINIT_VID4VINITIAL1_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID4VSINIT_VID4VINITIAL1_SHIFT (16)
+#define ODN_PDP_VID4VSINIT_VID4VINITIAL1_LENGTH (16)
+#define ODN_PDP_VID4VSINIT_VID4VINITIAL1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4VSINIT, VID4VINITIAL0
+*/
+#define ODN_PDP_VID4VSINIT_VID4VINITIAL0_MASK (0x0000FFFF)
+#define ODN_PDP_VID4VSINIT_VID4VINITIAL0_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID4VSINIT_VID4VINITIAL0_SHIFT (0)
+#define ODN_PDP_VID4VSINIT_VID4VINITIAL0_LENGTH (16)
+#define ODN_PDP_VID4VSINIT_VID4VINITIAL0_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4VCOEFF0_OFFSET (0x05F8)
+
+/* PDP, VID4VCOEFF0, VID4VCOEFF0
+*/
+#define ODN_PDP_VID4VCOEFF0_VID4VCOEFF0_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4VCOEFF0_VID4VCOEFF0_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4VCOEFF0_VID4VCOEFF0_SHIFT (0)
+#define ODN_PDP_VID4VCOEFF0_VID4VCOEFF0_LENGTH (32)
+#define ODN_PDP_VID4VCOEFF0_VID4VCOEFF0_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4VCOEFF1_OFFSET (0x05FC)
+
+/* PDP, VID4VCOEFF1, VID4VCOEFF1
+*/
+#define ODN_PDP_VID4VCOEFF1_VID4VCOEFF1_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4VCOEFF1_VID4VCOEFF1_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4VCOEFF1_VID4VCOEFF1_SHIFT (0)
+#define ODN_PDP_VID4VCOEFF1_VID4VCOEFF1_LENGTH (32)
+#define ODN_PDP_VID4VCOEFF1_VID4VCOEFF1_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4VCOEFF2_OFFSET (0x0600)
+
+/* PDP, VID4VCOEFF2, VID4VCOEFF2
+*/
+#define ODN_PDP_VID4VCOEFF2_VID4VCOEFF2_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4VCOEFF2_VID4VCOEFF2_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4VCOEFF2_VID4VCOEFF2_SHIFT (0)
+#define ODN_PDP_VID4VCOEFF2_VID4VCOEFF2_LENGTH (32)
+#define ODN_PDP_VID4VCOEFF2_VID4VCOEFF2_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4VCOEFF3_OFFSET (0x0604)
+
+/* PDP, VID4VCOEFF3, VID4VCOEFF3
+*/
+#define ODN_PDP_VID4VCOEFF3_VID4VCOEFF3_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4VCOEFF3_VID4VCOEFF3_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4VCOEFF3_VID4VCOEFF3_SHIFT (0)
+#define ODN_PDP_VID4VCOEFF3_VID4VCOEFF3_LENGTH (32)
+#define ODN_PDP_VID4VCOEFF3_VID4VCOEFF3_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4VCOEFF4_OFFSET (0x0608)
+
+/* PDP, VID4VCOEFF4, VID4VCOEFF4
+*/
+#define ODN_PDP_VID4VCOEFF4_VID4VCOEFF4_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4VCOEFF4_VID4VCOEFF4_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4VCOEFF4_VID4VCOEFF4_SHIFT (0)
+#define ODN_PDP_VID4VCOEFF4_VID4VCOEFF4_LENGTH (32)
+#define ODN_PDP_VID4VCOEFF4_VID4VCOEFF4_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4VCOEFF5_OFFSET (0x060C)
+
+/* PDP, VID4VCOEFF5, VID4VCOEFF5
+*/
+#define ODN_PDP_VID4VCOEFF5_VID4VCOEFF5_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4VCOEFF5_VID4VCOEFF5_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4VCOEFF5_VID4VCOEFF5_SHIFT (0)
+#define ODN_PDP_VID4VCOEFF5_VID4VCOEFF5_LENGTH (32)
+#define ODN_PDP_VID4VCOEFF5_VID4VCOEFF5_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4VCOEFF6_OFFSET (0x0610)
+
+/* PDP, VID4VCOEFF6, VID4VCOEFF6
+*/
+#define ODN_PDP_VID4VCOEFF6_VID4VCOEFF6_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4VCOEFF6_VID4VCOEFF6_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4VCOEFF6_VID4VCOEFF6_SHIFT (0)
+#define ODN_PDP_VID4VCOEFF6_VID4VCOEFF6_LENGTH (32)
+#define ODN_PDP_VID4VCOEFF6_VID4VCOEFF6_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4VCOEFF7_OFFSET (0x0614)
+
+/* PDP, VID4VCOEFF7, VID4VCOEFF7
+*/
+#define ODN_PDP_VID4VCOEFF7_VID4VCOEFF7_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4VCOEFF7_VID4VCOEFF7_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4VCOEFF7_VID4VCOEFF7_SHIFT (0)
+#define ODN_PDP_VID4VCOEFF7_VID4VCOEFF7_LENGTH (32)
+#define ODN_PDP_VID4VCOEFF7_VID4VCOEFF7_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4VCOEFF8_OFFSET (0x0618)
+
+/* PDP, VID4VCOEFF8, VID4VCOEFF8
+*/
+#define ODN_PDP_VID4VCOEFF8_VID4VCOEFF8_MASK (0x000000FF)
+#define ODN_PDP_VID4VCOEFF8_VID4VCOEFF8_LSBMASK (0x000000FF)
+#define ODN_PDP_VID4VCOEFF8_VID4VCOEFF8_SHIFT (0)
+#define ODN_PDP_VID4VCOEFF8_VID4VCOEFF8_LENGTH (8)
+#define ODN_PDP_VID4VCOEFF8_VID4VCOEFF8_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4HSINIT_OFFSET (0x061C)
+
+/* PDP, VID4HSINIT, VID4HINITIAL
+*/
+#define ODN_PDP_VID4HSINIT_VID4HINITIAL_MASK (0xFFFF0000)
+#define ODN_PDP_VID4HSINIT_VID4HINITIAL_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID4HSINIT_VID4HINITIAL_SHIFT (16)
+#define ODN_PDP_VID4HSINIT_VID4HINITIAL_LENGTH (16)
+#define ODN_PDP_VID4HSINIT_VID4HINITIAL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4HSINIT, VID4HPITCH
+*/
+#define ODN_PDP_VID4HSINIT_VID4HPITCH_MASK (0x0000FFFF)
+#define ODN_PDP_VID4HSINIT_VID4HPITCH_LSBMASK (0x0000FFFF)
+#define ODN_PDP_VID4HSINIT_VID4HPITCH_SHIFT (0)
+#define ODN_PDP_VID4HSINIT_VID4HPITCH_LENGTH (16)
+#define ODN_PDP_VID4HSINIT_VID4HPITCH_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4HCOEFF0_OFFSET (0x0620)
+
+/* PDP, VID4HCOEFF0, VID4HCOEFF0
+*/
+#define ODN_PDP_VID4HCOEFF0_VID4HCOEFF0_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF0_VID4HCOEFF0_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF0_VID4HCOEFF0_SHIFT (0)
+#define ODN_PDP_VID4HCOEFF0_VID4HCOEFF0_LENGTH (32)
+#define ODN_PDP_VID4HCOEFF0_VID4HCOEFF0_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4HCOEFF1_OFFSET (0x0624)
+
+/* PDP, VID4HCOEFF1, VID4HCOEFF1
+*/
+#define ODN_PDP_VID4HCOEFF1_VID4HCOEFF1_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF1_VID4HCOEFF1_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF1_VID4HCOEFF1_SHIFT (0)
+#define ODN_PDP_VID4HCOEFF1_VID4HCOEFF1_LENGTH (32)
+#define ODN_PDP_VID4HCOEFF1_VID4HCOEFF1_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4HCOEFF2_OFFSET (0x0628)
+
+/* PDP, VID4HCOEFF2, VID4HCOEFF2
+*/
+#define ODN_PDP_VID4HCOEFF2_VID4HCOEFF2_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF2_VID4HCOEFF2_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF2_VID4HCOEFF2_SHIFT (0)
+#define ODN_PDP_VID4HCOEFF2_VID4HCOEFF2_LENGTH (32)
+#define ODN_PDP_VID4HCOEFF2_VID4HCOEFF2_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4HCOEFF3_OFFSET (0x062C)
+
+/* PDP, VID4HCOEFF3, VID4HCOEFF3
+*/
+#define ODN_PDP_VID4HCOEFF3_VID4HCOEFF3_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF3_VID4HCOEFF3_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF3_VID4HCOEFF3_SHIFT (0)
+#define ODN_PDP_VID4HCOEFF3_VID4HCOEFF3_LENGTH (32)
+#define ODN_PDP_VID4HCOEFF3_VID4HCOEFF3_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4HCOEFF4_OFFSET (0x0630)
+
+/* PDP, VID4HCOEFF4, VID4HCOEFF4
+*/
+#define ODN_PDP_VID4HCOEFF4_VID4HCOEFF4_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF4_VID4HCOEFF4_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF4_VID4HCOEFF4_SHIFT (0)
+#define ODN_PDP_VID4HCOEFF4_VID4HCOEFF4_LENGTH (32)
+#define ODN_PDP_VID4HCOEFF4_VID4HCOEFF4_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4HCOEFF5_OFFSET (0x0634)
+
+/* PDP, VID4HCOEFF5, VID4HCOEFF5
+*/
+#define ODN_PDP_VID4HCOEFF5_VID4HCOEFF5_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF5_VID4HCOEFF5_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF5_VID4HCOEFF5_SHIFT (0)
+#define ODN_PDP_VID4HCOEFF5_VID4HCOEFF5_LENGTH (32)
+#define ODN_PDP_VID4HCOEFF5_VID4HCOEFF5_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4HCOEFF6_OFFSET (0x0638)
+
+/* PDP, VID4HCOEFF6, VID4HCOEFF6
+*/
+#define ODN_PDP_VID4HCOEFF6_VID4HCOEFF6_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF6_VID4HCOEFF6_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF6_VID4HCOEFF6_SHIFT (0)
+#define ODN_PDP_VID4HCOEFF6_VID4HCOEFF6_LENGTH (32)
+#define ODN_PDP_VID4HCOEFF6_VID4HCOEFF6_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4HCOEFF7_OFFSET (0x063C)
+
+/* PDP, VID4HCOEFF7, VID4HCOEFF7
+*/
+#define ODN_PDP_VID4HCOEFF7_VID4HCOEFF7_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF7_VID4HCOEFF7_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF7_VID4HCOEFF7_SHIFT (0)
+#define ODN_PDP_VID4HCOEFF7_VID4HCOEFF7_LENGTH (32)
+#define ODN_PDP_VID4HCOEFF7_VID4HCOEFF7_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4HCOEFF8_OFFSET (0x0640)
+
+/* PDP, VID4HCOEFF8, VID4HCOEFF8
+*/
+#define ODN_PDP_VID4HCOEFF8_VID4HCOEFF8_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF8_VID4HCOEFF8_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF8_VID4HCOEFF8_SHIFT (0)
+#define ODN_PDP_VID4HCOEFF8_VID4HCOEFF8_LENGTH (32)
+#define ODN_PDP_VID4HCOEFF8_VID4HCOEFF8_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4HCOEFF9_OFFSET (0x0644)
+
+/* PDP, VID4HCOEFF9, VID4HCOEFF9
+*/
+#define ODN_PDP_VID4HCOEFF9_VID4HCOEFF9_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF9_VID4HCOEFF9_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF9_VID4HCOEFF9_SHIFT (0)
+#define ODN_PDP_VID4HCOEFF9_VID4HCOEFF9_LENGTH (32)
+#define ODN_PDP_VID4HCOEFF9_VID4HCOEFF9_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4HCOEFF10_OFFSET (0x0648)
+
+/* PDP, VID4HCOEFF10, VID4HCOEFF10
+*/
+#define ODN_PDP_VID4HCOEFF10_VID4HCOEFF10_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF10_VID4HCOEFF10_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF10_VID4HCOEFF10_SHIFT (0)
+#define ODN_PDP_VID4HCOEFF10_VID4HCOEFF10_LENGTH (32)
+#define ODN_PDP_VID4HCOEFF10_VID4HCOEFF10_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4HCOEFF11_OFFSET (0x064C)
+
+/* PDP, VID4HCOEFF11, VID4HCOEFF11
+*/
+#define ODN_PDP_VID4HCOEFF11_VID4HCOEFF11_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF11_VID4HCOEFF11_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF11_VID4HCOEFF11_SHIFT (0)
+#define ODN_PDP_VID4HCOEFF11_VID4HCOEFF11_LENGTH (32)
+#define ODN_PDP_VID4HCOEFF11_VID4HCOEFF11_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4HCOEFF12_OFFSET (0x0650)
+
+/* PDP, VID4HCOEFF12, VID4HCOEFF12
+*/
+#define ODN_PDP_VID4HCOEFF12_VID4HCOEFF12_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF12_VID4HCOEFF12_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF12_VID4HCOEFF12_SHIFT (0)
+#define ODN_PDP_VID4HCOEFF12_VID4HCOEFF12_LENGTH (32)
+#define ODN_PDP_VID4HCOEFF12_VID4HCOEFF12_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4HCOEFF13_OFFSET (0x0654)
+
+/* PDP, VID4HCOEFF13, VID4HCOEFF13
+*/
+#define ODN_PDP_VID4HCOEFF13_VID4HCOEFF13_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF13_VID4HCOEFF13_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF13_VID4HCOEFF13_SHIFT (0)
+#define ODN_PDP_VID4HCOEFF13_VID4HCOEFF13_LENGTH (32)
+#define ODN_PDP_VID4HCOEFF13_VID4HCOEFF13_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4HCOEFF14_OFFSET (0x0658)
+
+/* PDP, VID4HCOEFF14, VID4HCOEFF14
+*/
+#define ODN_PDP_VID4HCOEFF14_VID4HCOEFF14_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF14_VID4HCOEFF14_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF14_VID4HCOEFF14_SHIFT (0)
+#define ODN_PDP_VID4HCOEFF14_VID4HCOEFF14_LENGTH (32)
+#define ODN_PDP_VID4HCOEFF14_VID4HCOEFF14_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4HCOEFF15_OFFSET (0x065C)
+
+/* PDP, VID4HCOEFF15, VID4HCOEFF15
+*/
+#define ODN_PDP_VID4HCOEFF15_VID4HCOEFF15_MASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF15_VID4HCOEFF15_LSBMASK (0xFFFFFFFF)
+#define ODN_PDP_VID4HCOEFF15_VID4HCOEFF15_SHIFT (0)
+#define ODN_PDP_VID4HCOEFF15_VID4HCOEFF15_LENGTH (32)
+#define ODN_PDP_VID4HCOEFF15_VID4HCOEFF15_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4HCOEFF16_OFFSET (0x0660)
+
+/* PDP, VID4HCOEFF16, VID4HCOEFF16
+*/
+#define ODN_PDP_VID4HCOEFF16_VID4HCOEFF16_MASK (0x000000FF)
+#define ODN_PDP_VID4HCOEFF16_VID4HCOEFF16_LSBMASK (0x000000FF)
+#define ODN_PDP_VID4HCOEFF16_VID4HCOEFF16_SHIFT (0)
+#define ODN_PDP_VID4HCOEFF16_VID4HCOEFF16_LENGTH (8)
+#define ODN_PDP_VID4HCOEFF16_VID4HCOEFF16_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4SCALESIZE_OFFSET (0x0664)
+
+/* PDP, VID4SCALESIZE, VID4SCALEWIDTH
+*/
+#define ODN_PDP_VID4SCALESIZE_VID4SCALEWIDTH_MASK (0x0FFF0000)
+#define ODN_PDP_VID4SCALESIZE_VID4SCALEWIDTH_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID4SCALESIZE_VID4SCALEWIDTH_SHIFT (16)
+#define ODN_PDP_VID4SCALESIZE_VID4SCALEWIDTH_LENGTH (12)
+#define ODN_PDP_VID4SCALESIZE_VID4SCALEWIDTH_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4SCALESIZE, VID4SCALEHEIGHT
+*/
+#define ODN_PDP_VID4SCALESIZE_VID4SCALEHEIGHT_MASK (0x00000FFF)
+#define ODN_PDP_VID4SCALESIZE_VID4SCALEHEIGHT_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID4SCALESIZE_VID4SCALEHEIGHT_SHIFT (0)
+#define ODN_PDP_VID4SCALESIZE_VID4SCALEHEIGHT_LENGTH (12)
+#define ODN_PDP_VID4SCALESIZE_VID4SCALEHEIGHT_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_PORTER_BLND0_OFFSET (0x0668)
+
+/* PDP, PORTER_BLND0, BLND0BLENDTYPE
+*/
+#define ODN_PDP_PORTER_BLND0_BLND0BLENDTYPE_MASK (0x00000010)
+#define ODN_PDP_PORTER_BLND0_BLND0BLENDTYPE_LSBMASK (0x00000001)
+#define ODN_PDP_PORTER_BLND0_BLND0BLENDTYPE_SHIFT (4)
+#define ODN_PDP_PORTER_BLND0_BLND0BLENDTYPE_LENGTH (1)
+#define ODN_PDP_PORTER_BLND0_BLND0BLENDTYPE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PORTER_BLND0, BLND0PORTERMODE
+*/
+#define ODN_PDP_PORTER_BLND0_BLND0PORTERMODE_MASK (0x0000000F)
+#define ODN_PDP_PORTER_BLND0_BLND0PORTERMODE_LSBMASK (0x0000000F)
+#define ODN_PDP_PORTER_BLND0_BLND0PORTERMODE_SHIFT (0)
+#define ODN_PDP_PORTER_BLND0_BLND0PORTERMODE_LENGTH (4)
+#define ODN_PDP_PORTER_BLND0_BLND0PORTERMODE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_PORTER_BLND1_OFFSET (0x066C)
+
+/* PDP, PORTER_BLND1, BLND1BLENDTYPE
+*/
+#define ODN_PDP_PORTER_BLND1_BLND1BLENDTYPE_MASK (0x00000010)
+#define ODN_PDP_PORTER_BLND1_BLND1BLENDTYPE_LSBMASK (0x00000001)
+#define ODN_PDP_PORTER_BLND1_BLND1BLENDTYPE_SHIFT (4)
+#define ODN_PDP_PORTER_BLND1_BLND1BLENDTYPE_LENGTH (1)
+#define ODN_PDP_PORTER_BLND1_BLND1BLENDTYPE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PORTER_BLND1, BLND1PORTERMODE
+*/
+#define ODN_PDP_PORTER_BLND1_BLND1PORTERMODE_MASK (0x0000000F)
+#define ODN_PDP_PORTER_BLND1_BLND1PORTERMODE_LSBMASK (0x0000000F)
+#define ODN_PDP_PORTER_BLND1_BLND1PORTERMODE_SHIFT (0)
+#define ODN_PDP_PORTER_BLND1_BLND1PORTERMODE_LENGTH (4)
+#define ODN_PDP_PORTER_BLND1_BLND1PORTERMODE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_PORTER_BLND2_OFFSET (0x0670)
+
+/* PDP, PORTER_BLND2, BLND2BLENDTYPE
+*/
+#define ODN_PDP_PORTER_BLND2_BLND2BLENDTYPE_MASK (0x00000010)
+#define ODN_PDP_PORTER_BLND2_BLND2BLENDTYPE_LSBMASK (0x00000001)
+#define ODN_PDP_PORTER_BLND2_BLND2BLENDTYPE_SHIFT (4)
+#define ODN_PDP_PORTER_BLND2_BLND2BLENDTYPE_LENGTH (1)
+#define ODN_PDP_PORTER_BLND2_BLND2BLENDTYPE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PORTER_BLND2, BLND2PORTERMODE
+*/
+#define ODN_PDP_PORTER_BLND2_BLND2PORTERMODE_MASK (0x0000000F)
+#define ODN_PDP_PORTER_BLND2_BLND2PORTERMODE_LSBMASK (0x0000000F)
+#define ODN_PDP_PORTER_BLND2_BLND2PORTERMODE_SHIFT (0)
+#define ODN_PDP_PORTER_BLND2_BLND2PORTERMODE_LENGTH (4)
+#define ODN_PDP_PORTER_BLND2_BLND2PORTERMODE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_PORTER_BLND3_OFFSET (0x0674)
+
+/* PDP, PORTER_BLND3, BLND3BLENDTYPE
+*/
+#define ODN_PDP_PORTER_BLND3_BLND3BLENDTYPE_MASK (0x00000010)
+#define ODN_PDP_PORTER_BLND3_BLND3BLENDTYPE_LSBMASK (0x00000001)
+#define ODN_PDP_PORTER_BLND3_BLND3BLENDTYPE_SHIFT (4)
+#define ODN_PDP_PORTER_BLND3_BLND3BLENDTYPE_LENGTH (1)
+#define ODN_PDP_PORTER_BLND3_BLND3BLENDTYPE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PORTER_BLND3, BLND3PORTERMODE
+*/
+#define ODN_PDP_PORTER_BLND3_BLND3PORTERMODE_MASK (0x0000000F)
+#define ODN_PDP_PORTER_BLND3_BLND3PORTERMODE_LSBMASK (0x0000000F)
+#define ODN_PDP_PORTER_BLND3_BLND3PORTERMODE_SHIFT (0)
+#define ODN_PDP_PORTER_BLND3_BLND3PORTERMODE_LENGTH (4)
+#define ODN_PDP_PORTER_BLND3_BLND3PORTERMODE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_PORTER_BLND4_OFFSET (0x0678)
+
+/* PDP, PORTER_BLND4, BLND4BLENDTYPE
+*/
+#define ODN_PDP_PORTER_BLND4_BLND4BLENDTYPE_MASK (0x00000010)
+#define ODN_PDP_PORTER_BLND4_BLND4BLENDTYPE_LSBMASK (0x00000001)
+#define ODN_PDP_PORTER_BLND4_BLND4BLENDTYPE_SHIFT (4)
+#define ODN_PDP_PORTER_BLND4_BLND4BLENDTYPE_LENGTH (1)
+#define ODN_PDP_PORTER_BLND4_BLND4BLENDTYPE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PORTER_BLND4, BLND4PORTERMODE
+*/
+#define ODN_PDP_PORTER_BLND4_BLND4PORTERMODE_MASK (0x0000000F)
+#define ODN_PDP_PORTER_BLND4_BLND4PORTERMODE_LSBMASK (0x0000000F)
+#define ODN_PDP_PORTER_BLND4_BLND4PORTERMODE_SHIFT (0)
+#define ODN_PDP_PORTER_BLND4_BLND4PORTERMODE_LENGTH (4)
+#define ODN_PDP_PORTER_BLND4_BLND4PORTERMODE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_PORTER_BLND5_OFFSET (0x067C)
+
+/* PDP, PORTER_BLND5, BLND5BLENDTYPE
+*/
+#define ODN_PDP_PORTER_BLND5_BLND5BLENDTYPE_MASK (0x00000010)
+#define ODN_PDP_PORTER_BLND5_BLND5BLENDTYPE_LSBMASK (0x00000001)
+#define ODN_PDP_PORTER_BLND5_BLND5BLENDTYPE_SHIFT (4)
+#define ODN_PDP_PORTER_BLND5_BLND5BLENDTYPE_LENGTH (1)
+#define ODN_PDP_PORTER_BLND5_BLND5BLENDTYPE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PORTER_BLND5, BLND5PORTERMODE
+*/
+#define ODN_PDP_PORTER_BLND5_BLND5PORTERMODE_MASK (0x0000000F)
+#define ODN_PDP_PORTER_BLND5_BLND5PORTERMODE_LSBMASK (0x0000000F)
+#define ODN_PDP_PORTER_BLND5_BLND5PORTERMODE_SHIFT (0)
+#define ODN_PDP_PORTER_BLND5_BLND5PORTERMODE_LENGTH (4)
+#define ODN_PDP_PORTER_BLND5_BLND5PORTERMODE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_PORTER_BLND6_OFFSET (0x0680)
+
+/* PDP, PORTER_BLND6, BLND6BLENDTYPE
+*/
+#define ODN_PDP_PORTER_BLND6_BLND6BLENDTYPE_MASK (0x00000010)
+#define ODN_PDP_PORTER_BLND6_BLND6BLENDTYPE_LSBMASK (0x00000001)
+#define ODN_PDP_PORTER_BLND6_BLND6BLENDTYPE_SHIFT (4)
+#define ODN_PDP_PORTER_BLND6_BLND6BLENDTYPE_LENGTH (1)
+#define ODN_PDP_PORTER_BLND6_BLND6BLENDTYPE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PORTER_BLND6, BLND6PORTERMODE
+*/
+#define ODN_PDP_PORTER_BLND6_BLND6PORTERMODE_MASK (0x0000000F)
+#define ODN_PDP_PORTER_BLND6_BLND6PORTERMODE_LSBMASK (0x0000000F)
+#define ODN_PDP_PORTER_BLND6_BLND6PORTERMODE_SHIFT (0)
+#define ODN_PDP_PORTER_BLND6_BLND6PORTERMODE_LENGTH (4)
+#define ODN_PDP_PORTER_BLND6_BLND6PORTERMODE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_PORTER_BLND7_OFFSET (0x0684)
+
+/* PDP, PORTER_BLND7, BLND7BLENDTYPE
+*/
+#define ODN_PDP_PORTER_BLND7_BLND7BLENDTYPE_MASK (0x00000010)
+#define ODN_PDP_PORTER_BLND7_BLND7BLENDTYPE_LSBMASK (0x00000001)
+#define ODN_PDP_PORTER_BLND7_BLND7BLENDTYPE_SHIFT (4)
+#define ODN_PDP_PORTER_BLND7_BLND7BLENDTYPE_LENGTH (1)
+#define ODN_PDP_PORTER_BLND7_BLND7BLENDTYPE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PORTER_BLND7, BLND7PORTERMODE
+*/
+#define ODN_PDP_PORTER_BLND7_BLND7PORTERMODE_MASK (0x0000000F)
+#define ODN_PDP_PORTER_BLND7_BLND7PORTERMODE_LSBMASK (0x0000000F)
+#define ODN_PDP_PORTER_BLND7_BLND7PORTERMODE_SHIFT (0)
+#define ODN_PDP_PORTER_BLND7_BLND7PORTERMODE_LENGTH (4)
+#define ODN_PDP_PORTER_BLND7_BLND7PORTERMODE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1LUMAKEY_ALPHA_TRANS_OPAQUE_OFFSET (0x06C8)
+
+/* PDP, VID1LUMAKEY_ALPHA_TRANS_OPAQUE, VID1LUMAKEYALPHA_TRANS
+*/
+#define ODN_PDP_VID1LUMAKEY_ALPHA_TRANS_OPAQUE_VID1LUMAKEYALPHA_TRANS_MASK (0x03FF0000)
+#define ODN_PDP_VID1LUMAKEY_ALPHA_TRANS_OPAQUE_VID1LUMAKEYALPHA_TRANS_LSBMASK (0x000003FF)
+#define ODN_PDP_VID1LUMAKEY_ALPHA_TRANS_OPAQUE_VID1LUMAKEYALPHA_TRANS_SHIFT (16)
+#define ODN_PDP_VID1LUMAKEY_ALPHA_TRANS_OPAQUE_VID1LUMAKEYALPHA_TRANS_LENGTH (10)
+#define ODN_PDP_VID1LUMAKEY_ALPHA_TRANS_OPAQUE_VID1LUMAKEYALPHA_TRANS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1LUMAKEY_ALPHA_TRANS_OPAQUE, VID1LUMAKEYALPHA_OPAQUE
+*/
+#define ODN_PDP_VID1LUMAKEY_ALPHA_TRANS_OPAQUE_VID1LUMAKEYALPHA_OPAQUE_MASK (0x000003FF)
+#define ODN_PDP_VID1LUMAKEY_ALPHA_TRANS_OPAQUE_VID1LUMAKEYALPHA_OPAQUE_LSBMASK (0x000003FF)
+#define ODN_PDP_VID1LUMAKEY_ALPHA_TRANS_OPAQUE_VID1LUMAKEYALPHA_OPAQUE_SHIFT (0)
+#define ODN_PDP_VID1LUMAKEY_ALPHA_TRANS_OPAQUE_VID1LUMAKEYALPHA_OPAQUE_LENGTH (10)
+#define ODN_PDP_VID1LUMAKEY_ALPHA_TRANS_OPAQUE_VID1LUMAKEYALPHA_OPAQUE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1LUMAKEY_LUMA_MAX_MIN_OFFSET (0x06CC)
+
+/* PDP, VID1LUMAKEY_LUMA_MAX_MIN, VID1LUMAKEYYMAX
+*/
+#define ODN_PDP_VID1LUMAKEY_LUMA_MAX_MIN_VID1LUMAKEYYMAX_MASK (0x03FF0000)
+#define ODN_PDP_VID1LUMAKEY_LUMA_MAX_MIN_VID1LUMAKEYYMAX_LSBMASK (0x000003FF)
+#define ODN_PDP_VID1LUMAKEY_LUMA_MAX_MIN_VID1LUMAKEYYMAX_SHIFT (16)
+#define ODN_PDP_VID1LUMAKEY_LUMA_MAX_MIN_VID1LUMAKEYYMAX_LENGTH (10)
+#define ODN_PDP_VID1LUMAKEY_LUMA_MAX_MIN_VID1LUMAKEYYMAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1LUMAKEY_LUMA_MAX_MIN, VID1LUMAKEYYMIN
+*/
+#define ODN_PDP_VID1LUMAKEY_LUMA_MAX_MIN_VID1LUMAKEYYMIN_MASK (0x000003FF)
+#define ODN_PDP_VID1LUMAKEY_LUMA_MAX_MIN_VID1LUMAKEYYMIN_LSBMASK (0x000003FF)
+#define ODN_PDP_VID1LUMAKEY_LUMA_MAX_MIN_VID1LUMAKEYYMIN_SHIFT (0)
+#define ODN_PDP_VID1LUMAKEY_LUMA_MAX_MIN_VID1LUMAKEYYMIN_LENGTH (10)
+#define ODN_PDP_VID1LUMAKEY_LUMA_MAX_MIN_VID1LUMAKEYYMIN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1LUMAKEY_C_RG_OFFSET (0x06D0)
+
+/* PDP, VID1LUMAKEY_C_RG, VID1LUMAKEYC_R
+*/
+#define ODN_PDP_VID1LUMAKEY_C_RG_VID1LUMAKEYC_R_MASK (0x0FFF0000)
+#define ODN_PDP_VID1LUMAKEY_C_RG_VID1LUMAKEYC_R_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID1LUMAKEY_C_RG_VID1LUMAKEYC_R_SHIFT (16)
+#define ODN_PDP_VID1LUMAKEY_C_RG_VID1LUMAKEYC_R_LENGTH (12)
+#define ODN_PDP_VID1LUMAKEY_C_RG_VID1LUMAKEYC_R_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1LUMAKEY_C_RG, VID1LUMAKEYC_G
+*/
+#define ODN_PDP_VID1LUMAKEY_C_RG_VID1LUMAKEYC_G_MASK (0x00000FFF)
+#define ODN_PDP_VID1LUMAKEY_C_RG_VID1LUMAKEYC_G_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID1LUMAKEY_C_RG_VID1LUMAKEYC_G_SHIFT (0)
+#define ODN_PDP_VID1LUMAKEY_C_RG_VID1LUMAKEYC_G_LENGTH (12)
+#define ODN_PDP_VID1LUMAKEY_C_RG_VID1LUMAKEYC_G_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1LUMAKEY_C_B_OFFSET (0x06D4)
+
+/* PDP, VID1LUMAKEY_C_B, VID1LUMAKEYALPHAMULT
+*/
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYALPHAMULT_MASK (0x20000000)
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYALPHAMULT_LSBMASK (0x00000001)
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYALPHAMULT_SHIFT (29)
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYALPHAMULT_LENGTH (1)
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYALPHAMULT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1LUMAKEY_C_B, VID1LUMAKEYEN
+*/
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYEN_MASK (0x10000000)
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYEN_LSBMASK (0x00000001)
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYEN_SHIFT (28)
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYEN_LENGTH (1)
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYEN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1LUMAKEY_C_B, VID1LUMAKEYOUTOFF
+*/
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYOUTOFF_MASK (0x03FF0000)
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYOUTOFF_LSBMASK (0x000003FF)
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYOUTOFF_SHIFT (16)
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYOUTOFF_LENGTH (10)
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYOUTOFF_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1LUMAKEY_C_B, VID1LUMAKEYC_B
+*/
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYC_B_MASK (0x00000FFF)
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYC_B_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYC_B_SHIFT (0)
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYC_B_LENGTH (12)
+#define ODN_PDP_VID1LUMAKEY_C_B_VID1LUMAKEYC_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2LUMAKEY_ALPHA_TRANS_OPAQUE_OFFSET (0x06D8)
+
+/* PDP, VID2LUMAKEY_ALPHA_TRANS_OPAQUE, VID2LUMAKEYALPHA_TRANS
+*/
+#define ODN_PDP_VID2LUMAKEY_ALPHA_TRANS_OPAQUE_VID2LUMAKEYALPHA_TRANS_MASK (0x03FF0000)
+#define ODN_PDP_VID2LUMAKEY_ALPHA_TRANS_OPAQUE_VID2LUMAKEYALPHA_TRANS_LSBMASK (0x000003FF)
+#define ODN_PDP_VID2LUMAKEY_ALPHA_TRANS_OPAQUE_VID2LUMAKEYALPHA_TRANS_SHIFT (16)
+#define ODN_PDP_VID2LUMAKEY_ALPHA_TRANS_OPAQUE_VID2LUMAKEYALPHA_TRANS_LENGTH (10)
+#define ODN_PDP_VID2LUMAKEY_ALPHA_TRANS_OPAQUE_VID2LUMAKEYALPHA_TRANS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2LUMAKEY_ALPHA_TRANS_OPAQUE, VID2LUMAKEYALPHA_OPAQUE
+*/
+#define ODN_PDP_VID2LUMAKEY_ALPHA_TRANS_OPAQUE_VID2LUMAKEYALPHA_OPAQUE_MASK (0x000003FF)
+#define ODN_PDP_VID2LUMAKEY_ALPHA_TRANS_OPAQUE_VID2LUMAKEYALPHA_OPAQUE_LSBMASK (0x000003FF)
+#define ODN_PDP_VID2LUMAKEY_ALPHA_TRANS_OPAQUE_VID2LUMAKEYALPHA_OPAQUE_SHIFT (0)
+#define ODN_PDP_VID2LUMAKEY_ALPHA_TRANS_OPAQUE_VID2LUMAKEYALPHA_OPAQUE_LENGTH (10)
+#define ODN_PDP_VID2LUMAKEY_ALPHA_TRANS_OPAQUE_VID2LUMAKEYALPHA_OPAQUE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2LUMAKEY_LUMA_MAX_MIN_OFFSET (0x06DC)
+
+/* PDP, VID2LUMAKEY_LUMA_MAX_MIN, VID2LUMAKEYYMAX
+*/
+#define ODN_PDP_VID2LUMAKEY_LUMA_MAX_MIN_VID2LUMAKEYYMAX_MASK (0x03FF0000)
+#define ODN_PDP_VID2LUMAKEY_LUMA_MAX_MIN_VID2LUMAKEYYMAX_LSBMASK (0x000003FF)
+#define ODN_PDP_VID2LUMAKEY_LUMA_MAX_MIN_VID2LUMAKEYYMAX_SHIFT (16)
+#define ODN_PDP_VID2LUMAKEY_LUMA_MAX_MIN_VID2LUMAKEYYMAX_LENGTH (10)
+#define ODN_PDP_VID2LUMAKEY_LUMA_MAX_MIN_VID2LUMAKEYYMAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2LUMAKEY_LUMA_MAX_MIN, VID2LUMAKEYYMIN
+*/
+#define ODN_PDP_VID2LUMAKEY_LUMA_MAX_MIN_VID2LUMAKEYYMIN_MASK (0x000003FF)
+#define ODN_PDP_VID2LUMAKEY_LUMA_MAX_MIN_VID2LUMAKEYYMIN_LSBMASK (0x000003FF)
+#define ODN_PDP_VID2LUMAKEY_LUMA_MAX_MIN_VID2LUMAKEYYMIN_SHIFT (0)
+#define ODN_PDP_VID2LUMAKEY_LUMA_MAX_MIN_VID2LUMAKEYYMIN_LENGTH (10)
+#define ODN_PDP_VID2LUMAKEY_LUMA_MAX_MIN_VID2LUMAKEYYMIN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2LUMAKEY_C_RG_OFFSET (0x06E0)
+
+/* PDP, VID2LUMAKEY_C_RG, VID2LUMAKEYC_R
+*/
+#define ODN_PDP_VID2LUMAKEY_C_RG_VID2LUMAKEYC_R_MASK (0x0FFF0000)
+#define ODN_PDP_VID2LUMAKEY_C_RG_VID2LUMAKEYC_R_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID2LUMAKEY_C_RG_VID2LUMAKEYC_R_SHIFT (16)
+#define ODN_PDP_VID2LUMAKEY_C_RG_VID2LUMAKEYC_R_LENGTH (12)
+#define ODN_PDP_VID2LUMAKEY_C_RG_VID2LUMAKEYC_R_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2LUMAKEY_C_RG, VID2LUMAKEYC_G
+*/
+#define ODN_PDP_VID2LUMAKEY_C_RG_VID2LUMAKEYC_G_MASK (0x00000FFF)
+#define ODN_PDP_VID2LUMAKEY_C_RG_VID2LUMAKEYC_G_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID2LUMAKEY_C_RG_VID2LUMAKEYC_G_SHIFT (0)
+#define ODN_PDP_VID2LUMAKEY_C_RG_VID2LUMAKEYC_G_LENGTH (12)
+#define ODN_PDP_VID2LUMAKEY_C_RG_VID2LUMAKEYC_G_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2LUMAKEY_C_B_OFFSET (0x06E4)
+
+/* PDP, VID2LUMAKEY_C_B, VID2LUMAKEYALPHAMULT
+*/
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYALPHAMULT_MASK (0x20000000)
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYALPHAMULT_LSBMASK (0x00000001)
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYALPHAMULT_SHIFT (29)
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYALPHAMULT_LENGTH (1)
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYALPHAMULT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2LUMAKEY_C_B, VID2LUMAKEYEN
+*/
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYEN_MASK (0x10000000)
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYEN_LSBMASK (0x00000001)
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYEN_SHIFT (28)
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYEN_LENGTH (1)
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYEN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2LUMAKEY_C_B, VID2LUMAKEYOUTOFF
+*/
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYOUTOFF_MASK (0x03FF0000)
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYOUTOFF_LSBMASK (0x000003FF)
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYOUTOFF_SHIFT (16)
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYOUTOFF_LENGTH (10)
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYOUTOFF_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2LUMAKEY_C_B, VID2LUMAKEYC_B
+*/
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYC_B_MASK (0x00000FFF)
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYC_B_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYC_B_SHIFT (0)
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYC_B_LENGTH (12)
+#define ODN_PDP_VID2LUMAKEY_C_B_VID2LUMAKEYC_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3LUMAKEY_ALPHA_TRANS_OPAQUE_OFFSET (0x06E8)
+
+/* PDP, VID3LUMAKEY_ALPHA_TRANS_OPAQUE, VID3LUMAKEYALPHA_TRANS
+*/
+#define ODN_PDP_VID3LUMAKEY_ALPHA_TRANS_OPAQUE_VID3LUMAKEYALPHA_TRANS_MASK (0x03FF0000)
+#define ODN_PDP_VID3LUMAKEY_ALPHA_TRANS_OPAQUE_VID3LUMAKEYALPHA_TRANS_LSBMASK (0x000003FF)
+#define ODN_PDP_VID3LUMAKEY_ALPHA_TRANS_OPAQUE_VID3LUMAKEYALPHA_TRANS_SHIFT (16)
+#define ODN_PDP_VID3LUMAKEY_ALPHA_TRANS_OPAQUE_VID3LUMAKEYALPHA_TRANS_LENGTH (10)
+#define ODN_PDP_VID3LUMAKEY_ALPHA_TRANS_OPAQUE_VID3LUMAKEYALPHA_TRANS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3LUMAKEY_ALPHA_TRANS_OPAQUE, VID3LUMAKEYALPHA_OPAQUE
+*/
+#define ODN_PDP_VID3LUMAKEY_ALPHA_TRANS_OPAQUE_VID3LUMAKEYALPHA_OPAQUE_MASK (0x000003FF)
+#define ODN_PDP_VID3LUMAKEY_ALPHA_TRANS_OPAQUE_VID3LUMAKEYALPHA_OPAQUE_LSBMASK (0x000003FF)
+#define ODN_PDP_VID3LUMAKEY_ALPHA_TRANS_OPAQUE_VID3LUMAKEYALPHA_OPAQUE_SHIFT (0)
+#define ODN_PDP_VID3LUMAKEY_ALPHA_TRANS_OPAQUE_VID3LUMAKEYALPHA_OPAQUE_LENGTH (10)
+#define ODN_PDP_VID3LUMAKEY_ALPHA_TRANS_OPAQUE_VID3LUMAKEYALPHA_OPAQUE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3LUMAKEY_LUMA_MAX_MIN_OFFSET (0x06EC)
+
+/* PDP, VID3LUMAKEY_LUMA_MAX_MIN, VID3LUMAKEYYMAX
+*/
+#define ODN_PDP_VID3LUMAKEY_LUMA_MAX_MIN_VID3LUMAKEYYMAX_MASK (0x03FF0000)
+#define ODN_PDP_VID3LUMAKEY_LUMA_MAX_MIN_VID3LUMAKEYYMAX_LSBMASK (0x000003FF)
+#define ODN_PDP_VID3LUMAKEY_LUMA_MAX_MIN_VID3LUMAKEYYMAX_SHIFT (16)
+#define ODN_PDP_VID3LUMAKEY_LUMA_MAX_MIN_VID3LUMAKEYYMAX_LENGTH (10)
+#define ODN_PDP_VID3LUMAKEY_LUMA_MAX_MIN_VID3LUMAKEYYMAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3LUMAKEY_LUMA_MAX_MIN, VID3LUMAKEYYMIN
+*/
+#define ODN_PDP_VID3LUMAKEY_LUMA_MAX_MIN_VID3LUMAKEYYMIN_MASK (0x000003FF)
+#define ODN_PDP_VID3LUMAKEY_LUMA_MAX_MIN_VID3LUMAKEYYMIN_LSBMASK (0x000003FF)
+#define ODN_PDP_VID3LUMAKEY_LUMA_MAX_MIN_VID3LUMAKEYYMIN_SHIFT (0)
+#define ODN_PDP_VID3LUMAKEY_LUMA_MAX_MIN_VID3LUMAKEYYMIN_LENGTH (10)
+#define ODN_PDP_VID3LUMAKEY_LUMA_MAX_MIN_VID3LUMAKEYYMIN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3LUMAKEY_C_RG_OFFSET (0x06F0)
+
+/* PDP, VID3LUMAKEY_C_RG, VID3LUMAKEYC_R
+*/
+#define ODN_PDP_VID3LUMAKEY_C_RG_VID3LUMAKEYC_R_MASK (0x0FFF0000)
+#define ODN_PDP_VID3LUMAKEY_C_RG_VID3LUMAKEYC_R_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID3LUMAKEY_C_RG_VID3LUMAKEYC_R_SHIFT (16)
+#define ODN_PDP_VID3LUMAKEY_C_RG_VID3LUMAKEYC_R_LENGTH (12)
+#define ODN_PDP_VID3LUMAKEY_C_RG_VID3LUMAKEYC_R_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3LUMAKEY_C_RG, VID3LUMAKEYC_G
+*/
+#define ODN_PDP_VID3LUMAKEY_C_RG_VID3LUMAKEYC_G_MASK (0x00000FFF)
+#define ODN_PDP_VID3LUMAKEY_C_RG_VID3LUMAKEYC_G_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID3LUMAKEY_C_RG_VID3LUMAKEYC_G_SHIFT (0)
+#define ODN_PDP_VID3LUMAKEY_C_RG_VID3LUMAKEYC_G_LENGTH (12)
+#define ODN_PDP_VID3LUMAKEY_C_RG_VID3LUMAKEYC_G_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3LUMAKEY_C_B_OFFSET (0x06F4)
+
+/* PDP, VID3LUMAKEY_C_B, VID3LUMAKEYALPHAMULT
+*/
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYALPHAMULT_MASK (0x20000000)
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYALPHAMULT_LSBMASK (0x00000001)
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYALPHAMULT_SHIFT (29)
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYALPHAMULT_LENGTH (1)
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYALPHAMULT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3LUMAKEY_C_B, VID3LUMAKEYEN
+*/
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYEN_MASK (0x10000000)
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYEN_LSBMASK (0x00000001)
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYEN_SHIFT (28)
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYEN_LENGTH (1)
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYEN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3LUMAKEY_C_B, VID3LUMAKEYOUTOFF
+*/
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYOUTOFF_MASK (0x03FF0000)
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYOUTOFF_LSBMASK (0x000003FF)
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYOUTOFF_SHIFT (16)
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYOUTOFF_LENGTH (10)
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYOUTOFF_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3LUMAKEY_C_B, VID3LUMAKEYC_B
+*/
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYC_B_MASK (0x00000FFF)
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYC_B_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYC_B_SHIFT (0)
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYC_B_LENGTH (12)
+#define ODN_PDP_VID3LUMAKEY_C_B_VID3LUMAKEYC_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4LUMAKEY_ALPHA_TRANS_OPAQUE_OFFSET (0x06F8)
+
+/* PDP, VID4LUMAKEY_ALPHA_TRANS_OPAQUE, VID4LUMAKEYALPHA_TRANS
+*/
+#define ODN_PDP_VID4LUMAKEY_ALPHA_TRANS_OPAQUE_VID4LUMAKEYALPHA_TRANS_MASK (0x03FF0000)
+#define ODN_PDP_VID4LUMAKEY_ALPHA_TRANS_OPAQUE_VID4LUMAKEYALPHA_TRANS_LSBMASK (0x000003FF)
+#define ODN_PDP_VID4LUMAKEY_ALPHA_TRANS_OPAQUE_VID4LUMAKEYALPHA_TRANS_SHIFT (16)
+#define ODN_PDP_VID4LUMAKEY_ALPHA_TRANS_OPAQUE_VID4LUMAKEYALPHA_TRANS_LENGTH (10)
+#define ODN_PDP_VID4LUMAKEY_ALPHA_TRANS_OPAQUE_VID4LUMAKEYALPHA_TRANS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4LUMAKEY_ALPHA_TRANS_OPAQUE, VID4LUMAKEYALPHA_OPAQUE
+*/
+#define ODN_PDP_VID4LUMAKEY_ALPHA_TRANS_OPAQUE_VID4LUMAKEYALPHA_OPAQUE_MASK (0x000003FF)
+#define ODN_PDP_VID4LUMAKEY_ALPHA_TRANS_OPAQUE_VID4LUMAKEYALPHA_OPAQUE_LSBMASK (0x000003FF)
+#define ODN_PDP_VID4LUMAKEY_ALPHA_TRANS_OPAQUE_VID4LUMAKEYALPHA_OPAQUE_SHIFT (0)
+#define ODN_PDP_VID4LUMAKEY_ALPHA_TRANS_OPAQUE_VID4LUMAKEYALPHA_OPAQUE_LENGTH (10)
+#define ODN_PDP_VID4LUMAKEY_ALPHA_TRANS_OPAQUE_VID4LUMAKEYALPHA_OPAQUE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4LUMAKEY_LUMA_MAX_MIN_OFFSET (0x06FC)
+
+/* PDP, VID4LUMAKEY_LUMA_MAX_MIN, VID4LUMAKEYYMAX
+*/
+#define ODN_PDP_VID4LUMAKEY_LUMA_MAX_MIN_VID4LUMAKEYYMAX_MASK (0x03FF0000)
+#define ODN_PDP_VID4LUMAKEY_LUMA_MAX_MIN_VID4LUMAKEYYMAX_LSBMASK (0x000003FF)
+#define ODN_PDP_VID4LUMAKEY_LUMA_MAX_MIN_VID4LUMAKEYYMAX_SHIFT (16)
+#define ODN_PDP_VID4LUMAKEY_LUMA_MAX_MIN_VID4LUMAKEYYMAX_LENGTH (10)
+#define ODN_PDP_VID4LUMAKEY_LUMA_MAX_MIN_VID4LUMAKEYYMAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4LUMAKEY_LUMA_MAX_MIN, VID4LUMAKEYYMIN
+*/
+#define ODN_PDP_VID4LUMAKEY_LUMA_MAX_MIN_VID4LUMAKEYYMIN_MASK (0x000003FF)
+#define ODN_PDP_VID4LUMAKEY_LUMA_MAX_MIN_VID4LUMAKEYYMIN_LSBMASK (0x000003FF)
+#define ODN_PDP_VID4LUMAKEY_LUMA_MAX_MIN_VID4LUMAKEYYMIN_SHIFT (0)
+#define ODN_PDP_VID4LUMAKEY_LUMA_MAX_MIN_VID4LUMAKEYYMIN_LENGTH (10)
+#define ODN_PDP_VID4LUMAKEY_LUMA_MAX_MIN_VID4LUMAKEYYMIN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4LUMAKEY_C_RG_OFFSET (0x0700)
+
+/* PDP, VID4LUMAKEY_C_RG, VID4LUMAKEYC_R
+*/
+#define ODN_PDP_VID4LUMAKEY_C_RG_VID4LUMAKEYC_R_MASK (0x0FFF0000)
+#define ODN_PDP_VID4LUMAKEY_C_RG_VID4LUMAKEYC_R_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID4LUMAKEY_C_RG_VID4LUMAKEYC_R_SHIFT (16)
+#define ODN_PDP_VID4LUMAKEY_C_RG_VID4LUMAKEYC_R_LENGTH (12)
+#define ODN_PDP_VID4LUMAKEY_C_RG_VID4LUMAKEYC_R_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4LUMAKEY_C_RG, VID4LUMAKEYC_G
+*/
+#define ODN_PDP_VID4LUMAKEY_C_RG_VID4LUMAKEYC_G_MASK (0x00000FFF)
+#define ODN_PDP_VID4LUMAKEY_C_RG_VID4LUMAKEYC_G_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID4LUMAKEY_C_RG_VID4LUMAKEYC_G_SHIFT (0)
+#define ODN_PDP_VID4LUMAKEY_C_RG_VID4LUMAKEYC_G_LENGTH (12)
+#define ODN_PDP_VID4LUMAKEY_C_RG_VID4LUMAKEYC_G_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4LUMAKEY_C_B_OFFSET (0x0704)
+
+/* PDP, VID4LUMAKEY_C_B, VID4LUMAKEYALPHAMULT
+*/
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYALPHAMULT_MASK (0x20000000)
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYALPHAMULT_LSBMASK (0x00000001)
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYALPHAMULT_SHIFT (29)
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYALPHAMULT_LENGTH (1)
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYALPHAMULT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4LUMAKEY_C_B, VID4LUMAKEYEN
+*/
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYEN_MASK (0x10000000)
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYEN_LSBMASK (0x00000001)
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYEN_SHIFT (28)
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYEN_LENGTH (1)
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYEN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4LUMAKEY_C_B, VID4LUMAKEYOUTOFF
+*/
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYOUTOFF_MASK (0x03FF0000)
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYOUTOFF_LSBMASK (0x000003FF)
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYOUTOFF_SHIFT (16)
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYOUTOFF_LENGTH (10)
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYOUTOFF_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4LUMAKEY_C_B, VID4LUMAKEYC_B
+*/
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYC_B_MASK (0x00000FFF)
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYC_B_LSBMASK (0x00000FFF)
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYC_B_SHIFT (0)
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYC_B_LENGTH (12)
+#define ODN_PDP_VID4LUMAKEY_C_B_VID4LUMAKEYC_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_CSCCOEFF0_OFFSET (0x0708)
+
+/* PDP, CSCCOEFF0, CSCCOEFFRU
+*/
+#define ODN_PDP_CSCCOEFF0_CSCCOEFFRU_MASK (0x003FF800)
+#define ODN_PDP_CSCCOEFF0_CSCCOEFFRU_LSBMASK (0x000007FF)
+#define ODN_PDP_CSCCOEFF0_CSCCOEFFRU_SHIFT (11)
+#define ODN_PDP_CSCCOEFF0_CSCCOEFFRU_LENGTH (11)
+#define ODN_PDP_CSCCOEFF0_CSCCOEFFRU_SIGNED_FIELD IMG_FALSE
+
+/* PDP, CSCCOEFF0, CSCCOEFFRY
+*/
+#define ODN_PDP_CSCCOEFF0_CSCCOEFFRY_MASK (0x000007FF)
+#define ODN_PDP_CSCCOEFF0_CSCCOEFFRY_LSBMASK (0x000007FF)
+#define ODN_PDP_CSCCOEFF0_CSCCOEFFRY_SHIFT (0)
+#define ODN_PDP_CSCCOEFF0_CSCCOEFFRY_LENGTH (11)
+#define ODN_PDP_CSCCOEFF0_CSCCOEFFRY_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_CSCCOEFF1_OFFSET (0x070C)
+
+/* PDP, CSCCOEFF1, CSCCOEFFGY
+*/
+#define ODN_PDP_CSCCOEFF1_CSCCOEFFGY_MASK (0x003FF800)
+#define ODN_PDP_CSCCOEFF1_CSCCOEFFGY_LSBMASK (0x000007FF)
+#define ODN_PDP_CSCCOEFF1_CSCCOEFFGY_SHIFT (11)
+#define ODN_PDP_CSCCOEFF1_CSCCOEFFGY_LENGTH (11)
+#define ODN_PDP_CSCCOEFF1_CSCCOEFFGY_SIGNED_FIELD IMG_FALSE
+
+/* PDP, CSCCOEFF1, CSCCOEFFRV
+*/
+#define ODN_PDP_CSCCOEFF1_CSCCOEFFRV_MASK (0x000007FF)
+#define ODN_PDP_CSCCOEFF1_CSCCOEFFRV_LSBMASK (0x000007FF)
+#define ODN_PDP_CSCCOEFF1_CSCCOEFFRV_SHIFT (0)
+#define ODN_PDP_CSCCOEFF1_CSCCOEFFRV_LENGTH (11)
+#define ODN_PDP_CSCCOEFF1_CSCCOEFFRV_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_CSCCOEFF2_OFFSET (0x0710)
+
+/* PDP, CSCCOEFF2, CSCCOEFFGV
+*/
+#define ODN_PDP_CSCCOEFF2_CSCCOEFFGV_MASK (0x003FF800)
+#define ODN_PDP_CSCCOEFF2_CSCCOEFFGV_LSBMASK (0x000007FF)
+#define ODN_PDP_CSCCOEFF2_CSCCOEFFGV_SHIFT (11)
+#define ODN_PDP_CSCCOEFF2_CSCCOEFFGV_LENGTH (11)
+#define ODN_PDP_CSCCOEFF2_CSCCOEFFGV_SIGNED_FIELD IMG_FALSE
+
+/* PDP, CSCCOEFF2, CSCCOEFFGU
+*/
+#define ODN_PDP_CSCCOEFF2_CSCCOEFFGU_MASK (0x000007FF)
+#define ODN_PDP_CSCCOEFF2_CSCCOEFFGU_LSBMASK (0x000007FF)
+#define ODN_PDP_CSCCOEFF2_CSCCOEFFGU_SHIFT (0)
+#define ODN_PDP_CSCCOEFF2_CSCCOEFFGU_LENGTH (11)
+#define ODN_PDP_CSCCOEFF2_CSCCOEFFGU_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_CSCCOEFF3_OFFSET (0x0714)
+
+/* PDP, CSCCOEFF3, CSCCOEFFBU
+*/
+#define ODN_PDP_CSCCOEFF3_CSCCOEFFBU_MASK (0x003FF800)
+#define ODN_PDP_CSCCOEFF3_CSCCOEFFBU_LSBMASK (0x000007FF)
+#define ODN_PDP_CSCCOEFF3_CSCCOEFFBU_SHIFT (11)
+#define ODN_PDP_CSCCOEFF3_CSCCOEFFBU_LENGTH (11)
+#define ODN_PDP_CSCCOEFF3_CSCCOEFFBU_SIGNED_FIELD IMG_FALSE
+
+/* PDP, CSCCOEFF3, CSCCOEFFBY
+*/
+#define ODN_PDP_CSCCOEFF3_CSCCOEFFBY_MASK (0x000007FF)
+#define ODN_PDP_CSCCOEFF3_CSCCOEFFBY_LSBMASK (0x000007FF)
+#define ODN_PDP_CSCCOEFF3_CSCCOEFFBY_SHIFT (0)
+#define ODN_PDP_CSCCOEFF3_CSCCOEFFBY_LENGTH (11)
+#define ODN_PDP_CSCCOEFF3_CSCCOEFFBY_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_CSCCOEFF4_OFFSET (0x0718)
+
+/* PDP, CSCCOEFF4, CSCCOEFFBV
+*/
+#define ODN_PDP_CSCCOEFF4_CSCCOEFFBV_MASK (0x000007FF)
+#define ODN_PDP_CSCCOEFF4_CSCCOEFFBV_LSBMASK (0x000007FF)
+#define ODN_PDP_CSCCOEFF4_CSCCOEFFBV_SHIFT (0)
+#define ODN_PDP_CSCCOEFF4_CSCCOEFFBV_LENGTH (11)
+#define ODN_PDP_CSCCOEFF4_CSCCOEFFBV_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_BGNDCOL_AR_OFFSET (0x071C)
+
+/* PDP, BGNDCOL_AR, BGNDCOL_A
+*/
+#define ODN_PDP_BGNDCOL_AR_BGNDCOL_A_MASK (0x03FF0000)
+#define ODN_PDP_BGNDCOL_AR_BGNDCOL_A_LSBMASK (0x000003FF)
+#define ODN_PDP_BGNDCOL_AR_BGNDCOL_A_SHIFT (16)
+#define ODN_PDP_BGNDCOL_AR_BGNDCOL_A_LENGTH (10)
+#define ODN_PDP_BGNDCOL_AR_BGNDCOL_A_SIGNED_FIELD IMG_FALSE
+
+/* PDP, BGNDCOL_AR, BGNDCOL_R
+*/
+#define ODN_PDP_BGNDCOL_AR_BGNDCOL_R_MASK (0x000003FF)
+#define ODN_PDP_BGNDCOL_AR_BGNDCOL_R_LSBMASK (0x000003FF)
+#define ODN_PDP_BGNDCOL_AR_BGNDCOL_R_SHIFT (0)
+#define ODN_PDP_BGNDCOL_AR_BGNDCOL_R_LENGTH (10)
+#define ODN_PDP_BGNDCOL_AR_BGNDCOL_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_BGNDCOL_GB_OFFSET (0x0720)
+
+/* PDP, BGNDCOL_GB, BGNDCOL_G
+*/
+#define ODN_PDP_BGNDCOL_GB_BGNDCOL_G_MASK (0x03FF0000)
+#define ODN_PDP_BGNDCOL_GB_BGNDCOL_G_LSBMASK (0x000003FF)
+#define ODN_PDP_BGNDCOL_GB_BGNDCOL_G_SHIFT (16)
+#define ODN_PDP_BGNDCOL_GB_BGNDCOL_G_LENGTH (10)
+#define ODN_PDP_BGNDCOL_GB_BGNDCOL_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, BGNDCOL_GB, BGNDCOL_B
+*/
+#define ODN_PDP_BGNDCOL_GB_BGNDCOL_B_MASK (0x000003FF)
+#define ODN_PDP_BGNDCOL_GB_BGNDCOL_B_LSBMASK (0x000003FF)
+#define ODN_PDP_BGNDCOL_GB_BGNDCOL_B_SHIFT (0)
+#define ODN_PDP_BGNDCOL_GB_BGNDCOL_B_LENGTH (10)
+#define ODN_PDP_BGNDCOL_GB_BGNDCOL_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_BORDCOL_R_OFFSET (0x0724)
+
+/* PDP, BORDCOL_R, BORDCOL_R
+*/
+#define ODN_PDP_BORDCOL_R_BORDCOL_R_MASK (0x000003FF)
+#define ODN_PDP_BORDCOL_R_BORDCOL_R_LSBMASK (0x000003FF)
+#define ODN_PDP_BORDCOL_R_BORDCOL_R_SHIFT (0)
+#define ODN_PDP_BORDCOL_R_BORDCOL_R_LENGTH (10)
+#define ODN_PDP_BORDCOL_R_BORDCOL_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_BORDCOL_GB_OFFSET (0x0728)
+
+/* PDP, BORDCOL_GB, BORDCOL_G
+*/
+#define ODN_PDP_BORDCOL_GB_BORDCOL_G_MASK (0x03FF0000)
+#define ODN_PDP_BORDCOL_GB_BORDCOL_G_LSBMASK (0x000003FF)
+#define ODN_PDP_BORDCOL_GB_BORDCOL_G_SHIFT (16)
+#define ODN_PDP_BORDCOL_GB_BORDCOL_G_LENGTH (10)
+#define ODN_PDP_BORDCOL_GB_BORDCOL_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, BORDCOL_GB, BORDCOL_B
+*/
+#define ODN_PDP_BORDCOL_GB_BORDCOL_B_MASK (0x000003FF)
+#define ODN_PDP_BORDCOL_GB_BORDCOL_B_LSBMASK (0x000003FF)
+#define ODN_PDP_BORDCOL_GB_BORDCOL_B_SHIFT (0)
+#define ODN_PDP_BORDCOL_GB_BORDCOL_B_LENGTH (10)
+#define ODN_PDP_BORDCOL_GB_BORDCOL_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_LINESTAT_OFFSET (0x0734)
+
+/* PDP, LINESTAT, LINENO
+*/
+#define ODN_PDP_LINESTAT_LINENO_MASK (0x00001FFF)
+#define ODN_PDP_LINESTAT_LINENO_LSBMASK (0x00001FFF)
+#define ODN_PDP_LINESTAT_LINENO_SHIFT (0)
+#define ODN_PDP_LINESTAT_LINENO_LENGTH (13)
+#define ODN_PDP_LINESTAT_LINENO_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C11C12_OFFSET (0x0738)
+
+/* PDP, CR_ODN_PDP_PROCAMP_C11C12, CR_PROCAMP_C12
+*/
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C11C12_CR_PROCAMP_C12_MASK (0x3FFF0000)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C11C12_CR_PROCAMP_C12_LSBMASK (0x00003FFF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C11C12_CR_PROCAMP_C12_SHIFT (16)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C11C12_CR_PROCAMP_C12_LENGTH (14)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C11C12_CR_PROCAMP_C12_SIGNED_FIELD IMG_FALSE
+
+/* PDP, CR_ODN_PDP_PROCAMP_C11C12, CR_PROCAMP_C11
+*/
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C11C12_CR_PROCAMP_C11_MASK (0x00003FFF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C11C12_CR_PROCAMP_C11_LSBMASK (0x00003FFF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C11C12_CR_PROCAMP_C11_SHIFT (0)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C11C12_CR_PROCAMP_C11_LENGTH (14)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C11C12_CR_PROCAMP_C11_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C13C21_OFFSET (0x073C)
+
+/* PDP, CR_ODN_PDP_PROCAMP_C13C21, CR_PROCAMP_C21
+*/
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C13C21_CR_PROCAMP_C21_MASK (0x3FFF0000)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C13C21_CR_PROCAMP_C21_LSBMASK (0x00003FFF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C13C21_CR_PROCAMP_C21_SHIFT (16)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C13C21_CR_PROCAMP_C21_LENGTH (14)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C13C21_CR_PROCAMP_C21_SIGNED_FIELD IMG_FALSE
+
+/* PDP, CR_ODN_PDP_PROCAMP_C13C21, CR_PROCAMP_C13
+*/
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C13C21_CR_PROCAMP_C13_MASK (0x00003FFF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C13C21_CR_PROCAMP_C13_LSBMASK (0x00003FFF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C13C21_CR_PROCAMP_C13_SHIFT (0)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C13C21_CR_PROCAMP_C13_LENGTH (14)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C13C21_CR_PROCAMP_C13_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C22C23_OFFSET (0x0740)
+
+/* PDP, CR_ODN_PDP_PROCAMP_C22C23, CR_PROCAMP_C23
+*/
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C22C23_CR_PROCAMP_C23_MASK (0x3FFF0000)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C22C23_CR_PROCAMP_C23_LSBMASK (0x00003FFF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C22C23_CR_PROCAMP_C23_SHIFT (16)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C22C23_CR_PROCAMP_C23_LENGTH (14)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C22C23_CR_PROCAMP_C23_SIGNED_FIELD IMG_FALSE
+
+/* PDP, CR_ODN_PDP_PROCAMP_C22C23, CR_PROCAMP_C22
+*/
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C22C23_CR_PROCAMP_C22_MASK (0x00003FFF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C22C23_CR_PROCAMP_C22_LSBMASK (0x00003FFF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C22C23_CR_PROCAMP_C22_SHIFT (0)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C22C23_CR_PROCAMP_C22_LENGTH (14)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C22C23_CR_PROCAMP_C22_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C31C32_OFFSET (0x0744)
+
+/* PDP, CR_ODN_PDP_PROCAMP_C31C32, CR_PROCAMP_C32
+*/
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C31C32_CR_PROCAMP_C32_MASK (0x3FFF0000)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C31C32_CR_PROCAMP_C32_LSBMASK (0x00003FFF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C31C32_CR_PROCAMP_C32_SHIFT (16)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C31C32_CR_PROCAMP_C32_LENGTH (14)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C31C32_CR_PROCAMP_C32_SIGNED_FIELD IMG_FALSE
+
+/* PDP, CR_ODN_PDP_PROCAMP_C31C32, CR_PROCAMP_C31
+*/
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C31C32_CR_PROCAMP_C31_MASK (0x00003FFF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C31C32_CR_PROCAMP_C31_LSBMASK (0x00003FFF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C31C32_CR_PROCAMP_C31_SHIFT (0)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C31C32_CR_PROCAMP_C31_LENGTH (14)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C31C32_CR_PROCAMP_C31_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C33_OFFSET (0x0748)
+
+/* PDP, CR_ODN_PDP_PROCAMP_C33, CR_PROCAMP_C33
+*/
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C33_CR_PROCAMP_C33_MASK (0x3FFF0000)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C33_CR_PROCAMP_C33_LSBMASK (0x00003FFF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C33_CR_PROCAMP_C33_SHIFT (16)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C33_CR_PROCAMP_C33_LENGTH (14)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C33_CR_PROCAMP_C33_SIGNED_FIELD IMG_FALSE
+
+/* PDP, CR_ODN_PDP_PROCAMP_C33, CR_PROCAMP_RANGE
+*/
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C33_CR_PROCAMP_RANGE_MASK (0x00000030)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C33_CR_PROCAMP_RANGE_LSBMASK (0x00000003)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C33_CR_PROCAMP_RANGE_SHIFT (4)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C33_CR_PROCAMP_RANGE_LENGTH (2)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C33_CR_PROCAMP_RANGE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, CR_ODN_PDP_PROCAMP_C33, CR_PROCAMP_EN
+*/
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C33_CR_PROCAMP_EN_MASK (0x00000001)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C33_CR_PROCAMP_EN_LSBMASK (0x00000001)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C33_CR_PROCAMP_EN_SHIFT (0)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C33_CR_PROCAMP_EN_LENGTH (1)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_C33_CR_PROCAMP_EN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_OUTOFFSET_BG_OFFSET (0x074C)
+
+/* PDP, CR_ODN_PDP_PROCAMP_OUTOFFSET_BG, CR_PROCAMP_OUTOFF_G
+*/
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_OUTOFFSET_BG_CR_PROCAMP_OUTOFF_G_MASK (0x0FFF0000)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_OUTOFFSET_BG_CR_PROCAMP_OUTOFF_G_LSBMASK (0x00000FFF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_OUTOFFSET_BG_CR_PROCAMP_OUTOFF_G_SHIFT (16)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_OUTOFFSET_BG_CR_PROCAMP_OUTOFF_G_LENGTH (12)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_OUTOFFSET_BG_CR_PROCAMP_OUTOFF_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, CR_ODN_PDP_PROCAMP_OUTOFFSET_BG, CR_PROCAMP_OUTOFF_B
+*/
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_OUTOFFSET_BG_CR_PROCAMP_OUTOFF_B_MASK (0x00000FFF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_OUTOFFSET_BG_CR_PROCAMP_OUTOFF_B_LSBMASK (0x00000FFF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_OUTOFFSET_BG_CR_PROCAMP_OUTOFF_B_SHIFT (0)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_OUTOFFSET_BG_CR_PROCAMP_OUTOFF_B_LENGTH (12)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_OUTOFFSET_BG_CR_PROCAMP_OUTOFF_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_OUTOFFSET_R_OFFSET (0x0750)
+
+/* PDP, CR_ODN_PDP_PROCAMP_OUTOFFSET_R, CR_PROCAMP_OUTOFF_R
+*/
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_OUTOFFSET_R_CR_PROCAMP_OUTOFF_R_MASK (0x00000FFF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_OUTOFFSET_R_CR_PROCAMP_OUTOFF_R_LSBMASK (0x00000FFF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_OUTOFFSET_R_CR_PROCAMP_OUTOFF_R_SHIFT (0)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_OUTOFFSET_R_CR_PROCAMP_OUTOFF_R_LENGTH (12)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_OUTOFFSET_R_CR_PROCAMP_OUTOFF_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_INOFFSET_BG_OFFSET (0x0754)
+
+/* PDP, CR_ODN_PDP_PROCAMP_INOFFSET_BG, CR_PROCAMP_INOFF_G
+*/
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_INOFFSET_BG_CR_PROCAMP_INOFF_G_MASK (0x03FF0000)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_INOFFSET_BG_CR_PROCAMP_INOFF_G_LSBMASK (0x000003FF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_INOFFSET_BG_CR_PROCAMP_INOFF_G_SHIFT (16)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_INOFFSET_BG_CR_PROCAMP_INOFF_G_LENGTH (10)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_INOFFSET_BG_CR_PROCAMP_INOFF_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, CR_ODN_PDP_PROCAMP_INOFFSET_BG, CR_PROCAMP_INOFF_B
+*/
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_INOFFSET_BG_CR_PROCAMP_INOFF_B_MASK (0x000003FF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_INOFFSET_BG_CR_PROCAMP_INOFF_B_LSBMASK (0x000003FF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_INOFFSET_BG_CR_PROCAMP_INOFF_B_SHIFT (0)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_INOFFSET_BG_CR_PROCAMP_INOFF_B_LENGTH (10)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_INOFFSET_BG_CR_PROCAMP_INOFF_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_INOFFSET_R_OFFSET (0x0758)
+
+/* PDP, CR_ODN_PDP_PROCAMP_INOFFSET_R, CR_PROCAMP_INOFF_R
+*/
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_INOFFSET_R_CR_PROCAMP_INOFF_R_MASK (0x000003FF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_INOFFSET_R_CR_PROCAMP_INOFF_R_LSBMASK (0x000003FF)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_INOFFSET_R_CR_PROCAMP_INOFF_R_SHIFT (0)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_INOFFSET_R_CR_PROCAMP_INOFF_R_LENGTH (10)
+#define ODN_PDP_CR_ODN_PDP_PROCAMP_INOFFSET_R_CR_PROCAMP_INOFF_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_SIGNAT_R_OFFSET (0x075C)
+
+/* PDP, SIGNAT_R, SIGNATURE_R
+*/
+#define ODN_PDP_SIGNAT_R_SIGNATURE_R_MASK (0x000003FF)
+#define ODN_PDP_SIGNAT_R_SIGNATURE_R_LSBMASK (0x000003FF)
+#define ODN_PDP_SIGNAT_R_SIGNATURE_R_SHIFT (0)
+#define ODN_PDP_SIGNAT_R_SIGNATURE_R_LENGTH (10)
+#define ODN_PDP_SIGNAT_R_SIGNATURE_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_SIGNAT_GB_OFFSET (0x0760)
+
+/* PDP, SIGNAT_GB, SIGNATURE_G
+*/
+#define ODN_PDP_SIGNAT_GB_SIGNATURE_G_MASK (0x03FF0000)
+#define ODN_PDP_SIGNAT_GB_SIGNATURE_G_LSBMASK (0x000003FF)
+#define ODN_PDP_SIGNAT_GB_SIGNATURE_G_SHIFT (16)
+#define ODN_PDP_SIGNAT_GB_SIGNATURE_G_LENGTH (10)
+#define ODN_PDP_SIGNAT_GB_SIGNATURE_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, SIGNAT_GB, SIGNATURE_B
+*/
+#define ODN_PDP_SIGNAT_GB_SIGNATURE_B_MASK (0x000003FF)
+#define ODN_PDP_SIGNAT_GB_SIGNATURE_B_LSBMASK (0x000003FF)
+#define ODN_PDP_SIGNAT_GB_SIGNATURE_B_SHIFT (0)
+#define ODN_PDP_SIGNAT_GB_SIGNATURE_B_LENGTH (10)
+#define ODN_PDP_SIGNAT_GB_SIGNATURE_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_REGISTER_UPDATE_CTRL_OFFSET (0x0764)
+
+/* PDP, REGISTER_UPDATE_CTRL, BYPASS_DOUBLE_BUFFERING
+*/
+#define ODN_PDP_REGISTER_UPDATE_CTRL_BYPASS_DOUBLE_BUFFERING_MASK (0x00000004)
+#define ODN_PDP_REGISTER_UPDATE_CTRL_BYPASS_DOUBLE_BUFFERING_LSBMASK (0x00000001)
+#define ODN_PDP_REGISTER_UPDATE_CTRL_BYPASS_DOUBLE_BUFFERING_SHIFT (2)
+#define ODN_PDP_REGISTER_UPDATE_CTRL_BYPASS_DOUBLE_BUFFERING_LENGTH (1)
+#define ODN_PDP_REGISTER_UPDATE_CTRL_BYPASS_DOUBLE_BUFFERING_SIGNED_FIELD IMG_FALSE
+
+/* PDP, REGISTER_UPDATE_CTRL, REGISTERS_VALID
+*/
+#define ODN_PDP_REGISTER_UPDATE_CTRL_REGISTERS_VALID_MASK (0x00000002)
+#define ODN_PDP_REGISTER_UPDATE_CTRL_REGISTERS_VALID_LSBMASK (0x00000001)
+#define ODN_PDP_REGISTER_UPDATE_CTRL_REGISTERS_VALID_SHIFT (1)
+#define ODN_PDP_REGISTER_UPDATE_CTRL_REGISTERS_VALID_LENGTH (1)
+#define ODN_PDP_REGISTER_UPDATE_CTRL_REGISTERS_VALID_SIGNED_FIELD IMG_FALSE
+
+/* PDP, REGISTER_UPDATE_CTRL, USE_VBLANK
+*/
+#define ODN_PDP_REGISTER_UPDATE_CTRL_USE_VBLANK_MASK (0x00000001)
+#define ODN_PDP_REGISTER_UPDATE_CTRL_USE_VBLANK_LSBMASK (0x00000001)
+#define ODN_PDP_REGISTER_UPDATE_CTRL_USE_VBLANK_SHIFT (0)
+#define ODN_PDP_REGISTER_UPDATE_CTRL_USE_VBLANK_LENGTH (1)
+#define ODN_PDP_REGISTER_UPDATE_CTRL_USE_VBLANK_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_REGISTER_UPDATE_STATUS_OFFSET (0x0768)
+
+/* PDP, REGISTER_UPDATE_STATUS, REGISTERS_UPDATED
+*/
+#define ODN_PDP_REGISTER_UPDATE_STATUS_REGISTERS_UPDATED_MASK (0x00000002)
+#define ODN_PDP_REGISTER_UPDATE_STATUS_REGISTERS_UPDATED_LSBMASK (0x00000001)
+#define ODN_PDP_REGISTER_UPDATE_STATUS_REGISTERS_UPDATED_SHIFT (1)
+#define ODN_PDP_REGISTER_UPDATE_STATUS_REGISTERS_UPDATED_LENGTH (1)
+#define ODN_PDP_REGISTER_UPDATE_STATUS_REGISTERS_UPDATED_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DBGCTRL_OFFSET (0x076C)
+
+/* PDP, DBGCTRL, DBG_READ
+*/
+#define ODN_PDP_DBGCTRL_DBG_READ_MASK (0x00000002)
+#define ODN_PDP_DBGCTRL_DBG_READ_LSBMASK (0x00000001)
+#define ODN_PDP_DBGCTRL_DBG_READ_SHIFT (1)
+#define ODN_PDP_DBGCTRL_DBG_READ_LENGTH (1)
+#define ODN_PDP_DBGCTRL_DBG_READ_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DBGCTRL, DBG_ENAB
+*/
+#define ODN_PDP_DBGCTRL_DBG_ENAB_MASK (0x00000001)
+#define ODN_PDP_DBGCTRL_DBG_ENAB_LSBMASK (0x00000001)
+#define ODN_PDP_DBGCTRL_DBG_ENAB_SHIFT (0)
+#define ODN_PDP_DBGCTRL_DBG_ENAB_LENGTH (1)
+#define ODN_PDP_DBGCTRL_DBG_ENAB_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DBGDATA_R_OFFSET (0x0770)
+
+/* PDP, DBGDATA_R, DBG_DATA_R
+*/
+#define ODN_PDP_DBGDATA_R_DBG_DATA_R_MASK (0x000003FF)
+#define ODN_PDP_DBGDATA_R_DBG_DATA_R_LSBMASK (0x000003FF)
+#define ODN_PDP_DBGDATA_R_DBG_DATA_R_SHIFT (0)
+#define ODN_PDP_DBGDATA_R_DBG_DATA_R_LENGTH (10)
+#define ODN_PDP_DBGDATA_R_DBG_DATA_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DBGDATA_GB_OFFSET (0x0774)
+
+/* PDP, DBGDATA_GB, DBG_DATA_G
+*/
+#define ODN_PDP_DBGDATA_GB_DBG_DATA_G_MASK (0x03FF0000)
+#define ODN_PDP_DBGDATA_GB_DBG_DATA_G_LSBMASK (0x000003FF)
+#define ODN_PDP_DBGDATA_GB_DBG_DATA_G_SHIFT (16)
+#define ODN_PDP_DBGDATA_GB_DBG_DATA_G_LENGTH (10)
+#define ODN_PDP_DBGDATA_GB_DBG_DATA_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DBGDATA_GB, DBG_DATA_B
+*/
+#define ODN_PDP_DBGDATA_GB_DBG_DATA_B_MASK (0x000003FF)
+#define ODN_PDP_DBGDATA_GB_DBG_DATA_B_LSBMASK (0x000003FF)
+#define ODN_PDP_DBGDATA_GB_DBG_DATA_B_SHIFT (0)
+#define ODN_PDP_DBGDATA_GB_DBG_DATA_B_LENGTH (10)
+#define ODN_PDP_DBGDATA_GB_DBG_DATA_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DBGSIDE_OFFSET (0x0778)
+
+/* PDP, DBGSIDE, DBG_VAL
+*/
+#define ODN_PDP_DBGSIDE_DBG_VAL_MASK (0x00000008)
+#define ODN_PDP_DBGSIDE_DBG_VAL_LSBMASK (0x00000001)
+#define ODN_PDP_DBGSIDE_DBG_VAL_SHIFT (3)
+#define ODN_PDP_DBGSIDE_DBG_VAL_LENGTH (1)
+#define ODN_PDP_DBGSIDE_DBG_VAL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DBGSIDE, DBG_SIDE
+*/
+#define ODN_PDP_DBGSIDE_DBG_SIDE_MASK (0x00000007)
+#define ODN_PDP_DBGSIDE_DBG_SIDE_LSBMASK (0x00000007)
+#define ODN_PDP_DBGSIDE_DBG_SIDE_SHIFT (0)
+#define ODN_PDP_DBGSIDE_DBG_SIDE_LENGTH (3)
+#define ODN_PDP_DBGSIDE_DBG_SIDE_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_OUTPUT_OFFSET (0x077C)
+
+/* PDP, OUTPUT, EIGHT_BIT_OUTPUT
+*/
+#define ODN_PDP_OUTPUT_EIGHT_BIT_OUTPUT_MASK (0x00000002)
+#define ODN_PDP_OUTPUT_EIGHT_BIT_OUTPUT_LSBMASK (0x00000001)
+#define ODN_PDP_OUTPUT_EIGHT_BIT_OUTPUT_SHIFT (1)
+#define ODN_PDP_OUTPUT_EIGHT_BIT_OUTPUT_LENGTH (1)
+#define ODN_PDP_OUTPUT_EIGHT_BIT_OUTPUT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, OUTPUT, OUTPUT_CONFIG
+*/
+#define ODN_PDP_OUTPUT_OUTPUT_CONFIG_MASK (0x00000001)
+#define ODN_PDP_OUTPUT_OUTPUT_CONFIG_LSBMASK (0x00000001)
+#define ODN_PDP_OUTPUT_OUTPUT_CONFIG_SHIFT (0)
+#define ODN_PDP_OUTPUT_OUTPUT_CONFIG_LENGTH (1)
+#define ODN_PDP_OUTPUT_OUTPUT_CONFIG_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_SYNCCTRL_OFFSET (0x0780)
+
+/* PDP, SYNCCTRL, SYNCACTIVE
+*/
+#define ODN_PDP_SYNCCTRL_SYNCACTIVE_MASK (0x80000000)
+#define ODN_PDP_SYNCCTRL_SYNCACTIVE_LSBMASK (0x00000001)
+#define ODN_PDP_SYNCCTRL_SYNCACTIVE_SHIFT (31)
+#define ODN_PDP_SYNCCTRL_SYNCACTIVE_LENGTH (1)
+#define ODN_PDP_SYNCCTRL_SYNCACTIVE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, SYNCCTRL, ODN_PDP_RST
+*/
+#define ODN_PDP_SYNCCTRL_ODN_PDP_RST_MASK (0x20000000)
+#define ODN_PDP_SYNCCTRL_ODN_PDP_RST_LSBMASK (0x00000001)
+#define ODN_PDP_SYNCCTRL_ODN_PDP_RST_SHIFT (29)
+#define ODN_PDP_SYNCCTRL_ODN_PDP_RST_LENGTH (1)
+#define ODN_PDP_SYNCCTRL_ODN_PDP_RST_SIGNED_FIELD IMG_FALSE
+
+/* PDP, SYNCCTRL, POWERDN
+*/
+#define ODN_PDP_SYNCCTRL_POWERDN_MASK (0x10000000)
+#define ODN_PDP_SYNCCTRL_POWERDN_LSBMASK (0x00000001)
+#define ODN_PDP_SYNCCTRL_POWERDN_SHIFT (28)
+#define ODN_PDP_SYNCCTRL_POWERDN_LENGTH (1)
+#define ODN_PDP_SYNCCTRL_POWERDN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, SYNCCTRL, LOWPWRMODE
+*/
+#define ODN_PDP_SYNCCTRL_LOWPWRMODE_MASK (0x08000000)
+#define ODN_PDP_SYNCCTRL_LOWPWRMODE_LSBMASK (0x00000001)
+#define ODN_PDP_SYNCCTRL_LOWPWRMODE_SHIFT (27)
+#define ODN_PDP_SYNCCTRL_LOWPWRMODE_LENGTH (1)
+#define ODN_PDP_SYNCCTRL_LOWPWRMODE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, SYNCCTRL, UPDSYNCTRL
+*/
+#define ODN_PDP_SYNCCTRL_UPDSYNCTRL_MASK (0x04000000)
+#define ODN_PDP_SYNCCTRL_UPDSYNCTRL_LSBMASK (0x00000001)
+#define ODN_PDP_SYNCCTRL_UPDSYNCTRL_SHIFT (26)
+#define ODN_PDP_SYNCCTRL_UPDSYNCTRL_LENGTH (1)
+#define ODN_PDP_SYNCCTRL_UPDSYNCTRL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, SYNCCTRL, UPDINTCTRL
+*/
+#define ODN_PDP_SYNCCTRL_UPDINTCTRL_MASK (0x02000000)
+#define ODN_PDP_SYNCCTRL_UPDINTCTRL_LSBMASK (0x00000001)
+#define ODN_PDP_SYNCCTRL_UPDINTCTRL_SHIFT (25)
+#define ODN_PDP_SYNCCTRL_UPDINTCTRL_LENGTH (1)
+#define ODN_PDP_SYNCCTRL_UPDINTCTRL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, SYNCCTRL, UPDCTRL
+*/
+#define ODN_PDP_SYNCCTRL_UPDCTRL_MASK (0x01000000)
+#define ODN_PDP_SYNCCTRL_UPDCTRL_LSBMASK (0x00000001)
+#define ODN_PDP_SYNCCTRL_UPDCTRL_SHIFT (24)
+#define ODN_PDP_SYNCCTRL_UPDCTRL_LENGTH (1)
+#define ODN_PDP_SYNCCTRL_UPDCTRL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, SYNCCTRL, UPDWAIT
+*/
+#define ODN_PDP_SYNCCTRL_UPDWAIT_MASK (0x000F0000)
+#define ODN_PDP_SYNCCTRL_UPDWAIT_LSBMASK (0x0000000F)
+#define ODN_PDP_SYNCCTRL_UPDWAIT_SHIFT (16)
+#define ODN_PDP_SYNCCTRL_UPDWAIT_LENGTH (4)
+#define ODN_PDP_SYNCCTRL_UPDWAIT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, SYNCCTRL, FIELD_EN
+*/
+#define ODN_PDP_SYNCCTRL_FIELD_EN_MASK (0x00002000)
+#define ODN_PDP_SYNCCTRL_FIELD_EN_LSBMASK (0x00000001)
+#define ODN_PDP_SYNCCTRL_FIELD_EN_SHIFT (13)
+#define ODN_PDP_SYNCCTRL_FIELD_EN_LENGTH (1)
+#define ODN_PDP_SYNCCTRL_FIELD_EN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, SYNCCTRL, CSYNC_EN
+*/
+#define ODN_PDP_SYNCCTRL_CSYNC_EN_MASK (0x00001000)
+#define ODN_PDP_SYNCCTRL_CSYNC_EN_LSBMASK (0x00000001)
+#define ODN_PDP_SYNCCTRL_CSYNC_EN_SHIFT (12)
+#define ODN_PDP_SYNCCTRL_CSYNC_EN_LENGTH (1)
+#define ODN_PDP_SYNCCTRL_CSYNC_EN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, SYNCCTRL, CLKPOL
+*/
+#define ODN_PDP_SYNCCTRL_CLKPOL_MASK (0x00000800)
+#define ODN_PDP_SYNCCTRL_CLKPOL_LSBMASK (0x00000001)
+#define ODN_PDP_SYNCCTRL_CLKPOL_SHIFT (11)
+#define ODN_PDP_SYNCCTRL_CLKPOL_LENGTH (1)
+#define ODN_PDP_SYNCCTRL_CLKPOL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, SYNCCTRL, VS_SLAVE
+*/
+#define ODN_PDP_SYNCCTRL_VS_SLAVE_MASK (0x00000080)
+#define ODN_PDP_SYNCCTRL_VS_SLAVE_LSBMASK (0x00000001)
+#define ODN_PDP_SYNCCTRL_VS_SLAVE_SHIFT (7)
+#define ODN_PDP_SYNCCTRL_VS_SLAVE_LENGTH (1)
+#define ODN_PDP_SYNCCTRL_VS_SLAVE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, SYNCCTRL, HS_SLAVE
+*/
+#define ODN_PDP_SYNCCTRL_HS_SLAVE_MASK (0x00000040)
+#define ODN_PDP_SYNCCTRL_HS_SLAVE_LSBMASK (0x00000001)
+#define ODN_PDP_SYNCCTRL_HS_SLAVE_SHIFT (6)
+#define ODN_PDP_SYNCCTRL_HS_SLAVE_LENGTH (1)
+#define ODN_PDP_SYNCCTRL_HS_SLAVE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, SYNCCTRL, BLNKPOL
+*/
+#define ODN_PDP_SYNCCTRL_BLNKPOL_MASK (0x00000020)
+#define ODN_PDP_SYNCCTRL_BLNKPOL_LSBMASK (0x00000001)
+#define ODN_PDP_SYNCCTRL_BLNKPOL_SHIFT (5)
+#define ODN_PDP_SYNCCTRL_BLNKPOL_LENGTH (1)
+#define ODN_PDP_SYNCCTRL_BLNKPOL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, SYNCCTRL, BLNKDIS
+*/
+#define ODN_PDP_SYNCCTRL_BLNKDIS_MASK (0x00000010)
+#define ODN_PDP_SYNCCTRL_BLNKDIS_LSBMASK (0x00000001)
+#define ODN_PDP_SYNCCTRL_BLNKDIS_SHIFT (4)
+#define ODN_PDP_SYNCCTRL_BLNKDIS_LENGTH (1)
+#define ODN_PDP_SYNCCTRL_BLNKDIS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, SYNCCTRL, VSPOL
+*/
+#define ODN_PDP_SYNCCTRL_VSPOL_MASK (0x00000008)
+#define ODN_PDP_SYNCCTRL_VSPOL_LSBMASK (0x00000001)
+#define ODN_PDP_SYNCCTRL_VSPOL_SHIFT (3)
+#define ODN_PDP_SYNCCTRL_VSPOL_LENGTH (1)
+#define ODN_PDP_SYNCCTRL_VSPOL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, SYNCCTRL, VSDIS
+*/
+#define ODN_PDP_SYNCCTRL_VSDIS_MASK (0x00000004)
+#define ODN_PDP_SYNCCTRL_VSDIS_LSBMASK (0x00000001)
+#define ODN_PDP_SYNCCTRL_VSDIS_SHIFT (2)
+#define ODN_PDP_SYNCCTRL_VSDIS_LENGTH (1)
+#define ODN_PDP_SYNCCTRL_VSDIS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, SYNCCTRL, HSPOL
+*/
+#define ODN_PDP_SYNCCTRL_HSPOL_MASK (0x00000002)
+#define ODN_PDP_SYNCCTRL_HSPOL_LSBMASK (0x00000001)
+#define ODN_PDP_SYNCCTRL_HSPOL_SHIFT (1)
+#define ODN_PDP_SYNCCTRL_HSPOL_LENGTH (1)
+#define ODN_PDP_SYNCCTRL_HSPOL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, SYNCCTRL, HSDIS
+*/
+#define ODN_PDP_SYNCCTRL_HSDIS_MASK (0x00000001)
+#define ODN_PDP_SYNCCTRL_HSDIS_LSBMASK (0x00000001)
+#define ODN_PDP_SYNCCTRL_HSDIS_SHIFT (0)
+#define ODN_PDP_SYNCCTRL_HSDIS_LENGTH (1)
+#define ODN_PDP_SYNCCTRL_HSDIS_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_HSYNC1_OFFSET (0x0784)
+
+/* PDP, HSYNC1, HBPS
+*/
+#define ODN_PDP_HSYNC1_HBPS_MASK (0x1FFF0000)
+#define ODN_PDP_HSYNC1_HBPS_LSBMASK (0x00001FFF)
+#define ODN_PDP_HSYNC1_HBPS_SHIFT (16)
+#define ODN_PDP_HSYNC1_HBPS_LENGTH (13)
+#define ODN_PDP_HSYNC1_HBPS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, HSYNC1, HT
+*/
+#define ODN_PDP_HSYNC1_HT_MASK (0x00001FFF)
+#define ODN_PDP_HSYNC1_HT_LSBMASK (0x00001FFF)
+#define ODN_PDP_HSYNC1_HT_SHIFT (0)
+#define ODN_PDP_HSYNC1_HT_LENGTH (13)
+#define ODN_PDP_HSYNC1_HT_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_HSYNC2_OFFSET (0x0788)
+
+/* PDP, HSYNC2, HAS
+*/
+#define ODN_PDP_HSYNC2_HAS_MASK (0x1FFF0000)
+#define ODN_PDP_HSYNC2_HAS_LSBMASK (0x00001FFF)
+#define ODN_PDP_HSYNC2_HAS_SHIFT (16)
+#define ODN_PDP_HSYNC2_HAS_LENGTH (13)
+#define ODN_PDP_HSYNC2_HAS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, HSYNC2, HLBS
+*/
+#define ODN_PDP_HSYNC2_HLBS_MASK (0x00001FFF)
+#define ODN_PDP_HSYNC2_HLBS_LSBMASK (0x00001FFF)
+#define ODN_PDP_HSYNC2_HLBS_SHIFT (0)
+#define ODN_PDP_HSYNC2_HLBS_LENGTH (13)
+#define ODN_PDP_HSYNC2_HLBS_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_HSYNC3_OFFSET (0x078C)
+
+/* PDP, HSYNC3, HFPS
+*/
+#define ODN_PDP_HSYNC3_HFPS_MASK (0x1FFF0000)
+#define ODN_PDP_HSYNC3_HFPS_LSBMASK (0x00001FFF)
+#define ODN_PDP_HSYNC3_HFPS_SHIFT (16)
+#define ODN_PDP_HSYNC3_HFPS_LENGTH (13)
+#define ODN_PDP_HSYNC3_HFPS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, HSYNC3, HRBS
+*/
+#define ODN_PDP_HSYNC3_HRBS_MASK (0x00001FFF)
+#define ODN_PDP_HSYNC3_HRBS_LSBMASK (0x00001FFF)
+#define ODN_PDP_HSYNC3_HRBS_SHIFT (0)
+#define ODN_PDP_HSYNC3_HRBS_LENGTH (13)
+#define ODN_PDP_HSYNC3_HRBS_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VSYNC1_OFFSET (0x0790)
+
+/* PDP, VSYNC1, VBPS
+*/
+#define ODN_PDP_VSYNC1_VBPS_MASK (0x1FFF0000)
+#define ODN_PDP_VSYNC1_VBPS_LSBMASK (0x00001FFF)
+#define ODN_PDP_VSYNC1_VBPS_SHIFT (16)
+#define ODN_PDP_VSYNC1_VBPS_LENGTH (13)
+#define ODN_PDP_VSYNC1_VBPS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VSYNC1, VT
+*/
+#define ODN_PDP_VSYNC1_VT_MASK (0x00001FFF)
+#define ODN_PDP_VSYNC1_VT_LSBMASK (0x00001FFF)
+#define ODN_PDP_VSYNC1_VT_SHIFT (0)
+#define ODN_PDP_VSYNC1_VT_LENGTH (13)
+#define ODN_PDP_VSYNC1_VT_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VSYNC2_OFFSET (0x0794)
+
+/* PDP, VSYNC2, VAS
+*/
+#define ODN_PDP_VSYNC2_VAS_MASK (0x1FFF0000)
+#define ODN_PDP_VSYNC2_VAS_LSBMASK (0x00001FFF)
+#define ODN_PDP_VSYNC2_VAS_SHIFT (16)
+#define ODN_PDP_VSYNC2_VAS_LENGTH (13)
+#define ODN_PDP_VSYNC2_VAS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VSYNC2, VTBS
+*/
+#define ODN_PDP_VSYNC2_VTBS_MASK (0x00001FFF)
+#define ODN_PDP_VSYNC2_VTBS_LSBMASK (0x00001FFF)
+#define ODN_PDP_VSYNC2_VTBS_SHIFT (0)
+#define ODN_PDP_VSYNC2_VTBS_LENGTH (13)
+#define ODN_PDP_VSYNC2_VTBS_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VSYNC3_OFFSET (0x0798)
+
+/* PDP, VSYNC3, VFPS
+*/
+#define ODN_PDP_VSYNC3_VFPS_MASK (0x1FFF0000)
+#define ODN_PDP_VSYNC3_VFPS_LSBMASK (0x00001FFF)
+#define ODN_PDP_VSYNC3_VFPS_SHIFT (16)
+#define ODN_PDP_VSYNC3_VFPS_LENGTH (13)
+#define ODN_PDP_VSYNC3_VFPS_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VSYNC3, VBBS
+*/
+#define ODN_PDP_VSYNC3_VBBS_MASK (0x00001FFF)
+#define ODN_PDP_VSYNC3_VBBS_LSBMASK (0x00001FFF)
+#define ODN_PDP_VSYNC3_VBBS_SHIFT (0)
+#define ODN_PDP_VSYNC3_VBBS_LENGTH (13)
+#define ODN_PDP_VSYNC3_VBBS_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_INTSTAT_OFFSET (0x079C)
+
+/* PDP, INTSTAT, INTS_VID4ORUN
+*/
+#define ODN_PDP_INTSTAT_INTS_VID4ORUN_MASK (0x00080000)
+#define ODN_PDP_INTSTAT_INTS_VID4ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_VID4ORUN_SHIFT (19)
+#define ODN_PDP_INTSTAT_INTS_VID4ORUN_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_VID4ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTSTAT, INTS_VID3ORUN
+*/
+#define ODN_PDP_INTSTAT_INTS_VID3ORUN_MASK (0x00040000)
+#define ODN_PDP_INTSTAT_INTS_VID3ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_VID3ORUN_SHIFT (18)
+#define ODN_PDP_INTSTAT_INTS_VID3ORUN_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_VID3ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTSTAT, INTS_VID2ORUN
+*/
+#define ODN_PDP_INTSTAT_INTS_VID2ORUN_MASK (0x00020000)
+#define ODN_PDP_INTSTAT_INTS_VID2ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_VID2ORUN_SHIFT (17)
+#define ODN_PDP_INTSTAT_INTS_VID2ORUN_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_VID2ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTSTAT, INTS_VID1ORUN
+*/
+#define ODN_PDP_INTSTAT_INTS_VID1ORUN_MASK (0x00010000)
+#define ODN_PDP_INTSTAT_INTS_VID1ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_VID1ORUN_SHIFT (16)
+#define ODN_PDP_INTSTAT_INTS_VID1ORUN_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_VID1ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTSTAT, INTS_GRPH4ORUN
+*/
+#define ODN_PDP_INTSTAT_INTS_GRPH4ORUN_MASK (0x00008000)
+#define ODN_PDP_INTSTAT_INTS_GRPH4ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_GRPH4ORUN_SHIFT (15)
+#define ODN_PDP_INTSTAT_INTS_GRPH4ORUN_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_GRPH4ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTSTAT, INTS_GRPH3ORUN
+*/
+#define ODN_PDP_INTSTAT_INTS_GRPH3ORUN_MASK (0x00004000)
+#define ODN_PDP_INTSTAT_INTS_GRPH3ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_GRPH3ORUN_SHIFT (14)
+#define ODN_PDP_INTSTAT_INTS_GRPH3ORUN_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_GRPH3ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTSTAT, INTS_GRPH2ORUN
+*/
+#define ODN_PDP_INTSTAT_INTS_GRPH2ORUN_MASK (0x00002000)
+#define ODN_PDP_INTSTAT_INTS_GRPH2ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_GRPH2ORUN_SHIFT (13)
+#define ODN_PDP_INTSTAT_INTS_GRPH2ORUN_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_GRPH2ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTSTAT, INTS_GRPH1ORUN
+*/
+#define ODN_PDP_INTSTAT_INTS_GRPH1ORUN_MASK (0x00001000)
+#define ODN_PDP_INTSTAT_INTS_GRPH1ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_GRPH1ORUN_SHIFT (12)
+#define ODN_PDP_INTSTAT_INTS_GRPH1ORUN_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_GRPH1ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTSTAT, INTS_VID4URUN
+*/
+#define ODN_PDP_INTSTAT_INTS_VID4URUN_MASK (0x00000800)
+#define ODN_PDP_INTSTAT_INTS_VID4URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_VID4URUN_SHIFT (11)
+#define ODN_PDP_INTSTAT_INTS_VID4URUN_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_VID4URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTSTAT, INTS_VID3URUN
+*/
+#define ODN_PDP_INTSTAT_INTS_VID3URUN_MASK (0x00000400)
+#define ODN_PDP_INTSTAT_INTS_VID3URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_VID3URUN_SHIFT (10)
+#define ODN_PDP_INTSTAT_INTS_VID3URUN_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_VID3URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTSTAT, INTS_VID2URUN
+*/
+#define ODN_PDP_INTSTAT_INTS_VID2URUN_MASK (0x00000200)
+#define ODN_PDP_INTSTAT_INTS_VID2URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_VID2URUN_SHIFT (9)
+#define ODN_PDP_INTSTAT_INTS_VID2URUN_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_VID2URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTSTAT, INTS_VID1URUN
+*/
+#define ODN_PDP_INTSTAT_INTS_VID1URUN_MASK (0x00000100)
+#define ODN_PDP_INTSTAT_INTS_VID1URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_VID1URUN_SHIFT (8)
+#define ODN_PDP_INTSTAT_INTS_VID1URUN_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_VID1URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTSTAT, INTS_GRPH4URUN
+*/
+#define ODN_PDP_INTSTAT_INTS_GRPH4URUN_MASK (0x00000080)
+#define ODN_PDP_INTSTAT_INTS_GRPH4URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_GRPH4URUN_SHIFT (7)
+#define ODN_PDP_INTSTAT_INTS_GRPH4URUN_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_GRPH4URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTSTAT, INTS_GRPH3URUN
+*/
+#define ODN_PDP_INTSTAT_INTS_GRPH3URUN_MASK (0x00000040)
+#define ODN_PDP_INTSTAT_INTS_GRPH3URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_GRPH3URUN_SHIFT (6)
+#define ODN_PDP_INTSTAT_INTS_GRPH3URUN_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_GRPH3URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTSTAT, INTS_GRPH2URUN
+*/
+#define ODN_PDP_INTSTAT_INTS_GRPH2URUN_MASK (0x00000020)
+#define ODN_PDP_INTSTAT_INTS_GRPH2URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_GRPH2URUN_SHIFT (5)
+#define ODN_PDP_INTSTAT_INTS_GRPH2URUN_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_GRPH2URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTSTAT, INTS_GRPH1URUN
+*/
+#define ODN_PDP_INTSTAT_INTS_GRPH1URUN_MASK (0x00000010)
+#define ODN_PDP_INTSTAT_INTS_GRPH1URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_GRPH1URUN_SHIFT (4)
+#define ODN_PDP_INTSTAT_INTS_GRPH1URUN_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_GRPH1URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTSTAT, INTS_VBLNK1
+*/
+#define ODN_PDP_INTSTAT_INTS_VBLNK1_MASK (0x00000008)
+#define ODN_PDP_INTSTAT_INTS_VBLNK1_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_VBLNK1_SHIFT (3)
+#define ODN_PDP_INTSTAT_INTS_VBLNK1_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_VBLNK1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTSTAT, INTS_VBLNK0
+*/
+#define ODN_PDP_INTSTAT_INTS_VBLNK0_MASK (0x00000004)
+#define ODN_PDP_INTSTAT_INTS_VBLNK0_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_VBLNK0_SHIFT (2)
+#define ODN_PDP_INTSTAT_INTS_VBLNK0_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_VBLNK0_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTSTAT, INTS_HBLNK1
+*/
+#define ODN_PDP_INTSTAT_INTS_HBLNK1_MASK (0x00000002)
+#define ODN_PDP_INTSTAT_INTS_HBLNK1_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_HBLNK1_SHIFT (1)
+#define ODN_PDP_INTSTAT_INTS_HBLNK1_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_HBLNK1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTSTAT, INTS_HBLNK0
+*/
+#define ODN_PDP_INTSTAT_INTS_HBLNK0_MASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_HBLNK0_LSBMASK (0x00000001)
+#define ODN_PDP_INTSTAT_INTS_HBLNK0_SHIFT (0)
+#define ODN_PDP_INTSTAT_INTS_HBLNK0_LENGTH (1)
+#define ODN_PDP_INTSTAT_INTS_HBLNK0_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_INTENAB_OFFSET (0x07A0)
+
+/* PDP, INTENAB, INTEN_VID4ORUN
+*/
+#define ODN_PDP_INTENAB_INTEN_VID4ORUN_MASK (0x00080000)
+#define ODN_PDP_INTENAB_INTEN_VID4ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_VID4ORUN_SHIFT (19)
+#define ODN_PDP_INTENAB_INTEN_VID4ORUN_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_VID4ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTENAB, INTEN_VID3ORUN
+*/
+#define ODN_PDP_INTENAB_INTEN_VID3ORUN_MASK (0x00040000)
+#define ODN_PDP_INTENAB_INTEN_VID3ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_VID3ORUN_SHIFT (18)
+#define ODN_PDP_INTENAB_INTEN_VID3ORUN_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_VID3ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTENAB, INTEN_VID2ORUN
+*/
+#define ODN_PDP_INTENAB_INTEN_VID2ORUN_MASK (0x00020000)
+#define ODN_PDP_INTENAB_INTEN_VID2ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_VID2ORUN_SHIFT (17)
+#define ODN_PDP_INTENAB_INTEN_VID2ORUN_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_VID2ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTENAB, INTEN_VID1ORUN
+*/
+#define ODN_PDP_INTENAB_INTEN_VID1ORUN_MASK (0x00010000)
+#define ODN_PDP_INTENAB_INTEN_VID1ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_VID1ORUN_SHIFT (16)
+#define ODN_PDP_INTENAB_INTEN_VID1ORUN_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_VID1ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTENAB, INTEN_GRPH4ORUN
+*/
+#define ODN_PDP_INTENAB_INTEN_GRPH4ORUN_MASK (0x00008000)
+#define ODN_PDP_INTENAB_INTEN_GRPH4ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_GRPH4ORUN_SHIFT (15)
+#define ODN_PDP_INTENAB_INTEN_GRPH4ORUN_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_GRPH4ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTENAB, INTEN_GRPH3ORUN
+*/
+#define ODN_PDP_INTENAB_INTEN_GRPH3ORUN_MASK (0x00004000)
+#define ODN_PDP_INTENAB_INTEN_GRPH3ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_GRPH3ORUN_SHIFT (14)
+#define ODN_PDP_INTENAB_INTEN_GRPH3ORUN_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_GRPH3ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTENAB, INTEN_GRPH2ORUN
+*/
+#define ODN_PDP_INTENAB_INTEN_GRPH2ORUN_MASK (0x00002000)
+#define ODN_PDP_INTENAB_INTEN_GRPH2ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_GRPH2ORUN_SHIFT (13)
+#define ODN_PDP_INTENAB_INTEN_GRPH2ORUN_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_GRPH2ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTENAB, INTEN_GRPH1ORUN
+*/
+#define ODN_PDP_INTENAB_INTEN_GRPH1ORUN_MASK (0x00001000)
+#define ODN_PDP_INTENAB_INTEN_GRPH1ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_GRPH1ORUN_SHIFT (12)
+#define ODN_PDP_INTENAB_INTEN_GRPH1ORUN_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_GRPH1ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTENAB, INTEN_VID4URUN
+*/
+#define ODN_PDP_INTENAB_INTEN_VID4URUN_MASK (0x00000800)
+#define ODN_PDP_INTENAB_INTEN_VID4URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_VID4URUN_SHIFT (11)
+#define ODN_PDP_INTENAB_INTEN_VID4URUN_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_VID4URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTENAB, INTEN_VID3URUN
+*/
+#define ODN_PDP_INTENAB_INTEN_VID3URUN_MASK (0x00000400)
+#define ODN_PDP_INTENAB_INTEN_VID3URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_VID3URUN_SHIFT (10)
+#define ODN_PDP_INTENAB_INTEN_VID3URUN_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_VID3URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTENAB, INTEN_VID2URUN
+*/
+#define ODN_PDP_INTENAB_INTEN_VID2URUN_MASK (0x00000200)
+#define ODN_PDP_INTENAB_INTEN_VID2URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_VID2URUN_SHIFT (9)
+#define ODN_PDP_INTENAB_INTEN_VID2URUN_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_VID2URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTENAB, INTEN_VID1URUN
+*/
+#define ODN_PDP_INTENAB_INTEN_VID1URUN_MASK (0x00000100)
+#define ODN_PDP_INTENAB_INTEN_VID1URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_VID1URUN_SHIFT (8)
+#define ODN_PDP_INTENAB_INTEN_VID1URUN_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_VID1URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTENAB, INTEN_GRPH4URUN
+*/
+#define ODN_PDP_INTENAB_INTEN_GRPH4URUN_MASK (0x00000080)
+#define ODN_PDP_INTENAB_INTEN_GRPH4URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_GRPH4URUN_SHIFT (7)
+#define ODN_PDP_INTENAB_INTEN_GRPH4URUN_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_GRPH4URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTENAB, INTEN_GRPH3URUN
+*/
+#define ODN_PDP_INTENAB_INTEN_GRPH3URUN_MASK (0x00000040)
+#define ODN_PDP_INTENAB_INTEN_GRPH3URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_GRPH3URUN_SHIFT (6)
+#define ODN_PDP_INTENAB_INTEN_GRPH3URUN_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_GRPH3URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTENAB, INTEN_GRPH2URUN
+*/
+#define ODN_PDP_INTENAB_INTEN_GRPH2URUN_MASK (0x00000020)
+#define ODN_PDP_INTENAB_INTEN_GRPH2URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_GRPH2URUN_SHIFT (5)
+#define ODN_PDP_INTENAB_INTEN_GRPH2URUN_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_GRPH2URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTENAB, INTEN_GRPH1URUN
+*/
+#define ODN_PDP_INTENAB_INTEN_GRPH1URUN_MASK (0x00000010)
+#define ODN_PDP_INTENAB_INTEN_GRPH1URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_GRPH1URUN_SHIFT (4)
+#define ODN_PDP_INTENAB_INTEN_GRPH1URUN_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_GRPH1URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTENAB, INTEN_VBLNK1
+*/
+#define ODN_PDP_INTENAB_INTEN_VBLNK1_MASK (0x00000008)
+#define ODN_PDP_INTENAB_INTEN_VBLNK1_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_VBLNK1_SHIFT (3)
+#define ODN_PDP_INTENAB_INTEN_VBLNK1_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_VBLNK1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTENAB, INTEN_VBLNK0
+*/
+#define ODN_PDP_INTENAB_INTEN_VBLNK0_MASK (0x00000004)
+#define ODN_PDP_INTENAB_INTEN_VBLNK0_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_VBLNK0_SHIFT (2)
+#define ODN_PDP_INTENAB_INTEN_VBLNK0_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_VBLNK0_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTENAB, INTEN_HBLNK1
+*/
+#define ODN_PDP_INTENAB_INTEN_HBLNK1_MASK (0x00000002)
+#define ODN_PDP_INTENAB_INTEN_HBLNK1_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_HBLNK1_SHIFT (1)
+#define ODN_PDP_INTENAB_INTEN_HBLNK1_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_HBLNK1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTENAB, INTEN_HBLNK0
+*/
+#define ODN_PDP_INTENAB_INTEN_HBLNK0_MASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_HBLNK0_LSBMASK (0x00000001)
+#define ODN_PDP_INTENAB_INTEN_HBLNK0_SHIFT (0)
+#define ODN_PDP_INTENAB_INTEN_HBLNK0_LENGTH (1)
+#define ODN_PDP_INTENAB_INTEN_HBLNK0_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_INTCLR_OFFSET (0x07A4)
+
+/* PDP, INTCLR, INTCLR_VID4ORUN
+*/
+#define ODN_PDP_INTCLR_INTCLR_VID4ORUN_MASK (0x00080000)
+#define ODN_PDP_INTCLR_INTCLR_VID4ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_VID4ORUN_SHIFT (19)
+#define ODN_PDP_INTCLR_INTCLR_VID4ORUN_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_VID4ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTCLR, INTCLR_VID3ORUN
+*/
+#define ODN_PDP_INTCLR_INTCLR_VID3ORUN_MASK (0x00040000)
+#define ODN_PDP_INTCLR_INTCLR_VID3ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_VID3ORUN_SHIFT (18)
+#define ODN_PDP_INTCLR_INTCLR_VID3ORUN_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_VID3ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTCLR, INTCLR_VID2ORUN
+*/
+#define ODN_PDP_INTCLR_INTCLR_VID2ORUN_MASK (0x00020000)
+#define ODN_PDP_INTCLR_INTCLR_VID2ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_VID2ORUN_SHIFT (17)
+#define ODN_PDP_INTCLR_INTCLR_VID2ORUN_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_VID2ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTCLR, INTCLR_VID1ORUN
+*/
+#define ODN_PDP_INTCLR_INTCLR_VID1ORUN_MASK (0x00010000)
+#define ODN_PDP_INTCLR_INTCLR_VID1ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_VID1ORUN_SHIFT (16)
+#define ODN_PDP_INTCLR_INTCLR_VID1ORUN_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_VID1ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTCLR, INTCLR_GRPH4ORUN
+*/
+#define ODN_PDP_INTCLR_INTCLR_GRPH4ORUN_MASK (0x00008000)
+#define ODN_PDP_INTCLR_INTCLR_GRPH4ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_GRPH4ORUN_SHIFT (15)
+#define ODN_PDP_INTCLR_INTCLR_GRPH4ORUN_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_GRPH4ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTCLR, INTCLR_GRPH3ORUN
+*/
+#define ODN_PDP_INTCLR_INTCLR_GRPH3ORUN_MASK (0x00004000)
+#define ODN_PDP_INTCLR_INTCLR_GRPH3ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_GRPH3ORUN_SHIFT (14)
+#define ODN_PDP_INTCLR_INTCLR_GRPH3ORUN_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_GRPH3ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTCLR, INTCLR_GRPH2ORUN
+*/
+#define ODN_PDP_INTCLR_INTCLR_GRPH2ORUN_MASK (0x00002000)
+#define ODN_PDP_INTCLR_INTCLR_GRPH2ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_GRPH2ORUN_SHIFT (13)
+#define ODN_PDP_INTCLR_INTCLR_GRPH2ORUN_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_GRPH2ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTCLR, INTCLR_GRPH1ORUN
+*/
+#define ODN_PDP_INTCLR_INTCLR_GRPH1ORUN_MASK (0x00001000)
+#define ODN_PDP_INTCLR_INTCLR_GRPH1ORUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_GRPH1ORUN_SHIFT (12)
+#define ODN_PDP_INTCLR_INTCLR_GRPH1ORUN_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_GRPH1ORUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTCLR, INTCLR_VID4URUN
+*/
+#define ODN_PDP_INTCLR_INTCLR_VID4URUN_MASK (0x00000800)
+#define ODN_PDP_INTCLR_INTCLR_VID4URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_VID4URUN_SHIFT (11)
+#define ODN_PDP_INTCLR_INTCLR_VID4URUN_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_VID4URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTCLR, INTCLR_VID3URUN
+*/
+#define ODN_PDP_INTCLR_INTCLR_VID3URUN_MASK (0x00000400)
+#define ODN_PDP_INTCLR_INTCLR_VID3URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_VID3URUN_SHIFT (10)
+#define ODN_PDP_INTCLR_INTCLR_VID3URUN_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_VID3URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTCLR, INTCLR_VID2URUN
+*/
+#define ODN_PDP_INTCLR_INTCLR_VID2URUN_MASK (0x00000200)
+#define ODN_PDP_INTCLR_INTCLR_VID2URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_VID2URUN_SHIFT (9)
+#define ODN_PDP_INTCLR_INTCLR_VID2URUN_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_VID2URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTCLR, INTCLR_VID1URUN
+*/
+#define ODN_PDP_INTCLR_INTCLR_VID1URUN_MASK (0x00000100)
+#define ODN_PDP_INTCLR_INTCLR_VID1URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_VID1URUN_SHIFT (8)
+#define ODN_PDP_INTCLR_INTCLR_VID1URUN_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_VID1URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTCLR, INTCLR_GRPH4URUN
+*/
+#define ODN_PDP_INTCLR_INTCLR_GRPH4URUN_MASK (0x00000080)
+#define ODN_PDP_INTCLR_INTCLR_GRPH4URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_GRPH4URUN_SHIFT (7)
+#define ODN_PDP_INTCLR_INTCLR_GRPH4URUN_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_GRPH4URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTCLR, INTCLR_GRPH3URUN
+*/
+#define ODN_PDP_INTCLR_INTCLR_GRPH3URUN_MASK (0x00000040)
+#define ODN_PDP_INTCLR_INTCLR_GRPH3URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_GRPH3URUN_SHIFT (6)
+#define ODN_PDP_INTCLR_INTCLR_GRPH3URUN_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_GRPH3URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTCLR, INTCLR_GRPH2URUN
+*/
+#define ODN_PDP_INTCLR_INTCLR_GRPH2URUN_MASK (0x00000020)
+#define ODN_PDP_INTCLR_INTCLR_GRPH2URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_GRPH2URUN_SHIFT (5)
+#define ODN_PDP_INTCLR_INTCLR_GRPH2URUN_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_GRPH2URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTCLR, INTCLR_GRPH1URUN
+*/
+#define ODN_PDP_INTCLR_INTCLR_GRPH1URUN_MASK (0x00000010)
+#define ODN_PDP_INTCLR_INTCLR_GRPH1URUN_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_GRPH1URUN_SHIFT (4)
+#define ODN_PDP_INTCLR_INTCLR_GRPH1URUN_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_GRPH1URUN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTCLR, INTCLR_VBLNK1
+*/
+#define ODN_PDP_INTCLR_INTCLR_VBLNK1_MASK (0x00000008)
+#define ODN_PDP_INTCLR_INTCLR_VBLNK1_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_VBLNK1_SHIFT (3)
+#define ODN_PDP_INTCLR_INTCLR_VBLNK1_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_VBLNK1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTCLR, INTCLR_VBLNK0
+*/
+#define ODN_PDP_INTCLR_INTCLR_VBLNK0_MASK (0x00000004)
+#define ODN_PDP_INTCLR_INTCLR_VBLNK0_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_VBLNK0_SHIFT (2)
+#define ODN_PDP_INTCLR_INTCLR_VBLNK0_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_VBLNK0_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTCLR, INTCLR_HBLNK1
+*/
+#define ODN_PDP_INTCLR_INTCLR_HBLNK1_MASK (0x00000002)
+#define ODN_PDP_INTCLR_INTCLR_HBLNK1_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_HBLNK1_SHIFT (1)
+#define ODN_PDP_INTCLR_INTCLR_HBLNK1_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_HBLNK1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, INTCLR, INTCLR_HBLNK0
+*/
+#define ODN_PDP_INTCLR_INTCLR_HBLNK0_MASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_HBLNK0_LSBMASK (0x00000001)
+#define ODN_PDP_INTCLR_INTCLR_HBLNK0_SHIFT (0)
+#define ODN_PDP_INTCLR_INTCLR_HBLNK0_LENGTH (1)
+#define ODN_PDP_INTCLR_INTCLR_HBLNK0_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_MEMCTRL_OFFSET (0x07A8)
+
+/* PDP, MEMCTRL, MEMREFRESH
+*/
+#define ODN_PDP_MEMCTRL_MEMREFRESH_MASK (0xC0000000)
+#define ODN_PDP_MEMCTRL_MEMREFRESH_LSBMASK (0x00000003)
+#define ODN_PDP_MEMCTRL_MEMREFRESH_SHIFT (30)
+#define ODN_PDP_MEMCTRL_MEMREFRESH_LENGTH (2)
+#define ODN_PDP_MEMCTRL_MEMREFRESH_SIGNED_FIELD IMG_FALSE
+
+/* PDP, MEMCTRL, BURSTLEN
+*/
+#define ODN_PDP_MEMCTRL_BURSTLEN_MASK (0x000000FF)
+#define ODN_PDP_MEMCTRL_BURSTLEN_LSBMASK (0x000000FF)
+#define ODN_PDP_MEMCTRL_BURSTLEN_SHIFT (0)
+#define ODN_PDP_MEMCTRL_BURSTLEN_LENGTH (8)
+#define ODN_PDP_MEMCTRL_BURSTLEN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_MEM_THRESH_OFFSET (0x07AC)
+
+/* PDP, MEM_THRESH, UVTHRESHOLD
+*/
+#define ODN_PDP_MEM_THRESH_UVTHRESHOLD_MASK (0xFF000000)
+#define ODN_PDP_MEM_THRESH_UVTHRESHOLD_LSBMASK (0x000000FF)
+#define ODN_PDP_MEM_THRESH_UVTHRESHOLD_SHIFT (24)
+#define ODN_PDP_MEM_THRESH_UVTHRESHOLD_LENGTH (8)
+#define ODN_PDP_MEM_THRESH_UVTHRESHOLD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, MEM_THRESH, YTHRESHOLD
+*/
+#define ODN_PDP_MEM_THRESH_YTHRESHOLD_MASK (0x001FF000)
+#define ODN_PDP_MEM_THRESH_YTHRESHOLD_LSBMASK (0x000001FF)
+#define ODN_PDP_MEM_THRESH_YTHRESHOLD_SHIFT (12)
+#define ODN_PDP_MEM_THRESH_YTHRESHOLD_LENGTH (9)
+#define ODN_PDP_MEM_THRESH_YTHRESHOLD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, MEM_THRESH, THRESHOLD
+*/
+#define ODN_PDP_MEM_THRESH_THRESHOLD_MASK (0x000001FF)
+#define ODN_PDP_MEM_THRESH_THRESHOLD_LSBMASK (0x000001FF)
+#define ODN_PDP_MEM_THRESH_THRESHOLD_SHIFT (0)
+#define ODN_PDP_MEM_THRESH_THRESHOLD_LENGTH (9)
+#define ODN_PDP_MEM_THRESH_THRESHOLD_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_ALTERNATE_3D_CTRL_OFFSET (0x07B0)
+
+/* PDP, ALTERNATE_3D_CTRL, ALT3D_ON
+*/
+#define ODN_PDP_ALTERNATE_3D_CTRL_ALT3D_ON_MASK (0x00000010)
+#define ODN_PDP_ALTERNATE_3D_CTRL_ALT3D_ON_LSBMASK (0x00000001)
+#define ODN_PDP_ALTERNATE_3D_CTRL_ALT3D_ON_SHIFT (4)
+#define ODN_PDP_ALTERNATE_3D_CTRL_ALT3D_ON_LENGTH (1)
+#define ODN_PDP_ALTERNATE_3D_CTRL_ALT3D_ON_SIGNED_FIELD IMG_FALSE
+
+/* PDP, ALTERNATE_3D_CTRL, ALT3D_BLENDSEL
+*/
+#define ODN_PDP_ALTERNATE_3D_CTRL_ALT3D_BLENDSEL_MASK (0x00000007)
+#define ODN_PDP_ALTERNATE_3D_CTRL_ALT3D_BLENDSEL_LSBMASK (0x00000007)
+#define ODN_PDP_ALTERNATE_3D_CTRL_ALT3D_BLENDSEL_SHIFT (0)
+#define ODN_PDP_ALTERNATE_3D_CTRL_ALT3D_BLENDSEL_LENGTH (3)
+#define ODN_PDP_ALTERNATE_3D_CTRL_ALT3D_BLENDSEL_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA0_R_OFFSET (0x07B4)
+
+/* PDP, GAMMA0_R, GAMMA0_R
+*/
+#define ODN_PDP_GAMMA0_R_GAMMA0_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA0_R_GAMMA0_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA0_R_GAMMA0_R_SHIFT (0)
+#define ODN_PDP_GAMMA0_R_GAMMA0_R_LENGTH (10)
+#define ODN_PDP_GAMMA0_R_GAMMA0_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA0_GB_OFFSET (0x07B8)
+
+/* PDP, GAMMA0_GB, GAMMA0_G
+*/
+#define ODN_PDP_GAMMA0_GB_GAMMA0_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA0_GB_GAMMA0_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA0_GB_GAMMA0_G_SHIFT (16)
+#define ODN_PDP_GAMMA0_GB_GAMMA0_G_LENGTH (10)
+#define ODN_PDP_GAMMA0_GB_GAMMA0_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA0_GB, GAMMA0_B
+*/
+#define ODN_PDP_GAMMA0_GB_GAMMA0_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA0_GB_GAMMA0_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA0_GB_GAMMA0_B_SHIFT (0)
+#define ODN_PDP_GAMMA0_GB_GAMMA0_B_LENGTH (10)
+#define ODN_PDP_GAMMA0_GB_GAMMA0_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA1_R_OFFSET (0x07BC)
+
+/* PDP, GAMMA1_R, GAMMA1_R
+*/
+#define ODN_PDP_GAMMA1_R_GAMMA1_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA1_R_GAMMA1_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA1_R_GAMMA1_R_SHIFT (0)
+#define ODN_PDP_GAMMA1_R_GAMMA1_R_LENGTH (10)
+#define ODN_PDP_GAMMA1_R_GAMMA1_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA1_GB_OFFSET (0x07C0)
+
+/* PDP, GAMMA1_GB, GAMMA1_G
+*/
+#define ODN_PDP_GAMMA1_GB_GAMMA1_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA1_GB_GAMMA1_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA1_GB_GAMMA1_G_SHIFT (16)
+#define ODN_PDP_GAMMA1_GB_GAMMA1_G_LENGTH (10)
+#define ODN_PDP_GAMMA1_GB_GAMMA1_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA1_GB, GAMMA1_B
+*/
+#define ODN_PDP_GAMMA1_GB_GAMMA1_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA1_GB_GAMMA1_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA1_GB_GAMMA1_B_SHIFT (0)
+#define ODN_PDP_GAMMA1_GB_GAMMA1_B_LENGTH (10)
+#define ODN_PDP_GAMMA1_GB_GAMMA1_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA2_R_OFFSET (0x07C4)
+
+/* PDP, GAMMA2_R, GAMMA2_R
+*/
+#define ODN_PDP_GAMMA2_R_GAMMA2_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA2_R_GAMMA2_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA2_R_GAMMA2_R_SHIFT (0)
+#define ODN_PDP_GAMMA2_R_GAMMA2_R_LENGTH (10)
+#define ODN_PDP_GAMMA2_R_GAMMA2_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA2_GB_OFFSET (0x07C8)
+
+/* PDP, GAMMA2_GB, GAMMA2_G
+*/
+#define ODN_PDP_GAMMA2_GB_GAMMA2_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA2_GB_GAMMA2_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA2_GB_GAMMA2_G_SHIFT (16)
+#define ODN_PDP_GAMMA2_GB_GAMMA2_G_LENGTH (10)
+#define ODN_PDP_GAMMA2_GB_GAMMA2_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA2_GB, GAMMA2_B
+*/
+#define ODN_PDP_GAMMA2_GB_GAMMA2_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA2_GB_GAMMA2_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA2_GB_GAMMA2_B_SHIFT (0)
+#define ODN_PDP_GAMMA2_GB_GAMMA2_B_LENGTH (10)
+#define ODN_PDP_GAMMA2_GB_GAMMA2_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA3_R_OFFSET (0x07CC)
+
+/* PDP, GAMMA3_R, GAMMA3_R
+*/
+#define ODN_PDP_GAMMA3_R_GAMMA3_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA3_R_GAMMA3_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA3_R_GAMMA3_R_SHIFT (0)
+#define ODN_PDP_GAMMA3_R_GAMMA3_R_LENGTH (10)
+#define ODN_PDP_GAMMA3_R_GAMMA3_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA3_GB_OFFSET (0x07D0)
+
+/* PDP, GAMMA3_GB, GAMMA3_G
+*/
+#define ODN_PDP_GAMMA3_GB_GAMMA3_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA3_GB_GAMMA3_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA3_GB_GAMMA3_G_SHIFT (16)
+#define ODN_PDP_GAMMA3_GB_GAMMA3_G_LENGTH (10)
+#define ODN_PDP_GAMMA3_GB_GAMMA3_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA3_GB, GAMMA3_B
+*/
+#define ODN_PDP_GAMMA3_GB_GAMMA3_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA3_GB_GAMMA3_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA3_GB_GAMMA3_B_SHIFT (0)
+#define ODN_PDP_GAMMA3_GB_GAMMA3_B_LENGTH (10)
+#define ODN_PDP_GAMMA3_GB_GAMMA3_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA4_R_OFFSET (0x07D4)
+
+/* PDP, GAMMA4_R, GAMMA4_R
+*/
+#define ODN_PDP_GAMMA4_R_GAMMA4_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA4_R_GAMMA4_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA4_R_GAMMA4_R_SHIFT (0)
+#define ODN_PDP_GAMMA4_R_GAMMA4_R_LENGTH (10)
+#define ODN_PDP_GAMMA4_R_GAMMA4_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA4_GB_OFFSET (0x07D8)
+
+/* PDP, GAMMA4_GB, GAMMA4_G
+*/
+#define ODN_PDP_GAMMA4_GB_GAMMA4_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA4_GB_GAMMA4_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA4_GB_GAMMA4_G_SHIFT (16)
+#define ODN_PDP_GAMMA4_GB_GAMMA4_G_LENGTH (10)
+#define ODN_PDP_GAMMA4_GB_GAMMA4_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA4_GB, GAMMA4_B
+*/
+#define ODN_PDP_GAMMA4_GB_GAMMA4_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA4_GB_GAMMA4_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA4_GB_GAMMA4_B_SHIFT (0)
+#define ODN_PDP_GAMMA4_GB_GAMMA4_B_LENGTH (10)
+#define ODN_PDP_GAMMA4_GB_GAMMA4_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA5_R_OFFSET (0x07DC)
+
+/* PDP, GAMMA5_R, GAMMA5_R
+*/
+#define ODN_PDP_GAMMA5_R_GAMMA5_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA5_R_GAMMA5_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA5_R_GAMMA5_R_SHIFT (0)
+#define ODN_PDP_GAMMA5_R_GAMMA5_R_LENGTH (10)
+#define ODN_PDP_GAMMA5_R_GAMMA5_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA5_GB_OFFSET (0x07E0)
+
+/* PDP, GAMMA5_GB, GAMMA5_G
+*/
+#define ODN_PDP_GAMMA5_GB_GAMMA5_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA5_GB_GAMMA5_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA5_GB_GAMMA5_G_SHIFT (16)
+#define ODN_PDP_GAMMA5_GB_GAMMA5_G_LENGTH (10)
+#define ODN_PDP_GAMMA5_GB_GAMMA5_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA5_GB, GAMMA5_B
+*/
+#define ODN_PDP_GAMMA5_GB_GAMMA5_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA5_GB_GAMMA5_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA5_GB_GAMMA5_B_SHIFT (0)
+#define ODN_PDP_GAMMA5_GB_GAMMA5_B_LENGTH (10)
+#define ODN_PDP_GAMMA5_GB_GAMMA5_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA6_R_OFFSET (0x07E4)
+
+/* PDP, GAMMA6_R, GAMMA6_R
+*/
+#define ODN_PDP_GAMMA6_R_GAMMA6_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA6_R_GAMMA6_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA6_R_GAMMA6_R_SHIFT (0)
+#define ODN_PDP_GAMMA6_R_GAMMA6_R_LENGTH (10)
+#define ODN_PDP_GAMMA6_R_GAMMA6_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA6_GB_OFFSET (0x07E8)
+
+/* PDP, GAMMA6_GB, GAMMA6_G
+*/
+#define ODN_PDP_GAMMA6_GB_GAMMA6_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA6_GB_GAMMA6_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA6_GB_GAMMA6_G_SHIFT (16)
+#define ODN_PDP_GAMMA6_GB_GAMMA6_G_LENGTH (10)
+#define ODN_PDP_GAMMA6_GB_GAMMA6_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA6_GB, GAMMA6_B
+*/
+#define ODN_PDP_GAMMA6_GB_GAMMA6_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA6_GB_GAMMA6_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA6_GB_GAMMA6_B_SHIFT (0)
+#define ODN_PDP_GAMMA6_GB_GAMMA6_B_LENGTH (10)
+#define ODN_PDP_GAMMA6_GB_GAMMA6_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA7_R_OFFSET (0x07EC)
+
+/* PDP, GAMMA7_R, GAMMA7_R
+*/
+#define ODN_PDP_GAMMA7_R_GAMMA7_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA7_R_GAMMA7_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA7_R_GAMMA7_R_SHIFT (0)
+#define ODN_PDP_GAMMA7_R_GAMMA7_R_LENGTH (10)
+#define ODN_PDP_GAMMA7_R_GAMMA7_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA7_GB_OFFSET (0x07F0)
+
+/* PDP, GAMMA7_GB, GAMMA7_G
+*/
+#define ODN_PDP_GAMMA7_GB_GAMMA7_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA7_GB_GAMMA7_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA7_GB_GAMMA7_G_SHIFT (16)
+#define ODN_PDP_GAMMA7_GB_GAMMA7_G_LENGTH (10)
+#define ODN_PDP_GAMMA7_GB_GAMMA7_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA7_GB, GAMMA7_B
+*/
+#define ODN_PDP_GAMMA7_GB_GAMMA7_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA7_GB_GAMMA7_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA7_GB_GAMMA7_B_SHIFT (0)
+#define ODN_PDP_GAMMA7_GB_GAMMA7_B_LENGTH (10)
+#define ODN_PDP_GAMMA7_GB_GAMMA7_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA8_R_OFFSET (0x07F4)
+
+/* PDP, GAMMA8_R, GAMMA8_R
+*/
+#define ODN_PDP_GAMMA8_R_GAMMA8_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA8_R_GAMMA8_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA8_R_GAMMA8_R_SHIFT (0)
+#define ODN_PDP_GAMMA8_R_GAMMA8_R_LENGTH (10)
+#define ODN_PDP_GAMMA8_R_GAMMA8_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA8_GB_OFFSET (0x07F8)
+
+/* PDP, GAMMA8_GB, GAMMA8_G
+*/
+#define ODN_PDP_GAMMA8_GB_GAMMA8_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA8_GB_GAMMA8_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA8_GB_GAMMA8_G_SHIFT (16)
+#define ODN_PDP_GAMMA8_GB_GAMMA8_G_LENGTH (10)
+#define ODN_PDP_GAMMA8_GB_GAMMA8_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA8_GB, GAMMA8_B
+*/
+#define ODN_PDP_GAMMA8_GB_GAMMA8_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA8_GB_GAMMA8_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA8_GB_GAMMA8_B_SHIFT (0)
+#define ODN_PDP_GAMMA8_GB_GAMMA8_B_LENGTH (10)
+#define ODN_PDP_GAMMA8_GB_GAMMA8_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA9_R_OFFSET (0x07FC)
+
+/* PDP, GAMMA9_R, GAMMA9_R
+*/
+#define ODN_PDP_GAMMA9_R_GAMMA9_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA9_R_GAMMA9_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA9_R_GAMMA9_R_SHIFT (0)
+#define ODN_PDP_GAMMA9_R_GAMMA9_R_LENGTH (10)
+#define ODN_PDP_GAMMA9_R_GAMMA9_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA9_GB_OFFSET (0x0800)
+
+/* PDP, GAMMA9_GB, GAMMA9_G
+*/
+#define ODN_PDP_GAMMA9_GB_GAMMA9_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA9_GB_GAMMA9_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA9_GB_GAMMA9_G_SHIFT (16)
+#define ODN_PDP_GAMMA9_GB_GAMMA9_G_LENGTH (10)
+#define ODN_PDP_GAMMA9_GB_GAMMA9_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA9_GB, GAMMA9_B
+*/
+#define ODN_PDP_GAMMA9_GB_GAMMA9_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA9_GB_GAMMA9_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA9_GB_GAMMA9_B_SHIFT (0)
+#define ODN_PDP_GAMMA9_GB_GAMMA9_B_LENGTH (10)
+#define ODN_PDP_GAMMA9_GB_GAMMA9_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA10_R_OFFSET (0x0804)
+
+/* PDP, GAMMA10_R, GAMMA10_R
+*/
+#define ODN_PDP_GAMMA10_R_GAMMA10_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA10_R_GAMMA10_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA10_R_GAMMA10_R_SHIFT (0)
+#define ODN_PDP_GAMMA10_R_GAMMA10_R_LENGTH (10)
+#define ODN_PDP_GAMMA10_R_GAMMA10_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA10_GB_OFFSET (0x0808)
+
+/* PDP, GAMMA10_GB, GAMMA10_G
+*/
+#define ODN_PDP_GAMMA10_GB_GAMMA10_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA10_GB_GAMMA10_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA10_GB_GAMMA10_G_SHIFT (16)
+#define ODN_PDP_GAMMA10_GB_GAMMA10_G_LENGTH (10)
+#define ODN_PDP_GAMMA10_GB_GAMMA10_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA10_GB, GAMMA10_B
+*/
+#define ODN_PDP_GAMMA10_GB_GAMMA10_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA10_GB_GAMMA10_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA10_GB_GAMMA10_B_SHIFT (0)
+#define ODN_PDP_GAMMA10_GB_GAMMA10_B_LENGTH (10)
+#define ODN_PDP_GAMMA10_GB_GAMMA10_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA11_R_OFFSET (0x080C)
+
+/* PDP, GAMMA11_R, GAMMA11_R
+*/
+#define ODN_PDP_GAMMA11_R_GAMMA11_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA11_R_GAMMA11_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA11_R_GAMMA11_R_SHIFT (0)
+#define ODN_PDP_GAMMA11_R_GAMMA11_R_LENGTH (10)
+#define ODN_PDP_GAMMA11_R_GAMMA11_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA11_GB_OFFSET (0x0810)
+
+/* PDP, GAMMA11_GB, GAMMA11_G
+*/
+#define ODN_PDP_GAMMA11_GB_GAMMA11_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA11_GB_GAMMA11_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA11_GB_GAMMA11_G_SHIFT (16)
+#define ODN_PDP_GAMMA11_GB_GAMMA11_G_LENGTH (10)
+#define ODN_PDP_GAMMA11_GB_GAMMA11_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA11_GB, GAMMA11_B
+*/
+#define ODN_PDP_GAMMA11_GB_GAMMA11_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA11_GB_GAMMA11_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA11_GB_GAMMA11_B_SHIFT (0)
+#define ODN_PDP_GAMMA11_GB_GAMMA11_B_LENGTH (10)
+#define ODN_PDP_GAMMA11_GB_GAMMA11_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA12_R_OFFSET (0x0814)
+
+/* PDP, GAMMA12_R, GAMMA12_R
+*/
+#define ODN_PDP_GAMMA12_R_GAMMA12_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA12_R_GAMMA12_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA12_R_GAMMA12_R_SHIFT (0)
+#define ODN_PDP_GAMMA12_R_GAMMA12_R_LENGTH (10)
+#define ODN_PDP_GAMMA12_R_GAMMA12_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA12_GB_OFFSET (0x0818)
+
+/* PDP, GAMMA12_GB, GAMMA12_G
+*/
+#define ODN_PDP_GAMMA12_GB_GAMMA12_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA12_GB_GAMMA12_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA12_GB_GAMMA12_G_SHIFT (16)
+#define ODN_PDP_GAMMA12_GB_GAMMA12_G_LENGTH (10)
+#define ODN_PDP_GAMMA12_GB_GAMMA12_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA12_GB, GAMMA12_B
+*/
+#define ODN_PDP_GAMMA12_GB_GAMMA12_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA12_GB_GAMMA12_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA12_GB_GAMMA12_B_SHIFT (0)
+#define ODN_PDP_GAMMA12_GB_GAMMA12_B_LENGTH (10)
+#define ODN_PDP_GAMMA12_GB_GAMMA12_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA13_R_OFFSET (0x081C)
+
+/* PDP, GAMMA13_R, GAMMA13_R
+*/
+#define ODN_PDP_GAMMA13_R_GAMMA13_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA13_R_GAMMA13_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA13_R_GAMMA13_R_SHIFT (0)
+#define ODN_PDP_GAMMA13_R_GAMMA13_R_LENGTH (10)
+#define ODN_PDP_GAMMA13_R_GAMMA13_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA13_GB_OFFSET (0x0820)
+
+/* PDP, GAMMA13_GB, GAMMA13_G
+*/
+#define ODN_PDP_GAMMA13_GB_GAMMA13_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA13_GB_GAMMA13_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA13_GB_GAMMA13_G_SHIFT (16)
+#define ODN_PDP_GAMMA13_GB_GAMMA13_G_LENGTH (10)
+#define ODN_PDP_GAMMA13_GB_GAMMA13_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA13_GB, GAMMA13_B
+*/
+#define ODN_PDP_GAMMA13_GB_GAMMA13_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA13_GB_GAMMA13_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA13_GB_GAMMA13_B_SHIFT (0)
+#define ODN_PDP_GAMMA13_GB_GAMMA13_B_LENGTH (10)
+#define ODN_PDP_GAMMA13_GB_GAMMA13_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA14_R_OFFSET (0x0824)
+
+/* PDP, GAMMA14_R, GAMMA14_R
+*/
+#define ODN_PDP_GAMMA14_R_GAMMA14_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA14_R_GAMMA14_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA14_R_GAMMA14_R_SHIFT (0)
+#define ODN_PDP_GAMMA14_R_GAMMA14_R_LENGTH (10)
+#define ODN_PDP_GAMMA14_R_GAMMA14_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA14_GB_OFFSET (0x0828)
+
+/* PDP, GAMMA14_GB, GAMMA14_G
+*/
+#define ODN_PDP_GAMMA14_GB_GAMMA14_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA14_GB_GAMMA14_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA14_GB_GAMMA14_G_SHIFT (16)
+#define ODN_PDP_GAMMA14_GB_GAMMA14_G_LENGTH (10)
+#define ODN_PDP_GAMMA14_GB_GAMMA14_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA14_GB, GAMMA14_B
+*/
+#define ODN_PDP_GAMMA14_GB_GAMMA14_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA14_GB_GAMMA14_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA14_GB_GAMMA14_B_SHIFT (0)
+#define ODN_PDP_GAMMA14_GB_GAMMA14_B_LENGTH (10)
+#define ODN_PDP_GAMMA14_GB_GAMMA14_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA15_R_OFFSET (0x082C)
+
+/* PDP, GAMMA15_R, GAMMA15_R
+*/
+#define ODN_PDP_GAMMA15_R_GAMMA15_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA15_R_GAMMA15_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA15_R_GAMMA15_R_SHIFT (0)
+#define ODN_PDP_GAMMA15_R_GAMMA15_R_LENGTH (10)
+#define ODN_PDP_GAMMA15_R_GAMMA15_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA15_GB_OFFSET (0x0830)
+
+/* PDP, GAMMA15_GB, GAMMA15_G
+*/
+#define ODN_PDP_GAMMA15_GB_GAMMA15_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA15_GB_GAMMA15_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA15_GB_GAMMA15_G_SHIFT (16)
+#define ODN_PDP_GAMMA15_GB_GAMMA15_G_LENGTH (10)
+#define ODN_PDP_GAMMA15_GB_GAMMA15_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA15_GB, GAMMA15_B
+*/
+#define ODN_PDP_GAMMA15_GB_GAMMA15_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA15_GB_GAMMA15_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA15_GB_GAMMA15_B_SHIFT (0)
+#define ODN_PDP_GAMMA15_GB_GAMMA15_B_LENGTH (10)
+#define ODN_PDP_GAMMA15_GB_GAMMA15_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA16_R_OFFSET (0x0834)
+
+/* PDP, GAMMA16_R, GAMMA16_R
+*/
+#define ODN_PDP_GAMMA16_R_GAMMA16_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA16_R_GAMMA16_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA16_R_GAMMA16_R_SHIFT (0)
+#define ODN_PDP_GAMMA16_R_GAMMA16_R_LENGTH (10)
+#define ODN_PDP_GAMMA16_R_GAMMA16_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA16_GB_OFFSET (0x0838)
+
+/* PDP, GAMMA16_GB, GAMMA16_G
+*/
+#define ODN_PDP_GAMMA16_GB_GAMMA16_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA16_GB_GAMMA16_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA16_GB_GAMMA16_G_SHIFT (16)
+#define ODN_PDP_GAMMA16_GB_GAMMA16_G_LENGTH (10)
+#define ODN_PDP_GAMMA16_GB_GAMMA16_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA16_GB, GAMMA16_B
+*/
+#define ODN_PDP_GAMMA16_GB_GAMMA16_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA16_GB_GAMMA16_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA16_GB_GAMMA16_B_SHIFT (0)
+#define ODN_PDP_GAMMA16_GB_GAMMA16_B_LENGTH (10)
+#define ODN_PDP_GAMMA16_GB_GAMMA16_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA17_R_OFFSET (0x083C)
+
+/* PDP, GAMMA17_R, GAMMA17_R
+*/
+#define ODN_PDP_GAMMA17_R_GAMMA17_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA17_R_GAMMA17_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA17_R_GAMMA17_R_SHIFT (0)
+#define ODN_PDP_GAMMA17_R_GAMMA17_R_LENGTH (10)
+#define ODN_PDP_GAMMA17_R_GAMMA17_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA17_GB_OFFSET (0x0840)
+
+/* PDP, GAMMA17_GB, GAMMA17_G
+*/
+#define ODN_PDP_GAMMA17_GB_GAMMA17_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA17_GB_GAMMA17_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA17_GB_GAMMA17_G_SHIFT (16)
+#define ODN_PDP_GAMMA17_GB_GAMMA17_G_LENGTH (10)
+#define ODN_PDP_GAMMA17_GB_GAMMA17_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA17_GB, GAMMA17_B
+*/
+#define ODN_PDP_GAMMA17_GB_GAMMA17_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA17_GB_GAMMA17_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA17_GB_GAMMA17_B_SHIFT (0)
+#define ODN_PDP_GAMMA17_GB_GAMMA17_B_LENGTH (10)
+#define ODN_PDP_GAMMA17_GB_GAMMA17_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA18_R_OFFSET (0x0844)
+
+/* PDP, GAMMA18_R, GAMMA18_R
+*/
+#define ODN_PDP_GAMMA18_R_GAMMA18_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA18_R_GAMMA18_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA18_R_GAMMA18_R_SHIFT (0)
+#define ODN_PDP_GAMMA18_R_GAMMA18_R_LENGTH (10)
+#define ODN_PDP_GAMMA18_R_GAMMA18_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA18_GB_OFFSET (0x0848)
+
+/* PDP, GAMMA18_GB, GAMMA18_G
+*/
+#define ODN_PDP_GAMMA18_GB_GAMMA18_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA18_GB_GAMMA18_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA18_GB_GAMMA18_G_SHIFT (16)
+#define ODN_PDP_GAMMA18_GB_GAMMA18_G_LENGTH (10)
+#define ODN_PDP_GAMMA18_GB_GAMMA18_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA18_GB, GAMMA18_B
+*/
+#define ODN_PDP_GAMMA18_GB_GAMMA18_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA18_GB_GAMMA18_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA18_GB_GAMMA18_B_SHIFT (0)
+#define ODN_PDP_GAMMA18_GB_GAMMA18_B_LENGTH (10)
+#define ODN_PDP_GAMMA18_GB_GAMMA18_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA19_R_OFFSET (0x084C)
+
+/* PDP, GAMMA19_R, GAMMA19_R
+*/
+#define ODN_PDP_GAMMA19_R_GAMMA19_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA19_R_GAMMA19_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA19_R_GAMMA19_R_SHIFT (0)
+#define ODN_PDP_GAMMA19_R_GAMMA19_R_LENGTH (10)
+#define ODN_PDP_GAMMA19_R_GAMMA19_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA19_GB_OFFSET (0x0850)
+
+/* PDP, GAMMA19_GB, GAMMA19_G
+*/
+#define ODN_PDP_GAMMA19_GB_GAMMA19_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA19_GB_GAMMA19_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA19_GB_GAMMA19_G_SHIFT (16)
+#define ODN_PDP_GAMMA19_GB_GAMMA19_G_LENGTH (10)
+#define ODN_PDP_GAMMA19_GB_GAMMA19_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA19_GB, GAMMA19_B
+*/
+#define ODN_PDP_GAMMA19_GB_GAMMA19_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA19_GB_GAMMA19_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA19_GB_GAMMA19_B_SHIFT (0)
+#define ODN_PDP_GAMMA19_GB_GAMMA19_B_LENGTH (10)
+#define ODN_PDP_GAMMA19_GB_GAMMA19_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA20_R_OFFSET (0x0854)
+
+/* PDP, GAMMA20_R, GAMMA20_R
+*/
+#define ODN_PDP_GAMMA20_R_GAMMA20_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA20_R_GAMMA20_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA20_R_GAMMA20_R_SHIFT (0)
+#define ODN_PDP_GAMMA20_R_GAMMA20_R_LENGTH (10)
+#define ODN_PDP_GAMMA20_R_GAMMA20_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA20_GB_OFFSET (0x0858)
+
+/* PDP, GAMMA20_GB, GAMMA20_G
+*/
+#define ODN_PDP_GAMMA20_GB_GAMMA20_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA20_GB_GAMMA20_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA20_GB_GAMMA20_G_SHIFT (16)
+#define ODN_PDP_GAMMA20_GB_GAMMA20_G_LENGTH (10)
+#define ODN_PDP_GAMMA20_GB_GAMMA20_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA20_GB, GAMMA20_B
+*/
+#define ODN_PDP_GAMMA20_GB_GAMMA20_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA20_GB_GAMMA20_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA20_GB_GAMMA20_B_SHIFT (0)
+#define ODN_PDP_GAMMA20_GB_GAMMA20_B_LENGTH (10)
+#define ODN_PDP_GAMMA20_GB_GAMMA20_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA21_R_OFFSET (0x085C)
+
+/* PDP, GAMMA21_R, GAMMA21_R
+*/
+#define ODN_PDP_GAMMA21_R_GAMMA21_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA21_R_GAMMA21_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA21_R_GAMMA21_R_SHIFT (0)
+#define ODN_PDP_GAMMA21_R_GAMMA21_R_LENGTH (10)
+#define ODN_PDP_GAMMA21_R_GAMMA21_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA21_GB_OFFSET (0x0860)
+
+/* PDP, GAMMA21_GB, GAMMA21_G
+*/
+#define ODN_PDP_GAMMA21_GB_GAMMA21_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA21_GB_GAMMA21_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA21_GB_GAMMA21_G_SHIFT (16)
+#define ODN_PDP_GAMMA21_GB_GAMMA21_G_LENGTH (10)
+#define ODN_PDP_GAMMA21_GB_GAMMA21_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA21_GB, GAMMA21_B
+*/
+#define ODN_PDP_GAMMA21_GB_GAMMA21_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA21_GB_GAMMA21_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA21_GB_GAMMA21_B_SHIFT (0)
+#define ODN_PDP_GAMMA21_GB_GAMMA21_B_LENGTH (10)
+#define ODN_PDP_GAMMA21_GB_GAMMA21_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA22_R_OFFSET (0x0864)
+
+/* PDP, GAMMA22_R, GAMMA22_R
+*/
+#define ODN_PDP_GAMMA22_R_GAMMA22_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA22_R_GAMMA22_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA22_R_GAMMA22_R_SHIFT (0)
+#define ODN_PDP_GAMMA22_R_GAMMA22_R_LENGTH (10)
+#define ODN_PDP_GAMMA22_R_GAMMA22_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA22_GB_OFFSET (0x0868)
+
+/* PDP, GAMMA22_GB, GAMMA22_G
+*/
+#define ODN_PDP_GAMMA22_GB_GAMMA22_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA22_GB_GAMMA22_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA22_GB_GAMMA22_G_SHIFT (16)
+#define ODN_PDP_GAMMA22_GB_GAMMA22_G_LENGTH (10)
+#define ODN_PDP_GAMMA22_GB_GAMMA22_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA22_GB, GAMMA22_B
+*/
+#define ODN_PDP_GAMMA22_GB_GAMMA22_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA22_GB_GAMMA22_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA22_GB_GAMMA22_B_SHIFT (0)
+#define ODN_PDP_GAMMA22_GB_GAMMA22_B_LENGTH (10)
+#define ODN_PDP_GAMMA22_GB_GAMMA22_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA23_R_OFFSET (0x086C)
+
+/* PDP, GAMMA23_R, GAMMA23_R
+*/
+#define ODN_PDP_GAMMA23_R_GAMMA23_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA23_R_GAMMA23_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA23_R_GAMMA23_R_SHIFT (0)
+#define ODN_PDP_GAMMA23_R_GAMMA23_R_LENGTH (10)
+#define ODN_PDP_GAMMA23_R_GAMMA23_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA23_GB_OFFSET (0x0870)
+
+/* PDP, GAMMA23_GB, GAMMA23_G
+*/
+#define ODN_PDP_GAMMA23_GB_GAMMA23_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA23_GB_GAMMA23_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA23_GB_GAMMA23_G_SHIFT (16)
+#define ODN_PDP_GAMMA23_GB_GAMMA23_G_LENGTH (10)
+#define ODN_PDP_GAMMA23_GB_GAMMA23_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA23_GB, GAMMA23_B
+*/
+#define ODN_PDP_GAMMA23_GB_GAMMA23_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA23_GB_GAMMA23_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA23_GB_GAMMA23_B_SHIFT (0)
+#define ODN_PDP_GAMMA23_GB_GAMMA23_B_LENGTH (10)
+#define ODN_PDP_GAMMA23_GB_GAMMA23_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA24_R_OFFSET (0x0874)
+
+/* PDP, GAMMA24_R, GAMMA24_R
+*/
+#define ODN_PDP_GAMMA24_R_GAMMA24_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA24_R_GAMMA24_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA24_R_GAMMA24_R_SHIFT (0)
+#define ODN_PDP_GAMMA24_R_GAMMA24_R_LENGTH (10)
+#define ODN_PDP_GAMMA24_R_GAMMA24_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA24_GB_OFFSET (0x0878)
+
+/* PDP, GAMMA24_GB, GAMMA24_G
+*/
+#define ODN_PDP_GAMMA24_GB_GAMMA24_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA24_GB_GAMMA24_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA24_GB_GAMMA24_G_SHIFT (16)
+#define ODN_PDP_GAMMA24_GB_GAMMA24_G_LENGTH (10)
+#define ODN_PDP_GAMMA24_GB_GAMMA24_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA24_GB, GAMMA24_B
+*/
+#define ODN_PDP_GAMMA24_GB_GAMMA24_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA24_GB_GAMMA24_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA24_GB_GAMMA24_B_SHIFT (0)
+#define ODN_PDP_GAMMA24_GB_GAMMA24_B_LENGTH (10)
+#define ODN_PDP_GAMMA24_GB_GAMMA24_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA25_R_OFFSET (0x087C)
+
+/* PDP, GAMMA25_R, GAMMA25_R
+*/
+#define ODN_PDP_GAMMA25_R_GAMMA25_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA25_R_GAMMA25_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA25_R_GAMMA25_R_SHIFT (0)
+#define ODN_PDP_GAMMA25_R_GAMMA25_R_LENGTH (10)
+#define ODN_PDP_GAMMA25_R_GAMMA25_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA25_GB_OFFSET (0x0880)
+
+/* PDP, GAMMA25_GB, GAMMA25_G
+*/
+#define ODN_PDP_GAMMA25_GB_GAMMA25_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA25_GB_GAMMA25_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA25_GB_GAMMA25_G_SHIFT (16)
+#define ODN_PDP_GAMMA25_GB_GAMMA25_G_LENGTH (10)
+#define ODN_PDP_GAMMA25_GB_GAMMA25_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA25_GB, GAMMA25_B
+*/
+#define ODN_PDP_GAMMA25_GB_GAMMA25_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA25_GB_GAMMA25_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA25_GB_GAMMA25_B_SHIFT (0)
+#define ODN_PDP_GAMMA25_GB_GAMMA25_B_LENGTH (10)
+#define ODN_PDP_GAMMA25_GB_GAMMA25_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA26_R_OFFSET (0x0884)
+
+/* PDP, GAMMA26_R, GAMMA26_R
+*/
+#define ODN_PDP_GAMMA26_R_GAMMA26_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA26_R_GAMMA26_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA26_R_GAMMA26_R_SHIFT (0)
+#define ODN_PDP_GAMMA26_R_GAMMA26_R_LENGTH (10)
+#define ODN_PDP_GAMMA26_R_GAMMA26_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA26_GB_OFFSET (0x0888)
+
+/* PDP, GAMMA26_GB, GAMMA26_G
+*/
+#define ODN_PDP_GAMMA26_GB_GAMMA26_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA26_GB_GAMMA26_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA26_GB_GAMMA26_G_SHIFT (16)
+#define ODN_PDP_GAMMA26_GB_GAMMA26_G_LENGTH (10)
+#define ODN_PDP_GAMMA26_GB_GAMMA26_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA26_GB, GAMMA26_B
+*/
+#define ODN_PDP_GAMMA26_GB_GAMMA26_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA26_GB_GAMMA26_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA26_GB_GAMMA26_B_SHIFT (0)
+#define ODN_PDP_GAMMA26_GB_GAMMA26_B_LENGTH (10)
+#define ODN_PDP_GAMMA26_GB_GAMMA26_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA27_R_OFFSET (0x088C)
+
+/* PDP, GAMMA27_R, GAMMA27_R
+*/
+#define ODN_PDP_GAMMA27_R_GAMMA27_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA27_R_GAMMA27_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA27_R_GAMMA27_R_SHIFT (0)
+#define ODN_PDP_GAMMA27_R_GAMMA27_R_LENGTH (10)
+#define ODN_PDP_GAMMA27_R_GAMMA27_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA27_GB_OFFSET (0x0890)
+
+/* PDP, GAMMA27_GB, GAMMA27_G
+*/
+#define ODN_PDP_GAMMA27_GB_GAMMA27_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA27_GB_GAMMA27_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA27_GB_GAMMA27_G_SHIFT (16)
+#define ODN_PDP_GAMMA27_GB_GAMMA27_G_LENGTH (10)
+#define ODN_PDP_GAMMA27_GB_GAMMA27_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA27_GB, GAMMA27_B
+*/
+#define ODN_PDP_GAMMA27_GB_GAMMA27_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA27_GB_GAMMA27_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA27_GB_GAMMA27_B_SHIFT (0)
+#define ODN_PDP_GAMMA27_GB_GAMMA27_B_LENGTH (10)
+#define ODN_PDP_GAMMA27_GB_GAMMA27_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA28_R_OFFSET (0x0894)
+
+/* PDP, GAMMA28_R, GAMMA28_R
+*/
+#define ODN_PDP_GAMMA28_R_GAMMA28_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA28_R_GAMMA28_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA28_R_GAMMA28_R_SHIFT (0)
+#define ODN_PDP_GAMMA28_R_GAMMA28_R_LENGTH (10)
+#define ODN_PDP_GAMMA28_R_GAMMA28_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA28_GB_OFFSET (0x0898)
+
+/* PDP, GAMMA28_GB, GAMMA28_G
+*/
+#define ODN_PDP_GAMMA28_GB_GAMMA28_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA28_GB_GAMMA28_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA28_GB_GAMMA28_G_SHIFT (16)
+#define ODN_PDP_GAMMA28_GB_GAMMA28_G_LENGTH (10)
+#define ODN_PDP_GAMMA28_GB_GAMMA28_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA28_GB, GAMMA28_B
+*/
+#define ODN_PDP_GAMMA28_GB_GAMMA28_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA28_GB_GAMMA28_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA28_GB_GAMMA28_B_SHIFT (0)
+#define ODN_PDP_GAMMA28_GB_GAMMA28_B_LENGTH (10)
+#define ODN_PDP_GAMMA28_GB_GAMMA28_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA29_R_OFFSET (0x089C)
+
+/* PDP, GAMMA29_R, GAMMA29_R
+*/
+#define ODN_PDP_GAMMA29_R_GAMMA29_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA29_R_GAMMA29_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA29_R_GAMMA29_R_SHIFT (0)
+#define ODN_PDP_GAMMA29_R_GAMMA29_R_LENGTH (10)
+#define ODN_PDP_GAMMA29_R_GAMMA29_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA29_GB_OFFSET (0x08A0)
+
+/* PDP, GAMMA29_GB, GAMMA29_G
+*/
+#define ODN_PDP_GAMMA29_GB_GAMMA29_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA29_GB_GAMMA29_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA29_GB_GAMMA29_G_SHIFT (16)
+#define ODN_PDP_GAMMA29_GB_GAMMA29_G_LENGTH (10)
+#define ODN_PDP_GAMMA29_GB_GAMMA29_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA29_GB, GAMMA29_B
+*/
+#define ODN_PDP_GAMMA29_GB_GAMMA29_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA29_GB_GAMMA29_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA29_GB_GAMMA29_B_SHIFT (0)
+#define ODN_PDP_GAMMA29_GB_GAMMA29_B_LENGTH (10)
+#define ODN_PDP_GAMMA29_GB_GAMMA29_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA30_R_OFFSET (0x08A4)
+
+/* PDP, GAMMA30_R, GAMMA30_R
+*/
+#define ODN_PDP_GAMMA30_R_GAMMA30_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA30_R_GAMMA30_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA30_R_GAMMA30_R_SHIFT (0)
+#define ODN_PDP_GAMMA30_R_GAMMA30_R_LENGTH (10)
+#define ODN_PDP_GAMMA30_R_GAMMA30_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA30_GB_OFFSET (0x08A8)
+
+/* PDP, GAMMA30_GB, GAMMA30_G
+*/
+#define ODN_PDP_GAMMA30_GB_GAMMA30_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA30_GB_GAMMA30_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA30_GB_GAMMA30_G_SHIFT (16)
+#define ODN_PDP_GAMMA30_GB_GAMMA30_G_LENGTH (10)
+#define ODN_PDP_GAMMA30_GB_GAMMA30_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA30_GB, GAMMA30_B
+*/
+#define ODN_PDP_GAMMA30_GB_GAMMA30_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA30_GB_GAMMA30_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA30_GB_GAMMA30_B_SHIFT (0)
+#define ODN_PDP_GAMMA30_GB_GAMMA30_B_LENGTH (10)
+#define ODN_PDP_GAMMA30_GB_GAMMA30_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA31_R_OFFSET (0x08AC)
+
+/* PDP, GAMMA31_R, GAMMA31_R
+*/
+#define ODN_PDP_GAMMA31_R_GAMMA31_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA31_R_GAMMA31_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA31_R_GAMMA31_R_SHIFT (0)
+#define ODN_PDP_GAMMA31_R_GAMMA31_R_LENGTH (10)
+#define ODN_PDP_GAMMA31_R_GAMMA31_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA31_GB_OFFSET (0x08B0)
+
+/* PDP, GAMMA31_GB, GAMMA31_G
+*/
+#define ODN_PDP_GAMMA31_GB_GAMMA31_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA31_GB_GAMMA31_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA31_GB_GAMMA31_G_SHIFT (16)
+#define ODN_PDP_GAMMA31_GB_GAMMA31_G_LENGTH (10)
+#define ODN_PDP_GAMMA31_GB_GAMMA31_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA31_GB, GAMMA31_B
+*/
+#define ODN_PDP_GAMMA31_GB_GAMMA31_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA31_GB_GAMMA31_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA31_GB_GAMMA31_B_SHIFT (0)
+#define ODN_PDP_GAMMA31_GB_GAMMA31_B_LENGTH (10)
+#define ODN_PDP_GAMMA31_GB_GAMMA31_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA32_R_OFFSET (0x08B4)
+
+/* PDP, GAMMA32_R, GAMMA32_R
+*/
+#define ODN_PDP_GAMMA32_R_GAMMA32_R_MASK (0x000003FF)
+#define ODN_PDP_GAMMA32_R_GAMMA32_R_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA32_R_GAMMA32_R_SHIFT (0)
+#define ODN_PDP_GAMMA32_R_GAMMA32_R_LENGTH (10)
+#define ODN_PDP_GAMMA32_R_GAMMA32_R_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GAMMA32_GB_OFFSET (0x08B8)
+
+/* PDP, GAMMA32_GB, GAMMA32_G
+*/
+#define ODN_PDP_GAMMA32_GB_GAMMA32_G_MASK (0x03FF0000)
+#define ODN_PDP_GAMMA32_GB_GAMMA32_G_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA32_GB_GAMMA32_G_SHIFT (16)
+#define ODN_PDP_GAMMA32_GB_GAMMA32_G_LENGTH (10)
+#define ODN_PDP_GAMMA32_GB_GAMMA32_G_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GAMMA32_GB, GAMMA32_B
+*/
+#define ODN_PDP_GAMMA32_GB_GAMMA32_B_MASK (0x000003FF)
+#define ODN_PDP_GAMMA32_GB_GAMMA32_B_LSBMASK (0x000003FF)
+#define ODN_PDP_GAMMA32_GB_GAMMA32_B_SHIFT (0)
+#define ODN_PDP_GAMMA32_GB_GAMMA32_B_LENGTH (10)
+#define ODN_PDP_GAMMA32_GB_GAMMA32_B_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VEVENT_OFFSET (0x08BC)
+
+/* PDP, VEVENT, VEVENT
+*/
+#define ODN_PDP_VEVENT_VEVENT_MASK (0x1FFF0000)
+#define ODN_PDP_VEVENT_VEVENT_LSBMASK (0x00001FFF)
+#define ODN_PDP_VEVENT_VEVENT_SHIFT (16)
+#define ODN_PDP_VEVENT_VEVENT_LENGTH (13)
+#define ODN_PDP_VEVENT_VEVENT_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VEVENT, VFETCH
+*/
+#define ODN_PDP_VEVENT_VFETCH_MASK (0x00001FFF)
+#define ODN_PDP_VEVENT_VFETCH_LSBMASK (0x00001FFF)
+#define ODN_PDP_VEVENT_VFETCH_SHIFT (0)
+#define ODN_PDP_VEVENT_VFETCH_LENGTH (13)
+#define ODN_PDP_VEVENT_VFETCH_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_HDECTRL_OFFSET (0x08C0)
+
+/* PDP, HDECTRL, HDES
+*/
+#define ODN_PDP_HDECTRL_HDES_MASK (0x1FFF0000)
+#define ODN_PDP_HDECTRL_HDES_LSBMASK (0x00001FFF)
+#define ODN_PDP_HDECTRL_HDES_SHIFT (16)
+#define ODN_PDP_HDECTRL_HDES_LENGTH (13)
+#define ODN_PDP_HDECTRL_HDES_SIGNED_FIELD IMG_FALSE
+
+/* PDP, HDECTRL, HDEF
+*/
+#define ODN_PDP_HDECTRL_HDEF_MASK (0x00001FFF)
+#define ODN_PDP_HDECTRL_HDEF_LSBMASK (0x00001FFF)
+#define ODN_PDP_HDECTRL_HDEF_SHIFT (0)
+#define ODN_PDP_HDECTRL_HDEF_LENGTH (13)
+#define ODN_PDP_HDECTRL_HDEF_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VDECTRL_OFFSET (0x08C4)
+
+/* PDP, VDECTRL, VDES
+*/
+#define ODN_PDP_VDECTRL_VDES_MASK (0x1FFF0000)
+#define ODN_PDP_VDECTRL_VDES_LSBMASK (0x00001FFF)
+#define ODN_PDP_VDECTRL_VDES_SHIFT (16)
+#define ODN_PDP_VDECTRL_VDES_LENGTH (13)
+#define ODN_PDP_VDECTRL_VDES_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VDECTRL, VDEF
+*/
+#define ODN_PDP_VDECTRL_VDEF_MASK (0x00001FFF)
+#define ODN_PDP_VDECTRL_VDEF_LSBMASK (0x00001FFF)
+#define ODN_PDP_VDECTRL_VDEF_SHIFT (0)
+#define ODN_PDP_VDECTRL_VDEF_LENGTH (13)
+#define ODN_PDP_VDECTRL_VDEF_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_OPMASK_R_OFFSET (0x08C8)
+
+/* PDP, OPMASK_R, MASKLEVEL
+*/
+#define ODN_PDP_OPMASK_R_MASKLEVEL_MASK (0x80000000)
+#define ODN_PDP_OPMASK_R_MASKLEVEL_LSBMASK (0x00000001)
+#define ODN_PDP_OPMASK_R_MASKLEVEL_SHIFT (31)
+#define ODN_PDP_OPMASK_R_MASKLEVEL_LENGTH (1)
+#define ODN_PDP_OPMASK_R_MASKLEVEL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, OPMASK_R, BLANKLEVEL
+*/
+#define ODN_PDP_OPMASK_R_BLANKLEVEL_MASK (0x40000000)
+#define ODN_PDP_OPMASK_R_BLANKLEVEL_LSBMASK (0x00000001)
+#define ODN_PDP_OPMASK_R_BLANKLEVEL_SHIFT (30)
+#define ODN_PDP_OPMASK_R_BLANKLEVEL_LENGTH (1)
+#define ODN_PDP_OPMASK_R_BLANKLEVEL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, OPMASK_R, MASKR
+*/
+#define ODN_PDP_OPMASK_R_MASKR_MASK (0x000003FF)
+#define ODN_PDP_OPMASK_R_MASKR_LSBMASK (0x000003FF)
+#define ODN_PDP_OPMASK_R_MASKR_SHIFT (0)
+#define ODN_PDP_OPMASK_R_MASKR_LENGTH (10)
+#define ODN_PDP_OPMASK_R_MASKR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_OPMASK_GB_OFFSET (0x08CC)
+
+/* PDP, OPMASK_GB, MASKG
+*/
+#define ODN_PDP_OPMASK_GB_MASKG_MASK (0x03FF0000)
+#define ODN_PDP_OPMASK_GB_MASKG_LSBMASK (0x000003FF)
+#define ODN_PDP_OPMASK_GB_MASKG_SHIFT (16)
+#define ODN_PDP_OPMASK_GB_MASKG_LENGTH (10)
+#define ODN_PDP_OPMASK_GB_MASKG_SIGNED_FIELD IMG_FALSE
+
+/* PDP, OPMASK_GB, MASKB
+*/
+#define ODN_PDP_OPMASK_GB_MASKB_MASK (0x000003FF)
+#define ODN_PDP_OPMASK_GB_MASKB_LSBMASK (0x000003FF)
+#define ODN_PDP_OPMASK_GB_MASKB_SHIFT (0)
+#define ODN_PDP_OPMASK_GB_MASKB_LENGTH (10)
+#define ODN_PDP_OPMASK_GB_MASKB_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_REGLD_ADDR_CTRL_OFFSET (0x08D0)
+
+/* PDP, REGLD_ADDR_CTRL, REGLD_ADDRIN
+*/
+#define ODN_PDP_REGLD_ADDR_CTRL_REGLD_ADDRIN_MASK (0xFFFFFFF0)
+#define ODN_PDP_REGLD_ADDR_CTRL_REGLD_ADDRIN_LSBMASK (0x0FFFFFFF)
+#define ODN_PDP_REGLD_ADDR_CTRL_REGLD_ADDRIN_SHIFT (4)
+#define ODN_PDP_REGLD_ADDR_CTRL_REGLD_ADDRIN_LENGTH (28)
+#define ODN_PDP_REGLD_ADDR_CTRL_REGLD_ADDRIN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_REGLD_ADDR_STAT_OFFSET (0x08D4)
+
+/* PDP, REGLD_ADDR_STAT, REGLD_ADDROUT
+*/
+#define ODN_PDP_REGLD_ADDR_STAT_REGLD_ADDROUT_MASK (0xFFFFFFF0)
+#define ODN_PDP_REGLD_ADDR_STAT_REGLD_ADDROUT_LSBMASK (0x0FFFFFFF)
+#define ODN_PDP_REGLD_ADDR_STAT_REGLD_ADDROUT_SHIFT (4)
+#define ODN_PDP_REGLD_ADDR_STAT_REGLD_ADDROUT_LENGTH (28)
+#define ODN_PDP_REGLD_ADDR_STAT_REGLD_ADDROUT_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_REGLD_STAT_OFFSET (0x08D8)
+
+/* PDP, REGLD_STAT, REGLD_ADDREN
+*/
+#define ODN_PDP_REGLD_STAT_REGLD_ADDREN_MASK (0x00800000)
+#define ODN_PDP_REGLD_STAT_REGLD_ADDREN_LSBMASK (0x00000001)
+#define ODN_PDP_REGLD_STAT_REGLD_ADDREN_SHIFT (23)
+#define ODN_PDP_REGLD_STAT_REGLD_ADDREN_LENGTH (1)
+#define ODN_PDP_REGLD_STAT_REGLD_ADDREN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_REGLD_CTRL_OFFSET (0x08DC)
+
+/* PDP, REGLD_CTRL, REGLD_ADDRLEN
+*/
+#define ODN_PDP_REGLD_CTRL_REGLD_ADDRLEN_MASK (0xFF000000)
+#define ODN_PDP_REGLD_CTRL_REGLD_ADDRLEN_LSBMASK (0x000000FF)
+#define ODN_PDP_REGLD_CTRL_REGLD_ADDRLEN_SHIFT (24)
+#define ODN_PDP_REGLD_CTRL_REGLD_ADDRLEN_LENGTH (8)
+#define ODN_PDP_REGLD_CTRL_REGLD_ADDRLEN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, REGLD_CTRL, REGLD_VAL
+*/
+#define ODN_PDP_REGLD_CTRL_REGLD_VAL_MASK (0x00800000)
+#define ODN_PDP_REGLD_CTRL_REGLD_VAL_LSBMASK (0x00000001)
+#define ODN_PDP_REGLD_CTRL_REGLD_VAL_SHIFT (23)
+#define ODN_PDP_REGLD_CTRL_REGLD_VAL_LENGTH (1)
+#define ODN_PDP_REGLD_CTRL_REGLD_VAL_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_UPDCTRL_OFFSET (0x08E0)
+
+/* PDP, UPDCTRL, UPDFIELD
+*/
+#define ODN_PDP_UPDCTRL_UPDFIELD_MASK (0x00000001)
+#define ODN_PDP_UPDCTRL_UPDFIELD_LSBMASK (0x00000001)
+#define ODN_PDP_UPDCTRL_UPDFIELD_SHIFT (0)
+#define ODN_PDP_UPDCTRL_UPDFIELD_LENGTH (1)
+#define ODN_PDP_UPDCTRL_UPDFIELD_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_INTCTRL_OFFSET (0x08E4)
+
+/* PDP, PVR_ODN_PDP_INTCTRL, HBLNK_LINE
+*/
+#define ODN_PDP_INTCTRL_HBLNK_LINE_MASK (0x00010000)
+#define ODN_PDP_INTCTRL_HBLNK_LINE_LSBMASK (0x00000001)
+#define ODN_PDP_INTCTRL_HBLNK_LINE_SHIFT (16)
+#define ODN_PDP_INTCTRL_HBLNK_LINE_LENGTH (1)
+#define ODN_PDP_INTCTRL_HBLNK_LINE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PVR_ODN_PDP_INTCTRL, HBLNK_LINENO
+*/
+#define ODN_PDP_INTCTRL_HBLNK_LINENO_MASK (0x00001FFF)
+#define ODN_PDP_INTCTRL_HBLNK_LINENO_LSBMASK (0x00001FFF)
+#define ODN_PDP_INTCTRL_HBLNK_LINENO_SHIFT (0)
+#define ODN_PDP_INTCTRL_HBLNK_LINENO_LENGTH (13)
+#define ODN_PDP_INTCTRL_HBLNK_LINENO_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_PDISETUP_OFFSET (0x0900)
+
+/* PDP, PDISETUP, PDI_BLNKLVL
+*/
+#define ODN_PDP_PDISETUP_PDI_BLNKLVL_MASK (0x00000040)
+#define ODN_PDP_PDISETUP_PDI_BLNKLVL_LSBMASK (0x00000001)
+#define ODN_PDP_PDISETUP_PDI_BLNKLVL_SHIFT (6)
+#define ODN_PDP_PDISETUP_PDI_BLNKLVL_LENGTH (1)
+#define ODN_PDP_PDISETUP_PDI_BLNKLVL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PDISETUP, PDI_BLNK
+*/
+#define ODN_PDP_PDISETUP_PDI_BLNK_MASK (0x00000020)
+#define ODN_PDP_PDISETUP_PDI_BLNK_LSBMASK (0x00000001)
+#define ODN_PDP_PDISETUP_PDI_BLNK_SHIFT (5)
+#define ODN_PDP_PDISETUP_PDI_BLNK_LENGTH (1)
+#define ODN_PDP_PDISETUP_PDI_BLNK_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PDISETUP, PDI_PWR
+*/
+#define ODN_PDP_PDISETUP_PDI_PWR_MASK (0x00000010)
+#define ODN_PDP_PDISETUP_PDI_PWR_LSBMASK (0x00000001)
+#define ODN_PDP_PDISETUP_PDI_PWR_SHIFT (4)
+#define ODN_PDP_PDISETUP_PDI_PWR_LENGTH (1)
+#define ODN_PDP_PDISETUP_PDI_PWR_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PDISETUP, PDI_EN
+*/
+#define ODN_PDP_PDISETUP_PDI_EN_MASK (0x00000008)
+#define ODN_PDP_PDISETUP_PDI_EN_LSBMASK (0x00000001)
+#define ODN_PDP_PDISETUP_PDI_EN_SHIFT (3)
+#define ODN_PDP_PDISETUP_PDI_EN_LENGTH (1)
+#define ODN_PDP_PDISETUP_PDI_EN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PDISETUP, PDI_GDEN
+*/
+#define ODN_PDP_PDISETUP_PDI_GDEN_MASK (0x00000004)
+#define ODN_PDP_PDISETUP_PDI_GDEN_LSBMASK (0x00000001)
+#define ODN_PDP_PDISETUP_PDI_GDEN_SHIFT (2)
+#define ODN_PDP_PDISETUP_PDI_GDEN_LENGTH (1)
+#define ODN_PDP_PDISETUP_PDI_GDEN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PDISETUP, PDI_NFEN
+*/
+#define ODN_PDP_PDISETUP_PDI_NFEN_MASK (0x00000002)
+#define ODN_PDP_PDISETUP_PDI_NFEN_LSBMASK (0x00000001)
+#define ODN_PDP_PDISETUP_PDI_NFEN_SHIFT (1)
+#define ODN_PDP_PDISETUP_PDI_NFEN_LENGTH (1)
+#define ODN_PDP_PDISETUP_PDI_NFEN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PDISETUP, PDI_CR
+*/
+#define ODN_PDP_PDISETUP_PDI_CR_MASK (0x00000001)
+#define ODN_PDP_PDISETUP_PDI_CR_LSBMASK (0x00000001)
+#define ODN_PDP_PDISETUP_PDI_CR_SHIFT (0)
+#define ODN_PDP_PDISETUP_PDI_CR_LENGTH (1)
+#define ODN_PDP_PDISETUP_PDI_CR_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_PDITIMING0_OFFSET (0x0904)
+
+/* PDP, PDITIMING0, PDI_PWRSVGD
+*/
+#define ODN_PDP_PDITIMING0_PDI_PWRSVGD_MASK (0x0F000000)
+#define ODN_PDP_PDITIMING0_PDI_PWRSVGD_LSBMASK (0x0000000F)
+#define ODN_PDP_PDITIMING0_PDI_PWRSVGD_SHIFT (24)
+#define ODN_PDP_PDITIMING0_PDI_PWRSVGD_LENGTH (4)
+#define ODN_PDP_PDITIMING0_PDI_PWRSVGD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PDITIMING0, PDI_LSDEL
+*/
+#define ODN_PDP_PDITIMING0_PDI_LSDEL_MASK (0x007F0000)
+#define ODN_PDP_PDITIMING0_PDI_LSDEL_LSBMASK (0x0000007F)
+#define ODN_PDP_PDITIMING0_PDI_LSDEL_SHIFT (16)
+#define ODN_PDP_PDITIMING0_PDI_LSDEL_LENGTH (7)
+#define ODN_PDP_PDITIMING0_PDI_LSDEL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PDITIMING0, PDI_PWRSV2GD2
+*/
+#define ODN_PDP_PDITIMING0_PDI_PWRSV2GD2_MASK (0x000003FF)
+#define ODN_PDP_PDITIMING0_PDI_PWRSV2GD2_LSBMASK (0x000003FF)
+#define ODN_PDP_PDITIMING0_PDI_PWRSV2GD2_SHIFT (0)
+#define ODN_PDP_PDITIMING0_PDI_PWRSV2GD2_LENGTH (10)
+#define ODN_PDP_PDITIMING0_PDI_PWRSV2GD2_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_PDITIMING1_OFFSET (0x0908)
+
+/* PDP, PDITIMING1, PDI_NLDEL
+*/
+#define ODN_PDP_PDITIMING1_PDI_NLDEL_MASK (0x000F0000)
+#define ODN_PDP_PDITIMING1_PDI_NLDEL_LSBMASK (0x0000000F)
+#define ODN_PDP_PDITIMING1_PDI_NLDEL_SHIFT (16)
+#define ODN_PDP_PDITIMING1_PDI_NLDEL_LENGTH (4)
+#define ODN_PDP_PDITIMING1_PDI_NLDEL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PDITIMING1, PDI_ACBDEL
+*/
+#define ODN_PDP_PDITIMING1_PDI_ACBDEL_MASK (0x000003FF)
+#define ODN_PDP_PDITIMING1_PDI_ACBDEL_LSBMASK (0x000003FF)
+#define ODN_PDP_PDITIMING1_PDI_ACBDEL_SHIFT (0)
+#define ODN_PDP_PDITIMING1_PDI_ACBDEL_LENGTH (10)
+#define ODN_PDP_PDITIMING1_PDI_ACBDEL_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_PDICOREID_OFFSET (0x090C)
+
+/* PDP, PDICOREID, PDI_GROUP_ID
+*/
+#define ODN_PDP_PDICOREID_PDI_GROUP_ID_MASK (0xFF000000)
+#define ODN_PDP_PDICOREID_PDI_GROUP_ID_LSBMASK (0x000000FF)
+#define ODN_PDP_PDICOREID_PDI_GROUP_ID_SHIFT (24)
+#define ODN_PDP_PDICOREID_PDI_GROUP_ID_LENGTH (8)
+#define ODN_PDP_PDICOREID_PDI_GROUP_ID_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PDICOREID, PDI_CORE_ID
+*/
+#define ODN_PDP_PDICOREID_PDI_CORE_ID_MASK (0x00FF0000)
+#define ODN_PDP_PDICOREID_PDI_CORE_ID_LSBMASK (0x000000FF)
+#define ODN_PDP_PDICOREID_PDI_CORE_ID_SHIFT (16)
+#define ODN_PDP_PDICOREID_PDI_CORE_ID_LENGTH (8)
+#define ODN_PDP_PDICOREID_PDI_CORE_ID_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PDICOREID, PDI_CONFIG_ID
+*/
+#define ODN_PDP_PDICOREID_PDI_CONFIG_ID_MASK (0x0000FFFF)
+#define ODN_PDP_PDICOREID_PDI_CONFIG_ID_LSBMASK (0x0000FFFF)
+#define ODN_PDP_PDICOREID_PDI_CONFIG_ID_SHIFT (0)
+#define ODN_PDP_PDICOREID_PDI_CONFIG_ID_LENGTH (16)
+#define ODN_PDP_PDICOREID_PDI_CONFIG_ID_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_PDICOREREV_OFFSET (0x0910)
+
+/* PDP, PDICOREREV, PDI_MAJOR_REV
+*/
+#define ODN_PDP_PDICOREREV_PDI_MAJOR_REV_MASK (0x00FF0000)
+#define ODN_PDP_PDICOREREV_PDI_MAJOR_REV_LSBMASK (0x000000FF)
+#define ODN_PDP_PDICOREREV_PDI_MAJOR_REV_SHIFT (16)
+#define ODN_PDP_PDICOREREV_PDI_MAJOR_REV_LENGTH (8)
+#define ODN_PDP_PDICOREREV_PDI_MAJOR_REV_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PDICOREREV, PDI_MINOR_REV
+*/
+#define ODN_PDP_PDICOREREV_PDI_MINOR_REV_MASK (0x0000FF00)
+#define ODN_PDP_PDICOREREV_PDI_MINOR_REV_LSBMASK (0x000000FF)
+#define ODN_PDP_PDICOREREV_PDI_MINOR_REV_SHIFT (8)
+#define ODN_PDP_PDICOREREV_PDI_MINOR_REV_LENGTH (8)
+#define ODN_PDP_PDICOREREV_PDI_MINOR_REV_SIGNED_FIELD IMG_FALSE
+
+/* PDP, PDICOREREV, PDI_MAINT_REV
+*/
+#define ODN_PDP_PDICOREREV_PDI_MAINT_REV_MASK (0x000000FF)
+#define ODN_PDP_PDICOREREV_PDI_MAINT_REV_LSBMASK (0x000000FF)
+#define ODN_PDP_PDICOREREV_PDI_MAINT_REV_SHIFT (0)
+#define ODN_PDP_PDICOREREV_PDI_MAINT_REV_LENGTH (8)
+#define ODN_PDP_PDICOREREV_PDI_MAINT_REV_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DITHERMATRIX2_OFFSET (0x0920)
+
+/* PDP, DITHERMATRIX2, DITHERMATRIX2X1Y1
+*/
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X1Y1_MASK (0x000000C0)
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X1Y1_LSBMASK (0x00000003)
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X1Y1_SHIFT (6)
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X1Y1_LENGTH (2)
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X1Y1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX2, DITHERMATRIX2X0Y1
+*/
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X0Y1_MASK (0x00000030)
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X0Y1_LSBMASK (0x00000003)
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X0Y1_SHIFT (4)
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X0Y1_LENGTH (2)
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X0Y1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX2, DITHERMATRIX2X1Y0
+*/
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X1Y0_MASK (0x0000000C)
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X1Y0_LSBMASK (0x00000003)
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X1Y0_SHIFT (2)
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X1Y0_LENGTH (2)
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X1Y0_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX2, DITHERMATRIX2X0Y0
+*/
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X0Y0_MASK (0x00000003)
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X0Y0_LSBMASK (0x00000003)
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X0Y0_SHIFT (0)
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X0Y0_LENGTH (2)
+#define ODN_PDP_DITHERMATRIX2_DITHERMATRIX2X0Y0_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DITHERMATRIX4_0_OFFSET (0x0924)
+
+/* PDP, DITHERMATRIX4_0, DITHERMATRIX4X3Y1
+*/
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X3Y1_MASK (0xF0000000)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X3Y1_LSBMASK (0x0000000F)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X3Y1_SHIFT (28)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X3Y1_LENGTH (4)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X3Y1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX4_0, DITHERMATRIX4X2Y1
+*/
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X2Y1_MASK (0x0F000000)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X2Y1_LSBMASK (0x0000000F)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X2Y1_SHIFT (24)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X2Y1_LENGTH (4)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X2Y1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX4_0, DITHERMATRIX4X1Y1
+*/
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X1Y1_MASK (0x00F00000)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X1Y1_LSBMASK (0x0000000F)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X1Y1_SHIFT (20)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X1Y1_LENGTH (4)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X1Y1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX4_0, DITHERMATRIX4X0Y1
+*/
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X0Y1_MASK (0x000F0000)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X0Y1_LSBMASK (0x0000000F)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X0Y1_SHIFT (16)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X0Y1_LENGTH (4)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X0Y1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX4_0, DITHERMATRIX4X3Y0
+*/
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X3Y0_MASK (0x0000F000)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X3Y0_LSBMASK (0x0000000F)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X3Y0_SHIFT (12)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X3Y0_LENGTH (4)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X3Y0_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX4_0, DITHERMATRIX4X2Y0
+*/
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X2Y0_MASK (0x00000F00)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X2Y0_LSBMASK (0x0000000F)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X2Y0_SHIFT (8)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X2Y0_LENGTH (4)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X2Y0_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX4_0, DITHERMATRIX4X1Y0
+*/
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X1Y0_MASK (0x000000F0)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X1Y0_LSBMASK (0x0000000F)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X1Y0_SHIFT (4)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X1Y0_LENGTH (4)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X1Y0_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX4_0, DITHERMATRIX4X0Y0
+*/
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X0Y0_MASK (0x0000000F)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X0Y0_LSBMASK (0x0000000F)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X0Y0_SHIFT (0)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X0Y0_LENGTH (4)
+#define ODN_PDP_DITHERMATRIX4_0_DITHERMATRIX4X0Y0_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DITHERMATRIX4_1_OFFSET (0x0928)
+
+/* PDP, DITHERMATRIX4_1, DITHERMATRIX4X3Y3
+*/
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X3Y3_MASK (0xF0000000)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X3Y3_LSBMASK (0x0000000F)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X3Y3_SHIFT (28)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X3Y3_LENGTH (4)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X3Y3_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX4_1, DITHERMATRIX4X2Y3
+*/
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X2Y3_MASK (0x0F000000)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X2Y3_LSBMASK (0x0000000F)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X2Y3_SHIFT (24)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X2Y3_LENGTH (4)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X2Y3_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX4_1, DITHERMATRIX4X1Y3
+*/
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X1Y3_MASK (0x00F00000)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X1Y3_LSBMASK (0x0000000F)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X1Y3_SHIFT (20)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X1Y3_LENGTH (4)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X1Y3_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX4_1, DITHERMATRIX4X0Y3
+*/
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X0Y3_MASK (0x000F0000)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X0Y3_LSBMASK (0x0000000F)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X0Y3_SHIFT (16)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X0Y3_LENGTH (4)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X0Y3_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX4_1, DITHERMATRIX4X3Y2
+*/
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X3Y2_MASK (0x0000F000)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X3Y2_LSBMASK (0x0000000F)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X3Y2_SHIFT (12)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X3Y2_LENGTH (4)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X3Y2_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX4_1, DITHERMATRIX4X2Y2
+*/
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X2Y2_MASK (0x00000F00)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X2Y2_LSBMASK (0x0000000F)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X2Y2_SHIFT (8)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X2Y2_LENGTH (4)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X2Y2_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX4_1, DITHERMATRIX4X1Y2
+*/
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X1Y2_MASK (0x000000F0)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X1Y2_LSBMASK (0x0000000F)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X1Y2_SHIFT (4)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X1Y2_LENGTH (4)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X1Y2_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX4_1, DITHERMATRIX4X0Y2
+*/
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X0Y2_MASK (0x0000000F)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X0Y2_LSBMASK (0x0000000F)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X0Y2_SHIFT (0)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X0Y2_LENGTH (4)
+#define ODN_PDP_DITHERMATRIX4_1_DITHERMATRIX4X0Y2_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DITHERMATRIX8_0_OFFSET (0x092C)
+
+/* PDP, DITHERMATRIX8_0, DITHERMATRIX8X4Y0
+*/
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X4Y0_MASK (0x3F000000)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X4Y0_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X4Y0_SHIFT (24)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X4Y0_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X4Y0_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_0, DITHERMATRIX8X3Y0
+*/
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X3Y0_MASK (0x00FC0000)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X3Y0_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X3Y0_SHIFT (18)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X3Y0_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X3Y0_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_0, DITHERMATRIX8X2Y0
+*/
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X2Y0_MASK (0x0003F000)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X2Y0_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X2Y0_SHIFT (12)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X2Y0_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X2Y0_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_0, DITHERMATRIX8X1Y0
+*/
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X1Y0_MASK (0x00000FC0)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X1Y0_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X1Y0_SHIFT (6)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X1Y0_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X1Y0_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_0, DITHERMATRIX8X0Y0
+*/
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X0Y0_MASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X0Y0_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X0Y0_SHIFT (0)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X0Y0_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_0_DITHERMATRIX8X0Y0_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DITHERMATRIX8_1_OFFSET (0x0930)
+
+/* PDP, DITHERMATRIX8_1, DITHERMATRIX8X1Y1
+*/
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X1Y1_MASK (0x3F000000)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X1Y1_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X1Y1_SHIFT (24)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X1Y1_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X1Y1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_1, DITHERMATRIX8X0Y1
+*/
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X0Y1_MASK (0x00FC0000)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X0Y1_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X0Y1_SHIFT (18)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X0Y1_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X0Y1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_1, DITHERMATRIX8X7Y0
+*/
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X7Y0_MASK (0x0003F000)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X7Y0_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X7Y0_SHIFT (12)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X7Y0_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X7Y0_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_1, DITHERMATRIX8X6Y0
+*/
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X6Y0_MASK (0x00000FC0)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X6Y0_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X6Y0_SHIFT (6)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X6Y0_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X6Y0_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_1, DITHERMATRIX8X5Y0
+*/
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X5Y0_MASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X5Y0_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X5Y0_SHIFT (0)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X5Y0_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_1_DITHERMATRIX8X5Y0_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DITHERMATRIX8_2_OFFSET (0x0934)
+
+/* PDP, DITHERMATRIX8_2, DITHERMATRIX8X6Y1
+*/
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X6Y1_MASK (0x3F000000)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X6Y1_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X6Y1_SHIFT (24)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X6Y1_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X6Y1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_2, DITHERMATRIX8X5Y1
+*/
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X5Y1_MASK (0x00FC0000)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X5Y1_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X5Y1_SHIFT (18)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X5Y1_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X5Y1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_2, DITHERMATRIX8X4Y1
+*/
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X4Y1_MASK (0x0003F000)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X4Y1_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X4Y1_SHIFT (12)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X4Y1_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X4Y1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_2, DITHERMATRIX8X3Y1
+*/
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X3Y1_MASK (0x00000FC0)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X3Y1_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X3Y1_SHIFT (6)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X3Y1_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X3Y1_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_2, DITHERMATRIX8X2Y1
+*/
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X2Y1_MASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X2Y1_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X2Y1_SHIFT (0)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X2Y1_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_2_DITHERMATRIX8X2Y1_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DITHERMATRIX8_3_OFFSET (0x0938)
+
+/* PDP, DITHERMATRIX8_3, DITHERMATRIX8X3Y2
+*/
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X3Y2_MASK (0x3F000000)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X3Y2_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X3Y2_SHIFT (24)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X3Y2_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X3Y2_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_3, DITHERMATRIX8X2Y2
+*/
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X2Y2_MASK (0x00FC0000)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X2Y2_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X2Y2_SHIFT (18)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X2Y2_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X2Y2_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_3, DITHERMATRIX8X1Y2
+*/
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X1Y2_MASK (0x0003F000)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X1Y2_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X1Y2_SHIFT (12)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X1Y2_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X1Y2_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_3, DITHERMATRIX8X0Y2
+*/
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X0Y2_MASK (0x00000FC0)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X0Y2_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X0Y2_SHIFT (6)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X0Y2_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X0Y2_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_3, DITHERMATRIX8X7Y1
+*/
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X7Y1_MASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X7Y1_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X7Y1_SHIFT (0)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X7Y1_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_3_DITHERMATRIX8X7Y1_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DITHERMATRIX8_4_OFFSET (0x093C)
+
+/* PDP, DITHERMATRIX8_4, DITHERMATRIX8X0Y3
+*/
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X0Y3_MASK (0x3F000000)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X0Y3_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X0Y3_SHIFT (24)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X0Y3_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X0Y3_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_4, DITHERMATRIX8X7Y2
+*/
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X7Y2_MASK (0x00FC0000)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X7Y2_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X7Y2_SHIFT (18)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X7Y2_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X7Y2_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_4, DITHERMATRIX8X6Y2
+*/
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X6Y2_MASK (0x0003F000)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X6Y2_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X6Y2_SHIFT (12)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X6Y2_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X6Y2_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_4, DITHERMATRIX8X5Y2
+*/
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X5Y2_MASK (0x00000FC0)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X5Y2_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X5Y2_SHIFT (6)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X5Y2_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X5Y2_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_4, DITHERMATRIX8X4Y2
+*/
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X4Y2_MASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X4Y2_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X4Y2_SHIFT (0)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X4Y2_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_4_DITHERMATRIX8X4Y2_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DITHERMATRIX8_5_OFFSET (0x0940)
+
+/* PDP, DITHERMATRIX8_5, DITHERMATRIX8X5Y3
+*/
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X5Y3_MASK (0x3F000000)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X5Y3_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X5Y3_SHIFT (24)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X5Y3_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X5Y3_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_5, DITHERMATRIX8X4Y3
+*/
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X4Y3_MASK (0x00FC0000)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X4Y3_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X4Y3_SHIFT (18)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X4Y3_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X4Y3_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_5, DITHERMATRIX8X3Y3
+*/
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X3Y3_MASK (0x0003F000)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X3Y3_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X3Y3_SHIFT (12)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X3Y3_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X3Y3_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_5, DITHERMATRIX8X2Y3
+*/
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X2Y3_MASK (0x00000FC0)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X2Y3_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X2Y3_SHIFT (6)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X2Y3_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X2Y3_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_5, DITHERMATRIX8X1Y3
+*/
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X1Y3_MASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X1Y3_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X1Y3_SHIFT (0)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X1Y3_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_5_DITHERMATRIX8X1Y3_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DITHERMATRIX8_6_OFFSET (0x0944)
+
+/* PDP, DITHERMATRIX8_6, DITHERMATRIX8X2Y4
+*/
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X2Y4_MASK (0x3F000000)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X2Y4_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X2Y4_SHIFT (24)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X2Y4_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X2Y4_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_6, DITHERMATRIX8X1Y4
+*/
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X1Y4_MASK (0x00FC0000)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X1Y4_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X1Y4_SHIFT (18)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X1Y4_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X1Y4_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_6, DITHERMATRIX8X0Y4
+*/
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X0Y4_MASK (0x0003F000)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X0Y4_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X0Y4_SHIFT (12)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X0Y4_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X0Y4_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_6, DITHERMATRIX8X7Y3
+*/
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X7Y3_MASK (0x00000FC0)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X7Y3_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X7Y3_SHIFT (6)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X7Y3_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X7Y3_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_6, DITHERMATRIX8X6Y3
+*/
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X6Y3_MASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X6Y3_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X6Y3_SHIFT (0)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X6Y3_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_6_DITHERMATRIX8X6Y3_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DITHERMATRIX8_7_OFFSET (0x0948)
+
+/* PDP, DITHERMATRIX8_7, DITHERMATRIX8X7Y4
+*/
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X7Y4_MASK (0x3F000000)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X7Y4_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X7Y4_SHIFT (24)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X7Y4_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X7Y4_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_7, DITHERMATRIX8X6Y4
+*/
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X6Y4_MASK (0x00FC0000)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X6Y4_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X6Y4_SHIFT (18)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X6Y4_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X6Y4_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_7, DITHERMATRIX8X5Y4
+*/
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X5Y4_MASK (0x0003F000)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X5Y4_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X5Y4_SHIFT (12)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X5Y4_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X5Y4_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_7, DITHERMATRIX8X4Y4
+*/
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X4Y4_MASK (0x00000FC0)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X4Y4_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X4Y4_SHIFT (6)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X4Y4_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X4Y4_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_7, DITHERMATRIX8X3Y4
+*/
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X3Y4_MASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X3Y4_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X3Y4_SHIFT (0)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X3Y4_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_7_DITHERMATRIX8X3Y4_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DITHERMATRIX8_8_OFFSET (0x094C)
+
+/* PDP, DITHERMATRIX8_8, DITHERMATRIX8X4Y5
+*/
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X4Y5_MASK (0x3F000000)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X4Y5_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X4Y5_SHIFT (24)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X4Y5_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X4Y5_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_8, DITHERMATRIX8X3Y5
+*/
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X3Y5_MASK (0x00FC0000)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X3Y5_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X3Y5_SHIFT (18)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X3Y5_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X3Y5_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_8, DITHERMATRIX8X2Y5
+*/
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X2Y5_MASK (0x0003F000)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X2Y5_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X2Y5_SHIFT (12)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X2Y5_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X2Y5_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_8, DITHERMATRIX8X1Y5
+*/
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X1Y5_MASK (0x00000FC0)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X1Y5_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X1Y5_SHIFT (6)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X1Y5_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X1Y5_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_8, DITHERMATRIX8X0Y5
+*/
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X0Y5_MASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X0Y5_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X0Y5_SHIFT (0)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X0Y5_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_8_DITHERMATRIX8X0Y5_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DITHERMATRIX8_9_OFFSET (0x0950)
+
+/* PDP, DITHERMATRIX8_9, DITHERMATRIX8X1Y6
+*/
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X1Y6_MASK (0x3F000000)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X1Y6_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X1Y6_SHIFT (24)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X1Y6_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X1Y6_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_9, DITHERMATRIX8X0Y6
+*/
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X0Y6_MASK (0x00FC0000)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X0Y6_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X0Y6_SHIFT (18)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X0Y6_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X0Y6_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_9, DITHERMATRIX8X7Y5
+*/
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X7Y5_MASK (0x0003F000)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X7Y5_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X7Y5_SHIFT (12)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X7Y5_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X7Y5_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_9, DITHERMATRIX8X6Y5
+*/
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X6Y5_MASK (0x00000FC0)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X6Y5_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X6Y5_SHIFT (6)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X6Y5_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X6Y5_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_9, DITHERMATRIX8X5Y5
+*/
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X5Y5_MASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X5Y5_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X5Y5_SHIFT (0)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X5Y5_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_9_DITHERMATRIX8X5Y5_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DITHERMATRIX8_10_OFFSET (0x0954)
+
+/* PDP, DITHERMATRIX8_10, DITHERMATRIX8X6Y6
+*/
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X6Y6_MASK (0x3F000000)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X6Y6_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X6Y6_SHIFT (24)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X6Y6_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X6Y6_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_10, DITHERMATRIX8X5Y6
+*/
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X5Y6_MASK (0x00FC0000)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X5Y6_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X5Y6_SHIFT (18)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X5Y6_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X5Y6_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_10, DITHERMATRIX8X4Y6
+*/
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X4Y6_MASK (0x0003F000)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X4Y6_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X4Y6_SHIFT (12)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X4Y6_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X4Y6_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_10, DITHERMATRIX8X3Y6
+*/
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X3Y6_MASK (0x00000FC0)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X3Y6_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X3Y6_SHIFT (6)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X3Y6_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X3Y6_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_10, DITHERMATRIX8X2Y6
+*/
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X2Y6_MASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X2Y6_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X2Y6_SHIFT (0)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X2Y6_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_10_DITHERMATRIX8X2Y6_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DITHERMATRIX8_11_OFFSET (0x0958)
+
+/* PDP, DITHERMATRIX8_11, DITHERMATRIX8X3Y7
+*/
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X3Y7_MASK (0x3F000000)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X3Y7_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X3Y7_SHIFT (24)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X3Y7_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X3Y7_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_11, DITHERMATRIX8X2Y7
+*/
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X2Y7_MASK (0x00FC0000)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X2Y7_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X2Y7_SHIFT (18)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X2Y7_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X2Y7_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_11, DITHERMATRIX8X1Y7
+*/
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X1Y7_MASK (0x0003F000)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X1Y7_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X1Y7_SHIFT (12)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X1Y7_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X1Y7_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_11, DITHERMATRIX8X0Y7
+*/
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X0Y7_MASK (0x00000FC0)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X0Y7_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X0Y7_SHIFT (6)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X0Y7_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X0Y7_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_11, DITHERMATRIX8X7Y6
+*/
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X7Y6_MASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X7Y6_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X7Y6_SHIFT (0)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X7Y6_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_11_DITHERMATRIX8X7Y6_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_DITHERMATRIX8_12_OFFSET (0x095C)
+
+/* PDP, DITHERMATRIX8_12, DITHERMATRIX8X7Y7
+*/
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X7Y7_MASK (0x00FC0000)
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X7Y7_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X7Y7_SHIFT (18)
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X7Y7_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X7Y7_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_12, DITHERMATRIX8X6Y7
+*/
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X6Y7_MASK (0x0003F000)
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X6Y7_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X6Y7_SHIFT (12)
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X6Y7_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X6Y7_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_12, DITHERMATRIX8X5Y7
+*/
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X5Y7_MASK (0x00000FC0)
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X5Y7_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X5Y7_SHIFT (6)
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X5Y7_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X5Y7_SIGNED_FIELD IMG_FALSE
+
+/* PDP, DITHERMATRIX8_12, DITHERMATRIX8X4Y7
+*/
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X4Y7_MASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X4Y7_LSBMASK (0x0000003F)
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X4Y7_SHIFT (0)
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X4Y7_LENGTH (6)
+#define ODN_PDP_DITHERMATRIX8_12_DITHERMATRIX8X4Y7_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH1_MEMCTRL_OFFSET (0x0960)
+
+/* PDP, GRPH1_MEMCTRL, GRPH1_LOCAL_GLOBAL_MEMCTRL
+*/
+#define ODN_PDP_GRPH1_MEMCTRL_GRPH1_LOCAL_GLOBAL_MEMCTRL_MASK (0x80000000)
+#define ODN_PDP_GRPH1_MEMCTRL_GRPH1_LOCAL_GLOBAL_MEMCTRL_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH1_MEMCTRL_GRPH1_LOCAL_GLOBAL_MEMCTRL_SHIFT (31)
+#define ODN_PDP_GRPH1_MEMCTRL_GRPH1_LOCAL_GLOBAL_MEMCTRL_LENGTH (1)
+#define ODN_PDP_GRPH1_MEMCTRL_GRPH1_LOCAL_GLOBAL_MEMCTRL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1_MEMCTRL, GRPH1_BURSTLEN
+*/
+#define ODN_PDP_GRPH1_MEMCTRL_GRPH1_BURSTLEN_MASK (0x000000FF)
+#define ODN_PDP_GRPH1_MEMCTRL_GRPH1_BURSTLEN_LSBMASK (0x000000FF)
+#define ODN_PDP_GRPH1_MEMCTRL_GRPH1_BURSTLEN_SHIFT (0)
+#define ODN_PDP_GRPH1_MEMCTRL_GRPH1_BURSTLEN_LENGTH (8)
+#define ODN_PDP_GRPH1_MEMCTRL_GRPH1_BURSTLEN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH1_MEM_THRESH_OFFSET (0x0964)
+
+/* PDP, GRPH1_MEM_THRESH, GRPH1_UVTHRESHOLD
+*/
+#define ODN_PDP_GRPH1_MEM_THRESH_GRPH1_UVTHRESHOLD_MASK (0xFF000000)
+#define ODN_PDP_GRPH1_MEM_THRESH_GRPH1_UVTHRESHOLD_LSBMASK (0x000000FF)
+#define ODN_PDP_GRPH1_MEM_THRESH_GRPH1_UVTHRESHOLD_SHIFT (24)
+#define ODN_PDP_GRPH1_MEM_THRESH_GRPH1_UVTHRESHOLD_LENGTH (8)
+#define ODN_PDP_GRPH1_MEM_THRESH_GRPH1_UVTHRESHOLD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1_MEM_THRESH, GRPH1_YTHRESHOLD
+*/
+#define ODN_PDP_GRPH1_MEM_THRESH_GRPH1_YTHRESHOLD_MASK (0x001FF000)
+#define ODN_PDP_GRPH1_MEM_THRESH_GRPH1_YTHRESHOLD_LSBMASK (0x000001FF)
+#define ODN_PDP_GRPH1_MEM_THRESH_GRPH1_YTHRESHOLD_SHIFT (12)
+#define ODN_PDP_GRPH1_MEM_THRESH_GRPH1_YTHRESHOLD_LENGTH (9)
+#define ODN_PDP_GRPH1_MEM_THRESH_GRPH1_YTHRESHOLD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1_MEM_THRESH, GRPH1_THRESHOLD
+*/
+#define ODN_PDP_GRPH1_MEM_THRESH_GRPH1_THRESHOLD_MASK (0x000001FF)
+#define ODN_PDP_GRPH1_MEM_THRESH_GRPH1_THRESHOLD_LSBMASK (0x000001FF)
+#define ODN_PDP_GRPH1_MEM_THRESH_GRPH1_THRESHOLD_SHIFT (0)
+#define ODN_PDP_GRPH1_MEM_THRESH_GRPH1_THRESHOLD_LENGTH (9)
+#define ODN_PDP_GRPH1_MEM_THRESH_GRPH1_THRESHOLD_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH2_MEMCTRL_OFFSET (0x0968)
+
+/* PDP, GRPH2_MEMCTRL, GRPH2_LOCAL_GLOBAL_MEMCTRL
+*/
+#define ODN_PDP_GRPH2_MEMCTRL_GRPH2_LOCAL_GLOBAL_MEMCTRL_MASK (0x80000000)
+#define ODN_PDP_GRPH2_MEMCTRL_GRPH2_LOCAL_GLOBAL_MEMCTRL_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH2_MEMCTRL_GRPH2_LOCAL_GLOBAL_MEMCTRL_SHIFT (31)
+#define ODN_PDP_GRPH2_MEMCTRL_GRPH2_LOCAL_GLOBAL_MEMCTRL_LENGTH (1)
+#define ODN_PDP_GRPH2_MEMCTRL_GRPH2_LOCAL_GLOBAL_MEMCTRL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2_MEMCTRL, GRPH2_BURSTLEN
+*/
+#define ODN_PDP_GRPH2_MEMCTRL_GRPH2_BURSTLEN_MASK (0x000000FF)
+#define ODN_PDP_GRPH2_MEMCTRL_GRPH2_BURSTLEN_LSBMASK (0x000000FF)
+#define ODN_PDP_GRPH2_MEMCTRL_GRPH2_BURSTLEN_SHIFT (0)
+#define ODN_PDP_GRPH2_MEMCTRL_GRPH2_BURSTLEN_LENGTH (8)
+#define ODN_PDP_GRPH2_MEMCTRL_GRPH2_BURSTLEN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH2_MEM_THRESH_OFFSET (0x096C)
+
+/* PDP, GRPH2_MEM_THRESH, GRPH2_UVTHRESHOLD
+*/
+#define ODN_PDP_GRPH2_MEM_THRESH_GRPH2_UVTHRESHOLD_MASK (0xFF000000)
+#define ODN_PDP_GRPH2_MEM_THRESH_GRPH2_UVTHRESHOLD_LSBMASK (0x000000FF)
+#define ODN_PDP_GRPH2_MEM_THRESH_GRPH2_UVTHRESHOLD_SHIFT (24)
+#define ODN_PDP_GRPH2_MEM_THRESH_GRPH2_UVTHRESHOLD_LENGTH (8)
+#define ODN_PDP_GRPH2_MEM_THRESH_GRPH2_UVTHRESHOLD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2_MEM_THRESH, GRPH2_YTHRESHOLD
+*/
+#define ODN_PDP_GRPH2_MEM_THRESH_GRPH2_YTHRESHOLD_MASK (0x001FF000)
+#define ODN_PDP_GRPH2_MEM_THRESH_GRPH2_YTHRESHOLD_LSBMASK (0x000001FF)
+#define ODN_PDP_GRPH2_MEM_THRESH_GRPH2_YTHRESHOLD_SHIFT (12)
+#define ODN_PDP_GRPH2_MEM_THRESH_GRPH2_YTHRESHOLD_LENGTH (9)
+#define ODN_PDP_GRPH2_MEM_THRESH_GRPH2_YTHRESHOLD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2_MEM_THRESH, GRPH2_THRESHOLD
+*/
+#define ODN_PDP_GRPH2_MEM_THRESH_GRPH2_THRESHOLD_MASK (0x000001FF)
+#define ODN_PDP_GRPH2_MEM_THRESH_GRPH2_THRESHOLD_LSBMASK (0x000001FF)
+#define ODN_PDP_GRPH2_MEM_THRESH_GRPH2_THRESHOLD_SHIFT (0)
+#define ODN_PDP_GRPH2_MEM_THRESH_GRPH2_THRESHOLD_LENGTH (9)
+#define ODN_PDP_GRPH2_MEM_THRESH_GRPH2_THRESHOLD_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH3_MEMCTRL_OFFSET (0x0970)
+
+/* PDP, GRPH3_MEMCTRL, GRPH3_LOCAL_GLOBAL_MEMCTRL
+*/
+#define ODN_PDP_GRPH3_MEMCTRL_GRPH3_LOCAL_GLOBAL_MEMCTRL_MASK (0x80000000)
+#define ODN_PDP_GRPH3_MEMCTRL_GRPH3_LOCAL_GLOBAL_MEMCTRL_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH3_MEMCTRL_GRPH3_LOCAL_GLOBAL_MEMCTRL_SHIFT (31)
+#define ODN_PDP_GRPH3_MEMCTRL_GRPH3_LOCAL_GLOBAL_MEMCTRL_LENGTH (1)
+#define ODN_PDP_GRPH3_MEMCTRL_GRPH3_LOCAL_GLOBAL_MEMCTRL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3_MEMCTRL, GRPH3_BURSTLEN
+*/
+#define ODN_PDP_GRPH3_MEMCTRL_GRPH3_BURSTLEN_MASK (0x000000FF)
+#define ODN_PDP_GRPH3_MEMCTRL_GRPH3_BURSTLEN_LSBMASK (0x000000FF)
+#define ODN_PDP_GRPH3_MEMCTRL_GRPH3_BURSTLEN_SHIFT (0)
+#define ODN_PDP_GRPH3_MEMCTRL_GRPH3_BURSTLEN_LENGTH (8)
+#define ODN_PDP_GRPH3_MEMCTRL_GRPH3_BURSTLEN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH3_MEM_THRESH_OFFSET (0x0974)
+
+/* PDP, GRPH3_MEM_THRESH, GRPH3_UVTHRESHOLD
+*/
+#define ODN_PDP_GRPH3_MEM_THRESH_GRPH3_UVTHRESHOLD_MASK (0xFF000000)
+#define ODN_PDP_GRPH3_MEM_THRESH_GRPH3_UVTHRESHOLD_LSBMASK (0x000000FF)
+#define ODN_PDP_GRPH3_MEM_THRESH_GRPH3_UVTHRESHOLD_SHIFT (24)
+#define ODN_PDP_GRPH3_MEM_THRESH_GRPH3_UVTHRESHOLD_LENGTH (8)
+#define ODN_PDP_GRPH3_MEM_THRESH_GRPH3_UVTHRESHOLD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3_MEM_THRESH, GRPH3_YTHRESHOLD
+*/
+#define ODN_PDP_GRPH3_MEM_THRESH_GRPH3_YTHRESHOLD_MASK (0x001FF000)
+#define ODN_PDP_GRPH3_MEM_THRESH_GRPH3_YTHRESHOLD_LSBMASK (0x000001FF)
+#define ODN_PDP_GRPH3_MEM_THRESH_GRPH3_YTHRESHOLD_SHIFT (12)
+#define ODN_PDP_GRPH3_MEM_THRESH_GRPH3_YTHRESHOLD_LENGTH (9)
+#define ODN_PDP_GRPH3_MEM_THRESH_GRPH3_YTHRESHOLD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3_MEM_THRESH, GRPH3_THRESHOLD
+*/
+#define ODN_PDP_GRPH3_MEM_THRESH_GRPH3_THRESHOLD_MASK (0x000001FF)
+#define ODN_PDP_GRPH3_MEM_THRESH_GRPH3_THRESHOLD_LSBMASK (0x000001FF)
+#define ODN_PDP_GRPH3_MEM_THRESH_GRPH3_THRESHOLD_SHIFT (0)
+#define ODN_PDP_GRPH3_MEM_THRESH_GRPH3_THRESHOLD_LENGTH (9)
+#define ODN_PDP_GRPH3_MEM_THRESH_GRPH3_THRESHOLD_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH4_MEMCTRL_OFFSET (0x0978)
+
+/* PDP, GRPH4_MEMCTRL, GRPH4_LOCAL_GLOBAL_MEMCTRL
+*/
+#define ODN_PDP_GRPH4_MEMCTRL_GRPH4_LOCAL_GLOBAL_MEMCTRL_MASK (0x80000000)
+#define ODN_PDP_GRPH4_MEMCTRL_GRPH4_LOCAL_GLOBAL_MEMCTRL_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH4_MEMCTRL_GRPH4_LOCAL_GLOBAL_MEMCTRL_SHIFT (31)
+#define ODN_PDP_GRPH4_MEMCTRL_GRPH4_LOCAL_GLOBAL_MEMCTRL_LENGTH (1)
+#define ODN_PDP_GRPH4_MEMCTRL_GRPH4_LOCAL_GLOBAL_MEMCTRL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4_MEMCTRL, GRPH4_BURSTLEN
+*/
+#define ODN_PDP_GRPH4_MEMCTRL_GRPH4_BURSTLEN_MASK (0x000000FF)
+#define ODN_PDP_GRPH4_MEMCTRL_GRPH4_BURSTLEN_LSBMASK (0x000000FF)
+#define ODN_PDP_GRPH4_MEMCTRL_GRPH4_BURSTLEN_SHIFT (0)
+#define ODN_PDP_GRPH4_MEMCTRL_GRPH4_BURSTLEN_LENGTH (8)
+#define ODN_PDP_GRPH4_MEMCTRL_GRPH4_BURSTLEN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH4_MEM_THRESH_OFFSET (0x097C)
+
+/* PDP, GRPH4_MEM_THRESH, GRPH4_UVTHRESHOLD
+*/
+#define ODN_PDP_GRPH4_MEM_THRESH_GRPH4_UVTHRESHOLD_MASK (0xFF000000)
+#define ODN_PDP_GRPH4_MEM_THRESH_GRPH4_UVTHRESHOLD_LSBMASK (0x000000FF)
+#define ODN_PDP_GRPH4_MEM_THRESH_GRPH4_UVTHRESHOLD_SHIFT (24)
+#define ODN_PDP_GRPH4_MEM_THRESH_GRPH4_UVTHRESHOLD_LENGTH (8)
+#define ODN_PDP_GRPH4_MEM_THRESH_GRPH4_UVTHRESHOLD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4_MEM_THRESH, GRPH4_YTHRESHOLD
+*/
+#define ODN_PDP_GRPH4_MEM_THRESH_GRPH4_YTHRESHOLD_MASK (0x001FF000)
+#define ODN_PDP_GRPH4_MEM_THRESH_GRPH4_YTHRESHOLD_LSBMASK (0x000001FF)
+#define ODN_PDP_GRPH4_MEM_THRESH_GRPH4_YTHRESHOLD_SHIFT (12)
+#define ODN_PDP_GRPH4_MEM_THRESH_GRPH4_YTHRESHOLD_LENGTH (9)
+#define ODN_PDP_GRPH4_MEM_THRESH_GRPH4_YTHRESHOLD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4_MEM_THRESH, GRPH4_THRESHOLD
+*/
+#define ODN_PDP_GRPH4_MEM_THRESH_GRPH4_THRESHOLD_MASK (0x000001FF)
+#define ODN_PDP_GRPH4_MEM_THRESH_GRPH4_THRESHOLD_LSBMASK (0x000001FF)
+#define ODN_PDP_GRPH4_MEM_THRESH_GRPH4_THRESHOLD_SHIFT (0)
+#define ODN_PDP_GRPH4_MEM_THRESH_GRPH4_THRESHOLD_LENGTH (9)
+#define ODN_PDP_GRPH4_MEM_THRESH_GRPH4_THRESHOLD_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1_MEMCTRL_OFFSET (0x0980)
+
+/* PDP, VID1_MEMCTRL, VID1_LOCAL_GLOBAL_MEMCTRL
+*/
+#define ODN_PDP_VID1_MEMCTRL_VID1_LOCAL_GLOBAL_MEMCTRL_MASK (0x80000000)
+#define ODN_PDP_VID1_MEMCTRL_VID1_LOCAL_GLOBAL_MEMCTRL_LSBMASK (0x00000001)
+#define ODN_PDP_VID1_MEMCTRL_VID1_LOCAL_GLOBAL_MEMCTRL_SHIFT (31)
+#define ODN_PDP_VID1_MEMCTRL_VID1_LOCAL_GLOBAL_MEMCTRL_LENGTH (1)
+#define ODN_PDP_VID1_MEMCTRL_VID1_LOCAL_GLOBAL_MEMCTRL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1_MEMCTRL, VID1_BURSTLEN
+*/
+#define ODN_PDP_VID1_MEMCTRL_VID1_BURSTLEN_MASK (0x000000FF)
+#define ODN_PDP_VID1_MEMCTRL_VID1_BURSTLEN_LSBMASK (0x000000FF)
+#define ODN_PDP_VID1_MEMCTRL_VID1_BURSTLEN_SHIFT (0)
+#define ODN_PDP_VID1_MEMCTRL_VID1_BURSTLEN_LENGTH (8)
+#define ODN_PDP_VID1_MEMCTRL_VID1_BURSTLEN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1_MEM_THRESH_OFFSET (0x0984)
+
+/* PDP, VID1_MEM_THRESH, VID1_UVTHRESHOLD
+*/
+#define ODN_PDP_VID1_MEM_THRESH_VID1_UVTHRESHOLD_MASK (0xFF000000)
+#define ODN_PDP_VID1_MEM_THRESH_VID1_UVTHRESHOLD_LSBMASK (0x000000FF)
+#define ODN_PDP_VID1_MEM_THRESH_VID1_UVTHRESHOLD_SHIFT (24)
+#define ODN_PDP_VID1_MEM_THRESH_VID1_UVTHRESHOLD_LENGTH (8)
+#define ODN_PDP_VID1_MEM_THRESH_VID1_UVTHRESHOLD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1_MEM_THRESH, VID1_YTHRESHOLD
+*/
+#define ODN_PDP_VID1_MEM_THRESH_VID1_YTHRESHOLD_MASK (0x001FF000)
+#define ODN_PDP_VID1_MEM_THRESH_VID1_YTHRESHOLD_LSBMASK (0x000001FF)
+#define ODN_PDP_VID1_MEM_THRESH_VID1_YTHRESHOLD_SHIFT (12)
+#define ODN_PDP_VID1_MEM_THRESH_VID1_YTHRESHOLD_LENGTH (9)
+#define ODN_PDP_VID1_MEM_THRESH_VID1_YTHRESHOLD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1_MEM_THRESH, VID1_THRESHOLD
+*/
+#define ODN_PDP_VID1_MEM_THRESH_VID1_THRESHOLD_MASK (0x000001FF)
+#define ODN_PDP_VID1_MEM_THRESH_VID1_THRESHOLD_LSBMASK (0x000001FF)
+#define ODN_PDP_VID1_MEM_THRESH_VID1_THRESHOLD_SHIFT (0)
+#define ODN_PDP_VID1_MEM_THRESH_VID1_THRESHOLD_LENGTH (9)
+#define ODN_PDP_VID1_MEM_THRESH_VID1_THRESHOLD_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2_MEMCTRL_OFFSET (0x0988)
+
+/* PDP, VID2_MEMCTRL, VID2_LOCAL_GLOBAL_MEMCTRL
+*/
+#define ODN_PDP_VID2_MEMCTRL_VID2_LOCAL_GLOBAL_MEMCTRL_MASK (0x80000000)
+#define ODN_PDP_VID2_MEMCTRL_VID2_LOCAL_GLOBAL_MEMCTRL_LSBMASK (0x00000001)
+#define ODN_PDP_VID2_MEMCTRL_VID2_LOCAL_GLOBAL_MEMCTRL_SHIFT (31)
+#define ODN_PDP_VID2_MEMCTRL_VID2_LOCAL_GLOBAL_MEMCTRL_LENGTH (1)
+#define ODN_PDP_VID2_MEMCTRL_VID2_LOCAL_GLOBAL_MEMCTRL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2_MEMCTRL, VID2_BURSTLEN
+*/
+#define ODN_PDP_VID2_MEMCTRL_VID2_BURSTLEN_MASK (0x000000FF)
+#define ODN_PDP_VID2_MEMCTRL_VID2_BURSTLEN_LSBMASK (0x000000FF)
+#define ODN_PDP_VID2_MEMCTRL_VID2_BURSTLEN_SHIFT (0)
+#define ODN_PDP_VID2_MEMCTRL_VID2_BURSTLEN_LENGTH (8)
+#define ODN_PDP_VID2_MEMCTRL_VID2_BURSTLEN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2_MEM_THRESH_OFFSET (0x098C)
+
+/* PDP, VID2_MEM_THRESH, VID2_UVTHRESHOLD
+*/
+#define ODN_PDP_VID2_MEM_THRESH_VID2_UVTHRESHOLD_MASK (0xFF000000)
+#define ODN_PDP_VID2_MEM_THRESH_VID2_UVTHRESHOLD_LSBMASK (0x000000FF)
+#define ODN_PDP_VID2_MEM_THRESH_VID2_UVTHRESHOLD_SHIFT (24)
+#define ODN_PDP_VID2_MEM_THRESH_VID2_UVTHRESHOLD_LENGTH (8)
+#define ODN_PDP_VID2_MEM_THRESH_VID2_UVTHRESHOLD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2_MEM_THRESH, VID2_YTHRESHOLD
+*/
+#define ODN_PDP_VID2_MEM_THRESH_VID2_YTHRESHOLD_MASK (0x001FF000)
+#define ODN_PDP_VID2_MEM_THRESH_VID2_YTHRESHOLD_LSBMASK (0x000001FF)
+#define ODN_PDP_VID2_MEM_THRESH_VID2_YTHRESHOLD_SHIFT (12)
+#define ODN_PDP_VID2_MEM_THRESH_VID2_YTHRESHOLD_LENGTH (9)
+#define ODN_PDP_VID2_MEM_THRESH_VID2_YTHRESHOLD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2_MEM_THRESH, VID2_THRESHOLD
+*/
+#define ODN_PDP_VID2_MEM_THRESH_VID2_THRESHOLD_MASK (0x000001FF)
+#define ODN_PDP_VID2_MEM_THRESH_VID2_THRESHOLD_LSBMASK (0x000001FF)
+#define ODN_PDP_VID2_MEM_THRESH_VID2_THRESHOLD_SHIFT (0)
+#define ODN_PDP_VID2_MEM_THRESH_VID2_THRESHOLD_LENGTH (9)
+#define ODN_PDP_VID2_MEM_THRESH_VID2_THRESHOLD_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3_MEMCTRL_OFFSET (0x0990)
+
+/* PDP, VID3_MEMCTRL, VID3_LOCAL_GLOBAL_MEMCTRL
+*/
+#define ODN_PDP_VID3_MEMCTRL_VID3_LOCAL_GLOBAL_MEMCTRL_MASK (0x80000000)
+#define ODN_PDP_VID3_MEMCTRL_VID3_LOCAL_GLOBAL_MEMCTRL_LSBMASK (0x00000001)
+#define ODN_PDP_VID3_MEMCTRL_VID3_LOCAL_GLOBAL_MEMCTRL_SHIFT (31)
+#define ODN_PDP_VID3_MEMCTRL_VID3_LOCAL_GLOBAL_MEMCTRL_LENGTH (1)
+#define ODN_PDP_VID3_MEMCTRL_VID3_LOCAL_GLOBAL_MEMCTRL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3_MEMCTRL, VID3_BURSTLEN
+*/
+#define ODN_PDP_VID3_MEMCTRL_VID3_BURSTLEN_MASK (0x000000FF)
+#define ODN_PDP_VID3_MEMCTRL_VID3_BURSTLEN_LSBMASK (0x000000FF)
+#define ODN_PDP_VID3_MEMCTRL_VID3_BURSTLEN_SHIFT (0)
+#define ODN_PDP_VID3_MEMCTRL_VID3_BURSTLEN_LENGTH (8)
+#define ODN_PDP_VID3_MEMCTRL_VID3_BURSTLEN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3_MEM_THRESH_OFFSET (0x0994)
+
+/* PDP, VID3_MEM_THRESH, VID3_UVTHRESHOLD
+*/
+#define ODN_PDP_VID3_MEM_THRESH_VID3_UVTHRESHOLD_MASK (0xFF000000)
+#define ODN_PDP_VID3_MEM_THRESH_VID3_UVTHRESHOLD_LSBMASK (0x000000FF)
+#define ODN_PDP_VID3_MEM_THRESH_VID3_UVTHRESHOLD_SHIFT (24)
+#define ODN_PDP_VID3_MEM_THRESH_VID3_UVTHRESHOLD_LENGTH (8)
+#define ODN_PDP_VID3_MEM_THRESH_VID3_UVTHRESHOLD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3_MEM_THRESH, VID3_YTHRESHOLD
+*/
+#define ODN_PDP_VID3_MEM_THRESH_VID3_YTHRESHOLD_MASK (0x001FF000)
+#define ODN_PDP_VID3_MEM_THRESH_VID3_YTHRESHOLD_LSBMASK (0x000001FF)
+#define ODN_PDP_VID3_MEM_THRESH_VID3_YTHRESHOLD_SHIFT (12)
+#define ODN_PDP_VID3_MEM_THRESH_VID3_YTHRESHOLD_LENGTH (9)
+#define ODN_PDP_VID3_MEM_THRESH_VID3_YTHRESHOLD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3_MEM_THRESH, VID3_THRESHOLD
+*/
+#define ODN_PDP_VID3_MEM_THRESH_VID3_THRESHOLD_MASK (0x000001FF)
+#define ODN_PDP_VID3_MEM_THRESH_VID3_THRESHOLD_LSBMASK (0x000001FF)
+#define ODN_PDP_VID3_MEM_THRESH_VID3_THRESHOLD_SHIFT (0)
+#define ODN_PDP_VID3_MEM_THRESH_VID3_THRESHOLD_LENGTH (9)
+#define ODN_PDP_VID3_MEM_THRESH_VID3_THRESHOLD_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4_MEMCTRL_OFFSET (0x0998)
+
+/* PDP, VID4_MEMCTRL, VID4_LOCAL_GLOBAL_MEMCTRL
+*/
+#define ODN_PDP_VID4_MEMCTRL_VID4_LOCAL_GLOBAL_MEMCTRL_MASK (0x80000000)
+#define ODN_PDP_VID4_MEMCTRL_VID4_LOCAL_GLOBAL_MEMCTRL_LSBMASK (0x00000001)
+#define ODN_PDP_VID4_MEMCTRL_VID4_LOCAL_GLOBAL_MEMCTRL_SHIFT (31)
+#define ODN_PDP_VID4_MEMCTRL_VID4_LOCAL_GLOBAL_MEMCTRL_LENGTH (1)
+#define ODN_PDP_VID4_MEMCTRL_VID4_LOCAL_GLOBAL_MEMCTRL_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4_MEMCTRL, VID4_BURSTLEN
+*/
+#define ODN_PDP_VID4_MEMCTRL_VID4_BURSTLEN_MASK (0x000000FF)
+#define ODN_PDP_VID4_MEMCTRL_VID4_BURSTLEN_LSBMASK (0x000000FF)
+#define ODN_PDP_VID4_MEMCTRL_VID4_BURSTLEN_SHIFT (0)
+#define ODN_PDP_VID4_MEMCTRL_VID4_BURSTLEN_LENGTH (8)
+#define ODN_PDP_VID4_MEMCTRL_VID4_BURSTLEN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4_MEM_THRESH_OFFSET (0x099C)
+
+/* PDP, VID4_MEM_THRESH, VID4_UVTHRESHOLD
+*/
+#define ODN_PDP_VID4_MEM_THRESH_VID4_UVTHRESHOLD_MASK (0xFF000000)
+#define ODN_PDP_VID4_MEM_THRESH_VID4_UVTHRESHOLD_LSBMASK (0x000000FF)
+#define ODN_PDP_VID4_MEM_THRESH_VID4_UVTHRESHOLD_SHIFT (24)
+#define ODN_PDP_VID4_MEM_THRESH_VID4_UVTHRESHOLD_LENGTH (8)
+#define ODN_PDP_VID4_MEM_THRESH_VID4_UVTHRESHOLD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4_MEM_THRESH, VID4_YTHRESHOLD
+*/
+#define ODN_PDP_VID4_MEM_THRESH_VID4_YTHRESHOLD_MASK (0x001FF000)
+#define ODN_PDP_VID4_MEM_THRESH_VID4_YTHRESHOLD_LSBMASK (0x000001FF)
+#define ODN_PDP_VID4_MEM_THRESH_VID4_YTHRESHOLD_SHIFT (12)
+#define ODN_PDP_VID4_MEM_THRESH_VID4_YTHRESHOLD_LENGTH (9)
+#define ODN_PDP_VID4_MEM_THRESH_VID4_YTHRESHOLD_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4_MEM_THRESH, VID4_THRESHOLD
+*/
+#define ODN_PDP_VID4_MEM_THRESH_VID4_THRESHOLD_MASK (0x000001FF)
+#define ODN_PDP_VID4_MEM_THRESH_VID4_THRESHOLD_LSBMASK (0x000001FF)
+#define ODN_PDP_VID4_MEM_THRESH_VID4_THRESHOLD_SHIFT (0)
+#define ODN_PDP_VID4_MEM_THRESH_VID4_THRESHOLD_LENGTH (9)
+#define ODN_PDP_VID4_MEM_THRESH_VID4_THRESHOLD_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH1_PANIC_THRESH_OFFSET (0x09A0)
+
+/* PDP, GRPH1_PANIC_THRESH, GRPH1_ALERT_UV_ENABLE
+*/
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_UV_ENABLE_MASK (0x80000000)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_UV_ENABLE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_UV_ENABLE_SHIFT (31)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_UV_ENABLE_LENGTH (1)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_UV_ENABLE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1_PANIC_THRESH, GRPH1_ALERT_Y_ENABLE
+*/
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_Y_ENABLE_MASK (0x40000000)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_Y_ENABLE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_Y_ENABLE_SHIFT (30)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_Y_ENABLE_LENGTH (1)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_Y_ENABLE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1_PANIC_THRESH, GRPH1_ALERT_UV_THRESHOLD_MAX
+*/
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_UV_THRESHOLD_MAX_MASK (0x3F800000)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_UV_THRESHOLD_MAX_LSBMASK (0x0000007F)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_UV_THRESHOLD_MAX_SHIFT (23)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_UV_THRESHOLD_MAX_LENGTH (7)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_UV_THRESHOLD_MAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1_PANIC_THRESH, GRPH1_ALERT_UV_THRESHOLD_MIN
+*/
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_UV_THRESHOLD_MIN_MASK (0x007F0000)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_UV_THRESHOLD_MIN_LSBMASK (0x0000007F)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_UV_THRESHOLD_MIN_SHIFT (16)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_UV_THRESHOLD_MIN_LENGTH (7)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_UV_THRESHOLD_MIN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1_PANIC_THRESH, GRPH1_ALERT_Y_THRESHOLD_MAX
+*/
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_Y_THRESHOLD_MAX_MASK (0x0000FF00)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_Y_THRESHOLD_MAX_LSBMASK (0x000000FF)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_Y_THRESHOLD_MAX_SHIFT (8)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_Y_THRESHOLD_MAX_LENGTH (8)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_Y_THRESHOLD_MAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH1_PANIC_THRESH, GRPH1_ALERT_Y_THRESHOLD_MIN
+*/
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_Y_THRESHOLD_MIN_MASK (0x000000FF)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_Y_THRESHOLD_MIN_LSBMASK (0x000000FF)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_Y_THRESHOLD_MIN_SHIFT (0)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_Y_THRESHOLD_MIN_LENGTH (8)
+#define ODN_PDP_GRPH1_PANIC_THRESH_GRPH1_ALERT_Y_THRESHOLD_MIN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH2_PANIC_THRESH_OFFSET (0x09A4)
+
+/* PDP, GRPH2_PANIC_THRESH, GRPH2_ALERT_UV_ENABLE
+*/
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_UV_ENABLE_MASK (0x80000000)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_UV_ENABLE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_UV_ENABLE_SHIFT (31)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_UV_ENABLE_LENGTH (1)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_UV_ENABLE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2_PANIC_THRESH, GRPH2_ALERT_Y_ENABLE
+*/
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_Y_ENABLE_MASK (0x40000000)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_Y_ENABLE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_Y_ENABLE_SHIFT (30)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_Y_ENABLE_LENGTH (1)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_Y_ENABLE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2_PANIC_THRESH, GRPH2_ALERT_UV_THRESHOLD_MAX
+*/
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_UV_THRESHOLD_MAX_MASK (0x3F800000)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_UV_THRESHOLD_MAX_LSBMASK (0x0000007F)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_UV_THRESHOLD_MAX_SHIFT (23)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_UV_THRESHOLD_MAX_LENGTH (7)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_UV_THRESHOLD_MAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2_PANIC_THRESH, GRPH2_ALERT_UV_THRESHOLD_MIN
+*/
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_UV_THRESHOLD_MIN_MASK (0x007F0000)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_UV_THRESHOLD_MIN_LSBMASK (0x0000007F)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_UV_THRESHOLD_MIN_SHIFT (16)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_UV_THRESHOLD_MIN_LENGTH (7)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_UV_THRESHOLD_MIN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2_PANIC_THRESH, GRPH2_ALERT_Y_THRESHOLD_MAX
+*/
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_Y_THRESHOLD_MAX_MASK (0x0000FF00)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_Y_THRESHOLD_MAX_LSBMASK (0x000000FF)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_Y_THRESHOLD_MAX_SHIFT (8)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_Y_THRESHOLD_MAX_LENGTH (8)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_Y_THRESHOLD_MAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH2_PANIC_THRESH, GRPH2_ALERT_Y_THRESHOLD_MIN
+*/
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_Y_THRESHOLD_MIN_MASK (0x000000FF)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_Y_THRESHOLD_MIN_LSBMASK (0x000000FF)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_Y_THRESHOLD_MIN_SHIFT (0)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_Y_THRESHOLD_MIN_LENGTH (8)
+#define ODN_PDP_GRPH2_PANIC_THRESH_GRPH2_ALERT_Y_THRESHOLD_MIN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH3_PANIC_THRESH_OFFSET (0x09A8)
+
+/* PDP, GRPH3_PANIC_THRESH, GRPH3_ALERT_UV_ENABLE
+*/
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_UV_ENABLE_MASK (0x80000000)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_UV_ENABLE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_UV_ENABLE_SHIFT (31)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_UV_ENABLE_LENGTH (1)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_UV_ENABLE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3_PANIC_THRESH, GRPH3_ALERT_Y_ENABLE
+*/
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_Y_ENABLE_MASK (0x40000000)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_Y_ENABLE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_Y_ENABLE_SHIFT (30)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_Y_ENABLE_LENGTH (1)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_Y_ENABLE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3_PANIC_THRESH, GRPH3_ALERT_UV_THRESHOLD_MAX
+*/
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_UV_THRESHOLD_MAX_MASK (0x3F800000)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_UV_THRESHOLD_MAX_LSBMASK (0x0000007F)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_UV_THRESHOLD_MAX_SHIFT (23)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_UV_THRESHOLD_MAX_LENGTH (7)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_UV_THRESHOLD_MAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3_PANIC_THRESH, GRPH3_ALERT_UV_THRESHOLD_MIN
+*/
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_UV_THRESHOLD_MIN_MASK (0x007F0000)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_UV_THRESHOLD_MIN_LSBMASK (0x0000007F)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_UV_THRESHOLD_MIN_SHIFT (16)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_UV_THRESHOLD_MIN_LENGTH (7)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_UV_THRESHOLD_MIN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3_PANIC_THRESH, GRPH3_ALERT_Y_THRESHOLD_MAX
+*/
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_Y_THRESHOLD_MAX_MASK (0x0000FF00)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_Y_THRESHOLD_MAX_LSBMASK (0x000000FF)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_Y_THRESHOLD_MAX_SHIFT (8)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_Y_THRESHOLD_MAX_LENGTH (8)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_Y_THRESHOLD_MAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH3_PANIC_THRESH, GRPH3_ALERT_Y_THRESHOLD_MIN
+*/
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_Y_THRESHOLD_MIN_MASK (0x000000FF)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_Y_THRESHOLD_MIN_LSBMASK (0x000000FF)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_Y_THRESHOLD_MIN_SHIFT (0)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_Y_THRESHOLD_MIN_LENGTH (8)
+#define ODN_PDP_GRPH3_PANIC_THRESH_GRPH3_ALERT_Y_THRESHOLD_MIN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_GRPH4_PANIC_THRESH_OFFSET (0x09AC)
+
+/* PDP, GRPH4_PANIC_THRESH, GRPH4_ALERT_UV_ENABLE
+*/
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_UV_ENABLE_MASK (0x80000000)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_UV_ENABLE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_UV_ENABLE_SHIFT (31)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_UV_ENABLE_LENGTH (1)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_UV_ENABLE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4_PANIC_THRESH, GRPH4_ALERT_Y_ENABLE
+*/
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_Y_ENABLE_MASK (0x40000000)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_Y_ENABLE_LSBMASK (0x00000001)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_Y_ENABLE_SHIFT (30)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_Y_ENABLE_LENGTH (1)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_Y_ENABLE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4_PANIC_THRESH, GRPH4_ALERT_UV_THRESHOLD_MAX
+*/
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_UV_THRESHOLD_MAX_MASK (0x3F800000)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_UV_THRESHOLD_MAX_LSBMASK (0x0000007F)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_UV_THRESHOLD_MAX_SHIFT (23)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_UV_THRESHOLD_MAX_LENGTH (7)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_UV_THRESHOLD_MAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4_PANIC_THRESH, GRPH4_ALERT_UV_THRESHOLD_MIN
+*/
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_UV_THRESHOLD_MIN_MASK (0x007F0000)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_UV_THRESHOLD_MIN_LSBMASK (0x0000007F)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_UV_THRESHOLD_MIN_SHIFT (16)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_UV_THRESHOLD_MIN_LENGTH (7)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_UV_THRESHOLD_MIN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4_PANIC_THRESH, GRPH4_ALERT_Y_THRESHOLD_MAX
+*/
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_Y_THRESHOLD_MAX_MASK (0x0000FF00)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_Y_THRESHOLD_MAX_LSBMASK (0x000000FF)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_Y_THRESHOLD_MAX_SHIFT (8)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_Y_THRESHOLD_MAX_LENGTH (8)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_Y_THRESHOLD_MAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, GRPH4_PANIC_THRESH, GRPH4_ALERT_Y_THRESHOLD_MIN
+*/
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_Y_THRESHOLD_MIN_MASK (0x000000FF)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_Y_THRESHOLD_MIN_LSBMASK (0x000000FF)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_Y_THRESHOLD_MIN_SHIFT (0)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_Y_THRESHOLD_MIN_LENGTH (8)
+#define ODN_PDP_GRPH4_PANIC_THRESH_GRPH4_ALERT_Y_THRESHOLD_MIN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID1_PANIC_THRESH_OFFSET (0x09B0)
+
+/* PDP, VID1_PANIC_THRESH, VID1_ALERT_UV_ENABLE
+*/
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_UV_ENABLE_MASK (0x80000000)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_UV_ENABLE_LSBMASK (0x00000001)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_UV_ENABLE_SHIFT (31)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_UV_ENABLE_LENGTH (1)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_UV_ENABLE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1_PANIC_THRESH, VID1_ALERT_Y_ENABLE
+*/
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_Y_ENABLE_MASK (0x40000000)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_Y_ENABLE_LSBMASK (0x00000001)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_Y_ENABLE_SHIFT (30)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_Y_ENABLE_LENGTH (1)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_Y_ENABLE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1_PANIC_THRESH, VID1_ALERT_UV_THRESHOLD_MAX
+*/
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_UV_THRESHOLD_MAX_MASK (0x3F800000)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_UV_THRESHOLD_MAX_LSBMASK (0x0000007F)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_UV_THRESHOLD_MAX_SHIFT (23)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_UV_THRESHOLD_MAX_LENGTH (7)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_UV_THRESHOLD_MAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1_PANIC_THRESH, VID1_ALERT_UV_THRESHOLD_MIN
+*/
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_UV_THRESHOLD_MIN_MASK (0x007F0000)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_UV_THRESHOLD_MIN_LSBMASK (0x0000007F)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_UV_THRESHOLD_MIN_SHIFT (16)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_UV_THRESHOLD_MIN_LENGTH (7)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_UV_THRESHOLD_MIN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1_PANIC_THRESH, VID1_ALERT_Y_THRESHOLD_MAX
+*/
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_Y_THRESHOLD_MAX_MASK (0x0000FF00)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_Y_THRESHOLD_MAX_LSBMASK (0x000000FF)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_Y_THRESHOLD_MAX_SHIFT (8)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_Y_THRESHOLD_MAX_LENGTH (8)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_Y_THRESHOLD_MAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID1_PANIC_THRESH, VID1_ALERT_Y_THRESHOLD_MIN
+*/
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_Y_THRESHOLD_MIN_MASK (0x000000FF)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_Y_THRESHOLD_MIN_LSBMASK (0x000000FF)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_Y_THRESHOLD_MIN_SHIFT (0)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_Y_THRESHOLD_MIN_LENGTH (8)
+#define ODN_PDP_VID1_PANIC_THRESH_VID1_ALERT_Y_THRESHOLD_MIN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID2_PANIC_THRESH_OFFSET (0x09B4)
+
+/* PDP, VID2_PANIC_THRESH, VID2_ALERT_UV_ENABLE
+*/
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_UV_ENABLE_MASK (0x80000000)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_UV_ENABLE_LSBMASK (0x00000001)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_UV_ENABLE_SHIFT (31)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_UV_ENABLE_LENGTH (1)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_UV_ENABLE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2_PANIC_THRESH, VID2_ALERT_Y_ENABLE
+*/
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_Y_ENABLE_MASK (0x40000000)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_Y_ENABLE_LSBMASK (0x00000001)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_Y_ENABLE_SHIFT (30)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_Y_ENABLE_LENGTH (1)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_Y_ENABLE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2_PANIC_THRESH, VID2_ALERT_UV_THRESHOLD_MAX
+*/
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_UV_THRESHOLD_MAX_MASK (0x3F800000)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_UV_THRESHOLD_MAX_LSBMASK (0x0000007F)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_UV_THRESHOLD_MAX_SHIFT (23)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_UV_THRESHOLD_MAX_LENGTH (7)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_UV_THRESHOLD_MAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2_PANIC_THRESH, VID2_ALERT_UV_THRESHOLD_MIN
+*/
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_UV_THRESHOLD_MIN_MASK (0x007F0000)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_UV_THRESHOLD_MIN_LSBMASK (0x0000007F)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_UV_THRESHOLD_MIN_SHIFT (16)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_UV_THRESHOLD_MIN_LENGTH (7)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_UV_THRESHOLD_MIN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2_PANIC_THRESH, VID2_ALERT_Y_THRESHOLD_MAX
+*/
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_Y_THRESHOLD_MAX_MASK (0x0000FF00)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_Y_THRESHOLD_MAX_LSBMASK (0x000000FF)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_Y_THRESHOLD_MAX_SHIFT (8)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_Y_THRESHOLD_MAX_LENGTH (8)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_Y_THRESHOLD_MAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID2_PANIC_THRESH, VID2_ALERT_Y_THRESHOLD_MIN
+*/
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_Y_THRESHOLD_MIN_MASK (0x000000FF)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_Y_THRESHOLD_MIN_LSBMASK (0x000000FF)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_Y_THRESHOLD_MIN_SHIFT (0)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_Y_THRESHOLD_MIN_LENGTH (8)
+#define ODN_PDP_VID2_PANIC_THRESH_VID2_ALERT_Y_THRESHOLD_MIN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID3_PANIC_THRESH_OFFSET (0x09B8)
+
+/* PDP, VID3_PANIC_THRESH, VID3_ALERT_UV_ENABLE
+*/
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_UV_ENABLE_MASK (0x80000000)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_UV_ENABLE_LSBMASK (0x00000001)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_UV_ENABLE_SHIFT (31)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_UV_ENABLE_LENGTH (1)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_UV_ENABLE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3_PANIC_THRESH, VID3_ALERT_Y_ENABLE
+*/
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_Y_ENABLE_MASK (0x40000000)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_Y_ENABLE_LSBMASK (0x00000001)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_Y_ENABLE_SHIFT (30)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_Y_ENABLE_LENGTH (1)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_Y_ENABLE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3_PANIC_THRESH, VID3_ALERT_UV_THRESHOLD_MAX
+*/
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_UV_THRESHOLD_MAX_MASK (0x3F800000)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_UV_THRESHOLD_MAX_LSBMASK (0x0000007F)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_UV_THRESHOLD_MAX_SHIFT (23)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_UV_THRESHOLD_MAX_LENGTH (7)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_UV_THRESHOLD_MAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3_PANIC_THRESH, VID3_ALERT_UV_THRESHOLD_MIN
+*/
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_UV_THRESHOLD_MIN_MASK (0x007F0000)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_UV_THRESHOLD_MIN_LSBMASK (0x0000007F)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_UV_THRESHOLD_MIN_SHIFT (16)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_UV_THRESHOLD_MIN_LENGTH (7)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_UV_THRESHOLD_MIN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3_PANIC_THRESH, VID3_ALERT_Y_THRESHOLD_MAX
+*/
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_Y_THRESHOLD_MAX_MASK (0x0000FF00)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_Y_THRESHOLD_MAX_LSBMASK (0x000000FF)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_Y_THRESHOLD_MAX_SHIFT (8)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_Y_THRESHOLD_MAX_LENGTH (8)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_Y_THRESHOLD_MAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID3_PANIC_THRESH, VID3_ALERT_Y_THRESHOLD_MIN
+*/
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_Y_THRESHOLD_MIN_MASK (0x000000FF)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_Y_THRESHOLD_MIN_LSBMASK (0x000000FF)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_Y_THRESHOLD_MIN_SHIFT (0)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_Y_THRESHOLD_MIN_LENGTH (8)
+#define ODN_PDP_VID3_PANIC_THRESH_VID3_ALERT_Y_THRESHOLD_MIN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_VID4_PANIC_THRESH_OFFSET (0x09BC)
+
+/* PDP, VID4_PANIC_THRESH, VID4_ALERT_UV_ENABLE
+*/
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_UV_ENABLE_MASK (0x80000000)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_UV_ENABLE_LSBMASK (0x00000001)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_UV_ENABLE_SHIFT (31)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_UV_ENABLE_LENGTH (1)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_UV_ENABLE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4_PANIC_THRESH, VID4_ALERT_Y_ENABLE
+*/
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_Y_ENABLE_MASK (0x40000000)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_Y_ENABLE_LSBMASK (0x00000001)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_Y_ENABLE_SHIFT (30)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_Y_ENABLE_LENGTH (1)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_Y_ENABLE_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4_PANIC_THRESH, VID4_ALERT_UV_THRESHOLD_MAX
+*/
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_UV_THRESHOLD_MAX_MASK (0x3F800000)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_UV_THRESHOLD_MAX_LSBMASK (0x0000007F)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_UV_THRESHOLD_MAX_SHIFT (23)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_UV_THRESHOLD_MAX_LENGTH (7)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_UV_THRESHOLD_MAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4_PANIC_THRESH, VID4_ALERT_UV_THRESHOLD_MIN
+*/
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_UV_THRESHOLD_MIN_MASK (0x007F0000)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_UV_THRESHOLD_MIN_LSBMASK (0x0000007F)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_UV_THRESHOLD_MIN_SHIFT (16)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_UV_THRESHOLD_MIN_LENGTH (7)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_UV_THRESHOLD_MIN_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4_PANIC_THRESH, VID4_ALERT_Y_THRESHOLD_MAX
+*/
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_Y_THRESHOLD_MAX_MASK (0x0000FF00)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_Y_THRESHOLD_MAX_LSBMASK (0x000000FF)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_Y_THRESHOLD_MAX_SHIFT (8)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_Y_THRESHOLD_MAX_LENGTH (8)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_Y_THRESHOLD_MAX_SIGNED_FIELD IMG_FALSE
+
+/* PDP, VID4_PANIC_THRESH, VID4_ALERT_Y_THRESHOLD_MIN
+*/
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_Y_THRESHOLD_MIN_MASK (0x000000FF)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_Y_THRESHOLD_MIN_LSBMASK (0x000000FF)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_Y_THRESHOLD_MIN_SHIFT (0)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_Y_THRESHOLD_MIN_LENGTH (8)
+#define ODN_PDP_VID4_PANIC_THRESH_VID4_ALERT_Y_THRESHOLD_MIN_SIGNED_FIELD IMG_FALSE
+
+#define ODN_PDP_BURST_BOUNDARY_OFFSET (0x09C0)
+
+/* PDP, BURST_BOUNDARY, BURST_BOUNDARY
+*/
+#define ODN_PDP_BURST_BOUNDARY_BURST_BOUNDARY_MASK (0x0000003F)
+#define ODN_PDP_BURST_BOUNDARY_BURST_BOUNDARY_LSBMASK (0x0000003F)
+#define ODN_PDP_BURST_BOUNDARY_BURST_BOUNDARY_SHIFT (0)
+#define ODN_PDP_BURST_BOUNDARY_BURST_BOUNDARY_LENGTH (6)
+#define ODN_PDP_BURST_BOUNDARY_BURST_BOUNDARY_SIGNED_FIELD IMG_FALSE
+
+
+/* ---------------------- End of register definitions ---------------------- */
+
+/* NUMREG defines the extent of register address space.
+*/
+
+#define ODN_PDP_NUMREG ((0x09C0 >> 2)+1)
+
+/* Info about video plane addresses */
+#define ODN_PDP_YADDR_BITS (ODN_PDP_VID1BASEADDR_VID1BASEADDR_LENGTH)
+#define ODN_PDP_YADDR_ALIGN 5
+#define ODN_PDP_UADDR_BITS (ODN_PDP_VID1UBASEADDR_VID1UBASEADDR_LENGTH)
+#define ODN_PDP_UADDR_ALIGN 5
+#define ODN_PDP_VADDR_BITS (ODN_PDP_VID1VBASEADDR_VID1VBASEADDR_LENGTH)
+#define ODN_PDP_VADDR_ALIGN 5
+
+#define ODN_PDP_YSTRIDE_BITS (ODN_PDP_VID1STRIDE_VID1STRIDE_LENGTH)
+#define ODN_PDP_YSTRIDE_ALIGN 5
+
+#define ODN_PDP_MAX_INPUT_WIDTH (ODN_PDP_VID1SIZE_VID1WIDTH_LSBMASK + 1)
+#define ODN_PDP_MAX_INPUT_HEIGHT (ODN_PDP_VID1SIZE_VID1HEIGHT_LSBMASK + 1)
+
+/* Maximum 6 bytes per pixel for RGB161616 */
+#define ODN_PDP_MAX_IMAGE_BYTES (ODN_PDP_MAX_INPUT_WIDTH * ODN_PDP_MAX_INPUT_HEIGHT * 6)
+
+/* Round up */
+#define ODN_PDP_MAX_IMAGE_PAGES ((ODN_PDP_MAX_IMAGE_BYTES+PAGE_SIZE-1)/PAGE_SIZE)
+
+#define ODN_PDP_YADDR_MAX (((1 << ODN_PDP_YADDR_BITS) - 1) << ODN_PDP_YADDR_ALIGN)
+#define ODN_PDP_UADDR_MAX (((1 << ODN_PDP_UADDR_BITS) - 1) << ODN_PDP_UADDR_ALIGN)
+#define ODN_PDP_VADDR_MAX (((1 << ODN_PDP_VADDR_BITS) - 1) << ODN_PDP_VADDR_ALIGN)
+#define ODN_PDP_YSTRIDE_MAX ((1 << ODN_PDP_YSTRIDE_BITS) << ODN_PDP_YSTRIDE_ALIGN)
+#define ODN_PDP_YADDR_ALIGNMASK ((1 << ODN_PDP_YADDR_ALIGN) - 1)
+#define ODN_PDP_UADDR_ALIGNMASK ((1 << ODN_PDP_UADDR_ALIGN) - 1)
+#define ODN_PDP_VADDR_ALIGNMASK ((1 << ODN_PDP_VADDR_ALIGN) - 1)
+#define ODN_PDP_YSTRIDE_ALIGNMASK ((1 << ODN_PDP_YSTRIDE_ALIGN) - 1)
+
+/* Field Values (some are reserved for future use) */
+#define ODN_PDP_SURF_PIXFMT_RGB332 0x3
+#define ODN_PDP_SURF_PIXFMT_ARGB4444 0x4
+#define ODN_PDP_SURF_PIXFMT_ARGB1555 0x5
+#define ODN_PDP_SURF_PIXFMT_RGB888 0x6
+#define ODN_PDP_SURF_PIXFMT_RGB565 0x7
+#define ODN_PDP_SURF_PIXFMT_ARGB8888 0x8
+#define ODN_PDP_SURF_PIXFMT_420_PL8 0x9
+#define ODN_PDP_SURF_PIXFMT_420_PL8IVU 0xA
+#define ODN_PDP_SURF_PIXFMT_420_PL8IUV 0xB
+#define ODN_PDP_SURF_PIXFMT_422_UY0VY1_8888 0xC
+#define ODN_PDP_SURF_PIXFMT_422_VY0UY1_8888 0xD
+#define ODN_PDP_SURF_PIXFMT_422_Y0UY1V_8888 0xE
+#define ODN_PDP_SURF_PIXFMT_422_Y0VY1U_8888 0xF
+#define ODN_PDP_SURF_PIXFMT_AYUV8888 0x10
+#define ODN_PDP_SURF_PIXFMT_YUV101010 0x15
+#define ODN_PDP_SURF_PIXFMT_RGB101010 0x17
+#define ODN_PDP_SURF_PIXFMT_420_PL10IUV 0x18
+#define ODN_PDP_SURF_PIXFMT_420_PL10IVU 0x19
+#define ODN_PDP_SURF_PIXFMT_422_PL10IUV 0x1A
+#define ODN_PDP_SURF_PIXFMT_422_PL10IVU 0x1B
+#define ODN_PDP_SURF_PIXFMT_RGB121212 0x1E
+#define ODN_PDP_SURF_PIXFMT_RGB161616 0x1F
+
+#define ODN_PDP_CTRL_CKEYSRC_PREV 0x0
+#define ODN_PDP_CTRL_CKEYSRC_CUR 0x1
+
+#define ODN_PDP_MEMCTRL_MEMREFRESH_ALWAYS 0x0
+#define ODN_PDP_MEMCTRL_MEMREFRESH_HBLNK 0x1
+#define ODN_PDP_MEMCTRL_MEMREFRESH_VBLNK 0x2
+#define ODN_PDP_MEMCTRL_MEMREFRESH_BOTH 0x3
+
+#define ODN_PDP_3D_CTRL_BLENDSEL_BGND_WITH_POS0 0x0
+#define ODN_PDP_3D_CTRL_BLENDSEL_POS0_WITH_POS1 0x1
+#define ODN_PDP_3D_CTRL_BLENDSEL_POS1_WITH_POS2 0x2
+#define ODN_PDP_3D_CTRL_BLENDSEL_POS2_WITH_POS3 0x3
+#define ODN_PDP_3D_CTRL_BLENDSEL_POS3_WITH_POS4 0x4
+#define ODN_PDP_3D_CTRL_BLENDSEL_POS4_WITH_POS5 0x5
+#define ODN_PDP_3D_CTRL_BLENDSEL_POS5_WITH_POS6 0x6
+#define ODN_PDP_3D_CTRL_BLENDSEL_POS6_WITH_POS7 0x7
+
+#define ODN_PDP_UADDR_UV_STRIDE_EQUAL_TO_Y_STRIDE 0x0
+#define ODN_PDP_UADDR_UV_STRIDE_EQUAL_TO_DOUBLE_Y_STRIDE 0x1
+#define ODN_PDP_UADDR_UV_STRIDE_EQUAL_TO_HALF_Y_STRIDE 0x2
+
+#define ODN_PDP_PROCAMP_OUTPUT_OFFSET_FRACTIONAL_BITS 1
+#define ODN_PDP_PROCAMP_COEFFICIENT_FRACTIONAL_BITS 10
+
+/*---------------------------------------------------------------------------*/
+
+#endif /* ODN_PDP_REGS_H */
diff --git a/drivers/gpu/drm/img-rogue/include/system/rgx_tc/odin_regs.h b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/odin_regs.h
new file mode 100644
index 000000000..5d5821623
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/odin_regs.h
@@ -0,0 +1,1026 @@
+/******************************************************************************
+@Title Odin system control register definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Odin FPGA register defs for IMG 3rd generation TCF
+
+ Auto generated headers, eg. odn_core.h:
+ regconv -d . -a 8 odn_core.def
+
+ Source files :
+ odn_core.def
+ mca_debug.def
+ sai_rx_debug.def
+ sai_tx_debug.def
+ ad_tx.def
+
+ Changes:
+ Removed obsolete copyright dates
+ Changed lower case to upper case
+ (eg. odn_core changed to ODN_CORE)
+ Changed PVR5__ to ODN_
+ Merged multiple .def files into one header
+
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+******************************************************************************/
+
+/* tab size 4 */
+
+#ifndef _ODIN_REGS_H_
+#define _ODIN_REGS_H_
+
+/******************************
+ Generated from: odn_core.def
+*******************************/
+
+/*
+ Register ID
+*/
+#define ODN_CORE_ID 0x0000
+#define ODN_ID_VARIANT_MASK 0x0000FFFFU
+#define ODN_ID_VARIANT_SHIFT 0
+#define ODN_ID_VARIANT_SIGNED 0
+
+#define ODN_ID_ID_MASK 0xFFFF0000U
+#define ODN_ID_ID_SHIFT 16
+#define ODN_ID_ID_SIGNED 0
+
+/*
+ Register REL
+*/
+#define ODN_CORE_REL 0x0004
+#define ODN_REL_MINOR_MASK 0x0000FFFFU
+#define ODN_REL_MINOR_SHIFT 0
+#define ODN_REL_MINOR_SIGNED 0
+
+#define ODN_REL_MAJOR_MASK 0xFFFF0000U
+#define ODN_REL_MAJOR_SHIFT 16
+#define ODN_REL_MAJOR_SIGNED 0
+
+/*
+ Register CHANGE_SET
+*/
+#define ODN_CORE_CHANGE_SET 0x0008
+#define ODN_CHANGE_SET_SET_MASK 0xFFFFFFFFU
+#define ODN_CHANGE_SET_SET_SHIFT 0
+#define ODN_CHANGE_SET_SET_SIGNED 0
+
+/*
+ Register USER_ID
+*/
+#define ODN_CORE_USER_ID 0x000C
+#define ODN_USER_ID_ID_MASK 0x000000FFU
+#define ODN_USER_ID_ID_SHIFT 0
+#define ODN_USER_ID_ID_SIGNED 0
+
+/*
+ Register USER_BUILD
+*/
+#define ODN_CORE_USER_BUILD 0x0010
+#define ODN_USER_BUILD_BUILD_MASK 0xFFFFFFFFU
+#define ODN_USER_BUILD_BUILD_SHIFT 0
+#define ODN_USER_BUILD_BUILD_SIGNED 0
+
+/*
+ Register SW_IF_VERSION
+*/
+#define ODN_CORE_SW_IF_VERSION 0x0014
+#define ODN_SW_IF_VERSION_VERSION_MASK 0x0000FFFFU
+#define ODN_SW_IF_VERSION_VERSION_SHIFT 0
+#define ODN_SW_IF_VERSION_VERSION_SIGNED 0
+
+/*
+ Register INTERNAL_RESETN
+*/
+#define ODN_CORE_INTERNAL_RESETN 0x0080
+#define ODN_INTERNAL_RESETN_DDR_MASK 0x00000001U
+#define ODN_INTERNAL_RESETN_DDR_SHIFT 0
+#define ODN_INTERNAL_RESETN_DDR_SIGNED 0
+
+#define ODN_INTERNAL_RESETN_MIG0_MASK 0x00000002U
+#define ODN_INTERNAL_RESETN_MIG0_SHIFT 1
+#define ODN_INTERNAL_RESETN_MIG0_SIGNED 0
+
+#define ODN_INTERNAL_RESETN_MIG1_MASK 0x00000004U
+#define ODN_INTERNAL_RESETN_MIG1_SHIFT 2
+#define ODN_INTERNAL_RESETN_MIG1_SIGNED 0
+
+#define ODN_INTERNAL_RESETN_PDP1_MASK 0x00000008U
+#define ODN_INTERNAL_RESETN_PDP1_SHIFT 3
+#define ODN_INTERNAL_RESETN_PDP1_SIGNED 0
+
+#define ODN_INTERNAL_RESETN_PDP2_MASK 0x00000010U
+#define ODN_INTERNAL_RESETN_PDP2_SHIFT 4
+#define ODN_INTERNAL_RESETN_PDP2_SIGNED 0
+
+#define ODN_INTERNAL_RESETN_PERIP_MASK 0x00000020U
+#define ODN_INTERNAL_RESETN_PERIP_SHIFT 5
+#define ODN_INTERNAL_RESETN_PERIP_SIGNED 0
+
+#define ODN_INTERNAL_RESETN_GIST_MASK 0x00000040U
+#define ODN_INTERNAL_RESETN_GIST_SHIFT 6
+#define ODN_INTERNAL_RESETN_GIST_SIGNED 0
+
+#define ODN_INTERNAL_RESETN_PIKE_MASK 0x00000080U
+#define ODN_INTERNAL_RESETN_PIKE_SHIFT 7
+#define ODN_INTERNAL_RESETN_PIKE_SIGNED 0
+
+/*
+ Register EXTERNAL_RESETN
+*/
+#define ODN_CORE_EXTERNAL_RESETN 0x0084
+#define ODN_EXTERNAL_RESETN_DUT_MASK 0x00000001U
+#define ODN_EXTERNAL_RESETN_DUT_SHIFT 0
+#define ODN_EXTERNAL_RESETN_DUT_SIGNED 0
+
+#define ODN_EXTERNAL_RESETN_DUT_SPI_MASK 0x00000002U
+#define ODN_EXTERNAL_RESETN_DUT_SPI_SHIFT 1
+#define ODN_EXTERNAL_RESETN_DUT_SPI_SIGNED 0
+
+#define ODN_EXTERNAL_RESETN_DUT_PEP_DDR_MASK 0x00000004U
+#define ODN_EXTERNAL_RESETN_DUT_PEP_DDR_SHIFT 2
+#define ODN_EXTERNAL_RESETN_DUT_PEP_DDR_SIGNED 0
+
+#define ODN_EXTERNAL_RESETN_DUT_IF_MASK 0x00000008U
+#define ODN_EXTERNAL_RESETN_DUT_IF_SHIFT 3
+#define ODN_EXTERNAL_RESETN_DUT_IF_SIGNED 0
+
+#define ODN_EXTERNAL_RESETN_DUT1_MASK 0x00000010U
+#define ODN_EXTERNAL_RESETN_DUT1_SHIFT 4
+#define ODN_EXTERNAL_RESETN_DUT1_SIGNED 0
+
+#define ODN_EXTERNAL_RESETN_DUT2_MASK 0x00000020U
+#define ODN_EXTERNAL_RESETN_DUT2_SHIFT 5
+#define ODN_EXTERNAL_RESETN_DUT2_SIGNED 0
+
+/*
+ Register EXTERNAL_RESET
+*/
+#define ODN_CORE_EXTERNAL_RESET 0x0088
+#define ODN_EXTERNAL_RESET_PVT_CAL_MASK 0x00000001U
+#define ODN_EXTERNAL_RESET_PVT_CAL_SHIFT 0
+#define ODN_EXTERNAL_RESET_PVT_CAL_SIGNED 0
+
+#define ODN_EXTERNAL_RESET_PLL_MASK 0x00000002U
+#define ODN_EXTERNAL_RESET_PLL_SHIFT 1
+#define ODN_EXTERNAL_RESET_PLL_SIGNED 0
+
+/*
+ Register INTERNAL_AUTO_RESETN
+*/
+#define ODN_CORE_INTERNAL_AUTO_RESETN 0x008C
+#define ODN_INTERNAL_AUTO_RESETN_AUX_MASK 0x00000001U
+#define ODN_INTERNAL_AUTO_RESETN_AUX_SHIFT 0
+#define ODN_INTERNAL_AUTO_RESETN_AUX_SIGNED 0
+
+/*
+ Register CLK_GEN_RESET
+*/
+#define ODN_CORE_CLK_GEN_RESET 0x0090
+#define ODN_CLK_GEN_RESET_DUT_CORE_MMCM_MASK 0x00000001U
+#define ODN_CLK_GEN_RESET_DUT_CORE_MMCM_SHIFT 0
+#define ODN_CLK_GEN_RESET_DUT_CORE_MMCM_SIGNED 0
+
+#define ODN_CLK_GEN_RESET_DUT_IF_MMCM_MASK 0x00000002U
+#define ODN_CLK_GEN_RESET_DUT_IF_MMCM_SHIFT 1
+#define ODN_CLK_GEN_RESET_DUT_IF_MMCM_SIGNED 0
+
+#define ODN_CLK_GEN_RESET_MULTI_MMCM_MASK 0x00000004U
+#define ODN_CLK_GEN_RESET_MULTI_MMCM_SHIFT 2
+#define ODN_CLK_GEN_RESET_MULTI_MMCM_SIGNED 0
+
+#define ODN_CLK_GEN_RESET_PDP_MMCM_MASK 0x00000008U
+#define ODN_CLK_GEN_RESET_PDP_MMCM_SHIFT 3
+#define ODN_CLK_GEN_RESET_PDP_MMCM_SIGNED 0
+
+/*
+ Register INTERRUPT_STATUS
+*/
+#define ODN_CORE_INTERRUPT_STATUS 0x0100
+#define ODN_INTERRUPT_STATUS_DUT_MASK 0x00000001U
+#define ODN_INTERRUPT_STATUS_DUT_SHIFT 0
+#define ODN_INTERRUPT_STATUS_DUT_SIGNED 0
+
+#define ODN_INTERRUPT_STATUS_PDP1_MASK 0x00000002U
+#define ODN_INTERRUPT_STATUS_PDP1_SHIFT 1
+#define ODN_INTERRUPT_STATUS_PDP1_SIGNED 0
+
+#define ODN_INTERRUPT_STATUS_PDP2_MASK 0x00000004U
+#define ODN_INTERRUPT_STATUS_PDP2_SHIFT 2
+#define ODN_INTERRUPT_STATUS_PDP2_SIGNED 0
+
+#define ODN_INTERRUPT_STATUS_PERIP_MASK 0x00000008U
+#define ODN_INTERRUPT_STATUS_PERIP_SHIFT 3
+#define ODN_INTERRUPT_STATUS_PERIP_SIGNED 0
+
+#define ODN_INTERRUPT_STATUS_UART_MASK 0x00000010U
+#define ODN_INTERRUPT_STATUS_UART_SHIFT 4
+#define ODN_INTERRUPT_STATUS_UART_SIGNED 0
+
+#define ODN_INTERRUPT_STATUS_GIST_IN_LNK_ERR_MASK 0x00000020U
+#define ODN_INTERRUPT_STATUS_GIST_IN_LNK_ERR_SHIFT 5
+#define ODN_INTERRUPT_STATUS_GIST_IN_LNK_ERR_SIGNED 0
+
+#define ODN_INTERRUPT_STATUS_GIST_IN_MB_ERR_MASK 0x00000040U
+#define ODN_INTERRUPT_STATUS_GIST_IN_MB_ERR_SHIFT 6
+#define ODN_INTERRUPT_STATUS_GIST_IN_MB_ERR_SIGNED 0
+
+#define ODN_INTERRUPT_STATUS_GIST_OUT_LNK_ERR_MASK 0x00000080U
+#define ODN_INTERRUPT_STATUS_GIST_OUT_LNK_ERR_SHIFT 7
+#define ODN_INTERRUPT_STATUS_GIST_OUT_LNK_ERR_SIGNED 0
+
+#define ODN_INTERRUPT_STATUS_GIST_OUT_MB_ERR_MASK 0x00000100U
+#define ODN_INTERRUPT_STATUS_GIST_OUT_MB_ERR_SHIFT 8
+#define ODN_INTERRUPT_STATUS_GIST_OUT_MB_ERR_SIGNED 0
+
+#define ODN_INTERRUPT_STATUS_DUT2_MASK 0x00000200U
+#define ODN_INTERRUPT_STATUS_DUT2_SHIFT 9
+#define ODN_INTERRUPT_STATUS_DUT2_SIGNED 0
+
+#define ODN_INTERRUPT_STATUS_AXI_LOCKUP_PROTECTION_MASK 0x00000400U
+#define ODN_INTERRUPT_STATUS_AXI_LOCKUP_PROTECTION_SHIFT 10
+#define ODN_INTERRUPT_STATUS_AXI_LOCKUP_PROTECTION_SIGNED 0
+
+#define ODN_INTERRUPT_STATUS_CDMA_MASK 0x00001800U
+#define ODN_INTERRUPT_STATUS_CDMA_SHIFT 11
+#define ODN_INTERRUPT_STATUS_CDMA_SIGNED 0
+
+#define ODN_INTERRUPT_STATUS_OS_IRQ_MASK 0x001FE000U
+#define ODN_INTERRUPT_STATUS_OS_IRQ_SHIFT 13
+#define ODN_INTERRUPT_STATUS_OS_IRQ_SIGNED 0
+
+#define ODN_INTERRUPT_STATUS_IRQ_TEST_MASK 0x40000000U
+#define ODN_INTERRUPT_STATUS_IRQ_TEST_SHIFT 30
+#define ODN_INTERRUPT_STATUS_IRQ_TEST_SIGNED 0
+
+#define ODN_INTERRUPT_STATUS_MASTER_STATUS_MASK 0x80000000U
+#define ODN_INTERRUPT_STATUS_MASTER_STATUS_SHIFT 31
+#define ODN_INTERRUPT_STATUS_MASTER_STATUS_SIGNED 0
+
+/*
+ Register INTERRUPT_ENABLE
+*/
+#define ODN_CORE_INTERRUPT_ENABLE 0x0104
+#define ODN_INTERRUPT_ENABLE_DUT_MASK 0x00000001U
+#define ODN_INTERRUPT_ENABLE_DUT_SHIFT 0
+#define ODN_INTERRUPT_ENABLE_DUT_SIGNED 0
+
+#define ODN_INTERRUPT_ENABLE_PDP1_MASK 0x00000002U
+#define ODN_INTERRUPT_ENABLE_PDP1_SHIFT 1
+#define ODN_INTERRUPT_ENABLE_PDP1_SIGNED 0
+
+#define ODN_INTERRUPT_ENABLE_PDP2_MASK 0x00000004U
+#define ODN_INTERRUPT_ENABLE_PDP2_SHIFT 2
+#define ODN_INTERRUPT_ENABLE_PDP2_SIGNED 0
+
+#define ODN_INTERRUPT_ENABLE_PERIP_MASK 0x00000008U
+#define ODN_INTERRUPT_ENABLE_PERIP_SHIFT 3
+#define ODN_INTERRUPT_ENABLE_PERIP_SIGNED 0
+
+#define ODN_INTERRUPT_ENABLE_UART_MASK 0x00000010U
+#define ODN_INTERRUPT_ENABLE_UART_SHIFT 4
+#define ODN_INTERRUPT_ENABLE_UART_SIGNED 0
+
+#define ODN_INTERRUPT_ENABLE_GIST_IN_LNK_ERR_MASK 0x00000020U
+#define ODN_INTERRUPT_ENABLE_GIST_IN_LNK_ERR_SHIFT 5
+#define ODN_INTERRUPT_ENABLE_GIST_IN_LNK_ERR_SIGNED 0
+
+#define ODN_INTERRUPT_ENABLE_GIST_IN_MB_ERR_MASK 0x00000040U
+#define ODN_INTERRUPT_ENABLE_GIST_IN_MB_ERR_SHIFT 6
+#define ODN_INTERRUPT_ENABLE_GIST_IN_MB_ERR_SIGNED 0
+
+#define ODN_INTERRUPT_ENABLE_GIST_OUT_LNK_ERR_MASK 0x00000080U
+#define ODN_INTERRUPT_ENABLE_GIST_OUT_LNK_ERR_SHIFT 7
+#define ODN_INTERRUPT_ENABLE_GIST_OUT_LNK_ERR_SIGNED 0
+
+#define ODN_INTERRUPT_ENABLE_GIST_OUT_MB_ERR_MASK 0x00000100U
+#define ODN_INTERRUPT_ENABLE_GIST_OUT_MB_ERR_SHIFT 8
+#define ODN_INTERRUPT_ENABLE_GIST_OUT_MB_ERR_SIGNED 0
+
+#define ODN_INTERRUPT_ENABLE_DUT2_MASK 0x00000200U
+#define ODN_INTERRUPT_ENABLE_DUT2_SHIFT 9
+#define ODN_INTERRUPT_ENABLE_DUT2_SIGNED 0
+
+#define ODN_INTERRUPT_ENABLE_AXI_LOCKUP_PROTECTION_MASK 0x00000400U
+#define ODN_INTERRUPT_ENABLE_AXI_LOCKUP_PROTECTION_SHIFT 10
+#define ODN_INTERRUPT_ENABLE_AXI_LOCKUP_PROTECTION_SIGNED 0
+
+#define ODN_INTERRUPT_ENABLE_CDMA_MASK 0x00001800U
+#define ODN_INTERRUPT_ENABLE_CDMA_SHIFT 11
+#define ODN_INTERRUPT_ENABLE_CDMA_SIGNED 0
+
+#define ODN_INTERRUPT_ENABLE_OS_IRQ_MASK 0x001FE000U
+#define ODN_INTERRUPT_ENABLE_OS_IRQ_SHIFT 13
+#define ODN_INTERRUPT_ENABLE_OS_IRQ_SIGNED 0
+
+#define ODN_INTERRUPT_ENABLE_IRQ_TEST_MASK 0x40000000U
+#define ODN_INTERRUPT_ENABLE_IRQ_TEST_SHIFT 30
+#define ODN_INTERRUPT_ENABLE_IRQ_TEST_SIGNED 0
+
+#define ODN_INTERRUPT_ENABLE_MASTER_ENABLE_MASK 0x80000000U
+#define ODN_INTERRUPT_ENABLE_MASTER_ENABLE_SHIFT 31
+#define ODN_INTERRUPT_ENABLE_MASTER_ENABLE_SIGNED 0
+
+/*
+ Register INTERRUPT_CLR
+*/
+#define ODN_CORE_INTERRUPT_CLR 0x010C
+#define ODN_INTERRUPT_CLR_DUT_MASK 0x00000001U
+#define ODN_INTERRUPT_CLR_DUT_SHIFT 0
+#define ODN_INTERRUPT_CLR_DUT_SIGNED 0
+
+#define ODN_INTERRUPT_CLR_PDP1_MASK 0x00000002U
+#define ODN_INTERRUPT_CLR_PDP1_SHIFT 1
+#define ODN_INTERRUPT_CLR_PDP1_SIGNED 0
+
+#define ODN_INTERRUPT_CLR_PDP2_MASK 0x00000004U
+#define ODN_INTERRUPT_CLR_PDP2_SHIFT 2
+#define ODN_INTERRUPT_CLR_PDP2_SIGNED 0
+
+#define ODN_INTERRUPT_CLR_PERIP_MASK 0x00000008U
+#define ODN_INTERRUPT_CLR_PERIP_SHIFT 3
+#define ODN_INTERRUPT_CLR_PERIP_SIGNED 0
+
+#define ODN_INTERRUPT_CLR_UART_MASK 0x00000010U
+#define ODN_INTERRUPT_CLR_UART_SHIFT 4
+#define ODN_INTERRUPT_CLR_UART_SIGNED 0
+
+#define ODN_INTERRUPT_CLR_GIST_IN_LNK_ERR_MASK 0x00000020U
+#define ODN_INTERRUPT_CLR_GIST_IN_LNK_ERR_SHIFT 5
+#define ODN_INTERRUPT_CLR_GIST_IN_LNK_ERR_SIGNED 0
+
+#define ODN_INTERRUPT_CLR_GIST_IN_MB_ERR_MASK 0x00000040U
+#define ODN_INTERRUPT_CLR_GIST_IN_MB_ERR_SHIFT 6
+#define ODN_INTERRUPT_CLR_GIST_IN_MB_ERR_SIGNED 0
+
+#define ODN_INTERRUPT_CLR_GIST_OUT_LNK_ERR_MASK 0x00000080U
+#define ODN_INTERRUPT_CLR_GIST_OUT_LNK_ERR_SHIFT 7
+#define ODN_INTERRUPT_CLR_GIST_OUT_LNK_ERR_SIGNED 0
+
+#define ODN_INTERRUPT_CLR_GIST_OUT_MB_ERR_MASK 0x00000100U
+#define ODN_INTERRUPT_CLR_GIST_OUT_MB_ERR_SHIFT 8
+#define ODN_INTERRUPT_CLR_GIST_OUT_MB_ERR_SIGNED 0
+
+#define ODN_INTERRUPT_CLR_DUT2_MASK 0x00000200U
+#define ODN_INTERRUPT_CLR_DUT2_SHIFT 9
+#define PVR5__INTERRUPT_CLR_DUT2_SIGNED 0
+
+#define ODN_INTERRUPT_CLR_AXI_LOCKUP_PROTECTION_MASK 0x00000400U
+#define ODN_INTERRUPT_CLR_AXI_LOCKUP_PROTECTION_SHIFT 10
+#define ODN_INTERRUPT_CLR_AXI_LOCKUP_PROTECTION_SIGNED 0
+
+#define ODN_INTERRUPT_CLR_CDMA_MASK 0x00001800U
+#define ODN_INTERRUPT_CLR_CDMA_SHIFT 11
+#define ODN_INTERRUPT_CLR_CDMA_SIGNED 0
+
+#define ODN_INTERRUPT_CLR_OS_IRQ_MASK 0x001FE000U
+#define ODN_INTERRUPT_CLR_OS_IRQ_SHIFT 13
+#define ODN_INTERRUPT_CLR_OS_IRQ_SIGNED 0
+
+#define ODN_INTERRUPT_CLR_IRQ_TEST_MASK 0x40000000U
+#define ODN_INTERRUPT_CLR_IRQ_TEST_SHIFT 30
+#define ODN_INTERRUPT_CLR_IRQ_TEST_SIGNED 0
+
+#define ODN_INTERRUPT_CLR_MASTER_CLEAR_MASK 0x80000000U
+#define ODN_INTERRUPT_CLR_MASTER_CLEAR_SHIFT 31
+#define ODN_INTERRUPT_CLR_MASTER_CLEAR_SIGNED 0
+
+/*
+ Register INTERRUPT_TEST
+*/
+#define ODN_CORE_INTERRUPT_TEST 0x0110
+#define ODN_INTERRUPT_TEST_INTERRUPT_TEST_MASK 0x00000001U
+#define ODN_INTERRUPT_TEST_INTERRUPT_TEST_SHIFT 0
+#define ODN_INTERRUPT_TEST_INTERRUPT_TEST_SIGNED 0
+
+/*
+ Register INTERRUPT_TIMEOUT_CLR
+*/
+#define ODN_CORE_INTERRUPT_TIMEOUT_CLR 0x0114
+#define ODN_INTERRUPT_TIMEOUT_CLR_INTERRUPT_MST_TIMEOUT_CLR_MASK 0x00000002U
+#define ODN_INTERRUPT_TIMEOUT_CLR_INTERRUPT_MST_TIMEOUT_CLR_SHIFT 1
+#define ODN_INTERRUPT_TIMEOUT_CLR_INTERRUPT_MST_TIMEOUT_CLR_SIGNED 0
+
+#define ODN_INTERRUPT_TIMEOUT_CLR_INTERRUPT_MST_TIMEOUT_MASK 0x00000001U
+#define ODN_INTERRUPT_TIMEOUT_CLR_INTERRUPT_MST_TIMEOUT_SHIFT 0
+#define ODN_INTERRUPT_TIMEOUT_CLR_INTERRUPT_MST_TIMEOUT_SIGNED 0
+
+/*
+ Register INTERRUPT_TIMEOUT
+*/
+#define ODN_CORE_INTERRUPT_TIMEOUT 0x0118
+#define ODN_INTERRUPT_TIMEOUT_INTERRUPT_TIMEOUT_THRESHOLD_COUNTER_MASK 0xFFFFFFFFU
+#define ODN_INTERRUPT_TIMEOUT_INTERRUPT_TIMEOUT_THRESHOLD_COUNTER_SHIFT 0
+#define ODN_INTERRUPT_TIMEOUT_INTERRUPT_TIMEOUT_THRESHOLD_COUNTER_SIGNED 0
+/*
+ Register SYSTEM_ID
+*/
+#define ODN_CORE_SYSTEM_ID 0x011C
+#define ODN_SYSTEM_ID_ID_MASK 0x0000FFFFU
+#define ODN_SYSTEM_ID_ID_SHIFT 0
+#define ODN_SYSTEM_ID_ID_SIGNED 0
+
+/*
+ Register SUPPORTED_FEATURES
+*/
+#define ODN_CORE_SUPPORTED_FEATURES 0x0120
+#define ODN_SUPPORTED_FEATURES_UNIMPLEMENTED_FREATURES_MASK 0xFFFFFFFEU
+#define ODN_SUPPORTED_FEATURES_UNIMPLEMENTED_FREATURES_SHIFT 1
+#define ODN_SUPPORTED_FEATURES_UNIMPLEMENTED_FREATURES_SIGNED 0
+
+#define ODN_SUPPORTED_FEATURES_2X_CDMA_AND_IRQS_MASK 0x00000001U
+#define ODN_SUPPORTED_FEATURES_2X_CDMA_AND_IRQS_SHIFT 0
+#define ODN_SUPPORTED_FEATURES_2X_CDMA_AND_IRQS_SIGNED 0
+
+/*
+ Register NUM_GPIO
+*/
+#define ODN_CORE_NUM_GPIO 0x0180
+#define ODN_NUM_GPIO_NUMBER_MASK 0x0000000FU
+#define ODN_NUM_GPIO_NUMBER_SHIFT 0
+#define ODN_NUM_GPIO_NUMBER_SIGNED 0
+
+/*
+ Register GPIO_EN
+*/
+#define ODN_CORE_GPIO_EN 0x0184
+#define ODN_GPIO_EN_DIRECTION_MASK 0x000000FFU
+#define ODN_GPIO_EN_DIRECTION_SHIFT 0
+#define ODN_GPIO_EN_DIRECTION_SIGNED 0
+
+/*
+ Register GPIO
+*/
+#define ODN_CORE_GPIO 0x0188
+#define ODN_GPIO_GPIO_MASK 0x000000FFU
+#define ODN_GPIO_GPIO_SHIFT 0
+#define ODN_GPIO_GPIO_SIGNED 0
+
+/*
+ Register NUM_DUT_CTRL
+*/
+#define ODN_CORE_NUM_DUT_CTRL 0x0190
+#define ODN_NUM_DUT_CTRL_NUM_PINS_MASK 0xFFFFFFFFU
+#define ODN_NUM_DUT_CTRL_NUM_PINS_SHIFT 0
+#define ODN_NUM_DUT_CTRL_NUM_PINS_SIGNED 0
+
+/*
+ Register DUT_CTRL1
+*/
+#define ODN_CORE_DUT_CTRL1 0x0194
+#define ODN_DUT_CTRL1_CONTROL1_MASK 0x3FFFFFFFU
+#define ODN_DUT_CTRL1_CONTROL1_SHIFT 0
+#define ODN_DUT_CTRL1_CONTROL1_SIGNED 0
+
+#define ODN_DUT_CTRL1_FBDC_BYPASS_MASK 0x40000000U
+#define ODN_DUT_CTRL1_FBDC_BYPASS_SHIFT 30
+#define ODN_DUT_CTRL1_FBDC_BYPASS_SIGNED 0
+
+#define ODN_DUT_CTRL1_DUT_MST_OFFSET_MASK 0x80000000U
+#define ODN_DUT_CTRL1_DUT_MST_OFFSET_SHIFT 31
+#define ODN_DUT_CTRL1_DUT_MST_OFFSET_SIGNED 0
+
+/*
+ Register DUT_CTRL2
+*/
+#define ODN_CORE_DUT_CTRL2 0x0198
+#define ODN_DUT_CTRL2_CONTROL2_MASK 0xFFFFFFFFU
+#define ODN_DUT_CTRL2_CONTROL2_SHIFT 0
+#define ODN_DUT_CTRL2_CONTROL2_SIGNED 0
+
+/*
+ Register NUM_DUT_STAT
+*/
+#define ODN_CORE_NUM_DUT_STAT 0x019C
+#define ODN_NUM_DUT_STAT_NUM_PINS_MASK 0xFFFFFFFFU
+#define ODN_NUM_DUT_STAT_NUM_PINS_SHIFT 0
+#define ODN_NUM_DUT_STAT_NUM_PINS_SIGNED 0
+
+/*
+ Register DUT_STAT1
+*/
+#define ODN_CORE_DUT_STAT1 0x01A0
+#define ODN_DUT_STAT1_STATUS1_MASK 0xFFFFFFFFU
+#define ODN_DUT_STAT1_STATUS1_SHIFT 0
+#define ODN_DUT_STAT1_STATUS1_SIGNED 0
+
+/*
+ Register DUT_STAT2
+*/
+#define ODN_CORE_DUT_STAT2 0x01A4
+#define ODN_DUT_STAT2_STATUS2_MASK 0xFFFFFFFFU
+#define ODN_DUT_STAT2_STATUS2_SHIFT 0
+#define ODN_DUT_STAT2_STATUS2_SIGNED 0
+
+/*
+ Register DASH_LEDS
+*/
+#define ODN_CORE_DASH_LEDS 0x01A8
+#define ODN_DASH_LEDS_REPA_MASK 0xFFF00000U
+#define ODN_DASH_LEDS_REPA_SHIFT 20
+#define ODN_DASH_LEDS_REPA_SIGNED 0
+
+#define ODN_DASH_LEDS_PIKE_MASK 0x00000FFFU
+#define ODN_DASH_LEDS_PIKE_SHIFT 0
+#define ODN_DASH_LEDS_PIKE_SIGNED 0
+
+/*
+ Register DUT_CLK_INFO
+*/
+#define ODN_CORE_DUT_CLK_INFO 0x01B0
+#define ODN_DUT_CLK_INFO_CORE_MASK 0x0000FFFFU
+#define ODN_DUT_CLK_INFO_CORE_SHIFT 0
+#define ODN_DUT_CLK_INFO_CORE_SIGNED 0
+
+#define ODN_DUT_CLK_INFO_MEM_MASK 0xFFFF0000U
+#define ODN_DUT_CLK_INFO_MEM_SHIFT 16
+#define ODN_DUT_CLK_INFO_MEM_SIGNED 0
+
+/*
+ Register DUT_CLK_PHSE
+*/
+#define ODN_CORE_DUT_CLK_PHSE 0x01B4
+#define ODN_DUT_CLK_PHSE_MEM_REQ_MASK 0x0000FFFFU
+#define ODN_DUT_CLK_PHSE_MEM_REQ_SHIFT 0
+#define ODN_DUT_CLK_PHSE_MEM_REQ_SIGNED 0
+
+#define ODN_DUT_CLK_PHSE_MEM_RD_MASK 0xFFFF0000U
+#define ODN_DUT_CLK_PHSE_MEM_RD_SHIFT 16
+#define ODN_DUT_CLK_PHSE_MEM_RD_SIGNED 0
+
+/*
+ Register CORE_STATUS
+*/
+#define ODN_CORE_CORE_STATUS 0x0200
+#define ODN_CORE_STATUS_PCIE_USER_LNK_UP_MASK 0x00000001U
+#define ODN_CORE_STATUS_PCIE_USER_LNK_UP_SHIFT 0
+#define ODN_CORE_STATUS_PCIE_USER_LNK_UP_SIGNED 0
+
+#define ODN_CORE_STATUS_MIG_C0_MMCM_LOCKED_MASK 0x00000010U
+#define ODN_CORE_STATUS_MIG_C0_MMCM_LOCKED_SHIFT 4
+#define ODN_CORE_STATUS_MIG_C0_MMCM_LOCKED_SIGNED 0
+
+#define ODN_CORE_STATUS_MIG_C0_INIT_CALIB_COMPLETE_MASK 0x00000020U
+#define ODN_CORE_STATUS_MIG_C0_INIT_CALIB_COMPLETE_SHIFT 5
+#define ODN_CORE_STATUS_MIG_C0_INIT_CALIB_COMPLETE_SIGNED 0
+
+#define ODN_CORE_STATUS_MIG_C1_MMCM_LOCKED_MASK 0x00000040U
+#define ODN_CORE_STATUS_MIG_C1_MMCM_LOCKED_SHIFT 6
+#define ODN_CORE_STATUS_MIG_C1_MMCM_LOCKED_SIGNED 0
+
+#define ODN_CORE_STATUS_MIG_C1_INIT_CALIB_COMPLETE_MASK 0x00000080U
+#define ODN_CORE_STATUS_MIG_C1_INIT_CALIB_COMPLETE_SHIFT 7
+#define ODN_CORE_STATUS_MIG_C1_INIT_CALIB_COMPLETE_SIGNED 0
+
+#define ODN_CORE_STATUS_PERIP_IMG2AXI_IDLE_MASK 0x00000100U
+#define ODN_CORE_STATUS_PERIP_IMG2AXI_IDLE_SHIFT 8
+#define ODN_CORE_STATUS_PERIP_IMG2AXI_IDLE_SIGNED 0
+
+#define ODN_CORE_STATUS_PERIP_AXI2IMG_IDLE_MASK 0x00000200U
+#define ODN_CORE_STATUS_PERIP_AXI2IMG_IDLE_SHIFT 9
+#define ODN_CORE_STATUS_PERIP_AXI2IMG_IDLE_SIGNED 0
+
+#define ODN_CORE_STATUS_GIST_SLV_C2C_CONFIG_ERROR_OUT_MASK 0x00001000U
+#define ODN_CORE_STATUS_GIST_SLV_C2C_CONFIG_ERROR_OUT_SHIFT 12
+#define ODN_CORE_STATUS_GIST_SLV_C2C_CONFIG_ERROR_OUT_SIGNED 0
+
+#define ODN_CORE_STATUS_GIST_MST_C2C_CONFIG_ERROR_OUT_MASK 0x00002000U
+#define ODN_CORE_STATUS_GIST_MST_C2C_CONFIG_ERROR_OUT_SHIFT 13
+#define ODN_CORE_STATUS_GIST_MST_C2C_CONFIG_ERROR_OUT_SIGNED 0
+
+/*
+ Register CORE_CONTROL
+*/
+#define ODN_CORE_CORE_CONTROL 0x0204
+#define ODN_CORE_CONTROL_BAR4_OFFSET_MASK 0x0000001FU
+#define ODN_CORE_CONTROL_BAR4_OFFSET_SHIFT 0
+#define ODN_CORE_CONTROL_BAR4_OFFSET_SIGNED 0
+
+#define ODN_CORE_CONTROL_HDMI_MONITOR_OVERRIDE_MASK 0x00000300U
+#define ODN_CORE_CONTROL_HDMI_MONITOR_OVERRIDE_SHIFT 8
+#define ODN_CORE_CONTROL_HDMI_MONITOR_OVERRIDE_SIGNED 0
+
+#define ODN_CORE_CONTROL_HDMI_MODULE_EN_MASK 0x00001C00U
+#define ODN_CORE_CONTROL_HDMI_MODULE_EN_SHIFT 10
+#define ODN_CORE_CONTROL_HDMI_MODULE_EN_SIGNED 0
+
+#define ODN_CORE_CONTROL_MCU_COMMUNICATOR_EN_MASK 0x00002000U
+#define ODN_CORE_CONTROL_MCU_COMMUNICATOR_EN_SHIFT 13
+#define ODN_CORE_CONTROL_MCU_COMMUNICATOR_EN_SIGNED 0
+
+#define ODN_CORE_CONTROL_PDP1_OFFSET_MASK 0x00070000U
+#define ODN_CORE_CONTROL_PDP1_OFFSET_SHIFT 16
+#define ODN_CORE_CONTROL_PDP1_OFFSET_SIGNED 0
+
+#define ODN_CORE_CONTROL_PDP2_OFFSET_MASK 0x00700000U
+#define ODN_CORE_CONTROL_PDP2_OFFSET_SHIFT 20
+#define ODN_CORE_CONTROL_PDP2_OFFSET_SIGNED 0
+
+#define ODN_CORE_CONTROL_DUT_OFFSET_MASK 0x07000000U
+#define ODN_CORE_CONTROL_DUT_OFFSET_SHIFT 24
+#define ODN_CORE_CONTROL_DUT_OFFSET_SIGNED 0
+
+/*
+ Register REG_BANK_STATUS
+*/
+#define ODN_CORE_REG_BANK_STATUS 0x0208
+#define ODN_REG_BANK_STATUS_ARB_SLV_RD_TIMEOUT_MASK 0xFFFFFFFFU
+#define ODN_REG_BANK_STATUS_ARB_SLV_RD_TIMEOUT_SHIFT 0
+#define ODN_REG_BANK_STATUS_ARB_SLV_RD_TIMEOUT_SIGNED 0
+
+/*
+ Register MMCM_LOCK_STATUS
+*/
+#define ODN_CORE_MMCM_LOCK_STATUS 0x020C
+#define ODN_MMCM_LOCK_STATUS_DUT_CORE_MASK 0x00000001U
+#define ODN_MMCM_LOCK_STATUS_DUT_CORE_SHIFT 0
+#define ODN_MMCM_LOCK_STATUS_DUT_CORE_SIGNED 0
+
+#define ODN_MMCM_LOCK_STATUS_DUT_IF_MASK 0x00000002U
+#define ODN_MMCM_LOCK_STATUS_DUT_IF_SHIFT 1
+#define ODN_MMCM_LOCK_STATUS_DUT_IF_SIGNED 0
+
+#define ODN_MMCM_LOCK_STATUS_MULTI_MASK 0x00000004U
+#define ODN_MMCM_LOCK_STATUS_MULTI_SHIFT 2
+#define ODN_MMCM_LOCK_STATUS_MULTI_SIGNED 0
+
+#define ODN_MMCM_LOCK_STATUS_PDPP_MASK 0x00000008U
+#define ODN_MMCM_LOCK_STATUS_PDPP_SHIFT 3
+#define ODN_MMCM_LOCK_STATUS_PDPP_SIGNED 0
+
+/*
+ Register GIST_STATUS
+*/
+#define ODN_CORE_GIST_STATUS 0x0210
+#define ODN_GIST_STATUS_MST_MASK 0x000001FFU
+#define ODN_GIST_STATUS_MST_SHIFT 0
+#define ODN_GIST_STATUS_MST_SIGNED 0
+
+#define ODN_GIST_STATUS_SLV_MASK 0x001FF000U
+#define ODN_GIST_STATUS_SLV_SHIFT 12
+#define ODN_GIST_STATUS_SLV_SIGNED 0
+
+#define ODN_GIST_STATUS_SLV_OUT_MASK 0x03000000U
+#define ODN_GIST_STATUS_SLV_OUT_SHIFT 24
+#define ODN_GIST_STATUS_SLV_OUT_SIGNED 0
+
+#define ODN_GIST_STATUS_MST_OUT_MASK 0x70000000U
+#define ODN_GIST_STATUS_MST_OUT_SHIFT 28
+#define ODN_GIST_STATUS_MST_OUT_SIGNED 0
+
+/*
+ Register DUT_MST_ADD
+*/
+#define ODN_CORE_DUT_MST_ADD 0x0214
+#define ODN_DUT_MST_ADD_SLV_OUT_MASK 0x0000003FU
+#define ODN_DUT_MST_ADD_SLV_OUT_SHIFT 0
+#define ODN_DUT_MST_ADD_SLV_OUT_SIGNED 0
+
+/*
+ Register DUT_MULTIPLX_INFO
+*/
+#define ODN_CORE_DUT_MULTIPLX_INFO 0x0218
+#define ODN_DUT_MULTIPLX_INFO_MEM_MASK 0x000000FFU
+#define ODN_DUT_MULTIPLX_INFO_MEM_SHIFT 0
+#define ODN_DUT_MULTIPLX_INFO_MEM_SIGNED 0
+
+/****************************
+ Generated from: ad_tx.def
+*****************************/
+
+/*
+ Register ADT_CONTROL
+*/
+#define ODN_AD_TX_DEBUG_ADT_CONTROL 0x0000
+#define ODN_SET_ADTX_READY_MASK 0x00000004U
+#define ODN_SET_ADTX_READY_SHIFT 2
+#define ODN_SET_ADTX_READY_SIGNED 0
+
+#define ODN_SEND_ALIGN_DATA_MASK 0x00000002U
+#define ODN_SEND_ALIGN_DATA_SHIFT 1
+#define ODN_SEND_ALIGN_DATA_SIGNED 0
+
+#define ODN_ENABLE_FLUSHING_MASK 0x00000001U
+#define ODN_ENABLE_FLUSHING_SHIFT 0
+#define ODN_ENABLE_FLUSHING_SIGNED 0
+
+/*
+ Register ADT_STATUS
+*/
+#define ODN_AD_TX_DEBUG_ADT_STATUS 0x0004
+#define ODN_REQUEST_COMPLETE_MASK 0x00000001U
+#define ODN_REQUEST_COMPLETE_SHIFT 0
+#define ODN_REQUEST_COMPLETE_SIGNED 0
+
+
+/******************************
+ Generated from: mca_debug.def
+*******************************/
+
+/*
+ Register MCA_CONTROL
+*/
+#define ODN_MCA_DEBUG_MCA_CONTROL 0x0000
+#define ODN_ALIGN_START_MASK 0x00000001U
+#define ODN_ALIGN_START_SHIFT 0
+#define ODN_ALIGN_START_SIGNED 0
+
+/*
+ Register MCA_STATUS
+*/
+#define ODN_MCA_DEBUG_MCA_STATUS 0x0004
+#define ODN_TCHECK_SDEBUG_MASK 0x40000000U
+#define ODN_TCHECK_SDEBUG_SHIFT 30
+#define ODN_TCHECK_SDEBUG_SIGNED 0
+
+#define ODN_CHECK_SDEBUG_MASK 0x20000000U
+#define ODN_CHECK_SDEBUG_SHIFT 29
+#define ODN_CHECK_SDEBUG_SIGNED 0
+
+#define ODN_ALIGN_SDEBUG_MASK 0x10000000U
+#define ODN_ALIGN_SDEBUG_SHIFT 28
+#define ODN_ALIGN_SDEBUG_SIGNED 0
+
+#define ODN_FWAIT_SDEBUG_MASK 0x08000000U
+#define ODN_FWAIT_SDEBUG_SHIFT 27
+#define ODN_FWAIT_SDEBUG_SIGNED 0
+
+#define ODN_IDLE_SDEBUG_MASK 0x04000000U
+#define ODN_IDLE_SDEBUG_SHIFT 26
+#define ODN_IDLE_SDEBUG_SIGNED 0
+
+#define ODN_FIFO_FULL_MASK 0x03FF0000U
+#define ODN_FIFO_FULL_SHIFT 16
+#define ODN_FIFO_FULL_SIGNED 0
+
+#define ODN_FIFO_EMPTY_MASK 0x0000FFC0U
+#define ODN_FIFO_EMPTY_SHIFT 6
+#define ODN_FIFO_EMPTY_SIGNED 0
+
+#define ODN_TAG_CHECK_ERROR_MASK 0x00000020U
+#define ODN_TAG_CHECK_ERROR_SHIFT 5
+#define ODN_TAG_CHECK_ERROR_SIGNED 0
+
+#define ODN_ALIGN_CHECK_ERROR_MASK 0x00000010U
+#define ODN_ALIGN_CHECK_ERROR_SHIFT 4
+#define ODN_ALIGN_CHECK_ERROR_SIGNED 0
+
+#define ODN_ALIGN_ERROR_MASK 0x00000008U
+#define ODN_ALIGN_ERROR_SHIFT 3
+#define ODN_ALIGN_ERROR_SIGNED 0
+
+#define ODN_TAG_CHECKING_OK_MASK 0x00000004U
+#define ODN_TAG_CHECKING_OK_SHIFT 2
+#define ODN_TAG_CHECKING_OK_SIGNED 0
+
+#define ODN_ALIGN_CHECK_OK_MASK 0x00000002U
+#define ODN_ALIGN_CHECK_OK_SHIFT 1
+#define ODN_ALIGN_CHECK_OK_SIGNED 0
+
+#define ODN_ALIGNMENT_FOUND_MASK 0x00000001U
+#define ODN_ALIGNMENT_FOUND_SHIFT 0
+#define ODN_ALIGNMENT_FOUND_SIGNED 0
+
+
+/*********************************
+ Generated from: sai_rx_debug.def
+**********************************/
+
+/*
+ Register SIG_RESULT
+*/
+#define ODN_SAI_RX_DEBUG_SIG_RESULT 0x0000
+#define ODN_SIG_RESULT_VALUE_MASK 0xFFFFFFFFU
+#define ODN_SIG_RESULT_VALUE_SHIFT 0
+#define ODN_SIG_RESULT_VALUE_SIGNED 0
+
+/*
+ Register INIT_SIG
+*/
+#define ODN_SAI_RX_DEBUG_INIT_SIG 0x0004
+#define ODN_INIT_SIG_VALUE_MASK 0x00000001U
+#define ODN_INIT_SIG_VALUE_SHIFT 0
+#define ODN_INIT_SIG_VALUE_SIGNED 0
+
+/*
+ Register SAI_BYPASS
+*/
+#define ODN_SAI_RX_DEBUG_SAI_BYPASS 0x0008
+#define ODN_BYPASS_CLK_TAPS_VALUE_MASK 0x000003FFU
+#define ODN_BYPASS_CLK_TAPS_VALUE_SHIFT 0
+#define ODN_BYPASS_CLK_TAPS_VALUE_SIGNED 0
+
+#define ODN_BYPASS_SET_MASK 0x00010000U
+#define ODN_BYPASS_SET_SHIFT 16
+#define ODN_BYPASS_SET_SIGNED 0
+
+#define ODN_BYPASS_EN_MASK 0x00100000U
+#define ODN_BYPASS_EN_SHIFT 20
+#define ODN_BYPASS_EN_SIGNED 0
+
+#define ODN_EN_STATUS_MASK 0x01000000U
+#define ODN_EN_STATUS_SHIFT 24
+#define ODN_EN_STATUS_SIGNED 0
+
+/*
+ Register SAI_CLK_TAPS
+*/
+#define ODN_SAI_RX_DEBUG_SAI_CLK_TAPS 0x000C
+#define ODN_CLK_TAPS_VALUE_MASK 0x000003FFU
+#define ODN_CLK_TAPS_VALUE_SHIFT 0
+#define ODN_CLK_TAPS_VALUE_SIGNED 0
+
+#define ODN_TRAINING_COMPLETE_MASK 0x00010000U
+#define ODN_TRAINING_COMPLETE_SHIFT 16
+#define ODN_TRAINING_COMPLETE_SIGNED 0
+
+/*
+ Register SAI_EYES
+*/
+#define ODN_SAI_RX_DEBUG_SAI_EYES 0x0010
+#define ODN_MIN_EYE_END_MASK 0x0000FFFFU
+#define ODN_MIN_EYE_END_SHIFT 0
+#define ODN_MIN_EYE_END_SIGNED 0
+
+#define ODN_MAX_EYE_START_MASK 0xFFFF0000U
+#define ODN_MAX_EYE_START_SHIFT 16
+#define ODN_MAX_EYE_START_SIGNED 0
+
+/*
+ Register SAI_DDR_INVERT
+*/
+#define ODN_SAI_RX_DEBUG_SAI_DDR_INVERT 0x0014
+#define ODN_DDR_INVERT_MASK 0x00000001U
+#define ODN_DDR_INVERT_SHIFT 0
+#define ODN_DDR_INVERT_SIGNED 0
+
+#define ODN_OVERIDE_VALUE_MASK 0x00010000U
+#define ODN_OVERIDE_VALUE_SHIFT 16
+#define ODN_OVERIDE_VALUE_SIGNED 0
+
+#define ODN_INVERT_OVERIDE_MASK 0x00100000U
+#define ODN_INVERT_OVERIDE_SHIFT 20
+#define ODN_INVERT_OVERIDE_SIGNED 0
+
+/*
+ Register SAI_TRAIN_ACK
+*/
+#define ODN_SAI_RX_DEBUG_SAI_TRAIN_ACK 0x0018
+#define ODN_TRAIN_ACK_FAIL_MASK 0x00000001U
+#define ODN_TRAIN_ACK_FAIL_SHIFT 0
+#define ODN_TRAIN_ACK_FAIL_SIGNED 0
+
+#define ODN_TRAIN_ACK_FAIL_COUNT_MASK 0x000000F0U
+#define ODN_TRAIN_ACK_FAIL_COUNT_SHIFT 4
+#define ODN_TRAIN_ACK_FAIL_COUNT_SIGNED 0
+
+#define ODN_TRAIN_ACK_COMPLETE_MASK 0x00000100U
+#define ODN_TRAIN_ACK_COMPLETE_SHIFT 8
+#define ODN_TRAIN_ACK_COMPLETE_SIGNED 0
+
+#define ODN_TRAIN_ACK_OVERIDE_MASK 0x00001000U
+#define ODN_TRAIN_ACK_OVERIDE_SHIFT 12
+#define ODN_TRAIN_ACK_OVERIDE_SIGNED 0
+
+/*
+ Register SAI_TRAIN_ACK_COUNT
+*/
+#define ODN_SAI_RX_DEBUG_SAI_TRAIN_ACK_COUNT 0x001C
+#define ODN_TRAIN_COUNT_MASK 0xFFFFFFFFU
+#define ODN_TRAIN_COUNT_SHIFT 0
+#define ODN_TRAIN_COUNT_SIGNED 0
+
+/*
+ Register SAI_CHANNEL_NUMBER
+*/
+#define ODN_SAI_RX_DEBUG_SAI_CHANNEL_NUMBER 0x0020
+#define ODN_CHANNEL_NUMBER_MASK 0x0000FFFFU
+#define ODN_CHANNEL_NUMBER_SHIFT 0
+#define ODN_CHANNEL_NUMBER_SIGNED 0
+
+/*
+ Register SAI_CHANNEL_EYE_START
+*/
+#define ODN_SAI_RX_DEBUG_SAI_CHANNEL_EYE_START 0x0024
+#define ODN_CHANNEL_EYE_START_MASK 0xFFFFFFFFU
+#define ODN_CHANNEL_EYE_START_SHIFT 0
+#define ODN_CHANNEL_EYE_START_SIGNED 0
+
+/*
+ Register SAI_CHANNEL_EYE_END
+*/
+#define ODN_SAI_RX_DEBUG_SAI_CHANNEL_EYE_END 0x0028
+#define ODN_CHANNEL_EYE_END_MASK 0xFFFFFFFFU
+#define ODN_CHANNEL_EYE_END_SHIFT 0
+#define ODN_CHANNEL_EYE_END_SIGNED 0
+
+/*
+ Register SAI_CHANNEL_EYE_PATTERN
+*/
+#define ODN_SAI_RX_DEBUG_SAI_CHANNEL_EYE_PATTERN 0x002C
+#define ODN_CHANNEL_EYE_PATTERN_MASK 0xFFFFFFFFU
+#define ODN_CHANNEL_EYE_PATTERN_SHIFT 0
+#define ODN_CHANNEL_EYE_PATTERN_SIGNED 0
+
+/*
+ Register SAI_CHANNEL_EYE_DEBUG
+*/
+#define ODN_SAI_RX_DEBUG_SAI_CHANNEL_EYE_DEBUG 0x0030
+#define ODN_CHANNEL_EYE_SENSE_MASK 0x00000001U
+#define ODN_CHANNEL_EYE_SENSE_SHIFT 0
+#define ODN_CHANNEL_EYE_SENSE_SIGNED 0
+
+#define ODN_CHANNEL_EYE_COMPLETE_MASK 0x00000002U
+#define ODN_CHANNEL_EYE_COMPLETE_SHIFT 1
+#define ODN_CHANNEL_EYE_COMPLETE_SIGNED 0
+
+
+/*********************************
+ Generated from: sai_tx_debug.def
+**********************************/
+
+/*
+ Register SIG_RESULT
+*/
+#define ODN_SAI_TX_DEBUG_SIG_RESULT 0x0000
+#define ODN_TX_SIG_RESULT_VALUE_MASK 0xFFFFFFFFU
+#define ODN_TX_SIG_RESULT_VALUE_SHIFT 0
+#define ODN_TX_SIG_RESULT_VALUE_SIGNED 0
+
+/*
+ Register INIT_SIG
+*/
+#define ODN_SAI_TX_DEBUG_INIT_SIG 0x0004
+#define ODN_TX_INIT_SIG_VALUE_MASK 0x00000001U
+#define ODN_TX_INIT_SIG_VALUE_SHIFT 0
+#define ODN_TX_INIT_SIG_VALUE_SIGNED 0
+
+/*
+ Register SAI_BYPASS
+*/
+#define ODN_SAI_TX_DEBUG_SAI_BYPASS 0x0008
+#define ODN_TX_BYPASS_EN_MASK 0x00000001U
+#define ODN_TX_BYPASS_EN_SHIFT 0
+#define ODN_TX_BYPASS_EN_SIGNED 0
+
+#define ODN_TX_ACK_RESEND_MASK 0x00000002U
+#define ODN_TX_ACK_RESEND_SHIFT 1
+#define ODN_TX_ACK_RESEND_SIGNED 0
+
+#define ODN_TX_DISABLE_ACK_SEND_MASK 0x00000004U
+#define ODN_TX_DISABLE_ACK_SEND_SHIFT 2
+#define ODN_TX_DISABLE_ACK_SEND_SIGNED 0
+
+/*
+ Register SAI_STATUS
+*/
+#define ODN_SAI_TX_DEBUG_SAI_STATUS 0x000C
+#define ODN_TX_TRAINING_COMPLETE_MASK 0x00000001U
+#define ODN_TX_TRAINING_COMPLETE_SHIFT 0
+#define ODN_TX_TRAINING_COMPLETE_SIGNED 0
+
+#define ODN_TX_TRAINING_ACK_COMPLETE_MASK 0x00000002U
+#define ODN_TX_TRAINING_ACK_COMPLETE_SHIFT 1
+#define ODN_TX_TRAINING_ACK_COMPLETE_SIGNED 0
+
+
+
+#endif /* _ODIN_REGS_H_ */
+
+/******************************************************************************
+ End of file (odin_regs.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/system/rgx_tc/orion_defs.h b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/orion_defs.h
new file mode 100644
index 000000000..1691151de
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/orion_defs.h
@@ -0,0 +1,183 @@
+/****************************************************************************
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Orion Memory Map - View from PCIe
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+****************************************************************************/
+
+#ifndef _ORION_DEFS_H_
+#define _ORION_DEFS_H_
+
+/*
+ * These defines have not been autogenerated
+ * Only values different from Odin will be included here
+ */
+
+#define DEVICE_ID_ORION 0x1020
+
+/* Odin system register banks */
+#define SRS_REG_BANK_ODN_CLK_BLK 0x02000
+
+/*
+ * Orion CLK regs - the srs_clk_blk module defs are not auto generated
+ */
+#define SRS_PDP_P_CLK_OUT_DIVIDER_REG1 0x620
+#define SRS_PDP_PCLK_ODIV1_LO_TIME_MASK 0x0000003FU
+#define SRS_PDP_PCLK_ODIV1_LO_TIME_SHIFT 0
+#define SRS_PDP_PCLK_ODIV1_HI_TIME_MASK 0x00000FC0U
+#define SRS_PDP_PCLK_ODIV1_HI_TIME_SHIFT 6
+
+#define SRS_PDP_P_CLK_OUT_DIVIDER_REG2 0x624
+#define SRS_PDP_PCLK_ODIV2_NOCOUNT_MASK 0x00000040U
+#define SRS_PDP_PCLK_ODIV2_NOCOUNT_SHIFT 6
+#define SRS_PDP_PCLK_ODIV2_EDGE_MASK 0x00000080U
+#define SRS_PDP_PCLK_ODIV2_EDGE_SHIFT 7
+#define SRS_PDP_PCLK_ODIV2_FRAC_MASK 0x00007C00U
+#define SRS_PDP_PCLK_ODIV2_FRAC_SHIFT 10
+
+#define SRS_PDP_P_CLK_OUT_DIVIDER_REG3 0x61C
+
+#define SRS_PDP_M_CLK_OUT_DIVIDER_REG1 0x628
+#define SRS_PDP_MCLK_ODIV1_LO_TIME_MASK 0x0000003FU
+#define SRS_PDP_MCLK_ODIV1_LO_TIME_SHIFT 0
+#define SRS_PDP_MCLK_ODIV1_HI_TIME_MASK 0x00000FC0U
+#define SRS_PDP_MCLK_ODIV1_HI_TIME_SHIFT 6
+
+#define SRS_PDP_M_CLK_OUT_DIVIDER_REG2 0x62C
+#define SRS_PDP_MCLK_ODIV2_NOCOUNT_MASK 0x00000040U
+#define SRS_PDP_MCLK_ODIV2_NOCOUNT_SHIFT 6
+#define SRS_PDP_MCLK_ODIV2_EDGE_MASK 0x00000080U
+#define SRS_PDP_MCLK_ODIV2_EDGE_SHIFT 7
+
+#define SRS_PDP_P_CLK_MULTIPLIER_REG1 0x650
+#define SRS_PDP_PCLK_MUL1_LO_TIME_MASK 0x0000003FU
+#define SRS_PDP_PCLK_MUL1_LO_TIME_SHIFT 0
+#define SRS_PDP_PCLK_MUL1_HI_TIME_MASK 0x00000FC0U
+#define SRS_PDP_PCLK_MUL1_HI_TIME_SHIFT 6
+
+#define SRS_PDP_P_CLK_MULTIPLIER_REG2 0x654
+#define SRS_PDP_PCLK_MUL2_NOCOUNT_MASK 0x00000040U
+#define SRS_PDP_PCLK_MUL2_NOCOUNT_SHIFT 6
+#define SRS_PDP_PCLK_MUL2_EDGE_MASK 0x00000080U
+#define SRS_PDP_PCLK_MUL2_EDGE_SHIFT 7
+#define SRS_PDP_PCLK_MUL2_FRAC_MASK 0x00007C00U
+#define SRS_PDP_PCLK_MUL2_FRAC_SHIFT 10
+
+#define SRS_PDP_P_CLK_MULTIPLIER_REG3 0x64C
+
+#define SRS_PDP_P_CLK_IN_DIVIDER_REG 0x658
+#define SRS_PDP_PCLK_IDIV_LO_TIME_MASK 0x0000003FU
+#define SRS_PDP_PCLK_IDIV_LO_TIME_SHIFT 0
+#define SRS_PDP_PCLK_IDIV_HI_TIME_MASK 0x00000FC0U
+#define SRS_PDP_PCLK_IDIV_HI_TIME_SHIFT 6
+#define SRS_PDP_PCLK_IDIV_NOCOUNT_MASK 0x00001000U
+#define SRS_PDP_PCLK_IDIV_NOCOUNT_SHIFT 12
+#define SRS_PDP_PCLK_IDIV_EDGE_MASK 0x00002000U
+#define SRS_PDP_PCLK_IDIV_EDGE_SHIFT 13
+
+/*
+ * DUT core clock input divider, DUT reference clock input divider
+ */
+#define SRS_DUT_CORE_CLK_OUT_DIVIDER1 0x0020
+#define SRS_DUT_CORE_CLK_OUT_DIVIDER1_HI_TIME_MASK 0x00000FC0U
+#define SRS_DUT_CORE_CLK_OUT_DIVIDER1_HI_TIME_SHIFT 6
+#define SRS_DUT_CORE_CLK_OUT_DIVIDER1_LO_TIME_MASK 0x0000003FU
+#define SRS_DUT_CORE_CLK_OUT_DIVIDER1_LO_TIME_SHIFT 0
+
+#define SRS_DUT_CORE_CLK_OUT_DIVIDER2 0x0024
+#define SRS_DUT_CORE_CLK_OUT_DIVIDER2_EDGE_MASK 0x00000080U
+#define SRS_DUT_CORE_CLK_OUT_DIVIDER2_EDGE_SHIFT 7
+#define SRS_DUT_CORE_CLK_OUT_DIVIDER2_NOCOUNT_MASK 0x00000040U
+#define SRS_DUT_CORE_CLK_OUT_DIVIDER2_NOCOUNT_SHIFT 6
+
+#define SRS_DUT_REF_CLK_OUT_DIVIDER1 0x0028
+#define SRS_DUT_REF_CLK_OUT_DIVIDER1_HI_TIME_MASK 0x00000FC0U
+#define SRS_DUT_REF_CLK_OUT_DIVIDER1_HI_TIME_SHIFT 6
+#define SRS_DUT_REF_CLK_OUT_DIVIDER1_LO_TIME_MASK 0x0000003FU
+#define SRS_DUT_REF_CLK_OUT_DIVIDER1_LO_TIME_SHIFT 0
+
+#define SRS_DUT_REF_CLK_OUT_DIVIDER2 0x002C
+#define SRS_DUT_REF_CLK_OUT_DIVIDER2_EDGE_MASK 0x00000080U
+#define SRS_DUT_REF_CLK_OUT_DIVIDER2_EDGE_SHIFT 7
+#define SRS_DUT_REF_CLK_OUT_DIVIDER2_NOCOUNT_MASK 0x00000040U
+#define SRS_DUT_REF_CLK_OUT_DIVIDER2_NOCOUNT_SHIFT 6
+
+/*
+ * DUT interface reference clock input divider
+ */
+
+#define SRS_DUT_MEM_CLK_OUT_DIVIDER1 0x0228
+#define SRS_DUT_MEM_CLK_OUT_DIVIDER1_HI_TIME_MASK 0x00000FC0U
+#define SRS_DUT_MEM_CLK_OUT_DIVIDER1_HI_TIME_SHIFT 6
+#define SRS_DUT_MEM_CLK_OUT_DIVIDER1_LO_TIME_MASK 0x0000003FU
+#define SRS_DUT_MEM_CLK_OUT_DIVIDER1_LO_TIME_SHIFT 0
+
+#define SRS_DUT_MEM_CLK_OUT_DIVIDER2 0x022C
+#define SRS_DUT_MEM_CLK_OUT_DIVIDER2_EDGE_MASK 0x00000080U
+#define SRS_DUT_MEM_CLK_OUT_DIVIDER2_EDGE_SHIFT 7
+#define SRS_DUT_MEM_CLK_OUT_DIVIDER2_NOCOUNT_MASK 0x00000040U
+#define SRS_DUT_MEM_CLK_OUT_DIVIDER2_NOCOUNT_SHIFT 6
+
+/*
+ * Min max values from Xilinx Virtex Ultrascale data sheet DS893,
+ * for speed grade 1. All in Hz.
+ */
+#define SRS_INPUT_CLOCK_SPEED 100000000U
+#define SRS_INPUT_CLOCK_SPEED_MIN 10000000U
+#define SRS_INPUT_CLOCK_SPEED_MAX 800000000U
+#define SRS_OUTPUT_CLOCK_SPEED_MIN 4690000U
+#define SRS_OUTPUT_CLOCK_SPEED_MAX 630000000U
+#define SRS_VCO_MIN 600000000U
+#define SRS_VCO_MAX 1200000000U
+#define SRS_PFD_MIN 10000000U
+#define SRS_PFD_MAX 450000000U
+
+/*
+ * Orion interrupt flags
+ */
+#define SRS_INTERRUPT_ENABLE_PDP1 (1 << SRS_INTERRUPT_ENABLE_PDP_SHIFT)
+#define SRS_INTERRUPT_ENABLE_DUT (1 << SRS_INTERRUPT_ENABLE_DUT_SHIFT)
+#define SRS_INTERRUPT_STATUS_PDP1 (1 << SRS_INTERRUPT_STATUS_PDP_SHIFT)
+#define SRS_INTERRUPT_STATUS_DUT (1 << SRS_INTERRUPT_STATUS_DUT_SHIFT)
+#define SRS_INTERRUPT_CLEAR_PDP1 (1 << SRS_INTERRUPT_CLR_PDP_SHIFT)
+#define SRS_INTERRUPT_CLEAR_DUT (1 << SRS_INTERRUPT_CLR_DUT_SHIFT)
+
+#endif /* _ORION_DEFS_H_ */
+
+/*****************************************************************************
+ End of file (orion_defs.h)
+*****************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/system/rgx_tc/orion_regs.h b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/orion_regs.h
new file mode 100644
index 000000000..2a626bd2b
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/orion_regs.h
@@ -0,0 +1,439 @@
+/******************************************************************************
+@Title Orion system control register definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Orion FPGA register defs for Sirius RTL
+@Author Autogenerated
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+******************************************************************************/
+
+#ifndef _OUT_DRV_H_
+#define _OUT_DRV_H_
+
+/*
+ Register ID
+*/
+#define SRS_CORE_ID 0x0000
+#define SRS_ID_VARIANT_MASK 0x0000FFFFU
+#define SRS_ID_VARIANT_SHIFT 0
+#define SRS_ID_VARIANT_SIGNED 0
+
+#define SRS_ID_ID_MASK 0xFFFF0000U
+#define SRS_ID_ID_SHIFT 16
+#define SRS_ID_ID_SIGNED 0
+
+/*
+ Register REVISION
+*/
+#define SRS_CORE_REVISION 0x0004
+#define SRS_REVISION_MINOR_MASK 0x000000FFU
+#define SRS_REVISION_MINOR_SHIFT 0
+#define SRS_REVISION_MINOR_SIGNED 0
+
+#define SRS_REVISION_MAJOR_MASK 0x00000F00U
+#define SRS_REVISION_MAJOR_SHIFT 8
+#define SRS_REVISION_MAJOR_SIGNED 0
+
+/*
+ Register CHANGE_SET
+*/
+#define SRS_CORE_CHANGE_SET 0x0008
+#define SRS_CHANGE_SET_SET_MASK 0xFFFFFFFFU
+#define SRS_CHANGE_SET_SET_SHIFT 0
+#define SRS_CHANGE_SET_SET_SIGNED 0
+
+/*
+ Register USER_ID
+*/
+#define SRS_CORE_USER_ID 0x000C
+#define SRS_USER_ID_ID_MASK 0x0000000FU
+#define SRS_USER_ID_ID_SHIFT 0
+#define SRS_USER_ID_ID_SIGNED 0
+
+/*
+ Register USER_BUILD
+*/
+#define SRS_CORE_USER_BUILD 0x0010
+#define SRS_USER_BUILD_BUILD_MASK 0xFFFFFFFFU
+#define SRS_USER_BUILD_BUILD_SHIFT 0
+#define SRS_USER_BUILD_BUILD_SIGNED 0
+
+/*
+ Register SOFT_RESETN
+*/
+#define SRS_CORE_SOFT_RESETN 0x0080
+#define SRS_SOFT_RESETN_DDR_MASK 0x00000001U
+#define SRS_SOFT_RESETN_DDR_SHIFT 0
+#define SRS_SOFT_RESETN_DDR_SIGNED 0
+
+#define SRS_SOFT_RESETN_USB_MASK 0x00000002U
+#define SRS_SOFT_RESETN_USB_SHIFT 1
+#define SRS_SOFT_RESETN_USB_SIGNED 0
+
+#define SRS_SOFT_RESETN_PDP_MASK 0x00000004U
+#define SRS_SOFT_RESETN_PDP_SHIFT 2
+#define SRS_SOFT_RESETN_PDP_SIGNED 0
+
+#define SRS_SOFT_RESETN_GIST_MASK 0x00000008U
+#define SRS_SOFT_RESETN_GIST_SHIFT 3
+#define SRS_SOFT_RESETN_GIST_SIGNED 0
+
+/*
+ Register DUT_SOFT_RESETN
+*/
+#define SRS_CORE_DUT_SOFT_RESETN 0x0084
+#define SRS_DUT_SOFT_RESETN_EXTERNAL_MASK 0x00000001U
+#define SRS_DUT_SOFT_RESETN_EXTERNAL_SHIFT 0
+#define SRS_DUT_SOFT_RESETN_EXTERNAL_SIGNED 0
+
+/*
+ Register SOFT_AUTO_RESETN
+*/
+#define SRS_CORE_SOFT_AUTO_RESETN 0x0088
+#define SRS_SOFT_AUTO_RESETN_CFG_MASK 0x00000001U
+#define SRS_SOFT_AUTO_RESETN_CFG_SHIFT 0
+#define SRS_SOFT_AUTO_RESETN_CFG_SIGNED 0
+
+/*
+ Register CLK_GEN_RESET
+*/
+#define SRS_CORE_CLK_GEN_RESET 0x0090
+#define SRS_CLK_GEN_RESET_DUT_CORE_MMCM_MASK 0x00000001U
+#define SRS_CLK_GEN_RESET_DUT_CORE_MMCM_SHIFT 0
+#define SRS_CLK_GEN_RESET_DUT_CORE_MMCM_SIGNED 0
+
+#define SRS_CLK_GEN_RESET_DUT_IF_MMCM_MASK 0x00000002U
+#define SRS_CLK_GEN_RESET_DUT_IF_MMCM_SHIFT 1
+#define SRS_CLK_GEN_RESET_DUT_IF_MMCM_SIGNED 0
+
+#define SRS_CLK_GEN_RESET_MULTI_MMCM_MASK 0x00000004U
+#define SRS_CLK_GEN_RESET_MULTI_MMCM_SHIFT 2
+#define SRS_CLK_GEN_RESET_MULTI_MMCM_SIGNED 0
+
+#define SRS_CLK_GEN_RESET_PDP_MMCM_MASK 0x00000008U
+#define SRS_CLK_GEN_RESET_PDP_MMCM_SHIFT 3
+#define SRS_CLK_GEN_RESET_PDP_MMCM_SIGNED 0
+
+/*
+ Register DUT_MEM
+*/
+#define SRS_CORE_DUT_MEM 0x0120
+#define SRS_DUT_MEM_READ_RESPONSE_LATENCY_MASK 0x0000FFFFU
+#define SRS_DUT_MEM_READ_RESPONSE_LATENCY_SHIFT 0
+#define SRS_DUT_MEM_READ_RESPONSE_LATENCY_SIGNED 0
+
+#define SRS_DUT_MEM_WRITE_RESPONSE_LATENCY_MASK 0xFFFF0000U
+#define SRS_DUT_MEM_WRITE_RESPONSE_LATENCY_SHIFT 16
+#define SRS_DUT_MEM_WRITE_RESPONSE_LATENCY_SIGNED 0
+
+/*
+ Register APM
+*/
+#define SRS_CORE_APM 0x0150
+#define SRS_APM_RESET_EVENT_MASK 0x00000001U
+#define SRS_APM_RESET_EVENT_SHIFT 0
+#define SRS_APM_RESET_EVENT_SIGNED 0
+
+#define SRS_APM_CAPTURE_EVENT_MASK 0x00000002U
+#define SRS_APM_CAPTURE_EVENT_SHIFT 1
+#define SRS_APM_CAPTURE_EVENT_SIGNED 0
+
+/*
+ Register NUM_GPIO
+*/
+#define SRS_CORE_NUM_GPIO 0x0180
+#define SRS_NUM_GPIO_NUMBER_MASK 0x0000000FU
+#define SRS_NUM_GPIO_NUMBER_SHIFT 0
+#define SRS_NUM_GPIO_NUMBER_SIGNED 0
+
+/*
+ Register GPIO_EN
+*/
+#define SRS_CORE_GPIO_EN 0x0184
+#define SRS_GPIO_EN_DIRECTION_MASK 0x000000FFU
+#define SRS_GPIO_EN_DIRECTION_SHIFT 0
+#define SRS_GPIO_EN_DIRECTION_SIGNED 0
+
+/*
+ Register GPIO
+*/
+#define SRS_CORE_GPIO 0x0188
+#define SRS_GPIO_GPIO_MASK 0x000000FFU
+#define SRS_GPIO_GPIO_SHIFT 0
+#define SRS_GPIO_GPIO_SIGNED 0
+
+/*
+ Register SPI_MASTER_IFACE
+*/
+#define SRS_CORE_SPI_MASTER_IFACE 0x018C
+#define SRS_SPI_MASTER_IFACE_ENABLE_MASK 0x00000001U
+#define SRS_SPI_MASTER_IFACE_ENABLE_SHIFT 0
+#define SRS_SPI_MASTER_IFACE_ENABLE_SIGNED 0
+
+/*
+ Register SRS_IP_STATUS
+*/
+#define SRS_CORE_SRS_IP_STATUS 0x0200
+#define SRS_SRS_IP_STATUS_PCIE_USER_LNK_UP_MASK 0x00000001U
+#define SRS_SRS_IP_STATUS_PCIE_USER_LNK_UP_SHIFT 0
+#define SRS_SRS_IP_STATUS_PCIE_USER_LNK_UP_SIGNED 0
+
+#define SRS_SRS_IP_STATUS_MIG_INIT_CALIB_COMPLETE_MASK 0x00000002U
+#define SRS_SRS_IP_STATUS_MIG_INIT_CALIB_COMPLETE_SHIFT 1
+#define SRS_SRS_IP_STATUS_MIG_INIT_CALIB_COMPLETE_SIGNED 0
+
+#define SRS_SRS_IP_STATUS_GIST_SLV_C2C_CONFIG_ERROR_OUT_MASK 0x00000004U
+#define SRS_SRS_IP_STATUS_GIST_SLV_C2C_CONFIG_ERROR_OUT_SHIFT 2
+#define SRS_SRS_IP_STATUS_GIST_SLV_C2C_CONFIG_ERROR_OUT_SIGNED 0
+
+#define SRS_SRS_IP_STATUS_GIST_MST_C2C_CONFIG_ERROR_OUT_MASK 0x00000008U
+#define SRS_SRS_IP_STATUS_GIST_MST_C2C_CONFIG_ERROR_OUT_SHIFT 3
+#define SRS_SRS_IP_STATUS_GIST_MST_C2C_CONFIG_ERROR_OUT_SIGNED 0
+
+/*
+ Register CORE_CONTROL
+*/
+#define SRS_CORE_CORE_CONTROL 0x0204
+#define SRS_CORE_CONTROL_BAR4_OFFSET_MASK 0x0000001FU
+#define SRS_CORE_CONTROL_BAR4_OFFSET_SHIFT 0
+#define SRS_CORE_CONTROL_BAR4_OFFSET_SIGNED 0
+
+#define SRS_CORE_CONTROL_HDMI_MONITOR_OVERRIDE_MASK 0x00000300U
+#define SRS_CORE_CONTROL_HDMI_MONITOR_OVERRIDE_SHIFT 8
+#define SRS_CORE_CONTROL_HDMI_MONITOR_OVERRIDE_SIGNED 0
+
+#define SRS_CORE_CONTROL_HDMI_MODULE_EN_MASK 0x00001C00U
+#define SRS_CORE_CONTROL_HDMI_MODULE_EN_SHIFT 10
+#define SRS_CORE_CONTROL_HDMI_MODULE_EN_SIGNED 0
+
+/*
+ Register REG_BANK_STATUS
+*/
+#define SRS_CORE_REG_BANK_STATUS 0x0208
+#define SRS_REG_BANK_STATUS_ARB_SLV_RD_TIMEOUT_MASK 0xFFFFFFFFU
+#define SRS_REG_BANK_STATUS_ARB_SLV_RD_TIMEOUT_SHIFT 0
+#define SRS_REG_BANK_STATUS_ARB_SLV_RD_TIMEOUT_SIGNED 0
+
+/*
+ Register MMCM_LOCK_STATUS
+*/
+#define SRS_CORE_MMCM_LOCK_STATUS 0x020C
+#define SRS_MMCM_LOCK_STATUS_DUT_CORE_MASK 0x00000001U
+#define SRS_MMCM_LOCK_STATUS_DUT_CORE_SHIFT 0
+#define SRS_MMCM_LOCK_STATUS_DUT_CORE_SIGNED 0
+
+#define SRS_MMCM_LOCK_STATUS_DUT_IF_MASK 0x00000002U
+#define SRS_MMCM_LOCK_STATUS_DUT_IF_SHIFT 1
+#define SRS_MMCM_LOCK_STATUS_DUT_IF_SIGNED 0
+
+#define SRS_MMCM_LOCK_STATUS_MULTI_MASK 0x00000004U
+#define SRS_MMCM_LOCK_STATUS_MULTI_SHIFT 2
+#define SRS_MMCM_LOCK_STATUS_MULTI_SIGNED 0
+
+#define SRS_MMCM_LOCK_STATUS_PDP_MASK 0x00000008U
+#define SRS_MMCM_LOCK_STATUS_PDP_SHIFT 3
+#define SRS_MMCM_LOCK_STATUS_PDP_SIGNED 0
+
+/*
+ Register GIST_STATUS
+*/
+#define SRS_CORE_GIST_STATUS 0x0210
+#define SRS_GIST_STATUS_MST_MASK 0x000001FFU
+#define SRS_GIST_STATUS_MST_SHIFT 0
+#define SRS_GIST_STATUS_MST_SIGNED 0
+
+#define SRS_GIST_STATUS_SLV_MASK 0x001FF000U
+#define SRS_GIST_STATUS_SLV_SHIFT 12
+#define SRS_GIST_STATUS_SLV_SIGNED 0
+
+#define SRS_GIST_STATUS_SLV_OUT_MASK 0x03000000U
+#define SRS_GIST_STATUS_SLV_OUT_SHIFT 24
+#define SRS_GIST_STATUS_SLV_OUT_SIGNED 0
+
+#define SRS_GIST_STATUS_MST_OUT_MASK 0x70000000U
+#define SRS_GIST_STATUS_MST_OUT_SHIFT 28
+#define SRS_GIST_STATUS_MST_OUT_SIGNED 0
+
+/*
+ Register SENSOR_BOARD
+*/
+#define SRS_CORE_SENSOR_BOARD 0x0214
+#define SRS_SENSOR_BOARD_ID_MASK 0x00000003U
+#define SRS_SENSOR_BOARD_ID_SHIFT 0
+#define SRS_SENSOR_BOARD_ID_SIGNED 0
+
+/*
+ Register INTERRUPT_STATUS
+*/
+#define SRS_CORE_INTERRUPT_STATUS 0x0218
+#define SRS_INTERRUPT_STATUS_DUT_MASK 0x00000001U
+#define SRS_INTERRUPT_STATUS_DUT_SHIFT 0
+#define SRS_INTERRUPT_STATUS_DUT_SIGNED 0
+
+#define SRS_INTERRUPT_STATUS_PDP_MASK 0x00000002U
+#define SRS_INTERRUPT_STATUS_PDP_SHIFT 1
+#define SRS_INTERRUPT_STATUS_PDP_SIGNED 0
+
+#define SRS_INTERRUPT_STATUS_I2C_MASK 0x00000004U
+#define SRS_INTERRUPT_STATUS_I2C_SHIFT 2
+#define SRS_INTERRUPT_STATUS_I2C_SIGNED 0
+
+#define SRS_INTERRUPT_STATUS_SPI_MASK 0x00000008U
+#define SRS_INTERRUPT_STATUS_SPI_SHIFT 3
+#define SRS_INTERRUPT_STATUS_SPI_SIGNED 0
+
+#define SRS_INTERRUPT_STATUS_APM_MASK 0x00000010U
+#define SRS_INTERRUPT_STATUS_APM_SHIFT 4
+#define SRS_INTERRUPT_STATUS_APM_SIGNED 0
+
+#define SRS_INTERRUPT_STATUS_OS_IRQ_MASK 0x00001FE0U
+#define SRS_INTERRUPT_STATUS_OS_IRQ_SHIFT 5
+#define SRS_INTERRUPT_STATUS_OS_IRQ_SIGNED 0
+
+#define SRS_INTERRUPT_STATUS_IRQ_TEST_MASK 0x40000000U
+#define SRS_INTERRUPT_STATUS_IRQ_TEST_SHIFT 30
+#define SRS_INTERRUPT_STATUS_IRQ_TEST_SIGNED 0
+
+#define SRS_INTERRUPT_STATUS_MASTER_STATUS_MASK 0x80000000U
+#define SRS_INTERRUPT_STATUS_MASTER_STATUS_SHIFT 31
+#define SRS_INTERRUPT_STATUS_MASTER_STATUS_SIGNED 0
+
+/*
+ Register INTERRUPT_ENABLE
+*/
+#define SRS_CORE_INTERRUPT_ENABLE 0x021C
+#define SRS_INTERRUPT_ENABLE_DUT_MASK 0x00000001U
+#define SRS_INTERRUPT_ENABLE_DUT_SHIFT 0
+#define SRS_INTERRUPT_ENABLE_DUT_SIGNED 0
+
+#define SRS_INTERRUPT_ENABLE_PDP_MASK 0x00000002U
+#define SRS_INTERRUPT_ENABLE_PDP_SHIFT 1
+#define SRS_INTERRUPT_ENABLE_PDP_SIGNED 0
+
+#define SRS_INTERRUPT_ENABLE_I2C_MASK 0x00000004U
+#define SRS_INTERRUPT_ENABLE_I2C_SHIFT 2
+#define SRS_INTERRUPT_ENABLE_I2C_SIGNED 0
+
+#define SRS_INTERRUPT_ENABLE_SPI_MASK 0x00000008U
+#define SRS_INTERRUPT_ENABLE_SPI_SHIFT 3
+#define SRS_INTERRUPT_ENABLE_SPI_SIGNED 0
+
+#define SRS_INTERRUPT_ENABLE_APM_MASK 0x00000010U
+#define SRS_INTERRUPT_ENABLE_APM_SHIFT 4
+#define SRS_INTERRUPT_ENABLE_APM_SIGNED 0
+
+#define SRS_INTERRUPT_ENABLE_OS_IRQ_MASK 0x00001FE0U
+#define SRS_INTERRUPT_ENABLE_OS_IRQ_SHIFT 5
+#define SRS_INTERRUPT_ENABLE_OS_IRQ_SIGNED 0
+
+#define SRS_INTERRUPT_ENABLE_IRQ_TEST_MASK 0x40000000U
+#define SRS_INTERRUPT_ENABLE_IRQ_TEST_SHIFT 30
+#define SRS_INTERRUPT_ENABLE_IRQ_TEST_SIGNED 0
+
+#define SRS_INTERRUPT_ENABLE_MASTER_ENABLE_MASK 0x80000000U
+#define SRS_INTERRUPT_ENABLE_MASTER_ENABLE_SHIFT 31
+#define SRS_INTERRUPT_ENABLE_MASTER_ENABLE_SIGNED 0
+
+/*
+ Register INTERRUPT_CLR
+*/
+#define SRS_CORE_INTERRUPT_CLR 0x0220
+#define SRS_INTERRUPT_CLR_DUT_MASK 0x00000001U
+#define SRS_INTERRUPT_CLR_DUT_SHIFT 0
+#define SRS_INTERRUPT_CLR_DUT_SIGNED 0
+
+#define SRS_INTERRUPT_CLR_PDP_MASK 0x00000002U
+#define SRS_INTERRUPT_CLR_PDP_SHIFT 1
+#define SRS_INTERRUPT_CLR_PDP_SIGNED 0
+
+#define SRS_INTERRUPT_CLR_I2C_MASK 0x00000004U
+#define SRS_INTERRUPT_CLR_I2C_SHIFT 2
+#define SRS_INTERRUPT_CLR_I2C_SIGNED 0
+
+#define SRS_INTERRUPT_CLR_SPI_MASK 0x00000008U
+#define SRS_INTERRUPT_CLR_SPI_SHIFT 3
+#define SRS_INTERRUPT_CLR_SPI_SIGNED 0
+
+#define SRS_INTERRUPT_CLR_APM_MASK 0x00000010U
+#define SRS_INTERRUPT_CLR_APM_SHIFT 4
+#define SRS_INTERRUPT_CLR_APM_SIGNED 0
+
+#define SRS_INTERRUPT_CLR_OS_IRQ_MASK 0x00001FE0U
+#define SRS_INTERRUPT_CLR_OS_IRQ_SHIFT 5
+#define SRS_INTERRUPT_CLR_OS_IRQ_SIGNED 0
+
+#define SRS_INTERRUPT_CLR_IRQ_TEST_MASK 0x40000000U
+#define SRS_INTERRUPT_CLR_IRQ_TEST_SHIFT 30
+#define SRS_INTERRUPT_CLR_IRQ_TEST_SIGNED 0
+
+#define SRS_INTERRUPT_CLR_MASTER_CLEAR_MASK 0x80000000U
+#define SRS_INTERRUPT_CLR_MASTER_CLEAR_SHIFT 31
+#define SRS_INTERRUPT_CLR_MASTER_CLEAR_SIGNED 0
+
+/*
+ Register INTERRUPT_TEST
+*/
+#define SRS_CORE_INTERRUPT_TEST 0x0224
+#define SRS_INTERRUPT_TEST_INTERRUPT_TEST_MASK 0x00000001U
+#define SRS_INTERRUPT_TEST_INTERRUPT_TEST_SHIFT 0
+#define SRS_INTERRUPT_TEST_INTERRUPT_TEST_SIGNED 0
+
+/*
+ Register INTERRUPT_TIMEOUT_CLR
+*/
+#define SRS_CORE_INTERRUPT_TIMEOUT_CLR 0x0228
+#define SRS_INTERRUPT_TIMEOUT_CLR_INTERRUPT_MST_TIMEOUT_CLR_MASK 0x00000002U
+#define SRS_INTERRUPT_TIMEOUT_CLR_INTERRUPT_MST_TIMEOUT_CLR_SHIFT 1
+#define SRS_INTERRUPT_TIMEOUT_CLR_INTERRUPT_MST_TIMEOUT_CLR_SIGNED 0
+
+#define SRS_INTERRUPT_TIMEOUT_CLR_INTERRUPT_MST_TIMEOUT_MASK 0x00000001U
+#define SRS_INTERRUPT_TIMEOUT_CLR_INTERRUPT_MST_TIMEOUT_SHIFT 0
+#define SRS_INTERRUPT_TIMEOUT_CLR_INTERRUPT_MST_TIMEOUT_SIGNED 0
+
+/*
+ Register INTERRUPT_TIMEOUT
+*/
+#define SRS_CORE_INTERRUPT_TIMEOUT 0x022C
+#define SRS_INTERRUPT_TIMEOUT_INTERRUPT_TIMEOUT_THRESHOLD_COUNTER_MASK 0xFFFFFFFFU
+#define SRS_INTERRUPT_TIMEOUT_INTERRUPT_TIMEOUT_THRESHOLD_COUNTER_SHIFT 0
+#define SRS_INTERRUPT_TIMEOUT_INTERRUPT_TIMEOUT_THRESHOLD_COUNTER_SIGNED 0
+
+#endif /* _OUT_DRV_H_ */
+
+/******************************************************************************
+ End of file (orion_regs.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/system/rgx_tc/pdp_regs.h b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/pdp_regs.h
new file mode 100644
index 000000000..bd26b0617
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/pdp_regs.h
@@ -0,0 +1,75 @@
+/*************************************************************************/ /*!
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__PDP_REGS_H__)
+#define __PDP_REGS_H__
+
+/*************************************************************************/ /*!
+ PCI Device Information
+*/ /**************************************************************************/
+
+#define DCPDP_VENDOR_ID_POWERVR (0x1010)
+
+#define DCPDP_DEVICE_ID_PCI_APOLLO_FPGA (0x1CF1)
+#define DCPDP_DEVICE_ID_PCIE_APOLLO_FPGA (0x1CF2)
+
+/*************************************************************************/ /*!
+ PCI Device Base Address Information
+*/ /**************************************************************************/
+
+/* PLL and PDP registers on base address register 0 */
+#define DCPDP_REG_PCI_BASENUM (0)
+
+#define DCPDP_PCI_PLL_REG_OFFSET (0x1000)
+#define DCPDP_PCI_PLL_REG_SIZE (0x0400)
+
+#define DCPDP_PCI_PDP_REG_OFFSET (0xC000)
+#define DCPDP_PCI_PDP_REG_SIZE (0x2000)
+
+/*************************************************************************/ /*!
+ Misc register information
+*/ /**************************************************************************/
+
+/* This information isn't captured in tcf_rgbpdp_regs.h so define it here */
+#define DCPDP_STR1SURF_FORMAT_ARGB8888 (0xE)
+#define DCPDP_STR1ADDRCTRL_BASE_ADDR_SHIFT (4)
+#define DCPDP_STR1POSN_STRIDE_SHIFT (4)
+
+#endif /* !defined(__PDP_REGS_H__) */
diff --git a/drivers/gpu/drm/img-rogue/include/system/rgx_tc/pfim_defs.h b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/pfim_defs.h
new file mode 100644
index 000000000..d39c06f70
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/pfim_defs.h
@@ -0,0 +1,69 @@
+/******************************************************************************
+@Title Odin PFIM definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Odin register defs for PDP-FBDC Interface Module
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+******************************************************************************/
+
+#ifndef _PFIM_DEFS_H_
+#define _PFIM_DEFS_H_
+
+/* Supported FBC modes */
+#define ODIN_PFIM_MOD_LINEAR (0x00)
+#define ODIN_PFIM_FBCDC_8X8_V12 (0x01)
+#define ODIN_PFIM_FBCDC_16X4_V12 (0x02)
+#define ODIN_PFIM_FBCDC_MAX (0x03)
+
+/* Supported pixel formats */
+#define ODN_PFIM_PIXFMT_NONE (0x00)
+#define ODN_PFIM_PIXFMT_ARGB8888 (0x0C)
+#define ODN_PFIM_PIXFMT_RGB565 (0x05)
+
+/* Tile types */
+#define ODN_PFIM_TILETYPE_8X8 (0x01)
+#define ODN_PFIM_TILETYPE_16X4 (0x02)
+#define ODN_PFIM_TILETYPE_32x2 (0x03)
+
+#define PFIM_ROUNDUP(X, Y) (((X) + ((Y) - 1U)) & ~((Y) - 1U))
+#define PFIM_RND_TAG (0x10)
+
+#endif /* _PFIM_DEFS_H_ */
+
+/******************************************************************************
+ End of file (pfim_defs.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/system/rgx_tc/pfim_regs.h b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/pfim_regs.h
new file mode 100644
index 000000000..4b8ff8213
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/pfim_regs.h
@@ -0,0 +1,265 @@
+/******************************************************************************
+@Title Odin PFIM control register definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Odin register defs for PDP-FBDC Interface Module
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+******************************************************************************/
+#ifndef _PFIM_REGS_H_
+#define _PFIM_REGS_H_
+
+/*
+ Register CR_PFIM_NUM_TILES
+*/
+#define CR_PFIM_NUM_TILES 0x0000
+#define CR_PFIM_NUM_TILES_MASK 0x007FFFFFU
+#define CR_PFIM_NUM_TILES_SHIFT 0
+#define CR_PFIM_NUM_TILES_SIGNED 0
+
+/*
+ Register CR_PFIM_TILES_PER_LINE
+*/
+#define CR_PFIM_TILES_PER_LINE 0x0004
+#define CR_PFIM_TILES_PER_LINE_PFIM_TILES_PER_LINE_MASK 0x000000FFU
+#define CR_PFIM_TILES_PER_LINE_PFIM_TILES_PER_LINE_SHIFT 0
+#define CR_PFIM_TILES_PER_LINE_PFIM_TILES_PER_LINE_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_YARGB_BASE_ADDR_LSB
+*/
+#define CR_PFIM_FBDC_YARGB_BASE_ADDR_LSB 0x0008
+#define CR_PFIM_FBDC_YARGB_BASE_ADDR_LSB_MASK 0xFFFFFFFFU
+#define CR_PFIM_FBDC_YARGB_BASE_ADDR_LSB_SHIFT 0
+#define CR_PFIM_FBDC_YARGB_BASE_ADDR_LSB_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_YARGB_BASE_ADDR_MSB
+*/
+#define CR_PFIM_FBDC_YARGB_BASE_ADDR_MSB 0x000C
+#define CR_PFIM_FBDC_YARGB_BASE_ADDR_MSB_MASK 0x00000003U
+#define CR_PFIM_FBDC_YARGB_BASE_ADDR_MSB_SHIFT 0
+#define CR_PFIM_FBDC_YARGB_BASE_ADDR_MSB_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_UV_BASE_ADDR_LSB
+*/
+#define CR_PFIM_FBDC_UV_BASE_ADDR_LSB 0x0010
+#define CR_PFIM_FBDC_UV_BASE_ADDR_LSB_MASK 0xFFFFFFFFU
+#define CR_PFIM_FBDC_UV_BASE_ADDR_LSB_SHIFT 0
+#define CR_PFIM_FBDC_UV_BASE_ADDR_LSB_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_UV_BASE_ADDR_MSB
+*/
+#define CR_PFIM_FBDC_UV_BASE_ADDR_MSB 0x0014
+#define CR_PFIM_FBDC_UV_BASE_ADDR_MSB_MASK 0x00000003U
+#define CR_PFIM_FBDC_UV_BASE_ADDR_MSB_SHIFT 0
+#define CR_PFIM_FBDC_UV_BASE_ADDR_MSB_SIGNED 0
+
+/*
+ Register CR_PFIM_PDP_Y_BASE_ADDR
+*/
+#define CR_PFIM_PDP_Y_BASE_ADDR 0x0018
+#define CR_PFIM_PDP_Y_BASE_ADDR_MASK 0xFFFFFFFFU
+#define CR_PFIM_PDP_Y_BASE_ADDR_SHIFT 0
+#define CR_PFIM_PDP_Y_BASE_ADDR_SIGNED 0
+
+/*
+ Register CR_PFIM_PDP_UV_BASE_ADDR
+*/
+#define CR_PFIM_PDP_UV_BASE_ADDR 0x001C
+#define CR_PFIM_PDP_UV_BASE_ADDR_MASK 0xFFFFFFFFU
+#define CR_PFIM_PDP_UV_BASE_ADDR_SHIFT 0
+#define CR_PFIM_PDP_UV_BASE_ADDR_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_REQ_CONTEXT
+*/
+#define CR_PFIM_FBDC_REQ_CONTEXT 0x0020
+#define CR_PFIM_FBDC_REQ_CONTEXT_MASK 0x00000007U
+#define CR_PFIM_FBDC_REQ_CONTEXT_SHIFT 0
+#define CR_PFIM_FBDC_REQ_CONTEXT_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_REQ_TAG
+*/
+#define CR_PFIM_FBDC_REQ_TAG 0x0024
+#define CR_PFIM_FBDC_REQ_TAG_YARGB_MASK 0x00000003U
+#define CR_PFIM_FBDC_REQ_TAG_YARGB_SHIFT 0
+#define CR_PFIM_FBDC_REQ_TAG_YARGB_SIGNED 0
+
+#define CR_PFIM_FBDC_REQ_TAG_UV_MASK 0x00000030U
+#define CR_PFIM_FBDC_REQ_TAG_UV_SHIFT 4
+#define CR_PFIM_FBDC_REQ_TAG_UV_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_REQ_SB_TAG
+*/
+#define CR_PFIM_FBDC_REQ_SB_TAG 0x0028
+#define CR_PFIM_FBDC_REQ_SB_TAG_YARGB_MASK 0x00000003U
+#define CR_PFIM_FBDC_REQ_SB_TAG_YARGB_SHIFT 0
+#define CR_PFIM_FBDC_REQ_SB_TAG_YARGB_SIGNED 0
+
+#define CR_PFIM_FBDC_REQ_SB_TAG_UV_MASK 0x00000030U
+#define CR_PFIM_FBDC_REQ_SB_TAG_UV_SHIFT 4
+#define CR_PFIM_FBDC_REQ_SB_TAG_UV_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_HDR_INVAL_REQ
+*/
+#define CR_PFIM_FBDC_HDR_INVAL_REQ 0x002C
+#define CR_PFIM_FBDC_HDR_INVAL_REQ_MASK 0x00000001U
+#define CR_PFIM_FBDC_HDR_INVAL_REQ_SHIFT 0
+#define CR_PFIM_FBDC_HDR_INVAL_REQ_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_PIX_FORMAT
+*/
+#define CR_PFIM_FBDC_PIX_FORMAT 0x0030
+#define CR_PFIM_FBDC_PIX_FORMAT_FBDC_PIX_FMT_MASK 0x0000007FU
+#define CR_PFIM_FBDC_PIX_FORMAT_FBDC_PIX_FMT_SHIFT 0
+#define CR_PFIM_FBDC_PIX_FORMAT_FBDC_PIX_FMT_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_CR_CH0123_VAL0
+*/
+#define CR_PFIM_FBDC_CR_CH0123_VAL0 0x0034
+#define CR_PFIM_FBDC_CR_CH0123_VAL0_MASK 0xFFFFFFFFU
+#define CR_PFIM_FBDC_CR_CH0123_VAL0_SHIFT 0
+#define CR_PFIM_FBDC_CR_CH0123_VAL0_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_CR_CH0123_VAL1
+*/
+#define CR_PFIM_FBDC_CR_CH0123_VAL1 0x0038
+#define CR_PFIM_FBDC_CR_CH0123_VAL1_MASK 0xFFFFFFFFU
+#define CR_PFIM_FBDC_CR_CH0123_VAL1_SHIFT 0
+#define CR_PFIM_FBDC_CR_CH0123_VAL1_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_CR_Y_VAL0
+*/
+#define CR_PFIM_FBDC_CR_Y_VAL0 0x003C
+#define CR_PFIM_FBDC_CR_Y_VAL0_MASK 0x000003FFU
+#define CR_PFIM_FBDC_CR_Y_VAL0_SHIFT 0
+#define CR_PFIM_FBDC_CR_Y_VAL0_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_CR_UV_VAL0
+*/
+#define CR_PFIM_FBDC_CR_UV_VAL0 0x0040
+#define CR_PFIM_FBDC_CR_UV_VAL0_MASK 0x000003FFU
+#define CR_PFIM_FBDC_CR_UV_VAL0_SHIFT 0
+#define CR_PFIM_FBDC_CR_UV_VAL0_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_CR_Y_VAL1
+*/
+#define CR_PFIM_FBDC_CR_Y_VAL1 0x0044
+#define CR_PFIM_FBDC_CR_Y_VAL1_MASK 0x000003FFU
+#define CR_PFIM_FBDC_CR_Y_VAL1_SHIFT 0
+#define CR_PFIM_FBDC_CR_Y_VAL1_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_CR_UV_VAL1
+*/
+#define CR_PFIM_FBDC_CR_UV_VAL1 0x0048
+#define CR_PFIM_FBDC_CR_UV_VAL1_MASK 0x000003FFU
+#define CR_PFIM_FBDC_CR_UV_VAL1_SHIFT 0
+#define CR_PFIM_FBDC_CR_UV_VAL1_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_FILTER_ENABLE
+*/
+#define CR_PFIM_FBDC_FILTER_ENABLE 0x004C
+#define CR_PFIM_FBDC_FILTER_ENABLE_MASK 0x00000001U
+#define CR_PFIM_FBDC_FILTER_ENABLE_SHIFT 0
+#define CR_PFIM_FBDC_FILTER_ENABLE_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_FILTER_STATUS
+*/
+#define CR_PFIM_FBDC_FILTER_STATUS 0x0050
+#define CR_PFIM_FBDC_FILTER_STATUS_MASK 0x0000000FU
+#define CR_PFIM_FBDC_FILTER_STATUS_SHIFT 0
+#define CR_PFIM_FBDC_FILTER_STATUS_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_FILTER_CLEAR
+*/
+#define CR_PFIM_FBDC_FILTER_CLEAR 0x0054
+#define CR_PFIM_FBDC_FILTER_CLEAR_MASK 0x0000000FU
+#define CR_PFIM_FBDC_FILTER_CLEAR_SHIFT 0
+#define CR_PFIM_FBDC_FILTER_CLEAR_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_TILE_TYPE
+*/
+#define CR_PFIM_FBDC_TILE_TYPE 0x0058
+#define CR_PFIM_FBDC_TILE_TYPE_MASK 0x00000003U
+#define CR_PFIM_FBDC_TILE_TYPE_SHIFT 0
+#define CR_PFIM_FBDC_TILE_TYPE_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_CLEAR_COLOUR_LSB
+*/
+#define CR_PFIM_FBDC_CLEAR_COLOUR_LSB 0x005C
+#define CR_PFIM_FBDC_CLEAR_COLOUR_LSB_MASK 0xFFFFFFFFU
+#define CR_PFIM_FBDC_CLEAR_COLOUR_LSB_SHIFT 0
+#define CR_PFIM_FBDC_CLEAR_COLOUR_LSB_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_CLEAR_COLOUR_MSB
+*/
+#define CR_PFIM_FBDC_CLEAR_COLOUR_MSB 0x0060
+#define CR_PFIM_FBDC_CLEAR_COLOUR_MSB_MASK 0xFFFFFFFFU
+#define CR_PFIM_FBDC_CLEAR_COLOUR_MSB_SHIFT 0
+#define CR_PFIM_FBDC_CLEAR_COLOUR_MSB_SIGNED 0
+
+/*
+ Register CR_PFIM_FBDC_REQ_LOSSY
+*/
+#define CR_PFIM_FBDC_REQ_LOSSY 0x0064
+#define CR_PFIM_FBDC_REQ_LOSSY_MASK 0x00000001U
+#define CR_PFIM_FBDC_REQ_LOSSY_SHIFT 0
+#define CR_PFIM_FBDC_REQ_LOSSY_SIGNED 0
+
+#endif /* _PFIM_REGS_H_ */
+
+/******************************************************************************
+ End of file (pfim_regs.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/system/rgx_tc/tcf_clk_ctrl.h b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/tcf_clk_ctrl.h
new file mode 100644
index 000000000..cc7b10fd8
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/tcf_clk_ctrl.h
@@ -0,0 +1,1018 @@
+/*************************************************************************/ /*!
+@Title Test Chip Framework system control register definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Autogenerated C -- do not edit
+ Generated from: tcf_clk_ctrl.def
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(_TCF_CLK_CTRL_H_)
+#define _TCF_CLK_CTRL_H_
+
+/*
+ * The following register definitions are valid if register 0x28 has value 0.
+ */
+
+/*
+ Register FPGA_ID_REG
+*/
+#define TCF_CLK_CTRL_FPGA_ID_REG 0x0000
+#define FPGA_ID_REG_CORE_CFG_MASK 0x0000FFFFU
+#define FPGA_ID_REG_CORE_CFG_SHIFT 0
+#define FPGA_ID_REG_CORE_CFG_SIGNED 0
+
+#define FPGA_ID_REG_CORE_ID_MASK 0xFFFF0000U
+#define FPGA_ID_REG_CORE_ID_SHIFT 16
+#define FPGA_ID_REG_CORE_ID_SIGNED 0
+
+/*
+ Register FPGA_REV_REG
+*/
+#define TCF_CLK_CTRL_FPGA_REV_REG 0x0008
+#define FPGA_REV_REG_MAINT_MASK 0x000000FFU
+#define FPGA_REV_REG_MAINT_SHIFT 0
+#define FPGA_REV_REG_MAINT_SIGNED 0
+
+#define FPGA_REV_REG_MINOR_MASK 0x0000FF00U
+#define FPGA_REV_REG_MINOR_SHIFT 8
+#define FPGA_REV_REG_MINOR_SIGNED 0
+
+#define FPGA_REV_REG_MAJOR_MASK 0x00FF0000U
+#define FPGA_REV_REG_MAJOR_SHIFT 16
+#define FPGA_REV_REG_MAJOR_SIGNED 0
+
+#define FPGA_REV_REG_DESIGNER_MASK 0xFF000000U
+#define FPGA_REV_REG_DESIGNER_SHIFT 24
+#define FPGA_REV_REG_DESIGNER_SIGNED 0
+
+/*
+ Register FPGA_DES_REV_1
+*/
+#define TCF_CLK_CTRL_FPGA_DES_REV_1 0x0010
+#define FPGA_DES_REV_1_MASK 0xFFFFFFFFU
+#define FPGA_DES_REV_1_SHIFT 0
+#define FPGA_DES_REV_1_SIGNED 0
+
+/*
+ Register FPGA_DES_REV_2
+*/
+#define TCF_CLK_CTRL_FPGA_DES_REV_2 0x0018
+#define FPGA_DES_REV_2_MASK 0xFFFFFFFFU
+#define FPGA_DES_REV_2_SHIFT 0
+#define FPGA_DES_REV_2_SIGNED 0
+
+/*
+ Register TCF_CORE_ID_REG
+*/
+#define TCF_CLK_CTRL_TCF_CORE_ID_REG 0x0020
+#define TCF_CORE_ID_REG_CORE_CFG_MASK 0x0000FFFFU
+#define TCF_CORE_ID_REG_CORE_CFG_SHIFT 0
+#define TCF_CORE_ID_REG_CORE_CFG_SIGNED 0
+
+#define TCF_CORE_ID_REG_CORE_ID_MASK 0xFFFF0000U
+#define TCF_CORE_ID_REG_CORE_ID_SHIFT 16
+#define TCF_CORE_ID_REG_CORE_ID_SIGNED 0
+
+/*
+ Register TCF_CORE_REV_REG
+*/
+#define TCF_CLK_CTRL_TCF_CORE_REV_REG 0x0028
+#define TCF_CORE_REV_REG_MAINT_MASK 0x000000FFU
+#define TCF_CORE_REV_REG_MAINT_SHIFT 0
+#define TCF_CORE_REV_REG_MAINT_SIGNED 0
+
+#define TCF_CORE_REV_REG_MINOR_MASK 0x0000FF00U
+#define TCF_CORE_REV_REG_MINOR_SHIFT 8
+#define TCF_CORE_REV_REG_MINOR_SIGNED 0
+
+#define TCF_CORE_REV_REG_MAJOR_MASK 0x00FF0000U
+#define TCF_CORE_REV_REG_MAJOR_SHIFT 16
+#define TCF_CORE_REV_REG_MAJOR_SIGNED 0
+
+#define TCF_CORE_REV_REG_DESIGNER_MASK 0xFF000000U
+#define TCF_CORE_REV_REG_DESIGNER_SHIFT 24
+#define TCF_CORE_REV_REG_DESIGNER_SIGNED 0
+
+/*
+ Register TCF_CORE_DES_REV_1
+*/
+#define TCF_CLK_CTRL_TCF_CORE_DES_REV_1 0x0030
+#define TCF_CORE_DES_REV_1_MASK 0xFFFFFFFFU
+#define TCF_CORE_DES_REV_1_SHIFT 0
+#define TCF_CORE_DES_REV_1_SIGNED 0
+
+/*
+ Register TCF_CORE_DES_REV_2
+*/
+#define TCF_CLK_CTRL_TCF_CORE_DES_REV_2 0x0038
+#define TCF_CORE_DES_REV_2_MASK 0xFFFFFFFFU
+#define TCF_CORE_DES_REV_2_SHIFT 0
+#define TCF_CORE_DES_REV_2_SIGNED 0
+
+
+/*
+ * The following register definitions are valid if register 0x28 has value 1.
+ */
+
+/*
+ Register ID
+*/
+#define TCF_CLK_CTRL_ID 0x0000
+#define VARIANT_MASK 0x0000FFFFU
+#define VARIANT_SHIFT 0
+#define VARIANT_SIGNED 0
+
+#define ID_MASK 0xFFFF0000U
+#define ID_SHIFT 16
+#define ID_SIGNED 0
+
+/*
+ Register REL
+*/
+#define TCF_CLK_CTRL_REL 0x0008
+#define MINOR_MASK 0x0000FFFFU
+#define MINOR_SHIFT 0
+#define MINOR_SIGNED 0
+
+#define MAJOR_MASK 0xFFFF0000U
+#define MAJOR_SHIFT 16
+#define MAJOR_SIGNED 0
+
+/*
+ Register CHANGE_SET
+*/
+#define TCF_CLK_CTRL_CHANGE_SET 0x0010
+#define SET_MASK 0xFFFFFFFFU
+#define SET_SHIFT 0
+#define SET_SIGNED 0
+
+/*
+ Register USER_ID
+*/
+#define TCF_CLK_CTRL_USER_ID 0x0018
+#define USER_ID_MASK 0x0000000FU
+#define USER_ID_SHIFT 0
+#define USER_ID_SIGNED 0
+
+/*
+ Register USER_BUILD
+*/
+#define TCF_CLK_CTRL_USER_BUILD 0x0020
+#define BUILD_MASK 0xFFFFFFFFU
+#define BUILD_SHIFT 0
+#define BUILD_SIGNED 0
+
+/*
+ Register SW_IF_VERSION
+*/
+#define TCF_CLK_CTRL_SW_IF_VERSION 0x0028
+#define VERSION_MASK 0x0000FFFFU
+#define VERSION_SHIFT 0
+#define VERSION_SIGNED 0
+
+/*
+ * The following register definitions are valid for all Apollo builds,
+ * even if some of the registers are not available for certain cores.
+ */
+
+/*
+ Register SCB_GENERAL_CONTROL
+*/
+#define TCF_CLK_CTRL_SCB_GENERAL_CONTROL 0x0040
+#define SCB_GC_TRANS_HALT_MASK 0x00000200U
+#define SCB_GC_TRANS_HALT_SHIFT 9
+#define SCB_GC_TRANS_HALT_SIGNED 0
+
+#define SCB_GC_CKD_REGS_MASK 0x00000100U
+#define SCB_GC_CKD_REGS_SHIFT 8
+#define SCB_GC_CKD_REGS_SIGNED 0
+
+#define SCB_GC_CKD_SLAVE_MASK 0x00000080U
+#define SCB_GC_CKD_SLAVE_SHIFT 7
+#define SCB_GC_CKD_SLAVE_SIGNED 0
+
+#define SCB_GC_CKD_MASTER_MASK 0x00000040U
+#define SCB_GC_CKD_MASTER_SHIFT 6
+#define SCB_GC_CKD_MASTER_SIGNED 0
+
+#define SCB_GC_CKD_XDATA_MASK 0x00000020U
+#define SCB_GC_CKD_XDATA_SHIFT 5
+#define SCB_GC_CKD_XDATA_SIGNED 0
+
+#define SCB_GC_SFR_REG_MASK 0x00000010U
+#define SCB_GC_SFR_REG_SHIFT 4
+#define SCB_GC_SFR_REG_SIGNED 0
+
+#define SCB_GC_SFR_SLAVE_MASK 0x00000008U
+#define SCB_GC_SFR_SLAVE_SHIFT 3
+#define SCB_GC_SFR_SLAVE_SIGNED 0
+
+#define SCB_GC_SFR_MASTER_MASK 0x00000004U
+#define SCB_GC_SFR_MASTER_SHIFT 2
+#define SCB_GC_SFR_MASTER_SIGNED 0
+
+#define SCB_GC_SFR_DET_DATA_MASK 0x00000002U
+#define SCB_GC_SFR_DET_DATA_SHIFT 1
+#define SCB_GC_SFR_DET_DATA_SIGNED 0
+
+#define SCB_GC_SFR_GEN_DATA_MASK 0x00000001U
+#define SCB_GC_SFR_GEN_DATA_SHIFT 0
+#define SCB_GC_SFR_GEN_DATA_SIGNED 0
+
+/*
+ Register SCB_MASTER_READ_COUNT
+*/
+#define TCF_CLK_CTRL_SCB_MASTER_READ_COUNT 0x0048
+#define MASTER_READ_COUNT_MASK 0x0000FFFFU
+#define MASTER_READ_COUNT_SHIFT 0
+#define MASTER_READ_COUNT_SIGNED 0
+
+/*
+ Register SCB_MASTER_READ_DATA
+*/
+#define TCF_CLK_CTRL_SCB_MASTER_READ_DATA 0x0050
+#define MASTER_READ_DATA_MASK 0x000000FFU
+#define MASTER_READ_DATA_SHIFT 0
+#define MASTER_READ_DATA_SIGNED 0
+
+/*
+ Register SCB_MASTER_ADDRESS
+*/
+#define TCF_CLK_CTRL_SCB_MASTER_ADDRESS 0x0058
+#define SCB_MASTER_ADDRESS_MASK 0x000003FFU
+#define SCB_MASTER_ADDRESS_SHIFT 0
+#define SCB_MASTER_ADDRESS_SIGNED 0
+
+/*
+ Register SCB_MASTER_WRITE_DATA
+*/
+#define TCF_CLK_CTRL_SCB_MASTER_WRITE_DATA 0x0060
+#define MASTER_WRITE_DATA_MASK 0x000000FFU
+#define MASTER_WRITE_DATA_SHIFT 0
+#define MASTER_WRITE_DATA_SIGNED 0
+
+/*
+ Register SCB_MASTER_WRITE_COUNT
+*/
+#define TCF_CLK_CTRL_SCB_MASTER_WRITE_COUNT 0x0068
+#define MASTER_WRITE_COUNT_MASK 0x0000FFFFU
+#define MASTER_WRITE_COUNT_SHIFT 0
+#define MASTER_WRITE_COUNT_SIGNED 0
+
+/*
+ Register SCB_BUS_SELECT
+*/
+#define TCF_CLK_CTRL_SCB_BUS_SELECT 0x0070
+#define BUS_SELECT_MASK 0x00000003U
+#define BUS_SELECT_SHIFT 0
+#define BUS_SELECT_SIGNED 0
+
+/*
+ Register SCB_MASTER_FILL_STATUS
+*/
+#define TCF_CLK_CTRL_SCB_MASTER_FILL_STATUS 0x0078
+#define MASTER_WRITE_FIFO_EMPTY_MASK 0x00000008U
+#define MASTER_WRITE_FIFO_EMPTY_SHIFT 3
+#define MASTER_WRITE_FIFO_EMPTY_SIGNED 0
+
+#define MASTER_WRITE_FIFO_FULL_MASK 0x00000004U
+#define MASTER_WRITE_FIFO_FULL_SHIFT 2
+#define MASTER_WRITE_FIFO_FULL_SIGNED 0
+
+#define MASTER_READ_FIFO_EMPTY_MASK 0x00000002U
+#define MASTER_READ_FIFO_EMPTY_SHIFT 1
+#define MASTER_READ_FIFO_EMPTY_SIGNED 0
+
+#define MASTER_READ_FIFO_FULL_MASK 0x00000001U
+#define MASTER_READ_FIFO_FULL_SHIFT 0
+#define MASTER_READ_FIFO_FULL_SIGNED 0
+
+/*
+ Register CLK_AND_RST_CTRL
+*/
+#define TCF_CLK_CTRL_CLK_AND_RST_CTRL 0x0080
+#define GLB_CLKG_EN_MASK 0x00020000U
+#define GLB_CLKG_EN_SHIFT 17
+#define GLB_CLKG_EN_SIGNED 0
+
+#define CLK_GATE_CNTL_MASK 0x00010000U
+#define CLK_GATE_CNTL_SHIFT 16
+#define CLK_GATE_CNTL_SIGNED 0
+
+#define DUT_DCM_RESETN_MASK 0x00000400U
+#define DUT_DCM_RESETN_SHIFT 10
+#define DUT_DCM_RESETN_SIGNED 0
+
+#define MEM_RESYNC_BYPASS_MASK 0x00000200U
+#define MEM_RESYNC_BYPASS_SHIFT 9
+#define MEM_RESYNC_BYPASS_SIGNED 0
+
+#define SYS_RESYNC_BYPASS_MASK 0x00000100U
+#define SYS_RESYNC_BYPASS_SHIFT 8
+#define SYS_RESYNC_BYPASS_SIGNED 0
+
+#define SCB_RESETN_MASK 0x00000010U
+#define SCB_RESETN_SHIFT 4
+#define SCB_RESETN_SIGNED 0
+
+#define PDP2_RESETN_MASK 0x00000008U
+#define PDP2_RESETN_SHIFT 3
+#define PDP2_RESETN_SIGNED 0
+
+#define PDP1_RESETN_MASK 0x00000004U
+#define PDP1_RESETN_SHIFT 2
+#define PDP1_RESETN_SIGNED 0
+
+#define DDR_RESETN_MASK 0x00000002U
+#define DDR_RESETN_SHIFT 1
+#define DDR_RESETN_SIGNED 0
+
+#define DUT_RESETN_MASK 0x00000001U
+#define DUT_RESETN_SHIFT 0
+#define DUT_RESETN_SIGNED 0
+
+/*
+ Register TEST_REG_OUT
+*/
+#define TCF_CLK_CTRL_TEST_REG_OUT 0x0088
+#define TEST_REG_OUT_MASK 0xFFFFFFFFU
+#define TEST_REG_OUT_SHIFT 0
+#define TEST_REG_OUT_SIGNED 0
+
+/*
+ Register TEST_REG_IN
+*/
+#define TCF_CLK_CTRL_TEST_REG_IN 0x0090
+#define TEST_REG_IN_MASK 0xFFFFFFFFU
+#define TEST_REG_IN_SHIFT 0
+#define TEST_REG_IN_SIGNED 0
+
+/*
+ Register TEST_CTRL
+*/
+#define TCF_CLK_CTRL_TEST_CTRL 0x0098
+#define PCI_TEST_OFFSET_MASK 0xF8000000U
+#define PCI_TEST_OFFSET_SHIFT 27
+#define PCI_TEST_OFFSET_SIGNED 0
+
+#define PDP1_HOST_MEM_SELECT_MASK 0x00000200U
+#define PDP1_HOST_MEM_SELECT_SHIFT 9
+#define PDP1_HOST_MEM_SELECT_SIGNED 0
+
+#define HOST_PHY_MODE_MASK 0x00000100U
+#define HOST_PHY_MODE_SHIFT 8
+#define HOST_PHY_MODE_SIGNED 0
+
+#define HOST_ONLY_MODE_MASK 0x00000080U
+#define HOST_ONLY_MODE_SHIFT 7
+#define HOST_ONLY_MODE_SIGNED 0
+
+#define PCI_TEST_MODE_MASK 0x00000040U
+#define PCI_TEST_MODE_SHIFT 6
+#define PCI_TEST_MODE_SIGNED 0
+
+#define TURN_OFF_DDR_MASK 0x00000020U
+#define TURN_OFF_DDR_SHIFT 5
+#define TURN_OFF_DDR_SIGNED 0
+
+#define SYS_RD_CLK_INV_MASK 0x00000010U
+#define SYS_RD_CLK_INV_SHIFT 4
+#define SYS_RD_CLK_INV_SIGNED 0
+
+#define MEM_REQ_CLK_INV_MASK 0x00000008U
+#define MEM_REQ_CLK_INV_SHIFT 3
+#define MEM_REQ_CLK_INV_SIGNED 0
+
+#define BURST_SPLIT_MASK 0x00000004U
+#define BURST_SPLIT_SHIFT 2
+#define BURST_SPLIT_SIGNED 0
+
+#define CLK_INVERSION_MASK 0x00000002U
+#define CLK_INVERSION_SHIFT 1
+#define CLK_INVERSION_SIGNED 0
+
+#define ADDRESS_FORCE_MASK 0x00000001U
+#define ADDRESS_FORCE_SHIFT 0
+#define ADDRESS_FORCE_SIGNED 0
+
+/*
+ Register CLEAR_HOST_MEM_SIG
+*/
+#define TCF_CLK_CTRL_CLEAR_HOST_MEM_SIG 0x00A0
+#define SIGNATURE_TAG_ID_MASK 0x00000F00U
+#define SIGNATURE_TAG_ID_SHIFT 8
+#define SIGNATURE_TAG_ID_SIGNED 0
+
+#define CLEAR_HOST_MEM_SIGNATURE_MASK 0x00000001U
+#define CLEAR_HOST_MEM_SIGNATURE_SHIFT 0
+#define CLEAR_HOST_MEM_SIGNATURE_SIGNED 0
+
+/*
+ Register HOST_MEM_SIGNATURE
+*/
+#define TCF_CLK_CTRL_HOST_MEM_SIGNATURE 0x00A8
+#define HOST_MEM_SIGNATURE_MASK 0xFFFFFFFFU
+#define HOST_MEM_SIGNATURE_SHIFT 0
+#define HOST_MEM_SIGNATURE_SIGNED 0
+
+/*
+ Register INTERRUPT_STATUS
+*/
+#define TCF_CLK_CTRL_INTERRUPT_STATUS 0x00C8
+#define INTERRUPT_MASTER_STATUS_MASK 0x80000000U
+#define INTERRUPT_MASTER_STATUS_SHIFT 31
+#define INTERRUPT_MASTER_STATUS_SIGNED 0
+
+#define OTHER_INTS_MASK 0x7FFE0000U
+#define OTHER_INTS_SHIFT 17
+#define OTHER_INTS_SIGNED 0
+
+#define HOST_MST_NORESPONSE_MASK 0x00010000U
+#define HOST_MST_NORESPONSE_SHIFT 16
+#define HOST_MST_NORESPONSE_SIGNED 0
+
+#define PDP2_INT_MASK 0x00008000U
+#define PDP2_INT_SHIFT 15
+#define PDP2_INT_SIGNED 0
+
+#define PDP1_INT_MASK 0x00004000U
+#define PDP1_INT_SHIFT 14
+#define PDP1_INT_SIGNED 0
+
+#define EXT_INT_MASK 0x00002000U
+#define EXT_INT_SHIFT 13
+#define EXT_INT_SIGNED 0
+
+#define SCB_MST_HLT_BIT_MASK 0x00001000U
+#define SCB_MST_HLT_BIT_SHIFT 12
+#define SCB_MST_HLT_BIT_SIGNED 0
+
+#define SCB_SLV_EVENT_MASK 0x00000800U
+#define SCB_SLV_EVENT_SHIFT 11
+#define SCB_SLV_EVENT_SIGNED 0
+
+#define SCB_TDONE_RX_MASK 0x00000400U
+#define SCB_TDONE_RX_SHIFT 10
+#define SCB_TDONE_RX_SIGNED 0
+
+#define SCB_SLV_WT_RD_DAT_MASK 0x00000200U
+#define SCB_SLV_WT_RD_DAT_SHIFT 9
+#define SCB_SLV_WT_RD_DAT_SIGNED 0
+
+#define SCB_SLV_WT_PRV_RD_MASK 0x00000100U
+#define SCB_SLV_WT_PRV_RD_SHIFT 8
+#define SCB_SLV_WT_PRV_RD_SIGNED 0
+
+#define SCB_SLV_WT_WR_DAT_MASK 0x00000080U
+#define SCB_SLV_WT_WR_DAT_SHIFT 7
+#define SCB_SLV_WT_WR_DAT_SIGNED 0
+
+#define SCB_MST_WT_RD_DAT_MASK 0x00000040U
+#define SCB_MST_WT_RD_DAT_SHIFT 6
+#define SCB_MST_WT_RD_DAT_SIGNED 0
+
+#define SCB_ADD_ACK_ERR_MASK 0x00000020U
+#define SCB_ADD_ACK_ERR_SHIFT 5
+#define SCB_ADD_ACK_ERR_SIGNED 0
+
+#define SCB_WR_ACK_ERR_MASK 0x00000010U
+#define SCB_WR_ACK_ERR_SHIFT 4
+#define SCB_WR_ACK_ERR_SIGNED 0
+
+#define SCB_SDAT_LO_TIM_MASK 0x00000008U
+#define SCB_SDAT_LO_TIM_SHIFT 3
+#define SCB_SDAT_LO_TIM_SIGNED 0
+
+#define SCB_SCLK_LO_TIM_MASK 0x00000004U
+#define SCB_SCLK_LO_TIM_SHIFT 2
+#define SCB_SCLK_LO_TIM_SIGNED 0
+
+#define SCB_UNEX_START_BIT_MASK 0x00000002U
+#define SCB_UNEX_START_BIT_SHIFT 1
+#define SCB_UNEX_START_BIT_SIGNED 0
+
+#define SCB_BUS_INACTIVE_MASK 0x00000001U
+#define SCB_BUS_INACTIVE_SHIFT 0
+#define SCB_BUS_INACTIVE_SIGNED 0
+
+/*
+ Register INTERRUPT_OP_CFG
+*/
+#define TCF_CLK_CTRL_INTERRUPT_OP_CFG 0x00D0
+#define PULSE_NLEVEL_MASK 0x80000000U
+#define PULSE_NLEVEL_SHIFT 31
+#define PULSE_NLEVEL_SIGNED 0
+
+#define INT_SENSE_MASK 0x40000000U
+#define INT_SENSE_SHIFT 30
+#define INT_SENSE_SIGNED 0
+
+#define INTERRUPT_DEST_MASK 0x0000000FU
+#define INTERRUPT_DEST_SHIFT 0
+#define INTERRUPT_DEST_SIGNED 0
+
+/*
+ Register INTERRUPT_ENABLE
+*/
+#define TCF_CLK_CTRL_INTERRUPT_ENABLE 0x00D8
+#define INTERRUPT_MASTER_ENABLE_MASK 0x80000000U
+#define INTERRUPT_MASTER_ENABLE_SHIFT 31
+#define INTERRUPT_MASTER_ENABLE_SIGNED 0
+
+#define INTERRUPT_ENABLE_MASK 0x7FFFFFFFU
+#define INTERRUPT_ENABLE_SHIFT 0
+#define INTERRUPT_ENABLE_SIGNED 0
+
+/*
+ Register INTERRUPT_CLEAR
+*/
+#define TCF_CLK_CTRL_INTERRUPT_CLEAR 0x00E0
+#define INTERRUPT_MASTER_CLEAR_MASK 0x80000000U
+#define INTERRUPT_MASTER_CLEAR_SHIFT 31
+#define INTERRUPT_MASTER_CLEAR_SIGNED 0
+
+#define INTERRUPT_CLEAR_MASK 0x7FFFFFFFU
+#define INTERRUPT_CLEAR_SHIFT 0
+#define INTERRUPT_CLEAR_SIGNED 0
+
+/*
+ Register YCC_RGB_CTRL
+*/
+#define TCF_CLK_CTRL_YCC_RGB_CTRL 0x00E8
+#define RGB_CTRL1_MASK 0x000001FFU
+#define RGB_CTRL1_SHIFT 0
+#define RGB_CTRL1_SIGNED 0
+
+#define RGB_CTRL2_MASK 0x01FF0000U
+#define RGB_CTRL2_SHIFT 16
+#define RGB_CTRL2_SIGNED 0
+
+/*
+ Register EXP_BRD_CTRL
+*/
+#define TCF_CLK_CTRL_EXP_BRD_CTRL 0x00F8
+#define PDP1_DATA_EN_MASK 0x00000003U
+#define PDP1_DATA_EN_SHIFT 0
+#define PDP1_DATA_EN_SIGNED 0
+
+#define PDP2_DATA_EN_MASK 0x00000030U
+#define PDP2_DATA_EN_SHIFT 4
+#define PDP2_DATA_EN_SIGNED 0
+
+#define EXP_BRD_OUTPUT_MASK 0xFFFFFF00U
+#define EXP_BRD_OUTPUT_SHIFT 8
+#define EXP_BRD_OUTPUT_SIGNED 0
+
+/*
+ Register HOSTIF_CONTROL
+*/
+#define TCF_CLK_CTRL_HOSTIF_CONTROL 0x0100
+#define HOSTIF_CTRL_MASK 0x000000FFU
+#define HOSTIF_CTRL_SHIFT 0
+#define HOSTIF_CTRL_SIGNED 0
+
+/*
+ Register DUT_CONTROL_1
+*/
+#define TCF_CLK_CTRL_DUT_CONTROL_1 0x0108
+#define DUT_CTRL_1_MASK 0xFFFFFFFFU
+#define DUT_CTRL_1_SHIFT 0
+#define DUT_CTRL_1_SIGNED 0
+
+/* TC ES2 additional needs those: */
+#define DUT_CTRL_TEST_MODE_SHIFT 0
+#define DUT_CTRL_TEST_MODE_MASK 0x3
+
+#define DUT_CTRL_VCC_0V9EN (1<<12)
+#define DUT_CTRL_VCC_1V8EN (1<<13)
+#define DUT_CTRL_VCC_IO_INH (1<<14)
+#define DUT_CTRL_VCC_CORE_INH (1<<15)
+
+/*
+ Register DUT_STATUS_1
+*/
+#define TCF_CLK_CTRL_DUT_STATUS_1 0x0110
+#define DUT_STATUS_1_MASK 0xFFFFFFFFU
+#define DUT_STATUS_1_SHIFT 0
+#define DUT_STATUS_1_SIGNED 0
+
+/*
+ Register DUT_CTRL_NOT_STAT_1
+*/
+#define TCF_CLK_CTRL_DUT_CTRL_NOT_STAT_1 0x0118
+#define DUT_STAT_NOT_CTRL_1_MASK 0xFFFFFFFFU
+#define DUT_STAT_NOT_CTRL_1_SHIFT 0
+#define DUT_STAT_NOT_CTRL_1_SIGNED 0
+
+/*
+ Register DUT_CONTROL_2
+*/
+#define TCF_CLK_CTRL_DUT_CONTROL_2 0x0120
+#define DUT_CTRL_2_MASK 0xFFFFFFFFU
+#define DUT_CTRL_2_SHIFT 0
+#define DUT_CTRL_2_SIGNED 0
+
+/*
+ Register DUT_STATUS_2
+*/
+#define TCF_CLK_CTRL_DUT_STATUS_2 0x0128
+#define DUT_STATUS_2_MASK 0xFFFFFFFFU
+#define DUT_STATUS_2_SHIFT 0
+#define DUT_STATUS_2_SIGNED 0
+
+/*
+ Register DUT_CTRL_NOT_STAT_2
+*/
+#define TCF_CLK_CTRL_DUT_CTRL_NOT_STAT_2 0x0130
+#define DUT_CTRL_NOT_STAT_2_MASK 0xFFFFFFFFU
+#define DUT_CTRL_NOT_STAT_2_SHIFT 0
+#define DUT_CTRL_NOT_STAT_2_SIGNED 0
+
+/*
+ Register BUS_CAP_BASE_ADDR
+*/
+#define TCF_CLK_CTRL_BUS_CAP_BASE_ADDR 0x0138
+#define BUS_CAP_BASE_ADDR_MASK 0xFFFFFFFFU
+#define BUS_CAP_BASE_ADDR_SHIFT 0
+#define BUS_CAP_BASE_ADDR_SIGNED 0
+
+/*
+ Register BUS_CAP_ENABLE
+*/
+#define TCF_CLK_CTRL_BUS_CAP_ENABLE 0x0140
+#define BUS_CAP_ENABLE_MASK 0x00000001U
+#define BUS_CAP_ENABLE_SHIFT 0
+#define BUS_CAP_ENABLE_SIGNED 0
+
+/*
+ Register BUS_CAP_COUNT
+*/
+#define TCF_CLK_CTRL_BUS_CAP_COUNT 0x0148
+#define BUS_CAP_COUNT_MASK 0xFFFFFFFFU
+#define BUS_CAP_COUNT_SHIFT 0
+#define BUS_CAP_COUNT_SIGNED 0
+
+/*
+ Register DCM_LOCK_STATUS
+*/
+#define TCF_CLK_CTRL_DCM_LOCK_STATUS 0x0150
+#define DCM_LOCK_STATUS_MASK 0x00000007U
+#define DCM_LOCK_STATUS_SHIFT 0
+#define DCM_LOCK_STATUS_SIGNED 0
+
+/*
+ Register AUX_DUT_RESETNS
+*/
+#define TCF_CLK_CTRL_AUX_DUT_RESETNS 0x0158
+#define AUX_DUT_RESETNS_MASK 0x0000000FU
+#define AUX_DUT_RESETNS_SHIFT 0
+#define AUX_DUT_RESETNS_SIGNED 0
+
+/*
+ Register TCF_SPI_MST_ADDR_RDNWR
+*/
+#define TCF_CLK_CTRL_TCF_SPI_MST_ADDR_RDNWR 0x0160
+#define TCF_SPI_MST_ADDR_MASK 0x0003FFFFU
+#define TCF_SPI_MST_ADDR_SHIFT 0
+#define TCF_SPI_MST_ADDR_SIGNED 0
+
+#define TCF_SPI_MST_RDNWR_MASK 0x00040000U
+#define TCF_SPI_MST_RDNWR_SHIFT 18
+#define TCF_SPI_MST_RDNWR_SIGNED 0
+
+#define TCF_SPI_MST_SLAVE_ID_MASK 0x00080000U
+#define TCF_SPI_MST_SLAVE_ID_SHIFT 19
+#define TCF_SPI_MST_SLAVE_ID_SIGNED 0
+
+#define TCF_SPI_MST_MASTER_ID_MASK 0x00300000U
+#define TCF_SPI_MST_MASTER_ID_SHIFT 20
+#define TCF_SPI_MST_MASTER_ID_SIGNED 0
+
+/*
+ Register TCF_SPI_MST_WDATA
+*/
+#define TCF_CLK_CTRL_TCF_SPI_MST_WDATA 0x0168
+#define TCF_SPI_MST_WDATA_MASK 0xFFFFFFFFU
+#define TCF_SPI_MST_WDATA_SHIFT 0
+#define TCF_SPI_MST_WDATA_SIGNED 0
+
+/*
+ Register TCF_SPI_MST_RDATA
+*/
+#define TCF_CLK_CTRL_TCF_SPI_MST_RDATA 0x0170
+#define TCF_SPI_MST_RDATA_MASK 0xFFFFFFFFU
+#define TCF_SPI_MST_RDATA_SHIFT 0
+#define TCF_SPI_MST_RDATA_SIGNED 0
+
+/*
+ Register TCF_SPI_MST_STATUS
+*/
+#define TCF_CLK_CTRL_TCF_SPI_MST_STATUS 0x0178
+#define TCF_SPI_MST_STATUS_MASK 0x0000000FU
+#define TCF_SPI_MST_STATUS_SHIFT 0
+#define TCF_SPI_MST_STATUS_SIGNED 0
+
+/*
+ Register TCF_SPI_MST_GO
+*/
+#define TCF_CLK_CTRL_TCF_SPI_MST_GO 0x0180
+#define TCF_SPI_MST_GO_MASK 0x00000001U
+#define TCF_SPI_MST_GO_SHIFT 0
+#define TCF_SPI_MST_GO_SIGNED 0
+
+/*
+ Register EXT_SIG_CTRL
+*/
+#define TCF_CLK_CTRL_EXT_SIG_CTRL 0x0188
+#define EXT_SYS_REQ_SIG_START_MASK 0x00000001U
+#define EXT_SYS_REQ_SIG_START_SHIFT 0
+#define EXT_SYS_REQ_SIG_START_SIGNED 0
+
+#define EXT_SYS_RD_SIG_START_MASK 0x00000002U
+#define EXT_SYS_RD_SIG_START_SHIFT 1
+#define EXT_SYS_RD_SIG_START_SIGNED 0
+
+#define EXT_MEM_REQ_SIG_START_MASK 0x00000004U
+#define EXT_MEM_REQ_SIG_START_SHIFT 2
+#define EXT_MEM_REQ_SIG_START_SIGNED 0
+
+#define EXT_MEM_RD_SIG_START_MASK 0x00000008U
+#define EXT_MEM_RD_SIG_START_SHIFT 3
+#define EXT_MEM_RD_SIG_START_SIGNED 0
+
+/*
+ Register EXT_SYS_REQ_SIG
+*/
+#define TCF_CLK_CTRL_EXT_SYS_REQ_SIG 0x0190
+#define EXT_SYS_REQ_SIG_MASK 0xFFFFFFFFU
+#define EXT_SYS_REQ_SIG_SHIFT 0
+#define EXT_SYS_REQ_SIG_SIGNED 0
+
+/*
+ Register EXT_SYS_RD_SIG
+*/
+#define TCF_CLK_CTRL_EXT_SYS_RD_SIG 0x0198
+#define EXT_SYS_RD_SIG_MASK 0xFFFFFFFFU
+#define EXT_SYS_RD_SIG_SHIFT 0
+#define EXT_SYS_RD_SIG_SIGNED 0
+
+/*
+ Register EXT_MEM_REQ_SIG
+*/
+#define TCF_CLK_CTRL_EXT_MEM_REQ_SIG 0x01A0
+#define EXT_MEM_REQ_SIG_MASK 0xFFFFFFFFU
+#define EXT_MEM_REQ_SIG_SHIFT 0
+#define EXT_MEM_REQ_SIG_SIGNED 0
+
+/*
+ Register EXT_MEM_RD_SIG
+*/
+#define TCF_CLK_CTRL_EXT_MEM_RD_SIG 0x01A8
+#define EXT_MEM_RD_SIG_MASK 0xFFFFFFFFU
+#define EXT_MEM_RD_SIG_SHIFT 0
+#define EXT_MEM_RD_SIG_SIGNED 0
+
+/*
+ Register EXT_SYS_REQ_WR_CNT
+*/
+#define TCF_CLK_CTRL_EXT_SYS_REQ_WR_CNT 0x01B0
+#define EXT_SYS_REQ_WR_CNT_MASK 0xFFFFFFFFU
+#define EXT_SYS_REQ_WR_CNT_SHIFT 0
+#define EXT_SYS_REQ_WR_CNT_SIGNED 0
+
+/*
+ Register EXT_SYS_REQ_RD_CNT
+*/
+#define TCF_CLK_CTRL_EXT_SYS_REQ_RD_CNT 0x01B8
+#define EXT_SYS_REQ_RD_CNT_MASK 0xFFFFFFFFU
+#define EXT_SYS_REQ_RD_CNT_SHIFT 0
+#define EXT_SYS_REQ_RD_CNT_SIGNED 0
+
+/*
+ Register EXT_SYS_RD_CNT
+*/
+#define TCF_CLK_CTRL_EXT_SYS_RD_CNT 0x01C0
+#define EXT_SYS_RD_CNT_MASK 0xFFFFFFFFU
+#define EXT_SYS_RD_CNT_SHIFT 0
+#define EXT_SYS_RD_CNT_SIGNED 0
+
+/*
+ Register EXT_MEM_REQ_WR_CNT
+*/
+#define TCF_CLK_CTRL_EXT_MEM_REQ_WR_CNT 0x01C8
+#define EXT_MEM_REQ_WR_CNT_MASK 0xFFFFFFFFU
+#define EXT_MEM_REQ_WR_CNT_SHIFT 0
+#define EXT_MEM_REQ_WR_CNT_SIGNED 0
+
+/*
+ Register EXT_MEM_REQ_RD_CNT
+*/
+#define TCF_CLK_CTRL_EXT_MEM_REQ_RD_CNT 0x01D0
+#define EXT_MEM_REQ_RD_CNT_MASK 0xFFFFFFFFU
+#define EXT_MEM_REQ_RD_CNT_SHIFT 0
+#define EXT_MEM_REQ_RD_CNT_SIGNED 0
+
+/*
+ Register EXT_MEM_RD_CNT
+*/
+#define TCF_CLK_CTRL_EXT_MEM_RD_CNT 0x01D8
+#define EXT_MEM_RD_CNT_MASK 0xFFFFFFFFU
+#define EXT_MEM_RD_CNT_SHIFT 0
+#define EXT_MEM_RD_CNT_SIGNED 0
+
+/*
+ Register TCF_CORE_TARGET_BUILD_CFG
+*/
+#define TCF_CLK_CTRL_TCF_CORE_TARGET_BUILD_CFG 0x01E0
+#define TCF_CORE_TARGET_BUILD_ID_MASK 0x000000FFU
+#define TCF_CORE_TARGET_BUILD_ID_SHIFT 0
+#define TCF_CORE_TARGET_BUILD_ID_SIGNED 0
+
+/*
+ Register MEM_THROUGH_SYS
+*/
+#define TCF_CLK_CTRL_MEM_THROUGH_SYS 0x01E8
+#define MEM_THROUGH_SYS_MASK 0x00000001U
+#define MEM_THROUGH_SYS_SHIFT 0
+#define MEM_THROUGH_SYS_SIGNED 0
+
+/*
+ Register HOST_PHY_OFFSET
+*/
+#define TCF_CLK_CTRL_HOST_PHY_OFFSET 0x01F0
+#define HOST_PHY_OFFSET_MASK 0xFFFFFFFFU
+#define HOST_PHY_OFFSET_SHIFT 0
+#define HOST_PHY_OFFSET_SIGNED 0
+
+/*
+ Register DEBUG_REG_SEL
+*/
+#define TCF_CLK_CTRL_DEBUG_REG_SEL 0x01F8
+#define DEBUG_REG_SELECT_MASK 0xFFFFFFFFU
+#define DEBUG_REG_SELECT_SHIFT 0
+#define DEBUG_REG_SELECT_SIGNED 0
+
+/*
+ Register DEBUG_REG
+*/
+#define TCF_CLK_CTRL_DEBUG_REG 0x0200
+#define DEBUG_REG_VALUE_MASK 0xFFFFFFFFU
+#define DEBUG_REG_VALUE_SHIFT 0
+#define DEBUG_REG_VALUE_SIGNED 0
+
+/*
+ Register JTAG_CTRL
+*/
+#define TCF_CLK_CTRL_JTAG_CTRL 0x0208
+#define JTAG_TRST_MASK 0x00000001U
+#define JTAG_TRST_SHIFT 0
+#define JTAG_TRST_SIGNED 0
+
+#define JTAG_TMS_MASK 0x00000002U
+#define JTAG_TMS_SHIFT 1
+#define JTAG_TMS_SIGNED 0
+
+#define JTAG_TCK_MASK 0x00000004U
+#define JTAG_TCK_SHIFT 2
+#define JTAG_TCK_SIGNED 0
+
+#define JTAG_TDO_MASK 0x00000008U
+#define JTAG_TDO_SHIFT 3
+#define JTAG_TDO_SIGNED 0
+
+#define JTAG_TDI_MASK 0x00000010U
+#define JTAG_TDI_SHIFT 4
+#define JTAG_TDI_SIGNED 0
+
+#define JTAG_DASH_N_REG_MASK 0x40000000U
+#define JTAG_DASH_N_REG_SHIFT 30
+#define JTAG_DASH_N_REG_SIGNED 0
+
+#define JTAG_DISABLE_MASK 0x80000000U
+#define JTAG_DISABLE_SHIFT 31
+#define JTAG_DISABLE_SIGNED 0
+
+/*
+ Register SAI_DEBUG_RDNWR
+*/
+#define TCF_CLK_CTRL_SAI_DEBUG_RDNWR 0x0300
+#define SAI_DEBUG_REG_ADDR_MASK 0x000001FFU
+#define SAI_DEBUG_REG_ADDR_SHIFT 0
+#define SAI_DEBUG_REG_ADDR_SIGNED 0
+
+#define SAI_DEBUG_REG_RDNWR_MASK 0x00000200U
+#define SAI_DEBUG_REG_RDNWR_SHIFT 9
+#define SAI_DEBUG_REG_RDNWR_SIGNED 0
+
+/*
+ Register SAI_DEBUG_WDATA
+*/
+#define TCF_CLK_CTRL_SAI_DEBUG_WDATA 0x0308
+#define SAI_DEBUG_REG_WDATA_MASK 0xFFFFFFFFU
+#define SAI_DEBUG_REG_WDATA_SHIFT 0
+#define SAI_DEBUG_REG_WDATA_SIGNED 0
+
+/*
+ Register SAI_DEBUG_RDATA
+*/
+#define TCF_CLK_CTRL_SAI_DEBUG_RDATA 0x0310
+#define SAI_DEBUG_REG_RDATA_MASK 0xFFFFFFFFU
+#define SAI_DEBUG_REG_RDATA_SHIFT 0
+#define SAI_DEBUG_REG_RDATA_SIGNED 0
+
+/*
+ Register SAI_DEBUG_GO
+*/
+#define TCF_CLK_CTRL_SAI_DEBUG_GO 0x0318
+#define SAI_DEBUG_REG_GO_MASK 0x00000001U
+#define SAI_DEBUG_REG_GO_SHIFT 0
+#define SAI_DEBUG_REG_GO_SIGNED 0
+
+/*
+ Register AUX_DUT_RESETS
+*/
+#define TCF_CLK_CTRL_AUX_DUT_RESETS 0x0320
+#define AUX_DUT_RESETS_MASK 0x0000000FU
+#define AUX_DUT_RESETS_SHIFT 0
+#define AUX_DUT_RESETS_SIGNED 0
+
+/*
+ Register DUT_CLK_CTRL
+*/
+#define TCF_CLK_CTRL_DUT_CLK_CTRL 0x0328
+#define MEM_REQ_PHSE_MASK 0x0000FFFFU
+#define MEM_REQ_PHSE_SHIFT 0
+#define MEM_REQ_PHSE_SIGNED 0
+
+/*
+ Register DUT_CLK_STATUS
+*/
+#define TCF_CLK_CTRL_DUT_CLK_STATUS 0x0330
+#define MEM_REQ_PHSE_SET_MASK 0x00000003U
+#define MEM_REQ_PHSE_SET_SHIFT 0
+#define MEM_REQ_PHSE_SET_SIGNED 0
+
+/*
+ Register DUT_CLK_INFO
+*/
+#define TCF_CLK_CTRL_DUT_CLK_INFO 0x0340
+#define CORE_MASK 0x0000FFFFU
+#define CORE_SHIFT 0
+#define CORE_SIGNED 0
+
+#define MEM_MASK 0xFFFF0000U
+#define MEM_SHIFT 16
+#define MEM_SIGNED 0
+
+/*
+ Register DUT_CLK_PHSE
+*/
+#define TCF_CLK_CTRL_DUT_CLK_PHSE 0x0348
+#define MEM_REQ_MASK 0x0000FFFFU
+#define MEM_REQ_SHIFT 0
+#define MEM_REQ_SIGNED 0
+
+#define MEM_RD_MASK 0xFFFF0000U
+#define MEM_RD_SHIFT 16
+#define MEM_RD_SIGNED 0
+
+#endif /* !defined(_TCF_CLK_CTRL_H_) */
+
+/*****************************************************************************
+ End of file (tcf_clk_ctrl.h)
+*****************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/system/rgx_tc/tcf_pll.h b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/tcf_pll.h
new file mode 100644
index 000000000..71eaf924b
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/tcf_pll.h
@@ -0,0 +1,311 @@
+/*************************************************************************/ /*!
+@Title Test Chip Framework PDP register definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Autogenerated C -- do not edit
+ Generated from tcf_pll.def
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(_TCF_PLL_H_)
+#define _TCF_PLL_H_
+
+/*
+ Register PLL_DDR2_CLK0
+*/
+#define TCF_PLL_PLL_DDR2_CLK0 0x0000
+#define DDR2_PLL_CLK0_PHS_MASK 0x00300000U
+#define DDR2_PLL_CLK0_PHS_SHIFT 20
+#define DDR2_PLL_CLK0_PHS_SIGNED 0
+
+#define DDR2_PLL_CLK0_MS_MASK 0x00030000U
+#define DDR2_PLL_CLK0_MS_SHIFT 16
+#define DDR2_PLL_CLK0_MS_SIGNED 0
+
+#define DDR2_PLL_CLK0_FREQ_MASK 0x000001FFU
+#define DDR2_PLL_CLK0_FREQ_SHIFT 0
+#define DDR2_PLL_CLK0_FREQ_SIGNED 0
+
+/*
+ Register PLL_DDR2_CLK1TO5
+*/
+#define TCF_PLL_PLL_DDR2_CLK1TO5 0x0008
+#define DDR2_PLL_CLK1TO5_PHS_MASK 0x3FF00000U
+#define DDR2_PLL_CLK1TO5_PHS_SHIFT 20
+#define DDR2_PLL_CLK1TO5_PHS_SIGNED 0
+
+#define DDR2_PLL_CLK1TO5_MS_MASK 0x000FFC00U
+#define DDR2_PLL_CLK1TO5_MS_SHIFT 10
+#define DDR2_PLL_CLK1TO5_MS_SIGNED 0
+
+#define DDR2_PLL_CLK1TO5_FREQ_MASK 0x000003FFU
+#define DDR2_PLL_CLK1TO5_FREQ_SHIFT 0
+#define DDR2_PLL_CLK1TO5_FREQ_SIGNED 0
+
+/*
+ Register PLL_DDR2_DRP_GO
+*/
+#define TCF_PLL_PLL_DDR2_DRP_GO 0x0010
+#define PLL_DDR2_DRP_GO_MASK 0x00000001U
+#define PLL_DDR2_DRP_GO_SHIFT 0
+#define PLL_DDR2_DRP_GO_SIGNED 0
+
+/*
+ Register PLL_PDP_CLK0
+*/
+#define TCF_PLL_PLL_PDP_CLK0 0x0018
+#define PDP_PLL_CLK0_PHS_MASK 0x00300000U
+#define PDP_PLL_CLK0_PHS_SHIFT 20
+#define PDP_PLL_CLK0_PHS_SIGNED 0
+
+#define PDP_PLL_CLK0_MS_MASK 0x00030000U
+#define PDP_PLL_CLK0_MS_SHIFT 16
+#define PDP_PLL_CLK0_MS_SIGNED 0
+
+#define PDP_PLL_CLK0_FREQ_MASK 0x000001FFU
+#define PDP_PLL_CLK0_FREQ_SHIFT 0
+#define PDP_PLL_CLK0_FREQ_SIGNED 0
+
+/*
+ Register PLL_PDP_CLK1TO5
+*/
+#define TCF_PLL_PLL_PDP_CLK1TO5 0x0020
+#define PDP_PLL_CLK1TO5_PHS_MASK 0x3FF00000U
+#define PDP_PLL_CLK1TO5_PHS_SHIFT 20
+#define PDP_PLL_CLK1TO5_PHS_SIGNED 0
+
+#define PDP_PLL_CLK1TO5_MS_MASK 0x000FFC00U
+#define PDP_PLL_CLK1TO5_MS_SHIFT 10
+#define PDP_PLL_CLK1TO5_MS_SIGNED 0
+
+#define PDP_PLL_CLK1TO5_FREQ_MASK 0x000003FFU
+#define PDP_PLL_CLK1TO5_FREQ_SHIFT 0
+#define PDP_PLL_CLK1TO5_FREQ_SIGNED 0
+
+/*
+ Register PLL_PDP_DRP_GO
+*/
+#define TCF_PLL_PLL_PDP_DRP_GO 0x0028
+#define PLL_PDP_DRP_GO_MASK 0x00000001U
+#define PLL_PDP_DRP_GO_SHIFT 0
+#define PLL_PDP_DRP_GO_SIGNED 0
+
+/*
+ Register PLL_PDP2_CLK0
+*/
+#define TCF_PLL_PLL_PDP2_CLK0 0x0030
+#define PDP2_PLL_CLK0_PHS_MASK 0x00300000U
+#define PDP2_PLL_CLK0_PHS_SHIFT 20
+#define PDP2_PLL_CLK0_PHS_SIGNED 0
+
+#define PDP2_PLL_CLK0_MS_MASK 0x00030000U
+#define PDP2_PLL_CLK0_MS_SHIFT 16
+#define PDP2_PLL_CLK0_MS_SIGNED 0
+
+#define PDP2_PLL_CLK0_FREQ_MASK 0x000001FFU
+#define PDP2_PLL_CLK0_FREQ_SHIFT 0
+#define PDP2_PLL_CLK0_FREQ_SIGNED 0
+
+/*
+ Register PLL_PDP2_CLK1TO5
+*/
+#define TCF_PLL_PLL_PDP2_CLK1TO5 0x0038
+#define PDP2_PLL_CLK1TO5_PHS_MASK 0x3FF00000U
+#define PDP2_PLL_CLK1TO5_PHS_SHIFT 20
+#define PDP2_PLL_CLK1TO5_PHS_SIGNED 0
+
+#define PDP2_PLL_CLK1TO5_MS_MASK 0x000FFC00U
+#define PDP2_PLL_CLK1TO5_MS_SHIFT 10
+#define PDP2_PLL_CLK1TO5_MS_SIGNED 0
+
+#define PDP2_PLL_CLK1TO5_FREQ_MASK 0x000003FFU
+#define PDP2_PLL_CLK1TO5_FREQ_SHIFT 0
+#define PDP2_PLL_CLK1TO5_FREQ_SIGNED 0
+
+/*
+ Register PLL_PDP2_DRP_GO
+*/
+#define TCF_PLL_PLL_PDP2_DRP_GO 0x0040
+#define PLL_PDP2_DRP_GO_MASK 0x00000001U
+#define PLL_PDP2_DRP_GO_SHIFT 0
+#define PLL_PDP2_DRP_GO_SIGNED 0
+
+/*
+ Register PLL_CORE_CLK0
+*/
+#define TCF_PLL_PLL_CORE_CLK0 0x0048
+#define CORE_PLL_CLK0_PHS_MASK 0x00300000U
+#define CORE_PLL_CLK0_PHS_SHIFT 20
+#define CORE_PLL_CLK0_PHS_SIGNED 0
+
+#define CORE_PLL_CLK0_MS_MASK 0x00030000U
+#define CORE_PLL_CLK0_MS_SHIFT 16
+#define CORE_PLL_CLK0_MS_SIGNED 0
+
+#define CORE_PLL_CLK0_FREQ_MASK 0x000001FFU
+#define CORE_PLL_CLK0_FREQ_SHIFT 0
+#define CORE_PLL_CLK0_FREQ_SIGNED 0
+
+/*
+ Register PLL_CORE_CLK1TO5
+*/
+#define TCF_PLL_PLL_CORE_CLK1TO5 0x0050
+#define CORE_PLL_CLK1TO5_PHS_MASK 0x3FF00000U
+#define CORE_PLL_CLK1TO5_PHS_SHIFT 20
+#define CORE_PLL_CLK1TO5_PHS_SIGNED 0
+
+#define CORE_PLL_CLK1TO5_MS_MASK 0x000FFC00U
+#define CORE_PLL_CLK1TO5_MS_SHIFT 10
+#define CORE_PLL_CLK1TO5_MS_SIGNED 0
+
+#define CORE_PLL_CLK1TO5_FREQ_MASK 0x000003FFU
+#define CORE_PLL_CLK1TO5_FREQ_SHIFT 0
+#define CORE_PLL_CLK1TO5_FREQ_SIGNED 0
+
+/*
+ Register PLL_CORE_DRP_GO
+*/
+#define TCF_PLL_PLL_CORE_DRP_GO 0x0058
+#define PLL_CORE_DRP_GO_MASK 0x00000001U
+#define PLL_CORE_DRP_GO_SHIFT 0
+#define PLL_CORE_DRP_GO_SIGNED 0
+
+/*
+ Register PLL_SYSIF_CLK0
+*/
+#define TCF_PLL_PLL_SYSIF_CLK0 0x0060
+#define SYSIF_PLL_CLK0_PHS_MASK 0x00300000U
+#define SYSIF_PLL_CLK0_PHS_SHIFT 20
+#define SYSIF_PLL_CLK0_PHS_SIGNED 0
+
+#define SYSIF_PLL_CLK0_MS_MASK 0x00030000U
+#define SYSIF_PLL_CLK0_MS_SHIFT 16
+#define SYSIF_PLL_CLK0_MS_SIGNED 0
+
+#define SYSIF_PLL_CLK0_FREQ_MASK 0x000001FFU
+#define SYSIF_PLL_CLK0_FREQ_SHIFT 0
+#define SYSIF_PLL_CLK0_FREQ_SIGNED 0
+
+/*
+ Register PLL_SYSIF_CLK1TO5
+*/
+#define TCF_PLL_PLL_SYSIF_CLK1TO5 0x0068
+#define SYSIF_PLL_CLK1TO5_PHS_MASK 0x3FF00000U
+#define SYSIF_PLL_CLK1TO5_PHS_SHIFT 20
+#define SYSIF_PLL_CLK1TO5_PHS_SIGNED 0
+
+#define SYSIF_PLL_CLK1TO5_MS_MASK 0x000FFC00U
+#define SYSIF_PLL_CLK1TO5_MS_SHIFT 10
+#define SYSIF_PLL_CLK1TO5_MS_SIGNED 0
+
+#define SYSIF_PLL_CLK1TO5_FREQ_MASK 0x000003FFU
+#define SYSIF_PLL_CLK1TO5_FREQ_SHIFT 0
+#define SYSIF_PLL_CLK1TO5_FREQ_SIGNED 0
+
+/*
+ Register PLL_SYS_DRP_GO
+*/
+#define TCF_PLL_PLL_SYS_DRP_GO 0x0070
+#define PLL_SYS_DRP_GO_MASK 0x00000001U
+#define PLL_SYS_DRP_GO_SHIFT 0
+#define PLL_SYS_DRP_GO_SIGNED 0
+
+/*
+ Register PLL_MEMIF_CLK0
+*/
+#define TCF_PLL_PLL_MEMIF_CLK0 0x0078
+#define MEMIF_PLL_CLK0_PHS_MASK 0x00300000U
+#define MEMIF_PLL_CLK0_PHS_SHIFT 20
+#define MEMIF_PLL_CLK0_PHS_SIGNED 0
+
+#define MEMIF_PLL_CLK0_MS_MASK 0x00030000U
+#define MEMIF_PLL_CLK0_MS_SHIFT 16
+#define MEMIF_PLL_CLK0_MS_SIGNED 0
+
+#define MEMIF_PLL_CLK0_FREQ_MASK 0x000001FFU
+#define MEMIF_PLL_CLK0_FREQ_SHIFT 0
+#define MEMIF_PLL_CLK0_FREQ_SIGNED 0
+
+/*
+ Register PLL_MEMIF_CLK1TO5
+*/
+#define TCF_PLL_PLL_MEMIF_CLK1TO5 0x0080
+#define MEMIF_PLL_CLK1TO5_PHS_MASK 0x3FF00000U
+#define MEMIF_PLL_CLK1TO5_PHS_SHIFT 20
+#define MEMIF_PLL_CLK1TO5_PHS_SIGNED 0
+
+#define MEMIF_PLL_CLK1TO5_MS_MASK 0x000FFC00U
+#define MEMIF_PLL_CLK1TO5_MS_SHIFT 10
+#define MEMIF_PLL_CLK1TO5_MS_SIGNED 0
+
+#define MEMIF_PLL_CLK1TO5_FREQ_MASK 0x000003FFU
+#define MEMIF_PLL_CLK1TO5_FREQ_SHIFT 0
+#define MEMIF_PLL_CLK1TO5_FREQ_SIGNED 0
+
+/*
+ Register PLL_MEM_DRP_GO
+*/
+#define TCF_PLL_PLL_MEM_DRP_GO 0x0088
+#define PLL_MEM_DRP_GO_MASK 0x00000001U
+#define PLL_MEM_DRP_GO_SHIFT 0
+#define PLL_MEM_DRP_GO_SIGNED 0
+
+/*
+ Register PLL_ALL_DRP_GO
+*/
+#define TCF_PLL_PLL_ALL_DRP_GO 0x0090
+#define PLL_ALL_DRP_GO_MASK 0x00000001U
+#define PLL_ALL_DRP_GO_SHIFT 0
+#define PLL_ALL_DRP_GO_SIGNED 0
+
+/*
+ Register PLL_DRP_STATUS
+*/
+#define TCF_PLL_PLL_DRP_STATUS 0x0098
+#define PLL_LOCKS_MASK 0x00003F00U
+#define PLL_LOCKS_SHIFT 8
+#define PLL_LOCKS_SIGNED 0
+
+#define PLL_DRP_GOOD_MASK 0x0000003FU
+#define PLL_DRP_GOOD_SHIFT 0
+#define PLL_DRP_GOOD_SIGNED 0
+
+#endif /* !defined(_TCF_PLL_H_) */
+
+/*****************************************************************************
+ End of file (tcf_pll.h)
+*****************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/system/rgx_tc/tcf_rgbpdp_regs.h b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/tcf_rgbpdp_regs.h
new file mode 100644
index 000000000..e87ba6152
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/system/rgx_tc/tcf_rgbpdp_regs.h
@@ -0,0 +1,559 @@
+/*************************************************************************/ /*!
+@Title Test Chip Framework PDP register definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Autogenerated C -- do not edit
+ Generated from: tcf_rgbpdp_regs.def
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(_TCF_RGBPDP_REGS_H_)
+#define _TCF_RGBPDP_REGS_H_
+
+/*
+ Register PVR_TCF_RGBPDP_STR1SURF
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_STR1SURF 0x0000
+#define STR1HEIGHT_MASK 0x000007FFU
+#define STR1HEIGHT_SHIFT 0
+#define STR1HEIGHT_SIGNED 0
+
+#define STR1WIDTH_MASK 0x003FF800U
+#define STR1WIDTH_SHIFT 11
+#define STR1WIDTH_SIGNED 0
+
+#define STR1PIXFMT_MASK 0x0F000000U
+#define STR1PIXFMT_SHIFT 24
+#define STR1PIXFMT_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_STR1ADDRCTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_STR1ADDRCTRL 0x0004
+#define STR1BASE_MASK 0x03FFFFFFU
+#define STR1BASE_SHIFT 0
+#define STR1BASE_SIGNED 0
+
+#define STR1INTFIELD_MASK 0x40000000U
+#define STR1INTFIELD_SHIFT 30
+#define STR1INTFIELD_SIGNED 0
+
+#define STR1STREN_MASK 0x80000000U
+#define STR1STREN_SHIFT 31
+#define STR1STREN_SIGNED 0
+
+/*
+ Register PVR_PDP_STR1POSN
+*/
+#define TCF_RGBPDP_PVR_PDP_STR1POSN 0x0008
+#define STR1STRIDE_MASK 0x000003FFU
+#define STR1STRIDE_SHIFT 0
+#define STR1STRIDE_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_MEMCTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_MEMCTRL 0x000C
+#define MEMREFRESH_MASK 0xC0000000U
+#define MEMREFRESH_SHIFT 30
+#define MEMREFRESH_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_STRCTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_STRCTRL 0x0010
+#define BURSTLEN_GFX_MASK 0x000000FFU
+#define BURSTLEN_GFX_SHIFT 0
+#define BURSTLEN_GFX_SIGNED 0
+
+#define THRESHOLD_GFX_MASK 0x0000FF00U
+#define THRESHOLD_GFX_SHIFT 8
+#define THRESHOLD_GFX_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_SYNCCTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_SYNCCTRL 0x0014
+#define HSDIS_MASK 0x00000001U
+#define HSDIS_SHIFT 0
+#define HSDIS_SIGNED 0
+
+#define HSPOL_MASK 0x00000002U
+#define HSPOL_SHIFT 1
+#define HSPOL_SIGNED 0
+
+#define VSDIS_MASK 0x00000004U
+#define VSDIS_SHIFT 2
+#define VSDIS_SIGNED 0
+
+#define VSPOL_MASK 0x00000008U
+#define VSPOL_SHIFT 3
+#define VSPOL_SIGNED 0
+
+#define BLNKDIS_MASK 0x00000010U
+#define BLNKDIS_SHIFT 4
+#define BLNKDIS_SIGNED 0
+
+#define BLNKPOL_MASK 0x00000020U
+#define BLNKPOL_SHIFT 5
+#define BLNKPOL_SIGNED 0
+
+#define HS_SLAVE_MASK 0x00000040U
+#define HS_SLAVE_SHIFT 6
+#define HS_SLAVE_SIGNED 0
+
+#define VS_SLAVE_MASK 0x00000080U
+#define VS_SLAVE_SHIFT 7
+#define VS_SLAVE_SIGNED 0
+
+#define INTERLACE_MASK 0x00000100U
+#define INTERLACE_SHIFT 8
+#define INTERLACE_SIGNED 0
+
+#define FIELDPOL_MASK 0x00000200U
+#define FIELDPOL_SHIFT 9
+#define FIELDPOL_SIGNED 0
+
+#define CLKPOL_MASK 0x00000800U
+#define CLKPOL_SHIFT 11
+#define CLKPOL_SIGNED 0
+
+#define CSYNC_EN_MASK 0x00001000U
+#define CSYNC_EN_SHIFT 12
+#define CSYNC_EN_SIGNED 0
+
+#define FIELD_EN_MASK 0x00002000U
+#define FIELD_EN_SHIFT 13
+#define FIELD_EN_SIGNED 0
+
+#define UPDWAIT_MASK 0x000F0000U
+#define UPDWAIT_SHIFT 16
+#define UPDWAIT_SIGNED 0
+
+#define UPDCTRL_MASK 0x01000000U
+#define UPDCTRL_SHIFT 24
+#define UPDCTRL_SIGNED 0
+
+#define UPDINTCTRL_MASK 0x02000000U
+#define UPDINTCTRL_SHIFT 25
+#define UPDINTCTRL_SIGNED 0
+
+#define UPDSYNCTRL_MASK 0x04000000U
+#define UPDSYNCTRL_SHIFT 26
+#define UPDSYNCTRL_SIGNED 0
+
+#define POWERDN_MASK 0x10000000U
+#define POWERDN_SHIFT 28
+#define POWERDN_SIGNED 0
+
+#define DISP_RST_MASK 0x20000000U
+#define DISP_RST_SHIFT 29
+#define DISP_RST_SIGNED 0
+
+#define SYNCACTIVE_MASK 0x80000000U
+#define SYNCACTIVE_SHIFT 31
+#define SYNCACTIVE_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_BORDCOL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_BORDCOL 0x0018
+#define BORDCOL_MASK 0x00FFFFFFU
+#define BORDCOL_SHIFT 0
+#define BORDCOL_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_UPDCTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_UPDCTRL 0x001C
+#define UPDFIELD_MASK 0x00000001U
+#define UPDFIELD_SHIFT 0
+#define UPDFIELD_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_HSYNC1
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_HSYNC1 0x0020
+#define HT_MASK 0x00000FFFU
+#define HT_SHIFT 0
+#define HT_SIGNED 0
+
+#define HBPS_MASK 0x0FFF0000U
+#define HBPS_SHIFT 16
+#define HBPS_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_HSYNC2
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_HSYNC2 0x0024
+#define HLBS_MASK 0x00000FFFU
+#define HLBS_SHIFT 0
+#define HLBS_SIGNED 0
+
+#define HAS_MASK 0x0FFF0000U
+#define HAS_SHIFT 16
+#define HAS_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_HSYNC3
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_HSYNC3 0x0028
+#define HRBS_MASK 0x00000FFFU
+#define HRBS_SHIFT 0
+#define HRBS_SIGNED 0
+
+#define HFPS_MASK 0x0FFF0000U
+#define HFPS_SHIFT 16
+#define HFPS_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_VSYNC1
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_VSYNC1 0x002C
+#define VT_MASK 0x00000FFFU
+#define VT_SHIFT 0
+#define VT_SIGNED 0
+
+#define VBPS_MASK 0x0FFF0000U
+#define VBPS_SHIFT 16
+#define VBPS_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_VSYNC2
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_VSYNC2 0x0030
+#define VTBS_MASK 0x00000FFFU
+#define VTBS_SHIFT 0
+#define VTBS_SIGNED 0
+
+#define VAS_MASK 0x0FFF0000U
+#define VAS_SHIFT 16
+#define VAS_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_VSYNC3
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_VSYNC3 0x0034
+#define VBBS_MASK 0x00000FFFU
+#define VBBS_SHIFT 0
+#define VBBS_SIGNED 0
+
+#define VFPS_MASK 0x0FFF0000U
+#define VFPS_SHIFT 16
+#define VFPS_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_HDECTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_HDECTRL 0x0038
+#define HDEF_MASK 0x00000FFFU
+#define HDEF_SHIFT 0
+#define HDEF_SIGNED 0
+
+#define HDES_MASK 0x0FFF0000U
+#define HDES_SHIFT 16
+#define HDES_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_VDECTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_VDECTRL 0x003C
+#define VDEF_MASK 0x00000FFFU
+#define VDEF_SHIFT 0
+#define VDEF_SIGNED 0
+
+#define VDES_MASK 0x0FFF0000U
+#define VDES_SHIFT 16
+#define VDES_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_VEVENT
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_VEVENT 0x0040
+#define VFETCH_MASK 0x00000FFFU
+#define VFETCH_SHIFT 0
+#define VFETCH_SIGNED 0
+
+#define VEVENT_MASK 0x0FFF0000U
+#define VEVENT_SHIFT 16
+#define VEVENT_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_OPMASK
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_OPMASK 0x0044
+#define MASKR_MASK 0x000000FFU
+#define MASKR_SHIFT 0
+#define MASKR_SIGNED 0
+
+#define MASKG_MASK 0x0000FF00U
+#define MASKG_SHIFT 8
+#define MASKG_SIGNED 0
+
+#define MASKB_MASK 0x00FF0000U
+#define MASKB_SHIFT 16
+#define MASKB_SIGNED 0
+
+#define BLANKLEVEL_MASK 0x40000000U
+#define BLANKLEVEL_SHIFT 30
+#define BLANKLEVEL_SIGNED 0
+
+#define MASKLEVEL_MASK 0x80000000U
+#define MASKLEVEL_SHIFT 31
+#define MASKLEVEL_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_INTSTAT
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_INTSTAT 0x0048
+#define INTS_HBLNK0_MASK 0x00000001U
+#define INTS_HBLNK0_SHIFT 0
+#define INTS_HBLNK0_SIGNED 0
+
+#define INTS_HBLNK1_MASK 0x00000002U
+#define INTS_HBLNK1_SHIFT 1
+#define INTS_HBLNK1_SIGNED 0
+
+#define INTS_VBLNK0_MASK 0x00000004U
+#define INTS_VBLNK0_SHIFT 2
+#define INTS_VBLNK0_SIGNED 0
+
+#define INTS_VBLNK1_MASK 0x00000008U
+#define INTS_VBLNK1_SHIFT 3
+#define INTS_VBLNK1_SIGNED 0
+
+#define INTS_STR1URUN_MASK 0x00000010U
+#define INTS_STR1URUN_SHIFT 4
+#define INTS_STR1URUN_SIGNED 0
+
+#define INTS_STR1ORUN_MASK 0x00000020U
+#define INTS_STR1ORUN_SHIFT 5
+#define INTS_STR1ORUN_SIGNED 0
+
+#define INTS_DISPURUN_MASK 0x00000040U
+#define INTS_DISPURUN_SHIFT 6
+#define INTS_DISPURUN_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_INTENAB
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_INTENAB 0x004C
+#define INTEN_HBLNK0_MASK 0x00000001U
+#define INTEN_HBLNK0_SHIFT 0
+#define INTEN_HBLNK0_SIGNED 0
+
+#define INTEN_HBLNK1_MASK 0x00000002U
+#define INTEN_HBLNK1_SHIFT 1
+#define INTEN_HBLNK1_SIGNED 0
+
+#define INTEN_VBLNK0_MASK 0x00000004U
+#define INTEN_VBLNK0_SHIFT 2
+#define INTEN_VBLNK0_SIGNED 0
+
+#define INTEN_VBLNK1_MASK 0x00000008U
+#define INTEN_VBLNK1_SHIFT 3
+#define INTEN_VBLNK1_SIGNED 0
+
+#define INTEN_STR1URUN_MASK 0x00000010U
+#define INTEN_STR1URUN_SHIFT 4
+#define INTEN_STR1URUN_SIGNED 0
+
+#define INTEN_STR1ORUN_MASK 0x00000020U
+#define INTEN_STR1ORUN_SHIFT 5
+#define INTEN_STR1ORUN_SIGNED 0
+
+#define INTEN_DISPURUN_MASK 0x00000040U
+#define INTEN_DISPURUN_SHIFT 6
+#define INTEN_DISPURUN_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_INTCLEAR
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_INTCLEAR 0x0050
+#define INTCLR_HBLNK0_MASK 0x00000001U
+#define INTCLR_HBLNK0_SHIFT 0
+#define INTCLR_HBLNK0_SIGNED 0
+
+#define INTCLR_HBLNK1_MASK 0x00000002U
+#define INTCLR_HBLNK1_SHIFT 1
+#define INTCLR_HBLNK1_SIGNED 0
+
+#define INTCLR_VBLNK0_MASK 0x00000004U
+#define INTCLR_VBLNK0_SHIFT 2
+#define INTCLR_VBLNK0_SIGNED 0
+
+#define INTCLR_VBLNK1_MASK 0x00000008U
+#define INTCLR_VBLNK1_SHIFT 3
+#define INTCLR_VBLNK1_SIGNED 0
+
+#define INTCLR_STR1URUN_MASK 0x00000010U
+#define INTCLR_STR1URUN_SHIFT 4
+#define INTCLR_STR1URUN_SIGNED 0
+
+#define INTCLR_STR1ORUN_MASK 0x00000020U
+#define INTCLR_STR1ORUN_SHIFT 5
+#define INTCLR_STR1ORUN_SIGNED 0
+
+#define INTCLR_DISPURUN_MASK 0x00000040U
+#define INTCLR_DISPURUN_SHIFT 6
+#define INTCLR_DISPURUN_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_INTCTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_INTCTRL 0x0054
+#define HBLNK_LINENO_MASK 0x00000FFFU
+#define HBLNK_LINENO_SHIFT 0
+#define HBLNK_LINENO_SIGNED 0
+
+#define HBLNK_LINE_MASK 0x00010000U
+#define HBLNK_LINE_SHIFT 16
+#define HBLNK_LINE_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_SIGNAT
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_SIGNAT 0x0058
+#define SIGNATURE_MASK 0xFFFFFFFFU
+#define SIGNATURE_SHIFT 0
+#define SIGNATURE_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_LINESTAT
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_LINESTAT 0x005C
+#define LINENO_MASK 0x00000FFFU
+#define LINENO_SHIFT 0
+#define LINENO_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_DBGCTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_DBGCTRL 0x0060
+#define DBG_ENAB_MASK 0x00000001U
+#define DBG_ENAB_SHIFT 0
+#define DBG_ENAB_SIGNED 0
+
+#define DBG_READ_MASK 0x00000002U
+#define DBG_READ_SHIFT 1
+#define DBG_READ_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_DBGDATA
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_DBGDATA 0x0064
+#define DBG_DATA_MASK 0x00FFFFFFU
+#define DBG_DATA_SHIFT 0
+#define DBG_DATA_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_DBGSIDE
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_DBGSIDE 0x0068
+#define DBG_SIDE_MASK 0x00000007U
+#define DBG_SIDE_SHIFT 0
+#define DBG_SIDE_SIGNED 0
+
+#define DBG_VAL_MASK 0x00000008U
+#define DBG_VAL_SHIFT 3
+#define DBG_VAL_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_REGLD_STAT
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_REGLD_STAT 0x0070
+#define REGLD_ADDROUT_MASK 0x00FFFFFFU
+#define REGLD_ADDROUT_SHIFT 0
+#define REGLD_ADDROUT_SIGNED 0
+
+#define REGLD_ADDREN_MASK 0x80000000U
+#define REGLD_ADDREN_SHIFT 31
+#define REGLD_ADDREN_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_REGLD_CTRL
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_REGLD_CTRL 0x0074
+#define REGLD_ADDRIN_MASK 0x00FFFFFFU
+#define REGLD_ADDRIN_SHIFT 0
+#define REGLD_ADDRIN_SIGNED 0
+
+#define REGLD_VAL_MASK 0x01000000U
+#define REGLD_VAL_SHIFT 24
+#define REGLD_VAL_SIGNED 0
+
+#define REGLD_ADDRLEN_MASK 0xFE000000U
+#define REGLD_ADDRLEN_SHIFT 25
+#define REGLD_ADDRLEN_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_CORE_ID
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_CORE_ID 0x0078
+#define CONFIG_ID_MASK 0x0000FFFFU
+#define CONFIG_ID_SHIFT 0
+#define CONFIG_ID_SIGNED 0
+
+#define CORE_ID_MASK 0x00FF0000U
+#define CORE_ID_SHIFT 16
+#define CORE_ID_SIGNED 0
+
+#define GROUP_ID_MASK 0xFF000000U
+#define GROUP_ID_SHIFT 24
+#define GROUP_ID_SIGNED 0
+
+/*
+ Register PVR_TCF_RGBPDP_CORE_REV
+*/
+#define TCF_RGBPDP_PVR_TCF_RGBPDP_CORE_REV 0x007C
+#define MAINT_REV_MASK 0x000000FFU
+#define MAINT_REV_SHIFT 0
+#define MAINT_REV_SIGNED 0
+
+#define MINOR_REV_MASK 0x0000FF00U
+#define MINOR_REV_SHIFT 8
+#define MINOR_REV_SIGNED 0
+
+#define MAJOR_REV_MASK 0x00FF0000U
+#define MAJOR_REV_SHIFT 16
+#define MAJOR_REV_SIGNED 0
+
+#endif /* !defined(_TCF_RGBPDP_REGS_H_) */
+
+/*****************************************************************************
+ End of file (tcf_rgbpdp_regs.h)
+*****************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/volcanic/rgx_fwif_alignchecks.h b/drivers/gpu/drm/img-rogue/include/volcanic/rgx_fwif_alignchecks.h
new file mode 100644
index 000000000..c09b369f8
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/volcanic/rgx_fwif_alignchecks.h
@@ -0,0 +1,191 @@
+/*************************************************************************/ /*!
+@File
+@Title RGX fw interface alignment checks
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Checks to avoid disalignment in RGX fw data structures
+ shared with the host
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(RGX_FWIF_ALIGNCHECKS_H)
+#define RGX_FWIF_ALIGNCHECKS_H
+
+/* for the offsetof macro */
+#if defined(__KERNEL__) && defined(__linux__)
+#include
+#else
+#include
+#endif
+
+/*!
+ ******************************************************************************
+ * Alignment UM/FW checks array
+ *****************************************************************************/
+
+#define RGXFW_ALIGN_CHECKS_UM_MAX 128U
+
+#if defined(PM_INTERACTIVE_MODE)
+#define HWRTDATA_PM_OFFSET offsetof(RGXFWIF_HWRTDATA, sPMMListDevVAddr),
+#define HWRTDATA_HEAPTABLE_OFFSET offsetof(RGXFWIF_HWRTDATA, psVHeapTableDevVAddr),
+#else
+#define HWRTDATA_PM_OFFSET offsetof(RGXFWIF_HWRTDATA, sPMRenderStateDevVAddr),
+#define HWRTDATA_HEAPTABLE_OFFSET
+#endif
+
+#define RGXFW_ALIGN_CHECKS_INIT0 \
+ sizeof(RGXFWIF_TRACEBUF), \
+ offsetof(RGXFWIF_TRACEBUF, ui32LogType), \
+ offsetof(RGXFWIF_TRACEBUF, sTraceBuf), \
+ offsetof(RGXFWIF_TRACEBUF, ui32TraceBufSizeInDWords), \
+ offsetof(RGXFWIF_TRACEBUF, ui32TracebufFlags), \
+ \
+ sizeof(RGXFWIF_SYSDATA), \
+ offsetof(RGXFWIF_SYSDATA, ePowState), \
+ offsetof(RGXFWIF_SYSDATA, ui32HWPerfDropCount), \
+ offsetof(RGXFWIF_SYSDATA, ui32LastDropOrdinal), \
+ offsetof(RGXFWIF_SYSDATA, ui32FWFaults), \
+ offsetof(RGXFWIF_SYSDATA, ui32HWRStateFlags), \
+ \
+ sizeof(RGXFWIF_OSDATA), \
+ offsetof(RGXFWIF_OSDATA, ui32HostSyncCheckMark), \
+ offsetof(RGXFWIF_OSDATA, ui32KCCBCmdsExecuted), \
+ \
+ sizeof(RGXFWIF_HWRINFOBUF), \
+ offsetof(RGXFWIF_HWRINFOBUF, aui32HwrDmLockedUpCount), \
+ offsetof(RGXFWIF_HWRINFOBUF, aui32HwrDmOverranCount), \
+ offsetof(RGXFWIF_HWRINFOBUF, aui32HwrDmRecoveredCount), \
+ offsetof(RGXFWIF_HWRINFOBUF, aui32HwrDmFalseDetectCount), \
+ \
+ /* RGXFWIF_CMDTA checks */ \
+ sizeof(RGXFWIF_CMDTA), \
+ offsetof(RGXFWIF_CMDTA, sGeomRegs), \
+ \
+ /* RGXFWIF_CMD3D checks */ \
+ sizeof(RGXFWIF_CMD3D), \
+ offsetof(RGXFWIF_CMD3D, s3DRegs), \
+ \
+ /* RGXFWIF_CMD_COMPUTE checks */ \
+ sizeof(RGXFWIF_CMD_COMPUTE), \
+ offsetof(RGXFWIF_CMD_COMPUTE, sCDMRegs), \
+ \
+ /* RGXFWIF_FREELIST checks */ \
+ sizeof(RGXFWIF_FREELIST), \
+ offsetof(RGXFWIF_FREELIST, sFreeListBaseDevVAddr),\
+ offsetof(RGXFWIF_FREELIST, sFreeListStateDevVAddr),\
+ offsetof(RGXFWIF_FREELIST, sFreeListLastGrowDevVAddr),\
+ offsetof(RGXFWIF_FREELIST, ui32MaxPages),\
+ offsetof(RGXFWIF_FREELIST, ui32CurrentPages),\
+ \
+ /* RGXFWIF_HWRTDATA checks */ \
+ sizeof(RGXFWIF_HWRTDATA), \
+ HWRTDATA_PM_OFFSET \
+ HWRTDATA_HEAPTABLE_OFFSET \
+ offsetof(RGXFWIF_HWRTDATA, apsFreeLists),\
+ /*offsetof(RGXFWIF_HWRTDATA, ui64VCECatBase),*/ \
+ offsetof(RGXFWIF_HWRTDATA, eState), \
+ \
+\
+ sizeof(RGXFWIF_HWPERF_CTL), \
+ offsetof(RGXFWIF_HWPERF_CTL, sBlkCfg), \
+ sizeof(RGXFWIF_CMDTDM), \
+ offsetof(RGXFWIF_CMDTDM, sTDMRegs)
+
+#define RGXFW_ALIGN_CHECKS_INIT RGXFW_ALIGN_CHECKS_INIT0
+
+
+
+/*!
+ ******************************************************************************
+ * Alignment KM checks array
+ *****************************************************************************/
+
+#define RGXFW_ALIGN_CHECKS_INIT_KM0 \
+ sizeof(RGXFWIF_SYSINIT), \
+ offsetof(RGXFWIF_SYSINIT, sFaultPhysAddr), \
+ offsetof(RGXFWIF_SYSINIT, sPDSExecBase), \
+ offsetof(RGXFWIF_SYSINIT, sUSCExecBase), \
+ offsetof(RGXFWIF_SYSINIT, asSigBufCtl), \
+ offsetof(RGXFWIF_SYSINIT, sTraceBufCtl), \
+ offsetof(RGXFWIF_SYSINIT, sFwSysData), \
+ \
+ sizeof(RGXFWIF_OSINIT), \
+ offsetof(RGXFWIF_OSINIT, psKernelCCBCtl), \
+ offsetof(RGXFWIF_OSINIT, psKernelCCB), \
+ offsetof(RGXFWIF_OSINIT, psFirmwareCCBCtl), \
+ offsetof(RGXFWIF_OSINIT, psFirmwareCCB), \
+ offsetof(RGXFWIF_OSINIT, sFwOsData), \
+ offsetof(RGXFWIF_OSINIT, sRGXCompChecks), \
+ \
+ /* RGXFWIF_FWRENDERCONTEXT checks */ \
+ sizeof(RGXFWIF_FWRENDERCONTEXT), \
+ offsetof(RGXFWIF_FWRENDERCONTEXT, sTAContext), \
+ offsetof(RGXFWIF_FWRENDERCONTEXT, s3DContext), \
+ \
+ sizeof(RGXFWIF_FWCOMPUTECONTEXT), \
+ offsetof(RGXFWIF_FWCOMPUTECONTEXT, sCDMContext), \
+ offsetof(RGXFWIF_FWCOMPUTECONTEXT, sStaticComputeContextState),\
+ offsetof(RGXFWIF_FWCOMPUTECONTEXT, ui32WorkEstCCBSubmitted),\
+ \
+ sizeof(RGXFWIF_FWTDMCONTEXT), \
+ offsetof(RGXFWIF_FWTDMCONTEXT, sTDMContext), \
+ offsetof(RGXFWIF_FWTDMCONTEXT, ui32WorkEstCCBSubmitted),\
+ \
+ sizeof(RGXFWIF_FWCOMMONCONTEXT), \
+ offsetof(RGXFWIF_FWCOMMONCONTEXT, psFWMemContext), \
+ offsetof(RGXFWIF_FWCOMMONCONTEXT, sRunNode), \
+ offsetof(RGXFWIF_FWCOMMONCONTEXT, psCCB), \
+ \
+ sizeof(RGXFWIF_MMUCACHEDATA), \
+ offsetof(RGXFWIF_MMUCACHEDATA, ui32CacheFlags), \
+ offsetof(RGXFWIF_MMUCACHEDATA, sMMUCacheSync), \
+ offsetof(RGXFWIF_MMUCACHEDATA, ui32MMUCacheSyncUpdateValue)
+
+#if defined(SUPPORT_TRP)
+#define RGXFW_ALIGN_CHECKS_INIT_KM \
+ RGXFW_ALIGN_CHECKS_INIT_KM0, \
+ offsetof(RGXFWIF_FWTDMCONTEXT, ui32TRPState), \
+ offsetof(RGXFWIF_FWTDMCONTEXT, aui64TRPChecksums2D)
+#else
+#define RGXFW_ALIGN_CHECKS_INIT_KM RGXFW_ALIGN_CHECKS_INIT_KM0
+#endif
+
+#endif /* RGX_FWIF_ALIGNCHECKS_H */
+
+/******************************************************************************
+ End of file (rgx_fwif_alignchecks.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/volcanic/rgx_fwif_hwperf.h b/drivers/gpu/drm/img-rogue/include/volcanic/rgx_fwif_hwperf.h
new file mode 100644
index 000000000..e430e86d6
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/volcanic/rgx_fwif_hwperf.h
@@ -0,0 +1,125 @@
+/*************************************************************************/ /*!
+@File rgx_fwif_hwperf.h
+@Title RGX HWPerf support
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Shared header between RGX firmware and Init process
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef RGX_FWIF_HWPERF_H
+#define RGX_FWIF_HWPERF_H
+
+#include "rgx_fwif_shared.h"
+#include "rgx_hwperf.h"
+#include "rgxdefs_km.h"
+
+/* Server and Firmware definitions only */
+
+/*! The number of HWPerf blocks in the GPU */
+
+#if defined(RGX_FIRMWARE)
+#define RGX_HWPERF_NUM_SPU ((RGX_FEATURE_NUM_SPU))
+#define RGX_HWPERF_NUM_USC ((RGX_FEATURE_NUM_CLUSTERS))
+#define RGX_HWPERF_NUM_ISP_PER_SPU ((RGX_FEATURE_NUM_ISP_PER_SPU))
+#define RGX_HWPERF_NUM_PBE ((RGX_FEATURE_PBE_PER_SPU) * (RGX_FEATURE_NUM_SPU))
+#define RGX_HWPERF_NUM_MERCER ((RGX_FEATURE_NUM_CLUSTERS))
+#define RGX_HWPERF_NUM_PBE_SHARED ((RGX_FEATURE_NUM_SPU))
+#define RGX_HWPERF_NUM_SWIFT ((RGX_FEATURE_NUM_SPU * RGX_FEATURE_MAX_TPU_PER_SPU))
+#define RGX_HWPERF_NUM_TEXAS ((RGX_FEATURE_NUM_SPU))
+#if (RGX_FEATURE_RAY_TRACING_ARCH > 2)
+#define RGX_HWPERF_NUM_RAC ((RGX_FEATURE_NUM_SPU))
+#else
+#define RGX_HWPERF_NUM_RAC ((0))
+#endif
+#define RGX_HWPERF_NUM_TPU ((RGX_FEATURE_NUM_SPU * RGX_FEATURE_MAX_TPU_PER_SPU))
+#define RGX_HWPERF_NUM_ISP ((RGX_FEATURE_NUM_CLUSTERS))
+
+#define RGX_CNTBLK_INDIRECT_COUNT(_class) ((RGX_HWPERF_NUM_ ## _class))
+
+/*! The number of layout blocks defined with configurable
+ * performance counters. Compile time constants.
+ * This is for the Series 8XT+ layout.
+ */
+#define RGX_HWPERF_MAX_DEFINED_BLKS (\
+ (IMG_UINT32)RGX_CNTBLK_ID_DIRECT_LAST +\
+ RGX_CNTBLK_INDIRECT_COUNT(ISP) +\
+ RGX_CNTBLK_INDIRECT_COUNT(MERCER) +\
+ RGX_CNTBLK_INDIRECT_COUNT(PBE) +\
+ RGX_CNTBLK_INDIRECT_COUNT(PBE_SHARED) +\
+ RGX_CNTBLK_INDIRECT_COUNT(USC) +\
+ RGX_CNTBLK_INDIRECT_COUNT(TPU) +\
+ RGX_CNTBLK_INDIRECT_COUNT(SWIFT) +\
+ RGX_CNTBLK_INDIRECT_COUNT(TEXAS) +\
+ RGX_CNTBLK_INDIRECT_COUNT(RAC))
+
+#endif /* RGX_FIRMWARE */
+
+/*****************************************************************************/
+
+/* Structure used in the FW's global control data to hold the performance
+ * counters provisioned for a given block. */
+typedef struct
+{
+ IMG_UINT32 uiBlockID;
+ IMG_UINT32 uiNumCounters; // Number of counters held
+ // in aui32CounterCfg
+ // [0..RGX_CNTBLK_COUNTERS_MAX)
+ IMG_UINT32 uiEnabled; // 1 => enabled, 0=> disabled
+ RGXFWIF_DEV_VIRTADDR psModel; // link to model table for uiBlockID
+ IMG_UINT32 aui32CounterCfg[RGX_CNTBLK_COUNTERS_MAX];
+} RGXFWIF_HWPERF_CTL_BLK;
+
+
+/*!
+ *****************************************************************************
+ * Structure used in the FW's global RGXFW_CTL store, holding HWPerf counter
+ * block configuration. It is written to by the Server on FW initialisation
+ * (PDUMP=1) and by the FW BG kCCB command processing code. It is read by
+ * the FW IRQ register programming and HWPerf event generation routines.
+ * Size of the sBlkCfg[] array must be consistent between KM/UM and FW.
+ * FW will ASSERT if the sizes are different
+ * (ui32NumBlocks != RGX_HWPERF_MAX_DEFINED_BLKS)
+ ****************************************************************************/
+typedef struct
+{
+ IMG_UINT32 ui32Reserved;
+ IMG_UINT32 ui32CtrlWord;
+ IMG_UINT32 ui32EnabledBlksCount;
+ IMG_UINT32 ui32NumBlocks;
+ RGXFWIF_HWPERF_CTL_BLK RGXFW_ALIGN sBlkCfg[1]; // First array entry
+} UNCACHED_ALIGN RGXFWIF_HWPERF_CTL;
+#endif
diff --git a/drivers/gpu/drm/img-rogue/include/volcanic/rgx_fwif_km.h b/drivers/gpu/drm/img-rogue/include/volcanic/rgx_fwif_km.h
new file mode 100644
index 000000000..fffe4934c
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/volcanic/rgx_fwif_km.h
@@ -0,0 +1,2357 @@
+/*************************************************************************/ /*!
+@File
+@Title RGX firmware interface structures used by pvrsrvkm
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description RGX firmware interface structures used by pvrsrvkm
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(RGX_FWIF_KM_H)
+#define RGX_FWIF_KM_H
+
+#include "img_types.h"
+#include "rgx_fwif_shared.h"
+#include "rgxdefs_km.h"
+#include "dllist.h"
+#include "rgx_hwperf.h"
+
+
+/*************************************************************************/ /*!
+ Logging type
+*/ /**************************************************************************/
+#define RGXFWIF_LOG_TYPE_NONE 0x00000000U
+#define RGXFWIF_LOG_TYPE_TRACE 0x00000001U
+#define RGXFWIF_LOG_TYPE_GROUP_MAIN 0x00000002U
+#define RGXFWIF_LOG_TYPE_GROUP_MTS 0x00000004U
+#define RGXFWIF_LOG_TYPE_GROUP_CLEANUP 0x00000008U
+#define RGXFWIF_LOG_TYPE_GROUP_CSW 0x00000010U
+#define RGXFWIF_LOG_TYPE_GROUP_BIF 0x00000020U
+#define RGXFWIF_LOG_TYPE_GROUP_PM 0x00000040U
+#define RGXFWIF_LOG_TYPE_GROUP_RTD 0x00000080U
+#define RGXFWIF_LOG_TYPE_GROUP_SPM 0x00000100U
+#define RGXFWIF_LOG_TYPE_GROUP_POW 0x00000200U
+#define RGXFWIF_LOG_TYPE_GROUP_HWR 0x00000400U
+#define RGXFWIF_LOG_TYPE_GROUP_HWP 0x00000800U
+#define RGXFWIF_LOG_TYPE_GROUP_RPM 0x00001000U
+#define RGXFWIF_LOG_TYPE_GROUP_DMA 0x00002000U
+#define RGXFWIF_LOG_TYPE_GROUP_MISC 0x00004000U
+#define RGXFWIF_LOG_TYPE_GROUP_DEBUG 0x80000000U
+#define RGXFWIF_LOG_TYPE_GROUP_MASK 0x80007FFEU
+#define RGXFWIF_LOG_TYPE_MASK 0x80007FFFU
+
+/* String used in pvrdebug -h output */
+#define RGXFWIF_LOG_GROUPS_STRING_LIST "main,mts,cleanup,csw,bif,pm,rtd,spm,pow,hwr,hwp,rpm,dma,misc,debug"
+
+/* Table entry to map log group strings to log type value */
+typedef struct {
+ const IMG_CHAR* pszLogGroupName;
+ IMG_UINT32 ui32LogGroupType;
+} RGXFWIF_LOG_GROUP_MAP_ENTRY;
+
+/*
+ Macro for use with the RGXFWIF_LOG_GROUP_MAP_ENTRY type to create a lookup
+ table where needed. Keep log group names short, no more than 20 chars.
+*/
+#define RGXFWIF_LOG_GROUP_NAME_VALUE_MAP { "none", RGXFWIF_LOG_TYPE_NONE }, \
+ { "main", RGXFWIF_LOG_TYPE_GROUP_MAIN }, \
+ { "mts", RGXFWIF_LOG_TYPE_GROUP_MTS }, \
+ { "cleanup", RGXFWIF_LOG_TYPE_GROUP_CLEANUP }, \
+ { "csw", RGXFWIF_LOG_TYPE_GROUP_CSW }, \
+ { "bif", RGXFWIF_LOG_TYPE_GROUP_BIF }, \
+ { "pm", RGXFWIF_LOG_TYPE_GROUP_PM }, \
+ { "rtd", RGXFWIF_LOG_TYPE_GROUP_RTD }, \
+ { "spm", RGXFWIF_LOG_TYPE_GROUP_SPM }, \
+ { "pow", RGXFWIF_LOG_TYPE_GROUP_POW }, \
+ { "hwr", RGXFWIF_LOG_TYPE_GROUP_HWR }, \
+ { "hwp", RGXFWIF_LOG_TYPE_GROUP_HWP }, \
+ { "rpm", RGXFWIF_LOG_TYPE_GROUP_RPM }, \
+ { "dma", RGXFWIF_LOG_TYPE_GROUP_DMA }, \
+ { "misc", RGXFWIF_LOG_TYPE_GROUP_MISC }, \
+ { "debug", RGXFWIF_LOG_TYPE_GROUP_DEBUG }
+
+
+/* Used in print statements to display log group state, one %s per group defined */
+#define RGXFWIF_LOG_ENABLED_GROUPS_LIST_PFSPEC "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
+
+/* Used in a print statement to display log group state, one per group */
+#define RGXFWIF_LOG_ENABLED_GROUPS_LIST(types) (((types) & RGXFWIF_LOG_TYPE_GROUP_MAIN) ?("main ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_MTS) ?("mts ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_CLEANUP) ?("cleanup ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_CSW) ?("csw ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_BIF) ?("bif ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_PM) ?("pm ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_RTD) ?("rtd ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_SPM) ?("spm ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_POW) ?("pow ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_HWR) ?("hwr ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_HWP) ?("hwp ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_RPM) ?("rpm ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_DMA) ?("dma ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_MISC) ?("misc ") :("")), \
+ (((types) & RGXFWIF_LOG_TYPE_GROUP_DEBUG) ?("debug ") :(""))
+
+
+/************************************************************************
+* RGX FW signature checks
+************************************************************************/
+#define RGXFW_SIG_BUFFER_SIZE_MIN (8192)
+
+#define RGXFWIF_TIMEDIFF_ID ((0x1UL << 28) | RGX_CR_TIMER)
+
+/*!
+ ******************************************************************************
+ * Trace Buffer
+ *****************************************************************************/
+
+/*! Default size of RGXFWIF_TRACEBUF_SPACE in DWords */
+#define RGXFW_TRACE_BUF_DEFAULT_SIZE_IN_DWORDS 12000U
+#define RGXFW_TRACE_BUFFER_ASSERT_SIZE 200U
+#if defined(RGXFW_META_SUPPORT_2ND_THREAD)
+#define RGXFW_THREAD_NUM 2U
+#else
+#define RGXFW_THREAD_NUM 1U
+#endif
+
+#define RGXFW_POLL_TYPE_SET 0x80000000U
+
+typedef struct
+{
+ IMG_CHAR szPath[RGXFW_TRACE_BUFFER_ASSERT_SIZE];
+ IMG_CHAR szInfo[RGXFW_TRACE_BUFFER_ASSERT_SIZE];
+ IMG_UINT32 ui32LineNum;
+} UNCACHED_ALIGN RGXFWIF_FILE_INFO_BUF;
+
+typedef struct
+{
+ IMG_UINT32 ui32TracePointer;
+
+#if defined(RGX_FIRMWARE)
+ IMG_UINT32 *pui32RGXFWIfTraceBuffer; /* To be used by firmware for writing into trace buffer */
+#else
+ RGXFWIF_DEV_VIRTADDR pui32RGXFWIfTraceBuffer;
+#endif
+ IMG_PUINT32 pui32TraceBuffer; /* To be used by host when reading from trace buffer */
+
+ RGXFWIF_FILE_INFO_BUF sAssertBuf;
+} UNCACHED_ALIGN RGXFWIF_TRACEBUF_SPACE;
+
+#define RGXFWIF_FWFAULTINFO_MAX (8U) /* Total number of FW fault logs stored */
+
+typedef struct
+{
+ IMG_UINT64 RGXFW_ALIGN ui64CRTimer;
+ IMG_UINT64 RGXFW_ALIGN ui64OSTimer;
+ IMG_UINT32 RGXFW_ALIGN ui32Data;
+ IMG_UINT32 ui32Reserved;
+ RGXFWIF_FILE_INFO_BUF sFaultBuf;
+} UNCACHED_ALIGN RGX_FWFAULTINFO;
+
+
+#define RGXFWIF_POW_STATES \
+ X(RGXFWIF_POW_OFF) /* idle and handshaked with the host (ready to full power down) */ \
+ X(RGXFWIF_POW_ON) /* running HW commands */ \
+ X(RGXFWIF_POW_FORCED_IDLE) /* forced idle */ \
+ X(RGXFWIF_POW_IDLE) /* idle waiting for host handshake */
+
+typedef enum
+{
+#define X(NAME) NAME,
+ RGXFWIF_POW_STATES
+#undef X
+} RGXFWIF_POW_STATE;
+
+/* Firmware HWR states */
+#define RGXFWIF_HWR_HARDWARE_OK (IMG_UINT32_C(0x1) << 0U) /*!< The HW state is ok or locked up */
+#define RGXFWIF_HWR_RESET_IN_PROGRESS (IMG_UINT32_C(0x1) << 1U) /*!< Tells if a HWR reset is in progress */
+#define RGXFWIF_HWR_GENERAL_LOCKUP (IMG_UINT32_C(0x1) << 3U) /*!< A DM unrelated lockup has been detected */
+#define RGXFWIF_HWR_DM_RUNNING_OK (IMG_UINT32_C(0x1) << 4U) /*!< At least one DM is running without being close to a lockup */
+#define RGXFWIF_HWR_DM_STALLING (IMG_UINT32_C(0x1) << 5U) /*!< At least one DM is close to lockup */
+#define RGXFWIF_HWR_FW_FAULT (IMG_UINT32_C(0x1) << 6U) /*!< The FW has faulted and needs to restart */
+#define RGXFWIF_HWR_RESTART_REQUESTED (0x1U << 7U) /*!< The FW has requested the host to restart it */
+
+#define RGXFWIF_PHR_STATE_SHIFT (8U)
+#define RGXFWIF_PHR_RESTART_REQUESTED (IMG_UINT32_C(1) << RGXFWIF_PHR_STATE_SHIFT) /*!< The FW has requested the host to restart it, per PHR configuration */
+#define RGXFWIF_PHR_RESTART_FINISHED (IMG_UINT32_C(2) << RGXFWIF_PHR_STATE_SHIFT) /*!< A PHR triggered GPU reset has just finished */
+#define RGXFWIF_PHR_RESTART_MASK (RGXFWIF_PHR_RESTART_REQUESTED | RGXFWIF_PHR_RESTART_FINISHED)
+
+#define RGXFWIF_PHR_MODE_OFF (0UL)
+#define RGXFWIF_PHR_MODE_RD_RESET (1UL)
+#define RGXFWIF_PHR_MODE_FULL_RESET (2UL)
+
+typedef IMG_UINT32 RGXFWIF_HWR_STATEFLAGS;
+
+/* Firmware per-DM HWR states */
+#define RGXFWIF_DM_STATE_WORKING (0x00U) /*!< DM is working if all flags are cleared */
+#define RGXFWIF_DM_STATE_READY_FOR_HWR (IMG_UINT32_C(0x1) << 0) /*!< DM is idle and ready for HWR */
+#define RGXFWIF_DM_STATE_NEEDS_SKIP (IMG_UINT32_C(0x1) << 2) /*!< DM need to skip to next cmd before resuming processing */
+#define RGXFWIF_DM_STATE_NEEDS_PR_CLEANUP (IMG_UINT32_C(0x1) << 3) /*!< DM need partial render cleanup before resuming processing */
+#define RGXFWIF_DM_STATE_NEEDS_TRACE_CLEAR (IMG_UINT32_C(0x1) << 4) /*!< DM need to increment Recovery Count once fully recovered */
+#define RGXFWIF_DM_STATE_GUILTY_LOCKUP (IMG_UINT32_C(0x1) << 5) /*!< DM was identified as locking up and causing HWR */
+#define RGXFWIF_DM_STATE_INNOCENT_LOCKUP (IMG_UINT32_C(0x1) << 6) /*!< DM was innocently affected by another lockup which caused HWR */
+#define RGXFWIF_DM_STATE_GUILTY_OVERRUNING (IMG_UINT32_C(0x1) << 7) /*!< DM was identified as over-running and causing HWR */
+#define RGXFWIF_DM_STATE_INNOCENT_OVERRUNING (IMG_UINT32_C(0x1) << 8) /*!< DM was innocently affected by another DM over-running which caused HWR */
+#define RGXFWIF_DM_STATE_HARD_CONTEXT_SWITCH (IMG_UINT32_C(0x1) << 9) /*!< DM was forced into HWR as it delayed more important workloads */
+#define RGXFWIF_DM_STATE_GPU_ECC_HWR (IMG_UINT32_C(0x1) << 10) /*!< DM was forced into HWR due to an uncorrected GPU ECC error */
+
+/* Firmware's connection state */
+typedef enum
+{
+ RGXFW_CONNECTION_FW_OFFLINE = 0, /*!< Firmware is offline */
+ RGXFW_CONNECTION_FW_READY, /*!< Firmware is initialised */
+ RGXFW_CONNECTION_FW_ACTIVE, /*!< Firmware connection is fully established */
+ RGXFW_CONNECTION_FW_OFFLOADING, /*!< Firmware is clearing up connection data */
+ RGXFW_CONNECTION_FW_STATE_COUNT
+} RGXFWIF_CONNECTION_FW_STATE;
+
+/* OS' connection state */
+typedef enum
+{
+ RGXFW_CONNECTION_OS_OFFLINE = 0, /*!< OS is offline */
+ RGXFW_CONNECTION_OS_READY, /*!< OS's KM driver is setup and waiting */
+ RGXFW_CONNECTION_OS_ACTIVE, /*!< OS connection is fully established */
+ RGXFW_CONNECTION_OS_STATE_COUNT
+} RGXFWIF_CONNECTION_OS_STATE;
+
+typedef struct
+{
+ IMG_UINT bfOsState : 3;
+ IMG_UINT bfFLOk : 1;
+ IMG_UINT bfFLGrowPending : 1;
+ IMG_UINT bfIsolatedOS : 1;
+ IMG_UINT bfReserved : 26;
+} RGXFWIF_OS_RUNTIME_FLAGS;
+
+typedef IMG_UINT32 RGXFWIF_HWR_RECOVERYFLAGS;
+
+#if defined(PVRSRV_STALLED_CCB_ACTION)
+#define PVR_SLR_LOG_ENTRIES 10
+#define PVR_SLR_LOG_STRLEN 30 /*!< MAX_CLIENT_CCB_NAME not visible to this header */
+
+typedef struct
+{
+ IMG_UINT64 RGXFW_ALIGN ui64Timestamp;
+ IMG_UINT32 ui32FWCtxAddr;
+ IMG_UINT32 ui32NumUFOs;
+ IMG_CHAR aszCCBName[PVR_SLR_LOG_STRLEN];
+} UNCACHED_ALIGN RGXFWIF_SLR_ENTRY;
+#endif
+
+/* firmware trace control data */
+typedef struct
+{
+ IMG_UINT32 ui32LogType;
+ RGXFWIF_TRACEBUF_SPACE sTraceBuf[RGXFW_THREAD_NUM];
+ IMG_UINT32 ui32TraceBufSizeInDWords; /*!< Member initialised only when sTraceBuf is actually allocated
+ * (in RGXTraceBufferInitOnDemandResources) */
+ IMG_UINT32 ui32TracebufFlags; /*!< Compatibility and other flags */
+} UNCACHED_ALIGN RGXFWIF_TRACEBUF;
+
+/*! @Brief Firmware system data shared with the Host driver */
+typedef struct
+{
+ IMG_UINT32 ui32ConfigFlags; /*!< Configuration flags from host */
+ IMG_UINT32 ui32ConfigFlagsExt; /*!< Extended configuration flags from host */
+ volatile RGXFWIF_POW_STATE ePowState;
+ volatile IMG_UINT32 ui32HWPerfRIdx;
+ volatile IMG_UINT32 ui32HWPerfWIdx;
+ volatile IMG_UINT32 ui32HWPerfWrapCount;
+ IMG_UINT32 ui32HWPerfSize; /*!< Constant after setup, needed in FW */
+ IMG_UINT32 ui32HWPerfDropCount; /*!< The number of times the FW drops a packet due to buffer full */
+
+ /* ui32HWPerfUt, ui32FirstDropOrdinal, ui32LastDropOrdinal only valid when FW is built with
+ * RGX_HWPERF_UTILIZATION & RGX_HWPERF_DROP_TRACKING defined in rgxfw_hwperf.c */
+ IMG_UINT32 ui32HWPerfUt; /*!< Buffer utilisation, high watermark of bytes in use */
+ IMG_UINT32 ui32FirstDropOrdinal; /*!< The ordinal of the first packet the FW dropped */
+ IMG_UINT32 ui32LastDropOrdinal; /*!< The ordinal of the last packet the FW dropped */
+ RGXFWIF_OS_RUNTIME_FLAGS asOsRuntimeFlagsMirror[RGXFW_MAX_NUM_OS];/*!< State flags for each Operating System mirrored from Fw coremem */
+ RGX_FWFAULTINFO sFaultInfo[RGXFWIF_FWFAULTINFO_MAX]; /*!< Firmware fault info */
+ IMG_UINT32 ui32FWFaults; /*!< Firmware faults count */
+ IMG_UINT32 aui32CrPollAddr[RGXFW_THREAD_NUM]; /*!< Failed poll address */
+ IMG_UINT32 aui32CrPollMask[RGXFW_THREAD_NUM]; /*!< Failed poll mask */
+ IMG_UINT32 aui32CrPollCount[RGXFW_THREAD_NUM]; /*!< Failed poll count */
+ IMG_UINT64 RGXFW_ALIGN ui64StartIdleTime;
+#if defined(SUPPORT_POWMON_COMPONENT)
+#if defined(SUPPORT_POWER_VALIDATION_VIA_DEBUGFS)
+ RGXFWIF_TRACEBUF_SPACE sPowerMonBuf;
+ IMG_UINT32 ui32PowerMonBufSizeInDWords;
+#endif
+#endif
+
+#if defined(SUPPORT_VALIDATION)
+ IMG_UINT32 ui32RenderKillingCtl; /*!< Rasterisation DM Killing Configuration from host */
+ IMG_UINT32 ui32CDMTDMKillingCtl; /*!< CDM/TDM Killing Configuration from host */
+#endif
+#if defined(SUPPORT_RGXFW_STATS_FRAMEWORK)
+#define RGXFWIF_STATS_FRAMEWORK_LINESIZE (8)
+#define RGXFWIF_STATS_FRAMEWORK_MAX (2048*RGXFWIF_STATS_FRAMEWORK_LINESIZE)
+ IMG_UINT32 RGXFW_ALIGN aui32FWStatsBuf[RGXFWIF_STATS_FRAMEWORK_MAX];
+#endif
+ RGXFWIF_HWR_STATEFLAGS ui32HWRStateFlags; /*!< Firmware's Current HWR state */
+ RGXFWIF_HWR_RECOVERYFLAGS aui32HWRRecoveryFlags[RGXFWIF_DM_MAX]; /*!< Each DM's HWR state */
+ IMG_UINT32 ui32FwSysDataFlags; /*!< Compatibility and other flags */
+} UNCACHED_ALIGN RGXFWIF_SYSDATA;
+
+/*!
+ * @InGroup ContextSwitching
+ * @Brief Firmware per-os data and configuration
+ */
+typedef struct
+{
+ IMG_UINT32 ui32FwOsConfigFlags; /*!< Configuration flags from an OS */
+ IMG_UINT32 ui32FWSyncCheckMark; /*!< Markers to signal that the host should perform a full sync check */
+ IMG_UINT32 ui32HostSyncCheckMark; /*!< Markers to signal that the Firmware should perform a full sync check */
+#if defined(PVRSRV_STALLED_CCB_ACTION)
+ IMG_UINT32 ui32ForcedUpdatesRequested;
+ IMG_UINT8 ui8SLRLogWp;
+ RGXFWIF_SLR_ENTRY sSLRLogFirst;
+ RGXFWIF_SLR_ENTRY sSLRLog[PVR_SLR_LOG_ENTRIES];
+ IMG_UINT64 RGXFW_ALIGN ui64LastForcedUpdateTime;
+#endif
+ volatile IMG_UINT32 aui32InterruptCount[RGXFW_THREAD_NUM]; /*!< Interrupt count from Threads > */
+ IMG_UINT32 ui32KCCBCmdsExecuted; /*!< Executed Kernel CCB command count */
+ RGXFWIF_DEV_VIRTADDR sPowerSync; /*!< Sync prim used to signal the host the power off state */
+ IMG_UINT32 ui32FwOsDataFlags; /*!< Compatibility and other flags */
+} UNCACHED_ALIGN RGXFWIF_OSDATA;
+
+/* Firmware trace time-stamp field breakup */
+
+/* RGX_CR_TIMER register read (48 bits) value*/
+#define RGXFWT_TIMESTAMP_TIME_SHIFT (0U)
+#define RGXFWT_TIMESTAMP_TIME_CLRMSK (IMG_UINT64_C(0xFFFF000000000000))
+
+/* Extra debug-info (16 bits) */
+#define RGXFWT_TIMESTAMP_DEBUG_INFO_SHIFT (48U)
+#define RGXFWT_TIMESTAMP_DEBUG_INFO_CLRMSK ~RGXFWT_TIMESTAMP_TIME_CLRMSK
+
+
+/* Debug-info sub-fields */
+/* Bit 0: RGX_CR_EVENT_STATUS_MMU_PAGE_FAULT bit from RGX_CR_EVENT_STATUS register */
+#define RGXFWT_DEBUG_INFO_MMU_PAGE_FAULT_SHIFT (0U)
+#define RGXFWT_DEBUG_INFO_MMU_PAGE_FAULT_SET (1U << RGXFWT_DEBUG_INFO_MMU_PAGE_FAULT_SHIFT)
+
+/* Bit 1: RGX_CR_BIF_MMU_ENTRY_PENDING bit from RGX_CR_BIF_MMU_ENTRY register */
+#define RGXFWT_DEBUG_INFO_MMU_ENTRY_PENDING_SHIFT (1U)
+#define RGXFWT_DEBUG_INFO_MMU_ENTRY_PENDING_SET (1U << RGXFWT_DEBUG_INFO_MMU_ENTRY_PENDING_SHIFT)
+
+/* Bit 2: RGX_CR_SLAVE_EVENT register is non-zero */
+#define RGXFWT_DEBUG_INFO_SLAVE_EVENTS_SHIFT (2U)
+#define RGXFWT_DEBUG_INFO_SLAVE_EVENTS_SET (1U << RGXFWT_DEBUG_INFO_SLAVE_EVENTS_SHIFT)
+
+/* Bit 3-15: Unused bits */
+
+#define RGXFWT_DEBUG_INFO_STR_MAXLEN 64
+#define RGXFWT_DEBUG_INFO_STR_PREPEND " (debug info: "
+#define RGXFWT_DEBUG_INFO_STR_APPEND ")"
+
+/* Table of debug info sub-field's masks and corresponding message strings
+ * to be appended to firmware trace
+ *
+ * Mask : 16 bit mask to be applied to debug-info field
+ * String : debug info message string
+ */
+
+#define RGXFWT_DEBUG_INFO_MSKSTRLIST \
+/*Mask, String*/ \
+X(RGXFWT_DEBUG_INFO_MMU_PAGE_FAULT_SET, "mmu pf") \
+X(RGXFWT_DEBUG_INFO_MMU_ENTRY_PENDING_SET, "mmu pending") \
+X(RGXFWT_DEBUG_INFO_SLAVE_EVENTS_SET, "slave events")
+
+/*!
+ ******************************************************************************
+ * HWR Data
+ *****************************************************************************/
+/*!
+ * @Defgroup HWRInfo FW HWR shared data interface
+ * @Brief Types grouping data structures and defines used in realising the HWR record.
+ * @{
+ */
+/*! @Brief HWR Lockup types */
+typedef enum
+{
+ RGX_HWRTYPE_UNKNOWNFAILURE = 0, /*!< Unknown failure */
+ RGX_HWRTYPE_OVERRUN = 1, /*!< DM overrun */
+ RGX_HWRTYPE_POLLFAILURE = 2, /*!< Poll failure */
+ RGX_HWRTYPE_BIF0FAULT = 3, /*!< BIF0 fault */
+ RGX_HWRTYPE_BIF1FAULT = 4, /*!< BIF1 fault */
+ RGX_HWRTYPE_TEXASBIF0FAULT = 5, /*!< TEXASBIF0 fault */
+ RGX_HWRTYPE_MMUFAULT = 6, /*!< MMU fault */
+ RGX_HWRTYPE_MMUMETAFAULT = 7, /*!< MMU META fault */
+ RGX_HWRTYPE_MIPSTLBFAULT = 8, /*!< MIPS TLB fault */
+ RGX_HWRTYPE_ECCFAULT = 9, /*!< ECC fault */
+ RGX_HWRTYPE_MMURISCVFAULT = 10, /*!< MMU RISCV fault */
+} RGX_HWRTYPE;
+
+#define RGXFWIF_HWRTYPE_BIF_BANK_GET(eHWRType) (((eHWRType) == RGX_HWRTYPE_BIF0FAULT) ? 0 : 1)
+
+#define RGXFWIF_HWRTYPE_PAGE_FAULT_GET(eHWRType) ((((eHWRType) == RGX_HWRTYPE_BIF0FAULT) || \
+ ((eHWRType) == RGX_HWRTYPE_BIF1FAULT) || \
+ ((eHWRType) == RGX_HWRTYPE_TEXASBIF0FAULT) || \
+ ((eHWRType) == RGX_HWRTYPE_MMUFAULT) || \
+ ((eHWRType) == RGX_HWRTYPE_MMUMETAFAULT) || \
+ ((eHWRType) == RGX_HWRTYPE_MIPSTLBFAULT) || \
+ ((eHWRType) == RGX_HWRTYPE_MMURISCVFAULT)) ? true : false)
+
+/************************
+ * GPU HW error codes *
+ ************************/
+typedef enum
+{
+ RGX_HW_ERR_NA = 0x0,
+ RGX_HW_ERR_PRIMID_FAILURE_DURING_DMKILL = 0x101,
+} RGX_HW_ERR;
+
+typedef struct
+{
+ IMG_UINT64 RGXFW_ALIGN ui64BIFReqStatus; /*!< BIF request status */
+ IMG_UINT64 RGXFW_ALIGN ui64BIFMMUStatus; /*!< MMU status */
+ IMG_UINT64 RGXFW_ALIGN ui64PCAddress; /*!< phys address of the page catalogue */
+ IMG_UINT64 RGXFW_ALIGN ui64Reserved;
+} RGX_BIFINFO;
+
+typedef struct
+{
+ IMG_UINT32 ui32FaultGPU; /*!< ECC fault in GPU */
+} RGX_ECCINFO;
+
+typedef struct
+{
+ IMG_UINT64 RGXFW_ALIGN aui64MMUStatus[2]; /*!< MMU status */
+ IMG_UINT64 RGXFW_ALIGN ui64PCAddress; /*!< phys address of the page catalogue */
+ IMG_UINT64 RGXFW_ALIGN ui64Reserved;
+} RGX_MMUINFO;
+
+typedef struct
+{
+ IMG_UINT32 ui32ThreadNum; /*!< Thread ID performing poll operation */
+ IMG_UINT32 ui32CrPollAddr; /*!< CR Poll Address */
+ IMG_UINT32 ui32CrPollMask; /*!< CR Poll mask */
+ IMG_UINT32 ui32CrPollLastValue; /*!< CR Poll last value */
+ IMG_UINT64 RGXFW_ALIGN ui64Reserved;
+} UNCACHED_ALIGN RGX_POLLINFO;
+
+typedef struct
+{
+ IMG_UINT32 ui32BadVAddr; /*!< VA address */
+ IMG_UINT32 ui32EntryLo;
+} RGX_TLBINFO;
+
+typedef struct
+{
+ union
+ {
+ RGX_BIFINFO sBIFInfo; /*!< BIF failure details */
+ RGX_MMUINFO sMMUInfo; /*!< MMU failure details */
+ RGX_POLLINFO sPollInfo; /*!< Poll failure details */
+ RGX_TLBINFO sTLBInfo; /*!< TLB failure details */
+ RGX_ECCINFO sECCInfo; /*!< ECC failure details */
+ } uHWRData;
+
+ IMG_UINT64 RGXFW_ALIGN ui64CRTimer; /*!< Timer value at the time of lockup */
+ IMG_UINT64 RGXFW_ALIGN ui64OSTimer; /*!< OS timer value at the time of lockup */
+ IMG_UINT32 ui32FrameNum; /*!< Frame number of the workload */
+ IMG_UINT32 ui32PID; /*!< PID belonging to the workload */
+ IMG_UINT32 ui32ActiveHWRTData; /*!< HWRT data of the workload */
+ IMG_UINT32 ui32HWRNumber; /*!< HWR number */
+ IMG_UINT32 ui32EventStatus; /*!< Core specific event status register at the time of lockup */
+ IMG_UINT32 ui32HWRRecoveryFlags; /*!< DM state flags */
+ RGX_HWRTYPE eHWRType; /*!< Type of lockup */
+ RGXFWIF_DM eDM; /*!< Recovery triggered for the DM */
+ IMG_UINT32 ui32CoreID; /*!< Core ID of the GPU */
+ RGX_HW_ERR eHWErrorCode; /*!< Error code used to determine HW fault */
+ IMG_UINT64 RGXFW_ALIGN ui64CRTimeOfKick; /*!< Workload kick time */
+ IMG_UINT64 RGXFW_ALIGN ui64CRTimeHWResetStart; /*!< HW reset start time */
+ IMG_UINT64 RGXFW_ALIGN ui64CRTimeHWResetFinish; /*!< HW reset stop time */
+ IMG_UINT64 RGXFW_ALIGN ui64CRTimeFreelistReady; /*!< freelist ready time on the last HWR */
+ IMG_UINT64 RGXFW_ALIGN ui64Reserved; /*!< Pad to 16 64-bit words */
+} UNCACHED_ALIGN RGX_HWRINFO;
+
+#define RGXFWIF_HWINFO_MAX_FIRST 8U /* Number of first HWR logs recorded (never overwritten by newer logs) */
+#define RGXFWIF_HWINFO_MAX_LAST 8U /* Number of latest HWR logs (older logs are overwritten by newer logs) */
+#define RGXFWIF_HWINFO_MAX (RGXFWIF_HWINFO_MAX_FIRST + RGXFWIF_HWINFO_MAX_LAST) /* Total number of HWR logs stored in a buffer */
+#define RGXFWIF_HWINFO_LAST_INDEX (RGXFWIF_HWINFO_MAX - 1U) /* Index of the last log in the HWR log buffer */
+
+typedef struct
+{
+ RGX_HWRINFO sHWRInfo[RGXFWIF_HWINFO_MAX]; /*!< Max number of recovery record */
+ IMG_UINT32 ui32HwrCounter; /*!< HWR counter used in FL reconstruction */
+ IMG_UINT32 ui32WriteIndex; /*!< Index for updating recovery information in sHWRInfo */
+ IMG_UINT32 ui32DDReqCount; /*!< Count of DebugDump requested to the host after recovery */
+ IMG_UINT32 ui32HWRInfoBufFlags; /* Compatibility and other flags */
+ IMG_UINT32 aui32HwrDmLockedUpCount[RGXFWIF_DM_MAX]; /*!< Lockup count for each DM */
+ IMG_UINT32 aui32HwrDmOverranCount[RGXFWIF_DM_MAX]; /*!< Overrun count for each DM */
+ IMG_UINT32 aui32HwrDmRecoveredCount[RGXFWIF_DM_MAX]; /*!< Lockup + Overrun count for each DM */
+ IMG_UINT32 aui32HwrDmFalseDetectCount[RGXFWIF_DM_MAX]; /*!< False lockup detection count for each DM */
+} UNCACHED_ALIGN RGXFWIF_HWRINFOBUF;
+
+/*! @} End of HWRInfo */
+
+#define RGXFWIF_CTXSWITCH_PROFILE_FAST_EN (IMG_UINT32_C(0x1))
+#define RGXFWIF_CTXSWITCH_PROFILE_MEDIUM_EN (IMG_UINT32_C(0x2))
+#define RGXFWIF_CTXSWITCH_PROFILE_SLOW_EN (IMG_UINT32_C(0x3))
+#define RGXFWIF_CTXSWITCH_PROFILE_NODELAY_EN (IMG_UINT32_C(0x4))
+
+#define RGXFWIF_CDM_ARBITRATION_TASK_DEMAND_EN (IMG_UINT32_C(0x1))
+#define RGXFWIF_CDM_ARBITRATION_ROUND_ROBIN_EN (IMG_UINT32_C(0x2))
+
+#define RGXFWIF_ISP_SCHEDMODE_VER1_IPP (IMG_UINT32_C(0x1))
+#define RGXFWIF_ISP_SCHEDMODE_VER2_ISP (IMG_UINT32_C(0x2))
+/*!
+ ******************************************************************************
+ * RGX firmware Init Config Data
+ * NOTE: Please be careful to keep backwards compatibility with DDKv1 for the
+ * CTXSWITCH controls.
+ *****************************************************************************/
+
+/* Flag definitions affecting the firmware globally */
+#define RGXFWIF_INICFG_CTXSWITCH_MODE_RAND (IMG_UINT32_C(0x1) << 0) /*!< Randomise context switch requests */
+#define RGXFWIF_INICFG_CTXSWITCH_SRESET_EN (IMG_UINT32_C(0x1) << 1)
+#define RGXFWIF_INICFG_HWPERF_EN (IMG_UINT32_C(0x1) << 2)
+#define RGXFWIF_INICFG_DM_KILL_MODE_RAND_EN (IMG_UINT32_C(0x1) << 3) /*!< Randomise DM-killing requests */
+#define RGXFWIF_INICFG_POW_RASCALDUST (IMG_UINT32_C(0x1) << 4)
+/* 5 unused */
+#define RGXFWIF_INICFG_FBCDC_V3_1_EN (IMG_UINT32_C(0x1) << 6)
+#define RGXFWIF_INICFG_CHECK_MLIST_EN (IMG_UINT32_C(0x1) << 7)
+#define RGXFWIF_INICFG_DISABLE_CLKGATING_EN (IMG_UINT32_C(0x1) << 8)
+#define RGXFWIF_INICFG_POLL_COUNTERS_EN (IMG_UINT32_C(0x1) << 9)
+/* 10 unused */
+/* 11 unused */
+#define RGXFWIF_INICFG_REGCONFIG_EN (IMG_UINT32_C(0x1) << 12)
+#define RGXFWIF_INICFG_ASSERT_ON_OUTOFMEMORY (IMG_UINT32_C(0x1) << 13)
+#define RGXFWIF_INICFG_HWP_DISABLE_FILTER (IMG_UINT32_C(0x1) << 14)
+#define RGXFWIF_INICFG_CUSTOM_PERF_TIMER_EN (IMG_UINT32_C(0x1) << 15)
+#define RGXFWIF_INICFG_CTXSWITCH_PROFILE_SHIFT (16)
+#define RGXFWIF_INICFG_CTXSWITCH_PROFILE_FAST (RGXFWIF_CTXSWITCH_PROFILE_FAST_EN << RGXFWIF_INICFG_CTXSWITCH_PROFILE_SHIFT)
+#define RGXFWIF_INICFG_CTXSWITCH_PROFILE_MEDIUM (RGXFWIF_CTXSWITCH_PROFILE_MEDIUM_EN << RGXFWIF_INICFG_CTXSWITCH_PROFILE_SHIFT)
+#define RGXFWIF_INICFG_CTXSWITCH_PROFILE_SLOW (RGXFWIF_CTXSWITCH_PROFILE_SLOW_EN << RGXFWIF_INICFG_CTXSWITCH_PROFILE_SHIFT)
+#define RGXFWIF_INICFG_CTXSWITCH_PROFILE_NODELAY (RGXFWIF_CTXSWITCH_PROFILE_NODELAY_EN << RGXFWIF_INICFG_CTXSWITCH_PROFILE_SHIFT)
+#define RGXFWIF_INICFG_CTXSWITCH_PROFILE_MASK (IMG_UINT32_C(0x7) << RGXFWIF_INICFG_CTXSWITCH_PROFILE_SHIFT)
+#define RGXFWIF_INICFG_DISABLE_DM_OVERLAP (IMG_UINT32_C(0x1) << 19)
+#define RGXFWIF_INICFG_ASSERT_ON_HWR_TRIGGER (IMG_UINT32_C(0x1) << 20)
+#define RGXFWIF_INICFG_FABRIC_COHERENCY_ENABLED (IMG_UINT32_C(0x1) << 21)
+#define RGXFWIF_INICFG_VALIDATE_IRQ (IMG_UINT32_C(0x1) << 22)
+#define RGXFWIF_INICFG_DISABLE_PDP_EN (IMG_UINT32_C(0x1) << 23)
+#define RGXFWIF_INICFG_SPU_POWER_STATE_MASK_CHANGE_EN (IMG_UINT32_C(0x1) << 24)
+#define RGXFWIF_INICFG_WORKEST (IMG_UINT32_C(0x1) << 25)
+#define RGXFWIF_INICFG_PDVFS (IMG_UINT32_C(0x1) << 26)
+#define RGXFWIF_INICFG_CDM_ARBITRATION_SHIFT (27)
+#define RGXFWIF_INICFG_CDM_ARBITRATION_TASK_DEMAND (RGXFWIF_CDM_ARBITRATION_TASK_DEMAND_EN << RGXFWIF_INICFG_CDM_ARBITRATION_SHIFT)
+#define RGXFWIF_INICFG_CDM_ARBITRATION_ROUND_ROBIN (RGXFWIF_CDM_ARBITRATION_ROUND_ROBIN_EN << RGXFWIF_INICFG_CDM_ARBITRATION_SHIFT)
+#define RGXFWIF_INICFG_CDM_ARBITRATION_MASK (IMG_UINT32_C(0x3) << RGXFWIF_INICFG_CDM_ARBITRATION_SHIFT)
+#define RGXFWIF_INICFG_ISPSCHEDMODE_SHIFT (29)
+#define RGXFWIF_INICFG_ISPSCHEDMODE_NONE (0)
+#define RGXFWIF_INICFG_ISPSCHEDMODE_VER1_IPP (RGXFWIF_ISP_SCHEDMODE_VER1_IPP << RGXFWIF_INICFG_ISPSCHEDMODE_SHIFT)
+#define RGXFWIF_INICFG_ISPSCHEDMODE_VER2_ISP (RGXFWIF_ISP_SCHEDMODE_VER2_ISP << RGXFWIF_INICFG_ISPSCHEDMODE_SHIFT)
+#define RGXFWIF_INICFG_ISPSCHEDMODE_MASK (RGXFWIF_INICFG_ISPSCHEDMODE_VER1_IPP |\
+ RGXFWIF_INICFG_ISPSCHEDMODE_VER2_ISP)
+#define RGXFWIF_INICFG_VALIDATE_SOCUSC_TIMER (IMG_UINT32_C(0x1) << 31)
+#define RGXFWIF_INICFG_ALL (0xFFFFF3FFU)
+
+/* Extended Flag definitions affecting the firmware globally */
+#define RGXFWIF_INICFG_EXT_ALL (0x0U)
+
+#define RGXFWIF_INICFG_SYS_CTXSWITCH_CLRMSK ~(RGXFWIF_INICFG_CTXSWITCH_MODE_RAND | \
+ RGXFWIF_INICFG_CTXSWITCH_SRESET_EN)
+
+/* Flag definitions affecting only workloads submitted by a particular OS */
+
+/*!
+ * @AddToGroup ContextSwitching
+ * @{
+ * @Name Per-OS DM context switch configuration flags
+ * @{
+ */
+#define RGXFWIF_INICFG_OS_CTXSWITCH_TDM_EN (IMG_UINT32_C(0x1) << 0) /*!< Enables TDM context switch */
+#define RGXFWIF_INICFG_OS_CTXSWITCH_GEOM_EN (IMG_UINT32_C(0x1) << 1) /*!< Enables GEOM-TA and GEOM-SHG context switch */
+#define RGXFWIF_INICFG_OS_CTXSWITCH_3D_EN (IMG_UINT32_C(0x1) << 2) /*!< Enables FRAG DM context switch */
+#define RGXFWIF_INICFG_OS_CTXSWITCH_CDM_EN (IMG_UINT32_C(0x1) << 3) /*!< Enables CDM context switch */
+#define RGXFWIF_INICFG_OS_CTXSWITCH_RDM_EN (IMG_UINT32_C(0x1) << 4)
+
+#define RGXFWIF_INICFG_OS_LOW_PRIO_CS_TDM (IMG_UINT32_C(0x1) << 5)
+#define RGXFWIF_INICFG_OS_LOW_PRIO_CS_GEOM (IMG_UINT32_C(0x1) << 6)
+#define RGXFWIF_INICFG_OS_LOW_PRIO_CS_3D (IMG_UINT32_C(0x1) << 7)
+#define RGXFWIF_INICFG_OS_LOW_PRIO_CS_CDM (IMG_UINT32_C(0x1) << 8)
+#define RGXFWIF_INICFG_OS_LOW_PRIO_CS_RDM (IMG_UINT32_C(0x1) << 9)
+
+#define RGXFWIF_INICFG_OS_ALL (0x3FFU)
+
+#define RGXFWIF_INICFG_OS_CTXSWITCH_DM_ALL (RGXFWIF_INICFG_OS_CTXSWITCH_GEOM_EN | \
+ RGXFWIF_INICFG_OS_CTXSWITCH_3D_EN | \
+ RGXFWIF_INICFG_OS_CTXSWITCH_CDM_EN | \
+ RGXFWIF_INICFG_OS_CTXSWITCH_TDM_EN | \
+ RGXFWIF_INICFG_OS_CTXSWITCH_RDM_EN)
+
+#define RGXFWIF_INICFG_OS_CTXSWITCH_CLRMSK ~(RGXFWIF_INICFG_OS_CTXSWITCH_DM_ALL)
+
+/*!
+ * @} End of Per-OS Context switch configuration flags
+ * @} End of AddToGroup ContextSwitching
+ */
+
+#define RGXFWIF_FILTCFG_TRUNCATE_HALF (IMG_UINT32_C(0x1) << 3)
+#define RGXFWIF_FILTCFG_TRUNCATE_INT (IMG_UINT32_C(0x1) << 2)
+#define RGXFWIF_FILTCFG_NEW_FILTER_MODE (IMG_UINT32_C(0x1) << 1)
+
+typedef enum
+{
+ RGX_ACTIVEPM_FORCE_OFF = 0,
+ RGX_ACTIVEPM_FORCE_ON = 1,
+ RGX_ACTIVEPM_DEFAULT = 2
+} RGX_ACTIVEPM_CONF;
+
+typedef enum
+{
+ RGX_RD_POWER_ISLAND_FORCE_OFF = 0,
+ RGX_RD_POWER_ISLAND_FORCE_ON = 1,
+ RGX_RD_POWER_ISLAND_DEFAULT = 2
+} RGX_RD_POWER_ISLAND_CONF;
+
+typedef struct
+{
+ IMG_UINT16 ui16RegNum; /*!< Register number */
+ IMG_UINT16 ui16IndirectRegNum; /*!< Indirect register number (or 0 if not used) */
+ IMG_UINT16 ui16IndirectStartVal; /*!< Start value for indirect register */
+ IMG_UINT16 ui16IndirectEndVal; /*!< End value for indirect register */
+} RGXFW_REGISTER_LIST;
+
+#if defined(RGX_FIRMWARE)
+typedef DLLIST_NODE RGXFWIF_DLLIST_NODE;
+#else
+typedef struct {RGXFWIF_DEV_VIRTADDR p;
+ RGXFWIF_DEV_VIRTADDR n;} RGXFWIF_DLLIST_NODE;
+#endif
+
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_SIGBUFFER;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_TRACEBUF;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_SYSDATA;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_OSDATA;
+#if defined(SUPPORT_TBI_INTERFACE)
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_TBIBUF;
+#endif
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_HWPERFBUF;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_HWRINFOBUF;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_RUNTIME_CFG;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_GPU_UTIL_FWCB;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_REG_CFG;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_HWPERF_CTL;
+typedef RGXFWIF_DEV_VIRTADDR PRGX_HWPERF_CONFIG_CNTBLK;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CCB_CTL;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CCB;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CCB_RTN_SLOTS;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_FWMEMCONTEXT;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_FWCOMMONCONTEXT;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_ZSBUFFER;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_COMMONCTX_STATE;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CORE_CLK_RATE;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_FIRMWAREGCOVBUFFER;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CCCB;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CCCB_CTL;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_FREELIST;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_HWRTDATA;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_TIMESTAMP_ADDR;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_RF_CMD;
+
+/*!
+ * This number is used to represent an invalid page catalogue physical address
+ */
+#define RGXFWIF_INVALID_PC_PHYADDR 0xFFFFFFFFFFFFFFFFLLU
+
+/*!
+ * This number is used to represent unallocated page catalog base register
+ */
+#define RGXFW_BIF_INVALID_PCREG 0xFFFFFFFFU
+
+/*!
+ Firmware memory context.
+*/
+typedef struct
+{
+ IMG_DEV_PHYADDR RGXFW_ALIGN sPCDevPAddr; /*!< device physical address of context's page catalogue */
+ IMG_UINT32 uiPageCatBaseRegID; /*!< associated page catalog base register (RGXFW_BIF_INVALID_PCREG == unallocated) */
+ IMG_UINT32 uiBreakpointAddr; /*!< breakpoint address */
+ IMG_UINT32 uiBPHandlerAddr; /*!< breakpoint handler address */
+ IMG_UINT32 uiBreakpointCtl; /*!< DM and enable control for BP */
+ IMG_UINT64 RGXFW_ALIGN ui64FBCStateIDMask; /*!< FBCDC state descriptor IDs (non-zero means defer on mem context activation) */
+ IMG_UINT32 ui32FwMemCtxFlags; /*!< Compatibility and other flags */
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+ IMG_UINT32 ui32OSid;
+ IMG_BOOL bOSidAxiProt;
+#endif
+
+} UNCACHED_ALIGN RGXFWIF_FWMEMCONTEXT;
+
+/*!
+ * FW context state flags
+ */
+#define RGXFWIF_CONTEXT_FLAGS_NEED_RESUME (0x00000001U)
+#define RGXFWIF_CONTEXT_FLAGS_TDM_HEADER_STALE (0x00000002U)
+
+/*!
+ * @InGroup ContextSwitching
+ * @Brief Firmware GEOM/TA context suspend state
+ */
+typedef struct
+{
+ IMG_UINT64 RGXFW_ALIGN uTAReg_DCE_CMD0;
+ IMG_UINT32 uTAReg_DCE_CMD1;
+ IMG_UINT32 uTAReg_DCE_WRITE;
+ IMG_UINT64 RGXFW_ALIGN uTAReg_DCE_DRAW0;
+ IMG_UINT64 RGXFW_ALIGN uTAReg_DCE_DRAW1;
+ IMG_UINT32 uTAReg_GTA_SO_PRIM[4];
+ IMG_UINT16 ui16TACurrentIdx;
+} UNCACHED_ALIGN RGXFWIF_TACTX_STATE_PER_GEOM;
+
+typedef struct
+{
+ /* FW-accessible TA state which must be written out to memory on context store */
+ RGXFWIF_TACTX_STATE_PER_GEOM asGeomCore[RGX_NUM_GEOM_CORES];
+} UNCACHED_ALIGN RGXFWIF_TACTX_STATE;
+
+/* The following defines need to be auto generated using the HW defines
+ * rather than hard coding it */
+#define RGXFWIF_ISP_PIPE_COUNT_MAX (20)
+#define RGXFWIF_PIPE_COUNT_PER_ISP (2)
+#define RGXFWIF_IPP_RESUME_REG_COUNT (1)
+
+#if !defined(__KERNEL__)
+#define RGXFWIF_ISP_COUNT (RGX_FEATURE_NUM_SPU * RGX_FEATURE_NUM_ISP_PER_SPU)
+#define RGXFWIF_ISP_PIPE_COUNT (RGXFWIF_ISP_COUNT * RGXFWIF_PIPE_COUNT_PER_ISP)
+#if RGXFWIF_ISP_PIPE_COUNT > RGXFWIF_ISP_PIPE_COUNT_MAX
+#error RGXFWIF_ISP_PIPE_COUNT should not be greater than RGXFWIF_ISP_PIPE_COUNT_MAX
+#endif
+#endif /* !defined(__KERNEL__) */
+
+/*!
+ * @InGroup ContextSwitching
+ * @Brief Firmware FRAG/3D context suspend state
+ */
+typedef struct
+{
+#if defined(PM_INTERACTIVE_MODE)
+ IMG_UINT32 RGXFW_ALIGN u3DReg_PM_DEALLOCATED_MASK_STATUS; /*!< Managed by PM HW in the non-interactive mode */
+#endif
+ IMG_UINT32 ui32CtxStateFlags; /*!< Compatibility and other flags */
+
+ /* FW-accessible ISP state which must be written out to memory on context store */
+ /* au3DReg_ISP_STORE should be the last element of the structure
+ * as this is an array whose size is determined at runtime
+ * after detecting the RGX core */
+ IMG_UINT64 RGXFW_ALIGN au3DReg_ISP_STORE[]; /*!< ISP state (per-pipe) */
+} UNCACHED_ALIGN RGXFWIF_3DCTX_STATE;
+
+#define RGXFWIF_CTX_USING_BUFFER_A (0)
+#define RGXFWIF_CTX_USING_BUFFER_B (1U)
+
+typedef struct
+{
+ IMG_UINT32 ui32CtxStateFlags; /*!< Target buffer and other flags */
+} RGXFWIF_COMPUTECTX_STATE;
+
+/*!
+ * @InGroup WorkloadContexts
+ * @Brief Firmware Common Context (or FWCC)
+ */
+typedef struct RGXFWIF_FWCOMMONCONTEXT_
+{
+ /* CCB details for this firmware context */
+ PRGXFWIF_CCCB_CTL psCCBCtl; /*!< CCB control */
+ PRGXFWIF_CCCB psCCB; /*!< CCB base */
+ RGXFWIF_DMA_ADDR sCCBMetaDMAAddr;
+
+ /* Context suspend state */
+ PRGXFWIF_COMMONCTX_STATE RGXFW_ALIGN psContextState; /*!< TA/3D context suspend state, read/written by FW */
+
+ /* Flags e.g. for context switching */
+ IMG_UINT32 ui32FWComCtxFlags;
+ IMG_UINT32 ui32Priority; /*!< Priority level */
+ IMG_UINT32 ui32PrioritySeqNum;
+
+ /* Framework state */
+ PRGXFWIF_RF_CMD RGXFW_ALIGN psRFCmd; /*!< Register updates for Framework */
+
+ /* Statistic updates waiting to be passed back to the host... */
+ IMG_BOOL bStatsPending; /*!< True when some stats are pending */
+ IMG_INT32 i32StatsNumStores; /*!< Number of stores on this context since last update */
+ IMG_INT32 i32StatsNumOutOfMemory; /*!< Number of OOMs on this context since last update */
+ IMG_INT32 i32StatsNumPartialRenders; /*!< Number of PRs on this context since last update */
+ RGXFWIF_DM eDM; /*!< Data Master type */
+ IMG_UINT64 RGXFW_ALIGN ui64WaitSignalAddress; /*!< Device Virtual Address of the signal the context is waiting on */
+ RGXFWIF_DLLIST_NODE RGXFW_ALIGN sWaitSignalNode; /*!< List entry for the wait-signal list */
+ RGXFWIF_DLLIST_NODE RGXFW_ALIGN sBufStalledNode; /*!< List entry for the buffer stalled list */
+ IMG_UINT64 RGXFW_ALIGN ui64CBufQueueCtrlAddr; /*!< Address of the circular buffer queue pointers */
+
+ IMG_UINT64 RGXFW_ALIGN ui64RobustnessAddress;
+ IMG_UINT32 ui32MaxDeadlineMS; /*!< Max HWR deadline limit in ms */
+ bool bReadOffsetNeedsReset; /*!< Following HWR circular buffer read-offset needs resetting */
+
+ RGXFWIF_DLLIST_NODE RGXFW_ALIGN sWaitingNode; /*!< List entry for the waiting list */
+ RGXFWIF_DLLIST_NODE RGXFW_ALIGN sRunNode; /*!< List entry for the run list */
+ RGXFWIF_UFO sLastFailedUFO; /*!< UFO that last failed (or NULL) */
+
+ PRGXFWIF_FWMEMCONTEXT psFWMemContext; /*!< Memory context */
+
+ /* References to the host side originators */
+ IMG_UINT32 ui32ServerCommonContextID; /*!< the Server Common Context */
+ IMG_UINT32 ui32PID; /*!< associated process ID */
+
+ IMG_BOOL bGeomOOMDisabled; /*!< True when Geom DM OOM is not allowed */
+
+} UNCACHED_ALIGN RGXFWIF_FWCOMMONCONTEXT;
+
+static_assert(sizeof(RGXFWIF_FWCOMMONCONTEXT) <= 256,
+ "Size of structure RGXFWIF_FWCOMMONCONTEXT exceeds maximum expected size.");
+
+typedef IMG_UINT64 RGXFWIF_TRP_CHECKSUM_2D[RGX_TRP_MAX_NUM_CORES][2];
+typedef IMG_UINT64 RGXFWIF_TRP_CHECKSUM_3D[RGX_TRP_MAX_NUM_CORES][4];
+typedef IMG_UINT64 RGXFWIF_TRP_CHECKSUM_GEOM[RGX_TRP_MAX_NUM_CORES][2];
+
+/*!
+ * @InGroup WorkloadContexts
+ * @Brief Firmware render context.
+ */
+typedef struct
+{
+ RGXFWIF_FWCOMMONCONTEXT sTAContext; /*!< Firmware context for the TA */
+ RGXFWIF_FWCOMMONCONTEXT s3DContext; /*!< Firmware context for the 3D */
+
+ RGXFWIF_STATIC_RENDERCONTEXT_STATE sStaticRenderContextState;
+
+ IMG_UINT32 ui32TotalNumPartialRenders; /*!< Total number of partial renders */
+ IMG_UINT32 ui32TotalNumOutOfMemory; /*!< Total number of OOMs */
+ IMG_UINT32 ui32WorkEstCCBSubmitted; /*!< Number of commands submitted to the WorkEst FW CCB */
+ IMG_UINT32 ui32FwRenderCtxFlags; /*!< Compatibility and other flags */
+} UNCACHED_ALIGN RGXFWIF_FWRENDERCONTEXT;
+
+/*!
+ Firmware compute context.
+*/
+typedef struct
+{
+ RGXFWIF_FWCOMMONCONTEXT sCDMContext; /*!< Firmware context for the CDM */
+
+ RGXFWIF_STATIC_COMPUTECONTEXT_STATE sStaticComputeContextState;
+
+ IMG_UINT32 ui32WorkEstCCBSubmitted; /*!< Number of commands submitted to the WorkEst FW CCB */
+
+ IMG_UINT32 ui32ComputeCtxFlags; /*!< Compatibility and other flags */
+
+ IMG_UINT32 ui32WGPState;
+ IMG_UINT32 aui32WGPChecksum[RGX_WGP_MAX_NUM_CORES];
+} UNCACHED_ALIGN RGXFWIF_FWCOMPUTECONTEXT;
+
+/*!
+ Firmware ray context.
+*/
+typedef struct
+{
+ RGXFWIF_FWCOMMONCONTEXT sRDMContext; /*!< Firmware context for the RDM */
+ RGXFWIF_STATIC_RAYCONTEXT_STATE sStaticRayContextState;
+ IMG_UINT32 ui32WorkEstCCBSubmitted; /*!< Number of commands submitted to the WorkEst FW CCB */
+
+} UNCACHED_ALIGN RGXFWIF_FWRAYCONTEXT;
+
+/*!
+ * @InGroup WorkloadContexts
+ * @Brief Firmware TDM context.
+ */
+typedef struct
+{
+ RGXFWIF_FWCOMMONCONTEXT sTDMContext; /*!< Firmware context for the TDM */
+
+ IMG_UINT32 ui32WorkEstCCBSubmitted; /*!< Number of commands submitted to the WorkEst FW CCB */
+#if defined(SUPPORT_TRP)
+ IMG_UINT32 ui32TRPState;
+ RGXFWIF_TRP_CHECKSUM_2D RGXFW_ALIGN aui64TRPChecksums2D;
+#endif
+
+} UNCACHED_ALIGN RGXFWIF_FWTDMCONTEXT;
+
+/*!
+ ******************************************************************************
+ * Defines for CMD_TYPE corruption detection and forward compatibility check
+ *****************************************************************************/
+
+/* CMD_TYPE 32bit contains:
+ * 31:16 Reserved for magic value to detect corruption (16 bits)
+ * 15 Reserved for RGX_CCB_TYPE_TASK (1 bit)
+ * 14:0 Bits available for CMD_TYPEs (15 bits) */
+
+
+/* Magic value to detect corruption */
+#define RGX_CMD_MAGIC_DWORD IMG_UINT32_C(0x2ABC)
+#define RGX_CMD_MAGIC_DWORD_MASK (0xFFFF0000U)
+#define RGX_CMD_MAGIC_DWORD_SHIFT (16U)
+#define RGX_CMD_MAGIC_DWORD_SHIFTED (RGX_CMD_MAGIC_DWORD << RGX_CMD_MAGIC_DWORD_SHIFT)
+
+/*!
+ * @InGroup KCCBTypes ClientCCBTypes
+ * @Brief Generic CCB control structure
+ */
+typedef struct
+{
+ volatile IMG_UINT32 ui32WriteOffset; /*!< write offset into array of commands (MUST be aligned to 16 bytes!) */
+ volatile IMG_UINT32 ui32ReadOffset; /*!< read offset into array of commands */
+ IMG_UINT32 ui32WrapMask; /*!< Offset wrapping mask (Total capacity of the CCB - 1) */
+ IMG_UINT32 ui32CmdSize; /*!< size of each command in bytes */
+} UNCACHED_ALIGN RGXFWIF_CCB_CTL;
+
+/*!
+ * @Defgroup KCCBTypes Kernel CCB data interface
+ * @Brief Types grouping data structures and defines used in realising the KCCB functionality
+ * @{
+ */
+
+#define RGXFWIF_MMUCACHEDATA_FLAGS_PT (0x1U) /* MMU_CTRL_INVAL_PT_EN */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_PD (0x2U) /* MMU_CTRL_INVAL_PD_EN */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_PC (0x4U) /* MMU_CTRL_INVAL_PC_EN */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_CTX_ALL (0x800U) /* MMU_CTRL_INVAL_ALL_CONTEXTS_EN */
+#define RGXFWIF_MMUCACHEDATA_FLAGS_TLB (0x0) /* not used */
+
+#define RGXFWIF_MMUCACHEDATA_FLAGS_INTERRUPT (0x4000000U) /* indicates FW should interrupt the host */
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_MMUCACHE type command
+ */
+typedef struct
+{
+ IMG_UINT32 ui32CacheFlags;
+ RGXFWIF_DEV_VIRTADDR sMMUCacheSync;
+ IMG_UINT32 ui32MMUCacheSyncUpdateValue;
+} RGXFWIF_MMUCACHEDATA;
+
+#define RGXFWIF_BPDATA_FLAGS_ENABLE (1U << 0)
+#define RGXFWIF_BPDATA_FLAGS_WRITE (1U << 1)
+#define RGXFWIF_BPDATA_FLAGS_CTL (1U << 2)
+#define RGXFWIF_BPDATA_FLAGS_REGS (1U << 3)
+
+typedef struct
+{
+ PRGXFWIF_FWMEMCONTEXT psFWMemContext; /*!< Memory context */
+ IMG_UINT32 ui32BPAddr; /*!< Breakpoint address */
+ IMG_UINT32 ui32HandlerAddr; /*!< Breakpoint handler */
+ IMG_UINT32 ui32BPDM; /*!< Breakpoint control */
+ IMG_UINT32 ui32BPDataFlags;
+ IMG_UINT32 ui32TempRegs; /*!< Number of temporary registers to overallocate */
+ IMG_UINT32 ui32SharedRegs; /*!< Number of shared registers to overallocate */
+ RGXFWIF_DM eDM; /*!< DM associated with the breakpoint */
+} RGXFWIF_BPDATA;
+
+#define RGXFWIF_KCCB_CMD_KICK_DATA_MAX_NUM_CLEANUP_CTLS (RGXFWIF_PRBUFFER_MAXSUPPORTED + 1U) /* +1 is RTDATASET cleanup */
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_KICK type command
+ */
+typedef struct
+{
+ PRGXFWIF_FWCOMMONCONTEXT psContext; /*!< address of the firmware context */
+ IMG_UINT32 ui32CWoffUpdate; /*!< Client CCB woff update */
+ IMG_UINT32 ui32CWrapMaskUpdate; /*!< Client CCB wrap mask update after CCCB growth */
+ IMG_UINT32 ui32NumCleanupCtl; /*!< number of CleanupCtl pointers attached */
+ PRGXFWIF_CLEANUP_CTL apsCleanupCtl[RGXFWIF_KCCB_CMD_KICK_DATA_MAX_NUM_CLEANUP_CTLS]; /*!< CleanupCtl structures associated with command */
+ IMG_UINT32 ui32WorkEstCmdHeaderOffset; /*!< offset to the CmdHeader which houses the workload estimation kick data. */
+} RGXFWIF_KCCB_CMD_KICK_DATA;
+
+/*!
+ * @Brief Command data for @Ref RGXFWIF_KCCB_CMD_COMBINED_TA_3D_KICK type command
+ */
+typedef struct
+{
+ RGXFWIF_KCCB_CMD_KICK_DATA sTACmdKickData; /*!< GEOM DM kick command data */
+ RGXFWIF_KCCB_CMD_KICK_DATA s3DCmdKickData; /*!< FRAG DM kick command data */
+} RGXFWIF_KCCB_CMD_COMBINED_TA_3D_KICK_DATA;
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_FORCE_UPDATE type command
+ */
+typedef struct
+{
+ PRGXFWIF_FWCOMMONCONTEXT psContext; /*!< address of the firmware context */
+ IMG_UINT32 ui32CCBFenceOffset; /*!< Client CCB fence offset */
+} RGXFWIF_KCCB_CMD_FORCE_UPDATE_DATA;
+
+/*!
+ * @Brief Resource types supported by \ref RGXFWIF_KCCB_CMD_CLEANUP type command
+ */
+typedef enum
+{
+ RGXFWIF_CLEANUP_FWCOMMONCONTEXT, /*!< FW common context cleanup */
+ RGXFWIF_CLEANUP_HWRTDATA, /*!< FW HW RT data cleanup */
+ RGXFWIF_CLEANUP_FREELIST, /*!< FW freelist cleanup */
+ RGXFWIF_CLEANUP_ZSBUFFER, /*!< FW ZS Buffer cleanup */
+} RGXFWIF_CLEANUP_TYPE;
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_CLEANUP type command
+ */
+typedef struct
+{
+ RGXFWIF_CLEANUP_TYPE eCleanupType; /*!< Cleanup type */
+ union {
+ PRGXFWIF_FWCOMMONCONTEXT psContext; /*!< FW common context to cleanup */
+ PRGXFWIF_HWRTDATA psHWRTData; /*!< HW RT to cleanup */
+ PRGXFWIF_FREELIST psFreelist; /*!< Freelist to cleanup */
+ PRGXFWIF_ZSBUFFER psZSBuffer; /*!< ZS Buffer to cleanup */
+ } uCleanupData;
+} RGXFWIF_CLEANUP_REQUEST;
+
+/*!
+ * @Brief Type of power requests supported in \ref RGXFWIF_KCCB_CMD_POW type command
+ */
+typedef enum
+{
+ RGXFWIF_POW_OFF_REQ = 1, /*!< GPU power-off request */
+ RGXFWIF_POW_FORCED_IDLE_REQ, /*!< Force-idle related request */
+ RGXFWIF_POW_NUM_UNITS_CHANGE, /*!< Request to change default powered scalable units */
+ RGXFWIF_POW_APM_LATENCY_CHANGE /*!< Request to change the APM latency period */
+} RGXFWIF_POWER_TYPE;
+
+/*!
+ * @Brief Supported force-idle related requests with \ref RGXFWIF_POW_FORCED_IDLE_REQ type request
+ */
+typedef enum
+{
+ RGXFWIF_POWER_FORCE_IDLE = 1, /*!< Request to force-idle GPU */
+ RGXFWIF_POWER_CANCEL_FORCED_IDLE, /*!< Request to cancel a previously successful force-idle transition */
+ RGXFWIF_POWER_HOST_TIMEOUT, /*!< Notification that host timed-out waiting for force-idle state */
+} RGXFWIF_POWER_FORCE_IDLE_TYPE;
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_POW type command
+ */
+typedef struct
+{
+ RGXFWIF_POWER_TYPE ePowType; /*!< Type of power request */
+ union
+ {
+ IMG_UINT32 ui32PowUnitsStateMask; /*!< New power units state mask */
+ IMG_BOOL bForced; /*!< If the operation is mandatory */
+ RGXFWIF_POWER_FORCE_IDLE_TYPE ePowRequestType; /*!< Type of Request. Consolidating Force Idle, Cancel Forced Idle, Host Timeout */
+ } uPowerReqData;
+} RGXFWIF_POWER_REQUEST;
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_SLCFLUSHINVAL type command
+ */
+typedef struct
+{
+ PRGXFWIF_FWCOMMONCONTEXT psContext; /*!< Context to fence on (only useful when bDMContext == TRUE) */
+ IMG_BOOL bInval; /*!< Invalidate the cache as well as flushing */
+ IMG_BOOL bDMContext; /*!< The data to flush/invalidate belongs to a specific DM context */
+ IMG_UINT64 RGXFW_ALIGN ui64Address; /*!< Optional address of range (only useful when bDMContext == FALSE) */
+ IMG_UINT64 RGXFW_ALIGN ui64Size; /*!< Optional size of range (only useful when bDMContext == FALSE) */
+} RGXFWIF_SLCFLUSHINVALDATA;
+
+typedef enum
+{
+ RGXFWIF_HWPERF_CTRL_TOGGLE = 0,
+ RGXFWIF_HWPERF_CTRL_SET = 1,
+ RGXFWIF_HWPERF_CTRL_EMIT_FEATURES_EV = 2
+} RGXFWIF_HWPERF_UPDATE_CONFIG;
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_HWPERF_UPDATE_CONFIG type command
+ */
+typedef struct
+{
+ RGXFWIF_HWPERF_UPDATE_CONFIG eOpCode; /*!< Control operation code */
+ IMG_UINT64 RGXFW_ALIGN ui64Mask; /*!< Mask of events to toggle */
+} RGXFWIF_HWPERF_CTRL;
+
+typedef enum
+{
+ RGXFWIF_HWPERF_CNTR_NOOP = 0, /* No-Op */
+ RGXFWIF_HWPERF_CNTR_ENABLE = 1, /* Enable Counters */
+ RGXFWIF_HWPERF_CNTR_DISABLE = 2 /* Disable Counters */
+} RGXFWIF_HWPERF_CNTR_CONFIG;
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_HWPERF_CONFIG_BLKS type command
+ */
+typedef struct
+{
+ IMG_UINT32 ui32CtrlWord;
+ IMG_UINT32 ui32NumBlocks; /*!< Number of RGX_HWPERF_CONFIG_CNTBLK in the array */
+ PRGX_HWPERF_CONFIG_CNTBLK sBlockConfigs; /*!< Address of the RGX_HWPERF_CONFIG_CNTBLK array */
+} RGXFWIF_HWPERF_CONFIG_ENABLE_BLKS;
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_CORECLKSPEEDCHANGE type command
+ */
+typedef struct
+{
+ IMG_UINT32 ui32NewClockSpeed; /*!< New clock speed */
+} RGXFWIF_CORECLKSPEEDCHANGE_DATA;
+
+#define RGXFWIF_HWPERF_CTRL_BLKS_MAX 16
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_HWPERF_CTRL_BLKS type command
+ */
+typedef struct
+{
+ bool bEnable;
+ IMG_UINT32 ui32NumBlocks; /*!< Number of block IDs in the array */
+ IMG_UINT16 aeBlockIDs[RGXFWIF_HWPERF_CTRL_BLKS_MAX]; /*!< Array of RGX_HWPERF_CNTBLK_ID values */
+} RGXFWIF_HWPERF_CTRL_BLKS;
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_ZSBUFFER_BACKING_UPDATE & \ref RGXFWIF_KCCB_CMD_ZSBUFFER_UNBACKING_UPDATE type commands
+ */
+typedef struct
+{
+ RGXFWIF_DEV_VIRTADDR sZSBufferFWDevVAddr; /*!< ZS-Buffer FW address */
+ IMG_BOOL bDone; /*!< action backing/unbacking succeeded */
+} RGXFWIF_ZSBUFFER_BACKING_DATA;
+
+#if defined(SUPPORT_VALIDATION)
+typedef struct
+{
+ IMG_UINT32 ui32RegWidth;
+ IMG_BOOL bWriteOp;
+ IMG_UINT32 ui32RegAddr;
+ IMG_UINT64 RGXFW_ALIGN ui64RegVal;
+} RGXFWIF_RGXREG_DATA;
+#endif
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_FREELIST_GROW_UPDATE type command
+ */
+typedef struct
+{
+ RGXFWIF_DEV_VIRTADDR sFreeListFWDevVAddr; /*!< Freelist FW address */
+ IMG_UINT32 ui32DeltaPages; /*!< Amount of the Freelist change */
+ IMG_UINT32 ui32NewPages; /*!< New amount of pages on the freelist (including ready pages) */
+ IMG_UINT32 ui32ReadyPages; /*!< Number of ready pages to be held in reserve until OOM */
+} RGXFWIF_FREELIST_GS_DATA;
+
+#define RGXFWIF_MAX_FREELISTS_TO_RECONSTRUCT (MAX_HW_TA3DCONTEXTS * RGXFW_MAX_FREELISTS * 2U)
+#define RGXFWIF_FREELISTS_RECONSTRUCTION_FAILED_FLAG 0x80000000U
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_FREELISTS_RECONSTRUCTION_UPDATE type command
+ */
+typedef struct
+{
+ IMG_UINT32 ui32FreelistsCount;
+ IMG_UINT32 aui32FreelistIDs[RGXFWIF_MAX_FREELISTS_TO_RECONSTRUCT];
+} RGXFWIF_FREELISTS_RECONSTRUCTION_DATA;
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_NOTIFY_WRITE_OFFSET_UPDATE type command
+ */
+typedef struct
+{
+ PRGXFWIF_FWCOMMONCONTEXT psContext; /*!< Context to that may need to be resumed following write offset update */
+} UNCACHED_ALIGN RGXFWIF_WRITE_OFFSET_UPDATE_DATA;
+
+/*!
+ ******************************************************************************
+ * Proactive DVFS Structures
+ *****************************************************************************/
+#define NUM_OPP_VALUES 16
+
+typedef struct
+{
+ IMG_UINT32 ui32Volt; /* V */
+ IMG_UINT32 ui32Freq; /* Hz */
+} UNCACHED_ALIGN PDVFS_OPP;
+
+typedef struct
+{
+ PDVFS_OPP asOPPValues[NUM_OPP_VALUES];
+#if defined(DEBUG)
+ IMG_UINT32 ui32MinOPPPoint;
+#endif
+ IMG_UINT32 ui32MaxOPPPoint;
+} UNCACHED_ALIGN RGXFWIF_PDVFS_OPP;
+
+typedef struct
+{
+ IMG_UINT32 ui32MaxOPPPoint;
+} UNCACHED_ALIGN RGXFWIF_PDVFS_MAX_FREQ_DATA;
+
+typedef struct
+{
+ IMG_UINT32 ui32MinOPPPoint;
+} UNCACHED_ALIGN RGXFWIF_PDVFS_MIN_FREQ_DATA;
+
+/*!
+ ******************************************************************************
+ * Register configuration structures
+ *****************************************************************************/
+
+#define RGXFWIF_REG_CFG_MAX_SIZE 512
+
+typedef enum
+{
+ RGXFWIF_REGCFG_CMD_ADD = 101,
+ RGXFWIF_REGCFG_CMD_CLEAR = 102,
+ RGXFWIF_REGCFG_CMD_ENABLE = 103,
+ RGXFWIF_REGCFG_CMD_DISABLE = 104
+} RGXFWIF_REGDATA_CMD_TYPE;
+
+typedef IMG_UINT32 RGXFWIF_REG_CFG_TYPE;
+#define RGXFWIF_REG_CFG_TYPE_PWR_ON 0U /* Sidekick power event */
+#define RGXFWIF_REG_CFG_TYPE_DUST_CHANGE 1U /* Rascal / dust power event */
+#define RGXFWIF_REG_CFG_TYPE_TA 2U /* TA kick */
+#define RGXFWIF_REG_CFG_TYPE_3D 3U /* 3D kick */
+#define RGXFWIF_REG_CFG_TYPE_CDM 4U /* Compute kick */
+#define RGXFWIF_REG_CFG_TYPE_TDM 5U /* TDM kick */
+#define RGXFWIF_REG_CFG_TYPE_ALL 6U /* Applies to all types. Keep as last element */
+
+typedef struct
+{
+ IMG_UINT64 ui64Addr;
+ IMG_UINT64 ui64Mask;
+ IMG_UINT64 ui64Value;
+} RGXFWIF_REG_CFG_REC;
+
+typedef struct
+{
+ RGXFWIF_REGDATA_CMD_TYPE eCmdType;
+ RGXFWIF_REG_CFG_TYPE eRegConfigType;
+ RGXFWIF_REG_CFG_REC RGXFW_ALIGN sRegConfig;
+
+} RGXFWIF_REGCONFIG_DATA;
+
+typedef struct
+{
+ /**
+ * PDump WRW command write granularity is 32 bits.
+ * Add padding to ensure array size is 32 bit granular.
+ */
+ IMG_UINT8 RGXFW_ALIGN aui8NumRegsType[PVR_ALIGN(RGXFWIF_REG_CFG_TYPE_ALL,sizeof(IMG_UINT32))];
+ RGXFWIF_REG_CFG_REC RGXFW_ALIGN asRegConfigs[RGXFWIF_REG_CFG_MAX_SIZE];
+} UNCACHED_ALIGN RGXFWIF_REG_CFG;
+
+typedef enum
+{
+ RGXFWIF_OS_ONLINE = 1,
+ RGXFWIF_OS_OFFLINE
+} RGXFWIF_OS_STATE_CHANGE;
+
+/*!
+ * @Brief Command data for \ref RGXFWIF_KCCB_CMD_OS_ONLINE_STATE_CONFIGURE type command
+ */
+typedef struct
+{
+ IMG_UINT32 ui32OSid;
+ RGXFWIF_OS_STATE_CHANGE eNewOSState;
+} UNCACHED_ALIGN RGXFWIF_OS_STATE_CHANGE_DATA;
+
+/*!
+ * @Brief List of command types supported by the Kernel CCB
+ */
+typedef enum
+{
+ /* Common commands */
+ RGXFWIF_KCCB_CMD_KICK = 101U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< DM workload kick command */
+ RGXFWIF_KCCB_CMD_MMUCACHE = 102U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< MMU cache invalidation request */
+ RGXFWIF_KCCB_CMD_BP = 103U | RGX_CMD_MAGIC_DWORD_SHIFTED,
+ RGXFWIF_KCCB_CMD_SLCFLUSHINVAL = 105U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< SLC flush and invalidation request */
+ RGXFWIF_KCCB_CMD_CLEANUP = 106U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests cleanup of a FW resource (type specified in the command data) */
+ RGXFWIF_KCCB_CMD_POW = 107U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Power request (type specified in the command data) */
+ RGXFWIF_KCCB_CMD_ZSBUFFER_BACKING_UPDATE = 108U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Backing for on-demand ZS-Buffer done */
+ RGXFWIF_KCCB_CMD_ZSBUFFER_UNBACKING_UPDATE = 109U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Unbacking for on-demand ZS-Buffer done */
+ RGXFWIF_KCCB_CMD_FREELIST_GROW_UPDATE = 110U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Freelist Grow done */
+ RGXFWIF_KCCB_CMD_FREELISTS_RECONSTRUCTION_UPDATE = 112U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Freelists Reconstruction done */
+ /* RGXFWIF_KCCB_CMD_NOTIFY_SIGNAL_UPDATE */
+ RGXFWIF_KCCB_CMD_NOTIFY_WRITE_OFFSET_UPDATE = 114U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Informs the firmware that the host has added more data to a CDM2 Circular Buffer */
+ RGXFWIF_KCCB_CMD_HEALTH_CHECK = 115U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Health check request */
+ RGXFWIF_KCCB_CMD_FORCE_UPDATE = 116U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Forcing signalling of all unmet UFOs for a given CCB offset */
+
+ RGXFWIF_KCCB_CMD_COMBINED_TA_3D_KICK = 117U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< There is a TA and a 3D command in this single kick */
+ RGXFWIF_KCCB_CMD_OS_ONLINE_STATE_CONFIGURE = 118U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Informs the FW that a Guest OS has come online / offline. */
+
+ /* Commands only permitted to the native or host OS */
+ RGXFWIF_KCCB_CMD_REGCONFIG = 200U | RGX_CMD_MAGIC_DWORD_SHIFTED,
+ RGXFWIF_KCCB_CMD_HWPERF_UPDATE_CONFIG = 201U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Configure HWPerf events (to be generated) and HWPerf buffer address (if required) */
+ RGXFWIF_KCCB_CMD_HWPERF_CONFIG_BLKS = 202U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Configure, clear and enable multiple HWPerf blocks */
+ RGXFWIF_KCCB_CMD_HWPERF_CTRL_BLKS = 203U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Enable or disable multiple HWPerf blocks (reusing existing configuration) */
+ RGXFWIF_KCCB_CMD_CORECLKSPEEDCHANGE = 204U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Core clock speed change event */
+ RGXFWIF_KCCB_CMD_HWPERF_CONFIG_ENABLE_BLKS_DIRECT = 205U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Configure, clear and enable multiple HWPerf blocks during the init process */
+ RGXFWIF_KCCB_CMD_LOGTYPE_UPDATE = 206U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Ask the firmware to update its cached ui32LogType value from the (shared) tracebuf control structure */
+ RGXFWIF_KCCB_CMD_PDVFS_LIMIT_MAX_FREQ = 207U | RGX_CMD_MAGIC_DWORD_SHIFTED,
+ RGXFWIF_KCCB_CMD_OSID_PRIORITY_CHANGE = 208U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Changes the relative scheduling priority for a particular OSID. It can only be serviced for the Host DDK */
+ RGXFWIF_KCCB_CMD_STATEFLAGS_CTRL = 209U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Set or clear firmware state flags */
+ /* RGXFWIF_KCCB_CMD_HCS_SET_DEADLINE */
+ /* RGXFWIF_KCCB_CMD_OS_ONLINE_STATE_CONFIGURE */
+ RGXFWIF_KCCB_CMD_PDVFS_LIMIT_MIN_FREQ = 212U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Set a minimum frequency/OPP point */
+ RGXFWIF_KCCB_CMD_PHR_CFG = 213U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Configure Periodic Hardware Reset behaviour */
+#if defined(SUPPORT_VALIDATION)
+ RGXFWIF_KCCB_CMD_RGXREG = 214U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Read RGX Register from FW */
+#endif
+ RGXFWIF_KCCB_CMD_WDG_CFG = 215U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Configure Safety Firmware Watchdog */
+} RGXFWIF_KCCB_CMD_TYPE;
+
+#define RGXFWIF_LAST_ALLOWED_GUEST_KCCB_CMD (RGXFWIF_KCCB_CMD_REGCONFIG - 1)
+
+/*! @Brief Kernel CCB command packet */
+typedef struct
+{
+ RGXFWIF_KCCB_CMD_TYPE eCmdType; /*!< Command type */
+ IMG_UINT32 ui32KCCBFlags; /*!< Compatibility and other flags */
+
+ /* NOTE: Make sure that uCmdData is the last member of this struct
+ * This is to calculate actual command size for device mem copy.
+ * (Refer RGXGetCmdMemCopySize())
+ * */
+ union
+ {
+ RGXFWIF_KCCB_CMD_KICK_DATA sCmdKickData; /*!< Data for Kick command */
+ RGXFWIF_KCCB_CMD_COMBINED_TA_3D_KICK_DATA sCombinedTA3DCmdKickData; /*!< Data for combined TA/3D Kick command */
+ RGXFWIF_MMUCACHEDATA sMMUCacheData; /*!< Data for MMU cache command */
+ RGXFWIF_BPDATA sBPData; /*!< Data for Breakpoint Commands */
+ RGXFWIF_SLCFLUSHINVALDATA sSLCFlushInvalData; /*!< Data for SLC Flush/Inval commands */
+ RGXFWIF_CLEANUP_REQUEST sCleanupData; /*!< Data for cleanup commands */
+ RGXFWIF_POWER_REQUEST sPowData; /*!< Data for power request commands */
+ RGXFWIF_HWPERF_CTRL sHWPerfCtrl; /*!< Data for HWPerf control command */
+ RGXFWIF_HWPERF_CONFIG_ENABLE_BLKS sHWPerfCfgEnableBlks; /*!< Data for HWPerf configure, clear and enable performance counter block command */
+ RGXFWIF_HWPERF_CTRL_BLKS sHWPerfCtrlBlks; /*!< Data for HWPerf enable or disable performance counter block commands */
+ RGXFWIF_CORECLKSPEEDCHANGE_DATA sCoreClkSpeedChangeData;/*!< Data for core clock speed change */
+ RGXFWIF_ZSBUFFER_BACKING_DATA sZSBufferBackingData; /*!< Feedback for Z/S Buffer backing/unbacking */
+ RGXFWIF_FREELIST_GS_DATA sFreeListGSData; /*!< Feedback for Freelist grow/shrink */
+ RGXFWIF_FREELISTS_RECONSTRUCTION_DATA sFreeListsReconstructionData; /*!< Feedback for Freelists reconstruction */
+ RGXFWIF_REGCONFIG_DATA sRegConfigData; /*!< Data for custom register configuration */
+ RGXFWIF_WRITE_OFFSET_UPDATE_DATA sWriteOffsetUpdateData; /*!< Data for informing the FW about the write offset update */
+#if defined(SUPPORT_PDVFS)
+ RGXFWIF_PDVFS_MAX_FREQ_DATA sPDVFSMaxFreqData;
+ RGXFWIF_PDVFS_MIN_FREQ_DATA sPDVFSMinFreqData; /*!< Data for setting the min frequency/OPP */
+#endif
+ RGXFWIF_OS_STATE_CHANGE_DATA sCmdOSOnlineStateData; /*!< Data for updating the Guest Online states */
+ RGXFWIF_DEV_VIRTADDR sTBIBuffer; /*!< Dev address for TBI buffer allocated on demand */
+ RGXFWIF_KCCB_CMD_FORCE_UPDATE_DATA sForceUpdateData; /*!< Data for signalling all unmet fences for a given CCB */
+#if defined(SUPPORT_VALIDATION)
+ RGXFWIF_RGXREG_DATA sFwRgxData; /*!< Data for reading off an RGX register */
+#endif
+ } UNCACHED_ALIGN uCmdData;
+} UNCACHED_ALIGN RGXFWIF_KCCB_CMD;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGXFWIF_KCCB_CMD);
+
+/*! @} End of KCCBTypes */
+
+/*!
+ * @Defgroup FWCCBTypes Firmware CCB data interface
+ * @Brief Types grouping data structures and defines used in realising the Firmware CCB functionality
+ * @{
+ */
+
+/*!
+ ******************************************************************************
+ * @Brief Command data of the \ref RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING and the
+ * \ref RGXFWIF_FWCCB_CMD_ZSBUFFER_UNBACKING Firmware CCB commands
+ *****************************************************************************/
+typedef struct
+{
+ IMG_UINT32 ui32ZSBufferID; /*!< ZS buffer ID */
+} RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING_DATA;
+
+/*!
+ ******************************************************************************
+ * @Brief Command data of the \ref RGXFWIF_FWCCB_CMD_FREELIST_GROW Firmware CCB
+ * command
+ *****************************************************************************/
+typedef struct
+{
+ IMG_UINT32 ui32FreelistID; /*!< Freelist ID */
+} RGXFWIF_FWCCB_CMD_FREELIST_GS_DATA;
+
+/*!
+ ******************************************************************************
+ * @Brief Command data of the \ref RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION
+ * Firmware CCB command
+ *****************************************************************************/
+typedef struct
+{
+ IMG_UINT32 ui32FreelistsCount; /*!< Freelists count */
+ IMG_UINT32 ui32HwrCounter; /*!< HWR counter */
+ IMG_UINT32 aui32FreelistIDs[RGXFWIF_MAX_FREELISTS_TO_RECONSTRUCT]; /*!< Array of freelist IDs to reconstruct */
+} RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION_DATA;
+
+#define RGXFWIF_FWCCB_CMD_CONTEXT_RESET_FLAG_PF (1U<<0) /*!< 1 if a page fault happened */
+#define RGXFWIF_FWCCB_CMD_CONTEXT_RESET_FLAG_ALL_CTXS (1U<<1) /*!< 1 if applicable to all contexts */
+
+/*!
+ ******************************************************************************
+ * @Brief Command data of the \ref RGXFWIF_FWCCB_CMD_CONTEXT_RESET_NOTIFICATION
+ * Firmware CCB command
+ *****************************************************************************/
+typedef struct
+{
+ IMG_UINT32 ui32ServerCommonContextID; /*!< Context affected by the reset */
+ RGX_CONTEXT_RESET_REASON eResetReason; /*!< Reason for reset */
+ RGXFWIF_DM eDM; /*!< Data Master affected by the reset */
+ IMG_UINT32 ui32ResetJobRef; /*!< Job ref running at the time of reset */
+ IMG_UINT32 ui32Flags; /*!< RGXFWIF_FWCCB_CMD_CONTEXT_RESET_FLAG bitfield */
+ IMG_UINT64 RGXFW_ALIGN ui64PCAddress; /*!< At what page catalog address */
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sFaultAddress; /*!< Page fault address (only when applicable) */
+} RGXFWIF_FWCCB_CMD_CONTEXT_RESET_DATA;
+
+/*!
+ ******************************************************************************
+ * @Brief Command data of the \ref RGXFWIF_FWCCB_CMD_CONTEXT_FW_PF_NOTIFICATION
+ * Firmware CCB command
+ *****************************************************************************/
+typedef struct
+{
+ IMG_DEV_VIRTADDR sFWFaultAddr; /*!< Page fault address */
+} RGXFWIF_FWCCB_CMD_FW_PAGEFAULT_DATA;
+
+/*!
+ ******************************************************************************
+ * List of command types supported by the Firmware CCB
+ *****************************************************************************/
+typedef enum
+{
+ RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING = 101U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests ZSBuffer to be backed with physical pages
+ \n Command data: RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING_DATA */
+ RGXFWIF_FWCCB_CMD_ZSBUFFER_UNBACKING = 102U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests ZSBuffer to be unbacked
+ \n Command data: RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING_DATA */
+ RGXFWIF_FWCCB_CMD_FREELIST_GROW = 103U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests an on-demand freelist grow
+ \n Command data: RGXFWIF_FWCCB_CMD_FREELIST_GS_DATA */
+ RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION = 104U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests freelists reconstruction
+ \n Command data: RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION_DATA */
+ RGXFWIF_FWCCB_CMD_CONTEXT_RESET_NOTIFICATION = 105U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Notifies host of a HWR event on a context
+ \n Command data: RGXFWIF_FWCCB_CMD_CONTEXT_RESET_DATA */
+ RGXFWIF_FWCCB_CMD_DEBUG_DUMP = 106U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests an on-demand debug dump
+ \n Command data: None */
+ RGXFWIF_FWCCB_CMD_UPDATE_STATS = 107U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests an on-demand update on process stats
+ \n Command data: RGXFWIF_FWCCB_CMD_UPDATE_STATS_DATA */
+#if defined(SUPPORT_PDVFS)
+ RGXFWIF_FWCCB_CMD_CORE_CLK_RATE_CHANGE = 108U | RGX_CMD_MAGIC_DWORD_SHIFTED,
+#endif
+ RGXFWIF_FWCCB_CMD_REQUEST_GPU_RESTART = 109U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Requests GPU restart
+ \n Command data: None */
+#if defined(SUPPORT_VALIDATION)
+ RGXFWIF_FWCCB_CMD_REG_READ = 110U | RGX_CMD_MAGIC_DWORD_SHIFTED,
+#if defined(SUPPORT_SOC_TIMER)
+ RGXFWIF_FWCCB_CMD_SAMPLE_TIMERS = 111U | RGX_CMD_MAGIC_DWORD_SHIFTED,
+#endif
+#endif
+ RGXFWIF_FWCCB_CMD_CONTEXT_FW_PF_NOTIFICATION = 112U | RGX_CMD_MAGIC_DWORD_SHIFTED, /*!< Notifies host of a FW pagefault
+ \n Command data: RGXFWIF_FWCCB_CMD_FW_PAGEFAULT_DATA */
+} RGXFWIF_FWCCB_CMD_TYPE;
+
+/*!
+ ******************************************************************************
+ * List of the various stats of the process to update/increment
+ *****************************************************************************/
+typedef enum
+{
+ RGXFWIF_FWCCB_CMD_UPDATE_NUM_PARTIAL_RENDERS=1, /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32TotalNumPartialRenders stat */
+ RGXFWIF_FWCCB_CMD_UPDATE_NUM_OUT_OF_MEMORY, /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32TotalNumOutOfMemory stat */
+ RGXFWIF_FWCCB_CMD_UPDATE_NUM_TA_STORES, /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32NumTAStores stat */
+ RGXFWIF_FWCCB_CMD_UPDATE_NUM_3D_STORES, /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32Num3DStores stat */
+ RGXFWIF_FWCCB_CMD_UPDATE_NUM_CDM_STORES, /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32NumCDMStores stat */
+ RGXFWIF_FWCCB_CMD_UPDATE_NUM_TDM_STORES /*!< PVRSRVStatsUpdateRenderContextStats should increase the value of the ui32NumTDMStores stat */
+} RGXFWIF_FWCCB_CMD_UPDATE_STATS_TYPE;
+
+/*!
+ ******************************************************************************
+ * @Brief Command data of the \ref RGXFWIF_FWCCB_CMD_UPDATE_STATS Firmware CCB
+ * command
+ *****************************************************************************/
+typedef struct
+{
+ RGXFWIF_FWCCB_CMD_UPDATE_STATS_TYPE eElementToUpdate; /*!< Element to update */
+ IMG_PID pidOwner; /*!< The pid of the process whose stats are being updated */
+ IMG_INT32 i32AdjustmentValue; /*!< Adjustment to be made to the statistic */
+} RGXFWIF_FWCCB_CMD_UPDATE_STATS_DATA;
+
+typedef struct
+{
+ IMG_UINT32 ui32CoreClkRate;
+} UNCACHED_ALIGN RGXFWIF_FWCCB_CMD_CORE_CLK_RATE_CHANGE_DATA;
+
+#if defined(SUPPORT_VALIDATION)
+typedef struct
+{
+ IMG_UINT64 ui64RegValue;
+} RGXFWIF_FWCCB_CMD_RGXREG_READ_DATA;
+
+#if defined(SUPPORT_SOC_TIMER)
+typedef struct
+{
+ IMG_UINT64 ui64timerGray;
+ IMG_UINT64 ui64timerBinary;
+ IMG_UINT64 aui64uscTimers[RGX_FEATURE_NUM_CLUSTERS];
+} RGXFWIF_FWCCB_CMD_SAMPLE_TIMERS_DATA;
+#endif
+#endif
+
+/*!
+ ******************************************************************************
+ * @Brief Firmware CCB command structure
+ *****************************************************************************/
+typedef struct
+{
+ RGXFWIF_FWCCB_CMD_TYPE eCmdType; /*!< Command type */
+ IMG_UINT32 ui32FWCCBFlags; /*!< Compatibility and other flags */
+
+ union
+ {
+ RGXFWIF_FWCCB_CMD_ZSBUFFER_BACKING_DATA sCmdZSBufferBacking; /*!< Data for Z/S-Buffer on-demand (un)backing*/
+ RGXFWIF_FWCCB_CMD_FREELIST_GS_DATA sCmdFreeListGS; /*!< Data for on-demand freelist grow/shrink */
+ RGXFWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION_DATA sCmdFreeListsReconstruction; /*!< Data for freelists reconstruction */
+ RGXFWIF_FWCCB_CMD_CONTEXT_RESET_DATA sCmdContextResetNotification; /*!< Data for context reset notification */
+ RGXFWIF_FWCCB_CMD_UPDATE_STATS_DATA sCmdUpdateStatsData; /*!< Data for updating process stats */
+ RGXFWIF_FWCCB_CMD_CORE_CLK_RATE_CHANGE_DATA sCmdCoreClkRateChange;
+ RGXFWIF_FWCCB_CMD_FW_PAGEFAULT_DATA sCmdFWPagefault; /*!< Data for context reset notification */
+#if defined(SUPPORT_VALIDATION)
+ RGXFWIF_FWCCB_CMD_RGXREG_READ_DATA sCmdRgxRegReadData;
+#if defined(SUPPORT_SOC_TIMER)
+ RGXFWIF_FWCCB_CMD_SAMPLE_TIMERS_DATA sCmdTimers;
+#endif
+#endif
+ } RGXFW_ALIGN uCmdData;
+} RGXFW_ALIGN RGXFWIF_FWCCB_CMD;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGXFWIF_FWCCB_CMD);
+
+/*! @} End of FWCCBTypes */
+
+/*!
+ ******************************************************************************
+ * Workload estimation Firmware CCB command structure for RGX
+ *****************************************************************************/
+typedef struct
+{
+ IMG_UINT16 ui16ReturnDataIndex; /*!< Index for return data array */
+ IMG_UINT32 ui32CyclesTaken; /*!< The cycles the workload took on the hardware */
+} RGXFWIF_WORKEST_FWCCB_CMD;
+
+/*!
+ * @Defgroup ClientCCBTypes Client CCB data interface
+ * @Brief Types grouping data structures and defines used in realising Client CCB commands/functionality
+ * @{
+ */
+
+/* Required memory alignment for 64-bit variables accessible by Meta
+ (The gcc meta aligns 64-bit variables to 64-bit; therefore, memory shared
+ between the host and meta that contains 64-bit variables has to maintain
+ this alignment) */
+#define RGXFWIF_FWALLOC_ALIGN sizeof(IMG_UINT64)
+
+#define RGX_CCB_TYPE_TASK (IMG_UINT32_C(1) << 15)
+#define RGX_CCB_FWALLOC_ALIGN(size) (((size) + (RGXFWIF_FWALLOC_ALIGN-1)) & ~(RGXFWIF_FWALLOC_ALIGN - 1))
+
+typedef IMG_UINT32 RGXFWIF_CCB_CMD_TYPE;
+
+/*!
+ * @Name Client CCB command types
+ * @{
+ */
+#define RGXFWIF_CCB_CMD_TYPE_GEOM (201U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< TA DM command */
+#define RGXFWIF_CCB_CMD_TYPE_TQ_3D (202U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< 3D DM command for TQ operation */
+#define RGXFWIF_CCB_CMD_TYPE_3D (203U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< 3D DM command */
+#define RGXFWIF_CCB_CMD_TYPE_3D_PR (204U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< 3D DM command for Partial render */
+#define RGXFWIF_CCB_CMD_TYPE_CDM (205U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< Compute DM command */
+#define RGXFWIF_CCB_CMD_TYPE_TQ_TDM (206U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< TDM command */
+#define RGXFWIF_CCB_CMD_TYPE_FBSC_INVALIDATE (207U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK)
+#define RGXFWIF_CCB_CMD_TYPE_TQ_2D (208U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK) /*!< 2D DM command for TQ operation */
+#define RGXFWIF_CCB_CMD_TYPE_PRE_TIMESTAMP (209U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK)
+#define RGXFWIF_CCB_CMD_TYPE_NULL (210U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK)
+#define RGXFWIF_CCB_CMD_TYPE_ABORT (211U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK)
+
+/* Leave a gap between CCB specific commands and generic commands */
+#define RGXFWIF_CCB_CMD_TYPE_FENCE (212U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Fence dependencies of a command */
+#define RGXFWIF_CCB_CMD_TYPE_UPDATE (213U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Fence updates of a command */
+#define RGXFWIF_CCB_CMD_TYPE_RMW_UPDATE (214U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Fence updates related to workload resources */
+#define RGXFWIF_CCB_CMD_TYPE_FENCE_PR (215U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Fence dependencies of a PR command */
+#define RGXFWIF_CCB_CMD_TYPE_PRIORITY (216U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Context priority update command */
+/* Pre and Post timestamp commands are supposed to sandwich the DM cmd. The
+ padding code with the CCB wrap upsets the FW if we don't have the task type
+ bit cleared for POST_TIMESTAMPs. That's why we have 2 different cmd types.
+*/
+#define RGXFWIF_CCB_CMD_TYPE_POST_TIMESTAMP (217U | RGX_CMD_MAGIC_DWORD_SHIFTED)
+#define RGXFWIF_CCB_CMD_TYPE_UNFENCED_UPDATE (218U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Unfenced fence updates of a command */
+#define RGXFWIF_CCB_CMD_TYPE_UNFENCED_RMW_UPDATE (219U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Unfenced fence updates related to workload resources */
+
+#if defined(SUPPORT_VALIDATION)
+#define RGXFWIF_CCB_CMD_TYPE_REG_READ (220U | RGX_CMD_MAGIC_DWORD_SHIFTED)
+#endif
+
+#define RGXFWIF_CCB_CMD_TYPE_PADDING (221U | RGX_CMD_MAGIC_DWORD_SHIFTED) /*!< Skip without action type command */
+#define RGXFWIF_CCB_CMD_TYPE_RAY (222U | RGX_CMD_MAGIC_DWORD_SHIFTED | RGX_CCB_TYPE_TASK)
+/*! @} End of Client CCB command types */
+
+typedef struct
+{
+ /* Index for the KM Workload estimation return data array */
+ IMG_UINT16 RGXFW_ALIGN ui16ReturnDataIndex;
+ /* Predicted time taken to do the work in cycles */
+ IMG_UINT32 RGXFW_ALIGN ui32CyclesPrediction;
+ /* Deadline for the workload (in usecs) */
+ IMG_UINT64 RGXFW_ALIGN ui64Deadline;
+} RGXFWIF_WORKEST_KICK_DATA;
+
+/*! @Brief Command header of a command in the client CCB buffer.
+ *
+ * Followed by this header is the command-data specific to the
+ * command-type as specified in the header.
+ */
+typedef struct
+{
+ RGXFWIF_CCB_CMD_TYPE eCmdType; /*!< Command data type following this command header */
+ IMG_UINT32 ui32CmdSize; /*!< Size of the command following this header */
+ IMG_UINT32 ui32ExtJobRef; /*!< external job reference - provided by client and used in debug for tracking submitted work */
+ IMG_UINT32 ui32IntJobRef; /*!< internal job reference - generated by services and used in debug for tracking submitted work */
+ RGXFWIF_WORKEST_KICK_DATA RGXFW_ALIGN sWorkEstKickData; /*!< Workload Estimation - Workload Estimation Data */
+} RGXFWIF_CCB_CMD_HEADER;
+
+/*
+ ******************************************************************************
+ * Client CCB commands which are only required by the kernel
+ *****************************************************************************/
+
+/*! @Brief Command data for \ref RGXFWIF_CCB_CMD_TYPE_PRIORITY type client CCB command */
+typedef struct
+{
+ IMG_UINT32 ui32Priority; /*!< Priority level */
+} RGXFWIF_CMD_PRIORITY;
+
+/*! @} End of ClientCCBTypes */
+
+/*!
+ ******************************************************************************
+ * Signature and Checksums Buffer
+ *****************************************************************************/
+typedef struct
+{
+ PRGXFWIF_SIGBUFFER sBuffer; /*!< Ptr to Signature Buffer memory */
+ IMG_UINT32 ui32LeftSizeInRegs; /*!< Amount of space left for storing regs in the buffer */
+} UNCACHED_ALIGN RGXFWIF_SIGBUF_CTL;
+
+typedef struct
+{
+ PRGXFWIF_FIRMWAREGCOVBUFFER sBuffer; /*!< Ptr to firmware gcov buffer */
+ IMG_UINT32 ui32Size; /*!< Amount of space for storing in the buffer */
+} UNCACHED_ALIGN RGXFWIF_FIRMWARE_GCOV_CTL;
+
+/*!
+ *****************************************************************************
+ * RGX Compatibility checks
+ *****************************************************************************/
+
+/* WARNING: Whenever the layout of RGXFWIF_COMPCHECKS_BVNC is a subject of change,
+ following define should be increased by 1 to indicate to compatibility logic,
+ that layout has changed */
+#define RGXFWIF_COMPCHECKS_LAYOUT_VERSION 3
+
+typedef struct
+{
+ IMG_UINT32 ui32LayoutVersion; /* WARNING: This field must be defined as first one in this structure */
+ IMG_UINT64 RGXFW_ALIGN ui64BVNC;
+} UNCACHED_ALIGN RGXFWIF_COMPCHECKS_BVNC;
+
+typedef struct
+{
+ IMG_UINT8 ui8OsCountSupport;
+} UNCACHED_ALIGN RGXFWIF_INIT_OPTIONS;
+
+#define RGXFWIF_COMPCHECKS_BVNC_DECLARE_AND_INIT(name) \
+ RGXFWIF_COMPCHECKS_BVNC (name) = { \
+ RGXFWIF_COMPCHECKS_LAYOUT_VERSION, \
+ 0, \
+ }
+#define RGXFWIF_COMPCHECKS_BVNC_INIT(name) \
+ do { \
+ (name).ui32LayoutVersion = RGXFWIF_COMPCHECKS_LAYOUT_VERSION; \
+ (name).ui64BVNC = 0; \
+ } while (0)
+
+typedef struct
+{
+ RGXFWIF_COMPCHECKS_BVNC sHWBVNC; /*!< hardware BVNC (from the RGX registers) */
+ RGXFWIF_COMPCHECKS_BVNC sFWBVNC; /*!< firmware BVNC */
+ IMG_UINT32 ui32FWProcessorVersion; /*!< identifier of the FW processor version */
+ IMG_UINT32 ui32DDKVersion; /*!< software DDK version */
+ IMG_UINT32 ui32DDKBuild; /*!< software DDK build no. */
+ IMG_UINT32 ui32BuildOptions; /*!< build options bit-field */
+ RGXFWIF_INIT_OPTIONS sInitOptions; /*!< initialisation options bit-field */
+ IMG_BOOL bUpdated; /*!< Information is valid */
+} UNCACHED_ALIGN RGXFWIF_COMPCHECKS;
+
+/*!
+ ******************************************************************************
+ * Updated configuration post FW data init.
+ *****************************************************************************/
+typedef struct
+{
+ IMG_UINT32 ui32ActivePMLatencyms; /* APM latency in ms before signalling IDLE to the host */
+ IMG_UINT32 ui32RuntimeCfgFlags; /* Compatibility and other flags */
+ IMG_BOOL bActivePMLatencyPersistant; /* If set, APM latency does not reset to system default each GPU power transition */
+ IMG_UINT32 ui32CoreClockSpeed; /* Core clock speed, currently only used to calculate timer ticks */
+ IMG_UINT32 ui32PowUnitsStateMask; /* Power Unit state mask set by the host */
+ IMG_UINT32 ui32PHRMode; /* Periodic Hardware Reset configuration values */
+ IMG_UINT32 ui32HCSDeadlineMS; /* New number of milliseconds C/S is allowed to last */
+ IMG_UINT32 ui32WdgPeriodUs; /* The watchdog period in microseconds */
+ IMG_UINT32 aui32OSidPriority[RGXFW_MAX_NUM_OS]; /*!< Array of priorities per OS */
+ PRGXFWIF_HWPERFBUF sHWPerfBuf; /* On-demand allocated HWPerf buffer address, to be passed to the FW */
+ RGXFWIF_DMA_ADDR sHWPerfDMABuf;
+} RGXFWIF_RUNTIME_CFG;
+
+/*!
+ *****************************************************************************
+ * Control data for RGX
+ *****************************************************************************/
+
+#define RGXFWIF_HWR_DEBUG_DUMP_ALL (99999U)
+
+#if defined(PDUMP)
+
+#define RGXFWIF_PID_FILTER_MAX_NUM_PIDS 32U
+
+typedef enum
+{
+ RGXFW_PID_FILTER_INCLUDE_ALL_EXCEPT,
+ RGXFW_PID_FILTER_EXCLUDE_ALL_EXCEPT
+} RGXFWIF_PID_FILTER_MODE;
+
+typedef struct
+{
+ IMG_PID uiPID;
+ IMG_UINT32 ui32OSID;
+} RGXFW_ALIGN RGXFWIF_PID_FILTER_ITEM;
+
+typedef struct
+{
+ RGXFWIF_PID_FILTER_MODE eMode;
+ /* each process in the filter list is specified by a PID and OS ID pair.
+ * each PID and OS pair is an item in the items array (asItems).
+ * if the array contains less than RGXFWIF_PID_FILTER_MAX_NUM_PIDS entries
+ * then it must be terminated by an item with pid of zero.
+ */
+ RGXFWIF_PID_FILTER_ITEM asItems[RGXFWIF_PID_FILTER_MAX_NUM_PIDS];
+} RGXFW_ALIGN RGXFWIF_PID_FILTER;
+#endif
+
+#if defined(SUPPORT_SECURITY_VALIDATION)
+#define RGXFWIF_SECURE_ACCESS_TEST_READ_WRITE_FW_DATA (0x1U << 0)
+#define RGXFWIF_SECURE_ACCESS_TEST_READ_WRITE_FW_CODE (0x1U << 1)
+#define RGXFWIF_SECURE_ACCESS_TEST_RUN_FROM_NONSECURE (0x1U << 2)
+#define RGXFWIF_SECURE_ACCESS_TEST_RUN_FROM_SECURE (0x1U << 3)
+#endif
+
+typedef enum
+{
+ RGXFWIF_USRM_DM_VDM = 0,
+ RGXFWIF_USRM_DM_DDM = 1,
+ RGXFWIF_USRM_DM_CDM = 2,
+ RGXFWIF_USRM_DM_PDM = 3,
+ RGXFWIF_USRM_DM_TDM = 4,
+ RGXFWIF_USRM_DM_LAST
+} RGXFWIF_USRM_DM;
+
+typedef enum
+{
+ RGXFWIF_UVBRM_DM_VDM = 0,
+ RGXFWIF_UVBRM_DM_DDM = 1,
+ RGXFWIF_UVBRM_DM_LAST
+} RGXFWIF_UVBRM_DM;
+
+typedef enum
+{
+ RGXFWIF_TPU_DM_PDM = 0,
+ RGXFWIF_TPU_DM_VDM = 1,
+ RGXFWIF_TPU_DM_CDM = 2,
+ RGXFWIF_TPU_DM_TDM = 3,
+ RGXFWIF_TPU_DM_LAST
+} RGXFWIF_TPU_DM;
+
+typedef enum
+{
+ RGXFWIF_GPIO_VAL_OFF = 0, /*!< No GPIO validation */
+ RGXFWIF_GPIO_VAL_GENERAL = 1, /*!< Simple test case that
+ initiates by sending data via the
+ GPIO and then sends back any data
+ received over the GPIO */
+ RGXFWIF_GPIO_VAL_AP = 2, /*!< More complex test case that writes
+ and reads data across the entire
+ GPIO AP address range.*/
+#if defined(SUPPORT_STRIP_RENDERING)
+ RGXFWIF_GPIO_VAL_SR_BASIC = 3, /*!< Strip Rendering AP based basic test.*/
+ RGXFWIF_GPIO_VAL_SR_COMPLEX = 4, /*!< Strip Rendering AP based complex test.*/
+#endif
+ RGXFWIF_GPIO_VAL_TESTBENCH = 5, /*!< Validates the GPIO Testbench. */
+ RGXFWIF_GPIO_VAL_LOOPBACK = 6, /*!< Send and then receive each byte
+ in the range 0-255. */
+ RGXFWIF_GPIO_VAL_LOOPBACK_LITE = 7, /*!< Send and then receive each power-of-2
+ byte in the range 0-255. */
+ RGXFWIF_GPIO_VAL_LAST
+} RGXFWIF_GPIO_VAL_MODE;
+
+typedef enum
+{
+ FW_PERF_CONF_NONE = 0,
+ FW_PERF_CONF_ICACHE = 1,
+ FW_PERF_CONF_DCACHE = 2,
+ FW_PERF_CONF_POLLS = 3,
+ FW_PERF_CONF_CUSTOM_TIMER = 4,
+ FW_PERF_CONF_JTLB_INSTR = 5,
+ FW_PERF_CONF_INSTRUCTIONS = 6
+} FW_PERF_CONF;
+
+typedef enum
+{
+ FW_BOOT_STAGE_TLB_INIT_FAILURE = -2,
+ FW_BOOT_STAGE_NOT_AVAILABLE = -1,
+ FW_BOOT_NOT_STARTED = 0,
+ FW_BOOT_BLDR_STARTED = 1,
+ FW_BOOT_CACHE_DONE,
+ FW_BOOT_TLB_DONE,
+ FW_BOOT_MAIN_STARTED,
+ FW_BOOT_ALIGNCHECKS_DONE,
+ FW_BOOT_INIT_DONE,
+} FW_BOOT_STAGE;
+
+/*!
+ * @AddToGroup KCCBTypes
+ * @{
+ * @Name Kernel CCB return slot responses
+ * @{
+ * Usage of bit-fields instead of bare integers
+ * allows FW to possibly pack-in several responses for each single kCCB command.
+ */
+
+#define RGXFWIF_KCCB_RTN_SLOT_CMD_EXECUTED (1U << 0) /*!< Command executed (return status from FW) */
+#define RGXFWIF_KCCB_RTN_SLOT_CLEANUP_BUSY (1U << 1) /*!< A cleanup was requested but resource busy */
+#define RGXFWIF_KCCB_RTN_SLOT_POLL_FAILURE (1U << 2) /*!< Poll failed in FW for a HW operation to complete */
+
+#define RGXFWIF_KCCB_RTN_SLOT_NO_RESPONSE 0x0U /*!< Reset value of a kCCB return slot (set by host) */
+/*!
+ * @} End of Name Kernel CCB return slot responses
+ * @} End of AddToGroup KCCBTypes
+ */
+
+typedef struct
+{
+ /* Fw-Os connection states */
+ volatile RGXFWIF_CONNECTION_FW_STATE eConnectionFwState;
+ volatile RGXFWIF_CONNECTION_OS_STATE eConnectionOsState;
+ volatile IMG_UINT32 ui32AliveFwToken;
+ volatile IMG_UINT32 ui32AliveOsToken;
+} UNCACHED_ALIGN RGXFWIF_CONNECTION_CTL;
+
+/*! @Brief Firmware OS Initialization data \ref RGXFWIF_OSINIT
+ * allocated by services and used by the Firmware on boot
+ **/
+typedef struct
+{
+ /* Kernel CCB */
+ PRGXFWIF_CCB_CTL psKernelCCBCtl; /*!< Kernel CCB Control */
+ PRGXFWIF_CCB psKernelCCB; /*!< Kernel CCB */
+ PRGXFWIF_CCB_RTN_SLOTS psKernelCCBRtnSlots; /*!< Kernel CCB return slots */
+
+ /* Firmware CCB */
+ PRGXFWIF_CCB_CTL psFirmwareCCBCtl; /*!< Firmware CCB control */
+ PRGXFWIF_CCB psFirmwareCCB; /*!< Firmware CCB */
+
+ /* Workload Estimation Firmware CCB */
+ PRGXFWIF_CCB_CTL psWorkEstFirmwareCCBCtl; /*!< Workload estimation control */
+ PRGXFWIF_CCB psWorkEstFirmwareCCB; /*!< Workload estimation buffer */
+
+ PRGXFWIF_HWRINFOBUF sRGXFWIfHWRInfoBufCtl; /*!< HWRecoveryInfo control */
+
+ IMG_UINT32 ui32HWRDebugDumpLimit; /*!< Firmware debug dump maximum limit */
+
+ PRGXFWIF_OSDATA sFwOsData; /*!< Firmware per-os shared data */
+
+ RGXFWIF_COMPCHECKS sRGXCompChecks; /*!< Compatibility checks to be populated by the Firmware */
+
+} UNCACHED_ALIGN RGXFWIF_OSINIT;
+
+/*! @Brief Firmware System Initialization data \ref RGXFWIF_SYSINIT
+ * allocated by services and used by the Firmware on boot
+ **/
+typedef struct
+{
+ IMG_DEV_PHYADDR RGXFW_ALIGN sFaultPhysAddr; /*!< Fault read address */
+
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sPDSExecBase; /*!< PDS execution base */
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sUSCExecBase; /*!< USC execution base */
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sFBCDCStateTableBase; /*!< FBCDC bindless texture state table base */
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sFBCDCLargeStateTableBase;
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sTextureHeapBase; /*!< Texture state base */
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sPDSIndirectHeapBase; /* Pixel Indirect State base */
+
+ IMG_UINT64 RGXFW_ALIGN ui64HWPerfFilter; /*! Event filter for Firmware events */
+
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sSLC3FenceDevVAddr; /*!< Address to use as a fence when issuing SLC3_CFI */
+
+ IMG_UINT64 RGXFW_ALIGN aui64UVBRMNumRegions[RGXFWIF_UVBRM_DM_LAST];
+ IMG_UINT32 RGXFW_ALIGN aui32TPUTrilinearFracMask[RGXFWIF_TPU_DM_LAST];
+ IMG_UINT32 RGXFW_ALIGN aui32USRMNumRegions[RGXFWIF_USRM_DM_LAST];
+
+ IMG_UINT32 ui32FilterFlags;
+
+ RGXFWIF_SIGBUF_CTL asSigBufCtl[RGXFWIF_DM_MAX]; /*!< Signature and Checksum Buffers for DMs */
+#if defined(SUPPORT_VALIDATION)
+ RGXFWIF_SIGBUF_CTL asValidationSigBufCtl[RGXFWIF_DM_MAX];
+ IMG_UINT64 RGXFW_ALIGN ui64RCEDisableMask;
+#endif
+
+ PRGXFWIF_RUNTIME_CFG sRuntimeCfg; /*!< Firmware Runtime configuration */
+
+ PRGXFWIF_TRACEBUF sTraceBufCtl; /*!< Firmware Trace buffer control */
+ PRGXFWIF_SYSDATA sFwSysData; /*!< Firmware System shared data */
+#if defined(SUPPORT_TBI_INTERFACE)
+ PRGXFWIF_TBIBUF sTBIBuf; /*!< Tbi log buffer */
+#endif
+
+ PRGXFWIF_GPU_UTIL_FWCB sGpuUtilFWCbCtl; /*!< GPU utilization buffer */
+ PRGXFWIF_REG_CFG sRegCfg; /*!< Firmware register user configuration */
+ PRGXFWIF_HWPERF_CTL sHWPerfCtl; /*!< HWPerf counter block configuration.*/
+
+#if defined(SUPPORT_FIRMWARE_GCOV)
+ RGXFWIF_FIRMWARE_GCOV_CTL sFirmwareGcovCtl; /*!< Firmware gcov buffer control */
+#endif
+
+ RGXFWIF_DEV_VIRTADDR sAlignChecks; /*!< Array holding Server structures alignment data */
+
+ IMG_UINT32 ui32InitialCoreClockSpeed; /*!< Core clock speed at FW boot time */
+
+ IMG_UINT32 ui32InitialActivePMLatencyms; /*!< APM latency in ms before signalling IDLE to the host */
+
+ IMG_BOOL bFirmwareStarted; /*!< Flag to be set by the Firmware after successful start */
+
+ IMG_UINT32 ui32MarkerVal; /*!< Host/FW Trace synchronisation Partition Marker */
+
+ IMG_UINT32 ui32FirmwareStartedTimeStamp; /*!< Firmware initialization complete time */
+
+ IMG_UINT32 ui32JonesDisableMask;
+
+ RGXFWIF_DMA_ADDR sCorememDataStore; /*!< Firmware coremem data */
+
+ FW_PERF_CONF eFirmwarePerf; /*!< Firmware performance counter config */
+
+#if defined(SUPPORT_PDVFS)
+ RGXFWIF_PDVFS_OPP RGXFW_ALIGN sPDVFSOPPInfo;
+
+ /**
+ * FW Pointer to memory containing core clock rate in Hz.
+ * Firmware (PDVFS) updates the memory when running on non primary FW thread
+ * to communicate to host driver.
+ */
+ PRGXFWIF_CORE_CLK_RATE RGXFW_ALIGN sCoreClockRate;
+#endif
+
+#if defined(PDUMP)
+ RGXFWIF_PID_FILTER sPIDFilter;
+#endif
+
+ RGXFWIF_GPIO_VAL_MODE eGPIOValidationMode;
+
+ RGX_HWPERF_BVNC sBvncKmFeatureFlags; /*!< Used in HWPerf for decoding BVNC Features*/
+
+#if defined(SUPPORT_SECURITY_VALIDATION)
+ IMG_UINT32 ui32SecurityTestFlags;
+ RGXFWIF_DEV_VIRTADDR pbSecureBuffer;
+ RGXFWIF_DEV_VIRTADDR pbNonSecureBuffer;
+#endif
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+ /*
+ * Used when validation is enabled to allow the host to check
+ * that MTS sent the correct sideband in response to a kick
+ * from a given OSes schedule register.
+ * Testing is enabled if RGXFWIF_KICK_TEST_ENABLED_BIT is set
+ *
+ * Set by the host to:
+ * (osid << RGXFWIF_KICK_TEST_OSID_SHIFT) | RGXFWIF_KICK_TEST_ENABLED_BIT
+ * reset to 0 by FW when kicked by the given OSid
+ */
+ IMG_UINT32 ui32OSKickTest;
+#endif
+
+} UNCACHED_ALIGN RGXFWIF_SYSINIT;
+
+static_assert(sizeof(RGXFWIF_SYSINIT) <= 952,
+ "Size of structure RGXFWIF_SYSINIT exceeds maximum expected size.");
+
+#if defined(SUPPORT_GPUVIRT_VALIDATION)
+#define RGXFWIF_KICK_TEST_ENABLED_BIT 0x1
+#define RGXFWIF_KICK_TEST_OSID_SHIFT 0x1
+#endif
+
+/*!
+ *****************************************************************************
+ * Timer correlation shared data and defines
+ *****************************************************************************/
+
+typedef struct
+{
+ IMG_UINT64 RGXFW_ALIGN ui64OSTimeStamp;
+ IMG_UINT64 RGXFW_ALIGN ui64OSMonoTimeStamp;
+ IMG_UINT64 RGXFW_ALIGN ui64CRTimeStamp;
+
+ /* Utility variable used to convert CR timer deltas to OS timer deltas (nS),
+ * where the deltas are relative to the timestamps above:
+ * deltaOS = (deltaCR * K) >> decimal_shift, see full explanation below */
+ IMG_UINT64 RGXFW_ALIGN ui64CRDeltaToOSDeltaKNs;
+
+ IMG_UINT32 ui32CoreClockSpeed;
+ IMG_UINT32 ui32Reserved;
+} UNCACHED_ALIGN RGXFWIF_TIME_CORR;
+
+
+/* The following macros are used to help converting FW timestamps to the Host
+ * time domain. On the FW the RGX_CR_TIMER counter is used to keep track of
+ * time; it increments by 1 every 256 GPU clock ticks, so the general
+ * formula to perform the conversion is:
+ *
+ * [ GPU clock speed in Hz, if (scale == 10^9) then deltaOS is in nS,
+ * otherwise if (scale == 10^6) then deltaOS is in uS ]
+ *
+ * deltaCR * 256 256 * scale
+ * deltaOS = --------------- * scale = deltaCR * K [ K = --------------- ]
+ * GPUclockspeed GPUclockspeed
+ *
+ * The actual K is multiplied by 2^20 (and deltaCR * K is divided by 2^20)
+ * to get some better accuracy and to avoid returning 0 in the integer
+ * division 256000000/GPUfreq if GPUfreq is greater than 256MHz.
+ * This is the same as keeping K as a decimal number.
+ *
+ * The maximum deltaOS is slightly more than 5hrs for all GPU frequencies
+ * (deltaCR * K is more or less a constant), and it's relative to the base
+ * OS timestamp sampled as a part of the timer correlation data.
+ * This base is refreshed on GPU power-on, DVFS transition and periodic
+ * frequency calibration (executed every few seconds if the FW is doing
+ * some work), so as long as the GPU is doing something and one of these
+ * events is triggered then deltaCR * K will not overflow and deltaOS will be
+ * correct.
+ */
+
+#define RGXFWIF_CRDELTA_TO_OSDELTA_ACCURACY_SHIFT (20)
+
+#define RGXFWIF_GET_DELTA_OSTIME_NS(deltaCR, K) \
+ (((deltaCR) * (K)) >> RGXFWIF_CRDELTA_TO_OSDELTA_ACCURACY_SHIFT)
+
+
+/*!
+ ******************************************************************************
+ * GPU Utilisation
+ *****************************************************************************/
+
+/* See rgx_common.h for a list of GPU states */
+#define RGXFWIF_GPU_UTIL_TIME_MASK (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF) & ~RGXFWIF_GPU_UTIL_STATE_MASK)
+
+#define RGXFWIF_GPU_UTIL_GET_TIME(word) ((word) & RGXFWIF_GPU_UTIL_TIME_MASK)
+#define RGXFWIF_GPU_UTIL_GET_STATE(word) ((word) & RGXFWIF_GPU_UTIL_STATE_MASK)
+
+/* The OS timestamps computed by the FW are approximations of the real time,
+ * which means they could be slightly behind or ahead the real timer on the Host.
+ * In some cases we can perform subtractions between FW approximated
+ * timestamps and real OS timestamps, so we need a form of protection against
+ * negative results if for instance the FW one is a bit ahead of time.
+ */
+#define RGXFWIF_GPU_UTIL_GET_PERIOD(newtime,oldtime) \
+ (((newtime) > (oldtime)) ? ((newtime) - (oldtime)) : 0U)
+
+#define RGXFWIF_GPU_UTIL_MAKE_WORD(time,state) \
+ (RGXFWIF_GPU_UTIL_GET_TIME(time) | RGXFWIF_GPU_UTIL_GET_STATE(state))
+
+
+/* The timer correlation array must be big enough to ensure old entries won't be
+ * overwritten before all the HWPerf events linked to those entries are processed
+ * by the MISR. The update frequency of this array depends on how fast the system
+ * can change state (basically how small the APM latency is) and perform DVFS transitions.
+ *
+ * The minimum size is 2 (not 1) to avoid race conditions between the FW reading
+ * an entry while the Host is updating it. With 2 entries in the worst case the FW
+ * will read old data, which is still quite ok if the Host is updating the timer
+ * correlation at that time.
+ */
+#define RGXFWIF_TIME_CORR_ARRAY_SIZE 256U
+#define RGXFWIF_TIME_CORR_CURR_INDEX(seqcount) ((seqcount) % RGXFWIF_TIME_CORR_ARRAY_SIZE)
+
+/* Make sure the timer correlation array size is a power of 2 */
+static_assert((RGXFWIF_TIME_CORR_ARRAY_SIZE & (RGXFWIF_TIME_CORR_ARRAY_SIZE - 1U)) == 0U,
+ "RGXFWIF_TIME_CORR_ARRAY_SIZE must be a power of two");
+
+typedef struct
+{
+ RGXFWIF_TIME_CORR sTimeCorr[RGXFWIF_TIME_CORR_ARRAY_SIZE];
+ IMG_UINT32 ui32TimeCorrSeqCount;
+
+ /* Compatibility and other flags */
+ IMG_UINT32 ui32GpuUtilFlags;
+
+ /* Last GPU state + OS time of the last state update */
+ IMG_UINT64 RGXFW_ALIGN ui64LastWord;
+
+ /* Counters for the amount of time the GPU was active/idle/blocked */
+ IMG_UINT64 RGXFW_ALIGN aui64StatsCounters[RGXFWIF_GPU_UTIL_STATE_NUM];
+} UNCACHED_ALIGN RGXFWIF_GPU_UTIL_FWCB;
+
+typedef struct
+{
+ IMG_UINT32 ui32RenderTargetIndex; //Render number
+ IMG_UINT32 ui32CurrentRenderTarget; //index in RTA
+ IMG_UINT32 ui32ActiveRenderTargets; //total active RTs
+ RGXFWIF_DEV_VIRTADDR sValidRenderTargets; //Array of valid RT indices
+ RGXFWIF_DEV_VIRTADDR sRTANumPartialRenders; //Array of number of occurred partial renders per render target
+ IMG_UINT32 ui32MaxRTs; //Number of render targets in the array
+ IMG_UINT32 ui32RTACtlFlags; /* Compatibility and other flags */
+} UNCACHED_ALIGN RGXFWIF_RTA_CTL;
+
+/*! @Brief Firmware Freelist holding usage state of the Parameter Buffers */
+typedef struct
+{
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sFreeListBaseDevVAddr; /*!< Free list device base address */
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sFreeListStateDevVAddr; /*!< Free list state buffer */
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sFreeListLastGrowDevVAddr; /*!< Free list base address at last grow */
+
+#if defined(PM_INTERACTIVE_MODE)
+ IMG_UINT64 RGXFW_ALIGN ui64CurrentDevVAddr;
+ IMG_UINT32 ui32CurrentStackTop;
+#endif
+
+ IMG_UINT32 ui32MaxPages;
+ IMG_UINT32 ui32GrowPages;
+ IMG_UINT32 ui32CurrentPages; /* HW pages */
+#if defined(PM_INTERACTIVE_MODE)
+ IMG_UINT32 ui32AllocatedPageCount;
+ IMG_UINT32 ui32AllocatedMMUPageCount;
+#endif
+#if defined(SUPPORT_SHADOW_FREELISTS)
+ IMG_UINT32 ui32HWRCounter;
+ PRGXFWIF_FWMEMCONTEXT psFWMemContext;
+#endif
+ IMG_UINT32 ui32FreeListID;
+ IMG_BOOL bGrowPending;
+ IMG_UINT32 ui32ReadyPages; /* Pages that should be used only when OOM is reached */
+ IMG_UINT32 ui32FreelistFlags; /* Compatibility and other flags */
+
+ IMG_BOOL bUpdatePending;
+ IMG_UINT32 ui32UpdateNewPages;
+ IMG_UINT32 ui32UpdateNewReadyPages;
+} UNCACHED_ALIGN RGXFWIF_FREELIST;
+
+
+#if defined(SUPPORT_SW_TRP)
+#define SW_TRP_SIGNATURE_FIRST_KICK 0U
+#define SW_TRP_SIGNATURE_SECOND_KICK 1U
+#define SW_TRP_SIGNATURE_COUNT 2U
+#define SW_TRP_GEOMETRY_SIGNATURE_SIZE 8U
+#define SW_TRP_FRAGMENT_SIGNATURE_SIZE 8U
+/* Space for tile usage bitmap, one bit per tile on screen */
+#define RGX_FEATURE_TILE_SIZE_X (32U)
+#define RGX_FEATURE_TILE_SIZE_Y (32U)
+#define SW_TRP_TILE_USED_SIZE ((ROGUE_RENDERSIZE_MAXX / RGX_FEATURE_TILE_SIZE_X + ROGUE_RENDERSIZE_MAXY / RGX_FEATURE_TILE_SIZE_Y) / (8U * sizeof(IMG_UINT32)))
+#endif
+
+/*!
+ ******************************************************************************
+ * Parameter Management (PM) control data for RGX
+ *****************************************************************************/
+typedef enum
+{
+ RGXFW_SPM_STATE_NONE = 0,
+ RGXFW_SPM_STATE_PR_BLOCKED,
+ RGXFW_SPM_STATE_WAIT_FOR_GROW,
+ RGXFW_SPM_STATE_WAIT_FOR_HW,
+ RGXFW_SPM_STATE_PR_RUNNING,
+ RGXFW_SPM_STATE_PR_AVOIDED,
+ RGXFW_SPM_STATE_PR_EXECUTED,
+ RGXFW_SPM_STATE_PR_FORCEFREE,
+} RGXFW_SPM_STATE;
+
+/*!
+ ******************************************************************************
+ * @Brief RGX firmware SPM Control Data:
+ * This structure holds all the internal SPM control Data of the firmware.
+ *****************************************************************************/
+typedef struct
+{
+ RGXFW_SPM_STATE eSPMState; /*!< Current state of TA OOM event */
+ RGXFWIF_UFO sPartialRenderTA3DFence; /*!< TA/3D fence object holding the value to let through the 3D partial command */
+#if defined(RGX_FIRMWARE)
+ RGXFWIF_FWCOMMONCONTEXT *ps3dContext; /*!< Pointer to the 3D Context holding the partial render */
+ RGXFWIF_PRBUFFER *apsPRBuffer[RGXFWIF_PRBUFFER_MAXSUPPORTED]; /*!< Array of pointers to PR Buffers which may be used if partial render is needed */
+#else
+ RGXFWIF_DEV_VIRTADDR ps3dContext; /*!< Pointer to the 3D Context holding the partial render */
+ RGXFWIF_DEV_VIRTADDR apsPRBuffer[RGXFWIF_PRBUFFER_MAXSUPPORTED]; /*!< Array of pointers to PR Buffers which may be used if partial render is needed */
+#endif
+ IMG_UINT32 ui32CmdOffset; /*!< CCCB offset of the command holding the partial render */
+ bool b3DMemFreeDetected; /*!< Indicates if a 3D Memory Free has been detected, which resolves OOM */
+#if defined(SUPPORT_AGP)
+ IMG_UINT32 ui32OOMCoreMask; /*!< Mask of all the cores that are OOM */
+ RGXFWIF_DM eCurrentDM; /*!< Current DM that is in SPM */
+#endif
+} RGXFW_ALIGN_DCACHEL RGXFW_SPMCTL;
+
+static_assert(sizeof(RGXFW_SPMCTL) <= 64,
+ "Size of structure RGXFW_SPMCTL exceeds maximum expected size.");
+
+/*!
+ ******************************************************************************
+ * HWRTData
+ *****************************************************************************/
+
+/* HWRTData flags */
+/* Deprecated flags 1:0 */
+#define HWRTDATA_HAS_LAST_TA (1U << 2)
+#define HWRTDATA_PARTIAL_RENDERED (1U << 3)
+#define HWRTDATA_KILLED (1U << 4)
+#define HWRTDATA_KILL_AFTER_TARESTART (1U << 5)
+#if defined(SUPPORT_AGP)
+#define HWRTDATA_USE_SECONDARY_GLOBAL_PB (1U << 6)
+#define HWRTDATA_GEOM_NEEDS_RESUME (1U << 7)
+#endif
+
+typedef enum
+{
+ RGXFWIF_RTDATA_STATE_NONE = 0,
+ RGXFWIF_RTDATA_STATE_KICKTA,
+ RGXFWIF_RTDATA_STATE_KICKTAFIRST,
+ RGXFWIF_RTDATA_STATE_TAFINISHED,
+ RGXFWIF_RTDATA_STATE_KICK3D,
+ RGXFWIF_RTDATA_STATE_3DFINISHED,
+ RGXFWIF_RTDATA_STATE_3DCONTEXTSTORED,
+ RGXFWIF_RTDATA_STATE_TAOUTOFMEM,
+ RGXFWIF_RTDATA_STATE_PARTIALRENDERFINISHED,
+ /* In case of HWR, we can't set the RTDATA state to NONE,
+ * as this will cause any TA to become a first TA.
+ * To ensure all related TA's are skipped, we use the HWR state */
+ RGXFWIF_RTDATA_STATE_HWR,
+ RGXFWIF_RTDATA_STATE_UNKNOWN = 0x7FFFFFFFU
+} RGXFWIF_RTDATA_STATE;
+
+typedef struct
+{
+ IMG_UINT32 ui32ScreenPixelMax;
+ IMG_UINT64 RGXFW_ALIGN ui64PPPMultiSampleCtl;
+ IMG_UINT32 ui32TEStride;
+ IMG_UINT32 ui32TPCSize;
+ IMG_UINT32 ui32TEScreen;
+ IMG_UINT32 ui32TEAA;
+ IMG_UINT32 ui32TEMTILE1;
+ IMG_UINT32 ui32TEMTILE2;
+ IMG_UINT32 ui32RgnStride;
+ IMG_UINT32 ui32ISPMergeLowerX;
+ IMG_UINT32 ui32ISPMergeLowerY;
+ IMG_UINT32 ui32ISPMergeUpperX;
+ IMG_UINT32 ui32ISPMergeUpperY;
+ IMG_UINT32 ui32ISPMergeScaleX;
+ IMG_UINT32 ui32ISPMergeScaleY;
+} UNCACHED_ALIGN RGXFWIF_HWRTDATA_COMMON;
+
+/*! @Brief Firmware Render Target data i.e. HWRTDATA used to hold the PM context */
+typedef struct
+{
+ IMG_UINT64 RGXFW_ALIGN ui64VCECatBase[4];
+ IMG_UINT64 RGXFW_ALIGN ui64VCELastCatBase[4];
+ IMG_UINT64 RGXFW_ALIGN ui64TECatBase[4];
+ IMG_UINT64 RGXFW_ALIGN ui64TELastCatBase[4];
+ IMG_UINT64 RGXFW_ALIGN ui64AlistCatBase;
+ IMG_UINT64 RGXFW_ALIGN ui64AlistLastCatBase;
+
+#if defined(PM_INTERACTIVE_MODE)
+ IMG_DEV_VIRTADDR RGXFW_ALIGN psVHeapTableDevVAddr;
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sPMMListDevVAddr;
+#else
+ /* Series8 PM State buffers */
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sPMRenderStateDevVAddr;
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sPMSecureRenderStateDevVAddr;
+#endif
+
+ PRGXFWIF_FREELIST RGXFW_ALIGN apsFreeLists[RGXFW_MAX_FREELISTS];
+ IMG_UINT32 aui32FreeListHWRSnapshot[RGXFW_MAX_FREELISTS];
+ IMG_BOOL bRenderStateNeedsReset;
+
+ RGXFWIF_DEV_VIRTADDR sHWRTDataCommonFwAddr;
+
+ IMG_UINT32 ui32HWRTDataFlags;
+ RGXFWIF_RTDATA_STATE eState;
+
+ RGXFWIF_CLEANUP_CTL sCleanupState;
+
+ RGXFWIF_RTA_CTL sRTACtl;
+
+ IMG_DEV_VIRTADDR RGXFW_ALIGN sTailPtrsDevVAddr;
+#if defined(RGX_FIRMWARE)
+ struct RGXFWIF_FWCOMMONCONTEXT_* psOwnerGeom;
+#else
+ RGXFWIF_DEV_VIRTADDR pui32OwnerGeomNotUsedByHost;
+#endif
+
+#if defined(PM_INTERACTIVE_MODE)
+ IMG_UINT64 RGXFW_ALIGN ui64PMAListStackPointer;
+ IMG_UINT32 ui32PMMListStackPointer;
+#endif
+#if defined(SUPPORT_SW_TRP)
+ /* SW-TRP state and signature data
+ *
+ * Stored state is used to kick the same geometry or 3D twice,
+ * State is stored before first kick and restored before second to rerun the same data.
+ * Signatures from both kicks are stored and compared */
+ IMG_UINT32 aaui32GeometrySignature[SW_TRP_SIGNATURE_COUNT][SW_TRP_GEOMETRY_SIGNATURE_SIZE];
+ IMG_UINT32 aaui32FragmentSignature[SW_TRP_SIGNATURE_COUNT][SW_TRP_FRAGMENT_SIGNATURE_SIZE];
+ IMG_UINT32 ui32KickFlagsCopy;
+ IMG_UINT32 ui32SW_TRPState;
+ IMG_UINT32 aui32TileUsed[SW_TRP_TILE_USED_SIZE];
+ RGXFW_SPMCTL sSPMCtlCopy;
+#endif
+#if defined(SUPPORT_TRP)
+ IMG_UINT32 ui32KickFlagsCopy;
+ IMG_UINT32 ui32TRPState;
+ RGXFWIF_TRP_CHECKSUM_3D aui64TRPChecksums3D;
+ RGXFWIF_TRP_CHECKSUM_GEOM aui64TRPChecksumsGeom;
+#endif
+} UNCACHED_ALIGN RGXFWIF_HWRTDATA;
+
+/* Sync_checkpoint firmware object.
+ * This is the FW-addressable structure use to hold the sync checkpoint's
+ * state and other information which needs to be accessed by the firmware.
+ */
+typedef struct
+{
+ IMG_UINT32 ui32State; /*!< Holds the current state of the sync checkpoint */
+ IMG_UINT32 ui32FwRefCount; /*!< Holds the FW reference count (num of fences/updates processed) */
+} SYNC_CHECKPOINT_FW_OBJ;
+
+/* Bit mask Firmware can use to test if a checkpoint has signalled or errored */
+#define SYNC_CHECKPOINT_SIGNALLED_MASK (0x1 << 0)
+
+#endif /* RGX_FWIF_KM_H */
+
+/******************************************************************************
+ End of file (rgx_fwif_km.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/volcanic/rgx_fwif_shared.h b/drivers/gpu/drm/img-rogue/include/volcanic/rgx_fwif_shared.h
new file mode 100644
index 000000000..570ccdd68
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/volcanic/rgx_fwif_shared.h
@@ -0,0 +1,356 @@
+/*************************************************************************/ /*!
+@File
+@Title RGX firmware interface structures
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description RGX firmware interface structures shared by both host client
+ and host server
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(RGX_FWIF_SHARED_H)
+#define RGX_FWIF_SHARED_H
+
+#include "img_types.h"
+#include "img_defs.h"
+#include "rgx_common.h"
+#include "powervr/mem_types.h"
+
+/* Indicates the number of RTDATAs per RTDATASET */
+#if defined(SUPPORT_AGP)
+#define RGXMKIF_NUM_RTDATAS 4U
+#define RGXMKIF_NUM_GEOMDATAS 4U
+#define RGXMKIF_NUM_RTDATA_FREELISTS 12U /* RGXMKIF_NUM_RTDATAS * RGXFW_MAX_FREELISTS */
+#define RGX_NUM_GEOM_CORES (2U)
+#else
+#define RGXMKIF_NUM_RTDATAS 2U
+#define RGXMKIF_NUM_GEOMDATAS 1U
+#define RGXMKIF_NUM_RTDATA_FREELISTS 2U /* RGXMKIF_NUM_RTDATAS * RGXFW_MAX_FREELISTS */
+#define RGX_NUM_GEOM_CORES (1U)
+#endif
+
+/* Maximum number of UFOs in a CCB command.
+ * The number is based on having 32 sync prims (as originally), plus 32 sync
+ * checkpoints.
+ * Once the use of sync prims is no longer supported, we will retain
+ * the same total (64) as the number of sync checkpoints which may be
+ * supporting a fence is not visible to the client driver and has to
+ * allow for the number of different timelines involved in fence merges.
+ */
+#define RGXFWIF_CCB_CMD_MAX_UFOS (32U+32U)
+
+/*
+ * This is a generic limit imposed on any DM (TA,3D,CDM,TDM,2D,TRANSFER)
+ * command passed through the bridge.
+ * Just across the bridge in the server, any incoming kick command size is
+ * checked against this maximum limit.
+ * In case the incoming command size is larger than the specified limit,
+ * the bridge call is retired with error.
+ */
+#define RGXFWIF_DM_INDEPENDENT_KICK_CMD_SIZE (1024U)
+
+typedef struct RGXFWIF_DEV_VIRTADDR_
+{
+ IMG_UINT32 ui32Addr;
+} RGXFWIF_DEV_VIRTADDR;
+
+typedef struct
+{
+ IMG_DEV_VIRTADDR RGXFW_ALIGN psDevVirtAddr;
+ RGXFWIF_DEV_VIRTADDR pbyFWAddr;
+} UNCACHED_ALIGN RGXFWIF_DMA_ADDR;
+
+typedef IMG_UINT8 RGXFWIF_CCCB;
+
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_UFO_ADDR;
+typedef RGXFWIF_DEV_VIRTADDR PRGXFWIF_CLEANUP_CTL;
+
+
+/*!
+ * @InGroup ClientCCBTypes
+ * @Brief Command data for fence & update types Client CCB commands.
+ */
+typedef struct
+{
+ PRGXFWIF_UFO_ADDR puiAddrUFO; /*!< Address to be checked/updated */
+ IMG_UINT32 ui32Value; /*!< Value to check-against/update-to */
+} RGXFWIF_UFO;
+
+typedef struct
+{
+ IMG_UINT32 ui32SubmittedCommands; /*!< Number of commands received by the FW */
+ IMG_UINT32 ui32ExecutedCommands; /*!< Number of commands executed by the FW */
+} UNCACHED_ALIGN RGXFWIF_CLEANUP_CTL;
+
+#define RGXFWIF_PRBUFFER_START IMG_UINT32_C(0)
+#define RGXFWIF_PRBUFFER_ZSBUFFER IMG_UINT32_C(0)
+#define RGXFWIF_PRBUFFER_MSAABUFFER IMG_UINT32_C(1)
+#define RGXFWIF_PRBUFFER_MAXSUPPORTED IMG_UINT32_C(2)
+
+typedef IMG_UINT32 RGXFWIF_PRBUFFER_TYPE;
+
+typedef enum
+{
+ RGXFWIF_PRBUFFER_UNBACKED = 0,
+ RGXFWIF_PRBUFFER_BACKED,
+ RGXFWIF_PRBUFFER_BACKING_PENDING,
+ RGXFWIF_PRBUFFER_UNBACKING_PENDING,
+}RGXFWIF_PRBUFFER_STATE;
+
+typedef struct
+{
+ IMG_UINT32 ui32BufferID; /*!< Buffer ID*/
+ IMG_BOOL bOnDemand; /*!< Needs On-demand Z/S/MSAA Buffer allocation */
+ RGXFWIF_PRBUFFER_STATE eState; /*!< Z/S/MSAA -Buffer state */
+ RGXFWIF_CLEANUP_CTL sCleanupState; /*!< Cleanup state */
+ IMG_UINT32 ui32PRBufferFlags; /*!< Compatibility and other flags */
+} UNCACHED_ALIGN RGXFWIF_PRBUFFER;
+
+/*
+ * Used to share frame numbers across UM-KM-FW,
+ * frame number is set in UM,
+ * frame number is required in both KM for HTB and FW for FW trace.
+ *
+ * May be used to house Kick flags in the future.
+ */
+typedef struct
+{
+ IMG_UINT32 ui32FrameNum; /*!< associated frame number */
+} CMD_COMMON;
+
+/*
+ * TA and 3D commands require set of firmware addresses that are stored in the
+ * Kernel. Client has handle(s) to Kernel containers storing these addresses,
+ * instead of raw addresses. We have to patch/write these addresses in KM to
+ * prevent UM from controlling FW addresses directly.
+ * Typedefs for TA and 3D commands are shared between Client and Firmware (both
+ * single-BVNC). Kernel is implemented in a multi-BVNC manner, so it can't use
+ * TA|3D CMD type definitions directly. Therefore we have a SHARED block that
+ * is shared between UM-KM-FW across all BVNC configurations.
+ */
+typedef struct
+{
+ CMD_COMMON sCmn; /*!< Common command attributes */
+ RGXFWIF_DEV_VIRTADDR sHWRTData; /* RTData associated with this command,
+ this is used for context selection and for storing out HW-context,
+ when TA is switched out for continuing later */
+
+ RGXFWIF_DEV_VIRTADDR asPRBuffer[RGXFWIF_PRBUFFER_MAXSUPPORTED]; /* Supported PR Buffers like Z/S/MSAA Scratch */
+
+} CMDTA3D_SHARED;
+
+/*!
+ * Client Circular Command Buffer (CCCB) control structure.
+ * This is shared between the Server and the Firmware and holds byte offsets
+ * into the CCCB as well as the wrapping mask to aid wrap around. A given
+ * snapshot of this queue with Cmd 1 running on the GPU might be:
+ *
+ * Roff Doff Woff
+ * [..........|-1----------|=2===|=3===|=4===|~5~~~~|~6~~~~|~7~~~~|..........]
+ * < runnable commands >< !ready to run >
+ *
+ * Cmd 1 : Currently executing on the GPU data master.
+ * Cmd 2,3,4: Fence dependencies met, commands runnable.
+ * Cmd 5... : Fence dependency not met yet.
+ */
+typedef struct
+{
+ IMG_UINT32 ui32WriteOffset; /*!< Host write offset into CCB. This
+ * must be aligned to 16 bytes. */
+ IMG_UINT32 ui32ReadOffset; /*!< Firmware read offset into CCB.
+ Points to the command that is
+ runnable on GPU, if R!=W */
+ IMG_UINT32 ui32DepOffset; /*!< Firmware fence dependency offset.
+ Points to commands not ready, i.e.
+ fence dependencies are not met. */
+ IMG_UINT32 ui32WrapMask; /*!< Offset wrapping mask, total capacity
+ in bytes of the CCB-1 */
+#if defined(SUPPORT_AGP)
+ IMG_UINT32 ui32ReadOffset2;
+#endif
+} UNCACHED_ALIGN RGXFWIF_CCCB_CTL;
+
+
+typedef IMG_UINT32 RGXFW_FREELIST_TYPE;
+
+#define RGXFW_LOCAL_FREELIST IMG_UINT32_C(0)
+#define RGXFW_GLOBAL_FREELIST IMG_UINT32_C(1)
+#if defined(SUPPORT_AGP)
+#define RGXFW_GLOBAL2_FREELIST IMG_UINT32_C(2)
+#define RGXFW_MAX_FREELISTS (RGXFW_GLOBAL2_FREELIST + 1U)
+#else
+#define RGXFW_MAX_FREELISTS (RGXFW_GLOBAL_FREELIST + 1U)
+#endif
+#define RGXFW_MAX_HWFREELISTS (2U)
+
+/*!
+ * @Defgroup ContextSwitching Context switching data interface
+ * @Brief Types grouping data structures and defines used in realising the Context Switching (CSW) functionality
+ * @{
+ */
+
+/*!
+ * @Brief GEOM DM or TA register controls for context switch
+ */
+typedef struct
+{
+ IMG_UINT64 uTAReg_DCE_CONTEXT_STATE_BASE_ADDR;
+ IMG_UINT64 uTAReg_TA_CONTEXT_STATE_BASE_ADDR; /*!< The base address of the TA's context state buffer */
+
+ struct
+ {
+ IMG_UINT64 uTAReg_DCE_CONTEXT_STORE_TASK_VDM0;
+ IMG_UINT64 uTAReg_DCE_CONTEXT_STORE_TASK_VDM1;
+ IMG_UINT64 uTAReg_DCE_CONTEXT_STORE_TASK_VDM2;
+
+ IMG_UINT64 uTAReg_DCE_CONTEXT_STORE_TASK_DDM0;
+ IMG_UINT64 uTAReg_DCE_CONTEXT_STORE_TASK_DDM1;
+ IMG_UINT64 uTAReg_DCE_CONTEXT_STORE_TASK_DDM2;
+ IMG_UINT64 uTAReg_DCE_CONTEXT_STORE_TASK_XFB;
+
+ /* VDM resume state update controls */
+ IMG_UINT64 uTAReg_DCE_CONTEXT_RESUME_TASK_VDM0;
+ IMG_UINT64 uTAReg_DCE_CONTEXT_RESUME_TASK_VDM1;
+ IMG_UINT64 uTAReg_DCE_CONTEXT_RESUME_TASK_VDM2;
+
+
+ IMG_UINT64 uTAReg_DCE_CONTEXT_RESUME_TASK_DDM0;
+ IMG_UINT64 uTAReg_DCE_CONTEXT_RESUME_TASK_DDM1;
+ IMG_UINT64 uTAReg_DCE_CONTEXT_RESUME_TASK_DDM2;
+ IMG_UINT64 uTAReg_DCE_CONTEXT_RESUME_TASK_XFB;
+ } asTAState[2];
+
+} RGXFWIF_TAREGISTERS_CSWITCH;
+/*! @} End of Defgroup ContextSwitching */
+
+typedef struct
+{
+ IMG_UINT64 u3DReg_IPP_CONTEXT_ADDR;
+} RGXFWIF_3DREGISTERS_CSWITCH;
+
+typedef struct
+{
+ IMG_UINT64 uCDMReg_CDM_CONTEXT_PDS0;
+ IMG_UINT64 uCDMReg_CDM_CONTEXT_PDS1;
+ IMG_UINT64 uCDMReg_CDM_TERMINATE_PDS;
+ IMG_UINT64 uCDMReg_CDM_TERMINATE_PDS1;
+
+ /* CDM resume controls */
+ IMG_UINT64 uCDMReg_CDM_RESUME_PDS0;
+ IMG_UINT64 uCDMReg_CDM_CONTEXT_PDS0_B;
+ IMG_UINT64 uCDMReg_CDM_RESUME_PDS0_B;
+
+} RGXFWIF_CDM_REGISTERS_CSWITCH;
+
+static_assert((sizeof(RGXFWIF_CDM_REGISTERS_CSWITCH) % 8U) == 0U,
+ "the size of the structure must be multiple of 8");
+
+#define RGXFWIF_CDM_REGISTERS_CSWITCH_SIZE sizeof(RGXFWIF_CDM_REGISTERS_CSWITCH)
+
+/*!
+ * @InGroup ContextSwitching
+ * @Brief Render context static register controls for context switch
+ */
+typedef struct
+{
+ RGXFWIF_TAREGISTERS_CSWITCH RGXFW_ALIGN asCtxSwitch_GeomRegs[RGX_NUM_GEOM_CORES];
+ RGXFWIF_3DREGISTERS_CSWITCH RGXFW_ALIGN sCtxSwitch_3DRegs; /*!< 3D registers for ctx switch */
+} RGXFWIF_STATIC_RENDERCONTEXT_STATE;
+
+#define RGXFWIF_STATIC_RENDERCONTEXT_SIZE sizeof(RGXFWIF_STATIC_RENDERCONTEXT_STATE)
+
+typedef struct
+{
+ RGXFWIF_CDM_REGISTERS_CSWITCH RGXFW_ALIGN sCtxSwitch_Regs; /*!< CDM registers for ctx switch */
+} RGXFWIF_STATIC_COMPUTECONTEXT_STATE;
+
+#define RGXFWIF_STATIC_COMPUTECONTEXT_SIZE sizeof(RGXFWIF_STATIC_COMPUTECONTEXT_STATE)
+
+typedef struct
+{
+ IMG_UINT64 uRDMReg_RDM_CONTEXT_STATE_BASE_ADDR;
+} RGXFWIF_RDM_REGISTERS_CSWITCH;
+
+static_assert((sizeof(RGXFWIF_RDM_REGISTERS_CSWITCH) % 8U) == 0U,
+ "the size of the structure must be multiple of 8");
+
+#define RGXFWIF_RDM_REGISTERS_CSWITCH_SIZE sizeof(RGXFWIF_RDM_REGISTERS_CSWITCH)
+
+typedef struct
+{
+ RGXFWIF_RDM_REGISTERS_CSWITCH RGXFW_ALIGN sCtxSwitch_Regs; /*!< RDM registers for ctx switch */
+} RGXFWIF_STATIC_RAYCONTEXT_STATE;
+
+#define RGXFWIF_STATIC_RAYCONTEXT_SIZE sizeof(RGXFWIF_STATIC_RAYCONTEXT_STATE)
+
+/*!
+ @Brief Context reset reason. Last reset reason for a reset context.
+*/
+typedef enum
+{
+ RGX_CONTEXT_RESET_REASON_NONE = 0, /*!< No reset reason recorded */
+ RGX_CONTEXT_RESET_REASON_GUILTY_LOCKUP = 1, /*!< Caused a reset due to locking up */
+ RGX_CONTEXT_RESET_REASON_INNOCENT_LOCKUP = 2, /*!< Affected by another context locking up */
+ RGX_CONTEXT_RESET_REASON_GUILTY_OVERRUNING = 3, /*!< Overran the global deadline */
+ RGX_CONTEXT_RESET_REASON_INNOCENT_OVERRUNING = 4, /*!< Affected by another context overrunning */
+ RGX_CONTEXT_RESET_REASON_HARD_CONTEXT_SWITCH = 5, /*!< Forced reset to ensure scheduling requirements */
+ RGX_CONTEXT_RESET_REASON_WGP_CHECKSUM = 6, /*!< CDM Mission/safety checksum mismatch */
+ RGX_CONTEXT_RESET_REASON_TRP_CHECKSUM = 7, /*!< TRP checksum mismatch */
+ RGX_CONTEXT_RESET_REASON_GPU_ECC_OK = 8, /*!< GPU ECC error (corrected, OK) */
+ RGX_CONTEXT_RESET_REASON_GPU_ECC_HWR = 9, /*!< GPU ECC error (uncorrected, HWR) */
+ RGX_CONTEXT_RESET_REASON_FW_ECC_OK = 10, /*!< FW ECC error (corrected, OK) */
+ RGX_CONTEXT_RESET_REASON_FW_ECC_ERR = 11, /*!< FW ECC error (uncorrected, ERR) */
+ RGX_CONTEXT_RESET_REASON_FW_WATCHDOG = 12, /*!< FW Safety watchdog triggered */
+ RGX_CONTEXT_RESET_REASON_FW_PAGEFAULT = 13, /*!< FW page fault (no HWR) */
+ RGX_CONTEXT_RESET_REASON_FW_EXEC_ERR = 14, /*!< FW execution error (GPU reset requested) */
+ RGX_CONTEXT_RESET_REASON_HOST_WDG_FW_ERR = 15, /*!< Host watchdog detected FW error */
+ RGX_CONTEXT_GEOM_OOM_DISABLED = 16, /*!< Geometry DM OOM event is not allowed */
+} RGX_CONTEXT_RESET_REASON;
+
+/*!
+ @Brief Context reset data shared with the host
+*/
+typedef struct
+{
+ RGX_CONTEXT_RESET_REASON eResetReason; /*!< Reset reason */
+ IMG_UINT32 ui32ResetExtJobRef; /*!< External Job ID */
+} RGX_CONTEXT_RESET_REASON_DATA;
+#endif /* RGX_FWIF_SHARED_H */
+
+/******************************************************************************
+ End of file (rgx_fwif_shared.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/volcanic/rgx_heaps.h b/drivers/gpu/drm/img-rogue/include/volcanic/rgx_heaps.h
new file mode 100644
index 000000000..b35b4f392
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/volcanic/rgx_heaps.h
@@ -0,0 +1,65 @@
+/*************************************************************************/ /*!
+@File
+@Title RGX heap definitions
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(RGX_HEAPS_H)
+#define RGX_HEAPS_H
+
+/*
+ Identify heaps by their names
+*/
+#define RGX_GENERAL_SVM_HEAP_IDENT "General SVM" /*!< SVM (shared virtual memory) Heap Identifier */
+#define RGX_GENERAL_HEAP_IDENT "General" /*!< RGX General Heap Identifier */
+#define RGX_GENERAL_NON4K_HEAP_IDENT "General NON-4K" /*!< RGX General non-4K Heap Identifier */
+#define RGX_PDSCODEDATA_HEAP_IDENT "PDS Code and Data" /*!< RGX PDS Code/Data Heap Identifier */
+#define RGX_USCCODE_HEAP_IDENT "USC Code" /*!< RGX USC Code Heap Identifier */
+#define RGX_VK_CAPT_REPLAY_HEAP_IDENT "Vulkan Capture Replay" /*!< RGX vulkan capture replay buffer Heap Identifier */
+#define RGX_SIGNALS_HEAP_IDENT "Signals" /*!< Compute Signals Heap Identifier */
+#define RGX_COMPONENT_CTRL_HEAP_IDENT "Component Control" /*!< RGX DCE Component Control Heap Identifier */
+#define RGX_FBCDC_HEAP_IDENT "FBCDC" /*!< RGX FBCDC State Table Heap Identifier */
+#define RGX_FBCDC_LARGE_HEAP_IDENT "Large FBCDC" /*!< RGX Large FBCDC State Table Heap Identifier */
+#define RGX_PDS_INDIRECT_STATE_HEAP_IDENT "PDS Indirect State" /*!< PDS Indirect State Table Heap Identifier */
+#define RGX_CMP_MISSION_RMW_HEAP_IDENT "Compute Mission RMW" /*!< Compute Mission RMW Heap Identifier */
+#define RGX_CMP_SAFETY_RMW_HEAP_IDENT "Compute Safety RMW" /*!< Compute Safety RMW Heap Identifier */
+#define RGX_TEXTURE_STATE_HEAP_IDENT "Texture State" /*!< Texture State Heap Identifier */
+#define RGX_VISIBILITY_TEST_HEAP_IDENT "Visibility Test" /*!< Visibility Test Heap Identifier */
+
+#endif /* RGX_HEAPS_H */
diff --git a/drivers/gpu/drm/img-rogue/include/volcanic/rgx_hwperf.h b/drivers/gpu/drm/img-rogue/include/volcanic/rgx_hwperf.h
new file mode 100644
index 000000000..4a88727d1
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/volcanic/rgx_hwperf.h
@@ -0,0 +1,1767 @@
+/*************************************************************************/ /*!
+@File
+@Title RGX HWPerf and Debug Types and Defines Header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Common data types definitions for hardware performance API
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+#ifndef RGX_HWPERF_H_
+#define RGX_HWPERF_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* These structures are used on both GPU and CPU and must be a size that is a
+ * multiple of 64 bits, 8 bytes to allow the FW to write 8 byte quantities at
+ * 8 byte aligned addresses. RGX_FW_STRUCT_*_ASSERT() is used to check this.
+ */
+
+/******************************************************************************
+ * Includes and Defines
+ *****************************************************************************/
+
+#include "img_types.h"
+#include "img_defs.h"
+
+#include "rgx_common.h"
+#include "pvrsrv_tlcommon.h"
+#include "pvrsrv_sync_km.h"
+
+
+#if defined(RGX_BVNC_CORE_KM_HEADER) && defined(RGX_BNC_CONFIG_KM_HEADER)
+/* HWPerf interface assumption checks */
+static_assert(RGX_FEATURE_NUM_CLUSTERS <= 16U,
+ "Cluster count too large for HWPerf protocol definition");
+#endif
+
+/*! Perf counter control words */
+#define RGX_HWPERF_CTRL_NOP (0) /*!< only update HW counters */
+#define RGX_HWPERF_CTRL_STATE_UPDATE_EN (1U << 31) /*!< persistent state update; see other flags below */
+#define RGX_HWPERF_CTRL_GEOM_FULLRANGE (1U) /*!< selectable geom and 3D counters are full range */
+#define RGX_HWPERF_CTRL_COMP_FULLRANGE (2U) /*!< selectable compute counters are full range */
+#define RGX_HWPERF_CTRL_TDM_FULLRANGE (4U) /*!< selectable TDM counters are full range */
+
+/******************************************************************************
+ * Packet Event Type Enumerations
+ *****************************************************************************/
+
+/*! Type used to encode the event that generated the packet.
+ * NOTE: When this type is updated the corresponding hwperfbin2json tool
+ * source needs to be updated as well. The RGX_HWPERF_EVENT_MASK_* macros will
+ * also need updating when adding new types.
+ *
+ * @par
+ * The event type values are incrementing integers for use as a shift ordinal
+ * in the event filtering process at the point events are generated.
+ * This scheme thus implies a limit of 63 event types.
+ */
+
+typedef IMG_UINT32 RGX_HWPERF_EVENT_TYPE;
+
+#define RGX_HWPERF_INVALID 0x00U /*!< Invalid. Reserved value. */
+
+/*! FW types 0x01..0x06 */
+#define RGX_HWPERF_FW_EVENT_RANGE_FIRST_TYPE 0x01U
+
+#define RGX_HWPERF_FW_BGSTART 0x01U /*!< Background task processing start */
+#define RGX_HWPERF_FW_BGEND 0x02U /*!< Background task end */
+#define RGX_HWPERF_FW_IRQSTART 0x03U /*!< IRQ task processing start */
+
+#define RGX_HWPERF_FW_IRQEND 0x04U /*!< IRQ task end */
+#define RGX_HWPERF_FW_DBGSTART 0x05U /*!< Debug event start */
+#define RGX_HWPERF_FW_DBGEND 0x06U /*!< Debug event end */
+
+#define RGX_HWPERF_FW_EVENT_RANGE_LAST_TYPE 0x06U
+
+/*! HW types 0x07..0x19 */
+#define RGX_HWPERF_HW_EVENT_RANGE0_FIRST_TYPE 0x07U
+
+#define RGX_HWPERF_HW_PMOOM_TAPAUSE 0x07U /*!< TA Pause at PM Out of Memory */
+
+#define RGX_HWPERF_HW_TAKICK 0x08U /*!< TA task started */
+#define RGX_HWPERF_HW_TAFINISHED 0x09U /*!< TA task finished */
+#define RGX_HWPERF_HW_3DTQKICK 0x0AU /*!< 3D TQ started */
+#define RGX_HWPERF_HW_3DKICK 0x0BU /*!< 3D task started */
+#define RGX_HWPERF_HW_3DFINISHED 0x0CU /*!< 3D task finished */
+#define RGX_HWPERF_HW_CDMKICK 0x0DU /*!< CDM task started */
+#define RGX_HWPERF_HW_CDMFINISHED 0x0EU /*!< CDM task finished */
+#define RGX_HWPERF_HW_TLAKICK 0x0FU /*!< TLA task started */
+#define RGX_HWPERF_HW_TLAFINISHED 0x10U /*!< TLS task finished */
+#define RGX_HWPERF_HW_3DSPMKICK 0x11U /*!< 3D SPM task started */
+#define RGX_HWPERF_HW_PERIODIC 0x12U /*!< Periodic event with updated HW counters */
+#define RGX_HWPERF_HW_RTUKICK 0x13U /*!< Reserved, future use */
+#define RGX_HWPERF_HW_RTUFINISHED 0x14U /*!< Reserved, future use */
+#define RGX_HWPERF_HW_SHGKICK 0x15U /*!< Reserved, future use */
+#define RGX_HWPERF_HW_SHGFINISHED 0x16U /*!< Reserved, future use */
+#define RGX_HWPERF_HW_3DTQFINISHED 0x17U /*!< 3D TQ finished */
+#define RGX_HWPERF_HW_3DSPMFINISHED 0x18U /*!< 3D SPM task finished */
+
+#define RGX_HWPERF_HW_PMOOM_TARESUME 0x19U /*!< TA Resume after PM Out of Memory */
+
+/*! HW_EVENT_RANGE0 used up. Use next empty range below to add new hardware events */
+#define RGX_HWPERF_HW_EVENT_RANGE0_LAST_TYPE 0x19U
+
+/*! other types 0x1A..0x1F */
+#define RGX_HWPERF_CLKS_CHG 0x1AU /*!< Clock speed change in GPU */
+#define RGX_HWPERF_GPU_STATE_CHG 0x1BU /*!< GPU work state change */
+
+/*! power types 0x20..0x27 */
+#define RGX_HWPERF_PWR_EST_RANGE_FIRST_TYPE 0x20U
+#define RGX_HWPERF_PWR_EST_REQUEST 0x20U /*!< Power estimate requested (via GPIO) */
+#define RGX_HWPERF_PWR_EST_READY 0x21U /*!< Power estimate inputs ready */
+#define RGX_HWPERF_PWR_EST_RESULT 0x22U /*!< Power estimate result calculated */
+#define RGX_HWPERF_PWR_EST_RANGE_LAST_TYPE 0x22U
+
+#define RGX_HWPERF_PWR_CHG 0x23U /*!< Power state change */
+
+/*! HW_EVENT_RANGE1 0x28..0x2F, for accommodating new hardware events */
+#define RGX_HWPERF_HW_EVENT_RANGE1_FIRST_TYPE 0x28U
+
+#define RGX_HWPERF_HW_TDMKICK 0x28U /*!< TDM task started */
+#define RGX_HWPERF_HW_TDMFINISHED 0x29U /*!< TDM task finished */
+#define RGX_HWPERF_HW_NULLKICK 0x2AU /*!< NULL event */
+
+#define RGX_HWPERF_HW_EVENT_RANGE1_LAST_TYPE 0x2AU
+
+/*! context switch types 0x30..0x31 */
+#define RGX_HWPERF_CSW_START 0x30U /*!< HW context store started */
+#define RGX_HWPERF_CSW_FINISHED 0x31U /*!< HW context store finished */
+
+/*! DVFS events */
+#define RGX_HWPERF_DVFS 0x32U /*!< Dynamic voltage/frequency scaling events */
+
+/*! firmware misc 0x38..0x39 */
+#define RGX_HWPERF_UFO 0x38U /*!< FW UFO Check / Update */
+#define RGX_HWPERF_FWACT 0x39U /*!< FW Activity notification */
+
+/*! last */
+#define RGX_HWPERF_LAST_TYPE 0x3BU
+
+/*! This enumeration must have a value that is a power of two as it is
+ * used in masks and a filter bit field (currently 64 bits long).
+ */
+#define RGX_HWPERF_MAX_TYPE 0x40U
+
+static_assert(RGX_HWPERF_LAST_TYPE < RGX_HWPERF_MAX_TYPE, "Too many HWPerf event types");
+
+/*! Macro used to check if an event type ID is present in the known set of hardware type events */
+#define HWPERF_PACKET_IS_HW_TYPE(_etype) (((_etype) >= RGX_HWPERF_HW_EVENT_RANGE0_FIRST_TYPE && (_etype) <= RGX_HWPERF_HW_EVENT_RANGE0_LAST_TYPE) || \
+ ((_etype) >= RGX_HWPERF_HW_EVENT_RANGE1_FIRST_TYPE && (_etype) <= RGX_HWPERF_HW_EVENT_RANGE1_LAST_TYPE))
+
+/*! Macro used to check if an event type ID is present in the known set of firmware type events */
+#define HWPERF_PACKET_IS_FW_TYPE(_etype) \
+ ((_etype) >= RGX_HWPERF_FW_EVENT_RANGE_FIRST_TYPE && \
+ (_etype) <= RGX_HWPERF_FW_EVENT_RANGE_LAST_TYPE)
+
+
+typedef enum {
+ RGX_HWPERF_HOST_INVALID = 0x00, /*!< Invalid, do not use. */
+ RGX_HWPERF_HOST_ENQ = 0x01, /*!< ``0x01`` Kernel driver has queued GPU work.
+ See RGX_HWPERF_HOST_ENQ_DATA */
+ RGX_HWPERF_HOST_UFO = 0x02, /*!< ``0x02`` UFO updated by the driver.
+ See RGX_HWPERF_HOST_UFO_DATA */
+ RGX_HWPERF_HOST_ALLOC = 0x03, /*!< ``0x03`` Resource allocated.
+ See RGX_HWPERF_HOST_ALLOC_DATA */
+ RGX_HWPERF_HOST_CLK_SYNC = 0x04, /*!< ``0x04`` GPU / Host clocks correlation data.
+ See RGX_HWPERF_HOST_CLK_SYNC_DATA */
+ RGX_HWPERF_HOST_FREE = 0x05, /*!< ``0x05`` Resource freed,
+ See RGX_HWPERF_HOST_FREE_DATA */
+ RGX_HWPERF_HOST_MODIFY = 0x06, /*!< ``0x06`` Resource modified / updated.
+ See RGX_HWPERF_HOST_MODIFY_DATA */
+ RGX_HWPERF_HOST_DEV_INFO = 0x07, /*!< ``0x07`` Device Health status.
+ See RGX_HWPERF_HOST_DEV_INFO_DATA */
+ RGX_HWPERF_HOST_INFO = 0x08, /*!< ``0x08`` Device memory usage information.
+ See RGX_HWPERF_HOST_INFO_DATA */
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT = 0x09, /*!< ``0x09`` Wait for sync event.
+ See RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA */
+ RGX_HWPERF_HOST_SYNC_SW_TL_ADVANCE = 0x0A, /*!< ``0x0A`` Software timeline advanced.
+ See RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA */
+
+ /*! last */
+ RGX_HWPERF_HOST_LAST_TYPE,
+
+ /*! This enumeration must have a value that is a power of two as it is
+ * used in masks and a filter bit field (currently 32 bits long).
+ */
+ RGX_HWPERF_HOST_MAX_TYPE = 0x20
+} RGX_HWPERF_HOST_EVENT_TYPE;
+
+/*!< The event type values are incrementing integers for use as a shift ordinal
+ * in the event filtering process at the point events are generated.
+ * This scheme thus implies a limit of 31 event types.
+ */
+static_assert(RGX_HWPERF_HOST_LAST_TYPE < RGX_HWPERF_HOST_MAX_TYPE, "Too many HWPerf host event types");
+
+
+/******************************************************************************
+ * Packet Header Format Version 2 Types
+ *****************************************************************************/
+
+/*! Major version number of the protocol in operation
+ */
+#define RGX_HWPERF_V2_FORMAT 2
+
+/*! Signature ASCII pattern 'HWP2' found in the first word of a HWPerfV2 packet
+ */
+#define HWPERF_PACKET_V2_SIG 0x48575032
+
+/*! Signature ASCII pattern 'HWPA' found in the first word of a HWPerfV2a packet
+ */
+#define HWPERF_PACKET_V2A_SIG 0x48575041
+
+/*! Signature ASCII pattern 'HWPB' found in the first word of a HWPerfV2b packet
+ */
+#define HWPERF_PACKET_V2B_SIG 0x48575042
+
+/*! Signature ASCII pattern 'HWPC' found in the first word of a HWPerfV2c packet
+ */
+#define HWPERF_PACKET_V2C_SIG 0x48575043
+
+#define HWPERF_PACKET_ISVALID(_val) (((_val) == HWPERF_PACKET_V2_SIG) || ((_val) == HWPERF_PACKET_V2A_SIG) || ((_val) == HWPERF_PACKET_V2B_SIG) || ((_val) == HWPERF_PACKET_V2C_SIG))
+/*!< Checks that the packet signature is one of the supported versions */
+
+/*! Type defines the HWPerf packet header common to all events. */
+typedef struct
+{
+ IMG_UINT32 ui32Sig; /*!< Always the value HWPERF_PACKET_SIG */
+ IMG_UINT32 ui32Size; /*!< Overall packet size in bytes */
+ IMG_UINT32 eTypeId; /*!< Event type information field */
+ IMG_UINT32 ui32Ordinal; /*!< Sequential number of the packet */
+ IMG_UINT64 ui64Timestamp; /*!< Event timestamp */
+} RGX_HWPERF_V2_PACKET_HDR, *RGX_PHWPERF_V2_PACKET_HDR;
+
+RGX_FW_STRUCT_OFFSET_ASSERT(RGX_HWPERF_V2_PACKET_HDR, ui64Timestamp);
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_V2_PACKET_HDR);
+
+
+/*! Mask for use with the IMG_UINT32 ui32Size header field */
+#define RGX_HWPERF_SIZE_MASK 0xFFFFU
+
+/*! This macro defines an upper limit to which the size of the largest variable
+ * length HWPerf packet must fall within, currently 3KB. This constant may be
+ * used to allocate a buffer to hold one packet.
+ * This upper limit is policed by packet producing code.
+ */
+#define RGX_HWPERF_MAX_PACKET_SIZE 0xC00U
+
+/*! Defines an upper limit to the size of a variable length packet payload.
+ */
+#define RGX_HWPERF_MAX_PAYLOAD_SIZE ((IMG_UINT32)(RGX_HWPERF_MAX_PACKET_SIZE-\
+ sizeof(RGX_HWPERF_V2_PACKET_HDR)))
+
+/*! Macro which takes a structure name and provides the packet size for
+ * a fixed size payload packet, rounded up to 8 bytes to align packets
+ * for 64 bit architectures. */
+#define RGX_HWPERF_MAKE_SIZE_FIXED(_struct) ((IMG_UINT32)(RGX_HWPERF_SIZE_MASK&(sizeof(RGX_HWPERF_V2_PACKET_HDR)+PVR_ALIGN(sizeof(_struct), PVRSRVTL_PACKET_ALIGNMENT))))
+
+/*! Macro which takes the number of bytes written in the data payload of a
+ * packet for a variable size payload packet, rounded up to 8 bytes to
+ * align packets for 64 bit architectures. */
+#define RGX_HWPERF_MAKE_SIZE_VARIABLE(_size) ((IMG_UINT32)(RGX_HWPERF_SIZE_MASK&(sizeof(RGX_HWPERF_V2_PACKET_HDR)+PVR_ALIGN((_size), PVRSRVTL_PACKET_ALIGNMENT))))
+
+/*! Macro to obtain the size of the packet */
+#define RGX_HWPERF_GET_SIZE(_packet_addr) ((IMG_UINT16)(((_packet_addr)->ui32Size) & RGX_HWPERF_SIZE_MASK))
+
+/*! Macro to obtain the size of the packet data */
+#define RGX_HWPERF_GET_DATA_SIZE(_packet_addr) (RGX_HWPERF_GET_SIZE(_packet_addr) - sizeof(RGX_HWPERF_V2_PACKET_HDR))
+
+/*! Masks for use with the IMG_UINT32 eTypeId header field */
+#define RGX_HWPERF_TYPEID_MASK 0x0007FFFFU
+#define RGX_HWPERF_TYPEID_EVENT_MASK 0x00007FFFU
+#define RGX_HWPERF_TYPEID_THREAD_MASK 0x00008000U
+#define RGX_HWPERF_TYPEID_STREAM_MASK 0x00070000U
+#define RGX_HWPERF_TYPEID_META_DMA_MASK 0x00080000U
+#define RGX_HWPERF_TYPEID_M_CORE_MASK 0x00100000U
+#define RGX_HWPERF_TYPEID_OSID_MASK 0x07000000U
+
+/*! Meta thread macros for encoding the ID into the type field of a packet */
+#define RGX_HWPERF_META_THREAD_SHIFT 15U
+#define RGX_HWPERF_META_THREAD_ID0 0x0U /*!< Meta Thread 0 ID */
+#define RGX_HWPERF_META_THREAD_ID1 0x1U /*!< Meta Thread 1 ID */
+/*! Obsolete, kept for source compatibility */
+#define RGX_HWPERF_META_THREAD_MASK 0x1U
+/*! Stream ID macros for encoding the ID into the type field of a packet */
+#define RGX_HWPERF_STREAM_SHIFT 16U
+/*! Meta DMA macro for encoding how the packet was generated into the type field of a packet */
+#define RGX_HWPERF_META_DMA_SHIFT 19U
+/*! Bit-shift macro used for encoding multi-core data into the type field of a packet */
+#define RGX_HWPERF_M_CORE_SHIFT 20U
+/*! OSID bit-shift macro used for encoding OSID into type field of a packet */
+#define RGX_HWPERF_OSID_SHIFT 24U
+typedef enum {
+ RGX_HWPERF_STREAM_ID0_FW, /*!< Events from the Firmware/GPU */
+ RGX_HWPERF_STREAM_ID1_HOST, /*!< Events from the Server host driver component */
+ RGX_HWPERF_STREAM_ID2_CLIENT, /*!< Events from the Client host driver component */
+ RGX_HWPERF_STREAM_ID_LAST,
+} RGX_HWPERF_STREAM_ID;
+
+/* Checks if all stream IDs can fit under RGX_HWPERF_TYPEID_STREAM_MASK. */
+static_assert(((IMG_UINT32)RGX_HWPERF_STREAM_ID_LAST - 1U) < (RGX_HWPERF_TYPEID_STREAM_MASK >> RGX_HWPERF_STREAM_SHIFT),
+ "Too many HWPerf stream IDs.");
+
+/*! Compile-time value used to seed the Multi-Core (MC) bit in the typeID field.
+ * Only set by RGX_FIRMWARE builds.
+ */
+#if defined(RGX_FIRMWARE)
+# if defined(RGX_FEATURE_GPU_MULTICORE_SUPPORT)
+#define RGX_HWPERF_M_CORE_VALUE 1U /*!< 1 => Multi-core supported */
+# else
+#define RGX_HWPERF_M_CORE_VALUE 0U /*!< 0 => Multi-core not supported */
+# endif
+#else
+#define RGX_HWPERF_M_CORE_VALUE 0U /*!< 0 => Multi-core not supported */
+#endif
+
+/*! Macros used to set the packet type and encode meta thread ID (0|1),
+ * HWPerf stream ID, multi-core capability and OSID within the typeID */
+#define RGX_HWPERF_MAKE_TYPEID(_stream, _type, _thread, _metadma, _osid)\
+ ((IMG_UINT32) ((RGX_HWPERF_TYPEID_STREAM_MASK&((IMG_UINT32)(_stream) << RGX_HWPERF_STREAM_SHIFT)) | \
+ (RGX_HWPERF_TYPEID_THREAD_MASK & ((IMG_UINT32)(_thread) << RGX_HWPERF_META_THREAD_SHIFT)) | \
+ (RGX_HWPERF_TYPEID_EVENT_MASK & (IMG_UINT32)(_type)) | \
+ (RGX_HWPERF_TYPEID_META_DMA_MASK & ((IMG_UINT32)(_metadma) << RGX_HWPERF_META_DMA_SHIFT)) | \
+ (RGX_HWPERF_TYPEID_OSID_MASK & ((IMG_UINT32)(_osid) << RGX_HWPERF_OSID_SHIFT)) | \
+ (RGX_HWPERF_TYPEID_M_CORE_MASK & ((IMG_UINT32)(RGX_HWPERF_M_CORE_VALUE) << RGX_HWPERF_M_CORE_SHIFT))))
+
+/*! Obtains the event type that generated the packet */
+#define RGX_HWPERF_GET_TYPE(_packet_addr) (((_packet_addr)->eTypeId) & RGX_HWPERF_TYPEID_EVENT_MASK)
+
+/*! Obtains the META Thread number that generated the packet */
+#define RGX_HWPERF_GET_THREAD_ID(_packet_addr) (((((_packet_addr)->eTypeId) & RGX_HWPERF_TYPEID_THREAD_MASK) >> RGX_HWPERF_META_THREAD_SHIFT))
+
+/*! Determines if the packet generated contains multi-core data */
+#define RGX_HWPERF_GET_M_CORE(_packet_addr) (((_packet_addr)->eTypeId & RGX_HWPERF_TYPEID_M_CORE_MASK) >> RGX_HWPERF_M_CORE_SHIFT)
+
+/*! Obtains the guest OSID which resulted in packet generation */
+#define RGX_HWPERF_GET_OSID(_packet_addr) (((_packet_addr)->eTypeId & RGX_HWPERF_TYPEID_OSID_MASK) >> RGX_HWPERF_OSID_SHIFT)
+
+/*! Obtain stream id */
+#define RGX_HWPERF_GET_STREAM_ID(_packet_addr) (((((_packet_addr)->eTypeId) & RGX_HWPERF_TYPEID_STREAM_MASK) >> RGX_HWPERF_STREAM_SHIFT))
+
+/*! Obtain information about how the packet was generated, which might affect payload total size */
+#define RGX_HWPERF_GET_META_DMA_INFO(_packet_addr) (((((_packet_addr)->eTypeId) & RGX_HWPERF_TYPEID_META_DMA_MASK) >> RGX_HWPERF_META_DMA_SHIFT))
+
+/*! Obtains a typed pointer to a packet given a buffer address */
+#define RGX_HWPERF_GET_PACKET(_buffer_addr) ((RGX_HWPERF_V2_PACKET_HDR *)(void *) (_buffer_addr))
+/*! Obtains a typed pointer to a data structure given a packet address */
+#define RGX_HWPERF_GET_PACKET_DATA_BYTES(_packet_addr) (IMG_OFFSET_ADDR((_packet_addr), sizeof(RGX_HWPERF_V2_PACKET_HDR)))
+/*! Obtains a typed pointer to the next packet given a packet address */
+#define RGX_HWPERF_GET_NEXT_PACKET(_packet_addr) ((RGX_HWPERF_V2_PACKET_HDR *) (IMG_OFFSET_ADDR((_packet_addr), RGX_HWPERF_SIZE_MASK&((_packet_addr)->ui32Size))))
+
+/*! Obtains a typed pointer to a packet header given the packet data address */
+#define RGX_HWPERF_GET_PACKET_HEADER(_packet_addr) ((RGX_HWPERF_V2_PACKET_HDR *) (IMG_OFFSET_ADDR((_packet_addr), -(IMG_INT32)sizeof(RGX_HWPERF_V2_PACKET_HDR))))
+
+
+/******************************************************************************
+ * Other Common Defines
+ *****************************************************************************/
+
+/*! This macro is not a real array size, but indicates the array has a variable
+ * length only known at run-time but always contains at least 1 element. The
+ * final size of the array is deduced from the size field of a packet header.
+ */
+#define RGX_HWPERF_ONE_OR_MORE_ELEMENTS 1U
+
+/*! This macro is not a real array size, but indicates the array is optional
+ * and if present has a variable length only known at run-time. The final
+ * size of the array is deduced from the size field of a packet header. */
+#define RGX_HWPERF_ZERO_OR_MORE_ELEMENTS 1U
+
+
+/*! Masks for use with the IMG_UINT32 ui32BlkInfo field */
+#define RGX_HWPERF_BLKINFO_BLKCOUNT_MASK 0xFFFF0000U
+#define RGX_HWPERF_BLKINFO_BLKOFFSET_MASK 0x0000FFFFU
+
+/*! Shift for the NumBlocks and counter block offset field in ui32BlkInfo */
+#define RGX_HWPERF_BLKINFO_BLKCOUNT_SHIFT 16U
+#define RGX_HWPERF_BLKINFO_BLKOFFSET_SHIFT 0U
+
+/*! Macro used to set the block info word as a combination of two 16-bit integers */
+#define RGX_HWPERF_MAKE_BLKINFO(_numblks, _blkoffset) ((IMG_UINT32) ((RGX_HWPERF_BLKINFO_BLKCOUNT_MASK&((_numblks) << RGX_HWPERF_BLKINFO_BLKCOUNT_SHIFT)) | (RGX_HWPERF_BLKINFO_BLKOFFSET_MASK&((_blkoffset) << RGX_HWPERF_BLKINFO_BLKOFFSET_SHIFT))))
+
+/*! Macro used to obtain the number of counter blocks present in the packet */
+#define RGX_HWPERF_GET_BLKCOUNT(_blkinfo) (((_blkinfo) & RGX_HWPERF_BLKINFO_BLKCOUNT_MASK) >> RGX_HWPERF_BLKINFO_BLKCOUNT_SHIFT)
+
+/*! Obtains the offset of the counter block stream in the packet */
+#define RGX_HWPERF_GET_BLKOFFSET(_blkinfo) (((_blkinfo) & RGX_HWPERF_BLKINFO_BLKOFFSET_MASK) >> RGX_HWPERF_BLKINFO_BLKOFFSET_SHIFT)
+
+/*! This macro gets the number of blocks depending on the packet version */
+#define RGX_HWPERF_GET_NUMBLKS(_sig, _packet_data, _numblocks) \
+ do { \
+ if (HWPERF_PACKET_V2B_SIG == _sig || HWPERF_PACKET_V2C_SIG == _sig) \
+ { \
+ (_numblocks) = RGX_HWPERF_GET_BLKCOUNT((_packet_data)->ui32BlkInfo);\
+ } \
+ else \
+ { \
+ IMG_UINT32 ui32VersionOffset = (((_sig) == HWPERF_PACKET_V2_SIG) ? 1 : 3);\
+ (_numblocks) = *(IMG_UINT16 *)(IMG_OFFSET_ADDR(&(_packet_data)->ui32WorkTarget, ui32VersionOffset)); \
+ } \
+ } while (0)
+
+/*! This macro gets the counter stream pointer depending on the packet version */
+#define RGX_HWPERF_GET_CNTSTRM(_sig, _hw_packet_data, _cntstream_ptr) \
+{ \
+ if (HWPERF_PACKET_V2B_SIG == _sig || HWPERF_PACKET_V2C_SIG == _sig) \
+ { \
+ (_cntstream_ptr) = (IMG_UINT32 *)(IMG_OFFSET_ADDR((_hw_packet_data), RGX_HWPERF_GET_BLKOFFSET((_hw_packet_data)->ui32BlkInfo))); \
+ } \
+ else \
+ { \
+ IMG_UINT32 ui32BlkStreamOffsetInWords = ((_sig == HWPERF_PACKET_V2_SIG) ? 6 : 8); \
+ (_cntstream_ptr) = (IMG_UINT32 *)(IMG_OFFSET_ADDR((_hw_packet_data), ui32BlkStreamOffsetInWords)); \
+ } \
+}
+
+/*! Masks for use with the RGX_HWPERF_UFO_EV eEvType field */
+#define RGX_HWPERF_UFO_STREAMSIZE_MASK 0xFFFF0000U
+#define RGX_HWPERF_UFO_STREAMOFFSET_MASK 0x0000FFFFU
+
+/*! Shift for the UFO count and data stream fields */
+#define RGX_HWPERF_UFO_STREAMSIZE_SHIFT 16U
+#define RGX_HWPERF_UFO_STREAMOFFSET_SHIFT 0U
+
+/*! Macro used to set UFO stream info word as a combination of two 16-bit integers */
+#define RGX_HWPERF_MAKE_UFOPKTINFO(_ssize, _soff) \
+ ((IMG_UINT32) ((RGX_HWPERF_UFO_STREAMSIZE_MASK&((_ssize) << RGX_HWPERF_UFO_STREAMSIZE_SHIFT)) | \
+ (RGX_HWPERF_UFO_STREAMOFFSET_MASK&((_soff) << RGX_HWPERF_UFO_STREAMOFFSET_SHIFT))))
+
+/*! Macro used to obtain UFO count*/
+#define RGX_HWPERF_GET_UFO_STREAMSIZE(_streaminfo) \
+ (((_streaminfo) & RGX_HWPERF_UFO_STREAMSIZE_MASK) >> RGX_HWPERF_UFO_STREAMSIZE_SHIFT)
+
+/*! Obtains the offset of the UFO stream in the packet */
+#define RGX_HWPERF_GET_UFO_STREAMOFFSET(_streaminfo) \
+ (((_streaminfo) & RGX_HWPERF_UFO_STREAMOFFSET_MASK) >> RGX_HWPERF_UFO_STREAMOFFSET_SHIFT)
+
+
+
+/******************************************************************************
+ * Data Stream Common Types
+ *****************************************************************************/
+
+/*! All the Data Masters HWPerf is aware of. When a new DM is added to this
+ * list, it should be appended at the end to maintain backward compatibility
+ * of HWPerf data.
+ */
+typedef enum {
+
+ RGX_HWPERF_DM_GP,
+ RGX_HWPERF_DM_TDM,
+ RGX_HWPERF_DM_GEOM,
+ RGX_HWPERF_DM_3D,
+ RGX_HWPERF_DM_CDM,
+ RGX_HWPERF_DM_RTU,
+
+ RGX_HWPERF_DM_LAST,
+
+ RGX_HWPERF_DM_INVALID = 0x1FFFFFFF
+} RGX_HWPERF_DM;
+
+/*! Enum containing bit position for 32bit feature flags used in hwperf and api */
+typedef enum {
+ RGX_HWPERF_FEATURE_PERFBUS_FLAG = 0x001,
+ RGX_HWPERF_FEATURE_S7_TOP_INFRASTRUCTURE_FLAG = 0x002,
+ RGX_HWPERF_FEATURE_XT_TOP_INFRASTRUCTURE_FLAG = 0x004,
+ RGX_HWPERF_FEATURE_PERF_COUNTER_BATCH_FLAG = 0x008,
+ RGX_HWPERF_FEATURE_ROGUEXE_FLAG = 0x010,
+ RGX_HWPERF_FEATURE_DUST_POWER_ISLAND_S7_FLAG = 0x020,
+ RGX_HWPERF_FEATURE_PBE2_IN_XE_FLAG = 0x040,
+ RGX_HWPERF_FEATURE_WORKLOAD_ESTIMATION = 0x080,
+ RGX_HWPERF_FEATURE_MULTICORE_FLAG = 0x100,
+ RGX_HWPERF_FEATURE_RAYTRACING_FLAG = 0x200,
+ RGX_HWPERF_FEATURE_CXT_TOP_INFRASTRUCTURE_FLAG = 0x400
+} RGX_HWPERF_FEATURE_FLAGS;
+
+/*! This structure holds the data of a firmware packet. */
+typedef struct
+{
+ RGX_HWPERF_DM eDM; /*!< DataMaster identifier, see RGX_HWPERF_DM */
+ IMG_UINT32 ui32TxtActCyc; /*!< Meta TXTACTCYC register value */
+ IMG_UINT32 ui32FWPerfCount0; /*!< Meta/MIPS PERF_COUNT0 register */
+ IMG_UINT32 ui32FWPerfCount1; /*!< Meta/MIPS PERF_COUNT1 register */
+ IMG_UINT32 ui32TimeCorrIndex; /*!< Internal field */
+ IMG_UINT32 ui32Padding; /*!< Reserved */
+} RGX_HWPERF_FW_DATA;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_FW_DATA);
+
+/*! This structure holds the data of a hardware packet, including counters. */
+typedef struct
+{
+ IMG_UINT32 ui32DMCyc; /*!< DataMaster cycle count register, 0 if none */
+ IMG_UINT32 ui32FrameNum; /*!< Frame number, undefined on some DataMasters */
+ IMG_UINT32 ui32PID; /*!< Process identifier */
+ IMG_UINT32 ui32DMContext; /*!< GPU Data Master (FW) Context */
+ IMG_UINT32 ui32WorkTarget; /*!< RenderTarget for a TA,3D; Frame context for RTU, 0x0 otherwise */
+ IMG_UINT32 ui32ExtJobRef; /*!< Client driver context job reference used for tracking/debugging */
+ IMG_UINT32 ui32IntJobRef; /*!< RGX Data master context job reference used for tracking/debugging */
+ IMG_UINT32 ui32TimeCorrIndex; /*!< Index to the time correlation at the time the packet was generated */
+ IMG_UINT32 ui32BlkInfo; /*!< <31..16> NumBlocks <15..0> Counter block stream offset */
+ IMG_UINT32 ui32WorkCtx; /*!< Work context: Render Context for TA/3D; RayTracing Context for RTU/SHG; 0x0 otherwise */
+ IMG_UINT32 ui32CtxPriority; /*!< Context priority */
+ IMG_UINT32 ui32GPUIdMask; /*!< GPU IDs active within this event */
+ IMG_UINT32 aui32CountBlksStream[RGX_HWPERF_ZERO_OR_MORE_ELEMENTS]; /*!< Counter data */
+ IMG_UINT32 ui32Padding2; /*!< Reserved. To ensure correct alignment */
+} RGX_HWPERF_HW_DATA;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_HW_DATA);
+
+/*! Mask for use with the aui32CountBlksStream field when decoding the
+ * counter block ID and mask word. */
+#define RGX_HWPERF_CNTBLK_ID_MASK 0xFFFF0000U
+#define RGX_HWPERF_CNTBLK_ID_SHIFT 16U
+
+/*! MAX value used in server handling of counter config arrays */
+#if defined(SUPPORT_VALIDATION)
+#define RGX_CNTBLK_COUNTERS_MAX 64
+#else
+#define RGX_CNTBLK_COUNTERS_MAX 12
+#endif
+
+
+/*! Obtains the counter block ID word from an aui32CountBlksStream field.
+ * The word combines Control bits (15-12), GPU-Id (11-8), Group (7-4), Unit
+ * within group (3-0) */
+#define RGX_HWPERF_GET_CNTBLK_IDW(_word) ((IMG_UINT16)(((_word)&RGX_HWPERF_CNTBLK_ID_MASK)>>RGX_HWPERF_CNTBLK_ID_SHIFT))
+
+/*! Obtains the counter block ID from the supplied RGX_HWPERF_HW_DATA address
+ * and stream index. May be used in decoding the counter block stream words of
+ * a RGX_HWPERF_HW_DATA structure. */
+#define RGX_HWPERF_GET_CNTBLK_ID(_data_addr, _idx) RGX_HWPERF_GET_CNTBLK_IDW((_data_addr)->aui32CountBlksStream[(_idx)])
+
+/*! Obtains the GPU ID from the supplied RGX_HWPERF_HW_DATA CNTBLK_IDW */
+#define RGX_HWPERF_GET_CNTBLK_GPUW(_word) ((IMG_UINT16)(((_word)&RGX_CNTBLK_ID_MC_GPU_MASK)>>RGX_CNTBLK_ID_MC_GPU_SHIFT))
+
+#define RGX_HWPERF_GET_CNT_MASKW(_word) ((IMG_UINT16)((_word)&(~RGX_HWPERF_CNTBLK_ID_MASK)))
+
+/*! Obtains the counter mask from the supplied RGX_HWPERF_HW_DATA address
+ * and stream index. May be used in decoding the counter block stream words
+ * of a RGX_HWPERF_HW_DATA structure. */
+#define RGX_HWPERF_GET_CNT_MASK(_data_addr, _idx) RGX_HWPERF_GET_CNT_MASKW((_data_addr)->aui32CountBlksStream[(_idx)])
+
+/*! Context switch packet event */
+typedef struct
+{
+ RGX_HWPERF_DM eDM; /*!< DataMaster identifier, see RGX_HWPERF_DM */
+ IMG_UINT32 ui32DMContext; /*!< GPU Data Master (FW) Context */
+ IMG_UINT32 ui32FrameNum; /*!< Client Frame number (TA, 3D only) */
+ IMG_UINT32 ui32TxtActCyc; /*!< Meta TXTACTCYC register value */
+ IMG_UINT32 ui32PerfCycle; /*!< Cycle count. Used to measure HW context store latency */
+ IMG_UINT32 ui32PerfPhase; /*!< Phase. Used to determine geometry content */
+ IMG_UINT32 ui32Padding[2]; /*!< Padding to 8 DWords */
+} RGX_HWPERF_CSW_DATA;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_CSW_DATA);
+
+/*! Enumeration of clocks supporting this event */
+typedef enum
+{
+ RGX_HWPERF_CLKS_CHG_INVALID = 0,
+
+ RGX_HWPERF_CLKS_CHG_NAME_CORE = 1,
+
+ RGX_HWPERF_CLKS_CHG_LAST,
+} RGX_HWPERF_CLKS_CHG_NAME;
+
+/*! This structure holds the data of a clocks change packet. */
+typedef struct
+{
+ IMG_UINT64 ui64NewClockSpeed; /*!< New Clock Speed (in Hz) */
+ RGX_HWPERF_CLKS_CHG_NAME eClockName; /*!< Clock name */
+ IMG_UINT32 ui32CalibratedClockSpeed; /*!< Calibrated new GPU clock speed (in Hz) */
+ IMG_UINT64 ui64OSTimeStamp; /*!< OSTimeStamp sampled by the host */
+ IMG_UINT64 ui64CRTimeStamp; /*!< CRTimeStamp sampled by the host and
+ correlated to OSTimeStamp */
+} RGX_HWPERF_CLKS_CHG_DATA;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_CLKS_CHG_DATA);
+
+/*! Enumeration of GPU utilisation states supported by this event */
+typedef IMG_UINT32 RGX_HWPERF_GPU_STATE;
+
+/*! This structure holds the data of a GPU utilisation state change packet. */
+typedef struct
+{
+ RGX_HWPERF_GPU_STATE eState; /*!< New GPU utilisation state */
+ IMG_UINT32 uiUnused1; /*!< Padding */
+ IMG_UINT32 uiUnused2; /*!< Padding */
+ IMG_UINT32 uiUnused3; /*!< Padding */
+} RGX_HWPERF_GPU_STATE_CHG_DATA;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_GPU_STATE_CHG_DATA);
+
+
+/*! Signature pattern 'HPE1' found in the first word of a PWR_EST packet data */
+#define HWPERF_PWR_EST_V1_SIG 0x48504531
+
+/*! Macros to obtain a component field from a counter ID word */
+#define RGX_HWPERF_GET_PWR_EST_HIGH_FLAG(_word) (((_word)&0x80000000)>>31)
+#define RGX_HWPERF_GET_PWR_EST_GPUID(_word) (((_word)&0x70000000)>>28)
+/*!< Obtains the GPU ID from a counter ID word */
+#define RGX_HWPERF_GET_PWR_EST_UNIT(_word) (((_word)&0x0F000000)>>24)
+#define RGX_HWPERF_GET_PWR_EST_NUMBER(_word) ((_word)&0x0000FFFF)
+
+#define RGX_HWPERF_PWR_EST_HIGH_OFFSET (31)
+#define RGX_HWPERF_PWR_EST_GPUID_OFFSET (28)
+#define RGX_HWPERF_PWR_EST_GPUID_MASK (0x7U)
+#define RGX_HWPERF_PWR_EST_UNIT_OFFSET (24)
+#define RGX_HWPERF_PWR_EST_UNIT_MASK (0xFU)
+#define RGX_HWPERF_PWR_EST_VALUE_MASK (0xFFFFU)
+
+/*! This macro constructs a counter ID for a power estimate data stream from
+ * the component parts of: high word flag, unit id, GPU id, counter number */
+#define RGX_HWPERF_MAKE_PWR_EST_COUNTERID(_high, _unit, _core, _number) \
+ ((IMG_UINT32)(((IMG_UINT32)((IMG_UINT32)(_high)&0x1U)<= RGX_BVNC_STR_SIZE_MAX),
+ "Space inside HWPerf packet data for BVNC string insufficient");
+
+#define RGX_HWPERF_MAX_BVNC_BLOCK_LEN (20U)
+
+/*! BVNC Features */
+typedef struct
+{
+ /*! Counter block ID, see RGX_HWPERF_CNTBLK_ID */
+ IMG_UINT16 ui16BlockID;
+
+ /*! Number of counters in this block type */
+ IMG_UINT16 ui16NumCounters;
+
+ /*! Number of blocks of this type */
+ IMG_UINT16 ui16NumBlocks;
+
+ /*! Reserved for future use */
+ IMG_UINT16 ui16Reserved;
+} RGX_HWPERF_BVNC_BLOCK;
+
+/*! BVNC Features */
+typedef struct
+{
+ IMG_CHAR aszBvncString[RGX_HWPERF_MAX_BVNC_LEN]; /*!< BVNC string */
+ IMG_UINT32 ui32BvncKmFeatureFlags; /*!< See RGX_HWPERF_FEATURE_FLAGS */
+ IMG_UINT16 ui16BvncBlocks; /*!< Number of blocks described in aBvncBlocks */
+ IMG_UINT16 ui16BvncGPUCores; /*!< Number of GPU cores present */
+ RGX_HWPERF_BVNC_BLOCK aBvncBlocks[RGX_HWPERF_MAX_BVNC_BLOCK_LEN]; /*!< Supported Performance Blocks for BVNC. See RGX_HWPERF_BVNC_BLOCK */
+} RGX_HWPERF_BVNC;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_BVNC);
+
+/*! Performance Counter Configuration data element. */
+typedef struct
+{
+ IMG_UINT32 ui32BlockID; /*!< Counter Block ID. See RGX_HWPERF_CNTBLK_ID */
+ IMG_UINT32 ui32NumCounters; /*!< Number of counters configured */
+ IMG_UINT32 ui32CounterVals[RGX_CNTBLK_COUNTERS_MAX]; /*!< Counters configured (ui32NumCounters worth of entries) */
+} RGX_HWPERF_COUNTER_CFG_DATA_EL;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_COUNTER_CFG_DATA_EL);
+
+/*! Performance Counter Configuration data. */
+typedef struct
+{
+ IMG_UINT32 ui32EnabledBlocks; /*!< Number of Enabled Blocks. */
+ RGX_HWPERF_COUNTER_CFG_DATA_EL uData; /*!< Start of variable length data. See RGX_HWPERF_COUNTER_CFG_DATA_EL */
+ IMG_UINT32 ui32Padding; /*!< reserved */
+} RGX_HWPERF_COUNTER_CFG;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_COUNTER_CFG);
+
+/*! Sub-event's data. */
+typedef union
+{
+ struct
+ {
+ RGX_HWPERF_DM eDM; /*!< Data Master ID. */
+ RGX_HWPERF_HWR_REASON eReason; /*!< Reason of the HWR. */
+ IMG_UINT32 ui32DMContext; /*!< FW render context */
+ } sHWR; /*!< HWR sub-event data. */
+
+ RGX_HWPERF_BVNC sBVNC; /*!< BVNC Features. See RGX_HWPERF_BVNC */
+ struct
+ {
+ IMG_UINT32 ui32EvMaskLo; /*!< Low order 32 bits of Filter Mask */
+ IMG_UINT32 ui32EvMaskHi; /*!< High order 32 bits of Filter Mask */
+ } sEvMsk; /*!< HW Filter Mask */
+ RGX_HWPERF_COUNTER_CFG sPCC; /*!< Performance Counter Config. See RGX_HWPERF_COUNTER_CFG */
+} RGX_HWPERF_FWACT_DETAIL;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_FWACT_DETAIL);
+
+/*! This structure holds the data of a FW activity event packet */
+typedef struct
+{
+ RGX_HWPERF_FWACT_EV eEvType; /*!< Event type. */
+ RGX_HWPERF_FWACT_DETAIL uFwActDetail; /*!< Data of the sub-event. */
+ IMG_UINT32 ui32Padding; /*!< Reserved. */
+} RGX_HWPERF_FWACT_DATA;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_FWACT_DATA);
+
+
+typedef enum {
+ RGX_HWPERF_UFO_EV_UPDATE, /*!< Update on the UFO objects. */
+ RGX_HWPERF_UFO_EV_CHECK_SUCCESS, /*!< Successful check on UFO objects. */
+ RGX_HWPERF_UFO_EV_PRCHECK_SUCCESS, /*!< Successful partial render check on UFO objects. */
+ RGX_HWPERF_UFO_EV_CHECK_FAIL, /*!< Unsuccessful check on UFO objects. */
+ RGX_HWPERF_UFO_EV_PRCHECK_FAIL, /*!< Unsuccessful partial render check on UFO objects. */
+ RGX_HWPERF_UFO_EV_FORCE_UPDATE, /*!< Forced erroring of the UFO objects. */
+
+ RGX_HWPERF_UFO_EV_LAST /*!< Reserved. Do not use. */
+} RGX_HWPERF_UFO_EV;
+
+/*! Data stream tuple. */
+typedef union
+{
+ struct
+ {
+ IMG_UINT32 ui32FWAddr; /*!< UFO's unique address */
+ IMG_UINT32 ui32Value; /*!< Value of the UFO object */
+ } sCheckSuccess;
+ struct
+ {
+ IMG_UINT32 ui32FWAddr; /*!< UFO's unique address */
+ IMG_UINT32 ui32Value; /*!< Value of the UFO object */
+ IMG_UINT32 ui32Required; /*!< Value of the UFO object required by the fence */
+ } sCheckFail;
+ struct
+ {
+ IMG_UINT32 ui32FWAddr; /*!< UFO's unique address */
+ IMG_UINT32 ui32OldValue; /*!< Value of UFO object before update */
+ IMG_UINT32 ui32NewValue; /*!< Value of UFO object after update */
+ } sUpdate;
+} RGX_HWPERF_UFO_DATA_ELEMENT;
+
+/*! This structure holds the packet payload data for UFO event. */
+typedef struct
+{
+ RGX_HWPERF_UFO_EV eEvType; /*!< Subtype of the event. See RGX_HWPERF_UFO_EV */
+ IMG_UINT32 ui32TimeCorrIndex; /*!< Index to the timer correlation data
+ at the time the packet was generated.
+ Used to approximate Host timestamps for
+ these events. */
+ IMG_UINT32 ui32PID; /*!< Client process identifier */
+ IMG_UINT32 ui32ExtJobRef; /*!< Reference used by callers of the RGX
+ API to track submitted work (for
+ debugging/trace purposes) */
+ IMG_UINT32 ui32IntJobRef; /*!< Internal reference used to track
+ submitted work (for debugging / trace
+ purposes) */
+ IMG_UINT32 ui32DMContext; /*!< GPU Data Master (FW) Context */
+ IMG_UINT32 ui32StreamInfo; /*!< Encoded number of elements in the
+ stream and stream data offset in the
+ payload */
+ RGX_HWPERF_DM eDM; /*!< Data Master number, see RGX_HWPERF_DM */
+ IMG_UINT32 ui32Padding; /*!< Unused, reserved */
+ IMG_UINT32 aui32StreamData[RGX_HWPERF_ONE_OR_MORE_ELEMENTS]; /*!< Series of tuples holding UFO objects data */
+} RGX_HWPERF_UFO_DATA;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_UFO_DATA);
+
+
+/*!
+ * RGX_HWPERF_KICK_TYPE describes the type of kick for events received / sent
+ * between KICK_START / KICK_END inclusively for all event types.
+ */
+typedef enum
+{
+ RGX_HWPERF_KICK_TYPE_TA3D, /*!< TA 3D Kick */
+ RGX_HWPERF_KICK_TYPE_CDM, /*!< Compute Data Master Kick */
+ RGX_HWPERF_KICK_TYPE_RS, /*!< Ray Store Kick */
+ RGX_HWPERF_KICK_TYPE_SHG, /*!< Scene Hierarchy Generator Kick */
+ RGX_HWPERF_KICK_TYPE_TQTDM, /*!< TQ 2D Data Master Kick */
+ RGX_HWPERF_KICK_TYPE_SYNC, /*!< Sync Kick */
+ RGX_HWPERF_KICK_TYPE_LAST,
+
+ RGX_HWPERF_KICK_TYPE_FORCE_32BIT = 0x7fffffff
+} RGX_HWPERF_KICK_TYPE;
+
+typedef struct
+{
+ RGX_HWPERF_KICK_TYPE ui32EnqType; /*!< Workload type sent to FW for
+ scheduling on GPU hardware.
+ See RGX_HWPERF_KICK_TYPE */
+ IMG_UINT32 ui32PID; /*!< Client process identifier */
+ IMG_UINT32 ui32ExtJobRef; /*!< Reference used by callers of the RGX API
+ to track submitted work (for debugging /
+ trace purposes) */
+ IMG_UINT32 ui32IntJobRef; /*!< internal reference used to track submitted
+ work (for debugging / trace purposes) */
+ IMG_UINT32 ui32DMContext; /*!< GPU Data Master (FW) Context */
+ IMG_UINT32 ui32Padding; /*!< Unused, reserved */
+ IMG_UINT64 ui64CheckFence_UID; /*!< ID of fence gating work execution on GPU */
+ IMG_UINT64 ui64UpdateFence_UID; /*!< ID of fence triggered after work completes on GPU */
+ IMG_UINT64 ui64DeadlineInus; /*!< Workload deadline in system monotonic time */
+ IMG_UINT32 ui32CycleEstimate; /*!< Estimated cycle time for the workload */
+ PVRSRV_FENCE hCheckFence; /*!< Fence this enqueue task waits for, before starting */
+ PVRSRV_FENCE hUpdateFence; /*!< Fence this enqueue task signals, on completion */
+ PVRSRV_TIMELINE hUpdateTimeline; /*!< Timeline on which the above hUpdateFence is created */
+
+ /* Align structure size to 8 bytes */
+} RGX_HWPERF_HOST_ENQ_DATA;
+
+/* Payload size must be multiple of 8 bytes to align start of next packet. */
+static_assert((sizeof(RGX_HWPERF_HOST_ENQ_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_ENQ_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+typedef struct
+{
+ RGX_HWPERF_UFO_EV eEvType; /*!< Subtype of the event */
+ IMG_UINT32 ui32StreamInfo; /*!< Encoded number of elements in the stream and
+ stream data offset in the payload */
+#ifdef __CHECKER__
+ /* Since we're not conforming to the C99 standard by not using a flexible
+ * array member need to add a special case for Smatch static code analyser. */
+ IMG_UINT32 aui32StreamData[];
+#else
+ IMG_UINT32 aui32StreamData[RGX_HWPERF_ONE_OR_MORE_ELEMENTS];
+ /*!< Series of tuples holding UFO objects data */
+
+ IMG_UINT32 ui32Padding; /*!< Reserved, align structure size to 8 bytes */
+#endif
+} RGX_HWPERF_HOST_UFO_DATA;
+
+/* Payload size must be multiple of 8 bytes to align start of next packet. */
+static_assert((sizeof(RGX_HWPERF_HOST_UFO_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_UFO_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+/*!
+ * RGX_HWPERF_HOST_RESOURCE_TYPE describes the type of resource which has been
+ * Allocated, Freed or Modified. The values are used to determine which event
+ * data structure to use to decode the data from the event stream
+ */
+typedef enum
+{
+ RGX_HWPERF_HOST_RESOURCE_TYPE_INVALID, /*!< Invalid */
+ RGX_HWPERF_HOST_RESOURCE_TYPE_SYNC, /*!< SyncPrim */
+ RGX_HWPERF_HOST_RESOURCE_TYPE_TIMELINE_DEPRECATED,
+ /*!< Timeline resource packets are
+ now emitted in client hwperf buffer */
+ RGX_HWPERF_HOST_RESOURCE_TYPE_FENCE_PVR, /*!< Fence for use on GPU (SYNC_CP backed) */
+ RGX_HWPERF_HOST_RESOURCE_TYPE_SYNC_CP, /*!< Sync Checkpoint */
+ RGX_HWPERF_HOST_RESOURCE_TYPE_FENCE_SW, /*!< Fence created on SW timeline */
+
+ RGX_HWPERF_HOST_RESOURCE_TYPE_LAST /*!< End of enumeration */
+} RGX_HWPERF_HOST_RESOURCE_TYPE;
+
+typedef union
+{
+ /*! Data for TYPE_TIMELINE (*Deprecated*). This sub-event is no longer
+ * generated in the HOST stream. Timeline data is now provided in the
+ * CLIENT stream instead.
+ */
+ struct
+ {
+ IMG_UINT32 uiPid; /*!< Identifier of owning process */
+ IMG_UINT64 ui64Timeline_UID1; /*!< Unique identifier for timeline resource */
+ IMG_CHAR acName[PVRSRV_SYNC_NAME_LENGTH];
+ /*!< Label or name given to the sync resource */
+ IMG_UINT32 ui32Padding; /*!< Reserved. Align structure size to 8 bytes */
+ } sTimelineAlloc;
+
+ /*! Data for TYPE_FENCE_PVR */
+ struct
+ {
+ IMG_PID uiPID; /*!< Identifier of owning process */
+ PVRSRV_FENCE hFence; /*!< Unique identifier for the fence resource */
+ IMG_UINT32 ui32CheckPt_FWAddr; /*!< Unique identifier of the check point
+ backing this fence on the GPU */
+ IMG_CHAR acName[PVRSRV_SYNC_NAME_LENGTH];
+ /*!< Label or name given to the sync resource */
+ } sFenceAlloc;
+
+ /*! Data for TYPE_SYNC_CP */
+ struct
+ {
+ IMG_UINT32 ui32CheckPt_FWAddr; /*!< Unique identifier for the check point resource */
+ PVRSRV_TIMELINE hTimeline; /*!< Unique identifier for the timeline resource */
+ IMG_PID uiPID; /*!< Identifier of owning process */
+ PVRSRV_FENCE hFence; /*!< Unique identifier for the fence resource */
+ IMG_CHAR acName[PVRSRV_SYNC_NAME_LENGTH];
+ /*!< Label or name given to the sync resource */
+ } sSyncCheckPointAlloc;
+
+ /*! Data for TYPE_FENCE_SW */
+ struct
+ {
+ IMG_PID uiPID; /*!< Identifier of owning process */
+ PVRSRV_FENCE hSWFence; /*!< Unique identifier for the SWFence resource */
+ PVRSRV_TIMELINE hSWTimeline; /*!< Unique identifier for the timeline resource */
+ IMG_UINT64 ui64SyncPtIndex; /*!< Sync-pt index where this SW timeline has reached */
+ IMG_CHAR acName[PVRSRV_SYNC_NAME_LENGTH];
+ /*!< Label or name given to the sync resource */
+ } sSWFenceAlloc;
+
+ /*! Data for TYPE_SYNC */
+ struct
+ {
+ IMG_UINT32 ui32FWAddr; /*!< Identifier of sync resource */
+ IMG_CHAR acName[PVRSRV_SYNC_NAME_LENGTH];
+ /*!< Label or name given to the sync resource */
+ } sSyncAlloc;
+} RGX_HWPERF_HOST_ALLOC_DETAIL;
+
+typedef struct
+{
+ RGX_HWPERF_HOST_RESOURCE_TYPE ui32AllocType;
+ /*!< This describes the type of the resource
+ allocated in the driver. See
+ RGX_HWPERF_HOST_RESOURCE_TYPE */
+ RGX_HWPERF_HOST_ALLOC_DETAIL RGXFW_ALIGN uAllocDetail;
+ /*!< Union of structures providing further
+ data regarding the resource allocated.
+ Size of data varies with union member that
+ is present, check ``ui32AllocType`` value
+ to decode */
+} RGX_HWPERF_HOST_ALLOC_DATA;
+
+/* Payload size must be multiple of 8 bytes to align start of next packet. */
+static_assert((sizeof(RGX_HWPERF_HOST_ALLOC_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_ALLOC_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+typedef union
+{
+ /*! Data for TYPE_TIMELINE (*Deprecated*) */
+ struct
+ {
+ IMG_UINT32 uiPid; /*!< Identifier of owning process */
+ IMG_UINT64 ui64Timeline_UID1; /*!< Unique identifier for the timeline resource */
+ IMG_UINT32 ui32Padding; /*!< Reserved. Align structure size to 8 bytes */
+ } sTimelineDestroy;
+
+ /*! Data for TYPE_FENCE_PVR */
+ struct
+ {
+ IMG_UINT64 ui64Fence_UID; /*!< Unique identifier for the fence resource */
+ IMG_UINT32 ui32Padding; /*!< Reserved. */
+ } sFenceDestroy;
+
+ /*! Data for TYPE_SYNC_CP */
+ struct
+ {
+ IMG_UINT32 ui32CheckPt_FWAddr; /*!< Unique identifier for the check point resource */
+ } sSyncCheckPointFree;
+
+ /*! Data for TYPE_SYNC */
+ struct
+ {
+ IMG_UINT32 ui32FWAddr; /*!< Unique identifier for the sync resource */
+ } sSyncFree;
+} RGX_HWPERF_HOST_FREE_DETAIL;
+
+typedef struct
+{
+ RGX_HWPERF_HOST_RESOURCE_TYPE ui32FreeType;
+ /*!< This describes the type of the resource
+ freed or released by the driver. See
+ RGX_HWPERF_HOST_RESOURCE_TYPE */
+ RGX_HWPERF_HOST_FREE_DETAIL uFreeDetail;
+ /*!< Union of structures providing further data
+ regarding the resource freed. Size of data
+ varies with union member that is present,
+ check ``ui32FreeType`` value to decode */
+ IMG_UINT32 ui32Padding; /*!< Reserved. Align structure size to 8 bytes */
+} RGX_HWPERF_HOST_FREE_DATA;
+
+/* Payload size must be multiple of 8 bytes to align start of next packet. */
+static_assert((sizeof(RGX_HWPERF_HOST_FREE_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_FREE_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+typedef struct
+{
+ IMG_UINT64 ui64CRTimestamp; /*!< CR timer value from the latest entry of
+ the time domains correlation table */
+ IMG_UINT64 ui64OSTimestamp; /*!< OS timestamp from the latest entry of the
+ time domains correlation table */
+ IMG_UINT32 ui32ClockSpeed; /*!< GPU clock speed from the latest entry of
+ the time domains correlation table */
+ IMG_UINT32 ui32Padding; /*!< Reserved, align structure size to 8 bytes */
+} RGX_HWPERF_HOST_CLK_SYNC_DATA;
+
+/* Payload size must be multiple of 8 bytes to align start of next packet. */
+static_assert((sizeof(RGX_HWPERF_HOST_CLK_SYNC_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_CLK_SYNC_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+typedef union
+{
+ /*! Data for TYPE_FENCE_PVR */
+ struct
+ {
+ IMG_UINT64 ui64NewFence_UID; /*!< Unique identifier for the new merged fence
+ resource that has been created */
+ IMG_UINT64 ui64InFence1_UID; /*!< Unique identifier for the fence resource */
+ IMG_UINT64 ui64InFence2_UID; /*!< Unique identifier of the check point backing
+ the fence on the GPU */
+ IMG_CHAR acName[PVRSRV_SYNC_NAME_LENGTH];
+ /*!< Label or name given to the sync resource */
+ IMG_UINT32 ui32Padding; /*!< Reserved. Align structure size to 8 bytes */
+ } sFenceMerge;
+} RGX_HWPERF_HOST_MODIFY_DETAIL;
+
+typedef struct
+{
+ RGX_HWPERF_HOST_RESOURCE_TYPE ui32ModifyType;
+ /*!< Describes the type of the resource
+ modified by the driver. See
+ RGX_HWPERF_HOST_RESOURCE_TYPE */
+
+ RGX_HWPERF_HOST_MODIFY_DETAIL uModifyDetail;
+ /*!< Union of structures providing further
+ data regarding the resource modified.
+ Size of data varies with union member that
+ is present.
+ Check ``uiModifyType`` value to decode */
+} RGX_HWPERF_HOST_MODIFY_DATA;
+
+/* Payload size must be multiple of 8 bytes to align start of next packet. */
+static_assert((sizeof(RGX_HWPERF_HOST_MODIFY_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_MODIFY_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+typedef enum
+{
+ RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_UNDEFINED = 0, /*!< Invalid */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_OK, /*!< Device OK */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_RESPONDING, /*!< Device responding to requests */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_DEAD, /*!< Device not responding */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_FAULT, /*!< Device has faulted */
+
+ RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS_LAST
+} RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS;
+
+typedef enum
+{
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_UNDEFINED = 0, /*!< Invalid */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_NONE, /*!< No underlying health reason. */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_ASSERTED, /*!< Device has asserted. */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_POLL_FAILING, /*!< Device poll has failed. */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_TIMEOUTS, /*!< Device timeout has fired. */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_QUEUE_CORRUPT, /*!< Queue has become corrupt. */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_QUEUE_STALLED, /*!< Queue has stalled. */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_IDLING, /*!< Device is idling. */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_RESTARTING, /*!< Device restarting. */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_MISSING_INTERRUPTS,/*!< Interrupts have been discarded. */
+
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON_LAST
+} RGX_HWPERF_HOST_DEVICE_HEALTH_REASON;
+
+/*! RGX_HWPERF_DEV_INFO_EV values */
+typedef enum
+{
+ RGX_HWPERF_DEV_INFO_EV_HEALTH, /*!< Health sub-event */
+
+ RGX_HWPERF_DEV_INFO_EV_LAST /*!< Last enumeration value */
+} RGX_HWPERF_DEV_INFO_EV;
+
+/*! RGX_HWPERF_HOST_DEV_INFO_DETAIL is a union of structures providing
+ * further data regarding the device's status
+ */
+typedef union
+{
+ /*! Data for device status event */
+ struct
+ {
+ RGX_HWPERF_HOST_DEVICE_HEALTH_STATUS eDeviceHealthStatus;
+ /*!< Device's health status */
+ RGX_HWPERF_HOST_DEVICE_HEALTH_REASON eDeviceHealthReason;
+ /*!< Reason for device's health status */
+ } sDeviceStatus;
+} RGX_HWPERF_HOST_DEV_INFO_DETAIL;
+
+/*! RGX_HWPERF_HOST_DEV_INFO_DATA contains device health status information */
+typedef struct
+{
+ IMG_UINT32 ui32Padding;
+ /*!< Reserved. Align structure size to 8 bytes */
+ RGX_HWPERF_DEV_INFO_EV eEvType;
+ /*!< Type of the sub-event. See
+ RGX_HWPERF_DEV_INFO_EV */
+ RGX_HWPERF_HOST_DEV_INFO_DETAIL uDevInfoDetail;
+ /*!< Union of structures providing further data
+ regarding the device's status. Size of data
+ varies with union member that is present,
+ check ``eEvType`` value to decode */
+} RGX_HWPERF_HOST_DEV_INFO_DATA;
+
+/* Payload size must be multiple of 8 bytes to align start of next packet. */
+static_assert((sizeof(RGX_HWPERF_HOST_DEV_INFO_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_DEV_INFO_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+/*! RGX_HWPERF_INFO_EV event subtype for RGX_HWPERF_HOST_INFO_DATA events */
+typedef enum
+{
+ RGX_HWPERF_INFO_EV_MEM_USAGE, /*!< Memory usage event */
+ RGX_HWPERF_INFO_EV_LAST /*!< End of enumeration */
+} RGX_HWPERF_INFO_EV;
+
+/*! RGX_HWPERF_HOST_INFO_DETAIL contains the data payload for the
+ * RGX_HWPERF_HOST_INFO_DATA event.
+ */
+typedef union
+{
+ /*! Host Memory usage statistics */
+ struct
+ {
+ IMG_UINT32 ui32TotalMemoryUsage; /*!< Total memory usage */
+ /*! Detailed memory usage */
+ struct
+ {
+ IMG_UINT32 ui32Pid; /*!< Process ID */
+ IMG_UINT32 ui32KernelMemUsage; /*!< Kernel memory usage */
+ IMG_UINT32 ui32GraphicsMemUsage; /*!< GPU memory usage */
+ } sPerProcessUsage[RGX_HWPERF_ZERO_OR_MORE_ELEMENTS];
+ } sMemUsageStats;
+} RGX_HWPERF_HOST_INFO_DETAIL;
+
+/*! RGX_HWPERF_HOST_INFO_DATA. Host Info data event payload contains device
+ * memory usage information.
+ */
+typedef struct
+{
+ IMG_UINT32 ui32Padding; /*!< Reserved. Align structure size to 8 bytes */
+ RGX_HWPERF_INFO_EV eEvType; /*!< Type of subevent. See RGX_HWPERF_INFO_EV */
+ RGX_HWPERF_HOST_INFO_DETAIL uInfoDetail;
+ /*!< Union of structures providing further data
+ regarding memory usage. Size varies with union
+ member that is present, check ``eEvType``
+ value to decode */
+} RGX_HWPERF_HOST_INFO_DATA;
+
+/* Payload size must be multiple of 8 bytes to align start of next packet. */
+static_assert((sizeof(RGX_HWPERF_HOST_INFO_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_INFO_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+/*! FENCE_WAIT_TYPE definitions */
+typedef enum
+{
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE_BEGIN = 0, /*!< Begin */
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE_END, /*!< End */
+
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE_LAST, /*!< Do not use */
+} RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE;
+
+/*! FENCE_WAIT_RESULT definitions */
+typedef enum
+{
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT_INVALID = 0, /*!< Invalid */
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT_TIMEOUT, /*!< Timed Out */
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT_PASSED, /*!< Passed */
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT_ERROR, /*!< Errored */
+
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT_LAST, /*!< Do not use */
+} RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT;
+
+/*! FENCE_WAIT_DETAIL Event Payload */
+typedef union
+{
+/*! Data for SYNC_FENCE_WAIT_TYPE_BEGIN */
+ struct
+ {
+ IMG_UINT32 ui32TimeoutInMs; /*!< Wait timeout (ms) */
+ } sBegin;
+
+ /*! Data for SYNC_FENCE_WAIT_TYPE_END */
+ struct
+ {
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_RESULT eResult; /*!< Wait result */
+ } sEnd;
+} RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DETAIL;
+
+/*! RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA Event Payload. This data structure
+ * is received whenever the host driver handles a wait for sync event request.
+ */
+typedef struct
+{
+ IMG_PID uiPID; /*!< Identifier of the owning process */
+ PVRSRV_FENCE hFence; /*!< Unique identifier for the fence resource */
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE eType;
+ /*!< Type of the subevent, see
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_TYPE */
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DETAIL uDetail;
+ /*!< Union of structures providing further data
+ regarding device's status. Size of data varies with
+ union member that is present, check ``eType`` value
+ to decode */
+
+} RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA;
+
+static_assert((sizeof(RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+/*! RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA.
+ * Software Timeline Advanced Event Payload. This data structure is received
+ * whenever the host driver processes a Software Timeline Advanced event.
+ */
+typedef struct
+{
+ IMG_PID uiPID; /*!< Identifier of the owning process */
+ PVRSRV_TIMELINE hTimeline; /*!< Unique identifier for the timeline resource */
+ IMG_UINT64 ui64SyncPtIndex; /*!< Index of the sync point to which the
+ timeline has advanced */
+
+} RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA;
+
+static_assert((sizeof(RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA) & (PVRSRVTL_PACKET_ALIGNMENT-1U)) == 0U,
+ "sizeof(RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA) must be a multiple PVRSRVTL_PACKET_ALIGNMENT");
+
+typedef enum
+{
+ RGX_HWPERF_RESOURCE_CAPTURE_TYPE_NONE,
+ RGX_HWPERF_RESOURCE_CAPTURE_TYPE_DEFAULT_FRAMEBUFFER,
+ RGX_HWPERF_RESOURCE_CAPTURE_TYPE_OFFSCREEN_FB_ATTACHMENTS,
+ RGX_HWPERF_RESOURCE_CAPTURE_TYPE_TILE_LIFETIME_DATA,
+
+ RGX_HWPERF_RESOURCE_TYPE_COUNT
+} RGX_HWPERF_RESOURCE_CAPTURE_TYPE;
+
+typedef struct
+{
+ IMG_UINT32 ui32Height;
+ IMG_UINT32 ui32Width;
+ IMG_UINT32 ui32BPP;
+ IMG_UINT32 ui32PixFormat;
+} RGX_RESOURCE_PER_SURFACE_INFO, *PRGX_RESOURCE_PER_SURFACE_INFO;
+
+typedef struct
+{
+ IMG_INT32 i32XOffset; /*!< render surface X shift */
+ IMG_INT32 i32YOffset; /*!< render surface Y shift */
+ IMG_UINT32 ui32WidthInTiles; /*!< number of TLT data points in X */
+ IMG_UINT32 ui32HeightInTiles; /*!< number of TLT data points in Y */
+} RGX_RESOURCE_PER_TLT_BUFFER_INFO, *PRGX_RESOURCE_PER_TLT_BUFFER_INFO;
+
+typedef union
+{
+ struct RGX_RESOURCE_CAPTURE_RENDER_SURFACES
+ {
+ IMG_UINT32 ui32RenderSurfaceCount;
+ RGX_RESOURCE_PER_SURFACE_INFO sSurface[RGX_HWPERF_ONE_OR_MORE_ELEMENTS];
+ } sRenderSurfaces;
+
+ struct RGX_RESOURCE_CAPTURE_TILE_LIFETIME_BUFFERS
+ {
+ RGX_RESOURCE_PER_TLT_BUFFER_INFO sTLTBufInfo[RGX_HWPERF_ONE_OR_MORE_ELEMENTS];
+ } sTLTBuffers;
+} RGX_RESOURCE_CAPTURE_DETAIL;
+
+typedef struct
+{
+ RGX_HWPERF_RESOURCE_CAPTURE_TYPE eType;
+ IMG_PID uPID;
+ IMG_UINT32 ui32ContextID;
+ IMG_UINT32 ui32FrameNum;
+ IMG_UINT32 ui32CapturedTaskJobRef; /* The job ref of the HW task that emitted the data */
+ IMG_INT32 eClientModule; /* RGX_HWPERF_CLIENT_API - ID that the capture is originating from. */
+ RGX_RESOURCE_CAPTURE_DETAIL uDetail; /* eType determines the value of the union */
+} RGX_RESOURCE_CAPTURE_INFO, *PRGX_RESOURCE_CAPTURE_INFO;
+
+#define RGX_RESOURCE_CAPTURE_INFO_BASE_SIZE() offsetof(RGX_RESOURCE_CAPTURE_INFO, uDetail)
+
+/*! Tile Lifetime Tracking header size. Only available if
+ * RGX_FEATURE_ISP_TILE_LIFETIME_TRACKING is present and enabled via
+ * SUPPORT_TLT_PERF
+ */
+#define RGX_TLT_HARDWARE_HDR_SIZE (16U)
+
+/* PVRSRVGetHWPerfResourceCaptureResult */
+typedef enum
+{
+ RGX_HWPERF_RESOURCE_CAPTURE_RESULT_NONE = 0,
+ RGX_HWPERF_RESOURCE_CAPTURE_RESULT_OK, /* We got data ok, expect more packets for this request. */
+ RGX_HWPERF_RESOURCE_CAPTURE_RESULT_NOT_READY, /* Signals a timeout on the connection - no data available yet. */
+ RGX_HWPERF_RESOURCE_CAPTURE_RESULT_COMPLETE_SUCCESS, /* The request completed successfully, signals the end of packets for the request. */
+ RGX_HWPERF_RESOURCE_CAPTURE_RESULT_COMPLETE_FAILURE /* The request failed, signals the end of packets for the request. */
+} RGX_HWPERF_RESOURCE_CAPTURE_RESULT_STATUS;
+
+typedef struct
+{
+ IMG_PID uPID; /* In case of a failed request pass the caller the PID and context ID. */
+ IMG_UINT32 ui32CtxID;
+ RGX_RESOURCE_CAPTURE_INFO *psInfo; /* Various meta-data regarding the captured resource which aid the requester when,
+ unpacking the resource data, valid if RGX_HWPERF_RESOURCE_CAPTURE_RESULT_OK is returned. */
+ IMG_BYTE *pbData; /* Buffer containing the captured resource data, valid if RGX_HWPERF_RESOURCE_CAPTURE_RESULT_OK is returned. */
+} RGX_RESOURCE_CAPTURE_RESULT;
+
+/*! This type is a union of packet payload data structures associated with
+ * various FW and Host events */
+typedef union
+{
+ RGX_HWPERF_FW_DATA sFW; /*!< Firmware event packet data,
+ events ``0x01-0x06`` */
+ RGX_HWPERF_HW_DATA sHW; /*!< Hardware event packet data,
+ events ``0x07-0x19``, ``0x28-0x29`` */
+ RGX_HWPERF_CLKS_CHG_DATA sCLKSCHG; /*!< Clock change event packet
+ data, events ``0x1A`` */
+ RGX_HWPERF_GPU_STATE_CHG_DATA sGPUSTATECHG; /*!< GPU utilisation state
+ change event packet data,
+ events ``0x1B`` */
+ RGX_HWPERF_PWR_EST_DATA sPWREST; /*!< Power estimate event
+ packet data,
+ events ``0x20-0x22`` */
+ RGX_HWPERF_PWR_CHG_DATA sPWR; /*!< Power event packet data,
+ events ``0x23`` */
+ RGX_HWPERF_CSW_DATA sCSW; /*!< Context switch packet data,
+ events ``0x30-0x31`` */
+ RGX_HWPERF_DVFS_DATA sDVFS; /*!< DVFS activity data,
+ events ``0x32`` */
+ RGX_HWPERF_UFO_DATA sUFO; /*!< UFO data, events ``0x38`` */
+ RGX_HWPERF_FWACT_DATA sFWACT; /*!< Firmware activity event
+ packet data,
+ events ``0x39`` */
+ /* */
+ RGX_HWPERF_HOST_ENQ_DATA sENQ; /*!< Host ENQ data,
+ events ``0x01`` (Host) */
+ RGX_HWPERF_HOST_UFO_DATA sHUFO; /*!< Host UFO data,
+ events ``0x02`` (Host) */
+ RGX_HWPERF_HOST_ALLOC_DATA sHALLOC; /*!< Host Alloc data,
+ events ``0x03`` (Host) */
+ RGX_HWPERF_HOST_CLK_SYNC_DATA sHCLKSYNC; /*!< Host CLK_SYNC data,
+ events ``0x04`` (Host) */
+ RGX_HWPERF_HOST_FREE_DATA sHFREE; /*!< Host Free data,
+ events ``0x05`` (Host) */
+ RGX_HWPERF_HOST_MODIFY_DATA sHMOD; /*!< Host Modify data,
+ events ``0x06`` (Host) */
+ RGX_HWPERF_HOST_DEV_INFO_DATA sHDEVINFO; /*!< Host device info data,
+ events ``0x07`` (Host) */
+ RGX_HWPERF_HOST_INFO_DATA sHINFO; /*!< Host info data,
+ events ``0x08`` (Host) */
+ RGX_HWPERF_HOST_SYNC_FENCE_WAIT_DATA sWAIT; /*!< Host fence-wait data,
+ events ``0x09`` (Host) */
+ RGX_HWPERF_HOST_SYNC_SW_TL_ADV_DATA sSWTLADV; /*!< Host SW-timeline advance
+ data, events ``0x0A`` (Host) */
+} RGX_HWPERF_V2_PACKET_DATA, *RGX_PHWPERF_V2_PACKET_DATA;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_V2_PACKET_DATA);
+
+#define RGX_HWPERF_GET_PACKET_DATA(_packet_addr) ((RGX_PHWPERF_V2_PACKET_DATA) (IMG_OFFSET_ADDR((_packet_addr), sizeof(RGX_HWPERF_V2_PACKET_HDR))))
+
+#define RGX_HWPERF_GET_DVFS_EVENT_TYPE_PTR(_packet_addr) \
+ ((RGX_HWPERF_DVFS_EV*) (IMG_OFFSET_ADDR((_packet_addr), sizeof(RGX_HWPERF_V2_PACKET_HDR) + offsetof(RGX_HWPERF_DVFS_DATA,eEventType))))
+
+/******************************************************************************
+ * API Types
+ *****************************************************************************/
+
+/*! Counter block IDs for all the hardware blocks with counters.
+ * Directly addressable blocks must have a value between 0..15 [0..0xF].
+ * Indirect groups have following encoding:
+ * First hex digit (LSB) represents a unit number within the group
+ * and the second hex digit represents the group number.
+ * Group 0 is the direct group, all others are indirect groups.
+ */
+typedef IMG_UINT32 RGX_HWPERF_CNTBLK_ID;
+
+/*! Directly addressable non bank-switched counter blocks */
+#define RGX_CNTBLK_ID_JONES 0x0000U
+#define RGX_CNTBLK_ID_SLC 0x0001U /*!< SLC-specific counter control */
+#define RGX_CNTBLK_ID_FBCDC 0x0002U
+#define RGX_CNTBLK_ID_FW_CUSTOM 0x0003U /*!< Custom FW provided counters */
+
+/*! Directly addressable SLC counter blocks - presence depends on GPU. */
+#define RGX_CNTBLK_ID_SLCBANK0 0x0004U /*!< SLCBANK0 counter control */
+#define RGX_CNTBLK_ID_SLCBANK1 0x0005U /*!< SLCBANK1 counter control */
+#define RGX_CNTBLK_ID_SLCBANK2 0x0006U /*!< SLCBANK2 counter control */
+#define RGX_CNTBLK_ID_SLCBANK3 0x0007U /*!< SLCBANK3 counter control */
+#define RGX_CNTBLK_ID_SLCBANK_ALL 0x4004U /*!< SLC ALL block ID */
+
+#define RGX_CNTBLK_ID_DIRECT_LAST 0x0008U /*!< Indirect blocks start from here */
+
+/*! Indirectly addressable counter blocks */
+#define RGX_CNTBLK_ID_ISP0 0x0010U /*!< ISP 1..N ISP */
+#define RGX_CNTBLK_ID_ISP1 0x0011U
+#define RGX_CNTBLK_ID_ISP2 0x0012U
+#define RGX_CNTBLK_ID_ISP3 0x0013U
+#define RGX_CNTBLK_ID_ISP4 0x0014U
+#define RGX_CNTBLK_ID_ISP5 0x0015U
+#define RGX_CNTBLK_ID_ISP6 0x0016U
+#define RGX_CNTBLK_ID_ISP7 0x0017U
+#define RGX_CNTBLK_ID_ISP_ALL 0x4010U
+
+#define RGX_CNTBLK_ID_MERCER0 0x0020U /*!< MERCER 1..N MERCER */
+#define RGX_CNTBLK_ID_MERCER1 0x0021U
+#define RGX_CNTBLK_ID_MERCER2 0x0022U
+#define RGX_CNTBLK_ID_MERCER3 0x0023U
+#define RGX_CNTBLK_ID_MERCER4 0x0024U
+#define RGX_CNTBLK_ID_MERCER5 0x0025U
+#define RGX_CNTBLK_ID_MERCER6 0x0026U
+#define RGX_CNTBLK_ID_MERCER7 0x0027U
+#define RGX_CNTBLK_ID_MERCER_ALL 0x4020U
+
+#define RGX_CNTBLK_ID_PBE0 0x0030U /*!< PBE 1..N PBE_PER_SPU x N SPU */
+#define RGX_CNTBLK_ID_PBE1 0x0031U
+#define RGX_CNTBLK_ID_PBE2 0x0032U
+#define RGX_CNTBLK_ID_PBE3 0x0033U
+#define RGX_CNTBLK_ID_PBE4 0x0034U
+#define RGX_CNTBLK_ID_PBE5 0x0035U
+#define RGX_CNTBLK_ID_PBE6 0x0036U
+#define RGX_CNTBLK_ID_PBE7 0x0037U
+#define RGX_CNTBLK_ID_PBE_ALL 0x4030U
+
+#define RGX_CNTBLK_ID_PBE_SHARED0 0x0040U /*!< PBE_SHARED 1..N SPU */
+#define RGX_CNTBLK_ID_PBE_SHARED1 0x0041U
+#define RGX_CNTBLK_ID_PBE_SHARED2 0x0042U
+#define RGX_CNTBLK_ID_PBE_SHARED3 0x0043U
+#define RGX_CNTBLK_ID_PBE_SHARED_ALL 0x4040U
+
+#define RGX_CNTBLK_ID_USC0 0x0050U /*!< USC 1..N USC */
+#define RGX_CNTBLK_ID_USC1 0x0051U
+#define RGX_CNTBLK_ID_USC2 0x0052U
+#define RGX_CNTBLK_ID_USC3 0x0053U
+#define RGX_CNTBLK_ID_USC4 0x0054U
+#define RGX_CNTBLK_ID_USC5 0x0055U
+#define RGX_CNTBLK_ID_USC6 0x0056U
+#define RGX_CNTBLK_ID_USC7 0x0057U
+#define RGX_CNTBLK_ID_USC_ALL 0x4050U
+
+#define RGX_CNTBLK_ID_TPU0 0x0060U /*!< TPU 1..N TPU */
+#define RGX_CNTBLK_ID_TPU1 0x0061U
+#define RGX_CNTBLK_ID_TPU2 0x0062U
+#define RGX_CNTBLK_ID_TPU3 0x0063U
+#define RGX_CNTBLK_ID_TPU4 0x0064U
+#define RGX_CNTBLK_ID_TPU5 0x0065U
+#define RGX_CNTBLK_ID_TPU6 0x0066U
+#define RGX_CNTBLK_ID_TPU7 0x0067U
+#define RGX_CNTBLK_ID_TPU_ALL 0x4060U
+
+#define RGX_CNTBLK_ID_SWIFT0 0x0070U /*!< SWIFT 1..N SWIFT */
+#define RGX_CNTBLK_ID_SWIFT1 0x0071U
+#define RGX_CNTBLK_ID_SWIFT2 0x0072U
+#define RGX_CNTBLK_ID_SWIFT3 0x0073U
+#define RGX_CNTBLK_ID_SWIFT4 0x0074U
+#define RGX_CNTBLK_ID_SWIFT5 0x0075U
+#define RGX_CNTBLK_ID_SWIFT6 0x0076U
+#define RGX_CNTBLK_ID_SWIFT7 0x0077U
+#define RGX_CNTBLK_ID_SWIFT_ALL 0x4070U
+
+#define RGX_CNTBLK_ID_TEXAS0 0x0080U /*!< TEXAS 1..N TEXAS */
+#define RGX_CNTBLK_ID_TEXAS1 0x0081U
+#define RGX_CNTBLK_ID_TEXAS2 0x0082U
+#define RGX_CNTBLK_ID_TEXAS3 0x0083U
+#define RGX_CNTBLK_ID_TEXAS_ALL 0x4080U
+
+#define RGX_CNTBLK_ID_RAC0 0x0090U /*!< RAC 1..N RAC */
+#define RGX_CNTBLK_ID_RAC1 0x0091U
+#define RGX_CNTBLK_ID_RAC2 0x0092U
+#define RGX_CNTBLK_ID_RAC3 0x0093U
+#define RGX_CNTBLK_ID_RAC_ALL 0x4090U
+
+#define RGX_CNTBLK_ID_LAST 0x0094U /*!< End of RAC block */
+
+/*! Masks for the counter block ID*/
+#define RGX_CNTBLK_ID_UNIT_MASK (0x000FU) /*!< Unit within group */
+#define RGX_CNTBLK_ID_GROUP_MASK (0x00F0U) /*!< Group value */
+#define RGX_CNTBLK_ID_GROUP_SHIFT (4U)
+#define RGX_CNTBLK_ID_MC_GPU_MASK (0x0F00U) /*!< GPU ID for MC use */
+#define RGX_CNTBLK_ID_MC_GPU_SHIFT (8U)
+#define RGX_CNTBLK_ID_UNIT_ALL_MASK (0x4000U) /*!< Program all units within a group */
+
+static_assert(
+ ((RGX_CNTBLK_ID_DIRECT_LAST + ((RGX_CNTBLK_ID_LAST & RGX_CNTBLK_ID_GROUP_MASK) >> RGX_CNTBLK_ID_GROUP_SHIFT)) <= RGX_HWPERF_MAX_BVNC_BLOCK_LEN),
+ "RGX_HWPERF_MAX_BVNC_BLOCK_LEN insufficient");
+
+#define RGX_HWPERF_EVENT_MASK_VALUE(e) (IMG_UINT64_C(1) << (e))
+
+/* When adding new counters here, make sure changes are made to rgxfw_hwperf_fwblk_valid() as well */
+#define RGX_CUSTOM_FW_CNTRS \
+ X(TA_LOCAL_FL_SIZE, 0x0, RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_TAKICK) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_PMOOM_TAPAUSE) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_PMOOM_TARESUME) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_TAFINISHED)) \
+ \
+ X(TA_GLOBAL_FL_SIZE, 0x1, RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_TAKICK) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_PMOOM_TAPAUSE) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_PMOOM_TARESUME) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_TAFINISHED)) \
+ \
+ X(3D_LOCAL_FL_SIZE, 0x2, RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_3DKICK) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_3DFINISHED)) \
+ \
+ X(3D_GLOBAL_FL_SIZE, 0x3, RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_3DKICK) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_3DFINISHED)) \
+ \
+ X(ISP_TILES_IN_FLIGHT, 0x4, RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_3DKICK) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_3DSPMKICK))
+
+/*! Counter IDs for the firmware held statistics */
+typedef enum
+{
+#define X(ctr, id, allow_mask) RGX_CUSTOM_FW_CNTR_##ctr = id,
+ RGX_CUSTOM_FW_CNTRS
+#undef X
+
+ /* always the last entry in the list */
+ RGX_CUSTOM_FW_CNTR_LAST
+} RGX_HWPERF_CUSTOM_FW_CNTR_ID;
+
+/*! Identifier for each counter in a performance counting module */
+typedef IMG_UINT32 RGX_HWPERF_CNTBLK_COUNTER_ID;
+
+/* sets all the bits from bit _b1 to _b2, in a IMG_UINT64 type */
+#define MASK_RANGE_IMPL(b1, b2) ((IMG_UINT64)((IMG_UINT64_C(1) << ((IMG_UINT32)(b2)-(IMG_UINT32)(b1) + 1U)) - 1U) << (IMG_UINT32)b1)
+#define MASK_RANGE(R) MASK_RANGE_IMPL(R##_FIRST_TYPE, R##_LAST_TYPE)
+#define RGX_HWPERF_HOST_EVENT_MASK_VALUE(e) (IMG_UINT32_C(1) << (e))
+
+/*! Mask macros for use with RGXCtrlHWPerf() API.
+ */
+#define RGX_HWPERF_EVENT_MASK_NONE (IMG_UINT64_C(0x0000000000000000))
+#define RGX_HWPERF_EVENT_MASK_DEFAULT RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_FWACT) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_PWR_CHG) | \
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_CLKS_CHG)
+#define RGX_HWPERF_EVENT_MASK_ALL (IMG_UINT64_C(0xFFFFFFFFFFFFFFFF))
+
+/*! HWPerf Firmware event masks
+ * @par
+ * All FW Start/End/Debug (SED) events. */
+#define RGX_HWPERF_EVENT_MASK_FW_SED (MASK_RANGE(RGX_HWPERF_FW_EVENT_RANGE))
+
+#define RGX_HWPERF_EVENT_MASK_FW_UFO (RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_UFO))
+#define RGX_HWPERF_EVENT_MASK_FW_CSW (RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_CSW_START) |\
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_CSW_FINISHED))
+/*! All FW events. */
+#define RGX_HWPERF_EVENT_MASK_ALL_FW (RGX_HWPERF_EVENT_MASK_FW_SED |\
+ RGX_HWPERF_EVENT_MASK_FW_UFO |\
+ RGX_HWPERF_EVENT_MASK_FW_CSW)
+
+/*! HW Periodic events (1ms interval). */
+#define RGX_HWPERF_EVENT_MASK_HW_PERIODIC (RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_HW_PERIODIC))
+/*! All HW Kick/Finish events. */
+#define RGX_HWPERF_EVENT_MASK_HW_KICKFINISH ((MASK_RANGE(RGX_HWPERF_HW_EVENT_RANGE0) |\
+ MASK_RANGE(RGX_HWPERF_HW_EVENT_RANGE1)) &\
+ ~(RGX_HWPERF_EVENT_MASK_HW_PERIODIC))
+
+#define RGX_HWPERF_EVENT_MASK_ALL_HW (RGX_HWPERF_EVENT_MASK_HW_KICKFINISH |\
+ RGX_HWPERF_EVENT_MASK_HW_PERIODIC)
+
+#define RGX_HWPERF_EVENT_MASK_ALL_PWR_EST (MASK_RANGE(RGX_HWPERF_PWR_EST_RANGE))
+
+#define RGX_HWPERF_EVENT_MASK_ALL_PWR (RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_CLKS_CHG) |\
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_GPU_STATE_CHG) |\
+ RGX_HWPERF_EVENT_MASK_VALUE(RGX_HWPERF_PWR_CHG))
+
+/*! HWPerf Host event masks
+ */
+#define RGX_HWPERF_EVENT_MASK_HOST_WORK_ENQ (RGX_HWPERF_HOST_EVENT_MASK_VALUE(RGX_HWPERF_HOST_ENQ))
+#define RGX_HWPERF_EVENT_MASK_HOST_ALL_UFO (RGX_HWPERF_HOST_EVENT_MASK_VALUE(RGX_HWPERF_HOST_UFO))
+#define RGX_HWPERF_EVENT_MASK_HOST_ALL_PWR (RGX_HWPERF_HOST_EVENT_MASK_VALUE(RGX_HWPERF_HOST_CLK_SYNC))
+
+
+/*! Type used in the RGX API RGXConfigHWPerfCounters() */
+typedef struct
+{
+ /*! Reserved for future use */
+ IMG_UINT32 ui32Reserved;
+
+ /*! Counter block ID, see RGX_HWPERF_CNTBLK_ID */
+ IMG_UINT16 ui16BlockID;
+
+ /*! Number of configured counters within this block */
+ IMG_UINT16 ui16NumCounters;
+
+ /*! Counter register values */
+ IMG_UINT16 ui16Counters[RGX_CNTBLK_COUNTERS_MAX];
+
+} UNCACHED_ALIGN RGX_HWPERF_CONFIG_CNTBLK;
+
+RGX_FW_STRUCT_SIZE_ASSERT(RGX_HWPERF_CONFIG_CNTBLK);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* RGX_HWPERF_H_ */
+
+/******************************************************************************
+ End of file
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/volcanic/rgx_hwperf_table.h b/drivers/gpu/drm/img-rogue/include/volcanic/rgx_hwperf_table.h
new file mode 100644
index 000000000..5c206e951
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/volcanic/rgx_hwperf_table.h
@@ -0,0 +1,511 @@
+/*************************************************************************/ /*!
+@File
+@Title HWPerf counter table header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Utility functions used internally for HWPerf data retrieval
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef RGX_HWPERF_TABLE_H
+#define RGX_HWPERF_TABLE_H
+
+#include "img_types.h"
+#include "img_defs.h"
+#include "rgx_fwif_hwperf.h"
+
+/*****************************************************************************/
+
+/* Forward declaration */
+typedef struct RGXFW_HWPERF_CNTBLK_TYPE_MODEL_ RGXFW_HWPERF_CNTBLK_TYPE_MODEL;
+
+/* Function pointer type for functions to check dynamic power state of
+ * counter block instance. Used only in firmware. */
+typedef IMG_BOOL (*PFN_RGXFW_HWPERF_CNTBLK_POWERED)(
+ RGX_HWPERF_CNTBLK_ID eBlkType,
+ IMG_UINT8 ui8UnitId);
+
+/* Counter block run-time info */
+typedef struct
+{
+ IMG_UINT32 uiNumUnits; /* Number of instances of this block type in the core */
+} RGX_HWPERF_CNTBLK_RT_INFO;
+
+/* Function pointer type for functions to check block is valid and present
+ * on that RGX Device at runtime. It may have compile logic or run-time
+ * logic depending on where the code executes: server, srvinit or firmware.
+ * Values in the psRtInfo output parameter are only valid if true returned.
+ */
+typedef IMG_BOOL (*PFN_RGXFW_HWPERF_CNTBLK_PRESENT)(
+ const struct RGXFW_HWPERF_CNTBLK_TYPE_MODEL_* psBlkTypeDesc,
+ const void *pvDev_km,
+ RGX_HWPERF_CNTBLK_RT_INFO *psRtInfo);
+
+/* This structure encodes properties of a type of performance counter block.
+ * The structure is sometimes referred to as a block type descriptor. These
+ * properties contained in this structure represent the columns in the block
+ * type model table variable below. These values vary depending on the build
+ * BVNC and core type.
+ * Each direct block has a unique type descriptor and each indirect group has
+ * a type descriptor.
+ */
+struct RGXFW_HWPERF_CNTBLK_TYPE_MODEL_
+{
+ IMG_UINT32 uiCntBlkIdBase; /* The starting block id for this block type */
+ IMG_UINT32 uiIndirectReg; /* 0 if direct type otherwise the indirect register value to select indirect unit */
+ IMG_UINT32 uiNumUnits; /* Number of instances of this block type in the core (compile time use) */
+ const IMG_CHAR *pszBlockNameComment; /* Name of the PERF register. Used while dumping the perf counters to pdumps */
+ PFN_RGXFW_HWPERF_CNTBLK_POWERED pfnIsBlkPowered; /* A function to determine dynamic power state for the block type */
+ PFN_RGXFW_HWPERF_CNTBLK_PRESENT pfnIsBlkPresent; /* A function to determine presence on RGX Device at run-time */
+ IMG_UINT16 *pszBlkCfgValid; /* Array of supported counters per block type */
+};
+
+/*****************************************************************************/
+
+/* Shared compile-time context ASSERT macro */
+#if defined(RGX_FIRMWARE)
+/* firmware context */
+# define DBG_ASSERT(_c) RGXFW_ASSERT((_c))
+#else
+/* host client/server context */
+# define DBG_ASSERT(_c) PVR_ASSERT((_c))
+#endif
+
+/*****************************************************************************
+ RGXFW_HWPERF_CNTBLK_TYPE_MODEL struct PFNs pfnIsBlkPowered()
+
+ Referenced in gasCntBlkTypeModel[] table below and only called from
+ RGX_FIRMWARE run-time context. Therefore compile time configuration is used.
+ *****************************************************************************/
+
+#if defined(RGX_FIRMWARE) && defined(RGX_FEATURE_PERFBUS)
+# include "rgxfw_pow.h"
+# include "rgxfw_utils.h"
+
+static inline IMG_BOOL rgxfw_hwperf_pow_st_direct(RGX_HWPERF_CNTBLK_ID eBlkType, IMG_UINT8 ui8UnitId);
+static inline IMG_BOOL rgxfw_hwperf_pow_st_direct(RGX_HWPERF_CNTBLK_ID eBlkType, IMG_UINT8 ui8UnitId)
+{
+ PVR_UNREFERENCED_PARAMETER(ui8UnitId);
+
+ switch (eBlkType)
+ {
+ case RGX_CNTBLK_ID_JONES:
+ case RGX_CNTBLK_ID_SLC:
+ case RGX_CNTBLK_ID_SLCBANK0:
+ case RGX_CNTBLK_ID_FBCDC:
+ case RGX_CNTBLK_ID_FW_CUSTOM:
+ return IMG_TRUE;
+
+#if !defined(RGX_FEATURE_CATURIX_TOP_INFRASTRUCTURE)
+ case RGX_CNTBLK_ID_SLCBANK1:
+ if (RGX_FEATURE_NUM_MEMBUS > 1U)
+ {
+ return IMG_TRUE;
+ }
+ else
+ {
+ return IMG_FALSE;
+ }
+
+ case RGX_CNTBLK_ID_SLCBANK2:
+ case RGX_CNTBLK_ID_SLCBANK3:
+ if (RGX_FEATURE_NUM_MEMBUS > 2U)
+ {
+ return IMG_TRUE;
+ }
+ else
+ {
+ return IMG_FALSE;
+ }
+#endif /* !defined(RGX_FEATURE_CATURIX_TOP_INFRASTRUCTURE) */
+
+ default:
+ return IMG_FALSE;
+ }
+}
+
+/* Only use conditional compilation when counter blocks appear in different
+ * islands for different Rogue families.
+ */
+static inline IMG_BOOL rgxfw_hwperf_pow_st_indirect(RGX_HWPERF_CNTBLK_ID eBlkType, IMG_UINT8 ui8UnitId);
+static inline IMG_BOOL rgxfw_hwperf_pow_st_indirect(RGX_HWPERF_CNTBLK_ID eBlkType, IMG_UINT8 ui8UnitId)
+{
+ PVR_UNREFERENCED_PARAMETER(ui8UnitId);
+
+ IMG_UINT32 ui32NumDustsEnabled = rgxfw_pow_get_enabled_units();
+
+ // We don't have any Dusts Enabled until first DC opens the GPU. This makes
+ // setting the PDump HWPerf trace buffers very difficult.
+ // To work around this we special-case some of the 'have to be there'
+ // indirect registers (e.g., TPU0)
+
+ switch (eBlkType)
+ {
+ case RGX_CNTBLK_ID_TPU0:
+ return IMG_TRUE;
+ /*NOTREACHED*/
+ break;
+ default:
+ if (((gsPowCtl.eUnitsPowState & RGXFW_POW_ST_RD_ON) != 0U) &&
+ (ui32NumDustsEnabled > 0U))
+ {
+ return IMG_TRUE;
+ }
+ else
+ {
+ return IMG_FALSE;
+ }
+ /*NOTREACHED*/
+ break;
+ }
+ return IMG_TRUE;
+}
+
+#else /* !defined(RGX_FIRMWARE) || !defined(RGX_FEATURE_PERFBUS) */
+
+# define rgxfw_hwperf_pow_st_direct ((void *)NULL)
+# define rgxfw_hwperf_pow_st_indirect ((void *)NULL)
+
+#endif /* !defined(RGX_FIRMWARE) || !defined(RGX_FEATURE_PERFBUS) */
+
+/*****************************************************************************
+ RGXFW_HWPERF_CNTBLK_TYPE_MODEL struct PFNs pfnIsBlkPowered() end
+ *****************************************************************************/
+
+/*****************************************************************************
+ RGXFW_HWPERF_CNTBLK_TYPE_MODEL struct PFNs pfnIsBlkPresent() start
+
+ Referenced in gasCntBlkTypeModel[] table below and called from all build
+ contexts:
+ RGX_FIRMWARE, PVRSRVCTL (UM) and PVRSRVKM (Server).
+
+ Therefore each function has two implementations, one for compile time and one
+ run time configuration depending on the context. The functions will inform the
+ caller whether this block is valid for this particular RGX device. Other
+ run-time dependent data is returned in psRtInfo for the caller to use.
+ *****************************************************************************/
+
+
+/* Used for all block types: Direct and Indirect */
+static inline IMG_BOOL rgx_hwperf_blk_present(const RGXFW_HWPERF_CNTBLK_TYPE_MODEL* psBlkTypeDesc, const void *pvDev_km, RGX_HWPERF_CNTBLK_RT_INFO *psRtInfo)
+{
+#if defined(__KERNEL__) /* Server context -- Run-time Only */
+ PVRSRV_RGXDEV_INFO *psDevInfo = (PVRSRV_RGXDEV_INFO *)pvDev_km;
+ PVRSRV_DEVICE_NODE *psNode;
+ IMG_UINT32 ui32MaxTPUPerSPU;
+ IMG_UINT32 ui32NumMemBus;
+ IMG_UINT32 ui32RTArchVal;
+
+ DBG_ASSERT(psDevInfo != NULL);
+ DBG_ASSERT(psBlkTypeDesc != NULL);
+ DBG_ASSERT(psRtInfo != NULL);
+
+ if (((psDevInfo == NULL) || (psBlkTypeDesc == NULL)) || (psRtInfo == NULL))
+ {
+ return IMG_FALSE;
+ }
+
+ psNode = psDevInfo->psDeviceNode;
+ DBG_ASSERT(psNode != NULL);
+
+ if (psNode == NULL)
+ {
+ return IMG_FALSE;
+ }
+
+ ui32MaxTPUPerSPU =
+ PVRSRV_GET_DEVICE_FEATURE_VALUE(psNode, MAX_TPU_PER_SPU);
+
+ if (PVRSRV_IS_FEATURE_SUPPORTED(psNode, CATURIX_TOP_INFRASTRUCTURE))
+ {
+ ui32NumMemBus = 1U;
+ }
+ else
+ {
+ ui32NumMemBus =
+ PVRSRV_GET_DEVICE_FEATURE_VALUE(psNode, NUM_MEMBUS);
+ }
+
+ ui32RTArchVal =
+ PVRSRV_GET_DEVICE_FEATURE_VALUE(psNode, RAY_TRACING_ARCH);
+
+ switch (psBlkTypeDesc->uiCntBlkIdBase)
+ {
+ case RGX_CNTBLK_ID_JONES:
+ case RGX_CNTBLK_ID_SLC:
+ case RGX_CNTBLK_ID_SLCBANK0:
+ case RGX_CNTBLK_ID_FBCDC:
+ case RGX_CNTBLK_ID_FW_CUSTOM:
+ psRtInfo->uiNumUnits = 1;
+ break;
+
+#if !defined(RGX_FEATURE_CATURIX_TOP_INFRASTRUCTURE)
+ case RGX_CNTBLK_ID_SLCBANK1:
+ if (ui32NumMemBus >= 2U)
+ {
+ psRtInfo->uiNumUnits = 1;
+ }
+ else
+ {
+ psRtInfo->uiNumUnits = 0;
+ }
+ break;
+
+ case RGX_CNTBLK_ID_SLCBANK2:
+ case RGX_CNTBLK_ID_SLCBANK3:
+ if (ui32NumMemBus > 2U)
+ {
+ psRtInfo->uiNumUnits = 1;
+ }
+ else
+ {
+ psRtInfo->uiNumUnits = 0;
+ }
+ break;
+#endif /* !defined(RGX_FEATURE_CATURIX_TOP_INFRASTRUCTURE) */
+
+ case RGX_CNTBLK_ID_TPU0:
+ case RGX_CNTBLK_ID_SWIFT0:
+ psRtInfo->uiNumUnits =
+ PVRSRV_GET_DEVICE_FEATURE_VALUE(psNode, NUM_SPU);
+ psRtInfo->uiNumUnits *= ui32MaxTPUPerSPU;
+ break;
+
+ case RGX_CNTBLK_ID_TEXAS0:
+ case RGX_CNTBLK_ID_PBE_SHARED0:
+
+ psRtInfo->uiNumUnits =
+ PVRSRV_GET_DEVICE_FEATURE_VALUE(psNode, NUM_SPU);
+ break;
+
+ case RGX_CNTBLK_ID_RAC0:
+ if (ui32RTArchVal > 2U)
+ {
+ psRtInfo->uiNumUnits =
+ PVRSRV_GET_DEVICE_FEATURE_VALUE(psNode, NUM_SPU);
+ }
+ else
+ {
+ psRtInfo->uiNumUnits = 0;
+ }
+ break;
+
+ case RGX_CNTBLK_ID_USC0:
+ case RGX_CNTBLK_ID_MERCER0:
+ psRtInfo->uiNumUnits =
+ PVRSRV_GET_DEVICE_FEATURE_VALUE(psNode, NUM_CLUSTERS);
+ break;
+
+ case RGX_CNTBLK_ID_PBE0:
+
+ psRtInfo->uiNumUnits =
+ PVRSRV_GET_DEVICE_FEATURE_VALUE(psNode, PBE_PER_SPU);
+ psRtInfo->uiNumUnits *=
+ PVRSRV_GET_DEVICE_FEATURE_VALUE(psNode, NUM_SPU);
+ break;
+
+ case RGX_CNTBLK_ID_ISP0:
+
+ psRtInfo->uiNumUnits =
+ PVRSRV_GET_DEVICE_FEATURE_VALUE(psNode, NUM_ISP_PER_SPU);
+ /* Adjust by NUM_SPU */
+
+ psRtInfo->uiNumUnits *=
+ PVRSRV_GET_DEVICE_FEATURE_VALUE(psNode, NUM_SPU);
+ break;
+
+ default:
+ return IMG_FALSE;
+ }
+ /* Verify that we have at least one unit present */
+ if (psRtInfo->uiNumUnits > 0U)
+ {
+ return IMG_TRUE;
+ }
+ else
+ {
+ return IMG_FALSE;
+ }
+#else /* FW context -- Compile-time only */
+ IMG_UINT32 ui32NumMemBus;
+ PVR_UNREFERENCED_PARAMETER(pvDev_km);
+ DBG_ASSERT(psBlkTypeDesc != NULL);
+
+ if (unlikely(psBlkTypeDesc == NULL))
+ {
+ return IMG_FALSE;
+ }
+
+#if !defined(RGX_FEATURE_CATURIX_TOP_INFRASTRUCTURE)
+ ui32NumMemBus = RGX_FEATURE_NUM_MEMBUS;
+#else
+ ui32NumMemBus = 1U;
+#endif /* !defined(RGX_FEATURE_CATURIX_TOP_INFRASTRUCTURE) */
+
+ switch (psBlkTypeDesc->uiCntBlkIdBase)
+ {
+ /* Handle the dynamic-sized SLC blocks which are only present if
+ * RGX_FEATURE_NUM_MEMBUS is appropriately set.
+ */
+ case RGX_CNTBLK_ID_SLCBANK1:
+ if (ui32NumMemBus >= 2U)
+ {
+ psRtInfo->uiNumUnits = 1;
+ }
+ else
+ {
+ psRtInfo->uiNumUnits = 0;
+ }
+ break;
+
+ case RGX_CNTBLK_ID_SLCBANK2:
+ case RGX_CNTBLK_ID_SLCBANK3:
+ if (ui32NumMemBus > 2U)
+ {
+ psRtInfo->uiNumUnits = 1;
+ }
+ else
+ {
+ psRtInfo->uiNumUnits = 0;
+ }
+ break;
+
+ default:
+ psRtInfo->uiNumUnits = psBlkTypeDesc->uiNumUnits;
+ break;
+ }
+ if (psRtInfo->uiNumUnits > 0U)
+ {
+ return IMG_TRUE;
+ }
+ else
+ {
+ return IMG_FALSE;
+ }
+#endif /* defined(__KERNEL__) */
+}
+
+#if !defined(__KERNEL__) /* Firmware or User-mode context */
+
+/* Used to instantiate a null row in the block type model table below where the
+ * block is not supported for a given build BVNC in firmware/user mode context.
+ * This is needed as the blockid to block type lookup uses the table as well
+ * and clients may try to access blocks not in the hardware. */
+#define RGXFW_HWPERF_CNTBLK_TYPE_UNSUPPORTED(_blkid) X(_blkid, 0, 0, #_blkid, NULL, NULL, NULL)
+
+#endif
+
+/*****************************************************************************
+ RGXFW_HWPERF_CNTBLK_TYPE_MODEL struct PFNs pfnIsBlkPresent() end
+ *****************************************************************************/
+
+/*****************************************************************************
+ RGXFW_HWPERF_CNTBLK_TYPE_MODEL gasCntBlkTypeModel[] table
+
+ This table holds the entries for the performance counter block type model.
+ Where the block is not present on an RGX device in question the
+ pfnIsBlkPresent() returns false, if valid and present it returns true.
+ Columns in the table with a ** indicate the value is a default and the value
+ returned in RGX_HWPERF_CNTBLK_RT_INFO when calling pfnIsBlkPresent()should
+ be used at runtime by the caller. These columns are only valid for compile
+ time BVNC configured contexts.
+
+ Order of table rows must match order of counter block IDs in the enumeration
+ RGX_HWPERF_CNTBLK_ID.
+
+ Table contains Xmacro styled entries. Each includer of this file must define
+ a gasCntBlkTypeModel[] structure which is local to itself. Only the layout is
+ defined here.
+
+ uiCntBlkIdBase : Block-ID
+ uiIndirectReg : 0 => Direct, non-zero => INDIRECT register address
+ uiNumUnits : Number of units present on the GPU
+ pszBlockNameComment : Name of the Performance Block
+ pfnIsBlkPowered : Function to determine power state of block
+ pfnIsBlkPresent : Function to determine block presence on the core
+ pszBlkCfgValid : Array of counters valid within this block type
+ *****************************************************************************/
+
+ // Furian 8XT V2 layout:
+
+ /* uiCntBlkIdBase, uiIndirectReg, uiNumUnits**, pszBlockNameComment, pfnIsBlkPowered, pfnIsBlkPresent */
+
+ /* RGX_CNTBLK_ID_JONES */
+#if defined(RGX_FIRMWARE) || defined(__KERNEL__)
+
+/* Furian 8XT Direct Performance counter blocks */
+
+#define RGX_CNT_BLK_TYPE_MODEL_DIRECT_LIST \
+ /* uiCntBlkIdBase, uiIndirectReg, uiNumUnits**, pszBlockNameComment, pfnIsBlkPowered, pfnIsBlkPresent */ \
+X(RGX_CNTBLK_ID_JONES, 0, 1, "PERF_BLK_JONES", rgxfw_hwperf_pow_st_direct, rgx_hwperf_blk_present, g_auiJONES), \
+X(RGX_CNTBLK_ID_SLC, 0, 1, "PERF_BLK_SLC", rgxfw_hwperf_pow_st_direct, rgx_hwperf_blk_present, g_auiSLC), \
+X(RGX_CNTBLK_ID_FBCDC, 0, 1, "PERF_BLK_FBCDC", rgxfw_hwperf_pow_st_direct, rgx_hwperf_blk_present, g_auiFBCDC), \
+X(RGX_CNTBLK_ID_FW_CUSTOM, 0, 1, "PERF_BLK_FW_CUSTOM", rgxfw_hwperf_pow_st_direct, rgx_hwperf_blk_present, g_auiFWCUSTOM), \
+X(RGX_CNTBLK_ID_SLCBANK0, 0, 1, "PERF_BLK_SLC0", rgxfw_hwperf_pow_st_direct, rgx_hwperf_blk_present, g_auiSLC0), \
+X(RGX_CNTBLK_ID_SLCBANK1, 0, 1, "PERF_BLK_SLC1", rgxfw_hwperf_pow_st_direct, rgx_hwperf_blk_present, g_auiSLC1), \
+X(RGX_CNTBLK_ID_SLCBANK2, 0, 1, "PERF_BLK_SLC2", rgxfw_hwperf_pow_st_direct, rgx_hwperf_blk_present, g_auiSLC2), \
+X(RGX_CNTBLK_ID_SLCBANK3, 0, 1, "PERF_BLK_SLC3", rgxfw_hwperf_pow_st_direct, rgx_hwperf_blk_present, g_auiSLC3)
+
+/* Furian 8XT Indirect Performance counter blocks */
+
+#if !defined(RGX_CR_RAC_INDIRECT)
+#define RGX_CR_RAC_INDIRECT (0x8398U)
+#endif
+
+#define RGX_CNT_BLK_TYPE_MODEL_INDIRECT_LIST \
+ /* uiCntBlkIdBase, uiIndirectReg, uiNumUnits**, pszBlockNameComment, pfnIsBlkPowered, pfnIsBlkPresent */ \
+X(RGX_CNTBLK_ID_ISP0, RGX_CR_ISP_INDIRECT, RGX_HWPERF_NUM_SPU * RGX_HWPERF_NUM_ISP_PER_SPU, "PERF_BLK_ISP", rgxfw_hwperf_pow_st_indirect, rgx_hwperf_blk_present, g_auiISP), \
+X(RGX_CNTBLK_ID_MERCER0, RGX_CR_MERCER_INDIRECT, RGX_HWPERF_NUM_MERCER, "PERF_BLK_MERCER", rgxfw_hwperf_pow_st_indirect, rgx_hwperf_blk_present, g_auiMERCER), \
+X(RGX_CNTBLK_ID_PBE0, RGX_CR_PBE_INDIRECT, RGX_HWPERF_NUM_PBE, "PERF_BLK_PBE", rgxfw_hwperf_pow_st_indirect, rgx_hwperf_blk_present, g_auiPBE), \
+X(RGX_CNTBLK_ID_PBE_SHARED0, RGX_CR_PBE_SHARED_INDIRECT, RGX_HWPERF_NUM_PBE_SHARED, "PERF_BLK_PBE_SHARED", rgxfw_hwperf_pow_st_indirect, rgx_hwperf_blk_present, g_auiPBE_SHARED), \
+X(RGX_CNTBLK_ID_USC0, RGX_CR_USC_INDIRECT, RGX_HWPERF_NUM_USC, "PERF_BLK_USC", rgxfw_hwperf_pow_st_indirect, rgx_hwperf_blk_present, g_auiUSC), \
+X(RGX_CNTBLK_ID_TPU0, RGX_CR_TPU_INDIRECT, RGX_HWPERF_NUM_TPU, "PERF_BLK_TPU", rgxfw_hwperf_pow_st_indirect, rgx_hwperf_blk_present, g_auiTPU), \
+X(RGX_CNTBLK_ID_SWIFT0, RGX_CR_SWIFT_INDIRECT, RGX_HWPERF_NUM_SWIFT, "PERF_BLK_SWIFT", rgxfw_hwperf_pow_st_indirect, rgx_hwperf_blk_present, g_auiSWIFT), \
+X(RGX_CNTBLK_ID_TEXAS0, RGX_CR_TEXAS_INDIRECT, RGX_HWPERF_NUM_TEXAS, "PERF_BLK_TEXAS", rgxfw_hwperf_pow_st_indirect, rgx_hwperf_blk_present, g_auiTEXAS), \
+X(RGX_CNTBLK_ID_RAC0, RGX_CR_RAC_INDIRECT, RGX_HWPERF_NUM_RAC, "PERF_BLK_RAC", rgxfw_hwperf_pow_st_indirect, rgx_hwperf_blk_present, g_auiRAC)
+
+#else /* !defined(RGX_FIRMWARE) && !defined(__KERNEL__) */
+
+#error "RGX_FIRMWARE or __KERNEL__ *MUST* be defined"
+
+#endif /* defined(RGX_FIRMWARE) || defined(__KERNEL__) */
+
+#endif /* RGX_HWPERF_TABLE_H */
+
+/******************************************************************************
+ End of file (rgx_hwperf_table.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/volcanic/rgx_options.h b/drivers/gpu/drm/img-rogue/include/volcanic/rgx_options.h
new file mode 100644
index 000000000..e7f650bee
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/volcanic/rgx_options.h
@@ -0,0 +1,294 @@
+/*************************************************************************/ /*!
+@File
+@Title RGX build options
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+/* Each build option listed here is packed into a dword which provides up to
+ * log2(RGX_BUILD_OPTIONS_MASK_KM + 1) flags for KM and
+ * (32 - log2(RGX_BUILD_OPTIONS_MASK_KM + 1)) flags for UM.
+ * The corresponding bit is set if the build option was enabled at compile
+ * time.
+ *
+ * In order to extract the enabled build flags the INTERNAL_TEST switch should
+ * be enabled in a client program which includes this header. Then the client
+ * can test specific build flags by reading the bit value at
+ * ##OPTIONNAME##_SET_OFFSET
+ * in RGX_BUILD_OPTIONS_KM or RGX_BUILD_OPTIONS.
+ *
+ * IMPORTANT: add new options to unused bits or define a new dword
+ * (e.g. RGX_BUILD_OPTIONS_KM2 or RGX_BUILD_OPTIONS2) so that the bitfield
+ * remains backwards compatible.
+ */
+
+#ifndef RGX_OPTIONS_H
+#define RGX_OPTIONS_H
+
+#define RGX_BUILD_OPTIONS_MASK_KM 0x0000FFFFUL
+
+#define NO_HARDWARE_OPTION "NO_HARDWARE "
+#if defined(NO_HARDWARE) || defined(INTERNAL_TEST)
+ #define NO_HARDWARE_SET_OFFSET OPTIONS_BIT0
+ #define OPTIONS_BIT0 (0x1UL << 0)
+ #if OPTIONS_BIT0 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT0 0x0UL
+#endif /* NO_HARDWARE */
+
+#define PDUMP_OPTION "PDUMP "
+#if defined(PDUMP) || defined(INTERNAL_TEST)
+ #define PDUMP_SET_OFFSET OPTIONS_BIT1
+ #define OPTIONS_BIT1 (0x1UL << 1)
+ #if OPTIONS_BIT1 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT1 0x0UL
+#endif /* PDUMP */
+
+/* No longer used */
+#define INTERNAL_TEST_OPTION "INTERNAL_TEST "
+#if defined(INTERNAL_TEST)
+ #define UNUSED_SET_OFFSET OPTIONS_BIT2
+ #define OPTIONS_BIT2 (0x1UL << 2)
+ #if OPTIONS_BIT2 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT2 0x0UL
+#endif
+
+/* No longer used */
+#define UNUSED_OPTION " "
+#if defined(INTERNAL_TEST)
+ #define OPTIONS_BIT3 (0x1UL << 3)
+ #if OPTIONS_BIT3 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT3 0x0UL
+#endif
+
+#define SUPPORT_RGX_OPTION " "
+#if defined(SUPPORT_RGX) || defined(INTERNAL_TEST)
+ #define SUPPORT_RGX_SET_OFFSET OPTIONS_BIT4
+ #define OPTIONS_BIT4 (0x1UL << 4)
+ #if OPTIONS_BIT4 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT4 0x0UL
+#endif /* SUPPORT_RGX */
+
+#define SUPPORT_SECURE_EXPORT_OPTION "SECURE_EXPORTS "
+#if defined(SUPPORT_SECURE_EXPORT) || defined(INTERNAL_TEST)
+ #define SUPPORT_SECURE_EXPORT_SET_OFFSET OPTIONS_BIT5
+ #define OPTIONS_BIT5 (0x1UL << 5)
+ #if OPTIONS_BIT5 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT5 0x0UL
+#endif /* SUPPORT_SECURE_EXPORT */
+
+#define SUPPORT_INSECURE_EXPORT_OPTION "INSECURE_EXPORTS "
+#if defined(SUPPORT_INSECURE_EXPORT) || defined(INTERNAL_TEST)
+ #define SUPPORT_INSECURE_EXPORT_SET_OFFSET OPTIONS_BIT6
+ #define OPTIONS_BIT6 (0x1UL << 6)
+ #if OPTIONS_BIT6 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT6 0x0UL
+#endif /* SUPPORT_INSECURE_EXPORT */
+
+#define SUPPORT_VFP_OPTION "VFP "
+#if defined(SUPPORT_VFP) || defined(INTERNAL_TEST)
+ #define SUPPORT_VFP_SET_OFFSET OPTIONS_BIT7
+ #define OPTIONS_BIT7 (0x1UL << 7)
+ #if OPTIONS_BIT7 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT7 0x0UL
+#endif /* SUPPORT_VFP */
+
+#define SUPPORT_WORKLOAD_ESTIMATION_OPTION "WORKLOAD_ESTIMATION "
+#if defined(SUPPORT_WORKLOAD_ESTIMATION) || defined(INTERNAL_TEST)
+ #define SUPPORT_WORKLOAD_ESTIMATION_OFFSET OPTIONS_BIT8
+ #define OPTIONS_BIT8 (0x1UL << 8)
+ #if OPTIONS_BIT8 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT8 0x0UL
+#endif /* SUPPORT_WORKLOAD_ESTIMATION */
+#define OPTIONS_WORKLOAD_ESTIMATION_MASK (0x1UL << 8)
+
+#define SUPPORT_PDVFS_OPTION "PDVFS "
+#if defined(SUPPORT_PDVFS) || defined(INTERNAL_TEST)
+ #define SUPPORT_PDVFS_OFFSET OPTIONS_BIT9
+ #define OPTIONS_BIT9 (0x1UL << 9)
+ #if OPTIONS_BIT9 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT9 0x0UL
+#endif /* SUPPORT_PDVFS */
+#define OPTIONS_PDVFS_MASK (0x1UL << 9)
+
+#define DEBUG_OPTION "DEBUG "
+#if defined(DEBUG) || defined(INTERNAL_TEST)
+ #define DEBUG_SET_OFFSET OPTIONS_BIT10
+ #define OPTIONS_BIT10 (0x1UL << 10)
+ #if OPTIONS_BIT10 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT10 0x0UL
+#endif /* DEBUG */
+/* The bit position of this should be the same as DEBUG_SET_OFFSET option
+ * when defined.
+ */
+#define OPTIONS_DEBUG_MASK (0x1UL << 10)
+
+#define SUPPORT_BUFFER_SYNC_OPTION "BUFFER_SYNC "
+#if defined(SUPPORT_BUFFER_SYNC) || defined(INTERNAL_TEST)
+ #define SUPPORT_BUFFER_SYNC_SET_OFFSET OPTIONS_BIT11
+ #define OPTIONS_BIT11 (0x1UL << 11)
+ #if OPTIONS_BIT11 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT11 0x0UL
+#endif /* SUPPORT_BUFFER_SYNC */
+
+#define SUPPORT_AUTOVZ_OPTION "AUTOVZ "
+#if defined(SUPPORT_AUTOVZ)
+ #define SUPPORT_AUTOVZ_OFFSET OPTIONS_BIT12
+ #define OPTIONS_BIT12 (0x1UL << 12)
+ #if OPTIONS_BIT12 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT12 0x0UL
+#endif /* SUPPORT_AUTOVZ */
+
+#define SUPPORT_AUTOVZ_HW_REGS_OPTION "AUTOVZ_HW_REGS "
+#if defined(SUPPORT_AUTOVZ_HW_REGS)
+ #define SUPPORT_AUTOVZ_HW_REGS_OFFSET OPTIONS_BIT13
+ #define OPTIONS_BIT13 (0x1UL << 13)
+ #if OPTIONS_BIT13 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT13 0x0UL
+#endif /* SUPPORT_AUTOVZ_HW_REGS */
+
+/* Bit 14 reserved for compatibility with Rogue code base */
+#define OPTIONS_BIT14 0x0UL
+
+#define VALIDATION_EN_MASK (0x1UL << 15)
+#define SUPPORT_VALIDATION_OPTION "VALIDATION "
+#if defined(SUPPORT_VALIDATION)
+ #define SUPPORT_VALIDATION_OFFSET OPTIONS_BIT15
+ #define OPTIONS_BIT15 (0x1UL << 15)
+ #if OPTIONS_BIT15 > RGX_BUILD_OPTIONS_MASK_KM
+ #error "Bit exceeds reserved range"
+ #endif
+#else
+ #define OPTIONS_BIT15 0x0UL
+#endif /* SUPPORT_VALIDATION */
+
+#define RGX_BUILD_OPTIONS_KM \
+ (OPTIONS_BIT0 |\
+ OPTIONS_BIT1 |\
+ OPTIONS_BIT2 |\
+ OPTIONS_BIT3 |\
+ OPTIONS_BIT4 |\
+ OPTIONS_BIT6 |\
+ OPTIONS_BIT7 |\
+ OPTIONS_BIT8 |\
+ OPTIONS_BIT9 |\
+ OPTIONS_BIT10 |\
+ OPTIONS_BIT11 |\
+ OPTIONS_BIT12 |\
+ OPTIONS_BIT13 |\
+ OPTIONS_BIT14 |\
+ OPTIONS_BIT15)
+
+#define RGX_BUILD_OPTIONS_LIST \
+ { \
+ NO_HARDWARE_OPTION, \
+ PDUMP_OPTION, \
+ INTERNAL_TEST_OPTION, \
+ UNUSED_OPTION, \
+ SUPPORT_RGX_OPTION, \
+ SUPPORT_SECURE_EXPORT_OPTION, \
+ SUPPORT_INSECURE_EXPORT_OPTION, \
+ SUPPORT_VFP_OPTION, \
+ SUPPORT_WORKLOAD_ESTIMATION_OPTION, \
+ SUPPORT_PDVFS_OPTION, \
+ DEBUG_OPTION, \
+ SUPPORT_BUFFER_SYNC_OPTION, \
+ SUPPORT_AUTOVZ_OPTION, \
+ SUPPORT_AUTOVZ_HW_REGS_OPTION, \
+ SUPPORT_VALIDATION_OPTION \
+ }
+
+#define RGX_BUILD_OPTIONS_MASK_FW \
+ (RGX_BUILD_OPTIONS_MASK_KM & \
+ ~OPTIONS_BIT11)
+
+#define OPTIONS_BIT31 (0x1UL << 31)
+#if OPTIONS_BIT31 <= RGX_BUILD_OPTIONS_MASK_KM
+#error "Bit exceeds reserved range"
+#endif
+#define SUPPORT_PERCONTEXT_FREELIST_SET_OFFSET OPTIONS_BIT31
+
+#define RGX_BUILD_OPTIONS (RGX_BUILD_OPTIONS_KM | OPTIONS_BIT31)
+
+#define OPTIONS_STRICT (RGX_BUILD_OPTIONS & \
+ ~(OPTIONS_DEBUG_MASK | \
+ OPTIONS_WORKLOAD_ESTIMATION_MASK | \
+ OPTIONS_PDVFS_MASK))
+
+#endif /* RGX_OPTIONS_H */
diff --git a/drivers/gpu/drm/img-rogue/include/volcanic/rgxheapconfig.h b/drivers/gpu/drm/img-rogue/include/volcanic/rgxheapconfig.h
new file mode 100644
index 000000000..8b11ba3f8
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/volcanic/rgxheapconfig.h
@@ -0,0 +1,278 @@
+/*************************************************************************/ /*!
+@File
+@Title RGX Device virtual memory map
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Memory heaps device specific configuration
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef RGXHEAPCONFIG_H
+#define RGXHEAPCONFIG_H
+
+#include "rgxdefs_km.h"
+
+
+#define RGX_HEAP_SIZE_4KiB IMG_UINT64_C(0x0000001000)
+#define RGX_HEAP_SIZE_64KiB IMG_UINT64_C(0x0000010000)
+#define RGX_HEAP_SIZE_256KiB IMG_UINT64_C(0x0000040000)
+
+#define RGX_HEAP_SIZE_1MiB IMG_UINT64_C(0x0000100000)
+#define RGX_HEAP_SIZE_2MiB IMG_UINT64_C(0x0000200000)
+#define RGX_HEAP_SIZE_4MiB IMG_UINT64_C(0x0000400000)
+#define RGX_HEAP_SIZE_16MiB IMG_UINT64_C(0x0001000000)
+#define RGX_HEAP_SIZE_256MiB IMG_UINT64_C(0x0010000000)
+
+#define RGX_HEAP_SIZE_1GiB IMG_UINT64_C(0x0040000000)
+#define RGX_HEAP_SIZE_2GiB IMG_UINT64_C(0x0080000000)
+#define RGX_HEAP_SIZE_4GiB IMG_UINT64_C(0x0100000000)
+#define RGX_HEAP_SIZE_16GiB IMG_UINT64_C(0x0400000000)
+#define RGX_HEAP_SIZE_32GiB IMG_UINT64_C(0x0800000000)
+#define RGX_HEAP_SIZE_64GiB IMG_UINT64_C(0x1000000000)
+#define RGX_HEAP_SIZE_128GiB IMG_UINT64_C(0x2000000000)
+#define RGX_HEAP_SIZE_256GiB IMG_UINT64_C(0x4000000000)
+#define RGX_HEAP_SIZE_512GiB IMG_UINT64_C(0x8000000000)
+
+/*
+ RGX Device Virtual Address Space Definitions
+
+ NOTES:
+ Base addresses have to be a multiple of 4MiB
+
+ This file defines the RGX virtual address heaps that are used in
+ application memory contexts. It also shows where the Firmware memory heap
+ fits into this, but the firmware heap is only ever created in the
+ Services KM/server component.
+
+ RGX_PDSCODEDATA_HEAP_BASE and RGX_USCCODE_HEAP_BASE will be programmed,
+ on a global basis, into RGX_CR_PDS_EXEC_BASE and RGX_CR_USC_CODE_BASE_*
+ respectively. Therefore if clients use multiple configs they must still
+ be consistent with their definitions for these heaps.
+
+ Shared virtual memory (GENERAL_SVM) support requires half of the address
+ space (512 GiB) be reserved for SVM allocations to mirror application CPU
+ addresses.
+
+ The GENERAL non-SVM region is 512 GiB to 768 GiB and is shared between the
+ general (4KiB) heap and the general non-4K heap. The first 128 GiB is used
+ for the GENERAL_HEAP (4KiB) and the last 32 GiB is used for the
+ GENERAL_NON4K_HEAP. This heap has a default page-size of 16K.
+ AppHint PVRSRV_APPHINT_GENERALNON4KHEAPPAGESIZE can be used to forced it
+ to these values: 4K,64K,256K,1M,2M.
+
+ Heaps must not start at 0x0000000000, as this is reserved for internal
+ use within device memory layer.
+ Range comments, those starting in column 0 below are a section heading of
+ sorts and are above the heaps in that range. Often this is the reserved
+ size of the heap within the range.
+*/
+
+
+/* 0x00_0000_0000 ************************************************************/
+
+/* 0x00_0000_0000 - 0x00_0040_0000 **/
+ /* 0 MiB to 4 MiB, size of 4 MiB : RESERVED **/
+
+/* 0x00_0040_0000 - 0x7F_FFC0_0000 **/
+ /* 4 MiB to 512 GiB, size of 512 GiB less 4 MiB : GENERAL_SVM_HEAP **/
+ #define RGX_GENERAL_SVM_HEAP_BASE IMG_UINT64_C(0x0000400000)
+ #define RGX_GENERAL_SVM_HEAP_SIZE (RGX_HEAP_SIZE_512GiB - RGX_HEAP_SIZE_4MiB)
+
+
+/* 0x80_0000_0000 ************************************************************/
+
+/* 0x80_0000_0000 - 0x9F_FFFF_FFFF **/
+ /* 512 GiB to 640 GiB, size of 128 GiB : GENERAL_HEAP **/
+ #define RGX_GENERAL_HEAP_BASE IMG_UINT64_C(0x8000000000)
+ #define RGX_GENERAL_HEAP_SIZE RGX_HEAP_SIZE_128GiB
+
+/* 0xA0_0000_0000 - 0xAF_FFFF_FFFF **/
+ /* 640 GiB to 704 GiB, size of 64 GiB : FREE **/
+
+/* 0xB0_0000_0000 - 0xB1_FFFF_FFFF **/
+ /* 704 GiB to 720 GiB, size of 16 GiB : RESERVED ROGUE **/
+
+/* B4_0000_0000 - 0xB7_FFFF_FFFF **/
+ /* 720 GiB to 736 GiB, size of 16 GiB : FREE **/
+
+/* 0xB8_0000_0000 - 0xBF_FFFF_FFFF **/
+ /* 736 GiB to 768 GiB, size of 32 GiB : GENERAL_NON4K_HEAP **/
+ #define RGX_GENERAL_NON4K_HEAP_BASE IMG_UINT64_C(0xB800000000)
+ #define RGX_GENERAL_NON4K_HEAP_SIZE RGX_HEAP_SIZE_32GiB
+
+
+/* 0xC0_0000_0000 ************************************************************/
+
+/* 0xC0_0000_0000 - 0xD9_FFFF_FFFF **/
+ /* 768 GiB to 872 GiB, size of 104 GiB : FREE **/
+
+/* 0xDA_0000_0000 - 0xDA_FFFF_FFFF **/
+ /* 872 GiB to 876 GiB, size of 4 GiB : PDSCODEDATA_HEAP **/
+ #define RGX_PDSCODEDATA_HEAP_BASE IMG_UINT64_C(0xDA00000000)
+ #define RGX_PDSCODEDATA_HEAP_SIZE RGX_HEAP_SIZE_4GiB
+
+/* 0xDB_0000_0000 - 0xDC_FFFF_FFFF **/
+ /* 876 GiB to 884 GiB, size of 8 GiB : RESERVED ROGUE **/
+
+/* 0xDD_0000_0000 - 0xDF_FFFF_FFFF **/
+ /* 884 GiB to 896 GiB, size of 12 GiB : FREE **/
+
+/* 0xE0_0000_0000 - 0xE0_FFFF_FFFF **/
+ /* 896 GiB to 900 GiB, size of 4 GiB : USCCODE_HEAP **/
+ #define RGX_USCCODE_HEAP_BASE IMG_UINT64_C(0xE000000000)
+ #define RGX_USCCODE_HEAP_SIZE RGX_HEAP_SIZE_4GiB
+
+/* 0xE1_0000_0000 - 0xE1_BFFF_FFFF **/
+ /* 900 GiB to 903 GiB, size of 3 GiB : RESERVED **/
+
+/* 0xE1_C000_000 - 0xE1_FFFF_FFFF **/
+ /* 903 GiB to 904 GiB, reserved 1 GiB, : FIRMWARE_HEAP **/
+
+ /* Firmware heaps defined in rgx_heap_firmware.h as they are not present in
+ application memory contexts, see:
+ RGX_FIRMWARE_RAW_HEAP_BASE
+ RGX_FIRMWARE_RAW_HEAP_SIZE
+ See header for other sub-heaps details
+ */
+
+/* 0xE2_0000_0000 - 0xE2_FFFF_FFFF **/
+ /* 904 GiB to 908 GiB, size of 4GiB : RESERVED ROGUE **/
+
+/* 0xE3_0000_0000 - 0xE3_FFFF_FFFF **/
+ /* 908 GiB to 912 GiB, size of 4 GiB : FREE **/
+
+/* 0xE4_0000_0000 - 0xE7_FFFF_FFFF **/
+ /* 912 GiB to 928 GiB, size 16 GiB : RESERVED_ROGUE **/
+
+/* 0xE8_0000_0000 - 0xE8_FFFF_FFFF **/
+ /* 928 GiB to 932 GiB, size of 4 GiB : FREE **/
+
+/* 0xE9_0000_0000 - 0xE9_3FFF_FFFF **/
+ /* 932 GiB to 933 GiB, size of 1 GiB : VK_CAPT_REPLAY_HEAP **/
+ #define RGX_VK_CAPT_REPLAY_HEAP_BASE IMG_UINT64_C(0xE900000000)
+ #define RGX_VK_CAPT_REPLAY_HEAP_SIZE RGX_HEAP_SIZE_1GiB
+
+/* 0xE9_4000_0000 - 0xE9_FFFF_FFFF **/
+ /* 933 GiB to 936 GiB, size of 3 GiB : FREE **/
+
+/* 0xEA_0000_0000 - 0xEA_0000_0FFF **/
+ /* 936 GiB to 937 GiB, size of min heap size : SIGNALS_HEAP **/
+ /* CDM Signals heap (31 signals less one reserved for Services).
+ * Size 960B rounded up to minimum heap size */
+ #define RGX_SIGNALS_HEAP_BASE IMG_UINT64_C(0xEA00000000)
+ #define RGX_SIGNALS_HEAP_SIZE DEVMEM_HEAP_MINIMUM_SIZE
+
+/* 0xEA_4000_0000 - 0xEA_FFFF_FFFF **/
+ /* 937 GiB to 940 GiB, size of 3 GiB : FREE **/
+
+/* 0xEB_0000_0000 - 0xEB_FFFF_FFFF **/
+ /* 940 GiB to 944 GiB, size 4 GiB : COMPONENT_CTRL_HEAP **/
+ #define RGX_COMPONENT_CTRL_HEAP_BASE IMG_UINT64_C(0xEB00000000)
+ #define RGX_COMPONENT_CTRL_HEAP_SIZE RGX_HEAP_SIZE_4GiB
+
+/* 0xEC_0000_0000 - 0xEC_001F_FFFF **/
+ /* 944 GiB to 945 GiB, size 2 MiB : FBCDC_HEAP **/
+ #define RGX_FBCDC_HEAP_BASE IMG_UINT64_C(0xEC00000000)
+ #define RGX_FBCDC_HEAP_SIZE RGX_HEAP_SIZE_2MiB
+
+/* 0xEC_4000_0000 - 0xEC_401F_FFFF **/
+ /* 945 GiB to 946 GiB, size 2 MiB : FBCDC_LARGE_HEAP **/
+ #define RGX_FBCDC_LARGE_HEAP_BASE IMG_UINT64_C(0xEC40000000)
+ #define RGX_FBCDC_LARGE_HEAP_SIZE RGX_HEAP_SIZE_2MiB
+
+/* 0xEC_8000_0000 - 0xEC_FFFF_FFFF **/
+ /* 946 GiB to 948 GiB, size of 3 GiB : FREE **/
+
+/* 0xED_0000_0000 - 0xED_00FF_FFFF */
+ /* 948 GiB to 949 GiB, size 16 MiB : PDS_INDIRECT_STATE_HEAP */
+ #define RGX_PDS_INDIRECT_STATE_HEAP_BASE IMG_UINT64_C(0xED00000000)
+ #define RGX_PDS_INDIRECT_STATE_HEAP_SIZE RGX_HEAP_SIZE_16MiB
+
+/* 0xED_4000_0000 - 0xED_FFFF_FFFF **/
+ /* 949 GiB to 952 GiB, size of 3 GiB : FREE **/
+
+/* 0xEE_0000_0000 - 0xEE_3FFF_FFFF **/
+ /* 952 GiB to 953 GiB, size of 1 GiB : CMP_MISSION_RMW_HEAP **/
+ #define RGX_CMP_MISSION_RMW_HEAP_BASE IMG_UINT64_C(0xEE00000000)
+ #define RGX_CMP_MISSION_RMW_HEAP_SIZE RGX_HEAP_SIZE_1GiB
+
+/* 0xEE_4000_0000 - 0xEE_FFFF_FFFF **/
+ /* 953 GiB to 956 GiB, size of 3 GiB : RESERVED **/
+
+/* 0xEF_0000_0000 - 0xEF_3FFF_FFFF **/
+ /* 956 GiB to 957 GiB, size of 1 GiB : CMP_SAFETY_RMW_HEAP **/
+ #define RGX_CMP_SAFETY_RMW_HEAP_BASE IMG_UINT64_C(0xEF00000000)
+ #define RGX_CMP_SAFETY_RMW_HEAP_SIZE RGX_HEAP_SIZE_1GiB
+
+/* 0xEF_4000_0000 - 0xEF_FFFF_FFFF **/
+ /* 957 GiB to 960 GiB, size of 3 GiB : RESERVED **/
+
+/* 0xF0_0000_0000 - 0xF0_FFFF_FFFF **/
+ /* 960 GiB to 964 GiB, size of 4 GiB : TEXTURE_STATE_HEAP (36-bit aligned) */
+ #define RGX_TEXTURE_STATE_HEAP_BASE IMG_UINT64_C(0xF000000000)
+ #define RGX_TEXTURE_STATE_HEAP_SIZE RGX_HEAP_SIZE_4GiB
+
+/* 0xF1_0000_0000 - 0xF1_FFFF_FFFF **/
+ /* 964 GiB to 968 GiB, size of 4 GiB : FREE **/
+
+/* 0xF2_0000_0000 - 0xF2_001F_FFFF **/
+ /* 968 GiB to 969 GiB, size of 2 MiB : VISIBILITY_TEST_HEAP **/
+ #define RGX_VISIBILITY_TEST_HEAP_BASE IMG_UINT64_C(0xF200000000)
+ #define RGX_VISIBILITY_TEST_HEAP_SIZE RGX_HEAP_SIZE_2MiB
+
+/* 0xF2_4000_0000 - 0xF2_FFFF_FFFF **/
+ /* 969 GiB to 972 GiB, size of 3 GiB : FREE **/
+
+/* 0xF3_0000_0000 - 0xF7_FFFF_FFFF **/
+ /* 972 GiB to 992 GiB, size of 20 GiB : FREE **/
+
+/* 0xF8_0000_0000 - 0xF9_FFFF_FFFF **/
+ /* 992 GiB to 1000 GiB, size 8 GiB : RESERVED ROGUE **/
+
+/* 0xFA_0000_0000 - 0xFF_FFFF_FFFF **/
+ /* 1000 GiB to 1024 GiB, size of 24 GiB : FREE **/
+
+
+/* 0xFF_FFFF_FFFF ************************************************************/
+
+/* End of RGX Device Virtual Address Space definitions */
+
+#endif /* RGXHEAPCONFIG_H */
+
+/******************************************************************************
+ End of file (rgxheapconfig.h)
+******************************************************************************/
diff --git a/drivers/gpu/drm/img-rogue/include/volcanic/system/rgx_tc/tc_clocks.h b/drivers/gpu/drm/img-rogue/include/volcanic/system/rgx_tc/tc_clocks.h
new file mode 100644
index 000000000..9463830fa
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/include/volcanic/system/rgx_tc/tc_clocks.h
@@ -0,0 +1,101 @@
+/*************************************************************************/ /*!
+@File
+@Title System Description Header
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description This header provides system-specific declarations and macros
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(TC_CLOCKS_H)
+#define TC_CLOCKS_H
+
+/*
+ * The core clock speed is passed through a multiplier depending on the TC
+ * version.
+ *
+ * On TC_ES1: Multiplier = x3, final speed = 270MHz
+ * On TC_ES2: Multiplier = x6, final speed = 540MHz
+ * On TCF5: Multiplier = 1x final speed = 45MHz
+ *
+ *
+ * The base (unmultiplied speed) can be adjusted using a module parameter
+ * called "sys_core_clk_speed", a number in Hz.
+ * As an example:
+ *
+ * PVR_SRVKM_PARAMS="sys_core_clk_speed=60000000" /etc/init.d/rc.pvr start
+ *
+ * would result in a core speed of 60MHz xMultiplier.
+ *
+ *
+ * The memory clock is unmultiplied and can be adjusted using a module
+ * parameter called "sys_mem_clk_speed", this should be the number in Hz for
+ * the memory clock speed.
+ * As an example:
+ *
+ * PVR_SRVKM_PARAMS="sys_mem_clk_speed=100000000" /etc/init.d/rc.pvr start
+ *
+ * would attempt to start the driver with the memory clock speed set to 100MHz.
+ *
+ *
+ * Same applies to the system interface clock speed, "sys_sysif_clk_speed".
+ * Needed for TCF5 but not for TC_ES2/ES1.
+ * As an example:
+ *
+ * PVR_SRVKM_PARAMS="sys_sysif_clk_speed=45000000" /etc/init.d/rc.pvr start
+ *
+ * would attempt to start the driver with the system clock speed set to 45MHz.
+ *
+ *
+ * All parameters can be specified at once, e.g.,
+ * PVR_SRVKM_PARAMS="sys_mem_clk_speed=MEMORY_SPEED sys_core_clk_speed=CORE_SPEED sys_sysif_clk_speed=SYSIF_SPEED" /etc/init.d/rc.pvr start
+ */
+
+#define RGX_TC_SYS_CLOCK_SPEED (45000000) /*< Unused */
+
+#if defined(TC_ODIN_27_5_254_2)
+ #define RGX_TC_CORE_CLOCK_SPEED (94000000)
+ #define RGX_TC_MEM_CLOCK_SPEED (40000000)
+ #define RGX_TC_CLOCK_MULTIPLEX (16)
+#else
+ /* FPGA tcfvuquad with Odin */
+ #define RGX_TC_CORE_CLOCK_SPEED (50000000) /* 3.125MHz */
+ #define RGX_TC_MEM_CLOCK_SPEED (40000000) /* 3.75MHz */
+ #define RGX_TC_CLOCK_MULTIPLEX (1)
+#endif
+
+#endif /* if !defined(TC_CLOCKS_H) */
diff --git a/drivers/gpu/drm/img-rogue/info_page.h b/drivers/gpu/drm/img-rogue/info_page.h
new file mode 100644
index 000000000..5816125d7
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/info_page.h
@@ -0,0 +1,99 @@
+/*************************************************************************/ /*!
+@File
+@Title Kernel/User mode general purpose shared memory.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description General purpose memory shared between kernel driver and user
+ mode.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef INFO_PAGE_KM_H
+#define INFO_PAGE_KM_H
+
+#include "pvrsrv_error.h"
+
+#include "pmr.h"
+#include "pvrsrv.h"
+#include "info_page_defs.h"
+
+/**
+ * @Function InfoPageCreate
+ * @Description Allocates resources for global information page.
+ * @Input psData pointer to PVRSRV data
+ * @Return PVRSRV_OK on success and other PVRSRV_ERROR code on error.
+ */
+PVRSRV_ERROR InfoPageCreate(PVRSRV_DATA *psData);
+
+/**
+ * @Function InfoPageDestroy
+ * @Description Frees all of the resource of global information page.
+ * @Input psData pointer to PVRSRV data
+ * @Return PVRSRV_OK on success and other PVRSRV_ERROR code on error.
+ */
+void InfoPageDestroy(PVRSRV_DATA *psData);
+
+/**
+ * @Function PVRSRVAcquireInfoPageKM()
+ * @Description This interface is used for obtaining the global information page
+ * which acts as a general purpose shared memory between KM and UM.
+ * The use of this information page outside of services is _not_
+ * recommended.
+ * @Output ppsPMR handle to exported PMR
+ * @Return
+ */
+PVRSRV_ERROR PVRSRVAcquireInfoPageKM(PMR **ppsPMR);
+
+/**
+ * @Function PVRSRVReleaseInfoPageKM()
+ * @Description This function matches PVRSRVAcquireInfoPageKM().
+ * @Input psPMR handle to exported PMR
+ * @Return PVRSRV_OK on success and other PVRSRV_ERROR code on error.
+ */
+PVRSRV_ERROR PVRSRVReleaseInfoPageKM(PMR *psPMR);
+
+/**
+ * @Function GetInfoPageDebugFlagsKM()
+ * @Description Return info page debug flags
+ * @Return info page debug flags
+ */
+static INLINE IMG_UINT32 GetInfoPageDebugFlagsKM(void)
+{
+ return (PVRSRVGetPVRSRVData())->pui32InfoPage[DEBUG_FEATURE_FLAGS];
+}
+
+#endif /* INFO_PAGE_KM_H */
diff --git a/drivers/gpu/drm/img-rogue/info_page_client.h b/drivers/gpu/drm/img-rogue/info_page_client.h
new file mode 100644
index 000000000..9df2461b5
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/info_page_client.h
@@ -0,0 +1,89 @@
+/*************************************************************************/ /*!
+@File
+@Title Kernel/User mode general purpose shared memory.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description General purpose shared memory (i.e. information page) mapped by
+ kernel space driver and user space clients. All info page
+ entries are sizeof(IMG_UINT32) on both 32/64-bit environments.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef INFO_PAGE_CLIENT_H
+#define INFO_PAGE_CLIENT_H
+
+#include "device_connection.h"
+#include "info_page_defs.h"
+#if defined(__KERNEL__)
+#include "pvrsrv.h"
+#endif
+
+/*************************************************************************/ /*!
+@Function GetInfoPage
+
+@Description Return Info Page address
+
+@Input hDevConnection - Services device connection
+
+@Return Info Page address
+*/
+/*****************************************************************************/
+static INLINE IMG_PUINT32 GetInfoPage(SHARED_DEV_CONNECTION hDevConnection)
+{
+#if defined(__KERNEL__)
+ return (PVRSRVGetPVRSRVData())->pui32InfoPage;
+#else
+ return hDevConnection->pui32InfoPage;
+#endif
+}
+
+/*************************************************************************/ /*!
+@Function GetInfoPageDebugFlags
+
+@Description Return Info Page debug flags
+
+@Input hDevConnection - Services device connection
+
+@Return Info Page debug flags
+*/
+/*****************************************************************************/
+static INLINE IMG_UINT32 GetInfoPageDebugFlags(SHARED_DEV_CONNECTION hDevConnection)
+{
+ return GetInfoPage(hDevConnection)[DEBUG_FEATURE_FLAGS];
+}
+
+#endif /* INFO_PAGE_CLIENT_H */
diff --git a/drivers/gpu/drm/img-rogue/info_page_defs.h b/drivers/gpu/drm/img-rogue/info_page_defs.h
new file mode 100644
index 000000000..d3bc1538a
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/info_page_defs.h
@@ -0,0 +1,91 @@
+/*************************************************************************/ /*!
+@File
+@Title Kernel/User mode general purpose shared memory.
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description General purpose shared memory (i.e. information page) mapped by
+ kernel space driver and user space clients. All information page
+ entries are sizeof(IMG_UINT32) on both 32/64-bit environments.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef INFO_PAGE_DEFS_H
+#define INFO_PAGE_DEFS_H
+
+
+/* CacheOp information page entries */
+#define CACHEOP_INFO_IDX_START 0x00
+#define CACHEOP_INFO_UMKMTHRESHLD (CACHEOP_INFO_IDX_START + 1) /*!< UM=>KM routing threshold in bytes */
+#define CACHEOP_INFO_KMDFTHRESHLD (CACHEOP_INFO_IDX_START + 2) /*!< KM/DF threshold in bytes */
+#define CACHEOP_INFO_LINESIZE (CACHEOP_INFO_IDX_START + 3) /*!< CPU data cache line size */
+#define CACHEOP_INFO_PGSIZE (CACHEOP_INFO_IDX_START + 4) /*!< CPU MMU page size */
+#define CACHEOP_INFO_IDX_END (CACHEOP_INFO_IDX_START + 5)
+
+/* HWPerf information page entries */
+#define HWPERF_INFO_IDX_START (CACHEOP_INFO_IDX_END)
+#define HWPERF_FILTER_SERVICES_IDX (HWPERF_INFO_IDX_START + 0)
+#define HWPERF_FILTER_EGL_IDX (HWPERF_INFO_IDX_START + 1)
+#define HWPERF_FILTER_OPENGLES_IDX (HWPERF_INFO_IDX_START + 2)
+#define HWPERF_FILTER_OPENCL_IDX (HWPERF_INFO_IDX_START + 3)
+#define HWPERF_FILTER_VULKAN_IDX (HWPERF_INFO_IDX_START + 4)
+#define HWPERF_FILTER_OPENGL_IDX (HWPERF_INFO_IDX_START + 5)
+#define HWPERF_INFO_IDX_END (HWPERF_INFO_IDX_START + 6)
+
+/* timeout values */
+#define TIMEOUT_INFO_IDX_START (HWPERF_INFO_IDX_END)
+#define TIMEOUT_INFO_VALUE_RETRIES (TIMEOUT_INFO_IDX_START + 0)
+#define TIMEOUT_INFO_VALUE_TIMEOUT_MS (TIMEOUT_INFO_IDX_START + 1)
+#define TIMEOUT_INFO_CONDITION_RETRIES (TIMEOUT_INFO_IDX_START + 2)
+#define TIMEOUT_INFO_CONDITION_TIMEOUT_MS (TIMEOUT_INFO_IDX_START + 3)
+#define TIMEOUT_INFO_TASK_QUEUE_RETRIES (TIMEOUT_INFO_IDX_START + 4)
+#define TIMEOUT_INFO_TASK_QUEUE_FLUSH_TIMEOUT_MS (TIMEOUT_INFO_IDX_START + 5)
+#define TIMEOUT_INFO_IDX_END (TIMEOUT_INFO_IDX_START + 6)
+
+/* Bridge Info */
+#define BRIDGE_INFO_IDX_START (TIMEOUT_INFO_IDX_END)
+#define BRIDGE_INFO_RGX_BRIDGES (BRIDGE_INFO_IDX_START + 0)
+#define BRIDGE_INFO_PVR_BRIDGES (BRIDGE_INFO_IDX_START + 1)
+#define BRIDGE_INFO_IDX_END (BRIDGE_INFO_IDX_START + 2)
+
+/* Debug features */
+#define DEBUG_FEATURE_FLAGS (BRIDGE_INFO_IDX_END)
+#define DEBUG_FEATURE_FULL_SYNC_TRACKING_ENABLED 0x1
+#define DEBUG_FEATURE_PAGE_FAULT_DEBUG_ENABLED 0x2
+#define DEBUG_FEATURE_FLAGS_IDX_END (DEBUG_FEATURE_FLAGS + 1)
+
+
+#endif /* INFO_PAGE_DEFS_H */
diff --git a/drivers/gpu/drm/img-rogue/info_page_km.c b/drivers/gpu/drm/img-rogue/info_page_km.c
new file mode 100644
index 000000000..9a0067102
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/info_page_km.c
@@ -0,0 +1,138 @@
+/*************************************************************************/ /*!
+@File info_page_km.c
+@Title Kernel/User space shared memory
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Implements general purpose shared memory between kernel driver
+ and user mode.
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include "info_page_defs.h"
+#include "info_page.h"
+#include "pvrsrv.h"
+#include "devicemem.h"
+#include "pmr.h"
+
+PVRSRV_ERROR InfoPageCreate(PVRSRV_DATA *psData)
+{
+ const PVRSRV_MEMALLOCFLAGS_T uiMemFlags = PVRSRV_MEMALLOCFLAG_CPU_READABLE |
+ PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE |
+ PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC |
+ PVRSRV_MEMALLOCFLAG_CPU_CACHE_INCOHERENT |
+ PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE |
+ PVRSRV_MEMALLOCFLAG_PHYS_HEAP_HINT(CPU_LOCAL);
+ PVRSRV_ERROR eError;
+
+ PVR_ASSERT(psData != NULL);
+
+ /* Allocate single page of memory for driver information page */
+ eError = DevmemAllocateExportable(psData->psHostMemDeviceNode,
+ OSGetPageSize(),
+ OSGetPageSize(),
+ OSGetPageShift(),
+ uiMemFlags,
+ "PVRSRVInfoPage",
+ &psData->psInfoPageMemDesc);
+ PVR_LOG_GOTO_IF_ERROR(eError, "DevmemAllocateExportable", e0);
+
+ eError = DevmemAcquireCpuVirtAddr(psData->psInfoPageMemDesc,
+ (void **) &psData->pui32InfoPage);
+ PVR_LOG_GOTO_IF_ERROR(eError, "DevmemAllocateExportable", e0);
+
+ /* Look-up the memory descriptor PMR handle */
+ eError = DevmemLocalGetImportHandle(psData->psInfoPageMemDesc,
+ (void **) &psData->psInfoPagePMR);
+ PVR_LOG_GOTO_IF_ERROR(eError, "DevmemLocalGetImportHandle", e0);
+
+ eError = OSLockCreate(&psData->hInfoPageLock);
+ PVR_LOG_GOTO_IF_ERROR(eError, "OSLockCreate", e0);
+
+ return PVRSRV_OK;
+
+e0:
+ InfoPageDestroy(psData);
+ return eError;
+}
+
+void InfoPageDestroy(PVRSRV_DATA *psData)
+{
+ if (psData->psInfoPageMemDesc)
+ {
+ if (psData->pui32InfoPage != NULL)
+ {
+ DevmemReleaseCpuVirtAddr(psData->psInfoPageMemDesc);
+ psData->pui32InfoPage = NULL;
+ }
+
+ DevmemFree(psData->psInfoPageMemDesc);
+ psData->psInfoPageMemDesc = NULL;
+ }
+
+ if (psData->hInfoPageLock)
+ {
+ OSLockDestroy(psData->hInfoPageLock);
+ psData->hInfoPageLock = NULL;
+ }
+}
+
+PVRSRV_ERROR PVRSRVAcquireInfoPageKM(PMR **ppsPMR)
+{
+ PVRSRV_DATA *psData = PVRSRVGetPVRSRVData();
+
+ PVR_LOG_RETURN_IF_FALSE(psData->psInfoPageMemDesc != NULL, "invalid MEMDESC"
+ " handle", PVRSRV_ERROR_INVALID_PARAMS);
+ PVR_LOG_RETURN_IF_FALSE(psData->psInfoPagePMR != NULL, "invalid PMR handle",
+ PVRSRV_ERROR_INVALID_PARAMS);
+
+ /* Copy the PMR import handle back */
+ *ppsPMR = psData->psInfoPagePMR;
+
+ /* Mark the PMR such that no layout changes can happen
+ * This is a fixed layout created during early stages of
+ * driver loading and shouldn't change later */
+ PMR_SetLayoutFixed(psData->psInfoPagePMR, IMG_TRUE);
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR PVRSRVReleaseInfoPageKM(PMR *ppsPMR)
+{
+ /* Nothing to do here as PMR is singleton */
+ PVR_UNREFERENCED_PARAMETER(ppsPMR);
+ return PVRSRV_OK;
+}
diff --git a/drivers/gpu/drm/img-rogue/interrupt_support.c b/drivers/gpu/drm/img-rogue/interrupt_support.c
new file mode 100644
index 000000000..c67d45352
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/interrupt_support.c
@@ -0,0 +1,151 @@
+/*************************************************************************/ /*!
+@File
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#include
+
+#include "pvr_debug.h"
+#include "allocmem.h"
+#include "interrupt_support.h"
+
+typedef struct LISR_DATA_TAG
+{
+ IMG_UINT32 ui32IRQ;
+ PFN_SYS_LISR pfnLISR;
+ void *pvData;
+} LISR_DATA;
+
+static irqreturn_t SystemISRWrapper(int irq, void *dev_id)
+{
+ LISR_DATA *psLISRData = (LISR_DATA *)dev_id;
+
+ PVR_UNREFERENCED_PARAMETER(irq);
+
+ if (psLISRData)
+ {
+ if (psLISRData->pfnLISR(psLISRData->pvData))
+ {
+ return IRQ_HANDLED;
+ }
+ }
+ else
+ {
+ PVR_DPF((PVR_DBG_ERROR, "%s: Missing interrupt data", __func__));
+ }
+
+ return IRQ_NONE;
+}
+
+PVRSRV_ERROR OSInstallSystemLISR(IMG_HANDLE *phLISR,
+ IMG_UINT32 ui32IRQ,
+ const IMG_CHAR *pszDevName,
+ PFN_SYS_LISR pfnLISR,
+ void *pvData,
+ IMG_UINT32 ui32Flags)
+{
+ LISR_DATA *psLISRData;
+ unsigned long ulIRQFlags = 0;
+
+ if (pfnLISR == NULL || pvData == NULL)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (ui32Flags & ~SYS_IRQ_FLAG_MASK)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ switch (ui32Flags & SYS_IRQ_FLAG_TRIGGER_MASK)
+ {
+ case SYS_IRQ_FLAG_TRIGGER_DEFAULT:
+ break;
+ case SYS_IRQ_FLAG_TRIGGER_LOW:
+ ulIRQFlags |= IRQF_TRIGGER_LOW;
+ break;
+ case SYS_IRQ_FLAG_TRIGGER_HIGH:
+ ulIRQFlags |= IRQF_TRIGGER_HIGH;
+ break;
+ default:
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ if (ui32Flags & SYS_IRQ_FLAG_SHARED)
+ {
+ ulIRQFlags |= IRQF_SHARED;
+ }
+
+ psLISRData = OSAllocMem(sizeof(*psLISRData));
+ if (psLISRData == NULL)
+ {
+ return PVRSRV_ERROR_OUT_OF_MEMORY;
+ }
+
+ psLISRData->ui32IRQ = ui32IRQ;
+ psLISRData->pfnLISR = pfnLISR;
+ psLISRData->pvData = pvData;
+
+ if (request_irq(ui32IRQ, SystemISRWrapper, ulIRQFlags, pszDevName, psLISRData))
+ {
+ OSFreeMem(psLISRData);
+
+ return PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER;
+ }
+
+ *phLISR = (IMG_HANDLE)psLISRData;
+
+ return PVRSRV_OK;
+}
+
+PVRSRV_ERROR OSUninstallSystemLISR(IMG_HANDLE hLISR)
+{
+ LISR_DATA *psLISRData = (LISR_DATA *)hLISR;
+
+ if (psLISRData == NULL)
+ {
+ return PVRSRV_ERROR_INVALID_PARAMS;
+ }
+
+ free_irq(psLISRData->ui32IRQ, psLISRData);
+
+ OSFreeMem(psLISRData);
+
+ return PVRSRV_OK;
+}
diff --git a/drivers/gpu/drm/img-rogue/interrupt_support.h b/drivers/gpu/drm/img-rogue/interrupt_support.h
new file mode 100644
index 000000000..b87772d22
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/interrupt_support.h
@@ -0,0 +1,103 @@
+/*************************************************************************/ /*!
+@File
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(INTERRUPT_SUPPORT_H)
+#define INTERRUPT_SUPPORT_H
+
+#include "img_types.h"
+#include "pvrsrv_error.h"
+#include "pvrsrv_device.h"
+
+/*! Default trigger type for the interrupt line. */
+#define SYS_IRQ_FLAG_TRIGGER_DEFAULT (0x0 << 0)
+/*! Interrupt triggered when interrupt line is low. */
+#define SYS_IRQ_FLAG_TRIGGER_LOW (0x1 << 0)
+/*! Interrupt triggered when interrupt line is high. */
+#define SYS_IRQ_FLAG_TRIGGER_HIGH (0x2 << 0)
+/*! Interrupt trigger mask. */
+#define SYS_IRQ_FLAG_TRIGGER_MASK (SYS_IRQ_FLAG_TRIGGER_DEFAULT | \
+ SYS_IRQ_FLAG_TRIGGER_LOW | \
+ SYS_IRQ_FLAG_TRIGGER_HIGH)
+/*! The irq is allowed to be shared among several devices. */
+#define SYS_IRQ_FLAG_SHARED (0x1 << 8)
+
+/*! Interrupt flags mask. */
+#define SYS_IRQ_FLAG_MASK (SYS_IRQ_FLAG_TRIGGER_MASK | \
+ SYS_IRQ_FLAG_SHARED)
+
+/*************************************************************************/ /*!
+@Description Pointer to a system Low-level Interrupt Service Routine (LISR).
+@Input pvData Private data provided to the LISR.
+@Return IMG_TRUE if interrupt handled, IMG_FALSE otherwise.
+*/ /**************************************************************************/
+typedef IMG_BOOL (*PFN_SYS_LISR)(void *pvData);
+
+/*************************************************************************/ /*!
+@Function OSInstallSystemLISR
+@Description Installs a system low-level interrupt handler
+@Output phLISR On return, contains a handle to the
+ installed LISR
+@Input ui32IRQ The IRQ number for which the
+ interrupt handler should be installed
+@Input pszDevName Name of the device for which the handler
+ is being installed
+@Input pfnLISR A pointer to an interrupt handler
+ function
+@Input pvData A pointer to data that should be passed
+ to pfnLISR when it is called
+@Input ui32Flags Interrupt flags
+@Return PVRSRV_OK on success, a failure code otherwise
+*/ /**************************************************************************/
+PVRSRV_ERROR OSInstallSystemLISR(IMG_HANDLE *phLISR,
+ IMG_UINT32 ui32IRQ,
+ const IMG_CHAR *pszDevName,
+ PFN_SYS_LISR pfnLISR,
+ void *pvData,
+ IMG_UINT32 ui32Flags);
+
+/*************************************************************************/ /*!
+@Function OSUninstallSystemLISR
+@Description Uninstalls a system low-level interrupt handler
+@Input hLISRData The handle to the LISR to uninstall
+@Return PVRSRV_OK on success, a failure code otherwise
+*/ /**************************************************************************/
+PVRSRV_ERROR OSUninstallSystemLISR(IMG_HANDLE hLISRData);
+#endif /* !defined(INTERRUPT_SUPPORT_H) */
diff --git a/drivers/gpu/drm/img-rogue/kernel_compatibility.h b/drivers/gpu/drm/img-rogue/kernel_compatibility.h
new file mode 100644
index 000000000..50d17e665
--- /dev/null
+++ b/drivers/gpu/drm/img-rogue/kernel_compatibility.h
@@ -0,0 +1,510 @@
+/*************************************************************************/ /*!
+@Title Kernel versions compatibility macros
+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@Description Per-version macros to allow code to seamlessly use older kernel
+@License Dual MIT/GPLv2
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 ("GPL") in which case the provisions
+of GPL are applicable instead of those above.
+
+If you wish to allow use of your version of this file only under the terms of
+GPL, and not to allow others to use your version of this file under the terms
+of the MIT license, indicate your decision by deleting the provisions above
+and replace them with the notice and other provisions required by GPL as set
+out in the file called "GPL-COPYING" included in this distribution. If you do
+not delete the provisions above, a recipient may use your version of this file
+under the terms of either the MIT license or GPL.
+
+This License is also included in this distribution in the file called
+"MIT-COPYING".
+
+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef __KERNEL_COMPATIBILITY_H__
+#define __KERNEL_COMPATIBILITY_H__
+
+#include
+
+/*
+ * Stop supporting an old kernel? Remove the top block.
+ * New incompatible kernel? Append a new block at the bottom.
+ *
+ * Please write you version test as `VERSION < X.Y`, and use the earliest
+ * possible version :)
+ */
+
+/* Linux 3.6 introduced seq_vprintf(). Earlier versions don't have this
+ * so we work around the limitation by vsnprintf() + seq_puts().
+ */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
+#define seq_vprintf(seq_file, fmt, args) \
+do { \
+ char aszBuffer[512]; /* maximum message buffer size */ \
+ vsnprintf(aszBuffer, sizeof(aszBuffer), fmt, args); \
+ seq_puts(seq_file, aszBuffer); \
+} while (0)
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
+
+/* Linux 3.7 split VM_RESERVED into VM_DONTDUMP and VM_DONTEXPAND */
+#define VM_DONTDUMP VM_RESERVED
+
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)) */
+
+/*
+ * Note: this fix had to be written backwards because get_unused_fd_flags
+ * was already defined but not exported on kernels < 3.7
+ *
+ * When removing support for kernels < 3.7, this block should be removed
+ * and all `get_unused_fd()` should be manually replaced with
+ * `get_unused_fd_flags(0)`
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
+
+/* Linux 3.19 removed get_unused_fd() */
+/* get_unused_fd_flags was introduced in 3.7 */
+#define get_unused_fd() get_unused_fd_flags(0)
+
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
+
+/*
+ * Headers shouldn't normally be included by this file but this is a special
+ * case as it's not obvious from the name that devfreq_add_device needs this
+ * include.
+ */
+#include