summaryrefslogtreecommitdiff
path: root/drivers/mxc/gpu-viv/hal/os
diff options
context:
space:
mode:
authorXianzhong <b07117@freescale.com>2013-10-10 00:24:05 +0800
committerXianzhong <b07117@freescale.com>2013-11-29 01:11:34 +0800
commit74523055b96629ed389de92118b8370c18e70088 (patch)
tree598fd7a2c8b038ca9d52a2687ba36cef130b7a2e /drivers/mxc/gpu-viv/hal/os
parent5721c2db080cd0f9f7370a5eee6704ea71a5c7a4 (diff)
ENGR00283031 [GPU]Integrate 4.6.9p13 release kernel driver
Integrate GPU 4.6.9p13 release kernel driver for Android. Signed-off-by: Xianzhong <b07117@freescale.com> Acked-by: Jason Liu
Diffstat (limited to 'drivers/mxc/gpu-viv/hal/os')
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c15
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h16
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c101
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c715
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h5
5 files changed, 727 insertions, 125 deletions
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 4d48bd55f115..bff85a0e9bf4 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
@@ -25,7 +25,9 @@
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/slab.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
#include <mach/hardware.h>
+#endif
#include <linux/pm_runtime.h>
#define _GC_OBJ_ZONE gcvZONE_DEVICE
@@ -305,6 +307,7 @@ gckGALDEVICE_Construct(
IN gctUINT LogFileSize,
IN struct device *pdev,
IN gctINT PowerManagement,
+ IN gctINT GpuProfiler,
OUT gckGALDEVICE *Device
)
{
@@ -369,6 +372,10 @@ gckGALDEVICE_Construct(
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
/*get gpu regulator*/
device->gpu_regulator = regulator_get(pdev, "cpu_vddgpu");
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ device->gpu_regulator = devm_regulator_get(pdev, "pu");
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
if (IS_ERR(device->gpu_regulator)) {
gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DRIVER,
"%s(%d): Failed to get gpu regulator %s/%s \n",
@@ -541,6 +548,10 @@ gckGALDEVICE_Construct(
device->kernels[gcvCORE_MAJOR]->hardware, PowerManagement
));
+ gcmkONERROR(gckHARDWARE_SetGpuProfiler(
+ device->kernels[gcvCORE_MAJOR]->hardware, GpuProfiler
+ ));
+
#if COMMAND_PROCESSOR_VERSION == 1
/* Start the command queue. */
gcmkONERROR(gckCOMMAND_Start(device->kernels[gcvCORE_MAJOR]->command));
@@ -599,6 +610,7 @@ gckGALDEVICE_Construct(
device->kernels[gcvCORE_2D]->hardware, PowerManagement
));
+
#if COMMAND_PROCESSOR_VERSION == 1
/* Start the command queue. */
gcmkONERROR(gckCOMMAND_Start(device->kernels[gcvCORE_2D]->command));
@@ -635,6 +647,7 @@ gckGALDEVICE_Construct(
device->kernels[gcvCORE_VG]->vg->hardware,
PowerManagement
));
+
#endif
}
else
@@ -849,6 +862,7 @@ gckGALDEVICE_Construct(
}
else
{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
mem_region = request_mem_region(
ContiguousBase, ContiguousSize, "galcore managed memory"
);
@@ -864,6 +878,7 @@ gckGALDEVICE_Construct(
gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
}
+#endif
device->requestedContiguousBase = ContiguousBase;
device->requestedContiguousSize = ContiguousSize;
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
index dde4f034442e..c51432f47c17 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
@@ -26,6 +26,15 @@
******************************* gckGALDEVICE Structure *******************************
\******************************************************************************/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+struct contiguous_mem_pool {
+ struct dma_attrs attrs;
+ dma_addr_t phys;
+ void *virt;
+ size_t size;
+};
+#endif
+
typedef struct _gckGALDEVICE
{
/* Objects. */
@@ -91,12 +100,16 @@ typedef struct _gckGALDEVICE
struct clk *clk_2d_axi;
struct clk *clk_vg_axi;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
/*Power management.*/
struct regulator *gpu_regulator;
#endif
/*Run time pm*/
struct device *pmdev;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ struct contiguous_mem_pool *pool;
+ struct reset_control *rstc[gcdMAX_GPU_COUNT];
+#endif
}
* gckGALDEVICE;
@@ -171,6 +184,7 @@ gceSTATUS gckGALDEVICE_Construct(
IN gctUINT LogFileSize,
IN struct device *pdev,
IN gctINT PowerManagement,
+ IN gctINT GpuProfiler,
OUT gckGALDEVICE *Device
);
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 bacd5311894d..ebd316e24c5b 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
@@ -1,7 +1,7 @@
/****************************************************************************
*
* Copyright (C) 2005 - 2013 by Vivante Corp.
-* Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
+* Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,7 +19,6 @@
*
*****************************************************************************/
-
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/notifier.h>
@@ -69,14 +68,27 @@ task_notify_func(struct notifier_block *self, unsigned long val, void *data)
#include <mach/viv_gpu.h>
#else
#include <linux/pm_runtime.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
#include <mach/busfreq.h>
+#else
+#include <linux/busfreq-imx6.h>
+#include <linux/reset.h>
+#endif
#endif
/* Zone used for header/footer. */
#define _GC_OBJ_ZONE gcvZONE_DRIVER
#if gcdENABLE_FSCALE_VAL_ADJUST
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+#include <linux/device_cooling.h>
+#define REG_THERMAL_NOTIFIER(a) register_devfreq_cooling_notifier(a);
+#define UNREG_THERMAL_NOTIFIER(a) unregister_devfreq_cooling_notifier(a);
+#else
extern int register_thermal_notifier(struct notifier_block *nb);
extern int unregister_thermal_notifier(struct notifier_block *nb);
+#define REG_THERMAL_NOTIFIER(a) register_thermal_notifier(a);
+#define UNREG_THERMAL_NOTIFIER(a) unregister_thermal_notifier(a);
+#endif
#endif
MODULE_DESCRIPTION("Vivante Graphics Driver");
@@ -116,7 +128,11 @@ module_param(registerMemBaseVG, ulong, 0644);
static ulong registerMemSizeVG = 2 << 10;
module_param(registerMemSizeVG, ulong, 0644);
+#if gcdENABLE_FSCALE_VAL_ADJUST
+static ulong contiguousSize = 128 << 20;
+#else
static ulong contiguousSize = 4 << 20;
+#endif
module_param(contiguousSize, ulong, 0644);
static ulong contiguousBase = 0;
@@ -134,6 +150,9 @@ module_param(compression, int, 0644);
static int powerManagement = 1;
module_param(powerManagement, int, 0644);
+static int gpuProfiler = 0;
+module_param(gpuProfiler, int, 0644);
+
static int signal = 48;
module_param(signal, int, 0644);
@@ -786,7 +805,9 @@ static int drv_init(struct device *pdev)
printk(KERN_INFO "Galcore version %d.%d.%d.%d\n",
gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, gcvVERSION_BUILD);
-
+ /* when enable gpu profiler, we need to turn off gpu powerMangement */
+ if(gpuProfiler)
+ powerManagement = 0;
if (showArgs)
{
printk("galcore options:\n");
@@ -818,6 +839,7 @@ static int drv_init(struct device *pdev)
printk(" physSize = 0x%08lX\n", physSize);
printk(" logFileSize = %d KB \n", logFileSize);
printk(" powerManagement = %d\n", powerManagement);
+ printk(" gpuProfiler = %d\n", gpuProfiler);
#if ENABLE_GPU_CLOCK_BY_DRIVER
printk(" coreClock = %lu\n", coreClock);
#endif
@@ -841,9 +863,14 @@ static int drv_init(struct device *pdev)
logFileSize,
pdev,
powerManagement,
+ gpuProfiler,
&device
));
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ device->pool = dev_get_drvdata(pdev);
+#endif
+
/* Start the GAL device. */
gcmkONERROR(gckGALDEVICE_Start(device));
@@ -1028,11 +1055,18 @@ static struct notifier_block thermal_hot_pm_notifier = {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+static int gpu_probe(struct platform_device *pdev)
+#else
static int __devinit gpu_probe(struct platform_device *pdev)
+#endif
{
int ret = -ENODEV;
struct resource* res;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ struct contiguous_mem_pool *pool;
+ struct reset_control *rstc;
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
struct device_node *dn =pdev->dev.of_node;
const u32 *prop;
#else
@@ -1077,7 +1111,22 @@ static int __devinit gpu_probe(struct platform_device *pdev)
registerMemSizeVG = res->end - res->start + 1;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ pool = devm_kzalloc(&pdev->dev, sizeof(*pool), GFP_KERNEL);
+ if (!pool)
+ return -ENOMEM;
+ pool->size = contiguousSize;
+ init_dma_attrs(&pool->attrs);
+ dma_set_attr(DMA_ATTR_WRITE_COMBINE, &pool->attrs);
+ pool->virt = dma_alloc_attrs(&pdev->dev, pool->size, &pool->phys,
+ GFP_KERNEL, &pool->attrs);
+ if (!pool->virt) {
+ dev_err(&pdev->dev, "Failed to allocate contiguous memory\n");
+ return -ENOMEM;
+ }
+ contiguousBase = pool->phys;
+ dev_set_drvdata(&pdev->dev, pool);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
prop = of_get_property(dn, "contiguousbase", NULL);
if(prop)
contiguousBase = *prop;
@@ -1095,30 +1144,56 @@ static int __devinit gpu_probe(struct platform_device *pdev)
if (!ret)
{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ rstc = devm_reset_control_get(&pdev->dev, "gpu3d");
+ galDevice->rstc[gcvCORE_MAJOR] = IS_ERR(rstc) ? NULL : rstc;
+
+ rstc = devm_reset_control_get(&pdev->dev, "gpu2d");
+ galDevice->rstc[gcvCORE_2D] = IS_ERR(rstc) ? NULL : rstc;
+
+ rstc = devm_reset_control_get(&pdev->dev, "gpuvg");
+ galDevice->rstc[gcvCORE_VG] = IS_ERR(rstc) ? NULL : rstc;
+#endif
platform_set_drvdata(pdev, galDevice);
#if gcdENABLE_FSCALE_VAL_ADJUST
- if(galDevice->kernels[gcvCORE_MAJOR])
- register_thermal_notifier(&thermal_hot_pm_notifier);
+ if (galDevice->kernels[gcvCORE_MAJOR])
+ REG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier);
#endif
gcmkFOOTER_NO();
return ret;
}
#if gcdENABLE_FSCALE_VAL_ADJUST
- unregister_thermal_notifier(&thermal_hot_pm_notifier);
+ UNREG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier);
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ dma_free_attrs(&pdev->dev, pool->size, pool->virt, pool->phys,
+ &pool->attrs);
#endif
gcmkFOOTER_ARG(KERN_INFO "Failed to register gpu driver: %d\n", ret);
return ret;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+static int gpu_remove(struct platform_device *pdev)
+#else
static int __devexit gpu_remove(struct platform_device *pdev)
+#endif
{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ gckGALDEVICE device = platform_get_drvdata(pdev);
+ struct contiguous_mem_pool *pool = device->pool;
+#endif
gcmkHEADER();
#if gcdENABLE_FSCALE_VAL_ADJUST
if(galDevice->kernels[gcvCORE_MAJOR])
- unregister_thermal_notifier(&thermal_hot_pm_notifier);
+ UNREG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier);
#endif
drv_exit();
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ dma_free_attrs(&pdev->dev, pool->size, pool->virt, pool->phys,
+ &pool->attrs);
+#endif
gcmkFOOTER_NO();
return 0;
}
@@ -1254,13 +1329,17 @@ MODULE_DEVICE_TABLE(of, mxs_gpu_dt_ids);
#ifdef CONFIG_PM
static int gpu_runtime_suspend(struct device *dev)
{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 7)
release_bus_freq(BUS_FREQ_HIGH);
+#endif
return 0;
}
static int gpu_runtime_resume(struct device *dev)
{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 7)
request_bus_freq(BUS_FREQ_HIGH);
+#endif
return 0;
}
@@ -1284,7 +1363,11 @@ static const struct dev_pm_ops gpu_pm_ops = {
static struct platform_driver gpu_driver = {
.probe = gpu_probe,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+ .remove = gpu_remove,
+#else
.remove = __devexit_p(gpu_remove),
+#endif
.suspend = gpu_suspend,
.resume = gpu_resume,
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 b7717fca0ec6..4c9b01aeded3 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
@@ -30,19 +30,30 @@
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/idr.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
#include <mach/hardware.h>
+#endif
#include <linux/workqueue.h>
#include <linux/idr.h>
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
#include <linux/math64.h>
#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+#include <linux/reset.h>
+static inline void imx_gpc_power_up_pu(bool flag) {}
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
#include <mach/common.h>
#endif
#include <linux/delay.h>
#include <linux/pm_runtime.h>
+#if gcdANDROID_NATIVE_FENCE_SYNC
+#include <linux/file.h>
+#include "gc_hal_kernel_sync.h"
+#endif
+
+
#define _GC_OBJ_ZONE gcvZONE_OS
/*******************************************************************************
@@ -148,6 +159,7 @@ typedef struct _gcsINTEGER_DB
{
struct idr idr;
spinlock_t lock;
+ gctINT curr;
}
gcsINTEGER_DB;
@@ -180,6 +192,14 @@ struct _gckOS
/* signal id database. */
gcsINTEGER_DB signalDB;
+#if gcdANDROID_NATIVE_FENCE_SYNC
+ /* Lock. */
+ gctPOINTER syncPointMutex;
+
+ /* sync point id database. */
+ gcsINTEGER_DB syncPointDB;
+#endif
+
gcsUSER_MAPPING_PTR userMap;
gctPOINTER debugLock;
@@ -215,6 +235,25 @@ typedef struct _gcsSIGNAL
}
gcsSIGNAL;
+#if gcdANDROID_NATIVE_FENCE_SYNC
+typedef struct _gcsSYNC_POINT * gcsSYNC_POINT_PTR;
+typedef struct _gcsSYNC_POINT
+{
+ /* The reference counter. */
+ atomic_t ref;
+
+ /* State. */
+ atomic_t state;
+
+ /* timeline. */
+ struct sync_timeline * timeline;
+
+ /* ID. */
+ gctUINT32 id;
+}
+gcsSYNC_POINT;
+#endif
+
typedef struct _gcsPageInfo * gcsPageInfo_PTR;
typedef struct _gcsPageInfo
{
@@ -336,10 +375,10 @@ _CreateMdlMap(
return gcvNULL;
}
- mdlMap->pid = ProcessID;
- mdlMap->vmaAddr = gcvNULL;
- mdlMap->vma = gcvNULL;
- mdlMap->reference = 0;
+ mdlMap->pid = ProcessID;
+ mdlMap->vmaAddr = gcvNULL;
+ mdlMap->vma = gcvNULL;
+ mdlMap->count = 0;
mdlMap->next = Mdl->maps;
Mdl->maps = mdlMap;
@@ -768,7 +807,32 @@ _AllocateIntegerId(
)
{
int result;
+ gctINT next;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+ idr_preload(GFP_KERNEL | gcdNOWARN);
+
+ spin_lock(&Database->lock);
+ next = (Database->curr + 1 <= 0) ? 1 : Database->curr + 1;
+ result = idr_alloc(&Database->idr, KernelPointer, next, 0, GFP_ATOMIC);
+
+ if (!result)
+ {
+ Database->curr = *Id;
+ }
+
+ spin_unlock(&Database->lock);
+
+ idr_preload_end();
+
+ if (result < 0)
+ {
+ return gcvSTATUS_OUT_OF_RESOURCES;
+ }
+
+ *Id = result;
+#else
again:
if (idr_pre_get(&Database->idr, GFP_KERNEL | gcdNOWARN) == 0)
{
@@ -777,8 +841,15 @@ again:
spin_lock(&Database->lock);
- /* Try to get a id greater than 0. */
- result = idr_get_new_above(&Database->idr, KernelPointer, 1, Id);
+ next = (Database->curr + 1 <= 0) ? 1 : Database->curr + 1;
+
+ /* Try to get a id greater than current id. */
+ result = idr_get_new_above(&Database->idr, KernelPointer, next, Id);
+
+ if (!result)
+ {
+ Database->curr = *Id;
+ }
spin_unlock(&Database->lock);
@@ -791,6 +862,7 @@ again:
{
return gcvSTATUS_OUT_OF_RESOURCES;
}
+#endif
return gcvSTATUS_OK;
}
@@ -1009,6 +1081,21 @@ gckOS_Construct(
/* Initialize signal id database. */
idr_init(&os->signalDB.idr);
+#if gcdANDROID_NATIVE_FENCE_SYNC
+ /*
+ * Initialize the sync point manager.
+ */
+
+ /* Initialize mutex. */
+ gcmkONERROR(gckOS_CreateMutex(os, &os->syncPointMutex));
+
+ /* Initialize sync point id database lock. */
+ spin_lock_init(&os->syncPointDB.lock);
+
+ /* Initialize sync point id database. */
+ idr_init(&os->syncPointDB.idr);
+#endif
+
#if gcdUSE_NON_PAGED_MEMORY_CACHE
os->cacheSize = 0;
os->cacheHead = gcvNULL;
@@ -1032,6 +1119,15 @@ gckOS_Construct(
return gcvSTATUS_OK;
OnError:
+
+#if gcdANDROID_NATIVE_FENCE_SYNC
+ if (os->syncPointMutex != gcvNULL)
+ {
+ gcmkVERIFY_OK(
+ gckOS_DeleteMutex(os, os->syncPointMutex));
+ }
+#endif
+
if (os->signalMutex != gcvNULL)
{
gcmkVERIFY_OK(
@@ -1105,6 +1201,15 @@ gckOS_Destroy(
_FreeAllNonPagedMemoryCache(Os);
#endif
+#if gcdANDROID_NATIVE_FENCE_SYNC
+ /*
+ * Destroy the sync point manager.
+ */
+
+ /* Destroy the mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->syncPointMutex));
+#endif
+
/*
* Destroy the signal manager.
*/
@@ -1962,12 +2067,6 @@ gckOS_AllocateNonPagedMemory(
gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
}
- if ((Os->device->baseAddress & 0x80000000) != (mdl->dmaHandle & 0x80000000))
- {
- mdl->dmaHandle = (mdl->dmaHandle & ~0x80000000)
- | (Os->device->baseAddress & 0x80000000);
- }
-
mdl->addr = addr;
/* Return allocated memory. */
@@ -2308,6 +2407,7 @@ gckOS_ReadRegisterEx(
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Address < Os->device->requestedRegisterMemSizes[Core]);
gcmkVERIFY_ARGUMENT(Data != gcvNULL);
*Data = readl((gctUINT8 *)Os->device->registerBases[Core] + Address);
@@ -2358,6 +2458,8 @@ gckOS_WriteRegisterEx(
{
gcmkHEADER_ARG("Os=0x%X Core=%d Address=0x%X Data=0x%08x", Os, Core, Address, Data);
+ gcmkVERIFY_ARGUMENT(Address < Os->device->requestedRegisterMemSizes[Core]);
+
writel(Data, (gctUINT8 *)Os->device->registerBases[Core] + Address);
/* Success. */
@@ -2800,16 +2902,25 @@ gckOS_MapPhysical(
if (mdl == gcvNULL)
{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ struct contiguous_mem_pool *pool = Os->device->pool;
+
+ if (Physical >= pool->phys && Physical < pool->phys + pool->size)
+ logical = (gctPOINTER)(Physical - pool->phys + pool->virt);
+ else
+ logical = gcvNULL;
+#else
/* Map memory as cached memory. */
request_mem_region(physical, Bytes, "MapRegion");
logical = (gctPOINTER) ioremap_nocache(physical, Bytes);
+#endif
if (logical == gcvNULL)
{
gcmkTRACE_ZONE(
gcvLEVEL_INFO, gcvZONE_OS,
- "%s(%d): Failed to ioremap",
- __FUNCTION__, __LINE__
+ "%s(%d): Failed to map physical address 0x%08x",
+ __FUNCTION__, __LINE__, Physical
);
MEMORY_UNLOCK(Os);
@@ -3622,7 +3733,7 @@ gckOS_Delay(
if (Delay > 0)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
- ktime_t delay = ktime_set(0, Delay * NSEC_PER_MSEC);
+ ktime_t delay = ktime_set(Delay/1000, (Delay%1000) * NSEC_PER_MSEC);
__set_current_state(TASK_UNINTERRUPTIBLE);
schedule_hrtimeout(&delay, HRTIMER_MODE_REL);
#else
@@ -3856,6 +3967,9 @@ gckOS_AllocatePagedMemoryEx(
gctSIZE_T bytes;
gctBOOL locked = gcvFALSE;
gceSTATUS status;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+ gctPOINTER addr = gcvNULL;
+#endif
gcmkHEADER_ARG("Os=0x%X Contiguous=%d Bytes=%lu", Os, Contiguous, Bytes);
@@ -3879,15 +3993,34 @@ gckOS_AllocatePagedMemoryEx(
if (Contiguous)
{
- /* Get contiguous pages, and suppress warning (stack dump) from kernel when
- we run out of memory. */
- mdl->u.contiguousPages =
- alloc_pages(GFP_KERNEL | gcdNOWARN | __GFP_NORETRY, GetOrder(numPages));
+ gctUINT32 order = get_order(bytes);
+
+ if (order >= MAX_ORDER)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+ addr =
+ alloc_pages_exact(numPages * PAGE_SIZE, GFP_KERNEL | gcdNOWARN | __GFP_NORETRY);
+
+ mdl->u.contiguousPages = addr
+ ? virt_to_page(addr)
+ : gcvNULL;
+
+ mdl->exact = gcvTRUE;
+#else
+ mdl->u.contiguousPages =
+ alloc_pages(GFP_KERNEL | gcdNOWARN | __GFP_NORETRY, order);
+#endif
if (mdl->u.contiguousPages == gcvNULL)
{
mdl->u.contiguousPages =
- alloc_pages(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN, GetOrder(numPages));
+ alloc_pages(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN, order);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+ mdl->exact = gcvFALSE;
+#endif
}
}
else
@@ -4032,7 +4165,16 @@ gckOS_FreePagedMemory(
if (mdl->contiguous)
{
- __free_pages(mdl->u.contiguousPages, GetOrder(mdl->numPages));
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+ if (mdl->exact == gcvTRUE)
+ {
+ free_pages_exact(page_address(mdl->u.contiguousPages), mdl->numPages * PAGE_SIZE);
+ }
+ else
+#endif
+ {
+ __free_pages(mdl->u.contiguousPages, GetOrder(mdl->numPages));
+ }
}
else
{
@@ -4214,13 +4356,13 @@ gckOS_LockPages(
}
mdlMap->vma->vm_flags |= gcdVM_FLAGS;
-#if !gcdPAGED_MEMORY_CACHEABLE
+
if (Cacheable == gcvFALSE)
{
/* Make this mapping non-cached. */
mdlMap->vma->vm_page_prot = gcmkPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot);
}
-#endif
+
addr = mdl->addr;
/* Now map all the vmalloc pages to this user address. */
@@ -4291,16 +4433,7 @@ gckOS_LockPages(
up_write(&current->mm->mmap_sem);
}
-#if 0
- else
- {
- /* mdlMap->vmaAddr != gcvNULL means current process has already locked this node. */
- MEMORY_UNLOCK(Os);
-
- gcmkFOOTER_ARG("*status=%d, mdlMap->vmaAddr=%x", gcvSTATUS_MEMORY_LOCKED, mdlMap->vmaAddr);
- return gcvSTATUS_MEMORY_LOCKED;
- }
-#endif
+ mdlMap->count++;
/* Convert pointer to MDL. */
*Logical = mdlMap->vmaAddr;
@@ -4311,9 +4444,6 @@ gckOS_LockPages(
*PageCount = mdl->numPages * (PAGE_SIZE / 4096);
- /* Increase reference count. */
- mdlMap->reference++;
-
MEMORY_UNLOCK(Os);
gcmkVERIFY_OK(gckOS_CacheFlush(
@@ -4580,13 +4710,11 @@ gckOS_UnlockPages(
{
if ((mdlMap->vmaAddr != gcvNULL) && (_GetProcessID() == mdlMap->pid))
{
- if (--mdlMap->reference > 0)
+ if (--mdlMap->count == 0)
{
- continue;
+ _UnmapUserLogical(mdlMap->pid, mdlMap->vmaAddr, mdl->numPages * PAGE_SIZE);
+ mdlMap->vmaAddr = gcvNULL;
}
-
- _UnmapUserLogical(mdlMap->pid, mdlMap->vmaAddr, mdl->numPages * PAGE_SIZE);
- mdlMap->vmaAddr = gcvNULL;
}
mdlMap = mdlMap->next;
@@ -5322,6 +5450,7 @@ OnError:
{
/* Get the user pages. */
down_read(&current->mm->mmap_sem);
+
result = get_user_pages(current,
current->mm,
memory & PAGE_MASK,
@@ -5331,109 +5460,127 @@ OnError:
pages,
gcvNULL
);
+
up_read(&current->mm->mmap_sem);
if (result <=0 || result < pageCount)
{
struct vm_area_struct *vma;
- /* Free the page table. */
- if (pages != gcvNULL)
+ /* Release the pages if any. */
+ if (result > 0)
{
- /* Release the pages if any. */
- if (result > 0)
+ for (i = 0; i < result; i++)
{
- for (i = 0; i < result; i++)
+ if (pages[i] == gcvNULL)
{
- if (pages[i] == gcvNULL)
- {
- break;
- }
-
- page_cache_release(pages[i]);
+ break;
}
+
+ page_cache_release(pages[i]);
+ pages[i] = gcvNULL;
}
- kfree(pages);
- pages = gcvNULL;
+ result = 0;
}
vma = find_vma(current->mm, memory);
- if (vma && (vma->vm_flags & VM_PFNMAP) )
+ if (vma && (vma->vm_flags & VM_PFNMAP))
{
pte_t * pte;
spinlock_t * ptl;
- unsigned long pfn;
+ gctUINTPTR_T logical = memory;
- pgd_t * pgd = pgd_offset(current->mm, memory);
- pud_t * pud = pud_offset(pgd, memory);
- if (pud)
+ for (i = 0; i < pageCount; i++)
{
- pmd_t * pmd = pmd_offset(pud, memory);
- pte = pte_offset_map_lock(current->mm, pmd, memory, &ptl);
- if (!pte)
+ pgd_t * pgd = pgd_offset(current->mm, logical);
+ pud_t * pud = pud_offset(pgd, logical);
+
+ if (pud)
+ {
+ pmd_t * pmd = pmd_offset(pud, logical);
+ pte = pte_offset_map_lock(current->mm, pmd, logical, &ptl);
+ if (!pte)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+ }
+ else
{
gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
}
+
+ pages[i] = pte_page(*pte);
+ pte_unmap_unlock(pte, ptl);
+
+ /* Advance to next. */
+ logical += PAGE_SIZE;
}
- else
+ }
+ else
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ /* Check if this memory is contiguous for old mmu. */
+ if (Os->device->kernels[Core]->hardware->mmuVersion == 0)
+ {
+ for (i = 1; i < pageCount; i++)
{
- gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ if (pages[i] != nth_page(pages[0], i))
+ {
+ /* Non-contiguous. */
+ break;
+ }
}
- pfn = pte_pfn(*pte);
-
- physical = (pfn << PAGE_SHIFT) | (memory & ~PAGE_MASK);
+ if (i == pageCount)
+ {
+ /* Contiguous memory. */
+ physical = page_to_phys(pages[0]) | (memory & ~PAGE_MASK);
- pte_unmap_unlock(pte, ptl);
+ if (!((physical - Os->device->baseAddress) & 0x80000000))
+ {
+ kfree(pages);
+ pages = gcvNULL;
- if ((Os->device->kernels[Core]->hardware->mmuVersion == 0)
- && !((physical - Os->device->baseAddress) & 0x80000000))
- {
- info->pages = gcvNULL;
- info->pageTable = gcvNULL;
+ info->pages = gcvNULL;
+ info->pageTable = gcvNULL;
- MEMORY_MAP_UNLOCK(Os);
+ MEMORY_MAP_UNLOCK(Os);
- *Address = physical - Os->device->baseAddress;
- *Info = info;
+ *Address = physical - Os->device->baseAddress;
+ *Info = info;
- gcmkFOOTER_ARG("*Info=0x%X *Address=0x%08x",
- *Info, *Address);
+ gcmkFOOTER_ARG("*Info=0x%X *Address=0x%08x",
+ *Info, *Address);
- return gcvSTATUS_OK;
+ return gcvSTATUS_OK;
+ }
}
}
- else
+
+ /* Reference pages. */
+ for (i = 0; i < pageCount; i++)
{
- gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ get_page(pages[i]);
}
}
}
- if (pages)
+ for (i = 0; i < pageCount; i++)
{
- for (i = 0; i < pageCount; i++)
- {
#ifdef CONFIG_ARM
- gctUINT32 data;
- get_user(data, (gctUINT32*)((memory & PAGE_MASK) + i * PAGE_SIZE));
+ gctUINT32 data;
+ get_user(data, (gctUINT32*)((memory & PAGE_MASK) + i * PAGE_SIZE));
#endif
- /* Flush(clean) the data cache. */
- gcmkONERROR(gckOS_CacheFlush(Os, _GetProcessID(), gcvNULL,
- (gctPOINTER)(gctUINTPTR_T)page_to_phys(pages[i]),
- (gctPOINTER)(memory & PAGE_MASK) + i*PAGE_SIZE,
- PAGE_SIZE));
- }
- }
- else
- {
+
/* Flush(clean) the data cache. */
gcmkONERROR(gckOS_CacheFlush(Os, _GetProcessID(), gcvNULL,
- (gctPOINTER)(gctUINTPTR_T)(physical & PAGE_MASK),
- (gctPOINTER)(memory & PAGE_MASK),
- PAGE_SIZE * pageCount));
+ (gctPOINTER)(gctUINTPTR_T)page_to_phys(pages[i]),
+ (gctPOINTER)(memory & PAGE_MASK) + i*PAGE_SIZE,
+ PAGE_SIZE));
}
#if gcdENABLE_VG
@@ -5454,20 +5601,14 @@ OnError:
(gctPOINTER *) &pageTable,
&address));
}
+
/* Fill the page table. */
for (i = 0; i < pageCount; i++)
{
gctUINT32 phys;
gctUINT32_PTR tab = pageTable + i * (PAGE_SIZE/4096);
- if (pages)
- {
- phys = page_to_phys(pages[i]);
- }
- else
- {
- phys = (physical & PAGE_MASK) + i * PAGE_SIZE;
- }
+ phys = page_to_phys(pages[i]);
#if gcdENABLE_VG
if (Core == gcvCORE_VG)
@@ -6116,7 +6257,7 @@ gckOS_CacheClean(
#else
dma_sync_single_for_device(
gcvNULL,
- Physical,
+ (dma_addr_t)Physical,
Bytes,
DMA_TO_DEVICE);
#endif
@@ -6195,7 +6336,7 @@ gckOS_CacheInvalidate(
#else
dma_sync_single_for_device(
gcvNULL,
- Physical,
+ (dma_addr_t)Physical,
Bytes,
DMA_FROM_DEVICE);
#endif
@@ -6269,7 +6410,7 @@ gckOS_CacheFlush(
#else
dma_sync_single_for_device(
gcvNULL,
- Physical,
+ (dma_addr_t)Physical,
Bytes,
DMA_BIDIRECTIONAL);
#endif
@@ -6818,6 +6959,9 @@ gckOS_SetGPUPower(
struct clk *clk_2dcore = Os->device->clk_2d_core;
struct clk *clk_2d_axi = Os->device->clk_2d_axi;
struct clk *clk_vg_axi = Os->device->clk_vg_axi;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ int ret;
+#endif
gctBOOL oldClockState = gcvFALSE;
gctBOOL oldPowerState = gcvFALSE;
@@ -6843,10 +6987,14 @@ gckOS_SetGPUPower(
}
if((Power == gcvTRUE) && (oldPowerState == gcvFALSE))
{
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
mutex_lock(&set_cpufreq_lock);
- if(!IS_ERR(Os->device->gpu_regulator))
- regulator_enable(Os->device->gpu_regulator);
+ if(!IS_ERR(Os->device->gpu_regulator)) {
+ ret = regulator_enable(Os->device->gpu_regulator);
+ if (ret != 0)
+ gckOS_Print("%s(%d): fail to enable pu regulator %d!\n",
+ __FUNCTION__, __LINE__, ret);
+ }
mutex_unlock(&set_cpufreq_lock);
#else
imx_gpc_power_up_pu(true);
@@ -6962,7 +7110,7 @@ gckOS_SetGPUPower(
pm_runtime_put_sync(Os->device->pmdev);
#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
mutex_lock(&set_cpufreq_lock);
if(!IS_ERR(Os->device->gpu_regulator))
regulator_disable(Os->device->gpu_regulator);
@@ -7028,6 +7176,10 @@ gckOS_ResetGPU(
}
gcmkFOOTER_NO();
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+ struct reset_control *rstc = Os->device->rstc[Core];
+ if (rstc)
+ reset_control_reset(rstc);
#else
imx_src_reset_gpu((int)Core);
#endif
@@ -8534,3 +8686,338 @@ gckOS_GetProcessNameByPid(
return gcvSTATUS_OK;
}
+#if gcdANDROID_NATIVE_FENCE_SYNC
+
+gceSTATUS
+gckOS_CreateSyncPoint(
+ IN gckOS Os,
+ OUT gctSYNC_POINT * SyncPoint
+ )
+{
+ gceSTATUS status;
+ gcsSYNC_POINT_PTR syncPoint;
+
+ gcmkHEADER_ARG("Os=0x%X", Os);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+
+ /* Create an sync point structure. */
+ syncPoint = (gcsSYNC_POINT_PTR) kmalloc(
+ sizeof(gcsSYNC_POINT), GFP_KERNEL | gcdNOWARN);
+
+ if (syncPoint == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ /* Initialize the sync point. */
+ atomic_set(&syncPoint->ref, 1);
+ atomic_set(&syncPoint->state, 0);
+
+ gcmkONERROR(_AllocateIntegerId(&Os->syncPointDB, syncPoint, &syncPoint->id));
+
+ *SyncPoint = (gctSYNC_POINT)(gctUINTPTR_T)syncPoint->id;
+
+ gcmkFOOTER_ARG("*SyncPonint=%d", syncPoint->id);
+ return gcvSTATUS_OK;
+
+OnError:
+ if (syncPoint != gcvNULL)
+ {
+ kfree(syncPoint);
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckOS_ReferenceSyncPoint(
+ IN gckOS Os,
+ IN gctSYNC_POINT SyncPoint
+ )
+{
+ gceSTATUS status;
+ gcsSYNC_POINT_PTR syncPoint;
+
+ gcmkHEADER_ARG("Os=0x%X", Os);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(SyncPoint != gcvNULL);
+
+ gcmkONERROR(
+ _QueryIntegerId(&Os->syncPointDB,
+ (gctUINT32)(gctUINTPTR_T)SyncPoint,
+ (gctPOINTER)&syncPoint));
+
+ /* Initialize the sync point. */
+ atomic_inc(&syncPoint->ref);
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckOS_DestroySyncPoint(
+ IN gckOS Os,
+ IN gctSYNC_POINT SyncPoint
+ )
+{
+ gceSTATUS status;
+ gcsSYNC_POINT_PTR syncPoint;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Os=0x%X SyncPoint=%d", Os, (gctUINT32)(gctUINTPTR_T)SyncPoint);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(SyncPoint != gcvNULL);
+
+ gcmkONERROR(gckOS_AcquireMutex(Os, Os->syncPointMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ gcmkONERROR(
+ _QueryIntegerId(&Os->syncPointDB,
+ (gctUINT32)(gctUINTPTR_T)SyncPoint,
+ (gctPOINTER)&syncPoint));
+
+ gcmkASSERT(syncPoint->id == (gctUINT32)(gctUINTPTR_T)SyncPoint);
+
+ if (atomic_dec_and_test(&syncPoint->ref))
+ {
+ gcmkVERIFY_OK(_DestroyIntegerId(&Os->syncPointDB, syncPoint->id));
+
+ /* Free the sgianl. */
+ syncPoint->timeline = gcvNULL;
+ kfree(syncPoint);
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->syncPointMutex));
+ acquired = gcvFALSE;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->syncPointMutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckOS_SignalSyncPoint(
+ IN gckOS Os,
+ IN gctSYNC_POINT SyncPoint
+ )
+{
+ gceSTATUS status;
+ gcsSYNC_POINT_PTR syncPoint;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Os=0x%X SyncPoint=%d", Os, (gctUINT32)(gctUINTPTR_T)SyncPoint);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(SyncPoint != gcvNULL);
+
+ gcmkONERROR(gckOS_AcquireMutex(Os, Os->syncPointMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ gcmkONERROR(
+ _QueryIntegerId(&Os->syncPointDB,
+ (gctUINT32)(gctUINTPTR_T)SyncPoint,
+ (gctPOINTER)&syncPoint));
+
+ gcmkASSERT(syncPoint->id == (gctUINT32)(gctUINTPTR_T)SyncPoint);
+
+ /* Get state. */
+ atomic_set(&syncPoint->state, gcvTRUE);
+
+ /* Signal timeline. */
+ if (syncPoint->timeline)
+ {
+ sync_timeline_signal(syncPoint->timeline);
+ }
+
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->syncPointMutex));
+ acquired = gcvFALSE;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ /* Release the mutex. */
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->syncPointMutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckOS_QuerySyncPoint(
+ IN gckOS Os,
+ IN gctSYNC_POINT SyncPoint,
+ OUT gctBOOL_PTR State
+ )
+{
+ gceSTATUS status;
+ gcsSYNC_POINT_PTR syncPoint;
+
+ gcmkHEADER_ARG("Os=0x%X SyncPoint=%d", Os, (gctUINT32)(gctUINTPTR_T)SyncPoint);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(SyncPoint != gcvNULL);
+
+ gcmkONERROR(
+ _QueryIntegerId(&Os->syncPointDB,
+ (gctUINT32)(gctUINTPTR_T)SyncPoint,
+ (gctPOINTER)&syncPoint));
+
+ gcmkASSERT(syncPoint->id == (gctUINT32)(gctUINTPTR_T)SyncPoint);
+
+ /* Get state. */
+ *State = atomic_read(&syncPoint->state);
+
+ /* Success. */
+ gcmkFOOTER_ARG("*State=%d", *State);
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckOS_CreateSyncTimeline(
+ IN gckOS Os,
+ OUT gctHANDLE * Timeline
+ )
+{
+ struct viv_sync_timeline * timeline;
+
+ /* Create viv sync timeline. */
+ timeline = viv_sync_timeline_create("viv timeline", Os);
+
+ if (timeline == gcvNULL)
+ {
+ /* Out of memory. */
+ return gcvSTATUS_OUT_OF_MEMORY;
+ }
+
+ *Timeline = (gctHANDLE) timeline;
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_DestroySyncTimeline(
+ IN gckOS Os,
+ IN gctHANDLE Timeline
+ )
+{
+ struct viv_sync_timeline * timeline;
+ gcmkASSERT(Timeline != gcvNULL);
+
+ /* Destroy timeline. */
+ timeline = (struct viv_sync_timeline *) Timeline;
+ sync_timeline_destroy(&timeline->obj);
+
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckOS_CreateNativeFence(
+ IN gckOS Os,
+ IN gctHANDLE Timeline,
+ IN gctSYNC_POINT SyncPoint,
+ OUT gctINT * FenceFD
+ )
+{
+ int fd = -1;
+ struct viv_sync_timeline *timeline;
+ struct sync_pt * pt = gcvNULL;
+ struct sync_fence * fence;
+ char name[32];
+ gcsSYNC_POINT_PTR syncPoint;
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Os=0x%X Timeline=0x%X SyncPoint=%d",
+ Os, Timeline, (gctUINT)(gctUINTPTR_T)SyncPoint);
+
+ gcmkONERROR(
+ _QueryIntegerId(&Os->syncPointDB,
+ (gctUINT32)(gctUINTPTR_T)SyncPoint,
+ (gctPOINTER)&syncPoint));
+
+ /* Cast timeline. */
+ timeline = (struct viv_sync_timeline *) Timeline;
+
+ fd = get_unused_fd();
+
+ if (fd < 0)
+ {
+ /* Out of resources. */
+ gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
+ }
+
+ /* Create viv_sync_pt. */
+ pt = viv_sync_pt_create(timeline, SyncPoint);
+
+ if (pt == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ /* Reference sync_timeline. */
+ syncPoint->timeline = &timeline->obj;
+
+ /* Build fence name. */
+ snprintf(name, 32, "viv sync_fence-%u", (gctUINT)(gctUINTPTR_T)SyncPoint);
+
+ /* Create sync_fence. */
+ fence = sync_fence_create(name, pt);
+
+ if (fence == NULL)
+ {
+ gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+ }
+
+ /* Install fence to fd. */
+ sync_fence_install(fence, fd);
+
+ *FenceFD = fd;
+ gcmkFOOTER_ARG("*FenceFD=%d", fd);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Error roll back. */
+ if (pt)
+ {
+ sync_pt_free(pt);
+ }
+
+ if (fd > 0)
+ {
+ put_unused_fd(fd);
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+#endif
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 9307e832e167..b22081740fdb 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
@@ -26,8 +26,8 @@ typedef struct _LINUX_MDL_MAP
{
gctINT pid;
gctPOINTER vmaAddr;
+ gctUINT32 count;
struct vm_area_struct * vma;
- gctINT reference;
struct _LINUX_MDL_MAP * next;
}
LINUX_MDL_MAP;
@@ -55,6 +55,9 @@ typedef struct _LINUX_MDL
gctINT numPages;
gctINT pagedMem;
gctBOOL contiguous;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+ gctBOOL exact;
+#endif
dma_addr_t dmaHandle;
PLINUX_MDL_MAP maps;
struct _LINUX_MDL * prev;