From 1ee20f30afd95a69d0c628d9fbfb3d2d9939427d Mon Sep 17 00:00:00 2001 From: Li Huang Date: Tue, 14 Jan 2020 09:57:54 +0800 Subject: [PATCH] RK3368 GPU: Rogue Q Init for 4.19. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1、Change Android sync to sync_file 2、Fixup compile error on 4.19 3、Fixup some crash on 4.19 4、Fixup some clang waring 5、Fixup clang warning Change-Id: Ie59a9252116f6e7cc97f5f9b9a25ae6d5d5f82b1 Signed-off-by: Li Huang --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/imgtec/apollo/sysconfig.c | 4 +- drivers/staging/imgtec/config_kernel.h | 6 +- drivers/staging/imgtec/pvr_drm.c | 15 +- drivers/staging/imgtec/pvr_drv.h | 3 + drivers/staging/imgtec/pvr_platform_drv.c | 96 +- drivers/staging/imgtec/pvr_sync_file.c | 2366 +++++++++++++++++ drivers/staging/imgtec/rogue/Makefile | 2 + drivers/staging/imgtec/rogue/cache_km.c | 22 +- .../staging/imgtec/rogue/connection_data.h | 84 + .../staging/imgtec/rogue/connection_server.h | 34 +- drivers/staging/imgtec/rogue/device.h | 289 +- .../staging/imgtec/rogue/devicemem_heapcfg.h | 3 +- .../cache_bridge/server_cache_bridge.c | 1 + .../server_devicememhistory_bridge.c | 1 + .../dmabuf_bridge/server_dmabuf_bridge.c | 1 + .../htbuffer_bridge/server_htbuffer_bridge.c | 1 + .../generated/mm_bridge/server_mm_bridge.c | 1 + .../pdump_bridge/server_pdump_bridge.c | 1 + .../pdumpmm_bridge/server_pdumpmm_bridge.c | 1 + .../pvrtl_bridge/server_pvrtl_bridge.c | 1 + .../rgxcmp_bridge/server_rgxcmp_bridge.c | 1 + .../server_rgxhwperf_bridge.c | 1 + .../server_rgxkicksync_bridge.c | 1 + .../rgxray_bridge/server_rgxray_bridge.c | 1 + .../rgxta3d_bridge/server_rgxta3d_bridge.c | 1 + .../rgxtq2_bridge/server_rgxtq2_bridge.c | 1 + .../rgxtq_bridge/server_rgxtq_bridge.c | 1 + .../generated/ri_bridge/server_ri_bridge.c | 1 + .../srvcore_bridge/server_srvcore_bridge.c | 1 + .../sync_bridge/server_sync_bridge.c | 1 + .../server_synctracking_bridge.c | 1 + drivers/staging/imgtec/rogue/handle.c | 1 + drivers/staging/imgtec/rogue/handle.h | 1 + drivers/staging/imgtec/rogue/hash.h | 3 +- drivers/staging/imgtec/rogue/mmu_common.h | 8 +- .../imgtec/rogue/osconnection_server.c | 1 + .../imgtec/rogue/osconnection_server.h | 3 +- drivers/staging/imgtec/rogue/osfunc.c | 33 +- drivers/staging/imgtec/rogue/osfunc_arm64.c | 16 +- drivers/staging/imgtec/rogue/physmem_dmabuf.c | 12 +- drivers/staging/imgtec/rogue/pmr.h | 5 +- drivers/staging/imgtec/rogue/pmr_impl.h | 2 + drivers/staging/imgtec/rogue/power.h | 5 +- .../staging/imgtec/rogue/psync_checkpoint.h | 81 + .../imgtec/rogue/psync_checkpoint_context.h | 76 + drivers/staging/imgtec/rogue/pvr_debugfs.c | 33 - drivers/staging/imgtec/rogue/pvr_debugfs.h | 32 +- .../staging/imgtec/rogue/pvr_dvfs_device.c | 5 +- drivers/staging/imgtec/rogue/pvr_notifier.h | 10 + drivers/staging/imgtec/rogue/pvr_uaccess.h | 2 +- drivers/staging/imgtec/rogue/pvrsrv_cleanup.h | 2 + .../staging/imgtec/rogue/pvrsrv_device_node.h | 338 +++ drivers/staging/imgtec/rogue/rgxhwperf.c | 2 +- drivers/staging/imgtec/rogue/rgxmipsmmuinit.h | 2 +- .../staging/imgtec/rogue/rk3368/sysconfig.c | 2 +- .../staging/imgtec/rogue/rogue_trace_events.h | 4 +- .../imgtec/rogue/server_sync_primitive.h | 70 + .../staging/imgtec/rogue/sync_checkpoint.h | 9 +- .../imgtec/rogue/sync_checkpoint_external.h | 7 +- .../imgtec/rogue/sync_checkpoint_internal.h | 58 +- drivers/staging/imgtec/rogue/sync_server.c | 18 - drivers/staging/imgtec/rogue/sync_server.h | 2 +- .../imgtec/rogue/sync_server_internal.h | 3 +- drivers/staging/imgtec/rogue/syscommon.h | 4 +- drivers/staging/imgtec/rogue/trace_events.c | 8 +- .../staging/imgtec/services_kernel_client.h | 10 + 68 files changed, 3261 insertions(+), 553 deletions(-) create mode 100644 drivers/staging/imgtec/pvr_sync_file.c create mode 100644 drivers/staging/imgtec/rogue/connection_data.h create mode 100644 drivers/staging/imgtec/rogue/psync_checkpoint.h create mode 100644 drivers/staging/imgtec/rogue/psync_checkpoint_context.h create mode 100644 drivers/staging/imgtec/rogue/pvrsrv_device_node.h create mode 100644 drivers/staging/imgtec/rogue/server_sync_primitive.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 1abf76be2aa8..978d01dd315c 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -126,4 +126,6 @@ source "drivers/staging/axis-fifo/Kconfig" source "drivers/staging/erofs/Kconfig" +source "drivers/staging/imgtec/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index ab0cbe8815b1..ae40b4be74ae 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -53,3 +53,4 @@ obj-$(CONFIG_SOC_MT7621) += mt7621-dts/ obj-$(CONFIG_STAGING_GASKET_FRAMEWORK) += gasket/ obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/ obj-$(CONFIG_EROFS_FS) += erofs/ +obj-$(CONFIG_POWERVR_ROGUE_N) += imgtec/ diff --git a/drivers/staging/imgtec/apollo/sysconfig.c b/drivers/staging/imgtec/apollo/sysconfig.c index 60f6d1a64506..2a82c2d67e48 100644 --- a/drivers/staging/imgtec/apollo/sysconfig.c +++ b/drivers/staging/imgtec/apollo/sysconfig.c @@ -701,7 +701,7 @@ typedef struct struct device *psDev; int iInterruptID; void *pvData; - PFN_LISR pfnLISR; + SYS_PFN_LISR pfnLISR; } LISR_DATA; static void ApolloInterruptHandler(void* pvData) @@ -713,7 +713,7 @@ static void ApolloInterruptHandler(void* pvData) PVRSRV_ERROR SysInstallDeviceLISR(IMG_HANDLE hSysData, IMG_UINT32 ui32IRQ, const IMG_CHAR *pszName, - PFN_LISR pfnLISR, + SYS_PFN_LISR pfnLISR, void *pvData, IMG_HANDLE *phLISRData) { diff --git a/drivers/staging/imgtec/config_kernel.h b/drivers/staging/imgtec/config_kernel.h index 0bb0350e6d8c..2dbbbf11b91c 100644 --- a/drivers/staging/imgtec/config_kernel.h +++ b/drivers/staging/imgtec/config_kernel.h @@ -86,12 +86,12 @@ #define PVR_LINUX_PHYSMEM_MAX_ALLOC_ORDER_NUM 2 #define PVR_LINUX_KMALLOC_ALLOCATION_THRESHOLD 16384 #define SUPPORT_KERNEL_SRVINIT -#define SUPPORT_NATIVE_FENCE_SYNC +#define SUPPORT_NATIVE_FENCE_SYNC #define PVR_DRM_NAME "pvr" #define DEVICE_MEMSETCPY_ALIGN_IN_BYTES 16 #define ANDROID #define SUPPORT_ION -#define PVR_ANDROID_ION_HEADER "../drivers/staging/android/ion/ion.h" -#define PVR_ANDROID_ION_PRIV_HEADER "../drivers/staging/android/ion/ion_priv.h" +#define PVR_ANDROID_ION_HEADER "../drivers/staging/android/ion_legency/ion.h" +#define PVR_ANDROID_ION_PRIV_HEADER "../drivers/staging/android/ion_legency/ion_priv.h" #define PVR_ANDROID_ION_USE_SG_LENGTH #define PVR_ANDROID_SYNC_HEADER "../drivers/staging/android/sync.h" diff --git a/drivers/staging/imgtec/pvr_drm.c b/drivers/staging/imgtec/pvr_drm.c index 24def946a82f..993818cf8315 100644 --- a/drivers/staging/imgtec/pvr_drm.c +++ b/drivers/staging/imgtec/pvr_drm.c @@ -93,7 +93,7 @@ const struct dev_pm_ops pvr_pm_ops = { }; -static int pvr_drm_load(struct drm_device *ddev, unsigned long flags) +int pvr_drm_load(struct drm_device *ddev, unsigned long flags) { struct _PVRSRV_DEVICE_NODE_ *dev_node; enum PVRSRV_ERROR srv_err; @@ -105,8 +105,12 @@ static int pvr_drm_load(struct drm_device *ddev, unsigned long flags) * The equivalent is done for PCI modesetting drivers by * drm_get_pci_dev() */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) if (ddev->platformdev) platform_set_drvdata(ddev->platformdev, ddev); +#else + dev_set_drvdata(ddev->dev, ddev); +#endif srv_err = PVRSRVDeviceCreate(ddev->dev, &dev_node); if (srv_err != PVRSRV_OK) { @@ -137,7 +141,7 @@ err_exit: return err; } -static int pvr_drm_unload(struct drm_device *ddev) +void pvr_drm_unload(struct drm_device *ddev) { DRM_DEBUG_DRIVER("device %p\n", ddev->dev); @@ -146,7 +150,7 @@ static int pvr_drm_unload(struct drm_device *ddev) PVRSRVDeviceDestroy(ddev->dev_private); ddev->dev_private = NULL; - return 0; + //return 0; } static int pvr_drm_open(struct drm_device *ddev, struct drm_file *dfile) @@ -268,8 +272,13 @@ const struct drm_driver pvr_drm_generic_driver = { .driver_features = DRIVER_MODESET | DRIVER_RENDER, .dev_priv_size = 0, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) + .load = NULL, + .unload = NULL, +#else .load = pvr_drm_load, .unload = pvr_drm_unload, +#endif .open = pvr_drm_open, .postclose = pvr_drm_release, diff --git a/drivers/staging/imgtec/pvr_drv.h b/drivers/staging/imgtec/pvr_drv.h index e92cfe96f64f..7ebb70d02644 100644 --- a/drivers/staging/imgtec/pvr_drv.h +++ b/drivers/staging/imgtec/pvr_drv.h @@ -55,6 +55,9 @@ struct vm_area_struct; extern const struct dev_pm_ops pvr_pm_ops; extern const struct drm_driver pvr_drm_generic_driver; +int pvr_drm_load(struct drm_device *ddev, unsigned long flags); +void pvr_drm_unload(struct drm_device *ddev); + #if defined(PDUMP) int dbgdrv_init(void); void dbgdrv_cleanup(void); diff --git a/drivers/staging/imgtec/pvr_platform_drv.c b/drivers/staging/imgtec/pvr_platform_drv.c index 16489489d164..a02c441d54c0 100644 --- a/drivers/staging/imgtec/pvr_platform_drv.c +++ b/drivers/staging/imgtec/pvr_platform_drv.c @@ -103,67 +103,54 @@ MODULE_PARM_DESC(num_devices, static int pvr_devices_register(void) { -#if defined(MODULE) && !defined(PVR_LDM_PLATFORM_PRE_REGISTERED) - struct platform_device_info pvr_dev_info = { - .name = SYS_RGX_DEV_NAME, - .id = -2, -#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 more correctly. - */ - .dma_mask = DMA_BIT_MASK(40), -#else - .dma_mask = DMA_BIT_MASK(32), -#endif - }; - unsigned int i; - - BUG_ON(pvr_num_devices == 0 || pvr_num_devices > MAX_DEVICES); - - pvr_devices = kmalloc_array(pvr_num_devices, sizeof(*pvr_devices), - GFP_KERNEL); - if (!pvr_devices) - return -ENOMEM; - - for (i = 0; i < pvr_num_devices; i++) { - pvr_devices[i] = platform_device_register_full(&pvr_dev_info); - if (IS_ERR(pvr_devices[i])) { - DRM_ERROR("unable to register device %u (err=%ld)\n", - i, PTR_ERR(pvr_devices[i])); - pvr_devices[i] = NULL; - return -ENODEV; - } - } -#endif /* defined(MODULE) && !defined(PVR_LDM_PLATFORM_PRE_REGISTERED) */ - return 0; } static void pvr_devices_unregister(void) { -#if defined(MODULE) && !defined(PVR_LDM_PLATFORM_PRE_REGISTERED) - unsigned int i; - - BUG_ON(!pvr_devices); - - for (i = 0; i < pvr_num_devices && pvr_devices[i]; i++) - platform_device_unregister(pvr_devices[i]); - - kfree(pvr_devices); - pvr_devices = NULL; -#endif /* defined(MODULE) && !defined(PVR_LDM_PLATFORM_PRE_REGISTERED) */ } static int pvr_probe(struct platform_device *pdev) { + struct drm_device *ddev; + int ret; + DRM_DEBUG_DRIVER("device %p\n", &pdev->dev); - //zxl:print gpu version on boot time - printk("PVR_K: sys.gpvr.version=%s\n",RKVERSION); + ddev = drm_dev_alloc(&pvr_drm_platform_driver, &pdev->dev); + if (IS_ERR(ddev)) + return PTR_ERR(ddev); + + //zxl:print gpu version on boot time + printk("PVR_K: sys.gpvr.version=%s\n", RKVERSION); + gpsPVRLDMDev = pdev; - return drm_platform_init(&pvr_drm_platform_driver, pdev); + /* + * The load callback, called from drm_dev_register, is deprecated, + * because of potential race conditions. Calling the function here, + * before calling drm_dev_register, avoids those potential races. + */ + BUG_ON(pvr_drm_platform_driver.load != NULL); + ret = pvr_drm_load(ddev, 0); + if (ret) + goto err_drm_dev_unref; + + ret = drm_dev_register(ddev, 0); + if (ret) + goto err_drm_dev_unload; + + return 0; + +err_drm_dev_unload: + pvr_drm_unload(ddev); +err_drm_dev_unref: + drm_dev_unref(ddev); + return ret; + + //gpsPVRLDMDev = pdev; + + //return drm_platform_init(&pvr_drm_platform_driver, pdev); } static int pvr_remove(struct platform_device *pdev) @@ -172,8 +159,19 @@ static int pvr_remove(struct platform_device *pdev) DRM_DEBUG_DRIVER("device %p\n", &pdev->dev); - drm_put_dev(ddev); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) + drm_dev_unregister(ddev); + /* The unload callback, called from drm_dev_unregister, is + * deprecated. Call the unload function directly. + */ + BUG_ON(pvr_drm_platform_driver.unload != NULL); + pvr_drm_unload(ddev); + + drm_dev_put(ddev); +#else + drm_put_dev(ddev); +#endif return 0; } diff --git a/drivers/staging/imgtec/pvr_sync_file.c b/drivers/staging/imgtec/pvr_sync_file.c new file mode 100644 index 000000000000..dc25bdd4d2f8 --- /dev/null +++ b/drivers/staging/imgtec/pvr_sync_file.c @@ -0,0 +1,2366 @@ +/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* vi: set ts=8 sw=8 sts=8: */ +/*************************************************************************/ /*! +@File pvr_sync_file.c +@Title Kernel driver for Android's sync mechanism +@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 "pvr_sync.h" +#include "pvr_fd_sync_kernel.h" +#include "services_kernel_client.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kernel_compatibility.h" + +#include + +#define for_each_sync_pt(s, f, c) \ + for ((c) = 0, (s) = (f)->num_fences == 0 ? \ + NULL : (struct sync_pt *)(f)->cbs[0].sync_pt; \ + (c) < (f)->num_fences; \ + (c)++, (s) = (c) < (f)->num_fences ? \ + (struct sync_pt *)(f)->cbs[c].sync_pt : NULL) + + +/* #define DEBUG_OUTPUT 1 */ + +#ifdef DEBUG_OUTPUT +#define DPF(fmt, ...) pr_err("pvr_sync: " fmt "\n", __VA_ARGS__) +#else +#define DPF(fmt, ...) do {} while (0) +#endif + +#define PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, fmt, ...) \ + do { \ + if (pfnDumpDebugPrintf) { \ + pfnDumpDebugPrintf(pvDumpDebugFile, fmt, __VA_ARGS__); \ + } else { \ + pr_info("pvr_sync: " fmt, __VA_ARGS__); \ + } \ + } while (0) + +#define SYNC_MAX_POOL_SIZE 10 + +enum { + SYNC_TL_TYPE = 0, + SYNC_PT_FENCE_TYPE = 1, + SYNC_PT_CLEANUP_TYPE = 2, + SYNC_PT_FOREIGN_FENCE_TYPE = 3, + SYNC_PT_FOREIGN_CLEANUP_TYPE = 4, +}; + +struct pvr_sync_append_data { + u32 nr_updates; + struct _RGXFWIF_DEV_VIRTADDR_ *update_ufo_addresses; + u32 *update_values; + u32 nr_checks; + struct _RGXFWIF_DEV_VIRTADDR_ *check_ufo_addresses; + u32 *check_values; + + /* The cleanup list is needed for rollback (as that's the only op + * taken). + */ + u32 nr_cleanup_syncs; + struct pvr_sync_native_sync_prim **cleanup_syncs; + + /* A FD is reserved in append_fences, but is not associated with + * the update fence until pvr_sync_get_update_fd(). + */ + int update_fence_fd; + + /* Keep the sync points around for fput and if rollback is needed */ + struct sync_file *update_fence; + struct pvr_sync_native_sync_prim *update_sync; + struct pvr_sync_native_sync_prim *update_timeline_sync; + struct sync_file *check_fence; +}; + +/* Services client sync prim wrapper. This is used to hold debug information + * and make it possible to cache unused syncs. + */ +struct pvr_sync_native_sync_prim { + /* List for the sync pool support. */ + struct list_head list; + + /* Base services sync prim structure */ + struct PVRSRV_CLIENT_SYNC_PRIM *client_sync; + + /* The next queued value which should be used */ + u32 next_value; + + /* Every sync data will get some unique id */ + u32 id; + + /* FWAddr used by the client sync */ + u32 vaddr; + + /* The type this sync is used for in our driver. Used in + * pvr_sync_debug_request(). + */ + u8 type; + + /* A debug class name also printed in pvr_sync_debug_request(). */ + char class[32]; + + /* List for the cleanup syncs attached to a sync_pt */ + struct list_head cleanup_list; +}; + +/* + * for sync_file, to define new pvr_dma_fence_timeline + * refer to sw_sync.c + * + * struct sync_timeline - sync object + * @kref: reference count on fence. + * @name: name of the sync_timeline. Useful for debugging + * @lock: lock protecting @pt_list and @value + * @pt_tree: rbtree of active (unsignaled/errored) sync_pts + * @pt_list: list of active (unsignaled/errored) sync_pts + * @sync_timeline_list: membership in global sync_timeline_list + */ +struct dma_fence_timeline { // 对标 sync_timeline + struct kref kref; + const struct dma_fence_ops *ops; + char name[32]; + + /* protected by lock */ + u64 context; + int value; + + struct rb_root pt_tree; + struct list_head pt_list; + spinlock_t lock; + + struct list_head sync_timeline_list; +}; + +/* This is the actual timeline metadata. We might keep this around after the + * base sync driver has destroyed the pvr_sync_timeline_wrapper object. + */ +struct pvr_sync_timeline { + /* Back reference to the sync_timeline. Not always valid */ + struct dma_fence_timeline *obj; + + /* Global timeline list support */ + struct list_head list; + + /* Timeline sync */ + struct pvr_sync_kernel_pair *kernel; + + /* Reference count for this object */ + struct kref kref; + + /* Used only by pvr_sync_update_all_timelines(). False if the timeline + * has been detected as racing with pvr_sync_destroy_timeline(). + */ + bool valid; +}; + +/* This is the IMG extension of a sync_timeline */ +struct pvr_sync_timeline_wrapper { + /* Original timeline struct. Needs to come first. */ + struct dma_fence_timeline obj; + + /* Pointer to extra timeline data. Separated life-cycle. */ + struct pvr_sync_timeline *timeline; +}; + +struct pvr_sync_kernel_pair { + /* Binary sync point representing the android native sync in hw. */ + struct pvr_sync_native_sync_prim *fence_sync; + + /* Cleanup sync list. If the base sync prim is used for "checking" + * only within a GL stream, there is no way of knowing when this has + * happened. So each check appends another sync prim just used for + * update at the end of the command, so we know if all syncs in this + * cleanup list are complete there are no outstanding renders waiting + * to check this, so it can safely be freed. + */ + struct list_head cleanup_sync_list; + /* A temporary pointer used to track the 'new' cleanup_sync added to + * cleanup_sync_list within pvr_sync_append_fences() + */ + struct pvr_sync_native_sync_prim *current_cleanup_sync; + + /* Sync points can go away when there are deferred hardware operations + * still outstanding. We must not free the SERVER_SYNC_PRIMITIVE until + * the hardware is finished, so we add it to a defer list which is + * processed periodically ("defer-free"). + * + * Note that the defer-free list is global, not per-timeline. + */ + struct list_head list; +}; + +struct pvr_sync_data { + /* Every sync point has a services sync object. This object is used + * by the hardware to enforce ordering -- it is attached as a source + * dependency to various commands. + */ + struct pvr_sync_kernel_pair *kernel; + + /* The timeline update value for this sync point. */ + u32 timeline_update_value; + + /* This refcount is incremented at create and dup time, and decremented + * at free time. It ensures the object doesn't start the defer-free + * process until it is no longer referenced. + */ + struct kref kref; +}; + +/* + * define dma_fence_pt + * + * struct sync_pt - sync_pt object + * @base: base fence object + * @link: link on the sync timeline's list + * @node: node in the sync timeline's tree + */ +struct dma_fence_pt { // 对标 sync_pt + struct dma_fence base; + struct list_head link; + struct rb_node node; +}; + +/* This is the IMG extension of a sync_pt */ +struct pvr_sync_pt { + /* Original sync_pt structure. Needs to come first. */ + struct dma_fence_pt pt; + + /* Private shared data */ + struct pvr_sync_data *sync_data; +}; + +/* This is the IMG extension of a sync_fence */ +struct pvr_sync_fence { + /* Original sync_fence structure. Needs to come first. */ + struct sync_file *fence; + + /* To ensure callbacks are always received for fences / sync_pts, even + * after the fence has been 'put' (freed), we must take a reference to + * the fence. We still need to 'put' the fence ourselves, but this might + * happen in irq context, where fput() is not allowed (in kernels <3.6). + * We must add the fence to a list which is processed in WQ context. + */ + struct list_head list; +}; + +/* Any sync point from a foreign (non-PVR) timeline needs to have a "shadow" + * sync prim. This is modelled as a software operation. The foreign driver + * completes the operation by calling a callback we registered with it. + */ +struct pvr_sync_fence_waiter { + /* Base sync driver waiter structure */ + struct dma_fence_cb waiter; + + /* "Shadow" sync prim backing the foreign driver's sync_pt */ + struct pvr_sync_kernel_pair *kernel; + + /* Optimizes lookup of fence for defer-put operation */ + struct pvr_sync_fence *sync_fence; +}; + +/* Global data for the sync driver */ +static struct { + /* Complete notify handle */ + void *command_complete_handle; + + /* Defer-free workqueue. Syncs may still be in use by the HW when freed, + * so we have to keep them around until the HW is done with them at + * some later time. This workqueue iterates over the list of free'd + * syncs, checks if they are in use, and frees the sync device memory + * when done with. + */ + struct workqueue_struct *defer_free_wq; + struct work_struct defer_free_work; + + /* check_status workqueue: When a foreign point is completed, a SW + * operation marks the sync as completed to allow the operations to + * continue. This completion may require the hardware to be notified, + * which may be expensive/take locks, so we push that to a workqueue + */ + struct workqueue_struct *check_status_wq; + struct work_struct check_status_work; + + /* Context used to create client sync prims. */ + struct SYNC_PRIM_CONTEXT *sync_prim_context; + + /* Debug notify handle */ + void *debug_notify_handle; + + /* Unique id counter for the sync prims */ + atomic_t sync_id; + + /* The global event object (used to wait between checks for + * deferred-free sync status). + */ + void *event_object_handle; +} pvr_sync_data; + +static void sync_timeline_get(struct dma_fence_timeline *obj) +{ + kref_get(&obj->kref); +} + +static void pvr_sync_release_timeline(struct pvr_sync_timeline *timeline); + +static void sync_timeline_free(struct kref *kref) +{ + struct dma_fence_timeline *obj = + container_of(kref, struct dma_fence_timeline, kref); + + struct pvr_sync_timeline_wrapper *timeline_wrapper = + (struct pvr_sync_timeline_wrapper *)obj; + + pvr_sync_release_timeline(timeline_wrapper->timeline); + + kfree(obj); +} + +static void sync_timeline_put(struct dma_fence_timeline *obj) +{ + kref_put(&obj->kref, sync_timeline_free); +} + +/*---------------------------------------------------------------------------*/ + +static inline +struct dma_fence_timeline *dma_fence_parent(struct dma_fence *fence) +{ + return container_of(fence->lock, struct dma_fence_timeline, lock); +} + +/*---------------------------------------------------------------------------*/ + +#define PVR_DRV_NAME "pvr" +#define PVR_TIMELINE_NAME PVR_DRV_NAME ".timeline" + +static const char * +pvr_fence_get_driver_name(struct dma_fence *fence) +{ + return PVR_DRV_NAME; +} + +static const char * +pvr_fence_get_timeline_name(struct dma_fence *fence) +{ + struct dma_fence_timeline *parent = dma_fence_parent(fence); + + return parent->name; +} + +static bool +pvr_fence_enable_signaling(struct dma_fence *fence) +{ + return true; +} + +static void pvr_sync_fence_install(struct sync_file *fence, int fd) +{ + fd_install(fd, fence->file); +} + +static inline +struct dma_fence_timeline *pvr_sync_pt_parent(struct dma_fence_pt *pt) +{ + return container_of(pt->base.lock, struct dma_fence_timeline, lock); +} + +/* List of timelines created by this driver */ +static LIST_HEAD(timeline_list); +static DEFINE_MUTEX(timeline_list_mutex); + +/* Sync pool support */ +static LIST_HEAD(sync_pool_free_list); +static LIST_HEAD(sync_pool_active_list); +static DEFINE_MUTEX(sync_pool_mutex); +static s32 sync_pool_size; +static u32 sync_pool_created; +static u32 sync_pool_reused; + +/* The "defer-free" object list. Driver global. */ +static LIST_HEAD(sync_prim_free_list); +static DEFINE_SPINLOCK(sync_prim_free_list_spinlock); + +/* The "defer-put" object list. Driver global. */ +static LIST_HEAD(sync_fence_put_list); +static DEFINE_SPINLOCK(sync_fence_put_list_spinlock); + +static void pvr_sync_update_all_timelines(void *command_complete_handle); + +static inline void set_sync_value(struct pvr_sync_native_sync_prim *sync, + u32 value) +{ + *(sync->client_sync->pui32LinAddr) = value; +} + +static inline u32 get_sync_value(struct pvr_sync_native_sync_prim *sync) +{ + return *(sync->client_sync->pui32LinAddr); +} + +static inline void complete_sync(struct pvr_sync_native_sync_prim *sync) +{ + *(sync->client_sync->pui32LinAddr) = sync->next_value; +} + +static inline bool is_sync_met(struct pvr_sync_native_sync_prim *sync) +{ + return *(sync->client_sync->pui32LinAddr) == sync->next_value; +} + +static inline +struct pvr_sync_timeline *get_timeline(struct dma_fence_timeline *obj) +{ + return ((struct pvr_sync_timeline_wrapper *)obj)->timeline; +} + +static inline struct pvr_sync_timeline *get_timeline_pt(struct dma_fence_pt *pt) +{ + return get_timeline(pvr_sync_pt_parent(pt)); +} + +static inline bool +pvr_sync_has_kernel_signaled(struct pvr_sync_kernel_pair *kernel) +{ + /* Idle syncs are always signaled */ + if (!kernel) + return 1; + + return is_sync_met(kernel->fence_sync); +} + +const struct dma_fence_ops pvr_fence_ops; + +static inline +struct dma_fence_pt *dma_fence_to_pvr_dma_fence_pt(struct dma_fence *fence) +{ + if (fence->ops != &pvr_fence_ops) { + BUG(); + return NULL; + } + + return container_of(fence, struct dma_fence_pt, base); +} + +static inline +struct pvr_sync_pt *dma_fence_to_pvr_sync_pt(struct dma_fence *dma_fence) +{ + struct dma_fence_pt *dma_fence_pt = dma_fence_to_pvr_dma_fence_pt(dma_fence); + + return container_of(dma_fence_pt, struct pvr_sync_pt, pt); +} + +#ifdef DEBUG_OUTPUT + +static char *debug_info_timeline(struct pvr_sync_timeline *timeline) +{ + static char info[256]; + + snprintf(info, sizeof(info), + "n='%s' id=%u fw=0x%x tl_curr=%u tl_next=%u", + timeline->obj ? timeline->obj->name : "?", + timeline->kernel->fence_sync->id, + timeline->kernel->fence_sync->vaddr, + get_sync_value(timeline->kernel->fence_sync), + timeline->kernel->fence_sync->next_value); + + return info; +} + +static char *debug_info_sync_pt(struct dma_fence_pt *pt) +{ + struct pvr_sync_timeline *timeline = get_timeline_pt(pt); + struct pvr_sync_pt *pvr_pt = (struct pvr_sync_pt *)pt; + struct pvr_sync_kernel_pair *kernel = pvr_pt->sync_data->kernel; + static char info[256], info1[256]; + + if (kernel) { + unsigned int cleanup_count = 0; + unsigned int info1_pos = 0; + struct list_head *pos; + + info1[0] = 0; + + list_for_each(pos, &kernel->cleanup_sync_list) { + struct pvr_sync_native_sync_prim *cleanup_sync = + list_entry(pos, + struct pvr_sync_native_sync_prim, + cleanup_list); + int string_size = 0; + + string_size = snprintf(info1 + info1_pos, + sizeof(info1) - info1_pos, + " # cleanup %u: id=%u fw=0x%x curr=%u next=%u", + cleanup_count, + cleanup_sync->id, + cleanup_sync->vaddr, + get_sync_value(cleanup_sync), + cleanup_sync->next_value); + cleanup_count++; + info1_pos += string_size; + /* Truncate the string and stop if we run out of space + * This should stop any underflow of snprintf's 'size' + * arg too + */ + if (info1_pos >= sizeof(info1)) + break; + } + + snprintf(info, sizeof(info), + "status=%d tl_taken=%u ref=%d # sync: id=%u fw=0x%x curr=%u next=%u%s # tl: %s", + pvr_sync_has_kernel_signaled(kernel), + pvr_pt->sync_data->timeline_update_value, + kref_read(&pvr_pt->sync_data->kref), + kernel->fence_sync->id, + kernel->fence_sync->vaddr, + get_sync_value(kernel->fence_sync), + kernel->fence_sync->next_value, + info1, debug_info_timeline(timeline)); + } else { + snprintf(info, sizeof(info), + "status=%d tl_taken=%u ref=%d # sync: idle # tl: %s", + pvr_sync_has_kernel_signaled(kernel), + pvr_pt->sync_data->timeline_update_value, + kref_read(&pvr_pt->sync_data->kref), + debug_info_timeline(timeline)); + } + + return info; +} + +#endif /* DEBUG_OUTPUT */ + +static enum PVRSRV_ERROR +sync_pool_get(struct pvr_sync_native_sync_prim **_sync, + const char *class_name, u8 type) +{ + struct pvr_sync_native_sync_prim *sync; + enum PVRSRV_ERROR error = PVRSRV_OK; + u32 sync_addr; + + mutex_lock(&sync_pool_mutex); + + if (list_empty(&sync_pool_free_list)) { + /* If there is nothing in the pool, create a new sync prim. */ + sync = kmalloc(sizeof(*sync), + GFP_KERNEL); + if (!sync) { + pr_err("pvr_sync: %s: Failed to allocate sync data\n", + __func__); + error = PVRSRV_ERROR_OUT_OF_MEMORY; + goto err_unlock; + } + + error = SyncPrimAlloc(pvr_sync_data.sync_prim_context, + &sync->client_sync, class_name); + if (error != PVRSRV_OK) { + pr_err("pvr_sync: %s: Failed to allocate sync prim (%s)\n", + __func__, PVRSRVGetErrorStringKM(error)); + goto err_free; + } + + error = SyncPrimGetFirmwareAddr(sync->client_sync, &sync_addr); + if (error != PVRSRV_OK) { + pr_err("pvr_sync: %s: Failed to get FW address (%s)\n", + __func__, PVRSRVGetErrorStringKM(error)); + goto err_sync_prim_free; + } + sync->vaddr = sync_addr; + + list_add_tail(&sync->list, &sync_pool_active_list); + ++sync_pool_created; + } else { + sync = list_first_entry(&sync_pool_free_list, + struct pvr_sync_native_sync_prim, list); + list_move_tail(&sync->list, &sync_pool_active_list); + --sync_pool_size; + ++sync_pool_reused; + } + + sync->id = atomic_inc_return(&pvr_sync_data.sync_id); + sync->type = type; + + strncpy(sync->class, class_name, sizeof(sync->class)); + sync->class[sizeof(sync->class) - 1] = '\0'; + /* Its crucial to reset the sync to zero */ + set_sync_value(sync, 0); + sync->next_value = 0; + + *_sync = sync; +err_unlock: + mutex_unlock(&sync_pool_mutex); + return error; + +err_sync_prim_free: + SyncPrimFree(sync->client_sync); + +err_free: + kfree(sync); + goto err_unlock; +} + +static void sync_pool_put(struct pvr_sync_native_sync_prim *sync) +{ + mutex_lock(&sync_pool_mutex); + + if (sync_pool_size < SYNC_MAX_POOL_SIZE) { + /* Mark it as unused */ + set_sync_value(sync, 0xffffffff); + + list_move(&sync->list, &sync_pool_free_list); + ++sync_pool_size; + } else { + /* Mark it as invalid */ + set_sync_value(sync, 0xdeadbeef); + + list_del(&sync->list); + SyncPrimFree(sync->client_sync); + kfree(sync); + } + + mutex_unlock(&sync_pool_mutex); +} + +static void sync_pool_clear(void) +{ + struct pvr_sync_native_sync_prim *sync, *n; + + mutex_lock(&sync_pool_mutex); + + list_for_each_entry_safe(sync, n, &sync_pool_free_list, list) { + /* Mark it as invalid */ + set_sync_value(sync, 0xdeadbeef); + + list_del(&sync->list); + SyncPrimFree(sync->client_sync); + kfree(sync); + --sync_pool_size; + } + + mutex_unlock(&sync_pool_mutex); +} + +static void pvr_sync_debug_request(void *hDebugRequestHandle, + u32 ui32VerbLevel, + DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, + void *pvDumpDebugFile) +{ + struct pvr_sync_native_sync_prim *sync; + + static const char *const type_names[] = { + "Timeline", "Fence", "Cleanup", + "Foreign Fence", "Foreign Cleanup" + }; + + if (ui32VerbLevel == DEBUG_REQUEST_VERBOSITY_HIGH) { + mutex_lock(&sync_pool_mutex); + + PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, + "Dumping all pending android native syncs (Pool usage: %d%% - %d %d)", + sync_pool_reused ? + (10000 / + ((sync_pool_created + sync_pool_reused) * + 100 / sync_pool_reused)) : 0, + sync_pool_created, sync_pool_reused); + + list_for_each_entry(sync, &sync_pool_active_list, list) { + if (is_sync_met(sync)) + continue; + + BUG_ON(sync->type >= ARRAY_SIZE(type_names)); + + PVR_DUMPDEBUG_LOG(pfnDumpDebugPrintf, pvDumpDebugFile, + "\tID = %d, FWAddr = 0x%08x: Current = 0x%08x, Next = 0x%08x, %s (%s)", + sync->id, sync->vaddr, + get_sync_value(sync), + sync->next_value, + sync->class, + type_names[sync->type]); + } + mutex_unlock(&sync_pool_mutex); + } +} + +/* + * 调用者必须保证 传入的 'fence' 指向 pvr_dma_fence. + */ +static bool pvr_sync_has_signaled(struct dma_fence *fence) +{ + struct dma_fence_pt *sync_pt = dma_fence_to_pvr_dma_fence_pt(fence); + struct pvr_sync_pt *pvr_pt = (struct pvr_sync_pt *)sync_pt; + + DPF("%s: # %s", __func__, debug_info_sync_pt(sync_pt)); + + return pvr_sync_has_kernel_signaled(pvr_pt->sync_data->kernel); +} + +static void wait_for_sync(struct pvr_sync_native_sync_prim *sync) +{ +#ifndef NO_HARDWARE + void *event_object = NULL; + enum PVRSRV_ERROR error = PVRSRV_OK; + + while (sync && !is_sync_met(sync)) { + if (!event_object) { + error = OSEventObjectOpen( + pvr_sync_data.event_object_handle, + &event_object); + if (error != PVRSRV_OK) { + pr_err("pvr_sync: %s: Error opening event object (%s)\n", + __func__, + PVRSRVGetErrorStringKM(error)); + break; + } + } + error = OSEventObjectWait(event_object); + if (error != PVRSRV_OK && error != PVRSRV_ERROR_TIMEOUT) { + pr_err("pvr_sync: %s: Error waiting on event object (%s)\n", + __func__, + PVRSRVGetErrorStringKM(error)); + } + } + + if (event_object) + OSEventObjectClose(event_object); +#endif /* NO_HARDWARE */ +} + +static void pvr_sync_defer_free(struct pvr_sync_kernel_pair *kernel) +{ + unsigned long flags; + + spin_lock_irqsave(&sync_prim_free_list_spinlock, flags); + list_add_tail(&kernel->list, &sync_prim_free_list); + spin_unlock_irqrestore(&sync_prim_free_list_spinlock, flags); + + queue_work(pvr_sync_data.defer_free_wq, &pvr_sync_data.defer_free_work); +} + +/* This function assumes the timeline_list_mutex is held while it runs */ + +static void pvr_sync_destroy_timeline_locked(struct kref *kref) +{ + struct pvr_sync_timeline *timeline = (struct pvr_sync_timeline *) + container_of(kref, struct pvr_sync_timeline, kref); + + pvr_sync_defer_free(timeline->kernel); + list_del(&timeline->list); + kfree(timeline); +} + +static void pvr_sync_destroy_timeline(struct kref *kref) +{ + mutex_lock(&timeline_list_mutex); + pvr_sync_destroy_timeline_locked(kref); + mutex_unlock(&timeline_list_mutex); +} + +static void pvr_sync_release_timeline(struct pvr_sync_timeline *timeline) +{ + /* If pvr_sync_open failed after calling sync_timeline_create, this + * can be called with a timeline that has not got a timeline sync + * or been added to our timeline list. Use a NULL timeline to + * detect and handle this condition + */ + if (!timeline) + return; + + DPF("%s: # %s", __func__, debug_info_timeline(timeline)); + + wait_for_sync(timeline->kernel->fence_sync); + + /* Whether or not we're the last reference, obj is going away + * after this function returns, so remove our back reference + * to it. + */ + timeline->obj = NULL; + + /* This might be the last reference to the timeline object. + * If so, we'll go ahead and delete it now. + */ + kref_put(&timeline->kref, pvr_sync_destroy_timeline); +} + +/* pvr_sync_create_sync_data() should be called with the bridge lock held */ +static struct pvr_sync_data * +pvr_sync_create_sync_data(struct dma_fence_timeline *obj) +{ + struct pvr_sync_data *sync_data = NULL; + enum PVRSRV_ERROR error; + + sync_data = kzalloc(sizeof(*sync_data), GFP_KERNEL); + if (!sync_data) + goto err_out; + + kref_init(&sync_data->kref); + + sync_data->kernel = + kzalloc(sizeof(*sync_data->kernel), + GFP_KERNEL); + + if (!sync_data->kernel) + goto err_free_data; + + INIT_LIST_HEAD(&sync_data->kernel->cleanup_sync_list); + + error = sync_pool_get(&sync_data->kernel->fence_sync, + obj->name, SYNC_PT_FENCE_TYPE); + + if (error != PVRSRV_OK) { + pr_err("pvr_sync: %s: Failed to allocate sync prim (%s)\n", + __func__, PVRSRVGetErrorStringKM(error)); + goto err_free_kernel; + } + +err_out: + return sync_data; + +err_free_kernel: + kfree(sync_data->kernel); +err_free_data: + kfree(sync_data); + sync_data = NULL; + goto err_out; +} + +static void pvr_sync_free_sync_data(struct kref *kref) +{ + struct pvr_sync_data *sync_data = (struct pvr_sync_data *) + container_of(kref, struct pvr_sync_data, kref); + + if (sync_data->kernel) + pvr_sync_defer_free(sync_data->kernel); + kfree(sync_data); +} + +static void pvr_sync_free_sync(struct dma_fence_pt *sync_pt) +{ + struct pvr_sync_pt *pvr_pt = (struct pvr_sync_pt *)sync_pt; + + DPF("%s: # %s", __func__, debug_info_sync_pt(sync_pt)); + + kref_put(&pvr_pt->sync_data->kref, pvr_sync_free_sync_data); +} + +static void timeline_fence_value_str(struct dma_fence *fence, + char *str, int size) +{ + snprintf(str, size, "%d", fence->seqno); +} + +static void timeline_fence_timeline_value_str(struct dma_fence *fence, + char *str, int size) +{ + struct dma_fence_timeline *parent = dma_fence_parent(fence); + + snprintf(str, size, "%d", parent->value); +} + +static void pvr_fence_release(struct dma_fence *fence) +{ + // struct pvr_sync_pt *pvr_sync_pt = dma_fence_to_pvr_sync_pt(fence); + struct dma_fence_pt *pt = dma_fence_to_pvr_dma_fence_pt(fence); + struct dma_fence_timeline *parent = dma_fence_parent(fence); + unsigned long flags; + + /*-------------------------------------------------------*/ + + /* 释放当前 pvr_sync_pt 实例的 private_data. */ + pvr_sync_free_sync(pt); + + /*-------------------------------------------------------*/ + /* 参考自 timeline_fence_release(). */ + + spin_lock_irqsave(fence->lock, flags); + if (!list_empty(&pt->link)) { + list_del(&pt->link); + rb_erase(&pt->node, &parent->pt_tree); + } + + spin_unlock_irqrestore(fence->lock, flags); + + sync_timeline_put(parent); + + dma_fence_free(fence); +} + +const struct dma_fence_ops pvr_fence_ops = { + //wait: refer to mali + .wait = dma_fence_default_wait, + .get_driver_name = pvr_fence_get_driver_name, + .get_timeline_name = pvr_fence_get_timeline_name, + .enable_signaling = pvr_fence_enable_signaling, +//Warning + .fence_value_str = timeline_fence_value_str, +//Warning + .timeline_value_str = timeline_fence_timeline_value_str, + .signaled = pvr_sync_has_signaled, + .release = pvr_fence_release, +}; + +/** + * pvr_sync_pt_create() - creates a sync pt + * @obj: parent sync_timeline + * @value: value of the fence + * + * Creates a new sync_pt (fence) as a child of @parent. @size bytes will be + * allocated allowing for implementation specific data to be kept after + * the generic sync_timeline struct. Returns the sync_pt object or + * NULL in case of error. + */ +struct dma_fence_pt *pvr_sync_pt_create(struct dma_fence_timeline *obj, + unsigned int value, struct pvr_sync_data *sync_data) +{ + struct dma_fence_pt *pt; + struct pvr_sync_pt *pvr_pt = NULL; + + pt = kzalloc(sizeof(*pt), GFP_KERNEL); + if (!pt) + return NULL; + + sync_timeline_get(obj); + dma_fence_init(&pt->base, &pvr_fence_ops, &obj->lock, + obj->context, value); + INIT_LIST_HEAD(&pt->link); + + spin_lock_irq(&obj->lock); + + pvr_pt = (struct pvr_sync_pt *)pt; + + pvr_pt->sync_data = sync_data; + + if (!dma_fence_is_signaled_locked(&pt->base)) { + struct rb_node **p = &obj->pt_tree.rb_node; + struct rb_node *parent = NULL; + + while (*p) { + struct dma_fence_pt *other; + int cmp; + + parent = *p; + other = rb_entry(parent, typeof(*pt), node); + cmp = value - other->base.seqno; + if (cmp > 0) { + p = &parent->rb_right; + } else if (cmp < 0) { + p = &parent->rb_left; + } else { + if (dma_fence_get_rcu(&other->base)) { + sync_timeline_put(obj); + kfree(pt); + pt = other; + goto unlock; + } + p = &parent->rb_left; + } + } + rb_link_node(&pt->node, parent, p); + rb_insert_color(&pt->node, &obj->pt_tree); + + parent = rb_next(&pt->node); + list_add_tail(&pt->link, + parent ? &rb_entry(parent, typeof(*pt), node)->link : &obj->pt_list); + } +unlock: + spin_unlock_irq(&obj->lock); + + return pt; +} + +/** + * sync_timeline_create() - creates a sync object + * @name: sync_timeline name + * + * Creates a new sync_timeline. Returns the sync_timeline object or NULL in + * case of error. + */ +static struct dma_fence_timeline *pvr_sync_timeline_create(const char *name, const struct dma_fence_ops *ops) +{ + struct dma_fence_timeline *obj; + + obj = kzalloc(sizeof(*obj), GFP_KERNEL); + if (!obj) + return NULL; + + kref_init(&obj->kref); + obj->ops = ops; + obj->context = dma_fence_context_alloc(1); + strlcpy(obj->name, name, sizeof(obj->name)); + + obj->pt_tree = RB_ROOT; + INIT_LIST_HEAD(&obj->pt_list); + spin_lock_init(&obj->lock); + + //sync_timeline_debug_add(obj); + + return obj; +} + +static bool timeline_fence_signaled(struct dma_fence *fence) +{ + return pvr_sync_has_signaled(fence); +} + +/** + * pvr_sync_timeline_signal() - signal a status change on a sync_timeline + * @obj: sync_timeline to signal + * @inc: num to increment on timeline->value + * + * A sync implementation should call this any time one of it's fences + * has signaled or has an error condition. + */ +static void pvr_sync_timeline_signal(struct dma_fence_timeline *obj) +{ + struct dma_fence_pt *pt, *next; + + //trace_sync_timeline(obj); + + spin_lock_irq(&obj->lock); + + //obj->value += inc; + + list_for_each_entry_safe(pt, next, &obj->pt_list, link) { + if (!timeline_fence_signaled(&pt->base)) + break; + + list_del_init(&pt->link); + rb_erase(&pt->node, &obj->pt_tree); + + /* + * A signal callback may release the last reference to this + * fence, causing it to be freed. That operation has to be + * last to avoid a use after free inside this loop, and must + * be after we remove the fence from the timeline in order to + * prevent deadlocking on timeline->lock inside + * timeline_fence_release(). + */ + dma_fence_signal_locked(&pt->base); + } + + spin_unlock_irq(&obj->lock); +} + +void pvr_sync_timeline_destroy(struct dma_fence_timeline *obj) +{ + //obj->destroyed = true; + /* + * Ensure timeline is marked as destroyed before + * changing timeline's fences status. + */ + //smp_wmb(); + + /* + * signal any children that their parent is going away. + */ + pvr_sync_timeline_signal(obj); + sync_timeline_put(obj); +} + +static inline bool is_pvr_timeline(struct dma_fence_timeline *obj) +{ + return obj->ops == &pvr_fence_ops; +} + +static inline bool is_pvr_dma_fence(struct dma_fence *dma_fence) +{ + return dma_fence->ops == &pvr_fence_ops; +} + +/* foreign sync handling */ + +static void pvr_sync_foreign_sync_pt_signaled(struct dma_fence *fence, + struct dma_fence_cb *_waiter) +{ + struct pvr_sync_fence_waiter *waiter = + (struct pvr_sync_fence_waiter *)_waiter; + unsigned long flags; + + /* Complete the SW operation and free the sync if we can. If we can't, + * it will be checked by a later workqueue kick. + */ + complete_sync(waiter->kernel->fence_sync); + + /* We can 'put' the fence now, but this function might be called in + * irq context so we must defer to WQ. + * This WQ is triggered in pvr_sync_defer_free, so adding it to the + * put list before that should guarantee it's cleaned up on the next + * wq run. + */ + spin_lock_irqsave(&sync_fence_put_list_spinlock, flags); + list_add_tail(&waiter->sync_fence->list, &sync_fence_put_list); + spin_unlock_irqrestore(&sync_fence_put_list_spinlock, flags); + + pvr_sync_defer_free(waiter->kernel); + + /* The completed sw-sync may allow other tasks to complete, + * so we need to allow them to progress. + */ + queue_work(pvr_sync_data.check_status_wq, + &pvr_sync_data.check_status_work); + + kfree(waiter); +} + +static struct pvr_sync_kernel_pair * +pvr_sync_create_waiter_for_foreign_sync(int fd) +{ + struct pvr_sync_native_sync_prim *cleanup_sync = NULL; + struct pvr_sync_kernel_pair *kernel = NULL; + struct pvr_sync_fence_waiter *waiter; + struct pvr_sync_fence *sync_fence; + + struct sync_file *fence; + + enum PVRSRV_ERROR error; + int err; + + //fence = sync_fence_fdget(fd); + fence = sync_file_get(fd); + if (!fence) { + pr_err("pvr_sync: %s: Failed to take reference on fence\n", + __func__); + goto err_out; + } + + kernel = kmalloc(sizeof(*kernel), GFP_KERNEL); + if (!kernel) { + pr_err("pvr_sync: %s: Failed to allocate sync kernel\n", + __func__); + goto err_put_fence; + } + + INIT_LIST_HEAD(&kernel->cleanup_sync_list); + + sync_fence = kmalloc(sizeof(*sync_fence), GFP_KERNEL); + if (!sync_fence) { + pr_err("pvr_sync: %s: Failed to allocate pvr sync fence\n", + __func__); + goto err_free_kernel; + } + + sync_fence->fence = fence; + + error = sync_pool_get(&kernel->fence_sync, + fence->user_name, SYNC_PT_FOREIGN_FENCE_TYPE); + if (error != PVRSRV_OK) { + pr_err("pvr_sync: %s: Failed to allocate sync prim (%s)\n", + __func__, PVRSRVGetErrorStringKM(error)); + goto err_free_sync_fence; + } + + kernel->fence_sync->next_value++; + + error = sync_pool_get(&cleanup_sync, fence->user_name, + SYNC_PT_FOREIGN_CLEANUP_TYPE); + if (error != PVRSRV_OK) { + pr_err("pvr_sync: %s: Failed to allocate cleanup sync prim (%s)\n", + __func__, PVRSRVGetErrorStringKM(error)); + goto err_free_sync; + } + + cleanup_sync->next_value++; + + list_add(&cleanup_sync->cleanup_list, &kernel->cleanup_sync_list); + + /* The custom waiter structure is freed in the waiter callback */ + waiter = kmalloc(sizeof(*waiter), GFP_KERNEL); + if (!waiter) { + pr_err("pvr_sync: %s: Failed to allocate waiter\n", __func__); + goto err_free_cleanup_sync; + } + + waiter->kernel = kernel; + waiter->sync_fence = sync_fence; + + err = dma_fence_add_callback(fence->fence, &waiter->waiter, + pvr_sync_foreign_sync_pt_signaled); + if (err) { + /* Fence signaled, get the completion result */ + err = dma_fence_get_status(fence->fence); + /* remap success completion to err code */ + if (err == 1) + err = 0; + + if (err < 0) { + pr_err("pvr_sync: %s: Fence was in error state (%d)\n", + __func__, err); + /* Fall-thru */ + + /* -1 means the fence was broken, 1 means the fence already + * signalled. In either case, roll back what we've done and + * skip using this sync_pt for synchronization. + */ + goto err_free_waiter; + } + } + + kernel->current_cleanup_sync = cleanup_sync; + +err_out: + return kernel; +err_free_waiter: + kfree(waiter); +err_free_cleanup_sync: + list_del(&cleanup_sync->cleanup_list); + sync_pool_put(cleanup_sync); +err_free_sync: + sync_pool_put(kernel->fence_sync); +err_free_sync_fence: + kfree(sync_fence); +err_free_kernel: + kfree(kernel); + kernel = NULL; +err_put_fence: + sync_file_put(fence); + goto err_out; +} + +static +struct pvr_sync_pt *pvr_sync_create_pt(struct pvr_sync_timeline *timeline) +{ + struct pvr_sync_data *sync_data; + struct pvr_sync_pt *pvr_pt = NULL; + + sync_data = pvr_sync_create_sync_data(timeline->obj); + if (!sync_data) { + pr_err("pvr_sync: %s: Failed to create sync data\n", __func__); + goto err_out; + } + + sync_data->kernel->fence_sync->next_value++; + +//Warning + pvr_pt = (struct pvr_sync_pt *) + pvr_sync_pt_create(timeline->obj, ++timeline->obj->value, sync_data); + + if (!pvr_pt) { + pr_err("pvr_sync: %s: Failed to create sync pt\n", __func__); + goto err_rollback_fence; + } + + /* Increment the timeline next value */ + pvr_pt->sync_data->timeline_update_value = + timeline->kernel->fence_sync->next_value++; + + return pvr_pt; + +err_rollback_fence: + sync_data->kernel->fence_sync->next_value--; + kref_put(&sync_data->kref, pvr_sync_free_sync_data); +err_out: + return NULL; +} + +/* Predeclare the pvr_sync_fops as it's used for comparison to ensure the + * update_timeline_fd passed in to pvr_sync_append_fences() is a pvr_sync + * timeline. + */ +static const struct file_operations pvr_sync_fops; + +enum PVRSRV_ERROR pvr_sync_append_fences( + const char *name, + const s32 check_fence_fd, + const s32 update_timeline_fd, + const u32 nr_updates, + const struct _RGXFWIF_DEV_VIRTADDR_ *update_ufo_addresses, + const u32 *update_values, + const u32 nr_checks, + const struct _RGXFWIF_DEV_VIRTADDR_ *check_ufo_addresses, + const u32 *check_values, + struct pvr_sync_append_data **append_sync_data) +{ + struct pvr_sync_native_sync_prim **cleanup_sync_pos; + struct pvr_sync_pt *update_point = NULL; + struct sync_file *update_fence = NULL; + struct pvr_sync_append_data *sync_data; + struct _RGXFWIF_DEV_VIRTADDR_ *update_address_pos; + struct _RGXFWIF_DEV_VIRTADDR_ *check_address_pos; + struct pvr_sync_timeline *timeline; + unsigned int num_used_sync_updates; + unsigned int num_used_sync_checks; + enum PVRSRV_ERROR err = PVRSRV_OK; + u32 *update_value_pos; + u32 *check_value_pos; + + struct dma_fence **fences = NULL; + unsigned int num_fences; + + if ((nr_updates && (!update_ufo_addresses || !update_values)) || + (nr_checks && (!check_ufo_addresses || !check_values))) { + err = PVRSRV_ERROR_INVALID_PARAMS; + goto err_out; + } + + sync_data = + kzalloc(sizeof(*sync_data), GFP_KERNEL); + if (!sync_data) { + err = PVRSRV_ERROR_OUT_OF_MEMORY; + goto err_out; + } + + sync_data->update_fence_fd = -1; + + if (update_timeline_fd >= 0) { + struct file *timeline_file; + + /* We reserve the update fence FD before taking any operations + * as we do not want to fail (e.g. run out of FDs) after the + * kick operation has been submitted to the hw. + */ + sync_data->update_fence_fd = get_unused_fd(); + if (sync_data->update_fence_fd < 0) { + err = PVRSRV_ERROR_OUT_OF_MEMORY; + goto err_free_append_data; + } + + timeline_file = fget(update_timeline_fd); + if (!timeline_file) { + pr_err("pvr_sync: %s: Failed to open supplied timeline fd (%d)\n", + __func__, update_timeline_fd); + err = PVRSRV_ERROR_HANDLE_NOT_FOUND; + goto err_free_append_data; + } + + if (timeline_file->f_op != &pvr_sync_fops) { + pr_err("pvr_sync: %s: Supplied timeline not pvr_sync timeline\n", + __func__); + fput(timeline_file); + err = PVRSRV_ERROR_INVALID_PARAMS; + goto err_free_append_data; + } + + timeline = get_timeline(timeline_file->private_data); + + /* We know this will not free the timeline as the user still + * has the fd referencing it. + */ + fput(timeline_file); + + if (!timeline) { + pr_err("pvr_sync: %s: Supplied timeline has no private data\n", + __func__); + err = PVRSRV_ERROR_HANDLE_NOT_FOUND; + goto err_free_append_data; + } + + update_point = pvr_sync_create_pt(timeline); + if (!update_point) { + printk("rk-debug pvr_sync: %s: Failed to create sync point\n", + __func__); + err = PVRSRV_ERROR_OUT_OF_MEMORY; + goto err_free_append_data; + } + + //update_fence = sync_fence_create(name, &update_point->pt); + update_fence = sync_file_create(&update_point->pt.base); + if (!update_fence) { + struct pvr_sync_native_sync_prim *fence_prim = + update_point->sync_data->kernel->fence_sync; + struct pvr_sync_native_sync_prim *timeline_prim = + timeline->kernel->fence_sync; + + pr_err("pvr_sync: %s: Failed to create sync file\n", + __func__); + err = PVRSRV_ERROR_OUT_OF_MEMORY; + + /* If the point was created but the fence failed to be + * created, the point must be manually free'd as a + * fence has not yet taken ownership. + */ + + /* First rollback the point's taken operations */ + timeline_prim->next_value--; + fence_prim->next_value--; + pvr_sync_free_sync(&update_point->pt); + goto err_free_append_data; + } + + sync_data->update_fence = update_fence; + sync_data->update_sync = + update_point->sync_data->kernel->fence_sync; + sync_data->update_timeline_sync = + timeline->kernel->fence_sync; + } + + sync_data->nr_checks = nr_checks; + sync_data->nr_updates = nr_updates; + + if (check_fence_fd >= 0) { + struct sync_file *fence = sync_file_get(check_fence_fd); // check_fence + struct pvr_sync_kernel_pair *sync_kernel; + unsigned int points_on_fence = 0; + bool has_foreign_point = false; + // struct dma_fence_pt *sync_pt; + struct dma_fence *dma_fence; + int j; + + if (!fence) { + pr_err("pvr_sync: %s: Failed to read sync private data for fd %d\n", + __func__, check_fence_fd); + err = PVRSRV_ERROR_HANDLE_NOT_FOUND; + goto err_free_fence; + } + + sync_data->check_fence = fence; + + /*-----------------------------------*/ + + if (dma_fence_is_array(fence->fence)) { + struct dma_fence_array *array = to_dma_fence_array(fence->fence); + if (!array) { + pr_err("%s: Failed to resolve dma fence array\n", + __func__); + } + + fences = array->fences; + num_fences = array->num_fences; + } else { + fences = &fence->fence; + num_fences = 1; + } + + (void)j; + for (j = 0, + dma_fence = ((num_fences == 0) ? NULL : fences[0]); + j < num_fences; + j++, + dma_fence = ((j < num_fences) ? fences[j] : NULL)) { + //for_each_sync_pt(sync_pt, fence, j) ... + struct pvr_sync_native_sync_prim *cleanup_sync = NULL; + struct dma_fence_pt *sync_pt; + struct pvr_sync_pt *pvr_pt; + + // if (!is_dma_fence_pt(fences[j])) { + if (!is_pvr_dma_fence(dma_fence)) { + // if (!sync_pt_get_status(sync_pt)) + if (!dma_fence_is_signaled(dma_fence)) + has_foreign_point = true; + continue; + } + + sync_pt = (struct dma_fence_pt *)dma_fence; + pvr_pt = (struct pvr_sync_pt *)sync_pt; + sync_kernel = pvr_pt->sync_data->kernel; + + if (!sync_kernel || + is_sync_met(sync_kernel->fence_sync)) { + continue; + } + + /* We will use the above sync for "check" only. In this + * case also insert a "cleanup" update command into the + * opengl stream. This can later be used for checking + * if the sync prim could be freed. + */ + err = sync_pool_get(&cleanup_sync, + pvr_sync_pt_parent(&pvr_pt->pt)->name, + SYNC_PT_CLEANUP_TYPE); + if (err != PVRSRV_OK) { + pr_err("pvr_sync: %s: Failed to allocate cleanup sync prim (%s)\n", + __func__, + PVRSRVGetErrorStringKM(err)); + goto err_free_append_data; + } + list_add(&cleanup_sync->cleanup_list, + &sync_kernel->cleanup_sync_list); + sync_kernel->current_cleanup_sync = cleanup_sync; + points_on_fence++; + } + + if (has_foreign_point) + points_on_fence++; + + /* Each point has 1 check value, and 1 update value (for the + * cleanup fence). + */ + sync_data->nr_checks += points_on_fence; + sync_data->nr_updates += points_on_fence; + sync_data->nr_cleanup_syncs += points_on_fence; + } + + if (update_point) { + /* A fence update requires 2 update values (fence and timeline) + */ + sync_data->nr_updates += 2; + } + + if (sync_data->nr_updates > 0) { + sync_data->update_ufo_addresses = + kzalloc(sizeof(*sync_data->update_ufo_addresses) * + sync_data->nr_updates, GFP_KERNEL); + if (!sync_data->update_ufo_addresses) { + pr_err("pvr_sync: %s: Failed to allocate update UFO address list\n", + __func__); + err = PVRSRV_ERROR_OUT_OF_MEMORY; + goto err_free_fence; + } + + sync_data->update_values = + kzalloc(sizeof(*sync_data->update_values) * + sync_data->nr_updates, GFP_KERNEL); + if (!sync_data->update_values) { + pr_err("pvr_sync: %s: Failed to allocate update value list\n", + __func__); + err = PVRSRV_ERROR_OUT_OF_MEMORY; + goto err_free_fence; + } + } + + if (sync_data->nr_checks > 0) { + + sync_data->check_ufo_addresses = + kzalloc(sizeof(*sync_data->check_ufo_addresses) * + sync_data->nr_checks, GFP_KERNEL); + if (!sync_data->check_ufo_addresses) { + pr_err("pvr_sync: %s: Failed to allocate check UFO address list\n", + __func__); + err = PVRSRV_ERROR_OUT_OF_MEMORY; + goto err_free_fence; + } + + sync_data->check_values = + kzalloc(sizeof(*sync_data->check_values) * + sync_data->nr_checks, GFP_KERNEL); + if (!sync_data->check_values) { + pr_err("pvr_sync: %s: Failed to allocate check value list\n", + __func__); + err = PVRSRV_ERROR_OUT_OF_MEMORY; + goto err_free_fence; + } + } + + if (sync_data->nr_cleanup_syncs > 0) { + sync_data->cleanup_syncs = + kzalloc(sizeof(*sync_data->cleanup_syncs) * + sync_data->nr_cleanup_syncs, GFP_KERNEL); + if (!sync_data->cleanup_syncs) { + pr_err("pvr_sync: %s: Failed to allocate cleanup rollback list\n", + __func__); + err = PVRSRV_ERROR_OUT_OF_MEMORY; + goto err_free_fence; + } + } + + update_address_pos = sync_data->update_ufo_addresses; + update_value_pos = sync_data->update_values; + check_address_pos = sync_data->check_ufo_addresses; + check_value_pos = sync_data->check_values; + cleanup_sync_pos = sync_data->cleanup_syncs; + + /* Everything should be allocated/sanity checked. No errors are + * possible after this point. + */ + + /* Append any check syncs */ + if (sync_data->check_fence) { + struct sync_file *fence = sync_data->check_fence; + bool has_foreign_point = false; + // struct dma_fence_pt *sync_pt; + struct dma_fence *dma_fence; + int j; + + if (dma_fence_is_array(fence->fence)) { + struct dma_fence_array *array = to_dma_fence_array(fence->fence); + if (!array) { + pr_err("%s: Failed to resolve dma fence array\n", + __func__); + } + + fences = array->fences; + num_fences = array->num_fences; + } else { + fences = &fence->fence; + num_fences = 1; + } + + (void)j; + for (j = 0, + dma_fence = ((num_fences == 0) ? NULL : fences[0]); + j < num_fences; + j++, + dma_fence = ((j < num_fences) ? fences[j] : NULL)) { + //for_each_sync_pt(sync_pt, fence, j) ... + struct dma_fence_pt *sync_pt; + struct pvr_sync_pt *pvr_pt; + struct pvr_sync_kernel_pair *sync_kernel; + + // if (!is_dma_fence_pt(fences[j])) { + if (!is_pvr_dma_fence(dma_fence)) { + // if (!sync_pt_get_status(sync_pt)) + if (!dma_fence_is_signaled(dma_fence)) + has_foreign_point = true; + continue; + } + + sync_pt = (struct dma_fence_pt *)dma_fence; + pvr_pt = (struct pvr_sync_pt *)sync_pt; + sync_kernel = pvr_pt->sync_data->kernel; + + if (!sync_kernel || + is_sync_met(sync_kernel->fence_sync)) { + continue; + } + + (*check_address_pos++).ui32Addr = + sync_kernel->fence_sync->vaddr; + *check_value_pos++ = + sync_kernel->fence_sync->next_value; + + (*update_address_pos++).ui32Addr = + sync_kernel->current_cleanup_sync->vaddr; + *update_value_pos++ = + ++sync_kernel->current_cleanup_sync->next_value; + *cleanup_sync_pos++ = sync_kernel->current_cleanup_sync; + + sync_kernel->current_cleanup_sync = NULL; + } + + if (has_foreign_point) { + struct pvr_sync_kernel_pair *foreign_sync_kernel = + pvr_sync_create_waiter_for_foreign_sync( + check_fence_fd); + + if (foreign_sync_kernel) { + struct pvr_sync_native_sync_prim *fence_sync = + foreign_sync_kernel->fence_sync; + struct pvr_sync_native_sync_prim *cleanup_sync = + foreign_sync_kernel-> + current_cleanup_sync; + + (*check_address_pos++).ui32Addr = + fence_sync->vaddr; + *check_value_pos++ = + fence_sync->next_value; + + (*update_address_pos++).ui32Addr = + cleanup_sync->vaddr; + *update_value_pos++ = + ++cleanup_sync->next_value; + *cleanup_sync_pos++ = cleanup_sync; + foreign_sync_kernel->current_cleanup_sync = + NULL; + } + } + } + + /* Append the update sync (if requested) */ + if (update_point) { + struct pvr_sync_data *sync_data = + update_point->sync_data; + struct pvr_sync_kernel_pair *sync_kernel = + sync_data->kernel; + + (*update_address_pos++).ui32Addr = + sync_kernel->fence_sync->vaddr; + *update_value_pos++ = + sync_kernel->fence_sync->next_value; + + (*update_address_pos++).ui32Addr = + timeline->kernel->fence_sync->vaddr; + + /* Copy in the timeline next value (which was incremented + * when this point was created). + */ + sync_data->timeline_update_value = + timeline->kernel->fence_sync->next_value; + + /* ...and set that to be updated when this kick is completed */ + *update_value_pos++ = + sync_data->timeline_update_value; + } + + /* We count the total number of sync points we attach, as it's possible + * some have become complete since the first loop through, or a waiter + * for a foreign point skipped (But they can never become un-complete, + * so it will only ever be the same or less, so the allocated arrays + * should still be sufficiently sized). + */ + num_used_sync_updates = + update_address_pos - sync_data->update_ufo_addresses; + num_used_sync_checks = + check_address_pos - sync_data->check_ufo_addresses; + + sync_data->nr_checks = nr_checks + num_used_sync_checks; + sync_data->nr_updates = nr_updates + num_used_sync_updates; + + /* Append original check and update sync values/addresses */ + if (update_ufo_addresses) + memcpy(update_address_pos, update_ufo_addresses, + sizeof(*update_ufo_addresses) * nr_updates); + if (update_values) + memcpy(update_value_pos, update_values, + sizeof(*update_values) * nr_updates); + + if (check_ufo_addresses) + memcpy(check_address_pos, check_ufo_addresses, + sizeof(*check_ufo_addresses) * nr_checks); + if (check_values) + memcpy(check_value_pos, check_values, + sizeof(*check_values) * nr_checks); + + *append_sync_data = sync_data; + + return PVRSRV_OK; + +err_free_fence: + if (update_point) { + /* First rollback the taken operations */ + timeline->kernel->fence_sync->next_value--; + update_point->sync_data->kernel->fence_sync->next_value--; + } +err_free_append_data: + pvr_sync_free_append_fences_data(sync_data); +err_out: + return err; +} + +void pvr_sync_get_updates(const struct pvr_sync_append_data *sync_data, + u32 *nr_fences, struct _RGXFWIF_DEV_VIRTADDR_ **ufo_addrs, u32 **values) +{ + *nr_fences = sync_data->nr_updates; + *ufo_addrs = sync_data->update_ufo_addresses; + *values = sync_data->update_values; +} + +void pvr_sync_get_checks(const struct pvr_sync_append_data *sync_data, + u32 *nr_fences, struct _RGXFWIF_DEV_VIRTADDR_ **ufo_addrs, u32 **values) +{ + *nr_fences = sync_data->nr_checks; + *ufo_addrs = sync_data->check_ufo_addresses; + *values = sync_data->check_values; +} + +void pvr_sync_rollback_append_fences(struct pvr_sync_append_data *sync_data) +{ + u32 i; + + if (!sync_data) + return; + + for (i = 0; i < sync_data->nr_cleanup_syncs; i++) { + struct pvr_sync_native_sync_prim *cleanup_sync = + sync_data->cleanup_syncs[i]; + + /* If this cleanup was called on a partially-created data set + * it's possible to have NULL cleanup sync pointers. + */ + if (!cleanup_sync) + continue; + cleanup_sync->next_value--; + } + + /* If there was an update, rollback the next values taken on the + * fence and timeline. This must be done before the sync_fence_put() + * as that may free the corresponding fence. + */ + + if (sync_data->update_sync) { + BUG_ON(sync_data->update_sync->next_value != 1); + sync_data->update_sync->next_value = 0; + sync_data->update_sync = NULL; + } + + if (sync_data->update_timeline_sync) { + BUG_ON(sync_data->update_timeline_sync->next_value == 0); + sync_data->update_timeline_sync->next_value--; + sync_data->update_timeline_sync = NULL; + } +} + +int pvr_sync_get_update_fd(struct pvr_sync_append_data *sync_data) +{ + int fd = -EINVAL; + + if (!sync_data || !sync_data->update_fence || + sync_data->update_fence_fd < 0) + goto err_out; + + fd = sync_data->update_fence_fd; + sync_data->update_fence_fd = -1; + + pvr_sync_fence_install(sync_data->update_fence, fd); + + /* Note: It is invalid for an FD to have been installed on the update + * fence then fput called - as this would leave a dangling reference + * in the FD table. Set it to NULL so the free_append_fences_data() + * call doesn't fput it. + */ + sync_data->update_fence = NULL; + +err_out: + return fd; +} + +void pvr_sync_free_append_fences_data(struct pvr_sync_append_data *sync_data) +{ + if (!sync_data) + return; + + if (sync_data->check_fence) + sync_file_put(sync_data->check_fence); + + if (sync_data->update_fence) + sync_file_put(sync_data->update_fence); + + if (sync_data->update_fence_fd >= 0) + put_unused_fd(sync_data->update_fence_fd); + + kfree(sync_data->update_ufo_addresses); + kfree(sync_data->update_values); + kfree(sync_data->check_ufo_addresses); + kfree(sync_data->check_values); + kfree(sync_data->cleanup_syncs); + kfree(sync_data); +} + +void pvr_sync_nohw_complete_fences(struct pvr_sync_append_data *sync_data) +{ + u32 i; + + if (!sync_data) + return; + + for (i = 0; i < sync_data->nr_cleanup_syncs; i++) { + struct pvr_sync_native_sync_prim *cleanup_sync = + sync_data->cleanup_syncs[i]; + + if (!cleanup_sync) + continue; + + complete_sync(cleanup_sync); + } + + if (sync_data->update_sync) + complete_sync(sync_data->update_sync); + if (sync_data->update_timeline_sync) + complete_sync(sync_data->update_timeline_sync); + + pvr_sync_update_all_timelines(NULL); +} + +/* ioctl and fops handling */ + +static int pvr_sync_open(struct inode *inode, struct file *file) +{ + struct pvr_sync_timeline_wrapper *timeline_wrapper; + struct pvr_sync_timeline *timeline; + char task_comm[TASK_COMM_LEN]; + enum PVRSRV_ERROR error; + int err = -ENOMEM; + + get_task_comm(task_comm, current); + +//Warning + timeline_wrapper = (struct pvr_sync_timeline_wrapper *) + pvr_sync_timeline_create(task_comm, &pvr_fence_ops); + if (!timeline_wrapper) { + pr_err("pvr_sync: %s: pvr_sync_timeline_create failed\n", __func__); + goto err_out; + } + + timeline = kmalloc(sizeof(*timeline), GFP_KERNEL); + if (!timeline) { + pr_err("pvr_sync: %s: Out of memory\n", __func__); + goto err_free_timeline_wrapper; + } + + timeline->kernel = kzalloc(sizeof(*timeline->kernel), + GFP_KERNEL); + if (!timeline->kernel) { + pr_err("pvr_sync: %s: Out of memory\n", __func__); + goto err_free_timeline; + } + + INIT_LIST_HEAD(&timeline->kernel->cleanup_sync_list); + + OSAcquireBridgeLock(); + error = sync_pool_get(&timeline->kernel->fence_sync, + task_comm, SYNC_TL_TYPE); + OSReleaseBridgeLock(); + + if (error != PVRSRV_OK) { + pr_err("pvr_sync: %s: Failed to allocate sync prim (%s)\n", + __func__, PVRSRVGetErrorStringKM(error)); + goto err_free_timeline_kernel; + } + + timeline_wrapper->timeline = timeline; + + timeline->obj = &timeline_wrapper->obj; + kref_init(&timeline->kref); + + mutex_lock(&timeline_list_mutex); + list_add_tail(&timeline->list, &timeline_list); + mutex_unlock(&timeline_list_mutex); + + DPF("%s: # %s", __func__, debug_info_timeline(timeline)); + + file->private_data = timeline_wrapper; + err = 0; +err_out: + return err; + +err_free_timeline_kernel: + kfree(timeline->kernel); +err_free_timeline: + kfree(timeline); + + /* Use a NULL timeline to detect this partially-setup timeline in the + * timeline release function (called by sync_timeline_destroy) and + * handle it appropriately. + */ + timeline_wrapper->timeline = NULL; +err_free_timeline_wrapper: + pvr_sync_timeline_destroy(&timeline_wrapper->obj); + goto err_out; +} + +static int pvr_sync_close(struct inode *inode, struct file *file) +{ + struct dma_fence_timeline *obj = file->private_data; + + if (is_pvr_timeline(obj)) { + DPF("%s: # %s", __func__, + debug_info_timeline(get_timeline(obj))); + } + + pvr_sync_timeline_destroy(obj); + return 0; +} + +static long pvr_sync_ioctl_rename(struct pvr_sync_timeline *timeline, + void __user *user_data) +{ + int err = 0; + struct pvr_sync_rename_ioctl_data data; + + if (!access_ok(VERIFY_READ, user_data, sizeof(data))) { + err = -EFAULT; + goto err; + } + + if (copy_from_user(&data, user_data, sizeof(data))) { + err = -EFAULT; + goto err; + } + + data.szName[sizeof(data.szName) - 1] = '\0'; + strlcpy(timeline->obj->name, data.szName, sizeof(timeline->obj->name)); + + mutex_lock(&sync_pool_mutex); + strlcpy(timeline->kernel->fence_sync->class, data.szName, + sizeof(timeline->kernel->fence_sync->class)); + mutex_unlock(&sync_pool_mutex); +err: + return err; +} + +static long +pvr_sync_ioctl(struct file *file, unsigned int cmd, unsigned long __user arg) +{ + struct dma_fence_timeline *obj = file->private_data; + void __user *user_data = (void __user *)arg; + long err = -ENOTTY; + + if (is_pvr_timeline(obj)) { + struct pvr_sync_timeline *pvr = get_timeline(obj); + + switch (cmd) { + case PVR_SYNC_IOC_RENAME: + err = pvr_sync_ioctl_rename(pvr, user_data); + break; + default: + break; + } + } + + return err; +} + +static void +pvr_sync_check_status_work_queue_function(struct work_struct *data) +{ + /* A completed SW operation may un-block the GPU */ + PVRSRVCheckStatus(NULL); +} + +/* Returns true if the freelist still has entries, else false if empty */ +static bool +pvr_sync_clean_freelist(void) +{ + struct pvr_sync_kernel_pair *kernel, *k; + struct pvr_sync_fence *sync_fence, *f; + LIST_HEAD(unlocked_free_list); + unsigned long flags; + bool freelist_empty; + + /* We can't call PVRSRVServerSyncFreeKM directly in this loop because + * that will take the mmap mutex. We can't take mutexes while we have + * this list locked with a spinlock. So move all the items we want to + * free to another, local list (no locking required) and process it + * in a second loop. + */ + + spin_lock_irqsave(&sync_prim_free_list_spinlock, flags); + list_for_each_entry_safe(kernel, k, &sync_prim_free_list, list) { + bool in_use = false; + struct list_head *pos; + + /* Check if this sync is not used anymore. */ + if (!is_sync_met(kernel->fence_sync)) + continue; + list_for_each(pos, &kernel->cleanup_sync_list) { + struct pvr_sync_native_sync_prim *cleanup_sync = + list_entry(pos, + struct pvr_sync_native_sync_prim, + cleanup_list); + + if (!is_sync_met(cleanup_sync)) { + in_use = true; + break; + } + } + + if (in_use) + continue; + + /* Remove the entry from the free list. */ + list_move_tail(&kernel->list, &unlocked_free_list); + } + + /* Wait and loop if there are still syncs on the free list (IE + * are still in use by the HW). + */ + freelist_empty = list_empty(&sync_prim_free_list); + + spin_unlock_irqrestore(&sync_prim_free_list_spinlock, flags); + + OSAcquireBridgeLock(); + + list_for_each_entry_safe(kernel, k, &unlocked_free_list, list) { + struct list_head *pos, *n; + + list_del(&kernel->list); + + sync_pool_put(kernel->fence_sync); + + list_for_each_safe(pos, n, &kernel->cleanup_sync_list) { + struct pvr_sync_native_sync_prim *cleanup_sync = + list_entry(pos, + struct pvr_sync_native_sync_prim, + cleanup_list); + list_del(&cleanup_sync->cleanup_list); + sync_pool_put(cleanup_sync); + } + kfree(kernel); + } + + OSReleaseBridgeLock(); + + /* sync_fence_put() must be called from process/WQ context + * because it uses fput(), which is not allowed to be called + * from interrupt context in kernels <3.6. + */ + INIT_LIST_HEAD(&unlocked_free_list); + + spin_lock_irqsave(&sync_fence_put_list_spinlock, flags); + list_for_each_entry_safe(sync_fence, f, &sync_fence_put_list, list) { + list_move_tail(&sync_fence->list, &unlocked_free_list); + } + spin_unlock_irqrestore(&sync_fence_put_list_spinlock, flags); + + list_for_each_entry_safe(sync_fence, f, &unlocked_free_list, list) { + list_del(&sync_fence->list); + sync_file_put(sync_fence->fence); + kfree(sync_fence); + } + + return !freelist_empty; +} + +static void +pvr_sync_defer_free_work_queue_function(struct work_struct *data) +{ + enum PVRSRV_ERROR error = PVRSRV_OK; + void *event_object; + + error = OSEventObjectOpen(pvr_sync_data.event_object_handle, + &event_object); + if (error != PVRSRV_OK) { + pr_err("pvr_sync: %s: Error opening event object (%s)\n", + __func__, PVRSRVGetErrorStringKM(error)); + return; + + } + + while (pvr_sync_clean_freelist()) { + + error = OSEventObjectWait(event_object); + + switch (error) { + + case PVRSRV_OK: + case PVRSRV_ERROR_TIMEOUT: + /* Timeout is normal behaviour */ + continue; + default: + pr_err("pvr_sync: %s: Error waiting for event object (%s)\n", + __func__, PVRSRVGetErrorStringKM(error)); + break; + } + } + error = OSEventObjectClose(event_object); + if (error != PVRSRV_OK) { + pr_err("pvr_sync: %s: Error closing event object (%s)\n", + __func__, PVRSRVGetErrorStringKM(error)); + } +} + +static const struct file_operations pvr_sync_fops = { + .owner = THIS_MODULE, + .open = pvr_sync_open, + .release = pvr_sync_close, + .unlocked_ioctl = pvr_sync_ioctl, + .compat_ioctl = pvr_sync_ioctl, +}; + +static struct miscdevice pvr_sync_device = { + .minor = MISC_DYNAMIC_MINOR, + .name = PVRSYNC_MODNAME, + .fops = &pvr_sync_fops, +}; + +static +void pvr_sync_update_all_timelines(void *command_complete_handle) +{ + struct pvr_sync_timeline *timeline, *n; + + mutex_lock(&timeline_list_mutex); + + list_for_each_entry(timeline, &timeline_list, list) { + /* If a timeline is destroyed via pvr_sync_release_timeline() + * in parallel with a call to pvr_sync_update_all_timelines(), + * the timeline_list_mutex will block destruction of the + * 'timeline' pointer. Use kref_get_unless_zero() to detect + * and handle this race. Skip the timeline if it's being + * destroyed, blocked only on the timeline_list_mutex. + */ + timeline->valid = + kref_get_unless_zero(&timeline->kref) ? true : false; + } + + list_for_each_entry_safe(timeline, n, &timeline_list, list) { + /* We know timeline is valid at this point because we're + * holding the list lock (so pvr_sync_destroy_timeline() has + * to wait). + */ + void *obj = timeline->obj; + + /* If we're racing with pvr_sync_release_timeline(), ignore */ + if (!timeline->valid) + continue; + + /* If syncs have signaled on the GPU, echo this in pvr_sync. + * + * At this point we know the timeline is valid, but obj might + * have raced and been set to NULL. It's only important that + * we use NULL / non-NULL consistently with the if() and call + * to sync_timeline_signal() -- the timeline->obj can't be + * freed (pvr_sync_release_timeline() will be stuck waiting + * for the timeline_list_mutex) but it might have been made + * invalid by the base sync driver, in which case this call + * will bounce harmlessly. + */ + if (obj) + pvr_sync_timeline_signal(obj); + + /* We're already holding the timeline_list_mutex */ + kref_put(&timeline->kref, pvr_sync_destroy_timeline_locked); + } + + mutex_unlock(&timeline_list_mutex); +} + +enum PVRSRV_ERROR pvr_sync_init(void *device_cookie) +{ + enum PVRSRV_ERROR error; + int err; + + DPF("%s", __func__); + + atomic_set(&pvr_sync_data.sync_id, 0); + + error = PVRSRVAcquireGlobalEventObjectKM( + &pvr_sync_data.event_object_handle); + if (error != PVRSRV_OK) { + pr_err("pvr_sync: %s: Failed to acquire global event object (%s)\n", + __func__, PVRSRVGetErrorStringKM(error)); + goto err_out; + } + + OSAcquireBridgeLock(); + + error = SyncPrimContextCreate(device_cookie, + &pvr_sync_data.sync_prim_context); + if (error != PVRSRV_OK) { + pr_err("pvr_sync: %s: Failed to create sync prim context (%s)\n", + __func__, PVRSRVGetErrorStringKM(error)); + OSReleaseBridgeLock(); + goto err_release_event_object; + } + + OSReleaseBridgeLock(); + + pvr_sync_data.defer_free_wq = + create_freezable_workqueue("pvr_sync_defer_free_workqueue"); + if (!pvr_sync_data.defer_free_wq) { + pr_err("pvr_sync: %s: Failed to create pvr_sync defer_free workqueue\n", + __func__); + goto err_free_sync_context; + } + + INIT_WORK(&pvr_sync_data.defer_free_work, + pvr_sync_defer_free_work_queue_function); + + pvr_sync_data.check_status_wq = + create_freezable_workqueue("pvr_sync_check_status_workqueue"); + if (!pvr_sync_data.check_status_wq) { + pr_err("pvr_sync: %s: Failed to create pvr_sync check_status workqueue\n", + __func__); + goto err_destroy_defer_free_wq; + } + + INIT_WORK(&pvr_sync_data.check_status_work, + pvr_sync_check_status_work_queue_function); + error = PVRSRVRegisterCmdCompleteNotify( + &pvr_sync_data.command_complete_handle, + &pvr_sync_update_all_timelines, + &device_cookie); + if (error != PVRSRV_OK) { + pr_err("pvr_sync: %s: Failed to register MISR notification (%s)\n", + __func__, PVRSRVGetErrorStringKM(error)); + goto err_destroy_status_wq; + } + + error = PVRSRVRegisterDbgRequestNotify( + &pvr_sync_data.debug_notify_handle, + device_cookie, + pvr_sync_debug_request, + DEBUG_REQUEST_ANDROIDSYNC, + NULL); + if (error != PVRSRV_OK) { + pr_err("pvr_sync: %s: Failed to register debug notifier (%s)\n", + __func__, PVRSRVGetErrorStringKM(error)); + goto err_unregister_cmd_complete; + } + + err = misc_register(&pvr_sync_device); + if (err) { + pr_err("pvr_sync: %s: Failed to register pvr_sync device (%d)\n", + __func__, err); + error = PVRSRV_ERROR_RESOURCE_UNAVAILABLE; + goto err_unregister_dbg; + } + + error = PVRSRV_OK; + return error; + +err_unregister_dbg: + PVRSRVUnregisterDbgRequestNotify(pvr_sync_data.debug_notify_handle); +err_unregister_cmd_complete: + PVRSRVUnregisterCmdCompleteNotify( + pvr_sync_data.command_complete_handle); +err_destroy_status_wq: + destroy_workqueue(pvr_sync_data.check_status_wq); +err_destroy_defer_free_wq: + destroy_workqueue(pvr_sync_data.defer_free_wq); +err_free_sync_context: + OSAcquireBridgeLock(); + SyncPrimContextDestroy(pvr_sync_data.sync_prim_context); + OSReleaseBridgeLock(); +err_release_event_object: + PVRSRVReleaseGlobalEventObjectKM(pvr_sync_data.event_object_handle); +err_out: + + return error; +} + +void pvr_sync_deinit(void) +{ + DPF("%s", __func__); + + misc_deregister(&pvr_sync_device); + + PVRSRVUnregisterDbgRequestNotify(pvr_sync_data.debug_notify_handle); + + PVRSRVUnregisterCmdCompleteNotify( + pvr_sync_data.command_complete_handle); + + /* This will drain the workqueue, so we guarantee that all deferred + * syncs are free'd before returning. + */ + destroy_workqueue(pvr_sync_data.defer_free_wq); + destroy_workqueue(pvr_sync_data.check_status_wq); + + OSAcquireBridgeLock(); + + sync_pool_clear(); + + SyncPrimContextDestroy(pvr_sync_data.sync_prim_context); + + OSReleaseBridgeLock(); + + PVRSRVReleaseGlobalEventObjectKM(pvr_sync_data.event_object_handle); +} diff --git a/drivers/staging/imgtec/rogue/Makefile b/drivers/staging/imgtec/rogue/Makefile index 644308007e2a..9d0f4f31db4a 100644 --- a/drivers/staging/imgtec/rogue/Makefile +++ b/drivers/staging/imgtec/rogue/Makefile @@ -150,6 +150,8 @@ ccflags-$(CONFIG_POWERVR_ROGUE_PDUMP) += -DPDUMP=1 # Android native synchronisation pvrsrvkm-$(CONFIG_SYNC) += ../pvr_sync.o +pvrsrvkm-$(CONFIG_SYNC_FILE) += ../pvr_sync_file.o + # Generated bridge code pvrsrvkm-y += generated/mm_bridge/server_mm_bridge.o pvrsrvkm-y += generated/mm_bridge/client_mm_direct_bridge.o diff --git a/drivers/staging/imgtec/rogue/cache_km.c b/drivers/staging/imgtec/rogue/cache_km.c index d518af2d85d5..e883c9921e83 100644 --- a/drivers/staging/imgtec/rogue/cache_km.c +++ b/drivers/staging/imgtec/rogue/cache_km.c @@ -45,7 +45,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)) #include #else -#include <../drivers/staging/android/sw_sync.h> +//Warning +//#include <../drivers/staging/android/sw_sync.h> #endif #include #include @@ -285,7 +286,7 @@ static INLINE void CacheOpStatExecLogHeader(IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESS static INLINE void CacheOpStatExecLogWrite(DLLIST_NODE *psNode) { - CACHEOP_WORK_ITEM *psCacheOpWorkItem; + CACHEOP_WORK_ITEM *psCacheOpWorkItem = NULL; IMG_UINT64 ui64ExecuteTime; IMG_UINT64 ui64QueuedTime; IMG_INT32 i32WriteOffset; @@ -591,7 +592,7 @@ static INLINE void CacheOpCPURangeBased(PVRSRV_DEVICE_NODE *psDevNode, IMG_CPU_PHYADDR sCpuPhyAddrEnd; IMG_CPU_PHYADDR sCpuPhyAddrStart; IMG_DEVMEM_SIZE_T uiRelFlushSize; - IMG_DEVMEM_OFFSET_T uiRelFlushOffset; + IMG_DEVMEM_OFFSET_T uiRelFlushOffset = 0; IMG_DEVMEM_SIZE_T uiNextPgAlignedOffset; /* These quantities allows us to perform cache operations @@ -599,7 +600,6 @@ static INLINE void CacheOpCPURangeBased(PVRSRV_DEVICE_NODE *psDevNode, perform more than is necessary */ PVR_ASSERT(uiPgAlignedOffset < uiCLAlignedEndOffset); uiRelFlushSize = (IMG_DEVMEM_SIZE_T)guiOSPageSize; - uiRelFlushOffset = 0; if (uiCLAlignedStartOffset > uiPgAlignedOffset) { @@ -1705,7 +1705,13 @@ PVRSRV_ERROR CacheOpSetTimeline (IMG_INT32 i32Timeline) return PVRSRV_ERROR_INVALID_PARAMS; } - sw_sync_timeline_inc(psFile->private_data, 1); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) + sw_sync_timeline_inc(psFile->private_data, 1); +#else + //Warning + //if (0 != sw_sync_ioctl_inc(psFile->private_data, count)) + // printk("PVR SW_SYNC_IOC_INC failed \n"); +#endif fput(psFile); eError = PVRSRV_OK; @@ -1985,6 +1991,12 @@ PVRSRV_ERROR CacheOpExec (PMR *psPMR, } eError = CacheOpRangeBased(psPMR, uiOffset, uiSize, uiCacheOp, &bUsedGlobalFlush); + if (eError != PVRSRV_OK) { + PVR_DPF((CACHEOP_DPFL, + "%s: CacheOpRangeBased failed (%u)", + __FUNCTION__, eError)); + } + #if defined(CACHEOP_DEBUG) sCacheOpWorkItem.bUMF = IMG_FALSE; sCacheOpWorkItem.bRBF = !bUsedGlobalFlush; diff --git a/drivers/staging/imgtec/rogue/connection_data.h b/drivers/staging/imgtec/rogue/connection_data.h new file mode 100644 index 000000000000..5f0978128a69 --- /dev/null +++ b/drivers/staging/imgtec/rogue/connection_data.h @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* -------------------------------------------------------------------------------------------------------- + * File: connection_data.h + * -------------------------------------------------------------------------------------------------------- + */ + +#ifndef __CONNECTION_DATA_H__ +#define __CONNECTION_DATA_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* --------------------------------------------------------------------------------------------------------- + * Include Files + * --------------------------------------------------------------------------------------------------------- + */ +// #include + +#include "handle.h" +#include "img_types.h" +#include "pvrsrv_cleanup.h" + + +/* --------------------------------------------------------------------------------------------------------- + * Macros Definition + * --------------------------------------------------------------------------------------------------------- + */ + + +/* --------------------------------------------------------------------------------------------------------- + * Types and Structures Definition + * --------------------------------------------------------------------------------------------------------- + */ +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; + + IMG_PID pid; + + void *hSecureData; + + IMG_HANDLE hProcessStats; + + IMG_HANDLE hClientTLStream; + + /* Structure which is hooked into the cleanup thread work list */ + PVRSRV_CLEANUP_THREAD_WORK sCleanupThreadFn; + + /* List navigation for deferred freeing of connection data */ + struct _CONNECTION_DATA_ **ppsThis; + struct _CONNECTION_DATA_ *psNext; +} CONNECTION_DATA; + +/* --------------------------------------------------------------------------------------------------------- + * Global Functions' Prototype + * --------------------------------------------------------------------------------------------------------- + */ + + +/* --------------------------------------------------------------------------------------------------------- + * Inline Functions Implementation + * --------------------------------------------------------------------------------------------------------- + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CONNECTION_DATA_H__ */ + diff --git a/drivers/staging/imgtec/rogue/connection_server.h b/drivers/staging/imgtec/rogue/connection_server.h index 481a07a49561..7a0effcbf6c4 100644 --- a/drivers/staging/imgtec/rogue/connection_server.h +++ b/drivers/staging/imgtec/rogue/connection_server.h @@ -48,6 +48,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "img_types.h" #include "handle.h" #include "pvrsrv_cleanup.h" +#include "connection_data.h" /* Variable used to hold in memory the timeout for the current time slice*/ extern IMG_UINT64 gui64TimesliceLimit; @@ -56,39 +57,6 @@ 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; - - IMG_PID pid; - - void *hSecureData; - - IMG_HANDLE hProcessStats; - - IMG_HANDLE hClientTLStream; - - /* Structure which is hooked into the cleanup thread work list */ - PVRSRV_CLEANUP_THREAD_WORK sCleanupThreadFn; - - /* List navigation for deferred freeing of connection data */ - struct _CONNECTION_DATA_ **ppsThis; - struct _CONNECTION_DATA_ *psNext; -} CONNECTION_DATA; - #include "osconnection_server.h" PVRSRV_ERROR PVRSRVConnectionConnect(void **ppvPrivData, void *pvOSData); diff --git a/drivers/staging/imgtec/rogue/device.h b/drivers/staging/imgtec/rogue/device.h index f55d9358039e..e1dc6d1b59f7 100644 --- a/drivers/staging/imgtec/rogue/device.h +++ b/drivers/staging/imgtec/rogue/device.h @@ -45,6 +45,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define __DEVICE_H__ +#include "pvrsrv_device_node.h" +#include "lock_types.h" #include "devicemem_heapcfg.h" #include "mmu_common.h" #include "ra.h" /* RA_ARENA */ @@ -66,98 +68,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. struct pvr_buffer_sync_context; #endif -typedef struct _PVRSRV_POWER_DEV_TAG_ PVRSRV_POWER_DEV; - #if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) struct SYNC_RECORD; #endif -/*********************************************************************/ /*! - @Function AllocUFOCallback - @Description Device specific callback for allocation of an 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 FreeUFOCallback - @Description Device specific callback for freeing of an 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; -} 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; - /*Order of the corresponding allocation */ - IMG_UINT32 ui32Order; -} PG_HANDLE; - #define MMU_BAD_PHYS_ADDR (0xbadbad00badULL) -typedef struct __DUMMY_PAGE__ -{ - /*Page handle for the dummy page allocated (UMA/LMA)*/ - PG_HANDLE sDummyPageHandle; - POS_LOCK psDummyPgLock; - ATOMIC_T atRefCounter; - /*Dummy page size in terms of log2 */ - IMG_UINT32 ui32Log2DummyPgSize; - IMG_UINT64 ui64DummyPgPhysAddr; -#if defined(PDUMP) -#define DUMMY_PAGE ("DUMMY_PAGE") - IMG_HANDLE hPdumpDummyPg; -#endif -} PVRSRV_DUMMY_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_ { @@ -176,207 +92,6 @@ typedef enum _PVRSRV_DEVICE_HEALTH_REASON_ PVRSRV_DEVICE_HEALTH_REASON_QUEUE_STALLED } PVRSRV_DEVICE_HEALTH_REASON; -typedef PVRSRV_ERROR (*FN_CREATERAMBACKEDPMR)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, - IMG_DEVMEM_SIZE_T uiSize, - IMG_DEVMEM_SIZE_T uiChunkSize, - IMG_UINT32 ui32NumPhysChunks, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 *pui32MappingTable, - IMG_UINT32 uiLog2PageSize, - PVRSRV_MEMALLOCFLAGS_T uiFlags, - const IMG_CHAR *pszAnnotation, - PMR **ppsPMRPtr); - -typedef struct _PVRSRV_DEVICE_NODE_ -{ - PVRSRV_DEVICE_IDENTIFIER sDevId; - - PVRSRV_DEVICE_STATE eDevState; - ATOMIC_T eHealthStatus; /* Holds values from PVRSRV_DEVICE_HEALTH_STATUS */ - ATOMIC_T eHealthReason; /* Holds values from PVRSRV_DEVICE_HEALTH_REASON */ - - IMG_HANDLE *hDebugTable; - - /* device specific MMU attributes */ - MMU_DEVICEATTRIBS *psMMUDevAttrs; - /* device specific MMU firmware atrributes, used only in some devices*/ - MMU_DEVICEATTRIBS *psFirmwareMMUDevAttrs; - - /* lock for power state transitions */ - POS_LOCK hPowerLock; - /* current system device power state */ - PVRSRV_SYS_POWER_STATE eCurrentSysPowerState; - PVRSRV_POWER_DEV *psPowerDev; - - /* - callbacks the device must support: - */ - - FN_CREATERAMBACKEDPMR pfnCreateRamBackedPMR[PVRSRV_DEVICE_PHYS_HEAP_LAST]; - - PVRSRV_ERROR (*pfnDevPxAlloc)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, size_t uiSize, - PG_HANDLE *psMemHandle, IMG_DEV_PHYADDR *psDevPAddr); - - 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; - - void (*pfnMMUCacheInvalidate)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, - IMG_HANDLE hDeviceData, - MMU_LEVEL eLevel, - IMG_BOOL bUnmap); - - PVRSRV_ERROR (*pfnMMUCacheInvalidateKick)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, - IMG_UINT32 *pui32NextMMUInvalidateUpdate, - IMG_BOOL bInterrupt); - - 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); - - PVRSRV_ERROR (*pfnResetHWRLogs)(struct _PVRSRV_DEVICE_NODE_ *psDevNode); - - /* 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); - -#if defined(SUPPORT_KERNEL_SRVINIT) && defined(RGXFW_ALIGNCHECKS) - PVRSRV_ERROR (*pfnAlignmentCheck)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT32 ui32FWAlignChecksSize, IMG_UINT32 aui32FWAlignChecks[]); -#endif - IMG_BOOL (*pfnCheckDeviceFeature)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT64 ui64FeatureMask); - - IMG_INT32 (*pfnGetDeviceFeatureValue)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT64 ui64FeatureMask); - - PVRSRV_DEVICE_CONFIG *psDevConfig; - - /* device post-finalise compatibility check */ - PVRSRV_ERROR (*pfnInitDeviceCompatCheck) (struct _PVRSRV_DEVICE_NODE_*); - - /* information about the device's address space and heaps */ - DEVICE_MEMORY_INFO sDevMemoryInfo; - - /* device's shared-virtual-memory heap size */ - IMG_UINT64 ui64GeneralSVMHeapSize; - - /* private device information */ - void *pvDevice; - - - -#if defined(SUPPORT_GPUVIRT_VALIDATION) - RA_ARENA *psOSidSubArena[GPUVIRT_VALIDATION_NUM_OS]; -#endif - - -#define PVRSRV_MAX_RA_NAME_LENGTH (50) - RA_ARENA **apsLocalDevMemArenas; - IMG_CHAR **apszRANames; - IMG_UINT32 ui32NumOfLocalMemArenas; - -#if defined(SUPPORT_PVRSRV_GPUVIRT) - IMG_CHAR szKernelFwRAName[RGXFW_NUM_OS][PVRSRV_MAX_RA_NAME_LENGTH]; - RA_ARENA *psKernelFwMemArena[RGXFW_NUM_OS]; - IMG_UINT32 uiKernelFwRAIdx; - RA_BASE_T ui64RABase[RGXFW_NUM_OS]; -#endif - - IMG_UINT32 ui32RegisteredPhysHeaps; - PHYS_HEAP **papsRegisteredPhysHeaps; - - /* - * Pointers to the device's physical memory heap(s) - * The first entry (apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL]) will be used for allocations - * where the PVRSRV_MEMALLOCFLAG_CPU_LOCAL flag is not set. Normally this will be an LMA heap - * (but the device configuration could specify a UMA heap here, if desired) - * The second entry (apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL]) will be used for allocations - * where the PVRSRV_MEMALLOCFLAG_CPU_LOCAL flag is set. Normally this will be a UMA heap - * (but the configuration could specify an LMA heap here, if desired) - * The third entry (apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_FW_LOCAL]) will be used for allocations - * where the PVRSRV_MEMALLOCFLAG_FW_LOCAL flag is set; this is used when SUPPORT_PVRSRV_GPUVIRT is enabled - * The device configuration will always specify two physical heap IDs - in the event of the device - * only using one physical heap, both of these IDs will be the same, and hence both pointers below - * will also be the same; when SUPPORT_PVRSRV_GPUVIRT is enabled the device configuration specifies - * three physical heap IDs, the last being for PVRSRV_DEVICE_PHYS_HEAP_FW_LOCAL allocations - */ - PHYS_HEAP *apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_LAST]; - - 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 */ - -#if defined(SUPPORT_BUFFER_SYNC) - struct pvr_buffer_sync_context *psBufferSyncContext; -#endif - - IMG_HANDLE hSyncServerNotify; - POS_LOCK hSyncServerListLock; - DLLIST_NODE sSyncServerSyncsList; - -#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) - IMG_HANDLE hSyncServerRecordNotify; - POS_LOCK hSyncServerRecordLock; - DLLIST_NODE sSyncServerRecordList; - struct SYNC_RECORD *apsSyncServerRecordsFreed[PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN]; - IMG_UINT32 uiSyncServerRecordFreeIdx; -#endif - - PSYNC_PRIM_CONTEXT hSyncPrimContext; - - PVRSRV_CLIENT_SYNC_PRIM *psSyncPrim; - /* 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 hHtbDbgReqNotify; - IMG_HANDLE hAppHintDbgReqNotify; - - PVRSRV_DUMMY_PAGE sDummyPage; - - DLLIST_NODE sMemoryContextPageFaultNotifyListHead; - -#if defined(PDUMP) - /* 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); -#endif -} PVRSRV_DEVICE_NODE; - PVRSRV_ERROR IMG_CALLCONV PVRSRVDeviceFinalise(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_BOOL bInitSuccessful); diff --git a/drivers/staging/imgtec/rogue/devicemem_heapcfg.h b/drivers/staging/imgtec/rogue/devicemem_heapcfg.h index f8a42bf9a57b..4b2b8673c4bc 100644 --- a/drivers/staging/imgtec/rogue/devicemem_heapcfg.h +++ b/drivers/staging/imgtec/rogue/devicemem_heapcfg.h @@ -48,13 +48,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "img_types.h" #include "pvrsrv_error.h" +#include "connection_data.h" /* FIXME: Find a better way of defining _PVRSRV_DEVICE_NODE_ */ struct _PVRSRV_DEVICE_NODE_; -/* FIXME: Find a better way of defining _CONNECTION_DATA_ */ -struct _CONNECTION_DATA_; /* diff --git a/drivers/staging/imgtec/rogue/generated/cache_bridge/server_cache_bridge.c b/drivers/staging/imgtec/rogue/generated/cache_bridge/server_cache_bridge.c index f6c44d9b7328..c2f9d42c6a39 100644 --- a/drivers/staging/imgtec/rogue/generated/cache_bridge/server_cache_bridge.c +++ b/drivers/staging/imgtec/rogue/generated/cache_bridge/server_cache_bridge.c @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "osfunc.h" #include "img_defs.h" #include "cache_km.h" diff --git a/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/server_devicememhistory_bridge.c b/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/server_devicememhistory_bridge.c index cb8bc58fb21f..6af9ab2081ba 100644 --- a/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/server_devicememhistory_bridge.c +++ b/drivers/staging/imgtec/rogue/generated/devicememhistory_bridge/server_devicememhistory_bridge.c @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "osfunc.h" #include "img_defs.h" #include "devicemem_history_server.h" diff --git a/drivers/staging/imgtec/rogue/generated/dmabuf_bridge/server_dmabuf_bridge.c b/drivers/staging/imgtec/rogue/generated/dmabuf_bridge/server_dmabuf_bridge.c index 01b289b95635..144be3d32e5e 100644 --- a/drivers/staging/imgtec/rogue/generated/dmabuf_bridge/server_dmabuf_bridge.c +++ b/drivers/staging/imgtec/rogue/generated/dmabuf_bridge/server_dmabuf_bridge.c @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "osfunc.h" #include "img_defs.h" #include "physmem_dmabuf.h" diff --git a/drivers/staging/imgtec/rogue/generated/htbuffer_bridge/server_htbuffer_bridge.c b/drivers/staging/imgtec/rogue/generated/htbuffer_bridge/server_htbuffer_bridge.c index 6356b7a2f9c4..358b4f82d05e 100644 --- a/drivers/staging/imgtec/rogue/generated/htbuffer_bridge/server_htbuffer_bridge.c +++ b/drivers/staging/imgtec/rogue/generated/htbuffer_bridge/server_htbuffer_bridge.c @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "osfunc.h" #include "img_defs.h" #include "htbserver.h" diff --git a/drivers/staging/imgtec/rogue/generated/mm_bridge/server_mm_bridge.c b/drivers/staging/imgtec/rogue/generated/mm_bridge/server_mm_bridge.c index 58fa70c6c62d..f56424a7d72b 100644 --- a/drivers/staging/imgtec/rogue/generated/mm_bridge/server_mm_bridge.c +++ b/drivers/staging/imgtec/rogue/generated/mm_bridge/server_mm_bridge.c @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "osfunc.h" #include "img_defs.h" #include "devicemem.h" diff --git a/drivers/staging/imgtec/rogue/generated/pdump_bridge/server_pdump_bridge.c b/drivers/staging/imgtec/rogue/generated/pdump_bridge/server_pdump_bridge.c index 0b38a253c0b5..865cb0727278 100644 --- a/drivers/staging/imgtec/rogue/generated/pdump_bridge/server_pdump_bridge.c +++ b/drivers/staging/imgtec/rogue/generated/pdump_bridge/server_pdump_bridge.c @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "osfunc.h" #include "img_defs.h" #include "devicemem_server.h" diff --git a/drivers/staging/imgtec/rogue/generated/pdumpmm_bridge/server_pdumpmm_bridge.c b/drivers/staging/imgtec/rogue/generated/pdumpmm_bridge/server_pdumpmm_bridge.c index f5bab7c87fbd..46e2b280b3ac 100644 --- a/drivers/staging/imgtec/rogue/generated/pdumpmm_bridge/server_pdumpmm_bridge.c +++ b/drivers/staging/imgtec/rogue/generated/pdumpmm_bridge/server_pdumpmm_bridge.c @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "osfunc.h" #include "img_defs.h" #include "devicemem_server.h" diff --git a/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/server_pvrtl_bridge.c b/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/server_pvrtl_bridge.c index f634b6b74356..5292c06f978c 100644 --- a/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/server_pvrtl_bridge.c +++ b/drivers/staging/imgtec/rogue/generated/pvrtl_bridge/server_pvrtl_bridge.c @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "osfunc.h" #include "img_defs.h" #include "tlserver.h" diff --git a/drivers/staging/imgtec/rogue/generated/rgxcmp_bridge/server_rgxcmp_bridge.c b/drivers/staging/imgtec/rogue/generated/rgxcmp_bridge/server_rgxcmp_bridge.c index c8e8dd99f048..2ad002d59a84 100644 --- a/drivers/staging/imgtec/rogue/generated/rgxcmp_bridge/server_rgxcmp_bridge.c +++ b/drivers/staging/imgtec/rogue/generated/rgxcmp_bridge/server_rgxcmp_bridge.c @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "osfunc.h" #include "img_defs.h" #include "rgxcompute.h" diff --git a/drivers/staging/imgtec/rogue/generated/rgxhwperf_bridge/server_rgxhwperf_bridge.c b/drivers/staging/imgtec/rogue/generated/rgxhwperf_bridge/server_rgxhwperf_bridge.c index f8becbab5a7f..5f2a845b6423 100644 --- a/drivers/staging/imgtec/rogue/generated/rgxhwperf_bridge/server_rgxhwperf_bridge.c +++ b/drivers/staging/imgtec/rogue/generated/rgxhwperf_bridge/server_rgxhwperf_bridge.c @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "osfunc.h" #include "img_defs.h" #include "rgxhwperf.h" diff --git a/drivers/staging/imgtec/rogue/generated/rgxkicksync_bridge/server_rgxkicksync_bridge.c b/drivers/staging/imgtec/rogue/generated/rgxkicksync_bridge/server_rgxkicksync_bridge.c index e210f569aa2d..049d045467f9 100644 --- a/drivers/staging/imgtec/rogue/generated/rgxkicksync_bridge/server_rgxkicksync_bridge.c +++ b/drivers/staging/imgtec/rogue/generated/rgxkicksync_bridge/server_rgxkicksync_bridge.c @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "osfunc.h" #include "img_defs.h" #include "rgxkicksync.h" diff --git a/drivers/staging/imgtec/rogue/generated/rgxray_bridge/server_rgxray_bridge.c b/drivers/staging/imgtec/rogue/generated/rgxray_bridge/server_rgxray_bridge.c index 9aac8f34cd08..977bc4cd992d 100644 --- a/drivers/staging/imgtec/rogue/generated/rgxray_bridge/server_rgxray_bridge.c +++ b/drivers/staging/imgtec/rogue/generated/rgxray_bridge/server_rgxray_bridge.c @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "osfunc.h" #include "img_defs.h" #include "rgxray.h" diff --git a/drivers/staging/imgtec/rogue/generated/rgxta3d_bridge/server_rgxta3d_bridge.c b/drivers/staging/imgtec/rogue/generated/rgxta3d_bridge/server_rgxta3d_bridge.c index af22437db776..755eb1d17dd3 100644 --- a/drivers/staging/imgtec/rogue/generated/rgxta3d_bridge/server_rgxta3d_bridge.c +++ b/drivers/staging/imgtec/rogue/generated/rgxta3d_bridge/server_rgxta3d_bridge.c @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "osfunc.h" #include "img_defs.h" #include "rgxta3d.h" diff --git a/drivers/staging/imgtec/rogue/generated/rgxtq2_bridge/server_rgxtq2_bridge.c b/drivers/staging/imgtec/rogue/generated/rgxtq2_bridge/server_rgxtq2_bridge.c index 7bec1ba1c18e..0228296e91e5 100644 --- a/drivers/staging/imgtec/rogue/generated/rgxtq2_bridge/server_rgxtq2_bridge.c +++ b/drivers/staging/imgtec/rogue/generated/rgxtq2_bridge/server_rgxtq2_bridge.c @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "osfunc.h" #include "img_defs.h" #include "rgxtdmtransfer.h" diff --git a/drivers/staging/imgtec/rogue/generated/rgxtq_bridge/server_rgxtq_bridge.c b/drivers/staging/imgtec/rogue/generated/rgxtq_bridge/server_rgxtq_bridge.c index 6dc9732f36f9..4368d7dfbdef 100644 --- a/drivers/staging/imgtec/rogue/generated/rgxtq_bridge/server_rgxtq_bridge.c +++ b/drivers/staging/imgtec/rogue/generated/rgxtq_bridge/server_rgxtq_bridge.c @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "osfunc.h" #include "img_defs.h" #include "rgxtransfer.h" diff --git a/drivers/staging/imgtec/rogue/generated/ri_bridge/server_ri_bridge.c b/drivers/staging/imgtec/rogue/generated/ri_bridge/server_ri_bridge.c index c1553c250351..d3eea25d0833 100644 --- a/drivers/staging/imgtec/rogue/generated/ri_bridge/server_ri_bridge.c +++ b/drivers/staging/imgtec/rogue/generated/ri_bridge/server_ri_bridge.c @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "osfunc.h" #include "img_defs.h" #include "ri_server.h" diff --git a/drivers/staging/imgtec/rogue/generated/srvcore_bridge/server_srvcore_bridge.c b/drivers/staging/imgtec/rogue/generated/srvcore_bridge/server_srvcore_bridge.c index eb9e2a2449c3..e1b7e0fdf80b 100644 --- a/drivers/staging/imgtec/rogue/generated/srvcore_bridge/server_srvcore_bridge.c +++ b/drivers/staging/imgtec/rogue/generated/srvcore_bridge/server_srvcore_bridge.c @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "osfunc.h" #include "img_defs.h" #include "srvcore.h" diff --git a/drivers/staging/imgtec/rogue/generated/sync_bridge/server_sync_bridge.c b/drivers/staging/imgtec/rogue/generated/sync_bridge/server_sync_bridge.c index f19eac649a16..d3eddb5c0ace 100644 --- a/drivers/staging/imgtec/rogue/generated/sync_bridge/server_sync_bridge.c +++ b/drivers/staging/imgtec/rogue/generated/sync_bridge/server_sync_bridge.c @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "osfunc.h" #include "img_defs.h" #include "sync.h" diff --git a/drivers/staging/imgtec/rogue/generated/synctracking_bridge/server_synctracking_bridge.c b/drivers/staging/imgtec/rogue/generated/synctracking_bridge/server_synctracking_bridge.c index 9c9508d7da47..edaad3ba8683 100644 --- a/drivers/staging/imgtec/rogue/generated/synctracking_bridge/server_synctracking_bridge.c +++ b/drivers/staging/imgtec/rogue/generated/synctracking_bridge/server_synctracking_bridge.c @@ -44,6 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "osfunc.h" #include "img_defs.h" #include "sync.h" diff --git a/drivers/staging/imgtec/rogue/handle.c b/drivers/staging/imgtec/rogue/handle.c index d0f8aaee26c2..1fb81812b8e2 100644 --- a/drivers/staging/imgtec/rogue/handle.c +++ b/drivers/staging/imgtec/rogue/handle.c @@ -53,6 +53,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include +#include "osfunc.h" #include "handle.h" #include "handle_impl.h" #include "allocmem.h" diff --git a/drivers/staging/imgtec/rogue/handle.h b/drivers/staging/imgtec/rogue/handle.h index fd90d8a57592..d0aaaa23e138 100644 --- a/drivers/staging/imgtec/rogue/handle.h +++ b/drivers/staging/imgtec/rogue/handle.h @@ -117,6 +117,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * no parent. */ +#include "lock_types.h" #include "img_types.h" #include "hash.h" diff --git a/drivers/staging/imgtec/rogue/hash.h b/drivers/staging/imgtec/rogue/hash.h index 6c8171b1235e..f8addf1f3eb0 100644 --- a/drivers/staging/imgtec/rogue/hash.h +++ b/drivers/staging/imgtec/rogue/hash.h @@ -45,10 +45,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define _HASH_H_ /* include5/ */ +#include "pvrsrv_error.h" #include "img_types.h" /* services/client/include/ or services/server/include/ */ -#include "osfunc.h" +// #include "osfunc.h" #if defined (__cplusplus) extern "C" { diff --git a/drivers/staging/imgtec/rogue/mmu_common.h b/drivers/staging/imgtec/rogue/mmu_common.h index 32483b6ff3fa..a8e152152c25 100644 --- a/drivers/staging/imgtec/rogue/mmu_common.h +++ b/drivers/staging/imgtec/rogue/mmu_common.h @@ -79,7 +79,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* services/server/include/ */ -#include "pmr.h" +// #include "pmr.h" +#include "pdump.h" +#include "pmr_impl.h" +#include "pvrsrv_memallocflags.h" +#include "powervr/mem_types.h" +#include "pdumpdefs.h" + /* include/ */ #include "img_types.h" diff --git a/drivers/staging/imgtec/rogue/osconnection_server.c b/drivers/staging/imgtec/rogue/osconnection_server.c index e56f8fb34ef2..baf70551ab3b 100644 --- a/drivers/staging/imgtec/rogue/osconnection_server.c +++ b/drivers/staging/imgtec/rogue/osconnection_server.c @@ -40,6 +40,7 @@ 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 "osfunc.h" #include "connection_server.h" #include "osconnection_server.h" diff --git a/drivers/staging/imgtec/rogue/osconnection_server.h b/drivers/staging/imgtec/rogue/osconnection_server.h index 192ef584821d..09c2b4bff97c 100644 --- a/drivers/staging/imgtec/rogue/osconnection_server.h +++ b/drivers/staging/imgtec/rogue/osconnection_server.h @@ -44,7 +44,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef _OSCONNECTION_SERVER_H_ #define _OSCONNECTION_SERVER_H_ -#include "handle.h" +// #include "handle.h" +#include "pvrsrv_device_node.h" #if defined(__linux__) || defined(__QNXNTO__) || defined(INTEGRITY_OS) diff --git a/drivers/staging/imgtec/rogue/osfunc.c b/drivers/staging/imgtec/rogue/osfunc.c index 241ff2464dd9..95702540eb66 100644 --- a/drivers/staging/imgtec/rogue/osfunc.c +++ b/drivers/staging/imgtec/rogue/osfunc.c @@ -60,6 +60,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include + +#include + + #if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || \ defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) || \ defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || \ @@ -68,7 +72,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #endif #include -#include +#include #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) #include #include @@ -172,10 +176,10 @@ PVRSRV_ERROR OSPhyContigPagesAlloc(PVRSRV_DEVICE_NODE *psDevNode, size_t uiSize, void OSPhyContigPagesFree(PVRSRV_DEVICE_NODE *psDevNode, PG_HANDLE *psMemHandle) { struct page *psPage = (struct page*) psMemHandle->u.pvHandle; - IMG_UINT32 uiSize, uiPageCount=0; + //IMG_UINT32 uiPageCount=0; - uiPageCount = (1 << psMemHandle->ui32Order); - uiSize = (uiPageCount * PAGE_SIZE); + //uiPageCount = (1 << psMemHandle->ui32Order); + //uiSize = (uiPageCount * PAGE_SIZE); #if defined(PVRSRV_ENABLE_PROCESS_STATS) #if !defined(PVRSRV_ENABLE_MEMORY_STATS) @@ -489,7 +493,12 @@ static inline IMG_UINT64 KClockns64(void) { ktime_t sTime = ktime_get(); +//ktime_t in 4.19 is defined s64, on 4.4 is defined union ktime. +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) return sTime.tv64; +#else + return sTime; +#endif } PVRSRV_ERROR OSClockMonotonicns64(IMG_UINT64 *pui64Time) @@ -1230,6 +1239,8 @@ IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, void *pvData, IMG_UINT32 ui32 psTimerCBData->ui32Delay = ((HZ * ui32MsTimeout) < 1000) ? 1 : ((HZ * ui32MsTimeout) / 1000); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) /* initialise object */ init_timer(&psTimerCBData->sTimer); @@ -1237,6 +1248,10 @@ IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, void *pvData, IMG_UINT32 ui32 psTimerCBData->sTimer.function = (void *)OSTimerCallbackWrapper; psTimerCBData->sTimer.data = (uintptr_t)psTimerCBData; +#else + timer_setup(&psTimerCBData->sTimer, (void *)OSTimerCallbackWrapper, 0); +#endif + return (IMG_HANDLE)(uintptr_t)(ui32i + 1); } @@ -1498,19 +1513,19 @@ PVRSRV_ERROR OSCopyFromUser(void *pvProcess, IMG_BOOL OSAccessOK(IMG_VERIFY_TEST eVerification, void *pvUserPtr, size_t ui32Bytes) { - IMG_INT linuxType; + //IMG_INT linuxType; if (eVerification == PVR_VERIFY_READ) { - linuxType = VERIFY_READ; + //linuxType = VERIFY_READ; } else { PVR_ASSERT(eVerification == PVR_VERIFY_WRITE); - linuxType = VERIFY_WRITE; + //linuxType = VERIFY_WRITE; } - return access_ok(linuxType, pvUserPtr, ui32Bytes); + return access_ok(NULL, pvUserPtr, ui32Bytes); } IMG_UINT64 OSDivide64r64(IMG_UINT64 ui64Divident, IMG_UINT32 ui32Divisor, IMG_UINT32 *pui32Remainder) @@ -1759,7 +1774,7 @@ PVRSRV_ERROR OSChangeSparseMemCPUAddrMap(void **psPageArray, */ #endif } - eError = PVRSRV_OK; + //eError = PVRSRV_OK; } if ((psVMA->vm_flags & VM_MIXEDMAP) || bIsLMA) diff --git a/drivers/staging/imgtec/rogue/osfunc_arm64.c b/drivers/staging/imgtec/rogue/osfunc_arm64.c index 74befa259393..a1662f14fe23 100644 --- a/drivers/staging/imgtec/rogue/osfunc_arm64.c +++ b/drivers/staging/imgtec/rogue/osfunc_arm64.c @@ -107,7 +107,7 @@ PVRSRV_ERROR OSCPUOperation(PVRSRV_CACHE_OP uiCacheOp) PVR_DPF((PVR_DBG_ERROR, "%s: Global cache operation type %d is invalid", __FUNCTION__, uiCacheOp)); - eError = PVRSRV_ERROR_INVALID_PARAMS; + //eError = PVRSRV_ERROR_INVALID_PARAMS; PVR_ASSERT(0); break; } @@ -121,13 +121,13 @@ void OSFlushCPUCacheRangeKM(PVRSRV_DEVICE_NODE *psDevNode, IMG_CPU_PHYADDR sCPUPhysStart, IMG_CPU_PHYADDR sCPUPhysEnd) { - struct dma_map_ops *dma_ops = get_dma_ops(psDevNode->psDevConfig->pvOSDevice); + const struct dma_map_ops *dma_ops = get_dma_ops(psDevNode->psDevConfig->pvOSDevice); PVR_UNREFERENCED_PARAMETER(pvVirtStart); PVR_UNREFERENCED_PARAMETER(pvVirtEnd); - dma_ops->sync_single_for_device(NULL, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_TO_DEVICE); - dma_ops->sync_single_for_cpu(NULL, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_FROM_DEVICE); + dma_ops->sync_single_for_device(psDevNode->psDevConfig->pvOSDevice, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_TO_DEVICE); + dma_ops->sync_single_for_cpu(psDevNode->psDevConfig->pvOSDevice, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_FROM_DEVICE); } void OSCleanCPUCacheRangeKM(PVRSRV_DEVICE_NODE *psDevNode, @@ -136,12 +136,12 @@ void OSCleanCPUCacheRangeKM(PVRSRV_DEVICE_NODE *psDevNode, IMG_CPU_PHYADDR sCPUPhysStart, IMG_CPU_PHYADDR sCPUPhysEnd) { - struct dma_map_ops *dma_ops = get_dma_ops(psDevNode->psDevConfig->pvOSDevice); + const struct dma_map_ops *dma_ops = get_dma_ops(psDevNode->psDevConfig->pvOSDevice); PVR_UNREFERENCED_PARAMETER(pvVirtStart); PVR_UNREFERENCED_PARAMETER(pvVirtEnd); - dma_ops->sync_single_for_device(NULL, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_TO_DEVICE); + dma_ops->sync_single_for_device(psDevNode->psDevConfig->pvOSDevice, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_TO_DEVICE); } void OSInvalidateCPUCacheRangeKM(PVRSRV_DEVICE_NODE *psDevNode, @@ -150,12 +150,12 @@ void OSInvalidateCPUCacheRangeKM(PVRSRV_DEVICE_NODE *psDevNode, IMG_CPU_PHYADDR sCPUPhysStart, IMG_CPU_PHYADDR sCPUPhysEnd) { - struct dma_map_ops *dma_ops = get_dma_ops(psDevNode->psDevConfig->pvOSDevice); + const struct dma_map_ops *dma_ops = get_dma_ops(psDevNode->psDevConfig->pvOSDevice); PVR_UNREFERENCED_PARAMETER(pvVirtStart); PVR_UNREFERENCED_PARAMETER(pvVirtEnd); - dma_ops->sync_single_for_cpu(NULL, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_FROM_DEVICE); + dma_ops->sync_single_for_cpu(psDevNode->psDevConfig->pvOSDevice, sCPUPhysStart.uiAddr, sCPUPhysEnd.uiAddr - sCPUPhysStart.uiAddr, DMA_FROM_DEVICE); } PVRSRV_CACHE_OP_ADDR_TYPE OSCPUCacheOpAddressType(PVRSRV_CACHE_OP uiCacheOp) diff --git a/drivers/staging/imgtec/rogue/physmem_dmabuf.c b/drivers/staging/imgtec/rogue/physmem_dmabuf.c index 991a2425919e..6141191d973c 100644 --- a/drivers/staging/imgtec/rogue/physmem_dmabuf.c +++ b/drivers/staging/imgtec/rogue/physmem_dmabuf.c @@ -81,7 +81,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * and using our dmabuf. */ -static int PVRDmaBufOpsAttach(struct dma_buf *psDmaBuf, struct device *psDev, +static int PVRDmaBufOpsAttach(struct dma_buf *psDmaBuf, struct dma_buf_attachment *psAttachment) { return -ENOSYS; @@ -123,8 +123,13 @@ static const struct dma_buf_ops sPVRDmaBufOps = .map_dma_buf = PVRDmaBufOpsMap, .unmap_dma_buf = PVRDmaBufOpsUnmap, .release = PVRDmaBufOpsRelease, - .kmap_atomic = PVRDmaBufOpsKMap, - .kmap = PVRDmaBufOpsKMap, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)) + //.map_atomic = PVRDmaBufOpsKMap, + .map = PVRDmaBufOpsKMap, +#else + .kmap_atomic = PVRDmaBufOpsKMap, + .kmap = PVRDmaBufOpsKMap, +#endif .mmap = PVRDmaBufOpsMMap, }; @@ -553,7 +558,6 @@ PhysmemCreateNewDmaBufBackedPMR(PVRSRV_DEVICE_NODE *psDevNode, psPrivData->ui32PhysPageCount = ui32PageCount; psPrivData->psSgTable = table; - ui32PageCount = 0; sg = table->sgl; uiSglOffset = 0; diff --git a/drivers/staging/imgtec/rogue/pmr.h b/drivers/staging/imgtec/rogue/pmr.h index 2e86c81143db..c59eba25252f 100644 --- a/drivers/staging/imgtec/rogue/pmr.h +++ b/drivers/staging/imgtec/rogue/pmr.h @@ -57,6 +57,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define _SRVSRV_PMR_H_ /* include/ */ +#include "pvrsrv_device_node.h" #include "img_types.h" #include "pdumpdefs.h" #include "pvrsrv_error.h" @@ -69,6 +70,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* services/server/include/ */ #include "pmr_impl.h" #include "physheap.h" +#include "connection_data.h" #define PMR_MAX_TRANSLATION_STACK_ALLOC (32) @@ -96,9 +98,6 @@ typedef struct _PMR_EXPORT_ PMR_EXPORT; typedef struct _PMR_PAGELIST_ PMR_PAGELIST; -typedef struct _CONNECTION_DATA_ CONNECTION_DATA; -typedef struct _PVRSRV_DEVICE_NODE_ PVRSRV_DEVICE_NODE; - /* * PMRCreatePMR * diff --git a/drivers/staging/imgtec/rogue/pmr_impl.h b/drivers/staging/imgtec/rogue/pmr_impl.h index 53da82b4b63a..78e1fca4f8c6 100644 --- a/drivers/staging/imgtec/rogue/pmr_impl.h +++ b/drivers/staging/imgtec/rogue/pmr_impl.h @@ -48,6 +48,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define _SRVSRV_PMR_IMPL_H_ /* include/ */ +#include "powervr/mem_types.h" +#include "pvrsrv_memallocflags.h" #include "img_types.h" #include "pvrsrv_error.h" diff --git a/drivers/staging/imgtec/rogue/power.h b/drivers/staging/imgtec/rogue/power.h index 3e0884bd1f95..49c75999482b 100644 --- a/drivers/staging/imgtec/rogue/power.h +++ b/drivers/staging/imgtec/rogue/power.h @@ -43,14 +43,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef POWER_H #define POWER_H +#include "device.h" #include "img_defs.h" #include "img_types.h" #include "pvrsrv_device.h" #include "pvrsrv_error.h" #include "servicesext.h" -typedef struct _PVRSRV_DEVICE_NODE_ PVRSRV_DEVICE_NODE; - #if !defined(SUPPORT_KERNEL_SRVINIT) typedef enum _PVRSRV_INIT_SERVER_STATE_ { @@ -76,8 +75,6 @@ PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState, * Power management *****************************************************************************/ -typedef struct _PVRSRV_POWER_DEV_TAG_ PVRSRV_POWER_DEV; - typedef IMG_BOOL (*PFN_SYS_DEV_IS_DEFAULT_STATE_OFF)(PVRSRV_POWER_DEV *psPowerDevice); IMG_IMPORT IMG_BOOL IsSystemStatePowered(PVRSRV_DEVICE_NODE *psDeviceNode); diff --git a/drivers/staging/imgtec/rogue/psync_checkpoint.h b/drivers/staging/imgtec/rogue/psync_checkpoint.h new file mode 100644 index 000000000000..3386bf6dcf72 --- /dev/null +++ b/drivers/staging/imgtec/rogue/psync_checkpoint.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* -------------------------------------------------------------------------------------------------------- + * File: psync_checkpoint.h + * -------------------------------------------------------------------------------------------------------- + */ + + +#ifndef __PSYNC_CHECKPOINT_H__ +#define __PSYNC_CHECKPOINT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* --------------------------------------------------------------------------------------------------------- + * Include Files + * --------------------------------------------------------------------------------------------------------- + */ +#include "psync_checkpoint_context.h" +#include "sync_checkpoint_internal_fw.h" + +/* --------------------------------------------------------------------------------------------------------- + * Macros Definition + * --------------------------------------------------------------------------------------------------------- + */ + + +/* --------------------------------------------------------------------------------------------------------- + * Types and Structures Definition + * --------------------------------------------------------------------------------------------------------- + */ + +typedef struct _SYNC_CHECKPOINT_BLOCK_ { + ATOMIC_T hRefCount; /*!< Ref count for this sync block */ + _SYNC_CHECKPOINT_CONTEXT *psContext; /*!< Our copy of the services connection */ + PVRSRV_DEVICE_NODE *psDevNode; + IMG_UINT32 ui32SyncBlockSize; /*!< Size of the sync checkpoint block */ + IMG_UINT32 ui32FirmwareAddr; /*!< Firmware address */ + DEVMEM_MEMDESC *hMemDesc; /*!< DevMem allocation for block */ + volatile IMG_UINT32 *pui32LinAddr; /*!< Server-code CPU mapping */ + IMG_UINT64 uiSpanBase; /*!< Base of this import (FW DevMem) in the span RA */ + DLLIST_NODE sListNode; /*!< List node for the sync chkpt block list */ +} SYNC_CHECKPOINT_BLOCK; + +// .CP : +typedef struct _SYNC_CHECKPOINT_ { + /* A sync checkpoint is assigned a unique ID, to avoid any confusion should + * the same memory be re-used later for a different checkpoint + */ + IMG_UINT32 ui32UID; /*!< Unique ID assigned to sync checkpoint (to distinguish checkpoints if memory is re-used)*/ + ATOMIC_T hRefCount; /*!< Ref count for this sync */ + ATOMIC_T hEnqueuedCCBCount; /*!< Num times sync has been put in CCBs */ + SYNC_CHECKPOINT_BLOCK *psSyncCheckpointBlock; /*!< Synchronisation block this checkpoint is allocated on */ + IMG_UINT64 uiSpanAddr; /*!< Span address of the sync */ + volatile _SYNC_CHECKPOINT_FW_OBJ *psSyncCheckpointFwObj; /*!< CPU view of the data held in the sync block */ + IMG_CHAR azName[SYNC_CHECKPOINT_NAME_SIZE]; /*!< Name of the checkpoint */ +#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) + PSYNC_CHECKPOINT_RECORD_HANDLE hRecord; /*!< Sync record handle */ +#endif + DLLIST_NODE sListNode; /*!< List node for the sync chkpt list */ +} _SYNC_CHECKPOINT; +typedef struct _SYNC_CHECKPOINT *PSYNC_CHECKPOINT; + +/* --------------------------------------------------------------------------------------------------------- + * Global Functions' Prototype + * --------------------------------------------------------------------------------------------------------- + */ + + +/* --------------------------------------------------------------------------------------------------------- + * Inline Functions Implementation + * --------------------------------------------------------------------------------------------------------- + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __PSYNC_CHECKPOINT_H__ */ + diff --git a/drivers/staging/imgtec/rogue/psync_checkpoint_context.h b/drivers/staging/imgtec/rogue/psync_checkpoint_context.h new file mode 100644 index 000000000000..29a8c6fc7253 --- /dev/null +++ b/drivers/staging/imgtec/rogue/psync_checkpoint_context.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* -------------------------------------------------------------------------------------------------------- + * File: psync_checkpoint_context.h + * -------------------------------------------------------------------------------------------------------- + */ + + +#ifndef __PSYNC_CHECKPOINT_CONTEXT_H__ +#define __PSYNC_CHECKPOINT_CONTEXT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* --------------------------------------------------------------------------------------------------------- + * Include Files + * --------------------------------------------------------------------------------------------------------- + */ +#include + + + +/* --------------------------------------------------------------------------------------------------------- + * Macros Definition + * --------------------------------------------------------------------------------------------------------- + */ + +#define SYNC_CHECKPOINT_MAX_CLASS_NAME_LEN 32 + +#define SYNC_CHECKPOINT_NAME_SIZE SYNC_CHECKPOINT_MAX_CLASS_NAME_LEN + +/* --------------------------------------------------------------------------------------------------------- + * Types and Structures Definition + * --------------------------------------------------------------------------------------------------------- + */ + +typedef struct _SYNC_CHECKPOINT_CONTEXT_ { + PVRSRV_DEVICE_NODE *psDevNode; + IMG_CHAR azName[SYNC_CHECKPOINT_NAME_SIZE]; /*!< Name of the RA */ + RA_ARENA *psSubAllocRA; /*!< RA context */ + IMG_CHAR azSpanName[SYNC_CHECKPOINT_NAME_SIZE]; /*!< Name of the span RA */ + RA_ARENA *psSpanRA; /*!< RA used for span management of SubAllocRA */ + ATOMIC_T hRefCount; /*!< Ref count for this context */ + ATOMIC_T hCheckpointCount; /*!< Checkpoint count for this context */ + POS_LOCK hCheckpointListLock; /*!< Checkpoint list lock */ + DLLIST_NODE sCheckpointList; /*!< List of checkpoints created on this context */ + IMG_HANDLE hCheckpointNotify; /*!< Handle for debug notifier callback */ +#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) + POS_LOCK hCheckpointRecordLock; + DLLIST_NODE sCheckpointRecordList; + struct SYNC_CHECKPOINT_RECORD *apsCheckpointRecordsFreed[PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN]; + IMG_UINT32 uiCheckpointRecordFreeIdx; + IMG_HANDLE hCheckpointRecordNotify; +#endif +} _SYNC_CHECKPOINT_CONTEXT; +typedef struct _SYNC_CHECKPOINT_CONTEXT *PSYNC_CHECKPOINT_CONTEXT; + + +/* --------------------------------------------------------------------------------------------------------- + * Global Functions' Prototype + * --------------------------------------------------------------------------------------------------------- + */ + + +/* --------------------------------------------------------------------------------------------------------- + * Inline Functions Implementation + * --------------------------------------------------------------------------------------------------------- + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __PSYNC_CHECKPOINT_CONTEXT_H__ */ + diff --git a/drivers/staging/imgtec/rogue/pvr_debugfs.c b/drivers/staging/imgtec/rogue/pvr_debugfs.c index dfda14c45310..89579e2614ce 100644 --- a/drivers/staging/imgtec/rogue/pvr_debugfs.c +++ b/drivers/staging/imgtec/rogue/pvr_debugfs.c @@ -68,39 +68,6 @@ static struct mutex gDebugFSLock; Statistic entry read functions */ /**************************************************************************/ -#if defined(PVRSRV_ENABLE_MEMTRACK_STATS_FILE) -typedef struct _PVR_DEBUGFS_RAW_DRIVER_STAT_ -{ - OS_STATS_PRINT_FUNC *pfStatsPrint; - PVR_DEBUGFS_ENTRY_DATA *pvDebugFsEntry; -} PVR_DEBUGFS_RAW_DRIVER_STAT; -#endif - -typedef struct _PVR_DEBUGFS_DRIVER_STAT_ -{ - void *pvData; - OS_STATS_PRINT_FUNC *pfnStatsPrint; - PVRSRV_INC_STAT_MEM_REFCOUNT_FUNC *pfnIncStatMemRefCount; - PVRSRV_DEC_STAT_MEM_REFCOUNT_FUNC *pfnDecStatMemRefCount; - IMG_UINT32 ui32RefCount; - PVR_DEBUGFS_ENTRY_DATA *pvDebugFSEntry; -} PVR_DEBUGFS_DRIVER_STAT; - -typedef struct _PVR_DEBUGFS_DIR_DATA_ -{ - struct dentry *psDir; - PVR_DEBUGFS_DIR_DATA *psParentDir; - IMG_UINT32 ui32RefCount; -} PVR_DEBUGFS_DIR_DATA; - -typedef struct _PVR_DEBUGFS_ENTRY_DATA_ -{ - struct dentry *psEntry; - PVR_DEBUGFS_DIR_DATA *psParentDir; - IMG_UINT32 ui32RefCount; - PVR_DEBUGFS_DRIVER_STAT *psStatData; -} PVR_DEBUGFS_ENTRY_DATA; - typedef struct _PVR_DEBUGFS_PRIV_DATA_ { const struct seq_operations *psReadOps; diff --git a/drivers/staging/imgtec/rogue/pvr_debugfs.h b/drivers/staging/imgtec/rogue/pvr_debugfs.h index 17fb73722f86..782c132ff6d1 100644 --- a/drivers/staging/imgtec/rogue/pvr_debugfs.h +++ b/drivers/staging/imgtec/rogue/pvr_debugfs.h @@ -61,11 +61,35 @@ typedef IMG_UINT32 (PVRSRV_DEC_STAT_MEM_REFCOUNT_FUNC)(void *pvStatPtr); typedef IMG_UINT32 (PVRSRV_INC_FSENTRY_PVDATA_REFCNT_FN)(void *pvData); typedef IMG_UINT32 (PVRSRV_DEC_FSENTRY_PVDATA_REFCNT_FN)(void *pvData); -typedef struct _PVR_DEBUGFS_DIR_DATA_ PVR_DEBUGFS_DIR_DATA; -typedef struct _PVR_DEBUGFS_ENTRY_DATA_ PVR_DEBUGFS_ENTRY_DATA; -typedef struct _PVR_DEBUGFS_DRIVER_STAT_ PVR_DEBUGFS_DRIVER_STAT; +typedef struct _PVR_DEBUGFS_DIR_DATA_ { + struct dentry *psDir; + struct _PVR_DEBUGFS_DIR_DATA_ *psParentDir; + IMG_UINT32 ui32RefCount; +} PVR_DEBUGFS_DIR_DATA; + +struct _PVR_DEBUGFS_ENTRY_DATA_; + +typedef struct _PVR_DEBUGFS_DRIVER_STAT_ { + void *pvData; + OS_STATS_PRINT_FUNC *pfnStatsPrint; + PVRSRV_INC_STAT_MEM_REFCOUNT_FUNC *pfnIncStatMemRefCount; + PVRSRV_DEC_STAT_MEM_REFCOUNT_FUNC *pfnDecStatMemRefCount; + IMG_UINT32 ui32RefCount; + struct _PVR_DEBUGFS_ENTRY_DATA_ *pvDebugFSEntry; +} PVR_DEBUGFS_DRIVER_STAT; + +typedef struct _PVR_DEBUGFS_ENTRY_DATA_ { + struct dentry *psEntry; + PVR_DEBUGFS_DIR_DATA *psParentDir; + IMG_UINT32 ui32RefCount; + PVR_DEBUGFS_DRIVER_STAT *psStatData; +} PVR_DEBUGFS_ENTRY_DATA; + #if defined(PVRSRV_ENABLE_MEMTRACK_STATS_FILE) -typedef struct _PVR_DEBUGFS_RAW_DRIVER_STAT_ PVR_DEBUGFS_RAW_DRIVER_STAT; +typedef struct _PVR_DEBUGFS_RAW_DRIVER_STAT_ { + OS_STATS_PRINT_FUNC *pfStatsPrint; + PVR_DEBUGFS_ENTRY_DATA *pvDebugFsEntry; +} PVR_DEBUGFS_RAW_DRIVER_STAT; #endif int PVRDebugFSInit(void); diff --git a/drivers/staging/imgtec/rogue/pvr_dvfs_device.c b/drivers/staging/imgtec/rogue/pvr_dvfs_device.c index b301b1f87a00..d552a027d421 100644 --- a/drivers/staging/imgtec/rogue/pvr_dvfs_device.c +++ b/drivers/staging/imgtec/rogue/pvr_dvfs_device.c @@ -70,8 +70,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "pvrsrv_device.h" #include "syscommon.h" -#include "rgxdevice.h" #include "rgxinit.h" +#include "rgxdevice.h" #include "pvr_dvfs_device.h" #include "power.h" @@ -247,7 +247,7 @@ static int GetOPPValues(struct device *dev, #if defined(CHROMIUMOS_WORKAROUNDS_KERNEL318) unsigned long *freq_table; #else - unsigned int *freq_table; + unsigned long *freq_table; #endif /* Start RCU read-side critical section to access device opp_list. */ @@ -478,7 +478,6 @@ PVRSRV_ERROR InitDVFS(PVRSRV_DEVICE_NODE *psDeviceNode) if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVInit: Failed to suspend DVFS")); - eError = eError; goto err_exit; } diff --git a/drivers/staging/imgtec/rogue/pvr_notifier.h b/drivers/staging/imgtec/rogue/pvr_notifier.h index 6fa968b10f09..0eff86d2b406 100644 --- a/drivers/staging/imgtec/rogue/pvr_notifier.h +++ b/drivers/staging/imgtec/rogue/pvr_notifier.h @@ -52,7 +52,10 @@ Command Complete Notifier Interface */ /***************************************************************************/ typedef IMG_HANDLE PVRSRV_CMDCOMP_HANDLE; +#ifndef _CMDCOMPNOTIFY_PFN_ typedef void (*PFN_CMDCOMP_NOTIFY)(PVRSRV_CMDCOMP_HANDLE hCmdCompHandle); +#define _CMDCOMPNOTIFY_PFN_ +#endif /**************************************************************************/ /*! @Function PVRSRVCmdCompleteInit @@ -147,12 +150,19 @@ Debug Notifier Interface struct _PVRSRV_DEVICE_NODE_; typedef IMG_HANDLE PVRSRV_DBGREQ_HANDLE; +#ifndef _DUMPDEBUG_PRINTF_FUNC_ typedef void (DUMPDEBUG_PRINTF_FUNC)(void *pvDumpDebugFile, const IMG_CHAR *pszFormat, ...); +#define _DUMPDEBUG_PRINTF_FUNC_ +#endif + +#ifndef _PFN_DBGREQ_NOTIFY_ typedef void (*PFN_DBGREQ_NOTIFY)(PVRSRV_DBGREQ_HANDLE hDebugRequestHandle, IMG_UINT32 ui32VerbLevel, DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, void *pvDumpDebugFile); +#define _PFN_DBGREQ_NOTIFY_ +#endif /**************************************************************************/ /*! diff --git a/drivers/staging/imgtec/rogue/pvr_uaccess.h b/drivers/staging/imgtec/rogue/pvr_uaccess.h index 74ddc58e4b4f..382cca4e78c8 100644 --- a/drivers/staging/imgtec/rogue/pvr_uaccess.h +++ b/drivers/staging/imgtec/rogue/pvr_uaccess.h @@ -42,7 +42,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef __PVR_UACCESS_H__ #define __PVR_UACCESS_H__ -#include +#include static inline unsigned long pvr_copy_to_user(void __user *pvTo, const void *pvFrom, unsigned long ulBytes) { diff --git a/drivers/staging/imgtec/rogue/pvrsrv_cleanup.h b/drivers/staging/imgtec/rogue/pvrsrv_cleanup.h index fc0d43298809..158b8e9d37bd 100644 --- a/drivers/staging/imgtec/rogue/pvrsrv_cleanup.h +++ b/drivers/staging/imgtec/rogue/pvrsrv_cleanup.h @@ -43,6 +43,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef PVRSRV_CLEANUP_H #define PVRSRV_CLEANUP_H +#include "dllist.h" + typedef PVRSRV_ERROR (*CLEANUP_THREAD_FN)(void *pvParam); /* typical number of times a caller should want the work to be retried in case diff --git a/drivers/staging/imgtec/rogue/pvrsrv_device_node.h b/drivers/staging/imgtec/rogue/pvrsrv_device_node.h new file mode 100644 index 000000000000..dba3b93a8cd3 --- /dev/null +++ b/drivers/staging/imgtec/rogue/pvrsrv_device_node.h @@ -0,0 +1,338 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* -------------------------------------------------------------------------------------------------------- + * File: pvrsrv_device_node.h + * -------------------------------------------------------------------------------------------------------- + */ + +#ifndef __PVRSRV_DEVICE_NODE_H__ +#define __PVRSRV_DEVICE_NODE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* --------------------------------------------------------------------------------------------------------- + * Include Files + * --------------------------------------------------------------------------------------------------------- + */ + +#include "powervr/sync_external.h" +#include "ra.h" +#include "devicemem_heapcfg.h" +#include "pvrsrv_device.h" +#include "mmu_common.h" +#include "img_types.h" +#include "lock_types.h" + + +/* --------------------------------------------------------------------------------------------------------- + * Macros Definition + * --------------------------------------------------------------------------------------------------------- + */ + + +/* --------------------------------------------------------------------------------------------------------- + * Types and Structures Definition + * --------------------------------------------------------------------------------------------------------- + */ + +typedef struct _PG_HANDLE_ { + union { + void *pvHandle; + IMG_UINT64 ui64Handle; + } u; + /*Order of the corresponding allocation */ + IMG_UINT32 ui32Order; +} PG_HANDLE; + +typedef PVRSRV_ERROR (*FN_CREATERAMBACKEDPMR)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, + IMG_DEVMEM_SIZE_T uiSize, + IMG_DEVMEM_SIZE_T uiChunkSize, + IMG_UINT32 ui32NumPhysChunks, + IMG_UINT32 ui32NumVirtChunks, + IMG_UINT32 *pui32MappingTable, + IMG_UINT32 uiLog2PageSize, + PVRSRV_MEMALLOCFLAGS_T uiFlags, + const IMG_CHAR *pszAnnotation, + PMR **ppsPMRPtr); + + +typedef struct _PVRSRV_POWER_DEV_TAG_ PVRSRV_POWER_DEV; + +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 struct _PVRSRV_DEVICE_IDENTIFIER_ { + /* Pdump memory and register bank names */ + IMG_CHAR *pszPDumpDevName; + IMG_CHAR *pszPDumpRegName; +} 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; + +/*********************************************************************/ /*! + @Function AllocUFOCallback + @Description Device specific callback for allocation of an 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 FreeUFOCallback + @Description Device specific callback for freeing of an 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 __DUMMY_PAGE__ { + /*Page handle for the dummy page allocated (UMA/LMA)*/ + PG_HANDLE sDummyPageHandle; + POS_LOCK psDummyPgLock; + ATOMIC_T atRefCounter; + /*Dummy page size in terms of log2 */ + IMG_UINT32 ui32Log2DummyPgSize; + IMG_UINT64 ui64DummyPgPhysAddr; +#if defined(PDUMP) +#define DUMMY_PAGE ("DUMMY_PAGE") + IMG_HANDLE hPdumpDummyPg; +#endif +} PVRSRV_DUMMY_PAGE ; + +// .CP : +typedef struct _PVRSRV_DEVICE_NODE_ { + PVRSRV_DEVICE_IDENTIFIER sDevId; + + PVRSRV_DEVICE_STATE eDevState; + ATOMIC_T eHealthStatus; /* Holds values from PVRSRV_DEVICE_HEALTH_STATUS */ + ATOMIC_T eHealthReason; /* Holds values from PVRSRV_DEVICE_HEALTH_REASON */ + + IMG_HANDLE *hDebugTable; + + /* device specific MMU attributes */ + MMU_DEVICEATTRIBS *psMMUDevAttrs; + /* device specific MMU firmware atrributes, used only in some devices*/ + MMU_DEVICEATTRIBS *psFirmwareMMUDevAttrs; + + /* lock for power state transitions */ + POS_LOCK hPowerLock; + /* current system device power state */ + PVRSRV_SYS_POWER_STATE eCurrentSysPowerState; + PVRSRV_POWER_DEV *psPowerDev; + + /* + callbacks the device must support: + */ + + FN_CREATERAMBACKEDPMR pfnCreateRamBackedPMR[PVRSRV_DEVICE_PHYS_HEAP_LAST]; + + PVRSRV_ERROR (*pfnDevPxAlloc)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, size_t uiSize, + PG_HANDLE *psMemHandle, IMG_DEV_PHYADDR *psDevPAddr); + + 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; + + void (*pfnMMUCacheInvalidate)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, + IMG_HANDLE hDeviceData, + MMU_LEVEL eLevel, + IMG_BOOL bUnmap); + + PVRSRV_ERROR (*pfnMMUCacheInvalidateKick)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, + IMG_UINT32 *pui32NextMMUInvalidateUpdate, + IMG_BOOL bInterrupt); + + 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); + + PVRSRV_ERROR (*pfnResetHWRLogs)(struct _PVRSRV_DEVICE_NODE_ *psDevNode); + + /* 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); + +#if defined(SUPPORT_KERNEL_SRVINIT) && defined(RGXFW_ALIGNCHECKS) + PVRSRV_ERROR (*pfnAlignmentCheck)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT32 ui32FWAlignChecksSize, IMG_UINT32 aui32FWAlignChecks[]); +#endif + IMG_BOOL (*pfnCheckDeviceFeature)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT64 ui64FeatureMask); + + IMG_INT32 (*pfnGetDeviceFeatureValue)(struct _PVRSRV_DEVICE_NODE_ *psDevNode, IMG_UINT64 ui64FeatureMask); + + PVRSRV_DEVICE_CONFIG *psDevConfig; + + /* device post-finalise compatibility check */ + PVRSRV_ERROR (*pfnInitDeviceCompatCheck)(struct _PVRSRV_DEVICE_NODE_ *); + + /* information about the device's address space and heaps */ + DEVICE_MEMORY_INFO sDevMemoryInfo; + + /* device's shared-virtual-memory heap size */ + IMG_UINT64 ui64GeneralSVMHeapSize; + + /* private device information */ + void *pvDevice; + + + +#if defined(SUPPORT_GPUVIRT_VALIDATION) + RA_ARENA *psOSidSubArena[GPUVIRT_VALIDATION_NUM_OS]; +#endif + + +#define PVRSRV_MAX_RA_NAME_LENGTH (50) + RA_ARENA **apsLocalDevMemArenas; + IMG_CHAR **apszRANames; + IMG_UINT32 ui32NumOfLocalMemArenas; + +#if defined(SUPPORT_PVRSRV_GPUVIRT) + IMG_CHAR szKernelFwRAName[RGXFW_NUM_OS][PVRSRV_MAX_RA_NAME_LENGTH]; + RA_ARENA *psKernelFwMemArena[RGXFW_NUM_OS]; + IMG_UINT32 uiKernelFwRAIdx; + RA_BASE_T ui64RABase[RGXFW_NUM_OS]; +#endif + + IMG_UINT32 ui32RegisteredPhysHeaps; + PHYS_HEAP **papsRegisteredPhysHeaps; + + /* + * Pointers to the device's physical memory heap(s) + * The first entry (apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL]) will be used for allocations + * where the PVRSRV_MEMALLOCFLAG_CPU_LOCAL flag is not set. Normally this will be an LMA heap + * (but the device configuration could specify a UMA heap here, if desired) + * The second entry (apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_CPU_LOCAL]) will be used for allocations + * where the PVRSRV_MEMALLOCFLAG_CPU_LOCAL flag is set. Normally this will be a UMA heap + * (but the configuration could specify an LMA heap here, if desired) + * The third entry (apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_FW_LOCAL]) will be used for allocations + * where the PVRSRV_MEMALLOCFLAG_FW_LOCAL flag is set; this is used when SUPPORT_PVRSRV_GPUVIRT is enabled + * The device configuration will always specify two physical heap IDs - in the event of the device + * only using one physical heap, both of these IDs will be the same, and hence both pointers below + * will also be the same; when SUPPORT_PVRSRV_GPUVIRT is enabled the device configuration specifies + * three physical heap IDs, the last being for PVRSRV_DEVICE_PHYS_HEAP_FW_LOCAL allocations + */ + PHYS_HEAP *apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_LAST]; + + 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 */ + +#if defined(SUPPORT_BUFFER_SYNC) + struct pvr_buffer_sync_context *psBufferSyncContext; +#endif + + IMG_HANDLE hSyncServerNotify; + POS_LOCK hSyncServerListLock; + DLLIST_NODE sSyncServerSyncsList; + +#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) + IMG_HANDLE hSyncServerRecordNotify; + POS_LOCK hSyncServerRecordLock; + DLLIST_NODE sSyncServerRecordList; + struct SYNC_RECORD *apsSyncServerRecordsFreed[PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN]; + IMG_UINT32 uiSyncServerRecordFreeIdx; +#endif + + PSYNC_PRIM_CONTEXT hSyncPrimContext; + + PVRSRV_CLIENT_SYNC_PRIM *psSyncPrim; + /* 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 hHtbDbgReqNotify; + IMG_HANDLE hAppHintDbgReqNotify; + + PVRSRV_DUMMY_PAGE sDummyPage; + + DLLIST_NODE sMemoryContextPageFaultNotifyListHead; + +#if defined(PDUMP) + /* 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); +#endif +} PVRSRV_DEVICE_NODE; + +/* --------------------------------------------------------------------------------------------------------- + * Global Functions' Prototype + * --------------------------------------------------------------------------------------------------------- + */ + + +/* --------------------------------------------------------------------------------------------------------- + * Inline Functions Implementation + * --------------------------------------------------------------------------------------------------------- + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __PVRSRV_DEVICE_NODE_H__ */ + diff --git a/drivers/staging/imgtec/rogue/rgxhwperf.c b/drivers/staging/imgtec/rogue/rgxhwperf.c index eb41379c2622..cf1aa166865e 100644 --- a/drivers/staging/imgtec/rogue/rgxhwperf.c +++ b/drivers/staging/imgtec/rogue/rgxhwperf.c @@ -1276,7 +1276,7 @@ void RGXHWPerfHostDeInit(void) if (gpsRgxDevInfo && gpsRgxDevInfo->hLockHWPerfHostStream) { OSLockDestroy(gpsRgxDevInfo->hLockHWPerfHostStream); - gpsRgxDevInfo->hLockHWPerfHostStream = IMG_FALSE; + gpsRgxDevInfo->hLockHWPerfHostStream = NULL; } /* Clear global RGX device reference */ diff --git a/drivers/staging/imgtec/rogue/rgxmipsmmuinit.h b/drivers/staging/imgtec/rogue/rgxmipsmmuinit.h index 2983de3f6243..67fe49232a55 100644 --- a/drivers/staging/imgtec/rogue/rgxmipsmmuinit.h +++ b/drivers/staging/imgtec/rogue/rgxmipsmmuinit.h @@ -46,7 +46,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. being otherwise cluttered by the contents of the latter */ #ifndef _SRVKM_RGXMIPSMMUINIT_H_ -#define _SRVKM_RGXMMIPSMUINIT_H_ +#define _SRVKM_RGXMIPSMMUINIT_H_ #include "device.h" #include "img_types.h" diff --git a/drivers/staging/imgtec/rogue/rk3368/sysconfig.c b/drivers/staging/imgtec/rogue/rk3368/sysconfig.c index b984f98c0bc8..8d93c2ed6f39 100644 --- a/drivers/staging/imgtec/rogue/rk3368/sysconfig.c +++ b/drivers/staging/imgtec/rogue/rk3368/sysconfig.c @@ -249,7 +249,7 @@ void SysDevDeInit(PVRSRV_DEVICE_CONFIG *psDevConfig) PVRSRV_ERROR SysInstallDeviceLISR(IMG_HANDLE hSysData, IMG_UINT32 ui32IRQ, const IMG_CHAR *pszName, - PFN_LISR pfnLISR, + SYS_PFN_LISR pfnLISR, void *pvData, IMG_HANDLE *phLISRData) { diff --git a/drivers/staging/imgtec/rogue/rogue_trace_events.h b/drivers/staging/imgtec/rogue/rogue_trace_events.h index bf763fb90d6f..29f8bcc168c9 100644 --- a/drivers/staging/imgtec/rogue/rogue_trace_events.h +++ b/drivers/staging/imgtec/rogue/rogue_trace_events.h @@ -62,7 +62,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. rem = do_div(t, USEC_PER_SEC); \ }) -void trace_fence_update_enabled_callback(void); +int trace_fence_update_enabled_callback(void); void trace_fence_update_disabled_callback(void); TRACE_EVENT_FN(rogue_fence_update, @@ -105,7 +105,7 @@ TRACE_EVENT_FN(rogue_fence_update, trace_fence_update_disabled_callback ); -void trace_fence_check_enabled_callback(void); +int trace_fence_check_enabled_callback(void); void trace_fence_check_disabled_callback(void); TRACE_EVENT_FN(rogue_fence_check, diff --git a/drivers/staging/imgtec/rogue/server_sync_primitive.h b/drivers/staging/imgtec/rogue/server_sync_primitive.h new file mode 100644 index 000000000000..934886e9bbbb --- /dev/null +++ b/drivers/staging/imgtec/rogue/server_sync_primitive.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* -------------------------------------------------------------------------------------------------------- + * File: server_sync_primitive.h + * -------------------------------------------------------------------------------------------------------- + */ + + +#ifndef __SERVER_SYNC_PRIMITIVE_H__ +#define __SERVER_SYNC_PRIMITIVE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* --------------------------------------------------------------------------------------------------------- + * Include Files + * --------------------------------------------------------------------------------------------------------- + */ + +#include "lock_types.h" +#include "dllist.h" +#include "powervr/sync_external.h" +#include "pvrsrv_device_node.h" + +/* --------------------------------------------------------------------------------------------------------- + * Macros Definition + * --------------------------------------------------------------------------------------------------------- + */ + +/* --------------------------------------------------------------------------------------------------------- + * Types and Structures Definition + * --------------------------------------------------------------------------------------------------------- + */ + +struct _SERVER_SYNC_PRIMITIVE_ { + PVRSRV_DEVICE_NODE *psDevNode; + PVRSRV_CLIENT_SYNC_PRIM *psSync; + IMG_UINT32 ui32NextOp; + IMG_UINT32 ui32RefCount; + IMG_UINT32 ui32UID; + IMG_UINT32 ui32LastSyncRequesterID; + DLLIST_NODE sNode; + /* PDump only data */ + IMG_BOOL bSWOperation; + IMG_BOOL bSWOpStartedInCaptRange; + IMG_UINT32 ui32LastHWUpdate; + IMG_BOOL bPDumped; + POS_LOCK hLock; + IMG_CHAR szClassName[SYNC_MAX_CLASS_NAME_LEN]; +}; +typedef struct _SERVER_SYNC_PRIMITIVE_ SERVER_SYNC_PRIMITIVE; + +/* --------------------------------------------------------------------------------------------------------- + * Global Functions' Prototype + * --------------------------------------------------------------------------------------------------------- + */ + + +/* --------------------------------------------------------------------------------------------------------- + * Inline Functions Implementation + * --------------------------------------------------------------------------------------------------------- + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __SERVER_SYNC_PRIMITIVE_H__ */ + diff --git a/drivers/staging/imgtec/rogue/sync_checkpoint.h b/drivers/staging/imgtec/rogue/sync_checkpoint.h index 1a8431603e06..5931fd02aa14 100644 --- a/drivers/staging/imgtec/rogue/sync_checkpoint.h +++ b/drivers/staging/imgtec/rogue/sync_checkpoint.h @@ -44,6 +44,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef _SYNC_CHECKPOINT_ #define _SYNC_CHECKPOINT_ +#include "psync_checkpoint.h" +#include "psync_checkpoint_context.h" #include "img_types.h" #include "pvrsrv_error.h" #include "pvrsrv_sync_km.h" @@ -53,13 +55,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "device_connection.h" -typedef struct _PVRSRV_DEVICE_NODE_ PVRSRV_DEVICE_NODE; - -typedef struct _SYNC_CHECKPOINT_CONTEXT *PSYNC_CHECKPOINT_CONTEXT; - -typedef struct _SYNC_CHECKPOINT *PSYNC_CHECKPOINT; - - /*************************************************************************/ /*! @Function SyncCheckpointContextCreate diff --git a/drivers/staging/imgtec/rogue/sync_checkpoint_external.h b/drivers/staging/imgtec/rogue/sync_checkpoint_external.h index 02b3e49d18d8..fdd85ff93ec4 100644 --- a/drivers/staging/imgtec/rogue/sync_checkpoint_external.h +++ b/drivers/staging/imgtec/rogue/sync_checkpoint_external.h @@ -45,11 +45,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef _SYNC_CHECKPOINT_EXTERNAL_ #define _SYNC_CHECKPOINT_EXTERNAL_ -#define SYNC_CHECKPOINT_MAX_CLASS_NAME_LEN 32 - -typedef struct _SYNC_CHECKPOINT_CONTEXT *PSYNC_CHECKPOINT_CONTEXT; - -typedef struct _SYNC_CHECKPOINT *PSYNC_CHECKPOINT; +#include "psync_checkpoint.h" +#include "psync_checkpoint_context.h" /* PVRSRV_SYNC_CHECKPOINT states. * The OS native sync implementation should call pfnIsSignalled() to determine if a diff --git a/drivers/staging/imgtec/rogue/sync_checkpoint_internal.h b/drivers/staging/imgtec/rogue/sync_checkpoint_internal.h index 02b4d18852ca..e3cded5b959d 100644 --- a/drivers/staging/imgtec/rogue/sync_checkpoint_internal.h +++ b/drivers/staging/imgtec/rogue/sync_checkpoint_internal.h @@ -45,6 +45,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef __SYNC_CHECKPOINT__ #define __SYNC_CHECKPOINT__ +#include "pvrsrv_device_node.h" +#include "psync_checkpoint.h" +#include "psync_checkpoint_context.h" #include "img_types.h" #include "sync_checkpoint_internal_fw.h" #include "sync_checkpoint.h" @@ -53,8 +56,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "lock.h" #include "devicemem.h" -typedef struct _PVRSRV_DEVICE_NODE_ PVRSRV_DEVICE_NODE; - #if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) struct SYNC_CHECKPOINT_RECORD; #endif @@ -62,62 +63,9 @@ struct SYNC_CHECKPOINT_RECORD; /* Private structures */ -#define SYNC_CHECKPOINT_NAME_SIZE SYNC_CHECKPOINT_MAX_CLASS_NAME_LEN - -typedef struct _SYNC_CHECKPOINT_CONTEXT_ -{ - PVRSRV_DEVICE_NODE *psDevNode; - IMG_CHAR azName[SYNC_CHECKPOINT_NAME_SIZE]; /*!< Name of the RA */ - RA_ARENA *psSubAllocRA; /*!< RA context */ - IMG_CHAR azSpanName[SYNC_CHECKPOINT_NAME_SIZE]; /*!< Name of the span RA */ - RA_ARENA *psSpanRA; /*!< RA used for span management of SubAllocRA */ - ATOMIC_T hRefCount; /*!< Ref count for this context */ - ATOMIC_T hCheckpointCount; /*!< Checkpoint count for this context */ - POS_LOCK hCheckpointListLock; /*!< Checkpoint list lock */ - DLLIST_NODE sCheckpointList; /*!< List of checkpoints created on this context */ - IMG_HANDLE hCheckpointNotify; /*!< Handle for debug notifier callback */ -#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) - POS_LOCK hCheckpointRecordLock; - DLLIST_NODE sCheckpointRecordList; - struct SYNC_CHECKPOINT_RECORD *apsCheckpointRecordsFreed[PVRSRV_FULL_SYNC_TRACKING_HISTORY_LEN]; - IMG_UINT32 uiCheckpointRecordFreeIdx; - IMG_HANDLE hCheckpointRecordNotify; -#endif -} _SYNC_CHECKPOINT_CONTEXT; - -typedef struct _SYNC_CHECKPOINT_BLOCK_ -{ - ATOMIC_T hRefCount; /*!< Ref count for this sync block */ - _SYNC_CHECKPOINT_CONTEXT *psContext; /*!< Our copy of the services connection */ - PVRSRV_DEVICE_NODE *psDevNode; - IMG_UINT32 ui32SyncBlockSize; /*!< Size of the sync checkpoint block */ - IMG_UINT32 ui32FirmwareAddr; /*!< Firmware address */ - DEVMEM_MEMDESC *hMemDesc; /*!< DevMem allocation for block */ - volatile IMG_UINT32 *pui32LinAddr; /*!< Server-code CPU mapping */ - IMG_UINT64 uiSpanBase; /*!< Base of this import (FW DevMem) in the span RA */ - DLLIST_NODE sListNode; /*!< List node for the sync chkpt block list */ -} SYNC_CHECKPOINT_BLOCK; typedef struct SYNC_CHECKPOINT_RECORD* PSYNC_CHECKPOINT_RECORD_HANDLE; -typedef struct _SYNC_CHECKPOINT_ -{ - /* A sync checkpoint is assigned a unique ID, to avoid any confusion should - * the same memory be re-used later for a different checkpoint - */ - IMG_UINT32 ui32UID; /*!< Unique ID assigned to sync checkpoint (to distinguish checkpoints if memory is re-used)*/ - ATOMIC_T hRefCount; /*!< Ref count for this sync */ - ATOMIC_T hEnqueuedCCBCount; /*!< Num times sync has been put in CCBs */ - SYNC_CHECKPOINT_BLOCK *psSyncCheckpointBlock; /*!< Synchronisation block this checkpoint is allocated on */ - IMG_UINT64 uiSpanAddr; /*!< Span address of the sync */ - volatile _SYNC_CHECKPOINT_FW_OBJ *psSyncCheckpointFwObj; /*!< CPU view of the data held in the sync block */ - IMG_CHAR azName[SYNC_CHECKPOINT_NAME_SIZE]; /*!< Name of the checkpoint */ -#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) - PSYNC_CHECKPOINT_RECORD_HANDLE hRecord; /*!< Sync record handle */ -#endif - DLLIST_NODE sListNode; /*!< List node for the sync chkpt list */ -} _SYNC_CHECKPOINT; - /*************************************************************************/ /*! @Function SyncCheckpointGetFirmwareAddr diff --git a/drivers/staging/imgtec/rogue/sync_server.c b/drivers/staging/imgtec/rogue/sync_server.c index d7f64b00147f..be29e4c12733 100644 --- a/drivers/staging/imgtec/rogue/sync_server.c +++ b/drivers/staging/imgtec/rogue/sync_server.c @@ -80,24 +80,6 @@ struct _SYNC_PRIMITIVE_BLOCK_ PRGXFWIF_UFO_ADDR uiFWAddr; /*!< The firmware address of the sync prim block */ }; -struct _SERVER_SYNC_PRIMITIVE_ -{ - PVRSRV_DEVICE_NODE *psDevNode; - PVRSRV_CLIENT_SYNC_PRIM *psSync; - IMG_UINT32 ui32NextOp; - IMG_UINT32 ui32RefCount; - IMG_UINT32 ui32UID; - IMG_UINT32 ui32LastSyncRequesterID; - DLLIST_NODE sNode; - /* PDump only data */ - IMG_BOOL bSWOperation; - IMG_BOOL bSWOpStartedInCaptRange; - IMG_UINT32 ui32LastHWUpdate; - IMG_BOOL bPDumped; - POS_LOCK hLock; - IMG_CHAR szClassName[SYNC_MAX_CLASS_NAME_LEN]; -}; - struct _SERVER_SYNC_EXPORT_ { SERVER_SYNC_PRIMITIVE *psSync; diff --git a/drivers/staging/imgtec/rogue/sync_server.h b/drivers/staging/imgtec/rogue/sync_server.h index 5ae0135a66b8..317f9db43cf5 100644 --- a/drivers/staging/imgtec/rogue/sync_server.h +++ b/drivers/staging/imgtec/rogue/sync_server.h @@ -41,6 +41,7 @@ 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 "server_sync_primitive.h" #include "img_types.h" #include "device.h" #include "devicemem.h" @@ -52,7 +53,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define _SYNC_SERVER_H_ typedef struct _SERVER_OP_COOKIE_ SERVER_OP_COOKIE; -typedef struct _SERVER_SYNC_PRIMITIVE_ SERVER_SYNC_PRIMITIVE; typedef struct _SYNC_PRIMITIVE_BLOCK_ SYNC_PRIMITIVE_BLOCK; typedef struct _SERVER_SYNC_EXPORT_ SERVER_SYNC_EXPORT; typedef struct _SYNC_CONNECTION_DATA_ SYNC_CONNECTION_DATA; diff --git a/drivers/staging/imgtec/rogue/sync_server_internal.h b/drivers/staging/imgtec/rogue/sync_server_internal.h index 2de4a7117c38..72e9603867a1 100644 --- a/drivers/staging/imgtec/rogue/sync_server_internal.h +++ b/drivers/staging/imgtec/rogue/sync_server_internal.h @@ -44,8 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef _SYNC_SERVER_INTERNAL_H_ #define _SYNC_SERVER_INTERNAL_H_ +#include "server_sync_primitive.h" #include "img_types.h" -typedef struct _SERVER_SYNC_PRIMITIVE_ SERVER_SYNC_PRIMITIVE; - #endif /*_SYNC_SERVER_INTERNAL_H_ */ diff --git a/drivers/staging/imgtec/rogue/syscommon.h b/drivers/staging/imgtec/rogue/syscommon.h index 428073146a56..027fd426b1b6 100644 --- a/drivers/staging/imgtec/rogue/syscommon.h +++ b/drivers/staging/imgtec/rogue/syscommon.h @@ -50,7 +50,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "pvrsrv_device.h" #include "pvrsrv_error.h" -typedef IMG_BOOL (*PFN_LISR)(void *pvData); +typedef IMG_BOOL (*SYS_PFN_LISR)(void *pvData); /**************************************************************************/ /*! @Function SysDevInit @@ -107,7 +107,7 @@ PVRSRV_ERROR SysDebugInfo(PVRSRV_DEVICE_CONFIG *psDevConfig, PVRSRV_ERROR SysInstallDeviceLISR(IMG_HANDLE hSysData, IMG_UINT32 ui32IRQ, const IMG_CHAR *pszName, - PFN_LISR pfnLISR, + SYS_PFN_LISR pfnLISR, void *pvData, IMG_HANDLE *phLISRData); diff --git a/drivers/staging/imgtec/rogue/trace_events.c b/drivers/staging/imgtec/rogue/trace_events.c index c360806fb0d1..18fe0b7a5de1 100644 --- a/drivers/staging/imgtec/rogue/trace_events.c +++ b/drivers/staging/imgtec/rogue/trace_events.c @@ -66,9 +66,11 @@ bool trace_rogue_are_fence_checks_traced(void) * simply a no-op, there is no harm in it. */ -void trace_fence_update_enabled_callback(void) +int trace_fence_update_enabled_callback(void) { fence_update_event_enabled = true; + //Warning + return 0; } void trace_fence_update_disabled_callback(void) @@ -76,9 +78,11 @@ void trace_fence_update_disabled_callback(void) fence_update_event_enabled = false; } -void trace_fence_check_enabled_callback(void) +int trace_fence_check_enabled_callback(void) { fence_check_event_enabled = true; + //Warning + return 0; } void trace_fence_check_disabled_callback(void) diff --git a/drivers/staging/imgtec/services_kernel_client.h b/drivers/staging/imgtec/services_kernel_client.h index b3d623029974..22ec8207c708 100644 --- a/drivers/staging/imgtec/services_kernel_client.h +++ b/drivers/staging/imgtec/services_kernel_client.h @@ -91,7 +91,10 @@ struct SYNC_PRIM_CONTEXT; /* pvr_notifier.h */ +#ifndef _CMDCOMPNOTIFY_PFN_ typedef void (*PFN_CMDCOMP_NOTIFY)(void *hCmdCompHandle); +#define _CMDCOMPNOTIFY_PFN_ +#endif enum PVRSRV_ERROR PVRSRVRegisterCmdCompleteNotify(void **phNotify, PFN_CMDCOMP_NOTIFY pfnCmdCompleteNotify, void *hPrivData); enum PVRSRV_ERROR PVRSRVUnregisterCmdCompleteNotify(void *hNotify); @@ -111,13 +114,20 @@ void PVRSRVCheckStatus(void *hCmdCompCallerHandle); #define DEBUG_REQUEST_VERBOSITY_HIGH 2 #define DEBUG_REQUEST_VERBOSITY_MAX DEBUG_REQUEST_VERBOSITY_HIGH +#ifndef _DUMPDEBUG_PRINTF_FUNC_ typedef void (DUMPDEBUG_PRINTF_FUNC)(void *pvDumpDebugFile, const char *fmt, ...) __printf(2, 3); +#define _DUMPDEBUG_PRINTF_FUNC_ +#endif +#ifndef _PFN_DBGREQ_NOTIFY_ typedef void (*PFN_DBGREQ_NOTIFY) (void *hDebugRequestHandle, __u32 ui32VerbLevel, DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, void *pvDumpDebugFile); +#define _PFN_DBGREQ_NOTIFY_ +#endif + enum PVRSRV_ERROR PVRSRVRegisterDbgRequestNotify(void **phNotify, struct _PVRSRV_DEVICE_NODE_ *psDevNode, PFN_DBGREQ_NOTIFY pfnDbgRequestNotify,