summaryrefslogtreecommitdiff
path: root/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c')
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c174
1 files changed, 174 insertions, 0 deletions
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
new file mode 100644
index 000000000000..7efae1c74bbe
--- /dev/null
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c
@@ -0,0 +1,174 @@
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2013 by Vivante Corp.
+*
+* 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
+* the Free Software Foundation; either version 2 of the license, or
+* (at your option) any later version.
+*
+* 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 write to the Free Software
+* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*****************************************************************************/
+
+
+#include <linux/kernel.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/syscalls.h>
+#include <linux/uaccess.h>
+
+#include "gc_hal_kernel_sync.h"
+
+#if gcdANDROID_NATIVE_FENCE_SYNC
+
+static struct sync_pt *
+viv_sync_pt_dup(
+ struct sync_pt * sync_pt
+ )
+{
+ gceSTATUS status;
+ struct viv_sync_pt *pt;
+ struct viv_sync_pt *src;
+ struct viv_sync_timeline *obj;
+
+ src = (struct viv_sync_pt *) sync_pt;
+ obj = (struct viv_sync_timeline *) sync_pt->parent;
+
+ /* Create the new sync_pt. */
+ pt = (struct viv_sync_pt *)
+ sync_pt_create(&obj->obj, sizeof(struct viv_sync_pt));
+
+ pt->stamp = src->stamp;
+ pt->sync = src->sync;
+
+ /* Reference sync point. */
+ status = gckOS_ReferenceSyncPoint(obj->os, pt->sync);
+
+ if (gcmIS_ERROR(status))
+ {
+ sync_pt_free((struct sync_pt *)pt);
+ return NULL;
+ }
+
+ return (struct sync_pt *)pt;
+}
+
+static int
+viv_sync_pt_has_signaled(
+ struct sync_pt * sync_pt
+ )
+{
+ gceSTATUS status;
+ gctBOOL state;
+ struct viv_sync_pt * pt;
+ struct viv_sync_timeline * obj;
+
+ pt = (struct viv_sync_pt *)sync_pt;
+ obj = (struct viv_sync_timeline *)sync_pt->parent;
+
+ status = gckOS_QuerySyncPoint(obj->os, pt->sync, &state);
+
+ if (gcmIS_ERROR(status))
+ {
+ /* Error. */
+ return -1;
+ }
+
+ return state;
+}
+
+static int
+viv_sync_pt_compare(
+ struct sync_pt * a,
+ struct sync_pt * b
+ )
+{
+ int ret;
+ struct viv_sync_pt * pt1 = (struct viv_sync_pt *) a;
+ struct viv_sync_pt * pt2 = (struct viv_sync_pt *) b;
+
+ ret = (pt1->stamp < pt2->stamp) ? -1
+ : (pt1->stamp == pt2->stamp) ? 0
+ : 1;
+
+ return ret;
+}
+
+static void
+viv_sync_pt_free(
+ struct sync_pt * sync_pt
+ )
+{
+ struct viv_sync_pt * pt;
+ struct viv_sync_timeline * obj;
+
+ pt = (struct viv_sync_pt *) sync_pt;
+ obj = (struct viv_sync_timeline *) sync_pt->parent;
+
+ gckOS_DestroySyncPoint(obj->os, pt->sync);
+}
+
+static struct sync_timeline_ops viv_timeline_ops =
+{
+ .driver_name = "viv_sync",
+ .dup = viv_sync_pt_dup,
+ .has_signaled = viv_sync_pt_has_signaled,
+ .compare = viv_sync_pt_compare,
+ .free_pt = viv_sync_pt_free,
+};
+
+struct viv_sync_timeline *
+viv_sync_timeline_create(
+ const char * name,
+ gckOS os
+ )
+{
+ struct viv_sync_timeline * obj;
+
+ obj = (struct viv_sync_timeline *)
+ sync_timeline_create(&viv_timeline_ops, sizeof(struct viv_sync_timeline), name);
+
+ obj->os = os;
+ obj->stamp = 0;
+
+ return obj;
+}
+
+struct sync_pt *
+viv_sync_pt_create(
+ struct viv_sync_timeline * obj,
+ gctSYNC_POINT SyncPoint
+ )
+{
+ gceSTATUS status;
+ struct viv_sync_pt * pt;
+
+ pt = (struct viv_sync_pt *)
+ sync_pt_create(&obj->obj, sizeof(struct viv_sync_pt));
+
+ pt->stamp = obj->stamp++;
+ pt->sync = SyncPoint;
+
+ /* Dup signal. */
+ status = gckOS_ReferenceSyncPoint(obj->os, SyncPoint);
+
+ if (gcmIS_ERROR(status))
+ {
+ sync_pt_free((struct sync_pt *)pt);
+ return NULL;
+ }
+
+ return (struct sync_pt *) pt;
+}
+
+#endif