a736d084032243142fc829628645c2b1dd1e8a99
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / gpu / ged / src / ged_monitor_3D_fence.c
1 #include <linux/version.h>
2 #include <linux/workqueue.h>
3 #include <linux/sched.h>
4 #include <asm/atomic.h>
5
6 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
7 #include <linux/sync.h>
8 #else
9 #include <../drivers/staging/android/sync.h>
10 #endif
11
12 #include <linux/mtk_gpu_utility.h>
13 #include "ged_monitor_3D_fence.h"
14 #include "ged_log.h"
15 #include "ged_base.h"
16
17 static atomic_t g_i32Count = ATOMIC_INIT(0);
18
19 #ifdef GED_DEBUG_MONITOR_3D_FENCE
20 extern GED_LOG_BUF_HANDLE ghLogBuf_GED;
21 #endif
22
23 typedef struct GED_MONITOR_3D_FENCE_TAG
24 {
25 struct sync_fence_waiter sSyncWaiter;
26 struct work_struct sWork;
27 struct sync_fence* psSyncFence;
28 } GED_MONITOR_3D_FENCE;
29
30 static void ged_sync_cb(struct sync_fence *fence, struct sync_fence_waiter *waiter)
31 {
32 GED_MONITOR_3D_FENCE *psMonitor;
33 psMonitor = GED_CONTAINER_OF(waiter, GED_MONITOR_3D_FENCE, sSyncWaiter);
34 schedule_work(&psMonitor->sWork);
35 }
36
37 static void ged_monitor_3D_fence_work_cb(struct work_struct *psWork)
38 {
39 GED_MONITOR_3D_FENCE *psMonitor;
40
41 #ifdef GED_DEBUG_MONITOR_3D_FENCE
42 ged_log_buf_print(ghLogBuf_GED, "ged_monitor_3D_fence_work_cb");
43 #endif
44
45 if (atomic_sub_return(1, &g_i32Count) < 1)
46 {
47 #ifdef GED_DEBUG_MONITOR_3D_FENCE
48 ged_log_buf_print(ghLogBuf_GED, "mtk_set_bottom_gpu_freq(0)");
49 #endif
50 mtk_set_bottom_gpu_freq(0);
51 }
52
53 psMonitor = GED_CONTAINER_OF(psWork, GED_MONITOR_3D_FENCE, sWork);
54 sync_fence_put(psMonitor->psSyncFence);
55 ged_free(psMonitor, sizeof(GED_MONITOR_3D_FENCE));
56 }
57
58 GED_ERROR ged_monitor_3D_fence_add(int fence_fd)
59 {
60 int err;
61 GED_MONITOR_3D_FENCE* psMonitor = (GED_MONITOR_3D_FENCE*)ged_alloc(sizeof(GED_MONITOR_3D_FENCE));
62
63 #ifdef GED_DEBUG_MONITOR_3D_FENCE
64 ged_log_buf_print(ghLogBuf_GED, "[+]ged_monitor_3D_fence_add");
65 #endif
66
67 if (!psMonitor)
68 {
69 return GED_ERROR_OOM;
70 }
71
72 sync_fence_waiter_init(&psMonitor->sSyncWaiter, ged_sync_cb);
73 INIT_WORK(&psMonitor->sWork, ged_monitor_3D_fence_work_cb);
74 psMonitor->psSyncFence = sync_fence_fdget(fence_fd);
75 if (NULL == psMonitor->psSyncFence)
76 {
77 ged_free(psMonitor, sizeof(GED_MONITOR_3D_FENCE));
78 return GED_ERROR_INVALID_PARAMS;
79 }
80
81 #ifdef GED_DEBUG_MONITOR_3D_FENCE
82 ged_log_buf_print(ghLogBuf_GED, "[+]sync_fence_wait_async");
83 #endif
84
85 err = sync_fence_wait_async(psMonitor->psSyncFence, &psMonitor->sSyncWaiter);
86
87 #ifdef GED_DEBUG_MONITOR_3D_FENCE
88 ged_log_buf_print(ghLogBuf_GED, "[-]sync_fence_wait_async, err = %d", err);
89 #endif
90
91 if ((1 == err) || (0 > err))
92 {
93 sync_fence_put(psMonitor->psSyncFence);
94 ged_free(psMonitor, sizeof(GED_MONITOR_3D_FENCE));
95 }
96 else if (0 == err)
97 {
98 int iCount = atomic_add_return (1, &g_i32Count);
99 if (iCount > 1)
100 {
101 //mtk_set_bottom_gpu_freq(iCount + 1);
102 mtk_set_bottom_gpu_freq(4);
103 }
104 }
105
106 #ifdef GED_DEBUG_MONITOR_3D_FENCE
107 ged_log_buf_print(ghLogBuf_GED, "[-]ged_monitor_3D_fence_add, count = %d", atomic_read(&g_i32Count));
108 #endif
109
110 return GED_OK;
111 }
112