fix mali for ttab
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / gpu / ged / src / ged_monitor_3D_fence.c
CommitLineData
6fa3eb70
S
1#include <linux/version.h>
2#include <linux/workqueue.h>
3#include <linux/sched.h>
4#include <asm/atomic.h>
db9a41fa 5#include <linux/module.h>
6fa3eb70
S
6
7#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
8#include <linux/sync.h>
9#else
10#include <../drivers/staging/android/sync.h>
11#endif
12
765691f5 13#include <linux/mtk_gpu_utility.h>
db9a41fa
S
14#include <trace/events/gpu.h>
15#ifdef GED_DVFS_ENABLE
16#include <mt_gpufreq.h>
17#endif
18
6fa3eb70 19#include "ged_monitor_3D_fence.h"
db9a41fa 20
6fa3eb70
S
21#include "ged_log.h"
22#include "ged_base.h"
db9a41fa
S
23#include "ged_type.h"
24#include "ged_dvfs.h"
25
26#include <asm/div64.h>
6fa3eb70
S
27
28static atomic_t g_i32Count = ATOMIC_INIT(0);
db9a41fa
S
29static unsigned int ged_monitor_3D_fence_debug = 0;
30static unsigned int ged_monitor_3D_fence_disable = 0;
31static unsigned int ged_monitor_3D_fence_systrace = 0;
32static unsigned long g_ul3DFenceDoneTime = 0;
33
34
35extern bool mtk_get_bottom_gpu_freq(unsigned int *pui32FreqLevel);
6fa3eb70
S
36
37#ifdef GED_DEBUG_MONITOR_3D_FENCE
38extern GED_LOG_BUF_HANDLE ghLogBuf_GED;
39#endif
db9a41fa 40extern GED_LOG_BUF_HANDLE ghLogBuf_DVFS;
6fa3eb70
S
41
42typedef struct GED_MONITOR_3D_FENCE_TAG
43{
db9a41fa 44 struct sync_fence_waiter sSyncWaiter;
6fa3eb70 45 struct work_struct sWork;
db9a41fa 46 struct sync_fence* psSyncFence;
6fa3eb70
S
47} GED_MONITOR_3D_FENCE;
48
49static void ged_sync_cb(struct sync_fence *fence, struct sync_fence_waiter *waiter)
50{
51 GED_MONITOR_3D_FENCE *psMonitor;
db9a41fa
S
52 unsigned long long t;
53
54 t = ged_get_time();
55
56
57 do_div(t,1000);
58
59 ged_monitor_3D_fence_notify();
60 ged_dvfs_cal_gpu_utilization_force();
6fa3eb70 61 psMonitor = GED_CONTAINER_OF(waiter, GED_MONITOR_3D_FENCE, sSyncWaiter);
db9a41fa
S
62
63 ged_log_buf_print(ghLogBuf_DVFS, "[-] ged_monitor_3D_fence_done (ts=%llu) %p", t, psMonitor->psSyncFence);
64
65 schedule_work(&psMonitor->sWork);
6fa3eb70
S
66}
67
68static void ged_monitor_3D_fence_work_cb(struct work_struct *psWork)
69{
70 GED_MONITOR_3D_FENCE *psMonitor;
71
db9a41fa 72
6fa3eb70 73#ifdef GED_DEBUG_MONITOR_3D_FENCE
db9a41fa 74 ged_log_buf_print(ghLogBuf_GED, "ged_monitor_3D_fence_work_cb");
6fa3eb70
S
75#endif
76
db9a41fa
S
77 if (atomic_sub_return(1, &g_i32Count) < 1)
78 {
79 if (0 == ged_monitor_3D_fence_disable)
80 {
81 unsigned int uiFreqLevelID;
82 if (mtk_get_bottom_gpu_freq(&uiFreqLevelID))
83 {
84 if (uiFreqLevelID > 0)
85 {
6fa3eb70 86#ifdef GED_DEBUG_MONITOR_3D_FENCE
db9a41fa
S
87 ged_log_buf_print(ghLogBuf_GED, "mtk_set_bottom_gpu_freq(0)");
88#endif
89 mtk_set_bottom_gpu_freq(0);
90#if 0
91#ifdef CONFIG_MTK_SCHED_TRACERS
92 if (ged_monitor_3D_fence_systrace)
93 {
94 unsigned long long t = cpu_clock(smp_processor_id());
95 trace_gpu_sched_switch("Smart Boost", t, 0, 0, 1);
96 }
97#endif
6fa3eb70 98#endif
db9a41fa
S
99 }
100 }
101 }
102 }
103
104 if (ged_monitor_3D_fence_debug > 0)
105 {
106 GED_LOGI("[-]3D fences count = %d\n", atomic_read(&g_i32Count));
107 }
6fa3eb70
S
108
109 psMonitor = GED_CONTAINER_OF(psWork, GED_MONITOR_3D_FENCE, sWork);
db9a41fa
S
110 sync_fence_put(psMonitor->psSyncFence);
111 ged_free(psMonitor, sizeof(GED_MONITOR_3D_FENCE));
112}
113
114unsigned long ged_monitor_3D_fence_done_time()
115{
116 return g_ul3DFenceDoneTime;
6fa3eb70
S
117}
118
119GED_ERROR ged_monitor_3D_fence_add(int fence_fd)
120{
db9a41fa
S
121 int err;
122 unsigned long long t;
123 GED_MONITOR_3D_FENCE* psMonitor;
124
125 t = ged_get_time();
126
127 do_div(t,1000);
128
129 psMonitor = (GED_MONITOR_3D_FENCE*)ged_alloc(sizeof(GED_MONITOR_3D_FENCE));
6fa3eb70
S
130
131#ifdef GED_DEBUG_MONITOR_3D_FENCE
db9a41fa 132 ged_log_buf_print(ghLogBuf_GED, "[+]ged_monitor_3D_fence_add");
6fa3eb70
S
133#endif
134
db9a41fa
S
135 if (!psMonitor)
136 {
137 return GED_ERROR_OOM;
138 }
6fa3eb70 139
db9a41fa
S
140 sync_fence_waiter_init(&psMonitor->sSyncWaiter, ged_sync_cb);
141 INIT_WORK(&psMonitor->sWork, ged_monitor_3D_fence_work_cb);
142 psMonitor->psSyncFence = sync_fence_fdget(fence_fd);
143 if (NULL == psMonitor->psSyncFence)
144 {
145 ged_free(psMonitor, sizeof(GED_MONITOR_3D_FENCE));
146 return GED_ERROR_INVALID_PARAMS;
147 }
148
149 ged_log_buf_print(ghLogBuf_DVFS, "[+] ged_monitor_3D_fence_add (ts=%llu) %p", t, psMonitor->psSyncFence);
6fa3eb70
S
150
151#ifdef GED_DEBUG_MONITOR_3D_FENCE
db9a41fa 152 ged_log_buf_print(ghLogBuf_GED, "[+]sync_fence_wait_async");
6fa3eb70
S
153#endif
154
db9a41fa 155 err = sync_fence_wait_async(psMonitor->psSyncFence, &psMonitor->sSyncWaiter);
6fa3eb70
S
156
157#ifdef GED_DEBUG_MONITOR_3D_FENCE
db9a41fa 158 ged_log_buf_print(ghLogBuf_GED, "[-]sync_fence_wait_async, err = %d", err);
6fa3eb70
S
159#endif
160
db9a41fa
S
161 if ((1 == err) || (0 > err))
162 {
163 sync_fence_put(psMonitor->psSyncFence);
164 ged_free(psMonitor, sizeof(GED_MONITOR_3D_FENCE));
165 }
166 else if (0 == err)
167 {
168 int iCount = atomic_add_return (1, &g_i32Count);
169 if (iCount > 1)
170 {
171 if (0 == ged_monitor_3D_fence_disable)
172 {
173 unsigned int uiFreqLevelID;
174 if (mtk_get_bottom_gpu_freq(&uiFreqLevelID))
175 {
176#ifdef GED_DVFS_ENABLE
177 if (uiFreqLevelID != mt_gpufreq_get_dvfs_table_num() - 1)
178#else
179 if (uiFreqLevelID != 9999) // NEVER TRUE
180#endif
181 {
182#if 0
183#ifdef CONFIG_MTK_SCHED_TRACERS
184 if (ged_monitor_3D_fence_systrace)
185 {
186 unsigned long long t = cpu_clock(smp_processor_id());
187 trace_gpu_sched_switch("Smart Boost", t, 1, 0, 1);
188 }
189#endif
190#endif
6fa3eb70 191
db9a41fa
S
192#ifdef GED_DVFS_ENABLE
193 mtk_set_bottom_gpu_freq(mt_gpufreq_get_dvfs_table_num() - 1);
194#endif
195 }
196 }
197 }
198 }
199 }
200
201 if (ged_monitor_3D_fence_debug > 0)
202 {
203 GED_LOGI("[+]3D fences count = %d\n", atomic_read(&g_i32Count));
204 }
6fa3eb70 205#ifdef GED_DEBUG_MONITOR_3D_FENCE
db9a41fa 206 ged_log_buf_print(ghLogBuf_GED, "[-]ged_monitor_3D_fence_add, count = %d", atomic_read(&g_i32Count));
6fa3eb70
S
207#endif
208
db9a41fa 209 return GED_OK;
6fa3eb70
S
210}
211
db9a41fa
S
212void ged_monitor_3D_fence_set_disable(GED_BOOL bFlag)
213{
214 if(bFlag!=ged_monitor_3D_fence_disable)
215 {
216 ged_monitor_3D_fence_disable = bFlag;
217 }
218}
219
220void ged_monitor_3D_fence_notify(void)
221{
222 unsigned long long t;
223
224 t = ged_get_time();
225
226 do_div(t,1000);
227
228 g_ul3DFenceDoneTime = (unsigned long)t;
229}
230
231
232module_param(ged_monitor_3D_fence_debug, uint, 0644);
233module_param(ged_monitor_3D_fence_disable, uint, 0644);
234module_param(ged_monitor_3D_fence_systrace, uint, 0644);