ARM: mali400: r5p2_rel0: add sc8830 platform codes
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / gpu / arm / mali400 / r5p2_rel0 / platform / sc8830 / mali_platform.c
1 /*
2  * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
3  *
4  * This program is free software and is provided to you under the terms of the
5  * GNU General Public License version 2 as published by the Free Software
6  * Foundation, and any use by you of this program is subject to the terms of
7  * such GNU licence.
8  *
9  * A copy of the licence is included with the program, and can also be obtained
10  * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
11  * MA  02110-1301, USA.
12  */
13
14 /**
15  * @file mali_platform.c
16  * Platform specific Mali driver functions for a default platform
17  */
18
19 #include <linux/version.h>
20 #include <linux/clk.h>
21 #include <linux/delay.h>
22 #include <linux/dma-mapping.h>
23 #ifdef CONFIG_SYSTEM_LOAD_ANALYZER
24 #include <linux/load_analyzer.h>
25 #endif
26 #include <linux/mali/mali_utgard.h>
27 #ifdef CONFIG_MALI_DT
28 #include <linux/of.h>
29 #endif
30 #include <linux/platform_device.h>
31 #include <linux/pm.h>
32 #ifdef CONFIG_PM_RUNTIME
33 #include <linux/pm_runtime.h>
34 #endif
35 #include <linux/semaphore.h>
36 #include <linux/vmalloc.h>
37 #include <linux/workqueue.h>
38
39 #ifdef CONFIG_64BIT
40 #include <soc/sprd/irqs.h>
41 #include <soc/sprd/sci.h>
42 #include <soc/sprd/sci_glb_regs.h>
43 #else
44 #include <soc/sprd/sci.h>
45 #include <soc/sprd/sci_glb_regs.h>
46 #endif
47
48 #include "base.h"
49 #include "mali_executor.h"
50 #include "mali_kernel_common.h"
51 #include "mali_kernel_linux.h"
52 #include "mali_pm.h"
53
54 #define GPU_GLITCH_FREE_DFS     0
55
56 #define UP_THRESHOLD            9/10
57 #define DOWN_THRESHOLD          5/10
58
59 #define __SPRD_GPU_TIMEOUT      (3*1000)
60
61 struct gpu_freq_info {
62         struct clk *clk_src;
63         int freq;
64         int div;
65         int up_threshold;
66 };
67
68 struct gpu_dfs_context {
69         int gpu_clock_on;
70         int gpu_power_on;
71
72         struct clk *gpu_clock;
73         struct clk *gpu_clock_i;
74         struct clk **gpu_clk_src;
75         int gpu_clk_num;
76
77         int cur_load;
78
79         struct gpu_freq_info *freq_list;
80         int freq_list_len;
81
82         const struct gpu_freq_info *freq_cur;
83         const struct gpu_freq_info *freq_next;
84
85         const struct gpu_freq_info *freq_min;
86         const struct gpu_freq_info *freq_max;
87         const struct gpu_freq_info *freq_default;
88         const struct gpu_freq_info *freq_9;
89         const struct gpu_freq_info *freq_8;
90         const struct gpu_freq_info *freq_7;
91         const struct gpu_freq_info *freq_5;
92         const struct gpu_freq_info *freq_range_max;
93         const struct gpu_freq_info *freq_range_min;
94
95         struct workqueue_struct *gpu_dfs_workqueue;
96         struct semaphore* sem;
97 };
98
99 extern int gpu_boost_level;
100 extern int gpu_boost_sf_level;
101
102 extern int gpu_freq_cur;
103 extern int gpu_freq_min_limit;
104 extern int gpu_freq_max_limit;
105 extern char* gpu_freq_list;
106
107 extern _mali_osk_errcode_t mali_executor_initialize(void);
108 extern void mali_executor_lock(void);
109 extern void mali_executor_unlock(void);
110
111 static void gpu_dfs_func(struct work_struct *work);
112 static void mali_platform_utilization(struct mali_gpu_utilization_data *data);
113
114 static DECLARE_WORK(gpu_dfs_work, &gpu_dfs_func);
115
116 DEFINE_SEMAPHORE(gpu_dfs_sem);
117
118 static struct gpu_dfs_context gpu_dfs_ctx = {
119         .sem = &gpu_dfs_sem,
120 };
121
122 struct mali_gpu_device_data mali_gpu_data = {
123         .shared_mem_size = ARCH_MALI_MEMORY_SIZE_DEFAULT,
124         .control_interval = 100,
125         .utilization_callback = mali_platform_utilization,
126         .get_clock_info = NULL,
127         .get_freq = NULL,
128         .set_freq = NULL,
129 };
130
131 static void gpu_freq_list_show(char *buf)
132 {
133         struct gpu_dfs_context *ctx = &gpu_dfs_ctx;
134         int i;
135
136         for (i = 0; i < ctx->freq_list_len; i++)
137                 buf += sprintf(buf, "%2d  %6d\n", i, ctx->freq_list[i].freq);
138 }
139
140 static int sprd_gpu_domain_state(void)
141 {
142         /* FIXME: rtc domain */
143         unsigned int power_state1, power_state2, power_state3;
144         unsigned long timeout = jiffies + msecs_to_jiffies(__SPRD_GPU_TIMEOUT);
145
146         do {
147                 cpu_relax();
148                 power_state1 = sci_glb_read(REG_PMU_APB_PWR_STATUS0_DBG,
149                                                 BITS_PD_GPU_TOP_STATE(-1));
150                 power_state2 = sci_glb_read(REG_PMU_APB_PWR_STATUS0_DBG,
151                                                 BITS_PD_GPU_TOP_STATE(-1));
152                 power_state3 = sci_glb_read(REG_PMU_APB_PWR_STATUS0_DBG,
153                                                 BITS_PD_GPU_TOP_STATE(-1));
154                 if (time_after(jiffies, timeout)) {
155                         pr_emerg("gpu domain not ready, state %08x %08x\n",
156                                 sci_glb_read(REG_PMU_APB_PWR_STATUS0_DBG, -1),
157                                 sci_glb_read(REG_AON_APB_APB_EB0, -1));
158                 }
159         } while ((power_state1 != power_state2) ||
160                         (power_state2 != power_state3));
161
162         return (int)(power_state1);
163 }
164
165 static void sprd_gpu_domain_wait_for_ready(void)
166 {
167         int timeout_count = 2000;
168
169         while (sprd_gpu_domain_state() != BITS_PD_GPU_TOP_STATE(0)) {
170                 if (!timeout_count) {
171                         pr_emerg(
172                         "gpu domain not ready too long time, state %08x %08x\n",
173                                 sci_glb_read(REG_PMU_APB_PWR_STATUS0_DBG, -1),
174                                 sci_glb_read(REG_AON_APB_APB_EB0, -1));
175                         return;
176                 }
177                 udelay(50);
178                 timeout_count--;
179         }
180 }
181
182 static inline void mali_set_div(int clock_div)
183 {
184         sci_glb_write(REG_GPU_APB_APB_CLK_CTRL, BITS_CLK_GPU_DIV(clock_div - 1),
185                         BITS_CLK_GPU_DIV(3));
186 }
187
188 static inline void mali_power_on(void)
189 {
190         sci_glb_clr(REG_PMU_APB_PD_GPU_TOP_CFG, BIT_PD_GPU_TOP_FORCE_SHUTDOWN);
191         udelay(100);
192         mali_executor_lock();
193         gpu_dfs_ctx.gpu_power_on = 1;
194         mali_executor_unlock();
195 }
196
197 static inline void mali_power_off(void)
198 {
199         mali_executor_lock();
200         gpu_dfs_ctx.gpu_power_on = 0;
201         mali_executor_unlock();
202         sci_glb_set(REG_PMU_APB_PD_GPU_TOP_CFG, BIT_PD_GPU_TOP_FORCE_SHUTDOWN);
203 }
204
205 static inline void mali_clock_on(void)
206 {
207         struct gpu_dfs_context *ctx = &gpu_dfs_ctx;
208         int i;
209
210         for (i = 0; i < ctx->gpu_clk_num; i++) {
211 #ifdef CONFIG_COMMON_CLK
212                 clk_prepare_enable(ctx->gpu_clk_src[i]);
213 #else
214                 clk_enable(ctx->gpu_clk_src[i]);
215 #endif
216         }
217
218 #ifdef CONFIG_COMMON_CLK
219         clk_prepare_enable(ctx->gpu_clock_i);
220 #else
221         clk_enable(ctx->gpu_clock_i);
222 #endif
223         sprd_gpu_domain_wait_for_ready();
224
225         clk_set_parent(ctx->gpu_clock, ctx->freq_default->clk_src);
226
227         MALI_DEBUG_ASSERT(ctx->freq_cur);
228         clk_set_parent(ctx->gpu_clock, ctx->freq_cur->clk_src);
229         mali_set_div(ctx->freq_cur->div);
230
231 #ifdef CONFIG_COMMON_CLK
232         clk_prepare_enable(ctx->gpu_clock);
233 #else
234         clk_enable(ctx->gpu_clock);
235 #endif
236         udelay(100);
237
238         mali_executor_lock();
239         ctx->gpu_clock_on = 1;
240         mali_executor_unlock();
241
242         gpu_freq_cur = ctx->freq_cur->freq;
243 #ifdef CONFIG_SYSTEM_LOAD_ANALYZER
244         store_external_load_factor(GPU_FREQ, gpu_freq_cur);
245 #endif
246 }
247
248 static inline void mali_clock_off(void)
249 {
250         struct gpu_dfs_context *ctx = &gpu_dfs_ctx;
251         int i;
252
253         gpu_freq_cur = 0;
254 #ifdef CONFIG_SYSTEM_LOAD_ANALYZER
255         store_external_load_factor(GPU_UTILIZATION, 0);
256         store_external_load_factor(GPU_FREQ, gpu_freq_cur);
257 #endif
258
259         mali_executor_lock();
260         ctx->gpu_clock_on = 0;
261         mali_executor_unlock();
262
263 #ifdef CONFIG_COMMON_CLK
264         clk_disable_unprepare(ctx->gpu_clock);
265         clk_disable_unprepare(ctx->gpu_clock_i);
266 #else
267         clk_disable(ctx->gpu_clock);
268         clk_disable(ctx->gpu_clock_i);
269 #endif
270
271         for (i = 0; i < ctx->gpu_clk_num; i++) {
272 #ifdef CONFIG_COMMON_CLK
273                 clk_disable_unprepare(ctx->gpu_clk_src[i]);
274 #else
275                 clk_disable(ctx->gpu_clk_src[i]);
276 #endif
277         }
278 }
279
280 int mali_platform_device_init(struct platform_device *pdev)
281 {
282 #ifndef CONFIG_SCX35L64BIT_FPGA /* not use fpga */
283         struct gpu_dfs_context *ctx = &gpu_dfs_ctx;
284         int i, err = -1;
285 #ifdef CONFIG_ARCH_SCX30G
286         int clksrc_300m_idx = -1;
287 #endif
288 #ifdef CONFIG_MALI_DT
289         extern struct of_device_id base_dt_ids[];
290         struct device_node *np;
291         int clk_cnt;
292
293         np = of_find_matching_node(NULL, base_dt_ids);
294         if (!np)
295                 return err;
296
297         ctx->gpu_clock_i = of_clk_get(np, 0);
298         MALI_DEBUG_ASSERT(ctx->gpu_clock_i);
299         ctx->gpu_clock = of_clk_get(np, 1);
300         MALI_DEBUG_ASSERT(ctx->gpu_clock);
301
302         clk_cnt = of_property_count_strings(np, "clock-names");
303         ctx->gpu_clk_num = clk_cnt - 2;
304         ctx->gpu_clk_src = vmalloc(sizeof(struct clk *) * ctx->gpu_clk_num);
305         MALI_DEBUG_ASSERT(ctx->gpu_clk_src);
306
307         for (i = 0; i < ctx->gpu_clk_num; i++) {
308                 const char *clk_name;
309
310                 of_property_read_string_index(np, "clock-names", i + 2,
311                                                 &clk_name);
312                 ctx->gpu_clk_src[i] = of_clk_get_by_name(np, clk_name);
313                 MALI_DEBUG_ASSERT(ctx->gpu_clk_src[i]);
314 #ifdef CONFIG_ARCH_SCX30G
315                 if (!strcmp(clk_name, "clk_300m_gpu_gate"))
316                         clksrc_300m_idx = i;
317 #endif
318         }
319
320         of_property_read_u32(np, "freq-list-len", &ctx->freq_list_len);
321         ctx->freq_list =
322                 vmalloc(sizeof(struct gpu_freq_info) * ctx->freq_list_len);
323         MALI_DEBUG_ASSERT(ctx->freq_list);
324
325         for (i = 0; i < ctx->freq_list_len; i++) {
326                 int clk;
327
328                 of_property_read_u32_index(np, "freq-lists", 3 * i + 1, &clk);
329                 ctx->freq_list[i].clk_src = ctx->gpu_clk_src[clk - 2];
330                 MALI_DEBUG_ASSERT(ctx->freq_list[i].clk_src);
331                 of_property_read_u32_index(np, "freq-lists", 3 * i,
332                                                 &ctx->freq_list[i].freq);
333                 of_property_read_u32_index(np, "freq-lists", 3 * i + 2,
334                                                 &ctx->freq_list[i].div);
335                 ctx->freq_list[i].up_threshold =
336                                         ctx->freq_list[i].freq * UP_THRESHOLD;
337         }
338
339         of_property_read_u32(np, "freq-default", &i);
340         ctx->freq_default = &ctx->freq_list[i];
341         MALI_DEBUG_ASSERT(ctx->freq_default);
342
343         of_property_read_u32(np, "freq-9", &i);
344         ctx->freq_9 = &ctx->freq_list[i];
345         MALI_DEBUG_ASSERT(ctx->freq_9);
346
347         of_property_read_u32(np, "freq-8", &i);
348         ctx->freq_8 = &ctx->freq_list[i];
349         MALI_DEBUG_ASSERT(ctx->freq_8);
350
351         of_property_read_u32(np, "freq-7", &i);
352         ctx->freq_7 = &ctx->freq_list[i];
353         MALI_DEBUG_ASSERT(ctx->freq_7);
354
355         of_property_read_u32(np, "freq-5", &i);
356         ctx->freq_5 = &ctx->freq_list[i];
357         MALI_DEBUG_ASSERT(ctx->freq_5);
358
359         of_property_read_u32(np, "freq-range-max", &i);
360         ctx->freq_range_max = &ctx->freq_list[i];
361         MALI_DEBUG_ASSERT(ctx->freq_range_max);
362
363         of_property_read_u32(np, "freq-range-min", &i);
364         ctx->freq_range_min = &ctx->freq_list[i];
365         MALI_DEBUG_ASSERT(ctx->freq_range_min);
366
367         of_node_put(np);
368
369         ctx->freq_max = ctx->freq_range_max;
370         ctx->freq_min = ctx->freq_range_min;
371         ctx->freq_cur = ctx->freq_default;
372 #endif
373
374         sci_glb_write(REG_PMU_APB_PD_GPU_TOP_CFG,
375                         BITS_PD_GPU_TOP_PWR_ON_DLY(1), 0xff0000);
376         sci_glb_write(REG_PMU_APB_PD_GPU_TOP_CFG,
377                         BITS_PD_GPU_TOP_PWR_ON_SEQ_DLY(1), 0xff00);
378         sci_glb_write(REG_PMU_APB_PD_GPU_TOP_CFG,
379                         BITS_PD_GPU_TOP_ISO_ON_DLY(1), 0xff);
380
381         mali_power_on();
382
383         mali_clock_on();
384 #ifdef CONFIG_ARCH_SCX30G
385         /* CPU could disable MPLL, so should increase MPLL refcnt */
386         if (clksrc_300m_idx != -1) {
387 #ifdef CONFIG_COMMON_CLK
388                 clk_prepare_enable(ctx->gpu_clk_src[clksrc_300m_idx]);
389 #else
390                 clk_enable(ctx->gpu_clk_src[clksrc_300m_idx]);
391 #endif
392         }
393 #endif
394
395         ctx->gpu_dfs_workqueue = create_singlethread_workqueue("gpu_dfs");
396
397         err = platform_device_add_data(pdev, &mali_gpu_data,
398                                         sizeof(mali_gpu_data));
399         if (!err) {
400 #ifdef CONFIG_PM_RUNTIME
401 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
402                 pm_runtime_set_autosuspend_delay(&(pdev->dev), 50);
403                 pm_runtime_use_autosuspend(&(pdev->dev));
404 #endif
405                 pm_runtime_enable(&(pdev->dev));
406 #endif
407         }
408
409         gpu_freq_list = vmalloc(sizeof(char) * 256);
410         gpu_freq_list_show(gpu_freq_list);
411
412         return err;
413 #else /* use fpga */
414 #ifdef CONFIG_MALI_DT
415         if (!of_find_matching_node(NULL, gpu_ids))
416                 return -1;
417 #endif
418         sci_glb_clr(REG_PMU_APB_PD_GPU_TOP_CFG, BIT_PD_GPU_TOP_FORCE_SHUTDOWN);
419         mdelay(2);
420
421         return 0;
422 #endif /* use fpga */
423 }
424
425 int mali_platform_device_deinit(struct platform_device *device)
426 {
427         struct gpu_dfs_context *ctx = &gpu_dfs_ctx;
428
429         destroy_workqueue(ctx->gpu_dfs_workqueue);
430
431         mali_clock_off();
432
433         mali_power_off();
434
435         vfree(gpu_freq_list);
436         vfree(ctx->freq_list);
437         vfree(ctx->gpu_clk_src);
438
439         return 0;
440 }
441
442 static int freq_search(struct gpu_freq_info freq_list[], int len, int key)
443 {
444         int low = 0, high = len - 1, mid;
445
446         if (key < 0)
447                 return -1;
448
449         while (low <= high) {
450                 mid = (low + high) / 2;
451
452                 if (key == freq_list[mid].freq)
453                         return mid;
454
455                 if (key < freq_list[mid].freq)
456                         high = mid - 1;
457                 else
458                         low = mid + 1;
459         }
460
461         return -1;
462 }
463
464 void mali_platform_power_mode_change(int power_mode)
465 {
466         struct gpu_dfs_context *ctx = &gpu_dfs_ctx;
467
468         down(ctx->sem);
469
470         MALI_DEBUG_PRINT(3,
471                 ("Mali power mode change %d, gpu_power_on=%d gpu_clock_on=%d\n",
472                         power_mode, ctx->gpu_power_on, ctx->gpu_clock_on));
473
474         switch (power_mode) {
475         case 0: /* MALI_POWER_MODE_ON */
476                 if (!ctx->gpu_power_on) {
477                         /*
478                          * The max limit feature is applied only utilization
479                          * routine, so GPU can work with max freq even though
480                          * max limit is set.
481                          */
482                         int max_index = freq_search(ctx->freq_list,
483                                                         ctx->freq_list_len,
484                                                         gpu_freq_max_limit);
485
486                         if (max_index >= 0)
487                                 ctx->freq_max = &ctx->freq_list[max_index];
488
489                         ctx->freq_cur = ctx->freq_max;
490                         mali_power_on();
491                         mali_clock_on();
492                 }
493
494                 if (!ctx->gpu_clock_on)
495                         mali_clock_on();
496                 break;
497         case 1: /* MALI_POWER_MODE_LIGHT_SLEEP */
498         case 2: /* MALI_POWER_MODE_DEEP_SLEEP */
499         default:
500                 if (ctx->gpu_clock_on)
501                         mali_clock_off();
502
503                 if (ctx->gpu_power_on)
504                         mali_power_off();
505                 break;
506         };
507
508         up(ctx->sem);
509 }
510
511 static void gpu_dfs_func(struct work_struct *work)
512 {
513         struct gpu_dfs_context *ctx = &gpu_dfs_ctx;
514
515         down(ctx->sem);
516
517         if (!ctx->gpu_power_on || !ctx->gpu_clock_on) {
518                 up(ctx->sem);
519                 return;
520         }
521
522         if (ctx->freq_next == ctx->freq_cur) {
523                 up(ctx->sem);
524                 return;
525         }
526
527 #if !GPU_GLITCH_FREE_DFS
528         mali_dev_pause();
529
530 #ifdef CONFIG_COMMON_CLK
531         clk_disable_unprepare(ctx->gpu_clock);
532 #else
533         clk_disable(ctx->gpu_clock);
534 #endif
535 #endif
536
537         if (ctx->freq_next->clk_src != ctx->freq_cur->clk_src)
538                 clk_set_parent(ctx->gpu_clock, ctx->freq_next->clk_src);
539
540         if (ctx->freq_next->div != ctx->freq_cur->div)
541                 mali_set_div(ctx->freq_next->div);
542
543         ctx->freq_cur = ctx->freq_next;
544         gpu_freq_cur = ctx->freq_cur->freq;
545 #ifdef CONFIG_SYSTEM_LOAD_ANALYZER
546         store_external_load_factor(GPU_FREQ, gpu_freq_cur);
547 #endif
548
549 #if !GPU_GLITCH_FREE_DFS
550 #ifdef CONFIG_COMMON_CLK
551         clk_prepare_enable(ctx->gpu_clock);
552 #else
553         clk_enable(ctx->gpu_clock);
554 #endif
555         udelay(100);
556
557         mali_dev_resume();
558 #endif
559
560         up(ctx->sem);
561 }
562
563 /*
564  * DVFS of SPRD implementation
565  */
566
567 #if !SPRD_DFS_ONE_STEP_SCALE_DOWN
568 static const struct gpu_freq_info
569 *get_next_freq(const struct gpu_freq_info *min_freq,
570                         const struct gpu_freq_info *max_freq, int target)
571 {
572         const struct gpu_freq_info *freq;
573
574         for (freq = min_freq; freq <= max_freq; freq++) {
575                 if (freq->up_threshold > target)
576                         return freq;
577         }
578
579         return max_freq;
580 }
581 #endif
582
583 static void mali_platform_utilization(struct mali_gpu_utilization_data *data)
584 {
585 #ifndef CONFIG_SCX35L64BIT_FPGA  /* not use fpga */
586         struct gpu_dfs_context *ctx = &gpu_dfs_ctx;
587         int max_index, min_index;
588
589         ctx->cur_load = data->utilization_gpu;
590
591         MALI_DEBUG_PRINT(3,
592                         ("GPU_DFS mali_utilization  gpu:%d  gp:%d pp:%d\n",
593                                 data->utilization_gpu, data->utilization_gp,
594                                 data->utilization_pp));
595         MALI_DEBUG_PRINT(3,
596                         ("GPU_DFS gpu_boost_level:%d gpu_boost_sf_level:%d\n",
597                                 gpu_boost_level, gpu_boost_sf_level));
598
599         switch (gpu_boost_level) {
600         case 10:
601                 ctx->freq_max = ctx->freq_min =
602                                         &ctx->freq_list[ctx->freq_list_len - 1];
603                 break;
604         case 9:
605                 ctx->freq_max = ctx->freq_min = ctx->freq_9;
606                 break;
607         case 7:
608                 ctx->freq_max = ctx->freq_min = ctx->freq_7;
609                 break;
610         case 5:
611                 ctx->freq_max = ctx->freq_min = ctx->freq_5;
612                 break;
613         case 0:
614         default:
615                 ctx->freq_max = ctx->freq_range_max;
616                 ctx->freq_min = ctx->freq_range_min;
617                 break;
618         }
619
620         if (!gpu_boost_level && (gpu_boost_sf_level > 0)) {
621                 ctx->freq_max = ctx->freq_min =
622                                         &ctx->freq_list[ctx->freq_list_len - 1];
623         }
624
625         gpu_boost_level = 0;
626         gpu_boost_sf_level = 0;
627
628         /*
629          * SPRD_MATCH_DFS_TO_LOWER_FREQ
630          *
631          * If user uses gpufreq_min/max_limit sysfs node, it is possible that
632          * the minimum DFS frequency is higher than the maximum one.
633          * So we should correct this inversion phenomenon and there are two
634          * possible solutions.
635          * The first one is to change the minimum DFS frequency as the maximum
636          * one and is suitable for power-saving mode which requires to keep
637          * minimum frequency always.
638          * The other one is to change the maximum DFS frequency as the minimum
639          * one and is suitable for performance mode which requires to keep
640          * maximum frequency always.
641          */
642
643         /* limit min freq */
644         min_index = freq_search(ctx->freq_list, ctx->freq_list_len,
645                                 gpu_freq_min_limit);
646         if ((min_index >= 0) &&
647                 (ctx->freq_min->freq < ctx->freq_list[min_index].freq)) {
648                 ctx->freq_min = &ctx->freq_list[min_index];
649 #if !SPRD_MATCH_DFS_TO_LOWER_FREQ
650                 if (ctx->freq_min->freq > ctx->freq_max->freq)
651                         ctx->freq_max = ctx->freq_min;
652 #endif
653         }
654
655         /* limit max freq */
656         max_index = freq_search(ctx->freq_list, ctx->freq_list_len,
657                                 gpu_freq_max_limit);
658         if ((max_index >= 0) &&
659                 (ctx->freq_max->freq > ctx->freq_list[max_index].freq)) {
660                 ctx->freq_max = &ctx->freq_list[max_index];
661 #if SPRD_MATCH_DFS_TO_LOWER_FREQ
662                 if (ctx->freq_max->freq < ctx->freq_min->freq)
663                         ctx->freq_min = ctx->freq_max;
664 #endif
665         }
666
667         /*
668          * Scale up to maximum frequency if current load ratio is equal or
669          * greater than UP_THRESHOLD.
670          */
671         if (ctx->cur_load >= (256 * UP_THRESHOLD)) {
672                 ctx->freq_next = ctx->freq_max;
673
674                 MALI_DEBUG_PRINT(3, ("GPU_DFS util %3d; next_freq %6d\n",
675                                         ctx->cur_load, ctx->freq_next->freq));
676         } else {
677                 int target_freq = ctx->freq_cur->freq * ctx->cur_load / 256;
678 #if SPRD_DFS_ONE_STEP_SCALE_DOWN
679                 /*
680                  * Scale down one step if current load ratio is equal or less
681                  * than DOWN_THRESHOLD.
682                  */
683                 ctx->freq_next = ctx->freq_cur;
684                 if (ctx->cur_load <= (256 * DOWN_THRESHOLD)) {
685                         if (ctx->freq_next != &ctx->freq_list[0])
686                                 ctx->freq_next--;
687
688                         /* Avoid meaningless scale down */
689                         if (ctx->freq_next->up_threshold < target_freq)
690                                 ctx->freq_next++;
691                 }
692
693                 /* Consider limit max & min freq */
694                 if (ctx->freq_next->freq > ctx->freq_max->freq)
695                         ctx->freq_next = ctx->freq_max;
696                 else if (ctx->freq_next->freq < ctx->freq_min->freq)
697                         ctx->freq_next = ctx->freq_min;
698 #else
699                 /* Scale down to target frequency */
700                 ctx->freq_next = get_next_freq(ctx->freq_min, ctx->freq_max,
701                                                                 target_freq);
702 #endif
703
704                 MALI_DEBUG_PRINT(3,
705                         ("GPU_DFS util %3d; target_freq %6d; cur_freq %6d -> next_freq %6d\n",
706                                 ctx->cur_load, target_freq, ctx->freq_cur->freq,
707                                 ctx->freq_next->freq));
708         }
709
710 #ifdef CONFIG_SYSTEM_LOAD_ANALYZER
711         store_external_load_factor(GPU_UTILIZATION, ctx->cur_load);
712 #endif
713
714         if (ctx->freq_next->freq != ctx->freq_cur->freq)
715                 queue_work(ctx->gpu_dfs_workqueue, &gpu_dfs_work);
716 #endif  /* not use fpga */
717 }
718
719 bool mali_is_on(void)
720 {
721         struct gpu_dfs_context *ctx = &gpu_dfs_ctx;
722
723         if (ctx->gpu_power_on && ctx->gpu_clock_on)
724                 return true;
725         else
726                 MALI_DEBUG_PRINT(5, ("gpu_power_on = %d, gpu_clock_on = %d\n",
727                                         ctx->gpu_power_on, ctx->gpu_clock_on));
728
729         return false;
730 }