summaryrefslogtreecommitdiff
path: root/drivers/mxc/gpu-viv/hal/os/linux
diff options
context:
space:
mode:
authorXianzhong <xianzhong.li@nxp.com>2019-01-11 23:28:33 +0800
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:35:55 +0800
commita03bac842b9f615d3795b272fd719957534ed77a (patch)
tree483fac327e03990991d70a70c3b738a9749072c4 /drivers/mxc/gpu-viv/hal/os/linux
parentd260e22591f1d645bcb0829ef128301bdb2e65ed (diff)
MGS-4501 upgrade vivante 6.2.4.p4 gpu driver
include critical gpu bug-fixings for Android 9.0 commit-id 20ea99e9db80e834c7970568a6122f11327dd5dc Signed-off-by: Xianzhong <xianzhong.li@nxp.com>
Diffstat (limited to 'drivers/mxc/gpu-viv/hal/os/linux')
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dma.c41
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dmabuf.c13
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_gfp.c65
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_reserved_mem.c2
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_user_memory.c6
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_cma.c2
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.h8
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h4
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c9
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c14
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_drm.c12
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h17
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c462
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h2
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h6
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c23
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h6
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.c24
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.config1
19 files changed, 471 insertions, 246 deletions
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 bed5f6db0c74..36bf9c5552f0 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
@@ -61,6 +61,10 @@
#include <linux/mman.h>
#include <asm/atomic.h>
#include <linux/dma-mapping.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,19,0)
+#include <linux/dma-direct.h>
+#endif
+
#include <linux/slab.h>
#include <linux/platform_device.h>
@@ -129,25 +133,6 @@ _DebugfsCleanup(
gckDEBUGFS_DIR_Deinit(&Allocator->debugfsDir);
}
-#ifdef CONFIG_ARM64
-static struct device *
-_GetDevice(
- IN gckOS Os
- )
-{
- gcsPLATFORM *platform;
-
- platform = Os->device->platform;
-
- if (!platform)
- {
- return gcvNULL;
- }
-
- return &platform->device->dev;
-}
-#endif
-
static gceSTATUS
_DmaAlloc(
IN gckALLOCATOR Allocator,
@@ -176,12 +161,10 @@ _DmaAlloc(
#endif
mdlPriv->kvaddr
-#if defined CONFIG_ARM64
- = dma_alloc_coherent(_GetDevice(os), NumPages * PAGE_SIZE, &mdlPriv->dmaHandle, gfp);
-#elif defined CONFIG_MIPS || defined CONFIG_CPU_CSKYV2 || defined CONFIG_PPC
- = dma_alloc_coherent(gcvNULL, NumPages * PAGE_SIZE, &mdlPriv->dmaHandle, gfp);
+#if defined CONFIG_MIPS || defined CONFIG_CPU_CSKYV2 || defined CONFIG_PPC || defined CONFIG_ARM64
+ = dma_alloc_coherent(galcore_device, NumPages * PAGE_SIZE, &mdlPriv->dmaHandle, gfp);
#else
- = dma_alloc_writecombine(gcvNULL, NumPages * PAGE_SIZE, &mdlPriv->dmaHandle, gfp);
+ = dma_alloc_writecombine(galcore_device, NumPages * PAGE_SIZE, &mdlPriv->dmaHandle, gfp);
#endif
#ifdef CONFLICT_BETWEEN_BASE_AND_PHYS
@@ -299,12 +282,10 @@ _DmaFree(
struct mdl_dma_priv *mdlPriv=(struct mdl_dma_priv *)Mdl->priv;
gcsDMA_PRIV_PTR allocatorPriv = (gcsDMA_PRIV_PTR)Allocator->privateData;
-#if defined CONFIG_ARM64
- dma_free_coherent(_GetDevice(os), Mdl->numPages * PAGE_SIZE, mdlPriv->kvaddr, mdlPriv->dmaHandle);
-#elif defined CONFIG_MIPS || defined CONFIG_CPU_CSKYV2 || defined CONFIG_PPC
- dma_free_coherent(gcvNULL, Mdl->numPages * PAGE_SIZE, mdlPriv->kvaddr, mdlPriv->dmaHandle);
+#if defined CONFIG_MIPS || defined CONFIG_CPU_CSKYV2 || defined CONFIG_PPC || defined CONFIG_ARM64
+ dma_free_coherent(galcore_device, Mdl->numPages * PAGE_SIZE, mdlPriv->kvaddr, mdlPriv->dmaHandle);
#else
- dma_free_writecombine(gcvNULL, Mdl->numPages * PAGE_SIZE, mdlPriv->kvaddr, mdlPriv->dmaHandle);
+ dma_free_writecombine(galcore_device, Mdl->numPages * PAGE_SIZE, mdlPriv->kvaddr, mdlPriv->dmaHandle);
#endif
gckOS_Free(os, mdlPriv);
@@ -504,8 +485,8 @@ static gceSTATUS
_DmaCache(
IN gckALLOCATOR Allocator,
IN PLINUX_MDL Mdl,
+ IN gctSIZE_T Offset,
IN gctPOINTER Logical,
- IN gctUINT32 Physical,
IN gctUINT32 Bytes,
IN gceCACHEOPERATION Operation
)
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 5f0e7b44948b..6f37daf74778 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
@@ -244,10 +244,10 @@ _DmabufAttach(
npages += (sg_dma_len(s) + PAGE_SIZE - 1) / PAGE_SIZE;
}
- /* Allocate page arrary. */
+ /* Allocate page array. */
gcmkONERROR(gckOS_Allocate(os, npages * gcmSIZEOF(*pagearray), (gctPOINTER *)&pagearray));
- /* Fill page arrary. */
+ /* Fill page array. */
for_each_sg(sgt->sgl, s, sgt->orig_nents, i)
{
for (j = 0; j < (sg_dma_len(s) + PAGE_SIZE - 1) / PAGE_SIZE; j++)
@@ -277,8 +277,7 @@ _DmabufAttach(
Mdl->priv = buf_desc;
- /* Need set it as true to avoid MMU mapping. */
- Mdl->contiguous = gcvTRUE;
+ Mdl->contiguous = (sgt->nents == 1) ? gcvTRUE : gcvFALSE;
gcmkFOOTER_NO();
return gcvSTATUS_OK;
@@ -417,8 +416,8 @@ static gceSTATUS
_DmabufCache(
IN gckALLOCATOR Allocator,
IN PLINUX_MDL Mdl,
+ IN gctSIZE_T Offset,
IN gctPOINTER Logical,
- IN gctUINT32 Physical,
IN gctUINT32 Bytes,
IN gceCACHEOPERATION Operation
)
@@ -434,8 +433,10 @@ _DmabufCache(
dma_sync_sg_for_device(galcore_device, sgt->sgl, sgt->nents, dir);
break;
case gcvCACHE_FLUSH:
- dir = DMA_BIDIRECTIONAL;
+ dir = DMA_TO_DEVICE;
dma_sync_sg_for_device(galcore_device, sgt->sgl, sgt->nents, dir);
+ dir = DMA_FROM_DEVICE;
+ dma_sync_sg_for_cpu(galcore_device, sgt->sgl, sgt->nents, dir);
break;
case gcvCACHE_INVALIDATE:
dir = DMA_FROM_DEVICE;
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 71a867c9302c..356456eaec4d 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
@@ -370,7 +370,7 @@ _GFPAlloc(
mdlPriv->dma_addr = dma_map_page(galcore_device,
mdlPriv->contiguousPages, 0, NumPages * PAGE_SIZE,
- DMA_TO_DEVICE);
+ DMA_FROM_DEVICE);
if (!mdlPriv->dma_addr)
{
@@ -427,7 +427,7 @@ _GFPAlloc(
}
result = dma_map_sg(galcore_device,
- mdlPriv->sgt.sgl, mdlPriv->sgt.nents, DMA_TO_DEVICE);
+ mdlPriv->sgt.sgl, mdlPriv->sgt.nents, DMA_FROM_DEVICE);
if (result != mdlPriv->sgt.nents)
{
@@ -680,7 +680,12 @@ _GFPMmap(
if (Cacheable == gcvFALSE)
{
+ /* Make this mapping non-cached. */
+#if gcdENABLE_BUFFERABLE_VIDEO_MEMORY
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+#else
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+#endif
}
if (platform && platform->ops->adjustProt)
@@ -883,24 +888,9 @@ _GFPMapKernel(
gctINT numPages = Mdl->numPages;
struct gfp_mdl_priv *mdlPriv = Mdl->priv;
-#if gcdNONPAGED_MEMORY_CACHEABLE
- if (Mdl->contiguous)
- {
- addr = page_address(mdlPriv->contiguousPages);
- }
- else
- {
- addr = vmap(mdlPriv->nonContiguousPages,
- numPages,
- 0,
- PAGE_KERNEL);
-
- /* Trigger a page fault. */
- memset(addr, 0, numPages * PAGE_SIZE);
- }
-#else
struct page ** pages;
gctBOOL free = gcvFALSE;
+ pgprot_t pgprot;
gctINT i;
if (Mdl->contiguous)
@@ -924,19 +914,26 @@ _GFPMapKernel(
pages = mdlPriv->nonContiguousPages;
}
- addr = vmap(pages, numPages, 0, pgprot_writecombine(PAGE_KERNEL));
-
- /* Trigger a page fault. */
- for (i = 0; i < numPages; i++)
+ /* ioremap() can't work on system memory since 2.6.38. */
+ if (Mdl->cacheable)
{
- *(gctINT *)(addr + PAGE_SIZE * i) = 0;
+ pgprot = PAGE_KERNEL;
}
+ else
+ {
+#if gcdENABLE_BUFFERABLE_VIDEO_MEMORY
+ pgprot = pgprot_writecombine(PAGE_KERNEL);
+#else
+ pgprot = pgprot_noncached(PAGE_KERNEL);
+#endif
+ }
+
+ addr = vmap(pages, numPages, 0, pgprot);
if (free)
{
kfree(pages);
}
-#endif
if (addr)
{
@@ -956,10 +953,7 @@ _GFPUnmapKernel(
IN gctPOINTER Logical
)
{
-
-#if !gcdNONPAGED_MEMORY_CACHEABLE
vunmap(Logical);
-#endif
return gcvSTATUS_OK;
}
@@ -968,8 +962,8 @@ static gceSTATUS
_GFPCache(
IN gckALLOCATOR Allocator,
IN PLINUX_MDL Mdl,
+ IN gctSIZE_T Offset,
IN gctPOINTER Logical,
- IN gctUINT32 Physical,
IN gctUINT32 Bytes,
IN gceCACHEOPERATION Operation
)
@@ -995,7 +989,7 @@ _GFPCache(
break;
case gcvCACHE_FLUSH:
- dir = DMA_BIDIRECTIONAL;
+ dir = DMA_TO_DEVICE;
if (mdlPriv->contiguous)
{
@@ -1008,6 +1002,19 @@ _GFPCache(
mdlPriv->sgt.sgl, mdlPriv->sgt.nents, dir);
}
+ dir = DMA_FROM_DEVICE;
+
+ if (mdlPriv->contiguous)
+ {
+ dma_sync_single_for_cpu(galcore_device,
+ mdlPriv->dma_addr, Mdl->numPages << PAGE_SHIFT, dir);
+ }
+ else
+ {
+ dma_sync_sg_for_cpu(galcore_device,
+ mdlPriv->sgt.sgl, mdlPriv->sgt.nents, dir);
+ }
+
break;
case gcvCACHE_INVALIDATE:
dir = DMA_FROM_DEVICE;
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 a39042fa5462..0b35e3dbac6d 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
@@ -399,8 +399,8 @@ static gceSTATUS
reserved_mem_cache_op(
IN gckALLOCATOR Allocator,
IN PLINUX_MDL Mdl,
+ IN gctSIZE_T Offset,
IN gctPOINTER Logical,
- IN gctUINT32 Physical,
IN gctUINT32 Bytes,
IN gceCACHEOPERATION Operation
)
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_user_memory.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_user_memory.c
index 7d4c378a1025..5759effdadeb 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_user_memory.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_user_memory.c
@@ -709,8 +709,8 @@ static gceSTATUS
_UserMemoryCache(
IN gckALLOCATOR Allocator,
IN PLINUX_MDL Mdl,
+ IN gctSIZE_T Offset,
IN gctPOINTER Logical,
- IN gctUINT32 Physical,
IN gctUINT32 Bytes,
IN gceCACHEOPERATION Operation
)
@@ -737,8 +737,10 @@ _UserMemoryCache(
dma_sync_sg_for_device(galcore_device, um->sgt.sgl, um->sgt.nents, dir);
break;
case gcvCACHE_FLUSH:
- dir = DMA_BIDIRECTIONAL;
+ dir = DMA_TO_DEVICE;
dma_sync_sg_for_device(galcore_device, um->sgt.sgl, um->sgt.nents, dir);
+ dir = DMA_FROM_DEVICE;
+ dma_sync_sg_for_cpu(galcore_device, um->sgt.sgl, um->sgt.nents, dir);
break;
case gcvCACHE_INVALIDATE:
dir = DMA_FROM_DEVICE;
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 f0a3d166f1a5..c6a28bbb31d9 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
@@ -472,8 +472,8 @@ static gceSTATUS
_CMACache(
IN gckALLOCATOR Allocator,
IN PLINUX_MDL Mdl,
+ IN gctSIZE_T Offset,
IN gctPOINTER Logical,
- IN gctUINT32 Physical,
IN gctUINT32 Bytes,
IN gceCACHEOPERATION Operation
)
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.h
index 81801c747e1a..4d103f1e24cc 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.h
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.h
@@ -285,12 +285,12 @@ typedef struct _gcsALLOCATOR_OPERATIONS
** PLINUX_MDL Mdl
** Pointer to a Mdl object.
**
+ ** gctSIZE_T Offset
+ ** Offset to this memory block
+ **
** gctPOINTER Logical
** Logical address, could be user address or kernel address
**
- ** gctUINT32_PTR Physical
- ** Physical address.
- **
** gctUINT32 Bytes
** Size of memory region.
**
@@ -305,8 +305,8 @@ typedef struct _gcsALLOCATOR_OPERATIONS
gceSTATUS (*Cache)(
IN gckALLOCATOR Allocator,
IN PLINUX_MDL Mdl,
+ IN gctSIZE_T Offset,
IN gctPOINTER Logical,
- IN gctUINT32 Physical,
IN gctUINT32 Bytes,
IN gceCACHEOPERATION Operation
);
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h
index a3428a1667b8..ee80046bffd6 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h
@@ -61,6 +61,10 @@
#include <linux/time.h>
#include <stdarg.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)
+#include <linux/nmi.h>
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
index 8f8657f4c81e..d0a930a12ed6 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
@@ -697,6 +697,7 @@ static int gc_clk_show(struct seq_file* m, void* data)
gcsINFO_NODE *node = m->private;
gckGALDEVICE device = node->device;
gctUINT i;
+ gceSTATUS status;
for (i = gcvCORE_MAJOR; i < gcvCORE_COUNT; i++)
{
@@ -710,7 +711,13 @@ static int gc_clk_show(struct seq_file* m, void* data)
continue;
}
#endif
- gckHARDWARE_QueryFrequency(hardware);
+
+ status = gckHARDWARE_QueryFrequency(hardware);
+ if (gcmIS_ERROR(status))
+ {
+ seq_printf(m, "query gpu%d clock fail.\n", i);
+ continue;
+ }
if (hardware->mcClk)
{
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
index f059fe34fe2b..87f26e721773 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
@@ -903,7 +903,11 @@ static int gpu_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
#endif /* USE_LINUX_PCIE */
{
int ret = -ENODEV;
- static u64 dma_mask = ~0ULL;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
+ static u64 dma_mask = DMA_BIT_MASK(40);
+#else
+ static u64 dma_mask = DMA_40BIT_MASK;
+#endif
gcsMODULE_PARAMETERS moduleParam = {
.irqLine = irqLine,
@@ -944,14 +948,12 @@ static int gpu_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
platform->device = pdev;
galcore_device = &pdev->dev;
- galcore_device->dma_mask = &dma_mask;
-
#if USE_LINUX_PCIE
if (pci_enable_device(pdev)) {
printk(KERN_ERR "galcore: pci_enable_device() failed.\n");
}
- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+ if (pci_set_dma_mask(pdev, dma_mask)) {
printk(KERN_ERR "galcore: Failed to set DMA mask.\n");
}
@@ -965,7 +967,9 @@ static int gpu_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (pci_enable_msi(pdev)) {
printk(KERN_ERR "galcore: Failed to enable MSI.\n");
}
-#endif
+# endif
+#else
+ galcore_device->dma_mask = &dma_mask;
#endif
if (platform->ops->getPower)
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 bfb76ac6b1a3..1fd340158dcc 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
@@ -557,12 +557,11 @@ static int viv_ioctl_gem_attach_aux(struct drm_device *drm, void *data,
if (args->ts_handle)
{
struct viv_gem_object *viv_ts_obj;
- size_t num = 0;
gckKERNEL kernel = gal_dev->device->map[gal_dev->device->defaultHwType].kernels[0];
gcsHAL_INTERFACE iface;
gctBOOL is2BitPerTile = gckHARDWARE_IsFeatureAvailable(kernel->hardware , gcvFEATURE_TILE_STATUS_2BITS);
gctBOOL isCompressionDEC400 = gckHARDWARE_IsFeatureAvailable(kernel->hardware , gcvFEATURE_COMPRESSION_DEC400);
- char __user* entry = gcvNULL;
+ gctPOINTER entry = gcvNULL;
gctUINT32 tileStatusFiller = (isCompressionDEC400 || ((kernel->hardware->identity.chipModel == gcv500) && (kernel->hardware->identity.chipRevision > 2)))
? 0xFFFFFFFF
: is2BitPerTile ? 0x55555555 : 0x11111111;
@@ -587,10 +586,9 @@ static int viv_ioctl_gem_attach_aux(struct drm_device *drm, void *data,
gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface));
/* Fill tile status node with tileStatusFiller. */
- entry = (char __user*)(uintptr_t)iface.u.LockVideoMemory.memory;
- for (num=0; num<gem_ts_obj->size; num++) {
- put_user(tileStatusFiller, entry+num);
- }
+ gcmkONERROR(gckVIDMEM_NODE_LockCPU(kernel, viv_ts_obj->node_handle, &entry));
+ memset(entry , tileStatusFiller , (__u64)gem_ts_obj->size);
+ gcmkONERROR(gckVIDMEM_NODE_UnlockCPU(kernel, viv_ts_obj->node_handle, entry));
/* UnLock tile status node. */
memset(&iface, 0, sizeof(iface));
@@ -750,7 +748,7 @@ OnError:
void viv_drm_postclose(struct drm_device *drm, struct drm_file *file)
{
gctINT i;
- gctUINT32 pid = gcmPTR2INT(file->driver_priv);
+ gctUINT32 pid = gcmPTR2SIZE(file->driver_priv);
gckGALDEVICE gal_dev = (gckGALDEVICE)drm->dev_private;
for (i = 0; i < gcdMAX_GPU_COUNT; ++i)
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
index 5d82642aed5a..c536e44d6755 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
@@ -118,14 +118,6 @@
/* Protection bit when mapping memroy to user sapce */
#define gcmkPAGED_MEMROY_PROT(x) pgprot_writecombine(x)
-#if gcdNONPAGED_MEMORY_BUFFERABLE
-#define gcmkIOREMAP ioremap_wc
-#define gcmkNONPAGED_MEMROY_PROT(x) pgprot_writecombine(x)
-#elif !gcdNONPAGED_MEMORY_CACHEABLE
-#define gcmkIOREMAP ioremap_nocache
-#define gcmkNONPAGED_MEMROY_PROT(x) pgprot_noncached(x)
-#endif
-
#define gcdSUPPRESS_OOM_MESSAGE 1
#if gcdSUPPRESS_OOM_MESSAGE
@@ -225,6 +217,9 @@ struct _gckOS
/* Signal management. */
+ /* Lock. */
+ spinlock_t signalLock;
+
/* signal id database. */
gcsINTEGER_DB signalDB;
@@ -271,7 +266,7 @@ typedef struct _gcsSIGNAL
gctBOOL manualReset;
/* The reference counter. */
- volatile int ref;
+ atomic_t ref;
/* The owner of the signal. */
gctHANDLE process;
@@ -279,8 +274,8 @@ typedef struct _gcsSIGNAL
/* ID. */
gctUINT32 id;
-#if gcdANDROID_NATIVE_FENCE_SYNC
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)
+#if gcdLINUX_SYNC_FILE
+#ifndef CONFIG_SYNC_FILE
/* Parent timeline. */
struct sync_timeline * timeline;
# else
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
index cb52a3b60362..36b1a2fd3409 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
@@ -73,7 +73,7 @@
#include <linux/anon_inodes.h>
#endif
-#if gcdANDROID_NATIVE_FENCE_SYNC
+#if gcdLINUX_SYNC_FILE
# include <linux/file.h>
# include "gc_hal_kernel_sync.h"
#endif
@@ -276,12 +276,11 @@ _AllocateIntegerId(
{
int result;
gctINT next;
- unsigned long flags;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
idr_preload(GFP_KERNEL | gcdNOWARN);
- spin_lock_irqsave(&Database->lock, flags);
+ spin_lock(&Database->lock);
next = (Database->curr + 1 <= 0) ? 1 : Database->curr + 1;
@@ -295,7 +294,7 @@ _AllocateIntegerId(
Database->curr = *Id = result;
}
- spin_unlock_irqrestore(&Database->lock, flags);
+ spin_unlock(&Database->lock);
idr_preload_end();
@@ -310,7 +309,7 @@ again:
return gcvSTATUS_OUT_OF_MEMORY;
}
- spin_lock_irqsave(&Database->lock, flags);
+ spin_lock(&Database->lock);
next = (Database->curr + 1 <= 0) ? 1 : Database->curr + 1;
@@ -322,7 +321,7 @@ again:
Database->curr = *Id;
}
- spin_unlock_irqstore(&Database->lock, flags);
+ spin_unlock(&Database->lock);
if (result == -EAGAIN)
{
@@ -347,7 +346,12 @@ _QueryIntegerId(
{
gctPOINTER pointer;
+ spin_lock(&Database->lock);
+
pointer = idr_find(&Database->idr, Id);
+
+ spin_unlock(&Database->lock);
+
if (pointer)
{
*KernelPointer = pointer;
@@ -370,8 +374,12 @@ _DestroyIntegerId(
IN gctUINT32 Id
)
{
+ spin_lock(&Database->lock);
+
idr_remove(&Database->idr, Id);
+ spin_unlock(&Database->lock);
+
return gcvSTATUS_OK;
}
@@ -541,6 +549,9 @@ gckOS_Construct(
* Initialize the signal manager.
*/
+ /* Initialize spinlock. */
+ spin_lock_init(&os->signalLock);
+
/* Initialize signal id database lock. */
spin_lock_init(&os->signalDB.lock);
@@ -675,6 +686,62 @@ gckOS_Destroy(
}
gceSTATUS
+gckOS_CreateKernelMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctSIZE_T Offset,
+ IN gctSIZE_T Bytes,
+ OUT gctPOINTER * Logical
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+ PLINUX_MDL mdl = (PLINUX_MDL)Physical;
+ gckALLOCATOR allocator = mdl->allocator;
+
+ gcmkHEADER_ARG("Os=%p Physical=%p Offset=0x%zx Bytes=0x%zx",
+ Os, Physical, Offset, Bytes);
+
+ if (mdl->addr)
+ {
+ /* Already mapped whole memory. */
+ *Logical = (gctUINT8_PTR)mdl->addr + Offset;
+ }
+ else
+ {
+ gcmkONERROR(allocator->ops->MapKernel(allocator, mdl, Logical));
+ }
+
+OnError:
+ gcmkFOOTER_ARG("*Logical=%p", gcmOPT_POINTER(Logical));
+ return status;
+}
+
+gceSTATUS
+gckOS_DestroyKernelMapping(
+ IN gckOS Os,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical
+ )
+{
+ PLINUX_MDL mdl = (PLINUX_MDL)Physical;
+ gckALLOCATOR allocator = mdl->allocator;
+
+ gcmkHEADER_ARG("Os=%p Physical=%p Logical=%p", Os, Physical, Logical);
+
+ if (mdl->addr)
+ {
+ /* Nothing to do. */
+ }
+ else
+ {
+ allocator->ops->UnmapKernel(allocator, mdl, Logical);
+ }
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
gckOS_CreateKernelVirtualMapping(
IN gckOS Os,
IN gctPHYS_ADDR Physical,
@@ -1323,6 +1390,8 @@ gckOS_AllocateNonPagedMemory(
/* Check status. */
gcmkONERROR(status);
+ mdl->cacheable = Flag & gcvALLOC_FLAG_CACHEABLE;
+
mdl->bytes = bytes;
mdl->numPages = numPages;
@@ -1330,6 +1399,12 @@ gckOS_AllocateNonPagedMemory(
gcmkONERROR(allocator->ops->MapKernel(allocator, mdl, &addr));
+ if (!strcmp(allocator->name, "gfp"))
+ {
+ /* Trigger a page fault. */
+ memset(addr, 0, numPages * PAGE_SIZE);
+ }
+
mdl->addr = addr;
if (InUserSpace)
@@ -2126,6 +2201,7 @@ gckOS_MapPhysical(
{
if ((physical >= mdl->dmaHandle)
&& (physical < mdl->dmaHandle + mdl->bytes)
+ && (mdl->addr != 0)
)
{
*Logical = mdl->addr + (physical - mdl->dmaHandle);
@@ -2148,6 +2224,7 @@ gckOS_MapPhysical(
struct page * page;
gctUINT numPages;
gctINT i;
+ pgprot_t pgprot;
numPages = GetPageCount(PAGE_ALIGN(offset + Bytes), 0);
@@ -2166,7 +2243,13 @@ gckOS_MapPhysical(
pages[i] = nth_page(page, i);
}
- logical = vmap(pages, numPages, 0, gcmkNONPAGED_MEMROY_PROT(PAGE_KERNEL));
+#if gcdENABLE_BUFFERABLE_VIDEO_MEMORY
+ pgprot = pgprot_writecombine(PAGE_KERNEL);
+#else
+ pgprot = pgprot_noncached(PAGE_KERNEL);
+#endif
+
+ logical = vmap(pages, numPages, 0, pgprot);
kfree(pages);
@@ -3102,6 +3185,7 @@ gckOS_AllocatePagedMemoryEx(
mdl->bytes = bytes;
mdl->numPages = numPages;
mdl->contiguous = Flag & gcvALLOC_FLAG_CONTIGUOUS;
+ mdl->cacheable = Flag & gcvALLOC_FLAG_CACHEABLE;
if (Gid != gcvNULL)
{
@@ -3336,17 +3420,14 @@ gckOS_MapPagesEx(
PLINUX_MDL mdl;
gctUINT32* table;
gctUINT32 offset = 0;
-#if gcdNONPAGED_MEMORY_CACHEABLE
- gckMMU mmu;
- PLINUX_MDL mmuMdl;
- gctUINT32 bytes;
- gctPHYS_ADDR pageTablePhysical;
-#endif
#if gcdPROCESS_ADDRESS_SPACE
gckKERNEL kernel = Os->device->kernels[Core];
gckMMU mmu;
#endif
+
+ gctUINT32 bytes = PageCount * 4;
+
gckALLOCATOR allocator;
gctUINT32 policyID = 0;
@@ -3383,11 +3464,6 @@ gckOS_MapPagesEx(
#endif
table = (gctUINT32 *)PageTable;
-#if gcdNONPAGED_MEMORY_CACHEABLE
- mmu = Os->device->kernels[Core]->mmu;
- bytes = PageCount * sizeof(*table);
- mmuMdl = (PLINUX_MDL)mmu->pageTablePhysical;
-#endif
if (platform && platform->ops->getPolicyID)
{
@@ -3483,21 +3559,56 @@ gckOS_MapPagesEx(
offset += PAGE_SIZE;
}
-#if gcdNONPAGED_MEMORY_CACHEABLE
- /* Get physical address of pageTable */
- pageTablePhysical = (gctPHYS_ADDR)(mmuMdl->dmaHandle +
- ((gctUINT32 *)PageTable - mmu->pageTableLogical));
+#if gcdENABLE_VG
+ if (Core == gcvCORE_VG)
+ {
+ gckVGMMU mmu = Os->device->kernels[gcvCORE_VG]->vg->mmu;
+ gctPHYS_ADDR mmuMdl = mmu->pageTablePhysical;
- /* Flush the mmu page table cache. */
- gcmkONERROR(gckOS_CacheClean(
- Os,
- _GetProcessID(),
- gcvNULL,
- pageTablePhysical,
- PageTable,
- bytes
- ));
-#endif
+ offset = (gctUINT8_PTR)PageTable - (gctUINT8_PTR)mmu->pageTableLogical;
+
+ gcmkVERIFY_OK(gckOS_CacheClean(
+ Os,
+ _GetProcessID(),
+ mmuMdl,
+ offset,
+ PageTable,
+ bytes
+ ));
+ }
+ else
+# endif
+ {
+ gckMMU mmu = Os->device->kernels[Core]->mmu;
+ gcsADDRESS_AREA * area = &mmu->area[0];
+
+ offset = (gctUINT8_PTR)PageTable - (gctUINT8_PTR)area->pageTableLogical;
+
+ /* must be in dynamic area. */
+ gcmkASSERT(offset < area->pageTableSize);
+
+ gcmkVERIFY_OK(gckOS_CacheClean(
+ Os,
+ 0,
+ area->pageTablePhysical,
+ offset,
+ PageTable,
+ bytes
+ ));
+
+ if (mmu->mtlbPhysical)
+ {
+ /* Flush MTLB table. */
+ gcmkVERIFY_OK(gckOS_CacheClean(
+ Os,
+ 0,
+ mmu->mtlbPhysical,
+ 0,
+ mmu->mtlbLogical,
+ mmu->mtlbSize
+ ));
+ }
+ }
OnError:
@@ -4382,7 +4493,7 @@ _CacheOperation(
IN gckOS Os,
IN gctUINT32 ProcessID,
IN gctPHYS_ADDR Handle,
- IN gctPHYS_ADDR_T Physical,
+ IN gctSIZE_T Offset,
IN gctPOINTER Logical,
IN gctSIZE_T Bytes,
IN gceCACHEOPERATION Operation
@@ -4408,15 +4519,16 @@ _CacheOperation(
mutex_unlock(&mdl->mapsMutex);
- if (mdlMap == gcvNULL)
+ if (ProcessID && mdlMap == gcvNULL)
{
return gcvSTATUS_INVALID_ARGUMENT;
}
- if (mdlMap->cacheable)
+ if ((!ProcessID && mdl->cacheable) ||
+ (mdlMap && mdlMap->cacheable))
{
allocator->ops->Cache(allocator,
- mdl, Logical, Physical, Bytes, Operation);
+ mdl, Offset, Logical, Bytes, Operation);
return gcvSTATUS_OK;
}
@@ -4445,8 +4557,8 @@ _CacheOperation(
** gctPHYS_ADDR Handle
** Physical address handle. If gcvNULL it is video memory.
**
-** gctPOINTER Physical
-** Physical address to flush.
+** gctSIZE_T Offset
+** Offset to this memory block.
**
** gctPOINTER Logical
** Logical address to flush.
@@ -4480,7 +4592,7 @@ gckOS_CacheClean(
IN gckOS Os,
IN gctUINT32 ProcessID,
IN gctPHYS_ADDR Handle,
- IN gctPHYS_ADDR_T Physical,
+ IN gctSIZE_T Offset,
IN gctPOINTER Logical,
IN gctSIZE_T Bytes
)
@@ -4496,7 +4608,7 @@ gckOS_CacheClean(
gcmkVERIFY_ARGUMENT(Bytes > 0);
gcmkONERROR(_CacheOperation(Os, ProcessID,
- Handle, Physical, Logical, Bytes,
+ Handle, Offset, Logical, Bytes,
gcvCACHE_CLEAN));
OnError:
@@ -4523,6 +4635,9 @@ OnError:
** gctPHYS_ADDR Handle
** Physical address handle. If gcvNULL it is video memory.
**
+** gctSIZE_T Offset
+** Offset to this memory block.
+**
** gctPOINTER Logical
** Logical address to flush.
**
@@ -4534,15 +4649,15 @@ gckOS_CacheInvalidate(
IN gckOS Os,
IN gctUINT32 ProcessID,
IN gctPHYS_ADDR Handle,
- IN gctPHYS_ADDR_T Physical,
+ IN gctSIZE_T Offset,
IN gctPOINTER Logical,
IN gctSIZE_T Bytes
)
{
gceSTATUS status;
- gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=%p Bytes=%lu",
- Os, ProcessID, Handle, Logical, Bytes);
+ gcmkHEADER_ARG("Os=%p ProcessID=%d Handle=%p Offset=0x%llx Logical=%p Bytes=0x%zx",
+ Os, ProcessID, Handle, Offset, Logical, Bytes);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -4550,7 +4665,7 @@ gckOS_CacheInvalidate(
gcmkVERIFY_ARGUMENT(Bytes > 0);
gcmkONERROR(_CacheOperation(Os, ProcessID,
- Handle, Physical, Logical, Bytes,
+ Handle, Offset, Logical, Bytes,
gcvCACHE_INVALIDATE));
OnError:
@@ -4576,6 +4691,9 @@ OnError:
** gctPHYS_ADDR Handle
** Physical address handle. If gcvNULL it is video memory.
**
+** gctSIZE_T Offset
+** Offset to this memory block.
+**
** gctPOINTER Logical
** Logical address to flush.
**
@@ -4587,15 +4705,15 @@ gckOS_CacheFlush(
IN gckOS Os,
IN gctUINT32 ProcessID,
IN gctPHYS_ADDR Handle,
- IN gctPHYS_ADDR_T Physical,
+ IN gctSIZE_T Offset,
IN gctPOINTER Logical,
IN gctSIZE_T Bytes
)
{
gceSTATUS status;
- gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=%p Bytes=%lu",
- Os, ProcessID, Handle, Logical, Bytes);
+ gcmkHEADER_ARG("Os=%p ProcessID=%d Handle=%p Offset=0x%llx Logical=%p Bytes=0x%zx",
+ Os, ProcessID, Handle, Offset, Logical, Bytes);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -4603,7 +4721,7 @@ gckOS_CacheFlush(
gcmkVERIFY_ARGUMENT(Bytes > 0);
gcmkONERROR(_CacheOperation(Os, ProcessID,
- Handle, Physical, Logical, Bytes,
+ Handle, Offset, Logical, Bytes,
gcvCACHE_FLUSH));
OnError:
@@ -5520,10 +5638,11 @@ gckOS_CreateSignal(
init_waitqueue_head(&signal->wait);
spin_lock_init(&signal->lock);
signal->manualReset = ManualReset;
- signal->ref = 1;
-#if gcdANDROID_NATIVE_FENCE_SYNC
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)
+ atomic_set(&signal->ref, 1);
+
+#if gcdLINUX_SYNC_FILE
+#ifndef CONFIG_SYNC_FILE
signal->timeline = gcvNULL;
# else
signal->fence = gcvNULL;
@@ -5573,7 +5692,8 @@ gckOS_DestroySignal(
{
gceSTATUS status;
gcsSIGNAL_PTR signal;
- unsigned long flags;
+ gctBOOL acquired = gcvFALSE;
+ unsigned long flags = 0;
gcmkHEADER_ARG("Os=0x%X Signal=0x%X", Os, Signal);
@@ -5581,31 +5701,49 @@ gckOS_DestroySignal(
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
- spin_lock_irqsave(&Os->signalDB.lock, flags);
- status = _QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal);
- if (gcmIS_ERROR(status))
- {
- spin_unlock_irqrestore(&Os->signalDB.lock, flags);
- gcmkONERROR(status);
+ if(in_irq()){
+ spin_lock(&Os->signalLock);
+ }else{
+ spin_lock_irqsave(&Os->signalLock, flags);
}
+ acquired = gcvTRUE;
+
+ gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal);
- signal->ref--;
- if (signal->ref == 0)
+ if (atomic_dec_and_test(&signal->ref))
{
gcmkVERIFY_OK(_DestroyIntegerId(&Os->signalDB, signal->id));
/* Free the sgianl. */
kfree(signal);
}
- spin_unlock_irqrestore(&Os->signalDB.lock, flags);
+
+ if(in_irq()){
+ spin_unlock(&Os->signalLock);
+ }else{
+ spin_unlock_irqrestore(&Os->signalLock, flags);
+ }
+
+ acquired = gcvFALSE;
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
+ if (acquired)
+ {
+ /* Release the mutex. */
+ if(in_irq()){
+ spin_unlock(&Os->signalLock);
+ }else{
+ spin_unlock_irqrestore(&Os->signalLock, flags);
+ }
+
+ }
+
gcmkFOOTER();
return status;
}
@@ -5641,14 +5779,14 @@ gckOS_Signal(
{
gceSTATUS status;
gcsSIGNAL_PTR signal;
-#if gcdANDROID_NATIVE_FENCE_SYNC
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)
+#if gcdLINUX_SYNC_FILE
+#ifndef CONFIG_SYNC_FILE
struct sync_timeline * timeline = gcvNULL;
# else
struct dma_fence * fence = gcvNULL;
# endif
#endif
- unsigned long flags;
+ unsigned long flags = 0;
gcmkHEADER_ARG("Os=0x%X Signal=0x%X State=%d", Os, Signal, State);
@@ -5656,13 +5794,15 @@ gckOS_Signal(
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
- spin_lock_irqsave(&Os->signalDB.lock, flags);
+ spin_lock_irqsave(&Os->signalLock, flags);
+
status = _QueryIntegerId(&Os->signalDB,
(gctUINT32)(gctUINTPTR_T)Signal,
(gctPOINTER)&signal);
+
if (gcmIS_ERROR(status))
{
- spin_unlock_irqrestore(&Os->signalDB.lock, flags);
+ spin_unlock_irqrestore(&Os->signalLock, flags);
gcmkONERROR(status);
}
@@ -5671,10 +5811,13 @@ gckOS_Signal(
* concurrent issue: signaling the signal while another thread is destroying
* it.
*/
+ atomic_inc(&signal->ref);
+
+ spin_unlock_irqrestore(&Os->signalLock, flags);
+
+ gcmkONERROR(status);
gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal);
- signal->ref++;
- spin_unlock_irqrestore(&Os->signalDB.lock, flags);
spin_lock(&signal->lock);
@@ -5684,8 +5827,8 @@ gckOS_Signal(
wake_up(&signal->wait);
-#if gcdANDROID_NATIVE_FENCE_SYNC
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)
+#if gcdLINUX_SYNC_FILE
+#ifndef CONFIG_SYNC_FILE
timeline = signal->timeline;
# else
fence = signal->fence;
@@ -5700,8 +5843,8 @@ gckOS_Signal(
spin_unlock(&signal->lock);
-#if gcdANDROID_NATIVE_FENCE_SYNC
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)
+#if gcdLINUX_SYNC_FILE
+#ifndef CONFIG_SYNC_FILE
/* Signal timeline. */
if (timeline)
{
@@ -5716,17 +5859,17 @@ gckOS_Signal(
# endif
#endif
- spin_lock_irqsave(&Os->signalDB.lock, flags);
- signal->ref --;
+ spin_lock_irqsave(&Os->signalLock, flags);
- if (signal->ref == 0)
+ if (atomic_dec_and_test(&signal->ref))
{
gcmkVERIFY_OK(_DestroyIntegerId(&Os->signalDB, signal->id));
/* Free the sgianl. */
kfree(signal);
}
- spin_unlock_irqrestore(&Os->signalDB.lock, flags);
+
+ spin_unlock_irqrestore(&Os->signalLock, flags);
/* Success. */
gcmkFOOTER_NO();
@@ -5810,7 +5953,6 @@ gckOS_WaitSignal(
gceSTATUS status;
gcsSIGNAL_PTR signal = gcvNULL;
int done;
- unsigned long flags;
gcmkHEADER_ARG("Os=0x%X Signal=0x%X Wait=0x%08X", Os, Signal, Wait);
@@ -5818,11 +5960,7 @@ gckOS_WaitSignal(
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
- spin_lock_irqsave(&Os->signalDB.lock, flags);
- status = _QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal);
- spin_unlock_irqrestore(&Os->signalDB.lock, flags);
-
- gcmkONERROR(status);
+ gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal);
@@ -5909,13 +6047,10 @@ _QuerySignal(
*/
gceSTATUS status;
gcsSIGNAL_PTR signal = gcvNULL;
- unsigned long flags;
- spin_lock_irqsave(&Os->signalDB.lock, flags);
status = _QueryIntegerId(&Os->signalDB,
(gctUINT32)(gctUINTPTR_T)Signal,
(gctPOINTER)&signal);
- spin_unlock_irqrestore(&Os->signalDB.lock, flags);
if (gcmIS_SUCCESS(status))
{
@@ -5959,37 +6094,33 @@ gckOS_MapSignal(
{
gceSTATUS status;
gcsSIGNAL_PTR signal = gcvNULL;
- unsigned long flags;
+ unsigned long flags = 0;
gcmkHEADER_ARG("Os=0x%X Signal=0x%X Process=0x%X", Os, Signal, Process);
gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
gcmkVERIFY_ARGUMENT(MappedSignal != gcvNULL);
- spin_lock_irqsave(&Os->signalDB.lock, flags);
- status = _QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal);
- if (gcmIS_ERROR(status))
- {
- spin_unlock_irqrestore(&Os->signalDB.lock, flags);
- gcmkONERROR(status);
- }
+ spin_lock_irqsave(&Os->signalLock, flags);
- signal->ref++;
+ gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
- if (signal->ref <= 1)
+ if (atomic_inc_return(&signal->ref) <= 1)
{
- spin_unlock_irqrestore(&Os->signalDB.lock, flags);
/* The previous value is 0, it has been deleted. */
gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
}
*MappedSignal = (gctSIGNAL) Signal;
- spin_unlock_irqrestore(&Os->signalDB.lock, flags);
+
+ spin_unlock_irqrestore(&Os->signalLock, flags);
/* Success. */
gcmkFOOTER_ARG("*MappedSignal=0x%X", *MappedSignal);
return gcvSTATUS_OK;
OnError:
+ spin_unlock_irqrestore(&Os->signalLock, flags);
+
gcmkFOOTER_NO();
return status;
}
@@ -6625,8 +6756,8 @@ gckOS_DetectProcessByName(
: gcvSTATUS_FALSE;
}
-#if gcdANDROID_NATIVE_FENCE_SYNC
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)
+#if gcdLINUX_SYNC_FILE
+#ifndef CONFIG_SYNC_FILE
gceSTATUS
gckOS_CreateSyncTimeline(
IN gckOS Os,
@@ -6683,21 +6814,14 @@ gckOS_CreateNativeFence(
char name[32];
gcsSIGNAL_PTR signal;
gceSTATUS status;
- unsigned long flags;
gcmkHEADER_ARG("Os=0x%X Timeline=0x%X Signal=%d",
Os, Timeline, (gctUINT)(gctUINTPTR_T)Signal);
- spin_lock_irqsave(&Os->signalDB.lock, flags);
- status = _QueryIntegerId(&Os->signalDB,
+ gcmkONERROR(
+ _QueryIntegerId(&Os->signalDB,
(gctUINT32)(gctUINTPTR_T)Signal,
- (gctPOINTER)&signal);
- if (gcmIS_ERROR(status))
- {
- spin_unlock_irqrestore(&Os->signalDB.lock, flags);
- gcmkONERROR(status);
- }
- spin_unlock_irqrestore(&Os->signalDB.lock, flags);
+ (gctPOINTER)&signal));
/* Cast timeline. */
timeline = (struct viv_sync_timeline *) Timeline;
@@ -6907,7 +7031,7 @@ OnError:
return status;
}
-# else /* v4.9.0 */
+# else /* !CONFIG_SYNC_FILE */
gceSTATUS
gckOS_CreateSyncTimeline(
@@ -6962,29 +7086,14 @@ gckOS_CreateNativeFence(
struct viv_sync_timeline *timeline;
gcsSIGNAL_PTR signal = gcvNULL;
gceSTATUS status = gcvSTATUS_OK;
- unsigned long flags;
/* Create fence. */
timeline = (struct viv_sync_timeline *) Timeline;
- spin_lock_irqsave(&Os->signalDB.lock, flags);
- status = _QueryIntegerId(&Os->signalDB,
+ gcmkONERROR(
+ _QueryIntegerId(&Os->signalDB,
(gctUINT32)(gctUINTPTR_T)Signal,
- (gctPOINTER)&signal);
- if (gcmIS_ERROR(status))
- {
- spin_unlock_irqrestore(&Os->signalDB.lock, flags);
- gcmkONERROR(status);
- }
-
- signal->ref++;
- if (signal->ref <= 1)
- {
- spin_unlock_irqrestore(&Os->signalDB.lock, flags);
- /* The previous value is 0, it has been deleted. */
- gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
- }
- spin_unlock_irqrestore(&Os->signalDB.lock, flags);
+ (gctPOINTER)&signal));
fence = viv_fence_create(timeline, signal);
@@ -7020,10 +7129,12 @@ OnError:
fput(sync->file);
}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,9,68)
if (fence)
{
dma_fence_put(fence);
}
+#endif
if (fd > 0)
{
@@ -7034,6 +7145,24 @@ OnError:
return status;
}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)
+/**
+ * sync_file_fdget() - get a sync_file from an fd
+ * @fd: fd referencing a fence
+ *
+ * Ensures @fd references a valid sync_file, increments the refcount of the
+ * backing file. Returns the sync_file or NULL in case of error.
+ */
+static struct sync_file *sync_file_fdget(int fd)
+{
+ struct file *file = fget(fd);
+
+ if (!file)
+ return NULL;
+
+ return file->private_data;
+}
+
gceSTATUS
gckOS_WaitNativeFence(
IN gckOS Os,
@@ -7045,8 +7174,77 @@ gckOS_WaitNativeFence(
struct viv_sync_timeline *timeline;
gceSTATUS status = gcvSTATUS_OK;
unsigned int i;
+ unsigned long timeout;
unsigned int numFences;
+ struct sync_file *sync_file;
+
+ timeline = (struct viv_sync_timeline *) Timeline;
+
+ sync_file = sync_file_fdget(FenceFD);
+
+ if (!sync_file)
+ {
+ gcmkONERROR(gcvSTATUS_GENERIC_IO);
+ }
+
+ numFences = sync_file->num_fences;
+
+ timeout = msecs_to_jiffies(Timeout);
+
+ for (i = 0; i < numFences; i++)
+ {
+ struct fence *f = sync_file->cbs[i].fence;
+ fence_get(f);
+
+ if (f->context != timeline->context &&
+ !fence_is_signaled(f))
+ {
+ signed long ret;
+ ret = fence_wait_timeout(f, 1, timeout);
+
+ if (ret == -ERESTARTSYS)
+ {
+ status = gcvSTATUS_INTERRUPTED;
+ fence_put(f);
+ break;
+ }
+ else if (ret <= 0)
+ {
+ status = gcvSTATUS_TIMEOUT;
+ fence_put(f);
+ break;
+ }
+ else
+ {
+ /* wait success. */
+ timeout -= ret;
+ }
+ }
+
+ fence_put(f);
+ }
+
+ return gcvSTATUS_OK;
+
+OnError:
+ return status;
+}
+
+# else
+
+gceSTATUS
+gckOS_WaitNativeFence(
+ IN gckOS Os,
+ IN gctHANDLE Timeline,
+ IN gctINT FenceFD,
+ IN gctUINT32 Timeout
+ )
+{
+ struct viv_sync_timeline *timeline;
+ gceSTATUS status = gcvSTATUS_OK;
+ unsigned int i;
unsigned long timeout;
+ unsigned int numFences;
struct dma_fence *fence;
struct dma_fence **fences;
@@ -7109,7 +7307,8 @@ OnError:
return status;
}
-# endif /* v4.9.0 */
+# endif
+# endif
#endif
#if gcdSECURITY
@@ -7365,6 +7564,11 @@ gckOS_QueryOption(
*Value = device->args.gpuProfiler;
return gcvSTATUS_OK;
}
+ else if (!strcmp(Option, "platformFlagBits"))
+ {
+ *Value = device->platform->flagBits;
+ return gcvSTATUS_OK;
+ }
return gcvSTATUS_NOT_SUPPORTED;
}
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h
index 3cea45f3ca26..6f63109903e1 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h
@@ -89,6 +89,8 @@ struct _LINUX_MDL
gctBOOL contiguous;
dma_addr_t dmaHandle;
+ gctBOOL cacheable;
+
struct mutex mapsMutex;
struct list_head mapsHead;
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h
index f83354d47735..b570195cf044 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h
@@ -281,12 +281,6 @@ typedef struct soc_platform_ops
}
gcsPLATFORM_OPERATIONS;
-enum
-{
- /* GPU can't issue more that 32bit physical address */
- gcvPLATFORM_FLAG_LIMIT_4G_ADDRESS = 1 << 0,
-};
-
struct soc_platform
{
#if USE_LINUX_PCIE
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c
index 3b5a2913a922..b366a2fb71fa 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c
@@ -56,7 +56,7 @@
#include <gc_hal.h>
#include <gc_hal_base.h>
-#if gcdANDROID_NATIVE_FENCE_SYNC
+#if gcdLINUX_SYNC_FILE
#include <linux/kernel.h>
#include <linux/file.h>
@@ -70,7 +70,7 @@
#include "gc_hal_kernel_sync.h"
#include "gc_hal_kernel_linux.h"
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)
+#ifndef CONFIG_SYNC_FILE
static struct sync_pt * viv_sync_pt_dup(struct sync_pt *sync_pt)
{
@@ -224,7 +224,7 @@ struct sync_pt * viv_sync_pt_create(struct viv_sync_timeline *obj,
return (struct sync_pt *)pt;
}
-#else /* v4.9.0 */
+#else
struct viv_sync_timeline * viv_sync_timeline_create(const char *name, gckOS Os)
{
@@ -308,6 +308,7 @@ static struct dma_fence_ops viv_fence_ops =
struct dma_fence * viv_fence_create(struct viv_sync_timeline *timeline,
gcsSIGNAL *signal)
{
+ gceSTATUS status;
struct viv_fence *fence;
struct dma_fence *old_fence = NULL;
unsigned seqno;
@@ -317,9 +318,17 @@ struct dma_fence * viv_fence_create(struct viv_sync_timeline *timeline,
if (!fence)
return NULL;
+ /* Reference signal in fence. */
+ status = gckOS_MapSignal(timeline->os, (gctSIGNAL)(uintptr_t)signal->id,
+ NULL, &fence->signal);
+
+ if (gcmIS_ERROR(status)) {
+ kfree(fence);
+ return NULL;
+ }
+
spin_lock_init(&fence->lock);
- fence->signal = (gctSIGNAL)(uintptr_t)signal->id;
fence->parent = timeline;
seqno = (unsigned)atomic64_inc_return(&timeline->seqno);
@@ -340,6 +349,10 @@ struct dma_fence * viv_fence_create(struct viv_sync_timeline *timeline,
if (!signal->done) {
signal->fence = (struct dma_fence*)fence;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,9,68)
+ dma_fence_get((struct dma_fence*)fence);
+#endif
}
spin_unlock(&signal->lock);
@@ -360,6 +373,6 @@ struct dma_fence * viv_fence_create(struct viv_sync_timeline *timeline,
return (struct dma_fence*)fence;
}
-#endif /* v4.9.0 */
+#endif
#endif
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h
index 695ccfff7918..d723e469a470 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h
@@ -58,7 +58,7 @@
#include <linux/types.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)
+#ifndef CONFIG_SYNC_FILE
/* sync.h is in drivers/staging/android/ for now. */
#include <sync.h>
@@ -98,7 +98,7 @@ struct viv_sync_timeline * viv_sync_timeline_create(const char *name, gckOS Os);
struct sync_pt * viv_sync_pt_create(struct viv_sync_timeline *obj,
gctSIGNAL signal);
-#else /* v4.9.0 */
+#else
#include <linux/sync_file.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)
@@ -146,6 +146,6 @@ void viv_sync_timeline_destroy(struct viv_sync_timeline *timeline);
struct dma_fence * viv_fence_create(struct viv_sync_timeline *timeline,
gcsSIGNAL *signal);
-#endif /* v4.9.0 */
+#endif
#endif /* __gc_hal_kernel_sync_h_ */
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.c
index 0349c95f4fa7..a64004e5b974 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.c
@@ -308,7 +308,7 @@ static struct notifier_block thermal_hot_pm_notifier =
static ssize_t gpu3DMinClock_show(struct device_driver *dev, char *buf)
{
- gctUINT currentf,minf,maxf;
+ gctUINT currentf = 0, minf = 0, maxf = 0;
gckGALDEVICE galDevice;
galDevice = platform_get_drvdata(pdevice);
@@ -345,8 +345,11 @@ static ssize_t gpu3DMinClock_store(struct device_driver *dev, const char *buf, s
return count;
}
-
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
static DRIVER_ATTR_RW(gpu3DMinClock);
+#else
+static DRIVER_ATTR(gpu3DMinClock, S_IRUGO | S_IWUSR, gpu3DMinClock_show, gpu3DMinClock_store);
+#endif
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
@@ -500,9 +503,11 @@ static ssize_t gpu_govern_store(struct device_driver *dev, const char *buf, size
return count;
}
-
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
static DRIVER_ATTR_RW(gpu_govern);
-
+#else
+static DRIVER_ATTR(gpu_govern, S_IRUGO | S_IWUSR, gpu_govern_show, gpu_govern_store);
+#endif
int init_gpu_opp_table(struct device *dev)
{
@@ -1505,9 +1510,16 @@ _AdjustParam(
{
patch_param(Platform->device, Args);
- if (of_find_compatible_node(NULL, NULL, "fsl,imx8mq-gpu") && ((Args->baseAddress + totalram_pages * PAGE_SIZE) > 0x100000000))
- Platform->flagBits = gcvPLATFORM_FLAG_LIMIT_4G_ADDRESS;
+ if (of_find_compatible_node(NULL, NULL, "fsl,imx8mq-gpu") &&
+ ((Args->baseAddress + totalram_pages * PAGE_SIZE) > 0x100000000))
+ {
+ Platform->flagBits |= gcvPLATFORM_FLAG_LIMIT_4G_ADDRESS;
+ }
+ if (of_find_compatible_node(NULL, NULL, "fsl,imx8mm-gpu"))
+ {
+ Platform->flagBits |= gcvPLATFORM_FLAG_IMX_MM;
+ }
return gcvSTATUS_OK;
}
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.config b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.config
index ea83bd993d35..56fcc26cffcd 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.config
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.config
@@ -7,6 +7,7 @@ EXTRA_CFLAGS += -DgcdANDROID
endif
EXTRA_CFLAGS += -DgcdANDROID_NATIVE_FENCE_SYNC=2
+
ifeq ($(CONFIG_SYNC)$(CONFIG_SYNC_FILE),)
$(warn CONFIG_SYNC or CONFIG_SYNC_FILE is not set in kernel config)
$(warn Android native fence sync requires CONFIG_SYNC or CONFIG_SYNC_FILE)