import OT_8063_20170412 mali driver
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / gpu / mt8127 / mali / mali / platform / arm / arm_core_scaling.c
1 /*
2 * This confidential and proprietary software may be used only as
3 * authorised by a licensing agreement from ARM Limited
4 * (C) COPYRIGHT 2013-2015 ARM Limited
5 * ALL RIGHTS RESERVED
6 * The entire notice above must be reproduced on all authorised
7 * copies and copies may only be made to the extent permitted
8 * by a licensing agreement from ARM Limited.
9 */
10
11 /**
12 * @file arm_core_scaling.c
13 * Example core scaling policy.
14 */
15
16 #include "arm_core_scaling.h"
17
18 #include <linux/mali/mali_utgard.h>
19 #include "mali_kernel_common.h"
20
21 #include <linux/workqueue.h>
22
23 static int num_cores_total;
24 static int num_cores_enabled;
25
26 static struct work_struct wq_work;
27
28 static void set_num_cores(struct work_struct *work)
29 {
30 int err = mali_perf_set_num_pp_cores(num_cores_enabled);
31 MALI_DEBUG_ASSERT(0 == err);
32 MALI_IGNORE(err);
33 }
34
35 static void enable_one_core(void)
36 {
37 if (num_cores_enabled < num_cores_total) {
38 ++num_cores_enabled;
39 schedule_work(&wq_work);
40 MALI_DEBUG_PRINT(3, ("Core scaling: Enabling one more core\n"));
41 }
42
43 MALI_DEBUG_ASSERT(1 <= num_cores_enabled);
44 MALI_DEBUG_ASSERT(num_cores_total >= num_cores_enabled);
45 }
46
47 static void disable_one_core(void)
48 {
49 if (1 < num_cores_enabled) {
50 --num_cores_enabled;
51 schedule_work(&wq_work);
52 MALI_DEBUG_PRINT(3, ("Core scaling: Disabling one core\n"));
53 }
54
55 MALI_DEBUG_ASSERT(1 <= num_cores_enabled);
56 MALI_DEBUG_ASSERT(num_cores_total >= num_cores_enabled);
57 }
58
59 static void enable_max_num_cores(void)
60 {
61 if (num_cores_enabled < num_cores_total) {
62 num_cores_enabled = num_cores_total;
63 schedule_work(&wq_work);
64 MALI_DEBUG_PRINT(3, ("Core scaling: Enabling maximum number of cores\n"));
65 }
66
67 MALI_DEBUG_ASSERT(num_cores_total == num_cores_enabled);
68 }
69
70 void mali_core_scaling_init(int num_pp_cores)
71 {
72 INIT_WORK(&wq_work, set_num_cores);
73
74 num_cores_total = num_pp_cores;
75 num_cores_enabled = num_pp_cores;
76
77 /* NOTE: Mali is not fully initialized at this point. */
78 }
79
80 void mali_core_scaling_sync(int num_cores)
81 {
82 num_cores_enabled = num_cores;
83 }
84
85 void mali_core_scaling_term(void)
86 {
87 flush_scheduled_work();
88 }
89
90 #define PERCENT_OF(percent, max) ((int) ((percent)*(max)/100.0 + 0.5))
91
92 void mali_core_scaling_update(struct mali_gpu_utilization_data *data)
93 {
94 /*
95 * This function implements a very trivial PP core scaling algorithm.
96 *
97 * It is _NOT_ of production quality.
98 * The only intention behind this algorithm is to exercise and test the
99 * core scaling functionality of the driver.
100 * It is _NOT_ tuned for neither power saving nor performance!
101 *
102 * Other metrics than PP utilization need to be considered as well
103 * in order to make a good core scaling algorithm.
104 */
105
106 MALI_DEBUG_PRINT(3, ("Utilization: (%3d, %3d, %3d), cores enabled: %d/%d\n", data->utilization_gpu, data->utilization_gp, data->utilization_pp, num_cores_enabled, num_cores_total));
107
108 /* NOTE: this function is normally called directly from the utilization callback which is in
109 * timer context. */
110
111 if (PERCENT_OF(90, 256) < data->utilization_pp) {
112 enable_max_num_cores();
113 } else if (PERCENT_OF(50, 256) < data->utilization_pp) {
114 enable_one_core();
115 } else if (PERCENT_OF(40, 256) < data->utilization_pp) {
116 /* do nothing */
117 } else if (PERCENT_OF(0, 256) < data->utilization_pp) {
118 disable_one_core();
119 } else {
120 /* do nothing */
121 }
122 }