From 8ef932230a47b493cf98bfb7a01ca47a9189fa28 Mon Sep 17 00:00:00 2001 From: Xianzhong Date: Fri, 3 Nov 2017 14:12:38 +0800 Subject: [PATCH] MGS-3214-2: gpu-viv: integrate 6.2.4 formal driver Support GEM DRM feature for Android DRM and X11 DRI3, Fixed GC7000XSVX OpenVX 1.1 CTS failures for i.MX8QM, Add more performance optimization for GPU benchmarks. Signed-off-by: Xianzhong --- drivers/mxc/gpu-viv/Kbuild | 4 +- .../hal/kernel/arch/gc_hal_kernel_hardware.c | 7 +- .../mxc/gpu-viv/hal/kernel/gc_hal_kernel.h | 20 + .../hal/kernel/gc_hal_kernel_video_memory.c | 16 +- .../hal/kernel/inc/gc_feature_database.h | 4 +- .../mxc/gpu-viv/hal/kernel/inc/gc_hal_drm.h | 132 +++++-- .../gpu-viv/hal/kernel/inc/gc_hal_options.h | 8 + .../gpu-viv/hal/kernel/inc/gc_hal_version.h | 4 +- .../default/gc_hal_kernel_allocator_dma.c | 2 +- .../default/gc_hal_kernel_allocator_dmabuf.c | 6 +- .../default/gc_hal_kernel_allocator_gfp.c | 4 +- .../gc_hal_kernel_allocator_reserved_mem.c | 4 +- .../freescale/gc_hal_kernel_allocator_cma.c | 2 +- .../hal/os/linux/kernel/gc_hal_kernel_drm.c | 356 ++++++++++++++++-- 14 files changed, 476 insertions(+), 93 deletions(-) diff --git a/drivers/mxc/gpu-viv/Kbuild b/drivers/mxc/gpu-viv/Kbuild index 84f0225bf3fe..580855fa186e 100644 --- a/drivers/mxc/gpu-viv/Kbuild +++ b/drivers/mxc/gpu-viv/Kbuild @@ -293,8 +293,10 @@ ifeq ($(SECURITY), 1) EXTRA_CFLAGS += -DgcdSECURITY=1 endif -ifneq ($(CONFIG_DRM),) +ifneq ($(CONFIG_DRM), ) EXTRA_CFLAGS += -DgcdENABLE_DRM=$(VIVANTE_ENABLE_DRM) +else +EXTRA_CFLAGS += -DgcdENABLE_DRM=0 endif EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel/inc diff --git a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c index ebec019f9972..6d802df0df43 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c +++ b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c @@ -2555,7 +2555,6 @@ gckHARDWARE_InitializeHardware( data)); } - if (_IsHardwareMatch(Hardware, gcv2500, 0x5422)) { gcmkONERROR(gckOS_ReadRegisterEx( @@ -7589,6 +7588,7 @@ gckHARDWARE_SetPowerManagementState( /* Start profiler. */ gcmkPROFILE_INIT(freq, time); + /* Convert the broadcast power state. */ switch (State) { @@ -8035,8 +8035,9 @@ gckHARDWARE_SetPowerManagementState( gcvTRUE)); Hardware->clockState = gcvTRUE; - +#if gcdDVFS if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_DYNAMIC_FREQUENCY_SCALING) != gcvTRUE) +#endif { /* Write the clock control register. */ gcmkONERROR(gckOS_WriteRegisterEx(os, @@ -8081,8 +8082,10 @@ gckHARDWARE_SetPowerManagementState( /* Only process this when hardware is enabled. */ if (Hardware->clockState && Hardware->powerState +#if gcdDVFS /* Don't touch clock control if dynamic frequency scaling is available. */ && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_DYNAMIC_FREQUENCY_SCALING) != gcvTRUE +#endif ) { if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF)) diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h index 55fcc8919ef4..2786506ab24c 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h @@ -1130,6 +1130,13 @@ typedef struct _gcsVIDMEM_NODE gcePOOL pool; gcsFENCE_SYNC sync[gcvENGINE_GPU_ENGINE_COUNT]; + + /* For DRM usage */ + gctUINT64 timeStamp; + gckVIDMEM_NODE tsNode; + gctUINT32 tilingMode; + gctUINT32 tsMode; + gctUINT64 clearValue; } gcsVIDMEM_NODE; @@ -1204,6 +1211,13 @@ typedef struct _gcsDEVICE } gcsDEVICE; +gceSTATUS +gckVIDMEM_HANDLE_Allocate( + IN gckKERNEL Kernel, + IN gckVIDMEM_NODE Node, + OUT gctUINT32 * Handle + ); + gceSTATUS gckVIDMEM_HANDLE_Reference( IN gckKERNEL Kernel, @@ -1241,6 +1255,12 @@ gckVIDMEM_NODE_Unlock( IN gctUINT32 ProcessID ); +gceSTATUS +gckVIDMEM_NODE_Reference( + IN gckKERNEL Kernel, + IN gckVIDMEM_NODE Node + ); + gceSTATUS gckVIDMEM_NODE_Dereference( IN gckKERNEL Kernel, diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c index 18620175fe87..386468d94249 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c @@ -2285,7 +2285,7 @@ OnError: ** Pointer to a variable receiving a handle represent this ** gckVIDMEM_NODE in userspace. */ -static gceSTATUS +gceSTATUS gckVIDMEM_HANDLE_Allocate( IN gckKERNEL Kernel, IN gckVIDMEM_NODE Node, @@ -2352,7 +2352,7 @@ OnError: return status; } -static gceSTATUS +gceSTATUS gckVIDMEM_NODE_Reference( IN gckKERNEL Kernel, IN gckVIDMEM_NODE Node @@ -2724,6 +2724,13 @@ gckVIDMEM_NODE_Dereference( } } + /* Should not cause recursive call since tsNode->tsNode should be NULL */ + if (Node->tsNode) + { + gcmkASSERT(!Node->tsNode->tsNode); + gckVIDMEM_NODE_Dereference(Kernel, Node->tsNode); + } + gcmkOS_SAFE_FREE(Kernel->os, Node); } @@ -2827,7 +2834,7 @@ static void _dmabuf_release(struct dma_buf *dmabuf) { gckVIDMEM_NODE nodeObject = dmabuf->priv; - gcmkVERIFY_OK(gckVIDMEM_NODE_Reference(nodeObject->kernel, nodeObject)); + gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(nodeObject->kernel, nodeObject)); } static void *_dmabuf_kmap(struct dma_buf *dmabuf, unsigned long offset) @@ -3277,13 +3284,14 @@ gckVIDMEM_NODE_WrapUserMemory( if (dmabuf->ops == &_dmabuf_ops) { - gctBOOL referenced = gcvFALSE; + gctBOOL referenced = gcvFALSE; gckVIDMEM_NODE nodeObject = dmabuf->priv; do { /* Reference the node. */ gcmkERR_BREAK(gckVIDMEM_NODE_Reference(Kernel, nodeObject)); + referenced = gcvTRUE; /* Allocate a handle for current process. */ gcmkERR_BREAK(gckVIDMEM_HANDLE_Allocate(Kernel, nodeObject, Handle)); found = gcvTRUE; diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_feature_database.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_feature_database.h index b64014be720a..9833ac43e91f 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_feature_database.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_feature_database.h @@ -53,7 +53,7 @@ *****************************************************************************/ -/*Auto created on 2017-09-29 05:51*/ +/*Auto created on 2017-10-12 14:21*/ #ifndef _gc_feature_database_h_ #define _gc_feature_database_h_ @@ -48807,7 +48807,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = { 0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */ 0x0, /* gcFEATURE_BIT_G2D_DEC400 */ 0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */ - 0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */ + 0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */ 0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */ 0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */ 0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */ diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_drm.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_drm.h index 8e08290f7624..9167e702031a 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_drm.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_drm.h @@ -53,22 +53,6 @@ *****************************************************************************/ -/* - * Copyright (C) 2015 Etnaviv Project - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - #ifndef __GC_HAL_DRM_H__ #define __GC_HAL_DRM_H__ @@ -76,29 +60,33 @@ extern "C" { #endif -enum VIV_GEM_PARAM { - VIV_GEM_PARAM_NODE = 0, - VIV_GEM_PARAM_POOL, - VIV_GEM_PARAM_SIZE, -}; +/* creation flag bits. */ +#define DRM_VIV_GEM_CONTIGUOUS 0x01 +#define DRM_VIV_GEM_CACHED 0x02 +#define DRM_VIV_GEM_SECURE 0x04 struct drm_viv_gem_create { - __u64 size; /* in */ - __u32 flags; /* in */ - __u32 handle; /* out */ + __u64 size; + __u32 flags; + __u32 handle; }; struct drm_viv_gem_lock { __u32 handle; __u32 cacheable; - __u32 gpu_va; - __u64 cpu_va; + __u64 logical; }; struct drm_viv_gem_unlock { __u32 handle; }; + +#define DRM_VIV_GEM_CLEAN_CACHE 0x01 +#define DRM_VIV_GEM_INVALIDATE_CACHE 0x02 +#define DRM_VIV_GEM_FLUSH_CACHE 0x03 +#define DRM_VIV_GEM_MEMORY_BARRIER 0x04 + struct drm_viv_gem_cache { __u32 handle; __u32 op; @@ -106,27 +94,101 @@ struct drm_viv_gem_cache { __u64 bytes; }; -struct drm_viv_gem_getinfo { + +#define DRM_VIV_GEM_PARAM_POOL 0x00 +#define DRM_VIV_GEM_PARAM_SIZE 0x01 + +struct drm_viv_gem_query { __u32 handle; __u32 param; __u64 value; }; + +struct drm_viv_gem_timestamp { + __u32 handle; + /* inc count, 0 for query current. */ + __u32 inc; + /* output inc'ed timestamp. */ + __u64 timestamp; +}; + + +/* basic tiling mode. */ +#define DRM_VIV_GEM_TILING_LINEAR 0x01 +#define DRM_VIV_GEM_TILING_TILED 0x02 +#define DRM_VIV_GEM_TILING_SUPERTILED 0x04 +#define DRM_VIV_GEM_TILING_MINORTILED 0x08 + +/* tiling mode modifiers. */ +#define DRM_VIV_GEM_TILING_SPLIT 0x10 +#define DRM_VIV_GEM_TILING_X_MAJOR 0x20 +#define DRM_VIV_GEM_TILING_Y_MAJOR 0x40 +#define DRM_VIV_GEM_TILING_SWAP 0x80 + +/* ts mode. */ +#define DRM_VIV_GEM_TS_NONE 0x00 +#define DRM_VIV_GEM_TS_DISABLED 0x01 +#define DRM_VIV_GEM_TS_NORMAL 0x02 +#define DRM_VIV_GEM_TS_COMPRESSED 0x03 + +struct drm_viv_gem_set_tiling { + __u32 handle; + __u32 tiling_mode; + + __u32 ts_mode; + __u64 clear_value; +}; + +struct drm_viv_gem_get_tiling { + __u32 handle; + __u32 tiling_mode; + + __u32 ts_mode; + __u64 clear_value; +}; + + +struct drm_viv_gem_attach_aux { + __u32 handle; + __u32 ts_handle; +}; + + +struct drm_viv_gem_ref_node { + __u32 handle; + + /* output. */ + __u32 node; + __u32 ts_node; +}; + + #define DRM_VIV_GEM_CREATE 0x00 #define DRM_VIV_GEM_LOCK 0x01 #define DRM_VIV_GEM_UNLOCK 0x02 #define DRM_VIV_GEM_CACHE 0x03 -#define DRM_VIV_GEM_GETINFO 0x04 -#define DRM_VIV_NUM_IOCTLS 0x05 +#define DRM_VIV_GEM_QUERY 0x04 +#define DRM_VIV_GEM_TIMESTAMP 0x05 +#define DRM_VIV_GEM_SET_TILING 0x06 +#define DRM_VIV_GEM_GET_TILING 0x07 +#define DRM_VIV_GEM_ATTACH_AUX 0x08 +#define DRM_VIV_GEM_REF_NODE 0x09 +#define DRM_VIV_NUM_IOCTLS 0x0A -#define DRM_IOCTL_VIV_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_CREATE, struct drm_viv_gem_create) -#define DRM_IOCTL_VIV_GEM_LOCK DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_LOCK, struct drm_viv_gem_lock) -#define DRM_IOCTL_VIV_GEM_UNLOCK DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_UNLOCK, struct drm_viv_gem_unlock) -#define DRM_IOCTL_VIV_GEM_CACHE DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_CACHE, struct drm_viv_gem_cache) -#define DRM_IOCTL_VIV_GEM_GETINFO DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_GETINFO, struct drm_viv_gem_getinfo) +#define DRM_IOCTL_VIV_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_CREATE, struct drm_viv_gem_create) +#define DRM_IOCTL_VIV_GEM_LOCK DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_LOCK, struct drm_viv_gem_lock) +#define DRM_IOCTL_VIV_GEM_UNLOCK DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_UNLOCK, struct drm_viv_gem_unlock) +#define DRM_IOCTL_VIV_GEM_CACHE DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_CACHE, struct drm_viv_gem_cache) +#define DRM_IOCTL_VIV_GEM_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_QUERY, struct drm_viv_gem_query) +#define DRM_IOCTL_VIV_GEM_TIMESTAMP DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_TIMESTAMP, struct drm_viv_gem_timestamp) +#define DRM_IOCTL_VIV_GEM_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_SET_TILING, struct drm_viv_gem_set_tiling) +#define DRM_IOCTL_VIV_GEM_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_GET_TILING, struct drm_viv_gem_get_tiling) +#define DRM_IOCTL_VIV_GEM_ATTACH_AUX DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_ATTACH_AUX, struct drm_viv_gem_attach_aux) +#define DRM_IOCTL_VIV_GEM_REF_NODE DRM_IOWR(DRM_COMMAND_BASE + DRM_VIV_GEM_REF_NODE, struct drm_viv_gem_ref_node) #if defined(__cplusplus) } #endif -#endif /* __ETNAVIV_DRM_H__ */ +#endif /* __GC_HAL_DRM_H__ */ diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h index 72815f618d7e..cf6e3eac09b6 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h @@ -1392,5 +1392,13 @@ VIV:gcdUSE_MMU_EXCEPTION # define gcd2D_COMPRESSION_DEC400_ALIGN_MODE 1 #endif +/* + gcdENABLE_KERNEL_FENCE + When enabled, use kernel fence to do resource tracking. +*/ +#ifndef gcdENABLE_KENREL_FENCE +# define gcdENABLE_KERNEL_FENCE 0 +#endif + #endif /* __gc_hal_options_h_ */ diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h index e9c02f9452ca..c83b7fe30cd8 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h @@ -62,8 +62,8 @@ #define gcvVERSION_PATCH 4 -#define gcvVERSION_BUILD 136949 +#define gcvVERSION_BUILD 138003 -#define gcvVERSION_STRING "6.2.4.pre6.136949" +#define gcvVERSION_STRING "6.2.4.138003" #endif /* __gc_hal_version_h_ */ diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dma.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dma.c index fd5721ee49c6..a412237faa99 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dma.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dma.c @@ -461,7 +461,7 @@ _DmaMapUser( up_write(¤t->mm->mmap_sem); OnError: - if (gcmIS_ERROR(status)) + if (gcmIS_ERROR(status) && userLogical) { _DmaUnmapUser(Allocator, Mdl, userLogical, Mdl->numPages * PAGE_SIZE); } diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dmabuf.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dmabuf.c index 49f0a30217ff..1b60b4dfaa05 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dmabuf.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dmabuf.c @@ -336,7 +336,7 @@ _DmabufUnmapUser( } userLogical -= buf_desc->sgtable->sgl->offset; - vm_munmap((unsigned long)userLogical, Mdl->numPages >> PAGE_SHIFT); + vm_munmap((unsigned long)userLogical, Mdl->numPages << PAGE_SHIFT); } static gceSTATUS @@ -376,9 +376,9 @@ _DmabufMapUser( *UserLogical = (gctPOINTER)userLogical; OnError: - if (gcmIS_ERROR(status)) + if (gcmIS_ERROR(status) && userLogical) { - _DmabufUnmapUser(Allocator, Mdl, *UserLogical, Mdl->numPages >> PAGE_SHIFT); + _DmabufUnmapUser(Allocator, Mdl, userLogical, Mdl->numPages << PAGE_SHIFT); } return status; } diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_gfp.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_gfp.c index cdf267e840df..2949e0b0c8b2 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_gfp.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_gfp.c @@ -787,9 +787,9 @@ _GFPMapUser( } OnError: - if (gcmIS_ERROR(status)) + if (gcmIS_ERROR(status) && userLogical) { - _GFPUnmapUser(Allocator, Mdl, *UserLogical, Mdl->numPages * PAGE_SIZE); + _GFPUnmapUser(Allocator, Mdl, userLogical, Mdl->numPages * PAGE_SIZE); } gcmkFOOTER(); return status; diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_reserved_mem.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_reserved_mem.c index 3f378807eda4..3c0e7cb15767 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_reserved_mem.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_reserved_mem.c @@ -341,9 +341,9 @@ reserved_mem_map_user( up_write(¤t->mm->mmap_sem); OnError: - if (gcmIS_ERROR(status)) + if (gcmIS_ERROR(status) && userLogical) { - reserved_mem_unmap_user(Allocator, Mdl, *UserLogical, res->size); + reserved_mem_unmap_user(Allocator, Mdl, userLogical, res->size); } gcmkFOOTER(); return status; diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_cma.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_cma.c index b623ae1a250b..8d7cf271cadd 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_cma.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_cma.c @@ -434,7 +434,7 @@ _CMAFSLMapUser( } OnError: - if (gcmIS_ERROR(status)) + if (gcmIS_ERROR(status) && userLogical) { _CMAFSLUnmapUser(Allocator, Mdl, userLogical, Mdl->numPages * PAGE_SIZE); } diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_drm.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_drm.c index 1fc8a51b638d..4b7644e540c9 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_drm.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_drm.c @@ -70,7 +70,8 @@ struct viv_gem_object { struct drm_gem_object base; - uint32_t node; + uint32_t node_handle; + gckVIDMEM_NODE node_object; }; struct dma_buf *viv_gem_prime_export(struct drm_device *drm, @@ -84,7 +85,7 @@ struct dma_buf *viv_gem_prime_export(struct drm_device *drm, if (gal_dev) { gckKERNEL kernel = gal_dev->device->map[gal_dev->device->defaultHwType].kernels[0]; - gcmkVERIFY_OK(gckVIDMEM_NODE_Export(kernel, viv_obj->node, flags, + gcmkVERIFY_OK(gckVIDMEM_NODE_Export(kernel, viv_obj->node_handle, flags, (gctPOINTER*)&dmabuf, gcvNULL)); } @@ -98,8 +99,11 @@ struct drm_gem_object *viv_gem_prime_import(struct drm_device *drm, struct viv_gem_object *viv_obj; gcsHAL_INTERFACE iface; + gckGALDEVICE gal_dev; + gckKERNEL kernel; + gctUINT32 processID; + gckVIDMEM_NODE nodeObject; gceSTATUS status = gcvSTATUS_OK; - gckGALDEVICE gal_dev = gcvNULL; gal_dev = (gckGALDEVICE)drm->dev_private; if (!gal_dev) @@ -115,11 +119,16 @@ struct drm_gem_object *viv_gem_prime_import(struct drm_device *drm, iface.u.WrapUserMemory.desc.dmabuf = gcmPTR_TO_UINT64(dmabuf); gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface)); + kernel = gal_dev->device->map[gal_dev->device->defaultHwType].kernels[0]; + gcmkONERROR(gckOS_GetProcessID(&processID)); + gcmkONERROR(gckVIDMEM_HANDLE_Lookup(kernel, processID, iface.u.WrapUserMemory.node, &nodeObject)); + /* ioctl output */ gem_obj = kzalloc(sizeof(struct viv_gem_object), GFP_KERNEL); drm_gem_private_object_init(drm, gem_obj, dmabuf->size); viv_obj = container_of(gem_obj, struct viv_gem_object, base); - viv_obj->node = iface.u.WrapUserMemory.node; + viv_obj->node_handle = iface.u.WrapUserMemory.node; + viv_obj->node_object = nodeObject; OnError: return gem_obj; @@ -136,7 +145,7 @@ void viv_gem_free_object(struct drm_gem_object *gem_obj) gckOS_ZeroMemory(&iface, sizeof(iface)); iface.command = gcvHAL_RELEASE_VIDEO_MEMORY; iface.hardwareType = gal_dev->device->defaultHwType; - iface.u.ReleaseVideoMemory.node = viv_obj->node; + iface.u.ReleaseVideoMemory.node = viv_obj->node_handle; gcmkVERIFY_OK(gckDEVICE_Dispatch(gal_dev->device, &iface)); drm_gem_object_release(gem_obj); @@ -152,8 +161,12 @@ static int viv_ioctl_gem_create(struct drm_device *drm, void *data, struct viv_gem_object *viv_obj; gcsHAL_INTERFACE iface; + gckGALDEVICE gal_dev; + gckKERNEL kernel; + gctUINT32 processID; + gckVIDMEM_NODE nodeObject; + gctUINT32 flags = 0; gceSTATUS status = gcvSTATUS_OK; - gckGALDEVICE gal_dev = gcvNULL; gal_dev = (gckGALDEVICE)drm->dev_private; if (!gal_dev) @@ -161,23 +174,41 @@ static int viv_ioctl_gem_create(struct drm_device *drm, void *data, gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); } + if (args->flags & DRM_VIV_GEM_CONTIGUOUS) + { + flags |= gcvALLOC_FLAG_CONTIGUOUS; + } + if (args->flags & DRM_VIV_GEM_CACHED) + { + flags |= gcvALLOC_FLAG_CACHEABLE; + } + if (args->flags & DRM_VIV_GEM_SECURE) + { + flags |= gcvALLOC_FLAG_SECURITY; + } + gckOS_ZeroMemory(&iface, sizeof(iface)); iface.command = gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY; iface.hardwareType = gal_dev->device->defaultHwType; iface.u.AllocateLinearVideoMemory.bytes = PAGE_ALIGN(args->size); iface.u.AllocateLinearVideoMemory.alignment = 256; iface.u.AllocateLinearVideoMemory.type = gcvSURF_RENDER_TARGET; /* should be general */ - iface.u.AllocateLinearVideoMemory.flag = args->flags; + iface.u.AllocateLinearVideoMemory.flag = flags; iface.u.AllocateLinearVideoMemory.pool = gcvPOOL_DEFAULT; gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface)); + kernel = gal_dev->device->map[gal_dev->device->defaultHwType].kernels[0]; + gcmkONERROR(gckOS_GetProcessID(&processID)); + gcmkONERROR(gckVIDMEM_HANDLE_Lookup(kernel, processID, iface.u.AllocateLinearVideoMemory.node, &nodeObject)); + /* ioctl output */ gem_obj = kzalloc(sizeof(struct viv_gem_object), GFP_KERNEL); drm_gem_private_object_init(drm, gem_obj, iface.u.AllocateLinearVideoMemory.bytes); ret = drm_gem_handle_create(file, gem_obj, &args->handle); viv_obj = container_of(gem_obj, struct viv_gem_object, base); - viv_obj->node = iface.u.AllocateLinearVideoMemory.node; + viv_obj->node_handle = iface.u.AllocateLinearVideoMemory.node; + viv_obj->node_object = nodeObject; /* drop reference from allocate - handle holds it now */ drm_gem_object_unreference_unlocked(gem_obj); @@ -213,12 +244,11 @@ static int viv_ioctl_gem_lock(struct drm_device *drm, void *data, gckOS_ZeroMemory(&iface, sizeof(iface)); iface.command = gcvHAL_LOCK_VIDEO_MEMORY; iface.hardwareType = gal_dev->device->defaultHwType; - iface.u.LockVideoMemory.node = viv_obj->node; + iface.u.LockVideoMemory.node = viv_obj->node_handle; iface.u.LockVideoMemory.cacheable = args->cacheable; gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface)); - args->cpu_va = iface.u.LockVideoMemory.memory; - args->gpu_va = iface.u.LockVideoMemory.address; + args->logical = iface.u.LockVideoMemory.memory; OnError: return gcmIS_ERROR(status) ? -ENOTTY : 0; @@ -252,7 +282,7 @@ static int viv_ioctl_gem_unlock(struct drm_device *drm, void *data, gckOS_ZeroMemory(&iface, sizeof(iface)); iface.command = gcvHAL_UNLOCK_VIDEO_MEMORY; iface.hardwareType = gal_dev->device->defaultHwType; - iface.u.UnlockVideoMemory.node = (gctUINT64)viv_obj->node; + iface.u.UnlockVideoMemory.node = (gctUINT64)viv_obj->node_handle; iface.u.UnlockVideoMemory.type = gcvSURF_TYPE_UNKNOWN; gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface)); @@ -276,6 +306,7 @@ static int viv_ioctl_gem_cache(struct drm_device *drm, void *data, gcsHAL_INTERFACE iface; gceSTATUS status = gcvSTATUS_OK; gckGALDEVICE gal_dev = gcvNULL; + gceCACHEOPERATION cache_op = 0; gal_dev = (gckGALDEVICE)drm->dev_private; if (!gal_dev) @@ -291,11 +322,29 @@ static int viv_ioctl_gem_cache(struct drm_device *drm, void *data, drm_gem_object_unreference_unlocked(gem_obj); viv_obj = container_of(gem_obj, struct viv_gem_object, base); + switch (args->op) + { + case DRM_VIV_GEM_CLEAN_CACHE: + cache_op = gcvCACHE_CLEAN; + break; + case DRM_VIV_GEM_INVALIDATE_CACHE: + cache_op = gcvCACHE_INVALIDATE; + break; + case DRM_VIV_GEM_FLUSH_CACHE: + cache_op = gcvCACHE_FLUSH; + break; + case DRM_VIV_GEM_MEMORY_BARRIER: + cache_op = gcvCACHE_MEMORY_BARRIER; + break; + default: + break; + } + gckOS_ZeroMemory(&iface, sizeof(iface)); iface.command = gcvHAL_CACHE; iface.hardwareType = gal_dev->device->defaultHwType; - iface.u.Cache.node = viv_obj->node; - iface.u.Cache.operation = args->op; + iface.u.Cache.node = viv_obj->node_handle; + iface.u.Cache.operation = cache_op; iface.u.Cache.logical = args->logical; iface.u.Cache.bytes = args->bytes; gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface)); @@ -304,25 +353,21 @@ OnError: return gcmIS_ERROR(status) ? -ENOTTY : 0; } -static int viv_ioctl_gem_getinfo(struct drm_device *drm, void *data, - struct drm_file *file) +static int viv_ioctl_gem_query(struct drm_device *drm, void *data, + struct drm_file *file) { - struct drm_viv_gem_getinfo *args = (struct drm_viv_gem_getinfo*)data; + struct drm_viv_gem_query *args = (struct drm_viv_gem_query*)data; struct drm_gem_object *gem_obj; struct viv_gem_object *viv_obj; gceSTATUS status = gcvSTATUS_OK; gckGALDEVICE gal_dev = gcvNULL; - gckKERNEL kernel; - gctUINT32 processID; - gckVIDMEM_NODE node = gcvNULL; gal_dev = (gckGALDEVICE)drm->dev_private; if (!gal_dev) { gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); } - kernel = gal_dev->device->map[gal_dev->device->defaultHwType].kernels[0]; gem_obj = drm_gem_object_lookup(file, args->handle); if (!gem_obj) @@ -332,36 +377,271 @@ static int viv_ioctl_gem_getinfo(struct drm_device *drm, void *data, drm_gem_object_unreference_unlocked(gem_obj); viv_obj = container_of(gem_obj, struct viv_gem_object, base); - gcmkONERROR(gckOS_GetProcessID(&processID)); - gcmkONERROR(gckVIDMEM_HANDLE_Lookup(kernel, processID, viv_obj->node, &node)); switch (args->param) { - case VIV_GEM_PARAM_NODE: - args->value = (__u64)viv_obj->node; - break; - case VIV_GEM_PARAM_POOL: - args->value = (__u64)node->pool; + case DRM_VIV_GEM_PARAM_POOL: + args->value = (__u64)viv_obj->node_object->pool; break; - case VIV_GEM_PARAM_SIZE: - args->value = (node->node->VidMem.memory->object.type == gcvOBJ_VIDMEM) - ? (__u64)node->node->VidMem.bytes - : (__u64)node->node->Virtual.bytes;; + case DRM_VIV_GEM_PARAM_SIZE: + args->value = (__u64)gem_obj->size; break; default: - break; + gcmkONERROR(gcvSTATUS_NOT_SUPPORTED); + } + +OnError: + return gcmIS_ERROR(status) ? -ENOTTY : 0; +} + +static int viv_ioctl_gem_timestamp(struct drm_device *drm, void *data, + struct drm_file *file) +{ + struct drm_viv_gem_timestamp *args = (struct drm_viv_gem_timestamp *)data; + struct drm_gem_object *gem_obj; + struct viv_gem_object *viv_obj; + + gceSTATUS status = gcvSTATUS_OK; + gckGALDEVICE gal_dev = gcvNULL; + + gal_dev = (gckGALDEVICE)drm->dev_private; + if (!gal_dev) + { + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); + } + + gem_obj = drm_gem_object_lookup(file, args->handle); + if (!gem_obj) + { + gcmkONERROR(gcvSTATUS_NOT_FOUND); + } + viv_obj = container_of(gem_obj, struct viv_gem_object, base); + + viv_obj->node_object->timeStamp += args->inc; + args->timestamp = viv_obj->node_object->timeStamp; + drm_gem_object_unreference_unlocked(gem_obj); + +OnError: + return gcmIS_ERROR(status) ? -ENOTTY : 0; +} + +static int viv_ioctl_gem_set_tiling(struct drm_device *drm, void *data, + struct drm_file *file) +{ + struct drm_viv_gem_set_tiling *args = (struct drm_viv_gem_set_tiling*)data; + struct drm_gem_object *gem_obj; + struct viv_gem_object *viv_obj; + + gceSTATUS status = gcvSTATUS_OK; + gckGALDEVICE gal_dev = gcvNULL; + + gal_dev = (gckGALDEVICE)drm->dev_private; + if (!gal_dev) + { + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); + } + + gem_obj = drm_gem_object_lookup(file, args->handle); + if (!gem_obj) + { + gcmkONERROR(gcvSTATUS_NOT_FOUND); + } + drm_gem_object_unreference_unlocked(gem_obj); + viv_obj = container_of(gem_obj, struct viv_gem_object, base); + + viv_obj->node_object->tilingMode = args->tiling_mode; + viv_obj->node_object->tsMode = args->ts_mode; + viv_obj->node_object->clearValue = args->clear_value; + +OnError: + return gcmIS_ERROR(status) ? -ENOTTY : 0; +} + +static int viv_ioctl_gem_get_tiling(struct drm_device *drm, void *data, + struct drm_file *file) +{ + struct drm_viv_gem_get_tiling *args = (struct drm_viv_gem_get_tiling*)data; + struct drm_gem_object *gem_obj; + struct viv_gem_object *viv_obj; + + gceSTATUS status = gcvSTATUS_OK; + gckGALDEVICE gal_dev = gcvNULL; + + gal_dev = (gckGALDEVICE)drm->dev_private; + if (!gal_dev) + { + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); } + gem_obj = drm_gem_object_lookup(file, args->handle); + if (!gem_obj) + { + gcmkONERROR(gcvSTATUS_NOT_FOUND); + } + drm_gem_object_unreference_unlocked(gem_obj); + viv_obj = container_of(gem_obj, struct viv_gem_object, base); + + args->tiling_mode = viv_obj->node_object->tilingMode; + args->ts_mode = viv_obj->node_object->tsMode; + args->clear_value = viv_obj->node_object->clearValue; + OnError: return gcmIS_ERROR(status) ? -ENOTTY : 0; } +static int viv_ioctl_gem_attach_aux(struct drm_device *drm, void *data, + struct drm_file *file) +{ + struct drm_viv_gem_attach_aux *args = (struct drm_viv_gem_attach_aux*)data; + struct drm_gem_object *gem_obj; + struct viv_gem_object *viv_obj; + + gceSTATUS status = gcvSTATUS_OK; + gckGALDEVICE gal_dev = gcvNULL; + gckVIDMEM_NODE nodeObj = gcvNULL; + + gal_dev = (gckGALDEVICE)drm->dev_private; + if (!gal_dev) + { + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); + } + + gem_obj = drm_gem_object_lookup(file, args->handle); + if (!gem_obj) + { + gcmkONERROR(gcvSTATUS_NOT_FOUND); + } + drm_gem_object_unreference_unlocked(gem_obj); + viv_obj = container_of(gem_obj, struct viv_gem_object, base); + nodeObj = viv_obj->node_object; + + /* do not support re-attach */ + if (nodeObj->tsNode) + { + gcmkONERROR(gcvSTATUS_NOT_SUPPORTED); + } + + if (args->ts_handle) + { + struct drm_gem_object *gem_ts_obj; + struct viv_gem_object *viv_ts_obj; + gckKERNEL kernel = gal_dev->device->map[gal_dev->device->defaultHwType].kernels[0]; + + gem_ts_obj = drm_gem_object_lookup(file, args->ts_handle); + if (!gem_ts_obj) + { + gcmkONERROR(gcvSTATUS_NOT_FOUND); + } + drm_gem_object_unreference_unlocked(gem_ts_obj); + viv_ts_obj = container_of(gem_ts_obj, struct viv_gem_object, base); + + gcmkONERROR(gckVIDMEM_NODE_Reference(kernel, viv_ts_obj->node_object)); + nodeObj->tsNode = viv_ts_obj->node_object; + } + +OnError: + return gcmIS_ERROR(status) ? -ENOTTY : 0; +} + +static int viv_ioctl_gem_ref_node(struct drm_device *drm, void *data, + struct drm_file *file) +{ + struct drm_viv_gem_ref_node *args = (struct drm_viv_gem_ref_node*)data; + struct drm_gem_object *gem_obj; + struct viv_gem_object *viv_obj; + + gceSTATUS status = gcvSTATUS_OK; + gckGALDEVICE gal_dev = gcvNULL; + gckKERNEL kernel = gcvNULL; + gctUINT32 processID; + gckVIDMEM_NODE nodeObj; + gctUINT32 nodeHandle = 0, tsNodeHandle = 0; + gctBOOL refered = gcvFALSE; + int ret = 0; + + gal_dev = (gckGALDEVICE)drm->dev_private; + if (!gal_dev) + { + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); + } + kernel = gal_dev->device->map[gal_dev->device->defaultHwType].kernels[0]; + + gem_obj = drm_gem_object_lookup(file, args->handle); + if (!gem_obj) + { + gcmkONERROR(gcvSTATUS_NOT_FOUND); + } + drm_gem_object_unreference_unlocked(gem_obj); + viv_obj = container_of(gem_obj, struct viv_gem_object, base); + nodeObj = viv_obj->node_object; + + gcmkONERROR(gckOS_GetProcessID(&processID)); + gcmkONERROR(gckVIDMEM_HANDLE_Allocate(kernel, nodeObj, &nodeHandle)); + gcmkONERROR( + gckKERNEL_AddProcessDB(kernel, + processID, gcvDB_VIDEO_MEMORY, + gcmINT2PTR(nodeHandle), + gcvNULL, + 0)); + gcmkONERROR(gckVIDMEM_NODE_Reference(kernel, nodeObj)); + refered = gcvTRUE; + + if (nodeObj->tsNode) + { + gcmkONERROR(gckVIDMEM_HANDLE_Allocate(kernel, nodeObj->tsNode, &tsNodeHandle)); + gcmkONERROR( + gckKERNEL_AddProcessDB(kernel, + processID, gcvDB_VIDEO_MEMORY, + gcmINT2PTR(tsNodeHandle), + gcvNULL, + 0)); + gcmkONERROR(gckVIDMEM_NODE_Reference(kernel, nodeObj->tsNode)); + } + args->node = nodeHandle; + args->ts_node = tsNodeHandle; + +OnError: + if (gcmIS_ERROR(status) && kernel) + { + gctUINT32 processID; + + gcmkVERIFY_OK(gckOS_GetProcessID(&processID)); + + if (tsNodeHandle) + { + gckVIDMEM_HANDLE_Dereference(kernel, processID, tsNodeHandle); + } + + if (nodeHandle) + { + gckVIDMEM_HANDLE_Dereference(kernel, processID, nodeHandle); + } + + if (refered) + { + gcmkONERROR(gckVIDMEM_NODE_Dereference(kernel, nodeObj)); + } + + args->node = 0; + args->ts_node = 0; + + ret = -ENOTTY; + } + + return ret; +} + static const struct drm_ioctl_desc viv_ioctls[] = { - DRM_IOCTL_DEF_DRV(VIV_GEM_CREATE, viv_ioctl_gem_create, DRM_AUTH | DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(VIV_GEM_LOCK, viv_ioctl_gem_lock, DRM_AUTH | DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(VIV_GEM_UNLOCK, viv_ioctl_gem_unlock, DRM_AUTH | DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(VIV_GEM_CACHE, viv_ioctl_gem_cache, DRM_AUTH | DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(VIV_GEM_GETINFO, viv_ioctl_gem_getinfo, DRM_AUTH | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(VIV_GEM_CREATE, viv_ioctl_gem_create, DRM_AUTH | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(VIV_GEM_LOCK, viv_ioctl_gem_lock, DRM_AUTH | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(VIV_GEM_UNLOCK, viv_ioctl_gem_unlock, DRM_AUTH | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(VIV_GEM_CACHE, viv_ioctl_gem_cache, DRM_AUTH | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(VIV_GEM_QUERY, viv_ioctl_gem_query, DRM_AUTH | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(VIV_GEM_TIMESTAMP, viv_ioctl_gem_timestamp, DRM_AUTH | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(VIV_GEM_SET_TILING, viv_ioctl_gem_set_tiling, DRM_AUTH | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(VIV_GEM_GET_TILING, viv_ioctl_gem_get_tiling, DRM_AUTH | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(VIV_GEM_ATTACH_AUX, viv_ioctl_gem_attach_aux, DRM_AUTH | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(VIV_GEM_REF_NODE, viv_ioctl_gem_ref_node, DRM_AUTH | DRM_RENDER_ALLOW), }; int viv_drm_open(struct drm_device *drm, struct drm_file *file) -- 2.17.1